Ugniježđeni WireGuard: srednji hop ne može odgovoriti na vlastiti port
Kada srednji hop šalje sve u jedan tunel, odgovori na njegovu ulaznu uslugu izlaze pogrešnim putem. Pravilo izvornog porta na interfejsu to ispravlja.
Tri WireGuard hopa stižu do mreže bez javne adrese, a zatim srednja mašina prestaje odgovarati na portu na kojem je trebala slušati. Tunel dalje i dalje radi, udaljeni host i dalje odgovara, i samo je srednji server utihnuo izvana. Ta kombinacija zbunjuje upravo zato što je sama sebi nanesena: srednji hop sluša svoju vlastitu tabelu rutiranja, a tabela šalje njegove odgovore na pogrešnu stranu.
Lanac koji radi dok ne progovoriš sa srednjom kutijom
Uzmite ilustrativan lanac: klijent A stiže do servera B preko UDP 500, a B ide dalje do servera C preko UDP 500. C prihvata saobraćaj samo sa adrese svog jedinog partnera, što ga čini listom i održava njegovo ponašanje jednostavnim. B nije list, i sve zanimljivo u vezi s ovim kvarom dešava se upravo tamo.
Razlika je važna jer uloge lista i sredine vuku u suprotnim smjerovima. List može poslati sve u jedan tunel bez posljedica, jer ništa drugo ne zavisi od njega. Srednji hop je istovremeno krajnja točka za klijente i klijent prema udaljenoj strani, a ta dva posla žele različito rutiranje.
Zašto odgovor izlazi kroz tunel
Na B, interfejs okrenut prema C nosi AllowedIPs = 0.0.0.0/0 zajedno s odgovarajućom zadanom rutom. Zato svaki paket koji B stvori odlazi u taj tunel, osim ako nešto konkretnije ne dobije prednost.
Paket od A upućen B stiže i biva prihvaćen, jer je B odredište i lokalna dostava se dešava prva. Odgovor je potpuno nov, lokalno generisan paket usmjeren na A-ovu javnu adresu, a to odredište odgovara zadanoj ruti u tunel. C ga prima, ne posjeduje tu adresu i odbacuje ga.
Simptom izgleda kao problem s vatrozidom ili neusklađenost ključa, a ovdje nijedno nije tačno. Snimanje na tunelu prema C pokazuje da odgovori idu u pogrešnom smjeru. To jedno zapažanje štedi više vremena od bilo kakvog čitanja konfiguracije, pa ga zapišite prije nego počnete mijenjati ključeve. Svako ko nije vidio snimanje pretpostavit će da je sam tunel pokvaren.
Usko popravljanje: pravila politike koja odgovaraju izvornom portu
Odgovori sa B-ovog slušajućeg soketa izlaze s izvornim portom 500. Pravilo politike može se poklopiti s tim i vratiti te pakete natrag u običnu tabelu:
ip rule add sport 500 table main priority 100
ip rule add sport 8080 table main priority 101
Pravila politike se pregledaju po redoslijedu prioriteta, a glavna tabela stoji na 32766, pa se pravilo na 100 pita prije nego zadana ruta tunela dobije riječ. Dodajte po jedan unos za svaki port koji mora ostati dostupan izvana i ništa više, kako bi proslijeđeni saobraćaj nastavio koristiti tunel za koji je napravljen.
Znajte granicu ovog trika. Selektor sport odgovara lokalno generisanim paketima, što pokriva tačno slučaj odgovora i namjerno ne pokriva saobraćaj koji B samo prosljeđuje za nekog drugog. Usluga hostovana iza B i dalje treba svoj vlastiti odgovor, a pretvaranje da je drukčije daje popravku koja radi za prvu uslugu a pada za drugu.
Dajte pravilu vlasnika
Pravilo otkucano u promptu nestaje sljedeći put kad se interfejs ponovno izgradi. U WireGuard postavci ga stavite tamo gdje se interfejs stvara i uklanja:
PostUp = ip rule add sport 500 table main priority 100
PostDown = ip rule del sport 500 table main priority 100
Ako interfejsom upravlja NetworkManager, hook distribucije ili ulazna točka kontejnera, par pripada tom vlasniku, a ne ručno uređenoj datoteci. Provjerite efektivna pravila nakon ponovnog povezivanja, ne samo nakon prvog pokretanja, jer prvo pokretanje je slučaj koji uvijek radi.
Iskreno uporedite alternative
Pravilo izvornog porta jedan je od četiri izlaza i najuži je od njih. Prednost mu je što uopće ne dira politiku tunela, zbog čega obično preživi kasnije izmjene. Uske popravke takođe glasno padaju kad prestanu važiti, dok široki izuzetak tiho nastavlja raditi dugo nakon što razlog za njega nestane. Ta razlika je važnija od elegancije kad nakon dvije godine kutijom upravlja neko drugi.
| Approach | What it costs | Where it breaks |
|---|---|---|
| Source-port policy rule | One rule per exposed port | Anything B forwards rather than originates |
| Destination exception route | A route pinned to specific client addresses | Clients whose address changes |
| Stop full-tunnelling on B | Loses the catch-all path toward C | Designs that depend on it |
| Split into two tunnels | More interfaces and more policy | Nothing, at the cost of complexity |
Provjerite s oba kraja nakon što odaberete. Sa strane A započnite vezu prema B-ovom portu i držite je zauzetom neko vrijeme. Na B natjerajte kernel da opravda put odgovora nečim poput ip route get <address-of-A> sport 500 i potvrdite da navodi WAN interfejs, a ne tunel. Nakon toga provjerite da nešto iza C još uvijek odgovara kroz lanac, što dokazuje da je izuzetak ostao uzak umjesto da se pretvori u obilaznicu. Na kraju zapišite portove u dizajnerske bilješke, inače sljedeći operater otkrije ovo na drugoj usluzi.