ASA und der Heisenbug mit der Default Route

Ein Kunde hat nach einem Umbau am Außenanschluss massive Probleme mit der Stabilität der IPv6 Versorgung. Nach nächtlicher Inaktivität ist am folgenden Morgen keine IPv6 Kommunikation möglich. Beginnt man auf der ASA zu debuggen, verschwindet das Problem sofort.

Heisenbergsches Nichts

Zunächst stellt sich die Frage, was denn so spannendes in der Nacht passiert sein kann. Eigentlich nichts.

Genau das ist das Problem. Es ist nichts passiert. Genau deswegen geht es nicht mehr. Zur Überprüfung lösche ich den IPv6 Nachbarschafts-Cache und das Problem tritt sofort wieder auf. Der IPv6 Nachbarschaftseintrag für das default Gateway will und will nicht wieder kommen.

Pingt man von der ASA aus ein externes Ziel an, verschwindet das Problem instantan. Auch der IPv6 Nachbarschaftseintrag ist wieder vorhanden.

Das Problem kann also kontrolliert ein- und ausgeschaltet werden. Damit ist der Heisenbug in einen Bohrbug verwandelt und die Suche kann beginnen.

Gestörte Nachbarschaft

Zuerst aktiviere ich das Debugging für IPv6 Nachbarschaftskram.

asa# debug ipv6 nd
asa# debug ipv6 icmp
asa# clear ipv6 neighbors
ICMPv6-ND: DELETE -> INCMP: 2001:db8:700:1d::1
ICMPv6-ND: Sending NS for 2001:db8:700:1d::1 on outside
ICMPv6-ND: Sending NS for 2001:db8:700:1d::1 on outside
ICMPv6-ND: Sending NS for 2001:db8:700:1d::1 on outside
ICMPv6-ND: INCMP deleted: 2001:db8:700:1d::1
ICMPv6-ND: INCMP -> DELETE: 2001:db8:700:1d::1
ICMPv6-ND: DELETE -> INCMP: 2001:db8:700:1d::1
ICMPv6-ND: Sending NS for 2001:db8:700:1d::1 on outside
ICMPv6-ND: Sending NS for 2001:db8:700:1d::1 on outside
ICMPv6-ND: Sending NS for 2001:db8:700:1d::1 on outside
ICMPv6-ND: INCMP deleted: 2001:db8:700:1d::1
ICMPv6-ND: INCMP -> DELETE: 2001:db8:700:1d::1
ICMPv6-ND: DELETE -> INCMP: 2001:db8:700:1d::1

Das Spiel wiederholt sich endlos.

Die ASA benötigt den Nachbarschaftseintrag des Default Gatways, der gerade fehlt (DELETE), und versucht dann per Neighbour Solication (NS) wieder die MAC zur IP zu ermitteln (INCoMPlete).

Allerdings bekommt sie keine Antwort zurück.

Also jetzt mal von der ASA aus pingen:

asa# ping 2001:db8::1
ICMPv6: Sending echo request to 2001:db8::1
ICMPv6-ND: INCMP deleted: 2001:db8:700:1d::1
ICMPv6-ND: INCMP -> DELETE: 2001:db8:700:1d::1
ICMPv6-ND: DELETE -> INCMP: 2001:db8:700:1d::1
ICMPv6-ND: Sending NS for 2001:db8:700:1d::1 on outside
ICMPv6-ND: Sending NS for 2001:db8:700:1d::1 on outside
?

Es fehlt nach wie vor die Antwort vom gegenüber liegenden Router. Deswegen schreibt der Ping sein erstes "?" hin.

ICMPv6: Sending echo request to 2001:db8::1
ICMPv6-ND: Sending NS for 2001:db8:700:1d::1 on outside
ICMPv6: Received ICMPv6 packet from 2001:db8:700:1d::1, type 136

Und auf einmal ist die Antwort da!

Sofort macht sich die ASA über die Rückmeldung her:

ICMPv6-ND: Received NA for 2001:db8:700:1d::1 on outside from 2001:db8:700:1d::1
ICMPv6-ND: INCMP -> REACH: 2001:db8:700:1d::1
ICMPv6: Received ICMPv6 packet from 2001:db8::1, type 129
ICMPv6: Received echo reply from 2001:4bd8::1
!

Das Ping Echo ist zurück, es schreibt ein "!" auf die Zeile und alles geht wieder.

Wenn man jetzt mal genau hinschaut, erkennt man deutlich den Unterschied zwischen den unbeantworteten Anfragen und der erfolgreichen Anfrage.

Ganz genau hinschauen! Sieht man's?

Der kleine Unterschied

Genau, da ist kein Unterschied.

Aber es muss etwas geben, was den Effekt auslöst. Also muss man noch genauer hinschauen.

asa(conf)# access-list debug-38594 extended permit icmp6 any6 any6 neighbor-advertisement 
asa(conf)# access-list debug-38594 extended permit icmp6 any6 any6 neighbor-redirect 
asa(conf)# access-list debug-38594 extended permit icmp6 any6 any6 neighbor-solicitation 
asa(conf)# access-list debug-38594 extended permit icmp6 any6 any6 router-advertisement 
asa(conf)# access-list debug-38594 extended permit icmp6 any6 any6 router-renumbering 
asa(conf)# access-list debug-38594 extended permit icmp6 any6 any6 router-solicitation
asa# capture d-38594 access-list debug-38594 packet-length 1500 interface outside circular-buffer

Es werden alle Nachbarschafts- und Router-Nachrichten mitgeschnitten. In voller Länge, damit man auch was sehen kann.

Und nun schauen wir mal nach den fehlenden Details:

asa# show capture d-38594 detail
17: 07:36:17.423180 6412.25e3.e7fd 3333.ff00.0001 0x86dd Length: 86
 fe80::6400:0 > ff02::1:ff00:1: icmp6: neighbor sol:
 who has 2001:db8:700:1d::1(src lladdr: 64:12:25:e3:e7:fd) [class 0xe0] (len 32, hlim255)

18: 07:36:17.433342 203a.0762.b442 6412.25e3.e7fd 0x86dd Length: 86
 2001:db8:700:1d::1 > fe80::6400:0: icmp6: neighbor adv:
 tgt is 2001:db8:700:1d::1(RSO)(tgt lladdr: 20:3a:07:62:b4:42) [class 0xe0] (len 32,hlim 255)

19: 07:36:18.415887 6412.25e3.e7fd 3333.ff00.0001 0x86dd Length: 86
 fe80::6400:0 > ff02::1:ff00:1: icmp6: neighbor sol:
 who has 2001:db8:700:1d::1(src lladdr: 64:12:25:e3:e7:fd) [class 0xe0] (len 32, hlim255)

20: 07:36:18.423211 203a.0762.b442 6412.25e3.e7fd 0x86dd Length: 86
 2001:db8:700:1d::1 > fe80::6400:0: icmp6: neighbor adv:
 tgt is 2001:db8:700:1d::1(RSO)(tgt lladdr: 20:3a:07:62:b4:42) [class 0xe0] (len 32,hlim 255)

21: 07:36:19.415887 6412.25e3.e7fd 3333.ff00.0001 0x86dd Length: 86
 fe80::6400:0 > ff02::1:ff00:1: icmp6: neighbor sol:
 who has 2001:db8:700:1d::1(src lladdr: 64:12:25:e3:e7:fd) [class 0xe0] (len 32, hlim255)

22: 07:36:19.421441 203a.0762.b442 6412.25e3.e7fd 0x86dd Length: 86
 2001:db8:700:1d::1 > fe80::6400:0: icmp6: neighbor adv:
 tgt is 2001:db8:700:1d::1(RSO)(tgt lladdr: 20:3a:07:62:b4:42) [class 0xe0] (len 32,hlim 255)

23: 07:36:20.422921 6412.25e3.e7fd 3333.ff00.0001 0x86dd Length: 86
 fe80::6400:0 > ff02::1:ff00:1: icmp6: neighbor sol:
 who has 2001:db8:700:1d::1(src lladdr: 64:12:25:e3:e7:fd) [class 0xe0] (len 32, hlim255)

24: 07:36:20.428124 203a.0762.b442 6412.25e3.e7fd 0x86dd Length: 86
 2001:db8:700:1d::1 > fe80::6400:0: icmp6: neighbor adv:
 tgt is 2001:db8:700:1d::1(RSO)(tgt lladdr: 20:3a:07:62:b4:42) [class 0xe0] (len 32,hlim 255)

25: 07:36:21.415856 6412.25e3.e7fd 3333.ff00.0001 0x86dd Length: 86
 fe80::6400:0 > ff02::1:ff00:1: icmp6: neighbor sol:
 who has 2001:db8:700:1d::1(src lladdr: 64:12:25:e3:e7:fd) [class 0xe0] (len 32, hlim255)

26: 07:36:21.419350 203a.0762.b442 6412.25e3.e7fd 0x86dd Length: 86
 2001:db8:700:1d::1 > fe80::6400:0: icmp6: neighbor adv:
 tgt is 2001:db8:700:1d::1(RSO)(tgt lladdr: 20:3a:07:62:b4:42) [class 0xe0] (len 32,hlim 255) 

Die ASA (fe80::6400:0) fragt per Link-Local Multicast (ff02::1:ff00:1) nach der MAC zur IP 2001:db8:700:1d::1. Soweit war das im Debug schon zu sehen.

Überraschenderweise antwortet die Zielmaschine (2001:db8:700:1d::1) der ASA (fe80::6400:0) mit den gewünschten Daten.

Das bedeutet, dass trotz Umbaus am Uplink keine Störung dort vorliegt: Die Antworten kommen an!

Und es bedeutet weiter, dass es allein ein Problem der ASA ist, was hier abgeht.

Als nächstes wird ein Ping von der ASA aus probiert:

27: 07:36:22.396021 6412.25e3.e7fd 203a.0762.b442 0x86dd Length: 86
 fe80::6400:0 > fe80::223a:7ff:fe62:b442: icmp6: neighbor sol:
 who has fe80::223a:7ff:fe62:b442(src lladdr: 64:12:25:e3:e7:fd) [class 0xe0] (len 32,hlim 255)

28: 07:36:22.399408 203a.0762.b442 6412.25e3.e7fd 0x86dd Length: 78
 fe80::223a:7ff:fe62:b442 > fe80::6400:0: icmp6: neighbor adv:
 tgt is fe80::223a:7ff:fe62:b442(RS) [class 0xe0] (len 24, hlim 255)

29: 07:36:22.416009 6412.25e3.e7fd 3333.ff00.0001 0x86dd Length: 86
 2001:db8:700:1d::2 > ff02::1:ff00:1: icmp6: neighbor sol:
 who has 2001:db8:700:1d::1(src lladdr: 64:12:25:e3:e7:fd) [class 0xe0] (len 32, hlim255)

30: 07:36:22.425988 203a.0762.b442 6412.25e3.e7fd 0x86dd Length: 86
 2001:db8:700:1d::1 > 2001:1438:700:1d::2: icmp6: neighbor adv:
 tgt is 2001:db8:700:1d::1(RSO)(tgt lladdr: 20:3a:07:62:b4:42) [class 0xe0] (len 32,hlim 255)

Zuerst kommt ein Abgleich der Nachbarschaftsbeziehung zwischen den Link-Local-Adressen selbst. Dieser funktioniert.

Und spontan ist die folgende Antwort für die ASA akzeptabel.

Das Problem besteht darin, dass die ASA für durchgereichten Datenverkehr die ND nach dem Default-GW mit der Quell-IP fe80::xxx macht, und dann die Antwort ignoriert. Wenn Sie dagegen selbst pingt, ist die Quell-IP des ND allerdings 2001:... und dann akzeptiert sie auch die Antwort.

Und wie sieht man das in dem Ausgabewust (der hier gekürzt ist)? Mit sort | uniq -c.

Auf der Zielgeraden

Ich hab' mal mit der link-lokal Adresse als Default-Route gespielt, weil ja offenbar kein Problem besteht, die MAC einer Link-Local Adresse zu ermitteln.

Es tritt das gleiche Problem auf:

5081: 11:22:27.164588 6412.25e3.e7fd 3333.ff62.b442 0x86dd Length: 86
 fe80::6400:0 > ff02::1:ff62:b442: icmp6: neighbor sol:
 who has fe80::223a:7ff:fe62:b442(src lladdr: 64:12:25:e3:e7:fd) [class 0xe0] (len 32,hlim 255)

5082: 11:22:27.167609 203a.0762.b442 6412.25e3.e7fd 0x86dd Length: 86
 fe80::223a:7ff:fe62:b442 > fe80::6400:0: icmp6: neighbor adv:
 tgt is fe80::223a:7ff:fe62:b442(RSO)(tgt lladdr: 20:3a:07:62:b4:42) [class 0xe0] (len32, hlim 255)

5083: 11:22:28.164557 6412.25e3.e7fd 3333.ff62.b442 0x86dd Length: 86
 fe80::6400:0 > ff02::1:ff62:b442: icmp6: neighbor sol:
 who has fe80::223a:7ff:fe62:b442(src lladdr: 64:12:25:e3:e7:fd) [class 0xe0] (len 32,hlim 255)

5084: 11:22:28.165869 203a.0762.b442 6412.25e3.e7fd 0x86dd Length: 86
 fe80::223a:7ff:fe62:b442 > fe80::6400:0: icmp6: neighbor adv:
 tgt is fe80::223a:7ff:fe62:b442(RSO)(tgt lladdr: 20:3a:07:62:b4:42) [class 0xe0] (len32, hlim 255)

5085: 11:22:29.173925 6412.25e3.e7fd 3333.ff62.b442 0x86dd Length: 86
 fe80::6400:0 > ff02::1:ff62:b442: icmp6: neighbor sol:
 who has fe80::223a:7ff:fe62:b442(src lladdr: 64:12:25:e3:e7:fd) [class 0xe0] (len 32,hlim 255)

5086: 11:22:29.180914 203a.0762.b442 6412.25e3.e7fd 0x86dd Length: 86
 fe80::223a:7ff:fe62:b442 > fe80::6400:0: icmp6: neighbor adv:
 tgt is fe80::223a:7ff:fe62:b442(RSO)(tgt lladdr: 20:3a:07:62:b4:42) [class 0xe0] (len32, hlim 255)

Wie bisher: Anfrage von Link-Local wird beantwortet, aber seitens der ASA nicht verarbeitet.

5087: 11:22:30.164664 6412.25e3.e7fd 3333.ff62.b442 0x86dd Length: 86
 2001:db8:700:1d::2 > ff02::1:ff62:b442: icmp6: neighbor sol:
 who has fe80::223a:7ff:fe62:b442(src lladdr: 64:12:25:e3:e7:fd) [class 0xe0] (len 32,hlim 255)

5088: 11:22:30.172262 203a.0762.b442 6412.25e3.e7fd 0x86dd Length: 86
 fe80::223a:7ff:fe62:b442 > 2001:db8:700:1d::2: icmp6: neighbor adv:
 tgt is fe80::223a:7ff:fe62:b442(RSO)(tgt lladdr: 20:3a:07:62:b4:42) [class 0xe0](len 32, hlim 255)

Wenn die ASA aber mit ihrer offiziellen Adresse anfragt, gibt es kein Problem.

Und noch etwas fällt auf:

5089: 11:22:31.194234 203a.0762.b442 6412.25e3.e7fd 0x86dd Length: 86
 fe80::223a:7ff:fe62:b442 > fe80::6400:0: icmp6: neighbor sol:
 who has fe80::6400:0(src lladdr: 20:3a:07:62:b4:42) [class 0xe0] (len 32, hlim 255)

5090: 11:22:32.200871 203a.0762.b442 6412.25e3.e7fd 0x86dd Length: 86
 fe80::223a:7ff:fe62:b442 > fe80::6400:0: icmp6: neighbor sol:
 who has fe80::6400:0(src lladdr: 20:3a:07:62:b4:42) [class 0xe0] (len 32, hlim 255)

5091: 11:22:33.207508 203a.0762.b442 6412.25e3.e7fd 0x86dd Length: 86
 fe80::223a:7ff:fe62:b442 > fe80::6400:0: icmp6: neighbor sol:
 who has fe80::6400:0(src lladdr: 20:3a:07:62:b4:42) [class 0xe0] (len 32, hlim 255)

Umgekehrt mag sie auch nicht auf Anfragen nach ihrer eigenen Link-Local Adresse antworten. Das gilt inbesondere auch dann, wenn das Paket schon an sie selbst adressiert ist.

5092: 11:22:35.178915 203a.0762.b442 6412.25e3.e7fd 0x86dd Length: 86
 fe80::223a:7ff:fe62:b442 > 2001:db8:700:1d::2: icmp6: neighbor sol:
 who has 2001:db8:700:1d::2(src lladdr: 20:3a:07:62:b4:42) [class 0xe0] (len 32,hlim 255)

5093: 11:22:35.179464 6412.25e3.e7fd 203a.0762.b442 0x86dd Length: 78
 2001:db8:700:1d::2 > fe80::223a:7ff:fe62:b442: icmp6: neighbor adv:
 tgt is 2001:db8:700:1d::2(RS) [class 0xe0] (len 24, hlim 255)

Wohl aber antwortet sie auf die Anfrage an ihre offizielle IP nach ihrer offiziellen IP.

Es scheint so, als ob die ASA die eigene Link-Local Adresse nicht mag.

Der Fehler scheint darin zu bestehen, dass die Link-Local Adresse auf der ASA nicht geändert werden darf. Warum auch immer.

Normalerweise habe ich händisch vergebene Link-Local Adressen nach dem Schema fe80::Gerät:Interface, was die Routingtabellen schön lesbar macht.

Also habe ich die Link-Local Adresse auf "system-default" gestellt und es scheint zu gehen. Selbst nach einem Löschen der Nachbarschafts-Caches erholt sich das System binnen Sekundenfrist von allein.

5123: 14:20:32.560914 6412.25e3.e7fd 3333.ff00.0001 0x86dd Length: 86
 fe80::6612:25ff:fee3:e7fd > ff02::1:ff00:1: icmp6: neighbor sol:
 who has 2001:db8:700:1d::1(src lladdr: 64:12:25:e3:e7:fd) [class 0xe0] (len 32, hlim255)

5124: 14:20:32.569077 203a.0762.b442 6412.25e3.e7fd 0x86dd Length: 86
 2001:db8:700:1d::1 > fe80::6612:25ff:fee3:e7fd: icmp6: neighbor adv:
 tgt is 2001:db8:700:1d::1(RSO)(tgt lladdr: 20:3a:07:62:b4:42) [class 0xe0] (len 32,hlim 255) 

Ein schöner Bug, Cisco.

Avatar
Marcus 04.09.2017 21:35
Wo ich gerade grinsen musste:

Normalerweise habe ich händisch vergebene Link-Local Adressen nach dem Scheme fe80::<geraet>:<interface/vlan>, was die Routingtabellen schön lesbar macht.

Das muss man ja dreimal "unquoten" um den Inhalt lesbar zu machen ;-)

Ciao
Marcus
Avatar
Dietz 25.08.2017 17:44
Ich möcht' ja nicht nörgeln, aber Du hattest keinen Heisenbug. Das war vielmehr ein Mandelbug (d.h. ein Bohrbug, der zunächst wie ein Heisenbug aussah) ;-).

2 Kommentare

Post a comment

Verwandter Inhalt