linux: приостанавливать процесс при запуске

#linux #iptables #spawn

#linux #iptables #порождать

Вопрос:

Я хотел бы запустить процесс, приостановленный, возможно, в контексте другого пользователя (например, через sudo -u …), настроить некоторые правила iptables для созданного процесса, продолжить выполнение процесса и удалить правила iptable, когда процесс существует.

Существуют ли какие-либо стандартные средства (bash, corutils и т.д.), Которые позволяют мне достичь вышеуказанного? В частности, как я могу запустить процесс в приостановленном состоянии и получить его pid?

Комментарии:

1. Почему вам нужно запускать процесс перед настройкой среды? Это звучит как типичное использование комбинации fork / exec.

2. Я должен убедиться, что все коммуникации проходят через мои пользовательские iptables.

3. @Let_Me_Be потому что iptables должен знать PID для работы, в данном случае

4. @hanshans Ты не ответил на мой вопрос. Я спрашиваю, почему вам нужно запускать процесс, прежде чем вы его настроите. Обычный процесс заключается в настройке среды и последующем запуске процесса. Это просто кажется странным.

5. @Robin Ну, это все еще обычный сценарий fork / exec. Но неважно, я явно упускаю суть.

Ответ №1:

Напишите сценарий-оболочку start-stopped.sh следующим образом:

 #!/bin/sh
kill -STOP $$                                    # suspend myself 
                                                 # ... until I receive SIGCONT
exec $@                                          # exec argument list
  

А затем вызвать его как:

 sudo -u $SOME_USER start-stopped.sh mycommand amp;  # start mycommand in stopped state
MYCOMMAND_PID=$!
setup_iptables $MYCOMMAND_PID                    # use its PID to setup iptables
sudo -u $SOME_USER kill -CONT $MYCOMMAND_PID     # make mycommand continue
wait $MYCOMMAND_PID                              # wait for its termination
MYCOMMAND_EXIT_STATUS=$?                         
teardown_iptables                                # remove iptables rules
report $MYCOMMAND_EXIT_STATUS                    # report errors, if necessary
  

Однако все это излишне. Вам не нужно запускать ваш процесс в приостановленном состоянии, чтобы выполнить работу. Просто создайте скрипт-оболочку setup_iptables_and_start :

 #!/bin/sh
setup_iptables $$             # use my own PID to setup iptables
exec sudo -u $SOME_USER $@    # exec'ed command will have same PID
  

А затем вызвать его как

 setup_iptables_and_start mycommand || report errors
teardown_iptables
  

Ответ №2:

Вы можете написать оболочку C для своей программы, которая будет делать что-то вроде этого :

  1. fork и выведите дочерний pid.
  2. В дочернем окне дождитесь, пока пользователь нажмет Enter. Это переводит дочерний элемент в спящий режим, и вы можете добавить правила с помощью pid.
  3. После добавления правил пользователь нажимает enter. Дочерний элемент запускает вашу оригинальную программу, используя exec или system .

Сработает ли это?

Редактировать: На самом деле вы можете выполнить описанную выше процедуру с помощью сценария оболочки. Попробуйте следовать сценарию bash:

 #!/bin/bash

echo "Pid is $$"
echo -n "Press Enter.." 
read 
exec $@
  

Вы можете запустить это как /bin/bash ./run.sh <your command>

Ответ №3:

Один из способов сделать это — заручиться gdb возможностью приостановить программу при запуске ее основной функции (используя команду «break main»). Это гарантирует, что процесс приостанавливается достаточно быстро (хотя некоторые процедуры инициализации могут выполняться раньше main , они, вероятно, не сделают ничего существенного). Однако для этого вам понадобится отладочная информация для программы, которую вы хотите приостановить.

Я предлагаю вам сначала попробовать это вручную, посмотреть, как это работает, а затем разработать сценарий того, что вы сделали.

В качестве альтернативы, возможно, удастся ограничить процесс (если вы действительно пытаетесь это сделать!) без использования iptables, используя вместо этого SELinux или инструмент на основе ptrace, такой как sydbox.

Комментарии:

1. нет, это не сработает. Мне нужен универсальный инструмент, который работает с любым приложением.

2. Как насчет SELinux или sydbox? (Теперь я вижу, что мне следовало выделить эту часть моего ответа в отдельный ответ.)

3. SELinux кажется излишним для того, что я хочу сделать (поддерживает ли Debian 6 это вообще), но я попытаюсь заглянуть в sydbox

Ответ №4:

Я полагаю, вы могли бы сами написать утилиту, которая разветвляется и в которой дочерний элемент разветвления приостанавливает себя непосредственно перед выполнением exec. В противном случае рассмотрите возможность использования библиотеки LD_PRELOAD для выполнения ваших «пользовательских» операций.

Если вы заботитесь о том, чтобы сделать это безопасным, вам, вероятно, следует обратить внимание на более мощные инструменты (с помощью chroot, возможно, паравиртуализации, пользовательского режима Linux и т.д. и т.п.);

Последний совет: если вы не возражаете еще немного поработать с кодированием, интерфейс ptrace должен позволить вам делать то, что вы описываете (поскольку он используется для реализации отладчиков с)

Ответ №5:

Вероятно, вам понадобится PID информация о программе, которую вы запускаете, прежде, чем эта программа действительно начнет выполняться. Вы могли бы сделать это следующим образом.

  • Запустите простой скрипт
  • Заставить скрипт ждать
    • Вероятно, вы можете использовать suspend встроенную версию bash, но в худшем случае вы можете заставить ее остановиться с помощью сигнала
  • Используйте PID процесс bash любым удобным для вас способом
  • Перезапустите остановленный процесс bash ( SIGCONT ) и выполните exec другой встроенный запуск вашего реального процесса (он унаследует PID)