Dejte OpenVPN CAP_NET_ADMIN bez předání rootu
Unit, který startuje jako neprivilegovaný uživatel, stále potřebuje správnou sadu schopností. Zkontrolujte unit, živý proces a hranici exec, v tomto pořadí.
Služba se spustí, log si stěžuje, že nemůže otevřít zařízení tun, a trasy se nikdy neobjeví. Spusťte capsh --print ve svém shellu a cap_net_admin je hned tam, což dělá selhání nemožným. Co se liší mezi vaším shellem a unitem, je přechod oprávnění, ne ochota jádra schopnost udělit. Projděte čtyři kontroly níže v pořadí a zastavte se u první, která mezeru vysvětlí.
Oddělte chybějící schopnost od skrytého zařízení
Dvě selhání vypadají z řádku logu stejně. Proces bez CAP_NET_ADMIN nemůže vytvořit ani nakonfigurovat rozhraní tunelu a proces, jehož sandbox skrývá /dev/net/tun, ho nemůže otevřít už od začátku. Přidání schopností druhou situaci neopraví.
Než cokoli upravíte, zkontrolujte, zda zařízení existuje uvnitř jmenného prostoru služby. PrivateDevices=yes je běžný řádek zpevnění, který uzel tun úplně odstraní, a restriktivní ProtectSystem může udělat cestu ke konfiguraci jen pro čtení způsobem, který se čte jako chyba oprávnění. Obě varianty vytvářejí řádky logu, které zmiňují tunel, a proto se vina svaluje na schopnosti. Nejprve potvrďte, že uzel existuje a lze ho otevřít, a pak pokračujte.
Vězte, na kterou sadu schopností se díváte
Linux drží povolenou, efektivní, děditelnou, ohraničující a ambientní sadu a právě ambientní sada přežije exec od uživatele, který není root. Souborové schopnosti na binárce mohou při exec předat povolená a efektivní práva, ale jen dokud nic v řetězu tento přenos neblokuje.
Právě zde sudo lidi mate. Příkaz spuštěný přes sudo -u zahájí nový přechod oprávnění a ambientní sada zmizí, takže stejná kontrola, která uspěje jako root, tam selže. Správce služeb je další přechod a nic ambientního nedá, pokud to unit neřekne.
Udělte schopnost v unitu, ne v obalu
Minimální sekce služby pro tunel, který musí vytvořit zařízení a nainstalovat trasy, vypadá takto.
[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.confAmbientCapabilities vloží právo do ambientní sady před spuštěním procesu a CapabilityBoundingSet brání procesu držet cokoli mimo tento seznam. NoNewPrivileges=yes blokuje získání oprávnění přes setuid nebo souborové schopnosti, zatímco schopnost, kterou unit výslovně uděluje, stále platí. Přidejte CAP_NET_BIND_SERVICE jen tehdy, když služba musí navázat nízký port, a nikdy nepřidávejte CAP_SYS_ADMIN jen proto, že to udělalo nějaké vlákno na fóru.
Pokud unit obaluje binárku do sudo, obal odstraňte. systemd už User= uplatňuje a tato extra vrstva je nejpravděpodobnější důvod, proč je ambientní sada prázdná.
Ověřujte proti živému procesu, ne proti souboru unitu
Přečtěte si, co správce skutečně použil, a pak si přečtěte proces, který spustil.
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")/statusPokud unit schopnost uvádí a CapEff ji stále nemá, nějaký drop-in přepisuje nastavení nebo krok ExecStartPre mění prostředí. Než budete předpokládat, že hlavní soubor je směrodatný, prohledejte drop-in adresáře podle názvu unitu, protože pozdější soubor tiše vyhraje. Pokud schopnost ukazují unit i proces a tunel stále selhává, vraťte se ke kontrolám zařízení a cesty místo rozšiřování ohraničující sady. Její rozšíření skryje skutečnou příčinu a nechá službu privilegovanější, než byla.
Raději upusťte oprávnění po startu
OpenVPN může začít s oprávněními a poté přejít na neprivilegovaný účet pomocí vlastních voleb user a group, přičemž persist-key a persist-tun udrží tunel dál použitelný. Takové uspořádání zužuje okno, ve kterém proces drží práva, a často se hodí víc než spouštět celý daemon neprivilegovaně s trvalými schopnostmi.
Ať zvolíte jakýkoli model, restartujte unit a po restartu systému kontroly zopakujte, protože služba, která funguje z interaktivního root shellu a při bootu selže, bývá rozdílem ve schopnosti, zařízení nebo souborových oprávněních. Zapište nastavení unitu vedle výstupu schopností procesu, aby další recenzent viděl, zda hranici posunula aktualizace balíčku nebo drop-in.