Tunnel http + ssh
Sur cette page nous allons voir comment créer un tunnel, permettant de faire passer tout et n'importe quoi à travers une simple connexion http.
Ingrédients
Pour ce faire il vous faut :
- 2 ordinateurs : un dans le réseau filtré et un hors de ce réseau mais accessible ;
- Un serveur SSH fonctionnel sur la machine hors du réseau ;
- Penser à préparer la recette avant de vous retrouver dans le réseau filtré ;
- Le paquet httptunnel installé sur les deux machines.
Configuration de la machine complice
Nous allons ici nous servir du couple hts et htc, ils sont tous deux dans le paquet httptunnel, il va donc falloir installer ce paquet sur chacune des deux machines.
Sur la machine complice lancer la commande :
hts --forward-port localhost:22 80
Ceci aura pour effet de créer un bout du tunnel sur le port 80 de la machine « complice » et la connexion provenant de ce port sera transférée sur le port local 22 (ssh).
Cette commande retourne immédiatement et ne dit rien, elle crée un daemon qui enregistre ses journaux (bien utiles) dans /var/log/syslog.
Automatisation
Afin d'automatiser le lancement de hts au démarrage de l'ordinateur, il est possible de créer un script dans /etc/init.d. Voici un exemple fait à partir du skeleton :
#! /bin/sh
- BEGIN INIT INFO
- Provides: tunnel
- Required-Start: $remote_fs
- Required-Stop: $remote_fs
- Default-Start: 2 3 4 5
- Default-Stop: 0 1 6
- Short-Description: tunnel HTTP
- Description: Create a HTTP tunnel on port 80 to port 22 of localhost
- END INIT INFO
- Do NOT "set -e"
- PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH='/sbin:/usr/sbin:/bin:/usr/bin'
DESC='Tunnel HTTP'
NAME='hts'
DAEMON=/usr/bin/$NAME
PIDFILE=/var/run/$NAME.pid
DAEMON_ARGS="--forward-port localhost:22 8080 --pid-file $PIDFILE"
SCRIPTNAME='/etc/init.d/tunnel'
- Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0
- Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
- Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
- Define LSB log_* functions.
- Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions
do_start()
{
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
$DAEMON_ARGS \
|| return 2
}
do_stop()
{
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
RETVAL="$?"
[ "$RETVAL" = 2 ] && return 2
# hts don't delete this pidfile when it exit.
rm -f $PIDFILE
return "$RETVAL"
}
do_reload() {
start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
return 0
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
restart|force-reload)
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
log_end_msg 1
;;
esac
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
exit 3
;;
esac
Configuration de votre machine
Sur la machine locale on commence par créer la seconde partie du tunnel http :
htc --forward-port 1234 complice:80
Cette commande va créer une sorte de proxy sur le port local 1234 et rediriger ces connexions sur l'autre bout du tunnel (donc le bout de la machine complice). Bien sûr remplacez « complice » par le nom de domaine ou l'adresse IP de votre machine extérieure.
Ce qu'il faut bien comprendre c'est que ce n'est pas une simple redirection, il y a une encapsulation de la connexion dans un flux http. L'avantage c'est de pouvoir traverser un proxy http de manière très simple, il suffit d'utiliser la commande :
htc --proxy votreproxy:8080 --forward-port 1234 complice:80
Dernière étape créer la connexion ssh à travers le tunnel en activant le proxy socks :
ssh -D 8080 login@localhost -p 1234
Non, il ne faut pas remplacer « localhost », c'est bien vers votre machine en local que doit pointer votre client ssh, mais il sera rediriger comme il faut. Une fois que vous êtes connectés ainsi, vous avez un proxy SOCKS accessible via localhost:8080.
Utilisation sur un serveur Web existant
Il est parfaitement possible de faire cohabiter un serveur Web sur la machine «complice» avec ce tunnel, du moment qu'on peut faire les virtualhosts. Pour cela:
- Sur la machine complice: Activez le module proxy, en clair faire dans le répertoire /etc/apache2/mods-enabled/
ln -s /etc/apache2/mods-available/proxy.conf
ln -s /etc/apache2/mods-available/proxy_ftp.load
ln -s /etc/apache2/mods-available/proxy_http.load
ln -s /etc/apache2/mods-available/proxy.load
- Décidez d'un port (ici on va prendre 8888) et lancez le tunnel sur ce port
$ hts --forward-port localhost:22 8888
- créez un nouveau serveur virtuel par un fichier /etc/apache2/sites-available/ssh.votredomaine.org contenant
<VirtualHost *:80>
ServerAdmin francois@ssh.votredomaine.org
DocumentRoot /var/www
ServerName ssh.votredomaine.org
ErrorDocument 404 /deprime.html
ErrorLog /var/log/apache2/ssh-error.log
CustomLog /var/log/apache2/ssh-access.log combined
<Proxy *>
AddDefaultCharset off
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://localhost:8888/
</VirtualHost>
Note:, Cette configuration devrait marcher, mais il est arrivé que le dialogue se fasse tout de même sur le port 8888 (en théorie non). Cela est du à un bug dans apache, cf ce rapport de bug
Remettez apache en route:
$ su
- cd /etc/apache2/sites-enabled
- ln -s ../sites-available/ssh.votredomaine.org
- /etc/init.d/apache2 reload
- Rajoutez une ligne DNS à votre domaine:
ssh IN A votre_IP
et relancez votre serveur DNS gérant votre domaine.
- Votre tunnel est prêt, sur la machine client, il n'y aura pas de changement. Un
htc --forward-port 1234 ssh.votredomaine.org
fonctionnera.
Expérimenté
Wifi