Скрипт много чего делает, в том числе считывает атрибуты wan-интерфейсов, отрабатывает ppp-ddns (bind9) для входящих pptp-подлючений вида ppp-ip-add-re-ss.example.net, ну разве что кофу не варит. Поэтому привёл только то, что необходимо.#!/bin/sh
# Check channels vars's
target="ya.ru" # ping target host
nums="14" # quantity echo requests
loss="16" # max losses echo replies in percent
chstate="$(cat /var/run/check_ch.state)" # State link path
# iptables route rules
ispdualrule="/etc/network/iptables-mangle-dual.rules"
isp1rule="/etc/network/iptables-mangle-isp1.rules"
isp2rule="/etc/network/iptables-mangle-isp2.rules"
# logging
timelog=$(date '+%b %d %T')
checklog="/var/log/check_channels.log"
## Functions
# CHECK ping hosts
check() {
echo "$timelog: Check alive cannels start. Probing $nums ICMP echo-request(s) for $target. Max packet loss $loss%." >> $checklog
if [ -d /proc/sys/net/ipv4/conf/$ifisp1 ] && [ -d /proc/sys/net/ipv4/conf/$ifisp2 ]; then
loss1=$(/bin/ping -q -c$nums -i 0.1 -I $ifisp1 $target |grep -v err |awk '/loss/ {print $6}' | sed 's/%//')
loss2=$(/bin/ping -q -c$nums -i 0.1 -I $ifisp2 $target |grep -v err |awk '/loss/ {print $6}' | sed 's/%//')
fi
}
# CHECK select channels
change() {
# check variables
if [ -z "$chstate" ]; then
chstate=0
fi
if [ -z $loss1 ]; then
if [ $chstate -ne 1 ]; then
echo "$timelog: Network unreachable or interface $ifisp1 not found. Check network settings." >> $checklog
/sbin/iptables-restore $isp2rule
exit 0
fi
echo "1" >/var/run/check_ch.state
elif [ -z $loss2 ]; then
if [ $chstate -ne 2 ]; then
echo "$timelog: Network unreachable or interface $ifisp2 not found. Check network settings." >> $checklog
/sbin/iptables-restore $isp1rule
exit 0
fi
echo "2" >/var/run/check_ch.state
fi
# ISP1 check
if [ $loss1 -gt $loss ]; then
if [ $chstate -ne 1 ]; then
/sbin/iptables-restore $isp2rule
fi
echo "1" >/var/run/check_ch.state
echo "$timelog: $target is $loss1% packet loss in $ifisp2 interface. Set default gateway via $ifisp1." >> $checklog
# ISP2 check
elif [ $loss2 -gt $loss ]; then
if [ $chstate -ne 2 ]; then
/sbin/iptables-restore $isp1rule
fi
echo "2" >/var/run/check_ch.state
echo "$timelog: $target is $loss2% packet loss in $ifisp1 interface. Set default gateway via $ifisp2." >> $checklog
elif [ $((($loss1+$loss2)/2)) -le $loss ]; then
if [ $chstate -ne 3 ]; then
/sbin/iptables-restore $ispdualrule
fi
echo "3" >/var/run/check_ch.state
echo "$timelog: $target is $((($loss1+$loss2)/2))% packet loss in BOTH interfaces. Set multiple gateways." >> $checklog
fi
}
check
sleep 2
change
У меня нет PPPoE, точнее был, теперь нет. Сейчас на двух WAN — DHCP, и скрипт заточен для DHCP, поэтому его нужно переписывать.
Варианты набора правил iptables ( тут исключил маршрутизацию на подсети провайдеров через ipset ). Внутренняя подсеть /24 поделена на 4x/26 у Вас могут быть другие варианты.
# Generated by iptables-save v1.4.20 on Sun Oct 20 14:14:17 2013
*mangle
:PREROUTING ACCEPT [450837:24944159]
:INPUT ACCEPT [438333:21033717]
:FORWARD ACCEPT [12266:3879776]
:OUTPUT ACCEPT [772374:1034374838]
:POSTROUTING ACCEPT [784605:1038253190]
:BALANCE - [0:0]
:ISP1 - [0:0]
:ISP2 - [0:0]
-A PREROUTING -m conntrack --ctstate RELATED,ESTABLISHED -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff
-A PREROUTING -i isp1 -j ISP1
-A PREROUTING -i isp0 -j ISP2
-A PREROUTING -s 192.168.0.64/26 -j ISP1
-A PREROUTING -s 192.168.0.128/26 -j BALANCE
-A PREROUTING -s 192.168.0.192/26 -j ISP2
-A PREROUTING -m state --state NEW -m connmark ! --mark 0x0 -j CONNMARK --save-mark --nfmask 0xffffffff --ctmask 0xffffffff
-A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
-A OUTPUT -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff
-A BALANCE -m statistic --mode nth --every 2 --packet 0 -j ISP1
-A BALANCE -m statistic --mode nth --every 2 --packet 1 -j ISP2
-A ISP1 -j MARK --set-xmark 0x1/0xffffffff
-A ISP2 -j MARK --set-xmark 0x2/0xffffffff
COMMIT
# Generated by iptables-save v1.4.20 on Sun Oct 20 14:14:17 2013
*mangle
:PREROUTING ACCEPT [450837:24944159]
:INPUT ACCEPT [438333:21033717]
:FORWARD ACCEPT [12266:3879776]
:OUTPUT ACCEPT [772374:1034374838]
:POSTROUTING ACCEPT [784605:1038253190]
:BALANCE - [0:0]
:ISP1 - [0:0]
:ISP2 - [0:0]
-A PREROUTING -m conntrack --ctstate RELATED,ESTABLISHED -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff
-A PREROUTING -i isp1 -j ISP1
-A PREROUTING -i isp0 -j ISP2
-A PREROUTING -s 192.168.0.64/26 -j ISP1
-A PREROUTING -s 192.168.0.128/26 -j ISP1
-A PREROUTING -s 192.168.0.192/26 -j ISP1
-A PREROUTING -m state --state NEW -m connmark ! --mark 0x0 -j CONNMARK --save-mark --nfmask 0xffffffff --ctmask 0xffffffff
-A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
-A OUTPUT -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff
-A BALANCE -m statistic --mode nth --every 2 --packet 0 -j ISP1
-A BALANCE -m statistic --mode nth --every 2 --packet 1 -j ISP2
-A ISP1 -j MARK --set-xmark 0x1/0xffffffff
-A ISP2 -j MARK --set-xmark 0x2/0xffffffff
COMMIT
# Generated by iptables-save v1.4.20 on Sun Oct 20 14:14:17 2013
*mangle
:PREROUTING ACCEPT [450837:24944159]
:INPUT ACCEPT [438333:21033717]
:FORWARD ACCEPT [12266:3879776]
:OUTPUT ACCEPT [772374:1034374838]
:POSTROUTING ACCEPT [784605:1038253190]
:BALANCE - [0:0]
:ISP1 - [0:0]
:ISP2 - [0:0]
-A PREROUTING -m conntrack --ctstate RELATED,ESTABLISHED -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff
-A PREROUTING -i isp1 -j ISP1
-A PREROUTING -i isp0 -j ISP2
-A PREROUTING -s 192.168.0.64/26 -j ISP2
-A PREROUTING -s 192.168.0.128/26 -j ISP2
-A PREROUTING -s 192.168.0.192/26 -j ISP2
-A PREROUTING -m state --state NEW -m connmark ! --mark 0x0 -j CONNMARK --save-mark --nfmask 0xffffffff --ctmask 0xffffffff
-A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
-A OUTPUT -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff
-A BALANCE -m statistic --mode nth --every 2 --packet 0 -j ISP1
-A BALANCE -m statistic --mode nth --every 2 --packet 1 -j ISP2
-A ISP1 -j MARK --set-xmark 0x1/0xffffffff
-A ISP2 -j MARK --set-xmark 0x2/0xffffffff
COMMIT[
Переключение маршрутизации только через iptables, ip route и ip rule не трогается, добавляется только ip rule add from all fwmark 0x{1,2} lookup $table
Вам наверняка потребуются другие варианты.
Повторю свой февральский пост: Вы нигде не найдёте готовых решений, я тоже искал — увы, ни одна вебморда не даёт того, что даёт шелл, т.е простых решений нет.