Votre VM est en NAT et vous voulez exposer un service (web, SSH, etc.) depuis l'extérieur ? Cette recette vous montre comment configurer le port forwarding selon votre firewall.
Prérequis
Section intitulée « Prérequis »- VM en NAT avec une IP fixe ou connue (ex:
192.168.122.10) - Accès root sur l'hôte KVM
- Connaître le port à exposer (ex: 80 pour HTTP, 22 pour SSH)
Principe
Section intitulée « Principe »En NAT, les VMs ne sont pas joignables depuis l'extérieur. Le port forwarding redirige un port de l'hôte vers un port de la VM :
Internet → hôte:8080 → NAT DNAT → VM:80Configuration selon le firewall
Section intitulée « Configuration selon le firewall »La règle de redirection est toujours la même sur le fond : une règle DNAT qui réécrit l'adresse de destination des paquets arrivant sur un port de l'hôte. Ce qui change, c'est l'outil qui la porte. Les trois onglets ci-dessous donnent la même configuration dans les trois systèmes de pare-feu que vous rencontrerez sur un hôte KVM. Identifiez le vôtre avant de copier quoi que ce soit.
firewalld est le firewall par défaut sur RHEL 9, Fedora, Rocky, Alma.
Vérifier que firewalld est actif
Section intitulée « Vérifier que firewalld est actif »La sortie doit indiquer active (running). Si le service est inactif, les
règles ajoutées plus bas ne seront pas appliquées.
systemctl status firewalldAjouter une règle de port forwarding
Section intitulée « Ajouter une règle de port forwarding »La première commande agit sur la configuration en cours uniquement : elle disparaîtrait au redémarrage. La seconde recopie l'état courant dans la configuration permanente, ce qui évite d'avoir à saisir la règle deux fois.
# Rediriger le port 8080 de l'hôte vers le port 80 de la VMsudo firewall-cmd --zone=public --add-forward-port=port=8080:proto=tcp:toaddr=192.168.122.10:toport=80
# Rendre la règle permanentesudo firewall-cmd --runtime-to-permanentVérifier
Section intitulée « Vérifier »La sortie doit reprendre la redirection exactement telle que vous l'avez saisie. Une sortie vide signifie que la règle a été posée sur une autre zone.
sudo firewall-cmd --zone=public --list-forward-portsSupprimer la règle
Section intitulée « Supprimer la règle »Le retrait doit reprendre les quatre paramètres à l'identique, sinon firewalld
ne reconnaît pas la règle à supprimer. Ici --permanent vise le fichier de
configuration, d'où le --reload qui applique le changement à la configuration
en cours.
sudo firewall-cmd --zone=public --remove-forward-port=port=8080:proto=tcp:toaddr=192.168.122.10:toport=80 --permanentsudo firewall-cmd --reloadnftables remplace iptables sur les distributions modernes.
Vérifier que nftables est actif
Section intitulée « Vérifier que nftables est actif »Le second affichage est le plus utile : il montre les tables et chaînes déjà en place. Sur un hôte KVM, libvirt y a en général posé ses propres règles, que vous ne devez pas écraser.
systemctl status nftablessudo nft list ruleset | head -20Ajouter une règle de port forwarding
Section intitulée « Ajouter une règle de port forwarding »Les deux règles sont indispensables et se complètent. La première réécrit l'adresse de destination, la seconde autorise le paquet réécrit à traverser l'hôte. Sans elle, la redirection a bien lieu mais le paquet est jeté juste après, ce qui se traduit par un délai d'attente côté client.
# Créer la règle DNATsudo nft add rule ip nat PREROUTING tcp dport 8080 dnat to 192.168.122.10:80
# Autoriser le forwardsudo nft add rule ip filter FORWARD ip daddr 192.168.122.10 tcp dport 80 acceptPersister les règles
Section intitulée « Persister les règles »Les règles ajoutées avec nft add vivent en mémoire et disparaissent au
redémarrage. Cette commande écrit l'intégralité du jeu de règles courant dans le
fichier chargé au démarrage : relisez-le avant de redémarrer, il contient
désormais aussi les règles générées par libvirt.
sudo nft list ruleset > /etc/nftables.confVérifier
Section intitulée « Vérifier »La chaîne doit contenir la règle dnat que vous venez d'ajouter. Si la commande
répond qu'aucune chaîne de ce nom n'existe, c'est que la table nat n'a pas été
créée sur ce système.
sudo nft list chain ip nat PREROUTINGiptables est encore utilisé sur certaines distributions ou configurations legacy.
Ajouter une règle de port forwarding
Section intitulée « Ajouter une règle de port forwarding »Même logique qu'avec nftables, avec une syntaxe différente : -t nat désigne la
table de traduction d'adresses, l'absence de -t dans la seconde commande vise
la table filter par défaut. L'ordre compte, -A ajoute la règle à la fin
de la chaîne : si une règle antérieure rejette déjà ce trafic, la vôtre ne sera
jamais atteinte.
# Rediriger le port 8080 de l'hôte vers le port 80 de la VMsudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.122.10:80
# Autoriser le forwardsudo iptables -A FORWARD -p tcp -d 192.168.122.10 --dport 80 -j ACCEPTPersister les règles
Section intitulée « Persister les règles »iptables ne sauvegarde rien de lui-même : sans l'un des paquets ci-dessous, les règles sont perdues au prochain redémarrage. La procédure diffère selon la famille de distribution.
sudo apt install iptables-persistentsudo netfilter-persistent savesudo dnf install iptables-servicessudo service iptables saveVérifier
Section intitulée « Vérifier »Le -n évite les résolutions DNS, qui rendent l'affichage lent et trompeur. Le
-v ajoute les compteurs de paquets : s'ils restent à zéro alors que vous
testez depuis l'extérieur, le trafic n'atteint même pas cette règle et le
problème se situe en amont.
sudo iptables -t nat -L PREROUTING -n -vsudo iptables -L FORWARD -n -vSupprimer la règle
Section intitulée « Supprimer la règle »-D supprime une règle décrite exactement comme elle a été ajoutée : reprenez
la ligne d'origine en remplaçant le seul -A par -D. Le moindre écart et
iptables répond que la règle n'existe pas.
sudo iptables -t nat -D PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.122.10:80sudo iptables -D FORWARD -p tcp -d 192.168.122.10 --dport 80 -j ACCEPTVérifier que ça fonctionne
Section intitulée « Vérifier que ça fonctionne »Le test doit impérativement partir d'une autre machine que l'hôte KVM. Un
curl lancé depuis l'hôte lui-même emprunte la chaîne OUTPUT et non
PREROUTING : il peut réussir alors que la redirection ne fonctionne pas pour
le reste du réseau, ou échouer alors qu'elle fonctionne. Vérifiez aussi que le
service écoute bien sur toutes les interfaces de la VM, et pas uniquement sur
127.0.0.1.
curl http://<ip-hote>:8080# Doit afficher la page web de la VMDépannage
Section intitulée « Dépannage »Ces trois symptômes se distinguent facilement l'un de l'autre, à condition de lire le message d'erreur. Un refus immédiat signifie que le paquet est arrivé quelque part et qu'on lui a répondu, donc que la redirection fonctionne au moins en partie. Un délai d'attente signifie au contraire qu'aucune réponse n'est revenue : le paquet est perdu en chemin.
| Problème | Cause probable | Solution |
|---|---|---|
| Connection refused | Service non démarré dans la VM | Vérifier que le service écoute sur le bon port |
| Connection timeout | Règle mal appliquée | Vérifier les règles avec iptables -L ou nft list |
| Marche en local, pas en externe | Firewall hôte bloque | Ouvrir le port sur l'interface externe |
Alternative : utiliser un bridge
Section intitulée « Alternative : utiliser un bridge »Si vous avez besoin d'exposer plusieurs services ou de simplifier la configuration, envisagez de passer en mode bridge. Voir le guide réseau KVM.