Mettre en oeuvre un dépôt Git sur le Web: la bonne méthode

Introduction

Si vous n'utilisez pas encore Git, sachez que vous devriez ;-). Ces derniers temps, ce logiciel de gestion de version en mode distribué a vraiment le vent en poupe. Son terrain initial était la gestion du code source du noyau Linux et il a été mis en oeuvre dans ce but. Néanmoins, depuis quelques années, son utilisation va en s'accroissant car c'est finalement un outil excellent qui a su bien évoluer et s'adapter aux besoins d'une très grande variété d'utilisation. Par exemple, mon site web personnel est géré avec Git.

Je ne vais pas faire un résumé de ce qu'est Git et en quoi il est formidable. Vous pouvez lire tout un tas de documents sur ce point. Sachant qu'on peut utiliser git pour de nombreuses choses et qu'il est prévu pour être un système décentralisé, il est donc très adapté à la structure éclatée d'Internet. De fait, la facilité d'accès aux dépôts Git, en écriture et en lecture est un critère à ne pas négliger.

Il est possible d'accéder à un dépôt Git via de nombreux protocoles. Celui qui est le plus souvent ouvert partout est le bien connu HTTP et Git gère bien entendu l'accès en lecture par ce protocole mais également en écriture.

Pour mes besoins internes, j'avais envie de tester un accès en écriture sécurisé (HTTPS+Authentification HTTP) afin d'avoir toujours accès à mes dépôts. Lors de mes recherches, j'ai trouvé des informations pas forcément à jour et l'objectif de ce document est de vous livrer la bonne démarche pour répondre à ce besoin sans chercher pendant des heures...

WebDAV pas assez intéressant

Ce qui provoque pas mal de perte de temps c'est qu'on trouve bon nombre d'articles sur le Web qui recommandent de mettre en place un serveur WebDAV pour "écrire" dans un répertoire HTTP. Ca semble de prime abord cohérent: git gère des fichiers et HTTP est un protocole qui donne accès à des fichiers...

Néanmoins, ça ne peut être utile que pour des configurations simples. En effet, Git, c'est plus que de la lecture/écriture de fichiers: les scripts "hooks" n'existent pas pour rien et ils sont particulièrement puissants. Néanmoins, HTTP n'est pas prévu pour lancer des scripts distants ! WebDAV est donc une solution intéressante uniquement si vous ne souhaitez pas lancer de scripts hooks.

Ce problème est préoccupant car dans pas mal de cas, un script hook est vraiment très utile voire nécéssaire. Etant donné que la majeure partie du traffic Internet est filtré en raison de mauvaises pratiques de firewall qui consistent à tout fermer sauf HTTP et qui sont malheureusement tellement répandues, il nous faut donc une solution pour notre problème si commun. Comme c'est un problème préoccupant, une solution a été mise en oeuvre: elle se nomme "smart http".

Git smart-http

Scott Schacon en parle sur son blog. Cet article est très intéressant car il explique comment fonctionnait Git avec HTTP avant la mise en place de smart-http.

Pour faire simple, la solution consiste simplement à mettre en place un script CGI sur le serveur qui gère plus de chose que la simple gestion de fichiers par le protocole HTTP.

Comme git est extrèmement bien documenté, un simple man git-http-backend vous donnera toute l'information de référence sur la mise en place de cette fonctionnalité. Néanmoins, j'ai testé pour vous et voici quelques conseils...

Mise en place du script CGI git-http-backend avec Apache 2.x

Une configuration simpliste ressemble à ça:

    # Dépôts Git (git-http-backend)
    SetEnv GIT_PROJECT_ROOT /var/local/git
    SetEnv GIT_HTTP_EXPORT_ALL
    SetEnv REMOTE_USER=$REDIRECT_REMOTE_USER 
    #Alias /git /var/local/git/
    ScriptAlias /git/ /usr/lib/git-core/git-http-backend/

    <LocationMatch "^/git/.*/git-receive-pack$">
           AuthType Basic
           AuthName "Git depots write Access"
           AuthUserFile /etc/apache2/git-users
           Require valid-user
    </LocationMatch>

Elle permet d'accéder en lecture à tous les dépôts git stockés dans /var/local/git (vous pouvez mettre ce que vous voulez à la place). Les variables d'environnement sont importantes. GIT_HTTP_EXPORT_ALL vous permet d'indiquer que tous les dépôts Git du répertoire précédent sont accessibles en lecture. REMOTE_USER permet de gérer l'authentification.

Le scriptAlias permet à Apache de lancer le CGI (git-http-backend) lors de l'appel de l'URL /git. Enfin, la directive LocationMatch permet de gérer l'authentification pour l'écriture distante dans le dépôt. En effet, lorsque vous allez écrire dans le dépôt, git (le client) va se connecter sur une URL de type http://monsiteweb.sdf/git/projet.git/git-receive-pack (pour la lecture, l'URL se termine par git-fetch-pack). L'accès à cet emplacement est donc protégé par une authentification HTTP de type Basic (en clair donc) en utilisant les comptes disponibles dans le fichier /etc/apache2/git-users.

Bien entendu, l'authentification HTTP Basic expose vos informations de connexion en clair. Vous devez donc activer cette configuration uniquement sur un site accessible en HTTPS. Pour ma part, j'ai placé l'accès en lecture également uniquement en HTTPS: ça fait moins de configuration à maintenir et il suffit d'ajouter une lettre (le s de https) pour avoir accès au dépôt: ça ne va pas me tuer !

Certificats auto-signés

Git, par défaut, s'attend à ce que tout ce qui vient d'un site web SSL respecte les règles de base de sécurité, à savoir, un certificat valide. Toutefois, il n'est pas toujours possible de disposer d'un tel certificat, tant pour des raisons de coûts que de pratique (c'est stupide de demander un certificat valide pour effectuer des tests par exemple).

Pour toutes ces raisons, il est parfois important d'indiquer à Git de ne pas chercher à vérifier le certificat SSL. Vous pouvez le faire grâce à l'option de configuration http.sslVerify:

 git config --global http.sslVerify false

Accès à l'archive en écriture

Malgré la configuration présentée ci-dessus, je n'arrivais toujours pas à écrire dans le dépôt. Après quelques recherches, je me suis rendu compte qu'il y avait un bug dans la dernière version de git qui pose des problèmes avec tout système d'authentification. En effet, il semble que lorsque git reçoit une demande d'authentification de la part du serveur Web (code 401) abandonne le processus en lieu et place de demander le login/password adapté. Ce bug n'était pas présent dans les versions précédentes de git.

Un moyen de contournement consiste à indiquer l'intégralité des éléments d'authentification directement dans l'URL du dépôt distant.

Après avoir lancé la commande:

git clone https://monsiteextraordinaire.sdf.df/git/top_sotfware.git

Vous pouvez afficher la configuration du dépôt:

cd top_software
git config -l 

 user.name=xxxx
 user.email=xxxxx
 http.sslverify=false
 core.repositoryformatversion=0
 core.filemode=true
 core.bare=false
 core.logallrefupdates=true
 remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
 remote.origin.url=https://monsiteextraordinaire.sdf.df/git/top_sotfware.git
 branch.master.remote=origin
 branch.master.merge=refs/heads/master

Pour faire contourner notre problème, il suffit d'indiquer les éléments d'accès dans remote.origin.url:

 git config remote.origin.url https://login:password@monsiteextraordinaire.sdf.df/git/top_sotfware.git

Maintenant, ça devrait fonctionner. Attention, votre login/password est en clair dans le fichier .git/config donc vous devrez bien configurer l'accès à ce fichier (un petit chmod 600 devrait faire l'affaire) ! Néanmoins, c'est la seule solution pratique qui permet de réaliser de nombreux petits commits/push en perdant le moins de temps.

Conclusion

Pouvoir écrire dans un dépôt Git depuis quasiment n'importe quel point d'accès à Internet est un vrai plus. En effet, plus besoin de faire des diff à stocker sur clef USB ou à envoyer par email. Vous pouvez faire vos modifications depuis n'importe où et ça devrait booster votre productivité et également votre utilisation de Git.

Ainsi, il n'y a plus à hésiter à créer un dépôt git pour tout et n'importe quoi (gérer un wiki, un blog, un système de traduction, du code, etc.)...