Un tunnel sans pelle

Et sans terre sur les mains. Classe non ?

Et bien, c'est possible grâce à SSH. (entre autre hein, tunnel est un terme plutôt répandu en informatique, mais bon ça fait une bonne accroche)

Pour parler plus directement, un tunnel ssh va vous permettre de communiquer via SSH avec un serveur distant, et plus pécisément de rediriger certains ports locaux vers ce serveur, qui en fera ce que vous voulez.

 

Typiquement, rediriger un port VNC dans un tunnel SSH permet de se connecter sur une machine distante de manière sécurisée. Alors que VNC de base, c'est quand même tout en clair à l'arrache.

Ce système permet de sécuriser la plupart des routages de ports sales que l'on peut faire sur une box pour rentrer dans son réseau. Bien sûr, il y a aussi des applications techniques plus intéressantes au niveau entreprise :-)

L'un des gros intérêts également, c'est que ça peut être utilisé sur un smartphone (ordiphone) sans aucun hack (ou rootage, ou jailbreak), contrairement à OpenVPN par exemple.

Il faut pas le dire

Avec cette technique, vous pouvez également (ouh, c'est mal) passer certaines protections ou proxy, par exemple en redirigeant toutes vos connexion HTTP (port 80) sur un tunnel ssh sur le port 443 (HTTPS très rarement filtré) vers votre serveur, qui ensuite vous redirigera vers le site que vous vouliez.

Inconvenient : vous profitez de votre bande passante potentiellement pourrie, surtout si vous vous auto-hébergez (c'est le bien !), puisque où que vous soyiez, toutes vos requêtes Internet passeront par chez vous.

Avantage : vous mettez un doigt dans l'os à tout ces "filtrages" pseudo sécurité qui en fait font chier que les gens honnêtes. (Dont vous faites bien sûr partie)

Ce besoin qu'on a tous connu (ou qu'on imagine au moins) servira de contexte pour ce tuto.

 

Le principe

Comme d'habitude, un petit rappel du principe technique de la chose.

Nous allons mettre en place sur un serveur, placé où bon vous semble, ce qu'on appelle un shell SSH qui attendra des connexions extérieures.

Ce système est sensé permettre un accès SSH à votre serveur. Comme ce n'est pas le but ici, nous allons détourner le problème en mettant en place un shell hyper restreint. De cette façon vous pourrez fournir la connexion à qui vous voulez, en étant sûr qu'ils ne feront pas de mauvaises choses avec votre serveur. (On ne sait jamais :-) )

La connexion se fera grâce à un couple clef/mot de passe, pour une sécurité maximum. La connexion au tunnel sera interdite par tout autre moyen, ce qui permet de limiter les attaques par brute force notamment.

Chaque personne voulant se connecter devra donc posséder un couple clef/mot de passe fourni par vous. Dans cette optique et pour suivre plus simplement qui a quoi, nous allons créer pour chaque compte un utilisateur du système, qui aura le droit d'utiliser le tunnel. Ces utilisateurs appartiendront tous au groupe tunnelssh.

Ce système, même s'il peut créer beaucoup d'utilisateur, présente l'avantage d'être à la fois clair et d'avoir des logs faciles à lire (chaque tentative de connexion étant loggué par utilisateur)

Le système de redirection de port sera à votre convenance. Comme dit plus haut, j'utiliserais pour ma part le port 443, le plus communément ouvert même dans des lieux "limitatifs" sur des wifi "ouverts".

 

Matériels, connaissances, besoins divers

Comme toujours quand on est un gros hacker barbu, plusieurs choses s'imposent.

Tout d'abord, il va vous falloir un serveur sous Linux, qui permettra d'installer la sortie du tunnel. Vous vous connecterez avec votre machine sur lui, qui se chargera de rediriger ce que vous voulez où vous voulez.

Pour ma part, j'utilise debian, mais SSH étant plutôt répandu, ça ne posera pas de problème à transcrire ailleurs.

Il vous faudra aussi une autre machine servant de client pour les tests (Ordiphone Android/Iphone, PC fixe, PC portable, tablette, ...)

Il est conseillé de disposer d'un minimum de connaissances dans la ligne de commande, et connaître un peu le réseau (notamment les ports) est un plus apprécié. Cependant, il est possible de copier-coller les commandes, donc pas la peine de trembler si vous ne maitrisez pas le bousin :-)

 

Enfin, comme l'objectif est de travailler honnêtement pour promouvoir un Internet plus libre, une bonne bière n'est pas de refus !

 

Bien. On est parti.

configuration du tunnel

Pour commencer, connectez vous sur votre serveur, via un SSH classique. Si vous utilisez directement un écran/clavier/souris, il faudra vérifier qu'openSSH est correctement installé :

$ sudo aptitude install openssh-server

Une fois cela fait, nous allons créer une deuxième instance d'OpenSSH server, qui va écouter sur le port 443 et qui servira exclusivement pour le tunnel. Pour ce faire, créez un fichier sshd_config_tunnel, placé dans /etc/ssh :

$ sudo nano /etc/ssh/sshd_config_tunnel

A l'intérieur, copiez-collez ce qui suit : 

Port 443

#ListenAddress ::
#ListenAddress 0.0.0.0
Protocol 2
# HostKeys for protocol version 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
#Privilege Separation is turned on for security
UsePrivilegeSeparation yes

KeyRegenerationInterval 3600
ServerKeyBits 768

# Logging
SyslogFacility AUTH
LogLevel INFO

# Authentication:
LoginGraceTime 120
PermitRootLogin no
AllowGroups tunnelssh

StrictModes yes

AllowTcpForwarding yes
#PermitOpen IP_LOCALE:PORT_LOCAL
AllowAgentForwarding no

RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile %h/.ssh/authorized_keys

IgnoreRhosts yes
RhostsRSAAuthentication no

HostbasedAuthentication no
#IgnoreUserKnownHosts yes

PermitEmptyPasswords no

ChallengeResponseAuthentication no
PasswordAuthentication no

# Kerberos options
#KerberosAuthentication no
#KerberosGetAFSToken no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes

# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes

X11Forwarding no
X11DisplayOffset 10
PrintMotd no
PrintLastLog yes
TCPKeepAlive yes
#UseLogin no

#MaxStartups 10:30:60
#Banner /etc/issue.net

AcceptEnv LANG LC_*

Subsystem sftp /usr/lib/openssh/sftp-server

UsePAM yes

C'est en fait un fichier de configuration ssh classique modifié pour notre usage. Je l'ai épuré des commentaires pour qu'il ne soit pas trop lourd, et j'ai mis en gras les morceaux importants :

  • Port 443 : c'est ici que vous allez définir sur quel port écoute votre serveur. Comme dit précedemment, j'utilise le port 443, mais vous mettez ce que vous voulez.
  • PermitRootLogin no : cette directive va interdire toute connexion au serveur avec l'utilisateur root.
  • AllowGroups tunnelssh : cela permet d'autoriser uniquement les utilisateurs appartenant au groupe tunnelssh de se connecter.
  • AllowTcpForwarding yes : cette directive va autoriser votre serveur SSH à transmettre ce qui lui arrive dessus vers une autre machine (typiquement vos requêtes Internet)
  • #PermitOpen IP_LOCALE:PORT_LOCAL : cette directive (ici commenté) peut vous servir si vous voulez utiliser votre tunnel pour accéder à une seule machine de votre réseau local. Par exemple, pour vous connecter sur votre PC avec VNC. Si vous désirez utilisez votre tunnel pour accéder à Internet, laissez cette ligne commentée.
  • PasswordAuthentication no : cette directive va imposer l'utilisation d'une clef SSH pour vous connecter au serveur.

 

Il va également vous falloir lancer ce serveur en parallèle du vrai serveur SSH (que je vous conseille de laisser pour les accès "administratifs" dont vous pourriez avoir besoin).

Pour ce faire, il suffit de créer dans le dossier /etc/init.d/ un nouveau fichier de lancement ssh :

$ sudo nano /etc/init.d/ssh_tunnel

Dans lequel vous pouvez copiez-collez :

#! /bin/sh

### BEGIN INIT INFO
# Provides: sshd_tunnel
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: OpenBSD Secure Shell server
### END INIT INFO

set -e

# /etc/init.d/ssh: start and stop the OpenBSD "secure shell(tm)" daemon

test -x /usr/sbin/sshd || exit 0
( /usr/sbin/sshd -\? 2>&1 | grep -q OpenSSH ) 2>/dev/null || exit 0

umask 022

if test -f /etc/default/ssh; then
. /etc/default/ssh
fi

. /lib/lsb/init-functions

if [ -n "$2" ]; then
SSHD_OPTS="$SSHD_OPTS $2"
fi

SSHD_OPTS="$SSHD_OPTS -f /etc/ssh/sshd_config_tunnel"

# Are we running from init?
run_by_init() {
([ "$previous" ] && [ "$runlevel" ]) || [ "$runlevel" = S ]
}

check_for_no_start() {
# forget it if we're trying to start, and /etc/ssh/sshd_not_to_be_run exists
if [ -e /etc/ssh/sshd_not_to_be_run ]; then
if [ "$1" = log_end_msg ]; then
log_end_msg 0
fi
if ! run_by_init; then
log_action_msg "OpenBSD Secure Shell server not in use (/etc/ssh/sshd_not_to_be_run)"
fi
exit 0
fi
}

check_dev_null() {
if [ ! -c /dev/null ]; then
if [ "$1" = log_end_msg ]; then
log_end_msg 1 || true
fi
if ! run_by_init; then
log_action_msg "/dev/null is not a character device!"
fi
exit 1
fi
}

check_privsep_dir() {
# Create the PrivSep empty dir if necessary
if [ ! -d /var/run/sshd_tunnel ]; then
mkdir /var/run/sshd_tunnel
chmod 0755 /var/run/sshd_tunnel
fi
}

check_config() {
if [ ! -e /etc/ssh/sshd_not_to_be_run ]; then
/usr/sbin/sshd $SSHD_OPTS -t || exit 1
fi
}

export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"

case "$1" in
start)
check_privsep_dir
check_for_no_start
check_dev_null
log_daemon_msg "Starting OpenBSD Secure Shell server" "sshd_tunnel"
if start-stop-daemon --start --quiet --oknodo --pidfile /var/run/sshd_tunnel.pid --exec /usr/sbin/sshd -- $SSHD_OPTS; then
log_end_msg 0
else
log_end_msg 1
fi
;;
stop)
log_daemon_msg "Stopping OpenBSD Secure Shell server" "sshd_tunnel"
if start-stop-daemon --stop --quiet --oknodo --pidfile /var/run/sshd_tunnel.pid; then
log_end_msg 0
else
log_end_msg 1
fi
;;

reload|force-reload)
check_for_no_start
check_config
log_daemon_msg "Reloading OpenBSD Secure Shell server's configuration" "sshd_tunnel"
if start-stop-daemon --stop --signal 1 --quiet --oknodo --pidfile /var/run/sshd_tunnel.pid --exec /usr/sbin/sshd; then
log_end_msg 0
else
log_end_msg 1
fi
;;

restart)
check_privsep_dir
check_config
log_daemon_msg "Restarting OpenBSD Secure Shell server" "sshd"
start-stop-daemon --stop --quiet --oknodo --retry 30 --pidfile /var/run/sshd_tunnel.pid
check_for_no_start log_end_msg
check_dev_null log_end_msg
if start-stop-daemon --start --quiet --oknodo --pidfile /var/run/sshd_tunnel.pid --exec /usr/sbin/sshd -- $SSHD_OPTS; then
log_end_msg 0
else
log_end_msg 1
fi
;;

try-restart)
check_privsep_dir
check_config
log_daemon_msg "Restarting OpenBSD Secure Shell server" "sshd"
set +e
start-stop-daemon --stop --quiet --retry 30 --pidfile /var/run/sshd_tunnel.pid
RET="$?"
set -e
case $RET in
0)
# old daemon stopped
check_for_no_start log_end_msg
check_dev_null log_end_msg
if start-stop-daemon --start --quiet --oknodo --pidfile /var/run/sshd_tunnel.pid --exec /usr/sbin/sshd -- $SSHD_OPTS; then
log_end_msg 0
else
log_end_msg 1
fi
;;
1)
# daemon not running
log_progress_msg "(not running)"
log_end_msg 0
;;
*)
# failed to stop
log_progress_msg "(failed to stop)"
log_end_msg 1
;;
esac
;;

status)
status_of_proc -p /var/run/sshd_tunnel.pid /usr/sbin/sshd sshd && exit 0 || exit $?
;;

*)
log_action_msg "Usage: /etc/init.d/ssh_tunnel {start|stop|reload|force-reload|restart|try-restart|status}"
exit 1
esac

exit 0

Ce fichier est une copie du fichier /etc/init.d/ssh classique, mais modifié pour lancer le bon fichier de configuration et pour tourner en parallèle du serveur classique (notamment avec son propre pid)

Les parties modifiées sont en gras.

Enregistrez le fichier puis rendez-le exécutable.

$ sudo chmod 755 /etc/init.d/ssh_tunnel

Si vous le souhaitez, vous pouvez configurer le tunnel pour se lancer au démarrage :

$ sudo update-rc.d ssh_tunnel defaults

Configuration du groupe d'utilisateur

Nous allons ensuite créer le groupe tunnelssh, qui sera utilisé pour toutes les connexions.

$ sudo groupadd tunnelssh

Il suffira ensuite de créer vos utilisateurs comme appartenant à ce groupe pour leur donner l'autorisation de se connecter au tunnel. Nous allons voir un script permettant de faire ça tout seul. :-)

Configuration du shell

Afin que vos utilisateurs ne puissent pas se balader dans votre serveur via l'accès SSH du tunnel, nous allons créer un shell bidon. Cela permettra en plus d'afficher une jolie bannière pour l'utilisation du tunnel.

En avant. Créez un fichier dans /usr/bin :

$ sudo nano /usr/bin/tunnelshell

Qui contient quelque chose dans ce genre là :

#!/bin/bash
echo "Connexion limitée au tunnel SSH."
read -p "Appuyez sur ENTREE pour vous déconnecter..."

Ainsi, toute personne se connectant sur votre tunnel verra apparaître ce message :

Connexion limitée au tunnel SSH.

Appuyez sur ENTREE pour vous déconnecter...

Comme indiqué, une pression de la touche entrée provoque la déconnexion immédiate du tunnel.
Vous êtes bien sûr libre de changer le message ! ;-)

On y est !

A ce stade, votre tunnel ssh est prêt à être utilisé. Il suffit de créer un utilisateur appartenant au groupe tunnelssh, de lui configurer comme shell /usr/bin/tunnelshell, puis de lui créer son couple clef/mot de passe.

Comme je suis super sympa (mouahahah), je vous propose un petit script qui fait tout ça tout seul.

Je vous conseille de le placer dans le dossier /root, ou à défaut dans un dossier à accès limité, puisqu'il contiendra tous les certificats de tous vos utilisateurs.

$ sudo mkdir /root/tunnelSSH

$ sudo nano /root/tunnelSSH/Addsshtunneluser.sh

Dans celui-ci, vous pouvez mettre : 

#!/bin/bash

if [ "$1" = "" ]; then
echo "Usage : Addsshtunneluser.sh name passphrase
fi

if [ "$2" = "" ]; then
echo "Usage : Addsshtunneluser.sh name passphrase
fi

mkdir /home/$1
mkdir /home/$1/.ssh
useradd $1 --home-dir /home/$1 --groups tunnelssh --no-user-group --shell /usr/bin/tunnelshell
ssh-keygen -t dsa -b 1024 -N $2 -f /home/$1/.ssh/id_dsa
cp /home/$1/.ssh/id_dsa.pub /home/$1/.ssh/authorized_keys
chmod 700 /home/$1/.ssh
chmod 600 /home/$1/.ssh/authorized_keys
chown -R $1:tunnelssh /home/$1
cp /home/$1/.ssh/id_dsa tunnelssh-$1

Ce script s'exécute de la manière suivante :

$ sudo bash /root/tunnelSSH/Addsshtunneluser.sh UTILISATEUR MOTDEPASSE

  • UTILISATEUR est le nom du nouvel utilisateur à créer
  • MOTDEPASSE est le mot de passe à donner à l'utilisateur

Le script va alors créer un utilisateur portant ce nom. L'utilisateur appartiendra au groupe tunnelssh, et disposera de son répertorie /home/UTILISATEUR

Le script va ensuite créer la clef SSH à l'aide du MOTDEPASSE (on parle bien sûr d'un couple clef privée/clef publique). Il va ensuite copier la dite clef dans le dossier /root/tunnelSSH/ avec un nom du type tunnelssh-UTILISATEUR, ce qui va vous permettre de la récupérer facilement pour la transmettre à l'utilisateur concerné.

Il lui faudra alors utiliser cette clef pour configurer son tunnel ssh de la manière suivante :

  • Adresse : l'adresse IP ou FQDN de votre serveur
  • Port : le port d'écoute de votre tunnel (ici 443)
  • Utilisateur : son nom d'utilisateur
  • Connexion par clef : avec la clef que vous lui avez transmis ainsi que le mot de passe associé

Normalement, tout doit baigner !

Voila, c'est creusé

Avec tout ça, vous devriez être à même de vous connecter depuis n'importe où sur votre serveur.

A titre informatif, pour mettre en place le tunnel côté client :

  • Windows : utilisez Putty (allié à PuttyGen pour transformer votre clef en format Putty)
  • Linux/MacOSX : utilisez simplement openssh :-)
  • Android : utilisez ConnectBot
  • iPhone : Payez... Mais vous l'avez choisi avec un tel téléphone !

Si jamais j'ai des demandes, je me lancerai dans un petit tuto pour l'une ou l'autre des plateformes :-)

Si vous avez des soucis, posez la question dans les commentaires !


Victor Avatar Victor est le rédacteur principal du blog.
Comments

Si vous avez des questions, si quelque chose n'est pas clair, n'hésitez pas à commenter !

  • Avatar
    Permalink

    Alban

    Posted on

    Pendant un moment j'ai cru qu'il s'agissait d'un tuto pour s'échapper de prison ^^

Ajouter un commentaire / Add a Comment

Vous pouvez utiliser la syntaxe Markdown pour formatter votre commentaire.

You can use the Markdown syntax to format your comment.

Flux Atom pour commentaire / Comment Atom Feed

Published

Category

Réseaux

Tags

Restez en contact