Назад | Перейти на главную страницу

Переадресация портов libvirt? (Вики-руководство нефункционально)

Я установил крючок на /etc/libvirt/hooks/qemu с разрешениями 755, принадлежащими 0: 0, со следующим содержимым:

#!/bin/bash

if [ "${1}" = "virtualmachine" ]; then
  GUEST_IP=192.168.122.2
  GUEST_PORT=1234
  HOST_PORT=1234

  if [ "${2}" = "stopped" ] || [ "${2}" = "reconnect" ]; then
    /sbin/iptables -D FORWARD -o virbr0 -d  $GUEST_IP -j ACCEPT
    /sbin/iptables -t nat -D PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
  fi
  if [ "${2}" = "start" ] || [ "${2}" = "reconnect" ]; then
    /sbin/iptables -I FORWARD -o virbr0 -d  $GUEST_IP -j ACCEPT
    /sbin/iptables -t nat -I PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
  fi
fi

Однако, когда я запускаю его и пытаюсь подключиться через telnet 192.168.1.1 1234 (Я знаю, что это не "правильно", просто проверяю порт вперед), это не удается. Служба работает, и к ней можно подключиться напрямую через выделенный порт. Однако я не могу сохранить выделенный порт, так как не могу выделить физический порт для каждой виртуальной машины.

Хост работает под управлением сервера Ubuntu 19.04, а гость работает под управлением Debian 10.

# 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:67

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             192.168.122.2       
ACCEPT     all  --  anywhere             192.168.122.0/24     ctstate RELATED,ESTABLISHED
ACCEPT     all  --  192.168.122.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         
ACCEPT     udp  --  anywhere             anywhere             udp dpt:bootpc
# qemu-system-x86_64 --version
QEMU emulator version 3.1.0 (Debian 1:3.1+dfsg-2ubuntu3.3)
Copyright (c) 2003-2018 Fabrice Bellard and the QEMU Project developers
# libvirtd --version
libvirtd (libvirt) 5.0.0

Как я могу исправить проблемы с переадресацией портов?

Я разобрался в проблеме, оказывается, мне нужно было запустить iptables -t nat -A POSTROUTING -j MASQUERADE.

Теперь это работает!

Если вы запускаете telnet в хост-системе, вам следует расширить правила. Чтобы перенаправить пакеты, отправленные локально, вы должны добавить правило DNAT в nat/OUTPUT цепь. В вашем случае вам следует добавить строку при соответствующем условии (запуск или переподключение):

/sbin/iptables -t nat -I OUTPUT -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT

Также добавьте противоположную команду для удаления правила.

/sbin/iptables -t nat -D OUTPUT -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT

Чтобы перечислить полный набор правил со счетчиками, лучше использовать iptables-save -c команда вместо iptables, которая по умолчанию показывает только таблицу фильтров.