Nachdem ich im dritten Teil dieser Beitragsreihe erneut einen langen Kampf mit dem Sophos Technical Support führen musste, befinden wir uns nun endlich auf der Zielgeraden:
Our development team has provided an update. Please let us know when you are available for a live remote session to address this issue.
Ganz so nah war ich der Problemlösung allerdings doch noch nicht, denn an dieser Stelle gab es erst mal eine Lektion Englisch für mich: Wie sich herausstellte, meinte der GES Engineer mit „Our development team has provided an update.“ nicht, dass ich ein Update bekomme, sondern einfach nur dass es Neuigkeiten gibt. 😀
Die Neuigkeiten sahen wie folgt aus: Man hatte ein Labor-Setup zwischen zwei XGS-Geräten aufgebaut und …Überraschung… alles funktionierte wie es soll. Warum es im Realbetrieb mit der ASA nicht funktioniert, hatte man nun auch herausgefunden. In den Logs der XGS tauchte nach kurzer Trennung der Internetverbindung und anschließendem Wiederaufbau nämlich die folgende Zeile auf:
2024-03-08 08:04:03Z 30[IKE] <Tunnel_1> received DELETE for ESP CHILD_SA with SPI 947d7842
Meiner Meinung nach ist das nicht wirklich verwunderlich. Wenn eine Unterbrechung der Internetverbindung zwischen den Peers auftritt, führen beide für sich Dead Peer Detection aus. Je nach genauer Konfiguration der Timer, ist es dabei durchaus denkbar, dass die ASA bereits erkannt hat, dass die Gegenseite nicht mehr erreichbar ist, die XGS jedoch noch einige Sekunden wartet, bevor sie eine weitere R-U-THERE Nachricht schicken wird. Wenn in diesem Moment die Unterbrechung der Verbindung zu Ende geht, hat die XGS noch immer aktive SAs, während die ASA diese bereits gelöscht hat. Wenn nun die ESP-Pakete der XGS bei der ASA ankommen, ist deren SPI für die ASA unbekannt. Durchaus nachvollziehbar, dass sie dann mit einem DELETE reagiert. Das verbietet der XGS aber nicht, einfach eine neue SA aufzubauen. Doch genau das war offenbar der Fall. Mit Empfang des DELETEs stellte die XGS jeden Versuch zum Aufbau einer neuen SA ein.
Das gilt übrigens auch ohne DPD und ohne Unterbrechung der Internetverbindung. Bei einem Site-to-site VPN sind beide Peers gleichberechtigt, daher kommt auch der „symmetrische“ Name. Das heißt, dass beide Seiten SAs auf- und abbauen dürfen, wann immer sie möchten. Auch wenn die Config-Dialoge das oft anders suggerieren: Die Rollenverteilung von Initiator und Responder ist nicht fest auf die Peers verteilt. Der Initiator einer SA ist der, der das erste Paket im Verbindungsaufbau dieser SA geschickt hat. Für eine andere SA – ob IKE SA oder Child SA – können die Rollen vertauscht sein. Und nirgends in den RFCs steht, dass ein DELETE nur vom Initiator ausgehen darf. Ich erinnere an dieser Stelle nochmal an den Hinweis meines Kollegen Lutz aus dem dritten Teil. Direkt in der Einleitung von RFC 4718 – IKEv2 Clarifications and Implementation Guidelines steht:
IKEv2/IPsec can be used for several different purposes, including IPsec-based remote access (sometimes called the „road warrior“ case), site-to-site virtual private networks (VPNs), and host-to-host protection of application traffic. While this document attempts to consider all of these uses, the remote access scenario has perhaps received more attention here than the other uses.
Im „Road Warrior“ Szenario ist natürlich der Road Warrior der Initiator und das VPN-Gateway in der Firmenzentrale der Responder. Anders kann es nicht funktionieren. Aber diese Denkweise haben offenbar viele fälschlicherweise auf den Site-to-site Fall übertragen. Da ich mittlerweile so gern aus RFCs zitiere, noch zwei Beispiele aus den Abschnitten 5.6. Deleting vs. Closing SAs und 5.7. Deleting a CHILD_SA Pair:
5.6. Deleting vs. Closing SAs
[…] In particular, Section 2.4 says that „If an IKE endpoint chooses to delete CHILD_SAs, it MUST send Delete payloads to the other end notifying it of the deletion“.
[…]
5.7. Deleting a CHILD_SA Pair
Section 1.4 describes how to delete SA pairs using the Informational exchange: „To delete an SA, an INFORMATIONAL exchange with one or more delete payloads is sent listing the SPIs (as they would be expected in the headers of inbound packets) of the SAs to be deleted. The recipient MUST close the designated SAs.“
Einerseits besagt das Zitat aus Abschnitt 5.6, dass ein IKE Endpoint ein DELETE senden muss, wenn er eine Child SA löschen will. Die Motivation, weshalb er das tun will – ausgelöst durch DPD oder was auch immer – spielt dabei keine Rolle. Anderseits geht es in den beiden Abschnitten um die konkrete Formulierung: Mit „an IKE endpoint“ ist nicht ausschließlich der Initiator und mit „the recepient“ nicht ausschließlich der Responder gemeint. Und insbesondere ist der Empfang eines DELETEs kein Verbot für den Empfänger, einen erneuten Tunnelaufbau zu initiieren. Die strongSwan-Einstellung closeaction=restart
(„Action to perform after a CHILD_SA gets closed by the peer.“, vgl. swanctl.conf) sollte ja eigentlich genau diesen erneuten Tunnelaufbau übernehmen…
Die oben erwähnte Live Session kam dann also zustande, wir simulierten einen Ausfall der Internetverbindung und das DELETE tauchte reproduzierbar erneut auf. Das wollte man mir natürlich als Bug in der ASA verkaufen. Ich solle doch bitte einen Case beim Cisco Support öffnen… Anstatt noch weitere Energie in das Ping Pong von RFC-Zitaten zu verschwenden, nutzte ich den Live Termin einfach, um zu demonstrieren, dass die Config-Änderung auto=route
das Problem ganz einfach löst: ein Einzeiler behebt das gesamte „Feature Gap“. Und das kam scheinbar gar nicht so schlecht an. Wenige Tage später:
In reference to the feature request, you had correctly identified the strongSwan trap feature (auto=route) in the XG device. This feature would be a valuable addition to SFOS.
Nach fast zwei Wochen Funkstille kam dann endlich die erlösende Nachricht:
Danach ging alles ganz schnell: Man holte mein Einverständnis ein, der Patch wurde durch Sophos über den Support Access installiert und nach einem Reboot enthielten die Config-Files nun die Einstellung auto=route
. Und das funktionierte genau so, wie bereits zuvor getestet. Ich antwortete also:
I am glad to inform you that, with parameter auto set to route, our problem is solved.
After an ISP disruption, the tunnels remain red which means that the dpdaction still does not work as expected. Probably, this is caused by the DELETE which is sent from the ASA site. But as I argued before, DPD paremeters are not negotiated between the peers. So it is quite expectable that one peer assumes the other as dead (and removes the SAs) while the other does not assume its peer as dead yet (and therefore still holds the SAs). If it now sends traffic through these SAs, the other peer doesn’t have key material anymore. So the traffic basically gets blackholed. The receiving peer may notify the sending peer about this circumstance by answering with a DELETE payload. That’s the reason why I do not consider the ASA‘s DELETE as a problem. The problem is that StrongSwan stops SA establishment after receiving that DELETE.
But as I wrote above, our problem is solved because with parameter auto set to route, StrongSwan installs a trap policy for the remote networks. I can now simply issue a ping from a machine located in the branch and StrongSwan tries to create a new SA. So you basically implemented the feature request.
Schließlich wurde mir der Patch zum Download zur Verfügung gestellt. Allerdings ist dieser versionsgebunden für SFOS V20.0.0 GA. Führt man ein Update auf Version 20 MR1 aus, welche mittlerweile veröffentlicht wurde, wird der Patch deaktiviert. So zumindest die Aussage von Sophos, geprüft habe ich das nicht.
Während des Rollouts kam es hier und da nochmal zu einem kleinen „Schluckauf“: Einige Child SAs konnten nicht ausgehandelt werden. Die ASA zeigte folgende Fehlermeldung im Log:
IKEv2-PLAT-2: (5301): Rejecting child SA with the same traffic selectors as existing child SA.
Im Detail habe ich das nicht untersucht. Vermutlich überlagerten sich die Trap Policies der XGS irgendwie mit der dpdaction
. Es war also nahe liegend, die Einstellung „Wenn Peer unerreichbar“ im IPsec-Profil von „Neu initiieren“ auf „Verbindung trennen“ umzustellen (vgl. Abbildung 1). Wie ich aber feststellen musste, hat dieser Parameter in SFOS V20.0.0 GA exakt keine Wirkung. Der Wert von dpdaction
blieb immer auf restart
.1
Also schrieb ich dem Sophos Support erneut:
[…] I would therefore ask you if you could change the patch file for testing purposes to: auto=route, closeaction=none, dpdaction=clear? Since the trap policies are installed after config load (auto=route), we don’t need DPD to reinitiate SAs anymore. We only need DPD to clear SAs in case of an unreachable peer (dpdaction=clear). After the XGS receives a close/delete, it is acceptable not to restart the connection (closeaction=none) since trap policies, which are still installed, do that job whenever the SA is needed.
Weitere 14 Tage später, wurde mir dann der zweite Patch zugeschickt. Nun wird die Auswahl aus Abbildung 1 tatsächlich auch in die strongSwan-Config übernommen. Anschließend war der Support noch so nett, mir den Patch zusätzlich auch für die XG-Serie zur Verfügung zu stellen, von denen unser Kunde auch noch vereinzelt Geräte einsetzt. Der Patch ist allerdings weiterhin versionsgebunden für SFOS V20.0.0 GA. Wann er in die offizielle Firmware aufgenommen wird, ist noch unklar:
As we have guided you development team taken as Feature and it will be available in Future however it’s Fix firmware not decided yet.
Wie oben bereits erwähnt, wurde inzwischen Version 20 MR1 veröffentlicht. Ich gehe davon aus, dass der Patch es nicht mehr in dieses Release geschafft hat. Entweder dann also in 20 MR2 oder Version 21.
Aktuell ist der Patch auf mehreren Geräten installiert und alles läuft soweit stabil. Man muss sich halt nur daran gewöhnen, dass die kleinen VPN-Lämpchen nicht mehr dauerhaft grün sind, da die SAs ja nur bei Bedarf aufgebaut werden. Insofern ist ein rotes Lämpchen also auch OK. Wenn ich in diesem Kommentar auch geschrieben habe, dass Teil 4 der letzte sein wird, so werde ich in einigen Wochen wohl noch einen kleinen abschließenden Artikel veröffentlichen.
Bis dahin danke ich allen Lesern, die bis hier am Ball geblieben sind! Und falls sich mal jemand von Sophos auf diesen Blog verirrt, danke ich dem Support und dem Dev Team natürlich ebenfalls, dass wir nun endlich eine Lösung gefunden haben – ich weiß, ich war anstrengend… Und trotzdem habe ich noch einen abschließenden Satz für Sophos, der nun sogar meinen Laptop ziert:
Danke an Flexoptix für diesen tollen Aufkleber. 😀
Foto von Michael Henry auf Unsplash
- Später habe ich hier eine Ausnahme festgestellt: Wenn man DPD im IPsec-Profil ganz deaktiviert, wird der Wert von
dpdaction
aufnone
gesetzt. ↩︎