Как Docker обходит UFW — и почему это опасно для вашего сайта
Наткнулся на статью про то, как Docker обходит UFW — и понял, что это не просто технический нюанс, а реальная угроза для любого сайта, который работает на сервере с контейнерами.
О чём речь и почему это важно для сайта
Речь о том, что даже если файрвол активен и показывает, что порт закрыт, контейнер всё равно может быть доступен из интернета. Это не ошибка, а особенность работы Docker: трафик к контейнеру проходит мимо стандартных правил UFW. И это не редкость — такие настройки встречаются у многих клиентов, даже тех, кто не знает, что делает.
На мой взгляд, самое опасное — не то, что это происходит, а то, что никто не видит. Владелец сайта думает: «файрвол включён — всё в порядке». А на деле — уязвимость может быть открыта, и это не про «хакеров», а про непонимание, как работает сеть.
Как это устроено — что тут вообще происходит
Когда запускаешь контейнер с открытым портом, Docker не просто открывает его. Он перенаправляет трафик через специальную цепочку в iptables — и доходит до UFW уже после трансляции адресов. То есть UFW видит не порт 18080, а внутренний порт контейнера. Правила, которые он проверяет, не срабатывают.
Это не баг. Это документировано. Docker и UFW несовместимы по архитектуре. Правила в DOCKER-USER, которые часто советуют добавлять, тоже не работают — потому что сопоставление идёт по уже изменённому порту. Пакет приходит уже после DNAT, и проверить исходный порт нельзя обычным способом.
Как понять, что это касается вашего сайта
Если у вас сайт на сервере с Docker — это уже повод проверить. Даже если вы не настраивали сеть, контейнеры могут быть запущены. Проверяю я это так: смотрю, какие порты открыты на хосте, и проверяю, откуда приходит трафик. Если есть контейнеры — сразу смотрю, как они подключены к сети.
Если у клиента есть доступ к серверу — я не доверяю только статусу UFW. Я проверяю, куда идёт трафик, и смотрю, нет ли контейнеров, которые «торчат» в интернете. Это не про «как проверить», а про «что смотреть» — и я это делаю в каждом аудите.
Что с этим делать — что я делаю в таких случаях
Я не добавляю правила в DOCKER-USER. Это не решает проблему. Я проверяю, насколько открыт доступ к контейнерам. Если порт не нужен — его закрываю. Если нужен — ограничиваю по IP. Или вообще не публикую наружу, а использую внутреннюю сеть.
Если сайт работает в контейнере — я смотрю, как он настроен. Если доступ открыт извне — я проверяю, почему. И если это не нужно — убираю. Это не про команды, а про логику: не открывать, если не нужно. И не доверять видимости.
Что здесь даёт поддержка
На постоянной поддержке я закрываю такие риски заранее. Если контейнеры используются — я проверяю, как они подключены к сети. Если порт открыт — я смотрю, нужен ли он. Если нет — закрываю. И не доверяю только статусу UFW.
Проверяю, как работает сеть, даже если клиент не знает, что контейнеры есть. И если есть — ограничиваю доступ. Это не про «как сделать», а про «что проверить». И я это делаю в каждом аудите. И да — у меня есть проверки, которые я применяю системно.