У меня есть сервер с одним внешним IP-адресом (например, 1.2.3.4
). На этом сервере я использую libvirt для запуска виртуальных машин. Теперь я хочу получить доступ к виртуальному серверу на моем хосте через ssh (port 1234
) снаружи.
В моей хост-системе я получил сетевой интерфейс eth0
который подключен к моему внешнему IP (1.2.3.4
).
Моя виртуальная машина подключена к хост-машине через интерфейс nat, который называется virbr0
с ip 192.168.122.235
.
Поскольку мне нужно перенаправить порт, я сделал следующее с iptable
iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 1234 -j DNAT --to-destination 192.168.122.235:1234
iptables -A FORWARD -p tcp -d 192.168.122.235 --dport 1234 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
Для базовых сетей у меня также есть UFW
работает на хосте позволяет port 1234
:
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), allow (routed)
New profiles: skip
To Action From
-- ------ ----
[SOMEOTHERPORTS]
1234/tcp ALLOW IN Anywhere
1234/tcp (v6) ALLOW IN Anywhere (v6)
Я убедился, что пересылка разрешена для всех задействованных сетевых интерфейсов:
user@someserver ~ # cat /proc/sys/net/ipv4/conf/virbr0/forwarding
1
user@someserver ~ # cat /proc/sys/net/ipv4/conf/eth0/forwarding
1
При попытке подключиться по ssh к серверу из внешней сети к 1.2.3.4
Я получил:
ssh: connect to host 1.2.3.4 port 1234: Connection refused
Я проверил ssh-соединение с хоста, которое работает отлично.
Следует учесть несколько вещей.
Что я здесь делаю не так?
Давайте посмотрим на текущую конфигурацию iptables, а затем мы сможем ее изучить.
UFW мешает iptables?
UFW - это интерфейс командной строки для iptables, но в нем отсутствуют многие функции iptables. Конфигурация iptables покажет нам, что сделал UFW на основе введенных вами команд. Однако вам не следует создавать правила с обоими на одном компьютере. Это требует осложнений. Если вы собираетесь вводить свои команды в UFW, все в порядке, но скрипты iptables должны быть отключены. Если вы собираетесь вводить свои команды в iptables, вам следует удалить UFW.
Как я могу заставить это работать?
Попробуй это.
iptables -t nat -I PREROUTING -p tcp -i eth0 --dport 1234 -j DNAT --to 192.168.122.235:1234
iptables -A FORWARD -i eth0 -o vibr0 -p tcp --dport 1234 -j ACCEPT
Но учтите, что гость подключается к хосту через NAT с адаптером. Так что это, вероятно, не сработает.
Вам действительно стоит подумать об изменении типа адаптера с NAT на мостовой.
У меня была практически такая же проблема. Я хотел перенаправить порт 22 с моего хост-компьютера на мою виртуальную машину, также работающую с KVM, с сетью NAT.
Я нашел этот пост: https://ubuntuforums.org/showthread.php?t=2261173&p=13210545#post13210545
Которые дали мне ответы.
TL; DR
192.168.1.161 - это IP моего сервера во внутренней сети. 192.168.122.2 - мой IP-адрес виртуальной машины на хосте.
iptables -t nat -I PREROUTING -p tcp -d 192.168.1.161 --dport 22 -j DNAT --to-destination 192.168.122.2:22
iptables -I FORWARD -m state -d 192.168.122.2/24 --state NEW,RELATED,ESTABLISHED -j ACCEPT
Заявление об ограничении ответственности. Я понятия не имею, что именно это делает. Он выглядит так же, как и многие другие найденные ответы, только некоторые теги параметров немного отличаются.
Это мои правила пересылки, которые очень хорошо подходят.
-A POSTROUTING -s 192.168.122.0/24 -d 224.0.0.0/24 -j RETURN
-A POSTROUTING -s 192.168.122.0/24 -d 255.255.255.255/32 -j RETURN
-A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p tcp -j MASQUERADE --to-ports 1024-65535
-A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p udp -j MASQUERADE --to-ports 1024-65535
-A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -j MASQUERADE
-A POSTROUTING -s 192.168.122.0/24 -o br1 -j MASQUERADE
-A INPUT -s 192.168.122.0/24 -j ACCEPT
-A FORWARD -d 192.168.122.0/24 -o virbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -s 192.168.122.0/24 -i virbr0 -j ACCEPT
-A FORWARD -i virbr0 -o virbr0 -j ACCEPT
-A FORWARD -o virbr0 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -i virbr0 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -i virbr0 -j ACCEPT
-A FORWARD -i br1 -o virbr0 -j ACCEPT
Я также думаю, что вам следует использовать мостовое соединение:
Попробуйте узнать свое название сети:
virsh net-edit <network name>
Название сети вы можете увидеть в Virt Manager. Обычно по умолчанию:
virsh net-edit default
Измените NAT на мост (также имя моста, которое вы найдете в Virt Manager)
<network>
<name>default</name>
<uuid>cc45a671-e8d8-4149-a6a5-8d5547551a58</uuid>
<forward mode='route'/>
<bridge name='virbr0' stp='on' delay='0'/>
<mac address='AA:CC:DD:86:53:54'/>
<ip address='192.168.122.1' netmask='255.255.255.0'>
<dhcp>
<range start='192.168.122.2' end='192.168.122.254'/>
</dhcp>
</ip>
</network>
Примечания:
В этом примере мы использовали DHCP для присвоения имен виртуальным машинам. Вы также можете сделать статические настройки
Если вы используете ifconfig, вы должны получить:
virbr0 Link encap: Ethernet Hardware Adresse AA: VV: CC: 86: 53: 54
inet Adresse: 192.168.122.1 Bcast: 192.168.122.255 Maske: 255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU: 1500 Metrik: 1 RX-Pakete: 127 Fehler: 0 Verloren: 0 Überläufe: 0 Fenster: 0 TX-Pakete: 44 Fehler: 0 Verloren: 0 Uberläufe: 0 Träger: 0 Kollisionen: 0 Sendewarteschlangenlänge: 0 RX-Bytes: 13032 (13.0 KB) TX-Bytes: 4707 (4.7 KB)
В основном вы должны использовать порт 22 для ssh
Попробуй использовать:
sudo iptables -t nat -A POSTROUTING -s 192.168.122.235 -j SNAT --to-source 1.2.3.4
Так что вы можете локализовать, если это проблема с портами. Фактически, вы можете после закрытия портов на виртуальной машине с помощью Gufw.