Ставите VPN клијент у контејнер и добијате један именски простор са тунелом унутра, а не домаћина који сав свој саобраћај усмерава кроз VPN. То су одвојени пројекти, и управо њихово третирање као једног доводи до тога да контејнери случајно постану привилеговани. Овај приручник покрива само прво: једну прегледану слику, један заштићени профил и клијентски процес ограничен на сопствени мрежни именски простор.

Почните од артефакта који је неко већ одобрио. Кораци испод претпостављају слику која садржи извршну датотеку openvpn и потпун клијентски профил чији су сертификат и кључни материјал већ решени унутар монтирања. Они не граде софтвер, не издају акредитиве и не покривају окружења без root-а нити нативне Windows контејнере, од којих свако мења одговор.

Шта контејнер добија, а шта не

Држите профил и све на шта се позива у локалном директоријуму са ограниченим дозволама, монтираном само за читање. Релативне путање унутар профила морају се решити у оквиру тог монтирања; то је детаљ који људи пропуштају када сертификат стоји један директоријум изнад профила и контејнер га никада не види.

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

Та датотека даје три ствари и не тражи ништа друго. Референца слике треба да буде причвршћена digest-ом ако ваша политика распоређивања то каже, а профил треба да буде прегледани, а не копија коју је неко уредио на самом месту на домаћину.

Само за читање овде значи да контејнер не може да мења ваше датотеке на домаћину; то не значи да контејнер не може да прочита приватни кључ који сте монтирали. То је цела поента монтирања, и зато дозволе датотека, власништво и начин на који је тајна стигла на домаћина и даље имају значај. Никада не преносите лозинку на командној линији и не уграђујте је у слој слике, јер обоје преживљава на местима која касније не можете очистити.

Могућности, entrypoint и замка између њих

Потребна су два подешавања и она обављају неповезане послове. NET_ADMIN дозвољава манипулацију интерфејсима и рутама унутар именског простора контејнера. Запис за уређај /dev/net/tun дозвољава процесу да уопште отвори уређај тунела. Давање једног без другог производи јасан неуспех, што је згодно: уређај TUN који недостаје не успева при отварању, док могућност која недостаје не успева када клијент покуша да конфигурише интерфејс.

Ниједно од тога не оправдава privileged: true. Привилеговани контејнер добија све могућности плус приступ уређајима, и то је много веће давање него што је потребно овом радном оптерећењу. референца о привилегијама и могућностима извршног окружења објашњава докле то давање сеже. Ако chart или блог објава то тражи, прво проверите да ли је захтев заправо био путања уређаја која недостаје или могућност која недостаје.

Преписивање entrypoint је део који уједа. Директно позивање openvpn је исправно за обичну слику и погрешно за сваку продуктну слику чија стартна скрипта припрема правила заштитног зида, датотеке резолвера или акредитиве пре покретања демона. Преписивање те скрипте прескаче припрему и оставља вас да отклањате грешке на тунелу који је настао у напола конфигурисаном именском простору.

Покрените клијент у првом плану и пустите га да буде главни процес контејнера. Процес који се демонизује одмах излази, контејнер се рестартује у петљи, а логови који су вам потребни разбацани су по рестартовањима која сва изгледају исто.

Проверавајте изнутра из именског простора, а не са домаћина

Подигните стек, потврдите у логу да је клијент достигао повезано стање, а затим прегледајте именски простор који заиста држи тунел.

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

Листа адреса треба да покаже интерфејс тунела са адресом из пула, а табела рута треба да покаже гурнуте дестинације које показују на њега. Ако интерфејс недостаје, клијент никада није стигао до његовог стварања. Ако постоји али ниједна рута га не користи, место за тражење су push или опције рута.

Затим тестирајте дестинацију која вам је важна, из именског простора који треба да користи тунел, помоћу апликације, а не само ping-ом. Решавање имена је одвојен неуспех који вреди експлицитно тестирати: гурнута DNS адреса сама не ажурира резолвер контејнера, а самостални клијент који игнорише push решаваће имена кроз оно што је слика конфигурисала.

Искључено стање је део уговора

Понашање при поновном повезивању захтева сопствену проверу, јер политика рестартовања доказује да се процес рестартује и не говори ништа о томе шта саобраћај ради у међувремену. Зауставите тунел, покушајте предвиђену дестинацију и посматрајте да ли се веза одбија, виси или тихо успева кроз уобичајену руту контејнера. Последњи исход је онај који је важан, и он је невидљив у здравом логу.

Ако радно оптерећење никада не сме да користи уобичајену путању, пројектујте то експлицитно правилима заштитног зида и сигналом спремности унутар именског простора. Kill switch је политика коју пишете и тестирате, а не својство које наслеђујете покретањем клијента у контејнеру.

На крају, запамтите границу: ове руте живе у именском простору контејнера и не замењују табелу рутирања домаћина. Правила за прослеђивање, превођење и заштитни зид у Docker-у остају део спољашњег пута, а објављени порт није VPN интерфејс.

Повезани чланци