Назад | Перейти на главную страницу

Настройте iptables для Docker вручную и разрешите доступ в Интернет для контейнеров

Я был очень недоволен поведением Docker в отношении изменения правил моего брандмауэра, потому что он просто открывает все порты на моем сервере.
Итак, я установил iptables-persistent и установил некоторые правила брандмауэра, которые блокируют весь входящий трафик, кроме портов 22, 80 и 443, и я убедился, что Docker перестанет вмешиваться в эти правила, создав /etc/systemd/system/docker.service.d/noiptables.conf со следующим содержанием:

[Service]
ExecStart=
ExecStart=/usr/bin/dockerd --iptables=false -H "fd://"

а затем перезагрузил сервер.

Теперь моя проблема в том, что мои контейнеры Docker больше не могут получить доступ к Интернету (интерфейс: ens3).

Вот мои правила:

*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o ens3 -j MASQUERADE
COMMIT

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]

# Allow localhost
-A INPUT -i lo -j ACCEPT
-A OUTPUT -o lo -j ACCEPT

# ICMP
-A INPUT -p icmp -j ACCEPT

# Docker
-A FORWARD -i docker0 -o ens3 -j ACCEPT
-A FORWARD -i ens3 -o docker0 -j ACCEPT


# Incoming
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -j DROP

# Outgoing
-A OUTPUT -j ACCEPT

# Routing
-A FORWARD -j DROP


COMMIT

Я хранил их в /etc/iptables/rules.v4 и /etc/iptables/rules.v6 и убедился, что они загружены, запустив sudo netfilter-persistent reload.

Согласно этому руководству: https://blog.daknob.net/debian-firewall-docker/ В *nat раздел будет выполнять свою работу, но это не так.

Моя система:

$ sudo iptables --version
iptables v1.6.1

$ uname -r
4.11.0-1-amd64

$ sudo lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux testing (buster)
Release:        testing
Codename:       buster

Во-первых, вы никогда не упоминали net.ipv4.ip_forward net.ipv4.ip_forward. Включите это, если еще не сделали.

Убедитесь, что у вас есть доступ в Интернет. curl httpbin.org/ip это хороший и простой способ проверить это.

Если вы это сделали, убедитесь, что ваши правила активны, проверив вывод iptables-save

Если да, отлаживайте его, вот псевдо-шаги:

  1. Внутри докера пропинговать внешний IP, скажем 8.8.8.8 и убедитесь, что вы не получите никакого ответа. Не используйте имя хоста. Давайте не будем исключать проблемы с DNS в нашем сценарии. Продолжайте работать для следующего шага.

  2. Внутри контейнера проверьте все интерфейсы один за другим с помощью tcpdump и найдите пакеты, предназначенные для 8.8.8.8. Это должно быть docker0 в соответствии с правилами, которые вы вставили в свой вопрос.

  3. Проверьте таблицу маршрутизации вашего хоста и убедитесь, что маршрут по умолчанию 0.0.0.0 находится на интерфейсе ens3.

Вы должны получить достаточно информации, чтобы решить проблему.