Cisco France Blog

J'ai testé pour vous: FlexVPN en hub&spoke

6 min read



Tout a commencé quand je me suis planté en beauté chez un client sur une configuration EasyVPN… Je me suis dit qu’il était temps de passer à autre chose 🙂 Il faut dire que les configuration guides disponibles pour EasyVPN ne sont pas forcément les plus limpides… FlexVPN, reposant sur IKEv2, est suffisamment flexible pour à l’avenir répondre à tous les cas de VPN. L’idée ici est de simplement faire une configuration en étoile où les sites distants vont s’authentifier sur un site principal avec des clés partagées simples pour monter un tunnel IPsec: en gros cela permet de pré-provisionner les configurations et de simplifier le déploiement. J’ai réussi du premier coup c’est dire si c’est simple!

Description du lab

Matériel et IOS utilisés

  • Hub: 2951 en 15.2(2)T1 – c2951-universalk9-mz.SPA.152-2.T1.bin
  • Spoke 1: 2951 en 15.2(2)T1 – c2951-universalk9-mz.SPA.152-2.T1.bin
  • Spoke 2: 892 en 15.2(3)T – c890-universalk9-mz.152-3.T.bin
  • Configuration

    Hub (site central)

    Tout d’abord je définis les clés partagées qui vont être utilisées par IKEv2. Au niveau du hub je fais simple et ne définis qu’une seule clé pour le hub et une clé qui sera identique sur tous les spokes (0.0.0.0 0.0.0.0). IKEv2 me permet de mettre en place 2 clés différentes sur le hub et le spoke.

    crypto ikev2 keyring MesClefs
     peer AllSpokes
      description Keys pour tous les spokes
      address 0.0.0.0 0.0.0.0
      pre-shared-key local CleHub
      pre-shared-key remote CleSpoke
    

    Ensuite je définis mon profile IKEv2 qui va être appelé pour tous les sites distants et qui va appeler le jeu de clés précédemment défini. Notez qu’on peut définir un seul profile valide pour tous les spokes qui appellera un jeu de clé qui pourront elles varier selon les spokes. Un template d’interface va s’instancier à chaque fois que le profile est appelé. La définition de ce template est décrite plus bas.

    crypto ikev2 profile ProfileHub
     match identity remote address 0.0.0.0
     authentication local pre-share
     authentication remote pre-share
     keyring local MesClefs
     virtual-template 10
    

    Je clarifie ensuite quelle est la combinaison d’algorithmes utilisés pour IPsec (chiffrement + authentification).

    crypto ipsec transform-set my-transform-set esp-3des esp-sha-hmac
    

    Je définis maintenant mon profile de protection IPsec qui va s’appuyer sur la combinaison d’algorithmes et le profile IKEv2 précédemment définis. Ce profile sera appelé au niveau de chaque interface tunnel instanciée pour effectuer la protection. Ici j’ai eu un peu de mal a comprendre pourquoi il fallait déclarer le profile IKEv2 puisque dans la configuration de ce dernier on fait référence au virtual-template qui lui fait appelle le profile IPsec… Ca boucle un peu! En fait la réponse est simple: tout dépend si le routeur est initiateur ou respondeur. En mode initiateur on part du tunnel pour appeler le profile IPsec pour demander à IKEv2 de monter la SA. En mode responder c’est l’inverse: on part de la SA pour instancier le virtual-template qui fait référence au profile de protection. Donc dans l’absolu on n’a pas besoin des 2 partout. Après en pratique on le met sans trop réfléchir partout: ça marche et ça permet d’avoir des configurations homogènes!

    crypto ipsec profile ProfileIPsecHub
     set transform-set my-transform-set
     set ikev2-profile ProfileHub
    

    Configuration d’une loopback qui est utilisée pour uniquement pour envoyer/recevoir le trafic qui sera envoyé dans le tunnel. Mes routeurs sont directement interconnectés par l’interface Gi0/0.

    interface Loopback10
     description Test FlexVPN reachability
     ip address 10.153.2.1 255.255.255.255
    !
    interface GigabitEthernet0/0
     ip address 10.153.0.51 255.255.255.0
    

    Et enfin la création de notre interface virtual-template qui sera instanciée à chaque initiation de connexion d’un routeur distant (sous réserve que ça passe au niveau IKEv2). Pour chaque instance la destination du tunnel sera remplacée par l’adresse du routeur distant qui fait la requête IKEv2. On parle de dVTI (dynamic virtual tunnel interface).

    interface Virtual-Template10 type tunnel
     ip unnumbered GigabitEthernet0/0
     tunnel source GigabitEthernet0/0
     tunnel mode ipsec ipv4
     tunnel protection ipsec profile ProfileIPsecHub
    

    Spoke 1

    Ici c’est plus ou moins la même chose. Notons les différences suivantes:

  • On déclare le hub comme peer et on restreint les clés pour lui.
  • On définit par une ACL le trafic que l’on va vouloir envoyer dans le tunnel. C’est ce qui permettra de demander au hub de créer la route pour le retour. Dans mon test c’est le trafic entre la loopback locale 10.153.2.2 et toutes les loopbacks des autres sites (10.153.2.0/24) que je veux chiffrer. Ca intègre la loopback du hub 10.153.2.1 et celle d’un autre spoke que je vais rajouter par la suite.
  • Pas de VTI, on applique directement la crypto map sur l’interface physique. Uniquement le trafic concerné par l’ACL précédente partira dans le tunnel. Il faut s’assurer que le trafic vers la loopback en question est déjà routé vers l’interface sur laquelle la crypto map est appliquée. Ici c’est ma route par défaut donc pas de problèmes.
  • crypto ikev2 keyring MesClefs
     peer Hub
      address 10.153.0.51
      pre-shared-key local CleSpoke
      pre-shared-key remote CleHub
    !
    crypto ikev2 profile ProfileSpoke
     match identity remote address 10.153.0.51 255.255.255.255
     authentication local pre-share
     authentication remote pre-share
     keyring local MesClefs
    !
    crypto ipsec transform-set my-transform-set esp-3des esp-sha-hmac
    !
    crypto map my-crypto-map 1 ipsec-isakmp
     set peer 10.153.0.51
     set transform-set my-transform-set
     set ikev2-profile ProfileSpoke
     match address MaListe
    !
    interface Loopback10
     ip address 10.153.2.2 255.255.255.255
    !
    interface GigabitEthernet0/0
     ip address 10.153.0.52 255.255.255.0
     crypto map my-crypto-map
    !
    ip access-list extended MaListe
     permit ip host 10.153.2.2 10.153.2.0 0.0.0.255
    

    Tests

    Sur le spoke je lance un ping vers le site distant, et la mécanique se met immédiatement en place:

    C2951-2#ping 10.153.2.1 source 10.153.2.2
    Type escape sequence to abort.
    Sending 5, 100-byte ICMP Echos to 10.153.2.1, timeout is 2 seconds:
    Packet sent with a source address of 10.153.2.2
    
    Jul 12 21:47:04.179: IPSEC(sa_request): ,
    (key eng. msg.) OUTBOUND local= 10.153.0.52:500, remote= 10.153.0.51:500,
    local_proxy= 10.153.2.2/255.255.255.255/256/0,
    remote_proxy= 10.153.2.0/255.255.255.0/256/0,
    protocol= ESP, transform= esp-3des esp-sha-hmac (Tunnel),
    lifedur= 3600s and 4608000kb,
    spi= 0x0(0), conn_id= 0, keysize= 0, flags= 0x0
    Jul 12 21:47:04.179: IKEv2:% Getting preshared key from profile keyring MesClefs
    Jul 12 21:47:04.179: IKEv2:% Matched peer block 'Hub'
    Jul 12 21:47:04.179: IKEv2:Searching Policy with fvrf 0, local address 10.153.0.52
    ...
    

    Sur le hub ça réagit également et notre virtual-template s’instancie. Comme les debugs sont un peu verbeux j’ai supprimé pas mal de lignes. J’espère que les puristes me pardonneront!

    Jul 12 21:41:30.274: IKEv2:Received Packet [From 10.153.0.52:500/To 10.153.0.51:500/VRF i0:f0]
    Initiator SPI : D4A788700922F259 - Responder SPI : 0000000000000000 Message id: 0
    IKEv2 IKE_SA_INIT Exchange REQUEST
    Jul 12 21:41:30.282: IKEv2:(SA ID = 1):Completed SA init exchange
    Jul 12 21:41:30.290: IKEv2:(SA ID = 1):Received Packet [From 10.153.0.52:500/To 10.153.0.51:500/VRF i0:f0]
    Jul 12 21:41:30.290: IKEv2:(SA ID = 1):Checking NAT discovery
    Jul 12 21:41:30.290: IKEv2:(SA ID = 1):NAT not found
    Jul 12 21:41:30.290: IKEv2:(SA ID = 1):Searching policy based on peer's identity '10.153.0.52' of type 'IPv4 address'
    Jul 12 21:41:30.290: IKEv2:found matching IKEv2 profile 'ProfileHub'
    Jul 12 21:41:30.290: IKEv2:% Getting preshared key from profile keyring MesClefs
    Jul 12 21:41:30.290: IKEv2:% Matched peer block 'AllSpokes'
    Jul 12 21:41:30.290: IKEv2:Searching Policy with fvrf 0, local address 10.153.0.51
    Jul 12 21:41:30.290: IKEv2:Using the Default Policy for Proposal
    Jul 12 21:41:30.290: IKEv2:Found Policy 'default'
    Jul 12 21:41:30.290: IKEv2:(SA ID = 1):Verify peer's policy
    src addr : 10.153.2.1
    dst addr : 10.153.2.2
    Jul 12 21:41:30.318: IPSEC(rte_mgr): VPN Route Added 10.153.2.2 255.255.255.255 via Virtual-Access2 in IP DEFAULT TABLE with tag 0 distance 1
    Jul 12 21:41:30.326: %LINEPROTO-5-UPDOWN: Line protocol on Interface Virtual-Access2, changed state to up
    

    On peut jeter un coup d’oeil à la session créée:

    C2951-1#sh crypto session
    Crypto session current status
    
    Interface: Virtual-Access2
    Session status: UP-ACTIVE
    Peer: 10.153.0.52 port 500
      IKEv2 SA: local 10.153.0.51/500 remote 10.153.0.52/500 Active
      IPSEC FLOW: permit ip 10.153.2.0/255.255.255.0 host 10.153.2.2
            Active SAs: 2, origin: crypto map
    

    On voit que la route est créée: elle est statique et directement connectée. Un peu bizarre mais elle est là c’est le principal.

    C2951-1#sh ip route 10.153.2.2
    Routing entry for 10.153.2.2/32
      Known via "static", distance 1, metric 0 (connected)
      Routing Descriptor Blocks:
      * directly connected, via Virtual-Access2
          Route metric is 0, traffic share count is 1

    On peut observer que notre Virtuel-Template 10 s’est bien instancié en Virtual-Access 2:

    C2951-1#sh run int virtual-access 2
    interface Virtual-Access2
     tunnel source GigabitEthernet0/0
     tunnel mode ipsec ipv4
     tunnel destination 10.153.0.52
     tunnel protection ipsec profile ProfileIPsecHub
    

    On vérifie que les paquets passent bien par le tunnel, je regarde le nombre de paquets reçus dans le tunnel, puis je ping le hub depuis le spoke et je vois que le nombre de paquets s’incrémente:

    C2951-1#sh int virtual-access 2 | i packets out|packets in
         39 packets input, 3900 bytes, 0 no buffer
         49 packets output, 4744 bytes, 0 underruns
    
    C2951-2#ping 10.153.2.1 source 10.153.2.2
    Type escape sequence to abort.
    Sending 5, 100-byte ICMP Echos to 10.153.2.1, timeout is 2 seconds:
    Packet sent with a source address of 10.153.2.2
    !!!!!
    Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/4 ms
    
    C2951-1#sh int virtual-access 2 | i packets out|packets in
         44 packets input, 4400 bytes, 0 no buffer
         54 packets output, 5224 bytes, 0 underruns
    

    Ajout d’un deuxième site distant

    Je rajoute un autre site distant en dupliquant exactement la configuration du premier site, à l’exception bien sur de l’adresse de loopback (10.153.2.3/32), de l’adresse de l’interface physique et de l’ACL. Notons que sur ce dernier point j’aurais pu simplifier l’ACL pour chiffrer tout le trafic entre les loopbacks en 10.153.2.0/24 sans changer à chaque fois l’IP source.

    Après le premier trafic matché au niveau du spoke (suite à l’envoi d’un ping comme précédemment), l’interface s’instancie sur le hub:

    C2951-1#sh crypto session
    Crypto session current status
    
    Interface: Virtual-Access3
    Session status: UP-ACTIVE
    Peer: 10.153.0.53 port 500
      IKEv2 SA: local 10.153.0.51/500 remote 10.153.0.53/500 Active
      IPSEC FLOW: permit ip 10.153.2.0/255.255.255.0 host 10.153.2.3
            Active SAs: 2, origin: crypto map
    
    Interface: Virtual-Access2
    Session status: UP-ACTIVE
    Peer: 10.153.0.52 port 500
      IKEv2 SA: local 10.153.0.51/500 remote 10.153.0.52/500 Active
      IPSEC FLOW: permit ip 10.153.2.0/255.255.255.0 host 10.153.2.2
            Active SAs: 2, origin: crypto map
    

    On peut aisément réplique à l’infini. Amusez-vous!

    Références

    Configuration guide FlexVPN 15.2T

    Authors

    Jerome Durand

    Technical Solutions Architect

    Laisser un commentaire


    1 commentaires

    1. sympa merci pour les infos