Hallo zusammen,
ich denke ich habe jetzt das Problem im Griff. Ich würde meine Erkenntnisse teilen, daher hier nochmal abschließend eine Zusammenfassung:
Setup:
OS: FreeBSD 12.1
Netzwerktreiber: virtio
Produkt: Root-Server (Mega-Ei OST20)
IPv4: DHCP
IPv6: Statisch
DNS: Netcup
Problem:
Die statisch konfigurierte (nach Netcup Anleitung) IPv6 Verbindung ist nicht stabil. Der initiale Ping6 ist extrem verzögert und es kommt zu Paketverlusten. Dieses Phänomen tritt in unregelmäßigen Intervallen ca alle 5-30 Minuten auf. Noch "schlimmer" verhält es sich, wenn versucht wird von außen den Server via IPv6 zu pingen. Es kommt zu Paketverlusten, bis eine Verbindung zustande kommt. Es kam auch vor, dass gar keine Verbindung etabliert wurde.
Nach der Rückmeldung anderer *BSD Nutzer hier im Forum tritt das dort ebenfalls auf (soweit ich das gelesen habe).
Um eine Fehlkonfiguration von meiner Seite ausschließen zu können habe ich auch das FreeBSD 12.1 Image von Netcup verwendet und konnte das Problem reproduzieren.
Analyse:
Disclaimer: Die Analyse beruht auf reinen Vermutungen. Ich habe leider von Netcup keine Informationen bekommen, ob diese Annahmen korrekt sind oder nicht.
Anfänglich hatte ich wie oben beschrieben die Vermutung, dass der Fehler im NDP liegt und die Einträge einfach nach sehr kurzer Zeit ungültig sind und dann wieder eine aus unerfindlichen Gründen lange Neighbor Discovery nötig ist. Diese Annahme war nicht korrekt. Nach weiterer Analyse konnte ich (mit Hilfe von Freunden) folgendes feststellen:
... Der Gateway für das IPv6 Subnet in dem mein RS hängt scheint 2a03:4000:42::2/48 zu sei; die Default Route liegt aber auf fe80::1%vtnet0. Im tcpdump konnte nun folgendes beobachtet werden: Der ping6 geht über die Default Route raus an google, dass ist soweit alles in Ordnung. Der Netcup Router schickt die Antwort aber über 2a03:4000:42::2 in dessem /48 Subnetz mein /64 Netz liegt und nicht über die Default Route fe80::1%vtnet0. Damit ist Ausgangsrichtung (an fe80::1%vtnet0) ungleich der Eingangsrichtung (zu meiner IP). FreeBSD und vermutlich auch die anderen *BSDs haben damit ein Problem. FreeBSD (*BSD) muss sich regelmäßig mit den beiden Routern sortieren. Sobald alles sortiert ist funktioniert IPv6 normal für eine gewisse Zeit. ...
Mehr kann man leider vom Server aus nicht wirklich feststellen.
Anmerkung: Dieses Phänomen tritt unter Linuxen nicht auftritt; im Rescue System (GRML Linux) ist nur der initiale Ping verzögert, danach funktioniert IPv6 wie es soll. Der IPv6 Stack der *BSDs entspricht der freien Referenzimplementierung des Kame-Projektes. Ob die Linux Distributionen sich ebenfalls nach dieser Implementierung richten ist mir unbekannt. Fakt ist, das Problem ist unter FreeBSD zu beobachten und unter GRML Linux nicht.
Zusätzlich gab es noch weitere Infos:
... Von dem was ich hier so gelesen habe ist das inkludierte v6 Netz geswitcht, jedes zus. erworbenes geroutet. Was das im Detail bedeutet weiß ich nicht, ich bin kein Netzwerkspezialist. ...
Lösung:
Wie von vmk und angeritten bereits erwähnt ist ein zusätzliches IPv6 Subnetz die Lösung. Wie KB19 es schon richtig geschrieben hat, bedeutet es:
... OK, das wird auf eine Adresse Deines primären Subnetzes geroutet, braucht also kein NDP für jede einzelne Adresse. ...
Zusatzinfo für alle die kein zusätzliches IPv6 Subnetz bekommen haben: Nachdem man das IPv6 Subnetz dem Server zugewiesen hat sind im SCP -> Netzwerk IPv6 zwei Subnetze gelistet. Zuerst das inkludierte Subnetz, mit der Info Gateway fe80::1. Für das zweite zusätzliche Subnetz bekommt man kein Gateway gelistet, sondern eine Routing to IPv6 Adresse. Diese Routing to IPv6 Adresse ist aus dem Adressbereich des inkludierten Netzes.
Wenn ich nun die Routing to Adresse als statische IPv6 Adresse auf dem Host eintrage bekomme ich eine stabile IPv6 Verbindung ohne initialem Lag, ohne irgendwelche Probleme. (Da das nirgends dokumentiert zu sein scheint hat es doch eine gewisse Zeit gebraucht um das herauszufinden). Auch sysctl net.inet6.icmp6.nd6_onlink_ns_rfc4861=1 ist dann nicht mehr nötig. Meine Vermutung ist, dass diese Routing to IPv6 mit dem zusätzlichen Subnetz im Routing von Netcup extra konfiguriert wird und das es dann einer Konfiguration entspricht mit dem FreeBSD (und hoffentlich auch die anderen) IPv6 Stack funktioniert.
Hinweis: Nach meinen Tests ist die Routing to Adresse die einzige, die problemfrei läuft. Alle anderen Adressen des Subnetzes haben weiterhin das oben beschriebene Problem. Wenn man aber mehr als eine IPv6 Adresse benötigt, z.B. für Jails, kann man problemlos die IPv6 Adressen des zusätzlichen Subnetzes verwenden. Knackpunkt hier: Das Netzwerkinterface (vtnet0 in meinem Fall) muss die Routing to Adresse haben und alle weiteren IPv6 Adressen (aus dem zusätzlichen Subnetz) können dann als alias zugefügt werden. Das ist wichtig, weil sonst logischerweise keine Route vom zusätzlichen Subnetz (über die Adresse des inkludierten Subnetzes) zum Default Gateway fe80::1 möglich ist.
Das Verhalten kann im Resuce System nachvollzogen werden:
1. Rescue System booten
2. ip -6 addr add [Subnetz ::2] dev ens3
3. ping6 heise.de
Der erste Ping ist verzögert und funktioniert danach (zumindest beim meinem RS). Memo die IP sollte nicht die Routing to Adresse sein.
1. Rescue System booten
2. ip -6 addr add [routing to] dev ens3
3. ping6 heise.de
Der erste Ping ist nicht verzögert. Alles funktioniert von anfang an.
Disclaimer: Wieso es funktioniert ist wieder eine Vermutung und ist keine von Netcup gesicherte Aussage.
Epilog
Ist bei allen Kunden im inkludierten IPv6 Subnetz der erste IPv6 Ping verzögert? Außerdem, wenn andere Kunden mit einem zusätzlichen IPv6 Subnetz das Verhalten im Rescue System nachvollziehen könnten und hier Feedback geben fände ich das sehr interessant.
Momentan ist dieser Lösungsweg nur ein 'works on my machine'. Falls diese Lösung anderen hilft wäre hier Feedback schön um den Lösungsweg zu legitimieren.
Beste Grüße
PS: Sorry für die wall of text