Требуется подключить локальную сеть к двум провайдерам.
В данный момент я сделал тестовый роутер на Ubunte, вот его конфиг
Что можно сказать по поводу такой реализации?
/etc/network/interfaces:
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
auto eth1
iface eth1 inet static
address 192.168.1.1
netmask 255.255.255.0
network 192.168.1.0
broadcast 192.168.1.255
# WAN1 network interface aliase
auto eth0
iface eth0 inet static
address aaa.aaa.aaa.100
netmask 255.255.255.128
network aaa.aaa.aaa.0
broadcast aaa.aaa.aaa.127
gateway aaa.aaa.aaa.1
# WAN1 network interface aliase
auto eth0:1
iface eth0:1 inet static
address aaa.aaa.aaa.101
netmask 255.255.255.128
network aaa.aaa.aaa.0
# WAN2 network interface aliase
auto eth2
iface eth2 inet static
address bbb.bbb.bbb.100
netmask 255.255.255.128
network bbb.bbb.bbb.0
broadcast bbb.bbb.bbb.127
gateway bbb.bbb.bbb.1
# WAN2 network interface aliase
auto eth2:1
iface eth2:1 inet static
address bbb.bbb.bbb.101
netmask 255.255.255.128
network bbb.bbb.bbb.0
-----------------------------------------------/etc/iproute2/rt_tables:
255 local
254 main
253 default
0 unspec
201 ISP1
202 ISP2
-----------------------------------------------/etc/rc.firewall/rc.customroute:
varnetwork=/etc/rc.firewall/varnetwork-fixed
. $varnetwork
## Выключаем Reverse Path Filtering для WAN-интерфейсов
if [ -n "$WANIF1" ]; then
echo 0 > /proc/sys/net/ipv4/conf/$WANIF1/rp_filter
echo "Disable 'Reverse Path Filtering' for interface WANIF1 ($WANIF1) - [OK]"
else
echo "Disable 'Reverse Path Filtering' for interface WANIF1 ($WANIF1) - [ERR]"
echo "WANIF1 ($WANIF1) is not defined"
fi
if [ -n "$WANIF2" ]; then
echo 0 > /proc/sys/net/ipv4/conf/$WANIF2/rp_filter
echo "Disable 'Reverse Path Filtering' for interface WANIF2 ($WANIF2) - [OK]"
else
echo "Disable 'Reverse Path Filtering' for interface WANIF2 ($WANIF2) - [ERR]"
echo "WANIF2 ($WANIF2) is not defined"
fi
## Добавление таблиц и маршрутов по умолчанию
$ip -statistics rule delete table $ROUTETABLE1 # Удаляем наши таблицы, если они присутсвуют в текущей конфигурации (вдруг мы просто перезапускаем скрипт?)
$ip -statistics rule delete table $ROUTETABLE2 # Аналогично для второй.
$ip -statistics rule delete table $ROUTETABLE1 # И делаем это два раза, так как у нас два правила на каждую таблицу.
$ip -statistics rule delete table $ROUTETABLE2 # Аналогично для второй.
#
$ip -statistics route flush table $ROUTETABLE1 # Обнуляем первую таблицу маршрутов
$ip -statistics rule add from $WANIP1 table $ROUTETABLE1 # Все пакеты от ip-адреса первого провайдера маршрутизировать по таблице ROUTETABLE1
$ip -statistics rule add fwmark $FWMARK1 table $ROUTETABLE1 # Все пакеты, которые имеют метку FWMARK1 маршрутизировать по таблице ROUTETABLE1
$ip -statistics route add default via $WANGW1 dev $WANIF1 table $ROUTETABLE1 #
$ip -statistics route flush cache # Очищаем кэш маршрутизации
#
$ip -statistics route flush table $ROUTETABLE2 # Обнуляем вторую таблицу маршрутов
$ip -statistics rule add from $WANIP2 table $ROUTETABLE2 # Все пакеты от ip-адреса второго провайдера маршрутизировать по таблице ROUTETABLE2
$ip -statistics rule add fwmark $FWMARK2 table $ROUTETABLE2 # Все пакеты, которые имеют метку FWMARK2 маршрутизировать по таблице ROUTETABLE2
$ip -statistics route add default via $WANGW2 dev $WANIF2 table $ROUTETABLE2 #
$ip -statistics route flush cache # Очищаем кэш маршрутизации
#$ip -statistics route add default via $WANGW1 # Назначаем шлюз по умолчанию (в данный момент указывается в \etc\network\interfaces)
exit 0
-----------------------------------------------/etc/rc.firewall/rc.firewall.regular:
varnetwork=/etc/rc.firewall/varnetwork-fixed
. $varnetwork
case "$1" in
"1" )
FWMARK2=$FWMARK1
;;
"2" )
FWMARK1=$FWMARK2
;;
* )
;;
esac
## Политика по умолчению (DENY). Explicitly accept desired INCOMING and OUTGOING connections
# Удаление всех существующих правил (Remove all existing rules belonging to this filter)
# Если не указана таблица ключом -t (--table), то очистка цепочек производится только в таблице filter
# (из Iptables Tutorial 1.1.19)
$iptables -v --flush -t filter
$iptables -v --flush -t nat
$iptables -v --flush -t mangle
$iptables -v --flush -t raw
# Удаление любых существующих пользовательских цепочек (Remove any existing user-defined chains)
$iptables -v --delete-chain -t filter
$iptables -v --delete-chain -t nat
$iptables -v --delete-chain -t mangle
$iptables -v --delete-chain -t raw
# Установка политик по умолчению (DROP) (Set the default policy of the filter to deny)
$iptables -v --policy INPUT DROP
$iptables -v --policy OUTPUT DROP
$iptables -v --policy FORWARD DROP
echo 1 > /proc/sys/net/ipv4/ip_forward
# Загрузка модулей
#$depmod -v -a
$modprobe -v ip_conntrack_ftp
$modprobe -v ip_nat_ftp
# Неограниченный трафик на обратной петле (Unlimited traffic on the loopback interface)
$iptables -v -t filter -A INPUT -i $LOOPBACKIF -p all -s $LOOPBACKNET -d $LOOPBACKNET -j ACCEPT
$iptables -v -t filter -A OUTPUT -o $LOOPBACKIF -p all -s $LOOPBACKNET -d $LOOPBACKNET -j ACCEPT
# Проброс WEB1EXTISP1 -> WEB1INT
# WEB1EXTISP2 -> WEB1INT
$iptables -v -t nat -A PREROUTING -i $WANIF1 -p tcp -d $WEB1EXTISP1 --dport 80 -j DNAT --to-destination $WEB1INT:80
$iptables -v -t filter -A FORWARD -i $WANIF1 -o $LANIF1 -p tcp -d $WEB1INT --dport 80 -j ACCEPT
$iptables -v -t filter -A FORWARD -i $LANIF1 -o $WANIF1 -p tcp -s $WEB1INT --sport 80 -j ACCEPT
$iptables -v -t nat -A POSTROUTING -o $WANIF1 -p tcp -s $WEB1INT -j SNAT --to-source $WEB1EXTISP1
$iptables -v -t nat -A PREROUTING -i $WANIF2 -p tcp -d $WEB1EXTISP2 --dport 80 -j DNAT --to-destination $WEB1INT:80
$iptables -v -t filter -A FORWARD -i $WANIF2 -o $LANIF1 -p tcp -d $WEB1INT --dport 80 -j ACCEPT
$iptables -v -t filter -A FORWARD -i $LANIF1 -o $WANIF2 -p tcp -s $WEB1INT --sport 80 -j ACCEPT
$iptables -v -t nat -A POSTROUTING -o $WANIF2 -p tcp -s $WEB1INT -j SNAT --to-source $WEB1EXTISP2
### Маркировки по-умолчанию ------------------------------------------------------------------------------------------- #
### На самом деле можно не маркировать одно из направлений, приняв его за напрвление по умолчанию
### Для этого направления в цепочке PREROUTING интерфейса LANIF1 отменяем маркировку и
### и указывает самым последним правило в POSTROUTING без указания -m mark --mark
### например, $iptables -v -t nat -A POSTROUTING -o $WANIFx -s $LANNET1 -j SNAT --to-source $WANIPx
### где WANIFx и WANIPx - интерфейс и ip-адрес через которые будет NAT-ится по умолчанию
$iptables -v -t mangle -A PREROUTING -p tcp -i $LANIF1 -s $TRUSTHOST1 -m mac --mac-source $TRUSTMAC6 -d ! $LANNET1 -m multiport --dport 21,5190 -j MARK --set-mark $FWMARK1
$iptables -v -t mangle -A PREROUTING -p tcp -i $LANIF1 -s $TRUSTHOST1 -m mac --mac-source $TRUSTMAC6 -d ! $LANNET1 -m multiport --dport 80,443,25,465,993,8010,8100 -j MARK --set-mark $FWMARK2
# Разрешение прохождения всего трафика (FORWARD) от $TRUSTHOST1
$iptables -v -t filter -A FORWARD -i $LANIF1 -o $WANIF1 -p all -s $TRUSTHOST1 -m mac --mac-source $TRUSTMAC6 -j ACCEPT
$iptables -v -t filter -A FORWARD -i $WANIF1 -o $LANIF1 -p all -d $TRUSTHOST1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
$iptables -v -t filter -A FORWARD -i $LANIF1 -o $WANIF2 -p all -s $TRUSTHOST1 -m mac --mac-source $TRUSTMAC6 -j ACCEPT
$iptables -v -t filter -A FORWARD -i $WANIF2 -o $LANIF1 -p all -d $TRUSTHOST1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# POSTROUTING
# NAT для пакетов имеющих метку FWMARK1
$iptables -v -t nat -A POSTROUTING -o $WANIF1 -s $LANNET1 -m mark --mark $FWMARK1 -j SNAT --to-source $WANIP1
# NAT для пакетов имеющих метку FWMARK2
$iptables -v -t nat -A POSTROUTING -o $WANIF2 -s $LANNET1 -m mark --mark $FWMARK2 -j SNAT --to-source $WANIP2
-----------------------------------------------
где WEB1INT веб-сервер внутри локальной сети (WEB1EXTISP1 и WEB1EXTISP2 его "внешнии" ip-адреса от разных провайдеров)
TRUSTHOST1 - клиенская рабочая станция, с разделеным между провайдерами трафикомВ файл /etc/rc.firewall/varnetwork-fixed вынесены все переменные
## Определение переменных. (При необходимости отредактируйте с учетом конфигурации вашей системы)
# Настройки для LAN1 интерфейса
LANIP1="192.168.1.1" # IP адрес внешнего интерфейса (LAN1)
LANIF1="eth1" # Внешний сетевой интерфейс (LAN1) подключение к интернету
LANNET1="192.168.1.0/24" # Диапазон реальных IP адресов (LAN1)
# Настройки для WAN1 интерфейса
WANIP1="aaa.aaa.aaa.100" # IP адрес внешнего интерфейса (WAN1)
WANIF1="eth0" # Внешний сетевой интерфейс (WAN1) подключение к интернету
WANNET1="aaa.aaa.aaa.0/25" # Диапазон реальных IP адресов (WAN1)
WANGW1="aaa.aaa.aaa.1" # Шлюз провайдера (WAN1)
# Настройки для WAN2 интерфейса
WANIP2="bbb.bbb.bbb.100" # IP адрес внешнего интерфейса (WAN2)
WANIF2="eth2" # Внешний сетевой интерфейс (WAN2) подключение к интернету
WANNET2="bbb.bbb.bbb.0/25" # Диапазон реальных IP адресов (WAN2)
WANGW2="bbb.bbb.bbb.1" # Шлюз провайдера (WAN2)
# Настройки для LOOPBACK интерфейса
LOOPBACKIP="127.0.0.1" # IP адрес обратной петли
LOOPBACKIF="lo" # Интерфейс обратной петли
LOOPBACKNET="127.0.0.0/8" # Зарезервированый диапазон адресов обратной петли
# Имена таблиц маршрутизации из файла /etc/iproute2/rt_tables
ROUTETABLE1="ISP1"
ROUTETABLE2="ISP2"
# Метки пакетов из файла /etc/rc.firewall/rc.firewall.regular
FWMARK1=10
FWMARK2=11
# Хосты внутри сети
WEB1EXTISP1="aaa.aaa.aaa.101" # Внешний IP адрес из сети WANNET1
WEB1EXTISP2="bbb.bbb.bbb.101" # Внешний IP адрес из сети WANNET2
WEB1INT="192.168.1.10" # Внутренний IP адрес из сети LANNET1
## Доверительные хосты и сети
TRUSTNET6="192.168.1.20/32" # Клиентский хост
TRUSTMAC6="xx:xx:xx:xx:xx:xx" # Клиентский хост MAC
-----------------------------------------------
При загрузки из файла /etc/rc.local запускается rc.customroute и rc.firewall.regularДумаю как организовать переключение в случаи недоступности одного из каналов
Пока есть вот такой скрипт, но какой-то он косолапый...
/etc/rc.firewall/testchannels:
TESTHOST1="всегда_работающий_отечественный_IP"
TESTHOST2="всегда_работающий_зарубежный_IP"
CPING="4"
RCFIREWALL=/etc/rc.firewall/rc.firewall.regular
varnetwork=/etc/rc.firewall/varnetwork-fixed
. $varnetwork
# Процедура проверки
ICMPTest () {
ping -I $WANIF1 -q -c $CPING $TESTHOST1 > /dev/null
WANIF1TESTHOST1="$?"
ping -I $WANIF1 -q -c $CPING $TESTHOST2 > /dev/null
WANIF1TESTHOST2="$?"
ping -I $WANIF2 -q -c $CPING $TESTHOST1 > /dev/null
WANIF2TESTHOST1="$?"
ping -I $WANIF2 -q -c $CPING $TESTHOST2 > /dev/null
WANIF2TESTHOST2="$?"
}
## Тест ICMP-обмена с тестовыми хостами
ICMPTest
## Действия по результатам тестов ICMP-обмена с тестовыми хостами
# 0000 - 0 # 0100 - 2 # 1000 - 2 # 1100 - 2
# 0001 - 1 # 0101 - 6 # 1001 - 6 # 1101 - 4
# 0010 - 1 # 0110 - 6 # 1010 - 6 # 1110 - 4
# 0011 - 1 # 0111 - 5 # 1011 - 5 # 1111 - 3
##
# 0 - доступно всё -> переключаем на штатный режим 0000
# 1 - полностью доступен первый канал -> переключаем на первый 0001, 0010, 0011
# 2 - полностью доступен второй канал -> переключаем на второй 0100, 1000, 1100
# 3 - полностью недоступны все каналы -> бездействие 1111
# 4 - полностью недоступен первый канал -> переключаем на второй 1101, 1110
# 5 - полностью недоступен второй канал -> переключаем на первый 0111, 1011
# 6 - частично доступны все каналы -> бездействие 0101, 0110, 1001, 1010
Handler () {
case "$1" in
"0" )
if [ -r $STATUSFILE ]; then
rm -f $STATUSFILE
if [ -x $MAIL ]; then
# Отправляем письмо
fi
# Запускаем RCFIREWALL "$1" ("0")
sh $RCFIREWALL
fi
;;
"1" | "5" )
if [ -r $STATUSFILE ]; then
read CURRENTSTATUS < $STATUSFILE
if $STATUSFILE -ne "$1"; then
echo "$1" > $STATUSFILE
if [ -x $MAIL ]; then
# Отправляем письмо
fi
# Запускаем RCFIREWALL "1"
sh $RCFIREWALL "1"
if
else
echo "$1" > $STATUSFILE
if [ -x $MAIL ]; then
# Отправляем письмо
fi
# Запускаем RCFIREWALL "1"
sh $RCFIREWALL "1"
fi
;;
"2" | "4" )
if [ -r $STATUSFILE ]; then
read CURRENTSTATUS < $STATUSFILE
if $STATUSFILE -ne "$1"; then
echo "$1" > $STATUSFILE
if [ -x $MAIL ]; then
# Отправляем письмо
fi
# Запускаем RCFIREWALL "2"
sh $RCFIREWALL "2"
if
else
echo "$1" > $STATUSFILE
if [ -x $MAIL ]; then
# Отправляем письмо
fi
# Запускаем RCFIREWALL "2"
sh $RCFIREWALL "2"
fi
;;
"3" )
if [ -r $STATUSFILE ]; then
read CURRENTSTATUS < $STATUSFILE
if $STATUSFILE -ne "$1"; then
echo "$1" > $STATUSFILE
if [ -x $MAIL ]; then
# Отправляем письмо
fi
else
echo "$1" > $STATUSFILE
if [ -x $MAIL ]; then
# Отправляем письмо
fi
fi
;;
* )
if [ -r $STATUSFILE ]; then
read CURRENTSTATUS < $STATUSFILE
if $STATUSFILE -ne "$1"; then
echo "$1" > $STATUSFILE
if [ -x $MAIL ]; then
# Отправляем письмо
fi
else
echo "$1" > $STATUSFILE
if [ -x $MAIL ]; then
# Отправляем письмо
fi
fi
;;
esac
}
# 0 - доступно всё -> переключаем на штатный режим 0000
if [ $WANIF1TESTHOST1 -eq 0 -a $WANIF1TESTHOST2 -eq 0 -a $WANIF2TESTHOST1 -eq 0 -a $WANIF2TESTHOST2 -eq 0 ]; then
Handler "0"
exit 0
fi
# 1 - полностью доступен первый канал -> переключаем на первый 0001, 0010, 0011
if [ $WANIF1TESTHOST1 -eq 0 -a $WANIF1TESTHOST2 -eq 0 -a $WANIF2TESTHOST1 -eq 0 -a $WANIF2TESTHOST2 -eq 1 ]; then
Handler "1"
exit 0
fi
if [ $WANIF1TESTHOST1 -eq 0 -a $WANIF1TESTHOST2 -eq 0 -a $WANIF2TESTHOST1 -eq 1 -a $WANIF2TESTHOST2 -eq 0 ]; then
Handler "1"
exit 0
fi
if [ $WANIF1TESTHOST1 -eq 0 -a $WANIF1TESTHOST2 -eq 0 -a $WANIF2TESTHOST1 -eq 1 -a $WANIF2TESTHOST2 -eq 1 ]; then
Handler "1"
exit 0
fi
# 2 - полностью доступен второй канал -> переключаем на второй 0100, 1000, 1100
if [ $WANIF1TESTHOST1 -eq 0 -a $WANIF1TESTHOST2 -eq 1 -a $WANIF2TESTHOST1 -eq 0 -a $WANIF2TESTHOST2 -eq 0 ]; then
Handler "2"
exit 0
fi
if [ $WANIF1TESTHOST1 -eq 1 -a $WANIF1TESTHOST2 -eq 0 -a $WANIF2TESTHOST1 -eq 0 -a $WANIF2TESTHOST2 -eq 0 ]; then
Handler "2"
exit 0
fi
if [ $WANIF1TESTHOST1 -eq 1 -a $WANIF1TESTHOST2 -eq 1 -a $WANIF2TESTHOST1 -eq 0 -a $WANIF2TESTHOST2 -eq 0 ]; then
Handler "2"
exit 0
fi
# 3 - полностью недоступны все каналы -> бездействие 1111
if [ $WANIF1TESTHOST1 -eq 1 -a $WANIF1TESTHOST2 -eq 1 -a $WANIF2TESTHOST1 -eq 1 -a $WANIF2TESTHOST2 -eq 1 ]; then
Handler "3"
exit 0
fi
# 4 - полностью недоступен первый канал -> переключаем на второй 1101, 1110
if [ $WANIF1TESTHOST1 -eq 1 -a $WANIF1TESTHOST2 -eq 1 -a $WANIF2TESTHOST1 -eq 0 -a $WANIF2TESTHOST2 -eq 1 ]; then
Handler "4"
exit 0
fi
if [ $WANIF1TESTHOST1 -eq 1 -a $WANIF1TESTHOST2 -eq 1 -a $WANIF2TESTHOST1 -eq 1 -a $WANIF2TESTHOST2 -eq 0 ]; then
Handler "4"
exit 0
fi
# 5 - полностью недоступен второй канал -> переключаем на первый 0111, 1011
if [ $WANIF1TESTHOST1 -eq 0 -a $WANIF1TESTHOST2 -eq 1 -a $WANIF2TESTHOST1 -eq 1 -a $WANIF2TESTHOST2 -eq 1 ]; then
Handler "5"
exit 0
fi
if [ $WANIF1TESTHOST1 -eq 1 -a $WANIF1TESTHOST2 -eq 0 -a $WANIF2TESTHOST1 -eq 1 -a $WANIF2TESTHOST2 -eq 1 ]; then
Handler "5"
exit 0
fi
# 6 - частично доступны все каналы -> бездействие 0101, 0110, 1001, 1010
if [ $WANIF1TESTHOST1 -eq 0 -a $WANIF1TESTHOST2 -eq 1 -a $WANIF2TESTHOST1 -eq 0 -a $WANIF2TESTHOST2 -eq 1 ]; then
Handler "6"
exit 0
fi
if [ $WANIF1TESTHOST1 -eq 0 -a $WANIF1TESTHOST2 -eq 1 -a $WANIF2TESTHOST1 -eq 1 -a $WANIF2TESTHOST2 -eq 0 ]; then
Handler "6"
exit 0
fi
if [ $WANIF1TESTHOST1 -eq 1 -a $WANIF1TESTHOST2 -eq 0 -a $WANIF2TESTHOST1 -eq 0 -a $WANIF2TESTHOST2 -eq 1 ]; then
Handler "6"
exit 0
fi
if [ $WANIF1TESTHOST1 -eq 1 -a $WANIF1TESTHOST2 -eq 0 -a $WANIF2TESTHOST1 -eq 1 -a $WANIF2TESTHOST2 -eq 0 ]; then
Handler "6"
exit 0
fi
-----------------------------------------------
засовываем его в cron и запускает, например, каждые 5 минут
Подскажите, может есть более элегантный способ это реализовать?Плюс к этому есть пара вопросов...
Как выбрать эти "всегда работающие ip"?
И какая утилита в linux позволяет отправлять письма через указанный внешний сервер. Дело в том, что ставить на роутер mta не хочется, а на сколько я помню mail, nail этого требуют. В данном же случаи была бы удобна утилита схожая с postie, которой можно указать через какой сервер отправлять сообщение
emerge -s ssmtp
....
Homepage: ftp://ftp.debian.org/debian/pool/main/s/ssmtp/
Description: Extremely simple MTA to get mail off the system to a Mailhub
License: GPL-2