6068 links
  • GuiGui's Show

  • Home
  • Login
  • RSS Feed
  • Tag cloud
  • Picture wall
  • Daily
Links per page: 20 50 100
page 1 / 1
  • A Farewell to ARPs: IPv4 Service on IPv6-Only Networks | RIPE Labs

    + What's ARP Got to Do with It?
    + IPv4 routes with an IPv6 next hop

    Je découvre que des systèmes (Linux, Mikrotik, Arista, Cisco), et même le protocole de routage Babel, prennent en charge les « v4-via-v6 routes », c'est-à-dire des routes IPv4 dont le prochain saut est une IPv6.

    L'adresse MAC du prochain saut est donc résolue avec ICMPv6 NDP au lieu d'ARP.

    Sous Linux, ces routes s'insèrent dans la table de routage de cette manière : ip -4 r a default via inet6 fe80::1 dev enp1s0. (« inet6 » après « via ».) Elles ont cette tête dans la table de routage : default via inet6 fe80::1 dev enp1s0.

    C'est absolument génial puisque cela permet un réseau informatique intégralement en IPv6, contenant des machines qui peuvent joindre les réseaux IPv4 sans mécanisme de transition IPv6<>IPv4. Évidemment, un tel réseau doit quand même être en capacité d'attribuer des adresses IPv4, et les routeurs et les terminaux doivent prendre en charge IPv6 et IPv4, donc tous les scénarios de transition d'IPv4 vers IPv6 ne sont pas couverts. (Évidemment, des réseaux uniquement IPv4 ne pourront pas joindre des destinations IPv6.)

    Linux prend en charge cela depuis sa version 5.2 de mi-2019. :O

    Comme l'expliquent les articles sus-pointés, c'est la suite logique d'une configuration fortement répandue, notamment chez les hébergeurs, qui consiste à configurer une machine virtuelle dans un réseau contenant une seule IPv4 (/32), voire une seule adresse IPv6 (/128), ce qui fait disparaître la notion de réseau niveau 2 et certaines des attaques qui vont avec (possibilité, pour l'hébergeur, de nettoyer l'intégralité du trafic ‒ ex. : anti-DDoS entre machines d'un même réseau ‒, et d'isoler ses clients) : ARP ne sert plus qu'à résoudre l'adresse MAC du routeur. Autant aller jusqu'au bout et résoudre cette adresse MAC via ICMPv6. :D

    (D'autres attaques, comme un serveur DHCP malveillant, un prétendu routeur IPv6 malveillant ‒ Router Advertisement ‒, etc. sont également résolues, mais une configuration statique produirait le même résultat, donc ça ne compte pas vraiment. Si la possibilité d'une usurpation du routeur via ARP disparaît, une usurpation NDP demeure.)

    Forcément, j'ai eu envie de monter une maquette.


    Maquette

    Définition

    Trois machines virtuelles KVM faisant tourner Debian 13 (Trixie).

    Terminal (198.18.0.2/32 / 2001:db8::2/64) <--> Routeur (198.19.0.1/24 / 2001:2::1/64) <--> Ternet (198.19.0.2/24 / 2001:2::2/64).

    Oui, Routeur n'a pas d'adresse de la forme 198.18.X.X, et n'est pas plus présente dans le réseau 2001:db8::/64. Il a des routes vers ces réseaux dont le prochain saut est une IPv6 locale au lien (rappel : en IPv6, le routage devrait toujours se faire ainsi).

    Oui, Ternet est une machine configurée de manière usuelle.

    Pour rappel, 198.18.0.0/15, 2001:db8::/32, et 2001:2::/48 sont des réseaux réservés pour des tests ou de la documentation, cf. IPv4 Special-Purpose Address Space et IPv6 Special-Purpose Address Space.


    Configuration

    Terminal
    # # Éviter des requêtes DNS inutiles dans mes traces réseau
    # systemctl stop systemd-timesyncd
    # systemctl mask systemd-timesyncd
    
    # cat > /etc/network/interfaces << EOF
    auto lo enp1s0
    
    iface lo inet loopback
    
    iface enp1s0 inet6 static
      address 2001:db8::2/64
      gateway fe80::1
      accept_ra 0
      autoconf 0
      dad-attempts 0
    
    iface enp1s0 inet static
      address 198.18.0.2/32
      post-up /usr/sbin/ip -4 route add default via inet6 fe80::1 dev enp1s0
      post-up /usr/sbin/ip -6 a a fe80::2/64 dev enp1s0
    EOF


    Ternet
    # systemctl stop systemd-timesyncd
    # systemctl mask systemd-timesyncd
    
    # cat > /etc/network/interfaces << EOF
    auto lo enp1s0
    
    iface lo inet loopback
    
    iface enp1s0 inet6 static
      address 2001:2::2/64
      gateway fe80::1
      accept_ra 0
      autoconf 0
      dad-attempts 0
    
    iface enp1s0 inet static
      address 198.19.0.2/24
      gateway 198.19.0.1
    EOF


    Routeur
    # systemctl stop systemd-timesyncd
    # systemctl mask systemd-timesyncd
    
    # cat > /etc/network/interfaces << EOF
    auto lo enp1s0 enp7s0
    
    iface lo inet loopback
    
    iface enp1s0 inet6 static
      address fe80::1/64
      post-up /usr/sbin/ip -4 route add 198.18.0.2/32 via inet6 fe80::2 dev enp1s0
      post-up /usr/sbin/ip -6 route add 2001:db8::/64 via fe80::2 dev enp1s0
      post-up echo 1 > /proc/sys/net/ipv4/ip_forward
      post-up echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
      post-up echo 1 > /proc/sys/net/ipv6/conf/enp1s0/forwarding
    
    iface enp7s0 inet6 static
      address 2001:2::1/64
      post-up /usr/sbin/ip a a fe80::1/64 dev enp7s0
      post-up echo 1 > /proc/sys/net/ipv6/conf/enp7s0/forwarding
    
    iface enp7s0 inet static
      address 198.19.0.1/24
    EOF


    État au démarrage, avant le test

    Terminal
    # ip a s dev enp1s0
    2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
        link/ether 52:54:00:70:9f:c8 brd ff:ff:ff:ff:ff:ff
        altname enx525400709fc8
        inet 198.18.0.2/32 brd 198.18.0.2 scope global enp1s0
           valid_lft forever preferred_lft forever
        inet6 2001:db8::2/64 scope global nodad 
           valid_lft forever preferred_lft forever
        inet6 fe80::2/64 scope link 
           valid_lft forever preferred_lft forever
        inet6 fe80::5054:ff:fe70:9fc8/64 scope link proto kernel_ll 
           valid_lft forever preferred_lft forever
    
    # ip -4 r s
    default via inet6 fe80::1 dev enp1s0
    
    # ip -6 r s
    2001:db8::/64 dev enp1s0 proto kernel metric 256 pref medium
    fe80::/64 dev enp1s0 proto kernel metric 256 pref medium
    default via fe80::1 dev enp1s0 metric 1024 onlink pref medium
    
    # ip -4 n
    #
    
    # ip -6 n
    # 


     Ternet
    # ip a s dev enp1s0
    2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:54:00:16:68:77 brd ff:ff:ff:ff:ff:ff
    altname enx525400166877
    inet 198.19.0.2/24 brd 198.19.0.255 scope global enp1s0
       valid_lft forever preferred_lft forever
    inet6 2001:2::2/64 scope global nodad 
       valid_lft forever preferred_lft forever
    inet6 fe80::5054:ff:fe16:6877/64 scope link proto kernel_ll 
       valid_lft forever preferred_lft forever
    
    # ip -4 r s
    default via 198.19.0.1 dev enp1s0 onlink 
    198.19.0.0/24 dev enp1s0 proto kernel scope link src 198.19.0.2 
    
    # ip -6 r s
    2001:2::/64 dev enp1s0 proto kernel metric 256 pref medium
    fe80::/64 dev enp1s0 proto kernel metric 256 pref medium
    default via fe80::1 dev enp1s0 metric 1024 onlink pref medium
    
    # ip -4 n
    #
    
    # ip -6 n
    # 


    Routeur
    # ip a s dev enp1s0
    2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:54:00:69:0f:ed brd ff:ff:ff:ff:ff:ff
    altname enx525400690fed
    inet6 fe80::1/64 scope link 
       valid_lft forever preferred_lft forever
    inet6 fe80::5054:ff:fe69:fed/64 scope link proto kernel_ll 
       valid_lft forever preferred_lft forever
    
    # ip a s dev enp7s0
    3: enp7s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:54:00:2a:ea:b5 brd ff:ff:ff:ff:ff:ff
    altname enx5254002aeab5
    inet 198.19.0.1/24 brd 198.19.0.255 scope global enp7s0
       valid_lft forever preferred_lft forever
    inet6 2001:2::1/64 scope global 
       valid_lft forever preferred_lft forever
    inet6 fe80::1/64 scope link 
       valid_lft forever preferred_lft forever
    inet6 fe80::5054:ff:fe2a:eab5/64 scope link proto kernel_ll 
       valid_lft forever preferred_lft forever
    
    # ip -4 r s
    198.18.0.2 via inet6 fe80::2 dev enp1s0
    198.19.0.0/24 dev enp7s0 proto kernel scope link src 198.19.0.1
    
    # ip -6 r s
    2001:2::/64 dev enp7s0 proto kernel metric 256 pref medium
    2001:db8::/64 via fe80::2 dev enp1s0 metric 1024 pref medium
    fe80::/64 dev enp7s0 proto kernel metric 256 pref medium
    fe80::/64 dev enp1s0 proto kernel metric 256 pref medium
    
    # ip -4 n
    #
    
    # ip -6 n
    #


    Caches ARP et NDP après le test

    Le test : ping -c 2 198.19.0.2 depuis Terminal.


    Terminal
    # ip -4 n
    #
    
    # ip -6 n
    fe80::1 dev enp1s0 lladdr 52:54:00:69:0f:ed router REACHABLE 


    Ternet
    # ip -4 n
    198.19.0.1 dev enp1s0 lladdr 52:54:00:2a:ea:b5 DELAY 
    
    # ip -6 n
    #


    Routeur
    # ip -4 n
    198.19.0.2 dev enp7s0 lladdr 52:54:00:16:68:77 REACHABLE 
    
    # ip -6 n
    fe80::2 dev enp1s0 lladdr 52:54:00:70:9f:c8 REACHABLE 


     Captures réseau

    Terminal
    1   0.000000    fe80::5054:ff:fe70:9fc8 →   ff02::1:ff00:1          ICMPv6  86  Neighbor Solicitation for fe80::1 from 52:54:00:70:9f:c8
    2   0.000473    fe80::1                 →   fe80::5054:ff:fe70:9fc8 ICMPv6  86  Neighbor Advertisement fe80::1 (rtr, sol, ovr) is at 52:54:00:69:0f:ed
    3   0.000509    198.18.0.2              →   198.19.0.2              ICMP    98  Echo (ping) request  id=0x0001, seq=1/256, ttl=64
    4   0.001634    fe80::5054:ff:fe69:fed  →   ff02::1:ff00:2          ICMPv6  86  Neighbor Solicitation for fe80::2 from 52:54:00:69:0f:ed
    5   0.001668    fe80::2                 →   fe80::5054:ff:fe69:fed  ICMPv6  86  Neighbor Advertisement fe80::2 (sol, ovr) is at 52:54:00:70:9f:c8
    6   0.001919    198.19.0.2              →   198.18.0.2              ICMP    98  Echo (ping) reply    id=0x0001, seq=1/256, ttl=63 (request in 3)
    7   1.001385    198.18.0.2              →   198.19.0.2              ICMP    98  Echo (ping) request  id=0x0001, seq=2/512, ttl=64
    8   1.002604    198.19.0.2              →   198.18.0.2              ICMP    98  Echo (ping) reply    id=0x0001, seq=2/512, ttl=63 (request in 7)


    Ternet
    1   0.000000    52:54:00:2a:ea:b5   →   Broadcast           ARP     42  Who has 198.19.0.2? Tell 198.19.0.1
    2   0.000057    52:54:00:16:68:77   →   52:54:00:2a:ea:b5   ARP     42  198.19.0.2 is at 52:54:00:16:68:77
    3   0.000335    198.18.0.2          →   198.19.0.2          ICMP    98  Echo (ping) request  id=0x0001, seq=1/256, ttl=63
    4   0.000397    198.19.0.2          →   198.18.0.2          ICMP    98  Echo (ping) reply    id=0x0001, seq=1/256, ttl=64 (request in 3)
    5   1.001143    198.18.0.2          →   198.19.0.2          ICMP    98  Echo (ping) request  id=0x0001, seq=2/512, ttl=63
    6   1.001190    198.19.0.2          →   198.18.0.2          ICMP    98  Echo (ping) reply    id=0x0001, seq=2/512, ttl=64 (request in 5)


    Routeur

    Certains paquets sont en double car je capture sur les deux interfaces réseau.

     1  0.000000    fe80::5054:ff:fe70:9fc8 →   ff02::1:ff00:1          ICMPv6   92 Neighbor Solicitation for fe80::1 from 52:54:00:70:9f:c8
     2  0.000076    fe80::1                 →   fe80::5054:ff:fe70:9fc8 ICMPv6   92 Neighbor Advertisement fe80::1 (rtr, sol, ovr) is at 52:54:00:69:0f:ed
     3  0.000412    198.18.0.2              →   198.19.0.2              ICMP    104 Echo (ping) request  id=0x0001, seq=1/256, ttl=64
     4  0.000454    52:54:00:2a:ea:b5       →                           ARP      48 Who has 198.19.0.2? Tell 198.19.0.1
     5  0.000824    52:54:00:16:68:77       →                           ARP      48 198.19.0.2 is at 52:54:00:16:68:77
     6  0.000833    198.18.0.2              →   198.19.0.2              ICMP    104 Echo (ping) request  id=0x0001, seq=1/256, ttl=63
     7  0.001203    198.19.0.2              →   198.18.0.2              ICMP    104 Echo (ping) reply    id=0x0001, seq=1/256, ttl=64 (request in 6)
     8  0.001237    fe80::5054:ff:fe69:fed  →   ff02::1:ff00:2          ICMPv6   92 Neighbor Solicitation for fe80::2 from 52:54:00:69:0f:ed
     9  0.001566    fe80::2                 →   fe80::5054:ff:fe69:fed  ICMPv6   92 Neighbor Advertisement fe80::2 (sol, ovr) is at 52:54:00:70:9f:c8
    10  0.001595    198.19.0.2              →   198.18.0.2              ICMP    104 Echo (ping) reply    id=0x0001, seq=1/256, ttl=63
    11  1.001480    198.18.0.2              →   198.19.0.2              ICMP    104 Echo (ping) request  id=0x0001, seq=2/512, ttl=64
    12  1.001504    198.18.0.2              →   198.19.0.2              ICMP    104 Echo (ping) request  id=0x0001, seq=2/512, ttl=63
    13  1.002104    198.19.0.2              →   198.18.0.2              ICMP    104 Echo (ping) reply    id=0x0001, seq=2/512, ttl=64 (request in 12)
    14  1.002121    198.19.0.2              →   198.18.0.2              ICMP    104 Echo (ping) reply    id=0x0001, seq=2/512, ttl=63


    v6-via-v4 routes ?

    Pour ceux qui se demandent si Linux permet des routes IPv6 dont le prochain saut est une IPv4 : nope.

    Sur Routeur :

    # ip -6 r a 3fff:42::/64 via inet 198.19.0.2 dev enp7s0
    Error: IPv6 does not support RTA_VIA attribute.
    
    # ip -6 r a 3fff:42::/64 via 198.19.0.2 dev enp7s0
    Error: inet6 address is expected rather than "198.19.0.2".

    Via https://mastodon.gougere.fr/@bortzmeyer/116985715930270669 et https://bsky.app/profile/aeris.eu.org.

    02/08/2026 18:11:39 - permalink -
    - https://labs.ripe.net/author/remco-van-mook/a-farewell-to-arps-ipv4-service-on-ipv6-only-networks/
Links per page: 20 50 100
page 1 / 1
Mentions légales identiques à celles de mon blog | CC BY-SA 3.0

Shaarli - The personal, minimalist, super-fast, database free, bookmarking service by the Shaarli community