После очередных проблем с провайдером (почему то банк-клиент не подключался) я решил более плотно задуматься о ручной распределении нагрузки на 2 канала. Т.е. проблемы были такие что не требовалось всю компанию переводить полностью на резервный канал. Нужно было в резервный канал запустить трафик от 2-х -3-х пользователей (в идеале трафик адресованный на некоторые порты). Нашёл в Интернете статейку http://www.opennet.ru/base/net/debian_multilink.txt.html по распределению нагрузки. Но у меня немного другая схема и я слегка переписал скрипты, своими непрямыми руками
Итак что мы имеем:
- в качестве сервера используется комп с UbuntuServer с 3-я сетевыми карточками (в примере скрипта описано что куда подключено)
- сервер выполняет функции NAT, port-forwarding (RDP сервер под Win2003), proxy (squid), почтовый сервер (postfix, dovecot), GRE туннель - создал для нормального подключения по VPN из внешки к Win2003
- сейчас всё построено на простеньких скриптах, которые натят весть трафик, идущий наружу,
трафик приходящий на 80 порт, смотрящий в локальную сеть, отправляется на порт 3128 этой же машины, порт форвардинг 1723 на локальную машину
- маршрутизация в принципе глобально не менялась - я просто добавил пару маршрутов для VPN сетей.
Теперь мне хочется написать по образу и подобию статьи скрипты маршрутизации и iptables с учётом особенностей моей сети. Т.е. при желании или по команде из другого скрипта направлять трафик из локальной сети (полностью или частично) на через одного из провайдеров.
Кое что написал если можно скажите что тут не так? Может где то логические ошибки
Скрипт iptables
Spoiler
Код:
# Включаем форвардинг пакетов
echo 1 > /proc/sys/net/ipv4/ip_forward
#Очищаем все таблицы
iptables -F
iptables -t nat -F
iptables -t mangle -F
iptables -X
iptables -t nat -X
iptables -t mangle -X
IP_LOCAL="192.168.0.10" # адрес нашего маршрутизатора в локальной сети.
IP_INET1="193.5.7.96" # адрес нашего маршрутизатора в сети первого провайдера.
IP_INET2="79.2.0.46" # адрес нашего марщрутизатора в сети второго провайдера.
IF_LOCAL="eth0" # имя интерфейса на локальную сеть
IF_INET1="ppp0" # имя интерфейса на первого провайдера.
IF_INET2="eth2" # имя интерфейса на второго провайдера.
NET_LOCAL="192.168.0.0/24" # локальная сеть.
NET_INET1="193.5.7.0/24" # адрес сети в которой гейт нашего первого провайдера.
NET_INET2="79.2.0.44/30" # адрес сети в которой гейт нашего второго провайдера.
NET_SUB1="192.168.0.0/25" # подсеть пользователей на первого провайдера
NET_SUB2="192.168.0.128/25" # подсеть пользователей на второго провайдера
GW1="193.5.7.126" # гейт первого провайдера.
GW2="79.2.0.45" # гейт второго провайдера.
# Разрешаем трафик на loopback-интерфейсе
iptables -A INPUT -i lo -j ACCEPT
# Разрешаем доступ из внутренней сети наружу
iptables -A FORWARD -i eth0 -o ppp0 -j ACCEPT
iptables -A FORWARD -i eth0 -o eth2 -j ACCEPT
# Запрещаем доступ снаружи во внутреннюю сеть
iptables -A FORWARD -i ppp0 -o ppp0 -j REJECT
iptables -A FORWARD -i eth2 -o eth2 -j REJECT
#Запрещаем broadcast пакеты на eth1 (требование провайдера)
iptables -A OUTPUT -o eth1 --dst 255.255.255.255 -j DROP
iptables -A INPUT -i eth1 --src 255.255.255.255 -j DROP
#Все пакеты, которые попали в цепочку PREROUTING таблицы mangle обрабатываем по двум правилам:
#все пакеты, которые идут от $NET_SUB1 и не в $NET_LOCAL маркируем меткой 10
iptables -t mangle -A PREROUTING -s $NET_SUB1 ! -d $NET_LOCAL -j MARK --set-mark 10
# все пакеты, которые идут от $NET_SUB1 и не в $NET_LOCAL маркируем меткой 20
iptables -t mangle -A PREROUTING -s $NET_SUB2 ! -d $NET_LOCAL -j MARK --set-mark 20
# Заворачиваем http трафик на прокси-сервер
iptables -t nat -A PREROUTING -i eth0 ! -d $NET_LOCAL -p tcp -m multiport --dport 80,8080 -j DNAT --to $IP_LOCAL:3128
#все пакеты, которые попали в цепочку POSTROUTING таблицы nat обрабатываем по двум правилам:
iptables -t nat -A POSTROUTING -m mark --mark 10 -j MASQUERADE # натим все пакеты которые имеют метку 10
iptables -t nat -A POSTROUTING -m mark --mark 20 -j MASQUERADE # натим все пакеты которые имеют метку 20
exit 0
Подключение к первому провайдеру по PPPoE. Я получаю адрес 193.5.7.96 ну и в таблице маршрутизации появляется 193.5.7.126 - я так понимаю это шлюз для ppp подключения. Так ли это?
Стандартная таблица маршрутизации
Spoiler
Код:
~$ route -n
Таблица маршутизации ядра протокола IP
Destination Gateway Genmask Flags Metric Ref Use Iface
193.105.37.126 0.0.0.0 255.255.255.255 UH 0 0 0 ppp0
192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
0.0.0.0 0.0.0.0 0.0.0.0 U 0 0 0 ppp0
Также в примере скрипта написано, что нужно указать подсеть провайдера.... Я размахнулся на 193.5.7.0/24. Может стоило меньшую сеть указать?
Модифицированный скрипт маршрутизации
Spoiler
Код:
#!/bin/sh
IP_LOCAL="192.168.0.10" # адрес нашего маршрутизатора в локальной сети.
IP_INET1="193.5.7.96" # адрес нашего маршрутизатора в сети первого провайдера.
IP_INET2="79.2.0.46" # адрес нашего марщрутизатора в сети второго провайдера.
IF_LOCAL="eth0" # имя интерфейса на локальную сеть
IF_INET1="ppp0" # имя интерфейса на первого провайдера.
IF_INET2="eth2" # имя интерфейса на второго провайдера.
NET_LOCAL="192.168.0.0/24" # локальная сеть.
NET_INET1="193.5.7.0/24" # адрес сети в которой гейт нашего первого провайдера.
NET_INET2="79.2.0.44/30" # адрес сети в которой гейт нашего второго провайдера.
GW_INET1="193.5.7.126" # гейт первого провайдера.
GW_INET2="79.2.0.45" # гейт второго провайдера.
ip route flush table inet_don #обнуляем первую таблицу маршрутов
ip route flush table inet_enforta #обнуляем вторую таблицу маршрутов
ip route add $NET_INET1 dev $IF_INET1 src $IP_INET1 table inet_don #закидываем в первую таблицу инфу о сети первого провайдера
ip route add $NET_LOCAL dev $IF_LOCAL table inet_don #закидываем в первую таблицу инфу о том, что у нас существует локальная сеть
ip route add $NET_INET2 dev $IF_INET2 table inet_don #закидываем в первую таблицу инфу о том, что у нас существует еще одна сеть
ip route add 127.0.0.0/8 dev lo table inet_don #закидываем в первую таблицу инфу о существовании лупбека
ip route add default dev $IF_INET1 table inet_don #закидываем в первую таблицу дефолтный гейт на первого провайдера
ip route add $NET_INET2 dev $IF_INET2 src $IP_INET2 table inet_enforta #закидываем во вторую таблицу инфу о сети второго провайдера
ip route add $NET_LOCAL dev $IF_LOCAL table inet_enforta #закидываем во вторую таблицу инфу о том, что у нас существует локальная с
ip route add $NET_INET1 dev $IF_INET1 table inet_enforta #закидываем во вторую таблицу инфу о том, что у нас существует еще одна се
ip route add 127.0.0.0/8 dev lo table inet_enforta #закидываем во вторую таблицу инфу о существовании лупбека.
ip route add default via $GW_INET2 table inet_enforta #закидываем во вторую таблицу дефолтный гейт на второго провайдера
ip route add $NET_INET1 dev $IF_INET1 src $IP_INET1 #заполняем основную таблицу адресов. сеть на первого провайдера
ip route add $NET_INET2 dev $IF_INET2 src $IP_INET2 #заполняем основную таблицу адресов. сеть на второго провайдера
ip route add default via $GW_INET1 #заполняем основную таблицу адресов. дефолтный гейт.
ip route add 192.168.2.0/24 dev $IF_LOCAL src 192.168.0.100 #заполняем основную таблицу адресов. VPN тунель
ip route add 192.168.3.0/24 dev $IF_LOCAL src 192.168.0.100 #заполняем основную таблицу адресов. Сеть Краснодара
ip route add 192.168.4.0/24 dev $IF_LOCAL src 192.168.0.100 #заполняем основную таблицу адресов. Сеть Ставраполя
ip rule delete table inet_don #удаляем наши таблицы, если они присутсвуют в текущей конфигурации (вдруг мы просто перезапускаем скр
ip rule delete table inet_enforta #аналогично для второй.
ip rule delete table inet_don #и делаем это два раза, так как у нас два правила на каждую таблицу.
ip rule delete table inet_enforta #аналогично для второй.
#а вот это важно для понимая! если понять что происходит в следующих строчках - то можно настраивать любые правила маршрутизации.
ip rule add from $IP_INET1 table inet_don #все пакеты от ip адреса первого провайдера маршрутизировать по таблице inet_don
ip rule add from $IP_INET2 table inet_enforta #все пакеты от ip адреса второго провайдера маршрутизировать по таблице inet_enforta
ip rule add fwmark 10 table inet_don #все пакеты, которые имеют метку 10 маршрутизировать по таблице inet_don
ip rule add fwmark 20 table inet_enforta #все пакеты, которые имеют метку 20 маршрутизировать по таблице inet_enforta
ip route flush cache #сбросить кеш маршрутизации
здесь интересно для чего удаляются маршруты типа ip rule delete table inet_don ? Стоит ли сбрасывть таблицу маршрутизации main? (я как то сбросил и пришлось локально перезапускать networking)
файл /etc/iproute2/rt_tables
Spoiler
Код:
#
# reserved values
#
255<--->local
254<--->main
253<--->default
0<----->unspec
#
# local
#
#1<---->inr.ruhep
10 inet_don
20 inet_enforta
Теперь собственно проблема: всё вписал в исполняющие файлы и запустил! Компы из подсети 192,168,0,0/25 работают так же а компы из другой сети 192,168,0,128/25 не работают. При трассировке с такого компа есть только 2 хопа - это адрес моего линуксового маршрутизатора и адрес шлюза провайдера - дальше "звёздочки"!. Пробовал снифить трафик tcp-dumpом - там появляются какие то ошибки. Народ в Интернете говорит менять сетевую. Пока поменять не получилось (времени не было), но факт в том, что при стандартной замене дефолтного шлюза на шлюз резервного провайдера - интернет у всей сети работает нормально.
В общем жду от гуру предложений и наводящих вопросов. Очень хочется сделать всё работоспособным а то от простого чтения мануалов уже мозг кипит.