保護 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