Hello tout le monde,
Après avoir beaucoup cherché comment remplacer la box, voici mon retour d'expérience.
Je suis client Bbox Pure Fibre avec option Débit+ (8G/1G). Tout d'abord, j'ai demandé l'ONT externe au support, ça s'est fait très simplement sans facturation supplémentaire.
Ensuite, j'ai cherché un routeur 10G
à un prix raisonnable. J'ai choisi un
iKOOLCORE R2 Max dont on peut retrouver des tests
sur ServeTheHome et
ici. J'ai pris la version avec CPU Intel N100 et refroidissement passif, le tout avec 8 Go de RAM et SSD de 128 Go, le minimum. J'en ai eu pour environ 340 €. La particularité de ce mini-PC (ou l'inconvénient diront certains) est qu'il n'a pas de SFP mais directement du RJ45, ce qui me convenait bien. Les interfaces 10G sont des Marvell Aquantia AQC113C
qui ne sont pour l'instant pas supportées sous FreeBSD donc pas d'OPNsense ou de pfSense possible sans passer par de la virtualisation (beurk).
Ce n'était pas un problème dans mon cas puisque je voulais une machine Linux pour bien comprendre ce que je faisais. J'ai installé Debian 13 Trixie qui n'est pas encore stable mais je voulais éviter un upgrade dans quelques mois.
Presque toute la configuration réseau est faite avec SystemD Networkd (sauf le DNS et le DHCPv4 qui sont gérés par Dnsmasq, bien que systemd-networkd
puisse aussi faire serveur DHCPv4). Je ne détaille pas la configuration Dnsmasq, elle n'a pas grand intérêt.
Merci à kgersen pour son aide sur
ce topic. Le fait que l'adresse IPv6 globale du routeur soit portée par la patte LAN était un peu déstabilisant pour moi au début mais ça fonctionne très bien comme ça

Voici la configuration présente dans
/etc/systemd/network. À noter que Debian 13 utilise SystemD version 257.
=== 10-lan0.link ===
[Match]
MACAddress=xx:xx:xx:xx:xx:xx
[Link]
Name=lan0
=== 10-lan0.network ===
[Match]
Name=lan0
[Network]
Bridge=lan
=== 10-lan1.link ===
[Match]
MACAddress=xx:xx:xx:xx:xx:xx
[Link]
Name=lan1
=== 10-lan1.network ===
[Match]
Name=lan1
[Network]
Bridge=lan
=== 10-lan2.link ===
[Match]
MACAddress=xx:xx:xx:xx:xx:xx
[Link]
Name=lan2
=== 10-lan2.network ===
[Match]
Name=lan2
[Network]
Bridge=lan
=== 10-lan.netdev ===
[NetDev]
Name=lan
Kind=bridge
=== 10-lan.network ===
[Match]
Name=lan
[Network]
Address=192.168.1.254/24
IPv4Forwarding=yes
# Voir aussi https://www.freedesktop.org/software/systemd/man/latest/systemd.network.html#IPv6Forwarding=
# "To ensure IPv6 packets forwarded, the global setting in networkd.conf(5) needs to be enabled."
IPv6Forwarding=yes
DHCPPrefixDelegation=yes
IPv6SendRA=yes
[DHCPPrefixDelegation]
UplinkInterface=wan
# Détermine les derniers octets de l'IP de l'interface
Token=::ffff
# Détermine les premiers octets de l'IP de l'interface
SubnetId=0xf
=== 10-wan0.link ===
[Match]
MACAddress=xx:xx:xx:xx:xx:xx
[Link]
Name=wan0
=== 10-wan0.network ===
[Match]
Name=wan0
[Network]
VLAN=wan
# Désactivation de l'autoconfiguration IPv6 de l'interface physique WAN, sinon
# elle reste en état "configuring" et bloque systemd-networkd-wait-online
LinkLocalAddressing=no
=== 10-wan.netdev ===
[NetDev]
Name=wan
Kind=vlan
# Ici, je clone la MAC de la Bbox, même si ça ne semble pas strictement nécessaire
MACAddress=xx:xx:xx:xx:xx:xx
[VLAN]
Id=100
=== 10-wan.network ===
[Match]
Name=wan
[Network]
IPv4Forwarding=yes
IPv6Forwarding=yes
IPv6AcceptRA=yes
DHCP=yes
[DHCPv6]
# Ne pas envoyer IA_NA
UseAddress=no
WithoutRA=solicit
DUIDType=link-layer
PrefixDelegationHint=::/64
IAID=1
Pour que la machine reçoive un préfixe en DHCPv6, il semble qu'il faille parfois attendre plusieurs dizaines de minutes voire plusieurs heures après le débranchement de la Bbox, même en clonant sa MAC. Le routeur Bouygues répond quelque chose comme "no prefixes available" pendant un bon moment (ça se voit avec
tcpdump -vvv -ni wan ip6 and udp and port 546). Une fois que ça fonctionne, on est tranquille et ça ne retombe pas (enfin tant qu'on ne remet pas la Bbox, j'imagine). Il ne faut pas hésiter à tester avec
https://github.com/kgersen/testdhcpv6pd/ aussi, ça dépanne bien.
J'ai renommé les 4 interfaces physiques en
lan0 à
lan2 et
wan0 pour rendre les choses plus lisibles. À noter qu'il semble nécessaire de rebooter pour que le renommage prenne effet.
On a donc 6 interfaces au total. 4 côté LAN :
lan0 à
lan2 font partie du bridge
lan :
# brctl show
bridge name bridge id STP enabled interfaces
lan 8000.xxxxxxxxxxxx no lan0
lan1
lan2
Et, côté WAN, on a l'interface physique
wan0 sur laquelle repose l'interface VLAN
wan.
Côté pare-feu, la configuration minimale à mettre dans
/etc/nftables.conf est la suivante :
#!/usr/sbin/nft -f
flush ruleset
table ip filter {
chain input {
type filter hook input priority filter; policy drop;
ct state established,related accept
ip protocol icmp accept
iifname lan accept
iifname lo accept
}
chain forward {
type filter hook forward priority filter; policy drop;
ct state established,related accept
iifname lan oifname wan accept comment "trafic du LAN vers le WAN"
}
chain output {
type filter hook output priority filter; policy accept;
}
}
table ip nat {
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
iifname lan oifname wan masquerade comment "source NAT en sortie sur le WAN"
}
}
table ip6 filter {
chain input {
type filter hook input priority filter; policy drop;
ct state established,related accept
iifname wan ip6 daddr fe80::/64 udp sport 547 udp dport 546 ct state new accept comment "DHCPv6"
meta l4proto ipv6-icmp accept
iifname lan accept
iifname lo accept
}
chain forward {
type filter hook forward priority filter; policy drop;
ct state established,related accept
iifname lan oifname wan accept comment "trafic du LAN vers le WAN"
}
}
Attention à bien ajouter cette directive dans
/etc/systemd/networkd.conf pour que le forwarding fonctionne en IPv6 !
[Network]
# Nécessaire seulement pour l'IPv6, voir
# https://www.freedesktop.org/software/systemd/man/latest/systemd.network.html#IPv6Forwarding=
IPv6Forwarding=yes
Et voilà, c'est tout ! Je n'ai mis aucun
sysctl à la main, j'ai laissé SystemD Networkd les gérer, ça permet d'avoir toute la configuration à un seul endroit.
Je suis très content du résultat, notamment car le routeur reboote en moins de 30 secondes. J'ai fait des tests de débit derrière le routeur en IPv4 (donc avec NAT) et le CPU et les cartes réseau semblent tenir la route et être en permanence autour de 50 °C, même quand j'atteins 6 ou 7 Gbit/s.
Le seul cas où un cœur du CPU sature est quand je dépasse les 6 Gbit/s sur une seule session TCP (
quand Bouygues ne décide pas de me couper l'IPv4). Mais, dès que je multiplie les sessions, par exemple dès
iperf3 -P3, les 4 cœurs se répartissent la charge et il n'y a plus de saturation. Même quand un des cœurs est à fond, il ne chauffe pas plus que d'habitude. Par contre on voit le compteur
dropped de
wan0 augmenter, j'imagine que ce n'est pas idéal. Quand je bride avec
iperf3, je vois que les dropped commencent à arriver autour de
-b 5.98G (rien à 5.9G). Dans tous les cas, je pense que ça ne se remarquera pas à l'usage.
N'hésitez pas si vous avez des questions ou des remarques sur la config !
EDIT du 20 février 2025 : j'ai enlevé la règle pour autoriser le DHCPv4, elle ne matche pas, le client utilisant des
raw sockets, voir
https://kb.isc.org/docs/aa-00378 pour un autre client DHCP.
On peut voir ça dans les logs de debug de NetworkD :
# systemctl service-log-level systemd-networkd.service debug
# networkctl reload
# networkctl reconfigure wan
# journalctl -u systemd-networkd -S -10min --grep raw
Feb 20 18:46:37 localhost systemd-networkd[464]: wan: DHCPv4 client: Received message from RAW socket, processing.
Feb 20 18:46:37 localhost systemd-networkd[464]: wan: DHCPv4 client: Received message from RAW socket, processing.
On peut capturer le trafic avec une règles de firewall de ce genre-là mais le drop n'a aucun effet :
table inet raw {
chain prerouting {
type filter hook prerouting priority raw; policy accept;
iifname wan udp sport 67 udp dport 68 nftrace set 1
iifname wan udp sport 67 udp dport 68 drop
}
}
Voici la sortie de
nft monitor qui montre bien un drop (mais NetworkD reçoit quand même le trafic) :
trace id 8a51b000 inet raw prerouting packet: iif "wan" ether saddr xx:xx:xx:xx:xx:xx ether daddr xx:xx:xx:xx:xx:xx ip saddr xx.xx.xx.xx ip daddr xx.xx.xx.xx.xx ip dscp cs6 ip ecn not-ect ip ttl 64 ip id 35120 ip protocol udp ip length 362 udp sport 67 udp dport 68 udp length 342 udp checksum 63469
trace id 8a51b000 inet raw prerouting rule iifname "wan" udp sport 67 udp dport 68 meta nftrace set 1 (verdict continue)
trace id 8a51b000 inet raw prerouting rule iifname "wan" udp sport 67 udp dport 68 drop (verdict drop)
Edit du 17 avril 2025 : on peut ajouter de l'
offload logiciel pour les sessions déjà établies à
nftables.conf, mais je déconseille de le faire. Lorsqu'on atteint un gros débit sur une seule connexion, ça
sature systématiquement un seul cœur, chose qui semble se produire légèrement moins souvent quand l'offload est désactivé.
Ça pourrait être intéressant avec XDP mais
xdp ne supporte pas encore les VLAN.