Git, Windows, SSH, Proxy, Firewall

Posted on Fri 24 May 2013 in Windows

Cet article est issue de mon ancien blog, il est copié tel quel et est peut être un peu vieux sur certains aspects

Après plusieurs semaines (mois ?) à plancher sur le sujet, j'ai enfin réussis ! et donc je vous gratifie d'un petit billet pour expliquer mon périple…

Le But

Cloner un dépôt Git par SSH en lecture/écriture.

Le Contexte

Le dépôt Git est auto-hébergé sur mon serveur faisant tourner Gitolite. On y accède par http en lecture seule et en SSH avec authentification par clé RSA pour y avoir accès en lecture/écriture.

Le client est mon PC de bureau sous Windows XP, connecté à internet à travers un proxy NTLM made in Microsoft. Par dessus, on lui a ajouté un parefeu qui bloque tous les ports à l'exception du port 80 et du 443.

La solution

Installation et test de Git

La solution se base sur l'installation de Git pour Windows en utilisant le backend OpenSSH pour les connexions SSH. Une fois l'installation terminée, ouvrez Git bash et tentez d'acceder à votre serveur Git par SSH :

gitbash$ ssh git@server

Si on vous demande un mot de passe, c'est pas fini mais c'est déjà pas mal. Vous pouvez aller directement au dernier paragraphe.

À ce moment là, j'avais une erreur du style : Bad file number. En fouillant un peu, je n'avais pas de proxy configuré.

Passer un proxy

Pour passer à travers un proxy http pour se connecter en SSH à un serveur, j'ai utiliser corkscrew. Pour pouvoir l'installer, il faudra télécharger le package sur le site officiel et le compiler à la main sous Windows avec Cygwin en utilisant les petites commandes classiques :

cygwin$ ./configure && make

Il faut ensuite copier le binaire généré (corkscrew.exe) dans C:\Program Files\Git\bin\ pour qu'il soit accessible depuis Git-Bash. Pour vérifier que tout va fonctionner, lancez la commande corkscrew dans Git-Bash. Il devrait râler avec le message suivant (ou presque) :

corkscrew 2.0 (agroman@agroman.net)
usage: corkscrew <proxyhost> <proxyport> <desthost> <destport> [authfile]

Si vous avez ce message, créez alors un fichier ~/.ssh/config. Sinon, la compilation ou l'installation de corkscrew n'est pas bonne et il faut recommencer.

Dans le fichier ~/.ssh/config, on va dire à OpenSSH d'utiliser un proxy pour se connecter à notre serveur Git :

Host <server_alias>
    User         <git_user>
    Hostname     <server_location>
    Proxycommand corkscrew <proxy_ip> <proxy_port> %h %p

Si votre proxy requiert une authentification, vous pouvez ajouter au bout de la ligne Proxycommand le chemin vers un fichier contenant votre login et mot de passe sous la forme :

user:password

Essayez votre nouvelle configuration. À partir de maintenant, il ne faut plus utiliser le vrai nom du serveur mais son alias défini dans le fichier config :

gitbash$ ssh server_alias

Si vous arrivez à vous connecter, tout va bien, vous êtes venu à bout de votre proxy. Ce n'était pas mon cas !

Cas des proxys NTLM

D'une manière générale, les outils qui viennent du monde Unix, et en particulier, corkscrew ou OpenSSH, ne supportent pas par défaut l'authentification NTLM. Il faut donc ajouter une couche logiciel pour réaliser l'authentification à leur place. C'est le rôle de Ntlmaps.

Ntlmaps est un petit outil écrit en Python 2 (en vrai, il nécessite un Python 1.5.2 minimum et ne tourne pas (encore) sous Python 3). Il faudra donc avoir Python 2 installé sur votre machine. Télécharger ensuite l'archive de Ntlmaps et décompressez la. On retrouve dedans 2 fichiers importants.

  • Le fichier de configuration server.cfg dans lequel il faut préciser l'adresse du proxy, le port, le domaine, l'utilisateur et le mot de passe :
PARENT_PROXY: <proxy_ip>
PARENT_PROXY_PORT: <proxy_port>
NT_DOMAIN: <your_domain>
USER: <your windows login>
PASSWORD: <your windows password>

Repérez aussi la valeur du LISTEN_PORT (par défaut 5865), on en aura besoin plus tard.

  • Le script de démarrage runserver.bat. Vérifiez bien que le chemin vers Python est correct (ce n'était pas bon sur mon installation).

Lancez le serveur Ntlmaps en executant le script runserver.bat. Là, une console s'ouvre vous indiquant que le serveur tourne et que tout va bien.

Si vous fermez cette fenêtre, vous n'aurez plus de serveur Ntlmaps, je dis ça au cas où certaines personnes seraient tentés tout couper !

Revenez maintenant sur le fichier de configuration SSH ~/.ssh/config et remplacez la ligne ProxyCommand par la suivante :

ProxyCommand corkscrew 127.0.0.1 5865 %h %p

Si votre LISTEN_PORT n'est pas 5865, remplacez le par la bonne valeur. (Je vous avais dit qu'on en aurait besoin !)

Vous pouvez désormais restester votre configuration :

gitbash$ ssh server_alias

Si tout va bien, c'est la fête. Sinon, il y a encore une chose à faire.

Changer de port

Comme je l'avais dit dans le contexte plus haut, le parefeu mis en place ne laisse passer que les ports 80 et 443. En d'autres termes, le port SSH par défaut (22) n'est pas accessible. Soit vous changez au niveau de votre serveur le port par défaut sur 80 ou 443 (ce qui sous-entends que vous n'avez pas de serveur web, ni de serveur web sécurisé, soit vous avez le magnifique sslh sur votre serveur.

Je ne reviens pas ici sur l'installation et la configuration de sslh, j'en ai déjà parler ici et je ferais peut être un article plus détaillé dessus. En gros, sslh est capable de multiplexer plusieurs services sur un même port et donc d'avoir accès à SSH et https sur le port 443 par exemple.

Une fois que vous avez un port alternatif qui n'est pas bloqué pour votre serveur SSH, testez la connectivité :

gitbash$ ssh -p 443 server_alias

Si ça marche vous y êtes presque. Sinon… ben là… je sais plus trop (mais si vous avez d'autres soucis, solutions, astuces… vous pouvez me les envoyer, ça peut être intéressant et ça peut compléter l'article !)

Maintenant, il va falloir dire à Git d'utiliser le port 443 au lieu du port 22. Et malheureusement l'option -p 443 n'existe pas dans Git ! Le seul moyen est encore une fois d'éditer le fichier de config SSH ~/.ssh/config et de lui ajouter sous la ligne HostName la ligne :

Port 443

À partir de maintenant, l'alias server_alias correspond à l'utilisateur <git_user> sur le serveur <server_location> sur le port 443, en passant par le proxy http (corkscrew) accessible sur 127.0.0.1 sur le port 5865 (ntlmaps) qui permet de s'authentifier sur votre proxy NTLM et de faire suivre la requête de connexion à ce dernier.

Prêt à cloner

Il ne reste plus qu'à configurer correctement vos clés RSA. Si vous n'en avez qu'une générale pour tout vos serveurs, copiez votre clé privée dans ~/.ssh/id_rsa. Sinon, utilisez encore une fois le fichier de configuration SSH en ajoutant à votre alias le chemin vers votre clé privée :

IdentityFile <path_to_private_key>

Et voilà, vous pouvez tout cloner de n'importe où.

Plus d'informations sur le fichier de config SSH : http://www.openbsd.org/ssh_config