Нахождение недолговечного процесса владельца TCP-соединений

15

Запуск tcpdumpна локальных подключений к серверу Apache, я нашел соединения TCP создаются и закрываются сразу каждые 2 секунды. Как мне найти, какой процесс отвечает за это? netstat -ctpне помогло, соединения были слишком быстрыми, а идентификатор процесса не отображается для TIME_WAIT.

Оказалось, что это были тесты на гапрокси, с которыми я мог проверить strace, но я до сих пор не знаю способа точно определить гапрокси.

pmezard
источник

Ответы:

20

Вы можете использовать Audit Framework для таких вещей. Они не очень "удобны для пользователя" или интуитивно понятны, поэтому требуют немного покопаться с вашей стороны.

Сначала убедитесь, что у вас установлен Audit, и что ваше ядро ​​его поддерживает.
Для Ubuntu вы можете установить его, apt-get install auditdнапример.

Затем вы добавляете политику аудита для мониторинга всех connectсистемных вызовов, например:

auditctl -a exit,always -F arch=b64 -S connect -k MYCONNECT

Если вы используете 32-битную установку Linux, вы должны изменить b64 на b32.

Эта команда вставит политику в структуру аудита, и любые системные вызовы connect () теперь будут записываться в ваши журналы аудита (обычно /var/log/audit/audit.log), чтобы вы могли на них посмотреть.

Например, соединение с netcat с портом 80 news.ycombinator.com приведет к чему-то вроде этого:

type=SYSCALL msg=audit(1326872512.453:12752): arch=c000003e syscall=42 success=no exit=-115 a0=3 a1=24e8fa0 a2=10 a3=7fff07a44cd0 items=0 ppid=5675 pid=7270 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts4 ses=4294967295 comm="nc" exe="/bin/nc.openbsd" key="MYCONNECT"
type=SOCKADDR msg=audit(1326872512.453:12752): saddr=02000050AE84E16A0000000000000000

Здесь вы можете видеть, что приложение /bin/nc.openbsd инициировало вызов connect (), если вы получаете много вызовов connect и хотите только отключить определенный ip или порт, вам нужно выполнить какое-то преобразование. Строка SOCKADDR содержит аргумент saddr, он начинается с 0200, за которым следует шестнадцатеричный номер порта (0050), что означает 80, а затем IP в шестнадцатеричном формате (AE84E16A), который является IP-адресом news.ycombinator.com 174.132.225.106.

Среда аудита может генерировать много журналов, поэтому не забудьте отключить ее, когда вы завершите свою миссию. Чтобы отключить вышеуказанную политику, просто замените -a на -d следующим образом:

auditctl -d exit,always -F arch=b64 -S connect -k MYCONNECT

Хорошая документация по структуре audd:
http://doc.opensuse.org/products/draft/SLES/SLES-security_sd_draft/part.audit.html

Преобразуйте IP-адреса в / из шестнадцатеричного, десятичного, двоичного и т. Д. По адресу:
http://www.kloth.net/services/iplocate.php

Общий шестнадцатеричный / десятичный конвертер:
http://www.statman.info/conversions/hexadecimal.html

Краткое введение в Audit, из стека обмена ИТ-безопасности. http://security.blogoverflow.com/2013/01/a-brief-introduction-to-auditd/

Изменить 1 :
Еще один быстрый способ сделать это (swedish: fulhack) - создать быстрый цикл, который отправляет вам данные о соединении, например:

while true;do
  ss -ntap -o state established '( dport = :80 )'
  sleep 1
done

Эта команда использует ssкоманду (статистика сокетов) для сброса текущих установленных подключений к порту 80, включая процесс, который его инициировал. Если данных много, вы можете добавить их | tee /tmp/outputпосле того, как все сделано, чтобы показать вывод на экране, а также записать его в / tmp / output для последующей обработки / копания. Если он не перехватывает быстрое соединение через прокси-сервер, попробуйте удалить его, sleep 1но будьте осторожны с обширной регистрацией, если это сильно загруженный компьютер. Изменить по необходимости!

Маттиас Анберг
источник
Спасибо вам за подробный ответ. Я верю вашему слову о решении для Audit, так как ядро ​​хоста не поддерживает его, и у меня сейчас нет времени, чтобы найти подходящее для экспериментов, но я буду иметь это в виду. Что касается решения для опроса, я начал делать что-то похожее с lsof, но остановился довольно быстро, потому что это не было ... удовлетворительно.
pmezard
2
Вы также можете использовать ausearch -iдля saddrавтоматического декодирования этих шестнадцатеричных строк.
Sch
ss более удовлетворяет, чем lsof, потому что он быстрее и имеет хорошие правила фильтрации - нет необходимости в grep. Я могу оценить проблемы с поддержкой: Systemtap - это еще один превосходный инструмент, но его запуск на рабочем сервере может быть ... неудовлетворительным.
Макс Мерфи
1

Вы также можете просматривать огромные журналы, которые вы получаете от "ausearch -i", чтобы видеть только те сокеты, которые успешно подключены к другому хосту в Интернете. Я написал упрощенный скрипт для получения каждого процесса и команды, создавшей сокет для подключения к хосту в Интернете, а также адрес подключения этого целевого хоста и текущее время, когда сокет был «создан». Вот:

#!/bin/bash

if [[ $EUID -ne 0 ]]; then

    echo "You must run this script as root boy!"
    exit 1  

fi

> proccessConnections.dat

connections=`ausearch -i | grep host: | awk -F "msg=audit" '{print $2}' | awk -F ": saddr" '{print $1}'`

connectionsNumber=`echo "$connections" | wc -l`

echo "Number of connections: $connectionsNumber"

echo "$connections" > conTemp.dat

let counter=1
while read connectInfo; do

    success=`ausearch -i | grep "$connectInfo" | grep "type=SYSCALL" | grep success=yes`    
    addressInfo=`ausearch -i | grep "$connectInfo" | grep type=SOCKADDR | awk -F ': ' '{print $2}'`
    processInfo=`ausearch -i | grep "$connectInfo" | grep "type=SYSCALL" | awk -F 'comm=' '{print $2}' | awk -F 'key' '{print $1}'` 

    if [[ $success != "" ]]
    then    
        echo "[$counter - $connectionsNumber] (success)     comm=$processInfo - $addressInfo - $connectInfo"
        echo "[$counter - $connectionsNumber] (success)     comm=$processInfo - $addressInfo - $connectInfo" >> proccessConnections.dat
    else
        echo "[$counter - $connectionsNumber] (no success)  comm=$processInfo - $addressInfo - $connectInfo"
        echo "[$counter - $connectionsNumber] (no success)  comm=$processInfo - $addressInfo - $connectInfo" >> proccessConnections.dat
    fi

    let counter++


done < conTemp.dat
Марсело Силва
источник