Вобразы кантэйнераў могуць змяшчаць усе патрэбныя бінарныя файлы і канфігурацыі OpenVPN і ўсё роўна пацярпець няўдачу пры першым сеткавым выкліку. Памылка называе /dev/net/tun, таму што праграма запытала ў ядра інтэрфейс TUN, а кантэйнер не меў ні вузла прылады, ні магчымасці стварыць яго. Гэта два асобныя дазволы, і выпраўленне аднаго пакідае другі роўна там, дзе ён быў.

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

Вузел прылады і магчымасць — гэта дзве дзверы

Вузел прылады — гэта аб’ект файлавай сістэмы, таму кантэйнер павінен бачыць яго ў сваёй прасторы імёнаў мантавання. Магчымасць — гэта дазвол, таму працэсу патрэбны CAP_NET_ADMIN у прасторы імёнаў, дзе будзе створаны інтэрфейс. Перадача прылады без магчымасці дае вам вузел, які адкрываецца, і ioctl, які не спраўляецца. Дазвол без прылады пакідае праграму няздольнай адкрыць хоць што-небудзь, таму абодва звычайна з’яўляюцца разам у прыкладах.

Налада devices у Docker адлюстроўвае прыладу хоста ў кантэйнеры, а cap_add карэктуе набор магчымасцей. Bind mount таго ж шляху паказвае файл, не ўжываючы семантыку доступу да прылады.

Аднавіце гэта па-за файлам Compose

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

ls -l /dev/net/tun
docker run --rm --cap-add NET_ADMIN --device /dev/net/tun:/dev/net/tun alpine sh -c 'apk add -q iproute2 && ip tuntap add dev tun9 mode tun && ip link show tun9'

Адсутнасць вузла на хосце азначае, што модуль tun недаступны, і гэта выпраўленне на баку хоста, а не кантэйнера. Вузел, які існуе, але не адкрываецца ўнутры кантэйнера, паказвае на доступ да прылады, і паведамленне скажа permission denied, а не no such file. Парадак гэтых дзвюх няўдач — гэта ўвесь дыягназ. Запішыце, якую вы бачылі, перш чым змяняць сцяг.

Памылкі пасля TUN — гэта іншыя праблемы

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

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

Праверце інтэрфейс унутры кантэйнера

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

ls -l /dev/net/tun
capsh --print | grep -i net_admin
ip link add dev tun9 type tun && ip link show tun9

Магчымасць, прысутная ў bounding set, але адсутная ў effective set, паводзіць сябе інакш, чым тая, што ніколі не выдавалася, і capsh паказвае абедзве. Калі вузел існуе і магчымасць ёсць, а стварэнне ўсё яшчэ церпіць няўдачу, асяроддзе выканання ўжывае нешта іншае, напрыклад профіль seccomp або палітыку AppArmor, якая абмяжоўвае аперацыю. Гэта трэцяя мяжа, якую дакументуе асяроддзе выканання, а не праграма.

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

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