Værten browser gennem tunnelen, og containeren ved siden af når intet. At udgive en port fra en container, der kører sin egen VPN-klient, er værre: anmodningen ankommer, og svaret forlader aldrig værten. Begge er routingbeslutninger på værten, og Docker er kun budbringeren.

Tre spørgsmål afgør, hvilken af de to du står med, og de tager cirka et minut.

To fejl, der ser ens ud

Den første er et problem med returvejen. En udgivet port oversættes ind i containeren, anmodningen ankommer, og svaret routes af værtens standardrute, som OpenVPN-klienten har peget på tun0. Svaret forlader en adresse, som den eksterne peer ikke forventer, og det droppes. Den anden er en præfiks-kollision: Dockers standardbro ejer 172.17.0.0/16, og en virksomhedstunnel skubber samme område.

Den ene rettes med en routingtabel, den anden ved at omnummerere en bro. At redigere, før du ved hvad der er hvad, er måden at ødelægge en fungerende container.

Afgør det med tre spørgsmål

Spørgsmål et: forsvinder fejlen, når du stopper VPN'en? Hvis alt virker med tunnelen nede, så mistænk returvejen. Spørgsmål to: viser ip route show table all det samme præfiks to gange, én gang på en bro og én gang på tun0? Det er kollisionen. Spørgsmål tre: er den berørte adresse en container, en NAT-gæst eller en broet gæst?

Det tredje spørgsmål er vigtigt, fordi hver har sin egen korrekte løsning, og at anvende containerløsningen på en libvirt-gæst spilder en aften.

ip route
ip route show table all | grep -E '172\.1[7-9]|10\.8'
docker network inspect bridge --format '{{.IPAM.Config}}'

Returvej: en tabel til én kildeadresse

Når containerens trafik skal ud gennem det fysiske interface, mens værten selv bruger tunnelen, er kildebaseret routing den mindste ændring. Tilføj en regel, der matcher containerens adresse, og send den til en dedikeret tabel. Intet andet på værten flytter sig.

ip rule add from 172.22.0.3 lookup 10
ip route add default via 172.22.0.1 table 10

Hver pakke, hvis kilde er den adresse, slår først tabel 10 op, og tabel 10 sender den til broens gateway i stedet for tunnelen.

Bekræft med ip route get 1.1.1.1 from 172.22.0.3. Svaret skal nævne broens interface, ikke tun0. Regler tilføjet på denne måde forsvinder ved genstart, så læg dem i den unit eller det netværkshook, der ejer containeren.

Samme mønster virker for en WireGuard-container, hvor returvejen også kræver en eksplicit regel.

Præfiks-kollision: omnummerér broen

En routingtabel sender ét præfiks ét sted hen. Hvis VPN'en skubber 172.17.0.0/16, mens Dockers bro allerede er der, vinder den lavere metrik: Docker installerer sin forbundne rute med metrik 0, og den skubbede rute ankommer med 50. Tunnelen ser så ødelagt ud, mens Docker fortsætter, eller omvendt, afhængigt af installationsrækkefølgen. Omnummerér broen i stedet for at kæmpe med metrikken.

{
  "bip": "10.200.0.1/24",
  "default-address-pools": [{"base": "10.201.0.0/16", "size": 24}]
}

Genstart Docker efter ændringen, og genskab netværk, der er bygget med den gamle pulje. At ændre metrikken i stedet flytter kun konflikten til næste opstart.

VM'er har igen brug for et andet svar

En libvirt-gæst på standard-NAT-netværket arver værtens routing og holder op med at nå udenverdenen, når værtens tunnel ejer standardruten. At skifte gæsten til en broet eller macvtap-enhed giver den sin egen vej på det fysiske netværk. I virt-manager tilføjer du hardware, vælger Network, sætter kilden til macvtap-værtsenheden, beholder virtio som model og deaktiverer derefter det gamle NAT-interface.

En macvtap-gæst kan normalt ikke nå sin egen vært. Det er forventet adfærd og ikke en fejl, og det hører i noten, du efterlader.

For en gæst, der kun skal bruge værtens LAN, har leverandørens klient muligvis den manglende kontakt: med Mullvad gendanner mullvad lan set allow lokal tilgængelighed uden at røre libvirt. Og når en container kun skal være tilgængelig gennem tunnelen, bind den udgivne port til tunneladressen, -p 10.8.0.5:8080:8080, i stedet for at udgive den på hver adresse.

Relaterede artikler