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

Перенаправление портов с помощью firewall-cmd

У меня есть несколько виртуальных машин, работающих поверх сервера (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'