การส่งต่อพอร์ตไปยังแขกใน libvirt / KVM


33

ฉันจะส่งต่อพอร์ตบนเซิร์ฟเวอร์ที่ใช้ libvirt / KVM ไปยังพอร์ตที่ระบุใน VM ได้อย่างไรเมื่อใช้ NAT

ตัวอย่างเช่นโฮสต์มี IP สาธารณะเท่ากับ 1.2.3.4 ฉันต้องการส่งต่อพอร์ต 80 ถึง 10.0.0.1 และพอร์ต 22 ถึง 10.0.0.2

ฉันคิดว่าฉันต้องเพิ่มกฎ iptables แต่ฉันไม่แน่ใจว่าเหมาะสมและควรระบุอะไร

เอาต์พุตของ 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         

เอาต์พุตของ 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)

ฉันใช้ Ubuntu 10.04


1
ทำไมต้องใช้ ifconfig ip คือผู้สืบทอดของ ifconfig ;)
Manuel Faux

5
คำถาม 233760 ตอบคำถามนี้ใน libvirt รุ่นที่ไม่เคยมีมาก่อน serverfault.com/questions/233760
akaihola

คำตอบ:


36

การปล่อยเสถียรล่าสุดสำหรับ libvirt สำหรับ Ubuntu คือรุ่น 0.7.5 ซึ่งไม่มีคุณสมบัติใหม่กว่า (เช่น hooks hooks และตัวกรองเครือข่าย) ซึ่งทำให้การกำหนดค่าเครือข่ายอัตโนมัติง่ายขึ้น นี่คือวิธีเปิดใช้งานการส่งต่อพอร์ตสำหรับ libvirt 0.7.5 บน Ubuntu 10.04 Lucid Lynx

กฎ iptables เหล่านี้ควรทำเคล็ดลับ:

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

การกำหนดค่าเริ่มต้นของ KVM NAT มีกฎคล้ายกับข้อที่ 3 ที่ฉันให้ไว้ข้างต้น แต่จะไม่ใช้สถานะใหม่ซึ่งจำเป็นสำหรับการยอมรับการเชื่อมต่อขาเข้า

หากคุณเขียนสคริปต์เริ่มต้นเพื่อเพิ่มกฎเหล่านี้และคุณไม่ระวัง libvirt 0.7.5 จะแทนที่กฎเหล่านั้นด้วยการแทรกสคริปต์ของตนเอง ดังนั้นเพื่อให้แน่ใจว่ากฎเหล่านี้มีการใช้อย่างถูกต้องเมื่อเริ่มต้นคุณต้องแน่ใจว่า libvirt ได้เริ่มต้นก่อนที่คุณจะแทรกกฎของคุณ

เพิ่มบรรทัดต่อไปนี้ใน /etc/rc.local หน้าบรรทัด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
) &

sleep 10ข้างต้นเป็นสับเพื่อให้แน่ใจว่าภูต libvirt ได้มีโอกาสที่จะเริ่มต้นกฎ iptables ก่อนที่เราเพิ่มของเราเอง ฉันไม่สามารถรอจนกว่าพวกเขาจะปล่อย libvirt เวอร์ชัน 0.8.3 สำหรับ Ubuntu


3
คุณสามารถอธิบายวิธีที่คุณจะทำกับ libvirt ปัจจุบันได้อย่างไร
Manuel Faux

1
คุณไม่ต้องการแฮ็กในขณะที่คำสั่งวนรอบและสลีปถ้าหนึ่งใน hook ของสคริปท์ทำงานหลังจาก libvirt เริ่มต้นเครือข่าย ฉันไม่แน่ใจว่าสคริปต์ / etc / libvirt / hooks / daemon ทำงานก่อนหรือหลังการเริ่มต้นเครือข่าย แต่ถ้าคุณใช้ / etc / libvirt / hooks / qemu คุณสามารถสร้างและทำลายกฎเมื่อเครื่องเสมือนที่เหมาะสมเริ่มต้นและ หยุด. ฉันไม่แน่ใจว่าคุณจะใช้ตัวกรองเครือข่ายได้อย่างไร (ตัวอย่างเลย) แต่ตัวอย่างบางส่วนที่libvirt.org/firewall.htmlมีกลิ่นเหมือนที่พวกเขาสามารถแก้ไขได้เพื่อสร้างกฎ iptables โดยอัตโนมัติ
Isaac Sutherland

ที่ยอดเยี่ยมผมสามารถยืนยันได้ว่าการทำงาน แต่ฉันไม่ได้พยายามจะเกิดอะไรขึ้นถ้าฉันเริ่มต้นเซิร์ฟเวอร์ ...
อารอน Lorincz

18

มีวิธีตั้งค่าการเปลี่ยนเส้นทางพอร์ตทันทีเมื่อแขกใช้เครือข่ายโหมดผู้ใช้ฉัน blogged เกี่ยวกับที่นี่:

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

คุณสามารถดูรายละเอียดที่นั่น แต่เพื่อความสะดวกนี่คือคำตอบที่ฉันคิดได้:

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

ซับเดี่ยวนี้ง่ายกว่าคำตอบอื่น ๆ แต่ใช้ได้ในบางสถานการณ์เท่านั้น (สแต็กเครือข่ายโหมดผู้ใช้)


3
โซลูชันของคุณน่าสนใจมาก - คุณสามารถรวมรายละเอียดสำคัญบางอย่าง (หรืออย่างน้อยบิตวิธีการ) ในคำตอบของคุณเพื่อให้ยังคงมีประโยชน์หากบล็อกของคุณไม่สามารถบำรุงรักษาได้หรือไม่? :)
voretaq7

เสร็จแล้วอย่าลังเลที่จะช่วยชื่อเสียง SF ของฉันให้สูงกว่า 1 ;-)
Adam Spires

วิธีการนี้ต้องการการใช้เครือข่ายในโหมดผู้ใช้ซึ่งทำให้เรามีข้อ จำกัด ที่ไม่น่าสนใจ ดู: linux-kvm.org/page/Networking#User_Networking ข้อมูลอ้างอิงอื่น ๆ : topic.alibabacloud.com/a/… , snippets.webaware.com.au/howto/ … ]
Eduardo Lucio

5

วิธี "ทางการ" มากกว่านี้ [1] ในการทำเช่นนี้คือการสร้างเบ็ดสคริปต์ตามที่อธิบายไว้ในเว็บไซต์ libvirt:

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

... โดยพื้นฐานสคริปต์นี้จะถูกเรียกใช้เมื่อแขกของ KVM ถูกบูทขึ้น สคริปต์จะเพิ่มกฎ iptable ที่เหมาะสม (คล้ายกับคำตอบของ Isaac Sutherland ด้านบน) โดยเพิ่มสถานะการเชื่อมต่อ 'ใหม่' อย่างถูกต้อง โปรดทราบว่าคุณต้องแก้ไขสคริปต์ด้วยค่าที่ถูกต้องสำหรับโฮสต์และพอร์ตของคุณ

[1] ถึงแม้ว่าเอกสาร libvirt จะบอกว่านี่เป็นแฮ็ค


0

วิธี "เพียงอย่างเดียว" ที่เราสามารถสร้างพอร์ตไปข้างหน้าโดยใช้ KVM (libvirt) กับ "เครือข่ายเริ่มต้น" (virbr0) กำลังใช้การแฮก / วิธีแก้ปัญหาที่ได้รับแจ้งจาก @Antony Nguyen หรือมากกว่าเพียงแค่คุณสามารถใช้libvirt-เบ็ด qemu

หัวข้อนี้มีคำอธิบายที่สมบูรณ์แบบของวิธีการที่จะแก้ปัญหานี้สำหรับ CentOS 7 (และแน่นอนสำหรับ distros อื่น ๆ ) โดยใช้ libvirt-เบ็ด 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
ขอบคุณสำหรับสิ่งนี้ แต่ด้วย KVM โดยเฉพาะจำเป็นต้องมีการตั้งค่าสถานะใหม่เช่นกัน
steveh7
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.