OpenVPN u Dockeru: ugovor o izvršavanju koji treba minimalnom klijentu
Pregledana slika, jedan zaštićeni profil, pristup TUN-u i NET_ADMIN. Šta kontejner dobija, šta ne smije dobiti i kako dokazati da tunel radi.
Stavite VPN klijent u kontejner i dobijete jedan imenski prostor s tunelom unutra, a ne host koji sav svoj saobraćaj usmjerava kroz VPN. To su odvojeni projekti, i upravo tretiranje ih kao jednog dovodi do toga da kontejneri slučajno postanu privilegirani. Ovaj priručnik pokriva samo prvo: jedna pregledana slika, jedan zaštićeni profil i klijentski proces ograničen na vlastiti mrežni imenski prostor.
Počnite od artefakta koji je neko već odobrio. Koraci ispod pretpostavljaju sliku koja sadrži izvršnu datoteku openvpn i kompletan klijentski profil sa certifikatom i ključnim materijalom već razriješenim unutar montaže. Oni ne grade softver, ne izdaju akreditive i ne pokrivaju rootless okruženja i izvorne Windows kontejnere, od kojih svako mijenja odgovor.
Šta kontejner dobija, a šta ne
Držite profil i sve na šta se poziva u lokalnom direktoriju s ograničenim dozvolama, montiranom samo za čitanje. Relativne putanje unutar profila moraju se razriješiti unutar te montaže; to je detalj koji ljudi propuste kada certifikat stoji jedan direktorij iznad profila i kontejner ga nikada ne vidi.
services:
vpn:
image: ${VPN_CLIENT_IMAGE:?set the reviewed image reference}
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun:/dev/net/tun
volumes:
- ./vpn:/vpn:ro
working_dir: /vpn
entrypoint: ["openvpn"]
command: ["--config", "/vpn/client.ovpn"]
Ta datoteka daje tri stvari i ne traži ništa drugo. Referenca slike treba biti prikvačena digestom ako vaša politika isporuke to nalaže, a profil treba biti pregledani, a ne kopija koju je neko uredio na hostu.
Samo za čitanje ovdje znači da kontejner ne može mijenjati vaše datoteke na hostu; ne znači da kontejner ne može pročitati privatni ključ koji ste montirali. To je cijela poenta montaže, i zato dozvole datoteka, vlasništvo i način na koji je tajna došla na host još uvijek imaju značenje. Nikada ne prosljeđujte lozinku na komandnoj liniji i ne ugrađujte je u sloj slike, jer oboje preživi na mjestima koja kasnije ne možete očistiti.
Mogućnosti, entrypoint i zamka između njih
Potrebne su dvije postavke i one rade nepovezane poslove. NET_ADMIN dozvoljava manipulaciju interfejsima i rutama unutar imenskog prostora kontejnera. Unos uređaja /dev/net/tun dozvoljava procesu da uopće otvori tunelski uređaj. Davanje jednog bez drugog daje jasan neuspjeh, što je zgodno: nedostajući TUN uređaj pada pri otvaranju, dok nedostajuća mogućnost pada kada klijent pokuša konfigurisati interfejs.
Nijedno od toga ne opravdava privileged: true. Privilegirani kontejner dobija sve mogućnosti plus pristup uređajima, i to je mnogo veće davanje nego što ovaj posao treba. referenca o privilegijama i mogućnostima izvršnog okruženja objašnjava dokle to davanje seže. Ako chart ili blog post to traži, prvo provjerite da li je zahtjev zapravo bio nedostajuća putanja uređaja ili nedostajuća mogućnost.
Prepisivanje entrypoint je dio koji ujeda. Direktno pozivanje openvpn ispravno je za običnu sliku i pogrešno za svaku produktnu sliku čija startna skripta priprema firewall pravila, resolver datoteke ili akreditive prije pokretanja demona. Prepisivanje te skripte preskače pripremu i ostavlja vas da otklanjate greške na tunelu koji je nastao u napola konfigurisanom imenskom prostoru.
Pokrenite klijent u prvom planu i pustite ga da bude glavni proces kontejnera. Proces koji se demonizira odmah izlazi, kontejner se restartuje u petlji, a logovi koji su vam potrebni razbacani su po restartima koji svi izgledaju isto.
Provjeravajte iz imenskog prostora, a ne s hosta
Podignite stack, potvrdite u logu da je klijent dostigao povezano stanje, a zatim pregledajte imenski prostor koji zaista drži tunel.
docker compose up -d
docker compose logs --tail 40 vpn
docker compose exec vpn ip -br addr
docker compose exec vpn ip route
Lista adresa treba pokazati tunelski interfejs s adresom iz pula, a tabela ruta treba pokazati gurane destinacije koje pokazuju na njega. Ako interfejs nedostaje, klijent nikada nije stigao do tačke stvaranja. Ako postoji ali nijedna ruta ga ne koristi, mjesto za traženje su push ili opcije ruta.
Zatim testirajte destinaciju do koje vam je stalo, iz imenskog prostora koji treba koristiti tunel, pomoću aplikacije, a ne samo pingom. Razrješavanje imena je odvojen neuspjeh koji vrijedi eksplicitno testirati: gurana DNS adresa ne ažurira resolver kontejnera sama po sebi, a samostalni klijent koji ignorira push razrješavat će imena kroz ono što je slika konfigurisala.
Odspojeno stanje je dio ugovora
Ponašanje pri ponovnom povezivanju treba vlastitu provjeru, jer politika restarta dokazuje da se proces restartuje i ne govori ništa o tome šta saobraćaj radi u međuvremenu. Zaustavite tunel, pokušajte predviđenu destinaciju i gledajte da li se veza odbija, visi ili tiho uspijeva kroz običnu rutu kontejnera. Posljednji ishod je onaj koji je važan, i on je nevidljiv u zdravom logu.
Ako posao nikada ne smije koristiti običnu putanju, projektujte to eksplicitno pravilima firewalla i signalom spremnosti unutar imenskog prostora. Kill switch je politika koju pišete i testirate, a ne svojstvo koje nasljeđujete pokretanjem klijenta u kontejneru.
Na kraju, zapamtite granicu: ove rute žive u imenskom prostoru kontejnera i ne zamjenjuju hostovu tabelu rutiranja. Dockerova pravila prosljeđivanja, prevođenja i firewalla ostaju dio vanjske putanje, a objavljeni port nije VPN interfejs.