β

使用TLS增强docker的安全性

GNUer's blog 151 阅读

之前部署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

  1. 创建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
  1. 启动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
作者:GNUer's blog
Just for You
原文地址:使用TLS增强docker的安全性, 感谢原作者分享。