Nun also der
versprochene Beitrag zur technischen Umsetzung des automatischen outbound routings.
Ich habe also einen Uplink zu Provider A, dort eine statische IP Adresse 192.0.2.18, das Gateway des Providers hat die IP Adresse 192.0.2.17, Netzmaske 255.255.255.252.
Bei Provider B habe ich einen statischen 8-er Block, also z.B. 172.17.2.16/29, der Router zum Provider hat die IP Adresse 172.17.2.17, ich nutze für meinen Rechner daher 172.17.2.18 mit Netzmaske 255.255.255.248.
Nun richte ich als Router für mein internes Netzwerk ein
NET5501 von Soekris ein, das hat 4 Netzwerk Ports. Dort baue ich ein Harddisk ein und installiere darauf ein
Debian Lenny.
Vorbereitend müssen wir in /etc/iproute2/rt_tables zwei Tabellen definieren, wir nennen sie ispa und ispb:
#
# reserved values
#
255 local
254 main
253 default
0 unspec
#
# local
#
1 ispa
2 ispb
Ein Auszug aus /etc/network/interfaces für eth0, eth1, und eth2:
# Internes privates Netzwerk
auto eth0
iface eth0 inet static
address 192.168.1.1
netmask 255.255.255.0
broadcast 192.168.1.255
network 192.168.1.0
# Uplink zu Provider B
auto eth1
iface eth1 inet static
address 172.17.2.18
netmask 255.255.255.248
broadcast 172.17.2.23
network 172.17.2.16
up /sbin/ip route add 172.17.2.16/29 dev eth1 src 172.17.2.18 table ispb
up /sbin/ip route add 192.168.1.0/24 dev eth0 table ispb
up /sbin/ip route add default via 172.17.2.17 table ispb
up /sbin/ip rule add from 172.17.2.18 table ispb priority 200
up /sbin/ip route flush cache
# Uplink zu Provider A
auto eth2
iface eth2 inet static
address 192.0.2.18
netmask 255.255.255.252
broadcast 192.0.2.19
network 192.0.2.16
up /sbin/ip route add 192.0.2.16/30 dev eth2 src 192.0.2.18 table ispa
up /sbin/ip route add 192.168.1.0/24 dev eth0 table ispa
up /sbin/ip route add default via 192.0.2.17 table ispa
up /sbin/ip rule add from 192.0.2.18 table ispa priority 100
up /sbin/ip route flush cache
Man beachte, das kein Eintrag für ein Default-gateway eingetragen wurde, den das default-gateway will ich später aus dem dynamische Routing erhalten.
Es gibt jedoch für beide Interfaces Richtung Provider die Regeln welche bewirken, dass eine Verbindung von aussen auf die jeweilige statische IP Adresse, wieder von dieser IP Adresse via dieses Interface weggeschickt wird. Zugriffe auf die externen Adressen von einem Rechner aus meinem LAN muss natürlich wieder ins LAN, daher jeweils die zusätzliche route via eth0.
Nun kommt das dynamische Routing. Dazu brauche ich einen Host irgendwo draussen im Internet, wo ich vollen Zugriff habe. Ich gebe jenem Host mal die IP Adresse 172.22.22.22. Um die Verbindung zu diesem Host via beide Uplink Provider zu überwachen, muss ich eine Verbindung herstellen, welche durch das automatische Routing unbeeinflusst bleibt. Dies wird gelöst durch zwei
OpenVPN Tunnels. Mein Router agiert als OpenVPN Server, wobei zwei verschiedene Konfigurationen auf jeweils einem Interface konfiguriert sind.
Es gibt also eine Datei /etc/openvpn/server-ispa.conf
local 192.0.2.18
port 1194
proto udp
dev tun
ca myCA.pem
cert myCert.pem
key myKey.pem
dh dh1024.pem
server 10.10.255.0 255.255.255.0
client-config-dir ccd
route 10.10.255.4 255.255.255.252
keepalive 5 45
tls-auth ta.key 0
cipher AES-128-CBC
comp-lzo
persist-key
persist-tun
Ebenso eine Datei /etc/openvpn/server-ispb.conf wo nur folgende Zeilen anders sind:
local 172.17.2.18
server 10.10.254.0 255.255.255.0
route 10.10.254.4 255.255.255.252
Im Verzeichnis /etc/openvpn/ccd machen wir noch zwei Dateien ispa-link:
ifconfig-push 10.10.255.5 10.10.255.6
und ispb-link:
ifconfig-push 10.10.254.5 10.10.254.6
Man muss natürlich die Zertifikate machen für die beiden OpenVPN-Links, was ich hier nicht weiter ausführe.
Damit kriegen wir auf unserem Router zwei weitere Netzwerk-Interfaces tun0 und tun1, welche jeweils je einen VPN Link via Provider A und Provider B zulassen.
Auf dem Rechner 172.22.22.22 im Internet setzen wir nun zwei OpenVPN Client-Konfigurationen auf,
also Datei /etc/openvpn/client-ispa.conf:
client
dev tun
proto udp
remote 192.0.2.18 1194
resolv-entry infinite
nobind
persist-key
persist-tun
ca myCA.pem
cert client-ispa-cert.pem
key client-ispb-key.pem
tls-auth ta.key 1
cipher AES-128-CBC
comp-lzo
Entsprechend natürlich auch eine Datei client-ispb.conf, wo folgende Dinge entsprechend ersetzt werden:
remote 172.17.2.18 1194
cert client-ispb-cert.pem
key client-ispb-key.pem
Nun haben wir also zwei dedizierte Verbindungen von Host 172.22.22.22 zu den beiden Interfaces 172.17.2.18 und 192.0.2.18 vom multihomed Router. Ueber diese Verbindungen werden nun
BGP Verbindungen konfiguriert. Dazu wird auf beiden Hosts
quagga installiert.
Auf dem Rechner 172.22.22.22 im Internet konfigurieren wir nur bgpd.conf:
hostname extern.example.domain
password veryhard
router bgp 64590
bgp router-id 172.22.22.22
neighbor 10.10.255.1 remote-as 64591
neighbor 10.10.255.1 update-source 10.10.255.5
neighbor 10.10.255.1 default-originate
neighbor 10.10.255.1 route-map set-nexthop-ispa out
neighbor 10.10.255.1 filter-list 1 in
neighbor 10.10.255.1 filter-list 1 out
neighbor 10.10.255.1 ebgp-multihop
neighbor 10.10.254.1 remote-as 64591
neighbor 10.10.254.1 update-source 10.10.254.5
neighbor 10.10.254.1 default-originate
neighbor 10.10.254.1 route-map set-nexthop-ispb out
neighbor 10.10.254.1 filter-list 1 in
neighbor 10.10.254.1 filter-list 1 out
neighbor 10.10.254.1 ebgp-multihop
route-map set-nexthop-ispa permit 10
set ip next-hop 192.0.2.17
route-map set-nexthop-ispb permit 10
set ip next-hop 172.17.2.17
ip as-path access-list 1 deny .*
Auf unserem Router für das LAN sieht die BGP Konfiguration ebenso aus, ausser, dass natürlich die IP-Adressen und AS Nummern entsprechend anders rum sind:
hostname router.example.domain
password veryhard
router bgp 64591
bgp router-id 192.168.1.1
neighbor 10.10.255.5 remote-as 64590
neighbor 10.10.255.5 update-source 10.10.255.1
neighbor 10.10.255.5 route-map set-nexthop-ispa in
neighbor 10.10.255.5 filter-list 1 out
neighbor 10.10.255.5 ebgp-multihop
neighbor 10.10.254.5 remote-as 64590
neighbor 10.10.254.5 update-source 10.10.254.1
neighbor 10.10.254.5 route-map set-nexthop-ispb in
neighbor 10.10.254.5 filter-list 1 out
neighbor 10.10.254.5 ebgp-multihop
route-map set-nexthop-ispa permit 10
set ip next-hop 192.0.2.17
set local-preference 120
route-map set-nexthop-ispb permit 10
set ip next-hop 172.17.2.17
set local-preference 110
ip as-path access-list 1 deny .*
Hier müssen wir auch ein zebra.conf machen, und zebra laufen lassen:
hostname router.example.domain
password veryhard
interface eth0
description internal
interface eth1
description ispb
interface eth2
description ispa
Der Router erhält nun via BGP die default Route, wobei er mit Vorzug Provider A wählt aufgrund der local-preference. Wenn einer der beiden Links nun wegfällt, wird automatisch der andere genommen.
Das lokale LAN muss natürlich noch mit NAT versehen werden, dazu werden auf dem Router folgende Einträge gemacht:
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 -j SNAT --to-source 172.17.2.18
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth2 -j SNAT --to-source 192.0.2.18
Damit hat nun das interne LAN ein Multihoming für Arme. Der einzige Nachteil ist, dass bestehende Sessions einen Leitungsunterbruch nicht überleben.