J’ai testé pour vous: IPv6 First Hop Security

Depuis le temps que j’en parlais il fallait que je m’exécute!

Objectif du lab

L’objectif est de montrer l’étendue des fonctions IPv6 First Hop Security maintenant disponible sur nos switchs d’accès 2960-S et 3k. Je ne vais pas à nouveau m’étendre sur le côté indispensable de ces fonctions qu’IPv6 soit déployé ou non! Vous trouverez de nombreux détails ici, et encore ici.

 

Description du lab

J’utilise un design classique recommandé dans les CVD (Cisco Validated Designs) à savoir un stack de 3750-X en pur L2 connecté sur un coeur L3 de cat6500 en sup2T via un Etherchannel. Le cat6k jouera le rôle de routeur et serveur officiel et mon 3k devra protéger le lien local d’attaques IPv6 sur l’accès. Vous m’excuserez d’avoir mélangé les topologies physiques et logiques sur le schéma suivant mais je pense que ça reste clair…

Matériel et IOS utilisés

  • Un stack de 3750-X en 15.0(1)SE2 – c3750e-universalk9-tar.150-1.SE2.bin
  • Un VSS de catalyst 6500-E avec sup2T en 15.0(1)SY1 – s2t54-adventerprisek9-mz.SPA.150-1.SY1.bin

Pour les postes de travail, les petits malins que vous êtes auront peut-être reconnu  les MAC CISCO… Je me suis payé le luxe d’utiliser 2 ISR G2 (des 2951) pour jouer le rôle de hosts. Premièrement parce que c’est plus simple pour moi de trouver un routeur qu’un PC 🙂 mais aussi parce que ca va me permettre très simplement de changer les adresses MAC et d’avoir accès en CLI à toutes les fonctions réseau qui me permettront de simuler des attaques.

Configuration initiale

J’ai une configuration vraiment minimaliste sur mes équipements, sans aucune protection IPv6 bien évidemment: 6500-VSS-2T

ipv6 unicast-routing
!
vlan 999
 name TEST-IPV6-FHS
!
interface Port-channel31
 switchport
 switchport trunk allowed vlan 999,1000
 switchport mode trunk
!
interface Vlan999
 description Gateway test IPv6 FHS
 no ip address
 ipv6 address 2001:DB8:0:1::1/64

3750-10GE-1

interface GigabitEthernet2/0/1
 switchport access vlan 999
 switchport mode access
 spanning-tree portfast
!
interface GigabitEthernet3/0/1
 switchport access vlan 999
 switchport mode access
 spanning-tree portfast

Tests et résultats

IPv6 RA guard

La fonction RA guard permet de contrôler qui est autorisé à envoyer des Router Advertisements, ainsi que de s’assurer que le contenu des RA est conforme à ce qui est attendu. Le host « GOOD » s’autoconfigure avec le préfixe envoyé par le Catalyst 6500:

GOOD#sh ipv6 interface gigabitEthernet 0/2 | i subnet
 2001:DB8:0:1:7281:5FF:FEF6:7DF2, subnet is 2001:DB8:0:1::/64 [EUI/CAL/PRE]

On envoie maintenant un préfixe depuis le host « BAD » et on s’assure d’avoir la préférence maximale au niveau route par défaut.

interface GigabitEthernet0/2
 description IPV6 BAD
 ipv6 address BAD::1/64
 ipv6 nd router-preference High

Et on voit que le host GOOD s’autoconfigure également avec le nouveau préfixe BAD::64

GOOD#sh ipv6 interface gigabitEthernet 0/2 | i subnet
 BAD::7281:5FF:FEF6:7DF2, subnet is BAD::/64 [EUI/CAL/PRE]
 2001:DB8:0:1:7281:5FF:FEF6:7DF2, subnet is 2001:DB8:0:1::/64 [EUI/CAL/PRE]

Si on regarde les détails on voit que le host BAD, c’est-à-dire notre hacker, est même préféré car la priorité du RA est High alors que la priorité par défaut est Medium.

GOOD#show ipv6 routers 
Router FE80::213:5FFF:FED0:1000 on GigabitEthernet0/2, last update 0 min
 Hops 64, Lifetime 1800 sec, AddrFlag=0, OtherFlag=0, MTU=1500
 HomeAgentFlag=0, Preference=Medium
 Reachable time 0 (unspecified), Retransmit time 0 (unspecified)
 Prefix 2001:DB8:0:1::/64 onlink autoconfig
 Valid lifetime 2592000, preferred lifetime 604800
Router FE80::7281:5FF:FEF6:7EA2 on GigabitEthernet0/2, last update 0 min
 Hops 64, Lifetime 1800 sec, AddrFlag=0, OtherFlag=0, MTU=1500
 HomeAgentFlag=0, Preference=High
 Reachable time 0 (unspecified), Retransmit time 0 (unspecified)
 Prefix BAD::/64 onlink autoconfig
 Valid lifetime 2592000, preferred lifetime 604800

On configure maintenant sur notre stack de 3750-X la fonction IPv6 RA Guard pour empêcher les RA venant de tous les ports clients. On ne configure rien depuis le coeur: on connaît l’équipement derrière et autant ne pas s’embêter à complexifier les choses davantage.

interface GigabitEthernet2/0/1
 switchport access vlan 999
 switchport mode access
 ipv6 nd raguard
 spanning-tree portfast
!
interface GigabitEthernet3/0/1
 switchport access vlan 999
 switchport mode access
 ipv6 nd raguard
 spanning-tree portfast

On peut voir le résultat sur notre host GOOD qui maintenant ne s’autoconfigure plus qu’avec les RA autorisés:

GOOD#sh ipv6 interface gi0/2 | i subnet
 2001:DB8:0:1:7281:5FF:FEF6:7DF2, subnet is 2001:DB8:0:1::/64 [EUI/CAL/PRE]

On peut logguer l’activité RA Guard sur le switch:

3750-10GE-1#debug ipv6 snooping raguard 
 IPv6 snooping - RA guard debugging is on

Et ensuite tout devient clair dans les logs:

*Mar 19 23:24:27.219: SISF[RAG]: Gi3/0/1 vlan 999 RA received by RA guard on Gi3/0/1 from FE80::7281:5FF:FEF6:7EA2
*Mar 19 23:24:27.219: SISF[RAG]: Gi3/0/1 vlan 999 option 1 : ND_OPT_SOURCE_LINKADDR
*Mar 19 23:24:27.219: SISF[RAG]: Gi3/0/1 vlan 999 option 3 : ND_OPT_PREFIX_INFORMATION
*Mar 19 23:24:27.219: SISF[RAG]: Gi3/0/1 vlan 999 option 5 : ND_OPT_MTU
*Mar 19 23:24:27.219: SISF[RAG]: Gi3/0/1 vlan 999 !Not a router port: all router messages disallowed
*Mar 19 23:24:27.219: SISF[RAG]: Gi3/0/1 vlan 999 ! DROP ROUTER-ADVERT src FE80::7281:5FF:FEF6:7EA2 dst FF02::1 reason = 3

On a des options plus fines pour le RA guard. On va pouvoir autoriser uniquement certains préfixes, certains routeurs, certaines priorités etc. dans les messages RA. Dans la plupart des designs usuels on n’aura certainement pas besoin de ces options: on a un ou 2 ports avec des routeurs et on maîtrise ce qui se passe à ce niveau là (pas de rogue RA possibles). On peut toujours imaginer utiliser ce RA guard « sélectif » pour éviter des erreurs de configurations mais attention à ce que la solution ne soit pas pire que le problème que l’on cherche à résoudre.

IPv6 DHCP Guard

La fonction DHCPv6 guard permet de contrôler les ports sur lesquels des serveurs DHCPv6 sont connectés. Je configure maintenant mon hacker comme serveur DHCPv6

ipv6 dhcp pool POOL-DHCPV6
 address prefix BAD:BAD:BAD:BAD::/64
 dns-server BAD::BAD
domain-name bad.bad
!
interface GigabitEthernet0/2
 ipv6 dhcp server POOL-DHCPV6

Mon host GOOD est lui configuré comme client DHCPv6 y compris pour l’autoconfiguration de ses adresses (stateful).

GOOD#sh ipv6 interface gi0/2 | i subnet
 BAD:BAD:BAD:BAD:F589:BA0F:6591:8758, subnet is BAD:BAD:BAD:BAD:F589:BA0F:6591:8758/128 
 2001:DB8:0:BAD:7281:5FF:FEF6:7DF2, subnet is 2001:DB8:0:BAD::/64 [EUI/CAL/PRE]

On applique simplement une commande pour interdire les messages provenant de serveurs DHCPv6 depuis les ports clients.

interface GigabitEthernet2/0/1
 ipv6 dhcp guard
!
interface GigabitEthernet3/0/1
 ipv6 dhcp guard

Si l’on redémarre notre host GOOD, on voit qu’il n’apprend plus les adresses du serveur DHCPv6 clandestin.

GOOD#sh ipv6 interface gi0/2 | i subnet
 2001:DB8:0:BAD:7281:5FF:FEF6:7DF2, subnet is 2001:DB8:0:BAD::/64 [EUI/CAL/PRE]

Là aussi on peut logguer l’activité:

3750-10GE-1#debug ipv6 snooping dhcp-guard 
 IPv6 snooping - DHCP Guard debugging is on

Les logs sont clairs: on filtre les messages DHCPv6 « server » venant de l’interface Gi3/0/1 et on laisse passer les messages DHCPv6 « client » depuis l’interface Gi2/0/1:

*Mar 20 00:16:33.141: SISF[DHG]: Gi2/0/1 vlan 999 DHCP Guard setting sec level to GUARD
*Mar 20 00:16:33.141: SISF[DHG]: Gi2/0/1 vlan 999 DHCP Client message for role dhcp client - Permit
*Mar 20 00:16:33.141: SISF[DHG]: Gi3/0/1 vlan 999 DHCP Guard setting sec level to GUARD
*Mar 20 00:16:33.141: SISF[DHG]: Gi3/0/1 vlan 999 DHCP Server message for role dhcp client - Deny

On ne configure rien sur notre upstream. On pourrait là aussi faire une configuration plus détaillée qui permettrait de filtrer en fonction du contenu du messages DHCPv6.

IPv6 Binding Identity Guard

La fonction IPv6 Binding Identity Guard va permettre de construire une table d’association entre adresses IPv6, adresses MAC et numéros de ports sur le switch, puis de contrôler que les messages NDP sont bien conformes à ce qui est dans cette table (que le host BAD ne tente pas de répondre à un message Neighbor Sollicitation qui ne lui aurait pas été destiné).

Au niveau configuration ici on a tenté de simplifier un maximum les choses en intégrant tout dans des commandes « IPv6 snooping ». Ces commandes IPv6 snooping permettent également d’implémenter RA Guard et DHCPv6 Guard. Les commandes vues plus haut ne sont donc pas forcément nécessaire si vous voulez déployer la totale: je m’explique…

On commence par définir une politique pour l’IPv6 snooping globale sur le switch qui s’appelle TEST-BINDING dans laquelle on va spécifier nos règles de sécurité:

  • Les méthodes utilisées pour construire la table de binding (en snoopant les messages DHCP, NDP ou même en regardant les paquets circulant sur le réseau). Cela est fait respectivement avec les commandes « protocol dhcp », « protocol ndp » et « data-glean ». Notez que par défaut le snooping DHCP et NDP est réalisé pour construire la table, vous ne verrez donc pas les commandes ci-dessous dans votre configuration.
  • Le nombre d’adresses utilisées par port (commande « limit address-count »). Attention en IPv6 on a beaucoup plus facilement plus qu’une adresse par port. Faites attention donc si vous tenez absolument à vous assurer qu’il n’y a pas de switch connecté sur le port.
  • Le tracking: les entrées dans le cache sont présentes pour une durée de 5 minutes. Ces entrées sont mises à jour continuellement et ce, selon la méthode utilisée pour construire la table de binding. Une fois le timer écoulé, c’est-à-dire si le host connecté à été inactif pendant ce temps, alors par défaut n’importe quel host peut récupérer l’adresse sur un autre port sans aucune vérification préalable. Avec l’option « tracking enable », le switch va à la fin du timer demander à l’host s’il est toujours vivant (en lui envoyant un message Neighbor Sollicitation). Une réponse de l’host mettra alors à jour la table de binding.
  • Le niveau de sécurité (security-level) qui peut être choisi parmi les suivants: « glean » va construire la table de binding mais ne va pas ensuite s’assurer que les échanges sont conformes à cette table. « inspect » va construire la table et ensuite filtrer les NS/NA qui ne correspondraient pas à la table construite. « guard », qui est le niveau par défaut, va en plus ajouter le filtrage des messages RA et DHCP venant du port. Vous voyez donc ici qu’on peut implémenter RA/DHCPv6 guard simplement avec notre policy IPv6 snooping.

Ici un exemple de configuration (notez que la plupart de ces éléments sont configurés par défaut aussi n’espérez pas voir tout dans votre fichier de configuration):

ipv6 snooping policy TEST-BINDING
 device-role node
 protocol dhcp
 protocol ndp
 data-glean
 limit address-count 10
 tracking enable
 security-level guard

J’applique ensuite ma politique IPv6 snooping sur les ports de mon switch:

interface GigabitEthernet2/0/1
 ipv6 snooping attach-policy TEST-BINDING
...

Notez qu’il est possible de spécifier sur quels VLANs du port cette règle sera active. Par défaut tous les VLANs sont concernés. Maintenant jetons un coup d’oeil à notre table de binding:

3750-10GE-1#sh ipv6 neighbors binding 
Binding Table has 3 entries, 3 dynamic 
Codes: L - Local, S - Static, ND - Neighbor Discovery, DH - DHCP, PKT - Other Packet, API - API created
Preflevel flags (prlvl):
0001:MAC and LLA match   0002:Orig trunk           0004:Orig access 
0008:Orig trusted trunk  0010:Orig trusted access  0020:DHCP assigned 
0040:Cga authenticated   0080:Cert authenticated   0100:Statically assigned

    IPv6 address                      Link-Layer addr Interface vlan prlvl age  state       Time left
ND  FE80::A8AA:AAFF:FEAA:AAAA         AAAA.AAAA.AAAA  Gi3/0/1   999  0005  23s  REACHABLE   280 s
ND  FE80::2022:22FF:FE22:2222         2222.2222.2222  Gi2/0/1   999  0005  3mn  REACHABLE   108 s
ND  2001:DB8:0:1:A8AA:AAFF:FEAA:AAAA  AAAA.AAAA.AAAA  Gi3/0/1   999  0005  33s  REACHABLE   276 s 
ND  2001:DB8:0:1:2022:22FF:FE22:2222  2222.2222.2222  Gi2/0/1   999  0005  2s   REACHABLE   304 s

Ici on voit bien sur chaque port les adresses globales et lien-local des hosts connectés. Quand je vous disais d’être vigilant si vous teniez à appliquer une limite d’adresse IPv6 par port je pense que vous comprenez mieux pourquoi: 2 hosts mais déjà 4 adresses dans la table! 🙂 On voit la méthode utilisée pour construire les différentes entrées présentes ici (NDP – code ND). On voit aussi pour chaque entrée des informations complémentaires: 005 = 004 + 001 – ici les entrées sont sur des ports en mode « access » et les adresses lien-local sont conformes aux adresses MAC.

Maintenant je vais rajouter un host sur le switch sur le port Gi3/0/2 qui va tenter de se faire passer pour notre GOOD toujours connecté sur le port Gi3/0/1. Ce nouvel host va avoir la même adresse MAC et la même adresse IP. Je rappelle que l’ensemble des ports est protégé par notre policy TEST-BINDING.

Le switch détecte que des entrées similaires sont déjà présentes dans la base et va filtrer les messages NA

[10:28:17] VLAN 999, From Gi3/0/2 seclvl [guard], MAC AAAA.AAAA.AAAA: NDP::NA, 
 1 addresses advertised: 
 IPv6 addr: 2001:DB8:0:1:A8AA:AAFF:FEAA:AAAA, Drop reason=More trusted entry exists

Mais attention, le switch à ce stade ne va pas filtrer le trafic!!! Il filtre exclusivement les messages de contrôle. Par exemple si je ping l’adresse lien-local de la passerelle par défaut, et que j’ai préalablement rempli ma neighbor table avec l’adresse MAC correspondante le trafic va passer:

BAD-2#ping FE80::21C:B0FF:FEB7:D7C0
Output Interface: GigabitEthernet0/2 
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to FE80::21C:B0FF:FEB7:D7C0, timeout is 2 seconds:
Packet sent with a source address of FE80::A8AA:AAFF:FEAA:AAAA%GigabitEthernet0/2
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 0/0/4 ms

Rien n’empêche pour le moment notre méchant garçon d’envoyer des paquets sur le réseau avec sa mauvaise adresse IPv6… Et c’est là qu’entre en jeu la fonctionnalité IPv6 source guard (quelle transition!)

IPv6 Source Guard

Si les fonctions IPv6 snooping agissent sur le plan de contrôle, la fonction IPv6 source guard va agir sur le plan de données. On va vérifier que le trafic venant d’un port a des adresses sources  conformes avec notre table de binding précédemment construite avec les commandes IPv6 snooping. Personnellement j’aurais même rajouté la commande directement dans notre politique de snooping. Mais on va voir qu’IPv6 source se met en oeuvre très simplement. Tout commence par implémenter une policy Source Guard globale qui n’a quasiment aucune option.

ipv6 source-guard policy TEST-SOURCEGUARD

On peut ajouter 2 options à notre politique (que je n’utilise pas ici):

  • Possibilité d’autoriser tout le trafic lien-local avec la commande « permit link-local »
  • Possibilité d’interdire tout le trafic provenant d’adresses global auto-configurées avec la commande « deny global-autoconf »

Ensuite on applique bêtement notre politique sur les ports du switch:

int Gi2/0/1
 ipv6 source-guard attach-policy TEST-SOURCEGUARD
...

On peut ensuite voir l’impact directement:

BAD-2#ping FE80::21C:B0FF:FEB7:D7C0
Output Interface: GigabitEthernet0/2 
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to FE80::21C:B0FF:FEB7:D7C0, timeout is 2 seconds:
Packet sent with a source address of FE80::A8AA:AAFF:FEAA:AAAA%GigabitEthernet0/2
.....
Success rate is 0 percent (0/5)

On a maintenant un réseau pas trop mal sécurisé au niveau 2 pour IPv6!

Références

http://www.cisco.com/en/US/docs/switches/lan/catalyst2960/software/release/15.0_2_se/configuration/guide/swipv6.html#wp1529279

Publicités

9 Responses to J’ai testé pour vous: IPv6 First Hop Security

  1. A reblogué ceci sur Blog Cisco IPv6 and commented:

    Ajoutez votre grain de sel personnel… (facultatif)

  2. Ping: IOS-XE 3.4.0SG – Catalyst 4500E et 4500-X « Blog Cisco Réseaux

  3. wissem says:

    Bonsoir
    Est ce que je peux appliquer ces mécansimes dans un switch virtuel cisco nexus 1000v,car je travaille dans un environnement virtuel .

  4. Navid says:

    Bonjour,
    Merci pour ce post! difficile de trouver plus précis, même sur les doc Cisco.
    Sauriez-vous exactement ce que signifient les device-role NODE et SWITCH qui sont configurables dans une police ipv6 snooping ?

    Merci,
    Navid

  5. Bonjour Navid!

    Merci pour le feedback ca fait plaisir. Pour la partie device-role je suis parti a la pêche car en effet c’est pas très explicite dans les config guides actuels…
    L’idée est la suivante: etre capable de distribuer le controle des bindings quand tu as des designs avec plusieurs switchs chaînés dans un VLAN (bref c’est quand meme souvent le cas)
    Prends un VLAN avec les switchs A et B: il convient de s’assurer avant de pousser une entrée dans la table de binding sur le switch A qu’elle n’est pas déjà présente sur le switch B. Pour ca 2 méthodes:
    1°) Tu flood toutes les entrées sur tous les switchs, ainsi le switch A va avoir les infos sur les bindings des hosts attachés sur le switch B et vice-versa. Pas super optimal en termes d’utilisation de mémoire.
    2°) Tu t’arranges pour qu’il y ait coopération entre tes switchs pour gérer les bindings et c’est la que l’option device-role switch, combinée la commande trusted-ports va rentrer en jeu. Je m’explique plus bas:

    Quand une nouvelle entrée va être détectée sur un port untrusted d’un switch (device-role node ou switch) le switch va mettre l’entrée dans sa table de binding en état « tentative » pour une durée de 800ms. A ce moment la un NS va etre envoyé sur tous les ports trusted avec un device-role = switch. Si pendant ce moment un NA est recu d’un port switch trusté alors l’entrée est effacée de la table de binding. Pendant la durée du tentative les ND et DAD recus sur le port en question sont bien évidemment bloqués.

    Je pense qu’on va documenter tout ca un peu mieux prochainement. Je risque de faire un post dédié sur le sujet avec schéma a la clé mais déjà j’espère avoir pu clarifier le fonctionnement. Bien faire attention a utiliser la notion de device-role en combinaison avec la notion de ports trusté pour que tout cela fonctionne!

    A bientot,
    Jeromr

  6. Navid says:

    Merci Jérôme pour la rapidité et la précision de ta réponse !

    J’imagine la table de binding avec 4 colonnes :
    – n° de VLAN
    – n° d’interface
    – adresse IPv6
    – adresse MAC

    Par contre, je ne vois pas pourquoi il convient de s’assurer que la même entrée n’est pas présente sur 2 switchs connectés ensemble. Si tu peux m’éclairer à ce sujet ? Merci.

    Si tu as un lien vers une doc Cisco qui explique ce « device-role », je suis aussi preneur !

    Merci beucoup !
    NAvid

    • En fait tu as dans la table de binding d’autres détails comme la manière dont tu as récupéré l’adresse (NDP, DHCP, DATA…) mais en gros oui la table de binding contient principalement les infos que tu mentionnes. Le meilleur de voir les détails est encore de faire le show qui va bien sur le switch: on donne des infos assez explicites.

      La logique de prévention du vol d’adresse est valable sur l’ensemble du niveau 2 (bref du VLAN). Si un switch sait vérifier localement qu’il peut ajouter un host car il ne vole pas l’adresse d’un autre host déjà présent dans sa table de binding tu dois aussi vérifier qu’un host que tu vas raccorder sur le switch A ne va pas voler l’adresse d’un autre host sur le switch B. Sauf dans les designs ou tu routes dès l’accès tu as besoin de te protéger globalement sur chaque VLAN et c’est la qu’entre en jeu la coopération inter-switch décrite dans ma précédente réponse.

      Je n’ai pour le moment pas trouvé d’infos publiques donc tu vas devoir j’ai peur te contenter pour le moment de mes explications 🙂 J’ai notifié que le device-role méritait d’être un peu mieux décrit sur nos config guides, nul doute que des choses vont arriver car on continue d’avancer sur les divers mécanismes de sécurité au niveau 2.

      A bientot!

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

%d blogueurs aiment cette page :