Як я можу визначити, який процес складає трафік 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 / lso, коли точно надсилається 3/4 udp-пакету, НЕ МОЖЛИВИЙ.

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

Хто-небудь може мені допомогти?

Я корінь на цій машині 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

Для створення цього вам доведеться вибирати підручні сторінки та файли заголовків, але те, що воно захоплює, це по суті цей системний виклик:, 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нашому ключовому слові ми хочемо використовувати при пошуку аудиту пізніше. Це може бути будь-що, але мені подобається робити це просто.

Пропустіть кілька хвилин і перегляньте аудиторські сліди. Необов’язково, ви можете змусити пару пакетів, вивівши хост у мережу, що спричинить пошук 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

я спробую це, але я думаю, що це правильна відповідь.
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.

Будемо сподіватися, що це приносить користь.


дійсно приємно зроблено! : thumbup:
ThorstenS

2
Хоча є улов. Якщо проблема викликана сценарієм оболонки, що нерестує підпроцес, який здійснює пошук DNS і цей процес швидко закінчується, то вихідний порт (57550 вище) буде змінюватися весь час. У цьому випадку техніка не працюватиме, і вам доведеться вжити більш різких заходів. Крім того, ваш netstat повинен був зробити так, grep -w 57550тому що кілька процесів можуть робити пошук DNS на одному сервері. Ваш метод не розрізнив би їх.
нульовий час

1
Я погоджуюся з обома вашими запереченнями, нульовий час (але все одно дякую за добрі слова, 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, використовуючи зонди netfilter, доступні в stap verson 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

4

Я б використовував чистий sniffer, наприклад tcpdump або wireshark для перегляду запитів DNS. Вміст запиту може дати уявлення про те, яка програма їх видає.


немає інформації в трафіку нюхав я просто вже переглядаю.
boos

Немає інформації? Порожні пакети? Що я мав на увазі, якщо щось намагається вирішити update.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

Оскільки я не маю репутаційних балів для коментарів, я додав це.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.