Transfert de ports vers des invités dans libvirt / KVM

33

Comment puis-je transférer des ports sur un serveur exécutant libvirt / KVM vers des ports spécifiés sur des VM, lorsque j'utilise NAT?

Par exemple, l'hôte a une adresse IP publique de 1.2.3.4. Je souhaite transférer les ports 80 à 10.0.0.1 et 22 à 10.0.0.2.

Je suppose que j’ai besoin d’ajouter des règles iptables, mais je ne suis pas sûr de savoir où est approprié ni ce qui devrait être spécifié.

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 de 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.

steveh7
la source
1
pourquoi utiliser ifconfig? ip est le successeur de ifconfig. ;)
Manuel Faux
5
La question 233760 aborde ceci sur jamais les versions de libvirt. serverfault.com/questions/233760
akaihola

Réponses:

37

La dernière version stable pour libvirt pour Ubuntu est la version 0.7.5, qui ne possède pas de fonctionnalités plus récentes (par exemple, des crochets de script et des filtres réseau) facilitant 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 KVM NAT par défaut fournit une règle similaire à la 3ème que j'ai donnée ci-dessus, mais elle omet l'état NEW, essentiel pour l'acceptation des connexions entrantes.

Si vous écrivez un script de démarrage pour ajouter ces règles sans faire attention, libvirt 0.7.5 les remplace en insérant les siennes. Ainsi, afin de vous assurer que ces règles sont correctement appliquées au démarrage, vous devez vous assurer que libvirt a été initialisé avant d'insérer 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
) &

Ce qui sleep 10précède est un hack permettant de s’assurer que le démon libvirt a eu la possibilité 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.

Isaac Sutherland
la source
3
Pouvez-vous expliquer comment vous procéderiez avec libvirt actuel?
Manuel Faux
1
Vous n'avez pas besoin des commandes while et while hacked while si l'un des scripts de hook s'exécute après que libvirt a initialisé sa mise en réseau. Je ne sais pas si le script / etc / libvirt / hooks / daemon est exécuté avant ou après l'initialisation du réseau, mais si vous utilisez / etc / libvirt / hooks / qemu, vous pouvez créer et détruire les règles lorsque les machines virtuelles appropriées démarrent et Arrêtez. Je ne sais pas comment vous utiliseriez les filtres réseau (le cas échéant), mais certains exemples de libvirt.org/firewall.html semblent pouvoir être modifiés pour automatiser la création de règles iptables.
Isaac Sutherland
Grand, je peux confirmer cela fonctionne, mais je ne l' ai pas essayé ce qui se passe si je redémarre le serveur ...
Aron Lorincz
18

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 rédigé un blog à 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).

Adam Spires
la source
3
Votre solution est très intéressante - Pouvez-vous inclure quelques-uns des détails saillants (ou au moins les instructions) dans votre réponse afin que ce soit toujours utile si votre blog est en maintenance? :)
voretaq7
C'est fait, n'hésitez pas à aider ma réputation de SF à atteindre un niveau supérieur à 1;
Adam Spiers
Cette approche nécessite l’utilisation d’un réseau en mode utilisateur, ce qui peut nous apporter des limitations inintéressantes. Voir: linux-kvm.org/page/Networking#User_Networking . Autres références: topic.alibabacloud.com/a/… , snippets.webaware.com.au/howto/… ]
Eduardo Lucio
5

Une façon plus "officielle" [1] de faire ceci est de créer un script hook comme décrit sur le site Web de libvirt:

http://wiki.libvirt.org/page/Networking#Forwarding_Incoming_Connections

... ce script sera essentiellement appelé lors de l’amorçage d’un invité KVM. Le script lui-même ajoutera les règles iptables appropriées (similaires à la réponse d'Isaac Sutherland ci-dessus) avec l'état de connexion "NEW" correctement ajouté. Notez que vous devez modifier le script avec les valeurs correctes pour vos hôtes et vos ports.

[1] bien que la documentation de libvirt elle-même indique que c'est un peu un hack, allez comprendre

Antony Nguyen
la source
0

Le "seul" moyen de transférer un port à l'aide de KVM (libvirt) avec le "réseau par défaut" (virbr0) consiste à utiliser le hack / solution de contournement informé par @Antony Nguyen. Ou plus simplement, vous pouvez utiliser libvirt-hook-qemu .

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/195840 .

Eduardo Lucio
la source
-1
iptables -t nat -I PREROUTING -d 1.2.3.4 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.1
 iptables -t nat -I PREROUTING -d 1.2.3.4 -p tcp --dport 22 -j DNAT --to-destination 10.0.0.1
topdog
la source
1
Merci pour cela, mais avec KVM en particulier, il avait aussi besoin du NOUVEAU drapeau d'état
steveh7