Можно ли в Linux iptables регистрировать имя процесса / команды, которая инициирует исходящее соединение?

27

Я хотел бы отслеживать процессы, которые инициируют исходящие соединения на рабочем столе Linux. Лучшее, что я могу придумать, это:

iptables -A OUTPUT -m state --state NEW -j LOG --log-uid

Это регистрирует uid / gid, который инициирует соединение, но не имя процесса / команды или даже pid. Если бы я мог просто получить pid, я мог бы, вероятно, создать сценарий, который извлекает имя процесса при записи журнала, но кажется, что это даже невозможно.

В идеале я также хотел бы регистрировать процессы, которые также принимают входящие соединения.

Любые идеи, как это может быть возможно с iptables [или что-нибудь еще] на коробке Linux?

Нак
источник
Я полагаю (не совсем уверен), что на этот вопрос ответили на сервере, посмотрите.
niXar
Лично я бы использовал sysdig для этой работы.
Чарльз Даффи

Ответы:

7

Вы можете написать программу для мониторинга / proc / net / tcp, чей вывод выглядит так:

obi-wan ~ # cat /proc/net/tcp
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
   0: 00000000:0050 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 4847458 1 e6060560 300 0 0 2 -1
   1: 00000000:04D2 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 4847477 1 f2e64da0 300 0 0 2 -1
   2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 7109 1 f2e65ac0 300 0 0 2 -1
   3: 0100007F:177A 00000000:0000 0A 00000000:00000000 00:00000000 00000000  1000        0 4864457 1 d2726540 300 0 0 2 -1
   4: 00000000:01BB 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 4847462 1 e60609c0 300 0 0 2 -1
   5: 6B00A8C0:0016 30F4B5CA:C3AB 01 00000044:00000000 01:00000031 00000000     0        0 4982752 3 f2e64940 55 4 0 2 -1
   6: 0100007F:B143 0100007F:BC5E 01 00000000:00000000 00:00000000 00000000  1000        0 2130283 1 d59cce40 21 4 1 2 -1
   7: 0100007F:BC5E 0100007F:B143 01 00000000:00000000 00:00000000 00000000  1000        0 2130285 1 d59cd2a0 21 4 0 2 -1
   8: 6B00A8C0:0016 3276C35B:8E11 01 00000000:00000000 02:000ADAB1 00000000     0        0 4982629 2 d2727260 40 4 8 2 2
   9: 6B00A8C0:0016 6500A8C0:DD5D 01 00000538:00000000 01:00000029 00000000     0        0 4864416 5 e6061b40 42 12 27 3 -1

Затем вы можете связать открытые порты с inode, которые могут быть связаны с процессами и файловыми дескрипторами, выполнив ссылку на чтение файловых дескрипторов, перечисленных для каждого процесса:

obi-wan ~ # readlink /proc/28850/fd/3
socket:[4847458]

Смотрите здесь, что индекс 4847458 соответствует первому сокету tcp в списке выше. Вывод netstat -tapn подтверждает это для меня (и вспомните, что 0x50 == 80):

obi-wan ~ # netstat -tapn
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN     28850/cherokee-work

Когда программа монитора обнаружит изменение в / proc / net / tcp, проанализируйте данные и определите, является ли изменение вновь открытым сокетом. Затем вы можете просто перечислить все файловые дескрипторы для каждого процесса, перечисленного в / proc, выполнив readlink для каждого из них, чтобы найти соответствующий inode. Как только вы обнаружите, что у вас есть pid-владелец, из которого вы можете получить все, что захотите, особенно если у вас есть учет процессов.

Если вам не нужно, чтобы ваше уведомление было мгновенным, тогда ваша программа мониторинга может использовать медленный опрос (возможно, период 50 мс или 100 мс, или даже 1000 мс).

Бен Коллинз
источник
2
Спасибо за предоставленную возможность! Но требование опроса и запроса каждого дескриптора открытого файла каждый раз не очень надежно и очень неэффективно. Я все еще надеюсь, что кто-то найдет лучшее решение или уточнить, почему это больше не является частью iptables и почему --cmd-owner считается нефиксированным.
nealmcb
Если ядро ​​не изменит свой макет / proc или пока не изменится netstat и readlink или ps (маловероятно), я бы сказал, что это достаточно надежно. Какого рода вопросы эффективности вас беспокоят? Если вы хотите мгновенную обработку, вам нужно написать модуль ядра для использования с iptables.
Бен Коллинз
Если я регистрирую отклоненные соединения, то сокет немедленно уничтожается ядром, поэтому у меня очень мало шансов увидеть его в / proc. Может быть, только изменить REJECT на DROP, чтобы истекло время соединения ...
Marki555
В этом сценарии это не помогает из-за сверхмалого временного окна, но что касается хрупкости синтаксического анализа / proc, можно также просто использовать «lsof -F -i» и получить красиво отвлеченный дамп сети данные. Это также может быть отфильтровано (скажем, только по определенному порту), и уже выполнило все сопоставления имени файла / pid / пользователя для вас.
dannysauer
9

Вы хотите модуль соответствия владельца, который работает только в цепочке OUTPUT (и, возможно, PREROUTING ...?). Прочитайте документы, но это будет работать примерно так:

iptables --append OUTPUT -m owner --cmd-owner "$app" \
--jump LOG --log-level DEBUG --log-prefix "OUTPUT $app packet died: "

источник
1
Может ли команда iptables log установить и интерполировать переменную таким образом? Кажется, это не работает для меня. Кроме того, похоже, что опция --cmd-owner была удалена в ядре> = 2.6.15. Это прискорбно, потому что это кажется полезным вариантом.
4
Да, --cmd-owner был удален: «нефиксированный битый»
guettli
1
Спасибо за информацию, @guettli. На permalink.gmane.org/… есть дополнительные подробности, в которых приводятся дополнительные сведения из журнала изменений: «[NETFILTER]: удалить злоупотребление tasklist_lock в владельце ipt {, 6}; удалить совпадения cmd / sid / pid, поскольку его нефиксированная ошибка нарушена и находится в способ блокировки меняется на tasklist_lock. " Но я все еще хотел бы больше фона или лучших альтернатив.
nealmcb
5

Ничего общего с iptables или журналированием; но вот интерфейс типа top, который опрашивает каталог / proc / и отображает пропускную способность для каждой программы / pid:

http://sourceforge.net/projects/nethogs

«NetHogs - это небольшой инструмент« net top ». Вместо того, чтобы разбивать трафик по протоколу или подсети, как это делают большинство инструментов, он группирует пропускную способность по процессам. NetHogs не полагается на специальный модуль ядра для загрузки».

локал
источник
Я обнаружил, что nethogs дает ненадежную статистику, но поверх 2 (+ netatop) это хорошо.
Тобу
1

Поскольку я смотрю на похожий вопрос, пытаясь ограничить скорость по скайпу, я нашел

$ netstat -p | grep <mycmdname>

хороший способ связать номер порта с pid / cmd, теперь pid-owner / cmd-owner больше не поддерживается напрямую в iptables; Затем вам нужно проанализировать результат, а затем добавить правило iptables в соответствии с портом; естественно, вам понадобится какой-нибудь код очистки после / при выключении / перезагрузке системы и т. д .; сохранить номер порта / с в файл для справки во время очистки

на самом деле хороший ответ на вопрос номера портов

$ sudo netstat -p | grep "tcp.*<mycmdname>" | sed -r "s/.*<MYCOMPUTER>:([0-9]+).*/\1/"`

вам может понадобиться настроить элемент grep tcp в соответствии с вашими потребностями

тогда для моих целей было проще всего добавить фильтры tc u32 по номерам портов, записи iptables по номерам портов аналогичные

отметка
источник