当咱们使用远程调用docker时,未设置TLS的docker,将能够被任何人调用,这是极其危险的。node
在阿里云上跑的docker,此次就被不怀好意的人扫描到了默认端口,2375/2376, 被部署了挖矿软件,而且将咱们本身的服务容器pause。linux
docker原生提供了使用TLS证书(客户端和服务端)进行安全保证。git
使用openssl来建立CA,并签署秘钥/证书。docker
首先建立一个certs目录,并内置三个子目录 ca、client、server。shell
$ mkdir -p ~/certs/{ca,client,server}
运行openssl建立CA秘钥和证书,并将CA证书保存在~/certs/ca 目录下。安全
$ openssl genrsa -out ~/certs/ca/ca-key.pem 2048 $ openssl req -x509 -new -nodes -key ~/certs/ca/ca-key.pem \ -days 10000 -out ~/certs/ca/ca.pem -subj '/CN=docker-CA'
建立一个用于client的openssl配置文件~/certs/client/openssl.cnftcp
[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
再建立一个用于server的openssl配置文件~/certs/server/openssl.cnfui
alt_names中的ip为Docker Server的ip,即client须要访问的ip,如有多个docker服务,此处填写多个,不然client将没法访问Docker Server。阿里云
[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 = docker.local IP.1 = 192.168.9.1 IP.2 = 192.168.9.2
为客户端建立并签署证书unix
$ openssl genrsa -out ~/certs/client/key.pem 2048 $ openssl req -new -key ~/certs/client/key.pem -out ~/certs/client/cert.csr \ -subj '/CN=docker-client' -config ~/certs/client/openssl.cnf $ openssl x509 -req -in ~/certs/client/cert.csr -CA ~/certs/ca/ca.pem \ -CAkey ~/certs/ca/ca-key.pem -CAcreateserial \ -out ~/certs/client/cert.pem -days 365 -extensions v3_req \ -extfile ~/certs/client/openssl.cnf
为服务端建立并签署证书
$ openssl genrsa -out ~/certs/server/key.pem 2048 $ openssl req -new -key ~/certs/server/key.pem \ -out ~/certs/server/cert.csr \ -subj '/CN=docker-server' -config ~/certs/server/openssl.cnf $ openssl x509 -req -in ~/certs/server/cert.csr -CA ~/certs/ca/ca.pem \ -CAkey ~/certs/ca/ca-key.pem -CAcreateserial \ -out ~/certs/server/cert.pem -days 365 -extensions v3_req \ -extfile ~/certs/server/openssl.cnf
此时,全部证书已经建立完毕,目录结构以下:
. ├── ca │ ├── ca-key.pem │ ├── ca.pem │ └── ca.srl ├── client │ ├── cert.csr │ ├── cert.pem │ ├── key.pem │ └── openssl.cnf └── server ├── cert.csr ├── cert.pem ├── key.pem └── openssl.cnf
查看配置文件位置
$ systemctl show --property=FragmentPath docker FragmentPath=/lib/systemd/system/docker.service
在配置文件中开启TLS,并配置服务端证书,将上一步生成好的server证书和ca.pem拷贝至/etc/docker/ssl。
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock --tlsverify --tlscacert=/etc/docker/ssl/ca.pem --tlscert=/etc/docker/ssl/cert.pem --tlskey=/etc/docker/ssl/key.pem
从新加载systemd和Docker服务
$ sudo systemctl daemon-reload $ sudo systemctl restart docker
此时,Docker Server端的TLS配置已经完成。
未使用TLS证书访问Docker Server
$ docker -H tcp://192.168.9.1:2376 version Client: Version: 17.03.0-ce API version: 1.26 Go version: go1.7.5 Git commit: 3a232c8 Built: Tue Feb 28 08:10:07 2017 OS/Arch: linux/amd64 Get http://101.37.164.86:3257/v1.26/version: malformed HTTP response "\x15\x03\x01\x00\x02\x02". * Are you trying to connect to a TLS-enabled daemon without TLS?
使用TLS证书访问DockerServer
$ docker --tlsverify --tlscacert=./ca.pem --tlscert=./client/cert.pem --tlskey=./client/key.pem -H tcp://192.168.9.1:2376 version Client: Version: 17.03.0-ce API version: 1.26 Go version: go1.7.5 Git commit: 3a232c8 Built: Tue Feb 28 08:10:07 2017 OS/Arch: linux/amd64 Server: Version: 17.03.1-ce API version: 1.27 (minimum version 1.12) Go version: go1.7.5 Git commit: c6d412e Built: Mon Mar 27 17:14:09 2017 OS/Arch: linux/amd64 Experimental: false