Класична продакшен-пастка на Ubuntu й Debian:
sudo ufw default deny incoming
sudo ufw allow 22
sudo ufw allow 443
# фаєрвол налаштовано, «все закрито»
А потім docker run -p 6379:6379 redis - і Redis доступний з інтернету, попри правила ufw.
Чому так: Docker сам керує правилами фаєрвола (iptables чи nftables) - без них не працювали б мережі bridge і публікація портів. Трафік на опублікований порт перенаправляється в контейнер у таблиці NAT ще до того, як потрапить у ланцюжки, якими керує ufw. Документація Docker прямо попереджає: Docker і ufw використовують правила фаєрвола несумісно.
Як захиститися:
1. Не публікувати те, що не має бути публічним - найнадійніше:
services:
redis:
# без ports - доступний лише іншим контейнерам у мережі
postgres:
ports:
- "127.0.0.1:5432:5432" # лише з самого хоста
2. Ланцюжок DOCKER-USER - Docker пропускає через нього трафік до контейнерів перед власними правилами. Туди додають обмеження (наприклад, дозволити порт лише з певних адрес). Правила в інших ланцюжках, створених Docker, змінювати не можна - Docker перезаписує їх.
3. Фаєрвол на рівні мережі чи хмари - security groups у AWS, фаєрвол провайдера (Hetzner Cloud Firewall) працюють поза хостом і не залежать від правил, які створює Docker.
4. Не вимикати керування фаєрволом Docker ("iptables": false) без глибокого розуміння - зламаються мережі контейнерів.
Перевірка ззовні, а не з самого сервера:
nmap -p 1-65535 ваш-сервер
і docker ps для переліку опублікованих портів.
Висновок для співбесіди: фаєрвол хоста не захищає опубліковані порти Docker; захищає правильна публікація (127.0.0.1 чи без ports) і фаєрвол на рівні мережі.