img

Ce qu’UniFi était

Il était une fois un bon logiciel. Il permettait à ses utilisateurs de gérer une flotte de bornes Wi-Fi avec facilité, de les grouper en site, d’utiliser des fonctionnalités avancées. En plus, il ne bloquait pas ses utilisateurs dans l’écosystème, leur permettait d’installer ce logiciel sur une Debian ou une Ubuntu, était relativement peu cher à l’achat, ne nécessitait pas d’abonnement.

Bref, ce logiciel était bien et la vie était belle. Et ce logiciel s’appelait UniFi.

Tout allait bien dans le meilleur des mondes mais ensuite, est venu le pire ennemi du logiciel. Le temps…

Le temps passait, les composants du logiciel devenaient vieux et fatigués. Le logiciel ne pouvait par exemple pas supporter une version de MongoDB supérieur à 3.6 (alors de que cette dernière est en fin de vie depuis longtemps) mais demandait une version de Java au moins égale à 11. Ce qui faisait que les utilisateurs étaient obligés soit d’utiliser une Ubuntu Focal Fossa spécifiquement, soit une Debian Stretch mais en utilisant la version backports de Java.

Et les utilisateurs commençèrent à en avoir plein le cul (enfin, surtout un), surtout pour gérer une seule et unique borne.

Plutôt que de faire évoluer le logiciel pour que ces briques de base puissent supporter des versions plus modernes de MongoDB ou de Java, ou de rendre son installation plus simple, le logiciel a choisi de continuer de grossir et d’offrir toujours plus de fonctionnalités gadgets dont personne ne se sert.

Alors le petit utilisateur en eut marre et décida que niquez-vous, vais le faire moi-même, marchera mieux…

La borne elle-même

Alors, en fait, si tu te connectes à une borne UniFi (j’ai une UAP-AC-Lite, mais je suppose que c’est à peu près pareil pour les autres modèles), tu pourras constater que c’est déjà une OpenWRT (!). En fait, pour être précis, il s’agit d’une LEDE un fork du projet OpenWRT destiné justement à le moderniser et qui a depuis refusionner avec ce dernier, en Janvier 2018 :

enbarr-BZ.6.2.49# cat /etc/openwrt_release
DISTRIB_ID='LEDE'
DISTRIB_RELEASE='17.01.6'
DISTRIB_REVISION='r3979-2252731af4'
DISTRIB_CODENAME='reboot'
DISTRIB_TARGET='ar71xx/ubnt'
DISTRIB_ARCH='mips_24kc'
DISTRIB_DESCRIPTION='LEDE Reboot 17.01.6 r3979-2252731af4'
DISTRIB_TAINTS='no-all mklibs busybox'

Précision pour pouvoir se connecter directement à la borne Wi-Fi : sous UniFi, allez dans les options, puis System, puis Advanced et tout en bas, vous pouvez révéler le mot de passe admin de l’ensemble des bornes. Il suffit ensuite de s’y connecter en SSH.

Ce qui est intéressant avec cette borne, c’est qu’elle était fraîchement mise à jour de quelques heures au moment d’écrire ces lignes. Donc, on a bien une version très largement obsolète de LEDE Project redevenu OpenWRT.

Downgrade, upgrade, degrade

Pour cette partie, je ne fais que suivre la documentation officielle, tu peux directement t’y référer. J’ai donc utilisé la méthode non-invasive qui me paraissait la plus simple. Première chose à faire, remettre un vieux firmware sur la borne. Il suffit d’aller télécharger le bon et le forcer via la console UniFi.

Une fois, la borne redémarrée, on peut de nouveau s’y connecter en SSH, aller dans /tmp, créer un dossier flash et y télécharger les éléments suivants :

Tu remarqueras que les versions ne correspondent pas. C’est à peu près normal, rien d’inquiétant. Une fois qu’on a fait tout ça, on peut tranquillement décompresser le tout :

tar -xzOf libc_1.1.24-3_mips_24kc.ipk ./data.tar.gz | tar -xvz
tar -xzOf mtd_26_mips_24kc.ipk ./data.tar.gz | tar -xvz
tar -xzOf libubox20210516_2021-05-16-b14c4688-2_mips_24kc.ipk ./data.tar.gz | tar -xvz

Tu as maintenant tout ce qu’il faut pour flasher la borne, il suffit de s’y mettre en deux étapes :

LD_LIBRARY_PATH=${PWD}/lib lib/ld-musl-mips-sf.so.1 sbin/mtd write openwrt-*.bin kernel0
LD_LIBRARY_PATH=${PWD}/lib lib/ld-musl-mips-sf.so.1 sbin/mtd erase kernel1

On vient de mettre à jour le kernel0 de mtd (je ne sais pas exactement à quoi ça correspond, mais je suppose que c’est du stockage avec plusieurs entrée de démarrage, façon OPNSense), et effacer le kernel1. Il suffit alors d’indiquer à mtd que l’on souhaite démarrer sur le kernel0 :

grep bs /proc/mtd # cette commande doit renvoyer bs quelque part
  mtd7: 00020000 00010000 "bs"
dd if=/dev/zero bs=1 count=1 of=/dev/mtd4 # écrase le premier octet de mtd4 avec 0x00
hexdump -C /dev/mtd4 | head # devrait indiquer 0x00 pour le premier octet

Une fois les opérations effectuées, tu peux redémarrer la borne (soit un reboot, soit on débranche). Au bout d’une grosse minute, la borne doit redémarrer avec l’adresse par défaut 192.168.1.1/24 et devrait être joignable sur le réseau local.

Première chose à faire : dans LuCI (l’interface Web d’OpenWRT), dans Network » Interfaces » LAN » DHCP Server » General Setup, désactive le DHCP pour cette interface (ça fera du bordel en moins). Tant que t’y es, tu peux aussi complètement démonétiser le router advertisement dans les mêmes paramètres sous IPv6 Settings.

À partir de ce moment, il suffit de remettre une adresse correcte à la machine (en DHCP ou une adresse fixe) et c’est en gros terminé. Tu peux recréer ton SSID et c’est réglé. Tu remarqueras qu’il y a deux interfaces radio0 et radio1 pour le Wi-Fi (une antenne fait du 2,4Ghz, une autre du 5Ghz). C’est normal, UniFi présentait tout de manière « unifiée » (LOLOLOLOL) mais OpenWRT te laisse le choix de ce que tu veux mettre où. Si tu ne veux pas te casser la tête, tu peux simplement remettre les mêmes paramètres sur les deux et laisser le périphérique qui se connecte choisir la meilleure connexion pour lui (de manière générale, ça ne devrait pas poser plus de problème que ça).

Mais si tu avais une configuration un peu plus compliquée, je t’invite à continuer de lire.

Un poil plus compliqué

Originellement, j’avais une configuration un poil plus compliqué : en fait, la borne était certes adressable sur un bout de réseau mais faisait plusieurs ponts SSID/VLAN (deux pour être précis). L’idée était d’avoir la borne isolée sur le réseau où se trouvait le serveur UniFi d’un côté, mais d’avoir mon VLAN domestique et mon VLAN IoT disponibles depuis la borne de l’autre.

D’où cette configuration « un peu » compliquée. La borne étant restée branchée de la même manière, elle a donc toujours nativement accès au VLAN isolé et les deux autres VLANs sont « taggés » via le switch derrière.

Il va donc falloir faire avaler cette configuration à OpenWRT. Absolument tout ce qui suit peut-être fait en ligne de commande (et je vais mettre les fichiers de configuration résultant à la fin), mais j’écris ce petit guide pour l’interface Web (parce qu’il y en a une plutôt claire, donc autant en profiter). Évidemment, il faudra adapter à ton cas spécifique si nécessaire.

Première chose à faire : vider complètement les règles de firewall. Elles sont conçues pour un routeur faisant du NAT, elles risquent donc te compliquer la vie dans un premier temps. Rien ne t’empêche d’en remettre après si tu le souhaites, mais pour un point d’accès Wi-Fi débile, je pense que c’est complètement inutile.

Donc, dans Network » Firewall » Traffic Rules, tu peux tout virer. Tout.

Deuxième chose : il va falloir dire à OpenWRT que le bridge par défaut a des VLANs à disposition. Pour cela, il faut se rendre dans Network » Interfaces » Devices et cliquer sur Configure… pour le bridge en question.

Dans le dernier onglet, on voit une option Bridge VLAN filtering. Il suffit de cocher la case et ensuite, tu peux entrer les VLANs qui sont taggés, natifs, etc… Pour le VLAN natif (celui qui est untagged justement sur l’interface de la borne), je te recommande de mettre le VLAN 1 et les options Egress untagged et Primary VLAN ID. J’ai essayé d’autres combinaisons sans beaucoup de succès et je ne sais pas si le souci vient d’OpenWRT ou de la façon dont le switch fonctionne (j’en doute…).

Bref, avec cette configuration, tu devrais avoir accès à des VLANs depuis le bridge. Surtout n’applique pas tout de suite la configuration, sinon tu perdras la main et il faudra tout recommencer !

Donc, une fois rendu là, il faut créer de nouveaux devices. Tu peux donc procéder pour en créer au moins un br-lan.1 qui correspondra au fameux VLAN 1 de tout à l’heure. Au moment de créer ces devices, tu vas voir un menu déroulant dans Existing device et pourvoir choisir Software VLAN: "br-lan.1" (lan), c’est celui qu’il faut choisir.

Tu peux créer les autres VLANs dont tu as besoin de la même manière (juste attention, il y a une limite au nombre de SSID sur chaque interface, donc créer 20 000 VLANs n’est probablement pas possible).

Une fois que tout cela est fait, retourne dans Network » Interfaces et associe l’interface LAN (créée par défaut) à br-lan.1. À partir de ce moment-là, tu peux appliquer, tu ne devrais pas perdre la main.

Et il ne reste plus qu’à créer les autres Interfaces pour OpenWRT selon les VLANs que tu as fait. Tu peux te contenter de les créer et des associer aux interfaces VLAN créées précédemment (avec un nom un peu explicite pour que ce soit plus simple), il n’y a rien d’autres à configurer.

Une fois tout ceci fait, tu peux créer tes SSID et y associer systématiquement la bonne interface. Le SSID se contentera alors de faire le passe-plat entre Wi-Fi et filaire, tout simplement.

Une petit aperçu de ce que ça donne dans les fichiers de conf derrière, comme promis :

config device
	option name 'br-lan'
	option type 'bridge'
	list ports 'eth0'

config interface 'lan'
	option proto 'static'
	option netmask '255.255.255.0'
	option gateway '100.64.0.1'
	option ipaddr '100.64.0.100'
	option device 'br-lan.1'
	list dns '100.64.0.1'
	list dns_search 'buttse.cx'
	option delegate '0'
	option ip6gw 'dead:beef::1'
	list ip6addr 'dead:beef::100/64'

config bridge-vlan
	option device 'br-lan'
	option vlan '200'
	list ports 'eth0:t' # ça correspond à un VLAN taggé

config bridge-vlan
	option device 'br-lan'
	option vlan '406'
	list ports 'eth0:t'

config bridge-vlan
	option device 'br-lan'
	option vlan '1'
	list ports 'eth0:u*' # et là, le VLAN natif non-taggé

config interface 'vlan200'
	option proto 'none'
	option device 'br-lan.200'

config interface 'vlan406'
	option proto 'none'
	option device 'br-lan.406'

Évidemment, tout ceci peut encore une fois être fait 100% en ligne de commande, juste il faut tout faire d’un coup et sans se louper (donc c’est pas si simple).

Conclusement

Voilà, tu as fièrement passer ta borne en OpenWRT, tu as supprimé une VM ou un conteneur bien encombrant et boursoufflé de partout et qui ne servait pas à grand-chose tout en gardant les mêmes fonctionnalités qu’avant. Et en bonus, tu vas pouvoir faire des trucs en plus sur la borne maintenant que son système est complètement libérée.

Bravo, tu peux te mettre une bonne tape sur l’épaule et retourner dormir.

Màj du 2023-03-08

Conclusion de la conclusion : ça peut être interéssant de désactiver complètement le routage IPv4 et IPv6 comme la borne ne « route » à proprement parler rien.

Pour cela, on pourra ajouter les lignes suivantes dans le /etc/rc.local :

sysctl net.ipv4.conf.all.forwarding=0
sysctl net.ipv6.conf.all.forwarding=0