У меня есть удаленный vps, работающий с CentOS 7, связанный firewalld
информация как ниже, firewalld
работает активно.
[root@doer mydir]# firewall-cmd --get-zone-of-interface=eth0
no zone
[root@ doer mydir]# firewall-cmd --list-ports
You're performing an operation over default zone ('public'),
but your connections/interfaces are in zone 'home' (see --get-active-zones)
You most likely need to use --zone=home option.
3306/tcp
Я запускаю контейнер Docker с программой Spring Boot, прослушивающей порт 8080, который сопоставлен с 9182 хост-машины, 9182 отсутствует в списке открытых портов, но я все еще могу получить доступ к веб-серверу через http: // HOST_MACHINE_IP: 9182, что случилось?
я добавил eth0
в общественную зону
firewall-cmd --permanent --zone=home --add-interface=eth0
и сейчас
[root@ doer mydir]# firewall-cmd --get-zone-of-interface=eth0
public
[root@ doer mydir]# firewall-cmd --list-ports
3306/tcp
все же я могу получить доступ к веб-серверу через http: // HOST_MACHINE_IP: 9182.
# firewall-cmd --list-all-zones
block
target: %%REJECT%%
icmp-block-inversion: no
interfaces:
sources:
services:
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
dmz
target: default
icmp-block-inversion: no
interfaces:
sources:
services: ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
drop
target: DROP
icmp-block-inversion: no
interfaces:
sources:
services:
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
external
target: default
icmp-block-inversion: no
interfaces:
sources:
services: ssh
ports:
protocols:
masquerade: yes
forward-ports:
source-ports:
icmp-blocks:
rich rules:
home (active)
target: default
icmp-block-inversion: no
interfaces: eth1
sources:
services: dhcpv6-client mdns samba-client ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
internal
target: default
icmp-block-inversion: no
interfaces:
sources:
services: dhcpv6-client mdns samba-client ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
Docker устанавливает свои собственные правила брандмауэра непосредственно в ядро хост-сервера, когда вы публикуете порт, без использования удобных инструментов управления брандмауэром уровня абстракции, таких как firewalld
и связанные firewall-cmd
(или аналогично ufw
или Shorewall и другие) предоставляют.
Поскольку докер их не использует любые правила, созданные докером, обычно не будут отображаться, если вы используете эти инструменты только для проверки своего брандмауэра.
Чтобы увидеть, какие правила Docker (или любое другое приложение, которое создает свои собственные правила) на самом деле создает в вашем брандмауэре, вам нужно будет использовать более низкий уровень iptables
и / или iptables-save
команды, которые покажут фактическую живую конфигурацию ядра.
Пытаться
[sudo] iptables -L -v -n --line-numbers
и
[sudo] iptables -L -v -n -t nat --line-numbers
или используйте
[sudo] iptables-save
Обычно правила брандмауэра, создаваемые Docker, имеют прецедент, потому что они вставляются перед правилами, управляемыми вашим удобным инструментом управления брандмауэром.
Я запускаю докер с программой springboot, которая прослушивает порт 8080, который сопоставлен с 9182 хост-машины, 9182 отсутствует в списке открытых портов, но я все еще могу получить доступ к веб-серверу через
http://<HOST_MACHINE_IP>:9182
, что случилось?
Ничего страшного.
Это именно то, что вы указали Docker при создании опубликованного порта:
Опубликованные порты
По умолчанию, когда вы создаете контейнер, он не публикует ни один из своих портов для внешнего мира. Чтобы сделать порт доступным для сервисов за пределами Docker или для контейнеров Docker, которые не подключены к сети контейнера, используйте флаг --publish или -p. Это создает правило брандмауэра который сопоставляет порт контейнера с портом на хосте Docker.https://docs.docker.com/config/containers/container-networking/
Чтобы добавить дополнительные элементы управления доступом к порту, опубликованному Docker, необходимо создать собственные правила в DOCKER-USER
цепочка iptables, как описано здесь: https://docs.docker.com/network/iptables/
Ни один из ответов на самом деле не объясняет причину.
Как сказал HermanB, Docker создает свои собственные правила ... но нигде!
Есть две цепочки, в которых таблица фильтров важна для входящего трафика: INPUT
и FORWARD
Firewalld использует для своих правил таблицу фильтров INPUT.
Docker создает маршрутизацию в PREROUTING
цепи DNAT
стол. Это, как следствие, должно направлять пакеты на FORWARD
цепь, а не INPUT
цепь.
Таким образом, весь трафик, который предполагается использовать контейнерами Docker, «обходит» межсетевой экран.
Поиск "firewalld docker" на serverfault даст вам десятки похожих вопросов.
Необходимо вручную добавить iptables
правила побеждают цель Firewalld. Жаль, что Docker не может нормально работать с Firewalld. Тем не менее, я считаю, что мы можем сделать что-то более чистое, если скажем Firewalld применить те же правила в цепочке FORWARD и разместить пользовательские цепочки Firewalld. перед цепи Докера.
В настоящее время пользовательские цепочки Firewalld (FORWARD_direct, FORWARD_IN_ZONES, FORWARD_OUT_ZONES
) идут после пользовательских цепочек Docker (DOCKER-USER, DOCKER-ISOLATION-STAGE-1, DOCKER
).
iptables -vL -t filter
Используйте firewall-cmd --list-all-zone, посмотрите на "домашнюю" зону, ваш интерфейс подключен к ней. Опубликуйте полные результаты, если у вас есть другие проблемы.