Custom Router (Teil 1) – Multiple Providers

Nun bin ich das langsame Internet und die ständigen ping-Spitzen(hoher ping) beim Spielen schon leid, Ein zweiter Provider muss her.

Ein kleiner lokaler Provider liefert ordentlich Bandbreite über WLAN Richtfunk. In dem Zusammenhang wird auch das Hausnetz etwas umgekrempelt und auf neuesten Stand der Technik gebracht.

Das Netzwerk

Die neue Netzwerkhardware besteht aus:

  • 1x Managed Switch
  • 2x AccessPoint
  • 1x Router (BananaPi)

networkPhysicalTopo

Dank des managed Switches ist die physische Verkabelung recht einfach und übersichtlich. Die Idee dahinter ist einfach mehrere VLANs zu definieren. Als Router wird ein kleiner stromsparender Rechner eingebaut, der mittels 802.1q-Trunk zwischen den VLANs das Routing übernimmt.

Mittels VLANs möchte ich die folgende Topologie realisieren.

Virtuelle Topologie

Den Switch habe ich in etwa so konfiguriert.

    
    Port    Typ     VLAN    Description
    1       Trunk   all     MainRouter
    2       Access  1       Managagement Port
    3       Trunk   2,3     AP1
    4       Trunk   2,3     AP2
    5       Access  2       HLAN
    6       Access  2       HLAN
    7       Access  2       HLAN
    8       Access  2       Server
    9       Access  2       HLAN
    10      Access  2       HLAN
    11      Access  2       HLAN
    12      Access  2       HLAN
    13      Access  2       HLAN
    14      Access  2       HLAN
    15      Access  2       HLAN
    16      Access  2       HLAN
    17      Access  2       HLAN
    18      Access  2       HLAN
    19      Access  2       HLAN
    20      Access  2       HLAN
    21      Access  2       HLAN
    22      Access  2       HLAN
    23      Access  100     Router Telekom
    24      Access  101     Router WaveNet

Die geplanten IP Ranges

10.0.0.0/24 Management VLAN1
    10.0.0.100 Switch 
    10.0.0.101 AP1 
    10.0.0.102 AP2 
    10.0.0.103 AP3 
    10.0.0.1   Router RaspberryPi
    

192.168.1.0/24 Hausnetz VLAN2
    192.168.1.1 Router RaspberryPi
    192.168.1.2 Server Intern
    192.168.1.3 Reciever
    
    

192.168.2.0/24 Gastnetz VLAN3
    192.168.2.1 Router RaspberryPi


10.0.2.0    External DMZ VLAN 5
10.0.1.0    Internal DMZ VLAN 4


172.16.0.0/30 Telekom Zwischennetz VLAN 100
    172.16.0.1 Router Intern
    172.16.0.2 Router Telekom Austria
    
 
172.17.0.1/24 WaveNet Zwischennetz VLAN 101
    172.17.0.10 Router Intern
    172.17.0.254 WaveNet AP/Router

Das Netwerk ist ja schnell zusammengestöpselt und die VLANs auch schnell definiert. (geht bei den meisten Switches recht einfach)

Die IP Range 172.17.0.0/30 ist von meinem Provider vorgegeben. Dieser macht ein DNAT auf meine interne IP 172.17.0.10. Ich selbst habe keinen Zugriff auf die Router Konfiguration.

Der Router

Nun zum Router. Dieser wird bei meinem Switch an Port 1 gestöpselt. Dieser wird als dot1q-Trunk konfiguriert über das alle VLAN IDs dürfen. Als Router verwende ich zur Zeit einen RaspberryPi Model B mir Raspbian (Debian). Aber alles sollte mehr oder weniger mit anderen Distributionen genau so funktionieren.

Interface Konfiguration

Raspbian kann in der Standard installtion nicht mit VLANs umgehen, es muss erst das Paket vlan installiert werden. Danach kann das Interface wie in Debian gewohnt konfiguriert werden. VLANs konfigurieren mit Debian ist recht einfach und gut >>Dokumentiert<< .

Meine Konfiguration sieht wie folgt aus:

auto lo
iface lo inet loopback

auto vlan1
iface vlan1 inet static
        address 10.0.0.1
        netmask 255.255.255.0
        vlan_raw_device eth0

auto vlan2
iface vlan2 inet static
        address 192.168.1.1
        netmask 255.255.255.0
        vlan_raw_device eth0


auto vlan3
iface vlan3 inet static
        address 192.168.2.1
        netmask 255.255.255.0
        vlan_raw_device eth0

auto vlan4
iface vlan4 inet static
        address 10.0.1.1
        netmask 255.255.255.0
        vlan_raw_device eth0

auto vlan5
iface vlan5 inet static
        address 10.0.2.1
        netmask 255.255.255.0
        vlan_raw_device eth0


auto vlan100
iface vlan100 inet static
        address 172.16.0.1
        netmask 255.255.255.252
        #gateway 172.16.0.2
        vlan_raw_device eth0

auto vlan101
iface vlan101 inet static
        address 172.17.0.10
        netmask 255.255.255.0
        gateway 172.17.0.254
        vlan_raw_device eth0




Die Konfiguration ist recht simpel. Jedes VLAN hat einfach ein virtuelles Interface. Alles was bei vlan100 raus gesendet wird besitzt das VLAN-Tag 100. Je nach dem ob der Router am Trunk das VLAN akzeptiert oder nicht dropt er das Frame oder sendet es weiter zum Empfänger.

Routing

Um das Routing beim booten zu aktivieren muss lediglich die Zeile

 net.ipv4.ip_forward=1

in der Date /etc/sysctl.conf auskommentiert werden.

echo 1 > /proc/sys/net/ipv4/ip_forward 

aktiviert das Routing ohne reboot.

Jetzt der eigentliche Trick bei der ganzen Routerkonfiguration. Eigentlich kann es nur eine default Route geben. Gibt es zwei wird anhand der Metric entschieden welche Route genommen wird. Nun will ich aber anhand diverser Paket-Merkmale entscheiden können welche Route ein Paket nehmen soll.

Firewall regeln kann man unter Linux mit Netfilter realisieren. Allerdings hat Netfilter nichts mit Routing zu tun. Man kann sich aber eines kleines Tricks behelfen. Man markiert mit Iptables die Pakete wie gewünscht. Iproute liest diese Markierung und trifft anhand dieser die Auswahl der Routingtabelle.

Den Routing Tabellen einen Namen geben

#
# reserved values
#
255     local
254     main
253     default
0       unspec
#
# local
#
#1      inr.ruhep
100 adsl-rt
101 wavenet-rt

Danach können die Routingtabellen befüllt werden

[soourcecode]
ip route add default via 172.16.0.2 dev vlan100 table adsl-rt
ip route add default via 172.17.0.254 dev vlan101 table wavenet-rt
[/sourcecode]
Und die Routing-Regeln werden definiert.

 ip rule add fwmark 0x64 table adsl-rt
 ip rule add fwmark 0x65 table wavenet-rt

Erweiterte Konfiguration der Interfaces

Damit auch bei einem Reboot die Routgingkonfiguration erhalten bleibt. Schreibe ich die erforderlichen Einträge in die Interface-Konfiguration. Mit der Konfigurationszeile post-up kann ein Befehl angegeben werden, der ausgeführt wird nachdem das Interface up ist.

auto lo
iface lo inet loopback

auto vlan1
iface vlan1 inet static
        address 10.0.0.1
        netmask 255.255.255.0
        vlan_raw_device eth0
        #lokale routen
        post-up ip route add 10.0.0.0/24 dev vlan1 table adsl-rt
        post-up ip route add 10.0.0.0/24 dev vlan1 table wavenet-rt

auto vlan2
iface vlan2 inet static
        address 192.168.1.1
        netmask 255.255.255.0
        vlan_raw_device eth0
        post-up ip route add 192.168.1.0/24 dev vlan2 table adsl-rt
        post-up ip route add 192.168.1.0/24 dev vlan2 table wavenet-rt


auto vlan3
iface vlan3 inet static
        address 192.168.2.1
        netmask 255.255.255.0
        vlan_raw_device eth0
        post-up ip route add 192.168.2.0/24 dev vlan3 table adsl-rt
        post-up ip route add 192.168.2.0/24 dev vlan3 table wavenet-rt

auto vlan4
iface vlan4 inet static
        address 10.0.1.1
        netmask 255.255.255.0
        vlan_raw_device eth0
        post-up ip route add 10.0.1.0/24 dev vlan4 table adsl-rt
        post-up ip route add 10.0.1.0/24 dev vlan4 table wavenet-rt

auto vlan5
iface vlan5 inet static
        address 10.0.2.1
        netmask 255.255.255.0
        vlan_raw_device eth0
        post-up ip route add 10.0.2.0/24 dev vlan5 table adsl-rt
        post-up ip route add 10.0.2.0/24 dev vlan5 table wavenet-rt


auto vlan100
iface vlan100 inet static
        address 172.16.0.1
        netmask 255.255.255.252
        #gateway 172.16.0.2
        vlan_raw_device eth0
        post-up ip route add 172.16.0.0/30 dev vlan100 table adsl-rt
        post-up ip route add 172.16.0.0/30 dev vlan100 table wavenet-rt
        post-up ip route add default via 172.16.0.2 dev vlan100 table adsl-rt
        post-up ip rule add fwmark 0x64 table adsl-rt


auto vlan101
iface vlan101 inet static
        address 172.17.0.10
        netmask 255.255.255.0
        gateway 172.17.0.254
        vlan_raw_device eth0
        post-up ip route add 172.17.0.0/24 dev vlan101 table adsl-rt
        post-up ip route add 172.17.0.0/24 dev vlan101 table wavenet-rt
        post-up ip route add default via 172.17.0.254 dev vlan101 table wavenet-rt
        post-up ip rule add fwmark 0x65 table wavenet-rt


Die Firewall

Als nächstes muss natürlich die Firewall konfiguriert werden. Dazu muss man etwas Verständnis für iptables haben. Folgende Grafik von Wikipedia ist sehr hilfreich.

Pakete können mit der Netfilter mangle-Tabelle verändert werden. Die wichtige Stelle im Netfilter ist die „routing decision“ Wie man in der Grafik schön erkennen kann. Müssen die Pakete bereits in der PREROUTING-Chain markiert werden

root@router /home/pi # iptables-save
# Generated by iptables-save v1.4.14 on Sat Sep 13 22:41:44 2014
*filter
:INPUT DROP [4:972]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [1905:245379]
:GUESTFILTER - [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -d 127.0.0.0/8 ! -i lo -j REJECT --reject-with icmp-port-unreachable
-A INPUT -i vlan100 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i vlan101 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -s 10.0.0.0/24 -i vlan1 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i vlan1 -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i vlan2 -o vlan100 -j ACCEPT
-A FORWARD -i vlan3 -o vlan100 -j ACCEPT
-A FORWARD -i vlan2 -o vlan101 -j ACCEPT
-A FORWARD -i vlan3 -o vlan101 -j ACCEPT
-A FORWARD -s 192.168.1.66/32 -i vlan2 -o vlan1 -j ACCEPT
COMMIT
# Completed on Sat Sep 13 22:41:44 2014
# Generated by iptables-save v1.4.14 on Sat Sep 13 22:41:44 2014
*nat
:PREROUTING ACCEPT [19:2183]
:INPUT ACCEPT [2:120]
:OUTPUT ACCEPT [13:943]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o vlan100 -j MASQUERADE
-A POSTROUTING -o vlan101 -j MASQUERADE
COMMIT
# Completed on Sat Sep 13 22:41:44 2014
# Generated by iptables-save v1.4.14 on Sat Sep 13 22:41:44 2014
*mangle
:PREROUTING ACCEPT [121:8163]
:INPUT ACCEPT [121:8163]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [107:12892]
:POSTROUTING ACCEPT [107:12892]
:GWMARK - [0:0]
-A PREROUTING -i vlan2 -j GWMARK
-A PREROUTING -i vlan3 -j GWMARK
-A GWMARK -j MARK --set-xmark 0x65/0xffffffff
COMMIT
# Completed on Sat Sep 13 22:41:44 2014

Hierbei handelt es sich um eine recht simple Firewallkonfiguration. Nur gibt es eben zwei Provider. Ich mache hier Masquarading zu den anderen Routern (Fritzbox, WaveNET-Router) um dort keine statischen Routen eintragen zu müssen.

Es gibt auf meinem Router also drei Routingtabellen

Für unmarkierte Pakete gilt die main-table

root@router /home/pi # ip route show table main

default via 172.16.0.6 dev vlan101
10.0.0.0/24 dev vlan1  proto kernel  scope link  src 10.0.0.1
10.0.1.0/24 dev vlan4  proto kernel  scope link  src 10.0.1.1
10.0.2.0/24 dev vlan5  proto kernel  scope link  src 10.0.2.1
172.16.0.0/30 dev vlan100  proto kernel  scope link  src 172.16.0.1
172.16.0.4/30 dev vlan101  proto kernel  scope link  src 172.16.0.5
192.168.1.0/24 dev vlan2  proto kernel  scope link  src 192.168.1.1
192.168.2.0/24 dev vlan3  proto kernel  scope link  src 192.168.2.1

Pakete mit der marke 0x64 gilt diese hier

root@router /home/pi # ip route show table 100
default via 172.16.0.2 dev vlan100
10.0.0.0/24 dev vlan1  scope link
10.0.1.0/24 dev vlan4  scope link
10.0.2.0/24 dev vlan5  scope link
171.16.0.0/30 dev vlan100  scope link
172.17.0.0/24 dev vlan101  scope link
192.168.1.0/24 dev vlan2  scope link
192.168.2.0/24 dev vlan3  scope link

Pakete mit der Marke 0x65 verwenden diese Raoutingtabelle

root@router /home/pi # ip route show table 101
default via 172.17.0.254 dev vlan101
10.0.0.0/24 dev vlan1  scope link
10.0.1.0/24 dev vlan4  scope link
10.0.2.0/24 dev vlan5  scope link
171.16.0.0/30 dev vlan100  scope link
172.17.0.0/24 dev vlan101  scope link
192.168.1.0/24 dev vlan2  scope link
192.168.2.0/24 dev vlan3  scope link

Wie man unschwer erkennen kann wird nun eigentlich immer der WaveNET Anschluss mit 20/2 MBit verwendet. Und die ADSL Leitung bleibt ungenutzt. Das mache ich mir zu nutze um QoS zu implementieren. Mit einfachen iptables-Regeln ist nun Möglich sehr genaue und einfache Routingentscheidungen zu treffen.

Hier ein Beispiel Teamspeak soll über den ADSL-Anschluss laufen.

Ein Teamspeak3 Server benutzt folgende Ports:

Default port (UDP eingehend): 9987
Default filetransfer port (TCP eingehend): 30033
Default serverquery port (TCP eingehend): 10011
Default weblist port (UDP ausgehend): 2010
Default tsdns port (TCP eingehend): 41144
Default accounting port (TCP ausgehend): 2008

Einfach entsprechend die Firewall Regeln definieren

Die ursprüngliche mangle-Tabelle sieht wie folgt aus.

root@router /home/pi # iptables -L -n --line-numbers -v -t mangle
Chain PREROUTING (policy ACCEPT 17 packets, 1028 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1       70 13072 GWMARK     all  --  vlan2  *       0.0.0.0/0            0.0.0.0/0
2        0     0 GWMARK     all  --  vlan3  *       0.0.0.0/0            0.0.0.0/0

Chain INPUT (policy ACCEPT 17 packets, 1028 bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 14 packets, 1736 bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 14 packets, 1736 bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain GWMARK (2 references)
num   pkts bytes target     prot opt in     out     source               destination
1       47  8504 MARK       all  --  *      *       0.0.0.0/0            0.0.0.0/0            MARK set 0x65

Alle Pakete werden mit 0x65 markiert, was die Pakete über das WaveNet routet.

Nun werden die TeamSpeak Pakete mit 0x64 markiert.

root@router /home/pi # iptables -t mangle -A GWMARK -i vlan2 --protocol udp --dport 9987 -j MARK --set-xmark 0x64
root@router /home/pi # iptables -t mangle -A GWMARK -i vlan2 --protocol tcp --dport 30033 -j MARK --set-xmark 0x64
root@router /home/pi # iptables -t mangle -A GWMARK -i vlan2 --protocol tcp --dport 10011 -j MARK --set-xmark 0x64
root@router /home/pi # iptables -t mangle -A GWMARK -i vlan2 --protocol tcp --dport 41144 -j MARK --set-xmark 0x64
root@router /home/pi # iptables -L -n --line-numbers -v -t mangle
Chain PREROUTING (policy ACCEPT 289 packets, 24964 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1       70 13072 GWMARK     all  --  vlan2  *       0.0.0.0/0            0.0.0.0/0
2        0     0 GWMARK     all  --  vlan3  *       0.0.0.0/0            0.0.0.0/0

Chain INPUT (policy ACCEPT 289 packets, 24964 bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 217 packets, 21140 bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 217 packets, 21140 bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain GWMARK (2 references)
num   pkts bytes target     prot opt in     out     source               destination
1       47  8504 MARK       all  --  *      *       0.0.0.0/0            0.0.0.0/0            MARK set 0x65
2        0     0 MARK       udp  --  vlan2  *       0.0.0.0/0            0.0.0.0/0            udp dpt:9987 MARK set 0x64
3        0     0 MARK       tcp  --  vlan2  *       0.0.0.0/0            0.0.0.0/0            tcp dpt:30033 MARK set 0x64
4        0     0 MARK       tcp  --  vlan2  *       0.0.0.0/0            0.0.0.0/0            tcp dpt:41144 MARK set 0x64
5        0     0 MARK       tcp  --  vlan2  *       0.0.0.0/0            0.0.0.0/0            tcp dpt:10011 MARK set 0x64

root@router /home/pi #

Und schon läuft der Traffic über ADSL statt über WaveNet (FunkInternet)

Ich verwende aber eigentlich immer den selben TeamSpeak Server darum trage ich dessen IP auch einfach ein (dessen genaue Port Konfiguration ist mir leider nicht bekannt)

iptables -t mangle -A GWMARK -i vlan2 --destination ts303.zap-hosting.com -j MARK --set-xmark 0x64

Nun ist man in der lage komplett frei zu entscheiden welche Services über welchen Provider geroutet werden sollen.

That’s it. Vielleicht will wer ja mal wer was ähnliches Aufbauen.

About Florian