Tegyen egy VPN-klienst egy konténerbe, és egy névteret kap egy benne lévő alagúttal, nem egy gazdagépet, amely minden forgalmát VPN-en keresztül irányítja. Ezek külön projektek, és az, hogy egyként kezeljük őket, az az út, amelyen a konténerek véletlenül kiváltságossá válnak. Ez az útmutató csak az elsőt fedi le: egy ellenőrzött image, egy védett profil és egy kliensfolyamat, amely a saját hálózati névterére korlátozódik.

Olyan artefaktumból induljon ki, amelyet valaki már jóváhagyott. Az alábbi lépések olyan image-t feltételeznek, amely tartalmazza a openvpn végrehajtható fájlt és egy teljes kliensprofilt, amelynek tanúsítványa és kulcsanyaga már fel van oldva a csatoláson belül. Nem építenek szoftvert, nem bocsátanak ki hitelesítő adatokat, és nem fedik le a root nélküli futtatókörnyezeteket vagy a natív Windows-konténereket, amelyek mindegyike megváltoztatja a választ.

Mit kap a konténer és mit nem

Tartsa a profilt és mindent, amire hivatkozik, egy helyi könyvtárban korlátozott jogosultságokkal, csak olvashatóként csatolva. A profilon belüli relatív útvonalaknak ezen a csatoláson belül kell feloldódniuk; ez az a részlet, amelyet az emberek kihagynak, amikor egy tanúsítvány egy könyvtárral a profil felett van, és a konténer soha nem látja.

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"]

Ez a fájl három dolgot ad, és semmi mást nem kér. Az image-hivatkozást digesttel kell rögzíteni, ha a telepítési szabályzata ezt mondja, és a profilnak az ellenőrzöttnek kell lennie, nem egy példánynak, amelyet valaki a gazdagépen helyben szerkesztett.

A csak olvasható itt azt jelenti, hogy a konténer nem módosíthatja a gazdagépen lévő fájlokat; nem azt, hogy a konténer nem olvashatja a csatolt privát kulcsot. Pontosan ez a csatolás értelme, és ezért számítanak továbbra is a fájljogosultságok, a tulajdonjog és az, hogyan került a titok a gazdagépre. Soha ne adjon át jelszót a parancssorban, és ne süsse bele egy image-rétegbe, mert mindkettő olyan helyeken marad meg, amelyeket később nem tud kitakarítani.

Képességek, entrypoint és a csapda közöttük

Két beállítás kell, és nem összefüggő munkát végeznek. A NET_ADMIN engedélyezi az interfészek és útvonalak manipulálását a konténer névterében. A /dev/net/tun eszközbejegyzés engedélyezi a folyamatnak, hogy egyáltalán megnyissa az alagút-eszközt. Az egyik megadása a másik nélkül világos hibát okoz, ami kényelmes: a hiányzó TUN-eszköz megnyitáskor hibázik, míg a hiányzó képesség akkor hibázik, amikor a kliens megpróbálja konfigurálni az interfészt.

Egyik sem igazolja a privileged: true beállítást. Egy kiváltságos konténer minden képességet és eszközhozzáférést megkap, és ez jóval nagyobb engedmény, mint amire ennek a munkaterhelésnek szüksége van. A futásidejű kiváltságokról és képességekről szóló hivatkozás elmagyarázza, milyen messzire ér ez az engedmény. Ha egy chart vagy egy blogbejegyzés kéri, először ellenőrizze, hogy a követelmény valójában nem egy hiányzó eszközútvonal vagy egy hiányzó képesség volt-e.

A entrypoint felülírása az a rész, amely harap. A openvpn közvetlen hívása helyes egy közönséges image esetében, és helytelen minden olyan termékimage esetében, amelynek indítószkriptje tűzfalszabályokat, feloldófájlokat vagy hitelesítő adatokat készít elő a démon futtatása előtt. Ennek a szkriptnek a felülírása kihagyja az előkészítést, és egy félig konfigurált névtérben feljött alagút hibakeresésével hagyja magára.

Futtassa a klienst előtérben, és hagyja, hogy a konténer fő folyamata legyen. Az a folyamat, amely daemonizálódik, azonnal kilép, a konténer hurokban újraindul, és a szükséges naplók olyan újraindítások között oszlanak meg, amelyek mind egyformán néznek ki.

A névtéren belülről ellenőrizzen, ne a gazdagépről

Hozza fel a stacket, erősítse meg a naplóban, hogy a kliens elérte a csatlakozott állapotot, majd vizsgálja meg azt a névteret, amely valójában az alagutat tartja.

docker compose up -d
docker compose logs --tail 40 vpn
docker compose exec vpn ip -br addr
docker compose exec vpn ip route

A címek listájának mutatnia kell egy alagút-interfészt a poolból származó címmel, az útvonaltáblának pedig a felé mutató pusholt célokat. Ha az interfész hiányzik, a kliens soha nem jutott el a létrehozásáig. Ha létezik, de egyetlen útvonal sem használja, a keresés helye a push vagy az útvonal-beállítások.

Ezután tesztelje a számára fontos célt abból a névtérből, amelynek az alagutat használnia kell, az alkalmazással, és ne csak pinggel. A névfeloldás külön hiba, amelyet érdemes kifejezetten tesztelni: a pusholt DNS-cím önmagában nem frissíti a konténer feloldóját, és egy önálló kliens, amely figyelmen kívül hagyja a pusht, azon keresztül oldja fel a neveket, amit az image beállított.

A leválasztott állapot a szerződés része

Az újracsatlakozási viselkedésnek saját ellenőrzés kell, mert az újraindítási szabályzat azt bizonyítja, hogy a folyamat újraindul, és semmit nem mond arról, mit tesz közben a forgalom. Állítsa le az alagutat, próbálja ki a szándékolt célt, és figyelje, hogy a kapcsolat elutasításra kerül-e, elakad-e, vagy csendben sikerül-e a konténer szokásos útvonalán. Az utolsó eredmény az, amely számít, és egy egészséges naplóban láthatatlan.

Ha a munkaterhelés soha nem használhatja a szokásos utat, tervezze ezt kifejezetten tűzfalszabályokkal és a névtéren belüli készenléti jellel. A kill switch olyan szabályzat, amelyet ír és tesztel, nem olyan tulajdonság, amelyet egy konténerben futó klienstől örököl.

Végül emlékezzen a határra: ezek az útvonalak a konténer névterében élnek, és nem helyettesítik a gazdagép útválasztási táblázatát. A Docker továbbítási, fordítási és tűzfalszabályai továbbra is a külső út részét képezik, és egy közzétett port nem VPN-interfész.

Kapcsolódó cikkek