У меня есть удаленный 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:
Докер устанавливает его собственные правила брандмауэра непосредственно в ядро хост-сервера, когда Вы публикуете порт, не используя уровень абстракции, удобные для пользователя инструменты управления брандмауэром, такой как firewalld
и связанное firewall-cmd
(или так же ufw
или Shorewall и другие) обеспечивают.
, Так как докер не использует их , любой докер правил создает, обычно не будет показываться, когда Вы только используете те инструменты для осмотра брандмауэра .
Для наблюдения, что управляет Докером (или любое другое приложение, которое создает его собственные правила) на самом деле создает в брандмауэре, который Вы должны использовать больше низкоуровневых iptables
и/или iptables-save
команд, которые покажут фактическую живую конфигурацию в ядре.
Попытка
[sudo] iptables -L -v -n --line-numbers
и
[sudo] iptables -L -v -n -t nat --line-numbers
или использование
[sudo] iptables-save
Обычно брандмауэр постановляет, что Докер создает, будет иметь прецедент, потому что они вставляются перед правилами, управляемыми Вашим удобным для пользователя инструментом управления брандмауэром.
я выполняю докера с springboot программой, слушающей на порте 8080, который отображается на 9182 из хост-машины, 9182 не находится во вводном списке портов, но я могу все еще получить доступ к веб-серверу до
http://<HOST_MACHINE_IP>:9182
, что не так?
Ничто не неправильно.
, Который является точно, что Вы дали Докеру команду делать при создании опубликованного порта:
Опубликованные порты
По умолчанию при создании контейнера он не публикует ни одного из своих портов к внешнему миру. Для предоставления доступа к порту доступным для сервисов за пределами Докера, или для контейнеров Докера, которые не подключены к container’s сети использование - публикует или флаг-p. Это создает правило брандмауэра, которое отображает контейнерный порт на порт на хосте Докера.https://docs.docker.com/config/containers/container-networking /
Для добавления большего количества средств управления доступом на порте, опубликованном Докером, требует создания собственных правил в DOCKER-USER
iptables цепочка, как зарегистрировано здесь: https://docs.docker.com/network/iptables /
Используйте брандмауэр-cmd - list-all-zone, посмотрите на "домашнюю" зону, Ваш интерфейс соединен на том. Отправьте полные результаты, если у Вас есть другая проблема.
Ни один из ответов не объясняет причину.
Как сказал HermanB, Docker создает свои собственные правила... но не везде!
Есть две цепочки, в которых таблица фильтров важна для входящего трафика: INPUT
и FORWARD
Firewalld использует таблицу фильтров INPUT для своих правил.
Docker создает маршруты в таблице PREROUTING
цепочки DNAT
. Это приводит к тому, что пакеты направляются в цепочку FORWARD
, а не в цепочку INPUT
.
Таким образом, весь трафик, который должен потребляться контейнерами Docker, «обходит» брандмауэр.
Поиск «firewalld docker» в serverfault даст вам десятки подобных вопросов.
Необходимость вручную добавлять правила iptables
противоречит цели Firewalld.Жаль, что Docker не может нормально работать с Firewalld.
Тем не менее, я считаю, что мы можем сделать что-то более чистое, сказав Firewalld применить те же правила в цепочке FORWARD И поместить пользовательские цепочки Firewalld перед цепочками Docker.
В настоящее время пользовательские цепочки Firewalld (FORWARD_direct, FORWARD_IN_ZONES, FORWARD_OUT_ZONES
) идут после пользовательских цепочек Docker (DOCKER-USER, DOCKER-ISOLATION-STAGE-1, DOCKER
).
iptables -vL -t filter