Kiel trovi, kiun systemd-sandbox rifuzis vian OpenVPN-hokon
La hoko funkcias kiel root kaj malsukcesas sub systemd, ĉar la unito konservas malpli da kapabloj, pli malgrandan /dev kaj nurlegajn vojojn.
La hoko funkcias, kiam vi rulas ĝin permane kiel root, kaj redonas Operation not permitted en la momento, kiam la servo lanĉas ĝin. La dosiero ne ŝanĝiĝis inter tiuj ruloj; la medio ŝanĝiĝis. systemd donas al la procezo pli malgrandan mondon: malpli da kapabloj, alian /dev, nurlegajn dosiersistemajn vojojn kaj plafonon de taskoj. Legu la malsukceson kiel limon, kiu rifuzis unu konkretan operacion, ne kiel skripton, kiu rompiĝis.
Komencu de la operacio, kiu estis rifuzita
Protokola linio, kiu diras, ke la unito malsukcesis, preskaŭ nenion diras al vi. La utila linio nomas la vokon, kiu estis rifuzita: aparata nodo, kiun oni ne povis malfermi, dosierujo, en kiun oni ne povis skribi, nomspaco, kiun oni ne povis krei. Trovu tiun vokon antaŭ ol tuŝi eĉ unu direktivon, ĉar ĉiu el ili respondas al malsama limigo. Poste legu la uniton, kiu efektive ruliĝis, inkluzive de drop-in-oj, anstataŭ la dosieron, kiun la pakaĵo liveris.
La suba peto presas la fragmentan vojon, la drop-in-dosierujojn kaj la ecojn, kiuj gravas por rifuzo de aparato aŭ dosiersistemo. Legu ĉiujn antaŭ ol decidi, kiu limo gravas:
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'Nenio en tiu bloko skribas. Se la rifuzita voko mankas en la ĵurnalo, altigu la detalecon de la kliento por unu rulo anstataŭ diveni direktivojn. Ruliĝanta procezo pruvas, ke la unito ekfunkciis, ne ke la hoko ruliĝis kun la bezonataj privilegioj.
Nomspaco bezonas muntajn rajtojn, kiujn TUN-aparato neniam uzas
Du operacioj, kiuj aspektas same ene de unu hoko, havas malsamajn permesprofilojn. Malfermi /dev/net/tun kaj krei la interfacon bezonas retan administradon plus aliron al tiu nodo. Krei nomitan retan nomspacon ankaŭ bezonas muntan laboron, ĉar la nomspaca ilo muntas freŝan /sys vidon kaj ligas statan dosierujon en sian lokon. upstream-klienta unito intence lasas muntan administradon ekster sia limiga aro, do la nomspaca paŝo estas rifuzita dum la tunelo mem estus funkciinta.
Tial doni la aparatan nodon ne savas la skripton. Aparata permeso respondas unu demandon, ĉu tiu procezo rajtas malfermi tiun nodon, kaj la nomspaca demando estas alia. Aligu la malsukcesantan vokon al ĝia kapablo antaŭ ol larĝigi ion ajn.
Testo en via ŝelo heredas ĉiun kapablon, kiun havas nelimigita root, kaj la unito heredas tion, kion konservis ĝia limiga aro. La du ruloj estas malsamaj eksperimentoj eĉ kiam la binara dosiero estas identa.
Aparatoj, protektitaj vojoj kaj taskoplafonoj
Kiam la rifuzita operacio estas konata, tri grupoj da direktivoj klarigas la plej multajn malsukcesojn. Aparatan aliron reguligas PrivateDevices, kiu anstataŭigas /dev per minimuma aro da pseŭdoapartoj, kaj DevicePolicy kun DeviceAllow, kiuj decidas, kion la cgroup permesas. /dev/net/tun ne estas parto de tiu minimuma aro, do unito kun PrivateDevices=yes ne povas malfermi ĝin, kion ajn diras la aparata politiko.
Dosiersistema protekto respondas duan demandon. ProtectHome=yes faras /home, /root kaj /run/user neatingeblaj, kaj ProtectSystem=full faras /usr, /boot kaj /etc nurlegeblaj. Tial hoko, kiu skribas apud sia propra agorda dosiero, funkcias en via ŝelo kaj malsukcesas sub la unito, kun la sama permesformo kiel mankanta kapablo. Movu la skribeblan enigon al vojo, kiun la politiko permesas, aŭ aldonu mallarĝan ReadWritePaths= eron.
Rimedlimoj estas la tria grupo, kaj la malplej evidenta. TasksMax= limigas, kiom da taskoj la unito rajtas krei, kaj plafono de dosierpriskribiloj kondutas same por soketoj kaj teniloj. Efektivigo, kiu kreskis preter la plafono, malsukcesas per rimeda eraro anstataŭ permesa eraro, kaj tial la preciza mesaĝo ankoraŭ gravas.
Elmetu la nomspacan paŝon el la hoko
Preparo, kiu bezonas privilegion, kiun la kliento ne rajtas havi, apartenas al sia propra unito. Oneshot, kiu ruliĝas antaŭ la kliento, konservas sian rezulton kaj estas ordigita antaŭ la konekto, donas al la nomspaca paŝo tion, kion ĝi bezonas, sen transdoni tiujn rajtojn al la tunela procezo. La kliento tiam referencas tiun uniton anstataŭ voki la skripton el sia up-hoko.
La suba ŝablono estas komenca formo, ne io aplikenda nelegite. Ĝi tenas la preparon tie, kie loĝas la privilegio, kaj lasas la tunelan uniton netuŝita:
# /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.targetAldonu la ordigon per drop-in anstataŭ redakti la pakaĵan uniton, por ke ĝisdatigo ne povu silente forĵeti vian ŝanĝon. La dosierujo estas ŝlosita al la nomo de la instanco, do dua profilo bezonas sian propran dosieron:
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-reloadRipetu la saman vokon post la ŝanĝo
Riparo konfirmiĝas nur kiam la sama voko produktas alian rezulton. Restartigu ambaŭ unitojn, plenumu la operacion, kiu malsukcesis, kaj komparu ĝian rezulton kun la ĵurnala linio, kiun vi konservis antaŭ la ŝanĝo. Unito, kiu ekfunkcias dum la hoko neniam plu ruliĝas, ne estas riparo.
La suba sekvenco tenas la komparon honesta, ĉar ĝi kontrolas la rifuzitan vokon anstataŭ la koloron de la unito. Konservu ĝian eligon apud la ĵurnala linio, kiun vi kaptis antaŭ la ŝanĝo:
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 tun0Nombru la rifuzojn anstataŭ legi la lastan linion, ĉar hoko povas malsukcesi, reprovi kaj sukcesi, kaj nur la nombro montras, ĉu la limo moviĝis. Lasu komenton en la drop-in nomante la direktivon, kiun vi malstreĉis, kaj la kialon, ĉar la sekva ĝisdatigo komparas vian agordon kun la pakaĵa defaŭlto. Unito, kiu ekfunkcias nur post kiam ĉiu protekto estas malŝaltita, ne estas riparita.