Linux-configbestanden beheren met Etckeeper
Linux-configuratiebestanden beheren met Etckeeper
Als je bij Linux de configuratiebestanden en wijzigingen daarin tot in detail wilt bijhouden, dan is Etckeeper precies wat je zoekt.
Het programma slaat de bestanden op in Git en zorgt dat je elke wijziging precies kunt achterhalen. Een kleine fout bij het bewerken van de systeemconfiguratie kun je daarmee snel verhelpen.
Nog snel even die twee opties instellen, wat kan er misgaan? Wie heeft dat niet al eens gedacht, en twee uur later zit je vertwijfeld in een verknoeid serversysteem te graven. Het is vaak lastig om foutief ingestelde diensten en kapotte configuratiebestanden weer op de rit te krijgen. En mogelijk zit de werkende versie van het configuratiebestand al niet meer in je back-ups.
Etckeeper helpt je hiermee: het programma maakt dagelijks automatisch of handmatig voor elke pakketinstallatie een kopie van de bestanden zoals die in /etc staan. Het grijpt op de achtergrond terug naar een versiecontrolesysteem. De ontwikkelaars raden hiervoor Git aan, hoewel je ook andere zoals Bazaar of Mercurial kunt gebruiken. Als je een beetje bekend bent met Git, dan kun je er snel mee uit de voeten. Voor nieuwkomers leggen we enkele basisprincipes uit in het kader op pagina 136. Als je je nog verder in de materie wilt verdiepen, dan kun je meer informatie vinden in [1].
In tegenstelling tot gebruikelijke manier waarop Git wijzigingen in bestanden bijhoudt, moeten bij configuratiebestanden ook de toegangsrechten worden beheerd. De wijzigingen van leesrechten kunnen in /etc relevant zijn, want weloverwogen software zal er bijvoorbeeld direct mee stoppen wanneer privésleutels opeens globale leesrechten hebben. Gewoon de inhoud van een bestand terugzetten is in dat geval dus niet voldoende. Etckeeper let daarom ook op wijzigingen in de toegangsrechten en slaat deze ook op. Met extended attributes, zoals die voor SELinux nodig zijn, kan Etckeeper echter niet omspringen.
Inrichten
Etckeeper is standaard onderdeel van de officiële pakketsources van grote distributies. In dit artikel hebben we gewerkt met het gebruik in Debian Stretch met Git als versiebeheersysteem. Op andere systemen werkt het in principe hetzelfde. Log allereerst in als root en installeer Git:
apt install git
Maak vervolgens een e-mailadres en een naam voor de gebruiker root aan:
git config --global user.name
"JOUW NAAM" git config --global user.email
JOUW@E-MAIL
Deze instellingen zijn nodig omdat anders Etckeeper al bij het inrichten ermee ophoudt. Het programma integreert zowel de naam als het e-mailadres in de commits. Daarna kun je Etckeeper installeren:
apt install etckeeper
Tijdens het installeren wordt er ook automatisch een Git-repository aangemaakt. De configuratiebeheerder rondt dit af met het weergeven van alle bestanden die in de repository zitten. De Git-metadata komt in de directory /etc/.git terecht. Als je dit bestand zou verwijderen, ben je alle versie-iteraties en metadata van de repository kwijt. Het is daarom aan te raden om die map ook in je back-up op te nemen, mocht dit niet al automatisch gebeuren.
In de directory /etc/etckeeper komen zowel het configuratiebestand etckeeper. conf als enkele submappen met scripts terecht. Deze scripts verzorgen de mogelijke operaties. Als je specifieke wensen hebt, kun je in de submappen enkele extra scripts maken, bijvoorbeeld om telkens wanneer Etckeeper een nieuwe commit aanmaakt, automatisch een e-mailbericht te ontvangen.
Het bestand etckeeper.conf biedt maar een paar instellingen.
VCS="git" GIT_COMMIT_OPTIONS="" HIGHLEVEL_PACKAGE_MANAGER=apt LOWLEVEL_PACKAGE_MANAGER=dpkg PUSH_REMOTE=""
Met de optie VCS stel je het versiecontrolesysteem in. GIT_COMMIT_OPTIONS stelt opties in die op het moment van de commit aan de Git-oproep worden doorgegeven. Je kunt daar bijvoorbeeld met de optie --author een dedicated auteurnaam voor Etckeeper opgeven of voor experimenteerdoeleinden de optie --dry-run definiëren. Daarmee maakt Git geen daadwerkelijke wijzigingen in de repository, maar doorloopt het alleen een testrun.
Eigen verantwoordelijkheid
Voor het dagelijks gebruik van Git in combinatie met Etckeeper hoef je maar enkele commando's te kennen. Het belangrijkste is git status. Daarmee krijg je een overzicht te zien van welke bestanden gewijzigd zijn sinds de laatste commit, dus sinds de laatste synchronisatie met de lokale Gitrepository. Welke wijzigingen dat precies zijn, toont de opdracht git diff, die in de vorm van een unified diff (à la Linux) de verschillen toont tussen een bestand dat in de Git-repository staat en de versie van dat bestand die in de map staat. Dat kunnen inhoudelijke verschillen zijn, maar soms ook alleen verschillen in de status van een bestand, zoals een wijziging van de bestandsnaam of een wijziging in de toegangsrechten.
De toegang tot de repository in /etc met grafische git-tools is niet zomaar mogelijk, want alleen root heeft daar toegang tot.
Als je iets wijzigt in /etc, creëer dan wanneer je er klaar mee bent een nieuwe versie-iteratie van je werk met
etckeeper commit "Mijn wijzigingen"
Met de parameter commit neemt Etckeeper alle wijzigingen over en slaat ze op in de repository. Etckeeper combineert hier de git-commando's add en commit. Uiteindelijk word je nog gevraagd een commitmessage in te voeren, waarin je omschrijft wat je gewijzigd hebt. Deze tekst is handig om later te kunnen zoeken naar eerdere wijzigingen in de map. Het is daarom belangrijk om nauwkeurig en beschrijvend te werk te gaan. Als je de verplichte tekst niet invoert, wordt er een teksteditor geopend waarin je de wijzigingen nogmaals in detail kunt bekijken en waar je in de eerste regel de omschrijving moet invoeren.
Met git lock kun je alle wijzigingen tot nu toe bekijken. Je krijgt dan een unieke commit-ID te zien met daarachter de naam van de auteur, het tijdstip van de wijziging en de beschrijving. Als je een eerdere toestand wilt herstellen, dan voer je
git checkout COMMIT-ID
uit. De commit-ID's zijn behoorlijk lang. Voor een kortere versie, voer je git log --abbrev-commit uit. Na de checkout van de gewenste versie, sla je de wijzigingen op met etckeeper commit. De oudere toestand wordt dan als een nieuwe commit geregistreerd.
Als je met meerdere mensen aan bestanden werkt, raden we aan om het programma sudo te installeren en in te richten. Etckeeper herkent automatisch wanneer het door sudo wordt gestart en neemt de git-instellingen over van de desbetreffende gebruiker, waardoor ook diens e-mailadres en naam in het logbestand terechtkomen. Op die manier kun je altijd achterhalen welke gebruiker iets heeft gewijzigd. Als je nog gedetailleerder te werk wilt gaan, kun je met
git blame BESTANDSNAAM
wijzigingen regel voor regel achterhalen en zien wanneer en door wie iets gewijzigd werd.
Automatisch
Iedereen vergeet wel eens om configuratiewijzigingen toe te passen. Voor zulke gevallen zorgt een cronjob voor een dagelijkse etckeeper-commit. Dit is zeker de moeite waard om uit te voeren. Als je het oudgediende cron niet helemaal vertrouwt en liever de modernere systemd-timer gebruikt [2], dan voer je de regel AVOID_DAILY_ AUTOCOMMITS en de systemd-timer systemctl enable etckeeper.timer uit. Zonder die timer voert Etckeeper de dagelijkse commits niet uit.
Vaak wordt het gebruik van Incron in combinatie met Etckeeper aangeraden. Incron is een bestandscontrole-daemon. We raden dit om twee redenen af: allereerst zullen er conflicten en recursieproblemen optreden als je niet heel goed uitgewerkte wrapper-scripts gebruikt. Daarnaast genereert de dienst bij elke wijziging van een bestand een commit, ook als je maar een enkele byte verandert. Dat lijkt in sommige gevallen misschien wel handig, maar zorgt vooral voor enorme logbestanden waarin je maar met veel moeite de bestandsversie kunt vinden die je zoekt.
Installatiebewaking
Etckeeper kan zich integreren in de pakketmanager van Linux-distributies en op die manier een beveiligingsmaatregel zijn bij het installeren van updates of nieuwe programma's. Als er in /etc wijzigingen opgetreden zijn die nog niet zijn opgeslagen, dan komen deze eerst in een commit en vervolgens wordt het pakket geïnstalleerd. Zodra dit klaar is, komt de volgende commit. Op die manier wordt de toestand van voor de installatie en erna vastgelegd. Als je denkt dat er iets niet helemaal in de haak is, activeer je de instelling AVOID_COMMIT_BEFORE_INSTALL. Etckeeper onderbreekt de pakketinstallatie dan, indien er nog bestandswijzigingen zijn die nog niet zijn uitgevoerd. Deze kun je dan eerst bekijken en opslaan. Vervolgens loopt de installatie automatisch verder.
Welke pakketmanager Etckeeper gebruikt wordt bepaald door de opties HIGHLEVEL_PACKAGE_MANAGER en LOWLEVEL_PAKKAGE_MANAGER. Bij Debian zijn dat apt en dpkg. Bij andere distributies moet je de desbetreffende varianten zelf invoeren.
Remote opslag
Als je configuratiebestanden liever centraal opslaat, dan kun je Etckeeper ook de opdracht geven om wijzigingen naar een remote repository te verzenden. Om een repository te genereren, moet je via SSH inloggen op de computer die de repository moet gaan hosten. Zoek een map uit voor de repository, bijvoorbeeld /data/etcconfig/mijn-pc. Ga naar die map en voer er het volgende commando uit:
git init --bare
Je hebt nu een bare-repository gemaakt. Deze dient alleen als doel voor de wijzigingen aan bestanden en bevat geen werkende kopie van die bestanden. Met het commando
git remote add origin ssh://
user@hostname:/data/etc-config/mijn-pc
geef je bij Etckeeper aan dat hij de bestanden naar deze remote repository moet uploaden. Met de optie PUSH_REMOTE stel je de naam in van de remote-repository die gebruikt moet worden en waar Etckeeper de wijzigingen naar toe stuurt. In dit voorbeeld heet die origin.
Let er op dat de doel-repository niet openbaar is. In /etc staan niet alleen eenvoudige configuratiebestanden, maar ook beveiligingscertificaten en -sleutels, wachtwoorden en toegangsgegevens van diensten zoals VPN's of SSH-servers. Het is daarom een bijzonder slecht plan om Etckeeper de opdracht te geven zijn bestanden naar een openbare GitHub-repository te uploaden. Je kunt beter een repository op een privéserver inrichten of een privé, betaalde GitHub-repository gebruiken.
Wil je toch je configuratiebestanden met de wereld delen, maar zorgen dat Etckeeper de vertrouwelijke gegevens niet opneemt in de synchronisatie? Breid dan het bestand .gitignore in /etc uit en voeg daaraan de bestanden en paden toe (relatief ten opzichte van /etc) waarvan je niet wilt dat ze in de repository terechtkomen. Elk pad moet daarvoor een eigen regel krijgen. Deze bestanden worden dan door Etckeeper volledig genegeerd, en zul je op een andere manier moeten opslaan.
Let er op dat commits die al uitgevoerd waren toch in de repository kunnen zitten. Alle bestanden die al zijn geüpload, zijn dan openbaar, ook als je ze uit de actuele repository verwijdert. Als je op een later tijdstip ontdekt dat je privé-sleutels naar de git hebt gekopieerd, moet je die meteen onbruikbaar maken en nieuwe genereren. Voorbeelden van privé SSH-sleutels die via Etckeeper naar GitHub zijn geüpload, zijn er in overvloed. (ddu)
Literatuur
[1] Herbert Braun, Onvergetelijk, De eerste stappen met GitHub en versiebeheersysteem Git, c't 5/2014, p.136
[2] Merlin Schumacher, The Times They Are A Changin', (On)regelmatige taken plannen met systemd, c't 12/2016, p.140