Replacing Orange Livebox router with a Linux box
Vincent Bernat
A few months ago, I moved back to France and I settled for Orange as an ISP with a bundle combining Internet and mobile subscription. In Switzerland, I was using my own router instead of the box provided by Swisscom. While there is an abundant documentation to replace the box provided by Orange, the instructions around a plain Linux box are kludgy. I am exposing here my own variation. I am only interested in getting IPv4/IPv6 access: no VoIP, no TV.
Update (2023-02)
Orange has updated the DHCP options required. The
value sent for rfc3118-authentication
and dhcp6.auth
are modified. We also
need to send dhcp-client-identifier
and dhcp6.client-id
. This page has been
updated accordingly.
Hardware#
Orange is using GPON for its FTTH deployment. Therefore, an ONT is needed to encapsulate and decapsulate Ethernet frames into GPON frames. Two form-factors are available. It can be small Huawei HG8010H box also acting as a media converter to Ethernet 1000BASE-T:
With a recent Livebox, Orange usually provides an SFP to be plugged inside the Livebox. For some reason I got the external ONT instead of the SFP version. As I have a Netgear GS110TP with two SFP ports, I have bought an SFP GPON FGS202 on eBay. It is the same model than Orange is providing with its Livebox 4. However, I did not find the motivation to test it.1
IPv4 configuration#
Internet is provided over VLAN 832 and configured with DHCPv4. The first step is
to setup the DHCP client to send some additional information, notably the RFC 3118 authentication string. It includes the alphanumeric connection
identifier prefixed by fti/
and the password provided by snail mail.
/etc/dhcp/dhclient.conf
looks like this:
option rfc3118-authentication code 90 = string; interface "internet" { timeout 60; retry 1; select-timeout 0; send vendor-class-identifier "sagem"; send user-class "+FSVDSL_livebox.Internet.softathome.Livebox4"; # See https://jsfiddle.net/kgersen/3mnsc6wy/ to generate this string send rfc3118-authentication 00:00:00:00:...; # Use the MAC address of the Livebox send dhcp-client-identifier 01:xx:xx:xx:xx:xx:xx; request subnet-mask, routers, domain-name-servers, domain-name, broadcast-address, dhcp-lease-time, dhcp-renewal-time, dhcp-rebinding-time, rfc3118-authentication; }
Orange expects some control packets, notably DHCP, to be tagged with
802.1p PCP 6. This is a 3-bit field within the Ethernet frame when
using VLANs. By default, Linux leaves this field blank. With ip
link
, we can translate Linux’s skb->priority
to a PCP. On Debian,
here is how to declare the VLAN interface:2
auto internet iface internet inet dhcp pre-up ip link add link eno1 name internet type vlan id 832 egress-qos-map 0:0 6:6 pre-up /etc/firewall/run post-down ip link del internet
The last step is to add the appropriate code in /etc/firewall/run
to
ensure DHCP, ARP, IGMP and ICMP packets have an internal priority
of 6. Netfilter’s CLASSIFY
target would be the easiest solution.
However, ISC DHCP client is using raw sockets and the packets it sent
won’t pass through Netfilter. A clean solution is to use tc
to
modify packets just before handing them to the network card. The
skbedit action allows one to change the priority associated to a
packet:3
# We need a qdisc to set filters tc qdisc replace dev internet root handle 1: prio tc filter del dev internet # DHCP (raw sockets, do not specify "protocol ip") tc filter add dev internet parent 1: prio 1 u32 \ match ip protocol 17 ff \ match ip dport 67 ffff \ action skbedit priority 0:6 # ARP tc filter add dev internet parent 1: prio 2 protocol 0x806 u32 \ match u32 0 0 \ action skbedit priority 0:6 # IGMP tc filter add dev internet parent 1: prio 3 protocol ip u32 \ match ip protocol 2 ff \ action skbedit priority 0:6 # ICMP tc filter add dev internet parent 1: prio 4 protocol ip u32 \ match ip protocol 1 ff \ action skbedit priority 0:6
With this configuration in place, ifup internet
should get you
connected through IPv4.
IPv6 configuration#
Native IPv6 is also available over the same VLAN. SLAAC autoconfiguration should be used to get a default route, but not the IP address. Instead, Orange is providing a /56 prefix through DHCPv6 “prefix delegation.”
The DHCP configuration is completed to send the DHCPv6 equivalents for vendor class, user class and authentication string:
# […] option dhcp6.auth code 11 = string; option dhcp6.userclass code 15 = string; option dhcp6.vendorclass code 16 = string; interface "internet" { timeout 60; retry 1; select-timeout 0; # […] 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.auth 00:00:00:00:...; send dhcp6.client-id 00:03:00:01:xx:xx:xx:xx:xx:xx; also request dhcp6.auth, dhcp6.vendor-opts; }
The firewall script is amended to classify DHCPv6 and ICMPv6 packets with priority 6:
# DHCPv6 tc filter add dev internet parent 1: prio 5 protocol ipv6 u32 \ match ip6 protocol 17 ff \ match ip6 dport 547 ffff \ action skbedit priority 0:6 # ICMPv6 tc filter add dev internet parent 1: prio 6 protocol ipv6 u32 \ match ip6 protocol 58 ff \ action skbedit priority 0:6
The definition of the internet
interface is updated to invoke the
DHCPv6 client:
auto internet iface internet inet dhcp pre-up ip link add link eno1 name internet type vlan id 832 egress-qos-map 0:0 6:6 pre-up /etc/firewall/run post-down ip link del internet up /lib/ifupdown/wait-for-ll6.sh && \ dhclient -6 -P -pf /run/dhclient6.$IFACE.pid \ -lf /var/lib/dhcp/dhclient6.$IFACE.leases \ -df /var/lib/dhcp/dhclient.$IFACE.leases \ $IFACE post-down dhclient -6 -r -pf /run/dhclient6.$IFACE.pid dhclient \ -lf /var/lib/dhcp/dhclient6.$IFACE.leases \ -df /var/lib/dhcp/dhclient.$IFACE.leases \ $IFACE || true
The /lib/ifupdown/wait-for-ll6.sh
script waits for the interface to
get a link-local address before continuing. The -P
option for the
DHCPv6 client enables prefix delegation and disables the normal
address query.
It is not over: the DHCPv6 client will receive a /56 prefix but there
is nothing configured to make use of it. You need to drop a script
in /etc/dhcp/dhclient-exit-hooks.d
to actually distribute this
prefix to your internal network. Here is a simplified non-tested
version of this script:
#!/bin/sh IA_PD_IFACES="lan-trusted lan-guest lan-games" case $reason in BOUND6|EXPIRE6|REBIND6|REBOOT6|RENEW6) offset=0 for iface in $IA_PD_IFACES; do # Remove old /64 prefix if there is a change [ -n "$old_ip6_prefix" ] && \ [ "$old_ip6_prefix" != "$new_ip6_prefix" ] && \ ip -6 addr flush dev $iface scope global # Compute and add new /64 prefix [ -n "$new_ip6_prefix" ] && { offset=$((offset + 1)) address=$(sipcalc --v6split=64 --split-verbose "$new_ip6_prefix" \ | grep '^Compressed' \ | awk "(NR == $offset)"' { print $NF }')1/64 ! ip -6 addr show dev $iface | grep -qwF $address || \ ip -6 addr add $address dev $iface done esac
At the top of the script, the IA_PD_IFACES
variable contains the
list of internal interfaces. From the /56 provided in
$new_ip6_prefix
, the script will assign a /64 to each of them—along
with the first address. For example, when being assigned
2001:db8:f:b00::/56
, we get:
$ ip -brief -6 a show scope global lan-trusted@eno1 UP 2001:db8:f:b00::1/64 lan-guest@eno1 UP 2001:db8:f:b01::1/64 lan-games@eno1 UP 2001:db8:f:b02::1/64
I am using dnsmasq to offer IPv6 router advertisements to hosts in
each network. This is done through the dhcp-range
directive:
dhcp-range=::,constructor:lan-trusted,ra-names dhcp-range=::,constructor:lan-guest,ra-names dhcp-range=::,constructor:lan-games,ra-names
The script also handles the default route by switching accept_ra
to 2 for the internet
interface to accept IPv6 router advertisements
even when forwarding is enabled and sending an IPv6 router discovery
packet using rdisc6:
case $old_ip6_prefix,$new_ip6_prefix in *,) # No IPv6 prefix delegation, remove old route sysctl -qw net/ipv6/conf/$interface/accept_ra=0 ip -6 route del default proto ra || true ;; *) # Otherwise, get a default route sysctl -qw net/ipv6/conf/$interface/accept_ra=2 rdisc6 $interface ;; esac
Be sure to use the complete script instead of the shortened
code above! If after ifdown internet && ifup internet
, you don’t get
a /56 prefix, you may have to reboot the ONT to clear an old DHCP
lease.
-
As Orange is using the serial number to authorize the ONT, my plan is to call Orange customer service, pretend I have got a replacement and provide the new serial number. ↩︎
-
There is no need to have the VLAN number in the interface name. I usually leaves them out as it doesn’t help to describe the interface. The VLAN number can still be recovered with
ip -d link show
. ↩︎ -
The first filter only works if the physical interface supports VLAN offloading. You can check this is the case with
ethtool -k eno1 | grep rx-vlan-offload
. Otherwise, the installed filter does not handle correctly the VLAN header and does not match the targeted packets. ↩︎