使用TLS增强docker的安全性

之前部署docker的时候都是没对docker的HTTP/socker接口进行加密。最近在线上部署的时候就得考虑这个。使用证书对docker进行加密主要参考官方的文档:

  1. https://docs.docker.com/v1.13/engine/security/https/
  2. https://github.com/docker/swarm/issues/341

docker engine配置TLS

主要注意做swarm cluster的时候 需要签发证书的时候subjectAltName里把本机的IP。生成证书的从网上找到的一个脚本做了修改,直接在里面把集群的IP都填进去,这样每个机器可以证书相同:

#!/bin/bash  
# This script will help you setup Docker for TLS authentication.  
# Run it passing in the arguement for the FQDN of your docker server  
#  
# For example:  
#    ./create-docker-tls.sh myhost.docker.com  
#  
# The script will also create a profile.d (if it exists) entry  
# which configures your docker client to use TLS  
#  
# We will also overwrite /etc/sysconfig/docker (again, if it exists) to configure the daemon.  
# A backup will be created at /etc/sysconfig/docker.unixTimestamp  
#  
# MIT License applies to this script.  I don't accept any responsibility for  
# damage you may cause using it.  
#  
  
set -e  
STR=2048  
if [ "$#" -gt 1 ]; then  
DOCKER_HOST1="$1"  
DOCKER_HOST2="$2"  
else  
echo " => ERROR: You must specify the docker FQDN as the first arguement to this scripts! <="  
exit 1  
fi  
  
if [ "$USER" == "root" ]; then  
echo " => WARNING: You're running this script as root, therefore root will be configured to talk to docker"  
echo " => If you want to have other users query docker too, you'll need to symlink /root/.docker to /theuser/.docker"  
fi  
  
echo " => Using : $DOCKER_HOST1  You MUST connect to docker using this host!"  
  
echo " => Ensuring config directory exists..."  
cd ./cert  
  
echo " => Verifying ca.srl"  
if [ ! -f "ca.src" ]; then  
echo " => Creating ca.srl"  
echo 01 > ca.srl  
fi  
  
echo " => Generating CA key"  
openssl genrsa \  
-out ca-key.pem $STR  
  
echo " => Generating CA certificate"  
openssl req \  
-new \  
-key ca-key.pem \  
-x509  \  
-sha256  \  
-days 3650 \  
-nodes \  
-subj "/CN=$" \  
-out ca.pem  
  
echo " => Generating server key"  
openssl genrsa \  
-out server-key.pem $STR  
  
echo " => Generating server CSR"  
openssl req \  
-subj "/CN=$DOCKER_HOST1" \  
-new \  
-sha256  \  
-key server-key.pem \  
-out server.csr  
  
echo " => Signing server CSR with CA"  
echo subjectAltName = "DNS:$DOCKER_HOST1,DNS:$DOCKER_HOST2,IP:127.0.0.1,IP:XXXXXX,IP:XXXXXX,IP:XXXXX,IP:XXXXX"  > extfile-server.cnf  
openssl x509 \  
-req \  
-days 3650 \  
-sha256  \  
-in server.csr \  
-CA ca.pem \  
-CAkey ca-key.pem \  
-out server-cert.pem \  
-extfile extfile-server.cnf  
  
echo " => Generating client key"  
openssl genrsa \  
-out key.pem $STR  
  
echo " => Generating client CSR"  
openssl req \  
-subj "/CN=docker.client" \  
-new \  
-key key.pem \  
-out client.csr  
  
echo " => Creating extended key usage"  
echo extendedKeyUsage = clientAuth > extfile.cnf  
  
echo " => Signing client CSR with CA"  
openssl x509 \  
-req \  
-days 3650 \  
-sha256  \  
-in client.csr \  
-CA ca.pem \  
-CAkey ca-key.pem \  
-out cert.pem \  
-extfile extfile.cnf  
  
if [ -d "/etc/profile.d" ]; then  
echo " => Creating profile.d/docker"  
sudo sh -c "echo '#!/bin/bash  
export DOCKER_CERT_PATH=/home/$USER/.docker  
export DOCKER_HOST=tcp://$DOCKER_HOST1:2376  
export DOCKER_TLS_VERIFY=1' > /etc/profile.d/docker.sh"  
sudo chmod +x /etc/profile.d/docker.sh  
source /etc/profile.d/docker.sh  
else  
echo " => WARNING: No /etc/profile.d directoy on your system."  
echo " =>   You will need to set the following environment variables before running the docker client:"  
echo " =>   DOCKER_HOST=tcp://$DOCKER_HOST1:2376"  
echo " =>   DOCKER_TLS_VERIFY=1"  
fi  
  
OPTIONS="--tlsverify --tlscacert=$HOME/.docker/ca.pem --tlscert=$HOME/.docker/server-cert.pem --tlskey=$HOME/.docker/server-key.pem -H=0.0.0.0:2376"  
if [ -f "/etc/sysconfig/docker" ]; then  
echo " => Configuring /etc/sysconfig/docker"  
BACKUP="/etc/sysconfig/docker.$(date +"%s")"  
sudo mv /etc/sysconfig/docker $BACKUP  
sudo sh -c "echo '# The following line was added by ./create-certs docker TLS configuration script  
OPTIONS="$OPTIONS"  
# A backup of the old file is at $BACKUP.' >> /etc/sysconfig/docker"  
echo " => Backup file location: $BACKUP"  
else  
echo " => WARNING: No /etc/sysconfig/docker file found on your system."  
echo " =>   You will need to configure your docker daemon with the following options:"  
echo " =>   $OPTIONS"  
fi  
  
export DOCKER_HOST=tcp://DOCKER_HOST:2376  
export DOCKER_TLS_VERIFY=1  
echo " => Done! You just need to restart docker for the changes to take effect"

附上docker.service

[Unit]  
Description=Docker Application Container Engine  
Documentation=http://docs.docker.com  
After=network.target  
Wants=docker-storage-setup.service  
  
[Service]  
Type=notify  
EnvironmentFile=-/etc/sysconfig/docker  
EnvironmentFile=-/etc/sysconfig/docker-storage  
EnvironmentFile=-/etc/sysconfig/docker-network  
Environment=GOTRACEBACK=crash  
ExecStart=/usr/bin/dockerd  -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock $OPTIONS   \  
--tlsverify --tlscacert=/etc/docker/cert/ca.pem --tlscert=/etc/docker/cert/server-cert.pem --tlskey=/etc/docker/cert/server-key.pem \  
--storage-driver=overlay \  
--cluster-store etcd://xxxxxx:2379/vxlan \  
--cluster-advertise=bond0:2375 \  
$DOCKER_STORAGE_OPTIONS \  
$DOCKER_NETWORK_OPTIONS \  
$ADD_REGISTRY \  
$BLOCK_REGISTRY \  
$INSECURE_REGISTRY  
LimitNOFILE=1048576  
LimitNPROC=1048576  
LimitCORE=infinity  
MountFlags=slave  
TimeoutStartSec=1min  
Restart=on-failure  
  
[Install]  
WantedBy=multi-user.target

swarm使用TLS

  • 创建manage
sudo docker run --restart=always -v /etc/docker/cert/:/cert/ --name swarm-manage -d -p 8888:2375 swarm -l debug  manage  --tlsverify --tlscacert=/cert/ca.pem --tlscert=/cert/server-cert.pem --tlskey=/cert/server-key.pem  etcd://xxxxx:2379/swarm
  • 启动agent
sudo docker run --restart=always --name swarm-agent -d  swarm join --addr=`hostname -i`:2375  etcd://xxxxx:2379/swarm

使用TLS连接swarm

$export DOCKER_HOST=tcp://xxxxx:8888 DOCKER_TLS_VERIFY=1  
$docker version  
Client:  
Version:      1.13.1  
API version:  1.24 (downgraded from 1.26)  
Go version:   go1.7.5  
Git commit:   092cba3  
Built:        Wed Feb  8 06:38:28 2017  
OS/Arch:      linux/amd64  
  
Server:  
Version:      swarm/1.2.6  
API version:  1.22 (minimum version )  
Go version:   go1.7.1  
Git commit:   `git rev-parse --short HEAD`  
Built:        `date -u`  
OS/Arch:      linux/amd64  
Experimental: false