Это первый раз, когда я обращаюсь к такой сетевой «проблеме», которую нужно решить с помощью Docker, и мне нужны некоторые исходные данные.
Это моя ситуация:
Ubuntu 14.04 с NginX, ufw в качестве брандмауэра и контейнеров Docker для запуска серверного приложения PHP.
Политика Ufw по умолчанию установлена на DROP для INPUT и OUTPUT, а также для FORWARD.
правило sysctl: net.ipv4.conf.all.forwarding = 0
Моя потребность:
Моя проблема:
Ufw настроен на прием входящих подключений на порт 8888 / tcp ТОЛЬКО с ip 8.8.8.8. Отсюда в основном:
sudo ufw allow in from 8.8.8.8 to any port 8888 proto tcp
Затем я запускаю контейнер с помощью:
docker run -p 8888:8888/tcp -p 127.0.0.1:4444:4444/tcp [other options ]
После этого бег nmap -p 8888 45.45.45.45
с машины, у которой НЕ ip = 8.8.8.8, я ожидаю получить port filtered
. Но....
Host is up (0.056s latency).
PORT STATE SERVICE
8888/tcp open unknown
Затем я снова попытался запустить контейнер без -p 8888:8888/tcp
а затем я попытался снова запустить nmap, и ...
Host is up (0.061s latency).
PORT STATE SERVICE
8888/tcp filtered unknown
Следовательно, кажется, поправьте меня, если я ошибаюсь, правила докеров имеют приоритет над правилами ufw.
Затем я искал способ разрешить входящий трафик в контейнере только с определенного адреса и нашел что-то вроде:
iptables -I DOCKER -i ext_if ! -s 8.8.8.8 -j DROP
И это сработало:
PORT STATE SERVICE
8888/tcp filtered unknown
Nmap done: 1 IP address (1 host up) scanned in 15.05 seconds
Тогда мой вопрос:
подходит ли приведенное выше решение для моего случая? Я имею в виду: действуя как указано выше, я отменяю правило ufw allow in from 8.8.8.8 to any port 8888 proto tcp
с правилом докера, которое гласит: «открывать порты только в том случае, если трафик идет с IP 8.8.8.8» ... это правильный подход?
не лучше ли оставить ufw выполнять «плохую работу» по отбрасыванию нежелательных пакетов, а затем просто перенаправлять трафик с фильтрованных портов на докер? Есть ли способ сделать это?
Я бы избегал этого решения, потому что, будучи правилом iptable цепочки DOCKER, это правило включает в себя все контейнеры, которые у меня есть или будут.
Спасибо.
Обратите внимание, что при запуске демон Docker добавляет DOCKER
цепь к *filter
и *nat
правила. Если впоследствии вы очистите все правила iptables, используя, например, ufw, вы можете нарушить ожидаемое поведение. Когда вы запускаете контейнер, FORWARD
правила добавлены к DOCKER
цепь. Докер выполняет такую команду:
iptables --wait -t filter -A DOCKER ! -i docker0 -o docker0 -p tcp -d 172.17.0.2 --dport 8888 -j ACCEPT
Однако это не откроет порт для мира, потому что Docker не изменяет INPUT
правила iptables
. Значит, что-то не так с вашими правилами ufw.
Если вам не нравится, что Docker изменяет ваш iptables
rules, вы можете отключить его в конфигурации службы Docker, добавив --iptables=false
.
В Linux правила ufw и docker реализованы поверх сетевой фильтр. Так это iptables
. Таким образом, невозможно заставить ufw делать одни вещи и заставить правила докеров делать другие - все эти вещи будут выполняться единственной базовой подсистемой netfilter.
Команда iptables-save
полезно выгрузить все, что было настроено для netfilter, включая правила докеров и ufw, а затем (с некоторыми усилиями) вы можете проследить цепочки и посмотреть, что он делает.