Иногда удобно получать доступ к инфраструктуре удаленно, но при этом безопасно. Возможно для мониторинга, или оперативного вмешательства либо по другим причинам. Получить доступ к API Docker-a, конечно. Для начала сгенерируем сертификаты:
Создаем корневой сертификат, его будем использовать для выпуска и подписи а так же верификации (сертификат выпускаем сроком на 10 лет, параметр -days):
# openssl genrsa -out ca-key.pem 2048
# openssl req -x509 -new -nodes -key ca-key.pem -days 3650 -out ca.pem -subj '/CN=Docker-CA'
Для дальнейшей настройки создадим файл openssl.cnf в него поместим некоторые настройки, в частности, мы укажем что выпускаемые нами сертификаты будут использоваться для взаимодействия и авторизации между хостами, а так же адреса хостов и другие, вы можете почитать документацию по openssl и добавить необходимые поля по своему усмотрению:
# cat openssl.conf
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = <внешний_ip_сервера>
IP.1 = <внешний_ip_сервера>
IP.2 = 127.0.0.1
Далее создадим сертификат сервера:
# openssl genrsa -out server-key.pem
# openssl req -new -key server-key.pem -out server-cert.csr -subj '/CN=Docker-server' -config openssl.cnf
# openssl x509 -req -in server-cert.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -days 3650 -extensions v3_req -extfile openssl.cnf
После чего создаем сертификаты клиента:
# openssl genrsa -out client-key.pem 2048
# openssl req -new -key client-key.pem -out client-cert.csr -subj '/CN=Docker-client' -config openssl.cnf
# openssl x509 -req -in client-cert.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out client-cert.pem -days 3650 -extensions v3_req -extfile openssl.cnf
На этом создание сертификатов завершено, помещаем корневой и клиентские сертификаты в папку ~/.docker
# cp ca.pem ~/.docker
# cp client-key.pem client-cert.pem ~/.docker
Далее переходим на удаленный сервер и вносим изменения в демон docker-а. Редактируем файл /etc/default/docker, добавляем в конец файла следующую строку. Обращаю внимание что в данном примере слушать API будем на всех интерфейсах, лучше ограничить это вашими сетями.
# nano /etc/default/docker
DOCKER_OPTS="-H=0.0.0.0:2376 -H unix:///var/run/docker.sock --tlsverify --tlscacert=/etc/docker/ssl/ca.pem --tlscert=/etc/docker/ssl/server-cert.pem --tlskey=/etc/docker/ssl/server-key.pem"
Далее редактируем файл /lib/systemd/system/docker.service, находим в нем секцию [Service], добавляем в начало секции EnvironmentFile=/etc/default/docker а так же правим параметр ExecStart:
# nano /lib/systemd/system/docker.service
EnvironmentFile=/etc/default/docker
ExecStart=/usr/bin/dockerd -H fd:// $DOCKER_OPTS --containerd=/run/containerd/containerd.sock
После чего создаем каталог ssl в папке демона docker и загружаем туда сертификаты сервера. Перезапускаем демон.
# mkdir /etc/docker/ssl
# scp ca.pem username@host:/etc/docker/ssl
# scp server-cert.pem username@host:/etc/docker/ssl
# scp server-key.pem username@host:/etc/docker/ssl
# systemctl daemon-reload
# service docker restart
Далее проверяем слушает ли демон порт API:
netstat -tulpan | grep 2376
tcp6 0 0 :::2376 :::* LISTEN 1872979/dockerd
Теперь можно подключаться с клиентской машины:
# docker -H <адрес_сервера>:2376 --tls --tlscert=client-cert.pem --tlskey=client-key.pem ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a9636e4b33c9 registry:2 "/entrypoint.sh /etc…" 7 weeks ago Up 2 hours 0.0.0.0:443->443/tcp, :::443->443/tcp, 5000/tcp registry_registry_1
Отлично, для безопасности добавьте так же правила iptables для ограничения доступа по разрешенным IP.