保護 Docker 守護程序套接字
預設情況下,Docker 透過一個非網路的 UNIX 套接字執行。它也可以選擇使用 SSH 或 TLS (HTTPS) 套接字進行通訊。
使用 SSH 保護 Docker 守護程序套接字
注意給定的
USERNAME必須有許可權訪問遠端機器上的 docker 套接字。請參考以非 root 使用者管理 Docker,瞭解如何為非 root 使用者授予 docker 套接字的訪問許可權。
以下示例建立一個 docker context,使用 SSH 連線到遠端 dockerd 守護程序 host1.example.com,並以遠端機器上的 docker-user 使用者身份進行連線。
$ docker context create \
--docker host=ssh://docker-user@host1.example.com \
--description="Remote engine" \
my-remote-engine
my-remote-engine
Successfully created context "my-remote-engine"
建立上下文後,使用 docker context use 將 docker CLI 切換到使用它,並連線到遠端引擎。
$ docker context use my-remote-engine
my-remote-engine
Current context is now "my-remote-engine"
$ docker info
<prints output of the remote engine>
使用 default 上下文切換回預設的(本地)守護程序。
$ docker context use default
default
Current context is now "default"
或者,使用 DOCKER_HOST 環境變數可以臨時切換 docker CLI 以使用 SSH 連線到遠端主機。這不需要建立上下文,可用於與不同的引擎建立臨時連線。
$ export DOCKER_HOST=ssh://docker-user@host1.example.com
$ docker info
<prints output of the remote engine>
SSH 提示
為了獲得最佳的 SSH 使用者體驗,請按如下方式配置 ~/.ssh/config,以允許為多次呼叫 docker CLI 重用 SSH 連線。
ControlMaster auto
ControlPath ~/.ssh/control-%C
ControlPersist yes使用 TLS (HTTPS) 保護 Docker 守護程序套接字
如果您需要 Docker 透過 HTTP 而不是 SSH 安全地訪問,您可以透過指定 tlsverify 標誌並讓 Docker 的 tlscacert 標誌指向受信任的 CA 證書來啟用 TLS (HTTPS)。
在守護程序模式下,它只允許來自透過該 CA 簽名的證書進行身份驗證的客戶端的連線。在客戶端模式下,它只連線到具有由該 CA 簽名的證書的伺服器。
重要使用 TLS 和管理 CA 是一個高階主題。在生產環境中使用之前,請熟悉 OpenSSL、x509 和 TLS。
使用 OpenSSL 建立 CA、伺服器和客戶端金鑰
注意在以下示例中,將所有
$HOST例項替換為您的 Docker 守護程序主機的 DNS 名稱。
首先,在 Docker 守護程序的主機上,生成 CA 私鑰和公鑰。
$ openssl genrsa -aes256 -out ca-key.pem 4096
Generating RSA private key, 4096 bit long modulus
..............................................................................++
........++
e is 65537 (0x10001)
Enter pass phrase for ca-key.pem:
Verifying - Enter pass phrase for ca-key.pem:
$ openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
Enter pass phrase for ca-key.pem:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:Queensland
Locality Name (eg, city) []:Brisbane
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Docker Inc
Organizational Unit Name (eg, section) []:Sales
Common Name (e.g. server FQDN or YOUR name) []:$HOST
Email Address []:Sven@home.org.au
現在您有了一個 CA,您可以建立一個伺服器金鑰和證書籤名請求 (CSR)。確保“通用名稱”與您用於連線到 Docker 的主機名匹配。
注意在以下示例中,將所有
$HOST例項替換為您的 Docker 守護程序主機的 DNS 名稱。
$ openssl genrsa -out server-key.pem 4096
Generating RSA private key, 4096 bit long modulus
.....................................................................++
.................................................................................................++
e is 65537 (0x10001)
$ openssl req -subj "/CN=$HOST" -sha256 -new -key server-key.pem -out server.csr
接下來,我們將使用我們的 CA 簽署公鑰。
由於 TLS 連線可以透過 IP 地址和 DNS 名稱進行,因此在建立證書時需要指定 IP 地址。例如,要允許使用 10.10.10.20 和 127.0.0.1 進行連線。
$ echo subjectAltName = DNS:$HOST,IP:10.10.10.20,IP:127.0.0.1 >> extfile.cnf
將 Docker 守護程序金鑰的擴充套件使用屬性設定為僅用於伺服器身份驗證。
$ echo extendedKeyUsage = serverAuth >> extfile.cnf
現在,生成已簽名的證書。
$ openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem \
-CAcreateserial -out server-cert.pem -extfile extfile.cnf
Signature ok
subject=/CN=your.host.com
Getting CA Private Key
Enter pass phrase for ca-key.pem:
授權外掛 提供了更精細的控制,以補充相互 TLS 的身份驗證。除了上述文件中描述的其他資訊外,執行在 Docker 守護程序上的授權外掛還會收到連線 Docker 客戶端的證書資訊。
對於客戶端身份驗證,建立一個客戶端金鑰和證書籤名請求。
注意為簡化接下來的幾個步驟,您也可以在 Docker 守護程序的主機上執行此步驟。
$ openssl genrsa -out key.pem 4096
Generating RSA private key, 4096 bit long modulus
.........................................................++
................++
e is 65537 (0x10001)
$ openssl req -subj '/CN=client' -new -key key.pem -out client.csr
為了使金鑰適用於客戶端身份驗證,建立一個新的擴充套件配置檔案。
$ echo extendedKeyUsage = clientAuth > extfile-client.cnf
現在,生成已簽名的證書。
$ openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem \
-CAcreateserial -out cert.pem -extfile extfile-client.cnf
Signature ok
subject=/CN=client
Getting CA Private Key
Enter pass phrase for ca-key.pem:
生成 cert.pem 和 server-cert.pem 後,您可以安全地刪除兩個證書籤名請求和擴充套件配置檔案。
$ rm -v client.csr server.csr extfile.cnf extfile-client.cnf
使用預設的 umask 022,您的私鑰是全域性可讀的,並且對您和您的組可寫。
為保護您的金鑰免受意外損壞,請移除它們的寫許可權。為了使它們僅對您可讀,請按如下方式更改檔案模式。
$ chmod -v 0400 ca-key.pem key.pem server-key.pem
證書可以是全域性可讀的,但您可能希望移除寫許可權以防止意外損壞。
$ chmod -v 0444 ca.pem server-cert.pem cert.pem
現在,您可以讓 Docker 守護程序只接受來自提供受您 CA 信任的證書的客戶端的連線。
$ dockerd \
--tlsverify \
--tlscacert=ca.pem \
--tlscert=server-cert.pem \
--tlskey=server-key.pem \
-H=0.0.0.0:2376
要連線到 Docker 並驗證其證書,請提供您的客戶端金鑰、證書和受信任的 CA。
提示此步驟應在您的 Docker 客戶端機器上執行。因此,您需要將您的 CA 證書、伺服器證書和客戶端證書複製到該機器上。
注意在以下示例中,將所有
$HOST例項替換為您的 Docker 守護程序主機的 DNS 名稱。
$ docker --tlsverify \
--tlscacert=ca.pem \
--tlscert=cert.pem \
--tlskey=key.pem \
-H=$HOST:2376 version
注意透過 TLS 的 Docker 應在 TCP 埠 2376 上執行。
警告如上例所示,當您使用證書身份驗證時,無需使用
sudo或docker組執行docker客戶端。這意味著任何擁有金鑰的人都可以向您的 Docker 守護程序發出任何指令,從而獲得對託管該守護程序的機器的 root 訪問許可權。請像保管 root 密碼一樣保管這些金鑰!
預設安全
如果您希望預設情況下保護您的 Docker 客戶端連線,可以將檔案移動到您主目錄下的 .docker 目錄中,並設定 DOCKER_HOST 和 DOCKER_TLS_VERIFY 變數(而不是在每次呼叫時傳遞 -H=tcp://$HOST:2376 和 --tlsverify)。
$ mkdir -pv ~/.docker
$ cp -v {ca,cert,key}.pem ~/.docker
$ export DOCKER_HOST=tcp://$HOST:2376 DOCKER_TLS_VERIFY=1
Docker 現在預設安全連線
$ docker ps
其他模式
如果您不希望進行完整的雙向身份驗證,可以透過混合使用標誌在各種其他模式下執行 Docker。
守護程序模式
tlsverify、tlscacert、tlscert、tlskey設定:驗證客戶端tls、tlscert、tlskey:不驗證客戶端
客戶端模式
tls:基於公共/預設 CA 池驗證伺服器tlsverify、tlscacert:基於給定的 CA 驗證伺服器tls、tlscert、tlskey:使用客戶端證書進行身份驗證,不基於給定的 CA 驗證伺服器tlsverify、tlscacert、tlscert、tlskey:使用客戶端證書進行身份驗證,並基於給定的 CA 驗證伺服器
如果找到,客戶端會發送其客戶端證書,因此您只需將您的金鑰放入 ~/.docker/{ca,cert,key}.pem。或者,如果您想將金鑰儲存在其他位置,可以使用環境變數 DOCKER_CERT_PATH 指定該位置。
$ export DOCKER_CERT_PATH=~/.docker/zone1/
$ docker --tlsverify ps
使用 curl 連線到安全的 Docker 埠
要使用 curl 進行測試 API 請求,您需要使用三個額外的命令列標誌。
$ curl https://$HOST:2376/images/json \
--cert ~/.docker/cert.pem \
--key ~/.docker/key.pem \
--cacert ~/.docker/ca.pem