Indlejret WireGuard: det midterste hop kan ikke svare på sin egen port
Når det midterste hop sender alt ind i én tunnel, forlader svar på dens indgående tjeneste ad den forkerte vej. En regel for kildeporten på interfacet retter det.
Tre WireGuard-hop når et netværk uden offentlig adresse, og derefter holder den midterste maskine op med at svare på den port, den skulle lytte på. Tunnelen videre virker stadig, den fjerne vært svarer stadig, og kun den midterste server selv er blevet tavs udefra. Den kombination er forvirrende, netop fordi den er selvforskyldt: det midterste hop adlyder sin egen routingtabel, og tabellen sender dets svar den forkerte vej.
En kæde, der virker, indtil du taler med den midterste boks
Tag en illustrativ kæde: klient A når server B på UDP 500, og B går videre til server C på UDP 500. C accepterer kun trafik fra sin eneste peer-adresse, hvilket gør den til et blad og holder dens adfærd enkel. B er ikke et blad, og alt det interessante ved denne fejl sker der.
Forskellen betyder noget, fordi blade- og mellemroller trækker i modsatte retninger. Et blad kan sende alt ind i én tunnel uden konsekvenser, da intet andet afhænger af det. Et midterste hop er samtidig et endepunkt for klienter og en klient mod den fjerne side, og de to opgaver vil have forskellig routing.
Hvorfor svaret forlader via tunnelen
På B bærer interfacet mod C AllowedIPs = 0.0.0.0/0 sammen med den matchende standardrute. Derfor går hver pakke, som B skaber, ind i den tunnel, medmindre noget mere specifikt får forrang.
En pakke fra A adresseret til B ankommer og accepteres, fordi B er destinationen, og lokal levering sker først. Svaret er en helt ny lokalt genereret pakke rettet mod A's offentlige adresse, og den destination matcher standardruten ind i tunnelen. C modtager den, ejer ikke den adresse og dropper den.
Symptomet læses som et firewallproblem eller en nøgleuoverensstemmelse, og ingen af delene er sande her. En optagelse på tunnelen mod C viser, at svarene går den forkerte vej. Den ene observation sparer mere tid end nogen mængde læsning af konfiguration, så skriv den ned, før du begynder at skifte nøgler. Enhver, der ikke har set optagelsen, vil antage, at tunnelen selv er i stykker.
Den snævre reparation: politikregler, der matcher en kildeport
Svar fra B's lyttende socket forlader med kildeport 500. En politikregel kan matche det og sende de pakker tilbage til den almindelige tabel:
ip rule add sport 500 table main priority 100
ip rule add sport 8080 table main priority 101
Politikregler konsulteres i prioriteret rækkefølge, og hovedtabellen ligger på 32766, så en regel på 100 spørges, før tunnelens standardrute får noget at sige. Tilføj én post pr. port, der skal forblive tilgængelig udefra, og intet mere, så videresendt trafik bliver ved med at bruge den tunnel, den blev bygget til.
Kend grænsen for dette trick. Vælgeren sport matcher lokalt genererede pakker, hvilket dækker præcis svartilfældet og bevidst ikke dækker trafik, som B blot videresender for en anden. En tjeneste, der hostes bag B, har stadig brug for sit eget svar, og at foregive andet giver en løsning, der virker for den første tjeneste og fejler for den anden.
Giv reglen en ejer
En regel skrevet i en prompt forsvinder næste gang, interfacet genopbygges. På en WireGuard-opsætning skal du lægge den der, hvor interfacet oprettes og fjernes:
PostUp = ip rule add sport 500 table main priority 100
PostDown = ip rule del sport 500 table main priority 100
Hvis NetworkManager, et distributionshook eller et container-entrypoint ejer interfacet, hører parret til hos den ejer frem for i en håndredigeret fil. Kontroller de effektive regler efter en genopkobling, ikke kun efter den første start, fordi den første start er det tilfælde, der altid virker.
Sammenlign alternativerne ærligt
Kildeportreglen er en af fire veje ud, og den er den snævreste af dem. Den har fordelen af slet ikke at røre tunnelpolitikken, hvilket er grunden til, at den har tendens til at overleve senere ændringer. Snævre rettelser fejler også højlydt, når de holder op med at gælde, hvorimod en bred undtagelse fortsætter med at virke stille længe efter, at grunden til den er forsvundet. Forskellen betyder mere end elegance, når en anden ejer boksen om to år.
| 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 |
Bekræft fra begge ender, når du har valgt. Fra A starter du en forbindelse til B's port og holder den beskæftiget et stykke tid. På B får du kernen til at begrunde svarvejen med noget som ip route get <address-of-A> sport 500, og bekræft, at den nævner WAN-interfacet og ikke tunnelen. Derefter kontrollerer du, at noget bag C stadig svarer gennem kæden, hvilket beviser, at undtagelsen forblev snæver i stedet for at blive en omvej. Til sidst skal du skrive portene ned i designnoterne, ellers genopdager den næste operatør det på en anden tjeneste.