Un brin de réseau


Tel un cahier de notes, ce blog propose des articles sur les technologies réseaux et leur utilisation pratique, le tout illustré avec des maquettes et des captures.

Python freeradius-api Python diffplus

IPv6 et BNG Partie 1

Dans cet article structuré en trois parties, nous abordons progressivement les concepts de l'IPv6 appliqués au BNG. Autrefois appelé BRAS, le TR-101 du Broadband Forum définit le rôle BNG ainsi :


    Broadband Remote Access Server (BRAS)
    The BRAS is the aggregation point for the user traffic. It provides aggregation
    capabilities (e.g. IP, PPP, Ethernet) (…) it can also support policy
    management and IP QoS in the access network. In this document,
    the term BRAS is used to describe the ATM-centric device
    

    Broadband Network Gateway (BNG)
    IP Edge Router where bandwidth and QoS policies may
    be applied. This term is used instead of BRAS to denote an
    Ethernet-centric IP edge node in this document.
    

Autrement dit, le BNG représente le point de terminaison des sessions des abonnés (subscribers)—et constitue également leur premier saut et passerelle. Historiquement, le terme BRAS s'emploie dans un contexte de réseau d'accès ATM et le terme BNG dans un contexte de réseau d'accès Ethernet.

Plan de l'article

Un ::cafe:babe ?

Revenons brièvement aux bases :


    IPv4
    x.x.x.x — où chaque x est un groupe de 8 bits (octet)
    (192.168.0.1)10 = (11000000.10101000.00000000.00000001)2

    IPv6
    x:x:x:x:x:x:x:x — où chaque x est un groupe de 16 bits composé de 4 sous-groupes de 4 bits (quartet)
    (2001:db8::1)16 = (0010-0000-0000-0001:0000-1101-1011-1000::0000-0000-0000-0001)2
    

Les réseaux IPv6, de la même façon qu'en IPv4, s'écrivent suivant la notation CIDR :


    192.168.0.0/24 — s'étend de 192.168.0.0 (network) à 192.168.0.255 (broadcast)
    2001:db8::/64  — s'étend de 2001:db8::0000:0000 (anycast) à 2001:db8::ffff:ffff (anycast)
    

Comme en IPv4, les première et dernière adresses d'un réseau IPv6 sont particulières, mais pas pour les mêmes raisons : elles peuvent être configurées en anycast—mécanisme non détaillé ici. Enfin, le hexspeak s'emploie parfois dans les adresses IPv6 pour en améliorer la lisibilité ou juste pour le fun :


    2a03:2880:f17b:0088:face:b00c::25de # l'adresse IPv6 de facebook.com contenant "face:b00c"
    2001:db8:cafe:babe::/64
    2001:db8:dead:beef::/64
    2001:db8:0:1::dead:c0de
    

Les types d'adresse IPv6

IPv6 distingue plusieurs types d'adresse unicast :

Type d'adresse (unicast) Portée Préfixe RFC
LLA (Link-Local unicast Address) Locale au lien (au domaine de broadcast L2) fe80::/10 RFC 4291
GUA (Global Unicast Address) Globale (Internet, VPN, etc.) 2000::/3 RFC 4291
ULA (Unique Local unicast Address) Locale au site (intra-site) voire au VPN (inter-sites) mais globalement unique fc00::/7 RFC 4193

Les types multicast et anycast, non pertinents pour cet article, existent également.

LLA (Link-Local unicast Address)

Conformément au standard, toute interface doit comporter une LLA :


    All interfaces are required to have at least one Link-Local unicast
    address (see Section 2.8 for additional required addresses).
  	

Ces adresses ont une portée locale et ne doivent pas être routées en dehors de leur lien. Elles sont une brique de base sur laquelle d'autres mécanismes s'appuient, comme ND (Neighbor Discovery) ou encore SLAAC et DHCPv6 pour l'assignation de « vraies » adresses (à plus grande portée) :


    Link-Local addresses are designed to be used for addressing on a
    single link for purposes such as automatic address configuration,
    neighbor discovery, or when no routers are present.

    Routers must not forward any packets with Link-Local source or
    destination addresses to other links.
  	

Appartenant au préfixe fe80::/10, elles suivent le format :


    |   10     |
    |  bits    |         54 bits         |          64 bits           |
    +----------+-------------------------+----------------------------+
    |1111111010|           0             |       interface ID         |
    +----------+-------------------------+----------------------------+
   	
Exemple

Les exemples ci-dessous illustrent l'utilisation des adresses LLA (en fe80) en support de l'autoconfiguration SLAAC et DHCPv6 ainsi que de ND (Neighbor Discovery). Apparaissent aussi des adresses multicast (en ff02) ayant une portée locale au lien.

cap-ipv6-lla-slaac
Autoconfiguration avec SLAAC basée sur les adresses LLA.
cap-ipv6-lla-dhcpv6
Autoconfiguration avec DHCPv6 basée sur les adresses LLA.
cap-ipv6-lla-nd
L'ARP de l'IPv6 (ND) basée sur les adresses LLA (le premier paquet).

GUA (Global Unicast Address)

Ces adresses ont une portée globale : elles sont publiques et souvent routées sur Internet. Mais pas toujours : tout comme en IPv4, elles peuvent rester cloisonnées dans un L3VPN hors Internet—les clients comprennent souvent mal ce point. Appartenant au préfixe 2000::/3, elles suivent le format :


    |         n bits         |   m bits  |       128-n-m bits         |
    +------------------------+-----------+----------------------------+
    | global routing prefix  | subnet ID |       interface ID         |
    +------------------------+-----------+----------------------------+
    

Les RIR (Regional Internet Registry) allouent la première partie, les global routing prefixes, généralement à des LIR (Local Internet Registry)—c'est-à-dire, à des opérateurs. Le RIPE NCC, notre RIR européen, alloue par défaut un /32 voire un /29 :


    The minimum IPv6 allocation size in the RIPE NCC service region is a /32 (4.3 billion subnets).
    According to the policies of the RIPE community, RIPE NCC members can request a larger IPv6 allocation (up to a /29)
    

La deuxième partie, ou subnetting, incombe aux LIR qui peuvent s'appuyer sur des best practices en vigueur que nous verrons plus bas.

Exemple

Ce blog est accessible à la fois en IPv4 et en IPv6 :


    >ping -4 brindereseau.fr
    Envoi d’une requête 'ping' sur brindereseau.fr [51.91.236.255] avec 32 octets de données :
    Réponse de 51.91.236.255: octets=32 temps=19 ms TTL=56

    >ping -6 brindereseau.fr
    Envoi d’une requête 'ping' sur brindereseau.fr [2001:41d0:301::29] avec 32 octets de données :
    Réponse de 2001:41d0:301::29: temps=21 ms
    

L'adresse IPv6 2001:41d0:301::29 appartient au préfixe global 2001:41d0::/32 d'OVH, apparemment redécoupé en 2001:41d0:301::/64.

ULA (Unique Local unicast Address)

Ces adresses ont une portée intra-site voire inter-sites (L3VPN) et ne doivent pas être routées sur Internet. En ceci, elles s'apparentent aux adresses privées de l'IPv4—à la différence qu'elles se veulent globalement uniques :


    This document defines an IPv6 unicast address format that is globally
    unique and is intended for local communications [IPV6].  They are not
    expected to be routable on the global Internet.  They are routable
    inside of a more limited area such as a site.  They may also be
    routed between a limited set of sites.
    

Elles remplacent les adresses Site-Local dépréciées par la RFC 3879, notamment car ces dernières avaient le même défaut que les adresses privées RFC 1918 de l'IPv4, à savoir le manque d'unicité. Utiliser un même réseau privé à plusieurs endroits présente en effet un risque de recouvrement—par exemple lors d'une fusion d'entreprise (et c'est fréquent). Reste alors à ré-adresser les sites ou à configurer du NAT entre eux : dans les deux cas, ce n'est pas une bonne nouvelle. Il n'y a pas lieu de s'encombrer de cet inconvénient dans IPv6, avant tout conçu pour pallier le manque d'adresses.

Appartenant au préfixe fc00::/7, elles suivent le format :


    | 7 bits |1|  40 bits   |  16 bits  |          64 bits           |
    +--------+-+------------+-----------+----------------------------+
    | Prefix |L| Global ID  | Subnet ID |        Interface ID        |
    +--------+-+------------+-----------+----------------------------+
    

Le global ID est généré de façon pseudo-aléatoire via un algorithme suggéré dans le standard et implémenté par des générateurs en ligne comme celui-ci.

Exemple

Générons par exemple un préfixe ULA (/48) et découpons-le en plusieurs réseaux par site (/64) :


    fde7:5992:7b53::/48 (préfixe généré pseudo-aléatoirement)
    ├── fde7:5992:7b53:0::/64 (premier site)
    ├── fde7:5992:7b53:1::/64 (deuxième site)
    └── fde7:5992:7b53:2::/64 (troisième site)
    

Enfin, la RFC 5375—de la catégorie des BCP (Best Current Practice)—résume bien les éléments abordés ci-dessus :


    ULAs have replaced the originally conceived site-local addresses in
    the IPv6 addressing architecture, for reasons described in [RFC3879].
    ULAs improve on site-locals by offering a high probability of the
    global uniqueness of the prefix used, which can be beneficial when
    there is (deliberate or accidental) leakage or when networks are
    merged.  ULAs are akin to the private address space [RFC1918]
    assigned for IPv4 networks, except that in IPv6 networks we may
    expect to see ULAs used alongside global addresses, with ULAs used
    internally and globals used externally.  Thus, use of ULAs does not
    imply use of NAT for IPv6.
    

Pourquoi des réseaux IPv6 en /64 ?

Version courte

ipv6-ripe-64-story
Image tirée de Basic IPv6 Course du RIPE que je conseille vivement.

Version longue

Un point commun apparaît dans le format des trois types d'adresse unicast (LLA, GUA et ULA) : la partie IID (Interface ID). Le standard originel édicte une règle concernant l'IID qui est importante par l'impact qu'elle a eu sur la taille des réseaux end-user :


    For all unicast addresses, except those that start with the binary
    value 000, Interface IDs are required to be 64 bits long and to be
    constructed in Modified EUI-64 format.
    

L'idée était d'avoir un IID automatiquement dérivé de l'adresse link-layer de l'interface—adresse au format EUI-48 (MAC-48) pour une interface Ethernet. Le format EUI-64, plus englobant, a été retenu avec une méthode de transformation d'un format à l'autre—illustrée dans la RFC 2464 pour Ethernet.

Le choix d'un IID sur 64 bits a eu pour conséquence des réseaux en /64. Des protocoles se sont ensuite basés sur cette taille, maintenant recommandée pour des questions de (rétro)compatibilité. La RFC 7421, qui dresse une analyse avec les pour et les contre, résume bien la chronologie :


    The notion of a /64 boundary in the address was introduced after the
    initial design of IPv6, following a period when it was expected to be
    at /80.  There were two motivations for setting it at /64.  One was
    (…) The other was the expectation that 64-bit Extended Unique
    Identifier (EUI-64) Media Access Control (MAC) addresses would become
    widespread in place of 48-bit addresses, coupled with the plan at
    that time that auto-configured addresses would normally be based on
    interface identifiers derived from MAC addresses.

    As a result, RFC 4291 describes a method of forming interface
    identifiers from IEEE EUI-64 hardware addresses [IEEE802], and this
    specifies that such interface identifiers are 64 bits long.
    

À titre d'exemple, la RFC 5375 §3 liste quelques mécanismes cassés en cas de /64 non respecté :


    Using a subnet prefix length other than a /64 will break many
    features of IPv6, including Neighbor Discovery (ND), Secure Neighbor
    Discovery (SEND) [RFC3971], privacy extensions [RFC4941], parts of
    Mobile IPv6 [RFC4866], Protocol Independent Multicast - Sparse Mode
    (PIM-SM) with Embedded-RP [RFC3956], and Site Multihoming by IPv6
    Intermediation (SHIM6) [SHIM6], among others.
    

Concrètement

Prenons l'exemple sur un routeur Cisco :


    Router#sho int gi0/0 | i address
      Hardware is iGbE, address is 0c72.bd49.0000 (bia 0c72.bd49.0000)

    Router#sho run int gi0/0 | i ipv6
     ipv6 enable                            # l'adresse LLA sera auto-générée depuis l'adresse MAC
     ipv6 address 2001:DB8:CAFE::/64 eui-64 # l'adresse GUA sera auto-générée depuis l'adresse MAC
     ipv6 address FDBE:427:BABE::/64 eui-64 # l'adresse ULA sera auto-générée depuis l'adresse MAC

    Router#sho ipv6 int gi0/0
      IPv6 is enabled, link-local address is fe80::E72:BDFF:FE49:0
      Global unicast address(es):
        2001:DB8:CAFE:0:E72:BDFF:FE49:0, subnet is 2001:DB8:CAFE::/64 [EUI]
        FDBE:427:BABE:0:E72:BDFF:FE49:0, subnet is FDBE:427:BABE::/64 [EUI]
    

Plus précisément, cette auto-génération s'appelle SLAAC (Stateless Address AutoConfiguration), définie dans la RFC 4862 :


    This document specifies the steps a host takes in deciding how to
    autoconfigure its interfaces in IP version 6.  The autoconfiguration
    process includes generating a link-local address, generating global
    addresses via stateless address autoconfiguration (…)
    

Mais…

Révéler l'adresse MAC dans l'IID pose des problèmes de sécurité et confidentialité décrits dans la RFC 7721 et n'est plus recommandé :


    There are a number of privacy and security implications that exist
    for hosts that use IEEE-identifier-based IIDs.  This section
    discusses four generic attack types: correlation of activities over
    time, location tracking, address scanning, and device-specific
    vulnerability exploitation.
    

Cela concerne en particulier les GUA exposées publiquement. Le document décrit aussi les solutions, comme l'emploi d'un IID aléatoire sans sémantique—ce que fait Windows par défaut. Bien que le postulat de base—dériver l'IID depuis l'adresse link-layer au format EUI-64 de l'interface—ne soit plus vraiment valable, la taille de facto des réseaux IPv6 reste /64, à une exception près.

Les liens point-à-point font-ils exception ?

La RFC 6164 autorise le /127 pour les liens point-à-point IPv6, à l'instar de la RFC 3021 qui autorise le /31 pour ceux IPv4 :


    Some operators have been using 127-bit prefixes, but this has been
    discouraged due to conflicts with Subnet-Router anycast [RFC3627].
    However, using 64-bit prefixes creates security issues that are
    particularly problematic on inter-router links, (…)

    This document provides a rationale for using 127-bit prefix lengths,
    reevaluates the reasons why doing so was considered harmful, and
    specifies how /127 prefixes can be used on inter-router links
    configured for use as point-to-point links.
    

Mentionnées en début d'article, les première et dernière adresses d'un réseau IPv6 sont particulières : elles sont réservées pour, si besoin, être configurées en anycast—mécanisme non détaillé ici. Un /127 rentre effectivement en conflit avec cette convention, les deux seules adresses disponibles étant configurées en unicast. Dans le même temps, un /64 pose des problèmes de sécurité dont le Neighbor Cache Exhaustion Issue—qui consiste à saturer le cache ARP de l'IPv6. Si ce problème concerne aussi bien les réseaux end-user, il s'avère particulièrement critique sur les liens backbone :


    This attack is not specific to point-to-point links, but is
    particularly harmful in the case of point-to-point backbone links,
    which may carry large amounts of traffic to many destinations over
    long distances.

    While there are a number of ways to mitigate this kind of issue,
    assigning /127 subnets eliminates it completely.
    

La recommandation en vigueur est alors de configurer les liens point-à-point en /127 tout en désactivant (ou en n'activant pas) l'anycast :


    Routers MUST support the assignment of /127 prefixes on point-to-
    point inter-router links.  Routers MUST disable Subnet-Router anycast
    for the prefix when /127 prefixes are used.
    

Enfin, noter que le RIPE-690 préconise de réserver un /64 (dans un inventaire IPAM) même si un /127 est effectivement configuré :


    If we decide to use /127 for each point to point link, then it is also
    advisable to allocate a /64 for each link and use just one /127 out of it.
    

Comment répartir un agrégat IPv6 entre les clients ?

Considérant la taille faramineuse d'un agrégat alloué par un RIR à un LIR (/29 ou /32), se pose légitimement la question de son redécoupage pour le répartir entre les clients. Heureusement, des BCP (Best Current Practice) apportent des réponses, comme la RFC 3177 actualisée par la RFC 6177 :


    RFC 3177 [RFC3177] called for a default end site IPv6 assignment size
    of /48.  Subsequently, the Regional Internet Registries (RIRs)
    developed and adopted IPv6 address assignment and allocation policies
    consistent with the recommendations of RFC 3177 [RIR-IPV6].  In 2005,
    the RIRs began discussing IPv6 address assignment policy again.
    Since then, APNIC [APNIC-ENDSITE], ARIN [ARIN-ENDSITE], and RIPE
    [RIPE-ENDSITE] have revised the end site assignment policy to
    encourage the assignment of smaller (i.e., /56) blocks to end sites.
    

Le RIPE-690 apporte aussi une solide vue d'ensemble :


    As a generic set of recommendations, you should consider the following:

      a. IPv6 is not the same as IPv4. In IPv6 you assign a short prefix to each end-user site,
         so they are able to have as many subnets (/64s) as they need.

      b. Assigning prefixes longer than /56 is strongly discouraged, so your choices are:
        1. If you want a simple addressing plan use a /48 for each end-user.
        2. Differentiate amongst types of customers by offering /48 for business customers and /56 for residential customers.
    

Ces extraits nous apprennent que chaque site client devrait se voir assigner un /56 voire un /48 afin de rendre disponible un grand nombre de /64 :

C'est…beaucoup. Sachant qu'un /64 offre 264 adresses soit 18 446 744 073 709 551 616 adresses.

ipv6-ripe-gua-distribution
Image tirée de Basic IPv6 Course du RIPE que je conseille vivement.