NET_ADMIN у кантэйнеры VPN: што ён можа змяніць і дзе
Магчымасць дазваляе змены інтэрфейсаў, маршрутаў і міжсеткавага экрана ў адной прасторы імёнаў сеткі. Пры сетцы хаста гэтая прастора — уласны стек хаста.
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 як пастаянную патрабу без заўвагі, якая гэта тлумачыць.
Запішыце прычыну побач з кожнай магчымасцю: якая аперацыя яе патрабавала і што без яе ламаецца. Гэтая заўвага перажывае абнаўленні вобраза, і менавіта яна адрознівае прагледжаны спіс прывілеяў ад таго, што вырас капіраваннем.