UFW говорит «всё закрыто», а Postgres торчит наружу: пишем аудит портов для docker compose на Python

nikita-practice 35 минут назад Краткое содержание статьи UFW говорит «всё закрыто», а Postgres торчит наружу: пишем аудит портов для docker compose на Python 6 мин 1.3K DevOps * Информационная безопасность * Python *...
<5 — 2026'da uzaya kaç SpaceX Starship fırlatması ulaşacak?
В сфере искусственного интеллекта произошло заметное событие. nikita-practice 35 минут назад Краткое содержание статьи UFW говорит «всё закрыто», а Postgres торчит наружу: пишем аудит портов для docker compose на Python 6 мин 1. 3K DevOps * Информационная безопасность * Python * Системное администрирование * Серверное администрирование * На этой неделе в топе снова всплыла старая история: свежий VPS, ufw default deny incoming, наружу только 22, 80 и 443, а потом в compose-файле появляется ports: - "5432:5432" — и через пару дней в базе лежит записка с биткойн-кошельком. Почему так происходит, уже разобрали подробно.
Я хочу про другое: как сделать так, чтобы такой compose-файл вообще не доехал до сервера. Ниже — два небольших скрипта на Python. Первый проверяет compose-файлы до деплоя и падает с ненулевым кодом, если порт опубликован на все интерфейсы.
Технические детали
Второй смотрит, что реально слушает на машине, без ss и netstat, прямо из /proc. Весь код я запускал на Python 3. 3, вывод в статье — настоящий.
Почему UFW тут не участвуетКоротко, чтобы дальше было понятно, что мы ловим. В документации Docker прямо написано, что Docker и ufw несовместимы: трафик к опубликованным портам контейнера перенаправляется в таблице nat, то есть раньше, чем пакеты доходят до цепочек INPUT и OUTPUT, с которыми работает ufw. Правила ufw для такого трафика просто не применяются.
Отсюда простой вывод: фаервол на хосте — не та линия обороны, на которую стоит рассчитывать для контейнеров. Надёжнее не публиковать лишнее вообще, а то, что нужно только вам, вешать на 127. 1 и ходить через SSH-туннель.
Отраслевые последствия
Ещё одна деталь из той же документации: если в маппинге порта не указан адрес хоста, Docker публикует порт на все адреса — и 0. То есть "5432:5432" и "0. 0:5432:5432" по смыслу одно и то же.
Какие бывают записи портовCompose понимает две формы. Короткая — строка вида target. Длинная — словарь с ключами target, published, host_ip, protocol.
Нам интересны три случая:адрес хоста — loopback (127. Это нормально;адреса нет, порт явно разрешён к публикации (80, 443). Это осознанное решение;адреса нет, и порт не из белого списка.
Событие, по словам экспертов, усилит конкуренцию в сфере ИИ.




