« IPsec sous debian avec strongswan » : différence entre les versions
Aucun résumé des modifications |
Aucun résumé des modifications |
||
(57 versions intermédiaires par le même utilisateur non affichées) | |||
Ligne 1 : | Ligne 1 : | ||
[[Category:serveur]] | |||
[[Category:debian]] | |||
[[Category:networking]] | |||
[[Category:VPN]] | |||
[[Category:IPsec]] | |||
<pre> | <pre> | ||
apt install strongswan strongswan-swanctl | |||
</pre> | </pre> | ||
Note : sous Openvz, vous aurez aussi besoin du paquet <code>libcharon-extra-plugins</code> qui fournit l'implémentation <code>kernel-libipsec</code> (au travers d'une interface TUN au lieu de VTI) | |||
=Tunnel VTI, authentifié par clés RSA, compatible avec pfsense= | |||
Basé sur https://wiki.strongswan.org/projects/strongswan/wiki/RouteBasedVPN <br><br> | |||
Dans <code>/etc/strongswan.d/charon.conf</code>, ajoutez l'option suivante : | |||
<pre>install_routes = no</pre> | |||
==Définition des clés RSA== | |||
Placer la CA dans <code>/etc/ipsec.d/cacerts</code> puis : | Placer la CA dans <code>/etc/ipsec.d/cacerts</code> puis : | ||
<pre> | <pre> | ||
Ligne 12 : | Ligne 27 : | ||
Placer la clé privée dans <code>/etc/ipsec.d/private/</code> | Placer la clé privée dans <code>/etc/ipsec.d/private/</code> | ||
Il faut définir la clé privé dans <code>/etc/ipsec.secrets</code> sous le format <code> | Il faut définir la clé privé dans <code>/etc/ipsec.secrets</code> sous le format <code>ID : TYPE KEY</code>. L'ID peut être vide, contenir une ip, un FQDN, user@FQSN, %any ou any6. TYPE est PSK ou RSA. KEY peut être soit une clé, soit un chemin vers une clé. | ||
<pre> : RSA /etc/ipsec.d/private/mykey.key</pre> | <pre>: RSA /etc/ipsec.d/private/mykey.key</pre> | ||
==ipsec.conf== | |||
De manière générale : | |||
* left* correspond à la machine locale | |||
* right* correspond à la machine distante | |||
<br> | |||
Les champs suivant sont à modifier : | |||
* left = l'ip de la machine locale (peut être une ip rfc1918) | |||
* right = l'ip de la machine distante (obligatoirement une ip accessible sur le réseau, donc pas d'ip rfc1918) | |||
* leftid une manière d'identifier la machine locale (IP, FQDN, etc). En cas d'authentification RSA, cet identifiant devra exister soit au champ CN soit au champ SubjectAltName du certificat local. | |||
* rightid une manière d'identifier la machine distante (IP, FQDN, etc). En cas d'authentification RSA, cet identifiant devra exister soit au champ CN soit au champ SubjectAltName du certificat distant. | |||
* leftcert contient le chemin vers le certificat ssl local. La clé privé est définie dans /etc/ipsec.secret | |||
* rightca contient une manière d'identifier la CA ayant généré le certificat distant. | |||
* leftsubnet est défini à l'ip locale servant de transport VTI. Vous avez besoin d'un minimum de deux ip pour définir un transport VTI, le choix de /30 est donc à privilégier. | |||
* rightsubnet est défini à l'ip distante servant de transport VTI. | |||
<pre> | |||
conn ipsec1 | |||
reqid = 1 | |||
fragmentation = yes | |||
keyexchange = ikev2 | |||
reauth = yes | |||
forceencaps = no | |||
mobike = no | |||
rekey = yes | |||
installpolicy = yes | |||
auto = start | |||
dpdaction = restart | |||
dpddelay = 10s | |||
dpdtimeout = 60s | |||
left = 211.124.34.153 | |||
right = 92.119.29.26 | |||
leftid = fqdn:nodeA.domain.tld | |||
rightid = fqdn:nodeB.domain.tld | |||
ikelifetime = 28800s | |||
lifetime = 3600s | |||
ike = aes128gcm128-sha512-modp4096! | |||
esp = aes128gcm128-sha256-modp2048! | |||
leftauth = pubkey | |||
rightauth = pubkey | |||
leftcert="/etc/ipsec.d/certs/mycert.crt" | |||
leftsendcert=always | |||
rightca="/CN=My Ca/ST=My Location/L=My City/O=My Company/OU=My Company Unit/" | |||
leftsubnet = 10.66.10.2/30 | |||
rightsubnet = 10.66.10.1 | |||
mark = 42 | |||
</pre> | |||
Notez l'option <code>mark = 42</code> qui devra être équivalente sur la définition du tunnel VTI au niveau de linux, sinon les paquets le traverserons pas ipsec. | |||
==Lancement== | |||
<pre>ipsec start</pre> | |||
<pre> | |||
ipsec status | |||
ipsec statusall | |||
</pre> | |||
Vous pouvez observer l'état des politiques de sécurité installés : | |||
<pre> | |||
ip xfrm state | |||
ip xfrm policy | |||
</pre> | |||
==création de l'interface== | |||
Afin de simplifier les règles, définissez les variables suivantes dans votre shell : | |||
<pre> | |||
LOCAL_IP=211.124.34.153 | |||
REMOTE_IP=92.119.29.26 | |||
LOCAL_TUNNEL=10.66.10.2 | |||
REMOTE_TUNNEL=10.66.10.1 | |||
</pre> | |||
Création du tunnel VTI linux : | |||
<pre> | |||
ip tunnel add ipsec0 local $LOCAL_IP remote $REMOTE_IP mode vti okey 42 ikey 42 | |||
ip link set ipsec0 up | |||
ip addr add ${LOCAL_TUNNEL}/30 remote ${REMOTE_TUNNEL}/30 dev ipsec0 | |||
sysctl -wq net.ipv4.conf.ipsec0.disable_policy=1 #recommandé | |||
</pre> | |||
<code>okey</code> et <code>ikey</code> (qui peuvent être substitué par un seul et unique <code>key</code>) doivent être équivalent à la <code>mark</code> défini dans ipsec.conf | |||
<br><br> | |||
NB : si vous montez un tunnel avec des IPv6, il faudra utiliser : <code>ip -6 tunnel add ipsec0 local $LOCAL_IP remote $REMOTE_IP mode vti6 okey 42 ikey 42</code> | |||
A ce stade, seul le tunnel sera joignable (10.66.10.1 et 10.66.10.2) car ipsec a installé une policy restrictive (<code>ip xfrm policy</code>).<br> | |||
Si d'autres ranges doivent être joignable de part et d'autres du VPN (ce qui est probable sinon vous n'utiliseriez pas VTI), vous avez deux solutions : désactiver l'installation automatique des policy et installer votre policy manuellement, ou modifier la configuration d'ipsec. | |||
===Solution 1 : installation manuelle des policy=== | |||
* Passez <code>installpolicy</code> à <code>no</code> dans <code>/etc/ipsec.conf</code> | |||
* Installez votre propre policy ouverte : | |||
<pre> | |||
ip xfrm policy add src 0.0.0.0/0 dst 0.0.0.0/0 dir fwd priority 368255 ptype main mark 0x2a tmpl src $REMOTE_IP dst $LOCAL_IP proto esp reqid 1 mode tunnel | |||
ip xfrm policy add src 0.0.0.0/0 dst 0.0.0.0/0 dir in priority 368255 ptype main mark 0x2a tmpl src $REMOTE_IP dst $LOCAL_IP proto esp reqid 1 mode tunnel | |||
ip xfrm policy add src 0.0.0.0/0 dst 0.0.0.0/0 dir out priority 368255 ptype main mark 0x2a tmpl src $LOCAL_IP dst $REMOTE_IP proto esp reqid 1 mode tunnel | |||
</pre> | |||
===Solution 2 : modification de la configuration IPsec=== | |||
Note : Cette solution est compatible avec pfsense depuis la version 2.4.4-p3 | |||
Dans ipsec.conf : | |||
* maintenez <code>installpolicy = yes</code> | |||
* Modifiez leftsubnet et rightsubnet en y ajoutant <code>0.0.0.0/0</code> : | |||
<pre> | |||
leftsubnet = 10.66.10.2/30,0.0.0.0/0 | |||
rightsubnet = 10.66.10.1,0.0.0.0/0 | |||
</pre> | |||
Note : c'est de cette manière que sont définis left|rightsubnet dans la configuration ipsec de pfsense. | |||
===Note=== | |||
Dans les faits, la documentation recommande de définir <code>left|rightsubnet=0.0.0.0/0</code> (et uniquement cela). Cette configuration est tout à fait valable du moment que vous montez un tunnel dans lequel vous maîtrisez totalement la configuration des deux démons ipsec. Si l'un des démons est, par exemple, géré par pfsense, cette configuration risque de ne pas fonctionner correctement. | |||
==Routage== | |||
Avec cette configuration, il vous suffira de router votre range, par exemple 192.168.1.0/24, vers l'ip distante du tunnel. | |||
<pre>ip route add 192.168.1.0/24 via $REMOTE_TUNNEL dev ipsec0</pre> | |||
Cela fait passer les paquets par le tunnel VTI, qui applique la mark (42 ici), et la marqué détectée permet au paquet de passer par ipsec. | |||
N'oubliez pas d'activer le forwarding ip si nécessaire (<code>/proc/sys/net/ipv4/ip_forward</code>) | |||
==Automatisation== | |||
Vous pouvez crée une copie de <code>/usr/lib/ipsec/_updown</code>.<br> | |||
Les sections du fichier qui nous intéressent ici sont <code>up-client:</code> et <code>down-client:</code> | |||
Pour invoquer automatiquement le fichier, il faut ajouter cette directive à votre <code>conn</code> dans <code>/etc/ipsec.conf</code> : | |||
<pre>leftupdown = /path/to/ipsec.updown</pre> | |||
Le fichier <code>/path/to/ipsec.updown</code> doit être exécutable. | |||
==Sécurisation iptables== | |||
Pour n'autoriser que le serveur distant à contacter le démon ipsec, vous aurez besoin de l'une (ou des deux) lignes suivantes dans votre firwall iptables : | |||
<pre> | |||
iptables -t filter -A INPUT -i ens192 -p udp -m multiport --dports 500,4500 -s $REMOTE_IP -j ACCEPT | |||
iptables -t filter -A INPUT -i ens192 -p esp -s $REMOTE_IP -j ACCEPT | |||
</pre> | |||
==Logs== | |||
Afin de réduire un peu la taille des logs, modifiez cela dans le fichier <code>/etc/strongswan.d/charon-logging.conf</code> : | |||
<pre> | |||
syslog { | |||
daemon { | |||
default = 1 | |||
net = 0 | |||
enc = 0 | |||
} | |||
auth { | |||
default = 1 | |||
net = 0 | |||
enc = 0 | |||
} | |||
} | |||
</pre> | |||
=Plus d'informations= | |||
https://wiki.strongswan.org/projects/strongswan/wiki/SecurityRecommendations |
Dernière version du 21 décembre 2022 à 23:20
apt install strongswan strongswan-swanctl
Note : sous Openvz, vous aurez aussi besoin du paquet libcharon-extra-plugins
qui fournit l'implémentation kernel-libipsec
(au travers d'une interface TUN au lieu de VTI)
Tunnel VTI, authentifié par clés RSA, compatible avec pfsense
Basé sur https://wiki.strongswan.org/projects/strongswan/wiki/RouteBasedVPN
Dans /etc/strongswan.d/charon.conf
, ajoutez l'option suivante :
install_routes = no
Définition des clés RSA
Placer la CA dans /etc/ipsec.d/cacerts
puis :
cd /etc/ipsec.d/cacerts/ ln -s myca.pem `openssl x509 -hash -noout -in myca.pem`.0
Placer le certificat dans /etc/ipsec.d/certs/
Placer la clé privée dans /etc/ipsec.d/private/
Il faut définir la clé privé dans /etc/ipsec.secrets
sous le format ID : TYPE KEY
. L'ID peut être vide, contenir une ip, un FQDN, user@FQSN, %any ou any6. TYPE est PSK ou RSA. KEY peut être soit une clé, soit un chemin vers une clé.
: RSA /etc/ipsec.d/private/mykey.key
ipsec.conf
De manière générale :
- left* correspond à la machine locale
- right* correspond à la machine distante
Les champs suivant sont à modifier :
- left = l'ip de la machine locale (peut être une ip rfc1918)
- right = l'ip de la machine distante (obligatoirement une ip accessible sur le réseau, donc pas d'ip rfc1918)
- leftid une manière d'identifier la machine locale (IP, FQDN, etc). En cas d'authentification RSA, cet identifiant devra exister soit au champ CN soit au champ SubjectAltName du certificat local.
- rightid une manière d'identifier la machine distante (IP, FQDN, etc). En cas d'authentification RSA, cet identifiant devra exister soit au champ CN soit au champ SubjectAltName du certificat distant.
- leftcert contient le chemin vers le certificat ssl local. La clé privé est définie dans /etc/ipsec.secret
- rightca contient une manière d'identifier la CA ayant généré le certificat distant.
- leftsubnet est défini à l'ip locale servant de transport VTI. Vous avez besoin d'un minimum de deux ip pour définir un transport VTI, le choix de /30 est donc à privilégier.
- rightsubnet est défini à l'ip distante servant de transport VTI.
conn ipsec1 reqid = 1 fragmentation = yes keyexchange = ikev2 reauth = yes forceencaps = no mobike = no rekey = yes installpolicy = yes auto = start dpdaction = restart dpddelay = 10s dpdtimeout = 60s left = 211.124.34.153 right = 92.119.29.26 leftid = fqdn:nodeA.domain.tld rightid = fqdn:nodeB.domain.tld ikelifetime = 28800s lifetime = 3600s ike = aes128gcm128-sha512-modp4096! esp = aes128gcm128-sha256-modp2048! leftauth = pubkey rightauth = pubkey leftcert="/etc/ipsec.d/certs/mycert.crt" leftsendcert=always rightca="/CN=My Ca/ST=My Location/L=My City/O=My Company/OU=My Company Unit/" leftsubnet = 10.66.10.2/30 rightsubnet = 10.66.10.1 mark = 42
Notez l'option mark = 42
qui devra être équivalente sur la définition du tunnel VTI au niveau de linux, sinon les paquets le traverserons pas ipsec.
Lancement
ipsec start
ipsec status ipsec statusall
Vous pouvez observer l'état des politiques de sécurité installés :
ip xfrm state ip xfrm policy
création de l'interface
Afin de simplifier les règles, définissez les variables suivantes dans votre shell :
LOCAL_IP=211.124.34.153 REMOTE_IP=92.119.29.26 LOCAL_TUNNEL=10.66.10.2 REMOTE_TUNNEL=10.66.10.1
Création du tunnel VTI linux :
ip tunnel add ipsec0 local $LOCAL_IP remote $REMOTE_IP mode vti okey 42 ikey 42 ip link set ipsec0 up ip addr add ${LOCAL_TUNNEL}/30 remote ${REMOTE_TUNNEL}/30 dev ipsec0 sysctl -wq net.ipv4.conf.ipsec0.disable_policy=1 #recommandé
okey
et ikey
(qui peuvent être substitué par un seul et unique key
) doivent être équivalent à la mark
défini dans ipsec.conf
NB : si vous montez un tunnel avec des IPv6, il faudra utiliser : ip -6 tunnel add ipsec0 local $LOCAL_IP remote $REMOTE_IP mode vti6 okey 42 ikey 42
A ce stade, seul le tunnel sera joignable (10.66.10.1 et 10.66.10.2) car ipsec a installé une policy restrictive (ip xfrm policy
).
Si d'autres ranges doivent être joignable de part et d'autres du VPN (ce qui est probable sinon vous n'utiliseriez pas VTI), vous avez deux solutions : désactiver l'installation automatique des policy et installer votre policy manuellement, ou modifier la configuration d'ipsec.
Solution 1 : installation manuelle des policy
- Passez
installpolicy
àno
dans/etc/ipsec.conf
- Installez votre propre policy ouverte :
ip xfrm policy add src 0.0.0.0/0 dst 0.0.0.0/0 dir fwd priority 368255 ptype main mark 0x2a tmpl src $REMOTE_IP dst $LOCAL_IP proto esp reqid 1 mode tunnel ip xfrm policy add src 0.0.0.0/0 dst 0.0.0.0/0 dir in priority 368255 ptype main mark 0x2a tmpl src $REMOTE_IP dst $LOCAL_IP proto esp reqid 1 mode tunnel ip xfrm policy add src 0.0.0.0/0 dst 0.0.0.0/0 dir out priority 368255 ptype main mark 0x2a tmpl src $LOCAL_IP dst $REMOTE_IP proto esp reqid 1 mode tunnel
Solution 2 : modification de la configuration IPsec
Note : Cette solution est compatible avec pfsense depuis la version 2.4.4-p3
Dans ipsec.conf :
- maintenez
installpolicy = yes
- Modifiez leftsubnet et rightsubnet en y ajoutant
0.0.0.0/0
:
leftsubnet = 10.66.10.2/30,0.0.0.0/0 rightsubnet = 10.66.10.1,0.0.0.0/0
Note : c'est de cette manière que sont définis left|rightsubnet dans la configuration ipsec de pfsense.
Note
Dans les faits, la documentation recommande de définir left|rightsubnet=0.0.0.0/0
(et uniquement cela). Cette configuration est tout à fait valable du moment que vous montez un tunnel dans lequel vous maîtrisez totalement la configuration des deux démons ipsec. Si l'un des démons est, par exemple, géré par pfsense, cette configuration risque de ne pas fonctionner correctement.
Routage
Avec cette configuration, il vous suffira de router votre range, par exemple 192.168.1.0/24, vers l'ip distante du tunnel.
ip route add 192.168.1.0/24 via $REMOTE_TUNNEL dev ipsec0
Cela fait passer les paquets par le tunnel VTI, qui applique la mark (42 ici), et la marqué détectée permet au paquet de passer par ipsec.
N'oubliez pas d'activer le forwarding ip si nécessaire (/proc/sys/net/ipv4/ip_forward
)
Automatisation
Vous pouvez crée une copie de /usr/lib/ipsec/_updown
.
Les sections du fichier qui nous intéressent ici sont up-client:
et down-client:
Pour invoquer automatiquement le fichier, il faut ajouter cette directive à votre conn
dans /etc/ipsec.conf
:
leftupdown = /path/to/ipsec.updown
Le fichier /path/to/ipsec.updown
doit être exécutable.
Sécurisation iptables
Pour n'autoriser que le serveur distant à contacter le démon ipsec, vous aurez besoin de l'une (ou des deux) lignes suivantes dans votre firwall iptables :
iptables -t filter -A INPUT -i ens192 -p udp -m multiport --dports 500,4500 -s $REMOTE_IP -j ACCEPT iptables -t filter -A INPUT -i ens192 -p esp -s $REMOTE_IP -j ACCEPT
Logs
Afin de réduire un peu la taille des logs, modifiez cela dans le fichier /etc/strongswan.d/charon-logging.conf
:
syslog { daemon { default = 1 net = 0 enc = 0 } auth { default = 1 net = 0 enc = 0 } }
Plus d'informations
https://wiki.strongswan.org/projects/strongswan/wiki/SecurityRecommendations