, , , , ,

Systemd : Échec de chargement du ruleset nftables

Au démarrage de la machine le service nftables.service tente de charger le ruleset mais les interfaces (notamment l'interface wifi) ne sont pas encore prêtes.

La configuration utilise systemd (via les fichers .link) pour renommer l'interface wifi. Les règles de filtrage utilisent l'interface renommée mais lorsque elle sont chargées par le service, l'interface wifi0 n'est pas encore disponible et le processus échoue.

Les journaux système retracent l'évènement :

journalctl -xeu nftables.service

...

░░ L'unité (unit) nftables.service a commencé à démarrer.
juin 27 09:20:06 node-7c87 nft[631]: /etc/nftables.conf:96:17-23: Error: Interface does not exist
juin 27 09:20:06 node-7c87 nft[631]:                 iif { "lan0", "wifi0" } udp dport {137, 138 } ip daddr 192.9.200.255 counter drop comment "Elimine les paquets net>
juin 27 09:20:06 node-7c87 nft[631]:                               ^^^^^^^
juin 27 09:20:06 node-7c87 nft[631]: /etc/nftables.conf:99:17-23: Error: Interface does not exist
juin 27 09:20:06 node-7c87 nft[631]:                 iif { "lan0", "wifi0" } udp dport 5353 ip daddr 224.0.0.251 counter drop comment "Elimine les paquets mDNS"
juin 27 09:20:06 node-7c87 nft[631]:                               ^^^^^^^
juin 27 09:20:06 node-7c87 systemd[1]: nftables.service: Main process exited, code=exited, status=1/FAILURE
░░ Subject: Unit process exited

L'activation du service échoue au démarrage et les règles ne sont pas chargées. Par contre si l'utilisateur lance manuellement le service tout se passe bien. Entre temps, l'interface wifi a bien été renommée et activée.

systemctl is-active nftables.service 
failed
 
systemctl start nftables.service
 
systemctl is-active nftables.service 
active

Une solution consiste à surcharger le fichier unité par défaut pour le service nftables.service et temporiser en attendant que l'interface soit disponible.

systemctl edit nftables.service

La directive ci-dessous permet de patienter jusqu'a ce que l'interface wifi0 soit disponible :

[Service]
ExecStartPre=timeout 60s bash -c 'until ip link show wifi0; do sleep 2; done'

Après modification du fichier unité et redémarrage de la machine, le service est correctement démarré. Les derniers logs apparaissant via la commande systemctl status nftables.service montrent que la boucle until permet bien de temporiser le démarrage du service en attendant la disponibilité de l'interface.

...
juin 27 11:13:20 node-7c87 timeout[359]: Device "wifi0" does not exist.
juin 27 11:13:22 node-7c87 timeout[797]: Device "wifi0" does not exist.
juin 27 11:13:24 node-7c87 timeout[803]: Device "wifi0" does not exist.
juin 27 11:13:26 node-7c87 timeout[1410]: 3: wifi0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
juin 27 11:13:26 node-7c87 timeout[1410]:     link/ether 34:cf:f6:b2:09:8a brd ff:ff:ff:ff:ff:ff
juin 27 11:13:26 node-7c87 systemd[1]: Finished nftables.service - nftables.
Notice: journal has been rotated since unit was started, output may be incomplete.

Références