存取授權插件
本文檔說明 Docker 引擎中可用的 Docker 引擎外掛程式。要檢視 Docker 引擎管理的外掛程式資訊,請參閱Docker 引擎外掛程式系統。
Docker 的現成授權模型是非黑即白。任何具有存取 Docker Daemon 權限的使用者都可以執行任何 Docker 用戶端命令。對於使用 Docker 引擎 API 連線 Daemon 的呼叫者也是如此。如果您需要更嚴格的存取控制,可以建立授權外掛程式並將其新增至 Docker Daemon 設定。使用授權外掛程式,Docker 管理員可以設定精細的存取策略來管理 Docker Daemon 的存取權限。
任何具備適當技能的人都可以開發授權外掛程式。這些技能,最基本的,是 Docker 的知識、對 REST 的理解,以及紮實的程式設計知識。本文檔說明授權外掛程式開發人員可用的架構、狀態和方法資訊。
基本原則
Docker 的外掛程式基礎架構允許透過使用通用 API 載入、移除和與第三方元件通訊來擴充 Docker。存取授權子系統就是使用這種機制建置的。
使用此子系統,您不需要重新建置 Docker Daemon 即可新增授權外掛程式。您可以將外掛程式新增至已安裝的 Docker Daemon。您需要重新啟動 Docker Daemon 才能新增新的外掛程式。
授權外掛程式會根據目前的驗證上下文和命令上下文來批准或拒絕 Docker Daemon 的請求。驗證上下文包含所有使用者詳細資訊和驗證方法。命令上下文包含所有相關的請求資料。
授權外掛程式必須遵循Docker 外掛程式 API中說明的規則。每個外掛程式都必須位於外掛程式探索區段下描述的目錄中。
**注意**
縮寫 `AuthZ` 和 `AuthN` 分別代表授權和驗證。
預設使用者授權機制
如果在Docker Daemon中啟用了 TLS,預設的使用者授權流程會從憑證主體名稱中擷取使用者詳細資訊。也就是說,「使用者」欄位會設定為用戶端憑證主體通用名稱,而「驗證方法」欄位會設定為 `TLS`。
基本架構
您負責將您的外掛程式註冊為 Docker Daemon 啟動程序的一部分。您可以安裝多個外掛程式並將它們鏈結在一起。此鏈可以排序。每個對 Daemon 的請求都會依序通過鏈。只有當所有外掛程式都授予對資源的存取權限時,才會授予存取權限。
當透過 CLI 或引擎 API 對 Docker Daemon 發出 HTTP 請求時,驗證子系統會將請求傳遞至已安裝的驗證外掛程式。請求包含使用者 (呼叫者) 和命令上下文。外掛程式負責決定是否允許或拒絕請求。
以下的循序圖描述了允許和拒絕授權流程




傳送至外掛程式的每個請求都包含已驗證的使用者、HTTP 標頭和請求/回應主體。只有使用者名稱和使用的驗證方法會傳遞至外掛程式。最重要的是,不會傳遞任何使用者憑證或權杖。最後,並非所有請求/回應主體都會傳送至授權外掛程式。只有 `Content-Type` 為 `text/*` 或 `application/json` 的請求/回應主體才會被傳送。
對於可能劫持 HTTP 連線 (`HTTP 升級`) 的命令,例如 `exec`,授權外掛程式只會針對初始 HTTP 請求呼叫。外掛程式核准命令後,授權就不會套用至流程的其餘部分。具體來說,串流資料不會傳遞至授權外掛程式。對於傳回區塊 HTTP 回應的命令,例如 `logs` 和 `events`,只有 HTTP 請求會傳送至授權外掛程式。
在請求/回應處理期間,某些授權流程可能需要對 Docker Daemon 進行額外的查詢。為了完成此類流程,外掛程式可以像一般使用者一樣呼叫 Daemon API。為了啟用這些額外的查詢,外掛程式必須提供讓管理員設定適當的驗證和安全性策略的方法。
Docker 用戶端流程
為了啟用和設定授權外掛程式,外掛程式開發人員必須支援本節中詳述的 Docker 用戶端互動。
設定 Docker Daemon
使用專用的命令列旗標,以 --authorization-plugin=PLUGIN_ID
的格式啟用授權插件。該旗標提供一個 PLUGIN_ID
值。此值可以是插件的 socket 或規格檔案的路徑。授權插件可以在不重新啟動守護行程式的情況下載入。參考 dockerd
文件 以獲得更多資訊。
$ dockerd --authorization-plugin=plugin1 --authorization-plugin=plugin2,...
Docker 的授權子系統支援多個 --authorization-plugin
參數。
呼叫已授權的命令 (允許)
$ docker pull centos
<...>
f1b10cd84249: Pull complete
<...>
呼叫未授權的命令 (拒絕)
$ docker pull centos
<...>
docker: Error response from daemon: authorization denied by plugin PLUGIN_NAME: volumes are not allowed.
來自外掛程式的錯誤
$ docker pull centos
<...>
docker: Error response from daemon: plugin PLUGIN_NAME failed with error: AuthZPlugin.AuthZReq: Cannot connect to the Docker daemon. Is the docker daemon running on this host?.
API 結構描述和實作
除了 Docker 的標準插件註冊方法外,每個插件都應該實作以下兩種方法
/AuthZPlugin.AuthZReq
這個授權請求方法會在 Docker 守護行程式處理客戶端請求之前被呼叫。/AuthZPlugin.AuthZRes
這個授權回應方法會在 Docker 守護行程式將回應返回給客戶端之前被呼叫。
/AuthZPlugin.AuthZReq
請求
{
"User": "The user identification",
"UserAuthNMethod": "The authentication method used",
"RequestMethod": "The HTTP method",
"RequestURI": "The HTTP request URI",
"RequestBody": "Byte array containing the raw HTTP request body",
"RequestHeader": "Byte array containing the raw HTTP request header as a map[string][]string "
}
回應
{
"Allow": "Determined whether the user is allowed or not",
"Msg": "The authorization message",
"Err": "The error message if things go wrong"
}
/AuthZPlugin.AuthZRes
請求
{
"User": "The user identification",
"UserAuthNMethod": "The authentication method used",
"RequestMethod": "The HTTP method",
"RequestURI": "The HTTP request URI",
"RequestBody": "Byte array containing the raw HTTP request body",
"RequestHeader": "Byte array containing the raw HTTP request header as a map[string][]string",
"ResponseBody": "Byte array containing the raw HTTP response body",
"ResponseHeader": "Byte array containing the raw HTTP response header as a map[string][]string",
"ResponseStatusCode":"Response status code"
}
回應
{
"Allow": "Determined whether the user is allowed or not",
"Msg": "The authorization message",
"Err": "The error message if things go wrong"
}
請求授權
每個插件都必須支援兩種請求授權訊息格式,一種是從守護行程式到插件,另一種是從插件到守護行程式。下表詳細說明了每種訊息中預期的內容。
守護行程式 -> 插件
名稱 | 類型 | 說明 |
---|---|---|
使用者 | 字串 | 使用者識別 |
驗證方法 | 字串 | 使用的驗證方法 |
請求方法 | 列舉 | HTTP 方法 (GET/DELETE/POST) |
請求 URI | 字串 | 包含 API 版本的 HTTP 請求 URI(例如,v.1.17/containers/json) |
請求標頭 | map[string]string | 請求標頭,以鍵值對的形式呈現(不包含授權標頭) |
請求主體 | []byte | 原始請求主體 |
插件 -> 守護行程式
名稱 | 類型 | 說明 |
---|---|---|
允許 | 布林值 | 布林值,指示是否允許或拒絕請求 |
訊息 | 字串 | 授權訊息(如果拒絕訪問,將返回給客戶端) |
錯誤 | 字串 | 錯誤訊息(如果插件遇到錯誤,將返回給客戶端。提供的字串值可能會出現在日誌中,因此不應包含機密資訊) |
回應授權
插件必須支援兩種授權訊息格式,一種是從守護行程式到插件,另一種是從插件到守護行程式。下表詳細說明了每種訊息中預期的內容。
守護行程式 -> 插件
名稱 | 類型 | 說明 |
---|---|---|
使用者 | 字串 | 使用者識別 |
驗證方法 | 字串 | 使用的驗證方法 |
請求方法 | 字串 | HTTP 方法 (GET/DELETE/POST) |
請求 URI | 字串 | 包含 API 版本的 HTTP 請求 URI(例如,v.1.17/containers/json) |
請求標頭 | map[string]string | 請求標頭,以鍵值對的形式呈現(不包含授權標頭) |
請求主體 | []byte | 原始請求主體 |
回應狀態碼 | 整數 | 來自 Docker 守護行程式的狀態碼 |
回應標頭 | map[string]string | 回應標頭,以鍵值對的形式呈現 |
回應主體 | []byte | Docker 守護行程式的原始回應主體 |
插件 -> 守護行程式
名稱 | 類型 | 說明 |
---|---|---|
允許 | 布林值 | 布林值,指示是否允許或拒絕回應 |
訊息 | 字串 | 授權訊息(如果拒絕訪問,將返回給客戶端) |
錯誤 | 字串 | 錯誤訊息(如果插件遇到錯誤,將返回給客戶端。提供的字串值可能會出現在日誌中,因此不應包含機密資訊) |