We often use Portainer to manage the docker environment, Jenkins to build and deploy the docker automatically, and the Docker API is used for remote management. Usually we just open a 2375 (usually) port without security protection, which is dangerous and can lead to remote hijacking attacks.Then we need to configure the TLS certified 2376 (usually) port.
Here we configure the CoreOS system:
1. Use the openssl that comes with the system to generate the corresponding server and client certificates
We use scripts to generate them automatically, which is very convenient. The scripts (auto-tls-certs.sh) are as follows:
#!/bin/bash # # ------------------------------------------------------------- # Automatically create Docker TLS certificates # ------------------------------------------------------------- # Here is the configuration information # --[BEGIN]------------------------------ CODE="dp" IP="docker The server ip" PASSWORD="Certificate Password" COUNTRY="CN" STATE="BEIJING" CITY="BEIJING" ORGANIZATION="company" ORGANIZATIONAL_UNIT="Dev" COMMON_NAME="$IP" EMAIL="mailbox" # --[END]-- # Generate CA key openssl genrsa -aes256 -passout "pass:$PASSWORD" -out "ca-key-$CODE.pem" 4096 # Generate CA openssl req -new -x509 -days 365 -key "ca-key-$CODE.pem" -sha256 -out "ca-$CODE.pem" -passin "pass:$PASSWORD" -subj "/C=$COUNTRY/ST=$STATE/L=$CITY/O=$ORGANIZATION/OU=$ORGANIZATIONAL_UNIT/CN=$COMMON_NAME/emailAddress=$EMAIL" # Generate Server key openssl genrsa -out "server-key-$CODE.pem" 4096 # Generate Server Certs. openssl req -subj "/CN=$COMMON_NAME" -sha256 -new -key "server-key-$CODE.pem" -out server.csr echo "subjectAltName = IP:$IP,IP:127.0.0.1" >> extfile.cnf echo "extendedKeyUsage = serverAuth" >> extfile.cnf openssl x509 -req -days 365 -sha256 -in server.csr -passin "pass:$PASSWORD" -CA "ca-$CODE.pem" -CAkey "ca-key-$CODE.pem" -CAcreateserial -out "server-cert-$CODE.pem" -extfile extfile.cnf # Generate Client Certs. rm -f extfile.cnf openssl genrsa -out "key-$CODE.pem" 4096 openssl req -subj '/CN=client' -new -key "key-$CODE.pem" -out client.csr echo extendedKeyUsage = clientAuth >> extfile.cnf openssl x509 -req -days 365 -sha256 -in client.csr -passin "pass:$PASSWORD" -CA "ca-$CODE.pem" -CAkey "ca-key-$CODE.pem" -CAcreateserial -out "cert-$CODE.pem" -extfile extfile.cnf rm -vf client.csr server.csr chmod -v 0400 "ca-key-$CODE.pem" "key-$CODE.pem" "server-key-$CODE.pem" chmod -v 0444 "ca-$CODE.pem" "server-cert-$CODE.pem" "cert-$CODE.pem" # Packaging client certificates mkdir -p "tls-client-certs-$CODE" cp -f "ca-$CODE.pem" "cert-$CODE.pem" "key-$CODE.pem" "tls-client-certs-$CODE/" cd "tls-client-certs-$CODE" tar zcf "tls-client-certs-$CODE.tar.gz" * mv "tls-client-certs-$CODE.tar.gz" ../ cd .. rm -rf "tls-client-certs-$CODE" # Copy server-side certificate mkdir -p /etc/docker/certs.d cp "ca-$CODE.pem" "server-cert-$CODE.pem" "server-key-$CODE.pem" /etc/docker/certs.d/
When the variables in the script are modified and run, a tls certificate is automatically created, and the server's certificate is in the / etc/docker/certs.d/directory:
The client's certificate is conveniently located in the directory where the script is run and a package of.tar.gz is automatically typed.
2. Configuring Docker services (official instructions)
Note that the certificate path is modified.
Enable the secure remote API on a new socket
Create a file called /etc/systemd/system/docker-tls-tcp.socket to make Docker available on a secured TCP socket on port 2376.
[Unit] Description=Docker Secured Socket for the API [Socket] ListenStream=2376 BindIPv6Only=both Service=docker.service [Install] WantedBy=sockets.target
Then enable this new socket:
systemctl enable docker-tls-tcp.socket systemctl stop docker systemctl start docker-tls-tcp.socket
Drop-in configuration
Create /etc/systemd/system/docker.service.d/10-tls-verify.conf drop-in for systemd Docker service:
[Service] Environment="DOCKER_OPTS=--tlsverify --tlscacert=/etc/docker/ca.pem --tlscert=/etc/docker/server.pem --tlskey=/etc/docker/server-key.pem"
Reload systemd config files and restart docker service:
sudo systemctl daemon-reload sudo systemctl restart docker.service
Configure Portainer Remote TLS Connection
Certificate Correspondence Selection:
- ca.pem
- cert.pem
- key.pem
That's it.Note that if you have previously opened an unauthenticated port 2375, close and disable it and restart the docker service.
# Stop unsafe port 2375 systemctl stop docker-tcp.socket # Disable this port systemctl disable docker-tcp.socket # Restart docker service systemctl restart docker.service