Я использую ufw
для настройки брандмауэра в моей хост-системе.Кажется, что ufw
в некоторых случаях позволит мне обойти определенные правила при использовании его в сочетании с докером.
Мне известно, что докер по умолчанию напрямую изменяет iptables, что приводит к определенным проблемам , особенно с ufw
, но я столкнулся с проблемой, которая мне кажется очень странной.
Вот что я сделал.
sudo ufw default deny incoming
sudo ufw allow ssh
8181
([ Контекст: позже это будет использоваться для создания ssh-туннеля к моему хосту и порта доступа 8181
из любого места - но сейчас это не важно ) sudo ufw allow from 127.0.0.1 to 127.0.0.1 port 8181
sudo ufw enable
Если я сейчас посмотрю на статус брандмауэра через sudo ufw status
, он покажет следующее:
Status: active
To Action From
-- ------ ----
22/tcp ALLOW Anywhere
127.0.0.1 8181 ALLOW 127.0.0.1
22/tcp (v6) ALLOW Anywhere (v6)
Выглядит хорошо, но теперь перейдем к странной части. У меня есть API, который работает внутри контейнера докера
, доступного на внутреннем порте 8080
.
Если я сейчас запущу контейнер докеров с помощью следующей команды и сопоставлю порт 8080
с портом 8181
в моей хост-системе
docker run -d --name ufw_test -p 8181:8080 mytest/web-app:latest
, похоже, что я обойду мое правило, которое я установил ранее, чтобы разрешить трафик только с 127.0.0.1
на 127.0.0.1
на порт 8181
. Я мог получить доступ к своему API отовсюду. Я пробовал это на разных ПК в одной сети, и мой API был доступен через 192.168.178.20:8181
с другого ПК.Я подумал, что способ исправить это - запустить мой контейнер следующим образом:
docker run -d --name ufw_test -p 127.0.0.1:8181:8080 mytest/web-app:latest
Это ограничит доступ к моему API так, как я предполагал, однако мне интересно, по какой причине сработала вторая команда, где сначала не сделал?
ufw
показывает только конфигурацию ufw и любые правила, вставленные непосредственно в конфигурацию вашего брандмауэра (с помощью iptables
напрямую или другого инструмента, такого как docker) без прохождения через ufw. НЕ отображается.
Правила брандмауэра в Linux применяются в том порядке, в котором они перечислены.Когда вы запускаете контейнер докеров , докер вставляет правила, необходимые вашим контейнерам докеров, перед существующими правилами и набором правил, который вы поддерживаете с помощью ufw.
Другими словами, Docker, открывающий порт, имеет приоритет над последующими правилами ufw, закрывающими конкретный порт.
Проверьте, например, с помощью [sudo] iptables-save
, какой у вас эффективный набор правил.
Что касается того, почему -p 127.0.0.1:8181:8080
работает по-другому?
Создаваемое докером правила брандмауэра по-прежнему будет иметь приоритет перед вашими правилами ufw, но вместо того, чтобы открывать порт на всех интерфейсах, в том числе для публики, вы теперь указываете докеру, что он будет гораздо более ограничительным и будет предоставлять порт только на localhost
.