У меня есть несколько виртуальных машин, работающих поверх сервера (Virtual Machine Manager, VMM). Я хочу перенаправить порт 80 на сервере на порт 80 одной из моих виртуальных машин. Хост работает под управлением CentOS7, поэтому за него отвечает firewalld. Судя по всему, firewalld также используется VMM для обработки виртуальных подключений, поэтому я не могу просто выбросить его из окна.
Я в основном воспроизвел все команды в этот поток без успеха, что сводится к:
firewall-cmd --permanent --zone=public --add-forward-port=port=80:proto=tcp:toport=80:toaddr=192.168.122.224
или
firewall-cmd --permanent --zone=public --add-rich-rule 'rule family=ipv4 forward-port port=80 protocol=tcp to-port=80 to-addr=192.168.122.224'
Текущий статус firewalld следующий:
[root@my-machine ~]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: enp8s0
sources:
services: ssh dhcpv6-client samba smtp http
ports: 25/tcp
protocols:
masquerade: yes
forward-ports:
source-ports:
icmp-blocks:
rich rules:
rule family="ipv4" forward-port port="80" protocol="tcp" to-port="80" to-addr="192.168.xxx.xxx"
Это результат
iptables -L -n -v
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
13917 8976K ACCEPT all -- * virbr0 0.0.0.0/0 192.168.122.0/24 ctstate RELATED,ESTABLISHED
13539 2093K ACCEPT all -- virbr0 * 192.168.122.0/24 0.0.0.0/0
0 0 ACCEPT all -- virbr0 virbr0 0.0.0.0/0 0.0.0.0/0
4 240 REJECT all -- * virbr0 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable <-----
1 133 REJECT all -- virbr0 * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
0 0 ACCEPT all -- virbr1 virbr1 0.0.0.0/0 0.0.0.0/0
0 0 REJECT all -- * virbr1 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
0 0 REJECT all -- virbr1 * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
0 0 FORWARD_direct all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 FORWARD_IN_ZONES_SOURCE all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 FORWARD_IN_ZONES all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 FORWARD_OUT_ZONES_SOURCE all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 FORWARD_OUT_ZONES all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate INVALID
0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
проблема во втором правиле, которое, похоже, отклоняет мои пакеты (я вижу, что число увеличивается при попытке подключения). Действительно, если я удалю его с помощью:
iptables -D FORWARD -o virbr0 -j REJECT --reject-with icmp-port-unreachable
у меня проброс портов работает. Что мне не хватает?
Смешивание firewalld с libvirt может привести вас к подобной ситуации.
По умолчанию с сетью "NAT" сеть libvirt устанавливает правила маскировки, чтобы виртуальные машины могли получить доступ к устаревшей сети IPv4 Internet. Но libvirt блокирует все входящие подключения к сетям "NAT".
Решение состоит в том, чтобы изменить сеть на обычную маршрутизируемую сеть, а затем позволить firewalld обрабатывать любую маскировку, которая может вам потребоваться.
Например, вы отредактируете сетевой XML и измените
<forward mode='nat'/>
к
<forward mode='route'/>
Я рекомендую вам изменить все В этом сценарии сети libvirt NAT будут маршрутизироваться, а не только той, на которую вы хотите перенаправить порты, если вы хотите разрешить сетям взаимодействовать друг с другом.
Затем вы устанавливаете маскировку в зоне firewalld, соответствующей интерфейсу, подключенному к остальной части Интернета. Например:
firewall-cmd [--permanent] --zone=public --add-masquerade
(В firewalld 0.4.4.6 или более поздней версии вы не должны использовать это, а вместо этого создайте расширенное правило для маскарада IPv4. В этих версиях есть ошибка, из-за которой правило маскировки IPv6 также добавляется при использовании --add-masquerade
, что нарушит подключение IPv6.)
firewall-cmd [--permanent] --zone=public --add-rich-rule='rule family=ipv4 masquerade'