Prérequis necessecaires

Matériels :

  • 1 pc avec 2 cartes réseaux 1Gbps
  • 1 mediaconvert SFP-RJ45 1Gbps
  • 1 freebox
  • 1 boitier ONU
  • des cables ethernet RJ45


Informations :

il nous faut 4 informations pour monter le tunnel 4rd :

  • ip full stack fournie par free, la demande ce fait via votre compte sur www.free.fr de la forme aaa.aaa.aaa.aaa
  • ipv6 de la freebox, fournie par l'interface web de la freebox (ou l'application android freebox companion) de la forme bbbb:bbb:bb:bbbb:b:bbbb:bbbb:b
  • la mac adress de la freebox : étiquette sous le boitier de la freebox, de la forme la:fr:ee:bo:xm:ac
  • le border router, fournie via une requette dhcpv6 étendue des options s46 au serveur dhcp.


Récupération du border router

Prenez 1 pc sous linux, connectez son port réseau au port rj45 du media converter et branchez le gbic du boitier ONU dans la cage sfp du media converter.
Pour que la requette dhcp étendue passe, il faut changer la mac du port réseau du pc par celle de la freebox. En postulant que le port réseau s'appelle enp3s0 , tapez la commande suivante :

ip link set dev enp3s0 address la:fr:ee:bo:xm:ac

Puis montez le vlan 836 avec les commande suivantes :

ip link add link enp3s0 name fbx.836 type vlan id 836
ip link set dev fbx.836 up

note : fbx.836 étant un nom arbitraire, ça aurai pu être toto40 ou answer42 ;-)
Ensuite, dans /etc/dhcpcd.conf, ajoutez :

option dhcp6_s46_rule
option dhcp6_s64_br
option dhcp6_s46_dmr
option dhcp6_s46_v4v6bind
option dhcp6_s46_portparams
option dhcp6_s46_cont_mape
option dhcp6_s46_cont_mapt


Et lancez la requete dhcp suivante :

dhcpcd -6 -d -T fbx.836

le résultat devrait être du genre :

dhcpcd-7.0.8 starting
DUID xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx
fbx.836: IAID xx:xx:xx:xx
fbx.836: delaying IPv6 router solicitation for 0.9 seconds
fbx.836: soliciting an IPv6 router
fbx.836: sending Router Solicitation
fbx.836: Router Advertisement from fe80::xxx:xxxx:xxxx:xxxx
fbx.836: executing `/usr/lib/dhcpcd/dhcpcd-run-hooks' TEST
interface=fbx.836
pid=32339
protocol=ra
reason=TEST
ifcarrier=up
ifflags=4163
ifmtu=1500
ifwireless=0
nd1_acquired=1056
nd1_from=fe80::xxx:xxxx:xxxx:xxxx
nd1_mtu=1700
nd1_now=1056
nd1_prefix_information1_flags=L
nd1_prefix_information1_length=80
nd1_prefix_information1_pltime=14400
nd1_prefix_information1_prefix=xxxx:xxx:x:xxxx:xxxx::
nd1_prefix_information1_vltime=86400
nd1_source_address=xxxxxxxxxxxx
fbx.836: soliciting a DHCPv6 lease
fbx.836: delaying SOLICIT6 (xid 0x5b9f2f), next in 0.8 seconds
fbx.836: broadcasting SOLICIT6 (xid 0x5b9f2f), next in 1.0 seconds
fbx.836: ADV xxxx:xxx:x:xxxx:xxxx::xx/xxx from xxxx::xxx:xxxx:xxxx:xxxx
fbx.836: ADVERTISE6 received from fe80::xxx:xxxx:xxxx:xxxx
fbx.836: dhcp_envoption 89.0/4: malformed embedded option
fbx.836: executing `/usr/lib/dhcpcd/dhcpcd-run-hooks' TEST
interface=fbx.836
pid=32339
protocol=dhcp6
reason=TEST
ifcarrier=up
ifflags=4163
ifmtu=1500
ifwireless=0
new_dhcp6_client_id=xxxxxxxxxxxxxxxxxxxxxxxxxxxx
new_dhcp6_ia_na1_ia_addr1=xxxx:xxx:x:xxxx:xxxx::xx
new_dhcp6_ia_na1_ia_addr1_pltime=604800
new_dhcp6_ia_na1_ia_addr1_vltime=2592000%%v% new_dhcp6_ia_na1_iaid=ff000344
new_dhcp6_ia_na1_t1=3600
new_dhcp6_ia_na1_t2=7200
new_dhcp6_preference=255
new_dhcp6_reconfigure_accept=1
new_dhcp6_s46_cont_mape_s46_rule_ea_len=22
new_dhcp6_s46_cont_mape_s46_rule_flags=
new_dhcp6_s46_cont_mape_s46_rule_ipv4_prefix=xx.xxx.x.x
new_dhcp6_s46_cont_mape_s46_rule_prefix4_len=12
new_dhcp6_s46_cont_mape_s64_br=zzzz:zzz:zz:zzzz::zzzz
new_dhcp6_server_id=xxxxxxxxxxxxxxxxxxxxxxxxxxxx

(oui j'ai un peux caché quelques infos )
L'information pertinente est celle-ci:

new_dhcp6_s46_cont_mape_s64_br=zzzz:zzz:zz:zzzz::zzzz


Nous avons donc nos 4 infos : ip full stack : aa.aa.aa.aaa
ipv6 de la freebox : bbbb:bbb:bb:bbbb:b:bbbb:bbbb:b
mac de la freebox : la:fr:ee:bo:xm:ac
ipv6 du border router : zzzz:zzz:zz:zzzz::zzzz
Et j'ajouterais une 5eme : IPLOCAL, qui est l'ipv4 de votre réseau local, a définir par vous même.

Mise en place

Je passe rapidememnt sur l'installation de proxmox, voyez avec les tutos sur le web. Bon, moi j'ai choisi proxmox par fainéantise et parce que c'est bien (c)(r)(tm). Mais ça peux être réalisé aussi avec un linux from scratch + qemu + ovs ou tout autres soluce privatives comme vmware/virtualbox.

Installation et configuration du proxmox :

Aller voir la doc officielle pour la base, je n'aborderais que la partie pci-passthrough.
Commencez par modifier la ligne ci-dessus de /etc/default/grub, modifier la ligne :

GRUB_CMDLINE_LINUX_DEFAULT="intel_iommu=on quiet"

puis tapez :

update-grub

Ensuite, dans /etc/modules, ajouter :

vfio
vfio_iommu_type1
vfio_pci
vfio_virqfd

puis lancez la commande :

update-initramfs -u -k all'

et rebootez.

Pour que le pci-passtrough fonctionne, il faut que la carte réseau soit dans un groupe iommu, la commande suivante permet de le vérifier :

find /sys/kernel/iommu_groups/ -type l | sort -u

Le résultat devrais ressembler à ça :

find /sys/kernel/iommu_groups/ -type l | sort -u
/sys/kernel/iommu_groups/0/devices/0000:00:00.0
/sys/kernel/iommu_groups/10/devices/0000:00:1e.0
/sys/kernel/iommu_groups/11/devices/0000:00:1f.0
/sys/kernel/iommu_groups/11/devices/0000:00:1f.2
/sys/kernel/iommu_groups/11/devices/0000:00:1f.3
/sys/kernel/iommu_groups/12/devices/0000:03:00.0
/sys/kernel/iommu_groups/13/devices/0000:03:00.1
/sys/kernel/iommu_groups/1/devices/0000:00:02.0
/sys/kernel/iommu_groups/2/devices/0000:00:16.0
/sys/kernel/iommu_groups/2/devices/0000:00:16.3
/sys/kernel/iommu_groups/3/devices/0000:00:19.0
/sys/kernel/iommu_groups/4/devices/0000:00:1a.0
/sys/kernel/iommu_groups/5/devices/0000:00:1b.0
/sys/kernel/iommu_groups/6/devices/0000:00:1c.0
/sys/kernel/iommu_groups/7/devices/0000:00:1c.2
/sys/kernel/iommu_groups/8/devices/0000:00:1c.4
/sys/kernel/iommu_groups/9/devices/0000:00:1d.0


l'info pertinente est celle là :

/sys/kernel/iommu_groups/13/devices/0000:03:00.1

dans le cas particulier de mon exemple, c'est une carte réseau 2 ports gigabit, chaque port à son groupe iommu, donc ça fonctionne \o/

Installation et configuration de la vm vyos

Il faut télécharger l'iso vyos 1.1.8 et la transférer dans le dossier iso du store proxmox. elle sera disponible pour la création de la vm, exemple, depuis l'hyperviseur :

wget https://downloads.vyos.io/release/1.1.8/vyos-1.1.8-amd64.iso -O /STORE2/template/iso/

( a supposer que votre store soit /STORE2/template/iso évidement )
Créez 1 switche virtuel, je vous encourage grandement à utiliser un openvswitch plustôt que les ponts du kernel linux. Le gain de performances est énorme ainsi que l'économie de cpu ;-)
puis 1 vm ayant les caractéristiques suivantes :

2 vcpu (type host) / 1Go ram / 2Go disque (scsi en virtio)
1 carte réseau de type virtio, ce sera eth0 dans vyos
1 carte réseau de type hostpci0, sans romfile (undefined), ce sera eth1 dans vyos

Pour la suite, dans vyos, je considere que :

eth0 = carte INTERNE virtuelle (votre reseau local)
eth1 = carte EXTERNE physique (celle du pci-passtrough) qui portera le tunnel ipv4-in-ipv6 (4rd pour les intimes)
tun0 = le tunnel en lui même.

C'est partis !

Démarrez votre super-vm-de-la-mort-qui-tue, ouvrez votre session et passez en mode configure , nous allons configurer eth0:

set interfaces ethernet eth0 address 'IPLOCAL/masque'
set interfaces ethernet eth0 description 'INTERNE'
set interfaces ethernet eth0 duplex 'auto'
set interfaces ethernet eth0 smp_affinity 'auto'
set interfaces ethernet eth0 speed 'auto'

petit rappel : IPLOCAL/masque c'est l'ip du réseau local porté par le switch virtuel dans proxmox, c'est à vous de définir ce plan d'adressage. Passons maintenant à eth1 :

set interfaces ethernet eth1 duplex 'auto'
set interfaces ethernet eth1 mac 'la:fr:ee:bo:xm:ac'
set interfaces ethernet eth1 mtu '1700'
set interfaces ethernet eth1 smp_affinity 'auto'
set interfaces ethernet eth1 speed 'auto'
set interfaces ethernet eth1 vif 836 address 'dhcpv6'
set interfaces ethernet eth1 vif 836 address 'bbbb:bbb:bb:bbbb:b:bbbb:bbbb:b/128'
set interfaces ethernet eth1 vif 836 description 'VLAN 836'
set interfaces ethernet eth1 vif 836 ipv6 address 'autoconf'
set interfaces ethernet eth1 vif 836 ipv6 'disable-forwarding'
set interfaces ethernet eth1 vif 836 ipv6 dup-addr-detect-transmits '1'
set interfaces ethernet eth1 vif 836 mtu '1700'

Comme vous le voyez, c'est simple, on change la mac de eth1 par celle de la freebox, puis le mtu est configuré à 1700 , ensuite, ajout du vlan 835, demande d'ip auprès du nro en dhcp, et enfin, ajout de l'ip de la freebox.
eth1 à donc 2 ipv6. celle attribuée par le nro et celle de la freebox. Arrivé là, vous pouvez-considérer que vous avez internet mais en ipv6 seulememnt. Vous devriez pinguer votre vm depuis internet, sur ces 2 ip :-D
Maintenant, nous allons monter le tunnel ipv via l'interface tun0, ça ce fait en 2 etapes, voici la permière :

set policy route tun0-out description 'Freebox tunnel TCPMSS clamping'
set policy route tun0-out rule 100 protocol 'tcp'
set policy route tun0-out rule 100 set tcp-mss '1460'
set policy route tun0-out rule 100 tcp flags 'SYN'

ouais mais normalement le mtu et le mss ce déduisent l'un de l'autre alors pourquoi forcer ? Bizarrement, c'est necessaire, le mtu de tun0 sera bien de 1500 et en enlevant les 40 octets de l'entête tcp/ip on a bien 1460. J'ai essayé de ne pas forcer le mss mais le débit baisse. Là moi je passe la main aux experts réseaux, demandez leur le pourquoi du comment !
Deuxième étape :

set interfaces tunnel tun0 address 'aa.aa.aa.aaa/32'
set interfaces tunnel tun0 description 'IPv4 FULL STACK'
set interfaces tunnel tun0 encapsulation 'ipip6'
set interfaces tunnel tun0 local-ip 'bbbb:bbb:bb:bbbb:b:bbbb:bbbb:b'
set interfaces tunnel tun0 remote-ip 'zzzz:zzz:zz:zzzz::zzzz'
set interfaces tunnel tun0 mtu '1500'
set interfaces tunnel tun0 multicast 'enable'
set interfaces tunnel tun0 policy route 'tun0-out'
set protocols static interface-route 0.0.0.0/0 next-hop-interface 'tun0'

Explications : Comme vous le savez, tun0 est une interface virtuelle, avec la première commande, on attribue l'ip full stack, la dexième est un simple descriptif, la troisième crée le tunnel avec encapsulation ip dans ip6 (comprenez ipv4-in-ipv6) . la 4ème donne l'entrée du tunnel : l'ipv6 de la freebox (et donc de eth1) et la 5eme est l'ipv6 de la sortie du tunnel : le router border. :-D
la dernière, est la route par défaut pour la partie ipv4.
Un peux de nat pour faire de votre vm vyos une passerelle :

set nat source rule 5 outbound-interface 'tun0'
set nat source rule 5 source address 'IPLOCAL/masque'
set nat source rule 5 translation address 'masquerade'
set nat source rule 7 outbound-interface 'tun0'
set nat source rule 7 translation address 'masquerade'

A partir de ce moment vous pouvez considérer que vous avez internet sur la partie ipv4. Vous devriez pinguer votre ip full stack depuis l'internet :-D
Cette configuration minimale de vyos vous donne accès à internet en ipv4 comme le faisais la freebox server.
Pour l'ipv6 ce sera l'obget d'un autre arcticle (quand j'aurais fini de me former là dessus)

Bon vous avez un proxmox qui tourne, un vyos qui tourne.... ben vous pouvez vous lancer dans l'autohébergerment et pousser plus loin la dé-google-isation de votre life :-)

n'oubliez pas de configurer le firewall de vyos !!!!!