Frage Weiterleiten von Ports an Gäste in libvirt / KVM


Wie kann ich Ports auf einem Server, der libvirt / KVM ausführt, an bestimmte Ports in VMs weiterleiten, wenn Sie NAT verwenden?

Zum Beispiel hat der Host eine öffentliche IP von 1.2.3.4. Ich möchte Port 80 zu 10.0.0.1 und Port 22 zu 10.0.0.2 weiterleiten.

Ich nehme an, dass ich iptables-Regeln hinzufügen muss, aber ich bin mir nicht sicher, wo und was genau angegeben werden sollte.

Ausgabe von 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         

Ausgabe von 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)

Ich benutze Ubuntu 10.04.


29
2017-08-13 07:34


Ursprung


Warum verwende ich ifconfig? ip ist der Nachfolger von ifconfig. ;) - Manuel Faux
Frage 233760 adressiert dies auf nie Versionen von libvirt. serverfault.com/questions/233760 - akaihola


Antworten:


Die neueste stabile Version für libvirt für Ubuntu ist Version 0.7.5, die nicht über einige neuere Funktionen verfügt (z. B. Skript-Hooks und Netzwerkfilter), die die automatische Netzwerkkonfiguration vereinfachen. Das heißt, hier ist, wie Port-Weiterleitung für libvirt 0.7.5 auf Ubuntu 10.04 Lucid Lynx zu aktivieren.

Diese iptables Regeln sollten den Trick machen:

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

Die standardmäßige KVM-NAT-Konfiguration bietet eine Regel, die der dritten entspricht, die ich oben angegeben habe, aber sie enthält den NEW-Status, der für die Annahme eingehender Verbindungen unabdingbar ist.

Wenn Sie ein Startskript schreiben, um diese Regeln hinzuzufügen, und Sie nicht vorsichtig sind, überschreibt libvirt 0.7.5 sie, indem sie ihre eigenen einfügt. Um sicherzustellen, dass diese Regeln beim Start korrekt angewendet werden, müssen Sie sicherstellen, dass libvirt initialisiert wurde Vor Sie fügen Ihre Regeln ein.

Fügen Sie die folgenden Zeilen zu /etc/rc.local vor der Zeile hinzu 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
) &

Das sleep 10 oben ist ein Hack, um sicherzustellen, dass der libvirt-Daemon eine Chance hatte, seine iptables-Regeln zu initialisieren, bevor wir unsere eigenen hinzufügen. Ich kann nicht warten, bis sie libvirt Version 0.8.3 für Ubuntu veröffentlichen.


32
2017-08-15 04:11



Kannst du erklären, wie du das mit dem aktuellen libvirt machen würdest? - Manuel Faux
Sie benötigen die gehackten Befehle while loop und sleep nicht, wenn eines der hook-Skripte ausgeführt wird, nachdem libvirt sein Netzwerk initialisiert hat. Ich bin nicht sicher, ob das Skript / etc / libvirt / hooks / daemon vor oder nach der Netzwerkinitialisierung ausgeführt wird, aber wenn Sie / etc / libvirt / hooks / qemu verwenden, können Sie die Regeln beim Start der entsprechenden virtuellen Maschinen erstellen und löschen halt. Ich bin nicht sicher, wie Sie Netzwerkfilter verwenden würden (wenn überhaupt), aber einige der Beispiele bei libvirt.org/firewall.html riechen, als könnten sie modifiziert werden, um die Erstellung von iptables-Regeln zu automatisieren. - Isaac Sutherland
Toll, ich kann bestätigen, dass es funktioniert, aber ich habe nicht versucht, was passiert, wenn ich den Server neu starte ... - Áron Lőrincz


Es gibt eine Möglichkeit, die Portumleitung im laufenden Betrieb einzurichten wenn der Gast das Benutzermodus-Netzwerk verwendetIch habe hier darüber gebloggt:

http://blog.adamspiers.org/2012/01/23/port-redirection-from-kvm-host-to-guest/

Sie können die Details dort sehen, aber aus Bequemlichkeit, hier ist die Lösung, die ich herausgefunden habe:

virsh qemu-monitor-command --hmp sles11 'hostfwd_add ::2222-:22'

Dieser One-Liner ist viel einfacher als die anderen Antworten, funktioniert aber nur in einigen Szenarien (User Mode Network Stack).


17
2018-01-23 02:12



Ihre Lösung ist ziemlich interessant - Können Sie einige der hervorstechenden Details (oder zumindest die How-To-Bits) in Ihre Antwort aufnehmen, damit sie immer noch nützlich ist, wenn Ihr Blog jemals wegen Wartungsarbeiten ausfällt? :) - voretaq7
Fertig, fühle mich frei, meinem SF Ruf zu helfen, höher als 1 zu gehen ;-) - Adam Spiers


Eine "offizielle" [1] Möglichkeit, dies zu tun, ist ein Hook-Skript wie auf der libvirt-Website beschrieben zu erstellen:

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

... im Grunde wird dieses Skript aufgerufen, wenn ein KVM-Gast hochgefahren wird. Das Skript selbst wird die passenden iptable-Regeln hinzufügen (ähnlich der obigen Antwort von Isaac Sutherland) mit dem korrekt hinzugefügten Verbindungsstatus 'NEU'. Beachten Sie, dass Sie das Skript mit den korrekten Werten für Ihre Hosts und Ports ändern müssen.

[1] Obwohl die libvirt-Dokumentation selbst sagt, dass dies eine Art Hack ist, geh Figur


3
2017-11-04 02:09





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

-1
2017-08-13 07:42



Vielen Dank dafür, aber speziell mit KVM brauchte es auch die NEUE Staatsflagge - steveh7