Problème libvirt avec nftables : erreur sur iptables au démarrage du réseau

Good job.
L’architecture nftables est directement embarquée dans le noyau.
Après passage {ip->nf}tables, il faut donc quand-même rebooter pour prévenir le noyau qu’il va gérer les tables nf.

Un peu de lecture de fond, à la demande.
――――――――――
What are the benefits of nftables?
→ The main advantages of nftables are:

Architecture that’s built right into the kernel
• A syntax that consolidates IPtables tools into a single command-line tool
• A compatibility layer that allows the use of IPtables rules syntax.
• A new, easy to learn syntax.
• Simplified process of adding firewall rules.
• Improved error reporting.
• Reduction in code replication.
• Better overall performance, retention and gradual changes in rule filtering.
――――――――――
nftables - Debian Wiki
Nftables - Gentoo Wiki
nftables - ArchWiki
Beginners Guide to nftables Traffic Filtering - Linux Audit
Moving from iptables to nftables - nftables wiki
netfilter/iptables project homepage - Documentation about the netfilter/iptables project
Configuring tables - nftables wiki
Home | firewalld
Legacy xtables tools - nftables wiki
Quick reference-nftables in 10 minutes - nftables wiki
Migrating my iptables setup to nftables - Red Hat Developer
Migrating Debian Buster from iptables to nftables - Gaelan Lloyd
――――――――――

2 J'aime

Merci pour les liens, j’ai pu recréer proprement mes « rules » (et les retrouver au redémarrage !).

Car si j’ai bien compris, les commandes « nft add ... » sont dynamiques et perdues si l’on s’arrête là. Une fois les règles créées, il faut afficher les tables (nft list table …) puis en faire un copier/coller dans /etc/nftables.conf pour les retrouver au prochain redémarrage !

Mais hélas mon problème de virtual network qui ne démarre pas est réapparu, et mes VMs ne démarrent plus.
Il semble bien qu’il y ait un problème entre libvirt et un système qui n’utilise que nftables : j’ai enfin trouvé une page qui évoque ce problème.

Le contournement serait de ne pas utiliser le réseau virtuel créé par libvirt :
$ sudo virsh net-autostart --network default --disable
(voir le supprimer $ sudo virsh net-destroy default)
pour ensuite utiliser des « bridge network » dans les VMs qui ne n’ajoutent pas de règles.

Voilà j’en suis là, je regarde comment créer cette interface réseau de type bridge dans mes VMs… Finalement ce ne sera pas plus mal qu’une interface de type NAT, où l’on est toujours embêté pour les accès aux machines du LAN…

Ton problème de compatibilité ‹ nftables / virtual network › est pointu, et comme je ne peux pas expérimenter, je ne sais pas. A creuser.

Ça par contre, un peu étrange.
Mon fichier /etc/nftables.conf ne bouge pas, heureusement.
A moins que tu évoques quelque-chose de spécifiquement relatif à la virtualisation.
Tu ne commences pas par le plus simple…
D’abord commencer par résoudre « le problème de virtual network qui ne démarre pas est réapparu ».

Pour le virtual network , je me demande si le message d’erreur est parlant, j’ai bien peur que cela n’ait rien à voir avec iptables…
Mais concernant nftables, voilà ce que je fais et constate. Je crée une table, une chain et une règle comme le dit la documentation :

$ sudo nft add table inet incoming-traffic
$ sudo nft add chain inet incoming-traffic management
$ sudo nft add rule inet incoming-traffic management tcp dport 22`

À ce stade, je peux visualiser la table et la règle.

$ sudo nft list tables
table inet filter
table inet incoming-traffic
$ sudo nft list table inet incoming-traffic
table inet incoming-traffic {
	chain management {
		tcp dport 22
	}
}

Et je redémarre. Et la table a disparu, je me retrouve avec la table par défaut (qui correspond au contenu du fichier /etc/nftables.conf :

$ sudo nft list tables
table inet filter
$ sudo nft list table inet filter
table inet filter {
	chain input {
		type filter hook input priority filter; policy accept;
	}

	chain forward {
		type filter hook forward priority filter; policy accept;
	}

	chain output {
		type filter hook output priority filter; policy accept;
	}
}

Donc je ne sais pas ce que je loupe, mais la seule manière que j’ai trouvé de conserver mes tables/chain/règles, c’est de les ajouter au fichier /etc/nftables.confdont je lis d’ailleurs qu’il contient la configuration de nftables dans la page wiki de debian : "By default, rules are located in /etc/nftables.conf".

Ça fait des années que je suis passé à nftables, et n’y touche plus.
Juste un petit check de temps en temps:
sudo nft list ruleset

Je crois me souvenir d’une subtilité liée à ta question, mais ça ne me revient pas pour le moment.

quelques vérifs, ça ne mange pas de pain:

systemctl list-unit-files |grep table

grep Exec /etc/systemd/system/sysinit.target.wants/nftables.service

Pour essai, tu peux mettre tes règles supplémentaires dans un fichier /etc/nftables.rules, et ajouter à /etc/nftables.conf

include "/etc/nftables.rules"

Bon, j’avance !

J’ai pu réactiver le réseau virtuel en réinstallant iptables (+reboot, ce que je n’avais pas fait la dernière fois). Donc mes VMs démarrent, tout va bien.

Mais du coup je ne sais plus trop où j’en suis côté iptables. Le service n’existe pas :

$ sudo systemctl status iptables.service 
Unit iptables.service could not be found.

Mais je vois les rules sans doute crées par libvirt lors de l’activation du réseau : sur un sudo iptables -L, je vois plein de rules à propos de LIBVIRT_ INP, ou LIBVIRT_FWX, etc…
Et quand je tape sudo nft list tables, je vois d’autres tables que la mienne qui ont été ajoutées :

$ sudo nft list tables
table inet filter
table inet incoming-traffic
table ip filter
table ip nat
table ip mangle
table ip6 filter
table ip6 nat
table ip6 mangle

Que faut-il en conclure ?

  • Je pense que ces tables « ip filter », « ip nat », « ip mangle », « ip6 filter », « ip6 nat », « ip6 mangle » ont été ajoutées par libvirt.
  • Mais que seul nftables gère désormais le firewall.
  • Et éventuellement une dépendance de libvirt sur iptables ! :wink:

Tu confirmes ?
Merci de ton aide.

systemctl list-unit-files |grep table
Si cette commande ne t’a rien retourné, ce n’est pas normal.

C’est bien exactement pour cette raison qu’il n’est pas souhaitable de mélanger iptables et nftables, point développé ici .

Iptables n’est pas géré par systemctl
dpkg -L iptables

Tu demandes de confirmer de multiples points simultanément.
Déjà, je te confirme que libvirt0 ne dépend pas d’iptables.

libvirt0 Depends:
libacl1 libapparmor1 libaudit1 libc6 libcap-ng0 libcurl3-gnutls libgcc-s1 libglib2.0-0 libgnutls30 libnl-3-200 libnuma1 libsasl2-2 libselinux1 libssh-4 libssh2-1 libtirpc3 libxml2 libyajl2

Pour savoir pourquoi tu aurais besoin d’iptables, c’est très simple: simule sa suppression !
sudo apt remove -s iptables

$ sudo systemctl list-unit-files |grep table
dbus-org.freedesktop.portable1.service        alias           -
nftables.service                              enabled         enabled
systemd-portabled.service                     static          -

Je me suis mal exprimé en parlant de dépendances. Le binaire n’a pas de dépendances, ok, mais de ce que je comprend de mon problème, c’est qu’en utilisant la commande virsh pour activer le réseau virtuel créé, si iptables n’est pas présent sur le système, cela ne fonctionne pas.

Je ne vois pas ce que je pourrais conclure d’autre, et en l’état, je suis bien obligé d’avoir à la fois iptables et nftables d’installés si je veux pouvoir utiliser mes VMs.

J’essaierai de voir si je peux reproduire le problème sur une autre machine. Pour l’instant je reste comme ça, je n’ai pas vraiment d’autre solution.

libvirt-clients: /usr/bin/virsh

libvirt-clients / Depends:
libvirt0 sensible-utils libc6 libgcc-s1 libglib2.0-0 libgnutls30 libreadline8 libxml2

Re …: que dit ceci
sudo apt remove -s iptables

$ sudo apt remove -s iptables
 Lecture des listes de paquets... Fait
Construction de l'arbre des dépendances... Fait
Lecture des informations d'état... Fait      
Le paquet suivant a été installé automatiquement et n'est plus nécessaire :
  libip6tc2
Veuillez utiliser « sudo apt autoremove » pour le supprimer.
Les paquets suivants seront ENLEVÉS :
  iptables
0 mis à jour, 0 nouvellement installés, 1 à enlever et 0 non mis à jour.
Remv iptables [1.8.8-1]

Tu n’as donc aucune dépendance inverse d’iptables.
Qu’est-ce qui t’empêche de l’enlever ?

Alors je le refais…

$ sudo virsh net-list --all
[sudo] Mot de passe de pascal : 
 Nom       État    Démarrage automatique   Persistent
-------------------------------------------------------
 default   actif   Oui                     Oui

Et je vire iptables :

$ sudo apt remove iptables

Et je redémarre.

$ sudo virsh net-list --all
 Nom       État      Démarrage automatique   Persistent
---------------------------------------------------------
 default   inactif   Oui                     Oui


$ sudo virsh net-start default
erreur :Impossible de démarrer le réseau default
erreur :internal error: Failed to apply firewall rules /usr/sbin/iptables -w --table filter --list-rules: libvirt:  erreur : cannot execute binary /usr/sbin/iptables: Aucun fichier ou dossier de ce type

Voilà, CQFD ! Et au passage :

$ sudo nft list tables
table inet filter
table inet incoming-traffic

Ma liste de tables de nftables est revenue à ce que j’avais fait : le défaut plus le include pour « incoming-traffic ».

Il faut donc purger/nettoyer tes configurations, et repartir sur du propre.
Ça m’étonnerait qu’il y ait une erreur de dépendance de tes paquets ‹ virsh** ›, à moins que tu pointes un bug de dépendance.

Que dit ceci:
ldd /usr/bin/virsh

Je t’ai mis ça sur pastebin.

Ce matin, j’avais mis les logs à debug pour libvirtd, du coup je t’ai mis le ldd de libvirtd aussi, car dans les logs, je voyais :

août 16 10:21:02 Ryzen7-5700G libvirtd[12015]: OBJECT_NEW: obj=0x7fcee02e40d0 classname=virMacMap
août 16 10:21:02 Ryzen7-5700G NetworkManager[882]: <info>  [1660638062.5325] manager: (virbr0): new Bridge device (/org/freedesktop/NetworkManager/Devices/14)
août 16 10:21:02 Ryzen7-5700G libvirtd[12015]: Starting transaction for firewall=0x7fcf100045a0 group=0x7fcf10005400 flags=0x0
août 16 10:21:02 Ryzen7-5700G libvirtd[12015]: Applying rule '/usr/sbin/iptables -w --table filter --list-rules'
août 16 10:21:02 Ryzen7-5700G libvirtd[12015]: internal error: Failed to apply firewall rules /usr/sbin/iptables -w --table filter --list-rules: libvirt:  erreur : cannot execute binary /usr/sbin/iptables: Aucun fichier ou dossier de ce type

On voit libvirtd, et juste avant NetworkManager.
Du coup je me demande si ce n’est pas network-manager qui cause problème : il « suggère » iptables…

$ sudo apt-cache depends network-manager
network-manager
  Dépend: libaudit1
  Dépend: libbluetooth3
  Dépend: libc6
  Dépend: libcurl3-gnutls
  Dépend: libglib2.0-0
  Dépend: libgnutls30
  Dépend: libjansson4
  Dépend: libmm-glib0
  Dépend: libndp0
  Dépend: libnewt0.52
  Dépend: libnm0
  Dépend: libpsl5
  Dépend: libreadline8
  Dépend: libselinux1
  Dépend: libsystemd0
    libelogind0
  Dépend: libteamdctl0
  Dépend: libudev1
  Dépend: dbus
  Dépend: udev
  Dépend: adduser
  Dépend: policykit-1
  Casse: ppp
  Casse: ppp
  Recommande: ppp
  Recommande: dnsmasq-base
    dnsmasq-base-lua
  Recommande: modemmanager
  Recommande: wireless-regdb
  Recommande: wpasupplicant
  Recommande: libpam-systemd
  Suggère: libteam-utils
  Suggère: iptables

Pas besoin d’une si longue liste pour N-M.
Network-manager ne dépend pas, mais Suggère: iptables, comme il pourrait suggérer nftables, c’est-à-dire suggère un firewall.
Tu ne pourrais pas enlever un paquet qui dépendrait d’iptables, sans supprimer iptables.
Toujours pas d’iptables.
Que dit ceci:

sudo grep -r '/usr/sbin/iptables' /etc/

dpkg -l |awk '$2 ~ /tables|qemu|fail|fire/ {print $1,$2}'

Tout s’éclaire ! Avant-hier, en désespoir de cause, j’avais envoyé un mail à la mailing list support user de libvirt (chez redhat en fait). Et j’ai eu la réponse hier soir.

Il y a bien une dépendance entre libvirt et iptables. Sur Debian, elle se trouve dans le paquet libvirt-daemon-system. D’après le type, si debian te laisse retirer iptables sans te prévenir, il s’agit d’un bug.

@Verner : je vais t’envoyer la réponse complète en MP, c’est très intéressant.

Maintenant, je me demande s’il ne faudrait pas créer un bug dans bookworm à ce sujet ? JE ne l’ai jamais fait, je ne sais même si j’ai le droit de le faire ?

Avant de parler de « bug », même si ça restait une hypothèse, il faut être prudent.

libvirt-daemon-system Depends:

iptables | firewalld, 
libvirt-daemon-system-systemd  | libvirt-daemon-system-sysv,
adduser, gettext-base, libvirt-clients, libvirt-daemon, 
libvirt-daemon-config-network, libvirt-daemon-config-nwfilter, 
debconf, logrotate, policykit-1

»»» iptables ou firewalld
Tu peux donc installer firewalld au lieu d’iptables, pour réellement éviter iptables.

▸▸ Le point qui m’échappe dans ce que je t’ai demandé, c’est comment tu peux supprimer iptables, sans supprimer libvirt-daemon-system. Pas normal.

Maintenant, quand je donne des commandes, ce n’est pas juste pour faire joli, j’aime bien voir le retour, sans avoir à redemander. C’est vous qui voyez.

Désolé, je n’ai pas renvoyé le retour des commandes parce que je croyais le problème identifié avec la réponse du support libvirt.

Le voilà :

$ sudo grep -r '/usr/sbin/iptables' /etc/
$ dpkg -l |awk '$2 ~ /tables|qemu|fail|fire/ {print $1,$2}'
ii firefox-esr
ii firefox-esr-l10n-fr
ii firewalld
ii iptables
ii ipxe-qemu
ii libnftables1:amd64
ii libvirt-daemon-driver-qemu
ii libxtables12:amd64
ii nftables
ii python3-firewall
ii python3-nftables
ii qemu-block-extra
ii qemu-efi-aarch64
ii qemu-efi-arm
ii qemu-system
ii qemu-system-arm
ii qemu-system-common
ii qemu-system-data
ii qemu-system-gui
ii qemu-system-mips
ii qemu-system-misc
ii qemu-system-ppc
ii qemu-system-sparc
ii qemu-system-x86
ii qemu-utils

Par ailleurs, le paquet firewalld est bien installé sur le système (même si le service est ‹ disabled ›).

Enfin, pour t’enlever tes doutes (!) … après c’est bookworm (testing), il peut y avoir des bugs, ce n’est pas un scandale :

$ sudo apt policy iptables
iptables:
  Installé : 1.8.8-1
  Candidat : 1.8.8-1
 Table de version :
 *** 1.8.8-1 500
        500 http://deb.debian.org/debian bookworm/main amd64 Packages
        100 /var/lib/dpkg/status

$ sudo apt policy libvirt-daemon-system
libvirt-daemon-system:
  Installé : 8.5.0-1
  Candidat : 8.5.0-1
 Table de version :
 *** 8.5.0-1 500
        500 http://deb.debian.org/debian bookworm/main amd64 Packages
        100 /var/lib/dpkg/status

$ sudo apt remove iptables
Lecture des listes de paquets... Fait
Construction de l'arbre des dépendances... Fait
Lecture des informations d'état... Fait      
Le paquet suivant a été installé automatiquement et n'est plus nécessaire :
  libip6tc2
Veuillez utiliser « sudo apt autoremove » pour le supprimer.
Les paquets suivants seront ENLEVÉS :
  iptables
0 mis à jour, 0 nouvellement installés, 1 à enlever et 153 non mis à jour.
Après cette opération, 2 536 ko d'espace disque seront libérés.
Souhaitez-vous continuer ? [O/n] o
(Lecture de la base de données... 226007 fichiers et répertoires déjà installés.
)
Suppression de iptables (1.8.8-1) ...
Traitement des actions différées (« triggers ») pour man-db (2.10.2-1) ...

$ sudo apt policy libvirt-daemon-system
libvirt-daemon-system:
  Installé : 8.5.0-1
  Candidat : 8.5.0-1
 Table de version :
 *** 8.5.0-1 500
        500 http://deb.debian.org/debian bookworm/main amd64 Packages
        100 /var/lib/dpkg/status
$ sudo apt policy iptables
iptables:
  Installé : (aucun)
  Candidat : 1.8.8-1
 Table de version :
     1.8.8-1 500
        500 http://deb.debian.org/debian bookworm/main amd64 Packages

Tu vois à quoi ça sert les commandes que je demande ?
Je vois seulement maintenant que firewalld est installé, donc parfaitement normal que tu puisses désinstaller iptables. -->> Pas de bug.

Donc, on récapitule.
Supprimer iptables n’est pas un problème, puisque firewalld est installé, mais désactivé.
Il faut donc … l’activer ->> firewalld.service

Après reboot, vois-tu toujours ça dans tes logs ?

libvirtd: Applying rule '/usr/sbin/iptables -w --table filter --list-rules'

Et remontre ça après reboot…
apt list -i '*tables*'
systemctl status firewalld.service

Oui je vois, c’est très intéressant. Je n’avais pas vu le ou pour iptables et firewalld. Comment fais-tu pour avoir une présentation comme ça ? quand je fais un sudo apt-cache depends libvirt-daemon-system, tout s’affiche lign par ligne, et le « | » n’est vraiment pas facile à lire.

Donc, j’autorise le service firewalld et supprime iptables :

$ sudo systemctl enable firewalld.service 
$ sudo apt remove iptables

Et je redémarre. Dans journalctl -b 0, je vois la même erreur :

août 17 18:25:40 Ryzen7-5700G libvirtd[1156]: internal error: Failed to apply firewall rules /usr/sbin/iptables -w --table filter --list-rules: libvirt:  erreur : cannot execute binary /usr/sbin/iptables:
août 17 18:25:40 Ryzen7-5700G libvirtd[1156]: internal error: Failed to apply firewall rules /usr/sbin/ip6tables -w --table filter --list-rules: libvirt:  erreur : cannot execute binary /usr/sbin/ip6tables: 

Voilà le retour de tes commandes :

$ sudo apt list -i '*tables*'
En train de lister... Fait
libnftables1/now 1.0.4-2 amd64  [installé, local]
libxtables12/now 1.8.8-1 amd64  [installé, local]
nftables/now 1.0.4-2 amd64  [installé, local]
python3-nftables/now 1.0.4-2 amd64  [installé, local]

$ sudo systemctl status firewalld.service 
● firewalld.service - firewalld - dynamic firewall daemon
     Loaded: loaded (/lib/systemd/system/firewalld.service; enabled; preset: enabled)
     Active: active (running) since Wed 2022-08-17 18:25:33 CEST; 6min ago
       Docs: man:firewalld(1)
   Main PID: 860 (firewalld)
      Tasks: 2 (limit: 37587)
     Memory: 45.1M
        CPU: 181ms
     CGroup: /system.slice/firewalld.service
             └─860 /usr/bin/python3 /usr/sbin/firewalld --nofork --nopid

août 17 18:25:33 Ryzen7-5700G systemd[1]: Starting firewalld - dynamic firewall daemon...
août 17 18:25:33 Ryzen7-5700G systemd[1]: Started firewalld - dynamic firewall daemon.
août 17 18:25:40 Ryzen7-5700G firewalld[860]: WARNING: COMMAND_FAILED: INVALID_IPV: 'ipv4' is not a valid backend or is unavailable
août 17 18:25:40 Ryzen7-5700G firewalld[860]: WARNING: COMMAND_FAILED: INVALID_IPV: 'ipv4' is not a valid backend or is unavailable

Après une rapide recherche sur le net, le message d’erreur sur ipv4 viendrait de l’absence de iptables !?

Et bien sûr le réseau virtuel n’est pas démarré :

$ sudo virsh net-list --all
 Nom       État      Démarrage automatique   Persistent
---------------------------------------------------------
 default   inactif   Oui                     Oui

$ sudo virsh net-start default
erreur :Impossible de démarrer le réseau default
erreur :internal error: Failed to apply firewall rules /usr/sbin/iptables -w --table filter --list-rules: libvirt:  erreur : cannot execute binary /usr/sbin/iptables: Aucun fichier ou dossier de ce type

Donc à mon avis, on en revient à ce que disait le type de redhat : libvirt a une dépendance à iptables (« libvirt still uses iptables to add its rules »). Et donc avec simplement firewalld, impossible de créer les règles pour le firewall.