3 changed files with 639 additions and 0 deletions
|
After Width: | Height: | Size: 420 KiB |
|
After Width: | Height: | Size: 328 KiB |
@ -0,0 +1,639 @@ |
|||
--- |
|||
title: "Fibre Orange : Remplacer sa Livebox par un routeur CentOS Stream 8" |
|||
date: '2023-12-14T00:00:00+02:00' |
|||
#description: "" |
|||
opensource: |
|||
- CentOS Stream |
|||
topics: |
|||
- Network |
|||
resources: |
|||
#- src: '*.yaml' |
|||
- src: '*.png' |
|||
- src: '*.jpeg' |
|||
--- |
|||
|
|||
Je suis abonné à l'offre Fibre d'Orange depuis 2016. |
|||
Et si je suis globalement satisfait de la qualité du réseau, je ne peux pas en dire autant de la Livebox fournie par Orange. |
|||
Les limitations sont nombreuses pour un geek souhaitant faire de l'hébergement de services à la maison : une seule plage IPv6 en /64, pas de configuration possible des tables de routage pour avoir plusieurs sous-réseaux IPv4, etc. |
|||
J'ai donc décidé de remplacer la Livebox par un routeur basé sur CentOS Stream 8. |
|||
Et l'aventure ne fut pas un long fleuve tranquille ! |
|||
Cet article présente la configuration que j'ai mise en place et qui me donne aujourd'hui satisfaction. |
|||
|
|||
<!--more--> |
|||
|
|||
## Besoin |
|||
|
|||
En tant que geek, j'ai des besoins bien particuliers quant au routeur qui gère mon accès internet : |
|||
|
|||
- Segmenter mon réseau en 5 sous-réseaux : Administration, DMZ, LAN, IoT et Invité. |
|||
- Offrir une plage d'adresse IPv4 et IPv6 à chaque sous-réseau. |
|||
- Héberger un Homelab à la maison (avec flux sortants et **entrants**) |
|||
- Faire tourner des VMs pour héberger mes services |
|||
|
|||
J'ai volontairement laissé de coté : |
|||
|
|||
- Le support des chaînes TV d'Orange |
|||
- Le support de la téléphonie Orange |
|||
|
|||
## Matériel |
|||
|
|||
Pour le serveur en lui-même, j'ai choisi un HP DL20 Gen9 pour les raisons suivantes : |
|||
|
|||
- J'avais déjà du matériel HP dans le Lab |
|||
- Taille plutôt compacte (format lame 1U, court) |
|||
- Silencieux (une fois démarré, on n'entend quasiment pas les ventilateurs) |
|||
- Extensible |
|||
|
|||
Je l'ai déniché pour 660 € sur eBay avec les caractéristiques suivantes : |
|||
|
|||
- 2 disques 3,5 pouces de 4 To chacun, sur carte RAID matérielle |
|||
- CPU [Intel Xeon E3-1270 v6](https://www.cpubenchmark.net/cpu.php?cpu=Intel+Xeon+E3-1270+v6+%40+3.80GHz&id=3014) |
|||
- 48 Go de DDR4 ECC |
|||
- Carte réseau supplémentaire Intel I350 au format "FlexibleLOM", avec 4 ports RJ-45 |
|||
|
|||
{{< attachedFigure src="hp-dl20-gen9.png" title="Serveur HP DL20 Gen9, vue de face, vue de dos." >}} |
|||
|
|||
Pour me raccorder au réseau fibre optique d'Orange, j'ai conservé l'ONT (*Optical Network Termination*) qui m'a été fourni avec la Livebox. |
|||
D'un coté, je branche la jarretière optique, et de l'autre je branche le câble RJ-45 qui va jusqu'au serveur HP. |
|||
|
|||
{{< attachedFigure src="Boitier-Fibre-Orange.jpeg" title="Boitier Fibre Orange. Source: [Wikipedia](https://commons.wikimedia.org/wiki/File:Boitier-Fibre-Orange_-_IMG_6456.jpg)" >}} |
|||
|
|||
## Logiciel |
|||
|
|||
Au moment où j'ai commencé à installer le serveur, la dernière version publiée de [CentOS Stream](https://www.centos.org/centos-stream/) était la 8. |
|||
Mais partez plutôt sur la dernière version disponible ! |
|||
|
|||
L'installation de CentOS Stream s'effectue, comme la majorité des distributions Linux : |
|||
|
|||
- Télécharger l'[ISO de CentOS Stream](https://www.centos.org/download/) |
|||
- [Copier l'ISO sur une clé USB](https://wiki.centos.org/HowTos(2f)InstallFromUSBkey.html) |
|||
- Démarrer le serveur et booter sur la clé USB |
|||
|
|||
## Spécificités de l'offre Fibre Orange |
|||
|
|||
L'offre Fibre d'Orange a quelques spécificités, désormais [bien connues des geeks de lafibre.info](https://lafibre.info/remplacer-livebox/) : |
|||
|
|||
- [Patcher le client DHCP](https://lafibre.info/remplacer-livebox/en-cours-remplacer-sa-livebox-par-un-routeur-ubiquiti-edgemax/msg320099/#msg320099) pour envoyer les paquets avec la priorité 802.1p numéro 6. |
|||
- Configurer l'interface réseau pour utiliser le VLAN 832. |
|||
- [Configurer le client DHCP](https://lafibre.info/remplacer-livebox/cacking-nouveau-systeme-de-generation-de-loption-90-dhcp/) pour envoyer le login et le mot de passe Orange. |
|||
- [Assurer la cohérence IPv4/IPv6](https://lafibre.info/remplacer-livebox/durcissement-du-controle-de-loption-9011-et-de-la-conformite-protocolaire/) |
|||
|
|||
Cet article couvre l'ensemble de ces points. |
|||
|
|||
Il est à noter qu'à partir du noyau 5.7, le filtre *"egress"* de *netfilter* devrait permettre la capture des paquets DHCPv4 et l'étiquetage de leur priorité. |
|||
Le client DHCP patché ne serait alors plus nécessaire. |
|||
|
|||
> Commit e687ad60af09 ("netfilter: add netfilter ingress hook after handle_ing() under unique static key") introduced the ability to classify packets on ingress. |
|||
> |
|||
> Allow the same on egress. |
|||
> |
|||
> This hook is also useful for NAT46/NAT64, tunneling and filtering of locally generated af_packet traffic such as dhclient. |
|||
|
|||
Source: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8537f78647c072bdb1a5dbe32e1c7e5b13ff1258 |
|||
|
|||
## Installation du client DHCP patché |
|||
|
|||
J'ai backporté le [patch de Zoc](https://lafibre.info/remplacer-livebox/en-cours-remplacer-sa-livebox-par-un-routeur-ubiquiti-edgemax/msg320099/#msg320099) dans les RPMs dhclient de CentOS Stream 8. |
|||
Les sources sont dans le dépot Git [nmasse-itix/dhclient-orange](https://github.com/nmasse-itix/dhclient-orange) et les RPMs sont disponibles publiquement sur un [partage Backblaze B2](https://f003.backblazeb2.com/file/dhclient-orange/dhclient-orange.repo). |
|||
|
|||
Installer le client DHCP patché. |
|||
|
|||
```sh |
|||
sudo curl -o /etc/yum.repos.d/dhclient-orange.repo https://f003.backblazeb2.com/file/dhclient-orange/dhclient-orange.repo |
|||
sudo dnf remove dhcp-client |
|||
sudo dnf install dhcp-client-orange-isp |
|||
``` |
|||
|
|||
Configurer NetworkManager pour qu'il utilise dhclient plutôt que son client DHCP interne. |
|||
|
|||
{{< highlightFile "/etc/NetworkManager/conf.d/dhclient.conf" "ini" "hl_lines=2" >}} |
|||
[main] |
|||
dhcp=dhclient |
|||
{{< / highlightFile >}} |
|||
|
|||
Redémarrer NetworkManager. |
|||
|
|||
```sh |
|||
sudo systemctl restart NetworkManager |
|||
``` |
|||
|
|||
## Configuration du client DHCP pour l'authentification Orange |
|||
|
|||
Pour configurer le client DHCP pour l'authentification Orange, il vous faudra trois choses : |
|||
|
|||
- L'adresse MAC de la Livebox que vous souhaitez remplacer (vous pouvez la trouver sur une étiquette sous la Livebox). Notez que dans le fichier de configuration ci-dessous, il faudra préfixer l'adresse MAC par "**01:**". |
|||
- La chaîne de caractère à envoyer dans l'option 90. Utilisez pour cela [le calculateur mis à disposition par la communauté lafibre.info](https://jsfiddle.net/kgersen/3mnsc6wy). |
|||
- Le nom de l'interface réseau sur laquelle vous avez connecté l'ONT Orange (**eno2** dans l'exemple ci-dessous), suffixé par **.832**. |
|||
|
|||
Saisir le contenu du fichier /etc/dhcp/dhclient.conf. |
|||
|
|||
{{< highlightFile "/etc/dhcp/dhclient.conf" "c" "hl_lines=4 7-8" >}} |
|||
option rfc3118-authentication code 90 = string; |
|||
option dhcp-client-identifier code 61 = string; |
|||
|
|||
interface "eno2.832" { |
|||
send vendor-class-identifier "sagem"; |
|||
send user-class "+FSVDSL_livebox.Internet.softathome.Livebox4"; |
|||
send dhcp-client-identifier 01:AA:BB:CC:DD:EE:FF; |
|||
send rfc3118-authentication 00:00:00:00:00:00:00:00:00:00:00:1a:09:00:00:05:58:01:03:41:01:0B:66:74:69:2F:64:75:6D:6D:79:3c:12:31:32:33:34:35:36:37:38:39:30:31:32:33:34:35:36:03:13:41:b9:80:f2:ea:3f:06:3b:2b:e7:08:ac:ec:9c:38:9e:ba; |
|||
request subnet-mask,routers,domain-name,broadcast-address,dhcp-lease-time,dhcp-renewal-time,dhcp-rebinding-time,rfc3118-authentication; |
|||
} |
|||
{{< / highlightFile >}} |
|||
|
|||
## Configuration de l'interface réseau pour utiliser le VLAN 832 |
|||
|
|||
Configurer l'interface réseau (ici **eno2**) à l'aide de NetworkManager pour utiliser le VLAN 832. |
|||
|
|||
```sh |
|||
sudo nmcli con add type ethernet con-name eno2.832 autoconnect yes ipv4.method disabled ipv6.method ignore connection.interface-name eno2 |
|||
sudo nmcli con add type vlan dev eno2 con-name eno2.832 id 832 egress "0:0,1:0,2:0,3:0,4:0,5:0,6:6,7:0" autoconnect yes ipv4.method auto ipv6.method ignore |
|||
``` |
|||
|
|||
À ce stade, vous devez obtenir une adresse IPv4 publique lorsque vous activez l'interface. |
|||
|
|||
```sh |
|||
sudo nmcli con up eno2.832 |
|||
``` |
|||
|
|||
La suite de l'article est très dépendante de choix que j'ai pu faire par ailleurs dans mon réseau domestique. |
|||
Aussi, considérez la comme une indication plus qu'un tutoriel pas à pas. |
|||
|
|||
## Configuration nécessaire à IPv6 |
|||
|
|||
Activer le routage des paquets IPv4 et IPv6. |
|||
Ne pas oublier d'adapter le nom de l'interface réseau ! |
|||
|
|||
{{< highlightFile "/etc/sysctl.d/99-fibre-orange.conf" "ini" "hl_lines=3" >}} |
|||
net.ipv4.ip_forward=1 |
|||
net.ipv6.conf.all.forwarding=1 |
|||
net/ipv6/conf/eno2.832/accept_ra=2 |
|||
net.ipv4.conf.all.src_valid_mark=1 |
|||
{{< / highlightFile >}} |
|||
|
|||
Recharger les paramètres noyaux avec la commande **sysctl**. |
|||
|
|||
```sh |
|||
sudo sysctl --system |
|||
``` |
|||
|
|||
Configurer ensuite le client DHCPv6 pour l'authentification Orange. |
|||
Même mode opératoire que pour IPv4, il vous faudra trois choses : |
|||
|
|||
- L'adresse MAC de la Livebox que vous souhaitez remplacer (vous pouvez la trouver sur une étiquette sous la Livebox). Notez que dans le fichier de configuration ci-dessous, il faudra préfixer l'adresse MAC par "**00:03:00:01:**". |
|||
- La chaîne de caractère à envoyer dans l'option 11. Utilisez pour cela [le calculateur mis à disposition par la communauté](https://jsfiddle.net/kgersen/3mnsc6wy). |
|||
- Le nom de l'interface réseau sur laquelle vous avez connecté l'ONT Orange (**eno2** dans l'exemple ci-dessous), suffixé par **.832**. |
|||
|
|||
Saisir le contenu du fichier /etc/dhcp/dhclient6.conf. |
|||
|
|||
{{< highlightFile "/etc/dhcp/dhclient.conf" "c" "hl_lines=5 9-10" >}} |
|||
option dhcp6.auth code 11 = string; |
|||
option dhcp6.vendorclass code 16 = string; |
|||
option dhcp6.userclass code 15 = string; |
|||
|
|||
interface "eno2.832" { |
|||
send dhcp6.vendorclass 00:00:04:0e:00:05:73:61:67:65:6d; |
|||
send dhcp6.userclass 00:2b:46:53:56:44:53:4c:5f:6c:69:76:65:62:6f:78:2e:49:6e:74:65:72:6e:65:74:2e:73:6f:66:74:61:74:68:6f:6d:65:2e:6c:69:76:65:62:6f:78:34; |
|||
send dhcp6.vendor-opts 00:00:05:58:00:06:00:0e:49:50:56:36:5f:52:45:51:55:45:53:54:45:44; |
|||
send dhcp6.client-id 00:03:00:01:AA:BB:CC:DD:EE:FF; |
|||
send dhcp6.auth 00:00:00:00:00:00:00:00:00:00:00:1a:09:00:00:05:58:01:03:41:01:0B:66:74:69:2F:64:75:6D:6D:79:3c:12:31:32:33:34:35:36:37:38:39:30:31:32:33:34:35:36:03:13:41:b9:80:f2:ea:3f:06:3b:2b:e7:08:ac:ec:9c:38:9e:ba; |
|||
also request dhcp6.name-servers, dhcp6.vendorclass, dhcp6.userclass, dhcp6.auth; |
|||
} |
|||
{{< / highlightFile >}} |
|||
|
|||
Créer le script de *dispatch* pour NetworkManager. |
|||
Ce script sera appelé automatiquement par NetworkManager après un *up* ou un *down* de l'interface réseau et lancera le client DHCPv6 en mode *Prefix Delegation*. |
|||
Ne pas oublier d'adapter le nom de l'interface réseau ! |
|||
|
|||
{{< highlightFile "/etc/NetworkManager/dispatcher.d/99-orange-ipv6" "sh" "hl_lines=5" >}} |
|||
#!/bin/bash |
|||
|
|||
set -Eeuo pipefail |
|||
|
|||
if [ "${DEVICE_IFACE:-}" != "eno2.832" ]; then |
|||
exit 0 |
|||
fi |
|||
|
|||
# Set log file for this shell and all commands executed |
|||
exec &>>/var/log/orange-ipv6.log |
|||
trap 'ret=$? ; if [ $ret -gt 0 ]; then echo "NM dispatcher script called with action = ${NM_DISPATCHER_ACTION:-} finished at $(date -Isecond) with code $ret"; fi' EXIT ERR |
|||
|
|||
case "$NM_DISPATCHER_ACTION" in |
|||
up) |
|||
signal=TERM |
|||
while [ -f "/var/run/NetworkManager/dhclient6-$DEVICE_IFACE.pid" ] && pgrep -F "/var/run/NetworkManager/dhclient6-$DEVICE_IFACE.pid" &>/dev/null; do |
|||
if pkill -F /var/run/NetworkManager/dhclient6-$DEVICE_IFACE.pid --signal "$signal"; then |
|||
signal=KILL |
|||
sleep 5 |
|||
fi |
|||
done |
|||
dhclient -P -6 -cf /etc/dhcp/dhclient6.conf -lf "/var/lib/NetworkManager/dhclient-$CONNECTION_UUID-$DEVICE_IFACE.lease" -pf "/var/run/NetworkManager/dhclient6-$DEVICE_IFACE.pid" "$DEVICE_IFACE" |
|||
;; |
|||
down) |
|||
if [ -f "/var/run/NetworkManager/dhclient6-$DEVICE_IFACE.pid" ]; then |
|||
pkill -F /var/run/NetworkManager/dhclient6-$DEVICE_IFACE.pid || true |
|||
fi |
|||
;; |
|||
*) |
|||
;; |
|||
esac |
|||
|
|||
exit 0 |
|||
{{< / highlightFile >}} |
|||
|
|||
Créer le répertoire **/etc/dhcp/dhclient-exit-hooks.d**. |
|||
|
|||
```sh |
|||
sudo mkdir -p /etc/dhcp/dhclient-exit-hooks.d |
|||
``` |
|||
|
|||
Créer le script de *hook* pour dhclient. |
|||
Il sera appelé par le client DHCPv6 après obtention d'un préfixe IPv6 et a pour tâche d'affecter les adresses IPv6 aux différentes interfaces du serveur. |
|||
Ne pas oublier d'adapter le nom de l'interface réseau et le nom de vos interfaces réseaux internes (chez moi, elles s'appelle ivs1, ivs2, etc.) ! |
|||
|
|||
{{< highlightFile "/etc/dhcp/dhclient-exit-hooks.d/99-orange-ipv6" "sh" "hl_lines=5 12" >}} |
|||
#!/bin/bash |
|||
|
|||
set -Eeuo pipefail |
|||
|
|||
if [ "${interface:-}" != "eno2.832" ]; then |
|||
exit 0 |
|||
fi |
|||
|
|||
# Issue a log in case of error |
|||
trap 'ret=$? ; if [ "$ret" -gt 0 ]; then echo "dhclient hook script called with reason = ${reason:-} finished at $(date -Isecond) with code $ret"; fi' EXIT ERR |
|||
|
|||
ifprefix="ivs" |
|||
internal_ifaces="$(ifconfig -a -s | egrep -o "^($ifprefix)[0-9]+" | sort -V)" |
|||
external_iface="$interface" |
|||
|
|||
temp="$(mktemp -d -t orange.XXXXXX)" |
|||
trap 'rm -rf "$temp"' EXIT |
|||
|
|||
function log () { |
|||
if [ -n "${DEBUG:-}" ]; then |
|||
echo "$@" |
|||
fi |
|||
"$@" |
|||
} |
|||
|
|||
function cleanup_interface () { |
|||
local interface="$1" |
|||
current_ipv6_addr="$(ip -6 -br addr show dev "$interface" scope global | awk 'NR == 1 { print $3 }')" |
|||
if [ -n "$current_ipv6_addr" ]; then |
|||
log ip addr delete "$current_ipv6_addr" dev "$interface" || true |
|||
fi |
|||
} |
|||
|
|||
case "${reason:-}" in |
|||
BOUND6|REBIND6) |
|||
# This should be set on startup. To be safe, recheck here. |
|||
sysctl -q net/ipv6/conf/eno2.832/accept_ra=2 |
|||
|
|||
if [ -n "${new_ip6_prefix:-}" ] ; then |
|||
ipcalc -S 64 "$new_ip6_prefix" --no-decorate > "$temp/networks" |
|||
for interface in $internal_ifaces $external_iface; do |
|||
if [ "$interface" == "$external_iface" ]; then |
|||
# eno2.832 gets subnet 0 |
|||
ipv6_network="$(head -n 1 $temp/networks)" |
|||
else |
|||
if [[ "$interface" =~ ^ivs ]]; then |
|||
# ivsX gets subnet X (X is guaranted to start at 1) |
|||
n="${interface#ivs}" |
|||
else |
|||
echo "Unsupported interface: $interface" |
|||
continue |
|||
fi |
|||
ipv6_network="$(awk -v "net_id=$n" 'NR == net_id + 1 { print }' $temp/networks)" |
|||
fi |
|||
|
|||
# Determine current and previous IPv6 addresses |
|||
new_ipv6_addr="$(echo "$ipv6_network" | sed -r 's|::/([0-9]+)|::1/\1|')" |
|||
old_ipv6_addr="$(ip -6 -br addr show dev "$interface" scope global | awk 'NR == 1 { print $3 }')" |
|||
|
|||
# Only replace the previous IPv6 address if the new one is different |
|||
if [ "${new_ipv6_addr}" != "$old_ipv6_addr" ]; then |
|||
cleanup_interface "$interface" |
|||
log ip addr add "$new_ipv6_addr" dev "$interface" |
|||
fi |
|||
done |
|||
fi |
|||
;; |
|||
RELEASE) |
|||
for interface in $internal_ifaces; do |
|||
cleanup_interface "$interface" |
|||
done |
|||
;; |
|||
*) |
|||
;; |
|||
esac |
|||
|
|||
exit 0 |
|||
{{< / highlightFile >}} |
|||
|
|||
N'oubliez pas de rendre ces deux scripts exécutables. |
|||
|
|||
```sh |
|||
sudo chmod 755 /etc/NetworkManager/dispatcher.d/99-orange-ipv6 |
|||
sudo chmod 755 /etc/dhcp/dhclient-exit-hooks.d/99-orange-ipv6 |
|||
``` |
|||
|
|||
Pour que l'IPv6 fonctionne, il faut correctement étiqueter les paquets DHCPv6 en priorité 6. |
|||
Pour cela, j'utilise **nftables**. |
|||
Le script est très dépendant de mes choix de réseau, je vous invite donc à le prendre comme un exemple pour créer le votre ensuite. |
|||
|
|||
Désactiver **firewalld**. |
|||
|
|||
```sh |
|||
sudo systemctl stop firewalld |
|||
sudo systemctl disable firewalld |
|||
sudo systemctl mask firewalld |
|||
``` |
|||
|
|||
Éditer le contenu du fichier **/etc/sysconfig/nftables.conf**. |
|||
|
|||
{{< highlightFile "/etc/sysconfig/nftables.conf" "ini" "hl_lines=" >}} |
|||
# Uncomment the include statement here to load the default config sample |
|||
# in /etc/nftables for nftables service. |
|||
|
|||
include "/etc/nftables/itix.nft" |
|||
|
|||
# To customize, either edit the samples in /etc/nftables, append further |
|||
# commands to the end of this file or overwrite it after first service |
|||
# start by calling: 'nft list ruleset >/etc/sysconfig/nftables.conf'. |
|||
{{< / highlightFile >}} |
|||
|
|||
Créer le fichier **/etc/nftables/update.nft**. |
|||
|
|||
{{< highlightFile "/etc/nftables/update.nft" "ini" "hl_lines=" >}} |
|||
#!/usr/sbin/nft -f |
|||
|
|||
flush table inet itix-fw |
|||
delete table inet itix-fw |
|||
flush table ip itix-nat |
|||
delete table ip itix-nat |
|||
|
|||
include "/etc/nftables/itix.nft" |
|||
{{< / highlightFile >}} |
|||
|
|||
Créer le fichier **/etc/nftables/itix.nft**. |
|||
|
|||
{{< highlightFile "/etc/nftables/itix.nft" "c" "hl_lines=42 45 57 72 74 76 86" >}} |
|||
#!/usr/sbin/nft -f |
|||
|
|||
table inet itix-fw { |
|||
chain Public-Services { |
|||
# Allow Ping |
|||
icmp type echo-request counter accept |
|||
|
|||
# Allow SSH |
|||
tcp dport { 22 } counter accept |
|||
} |
|||
|
|||
chain Forward-IPv6-from-Internet { |
|||
# Allow IPv6 ICMP |
|||
ip6 nexthdr ipv6-icmp counter accept |
|||
|
|||
# Enable TCP/UDP ports > 1024 |
|||
tcp dport > 1024 counter accept |
|||
udp dport > 1024 counter accept |
|||
} |
|||
|
|||
chain Orange-IPv6-Priority { |
|||
# DSCP is "Differenciated Service Code Point". See RFC 4594. |
|||
# CS6 is "Class Selector 6 (Internetwork Control)". |
|||
icmpv6 type { nd-neighbor-solicit, nd-router-solicit } ip6 dscp set cs6 meta priority set 0:6 counter |
|||
udp sport { dhcpv6-client, dhcpv6-server } ip6 dscp set cs6 meta priority set 0:6 counter |
|||
} |
|||
|
|||
chain Input { |
|||
type filter hook input priority filter + 20 |
|||
policy drop |
|||
|
|||
# Accept packets related to existing connections |
|||
ct state invalid counter drop |
|||
ct state { established, related } counter accept |
|||
|
|||
# Loopback |
|||
iifname lo counter accept |
|||
|
|||
# Accept all ethernet frames on the public interface so that we can then handle the VLANs |
|||
iifname eno2 accept |
|||
# Filter packets arriving on VLAN 832 |
|||
iifname eno2.832 counter jump Public-Services |
|||
|
|||
# Internal Interfaces |
|||
iifname { ivs1, ivs2, ivs3, ivs4, ivs5 } counter accept |
|||
} |
|||
|
|||
chain Output { |
|||
type filter hook output priority filter + 20 |
|||
policy accept |
|||
|
|||
# Accept packets related to existing connections |
|||
ct state invalid counter drop |
|||
ct state { established, related } counter accept |
|||
|
|||
# Tag all DHCPv6 packets with priority 6 |
|||
oifname eno2.832 counter jump Orange-IPv6-Priority |
|||
} |
|||
|
|||
chain Forward { |
|||
type filter hook forward priority filter + 20 |
|||
policy drop |
|||
|
|||
# Accept packets related to existing connections |
|||
ct state invalid counter drop |
|||
ct state { established, related } counter accept |
|||
|
|||
# Loopback |
|||
iifname lo counter accept |
|||
|
|||
# From the internal network to the internet |
|||
iifname { ivs1, ivs2, ivs3, ivs4, ivs5 } oifname eno2.832 counter accept |
|||
# From the internal network to the internal network |
|||
iifname { ivs1, ivs2, ivs3, ivs4, ivs5 } oifname { ivs1, ivs2, ivs3, ivs4, ivs5 } counter accept |
|||
# From the internet to the internal network |
|||
iifname eno2.832 oifname { ivs1, ivs2, ivs3, ivs4, ivs5 } counter jump Forward-IPv6-from-Internet |
|||
} |
|||
} |
|||
|
|||
table ip itix-nat { |
|||
chain Post-Routing { |
|||
type nat hook postrouting priority srcnat |
|||
policy accept |
|||
|
|||
# Masquerade all connections to the Internet |
|||
iifname { ivs1, ivs2, ivs3, ivs4, ivs5 } oifname eno2.832 counter masquerade |
|||
} |
|||
|
|||
} |
|||
{{< / highlightFile >}} |
|||
|
|||
Activer et démarrer le service **nftables**. |
|||
|
|||
```sh |
|||
sudo systemctl enable nftables |
|||
sudo systemctl start nftables |
|||
``` |
|||
|
|||
Vérifier avec la commande **sudo nft list tables** que les deux tables **itix-fw** et **itix-nat** ont bien été chargées. |
|||
|
|||
A ce moment là, vous pouvez essayer de faire un **nmcli con down eno2.832** puis **nmcli con up eno2.832** et vérifier que vous avez bien une adresse IPv4 publique et une adresse IPv6 globale. |
|||
|
|||
## Vérification périodique et cohérence IPv4/IPv6 |
|||
|
|||
Orange applique des règles de cohérence entre les protocoles IPv4 et IPv6. |
|||
Rien n'est documenté officiellement, mais sur le forum [lafibre.info](https://lafibre.info/remplacer-livebox/durcissement-du-controle-de-loption-9011-et-de-la-conformite-protocolaire/) quelques indications ont été données. |
|||
|
|||
Pour mettre en oeuvre ces règles, j'ai développé un script qui vérifie que les piles IPv4 et IPv6 sont opérationnelles et force un nouveau cycle DHCPv4 + DHCPv6 si nécessaire. |
|||
Pour éviter tout problème, je force également un renouvellement des baux DHCP toutes les 12 heures. |
|||
|
|||
{{< highlightFile "/usr/local/bin/fibre-orange" "sh" "hl_lines=5" >}} |
|||
#!/bin/bash |
|||
|
|||
set -Eeuo pipefail |
|||
|
|||
ORANGE_IFACE="eno2.832" |
|||
|
|||
declare -a TARGET_IPV4=("8.8.8.8" "8.8.4.4" "1.1.1.1" "1.0.0.1" "208.67.222.222" "208.67.220.220") |
|||
declare -a TARGET_IPV6=("2001:4860:4860::8888" "2001:4860:4860::8844" "2606:4700:4700::1111" "2606:4700:4700::1001" "2620:119:53::53" "2620:119:35::35") |
|||
|
|||
function help () { |
|||
echo "Usage: $0 {help|health-check|renew}" |
|||
} |
|||
|
|||
function error () { |
|||
echo "$1" >&2 |
|||
} |
|||
|
|||
function msg () { |
|||
echo "$1" |
|||
} |
|||
|
|||
function die () { |
|||
error "$1" "$@" |
|||
exit 1 |
|||
} |
|||
|
|||
function ping () { |
|||
/bin/ping "$1" -c 4 -I "$ORANGE_IFACE" -n -q -W 10 "$2" > /dev/null 2>&1 |
|||
} |
|||
|
|||
function orange_healthcheck () { |
|||
declare ipv4_check=0 |
|||
for ipv4 in ${TARGET_IPV4[@]}; do |
|||
if ping -4 "$ipv4"; then |
|||
ipv4_check=1 |
|||
else |
|||
msg "$ipv4 is not reachable!" |
|||
fi |
|||
done |
|||
|
|||
if [ "$ipv4_check" == "0" ]; then |
|||
error "IPv4 stack is down!" |
|||
fi |
|||
|
|||
declare ipv6_check=0 |
|||
for ipv6 in ${TARGET_IPV6[@]}; do |
|||
if ping -6 "$ipv6"; then |
|||
ipv6_check=1 |
|||
else |
|||
msg "$ipv6 is not reachable!" |
|||
fi |
|||
done |
|||
|
|||
if [ "$ipv6_check" == "0" ]; then |
|||
error "IPv6 stack is down!" |
|||
fi |
|||
|
|||
if [[ "$ipv4_check" == "0" || "$ipv6_check" == "0" ]]; then |
|||
return 1 |
|||
fi |
|||
|
|||
return 0 |
|||
} |
|||
|
|||
function kill_process () { |
|||
declare signal=TERM |
|||
while :; do |
|||
if [ -f "/var/run/NetworkManager/$1-$ORANGE_IFACE.pid" ] && pkill -F /var/run/NetworkManager/$1-$ORANGE_IFACE.pid --signal "$signal"; then |
|||
msg "Killed $1 with $signal!" |
|||
signal=KILL |
|||
sleep 5 |
|||
else |
|||
break |
|||
fi |
|||
done |
|||
|
|||
return 0 |
|||
} |
|||
|
|||
function is_dhclient4_running () { |
|||
if [ ! -f /var/run/NetworkManager/dhclient-$ORANGE_IFACE.pid ] || ! pgrep -F /var/run/NetworkManager/dhclient-$ORANGE_IFACE.pid &>/dev/null; then |
|||
return 1 |
|||
fi |
|||
return 0 |
|||
} |
|||
|
|||
function orange_renew () { |
|||
# Stop all dhclient instances |
|||
kill_process dhclient6 |
|||
kill_process dhclient |
|||
|
|||
# Sometimes the "nmcli device reapply" fails to restart the DHCP client. |
|||
# Monitor the dhclient process to know when it succeeded. |
|||
while ! is_dhclient4_running; do |
|||
nmcli device reapply "$ORANGE_IFACE" |
|||
sleep 30 |
|||
done |
|||
|
|||
return 0 |
|||
} |
|||
|
|||
case "${1:-}" in |
|||
health-check) |
|||
if ! orange_healthcheck; then |
|||
error "Renewing IPv4 and IPv6 DHCP leases..." |
|||
nmcli connection down $ORANGE_IFACE |
|||
sleep 2 |
|||
nmcli connection up $ORANGE_IFACE |
|||
fi |
|||
;; |
|||
renew) |
|||
orange_renew |
|||
;; |
|||
help) |
|||
help |
|||
;; |
|||
*) |
|||
error "Unkown action '${1:-}'!" |
|||
help |
|||
exit 1 |
|||
;; |
|||
esac |
|||
|
|||
exit 0 |
|||
{{< / highlightFile >}} |
|||
|
|||
Rendre le script exécutable. |
|||
|
|||
```sh |
|||
sudo chmod 755 /usr/local/bin/fibre-orange |
|||
``` |
|||
|
|||
Créer la crontab associée pour lancer ce script périodiquement. |
|||
|
|||
{{< highlightFile "/etc/cron.d/fibre-orange" "crontab" "hl_lines=" >}} |
|||
*/5 * * * * root /usr/local/bin/fibre-orange health-check |
|||
0 */12 * * * root /usr/local/bin/fibre-orange renew |
|||
{{< / highlightFile >}} |
|||
|
|||
## Conclusion |
|||
|
|||
Cela fait déjà plusieurs années que le serveur est installé et avec les dernières informations glanées sur le forum **lafibre.info**, la configuration est robuste. |
|||
Je n'ai pas tout expliqué dans l'article car la configuration que j'ai mise en place est complexe et n'apporterait pas grand chose pour le geek souhaitant remplacer sa Livebox par un routeur **CentOS Stream 8**. |
|||
|
|||
Par exemple, pour les sous-réseaux internes j'ai mis de l'**Open vSwitch**. |
|||
Pour acheminer les requètes HTTP & HTTPS, j'ai mis en place **Traefik**. |
|||
Pour héberger mes services, j'ai déployé **Kubernetes**. |
|||
Ça, je le garde pour un prochain article ! |
|||
Loading…
Reference in new issue