Docker: docker и iptables или файерволы

По умолчанию, 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&#39;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 &#39;docker port&#39; 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

Docker – full functional systemd with docker container: полнофункциональный docker контейнер с systemd

В одной из предыдущих публикаций я показал как собрать образ с нуля для контейнера на основе пакетной базы CentOS использую классический supermin инструмент.
Однако все такие контейнеры на базе некоторого исполняемого кода (как endpoint или cmd), берушего на себя функции начального процесса с PID 1, далеки от какой-либо эмуляции присутствия среды “контейнерной” ОС. Весь функционал пакета приложения может быть использован только если среда будет максимально похожа на ставшую уже стандартом де-факто systemd. Для этого нужен полноценный init (читай systemd) процесс, способный работать с сервисами в контейнерной изоляции docker как в обычной полной виртуализации или на обычном сервере. Почему это важно – понятно от сюда (https://docs.docker.com/config/containers/start-containers-automatically/).
Контенейры могут стартовать автоматически, а вот вся остальная логика запуска сервисов будет в руках менеджеров процессов.
Все это ни в коей мере не нужно если изолируется минимальный набор микро-приложения собственной сборки с интерпретатором и его зависимостями или тем более бинарник статической сборки. Изоляция кастомных микропрограмм по сути единственное важное и нужное в применении изоляций в docker или k3s.

В “родных” контейнерах изоляторах построенных на базе контейнеров systemd-nspawn все это заложено изначально, и такие контейнеры сразу запуcкают полноценный процесс init – systemd. Но так ли сложно обойти “костыли” архитектуры docker/k8s/k3s и запустить systemd под его изоляцией полноценно? Давайте проверим.

Углубившись слегка в понимание процесса загрузки ОС, в котором ядро передает управление некоему процессу init, мы можем понять, что любой такой процесс будет выполнять ряд логических процессов инициализации сервисов и среды из одной начальной точки до некоторого целевого состояния. И совсем не факт что мы не можем пропустить большую часть этих действий по своему усмотрению.

В systemd все это крутится вокруг сущностей целей, сервисов и юнитов. Значит, передавая в докер контейнер systemd как начальную входную точку, мы можем попытаться определить его цель по умолчанию на основе специфики обоих платформ. Хотя по всему видно, что они друг другу не друзья. И контейнеры на базе systemd-nspawn обладает не меньшей мощью и гибкостью.

Допустим, что как и в предыдущей публикации, мы уже знаем как создать базовую сущность supermin5 только с одним пакетом – yum.
Теперь попробуем создать это с двумя пакетами – systemd и yum:

$ supermin --verbose --prepare yum systemd -o centos8s.supermin.base.systemd
“Docker – full functional systemd with docker container: полнофункциональный docker контейнер с systemd”Continue reading

Как восстановить пароли, хранящиеся в DBeaver

Для DBeaver 6.1.3+ пароли теперь хранятся в файле “json” с новым шифрованием.
Где найти файл хранящий сохраненные пароли, Вы можете узнать на страницах официальной документации.
А потом Вы можете использовать скрипт на питоне 2/3 для расшифровки и вывода результатов.

“Как восстановить пароли, хранящиеся в DBeaver”Continue reading

Scroll to top