Met Gitolite maak je een eigen Git hosting op een centrale server in je thuisnetwerk, waarbij meerdere mensen het voor diverse projecten gebruiken. Gitolite is makkelijk te installeren en te beheren en biedt robuuste, fijnmazige access control op basis van SSH-keys.
Door: Matto Fransen
Git is vrijwel “de” standaard op het gebied van gedistribueerd versiebeheer. Git bestaat zo’n 15 jaar en veel open source projecten gebruiken Git voor hun versiebeheer, net als veel commerciële softwareontwikkelaars.
Versiebeheer in de Unix wereld gaat terug tot de jaren zeventig. Hoewel het zich richt op broncode, kun je alles wat platte tekst is in een versiebeheer systeem opnemen, naast broncode bijvoorbeeld configuratiebestanden, de teksten van blog-pagina’s, notities, enzovoorts.
Versiebeheer gebeurt op basis van verschillen tussen twee opeenvolgende versies en door alleen die verschillen te administreren is het schijfruimte-gebruik van versiebeheersystemen verrassend efficiënt. Moderne versiebeheersystemen raken niet van slag wanneer je naast platte tekst ook bestanden zoals afbeeldingen of PDF documenten in het systeem opneemt, echter zonder grote opslagruimte winst.
Gitolite biedt de features van een eenvoudige Git server, aangevuld met een makkelijk te gebruiken en goed doordacht rechtensysteem. Gitolite is lichtgewicht, het vormt nauwelijks een belasting voor je systeem en is geschikt voor kleine systeempjes zoals een Raspberry Pi of een Beaglebone Black en is beschikbaar onder de GPL2 licentie.
Gitolite heeft een beperkt wereldbeeld, het kent alleen projecten en gebruikers. Meerdere gebruikers kunnen dezelfde Gitolite server gebruiken, zonder dat iedereen op de server een eigen gebruikersaccount nodig heeft. De server heeft voor Gitolite maar één gebruiker nodig, bijvoorbeeld “gitolite3”. Binnen Gitolite werk je met SSH-keys. Elke SSH-key vertegenwoordigt een gebruiker.
Globaal werkt Gitolite als volgt. De gebruiker benadert de Git-server via SSH met de gebruikersnaam “gitolite3”, en gebruikt daarbij zijn eigen SSH-key. De SSH-daemon controleert de gebruikerstoegang aan de hand van de SSH-key en leidt deze door naar Gitolite. Gitolite herkent aan de SSH-key welke gebruiker het betreft en controleert of die de benodigde toegangsrechten heeft. Zo ja, dan kan de gebruiker de gewenste activiteit uitvoeren (klonen, updaten, enzovoorts). Je benadert Gilolite dus altijd via de SSH-daemon, wat een beproefde en robuuste toegang oplevert
De beheerder van Gitolite bepaalt via een configuratiebestand welke Git-repositories aangemaakt worden en wie welke rechten tot die repositories heeft. Wanneer de beheerder een nieuwe Git-repository benoemt, dan maakt Gitolite op de achtergrond een zogenoemde “bare repostiory” aan. De daartoe gerechtigde gebruikers klonen deze op hun eigen computer, voegen content toe en pushen dit vervolgens terug naar de Gitolite server.
Dit artikel behandelt de installatie van Gitolite op een Raspberry Pi, je installeert het echter net zo makkelijk op een “gewoon” Linux-systeem.
Maak eerst SSH-key aan, specifiek voor het beheer van Gitolite, voordat je Gitolite op je Raspberry Pi installeert. Dit doe je op je werkstation (laptop of PC), bijvoorbeeld met “ssh-keygen -f .ssh/beheerder”. Dit commando maakt een SSH-key aan op de juiste plek, in de directory ~/.ssh met de bestandsnaam “beheerder”, en de publieke key “beheerder.pub”. Deze publieke key is straks nodig bij de installatie van Gitotlite op de Raspberry Pi.
Maak, wanneer je voor jezelf nog geen SSH-key hebt, ook die aan, met “ssh-keygen”, kies de default bestandsnaam “id_rsa”.
Wij vervolgen hier de installatie van Gitolite op een Raspberry Pi met de december 2020 versie van Raspberry Pi OS Lite (2020-12-02-raspios-buster-armhf-lite.zip), waarop sshd reeds actief is.
Start, zoals altijd, met “sudo apt-get update && sudo apt-get upgrade”.
Pas op de Rapsberry Pi de configuratie van de SSH-server aan zodat authenticatie via SSH-keys mogelijk is. Dit doe je in het bestand /etc/ssh/sshd_config. Zoek de regel “#PubkeyAuthentication yes” en haal het hekje (#) aan het begin van de regel weg. Herstart sshd met “sudo service ssh restart”.
Maak op de Raspberry Pi een gebruiker voor jezelf aan, bijvoorbeeld “sudo adduser alice”. Het systeem vraagt om een wachtwoord. Controleer dat je vanaf je Linux computer over SSH kunt inloggen.
Maak vanaf je computer de eerder gemaakte persoonlijke publieke key bekend aan de Raspberry Pi, met “ssh-copy-id -i ~/.ssh/id_rsa {ip-adres-rapsberry}”.
Controleer hierna dat je inderdaad kunt inloggen op de Raspberry Pi zonder een wachtwoord in te hoeven voeren, met “ssh -i .ssh/id_rsa {ip-adres-rapsberry}”. Wanneer je bij het maken van je SSH-key een wachtwoord op de key zelf gezet hebt, moet je dit uiteraard wel invoeren.
Nadat dit werkt, wijzig je in de sshd_config de regel “#PasswordAuthentication yes” in “PasswordAuthentication no”. Herstart SSH en controleer vanaf een andere xterm dat je wel kunt inloggen met je SSH-key, maar niet met een wachtwoord. Klopt dit, verwijder dan de gebruiker “pi” (over SSH zijn “pi”, “root” en “admin” de meest aangevallen gebruikers).
Scp de publieke SSH-key voor het beheer naar de Raspberry Pi. Zet deze op een makkelijk te typen pad, scp de key bijvoorbeeld naar “/tmp/beheerder.pub”.
Hiermee zijn alle voorbereidingen klaar. Installeer gitolite3 nu met “sudo apt-get install gitolite3”. Het installatieproces vraagt in een dialoogscherm naar de beheerder-key. Heb je het voorbeeld hierboven gevolgd, dan voer je “/tmp/beheerder.pub” in.
Voeg op je Linux werkstation een paar regels toe in het bestand “~/.ssh/config”, zie listing 1. Maak het bestand aan wanneer dit nog niet bestaat. Hiermee vertel je aan SSH dat je voor de beheerwerkzaamheden de gebruikersnaam gitolite3 met de SSH-key “beheerder” kiest, en als gewone Gitolite-gebruiker de gebruikersnaam gitolite3 met de key “id_rsa”.
Het beheer van Gitolite doe je in een Git repository, niet op de server, maar op je lokale werkstation (laptop of PC). Je start de beheerwerkzaamheden met het maken van een kloon van de Gitolite beheer repository op je lokale machine. Je voert de beheerwerkzaamheden op deze lokale kloon uit. Hierna commit je de wijzigingen met ‘git commit’, die je vervolgens met ‘git push’ naar de Gitolite server stuurt. De Gitolite server herkent de wijzigingen en voert deze door. Wanneer je bijvoorbeeld een nieuwe project hebt aangemaakt, dan maakt Gitolite op dat moment een nieuwe repository aan.
We beginnen met het maken van een kloon van de beheer-repository, dit doe je op je Linux werkstation, met “git clone raspberrygitadmin:gitolite-admin.git”. Dit maakt de directory “gitolite-admin” aan, met hierin twee sub-directories: “conf” en “keydir”. De sub-directory “conf” bevat het configuratiebestand van Gitolite. In de sub-directory “keydir” komen de publieke SSH-keys van de Gitolite-gebruikers. De publike key van de beheerder staat hier reeds, met als bestandsnaam “admin.pub”.
Stel dat je Alice toegang wilt geven tot een of meer repositories, dan begin je met het kopiëren van haar publieke SSH-key naar de keydir, met de bestandsnaam van de key in het format “gebruikersnaam.pub”, in dit geval dus “alice.pub”. Waarschijnlijk heet haar publieke SSH-key “id_rsa.pub”, deze hernoem je naar “alice.pub” en plaatst deze in de sub-directory “keydir”. Wil je Alice, Bob en Charlie toegang geven tot bepaalde repositories, dan neem je de bestanden “alice.pub”, “bob.pub” en “charlie.pub” op in de keydir, zie listing 2. Op dezelfde manier voeg je ook je eigen publieke SSH-key, dus ook in het format “gebruikersnaam.pub”, dit is niet de beheerder.pub maar je eigen SSH-key.
Controleer met “git status” de wijzigingen die Git ziet. Indien accoord, dan doe je “git add -A” om alle wijzigingen op te nemen, gevolgd door “git commit -m ‘boodschap’”. Voor de boodschap neem je iets zodat je later je wijziging kunt snappen, bijvoorbeeld “eerste gebruikers aangemaakt”. Vervolgens breng je de repository op de Raspberry up to date met “git push”.
Listing 2: overzicht van de gitolite-admin directory
Verlaat de directory “keydir” en ga naar de directory “conf”. Hierin bevindt zich het bestand “gitolite.conf”. Open dit bestand met je favoriete editor. Je ziet hier twee regels die met het woord “repo” beginnen, eentje voor de repository “gitolite-admin” en eentje voor “testing”. Onder deze regels zie je een tekstregel met de toegangsregels voor deze twee repositories. Voeg hieronder je eigen repository toe, met daaronder een tekstregel die een gebruiker toegang geeft tot deze repository. Zie listing 3.
Herhaal de stappen om de wijzigingen in Git op te nemen, dus “git status”, “git add -A”, “git commit -m ‘boodschap’”. en “git push”. Vervang “boodschap” door een begrijpelijke tekst die je later nog snapt. Nadat je de push opdracht geeft, maakt Gitolite een nieuwe, lege repository aan en geeft hiervan een melding.
Controleer dat je de nieuwe repository kunt klonen met de betreffende SSH-key van de gebruiker met “git clone raspberrypigit:mijnrepo”. Git meldt dat je een lege repository gekloond hebt. Ga in de directory ‘mijnrepo’ en zet hierin een of meer bestanden. Voer ook nu de stappen uit om de wijzigingen in Git op te nemen, dus “git status”, “git add -A”, “git commit -m ‘boodschap’”. en “git push”. Vervang “boodschap” weer door heldere uitleg. Het “git push” commando synchroniseert je lokale Git naar de gitolite-server op de Raspberry Pi. Gefeliciteerd, je gitolite-server is nu in bedrijf.
Listing 3: mijnrepo toegevoegd aan gitolite.conf
Je zag in het configuratiebestand steeds eerst de regel “repo {reponaam}”, gevold door een regel met toegangsrechten. Dit kunnen ook meerdere regels met toegangsrechten zijn. Deze beginnen met de definitie van het toegangsrecht, “R” betekent lezen, “W” betekent schrijven en “+” betekent ook bijzondere rechten zoals rewind, delete branches of tags. Hierna volgt een is-teken (=) gevolgd door de gebruikersnamen voor wie die rechten van toepassing zijn, gescheiden door een spatie.
Groepen maak je aan met “@groepsnaam =” gevolgd door de individuele groepsleden gescheiden door een spatie. Bijvoorbeeld:
@linuxmag = alice bob charlie
Deze regels zet je bovenin, voorafgaand aan de “repo”-regels. De groep “@all” is een speciale groepsnaam en staat voor “alle bekende gebruikers”.
Dit is slechts een fractie van de configuratiemogelijkheden, maar voor huis-tuin-keukengebruik is dit meestal genoeg. Zie voor meer diepgang de Gitolite website.
Bevinden zich Git-gebruikers in je vrienden- of vriendinnenkring, biedt elkaar dan wederzijds Git-diensten aan. Je vriend gebruikt jouw server voor het hosten van zijn repositories en in ruil gebruik je zijn server voor het hosten van jouw repositories. Je hebt je repositories dan niet alleen thuis op je eigen Gitolite server staan, maar ook remote op de server van je vriend. Maak een scriptje maakt dat automatisch elke nacht de updates pusht, en je hebt een mooie off-site backup.
Git kent zogenoemde “cryptremotes”, de data wordt daarbij voor het pushen eerst met GnuPG versleuteld. Hierdoor is vertrouwelijkheid de inhoud van de repository gewaarborgd.
Je lokale Git repository blijft bij het gebruik van cryptremotes onaangetast. De benodigde schijfruimte blijft lokaal dus hetzelfde. Door de compressie van GnuPG wijkt de omvang van de versleutelde remote repository nauwelijks af, zodat dit nog steeds prima geschikt is voor de storage op een Raspberry Pi.
Je kunt je eigen Git-server voor verschillende doeleinden inzetten, bijvoorbeeld voor versiebeheer van de configuratiebestanden in je home-directory of de systeem configuratiebestanden in de etc-directory.
Een andere optie is om met behulp van Sparkleshare directories te synchroniseren. Dit is naast een handige manier om een backup van die directories te maken ook een mooie methode om verschillende systemen (bijvoorbeeld je laptop en je PC) met elkaar te synchroniseren.