Пересылка портов гостям в libvirt / KVM


33

Как переадресовать порты на сервере с libvirt / KVM на указанные порты на виртуальных машинах при использовании 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

Конфигурация NAT KVM по умолчанию предоставляет правило, аналогичное 3-му, которое я дал выше, но оно пропускает состояние NEW, которое необходимо для приема входящих соединений.

Если вы пишете сценарий запуска, чтобы добавить эти правила, и не будете осторожны, 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?
Мануэль Фо

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

Отлично, я могу подтвердить, что это работает, однако я не пробовал, что произойдет, если я перезапущу сервер ...
Aron Lorincz

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 ;-)
Adam Spiers

Этот подход требует использования сети в режиме пользователя, что может принести нам некоторые неинтересные ограничения. Смотрите: 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-hook-qemu .

В этой теме есть полное объяснение того, как решить эту проблему для CentOS 7 (и, конечно, для других дистрибутивов) с помощью 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
Спасибо вам за это, но для KVM, в частности, необходим также НОВЫЙ государственный флаг
steveh7
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.