Какой сертификат использует docker swarm join?

Я пытаюсь настроить рой docker.

Мне нужно, чтобы мои узлы обменивались данными по TLS.

Я создал сертификат для узла менеджера с extendedKeyUsage = serverAuth

Я настроил узел менеджера со следующим daemon.json:

{
    "hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2376"],
    "tlscacert": "/var/docker/ca.pem",
    "tlscert": "/var/docker/server-cert.pem",
    "tlskey": "/var/docker/server-key.pem",
    "tlsverify": true
}

Чтобы проверить это, я создал клиентский сертификат, использовал его для подключения к docker api с моего ноутбука, и я смог подключиться успешно.

Теперь мне нужно добавить один рабочий узел в рой.

Я настроил его так же, как и узел менеджера; с аналогичным daemon.json. Я использовал SSL-ключ с extendedKeyUsage = serverAuth и подтвердил клиентское соединение таким же образом, как и на узле менеджера.

Затем в менеджере я запустил docker swarm init

Чтобы присоединить рабочий узел к рою, я использовал следующую команду: docker swarm join --token XXX dockman.myhost.com:2376

Но я получаю ошибку:

Error response from daemon: rpc error: code = Unavailable desc = all SubConns are in TransientFailure, latest connection error: connection error: desc = "transport: authentication handshake failed: remote error: tls: bad certificate"

Я решил проверить это дальше, попытавшись подключиться к docker API на узле менеджера с рабочего узла:

sudo docker --tlsverify --tlscacert=/var/docker/ca.pem --tlscert=./server-cert.pem --tlskey=./server-key.pem -H=127.0.0.1:2376 version

Результат:

Client: Docker Engine - Community
 Version:           19.03.5
 API version:       1.40
 Go version:        go1.12.12
 Git commit:        633a0ea838
 Built:             Wed Nov 13 07:29:52 2019
 OS/Arch:           linux/amd64
 Experimental:      false
The server probably has client authentication (--tlsverify) enabled. Please check your TLS client certification settings: Get https://127.0.0.1:2376/v1.40/version: remote error: tls: bad certificate

Этот второй тест дал мне еще много поводов для размышлений. Конечно, он провалится, потому что я пытаюсь подключиться с помощью сертификата сервера, а не клиента, но разве это не то, что пытается сделать docker swarm join? Мне кажется бессмысленным помещать клиентский сертификат в daemon.json. Я погуглил на тему создания единого сертификата для сервера и клиента, и это возможно, но кажется, что это плохая практика. Я бы подумал, что об этом говорилось в учебнике, если бы это было необходимо.

Я застрял на этом этапе. Я не могу понять, какая настройка сертификата требуется.

Я следил за https://github.com/docker/docker.github.io/blob/master/swarm/configure-tls.md Здесь описано создание сертификатов, но ничего не говорится об аутентификации клиента или сервера.

Update 1

Я нашел документ, в котором говорится, что сертификаты должны быть клиентскими и серверными

https://hub.docker.com/_/swarm/

Поэтому я переделал сертификат узла, чтобы он был и клиентским, и серверным. Теперь команда docker version работает при запуске с узла, но не при присоединении роя.

0
задан 17 January 2020 в 17:02
2 ответа

Вы смешиваете режим Swarm ( docker swarm и аналогичные интерфейсы командной строки) с классическим Swarm на основе контейнера (размещенным как контейнер на концентраторе докеров). Это два разных инструмента.

Два набора документации см .:

Нет необходимости выполнять ручную настройку TLS в Swarm Mode, все это встроено, а порты для Swarm Mode отличаются от портов для сокета docker API. Вы не хотите выставлять API докеров в сети без уважительной причины (это частый источник взломов), и Swarm Mode не является причиной.

Следовательно, вам следует удалить параметр -H в команде dockerd вместе с любыми содержащимися там параметрами TLS. Затем запустите docker swarm init в первом диспетчере, который сгенерирует учетные данные TLS и выдаст токен, содержащий хэш самоподписанных сертификатов. Затем другие менеджеры и рабочие запускают docker swarm join для генерации клиентских сертификатов, подключения к менеджеру, проверки хэша сертификатов менеджера из токена и аутентификации менеджера с секретной частью токена соединения.

Вышеупомянутое зашифрует плоскость управления между менеджерами и рабочими. Чтобы зашифровать данные, передаваемые по оверлейным сетям между рабочими, вам необходимо включить IPSec в оверлейных сетях, которые вы создаете:

docker network create --opt encrypted --driver overlay app-overlay-net

Документация по этой функции находится по адресу: https://docs.docker.com/v17.09/ двигатель / руководство пользователя / сеть / модель-безопасности-наложения /

1
ответ дан 22 January 2020 в 14:01

Я был прав в том, что для работы все сертификаты должны быть сертификатами как клиента, так и сервера.

Затем я столкнулся с другими проблемами, главная из которых заключалась в том, что виртуальные машины на хосте, который я использую, запрещают использование порта 4789, поскольку он используется VMWare. Это порт пути данных по умолчанию, используемый для оверлейной сети.

Мне пришлось полностью удалить все узлы и менеджеры из роя (эффективно удалить его) и повторно включить его, используя параметр data-path-port:

docker swarm init --data-path-port = 7777

(я также указал адрес рекламы в качестве IP-адреса для каждого узла, но я не думаю, что это было необходимо)

Конечно, все мои секреты докеров, конфигурация докеров и некоторые из моих сетей докеров были потеряны в этом процессе, и мне пришлось воссоздать.

Как только я закончил это и изменил брандмауэр, чтобы разрешить UDP-связь между узлами с использованием порта данных, все снова заработало.

Поскольку сеть роя зашифрована, я думаю, что все должно работать.

0
ответ дан 22 January 2020 в 10:01

Теги

Похожие вопросы