Sit 'n VPN-kliënt in 'n houer en jy kry een naamruimte met 'n tonnel daarbinne, nie 'n gasheer wat al sy verkeer deur 'n VPN stuur nie. Dit is aparte projekte, en om hulle as een te behandel, is hoe houers per ongeluk bevoorreg raak. Hierdie handleiding dek net die eerste: een nagegane beeld, een beskermde profiel en 'n kliëntproses wat tot sy eie netwerknaamruimte beperk is.

Begin met 'n artefak wat iemand reeds goedgekeur het. Die stappe hieronder aanvaar 'n beeld wat die openvpn-uitvoerbare lêer bevat en 'n volledige kliëntprofiel met sy sertifikaat en sleutelmateriaal wat reeds binne die montering opgelos is. Hulle bou nie sagteware, skep nie geloofsbriewe nie en dek nie wortellose looptye en inheemse Windows-houers nie, wat elkeen die antwoord verander.

Wat die houer kry en nie kry nie

Hou die profiel en alles waarna dit verwys in 'n plaaslike gids met beperkte regte, gemonteer as net-lees. Relatiewe paadjies binne die profiel moet binne daardie montering oplos, en dit is 'n detail wat mense mis wanneer 'n sertifikaat een gids bo die profiel sit en die houer dit nooit sien nie.

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

Daardie lêer gee drie dinge en vra niks anders nie. Die beeldverwysing moet volgens digest vasgepen word as jou ontplooiingsbeleid dit sê, en die profiel moet die nagegane een wees eerder as 'n kopie wat iemand op die gasheer in plek geredigeer het.

Net-lees beteken hier die houer kan nie jou gasheerlêers verander nie; dit beteken nie die houer kan nie die privaatsleutel lees wat jy gemonteer het nie. Dit is die hele punt van die montering, en dit is ook waarom lêerregte, eienaarskap en hoe die geheim op die gasheer beland het steeds saak maak. Moet nooit 'n wagwoord op die opdragreël deurgee of in 'n beeldlaag inbak nie, want beide oorleef op plekke wat jy later nie kan skoonmaak nie.

Vermoëns, entrypoint en die lokval tussen hulle

Twee instellings word benodig en hulle doen onverwante werk. NET_ADMIN laat koppelvlak- en roetemanipulasie binne die houer se naamruimte toe. Die /dev/net/tun-toestelinskrywing laat die proses toe om die tonneltoestel hoegenaamd oop te maak. Om die een sonder die ander te gee, lewer 'n duidelike mislukking, wat gerieflik is: 'n ontbrekende TUN-toestel misluk met oopmaak, terwyl 'n ontbrekende vermoë misluk wanneer die kliënt die koppelvlak probeer opstel.

Nie een van dié regverdig privileged: true nie. 'n Bevoorregte houer kry elke vermoë plus toesteltoegang, en dit is 'n veel groter toekenning as wat hierdie werklading nodig het. Die verwysing vir looptydvoorregte en -vermoëns verduidelik hoe ver daardie toekenning strek. As 'n chart of 'n blogpos dit vra, kyk eers of die vereiste nie eintlik 'n ontbrekende toestelpad of 'n ontbrekende vermoë was nie.

Die entrypoint-oorheersing is die deel wat byt. Om openvpn direk aan te roep is korrek vir 'n gewone beeld en verkeerd vir enige produkbeeld wie se opstartskrip firewallreëls, resolver-lêers of geloofsbriewe voorberei voordat dit die daemon uitvoer. Om daardie skrip te oorheers, slaan die voorbereiding oor en laat jou 'n tonnel ontfout wat in 'n half-opgestelde naamruimte opgekom het.

Laat die kliënt op die voorgrond loop en laat dit die houer se hoofproses wees. 'n Proses wat daemoniseer, stop dadelik, die houer herbegin in 'n lus, en die logs wat jy nodig het, is versprei oor herstarts wat elkeen dieselfde lyk.

Verifieer van binne die naamruimte, nie van die gasheer nie

Bring die stapel op, bevestig in die log dat die kliënt 'n gekoppelde toestand bereik het, en ondersoek dan die naamruimte wat die tonnel werklik hou.

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

Die adreslys moet 'n tonnelkoppelvlak wys met 'n adres uit die poel, en die roetebeeld moet die gestuurde bestemmings wys wat daarheen wys. As die koppelvlak ontbreek, het die kliënt nooit die punt bereik om dit te skep nie. As dit bestaan maar geen roete dit gebruik nie, is die push of die roete-opsies die plek om te kyk.

Toets dan die bestemming wat jy saak maak, vanuit die naamruimte wat veronderstel is om die tonnel te gebruik, met die toepassing eerder as net 'n ping. Naamresolusie is 'n aparte mislukking wat die moeite werd is om eksplisiet te toets: 'n gestuurde DNS-adres werk nie vanself 'n houer se resolver op nie, en 'n selfstandige kliënt wat die push ignoreer, sal name oplos deur wat die beeld ook al opgestel het.

Die ontkoppelde toestand is deel van die kontrak

Herverbindingsgedrag het sy eie kontrole nodig, want 'n herbeginbeleid bewys die proses herbegin en sê niks oor wat verkeer intussen doen nie. Stop die tonnel, probeer die bedoelde bestemming, en kyk of die verbinding geweier word, hang, of stilweg deur die houer se gewone roete slaag. Die laaste uitkoms is die een wat saak maak, en dit is onsigbaar in 'n gesonde log.

As die werklading nooit die gewone pad mag gebruik nie, ontwerp dit eksplisiet met firewallreëls en 'n gereedheidsein binne die naamruimte. 'n Kill switch is 'n beleid wat jy skryf en toets, nie 'n eienskap wat jy erf deur 'n kliënt in 'n houer te laat loop nie.

Onthou laastens die grens: hierdie roetes leef in die houer se naamruimte en vervang nie die gasheer se roetebeeld nie. Docker se deurstuur-, vertaal- en firewallreëls bly deel van die buitenste pad, en 'n gepubliseerde poort is nie 'n VPN-koppelvlak nie.

Verwante artikels