Serviciul pornește, jurnalul se plânge că nu poate deschide dispozitivul tun, iar rutele nu apar niciodată. Rulați capsh --print în shell-ul propriu și cap_net_admin este chiar acolo, ceea ce face eșecul să pară imposibil. Ce diferă între shell-ul dumneavoastră și unitate este tranziția de privilegii, nu disponibilitatea nucleului de a acorda capabilitatea. Parcurgeți cele patru verificări de mai jos în ordine și opriți-vă la prima care explică diferența.

Separați o capabilitate lipsă de un dispozitiv ascuns

Două eșecuri arată la fel în linia de jurnal. Un proces fără CAP_NET_ADMIN nu poate crea sau configura interfața tunelului, iar un proces al cărui sandbox ascunde /dev/net/tun nu o poate deschide deloc. Adăugarea de capabilități nu va remedia al doilea caz.

Verificați dacă dispozitivul există în spațiul de nume al serviciului înainte de a modifica ceva. PrivateDevices=yes este o linie de întărire obișnuită care elimină complet nodul tun, iar un ProtectSystem restrictiv poate face calea de configurare doar-citire într-un mod care se citește ca o eroare de permisiuni. Ambele produc linii de jurnal care menționează tunelul, de aceea capabilitățile sunt învinuite. Confirmați mai întâi că nodul există și poate fi deschis, apoi mergeți mai departe.

Știți la ce set de capabilități vă uitați

Linux ține seturile permis, efectiv, moștenibil, de limitare și ambiental, iar setul ambiental este cel care supraviețuiește unui exec al unui utilizator care nu este root. Capabilitățile de fișier de pe binar pot transfera drepturi permise și efective la exec, dar numai atât timp cât nimic din lanț nu blochează acel transfer.

Aici sudo induce oamenii în eroare. O comandă rulată prin sudo -u începe o nouă tranziție de privilegii și setul ambiental dispare, așa că aceeași verificare care reușește ca root eșuează acolo. Managerul de servicii este încă o altă tranziție și nu acordă nimic ambiental dacă unitatea nu spune asta.

Acordați capabilitatea în unitate, nu într-un wrapper

O secțiune minimă de serviciu pentru un tunel care trebuie să creeze un dispozitiv și să instaleze rute se citește astfel.

[Unit]
Description=OpenVPN client, office profile
After=network-online.target

[Service]
Type=notify
User=openvpn
Group=openvpn
NoNewPrivileges=yes
AmbientCapabilities=CAP_NET_ADMIN
CapabilityBoundingSet=CAP_NET_ADMIN
ExecStart=/usr/sbin/openvpn --config /etc/openvpn/office.conf

AmbientCapabilities pune dreptul în setul ambiental înainte ca procesul să pornească, iar CapabilityBoundingSet împiedică procesul să dețină ceva în afara acelei liste. NoNewPrivileges=yes blochează obținerea de privilegii prin setuid sau capabilități de fișier, în timp ce capabilitatea acordată explicit de unitate se aplică în continuare. Adăugați CAP_NET_BIND_SERVICE doar când serviciul trebuie să lege un port jos, și nu adăugați niciodată CAP_SYS_ADMIN doar pentru că un fir de forum a făcut-o.

Dacă unitatea înfășoară binarul în sudo, eliminați wrapperul. systemd aplică deja User=, iar acel strat suplimentar este cel mai probabil motiv pentru care setul ambiental este gol.

Verificați pe procesul activ, nu pe fișierul unității

Citiți ce a aplicat de fapt managerul, apoi citiți procesul pe care l-a generat.

unit=openvpn-client@office
systemctl show -p User -p AmbientCapabilities "$unit"
systemctl show -p MainPID --value "$unit" | xargs -r getpcaps
grep -E '^Cap(Eff|Amb)' /proc/$(systemctl show -p MainPID --value "$unit")/status

Dacă unitatea enumeră capabilitatea și CapEff încă nu o are, un drop-in suprascrie setarea sau un pas ExecStartPre schimbă mediul. Căutați numele unității în directoarele drop-in înainte de a presupune că fișierul principal este autoritar, pentru că un fișier ulterior câștigă în tăcere. Dacă atât unitatea, cât și procesul arată capabilitatea și tunelul tot eșuează, întoarceți-vă la verificările de dispozitiv și cale în loc să lărgiți setul de limitare. Lărgirea lui ascunde cauza reală și lasă serviciul mai privilegiat decât era.

Preferiați să renunțați la privilegii după pornire

OpenVPN poate porni cu privilegii și apoi poate coborî la un cont fără privilegii prin propriile opțiuni user și group, cu persist-key și persist-tun păstrând tunelul utilizabil după aceea. Această aranjare îngustează fereastra în care procesul deține drepturi și adesea se potrivește mai bine decât pornirea întregului demon fără privilegii cu capabilități permanente.

Indiferent de modelul ales, reporniți unitatea și repetați verificările după o repornire, pentru că un serviciu care funcționează dintr-un shell root interactiv și eșuează la pornire este de obicei o diferență de capabilitate, dispozitiv sau permisiuni de fișier. Notați setările unității lângă ieșirea de capabilități a procesului, ca următorul recenzent să vadă dacă o actualizare de pachet sau un drop-in a mutat limita.

Articole similare