Paano hanapin kung aling systemd sandbox ang tumanggi sa iyong OpenVPN hook
Gumagana ang hook kapag pinatakbo mo ito nang manu-mano bilang root at nabigo sa ilalim ng systemd dahil mas kaunti ang kapabilidad na hawak ng unit, mas maliit ang /dev at read-only ang mga path.
Gumagana ang hook kapag pinatakbo mo ito nang manu-mano bilang root at nagbabalik ng Operation not permitted sa sandaling sinimulan ito ng serbisyo. Hindi nagbago ang file sa pagitan ng mga run na iyon; nagbago ang kapaligiran. Binibigyan ng systemd ang proseso ng mas maliit na mundo: mas kaunting kapabilidad, ibang /dev, read-only na mga path ng filesystem at isang takip sa mga gawain. Basahin ang kabiguan bilang isang hangganan na tumanggi sa isang partikular na operasyon, hindi bilang iskrip na nasira.
Magsimula sa Operasyong Tinanggihan
Ang linyang log na nagsasabing nabigo ang unit ay halos walang sinasabi sa iyo. Ang kapaki-pakinabang na linya ay pinangalanan ang tawag na tinanggihan: isang device node na hindi mabuksan, isang directory na hindi maisusulat, isang namespace na hindi magawa. Hanapin ang tawag na iyon bago mo hawakan ang kahit isang direktiba, dahil bawat isa ay tumutugma sa ibang paghihigpit. Pagkatapos basahin ang unit na aktwal na tumakbo, kasama ang mga drop-in, sa halip na ang file na ipinadala ng package.
Ang query sa ibaba ay naglalabas ng path ng fragment, ang mga drop-in na directory at ang mga property na mahalaga para sa pagtanggi ng device o filesystem. Basahin ang lahat bago magpasya kung aling hangganan ang may kaugnayan:
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'Walang nagsusulat sa block na iyon. Kung wala ang tinanggihang tawag sa journal, taasan ang verbosity ng client para sa isang run sa halip na hulaan ang mga direktiba. Ang tumatakbong proseso ay nagpapatunay na nagsimula ang unit, hindi na tumakbo ang hook kasama ang mga pribilehiyong kailangan nito.
Ang Namespace ay Nangangailangan ng Mount Rights na Hindi Kailanman Ginagamit ng TUN Device
Dalawang operasyon na magkamukha sa loob ng isang hook ay may magkaibang profile ng pahintulot. Ang pagbukas ng /dev/net/tun at paggawa ng interface ay nangangailangan ng network administration at access sa node na iyon. Ang paggawa ng pinangalanang network namespace ay nangangailangan din ng mount-related na trabaho, dahil ang namespace tool ay nag-mount ng bagong /sys view at inilalagay ang state directory sa lugar nito. Ang unit ng client sa upstream ay sadyang iniiwan ang mount administration sa labas ng bounding set nito, kaya ang namespace step ay tinatanggihan habang ang tunnel mismo ay gagana sana.
Iyon ang dahilan kung bakit ang pagbibigay ng device node ay hindi nagliligtas sa iskrip. Ang pahintulot sa device ay sumasagot sa isang tanong, kung maaaring buksan ng prosesong ito ang node na ito, at ang tanong ng namespace ay iba. Itugma ang nabigong tawag sa kapabilidad nito bago palawakin ang anuman.
Ang isang pagsubok sa iyong shell ay nagmamana ng bawat kapabilidad na hawak ng walang limitasyong root, at ang unit ay nagmamana ng kung ano ang iniwan ng bounding set nito. Ang dalawang run ay magkaibang eksperimento kahit na ang binary ay pareho.
Mga Device, Protektadong Path at Takip sa Gawain
Kapag alam na ang tinanggihang operasyon, tatlong grupo ng direktiba ang nagpapaliwanag sa karamihan ng kabiguan. Ang access sa device ay pinamamahalaan ng PrivateDevices, na pumapalit sa /dev ng isang minimal na set ng pseudo-device, at ng DevicePolicy kasama ang DeviceAllow, na nagpapasya kung ano ang pinapayagan ng cgroup. /dev/net/tun ay hindi bahagi ng minimal na set na iyon, kaya ang unit na may PrivateDevices=yes ay hindi ito mabubuksan anuman ang sabihin ng device policy.
Ang proteksyon ng filesystem ay sumasagot sa pangalawang tanong. ProtectHome=yes ginagawang /home, /root at /run/user hindi maabot, at ProtectSystem=full ginagawang /usr, /boot at /etc read-only. Kaya ang hook na nagsusulat sa tabi ng sarili nitong configuration file ay gumagana sa iyong shell at nabigo sa ilalim ng unit, na may parehong hugis ng pahintulot tulad ng nawawalang kapabilidad. Ilipat ang naisusulat na input sa path na pinapayagan ng policy, o magdagdag ng makitid na ReadWritePaths= entry.
Ang mga limitasyon sa resource ay ang ikatlong grupo, at ang pinakamaliit na halata. TasksMax= ay naglilimita kung gaano karaming gawain ang maaaring gawin ng unit, at ang takip ng file descriptor ay ganoon din sa mga socket at handle. Ang deployment na lumaki lampas sa takip ay nabigo sa resource error sa halip na permission error, kaya mahalaga pa rin ang eksaktong mensahe.
Ilabas ang Namespace Step sa Labas ng Hook
Ang paghahanda na nangangailangan ng pribilehiyong hindi dapat taglayin ng client ay nabibilang sa sarili nitong unit. Ang oneshot na tumatakbo bago ang client, nagpapanatili ng resulta nito at nakaayos bago ang koneksyon ay nagbibigay sa namespace step ng kailangan nito nang hindi ipinapasa ang mga karapatang iyon sa tunnel process. Pagkatapos ay tinutukoy ng client ang unit na iyon sa halip na tawagin ang iskrip mula sa up hook nito.
Ang template sa ibaba ay panimulang hugis, hindi isang bagay na ilalapat nang hindi binabasa. Pinapanatili nito ang paghahanda kung saan naninirahan ang pribilehiyo at iniiwan ang tunnel unit na hindi ginalaw:
# /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.targetIdagdag ang pagkakasunod-sunod gamit ang drop-in sa halip na i-edit ang packaged unit, para hindi ito maaaring tahimik na iwan ng upgrade. Ang directory ay naka-key sa pangalan ng instance, kaya ang pangalawang profile ay nangangailangan ng sarili nitong file:
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-reloadUlitin ang Parehong Invocation Pagkatapos ng Pagbabago
Ang pag-aayos ay nakumpirma lamang kapag ang parehong invocation ay gumawa ng ibang resulta. I-restart ang parehong unit, patakbuhin ang operasyong nabigo, at ihambing ang kinalabasan nito sa journal line na iniligtas mo bago ang pagbabago. Ang unit na nagsisimula habang hindi na tumatakbo muli ang hook ay hindi pag-aayos.
Ang sequence sa ibaba ay nagpapanatili ng tapat na paghahambing, dahil sinusuri nito ang tinanggihang tawag sa halip na ang kulay ng unit. Iligtas ang output nito sa tabi ng journal line na nakuha mo bago ang pagbabago:
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 tun0Bilangin ang mga pagtanggi sa halip na basahin ang huling linya, dahil ang hook ay maaaring mabigo, magretry at magtagumpay, at ang bilang lamang ang nagpapakita kung gumalaw ang hangganan. Mag-iwan ng komento sa drop-in na pinangalanan ang direktibang niluwagan mo at ang dahilan, dahil ihinahambing ng susunod na upgrade ang iyong configuration sa packaged default. Ang unit na nagsisimula lamang kapag hindi pinagana ang bawat proteksyon ay hindi pa naayos.