Inoltro delle porte agli ospiti in libvirt / KVM


33

Come posso inoltrare le porte su un server che esegue libvirt / KVM a porte specificate su VM, quando utilizzo NAT?

Ad esempio, l'host ha un IP pubblico di 1.2.3.4. Voglio inoltrare la porta da 80 a 10.0.0.1 e la porta da 22 a 10.0.0.2.

Presumo di dover aggiungere le regole di iptables, ma non sono sicuro di dove sia appropriato e cosa esattamente debba essere specificato.

Uscita di 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         

Uscita di 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)

Sto usando Ubuntu 10.04.


1
perché usare ifconfig? ip è il successore di ifconfig. ;)
Manuel Faux,

5
La domanda 233760 risolve questo problema in nessuna versione di libvirt. serverfault.com/questions/233760
akaihola,

Risposte:


37

L'ultima versione stabile di libvirt per Ubuntu è la versione 0.7.5, che non ha alcune nuove funzionalità (ad es. Hook di script e filtri di rete) che semplificano la configurazione automatica della rete. Detto questo, ecco come abilitare il port forwarding per libvirt 0.7.5 su Ubuntu 10.04 Lucid Lynx.

Queste regole di iptables dovrebbero fare il trucco:

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 configurazione NAT KVM predefinita fornisce una regola simile alla terza che ho dato sopra, ma omette il NUOVO stato, che è essenziale per accettare le connessioni in entrata.

Se scrivi uno script di avvio per aggiungere queste regole e non stai attento, libvirt 0.7.5 le sovrascrive inserendone le proprie. Quindi, al fine di assicurarsi che queste regole siano applicate correttamente all'avvio, è necessario assicurarsi che libvirt sia stato inizializzato prima di inserire le regole.

Aggiungi le seguenti righe a /etc/rc.local, prima della riga 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
) &

Quanto sleep 10sopra è un trucco per assicurarsi che il demone libvirt abbia avuto la possibilità di inizializzare le sue regole iptables prima di aggiungere il nostro. Non vedo l'ora che rilascino libvirt versione 0.8.3 per Ubuntu.


3
Puoi spiegare come lo faresti con l'attuale libvirt?
Manuel Faux,

1
Non hai bisogno dei comandi hacked while loop e sleep se uno degli script hook viene eseguito dopo che libvirt ha inizializzato la sua rete. Non sono sicuro che lo script / etc / libvirt / hooks / daemon venga eseguito prima o dopo l'inizializzazione della rete, ma se usi / etc / libvirt / hooks / qemu potresti creare e distruggere le regole quando si avviano le macchine virtuali appropriate e Stop. Non sono sicuro di come useresti i filtri di rete (se non del tutto), ma alcuni degli esempi su libvirt.org/firewall.html hanno l' odore di come potrebbero essere modificati per automatizzare la creazione delle regole di iptables.
Isaac Sutherland,

Ottimo, posso confermare che funziona, tuttavia non ho provato cosa succede se riavvio il server ...
Aron Lorincz,

18

C'è un modo per impostare il reindirizzamento delle porte al volo quando l'ospite utilizza la rete in modalità utente , ho scritto qui sul blog:

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

Puoi vedere i dettagli lì, ma per comodità, ecco la soluzione che ho capito:

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

Questo one-liner è molto più semplice delle altre risposte ma funziona solo in alcuni scenari (stack di rete in modalità utente).


3
La tua soluzione è piuttosto interessante: puoi includere alcuni dei dettagli salienti (o almeno i bit di istruzioni) nella tua risposta in modo che sia ancora utile se il tuo blog è inattivo per manutenzione? :)
voretaq7,

Fatto, sentiti libero di aiutare la mia reputazione in SF a superare 1 ;-)
Adam Spires il

Questo approccio richiede l'uso di una rete in modalità utente che può comportare alcune limitazioni poco interessanti. Vedi: linux-kvm.org/page/Networking#User_Networking . Altri riferimenti: topic.alibabacloud.com/a/… , snippets.webaware.com.au/howto/… ]
Eduardo Lucio,

5

Un modo più "ufficiale" [1] per farlo è quello di creare uno script hook come descritto sul sito web libvirt:

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

... fondamentalmente questo script verrà richiamato all'avvio di un guest KVM. Lo script stesso aggiungerà le regole iptable appropriate (simili alla risposta di Isaac Sutherland sopra) con lo stato di connessione "NUOVO" correttamente aggiunto. Si noti che è necessario modificare lo script con i valori corretti per host e porte.

[1] sebbene la stessa documentazione di libvirt affermi che questo è un tipo di hack, vai a capire


0

L '"unico" modo in cui possiamo fare un port forward usando KVM (libvirt) con la "rete predefinita" (virbr0) sta usando l'hack / soluzione alternativa informata da @Antony Nguyen. O più semplicemente puoi usare libvirt-hook-qemu .

Questo thread ha una spiegazione completa di come risolvere questo problema per CentOS 7 (e certamente per altre distro) usando libvirt-hook-qemu: https://superuser.com/a/1475915/195840 .


-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

1
Grazie per questo, ma con KVM in particolare aveva bisogno anche della NUOVA bandiera dello stato
steveh7
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.