访问授权插件

本文档介绍了 Docker 中可用的 Docker Engine 插件 发动机。要查看 Docker Engine 管理的插件的信息,请执行以下操作: 请参阅 Docker Engine 插件系统

Docker 开箱即用的授权模型是全有或全无。任何具有 访问 Docker 守护程序的权限可以运行任何 Docker 客户端命令。这 对于使用 Docker 的 Engine API 联系守护程序的调用者也是如此。如果你 需要更大的访问控制,您可以创建授权插件并添加 它们添加到你的 Docker 守护程序配置中。使用授权插件,一个 Docker 管理员可以配置精细访问策略来管理访问 添加到 Docker 守护程序。

任何具有适当技能的人都可以开发授权插件。这些 技能,从最基本的角度来看,是 Docker 知识、对 REST 的理解以及 扎实的编程知识。本文档介绍了架构、状态、 以及授权插件开发人员可用的方法信息。

基本原则

Docker 的插件基础设施使 通过加载、删除和通信来扩展 Docker 使用通用 API 的第三方组件。访问授权子系统 是使用此机制构建的。

使用此子系统,您无需重新构建 Docker 守护程序即可添加 授权插件。您可以将插件添加到已安装的 Docker 守护程序中。是吗 需要重启 Docker 守护进程才能添加新插件。

授权插件批准或拒绝对基于 Docker 守护进程的请求 在当前身份验证上下文和命令上下文上。这 authentication context 包含所有用户详细信息和身份验证方法。 命令上下文包含所有相关的请求数据。

授权插件必须遵循 Docker 插件 API 中描述的规则。 每个插件必须位于 Plugin discovery 部分中描述的目录中。

注意

缩写 和 表示 授权 和 身份验证 分别。AuthZAuthN

默认用户授权机制

如果在 Docker 守护程序中启用了 TLS,则默认用户授权流程将从证书使用者名称中提取用户详细信息。 也就是说,该字段设置为客户端证书使用者公用名,并且该字段设置为 。UserAuthenticationMethodTLS

基本体系结构

您负责将插件注册为 Docker 守护程序的一部分 启动。您可以安装多个插件并将它们链接在一起。这条链 可以订购。对守护进程的每个请求都按顺序通过链。 只有当所有插件都授予对资源的访问权限时,才会授予访问权限。

当通过 CLI 或通过 Engine API 时,身份验证子系统会将请求传递给已安装的 身份验证插件。请求包含用户 (调用方) 和命令 上下文。该插件负责决定是允许还是拒绝 请求。

下面的序列图描述了允许和拒绝授权流程:

授权允许流
授权拒绝流

发送到插件的每个请求都包含经过身份验证的用户,即 HTTP headers 和请求/响应正文。只有用户名和 使用的身份验证方法将传递给插件。最重要的是,没有用户 凭证或令牌。最后,并非所有请求/响应正文 将发送到授权插件。只有那些 是 要么 要么 被发送。Content-Typetext/*application/json

对于可能劫持 HTTP 连接 () 的命令(如 ),仅对 初始 HTTP 请求。一旦插件批准了该命令,授权就是 未应用于流的其余部分。具体来说,流数据不是 传递给授权插件。对于返回分块 HTTP 的命令 响应(如 and)中,仅将 HTTP 请求发送到 授权插件。HTTP Upgradeexeclogsevents

在请求/响应处理期间,某些授权流可能会 需要对 Docker 守护进程执行额外的查询。要完成此类流, plugins 可以像普通用户一样调用 daemon API。要启用这些 additional queries,该插件必须为管理员提供 配置适当的身份验证和安全策略。

Docker 客户端流

要启用和配置授权插件,插件开发人员必须 支持本节中详述的 Docker 客户端交互。

设置 Docker 守护程序

使用格式中的专用命令行标志启用授权插件。标志提供一个值。该值可以是插件的套接字或规范文件的路径。 可以在不重新启动守护进程的情况下加载授权插件。指 到 dockerd 文档以了解更多信息。--authorization-plugin=PLUGIN_IDPLUGIN_ID

$ dockerd --authorization-plugin=plugin1 --authorization-plugin=plugin2,...

Docker 的授权子系统支持多个参数。--authorization-plugin

调用授权命令 (allow)

$ docker pull centos
<...>
f1b10cd84249: Pull complete
<...>

调用未经授权的命令 (deny)

$ 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此 authorize 请求方法在 Docker 守护程序处理客户端请求之前调用。

  • /AuthZPlugin.AuthZRes在将响应从 Docker 守护程序返回到客户端之前,将调用此 authorize 响应方法。

/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]字符串请求标头作为键值对(不带授权标头)
请求正文[]字节原始请求正文

插件 -> 守护进程

名字类型描述
允许布尔指示是允许还是拒绝请求的布尔值
味精字符串授权消息(如果访问被拒绝,将返回给客户端)
犯 错字符串错误消息(如果插件遇到错误,将返回给客户端。提供的字符串值可能会出现在日志中,因此不应包含机密信息)

响应授权

该插件必须支持两种授权消息格式,一种是从守护程序到插件,另一种是从插件到守护程序。下表详细说明了每条消息中预期的内容。

守护进程 -> 插件

名字类型描述
用户字符串用户标识
身份验证方法字符串使用的身份验证方法
请求方法字符串HTTP 方法 (GET/DELETE/POST)
请求 URI字符串包含 API 版本的 HTTP 请求 URI(例如,v.1.17/containers/json)
请求标头map[string]字符串请求标头作为键值对(不带授权标头)
请求正文[]字节原始请求正文
响应状态代码intDocker 守护程序中的状态代码
响应标头map[string]字符串作为键值对的响应标头
响应正文[]字节原始 Docker 守护程序响应正文

插件 -> 守护进程

名字类型描述
允许布尔指示是允许还是拒绝响应的布尔值
味精字符串授权消息(如果访问被拒绝,将返回给客户端)
犯 错字符串错误消息(如果插件遇到错误,将返回给客户端。提供的字符串值可能会出现在日志中,因此不应包含机密信息)