Как я могу определить, какой процесс создает UDP-трафик в Linux?

39

Моя машина постоянно делает запрос трафика udp dns. что мне нужно знать, это PID процесса, генерирующего этот трафик.

Обычный способ в соединении TCP - использовать netstat / lsof и получить процесс, связанный с pid.

Является ли UDP соединением состояния, поэтому, когда я вызываю netastat / lsof, я вижу его, только если открыт сокет UDP и он отправляет трафик.

Я пытался с lsof -i UDPи с nestat -anpue, но я не могу найти, какой процесс выполняет этот запрос, потому что мне нужно точно вызвать lsof / netstat, когда отправляется трафик udp, если я вызываю lsof / netstat до / после отправки дейтаграммы udp невозможно просмотреть открытый сокет UDP.

Вызов netstat / lsof точно, когда отправляется пакет 3/4 udp, НЕВОЗМОЖЕН.

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

Кто-нибудь может мне помочь?

Я root на этой машине. FEDORA 12 Linux noise.company.lan 2.6.32.16-141.fc12.x86_64 # 1 SMP Ср. 7 июля 04:49:59 UTC 2010 x86_64 x86_64 x86_64 GNU / Linux

Боос
источник

Ответы:

48

Аудит Linux может помочь. Он будет по крайней мере определять местонахождение пользователей и процессов, осуществляющих сетевые подключения дейтаграмм. UDP-пакеты - это дейтаграммы.

Сначала установите auditdфреймворк на свою платформу и убедитесь, что он auditctl -lчто- то возвращает, даже если он говорит, что правила не определены.

Затем добавьте правило для наблюдения за системным вызовом socket()и отметьте его для более легкого поиска позже ( -k). Я должен предположить, что вы используете 64-битную архитектуру, но вы можете заменить b32ее, b64если нет.

auditctl -a exit,always -F arch=b64 -F a0=2 -F a1\&=2 -S socket -k SOCKET

Вы должны выбрать man-страницы и заголовочные файлы, чтобы построить это, но то, что он захватывает, по сути, это системный вызов: socket(PF_INET, SOCK_DGRAM|X, Y)где третий параметр не указан, но часто равен нулю. PF_INETравно 2 и SOCK_DGRAMравно 2. TCP-соединения будут использовать, SOCK_STREAMкоторый будет установлен a1=1. ( SOCK_DGRAMво втором параметре может быть ORed с помощью SOCK_NONBLOCKили SOCK_CLOEXEC, следовательно, &=сравнения.) Это -k SOCKETнаше ключевое слово, которое мы хотим использовать при последующем поиске журналов аудита. Это может быть что угодно, но мне нравится, чтобы все было просто.

Пусть пройдет несколько минут и просмотрите контрольные записи. При желании вы можете форсировать пару пакетов, выполняя команду ping для хоста в сети, что приведет к поиску DNS, который использует UDP, что должно отключить наше предупреждение аудита.

ausearch -i -ts today -k SOCKET

И вывод, похожий на раздел ниже, появится. Я сокращаю это, чтобы выделить важные части

type=SYSCALL ... arch=x86_64 syscall=socket success=yes exit=1 a0=2 a1=2 ... pid=14510 ... auid=zlagtime uid=zlagtime ... euid=zlagtime ... comm=ping exe=/usr/bin/ping key=SOCKET

В приведенном выше выводе мы видим, что pingкоманда вызвала открытие сокета. Я мог бы тогда запустить strace -p 14510процесс, если он все еще работал. ppid(Идентификатор родительского процесса) также перечислен в случае это сценарий , который нерестится проблема ребенок много.

Теперь, если у вас много UDP-трафика, этого будет недостаточно, и вам придется прибегнуть к OProfile или SystemTap , которые в настоящее время находятся за пределами моего опыта.

Это должно помочь сузить положение в общем случае.

Когда вы закончите, удалите правило аудита, используя ту же строку, которую вы использовали для его создания, только замените -aна -d.

auditctl -d exit,always -F arch=b64 -F a0=2 -F a1\&=2 -S socket -k SOCKET
zerolagtime
источник
Я попробую, но я думаю, что это правильный ответ.
Boos
Это не собирание трафика, сбрасываемого iptables, по крайней мере, для меня.
2rs2ts
1
+1 за простоту по сравнению с методом systemtap (который более аналитичен, но нуждается в пакетах разработки ядра)
basos
23

Вы можете использовать netstat, но вам нужны правильные флаги, и это работает, только если процесс, который отправляет данные, все еще жив. Он не найдет следов чего-то, что ненадолго ожило, отправило UDP-трафик, а затем ушло. Это также требует локальных привилегий root. Это говорит:

Вот я запускаю ncat на моем локальном хосте, отправляю трафик UDP на порт 2345 на (несуществующей) машине 10.11.12.13:

[madhatta@risby]$ ncat -u 10.11.12.13 2345 < /dev/urandom

Вот некоторые выходные данные tcpdump, подтверждающие, что трафик идет:

[root@risby ~]# tcpdump -n -n port 2345
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
12:41:32.391750 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192
12:41:32.399723 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192
12:41:32.401817 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192
12:41:32.407051 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192
12:41:32.413492 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192
12:41:32.417417 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192

Вот полезный бит , использующий netstat с флагом -a (для просмотра сведений о порте) и флагом -p для просмотра сведений об идентификаторе процесса. Это флаг -p, который требует привилегий root:

[root@risby ~]# netstat -apn|grep -w 2345
udp        0      0 192.168.3.11:57550          10.11.12.13:2345            ESTABLISHED 9152/ncat     

Как вы можете видеть, pid 9152 используется как открытый порт 2345 на указанном удаленном хосте. Netstat также помогает через ps и сообщает мне имя процесса ncat.

Надеюсь, это пригодится.

MadHatter поддерживает Монику
источник
действительно хорошо сделано! : thumbup:
ThorstenS
2
Хотя есть подвох. Если проблема вызвана сценарием оболочки, порождающим подпроцесс, который выполняет поиск DNS, и этот процесс быстро завершается, то порт источника (57550 выше) будет постоянно меняться. В этом случае техника не будет работать, и вам придется принимать более решительные меры. Кроме того, ваш netstat должен был выполнить, grep -w 57550потому что несколько процессов могли выполнять поиск DNS на одном и том же сервере. Ваш метод не отличит их.
zerolagtime
1
Я согласен с обоими вашими возражениями, zerolagtime (но все равно спасибо за ваши добрые слова, ThorstenS!).
MadHatter поддерживает Монику
17

У меня была точно такая же проблема, и, к сожалению, auditdона для меня мало что сделала.

У меня был трафик с некоторых из моих серверов, идущий в сторону DNS-адресов Google, 8.8.8.8и 8.8.4.4. Теперь у моего сетевого администратора умеренный OCD, и он хотел убрать весь ненужный трафик, так как у нас есть наши внутренние DNS-кеши. Он хотел отключить исходящий порт 53 для всех, кроме тех серверов кеша.

Итак, после неудачи с auditctl, я копаться в systemtap. Я придумаю следующий скрипт:

# cat >> udp_detect_domain.stp <<EOF
probe udp.sendmsg {
  if ( dport == 53 && daddr == "8.8.8.8" ) {
    printf ("PID %5d (%s) sent UDP to %15s 53\n", pid(), execname(), daddr)
  }
}
EOF

Тогда просто запустите:

stap -v udp_detect_domain.stp

Это вывод, который я получил:

PID  3501 (python) sent UDP to  8.8.8.8 53
PID  3501 (python) sent UDP to  8.8.8.8 53
PID  3506 (python) sent UDP to  8.8.8.8 53

Это оно! После изменения resolv.confэтих PID не принимал изменения.


Надеюсь это поможет :)

Яков Сосич
источник
5

Вот опция systemtap, использующая пробники сетевого фильтра, доступные в stap версии 1.8 и выше. Смотрите также man probe::netfilter.ip.local_out.

# stap -e 'probe netfilter.ip.local_out {
  if (dport == 53) # or parametrize
      printf("%s[%d] %s:%d\n", execname(), pid(), daddr, dport)
}'
ping[24738] 192.168.1.10:53
ping[24738] 192.168.1.10:53
^C
fche
источник
4

Я бы использовал сетевой сниффер типа tcpdump или wireshark для просмотра DNS-запросов. Содержимое запроса может дать представление о том, какая программа их выдаёт.

RedGrittyBrick
источник
никакой информации в потоке трафика я просто уже смотрю.
Boos
Нет информации? Пустые пакеты? Я имел в виду, что если что-то пытается разрешить updates.java.sun.com или rss.cnn.com, вы можете извлечь из этого что-то полезное.
RedGrittyBrick
DNS-запрос ищет внутренний прокси. Прямо сейчас я обнаружил, что процесс, но вопрос все еще жив для общей техники решения проблем
Boos
lsof -i | awk '/ UDP /'
c4f4t0r
3

Имейте в виду, что при использовании autitctl nscd, например, использует немного другой параметр в системном вызове сокета при выполнении DNS-запроса:

socket(AF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP)

Поэтому, чтобы убедиться, что вы перехватываете эти запросы в дополнение к тем, что были упомянуты выше, вы можете добавить дополнительный фильтр с тем же именем, если хотите:

auditctl -a exit,always -F arch=b64 -F a0=2  -F a1=2050 -S socket -k SOCKET

Здесь 2050 - это побитовое ИЛИ SOCK_DGRAM (2) и SOCK_NONBLOCK (2048).

Тогда поиск найдет оба фильтра с одинаковым ключом SOCKET:

ausearch -i -ts today -k SOCKET

Шестнадцатеричные значения для констант сокетов я нашел здесь: https://golang.org/pkg/syscall/#pkg-constants

Поскольку у меня нет комментариев к репутации, я добавил это.

Silverfibre
источник