Met Sudo en Polkit rootrechten verdelen
Alweer een wachtwoord invullen? Dat hoeft niet altijd. Wat zinvol is op een server, is irritant op een thuis-pc. Met sudo en polkit kun je wachtwoordverzoeken en shares aan je eigen wensen aanpassen, op een manier waarbij veiligheid en gemak in evenwicht zijn.
Bij veel Linux-distributies is sudo standaard geïnstalleerd. Het heeft het klassieke root-account voor desktopsystemen overbodig gemaakt. Inloggen als root hoeft niet meer en je hebt er ook geen apart wachtwoord meer voor nodig. In plaats daarvan kan een gebruiker die je tijdens het installeren hebt aangemaakt commando’s uitvoeren met de privileges van de systeembeheerder door voor een commando sudo in te voegen. Maar sudo is niet alleen een soort van loper waar je overal mee binnenkomt, maar eerder een digitaal sluitsysteem. Bij de instellingen kun je in detail vastleggen wie welk programma als ‘superuser’ – of als andere gebruiker – mag uitvoeren en of daar een wachtwoord voor nodig is.
Polkit heeft een vergelijkbare functie, maar is in eerste instantie minder prominent zichtbaar voor veel gebruikers. Wanneer je in Gnome, Cinnamon of KDE Plasma bij het installeren van een programma of bij het wijzigen van de printerconfiguratie of het gebruikersbeheer wordt gevraagd een wachtwoord op te geven, is polkit op de achtergrond aan het werk. Als je zonder een wachtwoord in te voeren het netwerk configureert – wat ooit in Linux nog op alle manieren beveiligd werd – dan krijg je dankzij polkit toegang tot beschermde resources.
Bij computers met slechts één gebruiker vervalt het gebruik van twee verschillende wachtwoorden (gebruiker en root), terwijl je toch alleen maar als gebruiker bent ingelogd. Je kunt bovendien het vragen naar een wachtwoord volledig uitschakelen en benaderingen in een logboek laten bijhouden.
Bij multi-usersystemen bieden sudo en polkit het voordeel dat je rootrechten kunt delen met meerdere gebruikers, maar elke gebruiker zich met zijn eigen wachtwoord moet identificeren – als er al naar wordt gevraagd. Indien nodig kun je je bij sudo en polkit authenticeren met een FIDO-beveiligingsstick, vingerafdrukken of gezichtsherkenning in plaats van wachtwoorden [1].
VERSCHILLENDE CONCEPTEN
Polkit, voorheen bekend onder de naam PolicyKit, en sudo hebben verschillende benaderingen. Bij sudo draaien de processen met rootrechten, terwijl bij Polkit de processen binnen de context van de gebruiker blijven en in plaats daarvan afgeschermde functies benaderen via gedefinieerde interfaces. Om dat te doen, moeten de ontwikkelaars de polkit-API in hun applicaties gebruiken. Sudo kan anderzijds met bijna elk programma direct worden gebruikt. Beide maken voor het authenticeren gebruik van de Linux-bibliotheek PAM (Pluggable Authentication Modules).
In plaats van het hele grafische pakketbeheer met rootrechten te starten, verzorgt polkit alleen de toegang tot de het installeren van packages. Verdere kritische systeembenaderingen vereisen een hernieuwde aanvraag, die, afhankelijk van hoe de configuratie is, de gebruiker wederom moet goedkeuren. Op een Ubuntu 20.04 LTS-systeem kunnen ruim 300 individuele acties in ruim 50 programma’s via polkit worden aangestuurd. Afhankelijk van de hoeveelheid applicaties die er geïnstalleerd zijn, kunnen dat er ook aanzienlijk meer zijn.
Helaas is het configureren van polkit een beetje omslachtig. Dat is niet verwonderlijk, omdat het gericht is op ontwikkelaars, distributeurs en systeembeheerders. Eindgebruikers moeten daarentegen gewoon aan de slag kunnen met een compleet systeem dat klaar is voor gebruik, en niet eerst hoeven worstelen met het configureren van polkit.
MAKKELIJKER WERKEN MET SUDO
Inmiddels is sudo bij veel Linux-distributies standaard al geïnstalleerd. Bij onder andere Fedora, Ubuntu en systemen die daarop zijn gebaseerd zoals Linux Mint, is sudo zo geconfigureerd dat de gebruikers van een bepaalde groep het zonder beperkingen kunnen gebruiken. Die administratieve groep wordt admin, sudo of wheel genoemd, afhankelijk van de distributie en de versie.
Meestal moet je sudo gebruiken wanneer je als normale gebruiker een opdracht op de terminal wilt uitvoeren met de rechten van de systeembeheerder, bijvoorbeeld om software te installeren. Om dat te doen, voeg je eenvoudigweg sudo toe vooraan het commando, bijvoorbeeld sudo apt install hello om het pakket hello te installeren. Als je je vervolgens voor sudo kunt authenticeren, wordt het commando uitgevoerd met de vereiste rechten. Kleine tip: als je vergeten bent een commando met sudo te starten, typ dan gewoon sudo !!. De bash-shell vervangt de uitroeptekens door het eerder ingevoerde commando inclusief alle parameters.
Het authenticatieproces onthoudt sudo meestal enkele minuten, zodat je het wachtwoord niet telkens hoeft in te typen. Ondanks die functie om het makkelijker te maken, worden complexere taken toch snel omslachtig, omdat je niet moet vergeten telkens sudo voor elk commando te zetten. Als je meerdere commando’s achter elkaar als root wilt uitvoeren, open dan een rootshell met sudo -i (ezelsbrug: i als in interactief). Daar kun je de commando’s dan zoals gebruikelijk uitvoeren.
Om een bestand met rootrechten te bewerken, open je het met sudoedit, wat hetzelfde is als sudo -e. Sudo maakt er een beveiligde kopie van en opent die met de standaard ingestelde editor, zoals Nano, Emacs of Vim. Daarvoor raadpleegt sudo de variabelen SUDO_EDITOR, VISUAL en EDITOR, of het valt terug op de standaardinstelling van het systeem. Zodra je de wijzigingen hebt gemaakt, kopieert sudo het bestand terug en verwijdert het tijdelijke bestand. De editor en het tijdelijke bestand hebben de rechten van de gebruiker, alleen voor het lezen en het schrijven van het bestand gebruikt sudoedit de hogere rechten. Aangezien het bestand pas terug wordt gekopieerd als de editor gesloten wordt, kun je tussenliggende toestanden opslaan zonder dat je een actuele configuratie per ongeluk onbruikbaar maakt.
Met sudo kun je commando’s niet alleen als root, maar ook als elke andere gebruiker uitvoeren. Om dat te doen, voeg je aan sudo de optie -u en de gewenste gebruikersnaam toe. Die functie kun je bijvoorbeeld testen met de systemgebruiker bin. sudo -u bin id
De tool id toont de huidige effectieve gebruikers-ID en
de lijst van geassocieerde groepen en is daarom zeer nuttig bij het testen van de sudo-configuratie.
SUDO-CONFIGURATIE
De rechten voor sudo zijn vastgelegd in /etc/sudoers. Die kun je het beste bewerken met visudo. Het commando opent /etc/sudoers met de in het systeem standaard ingestelde editor, net zoals dat met sudoedit gaat. Dat hoeft niet per se de vi-editor te zijn. Visudo doet ongeveer hetzelfde als sudoedit, maar controleert bij het afsluiten van de editor de configuratie ook nog op syntaxfouten. Als er een probleem wordt gevonden, geeft het aan waar de fout zit en biedt het aan om het bestand opnieuw te bewerken. Om ervoor te zorgen dat je jezelf niet bij je eigen systeem buitensluit, is het aan te raden om altijd Visudo te gebruiken. Bovendien is het slim om vooraf in een apart terminalvenster met sudo -i in te loggen. Die rootshell laat je dan openstaan. Mocht er dan iets misgaan met de configuratie, dan heb je altijd nog een voet tussen de deur en kun je de wijzigingen weer ongedaan maken of de fout corrigeren.
De syntaxis van het sudoers-bestand is even wennen. Het stamt nog uit de oude Unix-tijden. Aan het begin van het bestand worden de basisinstellingen van sudo gedefinieerd via defaults. Dan volgt een sectie om aliassen te definiëren. Daar later meer over. In eerste instantie zijn de secties vanaf ‘User privilege specification’ interessant: root ALL = (ALL:ALL) ALL
(…)
%sudo ALL = (ALL:ALL) ALL
Die regels zeggen dat zowel de gebruiker root als gebruikers van de groep sudo, ongeacht hun groeps-ID (Run-as), alle commando’s (Cmnd) mogen uitvoeren op alle machines (Host). De configuratie zou je als volgt kunnen interpreteren:
Wie Waar = (Als wie) Wat
User Host = (Run-as) Cmnd
De sudo-vermelding begint met wie er sudo mag gebruiken. Gebruikersnamen schrijf je zoals normaal en groepen worden voorafgegaan door een procentteken. Meerdere vermeldingen kun je scheiden met een komma (alex,bert,%wheel). De host kan de naam van de computer zijn, maar ook het ip-adres of een ip-bereik. Gebruik bij twijfel daar altijd ALL om problemen te voorkomen. Na het gelijkteken wordt tussen haakjes aangegeven onder welke user- en groeps-ID de processen moeten draaien. Ten slotte voer je de gewenste commando’s in, inclusief het volledige pad, die je ook door een komma van elkaar scheidt. Cmnd accepteert ook directory’s en past de regels dan toe op alle programma’s die in een directory staan, maar niet op mogelijke subdirectory’s. De hier gespecificeerde programma’s moeten alleen bewerkbaar zijn door root en moeten bij voorkeur in /usr/bin, /usr/local/bin of soortgelijke directory’s staan. Als een sudo-regel verwijst naar een script dat is opgeslagen in de eigen home-map, dan zou een aanvaller dat kunnen vervangen en zich rootrechten kunnen toe-eigenen.
Bij nieuwere versies is er bovendien /etc/sudoers.d/, waarmee je de configuratie kunt opsplitsen in verschillende bestanden. Op die manier zal een update aanpassingen die een gebruiker gemaakt heeft niet overschrijven. De aanwijzing #includedir /etc/ sudoers.d aan het eind van het sudoers-bestand laadt de individuele configuratiedelen gesorteerd op bestandsnaam. De volgorde van de regels is van belang omdat een latere regel de aanwijzingen van eerdere verklaringen overruled. Het commando sudo -l vertelt je welke rechten de actuele sudo-configuratie toestaat. Het verwerkt aliassen, groepslidmaatschappen en ip-informatie en toont de bestaande regels die gelden voor de actuele gebruiker.
VPN-VOORBEELDSCENARIO
We geven een voorbeeld hoe sudo gebruikt kan worden. Binnen een gezin delen Alex, Bert en Charlie een laptop, elk met een eigen account. Gebruiker Alex wil WireGuard gebruiken om een VPN-verbinding met het kantoor tot stand te brengen. Maar alle andere gebruikers moeten die verbinding kunnen verbreken zonder een wachtwoord in te hoeven voeren, voor het geval Alex dat vergeten is. Bovendien moeten alle gebruikers ook zonder wachtwoord een VPN-verbinding naar huis kunnen maken en met een VPN-aanbieder in de VS. Daarvoor kun je beter een nieuw bestand aanmaken met Visudo: visudo /etc/sudoers.d/10-vpn
Je kunt wel meteen alle gebruikers en commando’s invoeren, maar de sudo-configuratie zou dan wat onoverzichtelijk worden. Het is dan handig om eerst enkele aliassen te definiëren. Voor elk type (User, Host, Run-as, Cmnd) is er een alias-commando. De aliasnaam mag alleen bestaan uit hoofdletters, underscores en cijfers. Als je aan het eind van de regel \ typt, negeert sudo het regeleinde bij het interpreteren van de informatie. Cmnd_Alias VPN= /usr/bin/wg-quick up vpn-home, \ /usr/bin/wg-quick up vpn-usa, \ /usr/bin/wg-quick down
User_Alias FAMILY = alex,bert,charlie
sudo maakt bij de commando’s ook onderscheid tussen argumenten en opties. In het voorbeeld omvat de alias VPN alleen de genoemde oproepen van wg-quick.
Sudo kan daar en bij hosts ook overweg met wildcards, zoals /usr/bin/wg-quick up*. Als je alleen het pad specificeert, accepteert sudo ook alle argumenten. Als je dat wilt voorkomen, dan plaats je twee dubbele aanhalingstekens achter het commando (/bin/id "").
De volgende stap is om de aliassen in de eigenlijke regels gebruiken. Met de onderstaande regels mogen users die in FAMILY zijn gedefinieerd de commando’s uitvoeren die in VPN staan vermeld. De optie NOPASSWD:
voor de commando’s geeft aan dat de authenticatie met een wachtwoord wordt overgeslagen.
FAMILIE ALL = NOPASSWD: VPN alex ALL = /usr/bin/wg-quick up vpn-kantoor
Alex mag ook de VPN-verbinding met kantoor tot stand brengen. De ontbrekende Run-as-entry vervangt sudo automatisch door (root).
Je kunt de aliassen combineren met andere aliassen of waarden. Zo zijn bijvoorbeeld FAMILY,FRIENDS en FAMILY,dirk mogelijk. bert ALL = VPN,/bin/id
Sluit Visudo af om de wijzigingen toe te passen. Als Visudo een fout in de configuratie vindt, kun je met e de editor opnieuw openen of de wijzigingen met x weggooien. De derde optie Q kun je beter vermijden: daarmee slaat Visudo het bestand toch op, maar is sudo onbruikbaar totdat de fout verholpen is. Als Visudo niets te klagen heeft, kun je met sudo -l de regels weergeven. Gebruik sudo -l -U bert om de actieve regels voor gebruiker Bert te controleren. Houd er rekening mee dat Visudo de paden van de commando’s of hun opties niet controleert. Dat is een mogelijk bron voor fouten waar je zelf op moet letten.
GEAVANCEERDE SUDO-CONFIGURATIE
Je kunt voor programma’s een hashwaarde opslaan. Sudo controleert die en voert het commando alleen uit als de checksum ongewijzigd blijft. Dat kan zinvol zijn als bijvoorbeeld een script om een speciale reden niet in een beveiligde directory staat. Gebruik sha256sum om te weten te komen wat de hashwaarde is: sha256sum /home/bert/bin/skript.sh
Schrijf het resultaat vervolgens in de sudoers-regel direct voor het pad van het commando en zet ‘sha256:’ voor de hash-procedure: bert ALL=(ALL) sha256:f1523[...]6bc0e4 /home/ bert/bin/skript.sh
Wil je de optie NOPASSWD: gebruiken, dan moet die nog voor de hashwaarde-entry komen te staan.
Zoals eerder vermeld, onthoudt sudo de authenticatie enkele minuten. Bij elke aanroep wordt de timer gereset. Om het vragen naar het wachtwoord te forceren, bijvoorbeeld om de NOPASSWD-optie te testen, voer je sudo uit met de optie -k. In het sudoers-bestand kun je de duur van de timer instellen met de optie timestamp_timeout.
Defaults timestamp_timeout = 10
De waarde staat voor minuten, waarbij de decimale waarden zoals 2.5 toegestaan zijn. Als de waarde 0 is, wordt er altijd om authenticatie gevraagd en als de waarde negatief is, zoals -1, vervalt de ontgrendeling pas nadat de computer weer opnieuw opgestart is. Sudo slaat de authenticatie alleen op voor de betreffende terminalsessie. Als je wilt dat sudo systeembreed zonder authenticatie werkt, gebruik je de volgende optie:
Defaults timestamp_type = global
Sudo biedt nog veel meer mogelijkheden, maar dat is veel te uitgebreid om hier allemaal te bespreken. Meer informatie vind je bij de link op de laatste pagina van dit artikel.
SUDO PAST NIET ALTIJD
Ook al is sudo uiterst praktisch, het is niet in alle gevallen de ideale tool. De applicatie draait in de context van de rootgebruiker. Dat is vooral problematisch bij grafische programma’s. Als je bijvoorbeeld slechts één bestand in /etc wilt bewerken, heeft het weinig zin om Gedit met rootrechten te starten. In dat geval zou je sudoedit kunnen gebruiken om gedit in de variabele VISUAL in te voegen.
VISUAL=gedit sudoedit /etc/issue
Helaas werkt dat niet zonder problemen: als Gedit al gestart is, wordt het bestand met die programma-instantie geopend. Sudoedit ziet dat niet, gaat ervan uit dat het proces van Gedit klaar is en ziet een onveranderd bestand.
Een alternatief voor sudoedit is het GVFS (Gnome Virtual File System) en het speciale pad admin://, dat gebruikt wordt door Cinnamon, Gnome en Ubuntu. Om het bestand /etc/issue te bewerken, roep je Gedit op met gedit admin:///etc/issue of zoek je het op door het pad met Ctrl+L in een openstaand dialoogvenster in te voeren. GVFS zal dan toestemming vragen met behulp van polkit. Na succesvolle authenticatie kun je het bestand bewerken zonder Gedit met rootrechten uit te hoeven voeren. Dat werkt ook met de Nautilus-bestandsmanager en andere programma’s die GVFS gebruiken. Los van de security heeft het gebruik van admin:/// het voordeel dat de programma’s de instellingen van de gebruiker blijven gebruiken, zoals de bladwijzers in Nautilus.
Je definieert acties in een XML-bestand waarmee polkit toegang verleent tot beschermde resources, zoals hier het aanroepen van Baobab via pkexec.
POLKIT EN PKEXEC
In plaats van de ‘alles of niets’-methode van sudo, maakt polkit gerichte toegang tot beschermde bronnen mogelijk via interfaces zoals DBus. Een niet-geprivilegieerd programma (‘cliënt’) vraagt een programma met geprivilegieerde rechten (‘mechanisme’) om toegang tot een specifieke functie (‘actie’). Het mechanisme maakt gebruik van de polkit-dienst (‘polkit authority’) om na te gaan of en hoe toegang moet worden verleend. De polkit-service kan een authenticatiedienst (‘agent’) oproepen, zoals de polkit-implementatie in Gnome, die een wachtwoorddialoog toont. Die agent rapporteert het resultaat terug aan de polkit-service. Zodra het mechanisme vindt dat alles in orde is, verleent het toegang. Voorbeelden daarvan zijn de ontgrendelknop bij de Gnome-instellingen of het speciale pad admin:///.
Met pkexec heeft polkit ook een tool om commando’s uit te voeren in een andere gebruikerscontext, net als sudo. Maar voor de authenticatie worden de regels en dialogen van polkit gebruikt. Met pkexec id geef je het grafische wachtwoorddialoogvenster onder Gnome weer. Bij de nieuwere versies opent pkexec zonder argumenten een rootshell.
In tegenstelling tot sudo opent pkexec de grafische programma’s niet zonder meer. Dat is zoals beschreven ook niet echt nuttig, maar soms kun je daar niet omheen.
Op dat moment lukt het analyseren van het schijfgebruik in Gnome (Baobab) niet omdat het niet de juiste rechten heeft voor beveiligde mappen, waardoor je het ruimteverbruik van de systeempartitie niet kunt onderzoeken. Als je Baobab met pkexec wilt starten, moet je eerst je eigen polkit-actie definiëren. Aangezien Baobab zelf polkit nog niet ondersteunt, is de omweg via pkexec een wat lompe methode. De moeite om dat te doen is vooral nuttig als je de desktop in de Wayland-modus gebruikt, waarin sudo geen grafische programma’s kan starten.
EIGEN POLKIT-ACTIES DEFINIËREN
Maak een XML-bestand aan met de naam org.gnome. baobab.policy in /usr/share/polkit-1/actions/ met de inhoud van het kader onderaan.
Bij de
moeten zonder spaties door de XML-tags worden ingesloten, anders zal polkit de waarden niet correct interpreteren of zelfs negeren – in tegenstelling tot wat je eigenlijk zou verwachten bij XML.
De onder defaults gedefinieerde waarden kun je met een polkit-regel ook individueel overschrijven. Voor Ubuntu- en Debian-systemen wordt die regel nog steeds opgeslagen in het oudere pkla-formaat in /etc/ polkit-1/localauthority/50-local.d/. Om Baobab als gebruiker Bert zonder wachtwoordaanvraag te starten, maak je het bestand 95-baobab.pkla aan met de volgende inhoud.
[Baobab quickstart for Bert]
Identity=unix-user:bert Action=org.gnome.baobab ResultAny=no ResultInactive=no ResultActive=yes
De regel ResultActive=yes wijzigt de standaardinstelling voor allow_active die is gedefinieerd in het XML-bestand. Om dat toe te passen op alle gebruikers van de groep sudo in plaats van alleen Bert, geef je bij identity de waarde unix-group:sudo op. Meerdere gebruikers of groepen kun je scheiden met een puntkomma.
PRINTERCONFIGURATIE ZONDER ROOT
Onder Fedora mogen gebruikers met een systeembeheerdersaccount – dus de gebruikers die tot de groep wheel behoren – programma’s van Gnome installeren zonder een prompt te krijgen om hun wachtwoord in te voeren. Maar om een printer toe te voegen of de printerinstellingen te wijzigen, moeten ze zich met een wachtwoord authenticeren. Die inconsistentie kun je met polkit redelijk eenvoudig verhelpen. Het eerste wat je moet doen, is de gebruikte actie identificeren. Kijk daarvoor bij een terminalvenster naar de log-output van polkit: journalctl -f -u polkit.service
Druk vervolgens bij de Gnome-instellingen onder printers op de knop ‘Unlock...’. Het dialoogvenster voor het wachtwoord kun je direct weer wegklikken. Zoek naar de vermelding ‘action’ in de berichten. Daarnaast zou je de volgende ID moeten zien: ‘org.opensuse.cupspkhelper.mechanism.all-edit’.
Fedora gebruikt zowel de oude als de huidige indeling voor de configuratiebestanden. Bij de nieuwe indeling worden de regels geschreven als JavaScriptcode en opgeslagen in /etc/polkit-1/rules.d/. De code is wat omslachtiger, maar volgens polkit-ontwikkelaar David Zeuthen maakt dat het makkelijker om de regels te controleren. De eenvoudigste manier is om een bestaande regel als sjabloon te gebruiken. polkit.addRule(
function(action, subject) { if ((action.id == "org.opensuse. cupspkhelper.mechanism.all-edit") && subject.active == true && subject.local == true && subject.isInGroup("wheel")) { return polkit.Result.YES; } return polkit.Result.NOT_HANDLED;
});
Ten eerste controleert de if-voorwaarde of het de gewenste actie betreft. Voer die in bij action.id. Vervolgens wordt gecontroleerd of het een lokale, actieve sessie (subject.local/subject.active) betreft, vergelijkbaar met allow_active, en of de gebruiker lid is van de groep wheel. Die voorwaarden zijn gekoppeld als logische en (&&). Als alles klopt, geeft de configuratie polkit.Result.YES als resultaat, waarmee de printerconfiguratie direct toegankelijk is.
Zodra je het bestand hebt opgeslagen in /etc/ polkit-1/rules.d/90-org.opensuse.cupspkhelper.rules, zou bij de printereigenschappen de knop ‘Unlock ...’ vervangen moeten zijn door een blauwe ‘Add...’ knop. Als er een fout is, meldt polkit dat via de systeemlog.
Een veel voorkomende bron van fouten zijn de dubbele haakjes. Om dat te voorkomen, kun je de regels heb beste bewerken met een editor die syntaxis met kleuren highlight en haakjesparen kan markeren. In Gedit kun je dat activeren door in het menu ‘Beeld / Tekstmarkering...’ de optie JavaScript te selecteren.
VEILIG ZONDER WACHTWOORD
In plaats van alles overkoepelende rechten verlenen sudo en polkit gerichte toegang. Beide configuraties zijn op het eerste gezicht complex. Als je je erin verdiept, krijg je er veel flexibiliteit voor terug. Er wordt dan alleen nog maar om wachtwoorden gevraagd als dat ook echt noodzakelijk is. Andere gebruikers kun je meer rechten geven zonder dat je daar als beheerder wakker van hoeft te liggen. Polkit werkt daarbij beter samen met moderne desktopomgevingen en geeft gedetailleerdere mogelijkheden bij de toegang tot beschermde resources. In combinatie met een bewerkte PAM-configuratie staat niets een bijna wachtwoordvrije maar veilige Linux-ervaring in de weg.
Literatuur
[1] Jürgen Schmidt en Marco den Teuling, Linux-authenticatie makkelijker gemaakt, c’t 10/2019, p.84