Ako zistiť, ktorý systemd sandbox odmietol váš OpenVPN hook
Hook funguje ako root a pod systemd zlyháva, pretože unit si drží menej schopností, menší /dev a cesty len na čítanie.
Hook funguje, keď ho spustíte ručne ako root, a vracia Operation not permitted v okamihu, keď ho služba spustí. Súbor sa medzi týmito behmi nezmenil; zmenilo sa prostredie. systemd dáva procesu menší svet: menej schopností, iný /dev, cesty súborového systému len na čítanie a strop úloh. Čítajte zlyhanie ako hranicu, ktorá odmietla jednu konkrétnu operáciu, nie ako pokazený skript.
Začnite operáciou, ktorá bola odmietnutá
Riadok logu, že unit zlyhal, vám nepovie takmer nič. Užitočný riadok pomenuje volanie, ktoré bolo odmietnuté: uzol zariadenia, ktorý sa nepodarilo otvoriť, adresár, do ktorého sa nepodarilo zapísať, menný priestor, ktorý sa nepodarilo vytvoriť. Nájdite to volanie skôr, než sa dotknete jedinej direktívy, pretože každá zodpovedá inému obmedzeniu. Potom si prečítajte unit, ktorý skutočne bežal, vrátane drop-in súborov, namiesto súboru, ktorý dodal balík.
Dotaz nižšie vypíše cestu fragmentu, adresáre pre drop-in a vlastnosti, ktoré sú dôležité pri odmietnutí zariadenia alebo súborového systému. Prečítajte si ich všetky, než rozhodnete, ktorá hranica je relevantná:
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'Nič v tom bloku nezapisuje. Ak odmietnuté volanie v logu chýba, zvýšte podrobnosti klienta na jeden beh, namiesto aby ste hádali direktívy. Bežiaci proces dokazuje, že unit naštartoval, nie že hook bežal s potrebnými oprávneniami.
Menný priestor potrebuje práva na mount, ktoré zariadenie TUN nikdy nepoužíva
Dve operácie, ktoré vnútri jedného hooku vyzerajú rovnako, majú rôzne profily oprávnení. Otvorenie /dev/net/tun a vytvorenie rozhrania potrebuje správu siete plus prístup k tomu uzlu. Vytvorenie pomenovaného sieťového menného priestoru tiež potrebuje prácu s mount, pretože nástroj menných priestorov montuje čerstvý /sys pohľad a pripája adresár stavu na jeho miesto. klientsky unit z upstreamu zámerne necháva správu mount mimo svojej množiny obmedzení, takže krok s menným priestorom je odmietnutý, hoci tunel samotný by fungoval.
Preto udelenie uzla zariadenia skript nezachráni. Povolenie zariadenia odpovedá na jednu otázku, či tento proces smie otvoriť tento uzol, a otázka menného priestoru je iná. Priraďte zlyhávajúce volanie k jeho schopnosti skôr, než čokoľvek rozšírite.
Test vo vašom shelli dedí všetky schopnosti, ktoré má neobmedzený root, a unit dedí to, čo jeho množina obmedzení zachovala. Tie dva behy sú rôzne experimenty aj keď je binárka rovnaká.
Zariadenia, chránené cesty a stropy úloh
Keď je odmietnutá operácia známa, tri skupiny direktív vysvetlia väčšinu zlyhaní. Prístup k zariadeniam riadi PrivateDevices, ktorý nahrádza /dev minimálnou sadou pseudozariadení, a DevicePolicy s DeviceAllow, ktoré rozhodujú, čo cgroup dovolí. /dev/net/tun nie je súčasťou tejto minimálnej sady, takže unit s PrivateDevices=yes ho nemôže otvoriť, nech politika zariadení hovorí čokoľvek.
Ochrana súborového systému odpovedá na druhú otázku. ProtectHome=yes robí /home, /root a /run/user nedostupnými, a ProtectSystem=full robí /usr, /boot a /etc len na čítanie. Preto hook, ktorý zapisuje vedľa svojho konfiguračného súboru, funguje vo vašom shelli a pod unitom zlyháva, s rovnakým tvarom oprávnenia ako chýbajúca schopnosť. Presuňte zapisovaný vstup na cestu, ktorú politika dovoľuje, alebo pridajte úzky ReadWritePaths= záznam.
Limity prostriedkov sú tretia skupina a najmenej zrejmá. TasksMax= obmedzuje, koľko úloh smie unit vytvoriť, a strop deskriptorov súborov sa správa rovnako pre sockety a rukoväte. Nasadenie, ktoré prerástlo strop, zlyháva s chybou prostriedkov, nie s chybou oprávnení, a preto presná správa stále záleží.
Presuňte krok s menným priestorom z hooku
Príprava, ktorá potrebuje oprávnenie, ktoré klient nesmie mať, patrí do vlastného unitu. Oneshot, ktorý beží pred klientom, drží si svoj výsledok a je zoradený pred spojením, dá kroku s menným priestorom, čo potrebuje, bez toho aby tie práva odovzdal procesu tunela. Klient potom na ten unit odkazuje, namiesto aby skript volal zo svojho up hooku.
Šablóna nižšie je počiatočný tvar, nie niečo, čo sa aplikuje neprečítané. Drží prípravu tam, kde žije oprávnenie, a unit tunela necháva nedotknutý:
# /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.targetPridajte poradie cez drop-in, namiesto aby ste upravovali zabalený unit, aby upgrade nemohol ticho zahodiť vašu zmenu. Adresár je viazaný na názov inštancie, takže druhý profil potrebuje vlastný súbor:
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-reloadZopakujte to isté volanie po zmene
Oprava je potvrdená len vtedy, keď to isté volanie dá iný výsledok. Reštartujte oba unity, spustite operáciu, ktorá zlyhala, a porovnajte jej výsledok s riadkom logu, ktorý ste si uložili pred zmenou. Unit, ktorý naštartuje, ale hook už nikdy nebeží, nie je oprava.
Sekvencia nižšie drží porovnanie poctivé, pretože kontroluje odmietnuté volanie, nie farbu unitu. Uložte jej výstup vedľa riadku logu, ktorý ste zachytili pred zmenou:
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 tun0Počítajte odmietnutia, namiesto aby ste čítali posledný riadok, pretože hook môže zlyhať, skúsiť to znova a uspieť, a len počet ukáže, či sa hranica posunula. Nechajte v drop-ine komentár s názvom direktívy, ktorú ste uvoľnili, a dôvodom, pretože budúci upgrade porovnáva vašu konfiguráciu so zabaleným predvoleným nastavením. Unit, ktorý naštartuje až po vypnutí každej ochrany, nie je opravený.