Dies ist eine Geschichte von der Suche nach dem perfekten Tunnel.
Ich bin, mühsam ernährt sich das einsame Eichhörnchen, nach wie vor dabei, die von Ralf und Flo vor geraumer Zeit ausgeheckte Netzwerkstruktur für Freifunk Gütersloh umzusetzen. Mittlerweile habe ich auch einen unserer zwei BGP-Hosts »fast« so, wie ich ihn haben möchte, und dies auf Basis von puppet-Code. Ist ja schon mal was ;) Auch hat dieser Host einen Tunnel zwecks IPv4-Exit zum Freifunk Rheinland e. V. am Start, und auch jene separate BGP-Session scheint soweit zu tun (yeah!) ;)
Aber das bringt mich dann wieder zurück auf »Square One«, auf’s erste Feld also: ich möchte zumindest innerhalb unseres Netzes keine MTU <1500 fahren, weil es für UDP (bei IPv4) keine gesicherte Möglichkeit der MTU-Erkennung gibt (und die Krücken für TCPv4 sind auch bäh, wenngleich sie ja funktionieren).
Ziemlich angenervt haben mich bei der Suche so tolle Artikel wie dieser hier: OpenWRT Transparent Network Bridging Using GRE. GRETAP verwenden, selbst auf die MTU <1500 hinweisen, aber von einem transparenten Bridging sprechen. Ja nee, iss klar :(
Checking GRE Interface
root@wap1:~# ip link show gretap0 27: gretap0@NONE: mtu 1462 qdisc pfifo_fast state UNKNOWN mode DEFAULT qlen 1000 link/ether ee:d1:62:da:af:7f brd ff:ff:ff:ff:ff:ff
GRETAP jedenfalls ist nicht die Lösung, und zum Versuch, mit NOPMTUDISC einen normalen GRE-Tunnel aufzubauen, der dann bei Bedarf fragmentieren sollte, unten mehr. GRE scheint mir unter Linux eine lange; traurige Geschichte zu sein — bei Cisco geht das ja mit dem zwangsweisen Fragmentieren und neu setzen der TTL :-(
Gut, eine, wenn auch etwas komplexe, Lösung scheint es zu geben; ›einfach‹ das DF-Flag löschen. Das ist allerdings ein ziemlicher Eingriff in den Datenstrom (das orginäre Paket wird verändert, batman_adv oder auch OpenVPN greifen nur für den Transport auf Fragmentierung zurück, IIRC), der vom »Pico-Peering-Agreement« kaum gedeckt und aus Netzneutralitätssicht kaum zu befürworten ist :(
fastd, diese tinc-Alternative aus Gluon, kann leider auch nicht intern fragmentieren, und mangels Zeit des Entwicklers wird es wohl auch bis zum Jahresende dauern, bis dieses Feature endlich verfügbar ist — und was machen wir bis dahin? Ich kann schon verstehen, warum viel mit GRE gemacht wird; nur in der aktuellen Linux-Implementation ist es einfach untauglich, da unfähig, eine 1500er MTU nicht zu zerstören.

Um zwischen verschiedenen Netzen zu routen, brauche ich eine Verbindung; und da wir hier von einem Setup reden, wo mehrere VMs im gleichen IP-Adressbereich stehen, kommen wir um die Simulierung von Punkt-zu-Punkt-Verbindungen per Tunneln kaum umhin. Hinzu kommt, daß nicht alle Systeme im gleichen (V)LAN im gleichen DC stehen — mit 2-3 VMs bei Hetzner und dem Rest bei Telefónica wird auch hier ohne »virtuelle Kabel«, also Tunnel, das Zusammenspiel schwierig.
Technisch heißt das aber auch, daß die Datenpakete über diese Pfade, durch diese Tunnel also, fließen. Und da GRE wie GRETAP keine kompletten Ethernet-Pakete transportieren kann, halte ich diese Lösung für minderwertig. Andererseits lebe ich seit etlichen Jahren zu Hause mit einer MTU von 1492 — Telekom (V)DSL knabbert, eigentlich unverständlicherweise, ja auch an der MTU. Wobei: für alles, was mir wichtig ist, habe ich seit zig Jahren einen OpenVPN-Tunnel mit meinen PI-Adressen, der mit einer MTU von 1500 (über die auf 1492 Bytes begrenzte DSL-Leitung) hervorragend funktioniert …
Alles also nur Schall und Rauch? Fakt ist: wollen wir bei Freifunk Gütersloh den IPv4-Exit via Freifunk Rheinland e. V. nutzen, geht das nur mit einer MTU von 1400 (man hat aus GRE-in-GRE-Problemen wohl gelernt und ›garantiert‹ nur noch 1400 Bytes). Insofern erscheint eine MTU von 1476 Bytes gar nicht soo schlecht …
Bei GRE mit Linux gibt’s aber 2015, so scheint es, nur die Wahl zwischen Pest und Cholera; entweder begrenzte MTU, dafür tut traceroute …
root@gw01:~# traceroute -T -s 10.255.255.1 -m 50 ns.uu.net 1500 traceroute to ns.uu.net (137.39.1.3), 50 hops max, 60 byte packets 1 100.64.1.1 (100.64.1.1) 15.113 ms 15.108 ms 15.831 ms 2 100.64.0.178 (100.64.0.178) 21.471 ms 21.469 ms 21.466 ms 3 irb-1050.bb-a.fra3.fra.de.oneandone.net (195.20.242.193) 21.463 ms 21.459 ms 21.456 ms 4 xe-3-1-0-276.fra20.ip4.tinet.net (213.200.65.201) 21.453 ms 21.449 ms 21.477 ms 5 was14.ip4.gtt.net (141.136.111.165) 113.458 ms 113.454 ms 113.452 ms 6 0.xe-2-1-1.GW9.IAD8.ALTER.NET (152.179.50.29) 116.606 ms 116.750 ms 116.685 ms 7 0.xe-7-1-8.XT3.ATL5.ALTER.NET (152.63.5.202) 132.093 ms 0.xe-2-0-4.XT4.ATL5.ALTER.NET (152.63.82.5) 155.717 ms 155.665 ms 8 POS6-0.GW1.ATL5.ALTER.NET (152.63.80.129) 132.408 ms POS7-0.GW1.ATL5.ALTER.NET (152.63.80.141) 129.661 ms 129.865 ms 9 pos5-0.soesr1.atl5.maint.ops.us.uu.net (207.18.172.234) 132.629 ms 130.734 ms 133.137 ms 10 ns.UU.NET (137.39.1.3) 130.641 ms 132.044 ms 132.448 ms root@gw01:~# ping -c 5 -Mwant -I 10.255.255.1 -s 1500 137.39.1.3 PING 137.39.1.3 (137.39.1.3) from 10.255.255.1 : 1500(1528) bytes of data. From 10.255.255.1 icmp_seq=1 Frag needed and DF set (mtu = 1476) 1508 bytes from 10.255.255.1: icmp_seq=4 ttl=241 time=133 ms 1508 bytes from 10.255.255.1: icmp_seq=5 ttl=241 time=133 ms --- 137.39.1.3 ping statistics --- 5 packets transmitted, 2 received, +1 errors, 60% packet loss, time 4017ms
… oder GRE splittet die Pakete auf (was den Vorteil hat, daß sie dann vielleicht auch durch nachfolgende Nadelöhre passen), behält dann aber die TTL bei, was zu kaputtem traceroute führt:
root@gw01:~# traceroute -T -s 10.255.255.1 -m 50 ns.uu.net 1500 traceroute to ns.uu.net (137.39.1.3), 50 hops max, 60 byte packets 1 * * * 2 * * * […] 15 * * * 16 ns.UU.NET (137.39.1.3) 132.132 ms 133.886 ms 132.269 ms root@gw01:~# ping -c 5 -Mwant -I 10.255.255.1 -s 1500 137.39.1.3 PING 137.39.1.3 (137.39.1.3) from 10.255.255.1 : 1500(1528) bytes of data. 1508 bytes from 137.39.1.3: icmp_seq=2 ttl=241 time=133 ms 1508 bytes from 137.39.1.3: icmp_seq=3 ttl=241 time=133 ms 1508 bytes from 137.39.1.3: icmp_seq=4 ttl=241 time=133 ms 1508 bytes from 137.39.1.3: icmp_seq=5 ttl=241 time=133 ms --- 137.39.1.3 ping statistics --- 5 packets transmitted, 4 received, 20% packet loss, time 4011ms rtt min/avg/max/mdev = 133.551/133.767/133.934/0.299 ms
Um kein undokumentiertes Feature zu verpassen, habe ich auch ›nopmtudisc‹ mit ›ttl 64‹ versucht — und einen Typo in der Fehlermeldung gefunden ;)
root@gw01:~# ifup test
ttl != 0 and noptmudisc are incompatible
Failed to bring up test.
root@gw01:~# strings `which iptunnel` | grep disc
nopmtudisc
[ ttl TTL ] [ tos TOS ] [ nopmtudisc ] [ dev PHYS_DEV ]
ttl != 0 and noptmudisc are incompatible
Vorteil von GRE ist, daß es aus puppet einfach so rausfallen kann; für OpenVPN bräuchte ich einen Key-Austausch (oder alle Links arbeiten mit dem gleichen pre-shared Key, an sich ist Verschlüsselung ja eh’ nicht benötigt an der Stelle). Dann wiederum ist GRE aber IIRC ein Kernel-Modul, wohingegen OpenVPN im Userspace abläuft; der Overhead bei GRE je IP-Paket sollte daher geringer sein, die CPU-Belastung entsprechend ebenso etwas geringer. »Was tun?« sprach Zeus …
