Table des matières

Installation d'un VPN site à site avec StrongSwan

CréationNicolas THOREZ 2019/05/15 20:20

Le recours à un VPN est très utile dans différents cas. Les plus importants sont :

Sous linux, il existe plusieurs possibilités pour établir un tunnel VPN. Les plus courantes seront OpenVPN, intéressant dans le cadre d'un poste itinérant, et StrongSwan, pour les tunnel IPSec site à site.

Droits

Ce tutoriel a été réalisé sur deux debian stretch (version 9.4 et 9.7) et en tant que root. Les adresses IP choisies sont volontairement fausses.

Installation

apt-get update

apt-get install strongswan

Configuration

La configuration diffère légèrement entre les deux têtes de pont. Avant toute chose, il faut se mettre d'accord sur plusieurs points (dans ce tutoriel, mes choix sont en Gras) :

Adressage IP

Attention aux plages d'adressage. Un VPN ne pourra jamais fonctionner correctement si une plage d'adressage (par exemple : 192.168.0.0/24) existe des deux côtés du tunnel. En effet, les routeurs chercherons toujours à utiliser les routes les plus courtes et si une plage correspond aussi bien à du local qu'à du distant, la route locale sera toujours plus courte.

Voici donc mon tableau récapitulatif :

Paramètres Tête de pont A Tête de pont B
IP publique locale 78.79.1.2 89.90.3.4
IP publique distante 89.90.3.4 78.79.1.2
IP privée (si NAT) - 192.168.0.1
Plage 10.0.1.0/24 10.0.2.1/32
Type d'authentification PSK
Version IKE IKEv2
Cryptage AH AES256-SHA256
Diffie-Hellman AH Groupe 14 (MODP2048)
Durée de vie IKE 28800s
Cryptage ESP AES256-SHA256
Diffie-Hellman ESP Groupe 14 (MODP2048)
Durée de vie IPSec 1h

Une fois les paramètres déterminés, nous pouvons configurer chaque têtes de pont. Commençons donc par la première.

1ère tête de pont

nano /etc/network/interfaces

# "auto" correspond aux montage automatique de l'interface au démarrage de la machine
# "eth1:0" correspond à l'interface virtuelle 0 (la première) de l'interface physique eth1
auto eth1:0
# On déclare l'interface avec une adresse statique
iface eth1:0 inet static
        address 10.0.1.1/24

ifup eth1:0

nano /etc/ipsec.conf

## On commence par la configuration générale du daemon ipsec
config setup
    # Cette ligne sert à l'établissement des logs
    charondebug="cfg 2, dmn 2, ike 2, net 2"

## Ce bloc correspond aux paramètres de notre tunnel VPN, nommé pour l'occasion test-vpn
conn test-vpn
    # On indique le mode de démarrage du tunnel
    auto=start
    # On indique le type de tunnel
    type=tunnel
    # On indique la version du protocole IKE
    keyexchange=ikev2
    ## Les lignes suivantes sont optionnelles mais utiles. Elles permettent de vérifier si la connexion est toujours active.
    # C'est le DPD (Dead Peer Detection) 
    closeaction=hold
    dpdaction=hold
    dpddelay=30s
    dpdtimeout=150s
    ## Les lignes suivantes sont optionnelles mais utiles. Elles permettent de relancer la connexion en cas d'échec.
    rekey=yes
    keyingtries=5

    ## Le bloc "left" correspond à la partie locale de la tête de pont
    # "left" correspond à l'adresse IP locale du poste si il est derrière un NAT ou son adresse IP publique, le cas échéant
    left= 78.79.1.2
    # "leftid" correspond toujours à son adresse IP publique
    leftid= 78.79.1.2
    # "leftsubnet" correspond à la plage distribuée pour les postes distants 
    leftsubnet=10.0.1.0/24
    # La ligne suivante indique la présence d'un pare-feu
    leftfirewall=yes

    ## Le bloc "right" correspond à la partie distante de la tête de pont
    # "right" et "rightid" indique l'adresse IP publique de l'autre tête de pont 
    right= 89.90.3.4
    rightid= 89.90.3.4
    # "rightsubnet" correspond à la plage distribuée par le poste distant pour les postes locaux
    rightsubnet= 10.0.2.1/32 

    ## Ici, on commence les paramétrages de la phase 1 (ISAKMP)
    # On indique le type d'authentification choisie
    authby=secret
    # On indique nos choix de chiffrement et le groupe Diffie-Hellman 
    ike=aes256-sha256-modp2048
    # On indique la durée de vie de la phase 1
    ikelifetime=28800s
    
    ## Ici, on commence les paramétrage de la phase 2 (IPSEC)
    # On indique nos choix de chiffrement et le groupe Diffie-Hellman
    esp=aes256-sha256-modp2048
    # On indique la durée de vie de la phase 1
    lifetime=1h
    # On indique notre souhait de forcer l'encapsulation des données (pour plus de sécurité)
    forceencaps=yes
    # Cette ligne permet d'indiquer au daemon ipsec, son comportement en cas de perte de connexion
    # pull pour attendre l'établissement d'une connexion de la part de l'autre tête de pont
    # push pour établir cette connexion
    modeconfig=push

nano /etc/ipsec.secrets

# PSK pour test-vpn
78.79.1.2 89.90.3.4 : PSK "Azerty123"

Pare-feu

Il faut obligatoirement ouvrir les port UDP 500 et UDP 4500 sur votre solution de pare-feu et ce, pour chaque tête de pont.

Notre première tête de pont est paramétrée. Passons à la seconde.

2ème tête de pont

Pour la seconde tête de pont, le cheminement de la configuration est similaire, à l'exception du croisement des données au niveau des adresses IP.

nano /etc/network/interfaces

# "auto" correspond aux montage automatique de l'interface au démarrage de la machine
# "eth1:0" correspond à l'interface virtuelle 0 (la première) de l'interface physique eth1
auto eth1:0
# On déclare l'interface avec une adresse statique
iface eth1:0 inet static
        address 10.0.2.1/32

ifup eth1:0

nano /etc/ipsec.conf

## On commence par la configuration générale du daemon ipsec
config setup
    # Cette ligne sert à l'établissement des logs
    charondebug="cfg 2, dmn 2, ike 2, net 2"

## Ce bloc correspond aux paramètres de notre tunnel VPN. On peut utiliser un autre nom que celui de l'autre tête de pont.
conn test-vpn
    # On indique le mode de démarrage du tunnel
    auto=start
    # On indique le type de tunnel
    type=tunnel
    # On indique la version du protocole IKE
    keyexchange=ikev2
    ## Les lignes suivantes sont optionnelles mais utiles. Elles permettent de vérifier si la connexion est toujours active.
    # C'est le DPD (Dead Peer Detection) 
    closeaction=hold
    dpdaction=hold
    dpddelay=30s
    dpdtimeout=150s
    ## Les lignes suivantes sont optionnelles mais utiles. Elles permettent de relancer la connexion en cas d'échec.
    rekey=yes
    keyingtries=5

    ## Le bloc "left" correspond à la partie locale de la tête de pont
    # "left" correspond à l'adresse IP locale du poste si il est derrière un NAT ou son adresse IP publique, le cas échéant
    left= 192.168.0.1
    # "leftid" correspond toujours à son adresse IP publique
    leftid= 89.90.3.4
    # "leftsubnet" correspond à la plage distribuée pour les postes distants 
    leftsubnet=10.0.2.1/32
    # La ligne suivante indique la présence d'un pare-feu
    leftfirewall=yes

    ## Le bloc "right" correspond à la partie distante de la tête de pont
    # "right" et "rightid" indique l'adresse IP publique de l'autre tête de pont 
    right= 78.79.1.2
    rightid= 78.79.1.2
    # "rightsubnet" correspond à la plage distribuée par le poste distant pour les postes locaux
    rightsubnet= 10.0.1.0/24 

    ## Ici, on commence les paramétrages de la phase 1 (ISAKMP)
    # On indique le type d'authentification choisie
    authby=secret
    # On indique nos choix de chiffrement et le groupe Diffie-Hellman 
    ike=aes256-sha256-modp2048
    # On indique la durée de vie de la phase 1
    ikelifetime=28800s
    
    ## Ici, on commence les paramétrage de la phase 2 (IPSEC)
    # On indique nos choix de chiffrement et le groupe Diffie-Hellman
    esp=aes256-sha256-modp2048
    # On indique la durée de vie de la phase 1
    lifetime=1h
    # On indique notre souhait de forcer l'encapsulation des données (pour plus de sécurité)
    forceencaps=yes
    # Cette ligne permet d'indiquer au daemon ipsec, son comportement en cas de perte de connexion
    # pull pour attendre l'établissement d'une connexion de la part de l'autre tête de pont
    # push pour établir cette connexion
    modeconfig=push

Configurations inversées

On remarque bien que les parties "left" et "right" ont été inversées entre les deux configurations.

nano /etc/ipsec.secrets

# PSK pour test-vpn
89.90.3.4 78.79.1.2 : PSK "Azerty123"

Pare-feu

Il faut obligatoirement ouvrir les port UDP 500 et UDP 4500 sur votre solution de pare-feu et ce, pour chaque tête de pont.

La configuration des deux têtes de pont est maintenant terminée. Il ne reste plus qu'à lancer la connexion.

Prise en compte des paramétrages

Pour établir la connexion, il faut d'abord prendre en compte les configurations établies. Le plus simple est de redémarrer le daemon ipsec. Sinon il faut recharger la configuration.

Redémarrage

Attention : si vous avez plusieurs tunnel VPN et que vous redémarrer le daemon, la connexion des autres tunnels sera coupée. La première méthode est donc réservée aux postes ne gérant qu'un seul tunnel.

/etc/init.d/ipsec restart

ipsec down test-vpn

ipsec reload

ipsec rereadall

Établissement de la connexion

Il ne nous reste plus qu'à établir la connexion. Pour cela :

ipsec statusall

Si la connexion existe déjà, la console nous renvoie des informations de ce genre :

Status of IKE charon daemon (strongSwan 5.5.1, Linux 4.9.0-9-amd64, x86_64):
  uptime: 17 hours, since May 15 18:06:34 2019
  malloc: sbrk 1810432, mmap 0, used 1228912, free 581520
  worker threads: 11 of 16 idle, 5/0/0/0 working, job queue: 0/0/0/0, scheduled: 3
  loaded plugins: charon aesni aes rc2 sha2 sha1 md5 random nonce x509 revocation constraints pubkey pkcs1 pkcs7 pkcs8 pkcs12 pgp dnskey sshkey pem openssl fips-prf gmp agent xcbc hmac gcm attr kernel-netlink resolve socket-default connmark stroke updown
Listening IP addresses:
  78.79.1.2
  10.0.1.1
Connections:
test-vpn:  78.79.1.2...89.90.3.4  IKEv2, dpddelay=30s
test-vpn:   local:  [78.79.1.2] uses pre-shared key authentication
test-vpn:   remote: [89.90.3.4] uses pre-shared key authentication
test-vpn:   child:  10.0.1.0/24 === 10.0.2.1/32 TUNNEL, dpdaction=hold
Routed Connections:
test-vpn{24}:  ROUTED, TUNNEL, reqid 1
test-vpn{24}:   10.0.1.0/24 === 10.0.2.1/32
Security Associations (1 up, 0 connecting):
test-vpn[4]: ESTABLISHED 2 hours ago, 78.79.1.2[78.79.1.2]...89.90.3.4[89.90.3.4]
test-vpn[4]: IKEv2 SPIs: fa03f2ec5ef41906_i 979ecb282fca7b86_r*, pre-shared key reauthentication in 5 hours
test-vpn[4]: IKE proposal: AES_CBC_256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_2048
test-vpn{28}:  INSTALLED, TUNNEL, reqid 1, ESP in UDP SPIs: c26dcbcf_i c82d3f3f_o
test-vpn{28}:  AES_CBC_256/HMAC_SHA2_256_128/MODP_2048, 0 bytes_i, 0 bytes_o, rekeying in 34 minutes
test-vpn{28}:   10.0.1.0/24 === 10.0.2.1/32

Si ce n'est pas le cas, il suffit d'établir la connexion grâce à la commande :

ipsec up test-vpn

Nous aurons alors droit à un message de ce type :

initiating IKE_SA test-vpn[5] to 89.90.3.4
generating IKE_SA_INIT request 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(HASH_ALG) N(REDIR_SUP) ]
sending packet: from 78.79.1.2[500] to 89.90.3.4[500] (1172 bytes)
received packet: from 89.90.3.4[500] to 78.79.1.2[500] (464 bytes)
parsed IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(HASH_ALG) N(MULT_AUTH) ]
remote host is behind NAT
sending cert request for "CN=VPN certificate CA"
authentication of '78.79.1.2' (myself) with pre-shared key
establishing CHILD_SA test-vpn
generating IKE_AUTH request 1 [ IDi N(INIT_CONTACT) CERTREQ IDr AUTH SA TSi TSr N(MOBIKE_SUP) N(ADD_4_ADDR) N(MULT_AUTH) N(EAP_ONLY) ]
sending packet: from 78.79.1.2[4500] to 89.90.3.4[4500] (416 bytes)
received packet: from 89.90.3.4[4500] to 78.79.1.2[4500] (272 bytes)
parsed IKE_AUTH response 1 [ IDr AUTH SA TSi TSr N(AUTH_LFT) N(MOBIKE_SUP) N(ADD_4_ADDR) N(ADD_4_ADDR) N(ADD_4_ADDR) ]
authentication of '89.90.3.4' with pre-shared key successful
IKE_SA test-vpn[5] established between 78.79.1.2[78.79.1.2]...89.90.3.4[89.90.3.4]
scheduling reauthentication in 27990s
maximum IKE_SA lifetime 28530s
connection 'test-vpn' established successfully

Installation

Félicitation, votre tunnel est monté!

Résolution des pannes

Problème

Si le tunnel ne veux pas se monter.

Vérification

Il est intéressant d'observer les logs de la tête de pont distante lors de l'initialisation de la connexion :

tail -f /var/log/kern.log

Une autre bonne source d'information est d'observer sur le pare-feu, le flux de paquets sur les ports UDP 500. Par exemple sur un pare-feu de type IPTables sous debian :

tcpdump -i any host 78.79.1.2 and port 500