04/10/2009

Allocation d’IPv6 over OpenVPN

IPv6 - Spread the loveNous avons vu comment allouer des IPv4 over VPN. Nous pouvons aller plus loin et allouer des IPv6 via le VPN, plus particulièrement OpenVPN. Cette méthode pourrait même être une bonne solution pour offrir une connectivité IPv6 à vos machines alors que votre FAI s’embourbe encore en IPv4.

Dans cet article, tap0 est l’interface du serveur VPN. C’est via cette interface qu’on réalise le lien. La première étape est donc d’attribuer une IPv6 à votre interface tap0.

tap0 représentant le mode “bridge” d’OpenVPN ,

# "dev tun" will create a routed IP tunnel,
# "dev tap" will create an ethernet tunnel.

Nous somme donc sur le même segment Ethernet que le client du VPN. Ainsi, nous pouvons envoyer des trames d’autoconfiguration IPv6 aux clients de notre VPN !

Avertissement : Cet article a pour but de partager des connaissances avec un public avisé.

Configuration exemple d’un serveur OpenVPN TCP/TAP

port 1194
proto tcp-server
dev tap
dev-type tap
# Clefs:
ca keys/ca.crt
cert keys/server.crt
key keys/server.key
dh keys/dh1024.pem
server 10.0.98.0 255.255.255.0
# On push la route pour que les autres VPN soient visibles
# push "route 10.75.1.0 255.255.255.0"
# push "dhcp-option DNS 10.75.1.1"
ifconfig-pool-persist ipp.txt
float
# permet le trafic entre les clients du VPN
client-to-client
keepalive 10 120
tls-auth keys/ta.key 0 # This file is secret
cipher AES-256-CBC
max-clients 200
user vpn
group vpn
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
status-version 2
log-append /var/log/openvpn/openvpn.log
verb 4
mute 20

Configuration exemple d’un client OpenVPN TCP/TAP

client
dev tap1
proto tcp-client
remote xx.xx.xx.xx 1194
resolv-retry infinite
nobind
user nobody
group nobody
persist-key
persist-tun
tls-client
ca ipv6/ca.crt
cert ipv6/ipv6.crt
key ipv6/ipv6.key
ns-cert-type server
tls-auth ipv6/ta.key 1
cipher AES-256-CBC
verb 3

Vif du sujet

10.0.98.1 (concentrateur VPN) et 10.0.98.4 (client VPN) se pinguent en IPv4 sur le segment ethernet du VPN.
Nous pouvons désormais avancer

  • Activons l’IPv6 forwarding sur notre concentrateur VPN
    # echo "net.ipv6.conf.all.forwarding = 1" >> /etc/sysctl.conf
    # sysctl -p
  • Activons le proxy NDP (qui va nous servir a relayer les packets IPv6 entre eth0 et tap0)
    # echo "net.ipv6.conf.all.proxy_ndp = 1" >> /etc/sysctl.conf
    # sysctl -p

    Notre Concentrateur VPN est quasiment prêt à forwarder des trames IPv6.

  • Installons radvd et configurons-le (/etc/radvd.conf) :
    interface tap0
    {
           AdvSendAdvert on;
           MinRtrAdvInterval 3;
           MaxRtrAdvInterval 10;

           prefix 2001:758:f00:x::/64
           {
                   AdvOnLink on;
                   AdvAutonomous on;
                   AdvRouterAddr on;
           };
    };
  • Attribuons une adresse IPv6 a notre interface tap0:
    # ip -6 a add  2001:758:f00:x:x::1/64 dev tap0
  • Nous pouvons lancer radvd
    # /etc/init.d/radvd start
  • Vérifions sur le client que nous avons bien des trames IPv6 qui arrivent (si tap1 est l’interface VPN du côté client)
    # tcpdump -t -n -i tap1 -s 512 -vv ip6 or proto ipv6

    devrait donner des trames ainsi :

    IP6 (hlim 255, next-header ICMPv6 (58) payload length: 56) fe80::94c7:eaff:fe5e:ea46 > ff02::1: [icmp6 sum ok] ICMP6, router advertisement, length 56
            hop limit 64, Flags [none], pref medium, router lifetime 30s, reachable time 0s, retrans time 0s
              prefix info option (3), length 32 (4): 2001:758:f00:8::/64, Flags [onlink, auto, router], valid time 2592000s, pref. time 604800s
                0x0000:  40e0 0027 8d00 0009 3a80 0000 0000 2001
                0x0010:  0758 0f00 0008 0000 0000 0000 0000
              source link-address option (1), length 8 (1): 96:c7:ea:5e:ea:46
                0x0000:  96c7 ea5e ea46
  • Notre client VPN obtient une IPv6 grâce au radvd de notre concentrateur VPN (par exemple 2001:758:f00:x:ffff:ffff:ffff:ffff/64)
  • Configuration ndp proxy du concentrateur
    # ip -6 neigh add proxy 2001:758:f00:x:x::1 dev tap0
    # ip -6 neigh add proxy 2001:758:f00:x:ffff:ffff:ffff:ffff dev eth0

    Ainsi les packets a destination de 2001:758:f00:x:ffff:ffff:ffff:ffff arrivant sur eth0 seront automatiquement traite par 2001:758:f00:x:x::1 se trouvant sur le meme segment ethernet que 2001:758:f00:x:ffff:ffff:ffff:ffff

  • Test de la configuration :
    • Sur le client OpenVPN
      # ping6 2001:758:f00:x:x::1
    • Sur le concentrateur OpenVPN
      # ping6 2001:758:f00:x:ffff:ffff:ffff:ffff

    Si les deux ping6 passent vous pouvez continuer, sinon vous avez un soucis lors d’une des etapes précédentes.

Tests de pings

On peut essayer de pinger Google depuis le client

# ping6 ipv6.google.com

Et pinger le client depuis une machine hors du VPN

# ping6 2001:758:f00:x:ffff:ffff:ffff:ffff

Si tout passe c’est gagné, vous avez donné une connectivité IPv6 à une machine over VPN!

ERRATA

Attention openvpn à chaque connexion attribura dynamiquement et aléatoirement une adresse mac à l’interface tap1 du client du vpn.
Ainsi radvd se basant sur l’adresse mac de l’interface reseau afin d’attribuer une ipv6 pourra poser des problèmes du coté du concentrateur.
En effet il faut lancer la commande permettant au concentrateur via le proxy ndp de forwarder les trames.
C’est donc ultra pas pratique.
Plusieurs solutions s’offrent à vous en outre.
1) attribuer un nouveau subnet ipv6 (autre que celui attribué à eth0) sur votre tap0 du concentrateur vpn, ainsi vous vous évitez toute la partie concernant le proxy ndp.
2) Attribuer des ips fixes aux clients qui devront les donner manulement de leur coté à leur interface.
3) scripter via les scripts up.sh et down.sh fourni avec openvpn en natif.

Annexes

Côté serveur

2: eth0: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 100
    link/ether 00:30:48:82:ec:0e brd ff:ff:ff:ff:ff:ff
    inet 81.93.xx.xx/24 brd 81.93.xx.xx scope global eth0
    inet6 2001:758:f00:330:xx:xx:xx:xx/64 scope global
       valid_lft forever preferred_lft forever
    inet6 2001:758:f00:x::1/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::230:48ff:fe82:ec0e/64 scope link
       valid_lft forever preferred_lft forever

7: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 100
    link/ether 96:c7:ea:5e:ea:46 brd ff:ff:ff:ff:ff:ff
    inet 10.0.98.1/24 brd 10.0.98.255 scope global tap0
    inet6 2001:758:f00:x:x::1/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::94c7:eaff:fe5e:ea46/64 scope link
       valid_lft forever preferred_lft forever

Côté client

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
    link/ether 00:1c:c0:a7:b9:1f brd ff:ff:ff:ff:ff:ff
    inet 95.xx.xx.xx/24 brd 95.xx.xx.255 scope global eth0
    inet6 fe80::xx:xx:xx:xx/64 scope link
       valid_lft forever preferred_lft forever
9: tap1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 100
    link/ether 00:ff:51:47:f0:57 brd ff:ff:ff:ff:ff:ff
    inet 10.0.98.4/24 brd 10.0.98.255 scope global tap1
    inet6 2001:758:f00:x:ffff:ffff:ffff:ffff/64 scope global dynamic
       valid_lft 2591993sec preferred_lft 604793sec
    inet6 fe80::2ff:51ff:fe47:f057/64 scope link
       valid_lft forever preferred_lft forever