EdgeRouter 4
J’ai enfin eu la fibre ! Après avoir bataillé avec notre syndic et la mairie pour pousser SFR (j’aurais préféré Orange, mais je n’ai pas eu le choix malheureusement) à fibrer l’immeuble pendant plusieurs années ! On pourra dire que SFR a pris son temps. Me voilà donc avec une offre fibre à 1GB/s descendant et 200MB/s montant et un APU, mon ancien routeur, aux abois. En effet un speed test avec la box opérateur me donne un débit réel (mais non-garanti) de 830MB/s descendant, 260MB/s montant et un ping à 10ms, c’est un résultat très honorable par rapport à l’offre commerciale. Avec l’APU en revanche il m’est plus que difficile de dépasser le 300MB/s en descendant, ce qui se voit assez bien avec un htop montrant que le CPU est complètement à genou.
J’ai du coup craqué sur un EdgeRouter 4 de chez Ubiquiti pour remplacer mon APU et bien évidemment laisser la box SFR au placard. Ubiquiti propose des produits que je trouve assez intéressant :
- la cible sont les professionnels et éventuellement les particuliers bidouilleurs dont je fais parti
- le matériel contient des circuits dédiés permettant de décharger le processeur des opérations réseaux, DPI et IPSec
- la consommation est très faible : seulement 13W sur ce modèle
- le logiciel est ouvert à la modification (dans le sens : il peut faire bien plus que ce qu’à prévu initialement le fabricant)
- il est doté d’un port console pour pouvoir réparer le boitier même quand on a tout cassé
- la partie logicielle repose entièrement sur une stack Debian, sur lequel Ubiquiti a rajouté une interface web et en ligne de commande pour piloter le boitier.
- le prix est plus que raisonnable au vu de la qualité du matériel et de l’efficacité
EdgeRouter ou APU ?
Honnêtement c’est un petit bijou. Initialement j’avais pris une carte APU pour être au commande de tout. Le EdgeRouter respecte cela en tout point :
- on peut rajouter ou enlever des daemons
- eventuellement il est possible de compiler un logiciel et le faire exécuter par le EdgeRouter, en gardant à l’esprit que le CPU n’est pas non plus une foudre de guerre
- tous les services sont open-source, la partie propre à EdgeRouter étant la couche de gestion. Ainsi on retrouve dhcpd, dnsmasq, openssh, iptables, ipsec, radvd, strongswan, python, ddclient, dhclient, le kernel linux, busybox, monit, ntpd…
- les backups sont totalement consistentes avec la CLI
Je me retrouve donc avec un système opérationnel, robuste et plus simple à gérer et sur lequel je ne suis pas limité autrement que par les capacités matérielles.
J’ai listé dans le dernier paragraphe les articles qui m’ont aidé à modifier le router selon mon goûts et vais détailler comment fonctionne un routeur Ubiquiti.
Les fondations du EdgeRouter
Comme je l’ai indiqué en introduction, le routeur repose sur une base totalement open-source :
root@ubnt /config # cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 7 (wheezy)"
NAME="Debian GNU/Linux"
VERSION_ID="7"
VERSION="7 (wheezy)"
ID=debian
ANSI_COLOR="1;31"
HOME_URL="http://www.debian.org/"
SUPPORT_URL="http://www.debian.org/support/"
BUG_REPORT_URL="http://bugs.debian.org/"
Pour être plus précis, l’OS en question est EdgeOS, qui est un fork de Vyatta, lui-même basé sur Debian.
Pour des soucis d’efficacité énergétique, le CPU utilisé, un quad-core, repose sur une architecture mips64 (tout, mips ou arm, sera plus efficient que l’archi x86/amd64) :
root@ubnt /config # cat /proc/cpuinfo
system type : UBNT_E300
machine : Unknown
processor : 0
cpu model : Cavium Octeon III V0.2 FPU V0.0
BogoMIPS : 2000.00
wait instruction : yes
microsecond timers : yes
tlb_entries : 256
extra interrupt vector : yes
hardware watchpoint : yes, count: 2, address/irw mask: [0x0ffc, 0x0ffb]
isa : mips1 mips2 mips3 mips4 mips5 mips64r2
ASEs implemented : vz
shadow register sets : 1
kscratch registers : 4
core : 0
VCED exceptions : not available
VCEI exceptions : not available
Il existe quelques modules propriétaires (du moins, je n’ai pas réussi à trouver où étaient les codes sources) permettant de faire appels aux différents circuits d’accélération matérielle :
root@ubnt /config # lsmod
[...]
cvm_ipsec_kame 38319 0
ipv6 381814 71 sit,ip6table_mangle,nf_defrag_ipv6,cvm_ipsec_kame,xfrm6_mode_tunnel,nf_conntrack_ipv6
imq 6736 0
cavium_ip_offload 176733 0
ubnt_nf_app 10668 1 cavium_ip_offload
tdts 572293 2 cavium_ip_offload,ubnt_nf_app
octeon_rng 1890 0
rng_core 4168 2 octeon_rng
ubnt_platform 2528991 0
La surcouche Ubiquiti
Le EdgeRouter peut se gérer de 4 manières différentes :
- par l’interface web
- par l’interface en ligne de commande (CLI)
- directement en ssh comme dans toute distribution Linux, avec le risque de voir ses changements écrasés par la configuration de l’interface web/cli ou par un reboot
- grâce à /config
L’interface web est assez limitée en comparaison de la CLI mais pourra convenir à un usage très simple. Personnellement je la trouve trop limitée ce qui la rend un peu inutile à mon goût si ce n’est voir visuellement le traffic en temps réel et la santé générale du système.
La CLI
La ligne de commande est accessible soit via l’interface Web (en haut à droite), soit via SSH, que je trouve de loin plus pratique à une émulation de console à travers une page web.
Il existe 3 modes à la CLI :
- les commandes bash habituelles
- show, permettant de consulter différentes informations au runtime
- configure, permettant d’accéder à la configuration du routeur
Il est inutile que je détaille le premier mode, ce post ne sert pas à vous former sur Bash. Exactement il s’agit de vbash, pour lequel l’auto-complétion des fichiers et dossiers ne fonctionnent pas. Sans chercher plus loin, un sudo su me permet de retrouver un bash « normal ». Les deux autres modes en revanches sont la spécificité de EdgeOS et sont assez facile à prendre en main. En effet elles sont dotées de l’auto-complétion : un simple TAB-TAB permet d’afficher les sous-commandes possibles.
show Show
La commande show permet de récupérer un certain nombre d’informations sur le routeur à travers une interface unifiée (un truc complètement raté dans le monde de l’open-source) :
veovis@ubnt ~ $ show<TAB><TAB>
arp cspf firewall interfaces login queueing system upnp2
bfd date flow-accounting ip mpls reboot tech-support users
bgp debugging flow-accounting-ipt ipv6 nat route-map traffic-control version
bi-lsp dhcp hardware ldp ntp rsvp ubnt vpls
bridge dhcpv6 history lldp openvpn shutdown udapi vpn
configuration dhcpv6-pd host load-balance pppoe-client snmp unms vrrp
conntrack dns incoming log pppoe-server ssh-recovery update webproxy
veovis@ubnt ~ $ show ubnt<TAB><TAB>
discover discover-server offload
veovis@ubnt ~ $ show ubnt <TAB>
Possible completions:
discover Show UBNT discovered devices
discover-server
Show UBNT discover server state
offload Show UBNT offload status
veovis@ubnt ~ $ show ubnt offload
IP offload module : loaded
IPv4
forwarding: enabled
vlan : disabled
pppoe : disabled
gre : disabled
IPv6
forwarding: enabled
vlan : disabled
pppoe : disabled
IPSec offload module: loaded
Traffic Analysis :
export : enabled
dpi : enabled
version : 1.354
On peut ainsi explorer facilement tout ce que peut offrir show et les sous-commandes étant relativement explicites, deviner la bonne commande est plutôt aisé.
configure
De manière similaire à la commande show, le mode configure est aussi doté de la même d’auto-complétion. On rentre dans ce mode simplement en exécutant configure.
On peut alors
- show: consulter tout ou partie de la configuration
- set: modifier un paramètre
- commit: appliquer les changements effectués de manière non-persistante (perdu au prochain redémarrage)
- save: persister la configuration
- edit: peut être vu comme une sorte de « cd subSection »
- exit: remonter d’un cran (aka « cd .. ») ou quitter le mode configure si l’on est déjà au top-level
Ci-dessous un exemple mettant en évidence la commande edit, laquelle permet d’utiliser show ou set sans devoir spécifier le chemin du paramètre entier, edit permettant de changer de contexte ou de descendre dans l’arborescence. Ainsi plutôt que d’avoir à taper show interfaces ethernet eth2
, le edit interfaces
préalable me permet de ne taper que show ethernet eth2
pour avec le même résultat.
veovis@ubnt# show interfaces ethernet eth2
address dhcp
description wan0
dhcp-options {
client-option "send vendor-class-identifier "neufbox_NB6VAC-FXC-r0_NB6VAC-MAIN-R4.0.35_NB6VAC-XDSL-A2pv6F039p";"
default-route update
default-route-distance 210
name-server update
}
duplex auto
firewall {
local {
name WAN_LOCAL
}
}
speed auto
[edit]
veovis@ubnt# edit interfaces
[edit interfaces]
veovis@ubnt# show ethernet eth2
address dhcp
description wan0
dhcp-options {
client-option "send vendor-class-identifier "neufbox_NB6VAC-FXC-r0_NB6VAC-MAIN-R4.0.35_NB6VAC-XDSL-A2pv6F039p";"
default-route update
default-route-distance 210
name-server update
}
duplex auto
firewall {
local {
name WAN_LOCAL
}
}
speed auto
[edit interfaces]
veovis@ubnt# exit
[edit]
veovis@ubnt#
Ubiquiti a fait preuve d’ingéniosité en concevant le fichier de configuration se trouvant dans /config/config.boot
. Il s’agit d’un fichier texte lisible dans un format similaire à du JSON. On remarque que ce fichier respecte la même hiérarchie que le mode configure. Par cette simple idée, s’approprier la logique du mode configure devient un vrai jeu d’enfant. Il s’agit aussi du config tree que l’on trouve dans l’interface web.
/config
Dernier petit bijou, le dossier /config
. Contrairement au reste, le contenu de ce dossier sera préservé à travers une mise à jour du firmware. Grosso-modo, toutes nos bidouilles doivent se trouver ici.
root@ubnt /home/veovis # ls -lh /config/
total 44
drwxrwsr-x 3 root vyattacf 4.0K May 21 17:52 auth
-rw-rw-r-- 1 root vyattacf 15.8K Jul 7 14:58 config.boot
-rw-r--r-- 1 root vyattacf 2.0K Jul 29 15:17 dhcpd.leases
drwxrwsr-x 4 root vyattacf 4.0K May 21 17:05 scripts
drwxrwsr-x 2 root vyattacf 4.0K Apr 26 20:09 support
drwxr-xr-x 2 root root 4.0K Apr 26 19:25 udapi-bridge
drwxr-sr-x 3 root vyattacf 33 Jun 22 19:30 url-filtering
drwxrwsr-x 5 root vyattacf 4.0K May 28 20:33 user-data
drwxr-sr-x 3 www-data vyattacf 4.0K May 21 15:45 wizard
On va y trouver :
- le fichier de configuration
/config/config.boot
- les scripts de post-initialization dans
/config/scripts/post-config.d/
- les autres fichiers à garder dans
/config/user-data/
Les scripts initialisation m’ont servi entre autres à :
- ajouter des paquets supplémentaire (nsd3, htop, screen, unbound)
- remplacer dnsmasq par unbound
- ajouter des daemons supplémentaires
- configurer unbound et autres en copiant
/config/user-data/root/
dans/
Script permettant d’installer des paquets supplémentaires :
#!/bin/bash
# /config/scripts/post-config.d/00_install_packages.sh
packages='screen unbound nsd htop'
doneit='/var/lib/my_packages'
if [ -e $doneit ]; then
exit 0
fi
mount -t tmpfs -o size=30% tmpfs /var/lib/apt/lists
if [ $? != 0 ]; then
echo Could not mount tmpfs on /var/lib/apt/lists
exit 1
fi
apt-get update
apt-get --no-install-recommends install -y $packages
if [ $? == 0 ]; then
echo Package install successful
touch $doneit
else
echo Package install failed
fi
umount /var/lib/apt/lists
exit 0
Script permettant la fusion de /config/user-data/root/
dans /
et effectuant d’autres opérations spécifiques :
#!/bin/bash
# /config/scripts/post-config.d/10_restore-custom.sh
# to be stored into /config/scripts/post-config.d/10_restore-custom.sh
config_root=/config/user-data/root/
# custom PS1
sed -i -e 's/^PS1=.*$/PS1='"'"'\[\\033[01;32m\\]\\u@\\h\\[\\033[01;34m\\] \\w \\$\\[\\033[00m\\] '"'"'/' /etc/bash.bashrc
# disable ipv6 on eth2 because I do not use the tunnel from sfr
# echo 1 > /proc/sys/net/ipv6/conf/eth2/disable_ipv6
# synchronize the config tree with root
if [ ! -d "$config_root" ]; then
echo "Nothing to sync"
exit 0
fi
find "$config_root" \( -type f -o -type l \) -print | \
while read i;
do
target=$(echo $i | cut -d'/' -f5-)
dir=$(dirname /"$target")
mkdir -p "$dir"
cp "$i" "/$target"
done
# specific tasks for ipsec
ipsec rereadall
# specific tasks for unbound
curl "https://pgl.yoyo.org/adservers/serverlist.php?hostformat=unbound&showintro=1&mimetype=plaintext" > /etc/unbound/local-blocking-data.conf
systemctl enable unbound
systemctl restart unbound
if [ ! -d /var/run/nsd3 ]; then
install -d -o nsd -g nsd -m 755 /var/run/nsd3
fi
systemctl enable nsd
systemctl restart nsd
curl "https://pgl.yoyo.org/adservers/iplist.php?ipformat=iptables&showintro=1&mimetype=plaintext" | sed 's/OUTPUT/OUT_ADBLOCK/g' > /tmp/iptables.sh
#iptables -N OUT_ADBLOCK
#iptables -F OUT_ADBLOCK
#chmod +x /tmp/iptables.sh
#/tmp/iptables.sh
rm /tmp/iptables.sh
#iptables -D OUTPUT -o eth2 -p tcp -m multiport --dports 80,443 -j OUT_ADBLOCK
#iptables -A OUTPUT -o eth2 -p tcp -m multiport --dports 80,443 -j OUT_ADBLOCK
Mot de la fin
J’espère que cette introduction facilitera votre prise en main. Personnellement j’étais un peu frileux à l’idée de prendre du matos semi-propriétaire mais je suis au final extrêmement satisfait de cet investissement et je ne peux que le recommander pour toute personne ne souhaitant pas avoir un équipement étranger (la box opérateur) dans son réseau local. En bon passionné que je suis, j’attends avec impatience une nouvelle version majeure du firmware qui nous emmènerais sur un kernel 4.x, le kernel 3.10 actuellement utilisé n’étant plus supporté. J’ai lu que la principale difficulté provenait du constructeur CPU qui rechignerait à fournir un SDK compatible avec une version récente de Linux.