NET_ADMIN — гэта магчымасць Linux, якая дазваляе працэсу выконваць адміністраванне сеткі, і ў кантэйнеры яна робіць менавіта гэта ў той прасторы імёнаў сеткі, дзе выконваецца працэс. Гэта не ліцэнзія на адкрыццё сокета і не замена прыладзе ці маршруту. Цікавае пытанне ніколі не ў тым, ці дадзена магчымасць, а ў тым, якая прастора імёнаў атрымае змену.

Што ахоплівае магчымасць

Унутры сваёй прасторы імёнаў працэс з NET_ADMIN можа ўздымаць і апускаць інтэрфейсы, прызначаць адрасы, дадаваць і выдаляць маршруты і пісаць правілы міжсеткавага экрана — гэта група аперацый, якую capabilities(7) збірае пад гэтай магчымасцю. Ён таксама можа наладжваць параметры ўзроўню інтэрфейса, якія кіруюць тым, як ядро ставіць у чаргу і фільтруе трафік. Кліенту VPN звычайна патрэбна некалькі з іх пры запуску і больш нічога потым. Таму большасць вобразаў просіць больш правоў, чым выкарыстоўвае.

Аперацыі па-за гэтай прасторай не ахопліваюцца, а сумежныя прывілеі асобныя. Чытанне і запіс сырых пакетаў належыць NET_RAW, а стварэнне прылады tun патрабуе і магчымасці, і доступу да вузла прылады. Працэс без прылады атрымлівае памылку правоў, якая выглядае як сеткавая праблема, але ёй не з'яўляецца.

Прастора імёнаў вызначае радыус уражання

Кантэйнер у сваёй мосцевай сетцы дасягае свайго loopback, сваіх інтэрфейсаў і сваёй табліцы маршрутызацыі. Калі даць там NET_ADMIN, кліент VPN можа пабудаваць тунель, не закранаючы маршрутныя рашэнні хаста, — менавіта такую схему мяркуюць большасць вобразаў кантэйнераў.

Пераключыце гэты кантэйнер на сетку хаста, і той жа дазвол пачне змяняць маршруты хаста і ягоны міжсеткавы экран, бо асобнай прасторы імёнаў больш няма. Кліент, які павінен быў кіраваць адным тунелем, тады можа перанакіраваць трафік усёй машыны, а памылка ў яго скрыпце разбору пакідае хасту правілы, якіх ніхто не пісаў. У самой магчымасці нічога не змянілася; змяніўся кантэкст. Вось чаму адзін і той жа файл 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

Калі магчымасць ёсць, а спіс інтэрфейсаў усё яшчэ пусты, кліент збаў да таго, як змог нешта стварыць, і наступнае месца для пошуку — журналы кантэйнера. Калі тунель ёсць, але трафік не ідзе, табліца маршрутызацыі ўнутры кантэйнера адказвае на наступнае пытанне.

Праверце і шлях разбору, бо кліент, які піша правілы міжсеткавага экрана, можа пакінуць іх пасля сябе. Спыніце кантэйнер і пераправерце набор правілаў хаста, калі выкарыстоўваецца сетка хаста. Дазвол, патрэбны толькі на дзве секунды пры запуску, не варта апісваць у файле compose як пастаянную патрабу без заўвагі, якая гэта тлумачыць.

Запішыце прычыну побач з кожнай магчымасцю: якая аперацыя яе патрабавала і што без яе ламаецца. Гэтая заўвага перажывае абнаўленні вобраза, і менавіта яна адрознівае прагледжаны спіс прывілеяў ад таго, што вырас капіраваннем.

Падобныя артыкулы