Faire tourner des conteneurs sur UniFi OS 3.x et +

Faire tourner des conteneurs sur UniFi OS 3.x et +

Avant la version 3 d'UniFi OS, il était possible de lancer des conteneurs avec podman pour héberger certains services réseau sur votre routeur Ubiquiti UDM (aussi bien classique que Pro).

Libérez votre Ubiquiti Unifi Dream Machine
L’Unifi Dream Machine est un équipement réseau tout-en-un (routeur, switch, point d’accès wifi) puissant et sur lequel on peut ajouter d’autres services.

Ubiquiti a retiré, dans la mise à jour d'UniFi OS en version 3, le support de podman / docker à cause d'un changement majeur dans le kernel utilisé.

Heureusement, grâce aux efforts de boostchicken, le développeur qui a permis déjà d'utiliser podman sur UniFi OS 2, ainsi que des utilisateurs de UniFiOS-utilities, une nouvelle méthode a été trouvée pour vous permettre de continuer à héberger des services sur votre routeur sous UniFi OS 3, avec systemd-nspawn.

unifios-utilities/nspawn-container at main · unifi-utilities/unifios-utilities
A collection of enhancements for UnifiOS based devices - unifi-utilities/unifios-utilities

Nous allons donc détailler dans ce tutoriel comment mettre en place des conteneurs avec les versions UniFi OS 3 et supérieures.

Ce tutoriel a été testé et validé avec les versions 3 et 4 d'UniFi OS.


Sommaire

  1. Création du conteneur
  2. Configuration du conteneur
  3. Configuration du conteneur avec un réseau isolé macvlan
  4. Configuration de la persistance et du démarrage automatique
  5. Installation de services

Historique des versions

Version Date Commentaires
1 Aout 2024 Version initiale

Création du conteneur

Pour commencer, il faudra vous connecter en SSH à votre routeur UniFi.

Si ce n'est pas activé, rendez-vous dans UniFi OS, puis dans Console Settings et enfin cochez la case devant SSH et renseignez un mot de passe. Utilisez ensuite un client SSH comme Putty ou PowerShell sur Windows, ou directement depuis le terminal sur Linux ou MacOS.

En premier, nous allons installer systemd-container et debootstrap. debootstrap sera utilisé pour créer le répertoire qui stockera la base Debian et systemd-nspawn (inclus dans systemd-container) pour lancer le conteneur.

apt -y install systemd-container debootstrap

Créons maintenant un répertoire appelé debian-custom qui aura sa base Debian dans /data/custom/machines.

mkdir -p /data/custom/machines
cd /data/custom/machines
debootstrap --include=systemd,dbus unstable debian-custom
ℹ️
Cela peut prendre jusqu'à 10 minutes pour télécharger et installer tous les paquets nécessaires.
ℹ️
Le répertoire occupera environ 400 MB d'espace disque après l'installation, et pourra utiliser jusqu'à 1 GB qand vous aurez installé plusieurs services.
💡
Notez qu'il est également possible d'utiliser pacstrap ou un autre outil de création de distribution si vous souhaitez créer un conteneur tournant sur Arch Linux, Fedora ou une autre distribution à la place de Debian. (voir documentation et exemples ici)

Enfin, ouvrons un shell sur ce nouveau conteneur, définissons le mot de passe du compte root et activons le service réseau.

systemd-nspawn -M debian-custom -D /data/custom/machines/debian-custom
passwd root
systemctl enable systemd-networkd
echo "nameserver 1.1.1.1" > /etc/resolv.conf
echo "debian-custom" > /etc/hostname
exit
💡
Vous pouvez utiliser le serveur DNS de votre choix (y compris le vôtre).
Définissez le nom d'hôte que vous souhaitez pour le conteneur, debian-custom n'est qu'un exemple.
⚠️
Attention, vérifiez bien dans quelle console vous êtes connecté avant de poursuivre ce tutoriel et coller / lancer les commandes shell fournies.
Si le début de la ligne est root@<nom de votre UDM>, vous êtes connecté sur la console de l'UDM, si c'est root@<debian-custom> (ou le nom que vous donnez à votre conteneur) vous êtes connecté dans le conteneur.

Configuration du conteneur

Maintenant que le conteneur est créé, passons à sa configuration. Assurez-vous d'être revenu sur le shell d'UniFi OS et que vous n'êtes plus connecté dans le conteneur.

En premier lieu, nous allons lier le conteneur à /var/lib/machines pour pouvoir le contrôler à l'aide de la commande machinectl.

mkdir -p /var/lib/machines
ln -s /data/custom/machines/debian-custom /var/lib/machines/

Nous allons ensuite créer un fichier debian-custom.nspawn (où vous remplacerez debian-custom par le nom d'hôte de votre conteneur) dans /etc/systemd/nspawn, dans lequel nous stockerons les différents paramètres du conteneur (réseau, points de montage, ...). (Vous pouvez installer et utiliser nano qui est plus simple avec la commande apt install -y nano .)

mkdir -p /etc/systemd/nspawn
touch /etc/systemd/nspawn/debian-custom.nspawn
Si vous souhaitez isoler le conteneur de votre réseau dans un VLAN spécifique à l'aide d'un pont macvlan, pour lui appliquer des règles firewall particulières par exemple, il vous faut continuer au point 3.

Si vous voulez que le conteneur ait accès à votre réseau complet, vous pouvez utiliser le contenu suivant :

[Exec]
Boot=on
Capability=all
ResolvConf=off

[Network]
Private=off
VirtualEthernet=off

Après avoir configuré le fichier debian-custom.nspawn, démarrons le conteneur et voyons si ça fonctionne !

machinectl start debian-custom

Vous pouvez vérifier que le conteneur est bien démarré :

machinectl status debian-custom

Pour permettre au conteneur de se lancer automatiquement au démarrage, tapez la commande :

machinectl enable debian-custom

Et nous devrions être en mesure de nous connecter au shell du conteneur, ce que nous pouvons faire avec :

machinectl shell debian-custom

Maintenant que le conteneur est démarré, vous pouvez passer à la dernière étape d'installation de services pour y installer les services que vous souhaitez héberger sur votre UDM, comme vous le feriez sur n'importe quel système.


Configuration du conteneur avec un réseau isolé macvlan

En prérequis, il faut créer un nouveau réseau dans UniFi Networks en spécifiant un identifiant VLAN qui n'est pas déjà utilisé.

Téléchargez le script 10-setup-network.sh dans le répertoire /data/on_boot.d et éditez le pour renseigner les informations de votre réseau.

mkdir -p /data/on_boot.d && cd /data/on_boot.d
curl -LO https://raw.githubusercontent.com/unifi-utilities/unifios-utilities/main/nspawn-container/scripts/10-setup-network.sh
vi 10-setup-network.sh

Les informations à modifier sont les suivantes :

  • VLAN : Indiquez l'identifiant du VLAN que vous avez créé et dans lequel le conteneur sera attaché, par défaut il s'agit du VLAN 5.
  • IPV4_GW : Renseignez l'adresse IP de la passerelle du réseau, par défaut il s'agit de 10.0.5.1/24. Vous pouvez utiliser n'importe quel sous-réseau tant que celui-ci est différent des sous-réseaux existants dans UniFi.
  • IPV4_IP : Renseignez l'adresse IP du conteneur, par défaut 10.0.5.3. Vous pouvez utiliser n'importe quelle adresse IP sur le même sous-réseau que la passerelle définie par IPV4_GW.
  • Vous pouvez également modifier IPV6_GW et IPV6_IP si vous voulez activer le support de l'IPv6, sinon vous pouvez les laisser vide.

Créez ou modifiez le fichier /etc/systemd/nspawn/debian-custom.nspawn avec les paramètres suivants. Cela indiquera à nspawn d'isoler le réseau et de créer une interface macvlan dans le conteneur à partir de notre pont VLAN.

[Exec]
Boot=on
ResolvConf=off

[Network]
MACVLAN=br5
Attention, pensez à modifier le VLAN par celui que vous avez défini dans le script 10-setup-network.sh.

Créons maintenant un fichier mv-brX.network (où X est l'identifiant VLAN que vous avez défini plus tôt) dans le répertoire /etc/systemd/network de votre conteneur.

cd /data/custom/machines/debian-custom/etc/systemd/network
vim mv-br5.network

Collez y le contenu suivant, en remplaçant les différentes valeurs par celles que vous avez définies dans le fichier 10-setup-network.sh.

[Match]
Name=mv-br5

[Network]
IPForward=yes
Address=10.0.5.3/24
Gateway=10.0.5.1
Address=fd62:89a2:fda9:e23::3/64
Gateway=fd62:89a2:fda9:e23::1

Enfin, lançons le script 10-setup-network.sh, démarrons le conteneur, et vérifions que le réseau est fonctionnel.

chmod +x /data/on_boot.d/10-setup-network.sh
/data/on_boot.d/10-setup-network.sh
machinectl reboot debian-custom
machinectl shell debian-custom
ip addr show
ping -c4 1.1.1.1

Vous devriez voir l'adresse IP que vous avez défini dans votre VLAN. Si le conteneur n'a pas d'IP assignée, assurez vous d'avoir activé et démarré le service systemd-network et vérifiez à nouveau : systemctl enable --now systemd-networkd.
Si vous ne voyez toujours pas d'adresse IP sur l'interface mv-br5, vérifiez que vous utilisez le bon VLAN et que les valeurs dans les fichiers de configuration sont bien les mêmes. Vous pouvez également regarder les erreurs dans les journaux avec la commande journalctl -eu systemd-networkd.
Si le ping de 1.1.1.1 depuis le conteneur ne fonctionne pas, vérifiez que l'adresse IP du conteneur dans le script 10-setup-network.sh est correcte.

Le script 10-setup-network.sh doit être lancé à chaque démarrage de l'UDM. Le plus simple est d'utiliser le service udm-boot qui lancera automatiquement tous les scripts présents dans le répertoire /data/on_boot.d. Nous le mettrons en place un peu plus loin.


Configuration de la persistance et du démarrage automatique

Quand une mise à jour du firmware est appliquée sur l'UDM, les répertoires /data (qui contient les données du conteneur) et /etc/systemd (qui contient les scripts utilisés au démarrage) sont conservés, mais le contenu des répertoires /var et /usr sont supprimés par le script de mise à jour. Tous les paquets Debian supplémentaires qui sont installés sur l'UDM, comme systemd-container sont également supprimés.
Cela veut donc dire qu'il faut réinstaller le paquet systemd-container et recréer le lien entre notre conteneur et var/lib/machines (pour l'accès depuis machinectl) quand le firmware est mis à jour.
Il est possible d'automatiser cette opération avec un script qui se lance au démarrage et qui vérifiera si le paquet est installé.

Téléchargez le script  the 0-setup-system.sh dans le répertoire /data/on_boot.d.

mkdir -p /data/on_boot.d && cd /data/on_boot.d
curl -LO https://raw.githubusercontent.com/unifi-utilities/unifios-utilities/main/nspawn-container/scripts/0-setup-system.sh
chmod +x /data/on_boot.d/0-setup-system.sh

Téléchargez pour sauvegarde les fichiers des paquets systemd-container et ses dépendances, au cas où votre UDM ne serait pas connecté à Internet au moment du premier démarrage après application d'une mise à jour.

mkdir -p /data/custom/dpkg && cd /data/custom/dpkg
apt download systemd-container libnss-mymachines debootstrap arch-test

A nouveau, le script 0-setup-system.sh dans le répertoire /data/on_boot.d a besoin d'être lancé au démarrage de l'UDM et encore une fois, le plus simple est d'utiliser le service udm-boot qui lancera automatiquement tous les scripts présents dans le répertoire /data/on_boot.d.
Pour cela, il suffit de lancer le script suivant :

curl -fsL "https://raw.githubusercontent.com/unifi-utilities/unifios-utilities/HEAD/on-boot-script-2.x/remote_install.sh" | /bin/bash

Installation de services

Vous pouvez maintenant installer tous les services que vous souhaitez dans le conteneur comme vous le feriez sur n'importe quel système Linux.

Pensez à vous connecter dans le conteneur pour installer les services !
machinectl shell debian-custom
💡
Ce tutoriel vise seulement à vous fournir / rappeler les commandes pour installer ces services, et ne détaillera pas leur configuration ni utilisation.

Parmi les services les plus courants, on peut citer :

  • Adguard Home

Adguard Home est un serveur DNS qui sert de bloqueur de publicités et sites malveillants.

apt -y install curl
curl -s -S -L https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh -s -- -v

Rendez-vous ensuite sur http://10.0.5.3:3000 (ou l'adresse IP que vous avez définie pour le conteneur) pour configurer AdGuard Home.

  • Pi-Hole

Pi-Hole est également un serveur de DNS qui permet de bloquer les publicités.

apt -y install curl
curl -sSL https://install.pi-hole.net | PIHOLE_SKIP_OS_CHECK=true bash

Attention à bien définir la variable PIHOLE_SKIP_OS_CHECK à true pour sauter la vérification de l'OS installé.
Répondez aux différentes questions pour la configuration de Pi-Hole et vous pourrez accéder à la page d'administration de Pi-Hole depuis http://10.0.5.3/admin.

  • Zoraxy

Zoraxy est un reverse proxy amélioré avec des fonctions de monitoring.
Attention, récupérez bien la dernière version disponible ici.

mkdir zoraxy && cd zoraxy
wget https://github.com/tobychui/zoraxy/releases/download/3.1.0/zoraxy_linux_arm64
mv zoraxy_linux_arm64 zoraxy && chmod +x zoraxy
./zoraxy -port=:8000

Pensez à configurer Zoraxy en tant que service et à activer le démarrage automatique.
Rendez-vous sur la page de configuration depuis http://10.0.5.3:8000.


Conclusion

Voilà, j'espère que ce tutoriel vous aura été utile et vous permettra de faire tourner des services (NPM, Adguard, ...) sur votre UniFi Dream Machine.

Personnellement, j'ai choisi d'héberger sur l'UDM uniquement les services réseaux critiques Adguard Home, NPM et Zoraxy (qui est en test pour potentiellement remplacer NPM). J'ai fait ce choix tout simplement parce qu'ils sont indispensables au fonctionnement des autres services que j'héberge, et qu'ils doivent être disponibles en toutes conditions (du moment que j'ai un accès internet fonctionnel), donc même en cas d'indisponibilité du NUC ou du nas.

Merci de m'avoir lu, n'hésitez pas à laisser un commentaire sur cet article ou à venir échanger avec nous sur notre groupe Telegram si vous avez des questions, que ça soit sur ce tutoriel ou n'importe quel autre sujet.