當咱們使用遠程調用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