Вы настроили UFW, запретили весь входящий трафик, кроме SSH и веба, и чувствуете себя в безопасности. Но через несколько дней сервер начинает тормозить, а в базе данных появляется записка с требованием выкупа. Знакомая картина? Причина — в том, как Docker взаимодействует с iptables и UFW. В этой статье разберём, почему стандартный фаервол не спасает контейнеры, что ищут боты в открытых портах и как закрыть эту дыру без иллюзий.

Почему UFW не работает для Docker

UFW — это надстройка над iptables, которая управляет цепочками INPUT. Когда вы выполняете ufw default deny incoming, правила применяются к трафику, идущему на хост. Однако Docker создаёт собственные цепочки в iptables (DOCKER, DOCKER-USER) и добавляет правила в обход UFW. Контейнеры публикуют порты через NAT, и трафик до них доходит, даже если UFW запрещает входящие соединения. В результате ufw status показывает, что порт закрыт, но Docker его открывает.

Типичный сценарий: вы запускаете контейнер с PostgreSQL и указываете ports: - "5432:5432". Docker добавляет правило в цепочку DOCKER, которое принимает трафик на порт 5432 со всех интерфейсов. UFW при этом может оставаться в режиме deny, но это не мешает Docker. Проверить это можно командой iptables -L -n -v — вы увидите цепочки Docker с разрешающими правилами.

Что ищут боты в открытых портах

Сканеры постоянно обшаривают интернет в поисках открытых портов баз данных. Чаще всего их интересуют PostgreSQL (5432), MySQL (3306), Redis (6379), MongoDB (27017) и Elasticsearch (9200). Боты не взламывают целенаправленно — они просто перебирают стандартные порты и пытаются подключиться с дефолтными учётными данными или без аутентификации. Redis и MongoDB по умолчанию не требуют пароля, поэтому часто становятся жертвами.

После подключения бот может выполнить команду для загрузки майнера (например, kinsing или kdevtmpfsi) или зашифровать данные и оставить записку с требованием выкупа. В случае с Redis злоумышленники используют команду CONFIG SET для записи вредоносного кода в файлы или планировщик задач. PostgreSQL и MySQL атакуют перебором паролей, но если пароль слабый или отсутствует, доступ открыт.

Как защитить контейнеры: практические шаги

Первое и самое важное: не публикуйте порты баз данных наружу без необходимости. Если нужно подключаться к базе с ноутбука, используйте SSH-туннель. Вместо ports: - "5432:5432" привяжите порт к localhost: ports: - "127.0.0.1:5432:5432". Тогда Docker будет слушать только локальный интерфейс, и UFW (или отсутствие внешнего IP) защитит порт.

Второй шаг — настройте цепочку DOCKER-USER в iptables. Это специальная цепочка, которая обрабатывается до правил Docker и позволяет фильтровать трафик. Например, чтобы разрешить подключения к порту 5432 только с определённых IP, добавьте правило: iptables -I DOCKER-USER -p tcp --dport 5432 -s 203.0.113.0/24 -j ACCEPT и запретите остальное. Не забудьте сохранить правила.

Третий шаг — используйте встроенные механизмы аутентификации. Для Redis установите пароль через requirepass и отключите опасные команды. Для MongoDB включите авторизацию. Для PostgreSQL и MySQL используйте сильные пароли и ограничьте доступ по IP в конфигурации.

Типичные ошибки и как их избежать

  • Доверие только ufw status. Всегда проверяйте реальные правила iptables и сканируйте порты снаружи (например, с другого сервера через nmap).
  • Публикация портов без привязки к localhost. Даже если вы используете UFW, Docker обойдёт его. Явно указывайте 127.0.0.1 в ports.
  • Использование стандартных портов. Сканеры ищут именно 5432, 3306, 6379. Смена порта не панацея, но снижает шанс случайного обнаружения.
  • Отсутствие мониторинга. Настройте оповещения о подозрительной активности (например, всплеск CPU или необычные подключения к БД).

Пример из практики: разработчик поднял Redis на VPS с UFW, оставив порт 6379 открытым для удобства. Через сутки сервер начал майнить криптовалюту. Причина — Redis без пароля и открытый порт. Решение: привязка к localhost и установка пароля.

В заключение: UFW — полезный инструмент, но он не контролирует Docker. Чтобы не стать жертвой ботов, явно ограничивайте доступ к портам, используйте SSH-туннели и не полагайтесь на иллюзию защиты. Проверяйте конфигурацию и регулярно аудируйте открытые порты.