По умолчанию, docker daemon модифицирует iptables правила файервола без какого-либо уведомления или согласования с администратором. Для этого он используте к примеру цепочку с именем DOCKER и не только.
1 2 3 4 5 6 7 | Chain FORWARD (policy DROP) target prot opt source destination DOCKER all -- 0.0.0.0/0 0.0.0.0/0 ... Chain DOCKER (1 references) target prot opt source destination |
Более того, когда вы указываете docker открывать порт контейнера, он открывает его всему миру, нарушая ваши возможные правила iptables. Итак … если вы запускаете docker на хосте, на котором уже установлен брандмауэр на основе iptables, вам, вероятно, следует установить –iptables = false. Давайте возьмем пример. Вы хотите запустить nginx и связать containerPort 80 с hostPort 9090:
1 | docker run --name some-nginx -d -p 9090:80 nginx |
За сценой он добавляет правило iptables в цепочку фильтров DOCKER:
1 2 3 4 5 6 7 8 | Chain FORWARD (policy DROP) target prot opt source destination DOCKER all -- 0.0.0.0/0 0.0.0.0/0 ... Chain DOCKER (1 references) target prot opt source destination ACCEPT tcp -- 0.0.0.0/0 172.17.0.2 tcp dpt:9090 <-- это было добавлено при запуске контейнера |
Теперь порт 9090 доступен со всего мира. Потому что мы слушаем 9090 на любых IP-адресах (‘0.0.0.0)’из-за правил пересылки, которые динамически добавляются в цепочку фильтров DOCKER. Обратите внимание, что правила пересылки docker разрешают все внешние IP-адреса по умолчанию. Вы, вероятно, не хотите этого. Возможно, вы захотите публиковать порты только локально, а не в ‘0.0.0.0’, для внутреннего использования. Давайте прочитаем документацию по docker-run:
1 2 3 4 5 | -p=[] : Publish a container's port or a range of ports to the host format: ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort | containerPort Both hostPort and containerPort can be specified as a range of ports. When specifying ranges for both, the number of container ports in the range must match the number of host ports in the range. (e.g., `-p 1234-1236:1234-1236/tcp`) (use 'docker port' to see the actual mapping) |
Как видите, вы можете привязать hostPort к IP.
1 | docker run --name some-nginx -d -p 127.0.0.1:9090:80 nginx |
1 2 3 4 5 6 | # BEFORE netstat -an | grep 9090 tcp6 0 0 :::9090 :::* LISTEN # AFTER netstat -an | grep 9090 tcp 0 0 127.0.0.1:9090 0.0.0.0:* LISTEN |
Докер, хватит возиться с моими правилами iptables!
Допустим, вы используете докер на сервере, доступном в Интернете. У вас уже настроен межсетевой экран на основе iptables. Чтобы запретить docker вносить изменения в правила iptables вашей системы, вы должны установить –iptables=false при запуске демона. Для систем на основе sysvinit и upstart вы можете отредактировать /etc/default/docker. Для systemd вы можете сделать это – ‘systemd edit docker.service’ и добавить следующий код и перегрузить docker:
1 2 3 | [Service] ExecStart= ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --iptables=false |
Теперь перезагрузите брандмауэр и перезапустите демон Docker. Вы можете видеть, что цепочка с именем DOCKER и ссылки на нее в цепочке FORWARD исчезли.
1 2 3 4 5 | [root@vms csf]# csf -ra | egrep '(ERR|WARN)' *WARNING* RESTRICT_SYSLOG is disabled. See SECURITY WARNING in /etc/csf/csf.conf. [root@vms csf]# [root@vms csf]# iptables-save | egrep DOCK [root@vms csf]# |
Настройте iptables для работы с докером
Если вы все еще используете мост Ethernet, созданный docker и названный docker0, вы можете установить следующие правила для пересылки:
1 2 3 4 | [root@vms csf]# iptables-save | egrep docker0 -A INPUT -i docker0 -j ACCEPT -A OUTPUT -o docker0 -j ACCEPT [root@vms csf]# |
Теперь, если вы хотите открыть TCP-порт 10000 работающего контейнера для всего мира, этот контейнер должен предоставить порт любому IP-адресу (0.0.0.0) на стороне хоста:
1 2 3 4 | docker run --name some-nginx -d -p 10000:80 nginx netstat -an | grep 10000 tcp6 0 0 :::10000 :::* LISTEN |
Затем вы можете добавить это правило брандмауэра, чтобы разрешить миру доступ к вашему контейнеру через правила пересылки:
1 | -A INPUT -p tcp -m tcp --dport 10000 -j ACCEPT |