Описание проблемы
При настройке ufw в Unix системах может возникнуть ситуация, при которой Docker контейнеры не соблюдают правила файрволла.
Так, например, при разрешенных портах файрволла ufw 80, 443 и 22
контейнер с проброшенными портами 8000:80 (8000 - хост, 80 - контейнер) может быть доступен из вне с порта 8000 хоста, игнорируя правила файрволла.
Решение
Для решения данной проблемы необходимо изменить файл конфигурации UFW etc/ufw/after.rules
, добавив следующий листинг в конец файла.
Далее, используя команду
перезапустить UFW. Теперь нельзя будет обратиться к открытым портам Docker контейнера из вне, при этом контейнеры могут “общаться” между собой и также имеют доступ ко внешней сети.
Дополнительные настройки
Если необходимо разрешить публичным сетям доступ к контейнеру Docker, например, через его порт 80, выполните следующую команду, чтобы разрешить публичным сетям доступ к этому контейнеру:
Эта команда позволяет публичным сетям получить доступ ко всем контейнером с портом 80.
Примечание: Следует использовать именно порт контейнера 80, а не порт хоста 8000, если порты проброшены следующим образом:
Если необходимо запущено несколько Docker контейнеров с портом 80, но доступ из вне необходимо дать только одному определенному, выполните следующую команду:
172.17.0.2
- внутренний IP адрес контейнера.
Также, если прокол сети - UDP, например, DNS сервис, можно использовать аналогичные команды:
И для определенного контейнера с внутренним IP адресом 172.17.0.2
:
Как это работает
Следующие правила позволяют частным сетям обращаться друг к другу.
Следующие правила позволяют UFW управлять тем, разрешено ли публичным сетям обращаться к контейнерам Docker.
Следующие правила блокируют запросы на подключение, инициированные всеми публичными сетями, но позволяют внутренним сетям получать доступ к внешним сетям.
Для протокола TCP запрещается активное установление TCP-соединения из публичных сетей.
Для протокола UDP блокируются все обращения к портам с номером меньше 32767.
Почему выбирается именно этот порт?
Поскольку протокол UDP не имеет состояния, невозможно заблокировать handshake
, инициирующий запрос соединения, как это делает TCP.
Для GNU/Linux мы можем найти локальный диапазон портов в файле /proc/sys/net/ipv4/ip_local_port_range
.
По умолчанию диапазон составляет 32768: 60999
. При обращении к протоколу UDP из запущенного контейнера локальный порт будет выбран случайным образом из указанного выше диапазона портов, и сервер вернет данные на этот случайный порт.
Таким образом, можно предположить, что порты, которые “слушают” протокол UDP внутри всех контейнеров меньше 32768
. Именно по этой причине блокируются обращения публичных сетей к UDP-портам, которые меньше 32768.
Последнее изменение: 20.09.2024 15:57