Як знайсці, які systemd-sandbox адхіліў ваш хук OpenVPN
Хук працуе ад root і падае пад systemd, бо unit пакідае менш магчымасцяў, меншы /dev і шляхі толькі для чытання.
Хук працуе, калі вы запускаеце яго ўручную ад root, і вяртае Operation not permitted у момант, калі служба запускае яго. Файл паміж гэтымі запускамі не змяніўся; змянілася асяроддзе. systemd дае працэсу меншы свет: менш магчымасцяў, іншы /dev, шляхі файлавай сістэмы толькі для чытання і столак задач. Чытайце збой як мяжу, якая адхіліла адну канкрэтную аперацыю, а не як сцэнар, што зламаўся.
Пачніце з аперацыі, якую адхілілі
Радок журнала пра тое, што unit не запусціўся, не кажа амаль нічога. Карысны радок называе выклік, які адхілілі: вузел прылады, які не ўдалося адкрыць, каталог, у які не ўдалося запісаць, прастора імёнаў, якую не ўдалося стварыць. Знайдзіце гэты выклік, перш чым кранаць хоць адну дырэктыву, бо кожная адпавядае іншаму абмежаванню. Затым чытайце unit, які сапраўды працаваў, разам з drop-in, а не файл, які паставіў пакет.
Запыт ніжэй друкуе шлях фрагмента, каталогі drop-in і ўласцівасці, якія важныя для адмовы ў прыладзе ці файлавай сістэме. Прачытайце іх усе, перш чым вырашаць, якая мяжа мае значэнне:
systemctl show "[email protected]" -p FragmentPath -p DropInPaths -p PrivateDevices -p DevicePolicy -p DeviceAllow -p ProtectHome -p ProtectSystem -p TasksMax
journalctl -u "[email protected]" -b --no-pager | grep -iE 'operation not permitted|permission denied|cannot open|failed'Нішто ў гэтым блоку не піша. Калі адхіленага выкліку няма ў журнале, павялічце падрабязнасць кліента на адзін запуск замест здагадак пра дырэктывы. Працэс, які працуе, даказвае, што unit запусціўся, а не што хук працаваў з патрэбнымі прывілеямі.
Прастора імёнаў патрабуе правоў мантавання, якіх прылада TUN не выкарыстоўвае
Дзве аперацыі, якія выглядаюць аднолькава ўнутры аднаго хука, маюць розныя профілі дазволаў. Адкрыццё /dev/net/tun і стварэнне інтэрфейсу патрабуе сеткавага адміністравання і доступу да гэтага вузла. Стварэнне названай сеткавай прасторы імёнаў таксама патрабуе працы з мантаваннем, бо інструмент прасторы імёнаў мантуе свежы /sys выгляд і прывязвае каталог стану на месца. вышэйстаячая кліенцкая unit наўмысна пакідае кіраванне мантаваннем па-за сваім наборам межаў, таму крок з прасторай імёнаў адхіляецца, хаця сам тунель працаваў бы.
Вось чаму выдача вузла прылады не ратуе сцэнар. Дазвол на прыладу адказвае на адно пытанне: ці можа гэты працэс адкрыць гэты вузел. А пытанне прасторы імёнаў іншае. Супастаўце збойны выклік з яго магчымасцю, перш чым нешта пашыраць.
Тэст у вашай абалонцы ўспадкоўвае ўсе магчымасці неабмежаванага root, а unit успадкоўвае тое, што захаваў яго набор межаў. Гэтыя два запускі — розныя эксперыменты нават калі бінарнік адзін і той жа.
Прылады, абароненыя шляхі і столкі задач
Калі адхіленая аперацыя вядомая, тры групы дырэктыў тлумачаць большасць збояў. Доступ да прылад рэгулюе PrivateDevices, якая замяняе /dev мінімальным наборам псеўдапрылад, і DevicePolicy з DeviceAllow, якія вырашаюць, што дазваляе cgroup. /dev/net/tun не ўваходзіць у гэты мінімальны набор, таму unit з PrivateDevices=yes не можа адкрыць яго, што б ні казала палітыка прылад.
Ахова файлавай сістэмы адказвае на другое пытанне. ProtectHome=yes робіць /home, /root і /run/user недаступнымі, а ProtectSystem=full робіць /usr, /boot і /etc толькі для чытання. Таму хук, які піша побач са сваім файлам канфігурацыі, працуе ў вашай абалонцы і падае пад unit, з той жа формай дазволу, што і адсутная магчымасць. Перанясіце запісваны ўвод у шлях, які дазваляе палітыка, або дадайце вузкі ReadWritePaths= запіс.
Абмежаванні рэсурсаў — трэцяя група, і найменш відавочная. TasksMax= абмяжоўвае колькасць задач, якія unit можа стварыць, а столак дэскрыптараў файлаў дзейнічае гэтак жа для сокетаў і дэскрыптараў. Разгортванне, якое вырасла за столак, падае з памылкай рэсурсаў, а не з памылкай дазволу, і менавіта таму дакладнае паведамленне ўсё яшчэ важнае.
Вынясіце крок з прасторай імёнаў з хука
Падрыхтоўка, якая патрабуе прывілеі, якой кліент не павінен мець, належыць уласнаму unit. Oneshot, які працуе перад кліентам, захоўвае свой вынік і ўпарадкаваны перад злучэннем, дае кроку з прасторай імёнаў патрэбнае, не перадаючы гэтых правоў працэсу тунеля. Затым кліент спасылаецца на гэты unit замест выкліку сцэнара са свайго up-хука.
Шаблон ніжэй — пачатковая форма, а не тое, што трэба ўжываць не прачытаўшы. Ён захоўвае падрыхтоўку там, дзе жыве прывілея, і не кранае unit тунеля:
# /etc/systemd/system/[email protected]
[Unit]
Description=Namespace preparation for %i
Before=openvpn-client@%i.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/sbin/netns-up.sh %i
CapabilityBoundingSet=CAP_NET_ADMIN CAP_SYS_ADMIN
[Install]
WantedBy=multi-user.targetДадайце парадак праз drop-in, а не праз праўку пакетаванага unit, каб абнаўленне не магло моўчкі скінуць вашу змену. Каталог прывязаны да імя асобніка, таму другі профіль патрабуе ўласнага файла:
sudo mkdir -p /etc/systemd/system/[email protected]
sudo tee /etc/systemd/system/[email protected]/10-namespace.conf >/dev/null <<'CONF'
[Unit]
[email protected]
[email protected]
CONF
sudo systemctl daemon-reloadПаўтарыце той жа выклік пасля змены
Праверка рамонту магчымая толькі тады, калі той жа выклік дае іншы вынік. Перазапусціце абодва unit, выканайце аперацыю, якая падала, і параўнайце яе вынік з радком журнала, захаваным да змены. Unit, які запускаецца, але хук больш не працуе, — гэта не рамант.
Паслядоўнасць ніжэй трымае параўнанне сумленным, бо правярае адхілены выклік, а не колер unit. Захавайце яе вывад побач з радком журнала, які вы знялі да змены:
sudo systemctl restart "[email protected]" "[email protected]"
systemctl status "[email protected]" --no-pager
journalctl -u "[email protected]" -b --no-pager | grep -c 'Operation not permitted'
ip -brief addr show tun0Лічыце адмовы, а не чытайце апошні радок, бо хук можа падаць, паўтарыцца і атрымацца, і толькі лік паказвае, ці зрушылася мяжа. Пакіньце ў drop-in каментар з назвай дырэктывы, якую вы паслабілі, і прычынай, бо наступнае абнаўленне параўноўвае вашу канфігурацыю з пакетаванымі значэннямі па змаўчанні. Unit, які запускаецца толькі пасля адключэння ўсялякай аховы, не выпраўлены.