Meneruskan port ke tamu di libvirt / KVM

33

Bagaimana saya bisa meneruskan port pada server yang menjalankan libvirt / KVM ke port yang ditentukan pada VM, ketika menggunakan NAT?

Misalnya, tuan rumah memiliki IP publik 1.2.3.4. Saya ingin meneruskan port 80 ke 10.0.0.1 dan port 22 ke 10.0.0.2.

Saya berasumsi saya perlu menambahkan aturan iptables, tapi saya tidak yakin di mana yang sesuai dan apa yang harus ditentukan.

Output dari 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         

Output dari 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)

Saya menggunakan Ubuntu 10,04.

steveh7
sumber
1
mengapa menggunakan ifconfig? ip adalah penerus ifconfig. ;)
Manuel Faux
5
Pertanyaan 233760 membahas ini pada versi libvirt yang tidak pernah. serverfault.com/questions/233760
akaihola

Jawaban:

37

Rilis stabil terbaru untuk libvirt untuk Ubuntu adalah versi 0.7.5, yang tidak memiliki beberapa fitur yang lebih baru (yaitu skrip kait dan filter jaringan) yang membuat konfigurasi jaringan otomatis lebih mudah. Yang mengatakan, inilah cara mengaktifkan penerusan port untuk libvirt 0.7.5 di Ubuntu 10.04 Lucid Lynx.

Aturan iptables ini harus melakukan trik:

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

Konfigurasi default KVM NAT memberikan aturan yang mirip dengan ke-3 yang saya berikan di atas, tetapi menghilangkan status BARU, yang penting untuk menerima koneksi yang masuk.

Jika Anda menulis skrip startup untuk menambahkan aturan-aturan ini dan Anda tidak hati-hati, libvirt 0.7.5 menimpanya dengan memasukkan sendiri. Jadi, untuk memastikan aturan ini diterapkan dengan benar pada startup, Anda harus memastikan libvirt telah diinisialisasi sebelum Anda memasukkan aturan Anda.

Tambahkan baris berikut ke /etc/rc.local, sebelum baris 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
) &

Di sleep 10atas adalah hack untuk memastikan daemon libvirt memiliki kesempatan untuk menginisialisasi aturan iptables sebelum kita menambahkan kita sendiri. Saya tidak bisa menunggu sampai mereka merilis versi libvirt 0.8.3 untuk Ubuntu.

Isaac Sutherland
sumber
3
Bisakah Anda menjelaskan bagaimana Anda akan melakukan ini dengan libvirt saat ini?
Manuel Faux
1
Anda tidak memerlukan perintah loop dan sleep yang diretas jika salah satu skrip kait berjalan setelah libvirt menginisialisasi jaringannya. Saya tidak yakin apakah skrip / etc / libvirt / hooks / daemon dijalankan sebelum atau setelah inisialisasi jaringan, tetapi jika Anda menggunakan / etc / libvirt / hooks / qemu Anda dapat membuat dan menghancurkan aturan ketika mesin virtual yang sesuai mulai dan berhenti. Saya tidak yakin bagaimana Anda akan menggunakan filter jaringan (jika ada), tetapi beberapa contoh di libvirt.org/firewall.html berbau seperti mereka dapat dimodifikasi untuk mengotomatisasi pembuatan aturan iptables.
Isaac Sutherland
Hebat, saya bisa memastikan itu berfungsi, namun saya belum mencoba apa yang terjadi jika saya me-restart server ...
Aron Lorincz
18

Ada cara untuk mengatur redirection port dengan cepat ketika tamu menggunakan jaringan mode pengguna , saya membuat blog tentang hal itu di sini:

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

Anda dapat melihat detailnya di sana, tetapi untuk kenyamanan, inilah solusi yang saya temukan:

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

One-liner ini jauh lebih mudah daripada jawaban lain tetapi hanya berfungsi di beberapa skenario (tumpukan jaringan mode pengguna).

Adam Spires
sumber
3
Solusi Anda cukup menarik - Bisakah Anda memasukkan beberapa detail yang menonjol (atau setidaknya cara-bit) dalam jawaban Anda sehingga masih berguna jika blog Anda sedang down untuk pemeliharaan? :)
voretaq7
Selesai, jangan ragu untuk membantu reputasi SF saya lebih tinggi dari 1 ;-)
Adam Spires
Pendekatan ini membutuhkan penggunaan jaringan dalam mode pengguna yang dapat membawa kita beberapa batasan yang tidak menarik. Lihat: linux-kvm.org/page/Networking#User_Networking . Referensi lain: topic.alibabacloud.com/a/… , snippets.webaware.com.au/howto/… ]
Eduardo Lucio
5

Cara yang lebih "resmi" [1] untuk melakukannya adalah dengan membuat skrip kait seperti yang dijelaskan di situs web libvirt:

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

... pada dasarnya skrip ini akan dipanggil ketika seorang tamu KVM di-boot. Script itu sendiri akan menambahkan aturan iptable yang sesuai (mirip dengan jawaban Isaac Sutherland di atas) dengan status koneksi 'BARU' ditambahkan dengan benar. Perhatikan bahwa Anda harus memodifikasi skrip dengan nilai yang benar untuk host dan porta Anda.

[1] meskipun dokumentasi libvirt sendiri mengatakan ini adalah jenis hack, lanjutkan

Antony Nguyen
sumber
0

Cara "hanya" kita dapat membuat port forward menggunakan KVM (libvirt) dengan "jaringan default" (virbr0) menggunakan hack / solusi yang diinformasikan oleh @Antony Nguyen. Atau lebih sederhana, Anda dapat menggunakan libvirt-hook-qemu .

Utas ini memiliki penjelasan lengkap tentang cara mengatasi masalah ini untuk CentOS 7 (dan tentu saja untuk distro lainnya) menggunakan libvirt-hook-qemu: https://superuser.com/a/1475915/195840 .

Eduardo Lucio
sumber
-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
sumber
1
Terima kasih untuk ini, tetapi dengan KVM secara khusus diperlukan bendera negara BARU juga
steveh7