Linux EHOSTUNREACH med OpenVPN: vilket nästa hopp misslyckades?
EHOSTUNREACH kan komma från en uttryckligen onåbar rutt, en död granne eller en rapport på distans. Läs den valda rutten och nästa hopp innan du rör kryptot.
EHOSTUNREACH är lika ofta ett lokalt beslut som ett avlägset fel. Kärnan kan avvisa ett paket eftersom en rutt säger att målet är onåbart, eftersom Ethernet-nästa hopp aldrig svarade, eller eftersom en ICMP host-unreachable-rapport kom längre framifrån vägen. Varje källa bor i en egen tabell eller cache, och var och en åtgärdas på ett eget ställe. Läs den valda rutten och nästa hopps tillstånd innan du rör chiffer eller installerar om tunneln.
Välj den adress och det namespace som klienten faktiskt använder
Börja med att fästa målet och det nätverksnamespace som gav upphov till felet. En VPN-klient kan köra i sitt eget namespace, och en uppslagning från det förvalda använder en annan routingtabell med andra policyregler.
Uppslagningen måste använda samma källa, mark och tabellkontext som programmet som misslyckas, annars kan den svara på en fråga som ingen ställde. För en illustrativ IPv4-peer är de skrivskyddade kontrollerna:
ip -4 route get 198.51.100.25
ip -4 neigh show 198.51.100.1
ip -4 route show table all | grep -w unreachable
Ett resultat från ett administrativt skal bevisar bara vad det skalet skulle göra. Om klienten sätter en firewall mark eller binder till en VRF, upprepa uppslagningen med matchande mark eller inuti VRF:en och jämför den valda rutten och nästa hopp. Den första adressen att bekräfta är peer-adressen i profilen, inte det kluster eller den tjänst som användaren namnger.
En uttrycklig onåbar rutt avvisar paketet lokalt
En rutt av typen unreachable är ett avsiktligt lokalt svar. Den säger åt kärnan att kasta paketet och returnera EHOSTUNREACH till avsändaren, vilket är varför felet syns direkt och utan att någon trafik lämnar maskinen. Någon, eller någon automatisering, lade den rutten där med avsikt.
Rutttyperna är inte utbytbara. blackhole släpper paketet utan fel till avsändaren, prohibit returnerar EACCES och unreachable returnerar EHOSTUNREACH. En VPN-hjälpare som installerar en sink-rutt vid återanslutning kan därför ge en skur av host-unreachable-fel som försvinner när tunneln är uppe, medan en blackhole-rutt i stället skulle ge tysta tidsgränser.
Sök igenom alla tabeller efter typen innan du skyller på fjärränden. Regeln som väljer tabellen är lika viktig som rutten i den, och en rutt som läggs i huvudtabellen hjälper inte en klient vars policyregel skickar trafiken någon annanstans.
En död granne ger samma fel på Ethernet
När den valda rutten använder en on-link-gateway behöver leveransen en upplöst länklageradress. Kärnan skickar en ARP eller IPv6-grannförfrågan, och om inget svar kommer kan paketet inte ramas in. Sändningen misslyckas då med EHOSTUNREACH trots att rutten i sig är giltig.
Grannskapstabellen namnger steget. INCOMPLETE betyder att en upplösning pågår, FAILED betyder att det senaste försöket inte fick något svar, och REACHABLE eller STALE betyder att kärnan har en användbar adress. En FAILED-post för VPN-gatewayen är ett lokalt leveransproblem, inte bevis om tunnelns bortre sida.
Läs posten för det faktiska nästa hoppet, inte för fjärradressen på internet. En fjärradress nås normalt via en router, så den har ingen egen ARP-post; att fråga efter en är ett kategorifel som skickar folk att leta efter en saknad post som aldrig borde ha funnits.
Fjärrapporter och asynkrona UDP-fel
EHOSTUNREACH kan också komma utifrån. En router som inte kan vidarebefordra paketet kan skicka ICMP host unreachable, och kärnan lämnar rapporten till den socket som äger flödet. I så fall är rutten och grannen okej, och felet hör till ett hopp bortom det lokala nätet.
UDP gör det svårare att peka ut orsaken. Ett fel som returneras av ett senare send- eller receive-anrop kan avse ett tidigare datagram, så adressen och tiden för det misslyckade anropet stämmer kanske inte med paketet som utlöste rapporten. En ansluten UDP-socket får felet en gång, och en oansluten socket kanske aldrig ser det alls.
Därför hör tiden till bevisningen. Notera när felet dök upp, vilken peer-adress socketen använde och om tunneln just hade återanslutit. En skur direkt efter en ruttändring pekar på den lokala tabellen; ett enstaka fel minuter in i ett stabilt flöde pekar på en rapport från vägen.
Separera lagren innan du ändrar kryptot
Tre frågor klassificerar felet. Valde kärnan en rutt som avvisar målet? Valde den en giltig rutt men misslyckades med att lösa upp nästa hopp? Eller kom en rapport från bortom det lokala nätet? Bara det tredje fallet kan peka på tunnelns bortre ände, och inte ens då på krypteringen.
Autentiserings- och förhandlingsproblem visar sig som egna fel efter att transporten nått peeren. Att byta chiffer eller installera om klienten kan inte laga en lokal onåbar rutt, och det förstör rutt- och grannevisningen du skulle behöva för den verkliga orsaken.
Anteckna mål, namespace, vald tabell, nästa hopp, grannstatus och fel tidpunkt före den första ändringen. Kör samma uppslagning efter åtgärden; en rutt som nu pekar på tunneln och en grannpost som nu löses upp är starkare bevis än en lyckad ping till en orelaterad adress.