Решение вопроса с обходом запрещающих правил фаервола в Docker
Проблема:
При включенном фаерволе (iptables), настроенном на полный запрет входящего трафика, любой docker контейнер с опубликованными портами становится открытым для доступа из интернета, это обусловлено правилами iptables которые добавляет сам docker автоматически при установке.
Решение проблемы:
Установить скрипт, который добавляет необходимые правила в iptables которые по умолчанию запрещают доступ ко всем контейнерам со стороны интернета (доступ из диапазонов локальных сетей сохраняется). В дальнейшем если для какого-то docker контейнера нужно разрешить входящий трафик из интернета необходимо вместо стандартного iptables менеджера ufw использовать скрипт ufw-docker.
Установка ufw-docker:
Скачиваем файл скрипта и сохраняем его в /usr/local/bin/ufw-docker
sudo wget -O /usr/local/bin/ufw-docker https://github.com/chaifeng/ufw-docker/raw/master/ufw-docker
Меняем файлу скрипта разрешение на запуск
sudo chmod +x /usr/local/bin/ufw-docker
Выполняем установку необходимых для ufw-docker правил (добавляет пачку правил в /etc/ufw/after.rules)
sudo ufw-docker install
Перезагрузить фаервол чтобы изменения вступили в силу
systemctl restart ufw
Работа с ufw-docker:
ufw-docker <list|allow> [docker-instance-id-or-name [port[/tcp|/udp]] [network]]
ufw-docker delete allow [docker-instance-id-or-name [port[/tcp|/udp]] [network]]
Чтобы разрешить доступ из интернета к TCP порту 8080 контейнера с названием test_container (вместо имени можно указывать ID контейнера):
ufw-docker allow test_container 8080/tcp
ufw-docker delete allow test_container 8080/tcp
Чтобы разрешить доступ из интернета ко всем опубликованным портам контейнера c названием test_container:
ufw-docker allow test_container
Просмотр всех правил для контейнера test_container:
ufw-docker list test_container
Чтобы удалить все правила для контейнера test_container:
ufw-docker delete allow test_container
Просмотр всех правил созданных с помощью ufw-docker:
ufw-docker status
Важное примечание:
Номера портов, используемые с ufw-docker необходимо указывать именно те, которые внутри контейнера, а не те которые им сопоставлены в хостовой системе.
Eсли запустить контейнер с указанием публикации портов (параметр -p) таки образом:
Сервис, работающий внутри контейнера на порту 8080 будет доступен в хостовой системе на порту 88. Чтобы разрешить доступ к такому сервису из интернета с помощью ufw-docker необходимо указывать порт 8080, т.е. именно тот, на котором работает сервис внутри контейнера.
Важное примечание 2:
ufw-docker это просто удобное дополнение которое позволяет добавлять правила на основании имени контейнера в стандартный ufw. При этом если посмотреть ufw status, можно увидеть что эти правила создаются для внутренних ip адресов контейнеров, соответственно если удалить контейнер и создать его снова, есть вероятность что его ip адрес поменяется, соответственно старое разрешающее правило уже не будет работать. Рекомендую после пересоздания контейнера еще раз разрешать необходимые порты с помощью ufw-docker, при этом он автоматически удалит старые неактуальные.
Альтернативный способ запрета доступа из интернета
В случае если вам нужно закрыть доступ к контейнеру из интернета полностью, можно не публиковать порты вовсе, например если доступ из интернета организован с помощью reverse proxy работающем в другом контейнере.
Также можно публиковать порты с привязкой к localhost интерфейсу, в таком случае доступ из интернета будет закрыт, но будет доступен локально, например с RPC или API сервисами ноды можно будет взаимодействовать локально с помощью curl.
Так выглядит параметр -p при стандартной публикации порта с привязкой ко всем интерфейсам в системе:
Проверка доступности портов https://portchecker.co/