Miten isäntäkoneen liikenne reititetään Docker VPN -kontin kautta
VPN-kontti on verkon nimiavaruus, ei välityspalvelin. Valitse jaettu netns, todellinen SOCKS-kuuntelija tai reititetty yhdyskäytävä ja tarkista sitten ulostulopolku.
Tunnelikonttisi toimii, docker compose exec vpn curl -s https://ifconfig.me vastaa palveluntarjoajan osoitteella, ja silti työpöytäsi selain lähtee liikkeelle ISP:si kautta. Tämä ero on odotettavissa. VPN-asiakasta ajava kontti pitää verkon nimiavaruutta, reittejä ja tunnelirajapintaa, eikä mitään, mikä puhuu HTTP:tä tai SOCKSia; portin julkaiseminen siinä ei voi luoda kuuntelijaa, jota ei koskaan ollut.
Se, missä asiakas ajetaan, ratkaisee suunnittelun. Sisarkontti voi siirtyä tunnelin nimiavaruuteen, työpöytäsovellus ei voi, ja reititin tarvitsee reittejä eikä välityspalvelinkenttää. Jos kartoitus menee väärin, oire on sama: yhteys hylätty tai liikenne, joka ottaa hiljaa vanhan polun.
Sovita järjestely siihen, missä asiakas ajetaan
Kysy yksi kysymys ennen Composen muokkaamista: voidaanko asiakas käynnistää VPN-kontin verkon nimiavaruuden sisällä? Kaikki, mikä jo pyörii Linux-konttina, voi. Työpöydälläsi oleva selain, IDE tai CLI ei voi, koska sen välityspalvelinasetus odottaa protokollapalvelua, ei nimiavaruutta.
| Client | Arrangement | What must already exist |
|---|---|---|
| Another Compose service | Shares the vpn namespace via network_mode: service:vpn | A working tunnel and correct start order |
| Host browser, IDE or CLI | Proxy listener inside the namespace, published to host loopback | A configured SOCKS or HTTP proxy and its access rules |
| Router, VM or phone | The container as a layer-3 gateway | Forwarding, NAT and a return route |
Nämä kolme eivät sekoitu. Kontin siltaosoitteeseen osoittava HTTP-välityspalvelinkenttä ei tavoita mitään, ellei siellä kuuntele välityspalvelin, eikä välityspalvelinkuuntelija reititä reitittimen liikennettä. Päätä ensin ja seuraa sitten vastaavaa osiota.
Jaa tunnelin nimiavaruus sisarkontin kanssa
Tämä on halvin vaihtoehto, koska välityspalvelinprotokolla ei ole mukana. Sovellus liittyy vpn-palvelun nimiavaruuteen ja perii sen rajapinnat, reitit ja porttiavaruuden:
services:
vpn:
image: your-vpn-client
cap_add:
- NET_ADMIN
healthcheck:
test: ["CMD-SHELL", "ip link show tun0 >/dev/null"]
interval: 10s
retries: 5
app:
image: your-app
network_mode: service:vpn
depends_on:
vpn:
condition: service_healthyKolme rajoitusta seuraa siitä, että nimiavaruus kuuluu toiselle palvelulle. Sovellus ei saa omaa networks-avaintaan, koska sillä ei ole nimiavaruutta, johon kiinnittyä. Porttien julkaisu kuuluu vpn:lle, koska siellä nimiavaruus asuu. Ja vpn:n uudelleenluonti tuhoaa nimiavaruuden, johon sovellus liittyi, joten docker compose up -d --force-recreate vpn jättää sinulle myös app:n uudelleenluonnin; pelkkä uudelleenkäynnistys ei aina riitä. Composen palveluviite kattaa tämän järjestelyn ja sen porttien julkaisurajoituksen.
Älä oleta, että resolveri tulee mukana. /etc/resolv.conf on konttikohtainen tiedosto eikä osa verkon nimiavaruutta, joten sovellus voi yhä kysyä isännän resolveria, kun sen paketit lähtevät tunnelin kautta. Lue se kontin sisältä ja aseta dns: sovellukselle, kun yksityiset nimet on ratkaistava tunnelin kautta.
docker compose exec app ip route
docker compose exec app cat /etc/resolv.conf
docker compose exec app curl -s https://ifconfig.meJos reittiluettelo sisältää tunnelirajapinnan ja osoite on palveluntarjoajan, sovellus on tunnelin sisällä. Jos rajapinta puuttuu, app käynnistyi ennen kuin vpn:llä oli tunneli, joten luo app uudelleen, kun vpn ilmoittaa olevansa kunnossa.
Aseta todellinen välityspalvelinkuuntelija nimiavaruuteen isäntäasiakkaille
Työpöytäselain ei voi liittyä nimiavaruuteen, joten tunneli on altistettava palveluna. Aja todellinen SOCKS- tai HTTP-välityspalvelin vpn-nimiavaruuden sisällä ja julkaise vain sen portti:
services:
vpn:
ports:
- "127.0.0.1:1080:1080"
proxy:
image: your-proxy
network_mode: service:vpn
command: ["--socks", "0.0.0.0:1080"]Isännän puoleinen osoite on tuon kartoituksen tärkeä puoli. 127.0.0.1:1080 vasemmalla pitää kuuntelijan poissa LAN:ilta; paljas "1080:1080" julkaisee avoimen välityspalvelimen jokaiselle laitteelle, joka pääsee koneellesi.
Kontin puolella on oma ansansa. Julkaistut portit toimitetaan kontin osoitteeseen sillalla, ei sen loopbackiin, joten nimiavaruuden sisällä --socks 127.0.0.1:1080-asetuksella käynnistetty välityspalvelin hyväksyy sisarkonttien yhteydet ja hylkää kaiken, mikä saapuu julkaistun portin kautta. Sido se 0.0.0.0-osoitteeseen ja luota isännän puolen loopback-sidontaan eristyksessä. Sama sääntö koskee välityspalvelimen asetustiedoston kuunteluosoitetta.
Päätä sitten, missä nimet ratkaistaan. curlista --socks5 ratkaisee isäntänimen paikallisesti ja --socks5-hostname lähettää nimen välityspalvelimelle; selaimet näyttävät saman kytkimen eri nimellä. Paikallinen ratkaisu vuotaa kyselyn, vaikka sivu latautuisi tunnelin kautta.
Kohtele konttia yhdyskäytävänä vain paluureitillä
Reitittimet, VM:t ja puhelimet eivät käytä HTTP-välityspalvelinkenttää, ja jotkin sovellukset jättävät välityspalvelinmuuttujat kokonaan huomiotta. Niiden liikenteen reitittäminen tarkoittaa kerrosta 3: kontti välittää paketteja ja kääntää osoitteita tunnelirajapinnalla.
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADEKaksi asiaa jää helposti huomaamatta. Asiakas tarvitsee reitin, joka osoittaa sen oletusyhdyskäytävän tähän isäntään, ja vastausten on löydettävä takaisin, joko ylävirran reitittimen staattisella reitillä tai asiakkaihin päin olevan rajapinnan NAT:lla. Ilman toista näistä tunneli vie pyynnön ulos ja vastaus katoaa.
Sillä on myös laajin vaikutusalue. Koko LAN:in yhdyskäytävänä toimiva isäntä lähettää jokaisen väärin konfiguroidun asiakkaan VPN-tilisi kautta, ja tunnelin katkeaminen joko pimentää LAN:in tai palaa ISP:hen kill switchistä riippuen.
Tarkista ulostulopolku ja peruuta sitten järjestyksessä
Tarkista tässä järjestyksessä ja pysähdy ensimmäiseen epäonnistumiseen: ulostulo-osoite nimiavaruuden sisällä, ulostulo-osoite isännästä välityspalvelimen kautta, sitten nimien ratkaisu yksityiselle isännälle.
docker compose exec vpn curl -s https://ifconfig.me
curl -s -x socks5h://127.0.0.1:1080 https://ifconfig.me
curl -s -x socks5h://127.0.0.1:1080 http://internal.example/healthKahden ensimmäisen osoitteen pitäisi vastata palveluntarjoajaa, ja kolmas pitäisi ratkaista välityspalvelimen kautta sen sijaan, että se epäonnistuisi nimivirheeseen. Täsmäävä ensimmäinen rivi ja epäonnistuva toinen rivi tarkoittavat, että kuuntelija tai julkaistu portti on väärin, ei tunneli.
Peruuttaminen on asennuksen vastakohta. Poista välityspalvelimen ympäristömuuttujat komentotulkin profiilista ja kaikista systemd-yksiköistä, laske sitten pino alas, jotta jaettu nimiavaruus katoaa omistajansa mukana. Poista julkaistu portti ennen välityspalvelupalvelun poistamista, muuten isäntä pitää loopback-kuuntelijan, jota kukaan ei lue.
Ennen kuin jatkat, vahvista neljä asiaa: tärkeä asiakas todella saavuttaa tunnelin, vain nimiavaruuden omistaja julkaisee portteja, yksityiset nimet ratkeavat siellä missä aioit, ja mikään ei kuuntele isäntäosoitteessa, joka ei ole loopback. Jokainen näistä epäonnistuu tuotannossa hiljaa, ja jokainen on yhden rivin tarkistus yllä.