Przypominając i kompletując te informacje. Dysponujemy routerem z trzema interfejsami. Do interfejsu eth0 podłączone jest łącze podstawowe a do eth1 sieć lokalna LAN. Drugie łącze podłączone jest do interfejsu eth2. Adres publiczny po stronie pierwszego łącza to 198.51.100.100/24, adres po stronie drugiego łącza to 203.0.113.100/24 a adres po stronie sieci LAN to 192.168.0.1/24. Adresacja sieci LAN to 192.168.0.0/24.
Obydwa łącza to łącza asymetryczne o przepustowościach odpowiednio 8000kb/s na 500kb/s oraz 10000kb/s na 600kb/s.
Sposobów na wykorzystanie dwóch łączy, czyli Load Balancing, jest wiele. Opisywany scenariusz to "przerzucenie" na drugie łącze ruchu www oraz poczty e-mail. Zarówno www jak i poczta charakteryzują się "sporadycznością" ruchu. Dzięki temu, że ruch ten rzadko generuje długotrwałe i stałe obciążenie (w przeciwieństwie do ruchu p2p), dostępne pasmo bardzo dobrze współdzieli się na znaczną liczbę hostów. Dodatkowo poza wysyceniem downloadu (http, imap i pop3 - pobieranie), postaramy się wykorzystać upload drugiego łącza, wysyłając nim ruch smtp.
Skrypt zapewni, że wszystkie pakiety TCP o porcie docelowym wymienionym w zmiennej isp2_ports_tcp, zostaną oznaczone znacznikiem 0x2. Spowoduje to, w połączeniu z odpowiednią konfiguracją, że pakiety te będą routowane drugim łączem oraz kontrolowane przez odpowiednie sekcje NiceShapera.
Do utworzonego wcześniej pliku wklejamy poniższą zawartość, odpowiednio modyfikując, zmienne zdefiniowane na samym jego początku w części "Konfiguracja".
# === Konfiguracja ===
wan1_iface="eth0"
wan1_net="198.51.100.0/24"
wan1_ip="198.51.100.100"
wan1_gw="198.51.100.2"
lan_iface="eth1"
lan_net="192.168.0.0/24"
wan2_iface="eth2"
wan2_net="203.0.113.0/24"
wan2_ip="203.0.113.100"
wan2_gw="203.0.113.2"
isp2_ports_tcp="80,443,25,465,143,993,110,995"
# === Ustawienia systemu operacyjnego ===
IP=`which ip`
IPT=`which iptables`
NS=`which niceshaper`
ECHO=`which echo`
if [ -z "$IP" ]; then
echo "Brak programu ip (iproute)"
exit 255
fi
if [ -z "$IPT" ]; then
echo "Brak programu iptables"
exit 255
fi
if [ -z "$NS" ]; then
echo "Brak programu niceshaper"
exit 255
fi
if [ -z "$ECHO" ]; then
echo "Brak programu echo"
exit 255
fi
$ECHO 1 > /proc/sys/net/ipv4/ip_forward
$ECHO 0 > /proc/sys/net/ipv4/conf/all/rp_filter
# === NiceShaper ===
$ECHO "Zatrzymanie NiceShapera"
$NS stop
# === Routing ===
$ECHO "Routing - Czyszczenie"
$IP route flush table 241 2>/dev/null
$IP route flush table 242 2>/dev/null
$IP rule del fwmark 0x1 table 241 2>/dev/null
$IP rule del fwmark 0x2 table 242 2>/dev/null
$ECHO "Routing - Tabela 241"
$IP route add ${wan1_net} dev ${wan1_iface} table 241 # Routing lokalny
$IP route add ${wan2_net} dev ${wan2_iface} table 241 # Routing lokalny
$IP route add ${lan_net} dev ${lan_iface} table 241 # Routing lokalny
$IP route add default via ${wan1_gw} table 241 # Routing domyślny w tabeli 241 przez łącze nr.1
$ECHO "Routing - Tabela 242"
$IP route add ${wan1_net} dev ${wan1_iface} table 242 # Routing lokalny
$IP route add ${wan2_net} dev ${wan2_iface} table 242 # Routing lokalny
$IP route add ${lan_net} dev ${lan_iface} table 242 # Routing lokalny
$IP route add default via ${wan2_gw} table 242 # Routing domyślny w tabeli 242 przez łącze nr.2
$ECHO "Routing - Rules"
$IP rule add fwmark 0x1 table 241
$IP rule add fwmark 0x2 table 242
# === Markowanie pakietów ===
$ECHO "Markowanie pakietów - Przygotowanie reguł iptables"
$IPT -t mangle -F PREROUTING 2>/dev/null
$IPT -t mangle -F routemark 2>/dev/null
$IPT -t mangle -X routemark 2>/dev/null
$IPT -t mangle -N routemark
$IPT -t mangle -A routemark -i ${wan1_iface} -j MARK --set-mark 0x1
$IPT -t mangle -A routemark -i ${wan2_iface} -j MARK --set-mark 0x2
$IPT -t mangle -A routemark -i ${lan_iface} -p tcp -m multiport --dports ${isp2_ports_tcp} -j MARK --set-mark 0x2
$IPT -t mangle -A routemark -i ${lan_iface} -m mark ! --mark 0x2 -j MARK --set-mark 0x1
$IPT -t mangle -A routemark -j CONNMARK --save-mark
$IPT -t mangle -A PREROUTING -m state --state ESTABLISHED,RELATED -j CONNMARK --restore-mark
$IPT -t mangle -A PREROUTING -m state --state NEW -j routemark
# === NAT ===
$IPT -t nat -F POSTROUTING
$IPT -t nat -A POSTROUTING -o ${wan1_iface} -s ${lan_net} -j SNAT --to ${wan1_ip}
$IPT -t nat -A POSTROUTING -o ${wan2_iface} -s ${lan_net} -j SNAT --to ${wan2_ip}
# === NiceShaper ===
$ECHO "Uruchomienie NiceShapera"
$NS start
Ostatnie dwie klasy odpowiadają za upload. Filtry klasyfikują pakiety za pomocą adresu źródłowego oraz interfejsu którym pakiet opuszcza router (interfejs klasy), który zmienia się w zależności od tego, którym łączem pakiet zostaje wyroutowany na zewnątrz sieci.
Podsumowując, jak rozróżnić którym łączem routowany jest pakiet. W przypadku downloadu należy posłużyć się wartością znacznika, gdyż w tym kierunku interfejs wyjściowy nie zmienia się. Inaczej jest w przypadku uploadu, gdzie najwygodniej jest posłużyć się interfejsem wyjściowym, który zmienia się w zależności od łącza którym pakiet opuszcza router a dodatkowo nie jest wymagane zapisywanie kolejnego testu filtra, gdyż ten interfejs jest już określony w ramach klasy.
Teraz już pozostaje zduplikować powyższy zestaw klas dla każdego komputera w sieci lokalnej, oczywiście podmieniając adresy IP.
By uprościć konfigurację, zmniejszyć objętość i zwiększyć przejrzystość pliku klas, warto posłużyć się makrem foreach-pair (lub innym). Makro to wygeneruje kopie tego zestawu klas dla każdej pary "nazwa-ostatni oktet adresu IP".