Site to Site VPN between Cisco FTD and Strongswan
NOTICE : THIS ARTICLE IS NOT FULLY TRANSLATED TO ENGLISH YET
Introduction
Dans cet article, je vais dĂ©tailler comment configurer un VPN entre un firewall Cisco FTD (Firepower Thread Defense) et un serveur linux faisant tourner Strongswan. Afin de profiter de BGP pour propager mes sous-rĂ©seaux, nous configurerons un VPN “route-based” qui utilise des interfaces virtuelle “tunnel”. Ces interfaces virtuelles seront nommĂ©es VTI dans la suite de cet article (et du suivant).
Voici le schéma du VPN que nous allons réaliser.
Note: Les subnets 192.168.1.0/24 et 10.15.0.0/16 sont en réalité divisés en plusieurs sous-réseaux (qui ne sont pas affichés pour ne pas surcharger ce schéma).
Pour un rapide rappel entre “route-based” et “policy-based” :
Policy-based
Seul les paquets rĂ©pondant aux conditions d’une ACL seront authorisĂ©s Ă entrer / sortir du VPN. Une route implicite est crĂ©e pour permettre au systĂšme d’exploitation d’envoyer les paquets dans le tunnel VPN, cette route est basĂ©e sur l’ACL.
Exemple sur un FTD
> show access-list | include 192.168.157.0
access-list CSM_IPSEC_ACL_5 line 1 extended permit ip host xxx.xxx.146.94 192.168.157.0 255.255.255.0
>
> show route static
[...]
V 192.168.157.0 255.255.255.0
connected by VPN (advertised), VPN_INTERNET
[...]
La destination de l’ACL est 192.168.157.0/24 et c’est Ă©galement le mĂȘme sous-rĂ©seaux/masque pour la route implicite.
J’aurai bien montrĂ© la route implicite sur un linux faisant tournĂ© strongswan, mais je n’ai pas trouvĂ© comment faire.
Route-based
Une interface virtuelle (ou VTI) nommĂ©e tunnel va ĂȘtre dĂ©finie de chaque cotĂ© du VPN. Pour envoyer un paquets dans le tunnel VPN, le systĂšme n’a juste qu’Ă dĂ©finir des routes vers cette interface virtuelle. Peut-importe la nature de la route, static ou dynamique.
Exemple sur FTD
> show route | include 192.168.51.156
B 192.168.51.156 255.255.255.254 [20/0] via 169.254.51.1, 00:05:40
>
Note: 169.254.51.1 est l’IP de la VTI
Exemple sur linux
[centos@labfabear ~]$ ip route | grep 10.15.111.1
10.15.111.12/30 via 169.254.51.2 dev tunnel1 proto 186 metric 20
10.15.111.16/30 via 169.254.51.2 dev tunnel1 proto 186 metric 20
Note: 169.254.51.2 est l’IP de la VTI
Configuration de Firepower
Pour créer le VPN, il faut naviguer dans le menu Devices > Site to Site > Add VPN > Firepower Thread Defense Device
La premiĂšre page de configuration du VPN s’affiche, il va s’agir ici :
- De choisir entre Policy-based et Route-based
- De choisir la version de IKE
- De renseigner les IPs “peer” sur le firewall FTD lui-mĂȘme et sur le endpoint
Pour chaque node/peer :
-
Choisir le “device” : – Extranet pour le peer distant (ici notre serveur linux) – Le nom du firewall FTD qui servira de node pour le VPN (dans mon cas FTD Firewall)
-
Choisir l’IP du node : – Pour le firewall extranet (Serveur Linux) il faudra donner l’IP joinable via internet (IP publique, dans mon cas 10.10.10.10) – Pour le firewal local (FTD), il faut simplement sĂ©lĂ©ctionner la VTI qu’on utilisera et l’IP peer sera associĂ©e automatiquement (dans mon cas 20.20.20.20 sera donc sĂ©lĂ©ctionnĂ©)
On passe ensuite Ă l’onglet IKE.
Dans cette partie, on va configurer la phase 1 du VPN :
- La suite crypto et la durée de vie avant renegotiation (Policy)
- La clé pré-partagée (pre-shared key)
Il est important que les paramĂštres crypto (Integrity, Encryption, PRF et DH) ainsi que la clĂ© prĂ©-partagĂ©e soient les mĂȘmes sur le FTD et dans la configuration Strongswan, sinon le tunnel ne pourra pas ĂȘtre montĂ©.
L’onglet suivant concerne IPSec (Phase 2)
MĂȘme chose, on va choisir une suite crypto qui doit ĂȘtre la mĂȘme des deux cotĂ©s du VPN (je choisi en gĂ©nĂ©ral AES256 et SHA256), ainsi que :
- le temps (en seconde) avant renegotiation du tunnel IPSec ou
- le nombre de kilo-octet pouvant traverser le tunnel avant de dĂ©clencher une renegotiation (j’ai laissĂ© ce champs vide, je ne veux pas de limite de taille)
Tunnel configuration
interface Tunnel2
nameif Tunnel2
ip address 169.254.51.2 255.255.255.252
tunnel source interface VPN_INTERNET
tunnel destination 10.10.10.10
tunnel mode ipsec ipv4
tunnel protection ipsec profile FMC_IPSEC_PROFILE_3
!
Configuration IKEv2
crypto ikev2 policy 1
encryption aes-256
integrity sha256
group 14
prf sha256
lifetime seconds 86400
crypto ikev2 enable VPN_INTERNET
Configuration IPSec
crypto ipsec ikev2 ipsec-proposal CSM_IP_2
protocol esp encryption aes-256 aes-192 aes
protocol esp integrity sha-512 sha-384 sha-256 sha-1
crypto ipsec profile FMC_IPSEC_PROFILE_3
set ikev2 ipsec-proposal CSM_IP_2
set security-association lifetime kilobytes unlimited
Note : Si vous ĂȘtes confus par rapport au fait que j’ai choisi plusieurs algorithmes pour “encryption et integrity” rendez-vous dans la FAQ en fin d’article
Divers (IP endpoint/peer/node & IKEv2 Pre-Shared key)
tunnel-group 10.10.10.10 type ipsec-l2l
tunnel-group 10.10.10.10 general-attributes
default-group-policy .DefaultS2SGroupPolicy
tunnel-group 10.10.10.10 ipsec-attributes
ikev2 remote-authentication pre-shared-key *****
ikev2 local-authentication pre-shared-key *****
Configuration sur linux
Strongswan
/etc/strongswan/ipsec.conf
config setup
uniqueids=yes
charondebug="all"
conn centos-to-ftd
type=tunnel
auto=start
keyexchange=ikev2
authby=secret
left=10.10.10.10
leftsubnet=0.0.0.0/0
right=20.20.20.20
rightsubnet=0.0.0.0/0
ike=aes256-sha256-modp2048!
esp=aes256-sha256!
aggressive=no
keyingtries=%forever
ikelifetime=28800s
lifetime=3600s
dpddelay=30s
dpdtimeout=120s
dpdaction=restart
mark=51 #tagging de taffic avec vti
Les champs importants
- left : l’IP publique de votre machine linux
- right : l’IP publique de votre FTD
- ike : La suite crypto de la phase 1 (voir FAQ)
- esp : La quite crypto de la phase 2
- ikelifetime : le temps avant renegotiation de la phase 1
- lifetime : le temps avant renegotiation de la phase 2 (IpSec)
- mark : ID pour associer la connexion VPN Ă la VTI
- leftsubnet et rightsubnet : traffic selector, normalement utilisĂ© pour un policy-based VPN. Attention : Ces valeurs doivent ĂȘtre identiques avec le traffic selector de l’autre endpoint (FTD). voir FAQ
/etc/strongswan/ipsec.secrets
10.10.10.10 20.20.20.20 : PSK "*******************************"
La clé pré-partagée qui sera utilisée pour un duo de endpoint.
/etc/strongswan/strongswan.d/charon.conf
[...]
install_routes = no
[...]
install_routes installera implicitement une route redirigeant les paquets matchant le “traffic selector” dans le VPN. C’est indispensable pour un “policy-based” VPN, mais pour notre cas (route-based VPN) c’est dĂ©conseillĂ©. (Ă voir ce qu’il se passe ???)
Il faut dĂ©commenter cette ligne et spĂ©cifier “no” dans le cas d’un route-based VPN.
Création tunnel VTI
[root@labfabear ~]# ip tunnel add tunnel1 local 10.10.10.10 remote 20.20.20.20 mode vti key 51
[root@labfabear ~]# ip addr add 169.254.51.1 remote 169.254.51.2 dev tunnel1
[root@labfabear ~]# ip link set tunnel1 up
On crĂ©e la VTI qui va ĂȘtre utilisĂ©e comme passerelle pour envoyer/recevoir des paquets vers/depuis le VPN. La valeur aprĂšs “key” doit matcher celle qui a Ă©tĂ© mise aprĂšs “mark” dans le fichier /etc/strongswan/ipsec.conf On spĂ©cifie ensuite l’IP de la VTI locale (169.254.51.1), ainsi que l’IP de la VTI du FTD (169.254.51.2). Pour finir on active l’interface de la VTI.
Tests
Linux
Assurez-vous que le VPN est Ă©tabli correctement :
[root@labfabear ~]$ strongswan status centos-to-ftd
Security Associations (1 up, 0 connecting):
centos-to-ftd[419]: ESTABLISHED 58 minutes ago, 10.10.10.10[10.10.10.10]...20.20.20.20[20.20.20.20]
centos-to-ftd{1989}: INSTALLED, TUNNEL, reqid 310, ESP SPIs: cc96ad4b_i 2be16903_o
centos-to-ftd{1989}: 0.0.0.0/0 === 0.0.0.0/0
Note: Ne faites pas confiance Ă cette commande Ă 100%, j’en repalerai plus bas dans la FAQ, mais il se peut que la commande indique que le tunnel est “ESTABLISHED” alors que ça n’est pas le cas.
Un simple ping de la VTI du FTD depuis notre machine linux devrait pouvoir confirmer le bon fonctionnement du VPN
[root@labfabear ~]$ ping 169.254.51.2
PING 169.254.51.2 (169.254.51.2) 56(84) bytes of data.
64 bytes from 169.254.51.2: icmp_seq=1 ttl=255 time=6.44 ms
64 bytes from 169.254.51.2: icmp_seq=2 ttl=255 time=6.58 ms
64 bytes from 169.254.51.2: icmp_seq=3 ttl=255 time=6.44 ms
64 bytes from 169.254.51.2: icmp_seq=4 ttl=255 time=6.48 ms
On peut Ă©galement afficher les statistiques de la VTI pour confirmer qu’il y a bien des donnĂ©es Ă©changĂ©es
[root@labfabear ~]$ ip -s tunnel show tunnel1
tunnel1: ip/ip remote 20.20.20.20 local 10.10.10.10 ttl inherit key 51
RX: Packets Bytes Errors CsumErrs OutOfSeq Mcasts
839372 574373326 296 0 0 0
TX: Packets Bytes Errors DeadLoop NoRoute NoBufs
601756 50634978 4178 0 4178 0
FTD
Coté FTD, un simple ping peut également confirmer le bon fonctionnement du VPN.
> ping 169.254.51.1
Please use 'CTRL+C' to cancel/abort...
Sending 5, 100-byte ICMP Echos to 169.254.51.1, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/6/10 ms
>
Pour des statistiques, la commande ‘show vpn-sessiondb l2l’ est utile. Attention : Le profile VPN ne sera affichĂ© que lorsque des donnĂ©es auront commencĂ© Ă transiter dans le tunnel VPN. C’est pour cette raison que faire un ping en amont peut-ĂȘtre utile pour “amorcer” la construction du tunnel VPN (dans une configuration de base le tunnel VPN ne sera pas en ligne tant qu’aucune donnĂ©e n’a tentĂ© de l’emprunter).
> show vpn-sessiondb l2l
Session Type: LAN-to-LAN
Connection : 10.10.10.10
Index : 4804 IP Addr : 10.10.10.10
Protocol : IKEv2 IPsec
Encryption : IKEv2: (1)AES256 IPsec: (1)AES256
Hashing : IKEv2: (1)SHA256 IPsec: (1)SHA1
Bytes Tx : 29310 Bytes Rx : 15163
Login Time : 11:51:42 CEST Wed Aug 17 2022
Duration : 1h:06m:16s
Tunnel Zone : 0
Conclusion
Nous avons donc construit un VPN (routed-based) fonctionnel, mais pour l’instant il n’est pas trĂšs utile qu’il n’existe aucune route pour envoyer des donnĂ©es Ă travers. A ce stade du dĂ©ploiement on pourrait simplement rajouter des routes statiques sur le FTD et la machine linux avec pour gateway leurs VTI respectives, mais je vous propose de propager les routes en utilisant BGP Ă la place.
Voir Partie 2 : Mise en place de BPG Ă travert un tunnel VPN FTD<->Linux
FAQ
Q : Est-il possible de mélanger route-based et policy based ?
Je me suis la question de mettre un traffic selector plus restrictif que 0.0.0.0/0 au niveau de strongswan. Pas dans l’idĂ©e que ça change la table de routage (puisque j’ai dĂ©sactivĂ© la fonctionnalitĂ© de Strongswan de rajouter des routes [install_routes = no], mais plutĂŽt pour filtrer le traffic. Pour faire un test, j’ai changĂ© l’encryption domain cotĂ© Strongswan :
/etc/strongswan/ipsec.conf
[...]
conn centos-to-ftd
[...]
left=10.10.10.10
leftsubnet=192.168.51.157/32,169.254.52.1/32 #encryption domain
right=20.20.20.20
rightsubnet=0.0.0.0/0
[...]
AprĂšs relancement du service strongswan, le resultat de la commande strongswan status centos-to-ftd laisse penser que tout va bien.
[root@labfabear strongswan]# strongswan status centos-to-ftd
Security Associations (1 up, 0 connecting):
centos-to-ftd[2]: ESTABLISHED 31 seconds ago, 10.10.10.10[10.10.10.10]...20.20.20.20[20.20.20.20]
centos-to-ftd{2}: INSTALLED, TUNNEL, reqid 1, ESP SPIs: cf989189_i fb6aa0e7_o
centos-to-ftd{2}: 169.254.52.1/32 192.168.51.157/32 === 0.0.0.0/0
Mais en réalité, le tunnel ne se monte pas et on peut voir dans /var/log/messages le message suivant :
Aug 20 12:22:31 labfabear charon: 09[CFG] selected proposal: IKE:AES_CBC_256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_2048 [0/1927]
Aug 20 12:22:31 labfabear charon: 09[IKE] authentication of '10.10.10.10' (myself) with pre-shared key
Aug 20 12:22:31 labfabear charon: 09[IKE] establishing CHILD_SA centos-to-ftd{1}
Aug 20 12:22:31 labfabear charon: 09[ENC] generating IKE_AUTH request 1 [ IDi N(INIT_CONTACT) IDr AUTH SA TSi TSr N(MOBIKE_SUP) N(ADD_4_ADDR) N(ADD_4_ADDR) N
(ADD_4_ADDR) N(EAP_ONLY) N(MSG_ID_SYN_SUP) ]
Aug 20 12:22:31 labfabear charon: 09[NET] sending packet: from 10.10.10.10[4500] to 20.20.20.20[4500] (320 bytes)
Aug 20 12:22:31 labfabear charon: 10[NET] received packet: from 20.20.20.20[4500] to 10.10.10.10[4500] (160 bytes)
Aug 20 12:22:31 labfabear charon: 10[ENC] parsed IKE_AUTH response 1 [ V IDr AUTH N(TS_UNACCEPT) ]
Aug 20 12:22:31 labfabear charon: 10[IKE] authentication of '20.20.20.20' with pre-shared key successful
Aug 20 12:22:31 labfabear charon: 10[IKE] IKE_SA centos-to-ftd[1] established between 10.10.10.10[10.10.10.10]...20.20.20.20[20.20.20.20]
Aug 20 12:22:31 labfabear charon: 10[IKE] scheduling reauthentication in 28087s
Aug 20 12:22:31 labfabear charon: 10[IKE] maximum IKE_SA lifetime 28627s
Aug 20 12:22:31 labfabear charon: 10[IKE] received TS_UNACCEPTABLE notify, no CHILD_SA built
Aug 20 12:22:31 labfabear charon: 10[IKE] failed to establish CHILD_SA, keeping IKE_SA
La problĂšme (TS_UNACCEPTABLE) vient du fait que pour que la phase1 du vpn fonctionne, il faut que l’encryption domain soit le mĂȘme des deux cotĂ©s. Mais sur le FTD, l’encryption domain ressemble à ça :
IKEv2 SAs:
Session-id:11917, Status:UP-ACTIVE, IKE count:1, CHILD count:1
Tunnel-id Local Remote Status Role
1311346589 20.20.20.20/4500 10.10.10.10/4500 READY RESPONDER
Encr: AES-CBC, keysize: 256, Hash: SHA256, DH Grp:14, Auth sign: PSK, Auth verify: PSK
Life/Active Time: 86400/2312 sec
Child sa: local selector 0.0.0.0/0 - 255.255.255.255/65535
remote selector 0.0.0.0/0 - 255.255.255.255/65535
ESP spi in/out: 0xc26e770e/0xcd7cb8a9
0.0.0.0/0 en left et right. Je n’ai pas trouvĂ© comment changer le traffic selector sur le FTD lorsque le VPN est reglĂ© en “Route-Based”.
Q : Pourquoi y a-t-il plusieurs algorithmes encryption/integrity dans la partie IPSec du VPN FTD
C’est une partie de la configuration que je n’ai jamais modifiĂ©, quand j’ai commencĂ© Ă configurer le VPN FTD je ne savais pas encore ce que pouvais gĂ©rer Strongswan comme algorithmes, j’en ai donc mis plusieurs. Mais au final, pas d’inquiĂštude, les deux endpoint vont sĂ©lĂ©ctionner l’algorithmes le plus sĂ©curisĂ© qu’ils ont en commun.
Pour FTD : Encryption (aes-256 aes-192 aes) / Integrity (sha-512 sha-384 sha-256 sha-1) Pour Strongswan : Encryption (aes256) Integrity (sha256)
Encryption | Integrity | |
---|---|---|
FTD | aes-256aes-192aes | sha-512sha-384sha-256sha-1 |
Strongswan | aes256 | sha256 |
Et c’est effectivement ce que va choisir strongswan :
[root@labfabear strongswan]# grep -i "selected proposal" /var/log/messages | tail -n 1
Aug 20 17:53:27 labfabear charon: 09[CFG] selected proposal: ESP:AES_CBC_256/HMAC_SHA2_256_128/NO_EXT_SEQ
[root@labfabear strongswan]#