Linux:IPv6

De Djjnet.

Sommaire

Généralités

Ressources

Les adresses

Les adresses en IPv6 sont définies sur 128bits. Dans la plupart des cas, vous aurez deux parties préfix et jeton aussi nommé network et host. Celles-ci sont chacune sur 64bits pour faciliter l'autoconfiguration.

Afin de limiter le nombre de caractère dans l'écriture des adresses, elles sont utilisées en hexadécimal (soit par 4bits, dit nibble) ainsi :

2001:41d0:0001:2219:0000:0000:0000:0001

Le 0x habituel est enlevé et des : sont ajoutés par blocs de 16bits.

Les adresses peuvent être simplifiées en enlevant les 0 inutils, dans l'adresse précédente cela donne :

2001:41d0:1:2219:0:0:0:1

On peut encore simplifier lorsque la valeur du bloc de 16bits vaut 0 ainsi :

2001:41d0:1:2219::1

/!\ Attention, cette dernière simplification n'est possible qu'une fois, sinon nous ne savons pas combien de bloc sont présent pour chaque partie. 2001:0:1:2219:0:0:0:1 ne peut pas être écrit 2001::1:2219::1.

En IPv6, les adresses n'auront pas forcément la même portée, nous parlons de scope :

  • Scope Link : il s'agit d'adresses locales, disponibles uniquement dans un même réseau (physique, cad sans passer les routeurs). Elles sont dans le réseau FE80::/10
  • Scope Global : il s'agit des adresses publiques de l'IPv4. Ces adresses permettent de communiquer par l'Internet.

Les adresses autoconfigurées ou adresses "stateless"

IPv6 a été créé aussi pour l'autoconfiguration, celle-ci est réalisée avec le Router Advertisement et l'utilisation de l'adresse MAC pour générer l'adresse IPv6.

Par exemple, une adresse MAC 00:e0:4c:d0:bf:9c devient : 02e0:4cff:fed0:bf9c. ff:fe est ajouté au milieu de l'adresse, le 00 du début est transformé en 02 et les : sont adaptés pour garder les blocs de 16bits. On a ainsi le jeton de l'adresse, avec le préfix 2001:0:1:2219:, cela donne :

2001:0:1:2219:02e0:4cff:fed0:bf9c

Les adresses manuelles

Vous pouvez choisir vos propres adresses pour le jeton, comme j'ai fait pour les exemple avec :

2001:41d0:1:2219::1

Attention toute fois, le 7ième most significant bit doit toujours valoir 0.

Les affectations de réseaux

  • La RFC 1918 a défini des réseaux locaux comme le 10.0.0.0/8 mais ils sont maintenant "dépréciés". Ils commencaient par fecx: par exemple (x remplacé par 0 à f).
  • Les 6to4 adresses permettent d'encapsuler des adresses v4 dans des adresses v6 pour faire des tunnels, elles commmencent par 2002:

Par exemple, 192.168.1.1/5 donne 2002:c0a8:0101:5::1. Pour convertir simplement :

ipv4="1.2.3.4"; sla="5"; printf "2002:%02x%02x:%02x%02x:%04x::1" `echo $ipv4 | tr "." " "` $sla
2002:0102:0304:0005::1
  • Les Internet service providers (ISP) ont des adresses qui commence par 2001:. C'est le cas des adresses dans mes exemples.
  • Pour les documentations 3fff:ffff::/32 et 2001:0DB8::/32 (on fera une exception :) )
  • Et d'autres encore

Les adresses spéciales

  • Localhost ou 127.0.0.1 en IPv4 :
0000:0000:0000:0000:0000:0000:0000:0001
::1
  • Any ou 0.0.0.0 en IPv4 :
0000:0000:0000:0000:0000:0000:0000:0000
::
  • IPv4-mapped IPv6 address

Certaines applications vont écouter uniquement sur IPv4 mais afficher l'adresse sous forme d'IPv6, elles ont la forme suivante :

0:0:0:0:0:ffff:a.b.c.d/96
::ffff:a.b.c.d/96
::ffff:1.2.3.4

IPv6 et Linux

Généralités

  • Pour savoir si votre kernel est compatible IPv6 et que le module est bien chargé (ou directement dans le noyau), vous devez avoir dans /proc le fichier /proc/net/if_inet6 :
test -f /proc/net/if_inet6 && echo "Running kernel is IPv6 ready"
  • Pour charger automatiquement le module, vous devez avoir un alias par exemple dans /etc/modules.conf ou /etc/modprobe.d/aliases.
alias net-pf-10 ipv6

Pour le charger manuellement :

modprobe ipv6

Vérification :

lsmod |grep ipv6
nf_conntrack_ipv6      12084  6
nf_conntrack           55540  6 nf_conntrack_ipv6,xt_state,nf_conntrack_ftp,iptable_nat,nf_nat,nf_conntrack_ipv4
ipv6                  235396  34 ip6table_mangle,nf_conntrack_ipv6

interface réseau

Monter ou démonter les interfaces
ip link set dev eth0 up
ip link set dev eth0 down

équivalent à :

ifconfig eth0 up
ifconfig eth0 down
Voir la configuration

Par défaut si vous avez IPv6 d'activé dans votre noyau une adresse automatiquement configurée de Scope Link :

ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 00:e0:4c:d0:bf:9c
          inet adr:213.251.133.25  Bcast:213.251.133.255  Masque:255.255.255.0
          adr inet6: fe80::2e0:4cff:fed0:bf9c/64 Scope:Lien

Nous pouvons voir aussi avec :

ip -6 addr show dev eth0
2: eth0: <BROADCAST,MULTICAST,UP,10000> mtu 1500 qlen 1000
   inet6 fe80::21d:7dff:fed4:c99b/64 scope link
      valid_lft forever preferred_lft forever
Ajouter une IPv6

Ajoutons une IP de Scope Global, sachant que nous disposons du préfix 2001:41D0:1:2219::/64 :

ip -6 addr add 2001:41D0:1:2219::1/64 dev eth0

équivalent à :

ifconfig eth0 inet6 add 2001:41D0:1:2219::1/64

Voyons le résultat :

ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 00:e0:4c:d0:bf:9c
          inet adr:213.251.133.25  Bcast:213.251.133.255  Masque:255.255.255.0
          adr inet6: 2001:41d0:1:2219::1/64 Scope:Global
          adr inet6: fe80::2e0:4cff:fed0:bf9c/64 Scope:Lien
Supprimer une IPv6
ip -6 addr del 2001:41D0:1:2219::1/64 dev eth0

équivalent à :

ifconfig eth0 inet6 del 2001:41D0:1:2219::1/64
Pingons un peu

D'abors, ajoutons une adresse sur un autre serveur :

ip -6 addr add 2001:41D0:2:4Fc9::1/64 dev eth0

Pingons entre les serveurs :

ping6 2001:41D0:2:4Fc9::1
PING 2001:41D0:2:4Fc9::1(2001:41d0:2:4fc9::1) 56 data bytes
64 bytes from 2001:41d0:2:4fc9::1: icmp_seq=1 ttl=61 time=13.4 ms
64 bytes from 2001:41d0:2:4fc9::1: icmp_seq=2 ttl=61 time=4.25 ms
64 bytes from 2001:41d0:2:4fc9::1: icmp_seq=3 ttl=61 time=4.16 ms

Si vous avez plusieurs interface réseau, en IPv6, il peut être nécessaire de spécifier quelle interface utiliser en ajoutant le nom de l'interface après l'ip. C'est le cas par exemple des adresses locales :

ping6 fe80::2e0:4cff:fed0:bf9c
connect: Invalid argument
ping6 fe80::2e0:4cff:fed0:bf9c%eth0
PING fe80::2e0:4cff:fed0:bf9c%eth0(fe80::2e0:4cff:fed0:bf9c) 56 data bytes
From fe80::230:48ff:fede:edc6 icmp_seq=1 Destination unreachable: Address unreachable

Dans l'exemple, les serveurs ne sont pas sur le même réseau physique, donc le ping ne fonctionne pas.

Il est aussi possible de faire :

ping6 -I eth0 fe80::2e0:4cff:fed0:bf9c
route et passerelle

Il faut utiliser la commande route comme avant mais en précisant d'utiliser ipv6 ainsi :

route -A inet6

ou avec la commande ip mais pour une interface particulière :

ip -6 route show dev eth0

Ajouter une route passant par une passerelle :

route -A inet6 add 1234::/16 gw 1234:1234:0:1234::1

équivalent à :

ip -6 route add 1234::/16 via 1234:1234:0:1234::1

Pour la supprimer, on remplace add par del :

route -A inet6 del 1234::/16 gw 1234:1234:0:1234::1

équivalent à :

ip -6 route del 1234::/16 via 1234:1234:0:1234::1

Ajouter une route passant par une interface spécifique :

route -A inet6 add 1234::/16 dev eth1

Pour la supprimer :

route -A inet6 del 1234::/16 dev eth1

Préférez route à ip pour ce cas, sinon vous devez spécifier la metric.

/proc

Je ne présente pas ici comment modifier les paramètres dans /proc (il y a le echo > /proc ... le sysctl.conf, à vous de choisir)

/proc/sys/net/ipv6/conf/all/forwarding

Le forwarding est activé pour toutes les connexions par /proc/sys/net/ipv6/conf/all/forwarding à mettre à 1 pour l'activer.

echo 1 > /proc/sys/net/ipv6/conf/all/forwarding

/proc/sys/net/ipv6/conf/INTERFACE/forwarding aura la valeur du global.

/proc/sys/net/ipv6/conf/INTERFACE/accept_ra

Pour désactiver le router advertisements :

echo 0 > /proc/sys/net/ipv6/conf/eth0/accept_ra
/proc/sys/net/ipv6/conf/INTERFACE/autoconf

Pour désactiver l'autoconfiguration d'une interface :

echo 0 > /proc/sys/net/ipv6/conf/eth0/autoconf

iptables

iptables devient ip6tables. Les règles sont similaires. Voici un petit exemple qui autorise le port 80 en entré, l'icmp en entrée et sortie et les connexions établies :

#!/bin/bash
IPTABLES=/sbin/ip6tables
$IPTABLES -F
$IPTABLES -F INPUT
$IPTABLES -F OUTPUT
$IPTABLES -F FORWARD
$IPTABLES -F -t mangle
$IPTABLES -X
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
$IPTABLES -P FORWARD DROP
$IPTABLES -N firewall
$IPTABLES -A firewall -j DROP

$IPTABLES -A INPUT -p icmpv6 -j ACCEPT
$IPTABLES -A OUTPUT -p icmpv6 -j ACCEPT
# activate established mode on all protocols  (statefull inspection)
$IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Rejeter les paquets NEW et INVALID
$IPTABLES -A INPUT -m state --state INVALID -j firewall
$IPTABLES -A INPUT -p TCP -m state --state NEW ! --syn -j firewall
$IPTABLES -A OUTPUT -m state --state INVALID -j firewall
$IPTABLES -A OUTPUT -p TCP -m state --state NEW ! --syn -j firewall
$IPTABLES -A INPUT -p ALL -i lo -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -o lo -j ACCEPT
$IPTABLES -A INPUT -p TCP --dport 80 -j ACCEPT

Et les logiciels dans tout ça ?

postfix

IPv6 est supporté depuis la version 2.2 : http://www.postfix.org/IPV6_README.html

Il faut pour l'activer modifier inet_protocols. Par défaut, nous avons :

postconf |grep inet_protocols
inet_protocols = ipv4

Ajoutons cette directive à main.cf :

inet_protocols = ipv4, ipv6

Puis :

/etc/init.d/postfix restart

Nous avons maintenant avec netstat :

tcp6       0      0 :::25                   :::*                    LISTEN      0          28714554    32060/master

en plus de

tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN      0          28714552    32060/master

Connexion depuis un autre serveur vers le port 25 :

telnet 2001:41d0:1:2219:0:0:0:1 25
Trying 2001:41d0:1:2219::1...
Connected to 2001:41d0:1:2219:0:0:0:1.
Escape character is '^]'.
220 mx-backup.itenec.net ESMTP Postfix (Debian/GNU)

Si vous avez spécifié mynetwork dans main.cf, il faut ajouter les ipv6 entre [] :

mynetworks = 127.0.0.0/8 82.231... 89.89... 62.147... [::1]/128 [fe80::]/10 [2001:41d0:1:2219::]/64
bind - named

Afin que bind écoute sur le réseau IPv6, dans named.conf, dans la section options ajouter :

listen-on-v6 {
                       2001:41d0:1:2219::1;
};

On a alors avec netstat :

tcp6       0      0 2001:41d0:1:2219::1:53  :::*                    LISTEN      102        28720007    1247/named
udp6       0      0 2001:41d0:1:2219::1:53  :::*                                102        28720006    1247/named

Au niveau des enregistrements, rien de compliqué, voir http://www.isc.org/files/arm96.html#id2551089, il suffit d'ajouter des enregistrements AAAA au lieu de A pour IPv4. Par exemple :

mutua1          IN      A       213.251.133.25
mutua1          IN      AAAA    2001:41d0:1:2219::1
dig mutua1.itenec.net AAAA
...
mutua1.itenec.net.      60      IN      AAAA    2001:41d0:1:2219::1

Testons une requête DNS pour le champ MX utilisé par les serveurs de mails :

dig mx itenec.net
...
itenec.net.             60      IN      MX      10 mx1.itenec.net.
itenec.net.             60      IN      MX      20 mx-backup.itenec.net.
...
 ;; ADDITIONAL SECTION:
mx1.itenec.net.         60      IN      A       87.98.141.93
mx-backup.itenec.net.   60      IN      A       213.251.133.25
mx-backup.itenec.net.   60      IN      AAAA    2001:41d0:1:2219::1

On voit bien les deux types d'adresses v4 et v6.

Apache2

Si vous spécifiez le port d'écoute avec Listen 80 alors apache écoutent en ipv6 :

tcp6       0      0 :::80                   :::*                    LISTEN      0          23197035    1819/apache2

Si vous souhaitez spécifier l'adresse d'écoute, ajouter l'adresse entre [] :

Listen [2001:41d0:1:2219::1]:80

Vous avez maintenant :

tcp6       0      0 2001:41d0:1:2219::1:80  :::*                    LISTEN      0          29255101    12395/apache2

Attention de ne pas mettre à la fois Listen 80 et Listen IP:80 où vous aurez un conflit d'écoute de port au démarrage.

Pour les VirtualHost, seule particularité, ajouter les [] pour bien distinguer, le port, par exemple :

<VirtualHost [2001:41d0:1:2219::1]:443>
        ServerAdmin ...
        ServerName ...
        SSLEngine on
 
</VirtualHost>

IPv6 et Debian

Généralités

Sous Debian l'aliases du module ipv6 est mis dans /etc/modprobe.d/aliases

alias net-pf-10 ipv6

Routeur advertisement

Si vous souhaitez utiliser le Routeur advertisement, il existe le daemon radvd qui permet de répondre aux requêtes icmp d'autoconfiguration, utile sur votre routeur. Voici le package Debian : http://packages.debian.org/lenny/radvd.

Outils personnels
Google AdSense