Для того чтобы Ваша система автоматически перезагружалась через 5 секунд после kernel panic добавьте
kernel.panic = 5
в файл /etc/sysctl.conf и заставьте систему перечитать изменения с помошью команды
sysctl -p
Для того чтобы Ваша система автоматически перезагружалась через 5 секунд после kernel panic добавьте
kernel.panic = 5
в файл /etc/sysctl.conf и заставьте систему перечитать изменения с помошью команды
sysctl -p
Решил выяснить сколько трафика сможет занатить один Linux сервер, какая нагрузка будет при этом на CPU.
Выяснилось, что при одном и том, же сетевом трафике, но разном количестве пакетов нагрузка на CPU будет разная, что совершенно логично.
Приведу тестовые данные:
Итак тестовая система:
Однопроцессорный четырехядерный сервер Intel(R) Xeon(R) CPU E5405 2.00GHz
Сетевые адаптеры Broadcom NetXtreme II BCM5708 1000Base-T (B2) PCI-X 64-bit 133MHz
ОС CentOS 5.4
Правила для iptables простые /etc/sysconfig/iptables
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT DROP [0:0]
COMMIT
*nat
-A POSTROUTING -o eth0 -s 172.16.1.0/24 -j SNAT --to 192.168.0.1
-A POSTROUTING -o eth0 -s 172.16.2.0/24 -j SNAT --to 192.168.0.2
-A POSTROUTING -o eth0 -s 172.16.3.0/24 -j SNAT --to 192.168.0.3
--//--
-A POSTROUTING -o eth0 -s 172.16.254.0/24 -j SNAT --to 192.168.0.254
COMMIT
Пропустим через сервер трафик порядка 100 мегабит:
Входящий 90-100 мбит/с
Исходящий 50-60 мбит/с
Посмотрим количество пакетов:
vnstat -tr 15 -i eth0
409452 packets sampled in 15 seconds
Traffic average for eth0
rx 11291.52 kB/s 14072 packets/s
tx 5771.39 kB/s 13223 packets/s
Нагрузка на процессоры:
Cpu0 : 0.0%us, 0.0%sy, 0.0%ni, 91.0%id, 0.0%wa, 1.7%hi, 7.3%si, 0.0%st
Cpu1 : 0.0%us, 0.0%sy, 0.0%ni, 88.3%id, 0.0%wa, 3.7%hi, 8.0%si, 0.0%st
Количество соединений:
sysctl -a | grep ip_conntrack_count
net.ipv4.netfilter.ip_conntrack_count = 65405
Как видим нагрузка на каждый из процессоров всего в районе 7-8 процентов.
Увеличим трафик проходящий через сервер трафик до 200 мбит/с посмотрим как изменится картина
Трафик на обоих сетевых интерфейсах:
Входящий 200-230 мбит/с
Исходящий 130-150 мбит/с
vnstat -tr 15 -i eth0
873819 packets sampled in 15 seconds
Traffic average for eth0
rx 22922.61 kB/s 29719 packets/s
tx 14199.36 kB/s 28535 packets/s
Нагрузка на CPU
Cpu0 : 0.0%us, 0.0%sy, 0.0%ni, 68.0%id, 0.0%wa, 2.3%hi, 29.7%si, 0.0%st
Cpu1 : 0.0%us, 0.0%sy, 0.0%ni, 60.0%id, 0.0%wa, 4.7%hi, 35.0%si, 0.0%st
Увеличим трафик проходящий через сервер трафик до 350 мбит/с посмотрим как изменится картина
Трафик на обоих сетевых интерфейсах:
Входящий 350-370 мбит/с
Исходящий 190-210 мбит/с
vnstat -tr 15 -i eth0
1475987 packets sampled in 15 seconds
Traffic average for eth0
rx 37181.86 kB/s 49891 packets/s
tx 20991.49 kB/s 48507 packets/s
Нагрузка на CPU
Cpu0 : 0.0%us, 0.0%sy, 0.0%ni, 37.9%id, 0.0%wa, 1.7%hi, 60.5%si, 0.0%st
Cpu1 : 0.0%us, 0.0%sy, 0.0%ni, 19.5%id, 0.0%wa, 5.3%hi, 75.2%si, 0.0%st
Количество сетевых соединений
sysctl -a | grep ip_conntrack_count
net.ipv4.netfilter.ip_conntrack_count = 215402
Ну вот в принципе и все, как видим, даже обычный сервер в состоянии «заNATить» порядка 400 мегабит трафика.
Встала задача писать весь транзитный трафик с Cisco 6504, меня интересуют 2 гигабитных канала на интерфейсах Gi2/1 , Gi2/2. Можно было бы писать NetFlow напрямую с Cisco 6504, но на ней осуществляется нарезка полос (User Based Rate Limit microflow policy) совместно с которым экспорт в NetFlow не работает, поэтому будем извращаться :).
Для начала выгоним SPAN (копию интересующего меня трафика с Gi2/1 , Gi2/2 ) в два гигабитных порта Gi2/4 и Gi2/5.
!
vlan 100
!
!
interface Port-channel100
switchport
switchport access vlan 100
switchport mode access
!
interface GigabitEthernet2/4
switchport
switchport access vlan 100
switchport mode access
channel-group 100 mode on
!
interface GigabitEthernet2/5
switchport
switchport access vlan 100
switchport mode access
channel-group 100 mode on
!
monitor session 1 source interface Gi2/1 , Gi2/2
monitor session 1 destination interface Po100
!
Теперь необходимо определиться с инструментарием которым мы собираемся «ловить» поток и отдавать его в формате NetFlow.
На самом деле выбор не велик fprobe, ipcad, softflowd т. е. те вещи которые работают через pcap «умерли» сразу, попутно убив CPU сервера 🙂
Через ULOG iptables писать нельзя т. к. трафик не попадает ни в одну цепочку (ибо он не транзитный).
Нашелся один инструмент (ipt_netflow), но для его работоспособности в схеме со Span портом пришлось пропатчить ядро (здесь патченное ядро) и пропатчить сам модуль ipt_netflowустанавливать надо ipt_netflow (модуль iptables) и kmod-netflow-promisc (модуль ядра).
SPAN потоки приходят в сетевые адаптеры eth2 и eth3 сервера соответственно.
После установки этого чуда пишем в iptables
*raw
-A PREROUTING -i eth2 -j NETFLOW
-A PREROUTING -i eth3 -j NETFLOW
COMMIT
в /etc/modprobe.conf добавляем
options ipt_NETFLOW hashsize=160000 destination="127.0.0.1:2055"
результаты таковы, что при 1-1,5 gbit/sec трафика мы получаем следующую нагрузку на CPU
top
Tasks: 117 total, 1 running, 116 sleeping, 0 stopped, 0 zombie
Cpu0 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu1 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu2 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu3 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu4 : 0.0%us, 0.0%sy, 0.0%ni, 71.3%id, 0.3%wa, 0.0%hi, 28.3%si, 0.0%st
Cpu5 : 0.0%us, 0.0%sy, 0.0%ni, 69.5%id, 0.0%wa, 0.7%hi, 29.8%si, 0.0%st
Cpu6 : 0.0%us, 0.0%sy, 0.0%ni, 71.2%id, 0.0%wa, 0.3%hi, 28.4%si, 0.0%st
Cpu7 : 0.0%us, 1.0%sy, 0.0%ni, 68.2%id, 0.0%wa, 0.3%hi, 30.4%si, 0.0%st
Mem: 4044184k total, 2566136k used, 1478048k free, 485276k buffers
Swap: 2031608k total, 132k used, 2031476k free, 1622060k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
33 root 10 -5 0 0 0 S 2.7 0.0 32:41.04 events/7
1 root 15 0 10348 632 540 S 0.0 0.0 0:02.31 init
2 root RT -5 0 0 0 S 0.0 0.0 0:00.02 migration/0
3 root 34 19 0 0 0 S 0.0 0.0 0:03.06 ksoftirqd/0
4 root RT -5 0 0 0 S 0.0 0.0 0:00.00 watchdog/0
5 root RT -5 0 0 0 S 0.0 0.0 0:00.07 migration/1
6 root 34 19 0 0 0 S 0.0 0.0 0:00.04 ksoftirqd/1
7 root RT -5 0 0 0 S 0.0 0.0 0:00.00 watchdog/1
8 root RT -5 0 0 0 S 0.0 0.0 0:00.01 migration/2
9 root 34 19 0 0 0 S 0.0 0.0 0:00.03 ksoftirqd/2
cat /proc/net/stat/ipt_netflow
Flows: active 354747 (peak 540458 reached 0d16h37m ago), mem 30486K
Hash: size 160000 (mem 1250K), metric 2.7, 2.2, 1.0, 1.0. MemTraf: 121088697 pkt, 75450911 K (pdu 5, 276).
Timeout: active 1800, inactive 15. Maxflows 2000000
Rate: 1382824352 bits/sec, 298823 packets/sec; Avg 1 min: 1367908158 bps, 296724 pps; 5 min: 1361329134 bps, 296061 pps
cpu# stat: , sock: , traffic: , drop: Total stat: 38000468809 22085636328 1231067128, 0 0 0 0, sock: 41023746 0 0, 58651136 K, traffic: 23316703456, 13030478 MB, drop: 0, 0 K
cpu0 stat: 0 0 0, 0 0 0 0, sock: 0 0 0, 0 K, traffic: 0, 0 MB, drop: 0, 0 K
cpu1 stat: 0 0 0, 0 0 0 0, sock: 0 0 0, 0 K, traffic: 0, 0 MB, drop: 0, 0 K
cpu2 stat: 0 0 0, 0 0 0 0, sock: 0 0 0, 0 K, traffic: 0, 0 MB, drop: 0, 0 K
cpu3 stat: 0 0 0, 0 0 0 0, sock: 0 0 0, 0 K, traffic: 0, 0 MB, drop: 0, 0 K
cpu4 stat: 9502008868 5521585976 307793882, 0 0 0 0, sock: 0 0 0, 0 K, traffic: 5829379858, 3259408 MB, drop: 0, 0 K
cpu5 stat: 9495159604 5519723902 307727275, 0 0 0 0, sock: 0 0 0, 0 K, traffic: 5827451177, 3255443 MB, drop: 0, 0 K
cpu6 stat: 9500201467 5522411578 307754983, 0 0 0 0, sock: 0 0 0, 0 K, traffic: 5830166561, 3258689 MB, drop: 0, 0 K
cpu7 stat: 9503098870 5521914872 307790988, 0 0 0 0, sock: 41023746 0 0, 58651136 K, traffic: 5829705860, 3256938 MB, drop: 0, 0 K
sock0: 127.0.0.1:2055, sndbuf 33554432, filled 0, peak 140936; err: sndbuf reached 0, other 0
как видим трафик порядка 1.3 гбит/сек, 300 kpps 🙂
Вроде ничего не забыл.
Появилась задача: блокировать доступ некоторому списку пользователей доступ в сеть Internet, трафик пользователей проходит через софтварный (программный) Linux маршрутизатор (роутер).
Первая мысль — блокировать в iptables. Мысль это безусловна верная, но при большом количестве правил, это будет создавать излишнюю нагрузку на CPU. Так например линейный список из 1000 правил убьет производительность роутера под нуль.
Каким образом можно увеличить производительность данной схемы ?
Выход был найден – ipset.
Установка ipset для CentOS i386 занимает 1 минуту:
Подключаем CentALT:
rpm -ihv http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm
rpm -ihv http://centos.alt.ru/repository/centos/5/i386/centalt-release-5-3.noarch.rpm
Устанавливаем нужные пакеты:
yum install ipset kmod-ipset
Обновляем iptables — пересобран штатный для CentOS iptables, только добавлен модуль SET.
yum update iptables
Создаем файл /etc/ipset.conf в который будем писать ip которым запрещен доступ следующего содержания
#!/bin/bash
# Создаем новую цепочку правил
ipset -N access iphash
# добавляем список доступа
ipset -A access 192.168.0.2
ipset -A access 192.168.0.3
ipset -A access 192.168.0.4
добавляем в автоматический запуск в файл /etc/rc.d/rc.local
добавляем последней строку
/bin/bash /etc/ipset.conf
Затем добавляем в /etc/sysconfig/iptables единственную строку которая закроет доступ всем ip адресам из выше приведенного списка
-A FORWARD -m set --set access src -j DROP
перегружаем правила iptables
service iptables restart
Все.
Переход от блокировки в iptables на блокировку в ipset снизил нагрузку на систему более чем в 2 раза при количестве правил >1000, сетевой трафик проходящий через роутер в районе 100 kpps.
Подобным образом можно успешно защищаться от простейших DDOS атак.
Встала задача, ограничить количество устанавливаемых клиентами сетевых соединений проходящих через шлюз в единицу времени, на шлюзе стоит Linux.
На самом деле, я нашел всего два модуля для iptables, которые помогут мне помочь в решении данной задачи. Это модуль connlimit и модуль recent.
connlimit может работать только с tcp протоколом, и может ограничивать количество установленных tcp сессий для каждого клиента достаточно простым правилом, например пример приведенный ниже ограничит количество TCP сессий от каждого клиента из сети 172.16.0.0/12 в 200.
-A FORWARD -s 172.16.0.0/12 -p tcp --syn -m connlimit --connlimit-above 200 -j DROP
Но, как показало практическое тестирование connlimit очень сильно нагружает процессор, что делает его применение на роутере нецелесообразным, т.к. несколько клиентов в сети могут создать шторм сетевых пакетов, и вывести роутер из рабочего режима, затруднив остальным пользователям комфортную работу.
recent работает по следующему принципу: первым правилом iptables вы назначаете пакетам удовлетворяющим определенным критериям уникальное имя которое впоследствии будет использоваться этим модулем для наложения ограничений.
Например присвоим всем сетевыем пакетам с состоянием NEW (новое соединение), проходящие через сетевой интерфейс eth0 нашего роутера имя SYNF.
-A FORWARD -i eth0 -m state --state NEW -m recent --set --name SYNF --rsource
Вторым правилом мы скажем модулю, что если от какого-то клиента таких пакетов помеченных как SYNF больше 10 за 10 секунд, то такие пакеты должны отбрасываться.
-A FORWARD -i eth0 -m state --state NEW -m recent --update --seconds 10 --hitcount 10 --rttl --name SYNF --rsource -j DROP
Тестирование показало, что использование модуля recent не влияет на нагрузку роутера. Причем с помошью комбинации модулей state и recent можно делать достаточно интересные ограничения в сетевом трафике препятствуюя распространению спама, флуда и пр.
Купили такую железку Intel ServerAdapter 1000 ET Quad Port PCIe .
Смонтировали в сервер. Задача заставить данный адаптер работать в CentOS 5, и распределить сетевую нагрузку по нескольким очередям.
Загружаемся:
Информация в dmesg
Intel(R) Gigabit Ethernet Network Driver - version 1.3.16-k2
Copyright (c) 2007-2009 Intel Corporation.
ACPI: PCI Interrupt 0000:09:00.0[A] -> GSI 17 (level, low) -> IRQ 169
PCI: Setting latency timer of device 0000:09:00.0 to 64
EDAC MC0: Giving out device to i5000_edac.c I5000: DEV 0000:00:10.0
intel_rng: FWH not detected
ACPI: PCI Interrupt 0000:00:1f.3[B] -> GSI 20 (level, low) -> IRQ 162
igb 0000:09:00.0: Intel(R) Gigabit Ethernet Network Connection
igb 0000:09:00.0: eth2: (PCIe:2.5Gb/s:Width x4) 00:1b:21:3e:ae:28
igb 0000:09:00.0: eth2: PBA No: e64750-002
igb 0000:09:00.0: Using MSI-X interrupts. 4 rx queue(s), 1 tx queue(s)
ACPI: PCI Interrupt 0000:09:00.1[B] -> GSI 18 (level, low) -> IRQ 106
PCI: Setting latency timer of device 0000:09:00.1 to 64
igb 0000:09:00.1: Intel(R) Gigabit Ethernet Network Connection
igb 0000:09:00.1: eth2: (PCIe:2.5Gb/s:Width x4) 00:1b:21:3e:ae:29
igb 0000:09:00.1: eth2: PBA No: e64750-002
igb 0000:09:00.1: Using MSI-X interrupts. 4 rx queue(s), 1 tx queue(s)
ACPI: PCI Interrupt 0000:0a:00.0[A] -> GSI 19 (level, low) -> IRQ 218
PCI: Setting latency timer of device 0000:0a:00.0 to 64
igb 0000:0a:00.0: Intel(R) Gigabit Ethernet Network Connection
igb 0000:0a:00.0: eth3: (PCIe:2.5Gb/s:Width x4) 00:1b:21:3e:ae:2c
igb 0000:0a:00.0: eth3: PBA No: e64750-002
igb 0000:0a:00.0: Using MSI-X interrupts. 4 rx queue(s), 1 tx queue(s)
ACPI: PCI Interrupt 0000:0a:00.1[B] -> GSI 16 (level, low) -> IRQ 177
PCI: Setting latency timer of device 0000:0a:00.1 to 64
igb 0000:0a:00.1: Intel(R) Gigabit Ethernet Network Connection
igb 0000:0a:00.1: eth2: (PCIe:2.5Gb/s:Width x4) 00:1b:21:3e:ae:2d
igb 0000:0a:00.1: eth2: PBA No: e64750-002
igb 0000:0a:00.1: Using MSI-X interrupts. 4 rx queue(s), 1 tx queue(s)
На первый взгляд все замечательно адаптер определился и работает, но смутили надписи 4 rx queue(s), 1 tx queue(s) на каждом из портов. Все дело в том, что у данного адаптера по 8 rx (прием) очередей на каждый порт.
Проверим версию драйвера
modinfo igb
filename: /lib/modules/2.6.18-164.6.1.el5PAE/kernel/drivers/net/igb/igb.ko
version: 1.3.16-k2
license: GPL
description: Intel(R) Gigabit Ethernet Network Driver
author: Intel Corporation,
srcversion: 78555F0A019E05BADBD95AA
alias: pci:v00008086d000010D6sv*sd*bc*sc*i*
alias: pci:v00008086d000010A9sv*sd*bc*sc*i*
alias: pci:v00008086d000010A7sv*sd*bc*sc*i*
alias: pci:v00008086d000010E8sv*sd*bc*sc*i*
alias: pci:v00008086d000010E7sv*sd*bc*sc*i*
alias: pci:v00008086d000010E6sv*sd*bc*sc*i*
alias: pci:v00008086d0000150Asv*sd*bc*sc*i*
alias: pci:v00008086d000010C9sv*sd*bc*sc*i*
depends: 8021q
vermagic: 2.6.18-164.6.1.1.el5PAE SMP mod_unload 686 REGPARM 4KSTACKS gcc-4.1
parm: max_vfs:Maximum number of virtual functions to allocate per physical function (uint)
module_sig: 883f3504af3fe359a79aca2e69819291121b4409f6ecc47545455cf3b51a9aa99f40859e7bd7931a09f76b4b34dde9013eed67638dee172193713aff51f
Очень напрягает практически полное отсутствие секции parm, т.е. драйвер не знает практически никаких параметров.
Поднимем один порт например eth2 и посмотрим как обстоят дела в /proc/interrupts
cat /proc/interrupts|grep eth2
CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7 122: 0 0 0 0 0 0 0 0 PCI-MSI-X eth2-tx-0 130: 182 0 0 0 0 0 0 0 PCI-MSI-X eth2-rx-0 138: 182 0 0 0 0 0 0 0 PCI-MSI-X eth2-rx-1 146: 182 0 0 0 0 0 0 0 PCI-MSI-X eth2-rx-2 154: 182 0 0 0 0 0 0 0 PCI-MSI-X eth2-rx-3 162: 2 0 0 0 0 0 0 0 PCI-MSI-X eth2
Попытаемся подгрузить драйвер igb с нужными нам параметрами, для того чтобы задействовать по 8 очередей на порт.
modprobe igb IntMode=3,3,3,3 RSS=8,8,8,8
FATAL: Error inserting igb (/lib/modules/2.6.18-164.6.1.1.el5PAE/kernel/drivers/net/igb/igb.ko): Unknown symbol in module, or unknown parameter (see dmesg)
в dmesg
igb: Unknown parameter `IntMode'
igb: Unknown parameter `RSS'
опс, драйвер не знает таких параметров 🙁
Надо попробовать свежую версию драйвера igb может с ним нам повезет больше, т. к. собирать драйвер вручную было категорически лень, то вспомнился репозиторий ELREPO в котором данный драйвер присутствует.
Устанавливаем:
rpm -ihv http://elrepo.org/linux/elrepo/el5/i386/RPMS/kmod-igb-PAE-2.0.6-1.el5.elrepo.i686.rpm
Загружается http://elrepo.org/linux/elrepo/el5/i386/RPMS/kmod-igb-PAE-2.0.6-1.el5.elrepo.i686.rpm предупреждение: /var/tmp/rpm-xfer.cvXEF5: Заголовок V3 DSA signature: NOKEY, key ID baadae52 Подготовка... ########################################### [100%] 1:kmod-igb-PAE ########################################### [100%] Creating the symbolic links. This may take some time ... Done.
modinfo igb
filename: /lib/modules/2.6.18-164.6.1.1.el5PAE/weak-updates/igb/igb.ko version: 2.0.6 license: GPL description: Intel(R) Gigabit Ethernet Network Driver author: Intel Corporation, srcversion: AD1D1A409C0E0945FADD6A2 alias: pci:v00008086d000010D6sv*sd*bc*sc*i* alias: pci:v00008086d000010A9sv*sd*bc*sc*i* alias: pci:v00008086d000010A7sv*sd*bc*sc*i* alias: pci:v00008086d000010E8sv*sd*bc*sc*i* alias: pci:v00008086d0000150Dsv*sd*bc*sc*i* alias: pci:v00008086d000010E7sv*sd*bc*sc*i* alias: pci:v00008086d000010E6sv*sd*bc*sc*i* alias: pci:v00008086d00001518sv*sd*bc*sc*i* alias: pci:v00008086d0000150Asv*sd*bc*sc*i* alias: pci:v00008086d000010C9sv*sd*bc*sc*i* depends: vermagic: 2.6.18-8.el5PAE SMP mod_unload 686 REGPARM 4KSTACKS gcc-4.1 parm: InterruptThrottleRate:Interrupt Throttling Rate (array of int) parm: IntMode:Interrupt Mode (array of int) parm: LLIPort:Low Latency Interrupt TCP Port (array of int) parm: LLIPush:Low Latency Interrupt on TCP Push flag (array of int) parm: LLISize:Low Latency Interrupt on Packet Size (array of int) parm: RSS:RSS - multiqueue receive count (array of int) parm: VMDQ:VMDQ - VMDq multiqueue receive (array of int) parm: QueuePairs:QueuePairs - TX/RX queue pairs for interrupt handling (array of int) parm: debug:Debug level (0=none, ..., 16=all) (int)
Подгружаем драйвер с нужными параметрами
modprobe igb IntMode=3,3,3,3 RSS=8,8,8,8
Проверяем
cat /proc/interrupts |grep eth2
51: 6 0 0 0 0 0 0 0 PCI-MSI-X eth2 52: 5 0 0 0 0 0 0 0 PCI-MSI-X eth2-TxRx-0 53: 34 0 0 0 0 0 0 0 PCI-MSI-X eth2-rx-1 54: 8 0 0 0 0 0 0 0 PCI-MSI-X eth2-rx-2 59: 8 0 0 0 0 0 0 0 PCI-MSI-X eth2-rx-3 60: 8 0 0 0 0 0 0 0 PCI-MSI-X eth2-rx-4 61: 34 0 0 0 0 0 0 0 PCI-MSI-X eth2-rx-5 62: 8 0 0 0 0 0 0 0 PCI-MSI-X eth2-rx-6 67: 5 0 0 0 0 0 0 0 PCI-MSI-X eth2-rx-7
Теперь на каждый порт мы имеем по 8 очередей.
Победа.
Попытаемся заNAT-ить несколько сот мегабит трафика при штатном драйвере igb и проверим нагрузку на систему.
Для сравнения вспомним данный обзор, в котором процессоры умирали от si (system interrupts) при трафике в 400 мегабит.
«Дунем» через наш адаптер 400 мегабит входящего трафика, исходящий окажется в пределах 300 мегабит.
vnstat -i eth0 -tr
609740 packets sampled in 5 seconds
Traffic average for eth0
rx 45864.72 kB/s 61261 packets/s
tx 29906.86 kB/s 60686 packets/s
Посмотрим количество conntrack соединений
sysctl -a|grep net.ipv4.netfilter.ip_conntrack_count
net.ipv4.netfilter.ip_conntrack_count = 272495
Посмотрим нагрузку на ядра
top
Cpu0 : 0.0%us, 0.0%sy, 0.0%ni, 68.4%id, 0.0%wa, 0.7%hi, 30.9%si, 0.0%st Cpu1 : 0.0%us, 0.0%sy, 0.0%ni, 65.6%id, 0.0%wa, 3.3%hi, 31.1%si, 0.0%st Cpu2 : 0.0%us, 0.0%sy, 0.0%ni, 66.7%id, 0.0%wa, 0.3%hi, 33.0%si, 0.0%st Cpu3 : 0.0%us, 0.0%sy, 0.0%ni, 69.7%id, 0.0%wa, 0.3%hi, 30.0%si, 0.0%st Cpu4 : 0.3%us, 0.0%sy, 0.0%ni, 65.1%id, 0.0%wa, 0.7%hi, 33.9%si, 0.0%st Cpu5 : 0.0%us, 0.0%sy, 0.0%ni, 63.8%id, 0.0%wa, 0.7%hi, 35.5%si, 0.0%st Cpu6 : 0.0%us, 0.0%sy, 0.0%ni, 64.7%id, 0.0%wa, 3.0%hi, 32.3%si, 0.0%st Cpu7 : 0.0%us, 0.0%sy, 0.0%ni, 63.7%id, 0.0%wa, 0.7%hi, 35.7%si, 0.0%st Mem: 4147676k total, 340000k used, 3807676k free, 40524k buffers Swap: 1052248k total, 0k used, 1052248k free, 123408k cached
Как видим средняя нагрузка на CPU от system interrupts в районе 33% т.е. сервер будет в состоянии занатить 1 гигабит трафика.
Многие системные администраторы сталкивались с проблемой, когда количество сетевых соединений с сервером велико, происходит переполнение conntrack таблицы, из-за чего новые соединения не обрабатываются сервером.
Пример записи в логах указывающих на нехватку количества соединений:
localhost kernel: ip_conntrack: table full, dropping packet.
Увеличить размер conntrack таблицы можно через sysctl.
Размер conntrack таблицы во многих дистрибутивах составляет всего 65536 записей.
В CentOS 5 посмотреть текущее значение можно так:
sysctl -a|grep net.ipv4.netfilter.ip_conntrack_max
Увеличить значение можно через файл /etc/sysctl.conf внеся туда строку:
net.ipv4.netfilter.ip_conntrack_max = НОВОЕ_ЗНАЧЕНИЕ
и заставив систему перечитать изменения:
sysctl -p
Посмотреть сколько в данный момент записей в conntrack таблице можно так:
sysctl -a|grep net.ipv4.netfilter.ip_conntrack_count
В литературе нигде не указываются рекомендованные параметры данной переменной, мои рекомендации следующие:
Если у Вас нет нехватки оперативной памяти на сервере, то установите значение переменой net.ipv4.netfilter.ip_conntrack_max в 1 миллион записей, и отслеживайте значения количества соединений, постепенно уменьшая значение даной переменной до значения (Максимльное количество соединений) +30%.
Будьте осторожны, установив заведомо большое количество соединений при малом количестве оперативной памяти в сервере вы рискуете получить в логах сообщения ядра о нехватке оперативной памяти типа:
localhost kernel: Out of Memory:
и получить в итоге неуправляемую систему.
P.S.В дистрибутивах с новыми ядрами (>2.6.20) параметры задающие максимальное количество записей в conntrack таблице называются
net.netfilter.nf_conntrack_max и net.nf_conntrack_max
Исчерпывающая информация о conntrack находится здесь
Версия 4 Протокола Пограничных Маршрутизаторов (BGP4) — это протокол динамический маршрутизации, описанный в RFC 1771. Он предназначен для обмена информацией (т.е. таблицами маршрутизации) между маршрутизаторами, с целью обеспечить согласующееся представление о данной Автономной Системе (Autonomous System — AS). Может использоваться в режиме EGP (от англ. Exterior Gateway Protocol — Протокол Внешних Маршрутизаторов) или IGP (от англ. Interior Gateway Protocol — Протокол Внутренних Маршрутизаторов). В случае EGP — требуется, чтобы каждый из узлов сети имел свой собственный номер Автономной Системы (AS). BGP4 поддерживает Безклассовую Внутридоменную Маршрутизацию (Classless Inter Domain Routing — CIDR) и объединение маршрутов (объединение нескольких маршрутов в один).
Последующие примеры будем рассматривать на основе конфигурации сети, которая приведена ниже. AS 1 и 50 имеют еще ряд «соседей», но мы будем рассматривать только эти две Автономные Системы, в качестве своих «соседей». Взаимодействие между сетями, в данном примере, производится через туннели, но в общем случае это не обязательно.
| В данном примере используются зарезервированные номера AS, поэтому вы должны будете подставить свои собственные числа. |
--------------------
| 192.168.23.12/24 |
| AS: 23 |
--------------------
/ \
/ \
/ \
------------------ ------------------
| 192.168.1.1/24 |-------| 10.10.1.1/16 |
| AS: 1 | | AS: 50 |
------------------ ------------------
Конфигурирование (пример)
Следующая конфигурация написана для узла 192.168.23.12/24, но может быть с легкостью адаптирована и для других узлов.
Начинается с установки некоторых общих параметров, таких как: имя хоста, пароль и ключи отладки:
! имя хоста hostname anakin ! пароль password xxx ! разрешить пароль (режим суперпользователя) enable password xxx ! путь к файлу журнала log file /var/log/zebra/bgpd.log ! отладка: выводить отладочную информацию (этот раздел позднее может быть удален) debug bgp events debug bgp filters debug bgp fsm debug bgp keepalives debug bgp updates
Список доступа, используемый для ограничения перераспределения в локальных сетях (RFC 1918).
! RFC 1918 networks access-list local_nets permit 192.168.0.0/16 access-list local_nets permit 172.16.0.0/12 access-list local_nets permit 10.0.0.0/8 access-list local_nets deny any
Следующий шаг — настройка каждой из AS:
! Собственный номер AS
router bgp 23
! IP-адрес маршрутизатора
bgp router-id 192.168.23.12
! наша сеть, для оповещения "соседей"
network 192.168.23.0/24
! объявлять о всех подключенных маршрутах (= непосредственно подключенных интерфейсах)
redistribute connected
! объявлять о корневых маршрутах (= подставленных вручную)
redistribute kernel
Блок «router bgp» должен содержать сведения о своих «соседях»:
neighbor 192.168.1.1 remote-as 1 neighbor 192.168.1.1 distribute-list local_nets in neighbor 10.10.1.1 remote-as 50 neighbor 10.10.1.1 distribute-list local_nets in
Проверка конфигурации
| vtysh — это мультиплексор, соединяющий все интерфейсы Zebra. |
anakin# sh ip bgp summary BGP router identifier 192.168.23.12, local AS number 23 2 BGP AS-PATH entries 0 BGP community entries Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd 10.10.0.1 4 50 35 40 0 0 0 00:28:40 1 192.168.1.1 4 1 27574 27644 0 0 0 03:26:04 14 Total number of neighbors 2 anakin# anakin# sh ip bgp neighbors 10.10.0.1 BGP neighbor is 10.10.0.1, remote AS 50, local AS 23, external link BGP version 4, remote router ID 10.10.0.1 BGP state = Established, up for 00:29:01 .... anakin#
А теперь посмотрим — какие маршруты были полученв от «соседей»:
anakin# sh ip ro bgp
Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF,
B - BGP, > - selected route, * - FIB route
B>* 172.16.0.0/14 [20/0] via 192.168.1.1, tun0, 2d10h19m
B>* 172.30.0.0/16 [20/0] via 192.168.1.1, tun0, 10:09:24
B>* 192.168.5.10/32 [20/0] via 192.168.1.1, tun0, 2d10h27m
B>* 192.168.5.26/32 [20/0] via 192.168.1.1, tun0, 10:09:24
B>* 192.168.5.36/32 [20/0] via 192.168.1.1, tun0, 2d10h19m
B>* 192.168.17.0/24 [20/0] via 192.168.1.1, tun0, 3d05h07m
B>* 192.168.17.1/32 [20/0] via 192.168.1.1, tun0, 3d05h07m
B>* 192.168.32.0/24 [20/0] via 192.168.1.1, tun0, 2d10h27m
anakin#
Пожалуйста, дайте мне знать — насколько верна следующая информация, а так же присылайте ваши предложения, комментарии. Zebra — большой программный пакет динамической маршрутизации, который разработали Кунихиро Ишигуро (Kunihiro Ishiguro), Тошиаки Такеда (Toshiaki Takada) и Ясахиро Охара (Yasuhiro Ohara). С помощью Zebra вы легко и быстро сможете настроить OSPF, но на практике, при настройке протокола под весьма специфические потребности, вы столкнетесь со значительным числом параметров. Ниже приводятся некоторые из характеристик протокола OSPF:
Рассмотрим конфигурирование Zebra на примере сети:
----------------------------------------------------
| 192.168.0.0/24 |
| |
| Area 0 100BaseTX Switched |
| Backbone Ethernet |
----------------------------------------------------
| | | |
| | | |
|eth1 |eth1 |eth0 |
|100BaseTX |100BaseTX |100BaseTX |100BaseTX
|.1 |.2 |.253 |
--------- ------------ ----------- ----------------
|R Omega| |R Atlantis| |R Legolas| |R Frodo |
--------- ------------ ----------- ----------------
|eth0 |eth0 | | |
| | | | |
|2MbDSL/ATM |100BaseTX |10BaseT |10BaseT |10BaseT
------------ ------------------------------------ -------------------------------
| Internet | | 172.17.0.0/16 Area 1 | | 192.168.1.0/24 wlan Area 2|
------------ | Student network (dorm) | | barcelonawireless |
------------------------------------ -------------------------------
Пусть вас не пугает эта схема — дело в том, что большую часть работы Zebra выполнит самостоятельно и вам не потребуется вручную «поднимать» все маршруты. Самое главное, что вы должны уяснить из этой схемы — это топология сети. И особое внимание обратите на область 0 (area 0), как самую важную часть. Для начала сконфигурируем zebra под свои потребности (поправим файл zebra.conf):
hostname omega password xxx enable password xxx ! ! Описание интерфейсов. ! !interface lo ! пример описания интерфейса. ! interface eth1 multicast ! ! Статический маршрут по-умолчанию ! ip route 0.0.0.0/0 212.170.21.129 ! log file /var/log/zebra/zebra.log
В дистрибутиве Debian, кроме того необходимо подредактировать файл /etc/zebra/daemons, чтобы обеспечить запуск демонов во время загрузки системы.
zebra=yes ospfd=yes
Затем нужно внести соответствующие изменения в ospfd.conf (для случая IPv4) или в ospf6d.conf (для случая IPv6). Мой ospfd.conf выглядит так:
hostname omega password xxx enable password xxx ! router ospf network 192.168.0.0/24 area 0 network 172.17.0.0/16 area 1 ! ! направить вывод на stdout в журнал log file /var/log/zebra/ospfd.log
Здесь размещены инструкции, описывающие топологию сети.Запуск Zebra
Теперь запустим Zebra. Сделать это можно вручную — дав прямую команду zebra -d, либо с помощью сценария начальной загрузки — /etc/init.d/zebra start. После запуска, в журнале ospfd.log, появятся строки, примерно с таким содержанием:
2002/12/13 22:46:24 OSPF: interface 192.168.0.1 join AllSPFRouters Multicast group. 2002/12/13 22:46:34 OSPF: SMUX_CLOSE with reason: 5 2002/12/13 22:46:44 OSPF: SMUX_CLOSE with reason: 5 2002/12/13 22:46:54 OSPF: SMUX_CLOSE with reason: 5 2002/12/13 22:47:04 OSPF: SMUX_CLOSE with reason: 5 2002/12/13 22:47:04 OSPF: DR-Election[1st]: Backup 192.168.0.1 2002/12/13 22:47:04 OSPF: DR-Election[1st]: DR 192.168.0.1 2002/12/13 22:47:04 OSPF: DR-Election[2nd]: Backup 0.0.0.0 2002/12/13 22:47:04 OSPF: DR-Election[2nd]: DR 192.168.0.1 2002/12/13 22:47:04 OSPF: interface 192.168.0.1 join AllDRouters Multicast group. 2002/12/13 22:47:06 OSPF: DR-Election[1st]: Backup 192.168.0.2 2002/12/13 22:47:06 OSPF: DR-Election[1st]: DR 192.168.0.1 2002/12/13 22:47:06 OSPF: Packet[DD]: Negotiation done (Slave). 2002/12/13 22:47:06 OSPF: nsm_change_status(): scheduling new router-LSA origination 2002/12/13 22:47:11 OSPF: ospf_intra_add_router: Start
Не обращайте внимания на строки «…SMUX_CLOSE…», поскольку они относятся к SNMP и не представляют интереса для нас. Из приведенного листинга видно, что 192.168.0.1 — это Выделенный Маршрутизатор (Designated Router), а 192.168.0.2 —Резервный Выделенный Маршрутизатор (Backup Designated Router).
И zebra, и ospfd допускают возможность интерактивного взаимодействия с ними через telnet:
$ telnet localhost zebra $ telnet localhost ospfd
Попробуем посмотреть список установленных маршрутов, залогировавшись в zebra:
root@atlantis:~# telnet localhost zebra
Trying 127.0.0.1...
Connected to atlantis.
Escape character is '^]'.
Hello, this is zebra (version 0.92a).
Copyright 1996-2001 Kunihiro Ishiguro.
User Access Verification
Password:
atlantis> show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF,
B - BGP, > - selected route, * - FIB route
K>* 0.0.0.0/0 via 192.168.0.1, eth1
C>* 127.0.0.0/8 is directly connected, lo
O 172.17.0.0/16 [110/10] is directly connected, eth0, 06:21:53
C>* 172.17.0.0/16 is directly connected, eth0
O 192.168.0.0/24 [110/10] is directly connected, eth1, 06:21:53
C>* 192.168.0.0/24 is directly connected, eth1
atlantis> show ip ospf border-routers
============ OSPF router routing table =============
R 192.168.0.253 [10] area: (0.0.0.0), ABR
via 192.168.0.253, eth1
[10] area: (0.0.0.1), ABR
via 172.17.0.2, eth0
или напрямую, с помощью iproute:
root@omega:~# ip route 212.170.21.128/26 dev eth0 proto kernel scope link src 212.170.21.172 192.168.0.0/24 dev eth1 proto kernel scope link src 192.168.0.1 172.17.0.0/16 via 192.168.0.2 dev eth1 proto zebra metric 20 default via 212.170.21.129 dev eth0 proto zebra root@omega:~#
Отсюда видно, что zebra добавила ряд маршрутов, которых в таблице раньше не было. Новые маршруты появляются спустя несколько секунд после того, как были запущены zebra и ospfd. Теперь вы можете попробовать ping-ануть некоторые из узлов сети.Zebra выставляет маршруты автоматически, все что от вас требуется — прописать маршрутизаторы в конфигурационный файл и этого будет достаточно!
Для захвата и анализа OSPF-пакетов можно воспользоваться командой:
tcpdump -i eth1 ip[9] == 89
где число 89 — это номер протокола OSPF, а 9 — это номер октета в ip-заголовке, где хранится номер протокола.
OSPF имеет ряд дополнительных настраиваемых параметров, имеющих особое значение при работе в больших сетях. В одном из следующих выпусков этого документа мы покажем некоторые методологии тонкой подстройки протокола OSPF.
Меня зовут Педро Ларрой (Pedro Larroy) <piotr%member.fsf.org>. Здесь я расскажу об общих принципах настройки соединения локальной сети, в которой имеется большое число пользователей, к Интернет через маршрутизатор, работающий под управлением Linux. Маршрутизатор имеет реальный IP-адрес и производит Трансляцию Сетевых Адресов (NAT). Я живу в университетском общежитии, где проложена локальная сеть на 198 пользователей. Эта сеть соединена с Интернет через маршрутизатор, который я администрирую. Пользователи очень интенсивно работают в пиринговых сетях, что требует соответствующего управления трафиком. Надеюсь, что этот пример будет интересен читателям lartc.
Прежде всего я опишу процесс настройки своего маршрутизатора шаг за шагом, и в заключение расскажу, как сделать этот процесс автоматическим, выполняющимся в процессе загрузки системы. Сеть, к которой относится этот пример, является локальной (LAN). Она подключена к Интернет через маршрутизатор, который имеет единственный реальный IP-адрес. Разделение единственного реального IP-адреса между всеми пользователями в локальной сети осуществляется с помощью нескольких правил iptables. Для этого необходимо:
Для начала создадим несколько дисциплин (qdiscs), которые будут обслуживать трафик. Первой создается htb qdisc с 6-ю классами и различными приоритетами. Каждому классу назначена определенная пропускная способность, но при этом они могут задействовать неиспользуемую пропускную способность, если она не занята другими классами. Напомню, что классы с более высоким приоритетом (т.е. с более низким числом prio) будут получать «излишек» канала первыми. Подключение к Интернет осуществляется через модем ADSL, с пропускной способностью для входящего трафика 2 Мбит/сек, исходящего — 300 Кбит/сек. Я ограничиваю исходящую пропускную способность величиной в 240 Кбит/сек по той простой причине, что это максимальное значение, при котором время ожидания отклика остается минимальным. Величина этот параметра может быть определена экспериментально, путем наблюдения за изменением времени отклика при изменении величины пропускной способности.
Для начала, присвойте переменной CEIL величину, составляющую 75% от общей пропускной способности для исходящего трафика. Там, где я использую eth0 — назначьте свой интерфейс, который «смотрит» в Интернет. Сценарий (на языке командной оболочки), выполняющий настройку, начинается со следующих строк:
CEIL=240
tc qdisc add dev eth0 root handle 1: htb default 15
tc class add dev eth0 parent 1: classid 1:1 htb rate ${CEIL}kbit ceil ${CEIL}kbit
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 80kbit ceil 80kbit prio 0
tc class add dev eth0 parent 1:1 classid 1:11 htb rate 80kbit ceil ${CEIL}kbit prio 1
tc class add dev eth0 parent 1:1 classid 1:12 htb rate 20kbit ceil ${CEIL}kbit prio 2
tc class add dev eth0 parent 1:1 classid 1:13 htb rate 20kbit ceil ${CEIL}kbit prio 2
tc class add dev eth0 parent 1:1 classid 1:14 htb rate 10kbit ceil ${CEIL}kbit prio 3
tc class add dev eth0 parent 1:1 classid 1:15 htb rate 30kbit ceil ${CEIL}kbit prio 3
tc qdisc add dev eth0 parent 1:12 handle 120: sfq perturb 10
tc qdisc add dev eth0 parent 1:13 handle 130: sfq perturb 10
tc qdisc add dev eth0 parent 1:14 handle 140: sfq perturb 10
tc qdisc add dev eth0 parent 1:15 handle 150: sfq perturb 10
Эти строки создают одноярусное дерево HTB:
+---------+
| root 1: |
+---------+
|
+---------------------------------------+
| class 1:1 |
+---------------------------------------+
| | | | | |
+----+ +----+ +----+ +----+ +----+ +----+
|1:10| |1:11| |1:12| |1:13| |1:14| |1:15|
+----+ +----+ +----+ +----+ +----+ +----+
Мы создали различные классы обработки трафика, но классификация пока отсутствует, поэтому, к настоящему моменту, весь трафик пойдет через класс 1:15 ( который назначен классом по-умолчанию: tc qdisc add dev eth0 root handle 1: htb default 15 ). Теперь самое главное — нужно распределить трафик по имеющимся классам.
Устанавим фильтры, которые будут выполнять классификацию пакетов, основываясь на метках iptables. Мне нравятся iptables за их чрезвычайную гибкость и за возможность подсчитывать количество пакетов, пропущенных тем или иным правилом. Добавим в сценарий следующие строки:
tc filter add dev eth0 parent 1:0 protocol ip prio 1 handle 1 fw classid 1:10 tc filter add dev eth0 parent 1:0 protocol ip prio 2 handle 2 fw classid 1:11 tc filter add dev eth0 parent 1:0 protocol ip prio 3 handle 3 fw classid 1:12 tc filter add dev eth0 parent 1:0 protocol ip prio 4 handle 4 fw classid 1:13 tc filter add dev eth0 parent 1:0 protocol ip prio 5 handle 5 fw classid 1:14 tc filter add dev eth0 parent 1:0 protocol ip prio 6 handle 6 fw classid 1:15
Здесь задаются соответствия между специфическими значениями FWMARK ( handle x fw ) и классами (classid x:x). Теперь рассмотрим процесс установки меток на пакеты.
Для начала необходимо разобраться с тем, как движутся пакеты через iptables:
+------------+ принятие +---------+ +-------------+
Вход ---| PREROUTING |--- решения о --| FORWARD |-------+-------| POSTROUTING |- Выход
+------------+ маршрутизации +---------+ | +-------------+
| |
+-------+ +--------+
| INPUT |-Локальные процессы-| OUTPUT |
+-------+ +--------+
Далее я буду исходить из предположения, что всем таблицам назначена политика по-умолчанию -P ACCEPT. Наша локальная сеть относится к классу B, с адресами 172.17.0.0/16. Реальный IP-адрес — 212.170.21.172
Добавим правило iptables, которое будет выполнять SNAT, что позволит пользователям локальной сети общаться с внешним миром, и разрешим форвардинг пакетов:
echo 1 > /proc/sys/net/ipv4/ip_forward iptables -t nat -A POSTROUTING -s 172.17.0.0/255.255.0.0 -o eth0 -j SNAT --to-source 212.170.21.172
Проверим, что пакеты уходят через класс 1:15:
tc -s class show dev eth0
Добавим в цепочку PREROUTING, таблицы mangle, правила для установки меток на пакеты:
iptables -t mangle -A PREROUTING -p icmp -j MARK --set-mark 0x1 iptables -t mangle -A PREROUTING -p icmp -j RETURN
Теперь вы должны наблюдать увеличение значения счетчика пакетов в классе 1:10, при попытке ping-ануть из локальной сети какой-нибудь сайт в Интернете.
tc-s класс показывают dev eth0
Действие -j RETURN предотвращает движение пакетов по всем правилам. Поэтому все ICMP-пакеты будут проходить только это правило. Добавим еще ряд правил, которые будут изменять биты в поле TOS:
iptables -t mangle -A PREROUTING -m tos --tos Minimize-Delay -j MARK --set-mark 0x1 iptables -t mangle -A PREROUTING -m tos --tos Minimize-Delay -j RETURN iptables -t mangle -A PREROUTING -m tos --tos Minimize-Cost -j MARK --set-mark 0x5 iptables -t mangle -A PREROUTING -m tos --tos Minimize-Cost -j RETURN iptables -t mangle -A PREROUTING -m tos --tos Maximize-Throughput -j MARK --set-mark 0x6 iptables -t mangle -A PREROUTING -m tos --tos Maximize-Throughput -j RETURN
Поднимем приоритет для ssh-пакетов:
iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 22 -j MARK --set-mark 0x1 iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 22 -j RETURN
а так же для пакетов, с которых начинается TCP-соединение, т.е. SYN-пакетов:
iptables -t mangle -I PREROUTING -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j MARK --set-mark 0x1 iptables -t mangle -I PREROUTING -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j RETURN
И так далее. После того, как в цепочку PREROUTING, таблицы mangle, будут внесены все необходимые правила, закончим ее правилом:
iptables -t mangle -A PREROUTING -j MARK --set-mark 0x6
Это заключительное правило отправит оставшиеся немаркированные пакеты в класс 1:15. Фактически, это правило можно опустить, так как класс 1:15 был задан по-умолчанию, но тем не менее, я оставляю его, чтобы сохранить единство настроек и кроме того, иногда бывает полезно увидеть счетчик пакетов для этого правила.
Нелишним будет добавить те же правила в цепочку OUTPUT, заменив имя цепочки PREROUTING на OUTPUT (s/PREROUTING/OUTPUT/). Тогда трафик, сгенерированный локальными процессами на маршрутизаторе, также будет классифицирован по категориям. Но, в отличие от вышеприведенных правил, в цепочке OUTPUT, я устанавливаю метку -j MARK —set-mark 0x3, таким образом трафик от маршрутизатора получает более высокий приоритет.
В результате приведенных настроек, мы получили вполне работоспособную конфигурацию. Однако, в каждом конкретном случае, эти настройки всегда можно немного улучшить. Найдите время и проследите — куда идет основной трафик и как лучше им распорядиться. Я потратил огромное количество времени и наконец довел свою конфигурацию до оптимального уровня, практически сведя на нет бесчисленные таймауты.
Если вдруг обнаружится, что через некоторые классы проходит подавляющее большинство трафика, то к ним можно прикрепить другую дисциплину организации очереди, чтобы распределить канал более равномерно:
tc qdisc add dev eth0 parent 1:13 handle 130: sfq perturb 10 tc qdisc add dev eth0 parent 1:14 handle 140: sfq perturb 10 tc qdisc add dev eth0 parent 1:15 handle 150: sfq perturb 10
Уверен, что можно найти множество способов, чтобы произвести настройку маршрутизатора во время загрузки. Для себя я создал скрипт /etc/init.d/packetfilter, который принимает команды [start | stop | stop-tables | start-tables | reload-tables]. Он конфигурирует дисциплины (qdiscs) и загружает необходимые модули ядра. Этот же сценарий загружает правила iptables из файла /etc/network/iptables-rules, которые предварительно могут быть сохранены утилитой iptables-save и восстановлены —iptables-restore.