VPN par la pratique OpenVPN Stunnel

De Lea Linux
Aller à la navigation Aller à la recherche
La version imprimable n’est plus prise en charge et peut comporter des erreurs de génération. Veuillez mettre à jour les signets de votre navigateur et utiliser à la place la fonction d’impression par défaut de celui-ci.

VPN par la pratique

Par Jiel et Tony

1.1 OpenVPN : Installation et création

1. Installation d'OpenVPN

Comme nous n'avons pas Internet sur nos clients/serveurs de test, on installe OpenVPN à la main sur notre Live CD Ubuntu :

root@ubuntu:~/tp_VPN# dpkg -i openvpn_2.0.6-1_i386.deb
Selecting previously deselected package openvpn.
(Reading database ... 76142 files and directories currently installed.)
Unpacking openvpn (from openvpn_2.0.6-1_i386.deb) ...
Setting up openvpn (2.0.6-1) ...
Restarting virtual private network daemon:.

A noter que si l'on avait eu un accès au net, la technique suivante aurait suffit :

apt-get update && apt-get install openvpn

2. Préparation du serveur

On prépare les certificats et les clefs :

root@ubuntu:~/tp_VPN# cd /usr/share/doc/openvpn/examples/easy-rsa/2.0
root@ubuntu:/usr/share/doc/openvpn/examples/easy-rsa/2.0# gzip -d pkitool.gz

On décompresse les outils pour générer les clefs :

root@ubuntu:/usr/share/doc/openvpn/examples/easy-rsa/2.0# chmod 777 pkitool

On donne tous les droits au repertoire pkitool :

root@ubuntu:/usr/share/doc/openvpn/examples/easy-rsa/2.0# source ./vars
NOTE: If you run ./clean-all, I will be doing a rm -rf on /usr/share/doc/openvpn/examples/easy-rsa/2.0/keys
root@ubuntu:/usr/share/doc/openvpn/examples/

On exécute le script vars et charge les variables d'environnement :

easy-rsa/2.0# ./clean-all

On génère le certificat du CA. Ce certificat permettra de signer le certificat de tous nos clients et celui du serveur. Grâce à lui, on pourra rajouter autant de clients qu'on le souhaite pour se brancher sur notre serveur.

root@ubuntu:/usr/share/doc/openvpn/examples/easy-rsa/2.0# ./build-ca
Generating a 1024 bit RSA private key
................++++++
......++++++
writing new private key to 'ca.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [US]:FR
State or Province Name (full name) [CA]:94
Locality Name (eg, city) [SanFrancisco]:Creteil
Organization Name (eg, company) [Fort-Funston]:Paris12
Organizational Unit Name (eg, section) []:Master2SSI
Common Name (eg, your name or your server's hostname) [Fort-Funston CA]:ABC
Email Address [me@myhost.mydomain]:root@localhost
root@ubuntu:/usr/share/doc/openvpn/examples/

On génère maintenant le certificat pour le serveur :

easy-rsa/2.0# ./build-key-server server1
Generating a 1024 bit RSA private key
.................................++++++
..++++++
writing new private key to 'server1.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [US]:FR
State or Province Name (full name) [CA]:94
Locality Name (eg, city) [SanFrancisco]:Creteil
Organization Name (eg, company) [Fort-Funston]:Paris12
Organizational Unit Name (eg, section) []:Master2SSI
Common Name (eg, your name or your server's hostname) [server1]:server1
Email Address [me@myhost.mydomain]:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /usr/share/doc/openvpn/examples/easy-rsa/2.0/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'FR'
stateOrProvinceName   :PRINTABLE:'94'
localityName          :PRINTABLE:'Creteil'
organizationName      :PRINTABLE:'Paris12'
organizationalUnitName:PRINTABLE:'Master2SSI'
commonName            :PRINTABLE:'server1'
emailAddress          :IA5STRING:'me@myhost.mydomain'
Certificate is to be certified until Mar 26 02:30:21 2018 GMT (3650 days)
Sign the certificate? [y/n]:y
 
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
root@ubuntu:/usr/share/doc/openvpn/examples/easy-rsa/2.0#

3. Vérification du certificat

On vérifie le certificat créé pour le serveur server1 (on fera de même pour celui du client1 quand il sera créé) :

root@ubuntu:/usr/share/doc/openvpn/examples/easy-rsa/2.0# openssl x509 -in keys/server1.crt -noout -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1 (0x1)
        Signature Algorithm: md5WithRSAEncryption
        Issuer: C=FR, ST=94, L=Creteil, O=Paris12, OU=Master2SSI, CN=ABC/emailAddress=root@localhost
        Validity
           Not Before: Mar 28 02:30:21 2008 GMT
           Not After : Mar 26 02:30:21 2018 GMT
        Subject: C=FR, ST=94, L=Creteil, O=Paris12, OU=Master2SSI, CN=server1/emailAddress=me@myhost.mydomain
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (1024 bit)
                Modulus (1024 bit):
                    00:ee:d5:69:63:88:68:3e:54:27:b0:cd:34:88:66:
                    1f:8f:b5:4f:3d:ca:72:c0:67:09:82:2c:1c:4a:f4:
                    66:11:8d:e7:33:f4:26:8d:9f:c1:61:54:72:98:b9:
                    b8:a3:b4:7f:42:6a:7f:28:71:48:f9:5a:b5:e9:11:
                    38:7f:20:97:e2:d3:2c:86:2d:98:d2:07:4b:18:5b:
                    ff:4f:30:24:74:86:a4:35:3b:bd:94:dc:67:af:8c:
                    35:6a:41:4a:dc:94:cd:34:a9:49:54:75:1c:73:d2:
                    ee:bd:12:78:ec:64:62:1a:09:d5:d0:70:1f:1e:fb:
                    16:b3:fe:25:be:77:15:f3:df
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Cert Type:
                SSL Server
            Netscape Comment:
                OpenSSL Generated Server Certificate
            X509v3 Subject Key Identifier:
                AA:43:74:87:31:76:63:D5:04:97:62:40:13:F7:9E:AB:15:34:19:C3
            X509v3 Authority Key Identifier:
                keyid:67:92:22:44:BC:33:B9:C8:FF:69:96:11:C5:39:0D:64:03:29:DF:60
                DirName:/C=FR/ST=94/L=Creteil/O=Paris12/OU=Master2SSI/CN=ABC/emailAddress=root@localhost
                serial:E7:B7:58:95:0C:72:DA:ED

            X509v3 Extended Key Usage:
                TLS Web Server Authentication
            X509v3 Key Usage:
                Digital Signature, Key Encipherment
    Signature Algorithm: md5WithRSAEncryption
        b2:e9:fe:fd:78:c8:5d:da:e0:34:db:91:f6:43:27:53:59:02:
        53:07:c0:ec:f9:ca:73:82:5d:62:db:d4:88:56:f5:72:b4:1b:
        c3:3d:c4:a3:59:b2:c2:8d:9f:62:85:8f:5c:c9:4c:a9:f5:27:
        f9:17:cb:30:23:37:35:c0:72:56:5c:5a:f9:72:c9:28:b3:9f:
        fd:b7:d1:9f:e4:a0:e2:1c:e4:33:c5:86:b2:8c:46:aa:18:2a:
        72:9a:3f:2d:49:d4:74:f6:8a:18:99:fa:7a:94:fa:29:a2:5a:
        21:07:70:e1:fc:fd:70:05:1a:99:47:d7:4b:05:7d:ba:0c:7e:
        42:1a
root@ubuntu:/usr/share/doc/openvpn/examples/easy-rsa/2.0#

4. Création du certificat du client

On crée un certificat client SSL, pour le groupe qui va se connecter sur notre serveur. On s'y prend exactement comme pour créer le certificat pour le serveur.

easy-rsa/2.0# ./build-key-server client1
Generating a 1024 bit RSA private key
.................................++++++
..++++++
writing new private key to 'client1.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
State or Province Name (full name) [CA]:94
Locality Name (eg, city) [SanFrancisco]:Creteil
Organization Name (eg, company) [Fort-Funston]:Paris12
Organizational Unit Name (eg, section) []:Master2SSI
Common Name (eg, your name or your server's hostname) [client1]:client1
Email Address [me@myhost.mydomain]:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /usr/share/doc/openvpn/examples/easy-rsa/2.0/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'FR'
stateOrProvinceName   :PRINTABLE:'94'
localityName          :PRINTABLE:'Creteil'
organizationName      :PRINTABLE:'Paris12'
organizationalUnitName:PRINTABLE:'Master2SSI'
commonName            :PRINTABLE:'client1'
emailAddress          :IA5STRING:'me@myhost.mydomain'
Certificate is to be certified until Mar 26 02:41:30 2018 GMT (3650 days)
Sign the certificate? [y/n]:y
 

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
root@ubuntu:/usr/share/doc/openvpn/examples/easy-rsa/2.0#

5. Création des paramètres de Diffie-Hellman

On crée les paramètres Diffie-Hellman :

root@ubuntu:/usr/share/doc/openvpn/examples/easy-rsa/2.0# ./build-dh
Generating DH parameters, 1024 bit long safe prime, generator 2
This is going to take a long time
...................................................................+............
................................................................+...............
.........+.................+.......+............................................
.+..............................................................................
....+............................................................+..............
................................................................................
.......++*++*++*
root@ubuntu:/usr/share/doc/openvpn/examples/easy-rsa/2.0#

6. Copie des clefs dans le répertoire d'OpenVPN

On copie les fichiers ainsi créés dans le répertoire /etc/openvpn :

root@ubuntu:/usr/share/doc/openvpn/examples/easy-rsa/2.0# cp -r keys /etc/openvpn/

1.2 OpenVPN : configuration

On regarde les fichiers d'exemples. On copie server.conf dans /etc/openvpn :

root@ubuntu:/usr/share/doc/openvpn/examples/sample-config-files# cp server.conf.gz /etc/openvpn/
root@ubuntu:/usr/share/doc/openvpn/examples/sample-config-files#

On décompresse :

root@ubuntu:/usr/share/doc/openvpn/examples/sample-config-files# cd /etc/openvpn/
root@ubuntu:/etc/openvpn# gzip -d server.conf.gz
root@ubuntu:/etc/openvpn#

On édite ensuite ensuite le fichier de conf d'OpenVPN pour le serveur.

port 1194
proto udp
dev tun

ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/server1.crt
key /etc/openvpn/keys/server1.key # à garder bien secrête

dh /etc/openvpn/keys/dh1024.pem
 
server 10.8.0.0 255.255.255.0
comp-lzo
persist-key
persist-tun
status openvpn-status.log
verb 3

A) Configuration du client

On vérifie les fichiers d'exemples :

root@ubuntu:/etc/openvpn# cd /usr/share/doc/openvpn/examples/sample-config-files/
root@ubuntu:/usr/share/doc/openvpn/examples/sample-config-files# cp client.conf /etc/openvpn/
root@ubuntu:/usr/share/doc/openvpn/examples/sample-config-files# cd /etc/openvpn
root@ubuntu:/etc/openvpn#

On édite client.conf en rajoutant l'adresse du serveur VPN.

client
dev tun
proto udp

remote ip_du_server 1194

resolv-retry infinite
nobind
persist-key
persist-tun

ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/client1.crt
key /etc/openvpn/keys/client1.key

comp-lzo
verb 3

B) Distribution de certificats

On lance le serveur :

root@ubuntu:/etc/openvpn# mv server.conf openvpn.conf
root@ubuntu:/etc/openvpn# /etc/init.d/openvpn start
Starting virtual private network daemon: client(OK) openvpn(OK).

Une fois le client connecté, on obtient des informations sur lui en consultant /etc/openvpn/openvpn-status.log :

localhost openvpn # cat openvpn-status.log 
OpenVPN CLIENT LIST
Updated,Sun Dec 17 17:21:15 2006
Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since
ABC,88.169.118.169:34322,8851,9928,Sun Dec 17 17:18:29 2006
ROUTING TABLE
Virtual Address,Common Name,Real Address,Last Ref
10.8.0.6,ABC,88.169.118.169:34322,Sun Dec 17 17:21:01 2006
GLOBAL STATS
Max bcast/mcast queue length,0
END

Le fichier ipp.txt est quant à lui, vide chez le client et contient ABC,10.8.0.4 chez le serveur. On essaie de capturer sur l'interface sur laquelle partent nos paquets, ici, des pings:

17:36:58.100540 IP monclient.openvpn >    88.169.118.169.34322: UDP, length 125
        0x0000:  4500 0099 0000 4000 4011 be9c 5372 5939  E.....@.@...SrY9
        0x0010:  58a2 766a 04aa 8612 0085 8135 302e 335e  X.vj.......50.3^
        0x0020:  c78b ee3d 8792 ce09 da12 2207 5e06 40dd  ...=......".^.@.
        0x0030:  d2d1 8460 3e98 8c6e def3 e5af 28eb ec62  ...`>..n....(..b
        0x0040:  fb06 cd23 22b9 3e04 3e4d 58c2 4d4a 4ed1  ...#".>.>MX.MJN.
17:36:58.186103 IP 88.169.118.169.34322 > monclient.openvpn: UDP, length 125
        0x0000:  4500 0099 0000 4000 3711 c79c 58a2 766a  E.....@.7...X.vj
        0x0010:  5372 5939 8612 04aa 0085 6cae 30e3 834f  SrY9......l.0..O
        0x0020:  ad50 8cd8 b076 aa7b d241 05c4 9727 3253  .P...v.{.A...'2S
        0x0030:  ac79 26b4 d5fb 1238 1775 b717 ebca 3a6d  .y&....8.u....:m
        0x0040:  3936 c20d 0608 be9b 4a2d fc18 94f9 f1fb  96......J-......

C'est bien entendu chiffré, mais c'est bon de le vérifier (on voit un paquet UDP, mais les données ne nous sont pas compréhensibles).

Après avoir effectué quelques tests de connectivité avec ping, on remarque quelques «choses» intéressantes avec les outils classiques au niveau serveur :

localhost openvpn # arp -a
localhost openvpn # route
Table de routage IP du noyau
Destination     Passerelle      Genmask         Indic Metric Ref    Use Iface
10.8.0.2        *               255.255.255.255 UH    0      0        0 tun0
local312.lnsta1 *               255.255.255.255 UH    0      0        0 ppp0
10.8.0.0        10.8.0.2        255.255.255.0   UG    0      0        0 tun0
192.168.1.0     *               255.255.255.0   U     0      0        0 eth0
192.168.10.0    *               255.255.255.0   U     0      0        0 eth1
loopback        *               255.0.0.0       U     0      0        0 lo
default         local312.lnsta1 0.0.0.0         UG    0      0        0 ppp0

On constate que notre table de cache ARP est vide et que notre table de routage a obtenu quant à elle de nouvelles routes permettant de passer dans le tunnel.

C) Mode pont (Bridge)

On modifie les fichiers de configurations clients et serveur en remplaçant dev tun par dev tap.

On re-pratique les tests précédents :

localhost openvpn # route
Table de routage IP du noyau
Destination     Passerelle      Genmask         Indic Metric Ref    Use Iface
local232.lnfny1 *               255.255.255.255 UH    0      0        0 ppp0
10.8.0.0        *               255.255.255.0   U     0      0        0 tap0
192.168.1.0     *               255.255.255.0   U     0      0        0 eth0
192.168.10.0    *               255.255.255.0   U     0      0        0 eth1
loopback        *               255.0.0.0       U     0      0        0 lo
default         local232.lnfny1 0.0.0.0         UG    0      0        0 ppp0

La table de routage s'est un peu allégée.

Le mode pont nous permet d'agir directement au niveau de la couche 2. Le client se fait attribuer une IP lorsqu'il se connecte, mais il pourrait très bien avoir une conectivité IPv6 ou demander son IP à un serveur DHCP.

Le fichier ipp.txt n'a pas changé. Le fichier openvpn-status.log a quelque peu changé, et montre maintenant de nouvelles informations, telle l'adresse MAC du client :

OpenVPN CLIENT LIST
Updated,Sun Dec 17 17:48:58 2006
Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since
ABC,88.169.118.169:34393,5264,6927,Sun Dec 17 17:42:51 2006
ROUTING TABLE
Virtual Address,Common Name,Real Address,Last Ref
 8a:e5:8c:0a:a5:a6,ABC,88.169.118.169:34393,Sun Dec 17 17:42:53 2006
GLOBAL STATS
Max bcast/mcast queue length,1
END

Notre table ARP nous informe que l'on a bien accès à la couche 2 :

localhost openvpn # arp -a
? (10.8.0.4) at 8A:E5:8C:0A:A5:A6 [ether] on tap0

La capture du flux sur tap0 nous montre les échanges de requète ARP, explique pourquoi la table ARP se remplit.

Ce type de tunnel est donc parfait pour tout ce qui nécessite des protocoles au dessus de la couche 2, comme IPX par exemple. Avant, quand nous n'étions pas en mode pont, ce n'était pas possible de mettre des protocoles de niveau 3 dans notre tunnel.

D) Poussée de routes vers le client

Cette configuration force le client à passer tout son trafic sortant à l'intérieur du VPN. Cela permet de sécuriser de manière totale sa connexion. En point négatif, on pourra remarquer que cela augmente la latence du client (puisqu'il doit maintenant passer par le VPN pour sortir) et peut aussi limiter son débit.

On édite server.conf pour "pousser" les routes vers la machine du client, on rajoute la ligne suivante :

push "redirect-gateway def1"

Il faut aussi rajouter au serveur des règles pour activer le NAT si on veut que le client puisse sortir vers l'extérieur. En voici un exemple:

iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

2) VPN applicatif : Stunnel & SSH (ou tunneling de ports)

Stunnel 3.X

Si on fonctionne sur un ancien système, il est probable que l'on ait une ancienne version de stunnel. La version 4.0 a apporté de nombreux changements, dont un changement total de la façon de le lancer. La nouvelle version lit dans un fichier, tandis que l'ancienne prenait tous ses arguments en ligne de commande. Pour plus d'information, se réferrer à l'URL suivante Upgrading to stunnel 4 (en anglais).

Stunnel 4.X

Principe et utilité

Cet outil sert dans plusieurs cas :

  • quand on est sur un réseau non sûr et que l'on souhaite se connecter par exemple sur un serveur mail externe en POP afin d'y relever son courrier électronique
  • quand on a un serveur utilisant pour communiquer le protocole TCP et que l'on veut lui adjoindre la fonctionnalité SSL afin que son trafic soit chiffré

Stunnel est une sorte de proxy, il fonctionne comme suit : client (en clair) <=> Stunnel (sur la machine client) <=> Stunnel (sur un hôte de confiance ou directement sur le serveur)<=> leserveur (en clair)

Ainsi, tout l'échange entre le client et le serveur est sécurisé par stunnel.

Comme tout transite avec SSL, on pourra constater que la capture du trafic sur l'interface de sortie du client que la communication est totalement chiffrée.

Côté serveur

Nous allons ici nous employer a protéger un serveur HTTP qui n'a pas de connexion HTTPS. Le fichier de configuration /etc/stunnel/stunnel.conf ressemble à ce qui suit :

# Sample stunnel configuration file by Michal Trojnara 2002-2005
# Some options used here may not be adequate for your particular configuration
# Please make sure you understand them (especially the effect of chroot jail)

# Certificate/key is needed in server mode and optional in client mode
cert = /etc/stunnel/stunnel.pem
key = /etc/stunnel/stunnel.key

# Some security enhancements for UNIX systems - comment them out on Win32
# chroot = /chroot/stunnel/
setuid = stunnel
setgid = stunnel
# PID is created inside chroot jail
pid = /var/run/stunnel/stunnel.pid

# Some performance tunings
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1
#compression = rle

# Workaround for Eudora bug
#options = DONT_INSERT_EMPTY_FRAGMENTS

# Authentication stuff
#verify = 2
# Don't forget to c_rehash CApath
# CApath is located inside chroot jail:
#CApath = /certs
# It's often easier to use CAfile:
#CAfile = /etc/stunnel/certs.pem
# Don't forget to c_rehash CRLpath
# CRLpath is located inside chroot jail:
#CRLpath = /crls
# Alternatively you can use CRLfile:
#CRLfile = /etc/stunnel/crls.pem

# Some debugging stuff useful for troubleshooting
#debug = 7
output = /var/log/stunnel.log

# Use it for client mode
#client = yes

# Service-level configuration

#[pop3s]
#accept  = 995
#connect = 110

#[imaps]
#accept  = 993
#connect = 143

#[ssmtp]
#accept  = 465
#connect = 25

[https]
accept  = 443
connect = serveur_a_proteger:80
TIMEOUTclose = 0

Ici, on va donc dire d'écouter sur le port 443 un client stunnel afin de pouvoir se brancher de manière sécurisée sur le port 80 de ce site.

Côté client

On édite le fichier de configuration de stunnel pour le client, c'est à dire /etc/stunnel/stunnel.conf.

client = yes    # on est le client
#foreground = no

[443]
accept = localhost:80    # port en clair
connect = IP_serveur_stunnel:443    # serveur et son port SLL

Ensuite on lance stunnel par la commande :

[root@mamachine ssl]# stunnel /etc/stunnel/stunnel.conf

On voit que ça a marché :

[root@mamachine ssl]# netstat -l -t -n|grep :80
tcp        0      0 127.0.0.1:80                0.0.0.0:*                   LISTEN

Pour vraiment faire un vrai tunnel sécurisé, et que le client soit sûr que le serveur soit digne de confiance, le serveur aurait pu donner au client son certificat. Le client aurait juste eu à rajouter dans son fichier stunnel.conf la ligne suivante :

cert = /etc/stunnel/server.pem

Analyse du trafic

Avec l'aide Wireshark (ex-Ethereal), lorsqu'on capture un échange HTTP complet, on ne voit pas le trafic HTTP. Soit on a commencé la capture au début de l'échange et on voit que l'on a du SSL, soit on a commencé la capture au cours de l'échange et Wireshark ne voit que du TCP.

SSH

On utilise maintenant le même mécanisme mais en utilisant le protocole SSH.

Côté serveur

Il est très probable que le serveur SSH de notre distribution soit déjà directement bien configuré. Si on a un problème pour la suite, il faut penser à vérifier que l'on a activé le TCP port forwarding en rajoutant la ligne suivant dans son sshd_config (celui-ci est normalement activé par défaut si rien n'est précisé):

AllowTcpForwarding yes

Côté client

On va tenter de faire un tunnel via SSH. On choisit un port non privilégié (supérieur à 1024), ici on a pris 6712. On va ensuite demander au serveur SSH de nous rediriger le trafic d'un serveur choisi, ici le serveur web www.linuxfr.org.

[root@client ssl]# ssh -l luser -L 6712:www.linuxfr.org:80 serveur_ssh.tld
Warning: Permanently added '80.114.69.57' (RSA) to the list of known hosts.
Password:
Last login: Sun Dec 17 20:21:06 2006 from localhost
luser@remotehost ~ $ ls

La connexion au serveur SSH a marché. On lance un navigateur web sur localhost:6712, et on est immédiatement redirigé sur la page d'accueil de linuxfr.org. On peut vérifié que le tunnel a bien marché aussi avec la commande netstat :

[root@client openvpn]# netstat -l -t -n | grep :6712
tcp        0      0 127.0.0.1:6712              0.0.0.0:*                   LISTEN
tcp        0      0 ::1:6712                    :::*                        LISTEN
[root@client openvpn]#

Analyse de trafic

On ne peut pas voir de trafic HTTP avec Wireshark, tout est chiffré.

WGET et tunneling SSH

On va essayer de récupérer avec wget l'image qui est en haut à gauche du site linuxfr.org (un manchot) :

[root@client tmp]# wget 127.0.0.1:6712/images/top_bar_left_logo.png
--21:07:48--  http://127.0.0.1:6712/images/top_bar_left_logo.png
           => `top_bar_left_logo.png'
Connexion vers 127.0.0.1:6712...connecté.
requête HTTP transmise, en attente de la réponse...302 Found
Emplacement: http://linuxfr.org/ images/top_bar_left_logo.png [suivant]
--21:07:49--  http://linuxfr.org/ images/top_bar_left_logo.png
           => `top_bar_left_logo.png'
Résolution de linuxfr.org... 212.27.33.225
Connexion vers linuxfr.org|212.27.33.225|:80...connecté.
requête HTTP transmise, en attente de la réponse...200 OK
Longueur: 20,474 (20K) [image/png] 

100%[=============================================================================================================>] 20,474        --.--K/s

21:07:49 (240.57 KB/s) - « top_bar_left_logo.png » sauvegardé [20474/20474]

[root@client tmp]#

On a bien récupéré l'image et on peut la visionner. Wget est passé chez le client par le port 6712, au début. Puis, il s'est vu donné l'IP du site de linuxfr.org pour télécharger. C'est pourquoi il nous affiche qu'il a téléchargé sur linuxfr.org. Ainsi, seul le début de la requète est passé par le tunnel. Le reste de la transaction s'est effectuée en clair.

Tunneling SSH de port distant

[root@client tmp]# ssh -l user -R le_port_ouvert_a_distance:l_IP_de_l_hote_a_contacter:le_port_du_serveur_a_contacter le_serveur_distant
Password:
Last login: Sun Dec 17 21:22:21 2006 from localhost
user@localhost ~ $

Ainsi, toutes les requêtes sur le_server_distant:le_port_ouvert_a_distance seront ramenées à la machine qui aura établi la connexion SSH, et celle-ci transférera à son tour ses connexions vers l_IP_de_l_hote_a_contacter:le_port_du_serveur_a_contacter.

L'explication de la page de manuel SSH:

    -R [bind_address:]port:host:hostport
            Specifies that the given port on the remote (server) host is to
            be forwarded to the given host and port on the local side.  This
            works by allocating a socket to listen to port on the remote
            side, and whenever a connection is made to this port, the connec-
            tion is forwarded over the secure channel, and a connection is
            made to host port hostport from the local machine.

Cette fonctionnalité permet par exemple de donner un accès à des machines à l'intérieur d'un réseau.

Authentification forte SSH par clés

Une possibilité de SSH est l'authentification par clef. Celle-ci permet:

  • de s'authentifier avec une clef, ce qui augmente la sécurité entre le client serveur, car ce dernier peut ensuite exiger que tous les clients aient une clef pour se loguer (deux éléments requis au lieu d'un seul)
  • de s'authentifier de manière automatique, facilitant ainsi la mise en place de script

Il faut au préalable créer une clef:

~/$ ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_dsa):./maclef
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in ./maclef.
Your public key has been saved in ./maclef.pub.
The key fingerprint is:
f2:aa:d0:9e:4e:95:ff:29:f3:3b:ac:fc:0f:2d:b4:ef user@localhost

Ici, si vous entrez une passphrase, celle-ci sera demandée à chaque login. Si vous décidez de ne pas en mettre, cela permettra l'authentification sans login (pensez à protéger votre clef!).

Ensuite, il suffit d'envoyer la clef publique sur le serveur :

ssh-copy-id -i lecheminverslaclefPUBLIQUE IP_DU_SERVEUR

Vous aurez ainsi le plaisir de pouvoir vous loguer grâce à cette clef de la manière suivante :

ssh -i lecheminverslaclefPRIVEE IP_DU_SERVEUR

Conclusions

  • Avec le tunneling SSH, on a rien à configurer (avant il fallait éditer le fichier stunnel.conf). Il faut juste que le client possède un client SSH.
  • Par SSH on a l'avantage d'avoir une authentification par mot de passe (avec stunnel le client aurait peut cependant exiger d'avoir le certificat du serveur).
  • Un inconvénient est que les ports locaux qu'on utilise pour les transferts (ici 6712) sont accessibles par tous les utilisateurs éventuels de la machine, e.g. les passerelles.



@ Retour à la rubrique Sécurité et vie privée

Copyright

© 2006, 2010 Jiel Beaumadier et Tony Cheneau

Tête de GNU Vous avez l'autorisation de copier, distribuer et/ou modifier ce document suivant les termes de la GNU Free Documentation License, Version 1.2 ou n'importe quelle version ultérieure publiée par la Free Software Foundation; sans section invariante, sans page de garde, sans entête et sans page finale.