vendredi 19 mars 2010

basics 9 - tutoriel IPSec

IPSEC sert à sécuriser les échanges au niveau de la couche réseau (IP). Dans ce tutoriel, nous étudions le mode transport IPSec sous Ubuntu.

protocoles ESP et AH, modes transport et tunnel.


IPSec utilise deux protocoles: ESP et AH. ESP permet la confidentialité et l'authentification des échanges (chiffrement), AH n'assure que l'authentification (signature).
IPSec propose également deux modes: transport et tunnel. Le mode transport modifie l'en-tête IP. Le mode tunnel encapsule le paquet IP entier dans un nouveau paquet IP.
Le choix parmi ces modes et protocoles a des implications sur les propriétés de sécurité:

AH:


(image tirée ciscopress [26])

AH + transport

En mode transport, l'adresse IP de l'émetteur est conservée et authentifiée. Elle ne peut alors pas être modifiée par un routeur: la translation d'adresse NAT n'est pas possible.

AH + tunnel

En mode tunnel, l'adresse IP de la passerelle et de l'émetteur sont authentifiées. Le mode tunnel ne permet pas de cacher l'adresse IP du réseau interne. La translation d'adresse NAT est possible.

ESP:


(image tirée ciscopress [26])

ESP + transport

En mode transport, l'adresse IP de l'émetteur n'est pas signée. Seules les données sont authentifiées. La redirection des paquets est rendue possible. Cela permet la translation d'adresse NAT.

ESP + tunnel

En mode tunnel, l'adresse IP de l'émetteur est chiffrée avec les données. Seul le récepteur peut donc connaître cette adresse. Comme en mode transport, le nouvel en-tête IP n'est pas authentifié ce qui permet la translation d'adresse NAT.

SA et SPD

Une security association (SA) est une communication protégée par IPSEC entre deux machines.
La base de données définissant la politique de sécurité (SPD) contient les règles qui sont appliquées pour l'envoi et la réception de paquets IP.
Nous vous renvoyons à ipframe.com [28] pour davantage d'informations sur les SA et la SPD.

Ipsec-tools

Les ipsec-tools de Linux incluent [29]:
libipsec: la librairie de chiffrement,
setkey: outil pour manipuler et lister la SPD et les SA,

Remarque: racoon, le démon Internet Key Exchange (IKE) pour négotier automatiquement les clés de connexion IPSec, n'est pas installé par défaut.

connexion sécurisée avec gestion manuelle des clés

Commencons pas installer ipsec-tools sur notre serveur et notre client Linux
serveur$ sudo apt-get install ipsec-tools
client_linux$ sudo apt-get install ipsec-tools
Modifions les droits du fichier /etc/ipsect-tools.conf
serveur$ sudo chmod 750 /etc/ipsec-tools.conf
client-linux$ sudo chmod 750 /etc/ipsec-tools.conf
éditons le fichier /etc/ipsec-tools.conf de chacune des machines:
serveur$ sudo cat /etc/ipsec-tools.conf
#!/usr/sbin/setkey -f

## Flush the SAD and SPD
flush;
spdflush;

## AH security association (SA)
add 192.168.0.2 192.168.0.11 ah 10000 -A hmac-md5 "1234567890123456";
add 192.168.0.2 192.168.0.11 esp 10001 -E 3des-cbc "123456789012345678901234";
add 192.168.0.11 192.168.0.2 ah 20000 -A hmac-md5 "1234567890123456";
add 192.168.0.11 192.168.0.2 esp 20001 -E 3des-cbc "123456789012345678901234";

## security policy
spdadd 192.168.0.2 192.168.0.11 any -P out ipsec esp/transport//require ah/transport//require;
spdadd 192.168.0.11 192.168.0.2 any -P in ipsec esp/transport//require ah/transport//require;
client_linux$ sudo cat /etc/ipsec-tools.conf
#!/usr/sbin/setkey -f

## Flush the SAD and SPD
flush;
spdflush;

## AH security association (SA)
add 192.168.0.2 192.168.0.11 ah 10000 -A hmac-md5 "1234567890123456";
add 192.168.0.2 192.168.0.11 esp 10001 -E 3des-cbc "123456789012345678901234";
add 192.168.0.11 192.168.0.2 ah 20000 -A hmac-md5 "1234567890123456";
add 192.168.0.11 192.168.0.2 esp 20001 -E 3des-cbc "123456789012345678901234";

spdadd 192.168.0.11 192.168.0.2 any -P out ipsec esp/transport//require ah/transport//require;
spdadd 192.168.0.2 192.168.0.11 any -P in ipsec esp/transport//require ah/transport//require;
Lancons le service (il sera lancé systématiquement au boot des machines).
serveur$ sudo /etc/init.d/setkey start
client-linux$ sudo /etc/init.d/setkey start
A présent, lancons Wireshark sur notre intrus, puis pingons:
client-linux$ ping 192.168.0.2
intrus$ sudo wireshark


L'inconvénient avec cette méthode, est que les clés sont fixes et codées en dur dans le fichier de configuration.

connexion sécurisée avec gestion automatique de clés

IPSec peut utiliser le protocole Internet Key Exchange (IKE) [31] pour éviter l'utilisation d'une clé codée en dur. Ce protocole possède deux étapes:

phase1: génération de la première clé. Soit avec le :
  • mode secret partagé: à partir d'un secret déjà partagé, dans un échange Diffie-Hellman
  • mode chiffrement asymétrique: avec un crypto système par clés publiques,
  • mode signature: le chiffrement asymétrique sert pour signer et authentifier les hôtes, le secret partagé est établi grace à Diffie Hellman.

Phase 2: création des tunnels IPSec.

mode secret partagé

racoon

Installons racoon (choisissons "modification directe")
serveur$ sudo apt-get install racoon
client-linux$ sudo apt-get install racoon
En l'absence de SA prédéfinie, le démon Setkey utilisera Racoon. Modifions le fichier /etc/ipsec-tools.conf sur les deux machines ainsi:
serveur$ sudo cat /etc/ipsec-tools.conf

#!/usr/sbin/setkey -f

## Flush the SAD and SPD
flush;
spdflush;

## security policy
spdadd 192.168.0.2 192.168.0.11 any -P out ipsec esp/transport//require ah/transport//require;
spdadd 192.168.0.11 192.168.0.2 any -P in ipsec esp/transport//require ah/transport//require;

client_linux$ sudo cat /etc/ipsec-tools.conf

#!/usr/sbin/setkey -f

## Flush the SAD and SPD
flush;
spdflush;

## security policy
spdadd 192.168.0.11 192.168.0.2 any -P out ipsec esp/transport//require ah/transport//require;
spdadd 192.168.0.2 192.168.0.11 any -P in ipsec esp/transport//require ah/transport//require;

racoon.conf


Modifions le fichier /etc/racoon/racoon.conf sur les deux machines:

client_linux$ sudo cat /etc/racoon/racoon.conf

path pre_shared_key "/etc/racoon/psk.txt";

remote anonymous
{
     exchange_mode main;
    lifetime time 24 hour;
    proposal {
        encryption_algorithm 3des;
        hash_algorithm sha1;
        authentication_method pre_shared_key;
        dh_group modp1024 ;
    }
}

sainfo anonymous
{
    pfs_group modp1024;
    lifetime time 12 hour;
    encryption_algorithm 3des, blowfish 448, rijndael ;
    authentication_algorithm hmac_sha1, hmac_md5;
    compression_algorithm deflate ;
}
serveur$ sudo cat /etc/racoon/racoon.conf
(..idem...)
Remarque: si les fichiers de configuration sont différents sur les deux machines, il se peut que l'échange IP ne puisse pas se faire, ou ne puisse être amorcé que depuis l'une des deux machines. Par exemple, en supprimant "blowfish 448" et "rijndael" du fichier du client_linux.

Utilisons la documentation de racoon.conf [30] pour apporter quelques éclaircissements:

Le fichier de configuration est divisé en trois parties:

  • La première donne le chemin vers le fichier qui contiendra le secret partagé.
path pre_shared_key "/etc/racoon/psk.txt";
  • La seconde (remote) définit les paramètres de la phase 1 du protocole IKE.

les règles s'appliqueront à tout machine:
remote anonymous
le mode d'échange de cette phase refusera le mode "aggressive" (cf vulnérabilité [32])
exchange_mode main;
l'échange aura une validité d'une journée
lifetime time 24 hour;
la configuration de l'échange acceptée (à défaut de tout autre) sera 3des, sha1, mode secret partagé, avec un modulus Diffie-Hellman égal à 1024.
proposal {
    encryption_algorithm 3des;
    hash_algorithm sha1;
    authentication_method pre_shared_key;
    dh_group modp1024 ;
}

  • La troisième (sainfo) définit les paramètres de la seconde phase du protocole IKE. Ces paramètres seront utilisés conjointement avec la politique de sécurité définie dans la SPD du noyau.

les règles s'appliqueront à toute machine:
sainfo anonymous
le modulus Diffie-Hellman sera égal à 1024
pfs_group modp1024;
l'échange aura une validité de 12 heures
lifetime time 12 hour;
les algorihmes de chiffrement acceptés seront 3des, blowfish 448 ou rijnael
encryption_algorithm 3des, blowfish 448, rijndael ;
les algorithmes de signature seront hmac_sha1 ou hmac_md5
authentication_algorithm hmac_sha1, hmac_md5;
l'algorithme de compression sera deflate
compression_algorithm deflate ;

clé pré-partagée psk.txt

Assurons nous des droits du fichier /etc/racoon/psk.txt sur les deux machines
serveur$ sudo chmod 750 /etc/racoon/psk.txt
client_linux$ sudo chmod 750 /etc/racoon/psk.txt
Modifions ce fichier sur les deux machines de la façon suivante (tabulation entre l'IP et le secret):
serveur$ sudo cat /etc/racoon/psk.txt
# IPv4/v6 addresses
192.168.0.11 secretpartage

client_linux$ sudo cat /etc/racoon/psk.txt
# IPv4/v6 addresses
192.168.0.2 secretpartage

redémarrage des services

relancons les daemons racoon et setkey
serveur$ sudo /etc/init.d/racoon restart
serveur$ sudo /etc/init.d/setkey restart
client_linux$ sudo /etc/init.d/racoon restart
client_linux$ sudo /etc/init.d/setkey restart

testons

client_linux$ sudo wireshark
serveur$ ping 192.168.0.2
PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
64 bytes from 192.168.0.2: icmp_seq=3 ttl=64 time=0.823 ms
^C
--- 192.168.0.2 ping statistics ---
3 packets transmitted, 1 received, 66% packet loss, time 2001ms
rtt min/avg/max/mdev = 0.823/0.823/0.823/0.000 ms



Cette méthode de gestion automatique de clés avec secret partagé permet de générer des clés de session qui rendent difficile la recherche du secret partagé. Cependant, ce secret est inscrit en clair sur les machines.

mode chiffrement asymétrique

Dans ce mode, nous utilisons des certificats X509 dans la phase 1 du protocole IKE.

Remarque: si vous ne souhaitez pas vous frotter tout de suite à openssl, les clés générées sont téléchargeables ici .Vous pouvez alors sauter directement au paragraphe "installation des clés sur racoon".

génération des clés avec openSSL

installons openSSL sur le serveur
serveur$ sudo apt-get install openssl
créons un répertoire qui contiendra les clés publiques, et un autre qui contiendra les clés privées
serveur$ sudo mkdir /etc/ca
serveur$ sudo mkdir /etc/ca/private
Contrôlons les droits du répertoire private
serveur$ sudo chmod 750 /etc/ca/private
plaçons nous dans /etc/ca et générons une paire de clés. Nous choisissons "utilisateur" comme mot de passe de chiffrement de notre clé privée.
serveur$ cd /etc/ca
serveur:/etc/ca$ sudo openssl req -new -x509 -days 365 -newkey rsa:1024 -keyout cakey.pem -out cacert.pem



copions la clé privée dans notre répertoire /etc/ca/private, et modifions ses droits d'accès
serveur:/etc/ca$ sudo mv /etc/ca/cakey.pem /etc/ca/private
serveur:/etc/ca$ sudo chmod 600 /etc/ca/private/cakey.pem
créons un fichier index.txt qui contiendra un log de chaque certificat signé
serveur:/etc/ca$ sudo touch index.txt
créons un fichier serial qui contiendra le prochain numéro de série X509 disponible
serveur:/etc/ca$ sudo touch serial
serveur:/etc/ca$ sudo vi serial
01
:wq
créons un répertoire /etc/ca/newcerts dans lequel nous déposerons une copie de chaque certificat signé par la CA
serveur:/etc/ca$ sudo mkdir newcerts
modifions le fichier de configuration de openssl
serveur$ sudo vim /usr/lib/ssl/openssl.cnf
(...)
[ CA default ]
dir = .
(...)
commonName = optional
(...)
créons une requête de signature de certificat (certificat signing request) pour chacune de nos machines
serveur:/etc/ca$ sudo openssl req -new -days 365 -newkey rsa:1024 -keyout clientlinuxkey.pem -out clientlinuxreq.pem
serveur:/etc/ca$ sudo openssl req -new -days 365 -newkey rsa:1024 -keyout serveurkey.pem -out serveurreq.pem
signons chaque CSR
serveur:/etc/ca$ sudo openssl ca -in clientlinuxreq.pem -out clientlinuxcert.pem
serveur:/etc/ca$ sudo openssl ca -in serveurreq.pem -out serveurcert.pem


retirons le mot de passe protégeant la clé privé de chaque machine
serveur:/etc/ca$ sudo openssl rsa -in clientlinuxkey.pem -out clientlinuxkey.pem
serveur:/etc/ca$ sudo openssl rsa -in serveurkey.pem -out serveurkey.pem

installation des clés sur racoon

copions la clé publique, la clé privée, la clé publique du CA dans le répertoire /etc/racoon/certs de chaque machine
serveur:/etc/ca$ sudo mkdir /etc/racoon/certs
serveur:/etc/ca$ sudo cp serveurkey.pem /etc/racoon/certs/
serveur:/etc/ca$ sudo cp serveurcert.pem /etc/racoon/certs/
serveur:/etc/ca$ sudo cp cacert.pem /etc/racoon/certs/
Nous pouvons utiliser gftp pour récupérer ces clés sur le client_linux
client_linux$ sudo apt-get install gftp
client_linux$ sudo mkdir /etc/racoon/certs
client_linux$ sudo gftp


La clé privée ne doit pas être compromise:
serveur$ sudo chmod 600 /etc/racoon/certs/serveurkey.pem
client_linux$sudo chmod 600 /etc/racoon/certs/clientlinuxkey.pem
Modifions le fichier /etc/racoon/racoon.conf des deux machines
serveur$ sudo cat /etc/racoon/racoon.conf

path pre_shared_key "/etc/racoon/psk.txt";
path certificate "/etc/racoon/certs";

#remote anonymous
#{
# exchange_mode main;
# proposal {
# encryption_algorithm 3des;
# hash_algorithm sha1;
# authentication_method pre_shared_key;
# dh_group modp1024 ;
# }
# generate_policy off;
#}

remote 192.168.0.11
{
    exchange_mode main;
    my_identifier asn1dn;
    peers_identifier asn1dn;
    verify_identifier on;
    certificate_type x509 "serveurcert.pem" "serveurkey.pem";
    ca_type x509 "cacert.pem";
    lifetime time 24 hour;
    proposal {
        encryption_algorithm 3des;
        hash_algorithm sha1;
        authentication_method rsasig;
        dh_group modp1024;
    }
}

sainfo anonymous
{
    pfs_group modp1024;
    lifetime time 12 hour;
    encryption_algorithm 3des, blowfish 448, rijndael ;
    authentication_algorithm hmac_sha1, hmac_md5;
    compression_algorithm deflate ;
}

client_linux$ sudo cat /etc/racoon/racoon.conf

path pre_shared_key "/etc/racoon/psk.txt";
path certificate "/etc/racoon/certs";

#remote anonymous
#{
# exchange_mode main;
# proposal {
# encryption_algorithm 3des;
# hash_algorithm sha1;
# authentication_method pre_shared_key;
# dh_group modp1024 ;
# }
# generate_policy off;
#}

remote 192.168.0.2
{
    exchange_mode main;
    my_identifier asn1dn;
    peers_identifier asn1dn;
    verify_identifier on;
    certificate_type x509 "clientlinuxcert.pem" "clientlinuxkey.pem";
    ca_type x509 "cacert.pem";
    lifetime time 24 hour;
    proposal {
        encryption_algorithm 3des;
        hash_algorithm sha1;
        authentication_method rsasig;
        dh_group modp1024;
     }
}

sainfo anonymous
{
    pfs_group modp1024;
    lifetime time 12 hour;
    encryption_algorithm 3des, blowfish 448, rijndael ;
    authentication_algorithm hmac_sha1, hmac_md5;
    compression_algorithm deflate ;
}
Les informations sur chacune de ces commandes sont bien expliquées dans le man de racoon.conf [30].

redémarrage des services

relancons les daemons racoon et setkey
serveur$ sudo /etc/init.d/racoon restart
serveur$ sudo /etc/init.d/setkey restart
client_linux$ sudo /etc/init.d/racoon restart
client_linux$ sudo /etc/init.d/setkey restart

testons

intrus$ sudo wireshark

client_linux$ ping 192.168.0.2
$ ping 192.168.0.2
PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
64 bytes from 192.168.0.2: icmp_seq=3 ttl=64 time=0.820 ms
^C
--- 192.168.0.2 ping statistics ---
3 packets transmitted, 1 received, 66% packet loss, time 2019ms
rtt min/avg/max/mdev = 0.820/0.820/0.820/0.000 ms



Références

26) IPSEC - http://www.ciscopress.com/articles/article.asp?p=25477
27) IPSEC How-To - https://help.ubuntu.com/community/IPSecHowTo
28) IPSEC - http://www.frameip.com/ipsec/
29) ipsec-tools - http://ipsec-tools.sourceforge.net/
30) doc racoon.conf - http://netbsd.gw.com/cgi-bin/man-cgi?racoon.conf
31) protocole IKE - http://sylvestre.ledru.info/howto/securite/tunnels_et_vpn/node29.html
32) IKE agressive mode vulnerability - http://www.kb.cert.org/vuls/id/886601

Aucun commentaire:

Publier un commentaire