Ma vie sans GitHub - partie 1: Gitolite🔗
Introduction
Il y a quelque temps, j'ai décidé de quitter Github, en fermant mon compte. Après tout, ça va dans le sens de mes convictions. Pour l'instant, ça me va très bien, mais je reconnais que ce n'est pas très pratique pour travailler sur des projets de logiciels libres.
L'acquisition de Github par Microsoft et le fait qu'on trouve maintenant des millions de projets de logiciels libres, tous centralisés sur Github pose clairement la question du risque de tout mettre ses yeux dans le même panier. Que se passe-t-il si Github devient trop puissant et impose ses conditions ?
Néanmoins, nous sommes en 2018 et ne pas utiliser des outils modernes pour partager du code impose de revenir en arrière et d'exclure certaines bonnes pratiques. Aussi, je me devais de trouver un système adapté à mes moyens et à mes ambitions pour partager le code source libre qu'il m'arrive de produire.
Cet article tente d'améliorer l'aspect partage des choses en présentant une installation de gitolite, un logiciel de référence pour gérer les droits d'accès à des dépôts Git.
Principes de Gitolite
Avant d'utiliser un logiciel, c'est bien de savoir comment il fonctionne, du moins dans ses grandes lignes.
- gitolite utilise un compte UNIX standard pour opérer. De cette manière, la compromission de ce compte ne vient perturber que ce compte et pas le reste du système (du moins, de prime abord).
- le compte gitolite utilise un répertoire dédié qui contient deux ensembles:
- un répertoire de dépôts git (bare), c'est là qu'on mettra nos dépôts git. Ce répertoire se nomme
repositories
. - un répertoire caché (
.gitolite
) qui contient la logique de gitolite avec les scripts Perl à lancer dans les hooks. Il contient également les clefs publiques SSH des utilisateurs qui ont accès aux dépôts gits. - Il existe un dépôt de base nommé gitolite-admin qui permet d'interagir avec la configuration de gitolite. De fait, toute la conf de gitolite se fait à l'aide de ce dépôt qui contient des hooks spécifiques. Il est même déconseillé d'utiliser une autre méthode.
- Par défaut, gitolite permet l'accès aux dépôts git via SSH. Il est toutefois possible d'autoriser un accès via HTTP(S).
- Les utilisateurs déclarés dans gitolite son des utilisateurs indépendants du système d'exploitation.
Installation de gitolite sous Debian
Vous devez disposer d'une clef publique SSH pour le compte "administrateur" de gitolite. Pour ma part, j'y fous ma clef publique de GNUPG au format ssh-rsa que j'obtiens avec la commande gpg (voir ci-dessous).
Ensuite, vous pouvez installer le paquet Debian gitolite3. Ce dernier vous demandera où placer le répertoire spécifique à gitolite. Pour ma part, je le place dans /var/local/gitolite
.
$ gpg --export-ssh-key mon_compte_gpg > medspx.pub $ scp medspx.pub compte@srv.example.org:/tmp/ # apt install gitolite3 - clef SSH de l'administrateur: `/tmp/medspx.pub` # mv /var/lib/gitolite3 /var/local/gitolite # usermod --home /var/local/gitolite gitolite3
Voilà, c'est fait…
Après installation du paquet, debconf créé un utilisateur dédié. Il se nomme gitolite3
et a pour HOME le répertoire d'installation de gitolite que vous avez renseigné en amont.
Ce répertoire contient tout ce que j'ai expliqué dans les principes de gitolite sous la forme suivante:
.ssh
⇒ le répertoire de conf SSH de l'utilisateur gitolite3. On y trouve un fichier de clefs autorisées, modifié par un hook de gitolite.repositories
⇒ notre répertoire de dépôts qui contient le dépôt de configuration de gitolite (gitolite-admin.git
) ainsi qu'un dépôt de test (testing.git
)..gitolite
⇒ le répertoire "interne" de gitolite..gitolite.rc
⇒ le fichier de conf globale de gitolite (qui point vers/etc/gitolite3/gitolite.rc
.projects.list
⇒ un fichier pour gitweb dont on se fout (parce que je n'utilise pas gitweb).
Utiliser gitolite
Maintenant que gitolite est installé, il convient de l'utiliser et de commencer à le configurer correctement.
Tout commence par le clonage du dépôt gitolite-admin. Vous pouvez le cloner en utilisant le compte dédié gitolite (donc gitolite3
sous Debian). Comme vous avez renseigné votre clef SSH, vous avez le droit d'y avoir accès. Un simple clone via SSH donne la commande suivante:
git clone gitolite3@srv.example.org:gitolite-admin
Le dépôt contient deux répertoires:
keydir
: qui contient les fichiers de clefs publiques.conf
: qui contient les fichiers de configuration de gitolite. Pour l'instant, il ne devrait y avoir que le fichiergitolite.conf
.
Ajouter un utilisateur est assez simple: il suffit de récupérer sa clef publique dans un fichier avec le nom du compte suffixé avec l'extension .pub
dans le répertoire keydir
, de commiter le dépôt et de pousser la modification pour que la clef soit ajustée.
Pour gérer les droits des dépôts, il suffit de modifier le fichier de configuration: conf/gitolite.conf
. Sa syntaxe est assez simple à comprendre même si elle peut se complexifier avec des includes et d'autres éléments.
Néanmoins, il y a un élément que vous devez bien noter ! Vous devez toujours utiliser le compte SSH de l'utilisateur gitolite (donc gitolite3 sous Debian). En effet, SSH n'est pas automagique: il ne va pas créer un compte utilisateur POSIX à la volée pour vous permettre de vous connecter. Au contraire, c'est l'utilisateur gitolite3 qui, avec son shell spécial (le binaire de gitolite), va s'occuper de faire la gestion des droits. C'est bien noté ?
Import de dépôts existants
Pour ma part, j'ai beaucoup de dépôts sur mon serveur et il convient de les référencer/importer sous Gitolite. La doc sur le sujet est assez bien faîte:
# cd /var/local/gitolite/repositories # rm -r testing.git # cp -r ../..git/*.git . # chown -R gitolite3:gitolite3 *.git # su gitolite3 $ gitolite compile $ gitolite setup --hooks-only $ gitolite trigger POST_COMPILE
Ensuite, il reste à ajouter les dépôts dans le fichier de conf et le tour est joué.
Mise en place de l'accès via HTTP
Ok, maintenant, vous avez un accès à des dépôts git via SSH, de manière sécurisée pour l'authentification et le contrôle d'accès (qui sont deux choses différentes).
Mais bon, vous êtes ambitieux et vous voulez faire cool comme github et utiliser un service en HTTPS ! Et là, c'est le drame: gitolite ne gère pas super bien l'accès HTTP. En effet, gitolite ne gère pas du tout l'authentification mais uniquement le contrôle d'accès. Dans ce que nous avons vu, c'est SSH qui gère l'authentification, gitolite s'occupe du reste.
Pour la partie HTTP, c'est donc Apache qui va s'occuper de l'authentification et transférer ce qui va bien à gitolite. Mais, nous avons un problème majeur: Apache ne sait pas authentifier avec une clef SSH. Ce n'est pas prévu pour, ce n'est pas fait pour ! Il faut donc broder et c'est que nous propose la documentation de gitolite sur le sujet. Je vous invite aussi à lire cet article que j'ai finalement utilisé.
Comme on doit broder, autant le faire intelligemment, c'est à dire en comprenant ce qu'on fait. Nous devons faire les choses suivantes:
- Authentifier les utilisateurs depuis Apache.
- Lancer gitolite-shell depuis un process Apache via CGI.
- gitolite requière d'utiliser le compte gitolite3, il faut donc un mécanisme qui permette de le faire.
- Il y a des variables d'environnement à configurer pour que gitolite retrouve ses petits.
- Il faut un mécanisme pour que les utilisateurs puissent gérer leur mot de passe Apache.
D'un point de vue administration système, j'ai choisi d'utiliser au maximum ce qui est fourni par la distribution Debian. Ainsi, tout le système gitolite est géré par l'utilisateur gitolite3. J'aurais pu installer une version indépendante de gitolite, en plus du paquet Debian. C'est ce qui est recommendé dans la documentation sur l'accès HTTPS.
Le fait d'utiliser l'utilisateur gitolite3 via Apache implique d'utiliser le module suexec de ce dernier. Ceci n'est pas sans conséquence pour certains déploiements de sites web car pour le virtualhost, l'utilisateur qui lancera tous les scripts CGI sera maintenant gitolite3 et non www-data. Si vous utilisez cgit, vous serez impacté.
Mise en place du socle HTTP de base
Pour ma part, voici ce que j'ai fait:
- Installer le module Apache suexec et l'activer:
# apt install apache2-suexec-pristine # e2enmod suexec
- Créer un répertoire dans /var/www:
# mkdir /var/www/bin # chown gitolite3:gitolite3 bin
- Créer un fichier de script shell qui encapsule le lancement de gitolite:
#!/bin/bash # # Suexec wrapper for gitolite-shell # export GIT_PROJECT_ROOT="/var/local/gitolite/repositories" export GITOLITE_HTTP_HOME="/var/local/gitolite" exec /usr/share/gitolite3/gitolite-shell
- Modifier ses droits/appartenance
# chown gitolite3:gitolite3 /var/www/bin/gitolite-suexec.sh # chmod 0700 /var/www/bin/gitolite-suexec.sh
- Mettre la configuration suivante dans un fichier de conf d'Apache:
SuexecUserGroup gitolite3 gitolite3 SetEnv GIT_PROJECT_ROOT "/var/local/gitolite/repositories" ScriptAlias /git/ /var/www/bin/gitolite-suexec.sh/ SetEnv GITOLITE_HTTP_HOME "/var/local/gitolite" SetEnv GIT_HTTP_EXPORT_ALL <Location /git> AuthType Basic AuthBasicProvider file AuthName "Git depots Access" AuthUserFile /var/local/gitolite/gitolite-http-authuserfile Require valid-user </Location>
Une fois votre serveur Apache redémarré, vous devriez pouvoir accéder à vos dépôts en suivant les règles d'accès de gitolite.
Gestion des mots de passe par les utilisateurs
Dans tous les cas, retenez que vous allez devoir gérer des mots de passe Apache pour vos utilisateurs externes, en plus de leur clef SSH. Bon, je vous rassure, GitHub le fait aussi: vous créez un compte Github puis vous uploadez vos clefs SSH.
A notre niveau, gitolite est plutôt fait pour créer des comptes à partir d'une clef SSH publique. Le processus est plutôt inversé par rapport à Github. Mais pourquoi pas !
Néanmoins, une fois que vos utilisateurs ont une clef SSH référencée dans le système gitolite que vous avez mis en place, ils ont la liberté d'utiliser le binaire gitolite-shell qui fait un peu plus que de servit du git. En effet, gitolite-shell permet de lancer quelques commandes de gestion. Parmi celles-ci, il y en a une qui est très intéressante car elle se nomme htpasswd
et sa fonction est de gérer un mot de passe HTTPS pour Apache. Avec un peu de configuration, on peut tout à fait permettre aux utilisateurs de lancer cette commande.
Avant de commencer, il convient de modifier le fichier de configuration globale de gitolite. Ce dernier est situé dans /etc/gitolite3/gitolite.rc
.
Vous devez ajouter 'htpasswd'
à la liste des commandes autorisées (ENABLED). Ensuite, définissez la variable HTPASSWD_FILE avec le bon nom de fichier associé:
HTPASSWD_FILE => '/var/local/gitolite/gitolite-http-authuserfile',
Voilà, c'est fait.
Pour que vos utilisateurs puissent modifier leur mot de passe HTTP, il leur suffit de faire:
$ ssh gitolite3@sr.example.org htpasswd Please type in your new htpasswd at the prompt. You only have to type it once. NOTE THAT THE PASSWORD WILL BE ECHOED, so please make sure no one is shoulder-surfing, and make sure you clear your screen as well as scrollback history after you're done (or close your terminal instance). new htpasswd:
Et le tour est joué. Retenez bien que vous devrez maintenir deux choses:
- Votre clef SSH
- Votre mot de passe et compte HTTP.
Mais, c'est déjà ce que vous faites si vous êtes sous Github !
Accès non authentifiés via HTTP
Pour l'instant, nous n'avons fait que gérer les accès authentifiés via Apache. Il nous reste à permettre l'accès anonyme, sans authentification. Mais je ne vais pas traiter cet accès dans cet article car plein de solutions s'offrent à vous, d'un répertoire distinct pour les dépôts publics à l'utilisation d'un autre logiciel qui réalise l'accès HTTP pour vous (cgit peut le faire par exemple).
Conclusions
Pour résumer, si la mise en place de l'accès SSH via gitolite est assez simple, l'accès via HTTPS se révèle un poil plus complexe et source de compromis. Mais dans l'ensemble ça fonctionne correctement.
Le seul point négatif de gitolite, c'est le fait qu'il soit codé en Perl. Je sais par avance que jamais je ne pourrais me plonger dans le code interne de Gitolite à cause de ce facteur. En dehors de ce point qui m'oblige à faire confiance au développeur de ce logiciel, je dois dire que Gitolite est simple, plutôt robuste et qu'il ne consomme pas beaucoup de ressources.
Néanmoins, la partie HTTP est un poil complexe à gérer et je pense qu'il existe une marge de progrès dans l'application sur ce point. Après tout, l'accès par HTTPS est pratiquement un pré-requis de nos jours si on souhaite favoriser les échanges (surtout derrière des firewalls nazis).