Программный интернет шлюз для уже не маленькой компании (Shorewall, QoS во всю ширь). Часть 3

в 17:23, , рубрики: dnsmasq, iptables, linux, openvpn, ospf, quagga, shorewall, Настройка Linux, Сетевые технологии, системное администрирование

Представляю третью статью из серии, ориентированных на «продолжающих» системных администраторов, для опытных я вряд ли открою что-то новое.

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

Конкретно в этой части:

  • QoS во всю ширь в Shorewall
  • Более подробная настройка Shorewall
  • Раскидывание трафика по каналам в соответствии с протоколами
  • Костыли, без них, никуда

А в первой части были рассмотрены:

  • Простейшая настройка Shorewall
  • Ужасно сложная настройка dnsmasq
  • Не менее сложная настройка OpenVPN
  • И для многих продолжающих админов нетипичная, динамическая маршрутизация, на примере OSPF

А во второй:

  • Более подробная настройка Shorewall
  • Страшный и не понятный QoS
  • Балансировка нагрузки и резервирование

Планирование классификации трафика

Все, что описано дальше, это просто моё видение вопроса, ваше мнение может (и по хорошему должно быть) другим.

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

  • Служебный трафик (DNS, ICMP, TCP/ACK)
  • Туннельный трафик
  • Voip трафик
  • Административный (SSH и т.п.)
  • Пользовательский
    • Высоко приоритетный
    • Обычный
    • Низко приоритетный
    • VPN Трафик

В свою очередь, пользовательский трафик, внутри каждого класса, мы поделим между некоторыми службами.
Осознать всю непростую конфигурацию можно посмотрев на картинку (левый верхний угол: родительский класс, правый верхний: приоритет, по нижним углам: минимальная и максимальная скорость):

Программный интернет шлюз для уже не маленькой компании (Shorewall, QoS во всю ширь). Часть 3 - 1

Разруливать мы будем трафик на не очень то и быстром канале в 1 мбит (подумать только, не так давно и 128 кбит было круто), точнее на двух (чтобы было поинтереснее)!

Правила работают таким образом: если у класса есть несколько дочерних классов, с одинаковым приоритетом, то при расчете, кому сколько полосы дать сверх лимита, будет использована пропорция от минимальных скоростей этих классов. Если приоритеты не одинаковы, то они войдут в расчет как дополнительный весовой коэффициент. Сверх минимальной полосы, выделенной у класса, есть ещё некая не распределенная полоса, она может быть использована, если канал свободен в достаточной мере. В большинстве случаев я указывал для этой полосы ключевое значение full (максимум родительского класса).

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

Но хватит лирики, начнем (часть конфигов мы используем из прошлых статей, если что-то мной не настроено здесь, вы знаете где искать):

Объявим переменные:

params

#
# Shorewall -- /etc/shorewall/params
#
# Assign any variables that you need here.
#
# It is suggested that variable names begin with an upper case letter
# to distinguish them from variables used internally within the
# Shorewall programs
#
# Example:
#
#	NET_IF=eth0
#	NET_BCAST=130.252.100.255
#	NET_OPTIONS=routefilter,norfc1918
#
# Example (/etc/shorewall/interfaces record):
#
#	net	$NET_IF		$NET_BCAST	$NET_OPTIONS
#
# The result will be the same as if the record had been written
#
#	net	eth0		130.252.100.255	routefilter,norfc1918
#
###############################################################################
IF_RED1=eth0
# Шлюзы одинаковые, так как работаем в лаборатории, и оба интерфейса смотрят в одну сеть
GW_RED1=192.168.10.1
IF_RED2=eth2
GW_RED2=192.168.10.1
IF_GRN=eth1
NET_GRN=172.16.0.0/23
IF_TUN=tap+
# Тут у нас костыли из-за не полной поддержки ipset во всех местах, обещают исправить в ближайших релизах
IP_SLOW=172.16.0.45
IP_SLOW_SPEC=172.16.0.45
IP_VIP=172.16.0.46
IP_VIP_SPEC=172.16.0.46
IP_NORMAL=$NET_GRN
IP_NORMAL_SPEC=172.16.0.47
#LAST LINE -- DO NOT REMOVE

Объявим провайдеров:

providers

#
# Shorewall -- /etc/shorewall/providers
#
# For information about entries in this file, type "man shorewall-providers"
#
# For additional information, see http://shorewall.net/MultiISP.html
#
############################################################################################
#NAME	NUMBER	MARK	DUPLICATE	INTERFACE	GATEWAY		OPTIONS		COPY
pr1	1	0x10000	-		$IF_RED1	GW_RED1	track,balance=1
pr2	2	0x20000	-		$IF_RED2	GW_RED2	track,balance=1
# Этот раздел раскрою чуть позже. Это костылики :)
tap0	4	0x30000	-	tap0	-	loose
tap1	3	0x40000	-	tap1	-	loose

interfaces

#
# Shorewall -- /etc/shorewall/interfaces
#
# For information about entries in this file, type "man shorewall-interfaces"
#
# The manpage is also online at
# http://www.shorewall.net/manpages/shorewall-interfaces.html
#
###############################################################################
?FORMAT 2
###############################################################################
#ZONE		INTERFACE		OPTIONS
red		$IF_RED1		dhcp,routeback,optional
red		$IF_RED2		dhcp,routeback,optional
grn		$IF_GRN		dhcp,routeback,optional
tun		tap0		dhcp,routeback,optional
tun		tap1		dhcp,routeback,optional

Сделаем кой чего, во время запуска:

init

#
# Shorewall -- /etc/shorewall/init
#
# Add commands below that you want to be executed at the beginning of
# a "shorewall start", "shorewall-reload" or "shorewall restart" command.
#
# For additional information, see
# http://shorewall.net/shorewall_extension_scripts.htm
#
###############################################################################
modprobe ifb numifbs=3
ip link set ifb0 up
ip link set ifb1 up
ip link set ifb2 up
ipset -N ip_vip iphash
ipset -N ip_vip_spec iphash
ipset -N ip_normal iphash
ipset -A ip_normal $NET_GRN
ipset -N ip_normal_spec iphash
ipset -N ip_slow iphash
ipset -N ip_slow_spec iphash

started

#
# Shorewall -- /etc/shorewall/started
#
# Add commands below that you want to be executed after shorewall has
# been completely started, reloaded or restarted. The difference between
# this extension script and /etc/shorewall/start is that this one is
# invoked after the 'shorewall' chain has been created (thus
# signaling that the firewall is completely up).
#
# This script should not change the firewall configuration directly but
# may do so indirectly by running /sbin/shorewall with the 'nolock'
# option.
#
# See http://shorewall.net/shorewall_extension_scripts.htm for additional
# information.
#
###############################################################################
IPROUTE='/usr/sbin/ip'
IFS=$'n'
for line in $(grep tap /etc/shorewall/providers | grep loose);do
	IFS=$' tn' read -r -a line_ <<< "$line"
	$IPROUTE route del default table ${line_[1]} >/dev/null 2>&1
done

Дополним политику маршрутизации (необходимость этого шага раскрою ниже):

rtrules

#
# Shorewall -- /etc/shorewall/rtrules
#
# For information about entries in this file, type "man shorewall-rtrules"
#
# For additional information, see http://www.shorewall.net/MultiISP.html
#
####################################################################################
#SOURCE			DEST			PROVIDER	PRIORITY	MASK
0.0.0.0/0		0.0.0.0/0		tap0		19001
0.0.0.0/0		0.0.0.0/0		tap1		19002

Объявим кучу классов для трафика:

tcclasses

#
# Shorewall -- /etc/shorewall/tcclasses
#
# For information about entries in this file, type "man shorewall-tcclasses"
#
# See http://shorewall.net/traffic_shaping.htm for additional information.
#
###############################################################################
#INTERFACE:CLASS	MARK	RATE:		CEIL	PRIORITY	OPTIONS
#				DMAX:UMAX
INCLUDE tcclasses.1
INCLUDE tcclasses.2
INCLUDE tcclasses.3
INCLUDE tcclasses.4
INCLUDE tcclasses.5
INCLUDE tcclasses.6

tcclasses.1

#
# Shorewall -- /etc/shorewall/tcclasses
#
# For information about entries in this file, type "man shorewall-tcclasses"
#
# See http://shorewall.net/traffic_shaping.htm for additional information.
#
###############################################################################
#INTERFACE:CLASS	MARK	RATE:		CEIL	PRIORITY	OPTIONS
#				DMAX:UMAX
# Выделяем трафик, который попал на интерфейс локальной сети
# В этом классе будет весь трафик из интернета
1:1:2			-	1mbit		2mbit		1
# В этом от локальной сети
1:1:3			-	998mbit 	999mbit		2

# Выделим для ACK пакетов широкую полосу. Минимальная предполагает, что есть
# только TCP трафик с максимальным MTU (меньше всего пакетов ACK), и для
# плохово варианта, берем что у нас все пакеты в четверь от MTU (пакетов ACK больше),
# еще выделим поток пакетов до одного получателя
1:2:4			-	full*64/1500	full*64*4/1500	1	tcp-ack
# Для SSH у нас два класса, первый, для коротких пакетов (в основном команды)
1:2:5			-	32kbit		128kbit		2	
# Второй для длинных пакетов (для передачи файлов к примеру)
1:2:6			-	32kbit		full*9/10	5	flow=dst
# Отдельная полоса для DNS и ICMP,
1:2:7			-	32kbit		128kbit		3
# позволит уменьшить задержки на запросах DNS
1:7:8			-	16kbit		full		1	
# и сделает PING интереснее
1:7:9			-	16kbit		full		1	
# Тут выделяем отдельную полосу для VoIP трафика
1:2:A			-	180kbit		180kbit	1
# Это для чистого SIP (один канал u(a)law), используем еще и маркировку пакетов от nf_conntrack_sip
1:A:B			1	90kbit		full		1
# Это для SIP в VPN тунеле (межофисный трафик)
1:A:C			-	90kbit		full		1
# Выделяем пользовательский трафик
1:2:D			-	252kbit		full		4

# Класс обычного пользовательского трафика
1:D:E			-	100kbit		full		2
# Тут живет VPN (который запускает пользователь)
1:D:F			-	32kbit		full		1	
# Для HTTP(S) с короткими пакетами, выделим приоритет больше (будет казаться,
# что странички быстрее открываются)
1:E:10			-	25kbit		full		1	flow=dst
# Для RDP
1:E:12			-	15kbit		full		2	flow=dst
# Для HTTP(S) с длинными пакетами, дольше будут грузится картики и большие страницы
1:E:13			-	15kbit		full		3	flow=dst
# Для почтового трафика оперативность обычно менее важна
1:E:14			-	10kbit		full		4	flow=dst
# Сюда поместим трафик специального сервиса (к примеру, трансляцию Webinar)
1:E:16			-	25kbit		full		2	flow=dst
# Сюда упадет все, что мы не классифицировали явно
1:E:17			-	10kbit		full		5	default,flow=dst

# Класс VIP пользовательского трафика (VIP-ов у нас обычно не много), им приоритет выше
1:D:18			-	60kbit		full		1
# Для HTTP(S) с короткими пакетами, выделим приоритет больше (будет казаться,
# что странички быстрее открываются)
1:18:19			-	20kbit		full		1
# Для HTTP(S) с длинными пакетами, дольше будут грузится картики и большие страницы
1:18:1A			-	10kbit		full		3
# Для почтового трафика оперативность обычно менее важна
1:18:1B			-	10kbit		full		4
# Сюда поместим трафик VIP специального сервиса
1:18:1C			-	20kbit		full		2	

# Класс наказанных пользователей
1:D:1D			-	60kbit		full		3
# Для HTTP(S) с короткими пакетами, выделим приоритет больше (будет казаться,
# что странички быстрее открываются)
1:1D:1E			-	20kbit		full		1	
# Для HTTP(S) с длинными пакетами, дольше будут грузится картики и большие страницы
1:1D:1F			-	10kbit		full		3
# Для почтового трафика оперативность обычно менее важна
1:1D:20			-	10kbit		full		4	
# Сюда поместим трафик специального сервиса, пускай мучаются
1:1D:21			-	20kbit		full		2	

tcclasses.2

#
# Shorewall -- /etc/shorewall/tcclasses.2
#
# For information about entries in this file, type "man shorewall-tcclasses"
#
# See http://shorewall.net/traffic_shaping.htm for additional information.
#
###############################################################################
#INTERFACE:CLASS	MARK	RATE:		CEIL	PRIORITY	OPTIONS
#				DMAX:UMAX
# Выделяем трафик, который попал на интерфейс локальной сети
# В этом классе будет весь трафик из интернета
2:1:2			-	1mbit		1mbit		1
# В этом от локальной сети
2:1:3			-	999mbit 	999mbit		2

# Выделим для ACK пакетов широкую полосу. Минимальная предполагает, что есть
# только TCP трафик с максимальным MTU (меньше всего пакетов ACK), и для
# плохово варианта, берем что у нас все пакеты в четверь от MTU (пакетов ACK больше),
# еще выделим поток пакетов до одного получателя
2:2:4			-	full*64/1500	full*64*4/1500	1	tcp-ack
# Для SSH у нас два класса, первый, для коротких пакетов (в основном команды)
2:2:5			-	32kbit		128kbit		2	
# Второй для длинных пакетов (для передачи файлов к примеру)
2:2:6			-	32kbit		full*9/10	5	flow=nfct-src
# Отдельная полоса для DNS и ICMP,
2:2:7			-	32kbit		128kbit		3
# позволит уменьшить задержки на запросах DNS
2:7:8			-	16kbit		full		1	
# и сделает PING интереснее
2:7:9			-	16kbit		full		1	
# Тут выделяем отдельную полосу для VoIP трафика
2:2:A			-	180kbit		180kbit	1
# Это для чистого SIP (один канал u(a)law), используем еще и маркировку пакетов от nf_conntrack_sip
2:A:B			1	90kbit		full		1
# Это для SIP в VPN тунеле (межофисный трафик)
2:A:C			-	90kbit		full		1
# Выделяем пользовательский трафик
2:2:D			-	252kbit		full		4

# Класс обычного пользовательского трафика
2:D:E			-	100kbit		full		2
# Тут живет VPN (который запускает пользователь)
2:D:F			-	32kbit		full		1	
# Для HTTP(S) с короткими пакетами, выделим приоритет больше (будет казаться,
# что странички быстрее открываются)
2:E:10			-	25kbit		full		1	flow=nfct-src
# Для RDP
2:E:12			-	15kbit		full		2	flow=nfct-src
# Для HTTP(S) с длинными пакетами, дольше будут грузится картики и большие страницы
2:E:13			-	15kbit		full		3	flow=nfct-src
# Для почтового трафика оперативность обычно менее важна
2:E:14			-	10kbit		full		4	flow=nfct-src
# Сюда поместим трафик специального сервиса (к примеру, трансляцию Webinar)
2:E:16			-	25kbit		full		2	flow=nfct-src
# Сюда упадет все, что мы не классифицировали явно
2:E:17			-	10kbit		full		5	default,flow=nfct-src

# Класс VIP пользовательского трафика (VIP-ов у нас обычно не много), им приоритет выше
2:D:18			-	60kbit		full		1
# Для HTTP(S) с короткими пакетами, выделим приоритет больше (будет казаться,
# что странички быстрее открываются)
2:18:19			-	20kbit		full		1
# Для HTTP(S) с длинными пакетами, дольше будут грузится картики и большие страницы
2:18:1A			-	10kbit		full		3
# Для почтового трафика оперативность обычно менее важна
2:18:1B			-	10kbit		full		4
# Сюда поместим трафик VIP специального сервиса
2:18:1C			-	20kbit		full		2	

# Класс наказанных пользователей
2:D:1D			-	60kbit		full		3
# Для HTTP(S) с короткими пакетами, выделим приоритет больше (будет казаться,
# что странички быстрее открываются)
2:1D:1E			-	20kbit		full		1	
# Для HTTP(S) с длинными пакетами, дольше будут грузится картики и большие страницы
2:1D:1F			-	10kbit		full		3
# Для почтового трафика оперативность обычно менее важна
2:1D:20			-	10kbit		full		4	
# Сюда поместим трафик специального сервиса, пускай мучаются
2:1D:21			-	20kbit		full		2	

tcclasses.3

#
# Shorewall -- /etc/shorewall/tcclasses.3
#
# For information about entries in this file, type "man shorewall-tcclasses"
#
# See http://shorewall.net/traffic_shaping.htm for additional information.
#
###############################################################################
#INTERFACE:CLASS	MARK	RATE:		CEIL	PRIORITY	OPTIONS
#				DMAX:UMAX
# Выделим для ACK пакетов широкую полосу. Минимальная предполагает, что есть
# только TCP трафик с максимальным MTU (меньше всего пакетов ACK), и для
# плохово варианта, берем что у нас все пакеты в четверь от MTU (пакетов ACK больше),
# еще выделим поток пакетов до одного получателя
3:1:4			-	full*64/1500	full*64*4/1500	1	tcp-ack
# Для SSH у нас два класса, первый, для коротких пакетов (в основном команды)
3:1:5			-	32kbit		128kbit		2	
# Второй для длинных пакетов (для передачи файлов к примеру)
3:1:6			-	32kbit		full*9/10	5	flow=dst
# Отдельная полоса для DNS и ICMP,
3:1:7			-	32kbit		128kbit		3
# позволит уменьшить задержки на запросах DNS
3:7:8			-	16kbit		full		1	
# и сделает PING интереснее
3:7:9			-	16kbit		full		1	
# Тут выделяем отдельную полосу для VoIP трафика
3:1:A			-	180kbit		180kbit	1
# Это для чистого SIP (один канал u(a)law), используем еще и маркировку пакетов от nf_conntrack_sip
3:A:B			1	90kbit		full		1
# Это для SIP в VPN тунеле (межофисный трафик)
3:A:C			-	90kbit		full		1
# Выделяем пользовательский трафик
3:1:D			-	252kbit		full		4

# Класс обычного пользовательского трафика
3:D:E			-	100kbit		full		2
# Тут живет VPN (который запускает пользователь)
3:D:F			-	32kbit		full		1	
# Для HTTP(S) с короткими пакетами, выделим приоритет больше (будет казаться,
# что странички быстрее открываются)
3:E:10			-	25kbit		full		1	flow=dst
# Для RDP
3:E:12			-	15kbit		full		2	flow=dst
# Для HTTP(S) с длинными пакетами, дольше будут грузится картики и большие страницы
3:E:13			-	15kbit		full		3	flow=dst
# Для почтового трафика оперативность обычно менее важна
3:E:14			-	10kbit		full		4	flow=dst
# Сюда поместим трафик специального сервиса (к примеру, трансляцию Webinar)
3:E:16			-	25kbit		full		2	flow=dst
# Сюда упадет все, что мы не классифицировали явно
3:E:17			-	10kbit		full		5	default,flow=dst

tcclasses.4

#
# Shorewall -- /etc/shorewall/tcclasses.4
#
# For information about entries in this file, type "man shorewall-tcclasses"
#
# See http://shorewall.net/traffic_shaping.htm for additional information.
#
###############################################################################
#INTERFACE:CLASS	MARK	RATE:		CEIL	PRIORITY	OPTIONS
#				DMAX:UMAX
# Выделим для ACK пакетов широкую полосу. Минимальная предполагает, что есть
# только TCP трафик с максимальным MTU (меньше всего пакетов ACK), и для
# плохово варианта, берем что у нас все пакеты в четверь от MTU (пакетов ACK больше),
# еще выделим поток пакетов до одного получателя
4:1:4			-	full*64/1500	full*64*4/1500	1	tcp-ack
# Для SSH
4:1:6			-	32kbit		full*9/10	5	flow=nfct-src
# Отдельная полоса для DNS и ICMP,
4:1:7			-	32kbit		128kbit		3
# позволит уменьшить задержки на запросах DNS
4:7:8			-	16kbit		full		1	
# и сделает PING интереснее
4:7:9			-	16kbit		full		1	
# Тут выделяем отдельную полосу для VoIP трафика
4:1:A			-	180kbit		180kbit	1
# Это для чистого SIP (один канал u(a)law), используем еще и маркировку пакетов от nf_conntrack_sip
4:A:B			1	90kbit		full		1
# Это для SIP в VPN тунеле (межофисный трафик)
4:A:C			-	90kbit		full		1
# Выделяем пользовательский трафик
4:1:D			-	252kbit		full		4

# Класс обычного пользовательского трафика, другого здесь нет.
4:D:E			-	100kbit		full		2
# Тут живет VPN (который запускает пользователь)
4:D:F			-	32kbit		full		1	
# Для RDP
4:E:12			-	15kbit		full		2	flow=nfct-src
# Для HTTP(S)
4:E:13			-	25kbit		full		3	flow=nfct-src
# Для почтового трафика оперативность обычно менее важна
4:E:14			-	15kbit		full		4	flow=nfct-src
# Сюда поместим трафик специального сервиса (к примеру, трансляцию Webinar)
4:E:16			-	25kbit		full		2	flow=nfct-src
# Сюда упадет все, что мы не классифицировали явно
4:E:17			-	10kbit		full		5	default,flow=nfct-src

tcclasses.5

#
# Shorewall -- /etc/shorewall/tcclasses.5
#
# For information about entries in this file, type "man shorewall-tcclasses"
#
# See http://shorewall.net/traffic_shaping.htm for additional information.
#
###############################################################################
#INTERFACE:CLASS	MARK	RATE:		CEIL	PRIORITY	OPTIONS
#				DMAX:UMAX
# Выделим для ACK пакетов широкую полосу. Минимальная предполагает, что есть
# только TCP трафик с максимальным MTU (меньше всего пакетов ACK), и для
# плохово варианта, берем что у нас все пакеты в четверь от MTU (пакетов ACK больше),
# еще выделим поток пакетов до одного получателя
5:1:4			-	full*64/1500	full*64*4/1500	1	tcp-ack
# Для SSH у нас два класса, первый, для коротких пакетов (в основном команды)
5:1:5			-	32kbit		128kbit		2	
# Второй для длинных пакетов (для передачи файлов к примеру)
5:1:6			-	32kbit		full*9/10	5	flow=dst
# Отдельная полоса для DNS и ICMP,
5:1:7			-	32kbit		128kbit		3
# позволит уменьшить задержки на запросах DNS
5:7:8			-	16kbit		full		1	
# и сделает PING интереснее
5:7:9			-	16kbit		full		1	
# Тут выделяем отдельную полосу для VoIP трафика
5:1:A			-	180kbit		180kbit	1
# Это для чистого SIP (один канал u(a)law), используем еще и маркировку пакетов от nf_conntrack_sip
5:A:B			1	90kbit		full		1
# Это для SIP в VPN тунеле (межофисный трафик)
5:A:C			-	90kbit		full		1
# Выделяем пользовательский трафик
5:1:D			-	252kbit		full		4

# Класс обычного пользовательского трафика
5:D:E			-	100kbit		full		2
# Тут живет VPN (который запускает пользователь)
5:D:F			-	32kbit		full		1	
# Для HTTP(S) с короткими пакетами, выделим приоритет больше (будет казаться,
# что странички быстрее открываются)
5:E:10			-	25kbit		full		1	flow=dst
# Для RDP
5:E:12			-	15kbit		full		2	flow=dst
# Для HTTP(S) с длинными пакетами, дольше будут грузится картики и большие страницы
5:E:13			-	15kbit		full		3	flow=dst
# Для почтового трафика оперативность обычно менее важна
5:E:14			-	10kbit		full		4	flow=dst
# Сюда поместим трафик специального сервиса (к примеру, трансляцию Webinar)
5:E:16			-	25kbit		full		2	flow=dst
# Сюда упадет все, что мы не классифицировали явно
5:E:17			-	10kbit		full		5	default,flow=dst

tcclasses.6

#
# Shorewall -- /etc/shorewall/tcclasses.6
#
# For information about entries in this file, type "man shorewall-tcclasses"
#
# See http://shorewall.net/traffic_shaping.htm for additional information.
#
###############################################################################
#INTERFACE:CLASS	MARK	RATE:		CEIL	PRIORITY	OPTIONS
#				DMAX:UMAX
# Выделим для ACK пакетов широкую полосу. Минимальная предполагает, что есть
# только TCP трафик с максимальным MTU (меньше всего пакетов ACK), и для
# плохово варианта, берем что у нас все пакеты в четверь от MTU (пакетов ACK больше),
# еще выделим поток пакетов до одного получателя
6:1:4			-	full*64/1500	full*64*4/1500	1	tcp-ack
# Для SSH
6:1:6			-	32kbit		full*9/10	5	flow=nfct-src
# Отдельная полоса для DNS и ICMP,
6:1:7			-	32kbit		128kbit		3
# позволит уменьшить задержки на запросах DNS
6:7:8			-	16kbit		full		1	
# и сделает PING интереснее
6:7:9			-	16kbit		full		1	
# Тут выделяем отдельную полосу для VoIP трафика
6:1:A			-	180kbit		180kbit	1
# Это для чистого SIP (один канал u(a)law), используем еще и маркировку пакетов от nf_conntrack_sip
6:A:B			1	90kbit		full		1
# Это для SIP в VPN тунеле (межофисный трафик)
6:A:C			-	90kbit		full		1
# Выделяем пользовательский трафик
6:1:D			-	252kbit		full		4

# Класс обычного пользовательского трафика, другого здесь нет.
6:D:E			-	100kbit		full		2
# Тут живет VPN (который запускает пользователь)
6:D:F			-	32kbit		full		1	
# Для RDP
6:E:12			-	15kbit		full		2	flow=nfct-src
# Для HTTP(S)
6:E:13			-	25kbit		full		3	flow=nfct-src
# Для почтового трафика оперативность обычно менее важна
6:E:14			-	15kbit		full		4	flow=nfct-src
# Сюда поместим трафик специального сервиса (к примеру, трансляцию Webinar)
6:E:16			-	25kbit		full		2	flow=nfct-src
# Сюда упадет все, что мы не классифицировали явно
6:E:17			-	10kbit		full		5	default,flow=nfct-src

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

Еще небольшая особенность, внешний интерфейс (как физический, так и IFB), ничего не знает о структуре внутренней сети (если используется NAT), поэтому часть детальной классификации отсутствует.

Теперь будем трафик классифицировать (для классов с ACK и MARK, описывать мы ничего не будем, соответствующий трафик сам туда упадет) и фильтровать.

Запасемся подсказками:

Программный интернет шлюз для уже не маленькой компании (Shorewall, QoS во всю ширь). Часть 3 - 2

mangle

#
# Shorewall -- /etc/shorewall/mangle
#
# For information about entries in this file, type "man shorewall-mangle"
#
# See http://shorewall.net/traffic_shaping.htm for additional information.
# For usage in selecting among multiple ISPs, see
# http://shorewall.net/MultiISP.html
#
# See http://shorewall.net/PacketMarking.html for a detailed description of
# the Netfilter/Shorewall packet marking mechanism.
#
####################################################################################################################################################
#ACTION		SOURCE		DEST		PROTO	DEST	SOURCE	USER	TEST	LENGTH	TOS	CONNBYTES	HELPER	PROBABILITY	DSCP
#							PORT(S)	PORT(S)
# Важно, последнее совпадение и будет означать конечную классификацию!
# Восстановим метку пакета из метки соединения (если она сейчас 0)
RESTORE  0.0.0.0/0      0.0.0.0/0       all        -             -        -         0
# Прекращаем дальнейшую обработку, если метка уже стоит
CONTINUE 0.0.0.0/0      0.0.0.0/0       all        -             -        -         !0
# Установим метку для всех SIP пакетов, включая RTP
MARK(1)        0.0.0.0/0      0.0.0.0/0       all        -             -        -         -         -              -       - sip
# Если SIP трафик идет до нашей внутренней сети (к примеру в другой филиал), логическим И соеденить метку пакета и нашего тунеля
MARK(|0x40000)	172.16.0.0/12 172.16.0.0/12      all        -             -        -         -         -              -       - sip
MARK(|0x40000)	172.16.0.0/12 172.16.0.0/12     udp        4569
SAVE     0.0.0.0/0      0.0.0.0/0       all        -             -        -         !0

INCLUDE mangle.1
INCLUDE mangle.3
INCLUDE mangle.5

mangle.1

#
# Shorewall -- /etc/shorewall/mangle.1
#
# For information about entries in this file, type "man shorewall-mangle"
#
# See http://shorewall.net/traffic_shaping.htm for additional information.
# For usage in selecting among multiple ISPs, see
# http://shorewall.net/MultiISP.html
#
# See http://shorewall.net/PacketMarking.html for a detailed description of
# the Netfilter/Shorewall packet marking mechanism.
#
####################################################################################################################################################
#ACTION		SOURCE		DEST		PROTO	DEST	SOURCE	USER	TEST	LENGTH	TOS	CONNBYTES	HELPER	PROBABILITY	DSCP
#							PORT(S)	PORT(S)
# Важно, последнее совпадение и будет означать конечную классификацию!

# Класс обычного пользовательского трафика
# Для HTTP(S) с короткими пакетами, выделим приоритет больше (будет казаться,
# что странички быстрее открываются), тут все, что от 0 до 256kb
CLASSIFY(1:10)	-	+ip_normal	tcp	-	80,443	-	-	-	-		0:262144
# Для HTTP(S) с длинными пакетами, дольше будут грузится картики и большие страницы,
# тут все, что от 256kb
CLASSIFY(1:13)	-	+ip_normal	tcp	-	80,443	-	-	-	-		262145:
# Для почтового трафика оперативность обычно менее важна
CLASSIFY(1:14)	-	+ip_normal	tcp	-	25,110,143,465,587,993,995,2525,4190
# Сюда поместим трафик специального сервиса (к примеру, трансляцию Webinar, с порта 32765)
CLASSIFY(1:16)	-	+ip_normal_spec	tcp	-	32765

# Класс VIP пользовательского трафика (VIP-ов у нас обычно не много), им приоритет выше
# Для HTTP(S) с короткими пакетами, выделим приоритет больше (будет казаться,
# что странички быстрее открываются)
CLASSIFY(1:19)	-	+ip_vip	tcp	-	80,443	-	-	-	-		0:262144
# Для HTTP(S) с длинными пакетами, дольше будут грузится картики и большие страницы
CLASSIFY(1:1A)	-	+ip_vip	tcp	-	80,443	-	-	-	-		262145:
# Для почтового трафика оперативность обычно менее важна
CLASSIFY(1:1B)	-	+ip_vip	tcp	-	25,110,143,465,587,993,995,2525,4190
# Сюда поместим трафик VIP специального сервиса
CLASSIFY(1:1C)	-	+ip_vip_spec	tcp	-	32765

# Класс наказанных пользователей
# Для HTTP(S) с короткими пакетами, выделим приоритет больше (будет казаться,
# что странички быстрее открываются)
CLASSIFY(1:1E)	-	+ip_slow	tcp	-	80,443	-	-	-	-		0:262144
# Для HTTP(S) с длинными пакетами, дольше будут грузится картики и большие страницы
CLASSIFY(1:1F)	-	+ip_slow	tcp	-	80,443	-	-	-	-		262145:
# Для почтового трафика оперативность обычно менее важна
CLASSIFY(1:20)	-	+ip_slow	tcp	-	25,110,143,465,587,993,995,2525,4190
# Сюда поместим трафик специального сервиса, пускай мучаются
CLASSIFY(1:21)	-	+ip_slow_spec	tcp	-	32765

# Тут живет VPN (который запускает пользователь)
CLASSIFY(1:F)	-	-	udp	-	1194

# Это для IAX2
CLASSIFY(1:B)	-	-	udp	-	4569

# Это для SIP в VPN тунеле (межофисный трафик)
CLASSIFY(1:C)	-	-	udp	-	40032

# RDP
CLASSIFY(1:12)	-	-	tcp	-	3389
CLASSIFY(1:12)	-	-	udp	-	3389

# позволит уменьшить задержки на запросах DNS
CLASSIFY(1:8)	-	-	udp	-	53
CLASSIFY(1:8)	-	-	tcp	-	53
# и сделает PING интереснее
CLASSIFY(1:9)	-	-	icmp	echo-request,echo-reply

# Для SSH у нас два класса, первый, для коротких пакетов (в основном команды)
CLASSIFY(1:5)	-	-	tcp	-	22	-	-	0:512
# Второй для длинных пакетов (для передачи файлов к примеру)
CLASSIFY(1:6)	-	-	tcp	-	22	-	-	513:

CLASSIFY(1:3)	$NET_GRN	$NET_GRN

mangle.3

#
# Shorewall -- /etc/shorewall/mangle.3
#
# For information about entries in this file, type "man shorewall-mangle"
#
# See http://shorewall.net/traffic_shaping.htm for additional information.
# For usage in selecting among multiple ISPs, see
# http://shorewall.net/MultiISP.html
#
# See http://shorewall.net/PacketMarking.html for a detailed description of
# the Netfilter/Shorewall packet marking mechanism.
#
####################################################################################################################################################
#ACTION		SOURCE		DEST		PROTO	DEST	SOURCE	USER	TEST	LENGTH	TOS	CONNBYTES	HELPER	PROBABILITY	DSCP
#							PORT(S)	PORT(S)
# Важно, последнее совпадение и будет означать конечную классификацию!

# Класс обычного пользовательского трафика
# Для HTTP(S) с короткими пакетами, выделим приоритет больше (будет казаться,
# что странички быстрее открываются), тут все, что от 0 до 256kb
CLASSIFY(3:10)	-	-	tcp	80,443	-	-	-	-	-	0:262144
# Для HTTP(S) с длинными пакетами, дольше будут грузится картики и большие страницы,
# тут все, что от 256kb
CLASSIFY(3:13)	-	-	tcp	80,443	-	-	-	-	-	262145:
# Для почтового трафика оперативность обычно менее важна
CLASSIFY(3:14)	-	-	tcp	25,110,143,465,587,993,995,2525,4190
# Сюда поместим трафик специального сервиса (к примеру, трансляцию Webinar, с порта 32765)
CLASSIFY(3:16)	-	-	tcp	32765

# Тут живет VPN (который запускает пользователь)
CLASSIFY(3:F)	-	-	udp	1194

# Это для IAX2
CLASSIFY(3:B)	-	-	udp	4569

# Это для SIP в VPN тунеле (межофисный трафик)
CLASSIFY(3:C)	-	-	udp	40032

# RDP
CLASSIFY(3:12)	-	-	tcp	3389
CLASSIFY(3:12)	-	-	udp	3389

# позволит уменьшить задержки на запросах DNS
CLASSIFY(3:8)	-	-	udp	53
CLASSIFY(3:8)	-	-	tcp	53
# и сделает PING интереснее
CLASSIFY(3:9)	-	-	icmp	echo-request,echo-reply

# Для SSH у нас два класса, первый, для коротких пакетов (в основном команды)
CLASSIFY(3:5)	-	-	tcp	22	-	-	-	0:512
# Второй для длинных пакетов (для передачи файлов к примеру)
CLASSIFY(3:6)	-	-	tcp	22	-	-	-	513:

mangle.5

#
# Shorewall -- /etc/shorewall/mangle.5
#
# For information about entries in this file, type "man shorewall-mangle"
#
# See http://shorewall.net/traffic_shaping.htm for additional information.
# For usage in selecting among multiple ISPs, see
# http://shorewall.net/MultiISP.html
#
# See http://shorewall.net/PacketMarking.html for a detailed description of
# the Netfilter/Shorewall packet marking mechanism.
#
####################################################################################################################################################
#ACTION		SOURCE		DEST		PROTO	DEST	SOURCE	USER	TEST	LENGTH	TOS	CONNBYTES	HELPER	PROBABILITY	DSCP
#							PORT(S)	PORT(S)
# Важно, последнее совпадение и будет означать конечную классификацию!

# Класс обычного пользовательского трафика
# Для HTTP(S) с короткими пакетами, выделим приоритет больше (будет казаться,
# что странички быстрее открываются), тут все, что от 0 до 256kb
CLASSIFY(5:10)	-	-	tcp	80,443	-	-	-	-	-	0:262144
# Для HTTP(S) с длинными пакетами, дольше будут грузится картики и большие страницы,
# тут все, что от 256kb
CLASSIFY(5:13)	-	-	tcp	80,443	-	-	-	-	-	262145:
# Для почтового трафика оперативность обычно менее важна
CLASSIFY(5:14)	-	-	tcp	25,110,143,465,587,993,995,2525,4190
# Сюда поместим трафик специального сервиса (к примеру, трансляцию Webinar, с порта 32765)
CLASSIFY(5:16)	-	-	tcp	32765

# Тут живет VPN (который запускает пользователь)
CLASSIFY(5:F)	-	-	udp	1194

# Это для IAX2
CLASSIFY(5:B)	-	-	udp	4569

# Это для SIP в VPN тунеле (межофисный трафик)
CLASSIFY(5:C)	-	-	udp	40032

# RDP
CLASSIFY(5:12)	-	-	tcp	3389
CLASSIFY(5:12)	-	-	udp	3389

# позволит уменьшить задержки на запросах DNS
CLASSIFY(5:8)	-	-	udp	53
CLASSIFY(5:8)	-	-	tcp	53
# и сделает PING интереснее
CLASSIFY(5:9)	-	-	icmp	echo-request,echo-reply

# Для SSH у нас два класса, первый, для коротких пакетов (в основном команды)
CLASSIFY(5:5)	-	-	tcp	22	-	-	-	0:512
# Второй для длинных пакетов (для передачи файлов к примеру)
CLASSIFY(5:6)	-	-	tcp	22	-	-	-	513:

tcfilters

#
# Shorewall -- /etc/shorewall/tcfilters
#
# For information about entries in this file, type "man shorewall-tcfilters"
#
# See http://shorewall.net/traffic_shaping.htm for additional information.
#
########################################################################################################
#INTERFACE:	SOURCE		DEST		PROTO	DEST	SOURCE	TOS		LENGTH	PRIORITY
#CLASS							PORT(S)	PORT(S)
# Важно, первое совпадение и будет означать конечную классификацию!
INCLUDE tcfilters.2
INCLUDE tcfilters.4
INCLUDE tcfilters.6

tcfilters.2

#
# Shorewall -- /etc/shorewall/tcfilters.2
#
# For information about entries in this file, type "man shorewall-tcfilters"
#
# See http://shorewall.net/traffic_shaping.htm for additional information.
#
########################################################################################################
#INTERFACE:	SOURCE		DEST		PROTO	DEST	SOURCE	TOS		LENGTH	PRIORITY
#CLASS							PORT(S)	PORT(S)
# Важно, первое совпадение и будет означать конечную классификацию!
2:3	$NET_GRN	$NET_GRN
# Для SSH
2:6	-	-	tcp	22
# позволит уменьшить задержки на запросах DNS
2:8	-	-	udp	53
2:8	-	-	tcp	53
# и сделает PING интереснее
2:9	-	-	icmp	echo-request,echo-reply
# RDP
2:12	-	-	tcp	3389
2:12	-	-	udp	3389
# Это для IAX2
2:B	-	-	udp	4569
# Это для SIP в VPN тунеле (межофисный трафик)
2:C	-	-	udp	40032
# Тут живет VPN (который запускает пользователь)
2:F	-	-	udp	1194
# Класс наказанных пользователей
# Для HTTP(S)
2:1F	$IP_SLOW	0.0.0.0/0	tcp	80,443
# Для почтового трафика оперативность обычно менее важна
2:20	$IP_SLOW	-	tcp	25,110,143,465,587,993,995,2525,4190
# Сюда поместим трафик специального сервиса, пускай мучаются
2:21	$IP_SLOW_SPEC	-	tcp	32765
# Класс VIP пользовательского трафика (VIP-ов у нас обычно не много), им приоритет выше
# Для HTTP(S)
2:1A	$IP_VIP	-	tcp	80,443
# Для почтового трафика оперативность обычно менее важна
2:1B	$IP_VIP	-	tcp	25,110,143,465,587,993,995,2525,4190
# Сюда поместим трафик VIP специального сервиса
2:1C	$IP_VIP_SPEC	-	tcp	32765
# Класс обычного пользовательского трафика
# Для HTTP(S)
2:13	$IP_NORMAL	-	tcp	80,443
# Для почтового трафика оперативность обычно менее важна
2:14	$IP_NORMAL	-	tcp	25,110,143,465,587,993,995,2525,4190
# Сюда поместим трафик специального сервиса (к примеру, трансляцию Webinar, с порта 32765)
2:16	$IP_NORMAL_SPEC	-	tcp	32765

tcfilters.4

#
# Shorewall -- /etc/shorewall/tcfilters.4
#
# For information about entries in this file, type "man shorewall-tcfilters"
#
# See http://shorewall.net/traffic_shaping.htm for additional information.
#
########################################################################################################
#INTERFACE:	SOURCE		DEST		PROTO	DEST	SOURCE	TOS		LENGTH	PRIORITY
#CLASS							PORT(S)	PORT(S)
# Важно, первое совпадение и будет означать конечную классификацию!

# Так как в tcfilters работа с длинной пакета упрощенная, то и классификацию по длинне мы не сделаем
4:6	-	-	tcp	-	22

# позволит уменьшить задержки на запросах DNS
4:8	-	-	udp	-	53
4:8	-	-	tcp	-	53
# и сделает PING интереснее
4:9	-	-	icmp	echo-request,echo-reply

# RDP
4:12	-	-	tcp	-	3389
4:12	-	-	udp	-	3389

# Это для IAX2
4:B	-	-	udp	-	4569
# Это для SIP в VPN тунеле (межофисный трафик)
4:C	-	-	udp	-	40032

# Тут живет VPN (который запускает пользователь)
4:F	-	-	udp	-	1194

# Класс обычного пользовательского трафика, причем без суб-классов, так как это внешний интерфейс,
# о внутренней сети он ничего не знает. Для HTTP(S)
4:13	-	-	tcp	-	80,443
# Для почтового трафика оперативность обычно менее важна
4:14	-	-	tcp	-	25,110,143,465,587,993,995,2525,4190
# Сюда поместим трафик специального сервиса (к примеру, трансляцию Webinar, с порта 32765)
4:16	-	-	tcp	-	32765

tcfilters.6

#
# Shorewall -- /etc/shorewall/tcfilters.6
#
# For information about entries in this file, type "man shorewall-tcfilters"
#
# See http://shorewall.net/traffic_shaping.htm for additional information.
#
########################################################################################################
#INTERFACE:	SOURCE		DEST		PROTO	DEST	SOURCE	TOS		LENGTH	PRIORITY
#CLASS							PORT(S)	PORT(S)
# Важно, первое совпадение и будет означать конечную классификацию!

# Так как в tcfilters работа с длинной пакета упрощенная, то и классификацию по длинне мы не сделаем
6:6	-	-	tcp	-	22

# позволит уменьшить задержки на запросах DNS
6:8	-	-	udp	-	53
6:8	-	-	tcp	-	53
# и сделает PING интереснее
6:9	-	-	icmp	echo-request,echo-reply

# RDP
6:12	-	-	tcp	-	3389
6:12	-	-	udp	-	3389

# Это для IAX2
6:B	-	-	udp	-	4569

# Это для SIP в VPN тунеле (межофисный трафик)
6:C	-	-	udp	-	40032

# Тут живет VPN (который запускает пользователь)
6:F	-	-	udp	-	1194

# Класс обычного пользовательского трафика, причем без суб-классов, так как это внешний интерфейс,
# о внутренней сети он ничего не знает. Для HTTP(S)
6:13	-	-	tcp	-	80,443
# Для почтового трафика оперативность обычно менее важна
6:14	-	-	tcp	-	25,110,143,465,587,993,995,2525,4190
# Сюда поместим трафик специального сервиса (к примеру, трансляцию Webinar, с порта 32765)
6:16	-	-	tcp	-	32765

После перезапуска у нас заработает шейпинг!

Странные костыли

Собственно с применением OSPF многое стало лучше, но осталось одно не маленькое Но! Связь по VoIP между филиалами. С VPN все хорохо, и шифрует, и множественные пути дает (спасибо OSPF), но как шейпить VoIP, да так, что-бы голоса не заикались, ведь о данных, по понятным причинам, мы ничего не знаем, классифицировать шифрованный трафик не можем (но вот ребята из Cisco сделали реализацию)? Если VoIP идет у нас через внешнюю сеть, то проблемы нет (кроме не полного шифрования у IAX2 и отсутствия удобной маршрутизации альтернативных каналов). Поэтому направим VoIP в отдельный туннель! И тут привет от OSPF, маршрут строится либо через оба туннеля (если у них одинаковый вес), или через тот, где вес ниже (это тот, который у нас без телефонии).

Тут нам на помощь придет вот такой костыль:

/usr/local/bin/ospf_alt_route.sh

#!/bin/bash
METRIC_BOOST=$1
IP_INTERVAL=$2
IPROUTE='/usr/sbin/ip'
function search_and_del() {
# $1 - TABLE
# $2 - DST
# $3 - VIA
# $4 - METRIC
	TABLE=$1
	declare -a DST=("${!2}")
	declare -a VIA=("${!3}")
	declare -a METRIC=("${!4}")
	# Ищем маршруты, которые отсутсвуют в маршрутизации OSPF
	IFS=$'n' 
	for line in $(${IPROUTE} route show table $TABLE);do
		IFS=$' t' read -r -a line_ <<< "$line"
		CONT=0
		for i in "${!DST[@]}"; do
			if [ "${line_[0]}" = "${DST[$i]}" ]; then
				if [ "${line_[6]}" -eq "${METRIC[$i]}" ] && [ "${line_[2]}" = "${VIA[$i]}" ];then
					CONT=1
					continue
				fi
			fi
		done
		[ "$CONT" -eq "0" ] && eval "${IPROUTE} route del $line table $TABLE"
	done
}
DST_=''
METRIC_=''
DEV_=''
DST=''
VIA_PRIM=''
VIA_SEC=''
METRIC_PRIM=''
METRCI_SEC=''
TABLE_PRIM=''
TABLE_SEC=''
COUNT=0
# Найдем таблицы маршрутизации
while IFS=$' t'  read -r -a line_; do
if [[ $(( $(echo ${line_[4]} | sed -e 's/[a-zA-Z]*//') % 2)) == 0 ]];then
	TABLE_PRIM=${line_[1]}
else
	TABLE_SEC=${line_[1]}
fi
done < <(grep tap /etc/shorewall/providers | grep loose)
# Если номеров таблиц нет, то пропускаем кофигурацию полностью
[ -z "$TABLE_PRIM" ] || [ -z "$TABLE_SEC" ] && exit 0
# Получаем маршруты от OSPF
while IFS=$' t'  read -r -a line_; do
	# Ищем записи маршрутов в полном формате (по позиции слова via)
	if [ "${line_[3]}" == "via" ]; then
		# Запомним парметры для слдующих строк в сокращенном формате
		DST_=${line_[1]}
		METRIC_=${line_[2]}
		# Займемся только активными маршрутами
		if [ "${line_[$(( ${#line_[@]} -2 ))]}" != "inactive," ]; then
			DEV_=$(echo ${line_[$(( ${#line_[@]} -2 ))]} | sed -e "s/,//")
			if [[ $(( $(echo $DEV_ | sed -e 's/[a-zA-Z]*//') % 2)) == 0 ]];then
				DST[$COUNT]=$(echo ${line_[1]} | sed -e "s//32//")
				VIA_PRIM[$COUNT]=$(echo ${line_[$(( ${#line_[@]} -3 ))]} | sed -e "s/,//")
				METRIC_PRIM[$COUNT]=$(echo ${line_[2]} | sed -e "s/[[0-p]*///" | sed -e "s/]//")
				# Важно использовать статические адреса для OpenVPN клиентов,и важно, чтобы они шли с фиксированным
				# шагом относительно основного соединения, в моем случае это 128 (так как сеть /25)
				IFS=$'.' read -r -a IP <<< ${VIA_PRIM[$COUNT]}
				VIA_SEC[$COUNT]="${IP[0]}.${IP[1]}.${IP[2]}.$(( ${IP[3]} + $IP_INTERVAL ))"
				METRIC_SEC[$COUNT]=$(( ${METRIC_PRIM[$COUNT]} + $METRIC_BOOST ))
				COUNT=$(($COUNT + 1 ))
			fi
		fi
	else
		# Аналогичная обработка для сокращенного формата, используем данные от предыдущего шага
		if [ "${line_[$(( ${#line_[@]} -2 ))]}" != "inactive," ]; then
			DEV_=$(echo ${line_[$(( ${#line_[@]} -2 ))]} | sed -e "s/,//")
			if [[ $(( $(echo $DEV_ | sed -e 's/[a-zA-Z]*//') % 2)) == 0 ]];then
				DST[$COUNT]=$(echo $DST_ | sed -e "s//32//")
				if [ "${line_[0]}" == "via" ]; then
					VIA_PRIM[$COUNT]=$(echo ${line_[1]} | sed -e "s/,//")
				else
					VIA_PRIM[$COUNT]=$(echo ${line_[2]} | sed -e "s/,//")
				fi
				METRIC_PRIM[$COUNT]=$(echo $METRIC_ | sed -e "s/[[0-p]*///" | sed -e "s/]//")
				IFS=$'.' read -r -a IP <<< ${VIA_PRIM[$COUNT]}
				VIA_SEC[$COUNT]="${IP[0]}.${IP[1]}.${IP[2]}.$(( ${IP[3]} + $IP_INTERVAL ))"
				METRIC_SEC[$COUNT]=$(( ${METRIC_PRIM[$COUNT]} + $METRIC_BOOST ))
				COUNT=$(($COUNT + 1 ))
			fi
		fi
	fi
done  < <(/usr/bin/vtysh -c 'show ip route ospf' | grep via | grep tap | grep -v -e 'directly connected')
# Найдем несуществующие маршруты для основного и дополнительного тунеля
search_and_del $TABLE_PRIM DST[@] VIA_PRIM[@] METRIC_PRIM[@]
search_and_del $TABLE_SEC DST[@] VIA_SEC[@] METRIC_SEC[@]
# Прибьем шлюз по умолчанию для обоих тунелей
${IPROUTE} route del default table $TABLE_PRIM >/dev/null 2>&1
${IPROUTE} route del default table $TABLE_SEC >/dev/null 2>&1
# Пройдемся по массиву маршрутов, и добавим их в таблицы основного и дополнительного тунеля
for i in "${!DST[@]}"; do
	[ -z ${DST[$i]} ] || [ -z ${VIA_PRIM[$i]} ] || [ -z ${METRIC_PRIM[$i]} ] && continue
	${IPROUTE} route replace ${DST[$i]} via ${VIA_PRIM[$i]} table $TABLE_PRIM metric ${METRIC_PRIM[$i]} >/dev/null 2>&1
	# Так как OSPF строит маршруты и до конечной точки тунеля, то в маршрутах для вторичного тунеля появляется маршрут "сам к себе"
	if [ "${DST[$i]}" = "${VIA_SEC[$i]}" ]; then
		# Поэтому мы "развернем" маршруты
		${IPROUTE} route replace ${VIA_PRIM[$i]} via ${DST[$i]} table $TABLE_SEC metric ${METRIC_SEC[$i]} >/dev/null 2>&1
	else
		${IPROUTE} route replace ${DST[$i]} via ${VIA_SEC[$i]} table $TABLE_SEC metric ${METRIC_SEC[$i]} >/dev/null 2>&1
	fi
	# Удалим маршруты из таблицы main
	${IPROUTE} route del ${DST[$i]} via ${VIA_PRIM[$i]} metric ${METRIC_PRIM[$i]} >/dev/null 2>&1
done

Этот скрипт копирует маршруты, анонсированные OSPF в отдельную таблицу маршрутизации, и создает дополнительные маршруты, через второй туннель, до тех-же сетей, что нам анонсировал OSPF. А Shorewall создает для нас правила маршрутизации и дополнительные таблицы. А что-бы трафик телефонии бежал в этот туннель, мы его помечаем специальной меткой.

В policy routing можно увидеть такое:

Routing Rules

0:      from all lookup local
999:    from all lookup main
10000:  from all fwmark 0x10000/0xff0000 lookup pr1
10001:  from all fwmark 0x20000/0xff0000 lookup pr2
10002:  from all fwmark 0x40000/0xff0000 lookup tap1
10003:  from all fwmark 0x30000/0xff0000 lookup tap0
19001:  from all lookup tap0
20000:  from 192.168.10.37 lookup pr1
20000:  from 192.168.10.36 lookup pr2
32765:  from all lookup balance
32766:  from all lookup main
32767:  from all lookup default

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

Осталось только добавить этот скрипт в cron:

/etc/cron.d/ospf_alt_route

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 — 59)
# | .------------- hour (0 — 23)
# | | .---------- day of month (1 — 31)
# | | | .------- month (1 — 12) OR jan,feb,mar,apr…
# | | | | .---- day of week (0 — 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed

*/1 * * * * root /usr/local/bin/ospf_alt_route.sh 1 128

P.S.
Обновлены:

  • Скрипт для замены маршрутов
  • Задание cron
  • rtrules
  • Добавлен файл started

Автор: MagicGTS

Источник

Поделиться новостью

* - обязательные к заполнению поля