Переадресація портів до гостей в 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. ;)
Мануель Фокс

5
Питання 233760 стосується цього питання у жодних версіях libvirt. serverfault.com/questions/233760
akaihola

Відповіді:


37

Останній стабільний випуск libvirt для Ubuntu - це версія 0.7.5, яка не має деяких нових функцій (наприклад, гачки сценаріїв та мережеві фільтри), що полегшує автоматичне налаштування мережі. З цього приводу, ось як увімкнути переадресацію портів для 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
Чи можете ви пояснити, як би ви це зробили за допомогою поточного лібвірту?
Мануель Фокс

1
Вам не потрібні зламані команди циклу та режиму сну, якщо один із сценаріїв гака запускається після того, як libvirt ініціалізує свою мережу. Я не впевнений, що сценарій / etc / libvirt / hooks / daemon запускається до і після ініціалізації мережі, але якщо ви використовуєте / etc / libvirt / hooks / qemu, ви можете створити та знищити правила, коли запускаються відповідні віртуальні машини та Стоп. Я не впевнений, як би ви використовували мережеві фільтри (якщо вони взагалі були), але деякі приклади на libvirt.org/firewall.html мають запах, ніби вони могли змінити для автоматизації створення правил iptables.
Ісаак Сазерленд

Чудово, можу підтвердити, що це працює, однак я не намагався, що трапиться, якщо перезавантажую сервер ...
Арон Лоринц

18

Існує спосіб налаштувати переадресацію портів на ходу, коли гість використовує мережеві режими в користувальницькому режимі , я про це розміщував тут журнал:

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 ;-)
Адам Шпіерс

Цей підхід вимагає використання мережі в режимі користувача, що може принести нам деякі нецікаві обмеження. Дивіться: linux-kvm.org/page/Networking#User_Networking . Інші посилання: topic.alibabacloud.com/a/… , snippets.webaware.com.au/howto/… ]
Едуардо

5

Більш "офіційний" спосіб [1] зробити це - створити сценарій гачка, як описано на веб-сайті libvirt:

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

... в основному цей сценарій буде запущений під час завантаження гостя KVM. Сам скрипт додасть відповідні правила iptable (подібно до відповіді Ісаака Сазерленда вище) із правильним додаванням стану "NEW". Зауважте, що ви повинні змінити сценарій з правильними значеннями для своїх хостів і портів.

[1], хоча сама документація на libvirt говорить, що це щось на кшталт зламання


0

"Єдиний" спосіб ми можемо зробити порт вперед за допомогою KVM (libvirt) з "мережею за замовчуванням" (virbr0), використовуючи хак / вирішення, повідомлене @Antony Nguyen. Або простіше ви можете використовувати libvirt-hoke-qemu .

Цей потік має повне пояснення, як вирішити цю проблему для CentOS 7 (і, звичайно, для інших дистрибутивів) за допомогою libvirt-hoke-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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.