Zunächst definieren wir die Variablen:
$ cat /etc/balance/vars
- #!/bin/bash
- # LAN Schnittstelle
- IF0="eth1"
- # WAN Schnittstelle 1
- IF1="eth0"
- # WAN Schnittstelle 2
- IF2="ppp0"
- IP1="194.9.xx.xx"
- IP2="`ip addr show $IF2 | grep inet | awk '{print $2}'`"
- # Gateway 1
- P1="194.9.xx.xx"
- # Gateway 2
- P2="195.5.xx.xx"
- # LAN-Netzmaske
- P0_NET="192.168.0.0/24"
- # WAN1-Netzmaske
- P1_NET="194.9.xx.xx/xx"
- # WAN2-Netzmaske
- P2_NET="195.5.xx.xx/xx"
- TBL1="provider1"
- TBL2="provider2"
- # Relatives Gewicht der Kanalbandbreite
- W1="2"
- W2="1"
Fügen Sie zwei zusätzliche Routing-Tabellen in die Datei /etc/iproute2/rt_tables ein:
echo "1 provider1" >> /etc/iproute2/rt_tables
echo "2 provider2" >> /etc/iproute2/rt_tables
Nun schreiben wir ein Skript, das alle erforderlichen Routen und Firewall-Regeln einträgt:
cat /etc/balance/routing.sh
- #!/bin/bash
- . /etc/balance/vars
- echo "1" > /proc/sys/net/ipv4/ip_forward
- ip route add $P1_NET dev $IF1 src $IP1 table $TBL1 > /dev/null 2>&1
- ip route add default via $P1 table $TBL1 > /dev/null 2>&1
- ip route add $P2_NET dev $IF2 src $IP2 table $TBL2 > /dev/null 2>&1
- ip route add default via $P2 table $TBL2 > /dev/null 2>&1
- ip route add $P1_NET dev $IF1 src $IP1 > /dev/null 2>&1
- ip route add $P2_NET dev $IF2 src $IP2
- ip route add default via $P1 > /dev/null 2>&1
- ip rule add from $IP1 table $TBL1 > /dev/null 2>&1
- ip rule add from $IP2 table $TBL2 > /dev/null 2>&1
- ip route add $P0_NET dev $IF0 table $TBL1 > /dev/null 2>&1
- ip route add $P2_NET dev $IF2 table $TBL1 > /dev/null 2>&1
- ip route add 127.0.0.0/8 dev lo table $TBL1 > /dev/null 2>&1
- ip route add $P0_NET dev $IF0 table $TBL2 > /dev/null 2>&1
- ip route add $P1_NET dev $IF1 table $TBL2 > /dev/null 2>&1
- ip route add 127.0.0.0/8 dev lo table $TBL2 > /dev/null 2>&1
- iptables -t nat -F POSTROUTING
- iptables -t nat -A POSTROUTING -s $P0_NET -o $IF1 -j MASQUERADE
- iptables -t nat -A POSTROUTING -s $P0_NET -o $IF2 -j MASQUERADE
Diese Befehlsfolge stellt sicher, dass Antwortpakete über die Schnittstelle gesendet werden, über die die Anfrage empfangen wurde, und führt zudem Masking auf beiden Schnittstellen durch.
Nun schreiben wir ein Skript, das prüft, ob ein bestimmter Kanal aktiv ist, und entsprechend die Einträge für das Standard-Gateway anpasst.
$ cat /etc/balance/check.sh
- #!/bin/bash
- . /etc/balance/vars
- OLDIF1=0
- OLDIF2=0
- . /etc/balance/routing.sh
- while true; do
- ping -c 3 -s 100 $P1 -I $IF1 > /dev/null
- if [ $? -ne 0 ]; then
- echo "Failed IF1!"
- NEWIF1=0
- else
- NEWIF1=1
- fi
- ping -c 3 -s 100 $P2 -I $IF2 > /dev/null
- if [ $? -ne 0 ]; then
- echo "Failed IF2!"
- NEWIF2=0
- else
- NEWIF2=1
- fi
- if (( ($NEWIF1!=$OLDIF1) || ($NEWIF2!=$OLDIF2) )); then
- echo "Changing routes"
- if (( ($NEWIF1==1) && ($NEWIF2==1) )); then
- echo "Both channels"
- ip route delete default
- ip route add default scope global nexthop via $P1 dev $IF1 weight $W1 \
- nexthop via $P2 dev $IF2 weight $W2
- elif (( ($NEWIF1==1) && ($NEWIF2==0) )); then
- echo "First channel"
- ip route delete default
- ip route add default via $P1 dev $IF1
- elif (( ($NEWIF1==0) && ($NEWIF2==1) )); then
- echo "Second channel"
- ip route delete default
- ip route add default via $P2 dev $IF2
- fi
- else
- echo "Not changed"
- fi
- OLDIF1=$NEWIF1
- OLDIF2=$NEWIF2
- sleep 3
- done
Die Funktionsfähigkeit des Kanals wird durch Ping des Gateways überprüft. Wenn keine Antwort auf drei aufeinanderfolgende Ping-Anfragen erfolgt, gehen wir davon aus, dass der Kanal ausgefallen ist, und schließen ihn entsprechend aus der Routing-Tabelle aus.
Wenn also beide Kanäle funktionieren:
$ ip route
195.5.xx.xx dev ppp0 proto kernel scope link src 95.133.xx.xx
194.9.xx.xx/xx dev eth0 proto kernel scope link src 194.9.xx.xx
192.168.0.0/24 dev eth1 proto kernel scope link src 192.168.0.75
default
nexthop via 194.9.xx.xx dev eth0 weight 2
nexthop via 195.5.xx.xx dev ppp0 weight 1
Wir haben insgesamt zwei Default-Gateways: das erste mit dem Gewicht 2 und das zweite mit dem Gewicht 1. Das bedeutet, dass über den ersten Kanal doppelt so viel Traffic fließt wie über den zweiten.
Um diese Skripte an Ihre Anforderungen anzupassen, müssen Sie die Werte in der Datei vars konfigurieren. Die anderen Skripte erfordern praktisch keine weitere Anpassung.
