Доброго дня!
Занялся вопросом шейпинга трафика на роутере. Суть такова: 2 интернет-канала и 1 локалка. Первый канал основной, второй - резервный, при падении одного автоматом переключается на другой, с этим проблем нет.
Нужно ограничить входящий и исходящий трафик на обоих интерфейсах интернет-каналов. Иначе говоря, чтобы сам роутер не качал и не отдавал используя весь канал. Также нужно динамическое распределение полосы пользователям за NATом, иначе говоря, трафика который форвардится.
Много читал, много думал, много пробовал. В итоге дошел вот до чего:
#!/bin/sh
###################
#
# Traffic shaping
#
###################
#
# Settings
#
# TC utility location
TC="/sbin/tc"
# Local network
LOCAL_IF="vlan10"
LOCAL_RATE="100mbit"
# Provider 1
P1_IF="vlan11"
P1_RATE="4096kbit"
# Provider 2
P2_IF="vlan12"
P2_RATE="2048kbit"
# Rates
INET_RATE="1024kbit"
CEIL_RATE="1280kbit"
P2P_RATE="128kbit"
Переменные, все думаю понятно. 2 провайдера, один каналом 2 мбит, другой 4 мбит, локалка 100 мбит. Общая скорость интернета 1 мбит с возможностью разгона до 1280 кбит, скорость для торрентов, качалок и прочих неизвестных портов 128 кбит.
Про дисциплины очередей почитал, понял что такое. В скрипте удаляем если они уже имеются и заново добавляем:
#
# Delete existing disciplines
#
$TC qdisc del dev $LOCAL_IF root
$TC qdisc del dev $P1_IF root
$TC qdisc del dev $P2_IF root
#
# Add queueing disciplines
#
$TC qdisc add dev $LOCAL_IF root handle 1: htb
$TC qdisc add dev $P1_IF root handle 1: htb
$TC qdisc add dev $P2_IF root handle 1: htb
Я предпочел дисциплицы HTB (Hierarchical Token Bucket) основываюсь на документации и отзывах.
Я вроде даже более менее сообразил и в плане создания классов трафика:
#
# Add classes
#
# Local net
$TC class add dev $LOCAL_IF parent 1: classid 1:1 htb rate $LOCAL_RATE
$TC class add dev $LOCAL_IF parent 1:1 classid 1:10 htb rate $INET_RATE ceil $CEIL_RATE prio 1
$TC class add dev $LOCAL_IF parent 1:1 classid 1:20 htb rate $P2P_RATE ceil $P2P_RATE prio 2
# Provider 1
$TC class add dev $P1_IF parent 1: classid 1:1 htb rate $P1_RATE
$TC class add dev $P1_IF parent 1:1 classid 1:10 htb rate $INET_RATE ceil $CEIL_RATE prio 1
$TC class add dev $P1_IF parent 1:1 classid 1:20 htb rate $P2P_RATE ceil $P2P_RATE prio 2
# Provider 2
$TC class add dev $P2_IF parent 1: classid 1:1 htb rate $P2_RATE
$TC class add dev $P2_IF parent 1:1 classid 1:10 htb rate $INET_RATE ceil $CEIL_RATE prio 1
$TC class add dev $P2_IF parent 1:1 classid 1:20 htb rate $P2P_RATE ceil $P2P_RATE prio 2
И понял что для динамического распределения каналов мне необходимы дисциплины SFQ для классов.
#
# Add additional disciplines
#
# Local net
$TC qdisc add dev $LOCAL_IF parent 1:10 handle 10: sfq perturb 10
$TC qdisc add dev $LOCAL_IF parent 1:20 handle 20: sfq perturb 10
# Provider 1
$TC qdisc add dev $P1_IF parent 1:10 handle 10: sfq perturb 10
$TC qdisc add dev $P1_IF parent 1:20 handle 20: sfq perturb 10
# Provider 2
$TC qdisc add dev $P2_IF parent 1:10 handle 10: sfq perturb 10
$TC qdisc add dev $P2_IF parent 1:20 handle 20: sfq perturb 10
Где-то еще вычитал что для более менее равномерного распределения полосы сгодятся оные команды.
#
# Add filters
#
# Local net
$TC filter add dev $LOCAL_IF parent 10: protocol ip handle 10 flow hash keys dst divisor 256
$TC filter add dev $LOCAL_IF parent 20: protocol ip handle 20 flow hash keys dst divisor 256
# Provider 1
$TC filter add dev $P1_IF parent 10: protocol ip handle 10 flow hash keys dst divisor 256
$TC filter add dev $P2_IF parent 20: protocol ip handle 20 flow hash keys dst divisor 256
# Provider 2
$TC filter add dev $P2_IF parent 10: protocol ip handle 10 flow hash keys dst divisor 256
$TC filter add dev $P2_IF parent 20: protocol ip handle 20 flow hash keys dst divisor 256
Судя по всему определяет как очереди SFQ обрабатывать запросы.
И все, понеслись запарки в плане установки фильтров трафика, маркираторов и пр.
Сейчас использую iptables с вот таким вот конфигом:
#
# FORWARD Chain
#
# Other
$IPT -t mangle -A FORWARD -i $LOCAL_IFACE -o $P1_IFACE -j CLASSIFY --set-class 1:20
$IPT -t mangle -A FORWARD -i $LOCAL_IFACE -o $P2_IFACE -j CLASSIFY --set-class 1:20
$IPT -t mangle -A FORWARD -i $P1_IFACE -o $LOCAL_IFACE -j CLASSIFY --set-class 1:20
$IPT -t mangle -A FORWARD -i $P2_IFACE -o $LOCAL_IFACE -j CLASSIFY --set-class 1:20
# ICMP
$IPT -t mangle -A FORWARD -i $LOCAL_IFACE -o $P1_IFACE -p icmp -j CLASSIFY --set-class 1:10
$IPT -t mangle -A FORWARD -i $LOCAL_IFACE -o $P2_IFACE -p icmp -j CLASSIFY --set-class 1:10
$IPT -t mangle -A FORWARD -i $P1_IFACE -o $LOCAL_IFACE -p icmp -j CLASSIFY --set-class 1:10
$IPT -t mangle -A FORWARD -i $P2_IFACE -o $LOCAL_IFACE -p icmp -j CLASSIFY --set-class 1:10
# TCP
$IPT -t mangle -A FORWARD -i $LOCAL_IFACE -o $P1_IFACE -p tcp -m multiport --dport 20,21,22,25,53,80,110,143,443,995,3389,4899,5190,5222 -j CLASSIFY --set-class 1:10
$IPT -t mangle -A FORWARD -i $LOCAL_IFACE -o $P2_IFACE -p tcp -m multiport --dport 20,21,22,25,53,80,110,143,443,995,3389,4899,5190,5222 -j CLASSIFY --set-class 1:10
$IPT -t mangle -A FORWARD -i $P1_IFACE -o $LOCAL_IFACE -p tcp -m multiport --sport 20,21,22,25,53,80,110,143,443,995,3389,4899,5190,5222 -j CLASSIFY --set-class 1:10
$IPT -t mangle -A FORWARD -i $P2_IFACE -o $LOCAL_IFACE -p tcp -m multiport --sport 20,21,22,25,53,80,110,143,443,995,3389,4899,5190,5222 -j CLASSIFY --set-class 1:10
# UDP
$IPT -t mangle -A FORWARD -i $LOCAL_IFACE -o $P1_IFACE -p udp -m multiport --dport 53,123,5190,5222 -j CLASSIFY --set-class 1:10
$IPT -t mangle -A FORWARD -i $LOCAL_IFACE -o $P2_IFACE -p udp -m multiport --dport 53,123,5190,5222 -j CLASSIFY --set-class 1:10
$IPT -t mangle -A FORWARD -i $P2_IFACE -o $LOCAL_IFACE -p udp -m multiport --sport 53,123,5190,5222 -j CLASSIFY --set-class 1:10
$IPT -t mangle -A FORWARD -i $P2_IFACE -o $LOCAL_IFACE -p udp -m multiport --sport 53,123,5190,5222 -j CLASSIFY --set-class 1:10
Но по-моему это как-то коряво, стопудово можно эту конструкцию сделать куда компактней и удобней. Плюс это только маркировка трафика для форвардинга. Как мне ограничить трафик на внешних интерфейсах для самого роутера?
Господа, был бы очень признателен если бы кто-нибудь подробно объяснил формирование фильтров для трафика средствами tc, iptables и пр.
Я уже просто замучился.