Azure VPN und MTU
Wir nutzen natürlich Server und Dienste in Azure und haben dazu unser LAN über die Firewall mit einem IPSec-Tunnel zu einem Azure-Netzwerk verbunden. Eigentlich hat alles funktioniert aber dann gab es doch immer mal die ein oder andere Unterbrechungen. Webseiten wurden nicht ausgeliefert, RDP war nicht immer möglich. Das Fehlerbild wechselte und nach einiger Forschung haben wir das MTU Discovery dingfest gemacht. Doch lest selbst und beachtet dazu auch die Seiten Maximum Transmission Unit (MTU) und IP Fragmentation und Azure Fragmentation
Erste Analyse
Dass es immer mal irgendwo stockt, haben wir schon gemerkt aber es gehörte auch das Glück dazu, dass ein Client immer wieder das Problem hatte, so dass wir mit Wireshark auf Client und Server die Pakete untersuchen konnten. So haben wir bei einer HTTPS-Verbindung erkannt, dass der Server in Azure Pakete erneut sendet aber nie eine Antwort des Clients sieht.
Interessanterweise kamen aber auch kein "ICMP MTU Exceeded" Meldungen zurück. Wir haben dann von der AzureVm einfach PING-Pakete mit unterschiedlichen Größen gesendet.
ping 192.168.102.12 -f -l <paket>
Da Antwortverhalten dazu war aber dann doch wieder komisch. Dazu habe ich auch den Wireshark-Trace:
Paketgröße | Wireshark Pakete | Antwort | Interpretation |
---|---|---|---|
1394 |
9/11 |
Reply from 192.168.102.12: bytes=1394 time=33ms TTL=126 |
Der erste Ping mit 1394 Bytes wird vom Server versendet und von der Gegenstelle auch beantwortet. Die Antwort ist leider kleiner, so dass ich die MTU-Size in Gegenrichtung so gar nicht testen kann. Das ist schon mal komisch, denn normalerweise enthält die Rückantwort die gleichen Daten. |
1395 |
26 |
Request timed out. |
Ein Paket mit 1395 Bytes geht auch noch auf die Reise aber es kommt keine Antwort an. Es verschwindet einfach in einem schwarzen Loch. Auf der Gegenseite habe ich das Paket aber nicht gefunden. Es ist also auf der Übertragung zum Ziel verloren gegangen, ohne dass ein System eine Meldung gesendet hat. Das ist natürlich sehr schlecht. |
1396 |
37/39 |
Packet needs to be fragmented but DF set. |
Diese Paket ist noch ein Byte größer aber wird aktiv von der Gegenstelle abgelehnt. |
Kleine Pakete kommen durch und größer werden verworfen aber das ein Paket nicht ankommt, ist schon komisch.
MTU Check gegen die Route
Natürlich wollte ich wissen, wo der Fehler ist und haben dann per PING die weiteren Teilstecken analysiert.
Wieder ist PING meine Wahl aber da einige Stationen nicht auf ein PING reagieren, habe ich mir mit einem TTL Expired geholfen, indem ich den TTL reduziert habe. So kann man bei konformen Geräte auch eine Route samt Latenzzeit messen.
ping 192.168.102.12 -f -l 1393 -n 1 -i 1
Ein "TTL Expired" bedeutet indirekt, dass mein Paket zumindest bis dorthin gekommen ist.
Paketgröße | TTL=1 (172.17.0.4) | TTL=2-19 (?) | TTL=20 (192.168.102.12) |
---|---|---|---|
1372 |
TTL Expired |
Timeout |
Success |
1373 |
TTL Expired |
Timeout |
Fragmentation needed |
1394 |
TTL Expired |
Timeout |
Fragmentation needed |
1395 |
TTL Expired |
Timeout |
Fragmentation needed |
1396 |
Fragmentation needed |
Fragmentation needed |
Fragmentation needed |
Die Tabelle liefert erste Hinweise, denn das Default Gateway, was ich in Azure nicht mal per PING erreichen kann, verrät sich aber schon durch den "Fragmentation needed". Allerdings habe ich erst mit einem TTL=20 wieder eine Antwort bekommen. Die Verbindung sieht also wie folgt aus:
Jede Teilstrecke kann abweichende maximale MTUs haben und das kann sich bei Änderungen der Route sogar dynamisch wieder ändern. Daher ist es ja so wichtig, dass die ICMP-Statusmessages durchgelassen werden.
Bitte keine ICMP-Pakete blockieren, die "ICMP Fragmentation needed" melden!
Weiter habe ich diese Verbindung nicht analysiert. Eine Abhilfe könnte es ja sein, die MTU auf dem Server zu reduzieren, so dass er generell keine zu großen Pakete sendet. Für IPSec empfiehlt z.B. Cisco eine MTU-Size von 1400 Bytes.
Hierzu schreibt Microsoft auch:
Azure and VM MTU
The default MTU for Azure VMs is 1,500 bytes. The Azure Virtual Network stack
will attempt to fragment a packet at 1,400 bytes
Note that the Virtual Network stack isn't inherently inefficient because it
fragments packets at 1,400 bytes even though VMs have an MTU of 1,500.
A large percentage of network packets are much smaller than 1,400 or 1,500 bytes.
Quelle:
https://learn.microsoft.com/en-us/azure/virtual-network/virtual-network-tcpip-performance-tuning#azure-and-vm-mtu
Effektive Größe ermitteln
Da die MTU-Size in jede Richtung individuell ermittelt wird und eine Blockade von "ICMP not reachable" eine Erkennung blockiert, kann man nur auf der einen Seite Pakete senden und auf der anderen Seite sehen, ob diese ankommen. Ein test per ICMP funktioniert leider nicht, da das "Antwortpaket" von der Gegenseite ja genauso groß ist.
Ich müsste also ein System finden, mit dem ich ein großes Paket auf die Reise sende aber die Gegenseite mit einem kleinen Paket antwortet, was auf jeden Fall wieder zurück kommt. Leider kenne ich keine eingebaute Funktion, weswegen ich mir dann wieder mit Wireshark behelfe:
- Sender schickt Pakete mit der Größe
Das kann ein "PING -f -l 1500 <ipadresse>" sein, damit - Empfänger schaut mit Wireshark nach
Dort sollte ich die eingehenden ICMP-Pakete finden und wenn sie ausbleiben, dann war es wohl zu groß
Um das schnell zu ermitteln, kann ich das per Powershell recht einfach per Loop machen. Mit etwas Glück habe ich auch die Rückantwort und den ICMP not Reachable
PS C:\> 1460..1500 | %{Test-Connection -Ping -IPv4 192.168.178.1 -BufferSize $_ -DontFragment -Count 1} Destination: 192.168.178.1 Ping Source Address Latency BufferSize Status (ms) (B) ---- ------ ------- ------- ---------- ------ 1 FC-T480S 192.168.178.1 1 1460 Success 1 FC-T480S 192.168.178.1 1 1461 Success 1 FC-T480S 192.168.178.1 1 1462 Success 1 FC-T480S 192.168.178.1 1 1463 Success 1 FC-T480S 192.168.178.1 1 1464 Success 1 FC-T480S 192.168.178.1 1 1465 Success 1 FC-T480S 192.168.178.1 1 1466 Success 1 FC-T480S 192.168.178.1 1 1467 Success 1 FC-T480S 192.168.178.1 1 1468 Success 1 FC-T480S 192.168.178.1 1 1469 Success 1 FC-T480S 192.168.178.1 1 1470 Success 1 FC-T480S 192.168.178.1 1 1471 Success 1 FC-T480S 192.168.178.1 1 1472 Success 1 FC-T480S * 0 1473 PacketTooBig 1 FC-T480S * 0 1474 PacketTooBig 1 FC-T480S * 0 1475 PacketTooBig 1 FC-T480S * 0 1476 PacketTooBig 1 FC-T480S * 0 1477 PacketTooBig 1 FC-T480S * 0 1478 PacketTooBig 1 FC-T480S * 0 1479 PacketTooBig 1 FC-T480S * 0 1480 PacketTooBig 1 FC-T480S * 0 1481 PacketTooBig 1 FC-T480S * 0 1482 PacketTooBig 1 FC-T480S * 0 1483 PacketTooBig 1 FC-T480S * 0 1484 PacketTooBig
Das geht auch über mehrere Hops hinweg z.B. zu outlook.office365.com.
PS C:\> 1460..1500 | %{Test-Connection -Ping -IPv4 outlook.office365.com -BufferSize $_ -DontFragment -Count 1} Destination: outlook.office365.com Ping Source Address Latency BufferSize Status (ms) (B) ---- ------ ------- ------- ---------- ------ 1 FC-T480S 52.97.201.82 12 1460 Success 1 FC-T480S 52.97.201.82 12 1461 Success 1 FC-T480S 52.97.201.82 13 1462 Success 1 FC-T480S 52.97.201.82 12 1463 Success 1 FC-T480S 52.97.201.82 13 1464 Success 1 FC-T480S 52.97.201.82 13 1465 Success 1 FC-T480S 52.97.201.82 12 1466 Success 1 FC-T480S 52.97.201.82 12 1467 Success 1 FC-T480S 52.97.201.82 12 1468 Success 1 FC-T480S 52.97.201.82 13 1469 Success 1 FC-T480S 52.97.201.82 12 1470 Success 1 FC-T480S 52.97.201.82 12 1471 Success 1 FC-T480S 52.97.201.82 13 1472 Success 1 FC-T480S * 0 1473 PacketTooBig 1 FC-T480S * 0 1474 PacketTooBig 1 FC-T480S * 0 1475 PacketTooBig 1 FC-T480S * 0 1476 PacketTooBig 1 FC-T480S * 0 1477 PacketTooBig
In diesen beiden Fällen ist nun alles in Ordnung und ich bekomme ein ICMP PacketToBig zurück. Wenn das Paket aber einfach so verloren geht, dann sehe ich "nur" einen Timeout ohne mehr zu wissen oder es kann ja sein, dass der Rückkanal nur in der Größe beschränkt ist nicht funktioniert. In dem Fall bekomme ich dann "nur" einen Timeout.
PS C:\> 1460..1500 | %{Test-Connection -Ping -IPv4 192.168.180.100 -BufferSize $_ -DontFragment -Count 1} Destination: 192.168.178.100 Ping Source Address Latency BufferSize Status (ms) (B) ---- ------ ------- ------- ---------- ------ 1 FC-T480S 52.97.201.82 12 1460 Success 1 FC-T480S 52.97.201.82 13 1461 Success 1 FC-T480S * 0 1462 DestinationHost… 1 FC-T480S * 0 1463 DestinationHost…
Da kann ich dann raten, ob das Paket auf der Gegenseite angekommen ist oder die Rückantwort zu groß war. Dann ist der Blick mit Wireshark auf der Empfängerseite eine Option.
Natürlich könnte ich mir auch selbst einen Service schreiben, der Pakete annimmt und eine kleine Antwort zurückliefert.
MTU und Azure
Wenn aber MTU-Discovery und ICMP funktioniert, müssten sich die Partner auch ohne Hilfe auf dem IPSec-Tunnel auf eine MTU-Size einigen können. Ich habe also erst einmal die Azure-Dokumentationen durchforstet und einige interessante Aussagen gefunden:
The default MTU for Azure VMs is 1,500
bytes. The Azure Virtual Network stack will attempt to
fragment a packet at 1,400 bytes.
Quelle:
https://learn.microsoft.com/en-us/azure/virtual-network/virtual-network-tcpip-performance-tuning#azure-and-vm-mtu
... The default MTU used on Azure VMs,
and the default setting on most network devices globally, is
1,500 bytes...
Quelle: TCP/IP performance tuning for Azure VMs
https://docs.microsoft.com/en-us/azure/virtual-network/virtual-network-tcpip-performance-tuning
... We don't encourage customers to
increase VM MTUs. ...
Quelle: TCP/IP performance tuning for Azure VMs
https://docs.microsoft.com/en-us/azure/virtual-network/virtual-network-tcpip-performance-tuning
For Azure, we recommend that you set TCP
MSS clamping to 1,350 bytes and tunnel interface MTU to
1,400
Quelle: TCP/IP performance tuning for Azure VMs
https://docs.microsoft.com/en-us/azure/virtual-network/virtual-network-tcpip-performance-tuning
We don't recommend that Azure customers
change the default MTU value on virtual machines.
Quelle: TCP/IP performance tuning for Azure VMs
https://docs.microsoft.com/en-us/azure/virtual-network/virtual-network-tcpip-performance-tuning
Alle Aussagen kann ich verstehen und passen auch auf meine Umgebung. Eine Änderung der MTU-Size auf den Computern selbst wird nicht empfohlen und würde ich auch nur im Notfall umsetzen wollen. Damit störe ich ja auch den Verkehr zwischen Azure Maschinen. Also habe ich mal per PowerShell getestet.
1..5 | ` %{(Test-Connection ` -Ping 172.16.0.4 ` -Count 1 ` -BufferSize 1300 ` -DontFragment -Ttl $_ ` -TimeoutSeconds 1` ).reply ` } | ` select status,address,RoundtripTime ` | ft -AutoSize Status Address RoundtripTime ------ ------- ------------- TtlExpired 192.168.100.5 0 TimedOut 0.0.0.0 0 Success 172.16.0.4 35 Success 172.16.0.4 35 Success 172.16.0.4 35
Mit verschiedenen Paketgrößen bekomme ich dann unterschiedliche Antworten.
Paketgröße/Station | IP-Adresse | RoundTripTime | 1300 | 1372 | 1480 |
---|---|---|---|---|---|
1 | 192.168.100.5 | 0 | TTLExpired |
TTLExpired |
PacketToBig |
2 | 0.0.0.0 | 0 | TimeOut |
PacketToBig |
PacketToBig |
3 | 172.16.0.4 | 35 | Success |
PacketToBig |
PacketToBig |
4 | 172.16.0.4 | 35 | Success |
PacketToBig |
PacketToBig |
5 | 172.16.0.4 | 35 | Success |
PacketToBig |
PacketToBig |
Zwischen Hop 1 und 3 liegen natürlich mehr Stationen. Durch das VPN sind die Zwischenstationen aber natürlich nicht direkt sichtbar. Über die Latenzzeit kann man aber schon mutmaßen, dass es Zwischenstationen gibt.
- IP Fragmentation
- About VPN devices and IPsec/IKE
parameters for Site-to-Site VPN Gateway
connections
https://docs.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-about-vpn-devices - TCP/IP performance tuning for Azure VMs
https://docs.microsoft.com/en-us/azure/virtual-network/virtual-network-tcpip-performance-tuning
IPSec Path Maximum Transmission Units
Auf der Liste der Empfehlungen fällt eine Aussage bezüglich des Tunnels auf:
For Azure, we recommend that you set TCP MSS clamping to
1,350 bytes and tunnel interface MTU to 1,400
Quelle: TCP/IP performance tuning for Azure VMs
https://docs.microsoft.com/en-us/azure/virtual-network/virtual-network-tcpip-performance-tuning
Leider kann ich in der Azure auf dem VPN-Gateway keine MTU-Size einstellen. Hier wäre es aber schon wichtig, denn Azure verschlüsselt die Pakete und sendet sie über das Internet zu meinem On-Premises-System. Wenn die Pakete da aber nicht ankommen, sollten die Router im Internet ein "Fragmentation Needed" senden und das AzureVPN-Gateway selbst die Pakete fragmentieren oder den "ICMP fragmentation needed" an meinen Sender weiter geben. Das letztere Verfahren ist präferiert um optimale Paketgrößen zu senden und ineffiziente Fragmentierungen zu sparen. Mit IPv6 wird eh nicht mehr fragmentiert.
Es könnte aber natürlich auch die On-Premises VPN-Seite sein, bei der das Paket ankommt und als zu groß abgelehnt wird. Auf einer Sophos UTM9 gibt es dazu eine Einstellung im IPSec-Remote Gateway:
Eine Änderung beim Fehlerbild habe ich damit aber leider nicht feststellen können. Früher gab es wohl auch eine Option, um in der GUI die MTUSize und das Verhalten auf ICMP zu manipulieren.
- Webadmin -> IPSec VPN -> Advanced -> MTU. Play around with some settings
Webadmin -> IPSec VPN -> Advanced -> Send ICMP Messages should be enabled
https://community.sophos.com/products/unified-threat-management/f/vpn-site-to-site-and-remote-access/51779/site-to-site-ipsec-tunnel-mtu
Der Eintrag ist aber schon so alt, dass die Menüs nicht mehr vorhanden sind. In einem anderen Blog-Beitrag finde ich nur den Hinweis auf die neue Version
To fix this issue, we proposed a XG
appliance instead of SG. XG appliance is possible to edit
both MTU and MSS on the WEB UI.
Quelle:
https://community.sophos.com/products/unified-threat-management/f/general-discussion/89663/issue-of-mss-on-ipsec-vpn
- Cisco: Resolving Connectivity Issues
https://sc1.checkpoint.com/documents/R76/CP_R76_VPN_AdminGuide/14156.htm - Issue of MSS on IPSEC VPN
https://community.sophos.com/products/unified-threat-management/f/general-discussion/89663/issue-of-mss-on-ipsec-vpn - IPSec & MSS
https://community.sophos.com/products/unified-threat-management/f/vpn-site-to-site-and-remote-access/55203/ipsec-mss/202291#202291 - Configure a Maximum Transmission Unit (MTU) Value
https://www.watchguard.com/help/docs/help-center/en-US/Content/en-US/Fireware/bovpn/manual/bovpn_vif_mtu.html
Workaround
Damit die Dienste aber nun mal schnell funktionieren, habe ich entgegen der Empfehlung von Microsoft auf der AzureVM die MTU-Size von 1500 auf 1400 Bytes reduziert.
Achtung: Das Interface kann sich bei Azure ändern, wenn die VM auf einem anderen Azure-Host neu gestartet wird. Die Einstellung ist also "flüchtig"
C:\>netsh interface ipv4 show interface Idx Met MTU State Name --- ---------- ---------- ------------ --------------------------- 1 75 4294967295 connected Loopback Pseudo-Interface 1 4 10 1500 connected Ethernet C:> netsh interface ipv4 set subinterface "4" mtu=1400 store=persistent C:\>netsh interface ipv4 show interface Idx Met MTU State Name --- ---------- ---------- ------------ --------------------------- 1 75 4294967295 connected Loopback Pseudo-Interface 1 4 10 1400 connected Ethernet
Damit war dann eine reibungslose Kommunikation mit dem Server möglich.
Eine finale Lösung steht natürlich noch aus. Vor allem kann das ja mit jeder weiteren AzureVM wieder passieren. Hier habe ich den "Fehler" nur einkreisen können, weil er beständig war. Die gleichen Zugriffe auf einen anderen AzureVM-Server im gleichen AzureVM-Subnetz haben keine Probleme aufgezeigt und ein anderer Client konnte auch vorher mit dem Server arbeiten
Es ist also nicht immer einfach so eine Unstimmigkeit zu analysieren und fertig bin ich damit auch nicht.
Checkliste
Wie so oft zeigen solche Support-Anfragen, dass es nicht damit getan ist, eine Konfiguration einzurichten. Sie muss auch robust getestet werden. Dazu muss man natürlich wissen, was man testen soll. Ab sofort gehört auf jeden Fall aber ein MTU-Test per PING dazu.
Prüfpunkt | Erledigt |
---|---|
Kleiner PINGZuerst nutze ich einen einfachen PING, der normalerweise nur 64 Byte sendet, um die generelle Durchlässigkeit zu testen |
|
PING KetteUnd dann muss ich halte ein PING starten, der unterschiedliche Paketgrößen vorsieht. Per PowerShell ist das am einfachsten: Hier einmal mit Google als Gegenstelle 1300..1500| %{Test-Connection -Ping 8.8.8.8 -Count 1 -BufferSize $_ -DontFragment} Ping Source Address Latency BufferSize Status (ms) (B) ---- ------ ------- ------- ---------- ------ .... 1 FC-T480S 8.8.8.8 16 1466 Success 1 FC-T480S 8.8.8.8 18 1467 Success 1 FC-T480S 8.8.8.8 16 1468 Success 1 FC-T480S 8.8.8.8 14 1469 Success 1 FC-T480S 8.8.8.8 18 1470 Success 1 FC-T480S 8.8.8.8 16 1471 Success 1 FC-T480S 8.8.8.8 15 1472 Success 1 FC-T480S * 0 1473 PacketTooBig 1 FC-T480S * 0 1474 PacketTooBig 1 FC-T480S * 0 1475 PacketTooBig 1 FC-T480S * 0 1476 PacketTooBig ... Sie sehen hier gut, dass die maximale Paketgröße bei 1472 Bytes liegt. Allerdings ist hier auch die Spalte "Latency" interessant, die zur gleichen Zeit auf 0 geht. Hier dürfte als eher die MTU-Size meines lokalen Computers (1500 = 1472 Bytes Daten + 28 Bytes Ethernet) größere Paket verhindern. |
|
TTL PINGSofern möglich interessiert mich natürlich auch, wo der "Engpass" ist. Also nehme ich mir den Grenzwert und laufe mit einem aufsteigenden TTL den Weg ab. 1..30 ` | %{(Test-Connection -Ping 8.8.8.8 -Count 1 -BufferSize 1473 -DontFragment -Ttl $_).reply} ` | select status,address Status Address ------ ------- TtlExpired 192.168.178.1 TtlExpired 100.68.0.1 PacketTooBig 100.127.1.13 Irgendwann kommt das "PacketTooBig" zurück, der zumindest den Weg bis dorthin dokumentiert. Wenn es "dahinter" wieder mit größeren Paketen weiter geht, dann kann das so nicht ermittelt werden. |
Weitere Links
- Maximum Transmission Unit (MTU)
- IP Fragmentation
- Azure Fragmentation
- TCP/IP performance tuning for Azure VMs
https://docs.microsoft.com/en-us/azure/virtual-network/virtual-network-tcpip-performance-tuning - WINDOWS (10): SETZEN DER MTU ALLER
NETZWERKKARTEN (AUSSER LOOPBACK
https://krausens-online.de/windows-10-setzen-der-mtu-aller-netzwerkkarten-ausser-loopback/ - Path Maximum Transmission Unit Discovery
(PMTUD) For IPsec Tunnels Using The Internet
Key Exchange Protocol (IKE) Version 2
https://tools.ietf.org/id/draft-spiriyath-ipsecme-dynamic-ipsec-pmtu-00.html - Resolve IPv4 Fragmentation, MTU, MSS,
and PMTUD Issues with GRE and IPsec
https://www.cisco.com/c/en/us/support/docs/ip/generic-routing-encapsulation-gre/25885-pmtud-ipfrag.html - How can we improve Azure Networking?
https://feedback.azure.com/forums/217313-networking/suggestions/31361485-configurable-mtu - TCP MSS adjustment for IPSec traffic
https://knowledgebase.paloaltonetworks.com/KCSArticleDetail?id=kA10g000000ClW3CAK - MTU woes in IPsec tunnels and how you
can fix it
https://www.zeitgeist.se/2013/11/26/mtu-woes-in-ipsec-tunnels-how-to-fix/ - TCP/IP performance tuning for Azure VMs
https://learn.microsoft.com/en-us/azure/virtual-network/virtual-network-tcpip-performance-tuning - Troubleshoot Networking in Microsoft
Azure
https://msandbu.org/troubleshoot-networking-in-microsoft-azure/