Connexion SSH à travers un proxy web

Il est possible de faire passer une connexion SSH à travers un proxy web du moment que celui-ci autorise la méthode CONNECT. Cette méthode est utilisée lors des connexions HTTPs par exemple et sert à établir un tunnel HTTP. Il est de ce fait assez courant qu’un proxy (ou serveur mandataire) laisse passer ce genre de communication. Tant mieux car c’est ce que nous allons utiliser.

Pour nous faciliter cette tâche, il existe un utilitaire qui s’occupe d’établir une fausse connexion HTTP entre votre machine et la machine distante. Car un proxy n’est juste qu’un relai, entre une machine sur le réseau local qui demande une requête HTTP, et le serveur distant. Ce logiciel demande donc à notre proxy web, s’il peut se connecter à la machine distante pour communiquer avec elle. Le serveur proxy s’exécute en pensant qu’il va s’agir d’une communication HTTPs, notre logiciel communique donc maintenant avec la machine distante et passe maintenant le relai à la commande ssh. Cet utilitaire s’appelle « corkscrew » (tire-bouchon en anglais), son site officiel est ici.

L’avantage de cette méthode, c’est que la machine distante n’a pas à avoir de configuration spécifique. Le seul problème est quand le proxy web n’est pas autorisé à joindre le port 22 (ssh) sur une machine distante, car c’est assez rare que des machines s’échangent des données en HTTP avec ce port. Dans ce cas, il suffit soit de faire une redirection de port sur la machine distante (ip proxy => port 443 => port 22/ssh), soit de lancer le démon ssh en écoute sur un autre port. Il suffira de choisir le port 443 qui correspond habituellement au HTTPs pour être tranquille avec ce genre de filtrage.

Comment parler à votre proxy

Pour tester votre proxy:

[tipiak@client ~]$ nc proxy.reseau.local 3128
CONNECT serveur.distant.com:22 HTTP/1.1
Host: serveur.distant.com:22 (appuyer sur entrée 2 fois)
....
blabla...
Access Denied
...

Si le proxy vous répond par une page html, comme quoi vous n’avez pas acces, c’est donc que les communications vers le port 22 sont interdites. Restera la méthode vers le port 443 qui sera en fait redirigé vers votre démon ssh:

[tipiak@client ~]$ nc proxy.reseau.local 3128
CONNECT serveur.distant.com:443 HTTP/1.1
Host: serveur.distant.com:443

HTTP/1.0 200 Connection established

Voilà, c’est mieux.

Configuration du client SSH

La configuration du client SSH permet d’indiquer une commande qui sert à établir une connexion à un intermediaire. C’est avec ce paramètre que nous allons indiquer qu’il faille utiliser corkscrew. Soit vous modifier la configuration du client ssh sur la machine de manière globale, et donc toutes les connexions ssh passeront par corkscrew, soit vous utilisez un fichier de configuration annexe qui sera utilisé au cas par cas. Le fichier de configuration du client est /etc/ssh/ssh_config. Pour avoir la manière globale suffit de le modifier directement, sinon il faut le copier dans un autre fichier (par exemple cp /etc/ssh/ssh_config ~/corkscrew.conf).

Pour utiliser corkscrew, il faut ajouter cette ligne:

# remplacer proxy.reseau.local par l'adresse du proxy
# remplacer 3128 par le port du proxyProxyCommand /usr/local/bin/corkscrew proxy.reseau.local 3128 %h %p

L’appel à la commande « ssh serveur.distant.com » sera donc remplacé par « /usr/local/bin/corkscrew proxy.reseau.local 3128 serveur.distant.com 22 », dans le cas de la configuration globale. Si vous avez opté pour la manière au cas par cas, il faut indiquer à la commande ssh notre fichier de configuration spécifique:

ssh -f ~/corkscrew.conf toto@serveur.distant.com

Si comme expliquez plus haut, le port 22 est interdit, on précisera le numero de port distant (ici 443):

ssh -f ~/corkscrew.conf toto@serveur.distant.com -p443

Et voilà.

Configuration éventuelle du serveur SSH

Cette configuration n’intervient que si le port 22 par défaut pour le protocole SSH est interdit par le serveur proxy. Il existe 2 méthode pour utiliser un autre port pour votre serveur SSH:

  • Associer le démon sur un autre port pour l’écoute en plus du port 22
  • Utiliser le pare-feu pour rediriger un flux vers le port 22

Associer le démon ssh au port 443

Il faut editer le fichier /etc/ssh/sshd_config et s’assurer d’avoir les lignes suivantes:

Port 22
Port 443

Il ne reste plus qu’à relancer le service sshd:

[root@serveur ~]# service sshd restart

Rediriger la connexion vers le port 22

Cette méthode est plus complexe mais si vous avez déjà un serveur web en HTTPs sur votre serveur distant vous n’aurez pas trop le choix. Pour cela on rajoute une configuration dans le pare-feu:

*nat
:PREROUTING ACCEPT [7:913]
:POSTROUTING ACCEPT [1:83]
:OUTPUT ACCEPT [1:83]
# Requetes entrantes
-A PREROUTING -s <IP PUBLIQUE DU PROXY> -p tcp -m tcp --dport 443 -j DNAT --to-destination <IP PUBLIQUE DU SERVEUR>:22
# Requetes sortantes
-A POSTROUTING -s <IP PUBLIQUE DU SERVEUR> -p tcp -m tcp --sport 22 -d <IP PUBLIQUE DU PROXY> -j SNAT --to-source <IP PUBLIQUE DU SERVEUR>:443
COMMIT
*filter
[...]
# HTTPS
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
[...]

Cette configuration se fait dans le fichier /etc/sysconfig/iptables associée au service iptables (à relancer après les modifications). Ceci est bien sûr un exemple, qu’il faudra adapter.

Autres méthodes

Il existe d’autres utilitaires que corkscrew, comme hts ou httptunnel (cf billet du blog de Nicolargo). Les man-pages de ssh_config semble aussi nous indiquer que c’est possible avec netcat/nc.

L’ultime solution, si le proxy n’accepte pas les tunnels HTTP, reste l’utilisation d’un shell dans une page web, avec l’excellent AjaxTerm (attention à la sécurité).

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *