LINUXMAKER, OpenSource, Tutorials

Ein Linux-Host mit mehr als einem Default-Gateway

Situation

Normalerweise haben Sie in einem Linux-Host mit mehreren Netzwerk-Interfaces ein Default-Getways, über das grundsätzlich geroutet wird. Alles Andere produziert ein asynchrones Routing in dem System und Router die Pakete möglicherweise verwerfen werden.

Problemlösung

Um diesem Problem aus dem Weg gehen zu können, existiert in allen aktuellen Linux-Distributionen das Programm "iproute2", das generell auch bereits installiert ist. Wie bereits erwähnt kann in einem Linux-System nur eine Routingtabelle mit nur einem Gateway eingetragen sein. "iproute2" ermöglicht es allerdings einerseits weitere Routingtabellen anzulegen und andererseits diese regebasiert im System verwenden zu lassen.

Ausgangssituation

Es wird davon ausgegangen, dass im System die zwei Interfaces enp0s3lf6 und wpl5s0 vorhanden sind. Die beiden zu verwendeten Netzwerke, haben die Adressen 192.168.0.0/24 und 172.10.0.0/24. Dabei repräsentiert jeweils die .1 das Gateway des jeweiligen Netzes. In Debian oder Ubuntu sähe die Ausgangskonfiguration des Netzes in der /etc/network/interfaces wie folgt aus:

network interface auto lo
iface lo inet loopback
# The primary network interface allow-hotplug enp0s3lf6
iface enp0s3lf6 inet static
    address 192.168.0.10
    netmask 255.255.255.0
    gateway 192.168.0.1
# The secondary network interface
allow-hotplug wpl5s0
iface wpl5s0 inet static
    address 172.10.0.10
    netmask 255.255.255.0

Generieren der zweiten Routingtabelle

Für diese zusätzlichen Routingtabellen existiert die Datei /etc/iproute2/rt_tables, die entsprechend modifiziert werden muss. Unserer neuen Routingtabelle geben wir den Namen "srvnet" und die Präferenz von 1.

#
# reserved values
#
255     local
254     main
253     default
0       unspec
#
# local
#
1        srvnet

Konfiguration der Routingtabellen und Aktivierung der Routingregeln

Anschliessend werden die neue Routingtabelle und die Regeln für die Nutzung der Routingtabelle durch das System wie folgt generiert:

ip route add 172.10.0.0/24 dev wpl5s0 src 172.10.0.10 table svrnet
ip route add default via 172.10.0.1 dev wpl5s0 table srvnet

ip rule add from 172.10.0.10/32 table srvnet
ip rule add to 172.10.0.10/32 table srvnet

Die beiden ersten Zeilen legen fest, dass das 172.10.0.0/24 über das Interface wpl5s0 erreicht werden kann und das Default-Gateway auf diesem Interface liegt. Mit den beiden Regeln in Zeile 3 und 4 wird festgelegt, dass sowohl der eingehende Traffic über die IP-Adresse 172.10.0.10 laufen soll, als auch der Traffic zu und über diese IP-Adresse jedes Mal die Routingtabelle srvnet zu nutzen hat.

Sobald das System neugestartet wird, gehen die "ip route"- und "ip-rule"-Befehle wieder verloren. Um dem Verlust vorzubeugen können die Befehle in der Netzwerkkonfiguration dauerhaft mit dem Parameter "post-up" in der Datei /etc/network/interfaces eingetragen werden. Damit ist mit jeder Initialisierung der Interfaces auch das Routing bereits konfiguriert.

iface wpl5s0 inet static
    address 172.10.0.10
    netmask 255.255.255.0
    post-up ip route add 172.10.0.0/24 dev wpl5s0 src 172.10.0.10 table svrnet
    post-up ip route add default via 172.10.0.1 dev wpl5s0 table srvnet
    post-up ip rule add from 172.10.0.10/32 table srvnet
    post-up ip rule add to 172.10.0.10/32 table srvnet

Sofern mehr als zwei Netzwerk-Interfaces existieren, wiederholt man diese Prozedur für jedes weiteres Interface wie beschrieben.

Lösung mit dynamischen IP-Adressen

Sobald DHCP mit dynamischer Adressvergabe zum Einsatz kommt, wird unsere Lösung so nicht funktionieren. Denn die IP-Adresse wird zum Zeitpunkt der Konfiguration des Interfaces noch nicht bekannt sein. Abhilfe kann ein ebenfalls über "post-up" eingebundenes Script leisten

iface wpl5s0 inet dhcp
    post-up /etc/network/if-up.d/routeaddWlan

Dazu wird unterhalb von /etc/network/if-up.d/ folgendes Bash-Script erstellt.

# vi /etc/network/if-up.d/routeaddWlan

#!/bin/bash
set -e
INTERFACE=`ip addr show | grep -e ':\s*wl' | awk '{print $2}' | cut -d: -f 1`
IP=`ip addr show dev $INTERFACE | grep 'inet ' | awk '{print $2}' | cut -d/ -f 1`
SUBNET=`ip route show | grep 'default' | grep $INTERFACE | awk '{print $3}' | sed 's/.$/0/g'`
GATEWAY=`ip route show | grep 'default' | grep $INTERFACE | awk '{print $3}'`
ip route add $SUBNET/24 dev $INTERFACE src $IP table srvnet
ip route add default via $GATEWAY dev $INTERFACE table srvnet
ip rule add from $IP/32 table srvnet
ip rule add to $IP/32 table srvnet

Das Script ermittelt die via DHCP zugewiesene IP-Adresse, das Subnet und das Gateway, um diese Werte den ip-Befehlen zur Verfügung zustellen. Anschliessend führt es die ip-Befehle aus, so dass diese nicht mehr in der /etc/network/interfaces festgehalten werden müssen.

Abschliessende Tests der Konfiguration

Der ip-Befehl stellt einige Parameter parat, mit denen sich die Routingtabellen und die Regeln anzeigen lassen.

ip route ls table 0

zeigen alle derzeit vorhandenen Routingtabellen inclusive des Inhaltes an. Alternativ auch

ip route ls table srvnet

Dagegen zeigen

ip rule show

oder

ip rule ls

alle Regeln an, wann welche Routingtabelle genutzt wird. Die Regeln werden so lange abgearbeitet, bis eine Route gefunden wird.