NET_ADMIN е Linux способноста што му дозволува на процесот да врши мрежна администрација, а во контејнер тоа го прави токму во мрежниот именски простор во кој работи процесот. Тоа не е лиценца за отворање сокет и не е замена за уред или рута. Интересното прашање никогаш не е дали способноста е доделена, туку кој именски простор ја добива промената.

Што покрива способноста

Во својот именски простор, процес што држи NET_ADMIN може да крева и спушта интерфејси, да доделува адреси, да додава и отстранува рути и да пишува firewall правила, што е групата операции што capabilities(7) ги собира под оваа способност. Може и да ги прилагодува поставките на ниво на интерфејс што контролираат како јадрото го става сообраќајот во ред и го филтрира. VPN клиентот обично бара неколку од нив при стартување и ништо друго потоа. Затоа повеќето слики бараат поголем опсег отколку што користат.

Операциите надвор од тој именски простор не се покриени, а соседните привилегии се одделни. Читањето и пишувањето сурови пакети и припаѓа на NET_RAW, а создавањето tun уред бара и способноста и пристап до јазолот на уредот. Процес без уредот добива грешка за дозвола што изгледа како мрежен проблем и не е.

Именскиот простор го одредува радиусот на штетата

Контејнер на сопствената мостовна мрежа достигнува сопствен loopback, сопствени интерфејси и сопствена табела за рутирање. Доделувањето на NET_ADMIN таму му дозволува на VPN клиентот да изгради тунел без да ги допре одлуките за рутирање на хостот, што е распоредот што го претпоставуваат повеќето контејнерски слики.

Префрлете го тој контејнер на хост мрежа и истото доделување сега ги уредува рутите на хостот и firewall-от на хостот, бидејќи не остана одделен именски простор. Клиентот што требаше да управува со еден тунел тогаш може да го пренасочи сообраќајот на целата машина, а грешка во неговата скрипта за расклопување му остава на хостот правила што никој не ги напишал. Ништо во самата способност не се промени; контекстот се промени. Затоа истиот compose фајл се однесува различно на два хоста.

Три предуслови што се спојуваат во еден

Неуспесите при стартување во VPN контејнери обично вклучуваат една од три одделни работи: способноста, тунелскиот уред и поддршката на јадрото за протоколот. Доделувањето на сите три одеднаш работи, и исто така го прави следниот неуспех невозможен за припишување. Минимален compose фрагмент ја доделува способноста и експлицитно го пренесува јазолот на уредот:

services:
  vpn:
    image: example/vpn-client:latest
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1

Прочитајте ја сопствената документација на сликата за тоа кои sysctl и се потребни, бидејќи sysctl во контејнер може да бара дополнителна привилегија или поставка на ниво на хост. Каде сликата поддржува само режим на кориснички простор, уред воопшто не е потребен и списокот со способности соодветно се намалува.

Доделете ја тесната операција, не режимот

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

Распоредувањата без root и во кориснички именски простори го менуваат тоа што способноста значи во практика, бидејќи процесот може да ја држи само во мапиран именски простор. Копирањето список со способности од пример со root во извршна околина без root и очекувањето ист опсег е вообичаен начин да се изгуби попладне.

Тајните припаѓаат на одделна одлука. Држењето на NET_ADMIN не кажува ништо за тоа кој идентитет на партнер го презентира клиентот, кои акредитиви ги вчитува или како тие се ротираат. Мрежната администрација не дава доверба.

Проверете ја промената и запишете зошто постои дозволата

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

docker inspect --format '{{.HostConfig.CapAdd}} {{.HostConfig.NetworkMode}} {{.HostConfig.Privileged}}' vpn
docker exec vpn sh -c 'grep CapEff /proc/self/status'
docker exec vpn ip -br addr
docker exec vpn ip route

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

Тестирајте го и патот за расклопување, бидејќи клиент што пишува firewall правила може да ги остави зад себе. Запрете го контејнерот и повторно проверете го множеството правила на хостот ако се користи хост мрежа. Дозволата што е потребна само две секунди при стартување не треба во compose фајлот да се опишува како трајно барање без забелешка што го објаснува тоа.

Запишете ја причината до секоја способност: која операција ја бараше и што откажува без неа. Таа забелешка преживува ажурирања на сликата, и токму таа е разликата меѓу прегледан список со привилегии и оној што пораснал со копирање и лепење.

Поврзани статии