J’ai enfin eu la fibre ! après avoir bataillé avec notre syndic et la mairie pour pousser SFR à fibrer l’immeuble pendant plusieurs année ! 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. Uniquiti 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 circuit 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 un i7 dernier cri
- 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 paragraphes les articles qui m’ont aidé à modifier le router selon mon goûts et vais détaillé 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 ou très standard. 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, il s’agit juste de 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 peux offrir show et les sous-commandes étant relativement explicite, 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 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 me permettant d’installer des paquets supplémentaires :
#!/bin/bash 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 # 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é provenant du constructeur CPU qui rechignerait à fournir un SDK compatible avec une version récente de Linux.