Защищаем сервер Asterisk с помощью fail2ban

Итак, пришло время поговорить о защите. На написание поста меня сподвигла атака из США жестким брутом. Дело было так, я зашел на сервер оптимизировать конфиг users.conf(Об этом в следующей статье). После правки файла, я благополучно зашел в консоль Asterisk и увидел кучу сообщений (примерно 5 раз в секунду) о том, что с такого-то IP попытка зайти под пользователем 104. Меня это сначала смутило. А потом я решил поставить fail2ban, чтобы обезопасить себя. Итак, статья в моем стиле — поэтому никакой лишней инфы не будет, только то что нужно чтобы закрыть доступ для атакующего IP. Защищать будем Asterisk, ну и бонусом SSH.

Шаг 1. Установка fail2ban.

apt-get install fail2ban

Шаг 2. Установка python и iptables. Возможно вам понадобиться установить эти пакеты, поэтому

apt-get install iptables python

Шаг 3. Конфигурация fail2ban. Итак, займемся конфигурацией. Для этого перейдем в каталог /etc/fail2ban/filter.d.

cd /etc/fail2ban/filter.d

Создаем новый фильтр:

touch asterisk.conf

Содержимое файла /etc/fail2ban/filter.d/asterisk.conf должно быть примерно таким:

# Fail2Ban configuration file
# $Revision: 250 $
[INCLUDES]
# Read common prefixes. If any customizations available -- read them from
# common.local
#before = common.conf
[Definition]
#_daemon = asterisk
# Option:  failregex
# Notes.:  regex to match the password failures messages in the logfile. The
#          host must be matched by a group named "host". The tag "" can
#          be used for standard IP/hostname matching and is only an alias for
#          (?:::f{4,6}:)?(?P\S+)
# Values:  TEXT
failregex = NOTICE.* .*: Registration from '.*' failed for '' - Wrong password
NOTICE.* .*: Registration from '.*' failed for '' - No matching peer found
NOTICE.* .*: Registration from '.*' failed for '' - Username/auth name mismatch
NOTICE.* .*: Registration from '.*' failed for '' - Device does not match ACL
NOTICE.* failed to authenticate as '.*'$
NOTICE.* .*: No registration for peer '.*' \(from \)
NOTICE.* .*: Host failed MD5 authentication for '.*' (.*)
NOTICE.* .*: Failed to authenticate user .*@.*
# Option:  ignoreregex
# Notes.:  regex to ignore. If this regex matches, the line is ignored.
# Values:  TEXT
ignoreregex =

Шаг 4. Редактируем /etc/fail2ban/jail.conf. В конец файла добавляем следующее содержимое:

[asterisk-iptables]
enabled  = true
filter   = asterisk
action   = iptables-allports[name=ASTERISK, protocol=all]
sendmail-whois[name=ASTERISK, dest=root, sender=fail2ban@example.org]
logpath  = /var/log/asterisk/messages #(Тут внимательно! Посмотрите где у вас логи храняться!)
maxretry = 5
bantime = 259200

Шаг 5. Логирование Asterisk. Открываем /etc/asterisk/logger.conf и раскомментируем:

[general]
dateformat=%F %T

В консоли перегружаем сервис логирования:

asterisk -rx "logger reload"

Шаг 6. Запуск.

/etc/init.d/iptables start

Проверим:

iptables -L -v

Должно появиться что то типа этого:

 iptables -L -v

Chain INPUT (policy ACCEPT 20100 packets, 3866K bytes)
pkts bytes target     prot opt in     out     source               destination
62  5692 fail2ban-ssh  tcp  --  any    any     anywhere             anywhere            multiport dports ssh
2049  471K fail2ban-ASTERISK  all  --  any    any     anywhere             anywhere

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 18948 packets, 5246K bytes)
pkts bytes target     prot opt in     out     source               destination

Chain fail2ban-ASTERISK (1 references)
pkts bytes target     prot opt in     out     source               destination
2049  471K RETURN     all  --  any    any     anywhere             anywhere

Chain fail2ban-ssh (1 references)
pkts bytes target     prot opt in     out     source               destination
62  5692 RETURN     all  --  any    any     anywhere             anywhere

Шаг 7. Автозапуск fail2ban и iptables:

update-rc.d iptables defaults
update-rc.d fail2ban defaults

http://www.fail2ban.org/wiki/index.php/Asterisk

http://www.voip-info.org/wiki/view/Fail2Ban+%28with+iptables%29+And+Asterisk

Force iptables to log messages to a different log file

According to man page:
Iptables is used to set up, maintain, and inspect the tables of IP packet filter rules in the Linux kernel. Several different tables may be defined. Each table contains a number of built-in chains and may also contain user defined chains.

By default, Iptables log message to a /var/log/messages file. However you can change this location. I will show you how to create a new logfile called /var/log/iptables.log. Changing or using a new file allows you to create better statistics and/or allows you to analyze the attacks.

Iptables default log file

For example, if you type the following command, it will display current iptables log from /var/log/messages file:
# tail -f /var/log/messages
Output:

Oct  4 00:44:28 debian gconfd (vivek-4435): Resolved address "xml:readonly:/etc/gconf/gconf.xml.defaults" to a read-only configuration source at position 2
Oct  4 01:14:19 debian kernel: IN=ra0 OUT= MAC=00:17:9a:0a:f6:44:00:08:5c:00:00:01:08:00 SRC=200.142.84.36 DST=192.168.1.2 LEN=60 TOS=0x00 PREC=0x00 TTL=51 ID=18374 DF PROTO=TCP SPT=46040 DPT=22 WINDOW=5840 RES=0x00 SYN URGP=0
Oct  4 00:13:55 debian kernel: IN=ra0 OUT= MAC=ff:ff:ff:ff:ff:ff:00:18:de:55:0a:56:08:00 SRC=192.168.1.30 DST=192.168.1.255LEN=78 TOS=0x00 PREC=0x00 TTL=128 ID=13461 PROTO=UDP SPT=137 DPT=137 LEN=58

Procedure to log the iptables messages to a different log file

Open your /etc/syslog.conf file:
# vi /etc/syslog.conf
Append following line
kern.warning /var/log/iptables.log
Save and close the file.

Restart the syslogd (Debian / Ubuntu Linux):# /etc/init.d/sysklogd restartOn the other hand, use following command to restart syslogd under Red Hat/Cent OS/Fedora Core Linux:# /etc/init.d/syslog restart

Now make sure you pass the log-level 4 option with log-prefix to iptables. For example:
# DROP everything and Log it
iptables -A INPUT -j LOG --log-level 4
iptables -A INPUT -j DROP

For example, drop and log all connections from IP address 64.55.11.2 to your /var/log/iptables.log file:
iptables -A INPUT -s 64.55.11.2 -m limit --limit 5/m --limit-burst 7 -j LOG --log-prefix '** HACKERS **'--log-level 4
iptables -A INPUT -s 64.55.11.2 -j DROP

Where,

  • —log-level 4: Level of logging. The level # 4 is for warning.
  • —log-prefix ‘*** TEXT ***’: Prefix log messages with the specified prefix (TEXT); up to 29 letters long, and useful for distinguishing messages in the logs.

You can now see all iptables message logged to /var/log/iptables.log file:
# tail -f /var/log/iptables.log

Updated for accuracy.

Запуск нескольких сайтов с различными SLA

От переводчика (А.К.): SLA (от англ. Service Level Agreement) означает «Соглашение об Уровне Обслуживания» — основной документ, регламентирующий взаимоотношения между ИТ-компанией и заказчиком.

Сделать это можно несколькими способами. Прежде всего следует упомянуть, что Apache поддерживает подобную функциональность в виде модулей, но мы продемонстрируем как добиться этого средствами операционной системы. Эти строки взяты из примера, представленного Джамалом Хади (Jamal Hadi).

Допустим, что у нас есть два клиента, которые арендуют некоторую долю нашего канала под http, ftp и потоковое audio. Первый клиент арендует полосу в 2 Мбита, второй — 5 Мбит. Для начала назначим нашим клиентам виртуальные IP-адреса на нашем сервере:

# ip address add 188.177.166.1 dev eth0
# ip address add 188.177.166.2 dev eth0

Решение проблемы о том, как назначить правильные IP-адреса различным службам, оставляем за вами. Практически все популярные демоны поддерживают такую возможность.
Присоединяем CBQ qdisc к eth0:

# tc qdisc add dev eth0 root handle 1: cbq bandwidth 10Mbit cell 8 avpkt 1000 \
mpu 64

Создаем классы клиентов:

# tc class add dev eth0 parent 1:0 classid 1:1 cbq bandwidth 10Mbit rate \
2MBit avpkt 1000 prio 5 bounded isolated allot 1514 weight 1 maxburst 21
# tc class add dev eth0 parent 1:0 classid 1:2 cbq bandwidth 10Mbit rate \
5Mbit avpkt 1000 prio 5 bounded isolated allot 1514 weight 1 maxburst 21

И добавляем фильтры к классам:

##FIXME: Для чего нужна первая строка, что она делает? Каково назначение "делителя" (divisor)?:
##FIXME: Делитель имеет отношение к хеш-таблице и номеру пула
## (bucket) - ahu
# tc filter add dev eth0 parent 1:0 protocol ip prio 5 handle 1: u32 divisor 1
# tc filter add dev eth0 parent 1:0 prio 5 u32 match ip src 188.177.166.1
flowid 1:1
# tc filter add dev eth0 parent 1:0 prio 5 u32 match ip src 188.177.166.2
flowid 1:2

FIXME: Почему нет token bucket filter?

Прозрачное проксирование с помощью netfilter, iproute2, ipchains и squid

Этот раздел написал Рэм Нарул (Ram Narula), из «Internet for Education» (Таиланд).

Прозрачное проксирование — это обычное перенаправление серверу squid трафика, отправляемого на порт 80 (web).

Существует 3 общеизвестных способа такого перенаправления:

Шлюз.
Вы можете настроить шлюз таким образом, что он будет перенапрвлять все пакеты, адресованные на порт 80, сереверу squid

НО

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

Layer 4 switch
Свичи выполняют такое перенаправление без особых проблем.

НО

Стоимость этого оборудования очень высока и может быть сопоставима с ценой связки «обычный роутер» + «Linux-сервер»

Использовать кэш-сервер в качестве шлюза.
Вы можете отправить ВЕСЬ трафик через кэш-сервер.

НО

Это довольно рисковано, поскольку squid довольно значительно нагружает CPU, что может привести к снижению производительности сети. Кроме того, squid может «рухнуть» и тогда никто из сети не сможет выйти в Интернет.

Мы предлагаем 4-й вариант:
Linux+NetFilter.
Эта методика предполагает установку меток на пакеты, с портом назначения равным числу 80, и дальнейшая маршрутизация помеченных пакетов, с помощью iproute2, на squid.

|—————-|
| Реализация |
|—————-|

Используемые адреса
10.0.0.1 naret (NetFilter)
10.0.0.2 silom (Squid)
10.0.0.3 donmuang (Router, соединенный с Интернет)
10.0.0.4 kaosarn (некий сервер в сети)
10.0.0.5 RAS
10.0.0.0/24 main network
10.0.0.0/19 total network

|—————|
|Структура сети |
|—————|

Internet
|
donmuang
|
————hub/switch———-
| | | |
naret silom kaosarn RAS etc.

Прежде всего — весь трафик должен идти через naret, для этого на всех компьютерах пропишем его в качестве шлюза по-умолчанию. Исключение составляет silom, для которого шлюз по-умолчанию — donmuang (в противном случае web-трафик зациклится).
(на всех компьютерах в моей сети был прописан шлюз по-умолчанию — 10.0.0.1, который ранее принадлежал donmuang, поэтому я изменил IP-адрес у donmuang на 10.0.0.3, а серверу naret присвоил адрес 10.0.0.1)

Silom
——
-настройка squid и ipchains

Настройте прокси-сервер squid на silom. Убедитесь, что он поддерживает прозрачное проксирование. Обычно прокси-серверу, для приема запросов от пользователей, назначают порт 3128, поэтому весь трафик, отправляемый на порт 80 будет перенаправлен на порт 3128. С помощью ipchains это делают следующие правила:
silom# ipchains -N allow1
silom# ipchains -A allow1 -p TCP -s 10.0.0.0/19 -d 0/0 80 -j REDIRECT 3128
silom# ipchains -I input -j allow1

iptables:
silom# iptables -t nat -A PREROUTING -i eth0 -p tcp —dport 80 -j REDIRECT —to-port 3128

За информацией по настройке сервера squid, обращайтесь на http://squid.nlanr.net/.
Убедитесь, что на этом сервере разрешен форвардинг, и заданный по умолчанию шлюз для него — donmuang (НЕ naret!).

Naret
——
-настройка iptables и iproute2
-запрет ICMP-сообщений о перенаправлении (если необходимо)

Пометить пакеты, с портом назначения 80, числовой меткой 2.

naret# iptables -A PREROUTING -i eth0 -t mangle -p tcp —dport 80 \
-j MARK —set-mark 2

Настроить маршрутизацию так, чтобы помеченные пакеты отправлялись на silom

naret# echo 202 www.out >> /etc/iproute2/rt_tables
naret# ip rule add fwmark 2 table www.out
naret# ip route add default via 10.0.0.2 dev eth0 table www.out
naret# ip route flush cache

Если donmuang и naret находятся в одной подсети, то naret не должен выдавать ICMP-сообщения о перенаправлении. Запрет можно наложить так:
naret# echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects
naret# echo 0 > /proc/sys/net/ipv4/conf/default/send_redirects
naret# echo 0 > /proc/sys/net/ipv4/conf/eth0/send_redirects

На этом настройку можно считать завершенной. Проверим конфигурацию

Для naret:

naret# iptables -t mangle -L
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
MARK tcp — anywhere anywhere tcp dpt:www MARK set 0x2

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

naret# ip rule ls
0: from all lookup local
32765: from all fwmark 2 lookup www.out
32766: from all lookup main
32767: from all lookup default

naret# ip route list table www.out
default via 203.114.224.8 dev eth0

naret# ip route
10.0.0.1 dev eth0 scope link
10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.1
127.0.0.0/8 dev lo scope link
default via 10.0.0.3 dev eth0

|——-|
|-КОНЕЦ-|
|——-|

15.5.1. Схема движения пакетов после настройки.

|——————————————|
| Схема движения пакетов |
|——————————————|

ИНТЕРНЕТ
/\
||
\/
———————donmuang————————
/\ /\ ||
|| || ||
|| \/ ||
naret silom ||
*destination port 80 ================>(cache) ||
/\ || ||
|| \/ \/
\\===================================kaosarn, RAS, и пр.

Обратите внимание, в данном случае сеть получилась асимметричной, т.е. добавился один лишний переход для исходящих пакетов.
Ниже приводится путь, проделываемый пакетами в/из Интернет для компьютера kaosarn.

Для web/http трафика:

kaosarn http request->naret->silom->donmuang->internet
http replies from Internet->donmuang->silom->kaosarn

Для прочего трафика:
kaosarn outgoing data->naret->donmuang->internet
incoming data from Internet->donmuang->kaosarn

http://docstore.mik.ua/manuals/ru/LARTC/x2540.html

Решение проблемы с Path MTU Discovery путем настройки MTU/MSS

Общеизвестно, что скорость передачи данных возрастает с увеличением размера пакета. Это вполне естественно, ведь для каждого пакета в потоке принимается решение о выборе маршрута. К примеру, файл, размером в 1 мегабайт, будет передан быстрее, если он будет разбит на 700 пакетов (при максимальном размере пакета), а не на 4000.

Однако, не все сегменты Интернет могут передавать пакеты, с максимальной полезной нагрузкой в 1460 байт. Поэтому необходимо найти такой размер, который будет максимально возможным для заданного маршрута.

Процесс поиска такого размера называется ‘Path MTU Discovery’ (Поиск Максимального Размера Пакета для выбранного Пути), где MTU означает ‘Maximum Transfer Unit’ (Максимальный Размер Блока передачи данных).

Когда на маршрутизатор поступает пакет, который не может быть передан по выбранному маршруту целиком (без фрагментации) И у него установлен флаг «Don’t Fragment» (Не фрагментировать), то в ответ отправляется ICMP-сообщение о том, что пакет был сброшен из-за невозможности «протолкнуть» его по выбранному маршруту. Компьютер, выполнивший посылку, начинает последовательно уменьшать размер пакетов до тех пор, пока они не смогут быть переданы по выбранному маршруту.

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

В результате таких действий процесс поиска оптимального размера пакета работает все хуже и хуже, а на некоторых маршрутизаторах вообще не работает, что в свою очередь порождает сеансы TCP/IP с весьма странным поведением, которые «умирают» спустя некоторое время.

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

15.6.1. Решение

Если вы столкнетесь с подобной проблемой, то можно посоветовать отключить ‘Path MTU Discovery’ и установить MTU вручную. Koos van den Hout пишет:

У меня возникла следующая проблема: для арендованного мною канала, работающего через ppp, на скорости 33.6К, я установил величину MTU/MRU, равную 296. Это дает мне достаточно приемлемое время отклика.

Со моей стороны установлен роутер (с маскарадингом), работающий под управлением Linux.

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

После этого возникла масса проблем с авторизацией в irc. В процессе длительных поисков я установил, что само соединение проходит и даже показывается системой как ‘connected’, но я не получал motd от irc (motd — от англ. Message of The Day, которое демонстрируется после успешной авторизации, прим. перев.). Кроме того, помятуя о проблеме, связанной с MTU, я определил, что проблема исчезала только в том случае, когда MTU устанавливался равным 296. А так как серверы irc блокируют весь трафик, который напрямую не связан с их работой, то в числе блокируемых оказался и ICMP.

Мне удалось убедить администратора WEB-сервера в истинных причинах возникновения проблем, но администратор IRC-сервера отказался устранять их.

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

Решение:

ip route add default via 10.0.0.1 mtu 296

(10.0.0.1 — шлюз по-умолчанию, внутренний адрес маршрутизатора с маскарадингом)
Вообще, можно запретить ‘PMTU Discovery’ путем настройки специфических маршрутов. Например, если проблемы наблюдаются только с определенной подсетью, то это должно помочь:

ip route add 195.96.96.0/24 via 10.0.0.1 mtu 1000

Как уже говорилось выше, Path MTU Discovery не работает в Интернет должным образом. Если вам известны факты существования сегментов в вашей сети, где размер MTU ограничен, то вы уже не можете полагаться на безотказную работу Path MTU Discovery.

Однако, помимо MTU, есть еще один способ ограничения размера пакета — это, так называемый MSS (Maximum Segment Size — Максимальный Размер Сегмента). MSS — это поле в заголовке TCP-пакета SYN.

С недавних пор, ядра Linux и некоторые драйверы PPPoE, стали поддерживать такую особенность, как ‘clamp the MSS’ (ограничение размера MSS).

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

С другой стороны — за атакущим сохраняется возможность нарушить связь путем модификации пакетов. Однако, следует заметить, что мы довольно часто используем эту возможность и это приносит свои положительные плоды.

Чтобы иметь возможность манипулировать размером сегмента, у вас должны быть установлены iptables, не ниже 1.2.1a и ядро Linux, не ниже 2.4.3. Основная команда iptables:

# iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

Она рассчитает правильный MSS для вашего соединения. Если вы достаточно уверены в себе и в своих знаниях, можете попробовать нечто подобное:

# iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 128

Это правило устанавливает MSS равным 128. Очень полезно, если вы наблюдаете разрывы при передаче голосовых данных, когда поток небольших пакетов VoIP прерывается «огромными» http-пакетами.

Ограничение скорости для отдельного хоста или подсети

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

Эти три строки сделают все что вам нужно:

tc qdisc add dev $DEV root handle 1: cbq avpkt 1000 bandwidth 10mbit

tc class add dev $DEV parent 1: classid 1:1 cbq rate 512kbit \
allot 1500 prio 5 bounded isolated

tc filter add dev $DEV parent 1: protocol ip prio 16 u32 \
match ip dst 195.96.96.97 flowid 1:1

Первая строка — назначает базовую дисциплину на заданный интерфейс и сообщает ядру, что пропускная способность интерфейса составляет 10 Мбит/сек. Если вы установите неверное значение, то особого вреда не будет, однако, всегда стремитесь устанавливать верные значения, это повысит точность вычислений.

Вторая строка создает класс с полосой пропускания 512 Кбит/сек. Подробное описание CBQ содержит раздел Дисциплины обработки очередей для управления пропускной способностью.

Последняя строка говорит о том, какой трафик должен формироваться классом, определенным выше. Трафик, не подпадающий под заданное в фильтре условие, НЕ ОГРАНИЧИВАЕТСЯ! Более сложные примеры назначения условий (подсети, порт отправителя, порт адресата), вы найдете в разделе Наиболее употребимые способы фильтрации.

Если вы внесли какие-либо изменения в сценарий и желаете перезапустить его — предварительно запустите команду tc qdisc del dev $DEV root, чтобы очистить существующую конфигурацию.

Сценарий может быть немного улучшен, за счет добавления в конец дополнительной строки tc qdisc add dev $DEV parent 1:1 sfq perturb 10. За подробным описанием обращайтесь к разделу Stochastic Fairness Queueing.

Bonding производительность

Задача – протестировать суммарную пропускную полосу получаемую при помощи бондинга (bonding — объединение нескольких физических интерфейсов в один логический, с расширенной по сравнению с любым из составных интерфейсов полосой пропускания) двух гигабитных сетевых интерфейсов.

Тестирование производилось с помощью двух серверов в каждом из которых было по два гигабитных сетевых интерфейса (Broadcom Corporation NetXtreme II BCM5708 Gigabit Ethernet), физически сетевые платы серверов были соединены между собой с помощью двух кросоверных пачкордов.

ОС: CentOS 5.3.

Для начала протестируем максимальную скорость передачи данных по каждому интерфейсу в отдельности при помощи двух утилит iperf и netperf.
iperf показал результаты 949-968 Mbits/sec
netperf показал результаты от 865.64 до 956.35 10^6bits/sec

Теперь настроим bonding на обоих серверах и повторим тесты производительности.

Подгружаем модуль бондинга, для этого в файлы /etc/modprobe.conf на обоих серверах внесем следующие строки:

alias bond0 bonding
options bond0 miimon=100 mode=0

Настройки сетевых интерфейсов на первом сервере.
cat ifcfg-eth0

# Broadcom Corporation NetXtreme II BCM5708 Gigabit Ethernet
DEVICE=eth0
ONBOOT=yes
BOOTPROTO=none
USERCTL=no
MASTER=bond0
SLAVE=yes
HWADDR=00:21:5E:3F:E5:A0

Второй адаптер
cat ifcfg-eth1

# Broadcom Corporation NetXtreme II BCM5708 Gigabit Ethernet
DEVICE=eth1
ONBOOT=yes
BOOTPROTO=none
USERCTL=no
MASTER=bond0
SLAVE=yes
HWADDR=00:21:5E:3F:E5:A2

Настраиваем сетевые параметры интерфейса бондинга
cat ifcfg-bond0

DEVICE=bond0
IPADDR=192.168.10.1
NETMASK=255.255.255.0
NETWORK=192.168.10.0
BROADCAST=192.168.10.255
ONBOOT=yes
BOOTPROTO=none
USERCTL=no

Перезагрузимся, для того, чтобы изменения вступили в силу.

Теперь аналогичным образом настроим сеть на сервере 2, соответственно назначив интерфейсу bond0 ip адрес 192.168.10.2 .

Теперь внимательно посмотрим, что же нам выдаст команда
cat /proc/net/bonding/bond0

Ethernet Channel Bonding Driver: v3.2.4 (January 28, 2008)

Bonding Mode: load balancing (round-robin)
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 0
Down Delay (ms): 0

Slave Interface: eth0
MII Status: up
Link Failure Count: 1
Permanent HW addr: 00:21:5e:3f:eb:7c

Slave Interface: eth1
MII Status: up
Link Failure Count: 1
Permanent HW addr: 00:21:5e:3f:eb:7e

Протестируем производительность с помошью утилиты iperf в один tcp поток.

На первом сервере запускаем iperf -s .
На втором сервере запускаем iperf -c 192.168.10.2

По 10 проходам получаем такие результаты:

Тест 1 1.88 Gbits/sec
Тест 2 1.87 Gbits/sec
Тест 3 1.88 Gbits/sec
Тест 4 1.87 Gbits/sec
Тест 5 1.88 Gbits/sec
Тест 6 1.88 Gbits/sec
Тест 7 1.88 Gbits/sec
Тест 8 1.88 Gbits/sec
Тест 9 1.88 Gbits/sec
Тест 10 1.88 Gbits/sec

Cо стороны первого сервера вывод данных от iperf выглядит так:

Client connecting to 192.168.10.2, TCP port 5001
TCP window size: 16.0 KByte (default)
------------------------------------------------------------
[ 3] local 192.168.10.1 port 39151 connected with 192.168.10.2 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-10.0 sec 2.19 GBytes 1.88 Gbits/sec

Протестируем производительность с помошью утилиты iperf в 100 tcp потоков.

На первом сервере запускаем iperf -s .
На втором сервере запускаем iperf -c 192.168.10.2 -P 100

По результатам 10 тестов получаем такие результаты:
iperf на первом и втором сервере после запуска выдавал разные результаты, поэтому я привожу оба результата.

Тест 1 1.83 1.88 Gbits/sec
Тест 2 1.84 1.89 Gbits/sec
Тест 3 1.44 1.88 Gbits/sec
Тест 4 1.85 1.87 Gbits/sec
Тест 5 1.87 1.88 Gbits/sec
Тест 6 1.76 1.88 Gbits/sec
Тест 7 1.84 1.87 Gbits/sec
Тест 8 1.83 1.85 Gbits/sec
Тест 9 1.87 1.89 Gbits/sec
Тест 10 1.83 1.84 Gbits/sec

Тестируем производительность с помошью netperf
На первом сервере запускаем netserver -p 10000 -n 4
На втором сервере запускаем netperf -p 10000 -H 192.168.10.2 -l 30

После 10 проходов получаем такие результаты (10^6bits/sec):

Тест 1 1206.99
Тест 2 1710.40
Тест 3 1878.43
Тест 4 1857.45
Тест 5 1874.43
Тест 6 1878.10
Тест 7 1862.14
Тест 8 1876.81
Тест 9 1876.41
Тест 10 1876.15

Со стороны второго сервера вывод данных после тестирования выглядят так:

TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 192.168.10.2 (192.168.10.2) port 0 AF_INET
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec

87380 16384 16384 30.01 1878.43

Вывод: При использовании bonding для двух гигабитных сетевых адаптеров имеет смысл и его использование увеличивает пропускную способность сети в 2 раза.

http://centos.alt.ru/?p=12

Количество соединений с сервером

Посмотреть сколько в данный момент с сервером установленно соединений и в каком они состоянии можно просто выполнив :

netstat -an|awk '/tcp/ {print $6}'|sort|uniq -c

Вывод будет выглядеть примерно следующим образом

83 ESTABLISHED
9 FIN_WAIT1
93 FIN_WAIT2
9 LAST_ACK
6 LISTEN
7 SYN_RECV
817 TIME_WAIT

SMP-affinity

Не многие знают, что они могут значительно повысить производительность сетевой подсистемы Linux на мультипроцессорных или многоядерных системах за счёт распределения системных прерываний от сетевых адаптеров на различные процессоры/ядра.

Дело в том, что при интенсивной сетевой нагрузке сетевые платы вызывают слишком много системных прерываний (Вы можете посмотреть нагрузку на процессоры Вашего сервера создаваемую обработкой системных прерываний с помощью утилиты top – параметр si), что влечёт за собой потерю пакетов проходящих на/через сетевые интерфейсы.

Допустим, что у Вас в системе есть два процессора и два сетевых адаптера, сделаем так, чтобы системные прерывания от eth0 обрабатывались первым процессором, а прерывания от второго сетевого адаптера eth1 обрабатывались вторым процессором.

Проверим как обрабатываются прерывания от сетевых адаптеров в данный момент: cat /proc/interrupts

           CPU0       CPU1
  0: 1025359421 1011223877    IO-APIC-edge  timer
  1:          7     443237    IO-APIC-edge  i8042
  6:          3          2    IO-APIC-edge  floppy
  7:          0          0    IO-APIC-edge  parport0
  8:          0   18718112    IO-APIC-edge  rtc
  9:          1          0    IO-APIC-level  acpi
 12:   11950434        756    IO-APIC-edge  i8042
90:      790345          0    IO-APIC-level  eth0
169:         69   10339595    IO-APIC-level  uhci_hcd:usb5, HDA Intel, i915@pci:0000:00:02.0
177:          79073095  0     IO-APIC-level  eth1
209:          0          0    IO-APIC-level  uhci_hcd:usb4
217:     212348          1    IO-APIC-level  ehci_hcd:usb1, uhci_hcd:usb2
225:   24498064       3245    IO-APIC-level  uhci_hcd:usb3, libata
NMI:          0          0
LOC: 2036559271 2036559270
ERR:          0
MIS:          0

как мы можем видеть в приведённом примере первый сетевого адаптер «висит» на IRQ 90, а второй на IRQ 177. Причём явно видно что прерывания как от первого, так и второго сетевого адаптера обрабатываются первым процессором в системе.

Исправим данную ситуацию, для этого нам необходимо записать число “2″ в файл /proc/irq/177/smp_affinity

echo "2" >/proc/irq/177/smp_affinity

после этого посмотрим как изменилась ситуация:

cat /proc/interrupts
           CPU0       CPU1
  0: 1025359421 1011223877    IO-APIC-edge  timer
  1:          7     443237    IO-APIC-edge  i8042
  6:          3          2    IO-APIC-edge  floppy
  7:          0          0    IO-APIC-edge  parport0
  8:          0   18718112    IO-APIC-edge  rtc
  9:          1          0    IO-APIC-level  acpi
 12:   11950434        756    IO-APIC-edge  i8042
90:      790345          0    IO-APIC-level  eth0
169:         69   10339595    IO-APIC-level  uhci_hcd:usb5, HDA Intel, i915@pci:0000:00:02.0
177:   79073095    3672362    IO-APIC-level  eth1
209:          0          0    IO-APIC-level  uhci_hcd:usb4
217:     212348          1    IO-APIC-level  ehci_hcd:usb1, uhci_hcd:usb2
225:   24498064       3245    IO-APIC-level  uhci_hcd:usb3, libata
NMI:          0          0
LOC: 2036559271 2036559270
ERR:          0
MIS:          0

как видим счётчик прерываний для eth1 на CPU0 не изменился, но появились цифры ниже CPU1 т.е. обработка прерываний от второго сетевого адаптера eth1 обрабатывается вторым процессором в системе.

Небольшое объяснение насчёт того, что же значит цифра 2 !
Linux каждому cpu в системе ставит в соответствие некую цифру обозначающую данный процессор в системе. Ниже приведена таблица для 4-х процессорной системы

            двоичный    шестнадцатеричный
    CPU 0    0001         1
    CPU 1    0010         2
    CPU 2    0100         4
    CPU 3    1000         8

т.е. если бы у нас в вышеприведённом примере было не 2 а четыре процессора и мы бы хотели обрабатывать прерывания от eth1 на третьем процессоре CPU2, то нам для этого пришлось бы вместо 2 записать цифру 4 в файл /proc/irq/177/smp_affinity .

Любознательный читатель может спросить, что же было бы если бы мы записали в данный файл число которого нет в приведённой таблице, например echo “3″ >/proc/irq/177/smp_affinity. Ответ прост прерывания от eth1 обрабатывались бы первым и вторым процессором т.к.

           двоичный     шестнадцатеричный
    CPU 0    0001         1
  + CPU 2    0010         2
    -----------------------
             0011         3

Стоит особо отметить, нет смысла обрабатывать системные прерывания от одного сетевого адаптера на нескольких процессорах/ядрах т.к. суммарно system interrupts от данного адаптера никогда не превысит 100%, т.е. максимум, что Вы сможете получить это 50% загрузки на одном процессоре/ядре и 50% на другом.

Дополнение: у компании Intel существуют чипсеты 82575 и 82576 сетевые карты на базе которых имеют несколько очередей каждая из которых может обрабатываться отдельным ядром/процессором.

Выглядит это следующим образом

cat /proc/interrupts
           CPU0       CPU1       CPU2       CPU3       CPU4       CPU5       CPU6       CPU7
  0:   72718527   72693470   72701000   72694778   72698856   72705975   72697612   72709066    IO-APIC-edge  timer
  1:          0          1          0          0          0          0          1          0    IO-APIC-edge  i8042
  6:          0          0          2          0          0          0          1          0    IO-APIC-edge  floppy
  8:          0          0          0          0          0          1          0          0    IO-APIC-edge  rtc
  9:          0          0          0          0          0          0          0          1   IO-APIC-level  acpi
 14:     143672     144923     144966     146156     144955     144426     144156     144955    IO-APIC-edge  ata_piix
 15:     892735     915776     908202     913235     910358     903767     912399     900143    IO-APIC-edge  ide1
 58:          0          0          0          0          0          0          0          0   IO-APIC-level  uhci_hcd:usb3
 66:         64          0          0 2259148530          0          0          0          0       PCI-MSI-X  eth0-tx0
 74: 2992330737          0          0          0          0          0          0          0       PCI-MSI-X  eth0-rx0
 82:       4197 3028991669          0          0          0          0          0          0       PCI-MSI-X  eth0-rx1
 90:       4091          0 3008220806          0          0          0          0          0       PCI-MSI-X  eth0-rx2
 98:       4092          0          0 2999334745          0          0          0          0       PCI-MSI-X  eth0-rx3
106:          2          0          0          0          0          0          0          0       PCI-MSI-X  eth0
114:          7          0          0          0          0          0          0 2265679966       PCI-MSI-X  eth1-tx0
122:          1          0          0          0 3906833163          0          0          0       PCI-MSI-X  eth1-rx0
130:          1          0          0          0          0 3957703625          0          0       PCI-MSI-X  eth1-rx1
138:          1          0          0          0          0          0 3918250115          0       PCI-MSI-X  eth1-rx2
146:          1          0          0          0          0          0          0 3928688764       PCI-MSI-X  eth1-rx3
154:          2          0          0          0          0          0          0          0       PCI-MSI-X  eth1
169:          0          0          0          0          0          0          0          0   IO-APIC-level  uhci_hcd:usb5
177:          1          0          0          0          1          1          1          1   IO-APIC-level  uhci_hcd:usb4, aic94xx
185:          0          0          0          0          0          0          0          0   IO-APIC-level  ehci_hcd:usb1, uhci_hcd:usb2
NMI:          0          0          0          0          0          0          0          0
LOC:  581643579  581643516  581643609  581643411  581643494  581643475  581643531  581643008
ERR:          0
MIS:          0

За данную информацию спасибо Marian Ivasiuk

Подробнее прочитать о SMP-Affinity можно по этому адресу http://www.cs.uwaterloo.ca/~brecht/servers/apic/SMP-affinity.txt
http://centos.alt.ru/?p=26

Iptables производительность

Низкая производительность роутера может быть связанна с некорректными настройками iptables.

Первое, что Вам необходимо сделать если на роутере нет NAT — отключить connection tracking делается это в таблице nat цепочка PREROUTING.

*raw
-A PREROUTING -j NOTRACK
COMMIT

Имейте ввиду, что если у Вас используются правила iptables с использованием модуля match, то Вам придется отказаться от их использования, также у Вас перестанут работать правила использующие conntrack таблицу.

Следующее проверить какие правила iptables отрабатываются чаще всего, и поставить их первыми. Посмотреть какие правила срабатывают чаще всего можно так:

iptables -L -n -v

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

Пример:
Допустим есть сеть домового провайдера. Количество клиентов порядка 10000. При блокировании клиента он блокируется в правилах iptables. На текущий момент заблокированно 2000 клиентов, т. е. в iptables 2000 правил для пакетного фильтра типа:

-A FORWARD -s 192.168.0.1 -j DROP
-A FORWARD -s 192.168.0.2 -j DROP
-A FORWARD -s 192.168.0.3 -j DROP
--/ И так дальше/--
-A FORWARD -s 192.168.1.1 -j DROP
-A FORWARD -s 192.168.1.2 -j DROP
-A FORWARD -s 192.168.1.3 -j DROP
--/ И так дальше/--
-A FORWARD -s 192.168.2.1 -j DROP
-A FORWARD -s 192.168.2.2 -j DROP
-A FORWARD -s 192.168.2.3 -j DROP
--/ И так дальше/--
-A FORWARD -s 192.168.7.1 -j DROP
-A FORWARD -s 192.168.7.2 -j DROP
-A FORWARD -s 192.168.7.254 -j DROP
# Всех остальных пропускаем
-A FORWARD -j ACCEPT

т.е. для того чтобы проверить пропустить или заблокировать пакеты от машины 192.168.8.254 будет произведено 2000 проверок в правилах iptables . ЭТО УЖАСНО. При интенсивном сетевом обмене ни о какой производительности речи быть не может.

Перепишем данные правила следующим образом:

-A FORWARD -s 192.168.0.0/24 -j NET-00
-A FORWARD -s 192.168.1.0/24 -j NET-01
-A FORWARD -s 192.168.2.0/24 -j NET-02
-A FORWARD -s 192.168.3.0/24 -j NET-03
-A FORWARD -s 192.168.4.0/24 -j NET-04
-A FORWARD -s 192.168.5.0/24 -j NET-05
-A FORWARD -s 192.168.6.0/24 -j NET-06
-A FORWARD -s 192.168.7.0/24 -j NET-07
//
-A NET-00 -s 192.168.0.1 -j DROP
-A NET-00 -s 192.168.0.2 -j DROP
-A NET-00 -s 192.168.0.3 -j DROP
--/ И так дальше/--
-A NET-01 -s 192.168.1.1 -j DROP
-A NET-01 -s 192.168.1.2 -j DROP
-A NET-01 -s 192.168.1.3 -j DROP
--/ И так дальше/--
-A NET-07 -s 192.168.7.1 -j DROP
-A NET-07 -s 192.168.7.2 -j DROP
-A NET-07 -s 192.168.7.3 -j DROP
-A FORWARD -j ACCEPT

В наших новых правилах для аналогичной проверки необходимо 255 проверок, итак немного модифицировав правила для iptables мы сократили количество проверок в пакетном фильтре в 4 раза.

Еще одним способом избавиться от узкого места в iptables – использовать ipset.

http://centos.alt.ru/?p=32