Comment puis-je transférer des ports sur un serveur exécutant libvirt/KVM vers des ports spécifiés sur des VM, lors de l'utilisation de NAT?
Par exemple, l'hôte a une adresse IP publique de 1.2.3.4. Je veux transférer le port 80 à 10.0.0.1 et le port 22 à 10.0.0.2.
Je suppose que je dois ajouter des règles iptables, mais je ne sais pas où il convient et ce qui doit être spécifié exactement.
Sortie d'iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT udp -- anywhere anywhere udp dpt:domain
ACCEPT tcp -- anywhere anywhere tcp dpt:domain
ACCEPT udp -- anywhere anywhere udp dpt:bootps
ACCEPT tcp -- anywhere anywhere tcp dpt:bootps
Chain FORWARD (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere 10.0.0.0/24 state RELATED,ESTABLISHED
ACCEPT all -- 10.0.0.0/24 anywhere
ACCEPT all -- anywhere anywhere
REJECT all -- anywhere anywhere reject-with icmp-port-unreachable
REJECT all -- anywhere anywhere reject-with icmp-port-unreachable
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Sortie d'ifconfig
eth0 Link encap:Ethernet HWaddr 00:1b:fc:46:73:b9
inet addr:192.168.1.14 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: fe80::21b:fcff:fe46:73b9/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:201 errors:0 dropped:0 overruns:0 frame:0
TX packets:85 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:31161 (31.1 KB) TX bytes:12090 (12.0 KB)
Interrupt:17
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
virbr1 Link encap:Ethernet HWaddr ca:70:d1:77:b2:48
inet addr:10.0.0.1 Bcast:10.0.0.255 Mask:255.255.255.0
inet6 addr: fe80::c870:d1ff:fe77:b248/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:468 (468.0 B)
J'utilise Ubuntu 10.04.
La dernière version stable de libvirt pour Ubuntu est la version 0.7.5, qui n'a pas de fonctionnalités plus récentes (c'est-à-dire des crochets de script et des filtres réseau) qui facilitent la configuration automatique du réseau. Cela dit, voici comment activer la redirection de port pour libvirt 0.7.5 sur Ubuntu 10.04 Lucid Lynx.
Ces règles iptables devraient faire l'affaire:
iptables -t nat -I PREROUTING -p tcp -d 1.2.3.4 --dport 80 -j DNAT --to-destination 10.0.0.1:80
iptables -t nat -I PREROUTING -p tcp -d 1.2.3.4 --dport 22 -j DNAT --to-destination 10.0.0.2:22
iptables -I FORWARD -m state -d 10.0.0.0/24 --state NEW,RELATED,ESTABLISHED -j ACCEPT
La configuration par défaut KVM NAT fournit une règle similaire à la troisième que j'ai donnée ci-dessus, mais elle omet le nouvel état, qui est essentiel pour accepter les connexions entrantes.
Si vous écrivez un script de démarrage pour ajouter ces règles et que vous ne faites pas attention, libvirt 0.7.5 les remplace en insérant les siennes. Donc, pour vous assurer que ces règles sont appliquées correctement au démarrage, vous devez vous assurer que libvirt a initialisé avant vous insérez vos règles.
Ajoutez les lignes suivantes à /etc/rc.local, avant la ligne exit 0
:
(
# Make sure the libvirt has started and has initialized its network.
while [ `ps -e | grep -c libvirtd` -lt 1 ]; do
sleep 1
done
sleep 10
# Set up custom iptables rules.
iptables -t nat -I PREROUTING -p tcp -d 1.2.3.4 --dport 80 -j DNAT --to-destination 10.0.0.1:80
iptables -t nat -I PREROUTING -p tcp -d 1.2.3.4 --dport 22 -j DNAT --to-destination 10.0.0.2:22
iptables -I FORWARD -m state -d 10.0.0.0/24 --state NEW,RELATED,ESTABLISHED -j ACCEPT
) &
Le sleep 10
ci-dessus est un hack pour s'assurer que le démon libvirt a eu la chance d'initialiser ses règles iptables avant d'ajouter les nôtres. Je ne peux pas attendre jusqu'à ce qu'ils libèrent la version 0.8.3 de libvirt pour Ubuntu.
Il existe un moyen de configurer la redirection de port à la volée lorsque l'invité utilise un réseau en mode utilisateur , j'ai blogué à ce sujet ici:
http://blog.adamspiers.org/2012/01/23/port-redirection-from-kvm-Host-to-guest/
Vous pouvez voir les détails ici, mais pour plus de commodité, voici la solution que j'ai trouvée:
virsh qemu-monitor-command --hmp sles11 'hostfwd_add ::2222-:22'
Ce one-liner est beaucoup plus facile que les autres réponses mais ne fonctionne que dans certains scénarios (pile réseau en mode utilisateur).
Une façon plus "officielle" [1] de le faire est de créer un script de hook comme décrit sur le site Web de libvirt:
http://wiki.libvirt.org/page/Networking#Forwarding_Incoming_Connections
... en gros, ce script sera invoqué quand un KVM est démarré. Le script lui-même ajoutera les règles iptables appropriées (similaires à la réponse d'Isaac Sutherland ci-dessus) avec la connexion 'NEW' état correctement ajouté. Notez que vous devez modifier le script avec les valeurs correctes pour vos hôtes et ports.
[1] bien que la documentation de libvirt elle-même dise que c'est une sorte de hack, allez comprendre
La "seule" façon dont nous pouvons faire un port en avant en utilisant KVM (libvirt) avec le "réseau par défaut" (virbr0) utilise le hack/contournement informé par @Antony Nguyen. Ou plus simplement vous peut utiliser libvirt-hook-qem .
Ce fil a une explication complète de la façon de résoudre ce problème pour CentOS 7 (et certainement pour d'autres distributions) en utilisant libvirt-hook-qemu: https://superuser.com/a/1475915/19584 .