保護 Docker 守護程式通訊端

預設情況下,Docker 透過非網路的 UNIX socket 執行。它也可以選擇性地使用 SSH 或 TLS (HTTPS) socket 進行通訊。

使用 SSH 保護 Docker daemon socket

注意

指定的 USERNAME 必須具有存取遠端機器上 docker socket 的權限。請參閱以非 root 使用者身分管理 Docker,了解如何授予非 root 使用者存取 docker socket 的權限。

以下範例建立了一個 docker context,以便使用 SSH 連接到 host1.example.com 上的遠端 dockerd daemon,並以遠端機器上的 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"

建立 context 後,使用 docker context usedocker CLI 切換為使用該 context,並連接到遠端引擎。

$ 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 context 切換回預設(本機)daemon。

$ docker context use default
default
Current context is now "default"

或者,使用 DOCKER_HOST 環境變數暫時將 docker CLI 切換為使用 SSH 連接到遠端主機。這不需要建立 context,對於與不同引擎建立臨時連線非常有用。

$ export DOCKER_HOST=ssh://docker-user@host1.example.com
$ docker info
<prints output of the remote engine>

SSH 提示

為了獲得最佳的 SSH 使用體驗,請依以下方式設定 ~/.ssh/config,以允許重複使用 SSH 連線進行多次 docker CLI 調用。

ControlMaster     auto
ControlPath       ~/.ssh/control-%C
ControlPersist    yes

使用 TLS (HTTPS) 保護 Docker daemon socket

如果您需要以安全的方式透過 HTTP(而非 SSH)存取 Docker,可以透過指定 tlsverify 旗標並將 Docker 的 tlscacert 旗標指向受信任的 CA 憑證來啟用 TLS (HTTPS)。

在 daemon 模式下,它僅允許由該 CA 簽署之憑證進行驗證的用戶端連線。在用戶端模式下,它僅連接到具有由該 CA 簽署之憑證的伺服器。

重要

使用 TLS 並管理 CA 是一個進階主題。在使用於生產環境之前,請先熟悉 OpenSSL、x509 和 TLS。

使用 OpenSSL 建立 CA、伺服器金鑰與用戶端金鑰

注意

將以下範例中的所有 $HOST 替換為您的 Docker daemon 主機的 DNS 名稱。

首先,在 Docker daemon 的主機上,產生 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)。請確保「通用名稱 (Common Name)」與您用於連接 Docker 的主機名稱相符。

注意

將以下範例中的所有 $HOST 替換為您的 Docker daemon 主機的 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.20127.0.0.1 進行連線:

$ echo subjectAltName = DNS:$HOST,IP:10.10.10.20,IP:127.0.0.1 >> extfile.cnf

設定 Docker daemon 金鑰的延伸使用屬性,使其僅用於伺服器驗證。

$ 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:

授權外掛 (Authorization plugins) 提供了更細粒度的控制,以補充雙向 TLS 的驗證。除了上述文件中描述的其他資訊外,在 Docker daemon 上執行的授權外掛會接收連接 Docker 用戶端的憑證資訊。

對於用戶端驗證,請建立用戶端金鑰與憑證簽署請求。

注意

為了簡化接下來的幾個步驟,您也可以在 Docker daemon 的主機上執行此步驟。

$ 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.pemserver-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 daemon 僅接受來自提供由您的 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 daemon 主機的 DNS 名稱。

$ docker --tlsverify \
    --tlscacert=ca.pem \
    --tlscert=cert.pem \
    --tlskey=key.pem \
    -H=$HOST:2376 version
注意

透過 TLS 的 Docker 應在 TCP 埠 2376 上執行。

警告

如上例所示,當您使用憑證驗證時,不需要使用 sudodocker 群組來執行 docker 用戶端。這意味著任何持有金鑰的人都可以對您的 Docker daemon 發出任何指令,從而賦予他們託管 daemon 之機器的 root 權限。請妥善保管這些金鑰,就像保護 root 密碼一樣!

預設安全機制

如果您希望預設保護您的 Docker 用戶端連線,可以將這些檔案移動到家目錄中的 .docker 目錄,並設定 DOCKER_HOSTDOCKER_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。

Daemon 模式

  • 設定 tlsverifytlscacerttlscerttlskey:驗證用戶端
  • 設定 tlstlscerttlskey:不驗證用戶端

用戶端模式

  • 設定 tls:根據公用/預設 CA 池驗證伺服器
  • 設定 tlsverifytlscacert:根據給定的 CA 驗證伺服器
  • 設定 tlstlscerttlskey:使用用戶端憑證進行驗證,不根據給定的 CA 驗證伺服器
  • 設定 tlsverifytlscacerttlscerttlskey:使用用戶端憑證進行驗證,並根據給定的 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
© . This site is unofficial and not affiliated with Kubernetes or Docker Inc.