« Strongswan » : différence entre les versions

De Wiki doc

(Phrase non terminé (pressé d'aller manger :D))
(Ajout du support d'ed25519 + suppression d'un doublon dans les sources.)
 
(3 versions intermédiaires par le même utilisateur non affichées)
Ligne 35 : Ligne 35 :
ipsec pki --self -t ecdsa --in /etc/ipsec.d/private/YC-NM_ycharbi_key.pem --outform pem --lifetime 3650 --dn "CN=YC-NM_ycharbi_crt" > /etc/ipsec.d/certs/YC-NM_ycharbi_crt.pem
ipsec pki --self -t ecdsa --in /etc/ipsec.d/private/YC-NM_ycharbi_key.pem --outform pem --lifetime 3650 --dn "CN=YC-NM_ycharbi_crt" > /etc/ipsec.d/certs/YC-NM_ycharbi_crt.pem
</source>
</source>
{{info|Depuis ''Strongswan 5.5.2'', il est possible d'utiliser des clés ''ed25519''. Pour [https://wiki.strongswan.org/issues/2308 se faire], il faudra remplacer le type <source lang="bash" inline>ecdsa</source> par <source lang="bash" inline>ed25519</source> dans les deux commandes précédentes ainsi que <source lang="bash" inline>ECDSA</source> par <source lang="bash" inline>PKCS8</source> dans <source lang="bash" inline>ipsec.secrets</source>. Il sera également préférable d'utiliser la liste cryptographique l'implémentant comme ceci: <source lang="bash" inline>aes256gcm128-sha512-curve25519!</source> dans <source lang="bash" inline>ipsec.conf</source>.}}
'''Configuration de la connexion'''
'''Configuration de la connexion'''
  vim /etc/ipsec.conf
  vim /etc/ipsec.conf
<source lang="ini">
<source lang="bash">
conn %default
conn %default
ikelifetime=60m
ikelifetime=60m
keylife=20m
keylife=20m
rekeymargin=3m
rekeymargin=3m
keyingtries=1
keyingtries=%forever
keyexchange=ikev2
keyexchange=ikev2
mobike=no
mobike=no
Ligne 58 : Ligne 61 :
rightid=@lesmorin
rightid=@lesmorin
rightcert=YC-NM_lesmorin_crt.pem
rightcert=YC-NM_lesmorin_crt.pem
auto=add
auto=route
</source>
</source>


'''Ajout d'une ACL pour la connexion'''
'''Ajout d'une ACL pour la connexion'''
  vim /etc/ipsec.secrets
  vim /etc/ipsec.secrets
  @lesmorin @ycharbi : ECDSA /etc/ipsec.d/private/YC-NM_lesmorin_key.pem
  @lesmorin @ycharbi : ECDSA /etc/ipsec.d/private/YC-NM_ycharbi_key.pem
 
'''Configuration de l'interface réseau'''
'''Configuration de l'interface réseau'''
<source lang="bash">
<source lang="bash">
Ligne 101 : Ligne 105 :
'''Configuration de la connexion'''
'''Configuration de la connexion'''
  vim /etc/ipsec.conf
  vim /etc/ipsec.conf
<source lang="ini">
<source lang="bash">
conn %default
conn %default
ikelifetime=60m
ikelifetime=60m
keylife=20m
keylife=20m
rekeymargin=3m
rekeymargin=3m
keyingtries=1
keyingtries=%forever
keyexchange=ikev2
keyexchange=ikev2
mobike=no
mobike=no
Ligne 122 : Ligne 126 :
rightid=@ycharbi
rightid=@ycharbi
rightcert=YC-NM_ycharbi_crt.pem
rightcert=YC-NM_ycharbi_crt.pem
auto=add
auto=route
</source>
</source>


Ligne 128 : Ligne 132 :
  vim /etc/ipsec.secrets
  vim /etc/ipsec.secrets
  @lesmorin @ycharbi : ECDSA /etc/ipsec.d/private/YC-NM_lesmorin_key.pem
  @lesmorin @ycharbi : ECDSA /etc/ipsec.d/private/YC-NM_lesmorin_key.pem
'''Configuration de l'interface réseau'''
'''Configuration de l'interface réseau'''
<source lang="bash">
<source lang="bash">
Ligne 135 : Ligne 140 :
         netmask 255.255.255.0
         netmask 255.255.255.0
         gateway 192.168.181.254
         gateway 192.168.181.254
         up   ip addr add 10.254.254.253 dev eth0
         up ip addr add 10.254.254.253 dev eth0
         up   ip route add 10.254.254.254/32 dev ens3 src 10.254.254.253 || true
         up ip route add 10.254.254.254/32 dev eth0 src 10.254.254.253 || true
         down ip route del 10.254.254.254/32 dev ens3 src 10.254.254.253 || true
         down ip route del 10.254.254.254/32 dev eth0 src 10.254.254.253 || true
         down ip addr del 10.254.254.253 dev eth0
         down ip addr del 10.254.254.253 dev eth0
</source>
</source>


Ligne 145 : Ligne 150 :


==Connexion==
==Connexion==
À faire sur l'un des deux serveurs.
À faire sur l'un des deux serveurs. Si vous avez utilisé l'option <source lang="ini" inline>auto=start</source>, la connexion s'est initialisée d'elle même au redémarrage du démon. Dans le cas d'une option à <source lang="ini" inline>auto=add</source>, la commande suivante permet d'initier la connexion.


'''Initier la connexion bilatérale'''
'''Initier la connexion bilatérale'''
Ligne 182 : Ligne 187 :
'''Sur ipsec1'''
'''Sur ipsec1'''
  ping 10.254.254.253
  ping 10.254.254.253
'''Sur ipsec2'''
'''Sur ipsec2'''
  ping 10.254.254.254
  ping 10.254.254.254
À ce stade, c'est terminé. La partie suivante n'est que bonus.
À ce stade, c'est terminé. La partie suivante n'est que bonus.
==Correction de problèmes==
'''Retenter la connexion lors d'un échec de résolution de nom DNS'''
Lors du démarrage d'une machine avec l'option <source lang="ini" inline>auto=start</source>, le service ''strongwan'' fait appel au démon ''charon'' (IKE) pour initier la connexion. Le problème est que cet imbécile le fait avant que la partie réseau ne soit pleinement opérationnelle. On se tape donc une jolie erreur de résolution DNS et comme ce couillon s’arrête à la première erreur, rien ne se passe. Il faut donc lui dire de réessayer (toute les 30 secondes dans notre cas).
vim /etc/strongswan.d/charon.conf
À la ligne 208 au moment ou j’écris ceci
retry_initiate_interval = 30
'''Relancer le service'''
systemctl restart strongswan.service
=Configuration d'un tunnel GRE=
=Configuration d'un tunnel GRE=
Petit bonus, nous allons utiliser  [[Open vSwitch]] pour monter un tunnel GRE entre nos deux serveurs, et ceux, dans le but d'y faire passer un lien trunk 802.1Q pour transporter nos VLAN.
Petit bonus, nous allons utiliser  [[Open vSwitch]] pour monter un tunnel GRE entre nos deux serveurs, et ceux, dans le but d'y faire passer un lien trunk 802.1Q pour transporter nos VLAN.
Ligne 192 : Ligne 209 :
==Sur les deux serveurs==
==Sur les deux serveurs==
  apt install openvswitch-switch
  apt install openvswitch-switch
==Sur ipsec1==
==Sur ipsec1==
  ovs-vsctl --may-exist add-br br0
  ovs-vsctl --may-exist add-br br0
  ovs-vsctl add-port br0 gre0 trunks=10,20,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009 -- set interface gre0 type=gre options:remote_ip=10.254.254.253
  ovs-vsctl add-port br0 gre0 trunks=10,20,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009 -- set interface gre0 type=gre options:remote_ip=10.254.254.253
==Sur ipsec2==
==Sur ipsec2==
  ovs-vsctl add-br br0
  ovs-vsctl add-br br0
  ovs-vsctl add-port br0 gre0 trunks=10,20,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009 -- set interface gre0 type=gre options:remote_ip=10.254.254.254
  ovs-vsctl add-port br0 gre0 trunks=10,20,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009 -- set interface gre0 type=gre options:remote_ip=10.254.254.254
==Sur les clients==
Dé lors, vos machines virtuelles et vos conteneurs appartenant à l'un des VLAN du trunk GRE pourrons communiqué sur le même réseau sans passerelle à leurs paires via le tunnel IPSec. Un seul bémol au tableau, il faut modifier le MTU des interfaces réseau de ces éléments pour qu'ils puissent communiquer (sinon seul le ''ping'' passe - c'est un peu limitant je dois dire).
'''Dans chaque MV ou conteneur'''
vim /etc/network/interfaces
<source lang="bash">
auto eth0
iface eth0 inet static
address 10.10.0.1
netmask 255.255.255.248
gateway 10.10.0.6
up ip link set $IFACE mtu 1368
</source>
''Bien que ce caractéristique soit censé être géré par le protocole PMTUD, je n'ai pas réussi à le faire fonctionner dans cette installation. On est donc obligé de ce faire chier de la sorte (bon courage avec l'IOT...). À améliorer donc...''
''Édit: Il semblerait que ce problème de MTU soit insoluble avec [[Open vSwitch]] (un bogue qui n'inquiète visiblement pas les développeurs du projet...), Nous avons donc réalisé une migration de notre réseau sous les VLAN natifs fournis par Linux via la fonctionnalité [[Vlan - linux|VLAN filtering]] offerte par les ponts réseaux via "iproute2". Le résultat est sans appel. Ça tourne nickel sans toucher aux MTU !''


=Sources=
=Sources=
* https://wiki.strongswan.org/projects/strongswan/wiki/ConnSection
* https://wiki.strongswan.org/projects/strongswan/wiki/ConnSection
* https://wiki.strongswan.org/projects/strongswan/wiki/ConnSection
* https://wiki.strongswan.org/projects/strongswan/wiki/VirtualIp
* https://wiki.strongswan.org/projects/strongswan/wiki/VirtualIp
* https://wiki.strongswan.org/projects/strongswan/wiki/IKEv2CipherSuites
* https://wiki.strongswan.org/projects/strongswan/wiki/IKEv2CipherSuites
* https://strongswan.org/testresults4.html
* https://strongswan.org/testresults4.html

Dernière version du 7 mai 2020 à 16:36


Strongswan est une implémentation libre du protocole IPSec sous Linux. Nous utilisons ce type de tunnel pour la réplication des bases de données entre nos deux Wiki: https://doc.ycharbi.fr et https://doc.lesmorin.fr.

Nous documenterons la mise en place de ce type de VPN et en bonus, la mise en place d'un tunnel GRE avec Open vSwitch pour y faire passer un lien trunk. Dans chacune des explications, nous partons du principe que deux serveurs derrière un NAT (le cas concret d'Internet avec IPv4) veulent se connecter ensemble (IKEv2 gère automatiquement le NAT).

Il est possible de s'authentifier via un mot de passe (PSK) ou via un certificat (PKI).

Connexion par PKI

Dans cette section, nous allons voir comment utiliser une paire de clés publique/privée pour la connexion au VPN.

Installation des paquets

À effectuer sur les deux serveurs:

apt install strongswan strongswan-pki

Sur le serveur 1

Configuration des noms

Pour la clarté du tuto, nous utiliserons les noms appliqués dans cette section.

Changement du nom d'hôte

vim /etc/hostname
ipsec1

Résolution des paires

vim /etc/hosts
192.168.180.96	ipsec1
192.168.181.18	ipsec2

Configuration IPSec

Création des clés

ipsec pki --gen --type ecdsa --outform pem --size 521 > /etc/ipsec.d/private/YC-NM_ycharbi_key.pem
ipsec pki --self -t ecdsa --in /etc/ipsec.d/private/YC-NM_ycharbi_key.pem --outform pem --lifetime 3650 --dn "CN=YC-NM_ycharbi_crt" > /etc/ipsec.d/certs/YC-NM_ycharbi_crt.pem

INFORMATION

Depuis Strongswan 5.5.2, il est possible d'utiliser des clés ed25519. Pour se faire, il faudra remplacer le type ecdsa par ed25519 dans les deux commandes précédentes ainsi que ECDSA par PKCS8 dans ipsec.secrets. Il sera également préférable d'utiliser la liste cryptographique l'implémentant comme ceci: aes256gcm128-sha512-curve25519! dans ipsec.conf.

Configuration de la connexion

vim /etc/ipsec.conf
conn %default
	ikelifetime=60m
	keylife=20m
	rekeymargin=3m
	keyingtries=%forever
	keyexchange=ikev2
	mobike=no
 
conn YC-NM
	ike=aes256gcm128-sha512-ecp521!
	esp=aes256gcm128-sha512-ecp521!
	left=ipsec1
	leftsubnet=10.254.254.254/32
	leftid=@ycharbi
	leftcert=YC-NM_ycharbi_crt.pem
	leftfirewall=yes
	right=ipsec2
	rightsubnet=10.254.254.253/32
	rightid=@lesmorin
	rightcert=YC-NM_lesmorin_crt.pem
	auto=route

Ajout d'une ACL pour la connexion

vim /etc/ipsec.secrets
@lesmorin @ycharbi : ECDSA /etc/ipsec.d/private/YC-NM_ycharbi_key.pem

Configuration de l'interface réseau

allow-hotplug eth0
iface eth0 inet static
        address 192.168.180.96
        netmask 255.255.255.0
        gateway 192.168.180.254
        up ip addr add 10.254.254.254 dev eth0
        up ip route add 10.254.254.253/32 dev eth0 src 10.254.254.254 || true
        down ip route del 10.254.254.253/32 dev eth0 src 10.254.254.254 || true
        down ip addr del 10.254.254.254 dev eth0

Donner le certificat à ipsec2

scp /etc/ipsec.d/certs/YC-NM_ycharbi_crt.pem root@ipsec2:/etc/ipsec.d/certs/

Sur le serveur 2

Configuration des noms

Changement du nom d'hôte

vim /etc/hostname
ipsec2

Résolution des paires

vim /etc/hosts
192.168.180.96	ipsec1
192.168.181.18	ipsec2

Configuration IPSec

Création des clés

ipsec pki --gen --type ecdsa --outform pem --size 521 > /etc/ipsec.d/private/YC-NM_lesmorin_key.pem
ipsec pki --self -t ecdsa --in /etc/ipsec.d/private/YC-NM_lesmorin_key.pem --outform pem --lifetime 3650 --dn "CN=YC-NM_lesmorin_crt" > /etc/ipsec.d/certs/YC-NM_lesmorin_crt.pem

Configuration de la connexion

vim /etc/ipsec.conf
conn %default
	ikelifetime=60m
	keylife=20m
	rekeymargin=3m
	keyingtries=%forever
	keyexchange=ikev2
	mobike=no
 
conn YC-NM
	ike=aes256gcm128-sha512-ecp521!
	esp=aes256gcm128-sha512-ecp521!
	left=ipsec2
	leftsubnet=10.254.254.253/32
	leftid=@lesmorin
	leftcert=YC-NM_lesmorin_crt.pem
	leftfirewall=yes
	right=ipsec1
	rightsubnet=10.254.254.254/32
	rightid=@ycharbi
	rightcert=YC-NM_ycharbi_crt.pem
	auto=route

Ajout d'une ACL pour la connexion

vim /etc/ipsec.secrets
@lesmorin @ycharbi : ECDSA /etc/ipsec.d/private/YC-NM_lesmorin_key.pem

Configuration de l'interface réseau

allow-hotplug eth0
iface eth0 inet static
        address 192.168.181.18
        netmask 255.255.255.0
        gateway 192.168.181.254
        up ip addr add 10.254.254.253 dev eth0
        up ip route add 10.254.254.254/32 dev eth0 src 10.254.254.253 || true
        down ip route del 10.254.254.254/32 dev eth0 src 10.254.254.253 || true
        down ip addr del 10.254.254.253 dev eth0

Donner le certificat à ipsec1

scp /etc/ipsec.d/certs/YC-NM_lesmorin_crt.pem  root@ipsec1:/etc/ipsec.d/certs/

Connexion

À faire sur l'un des deux serveurs. Si vous avez utilisé l'option auto=start, la connexion s'est initialisée d'elle même au redémarrage du démon. Dans le cas d'une option à auto=add, la commande suivante permet d'initier la connexion.

Initier la connexion bilatérale

ipsec up YC-NM
initiating IKE_SA YC-NM[1] to 192.168.180.96
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 192.168.181.18[500] to 192.168.180.96[500] (332 bytes)
received packet: from 192.168.180.96[500] to 192.168.181.18[500] (332 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) ]
authentication of 'CN=YC-NM_lesmorin_crt' (myself) with ECDSA_WITH_SHA512_DER successful
establishing CHILD_SA YC-NM
generating IKE_AUTH request 1 [ IDi N(INIT_CONTACT) IDr AUTH SA TSi TSr N(MULT_AUTH) N(EAP_ONLY) ]
sending packet: from 192.168.181.18[500] to 192.168.180.96[500] (401 bytes)
received packet: from 192.168.180.96[500] to 192.168.181.18[500] (350 bytes)
parsed IKE_AUTH response 1 [ IDr AUTH SA TSi TSr N(AUTH_LFT) ]
  using trusted certificate "CN=YC-NM_ycharbi_crt"
authentication of 'CN=YC-NM_ycharbi_crt' with ECDSA_WITH_SHA512_DER successful
IKE_SA YC-NM[1] established between 192.168.181.18[CN=YC-NM_lesmorin_crt]...192.168.180.96[CN=YC-NM_ycharbi_crt]
scheduling reauthentication in 3314s
maximum IKE_SA lifetime 3494s
CHILD_SA YC-NM{1} established with SPIs c3c1c23c_i cd8f8267_o and TS 10.254.254.253/32 === 10.254.254.254/32
connection 'YC-NM' established successfully

Afficher l'état du tunnel

ipsec status
Security Associations (1 up, 0 connecting):
       YC-NM[1]: ESTABLISHED 2 minutes ago, 192.168.181.18[CN=YC-NM_lesmorin_crt]...192.168.180.96[CN=YC-NM_ycharbi_crt]
       YC-NM{1}:  INSTALLED, TUNNEL, reqid 1, ESP SPIs: c3c1c23c_i cd8f8267_o
       YC-NM{1}:   10.254.254.253/32 === 10.254.254.254/32

Tests de fonctionnement

Sur ipsec1

ping 10.254.254.253

Sur ipsec2

ping 10.254.254.254

À ce stade, c'est terminé. La partie suivante n'est que bonus.

Correction de problèmes

Retenter la connexion lors d'un échec de résolution de nom DNS

Lors du démarrage d'une machine avec l'option auto=start, le service strongwan fait appel au démon charon (IKE) pour initier la connexion. Le problème est que cet imbécile le fait avant que la partie réseau ne soit pleinement opérationnelle. On se tape donc une jolie erreur de résolution DNS et comme ce couillon s’arrête à la première erreur, rien ne se passe. Il faut donc lui dire de réessayer (toute les 30 secondes dans notre cas).

vim /etc/strongswan.d/charon.conf

À la ligne 208 au moment ou j’écris ceci

retry_initiate_interval = 30

Relancer le service

systemctl restart strongswan.service

Configuration d'un tunnel GRE

Petit bonus, nous allons utiliser Open vSwitch pour monter un tunnel GRE entre nos deux serveurs, et ceux, dans le but d'y faire passer un lien trunk 802.1Q pour transporter nos VLAN.

Cette partie peut vous être utile si vous voulez utiliser nos documentations sur LXC et QEMU dans des VLAN.

Sur les deux serveurs

apt install openvswitch-switch

Sur ipsec1

ovs-vsctl --may-exist add-br br0
ovs-vsctl add-port br0 gre0 trunks=10,20,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009 -- set interface gre0 type=gre options:remote_ip=10.254.254.253

Sur ipsec2

ovs-vsctl add-br br0
ovs-vsctl add-port br0 gre0 trunks=10,20,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009 -- set interface gre0 type=gre options:remote_ip=10.254.254.254

Sur les clients

Dé lors, vos machines virtuelles et vos conteneurs appartenant à l'un des VLAN du trunk GRE pourrons communiqué sur le même réseau sans passerelle à leurs paires via le tunnel IPSec. Un seul bémol au tableau, il faut modifier le MTU des interfaces réseau de ces éléments pour qu'ils puissent communiquer (sinon seul le ping passe - c'est un peu limitant je dois dire).

Dans chaque MV ou conteneur

vim /etc/network/interfaces
auto eth0
iface eth0 inet static
	address 10.10.0.1
	netmask 255.255.255.248
	gateway 10.10.0.6
	up ip link set $IFACE mtu 1368

Bien que ce caractéristique soit censé être géré par le protocole PMTUD, je n'ai pas réussi à le faire fonctionner dans cette installation. On est donc obligé de ce faire chier de la sorte (bon courage avec l'IOT...). À améliorer donc...

Édit: Il semblerait que ce problème de MTU soit insoluble avec Open vSwitch (un bogue qui n'inquiète visiblement pas les développeurs du projet...), Nous avons donc réalisé une migration de notre réseau sous les VLAN natifs fournis par Linux via la fonctionnalité VLAN filtering offerte par les ponts réseaux via "iproute2". Le résultat est sans appel. Ça tourne nickel sans toucher aux MTU !

Sources