Назад | Перейти на главную страницу

Как я могу узнать общее количество TCP-соединений для данного порта и периода времени по IP-адресу?

В системе Linux существует множество методов для перечисления ток TCP-соединения для данного порта путем подключения IP, но: как я могу подсчитать общее количество подключений к порту для каждого IP-адреса источника за период времени?

Включите iptables и установите для него LOG для входящих подключений. Пример правила:

 -A INPUT --state NEW -p tcp --dport 4711 -j LOG

(где 4711 - порт, который вы хотите отслеживать).

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

Вы можете использовать tcpdump для регистрации всех пакетов SYN (без ACK):

tcpdump "dst port 4711 and tcp[tcpflags] & (tcp-syn|tcp-ack) == tcp-syn"

или зарегистрировать все пакеты SYN + ACK (установленные соединения):

tcpdump "src port 4711 and tcp[tcpflags] & (tcp-syn|tcp-ack) == (tcp-syn|tcp-ack)"

А затем объедините его с wc -l подсчитать все строки

Вам также понадобится способ измерения фиксированных периодов времени (вы можете попросить cron просто отправлять ему SIGINT через равные промежутки времени, tcpdump будет подсчитывать байты и пакеты, но только регистрировать время)

Обновление: нет необходимости говорить, взгляните на страницу руководства tcpdump и рассмотрите возможность использования некоторых параметров, таких как: -i (слушаем только один интерфейс), -p (отключить неразборчивый режим; менее инвазивный) или некоторые параметры вывода. Tcpdump требует прав root, и вашему боссу это может не понравиться, потому что это своего рода хакерский инструмент. С другой стороны, вам не нужно ничего трогать в вашей системе, чтобы запустить его (в отличие от iptables LOG решение)

Также обратите внимание на небольшую разницу src / dsk в фильтре. Если вы ловите пакеты SYN + ACK и хотите подсчитать соединения к сервер на порту 4711 вам нужен src. Если вы перехватываете пакеты SYN +! ACK с тем же результатом, вам понадобится dst. Если считать соединения на самом сервере, всегда нужно использовать обратное.

Решение SystemTap

Скрипт вдохновлен tcp_connections.stp пример:

#!/usr/bin/env stap
# To monitor another TCP port run:
#     stap -G port=80 tcp_connections.stp
# or
#     ./tcp_connections.stp -G port=80
global port = 22
global connections

function report() {
  foreach (addr in connections) {
    printf("%s: %d\n", addr, @count(connections[addr]))
  }
}

probe end {
  printf("\n=== Summary ===\n")
  report()
}

probe kernel.function("tcp_accept").return?,
      kernel.function("inet_csk_accept").return? {
  sock = $return
  if (sock != 0) {
    local_port = inet_get_local_port(sock)
    if (local_port == port) {
      remote_addr = inet_get_ip_source(sock)
      connections[remote_addr] <<< 1
      printf("%s New connection from %s\n", ctime(gettimeofday_s()), remote_addr)
    }
  }
}

Вывод:

[root@bubu ~]# ./tcp_connections.stp -G port=80
Mon Mar 17 04:13:03 2014 New connection from 192.168.122.1
Mon Mar 17 04:13:04 2014 New connection from 192.168.122.1
Mon Mar 17 04:13:08 2014 New connection from 192.168.122.4
^C
=== Summary ===
192.168.122.1: 2
192.168.122.4: 1

Strace решение

Либо запустите программу под strace:

strace -r -f -e trace=accept -o /tmp/strace ${PROGRAM} ${ARGS}

или отследить уже запущенную программу:

strace -r -f -e trace=accept -o /tmp/strace -p ${PID_OF_PROGRAM}

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

Результат выглядит примерно так:

999        0.000000 accept(3, {sa_family=AF_INET, sin_port=htons(34702), sin_addr=inet_addr("192.168.122.4")}, [16]) = 5
999        0.008079 --- SIGCHLD (Child exited) @ 0 (0) ---
999        1.029846 accept(3, {sa_family=AF_INET, sin_port=htons(34703), sin_addr=inet_addr("192.168.122.4")}, [16]) = 5
999        0.008276 --- SIGCHLD (Child exited) @ 0 (0) ---
999        3.580122 accept(3, {sa_family=AF_INET, sin_port=htons(50114), sin_addr=inet_addr("192.168.122.1")}, [16]) = 5

и может быть отфильтрован с помощью:

# gawk 'match($0, /^([0-9]+)[[:space:]]+([0-9.]+)[[:space:]]+accept\(.*htons\(([^)]+)\),.*inet_addr\("([^"]+)"\).*[[:space:]]+=[[:space:]]+([1-9][0-9]*)/, m) {connections[m[4]]++} END {for (addr in connections) printf("%s: %d\n", addr, connections[addr]); }' /tmp/strace
192.168.122.4: 3
192.168.122.1: 2

Краткое объяснение однострочности AKW: m[1] это PID, m[2] это отметка времени, m[3] это удаленный порт и m[4] удаленный адрес.

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

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

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

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

Есть еще один общий класс решений - netflow. Его сложнее настроить, но если все сделано правильно, это особенно эффективно, и если вы занимаетесь крупномасштабным или постоянным мониторингом, я бы посмотрел в этом направлении. Захват необработанных данных может быть выполнен в вашем брандмауэре (например, fprobe-ulo) или с помощью более медленной библиотеки libpcap (например, fprobeg). Система захвата отправляет данные потока через сеть на сборщик (например, nfdump), и тогда у вас есть множество инструментов для анализа этих данных (например, nfsen).

Некоторые маршрутизаторы (особенно оборудование cisco) поставляются с захватом netflow, и его также можно настроить для других маршрутизаторов с помощью прошивки сторонних производителей или, конечно, вы можете запустить его в своей системе Linux. При желании многие точки сбора могут пересылать свои данные о потоках одному сборщику. Вы можете найти варианты бесплатного программного обеспечения, например, на http://www.networkuptime.com/tools/netflow/, а также есть много коммерческих предложений.

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

Будьте осторожны каждый раз, когда вы возитесь с правилами брандмауэра на удаленном сервере, и в целом я бы рекомендовал найти хороший интерфейс для настройки вашего брандмауэра, а не напрямую вводить команды iptables. (Мне нравится ferm, но есть много хороших).

Еще одна вещь, о которой нужно подумать - иногда вы вообще не хотите делать это на сетевом уровне. Иногда уместно отслеживать системные вызовы процесса демона с помощью strace или подобного. Это интенсивно использует процессор, и будьте осторожны, чтобы замедлить процесс Daemon, но в некоторых случаях это может быть целесообразным, в основном в зависимости от того, какую другую информацию вам нужно собрать одновременно, или, возможно, если вам нужно изолировать один разветвленный дочерний элемент демона.

До сих пор лучшим решением для меня было просто получать содержимое / proc / net / ip_conntrack каждые 20 секунд, регистрировать его в файле с именем файла, содержащим соответствующую временную метку, и использовать их в качестве входных данных для любого из сценариев фильтрации, или даже строчки, когда это необходимо. Чтобы сэкономить ваше время, вы можете использовать мой скрипт. Я использую записи crontab, чтобы убедиться, что скрипт запускается каждую минуту (в текущей конфигурации он длится 60 секунд, не стесняйтесь его изменять :-)

 cat conn_minute.sh
#!/bin/bash

function save_log {
LOG_DIR=/mnt/logs/ip_conntrack/`date +%Y%m%d`
TEMP_FILE=$LOG_DIR/`date +%Y%m%d_%H%M%S`.gz
LOG_FILE=$LOG_DIR/`date +%Y%m%d_%H`.tar
if [ ! -d $LOG_DIR ]
then
    mkdir $LOG_DIR
fi
gzip -c /proc/net/ip_conntrack > $TEMP_FILE
if [ -f $LOG_FILE ]; then
    tar -rf $LOG_FILE $TEMP_FILE 2> /dev/null
else
    tar -cf $LOG_FILE $TEMP_FILE 2> /dev/null
fi
rm $TEMP_FILE
}
function log_minute {
i=1;
LOOP_COUNTER=3
LOOP_TIME=20
while [ $i -le $LOOP_COUNTER ]; do
    save_log
    i=$[i+1]
    sleep $LOOP_TIME
done
}

log_minute

Вы можете настроить, как часто вы хотите сбрасывать содержимое ip_conntrack, изменив LOOP_COUNTER и LOOP_TIME соответственно. Таким образом, чтобы получать его каждые 5 секунд, это будет: LOOP_COUNTER = 12, LOOP_TIME = 5. LOG_DIR подразумевает, куда будут сохраняться журналы.

После этого вы можете использовать zcat для cat файлов, которые вас интересуют, и использовать grep для фильтрации исходных IP-адресов / портов, которые вас интересуют (или просто использовать zgrep). grep -c будет считать все, что вам нужно. Вы также можете использовать grep src=1.2.3.4 | grep dport=63793 | sort | uniq | wc -l.

Напишите журнал самостоятельно:

$> nohup netstat -c | grep -E "xxx|xxxx" >> netstat_log 2>&1 &

nohub перенесет этот процесс на задний план, чтобы он пережил ваш выход из системы

netstat -c заставит netstat печатать выбранную информацию каждую секунду, непрерывно, навсегда

grep -E "ххх | хххх" Захватит желаемый контент, например порт и

>> netstat_log ... запишет это в "./netstat_log" (используйте здесь желаемый файл журнала)

Подключение выхода к | wc -l woud считает (wc) его строки (-l).

Посмотри на

. Все они немного устарели, но писать сценарии для работы, которую другие сделали лучше, скучно. Некоторые дают вам красивые картинки, некоторые специализируются больше на криминалистическом анализе и облаживании плохих парней, некоторые (iplog) - это просто действительно простые счетчики, которые регистрируют в БД, у некоторых есть блестящие интерфейсы, которые вы можете показать своему боссу.

Также есть целый набор инструментов для реализации бесплатного стека, совместимого с netflow, в Linux. И целая куча людей пытается продать эту поддержку. (Я не собираюсь рекомендовать коммерческий продукт ...) То, что вы просите, намного проще, чем то, на что способны некоторые из них.

IMHO (Free | Net | Open) BSD уже много лет далеко опережает своего рода анализ. Брандмауэр pFsense предоставит вам как минимум 7 вариантов из коробки.