非常教程

Docker 17参考手册

引擎: 扩展 | Engine: Extend

访问授权插件(引擎) | Access authorization plugin (Engine)

创建授权插件

本文档描述了Docker Engine中通常提供的Docker Engine插件。要查看由Docker Engine管理的插件的信息,请参阅Docker Engine插件系统。

Docker的开箱即用授权模式是全部或没有。任何有权访问Docker守护程序的用户都可以运行任何Docker客户端命令。对于使用Docker的Engine API来调用守护进程的调用者也是如此。如果您需要更大的访问控制权,您可以创建授权插件并将其添加到Docker守护程序配置中。使用授权插件,Docker管理员可以配置粒度访问策略来管理对Docker守护进程的访问。

任何具有相应技能的人都可以开发授权插件。这些技能,最基本的是Docker的知识,对REST的理解以及良好的编程知识。本文档描述授权插件开发人员可用的体系结构,状态和方法信息。

基本原则

Docker的插件基础架构可以通过使用通用API加载,删除和与第三方组件进行通信来扩展Docker。访问授权子系统是使用这种机制构建的。

使用这个子系统,您不需要重建Docker守护程序来添加授权插件。您可以将插件添加到已安装的Docker守护程序。您确实需要重新启动Docker守护程序才能添加新的插件。

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

授权插件必须遵循Docker插件API每个插件必须驻留在插件发现部分。

注意:分别是缩写AuthZAuthN平均授权和认证。

默认用户授权机制

如果在Docker守护进程中启用了TLS,则默认的用户授权流程会从证书主体名称中提取用户详细信息。即,User字段设置为客户端证书主题公用名称,并且该AuthenticationMethod字段设置为TLS

基本架构

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

当通过CLI或通过引擎API向Docker守护进程发出HTTP请求时,身份验证子系统会将请求传递给已安装的身份验证插件。该请求包含用户(调用者)和命令上下文。该插件负责决定是允许还是拒绝该请求。

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

访问授权插件(引擎)  |  Access authorization plugin (Engine)

访问授权插件(引擎)  |  Access authorization plugin (Engine)

发送给插件的每个请求都包括经过身份验证的用户,HTTP标头和请求/响应主体。只有用户名和使用的认证方法被传递给插件。最重要的是,没有用户凭证或令牌传递。最后,并非所有的请求/响应主体都被发送到授权插件。只有那些请求/响应机构,其中Content-Type或者是text/*application/json被发送。

对于可能劫持HTTP连接(HTTP Upgrade)的命令,例如exec,授权插件仅针对初始HTTP请求进行调用。一旦插件批准了该命令,授权就不会应用于其余的流程。具体来说,流式传输数据不会传递给授权插件。对于返回分块HTTP响应的命令,比如logsevents,只有HTTP请求被发送到授权插件。

在请求/响应处理期间,一些授权流可能需要对Docker守护进程执行额外的查询。为了完成这样的流程,插件可以像守护用户一样调用守护进程API。要启用这些额外的查询,插件必须为管理员提供配置正确的身份验证和安全策略的手段。

Docker客户端流量

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

设置Docker守护进程

使用--authorization-plugin=PLUGIN_ID格式中的专用命令行标志启用授权插件。该标志提供一个PLUGIN_ID值。该值可以是插件的套接字或指定文件的路径。授权插件可以在不重新启动守护进程的情况下加载。请参阅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"
}

请求授权

每个插件必须支持两种请求授权消息格式,一种是从守护进程到插件,然后从插件到守护进程。下面的表格详细列出了每条消息所期望的内容。

Daemon->插件

Name

类型

描述

用户

用户标识

身份验证方法

使用的验证方法

请求方法

枚举

HTTP方法(GET / DELETE / POST)

请求URI

包含API版本的HTTP请求URI(例如,v.1.17 / containers / json)

请求标头

mapstringstring

请求标头作为键值对(不含授权标头)

请求正文

[]byte

原始请求主体

Plugin -> Daemon

Name

类型

描述

Allow

布尔

指示请求是允许还是拒绝的布尔值

Msg

授权消息(如果访问被拒绝,将返回给客户端)

Err

错误信息(如果插件遇到错误,将返回给客户端。提供的字符串值可能会出现在日志中,因此不应包含机密信息)

响应授权

插件必须支持两种授权消息格式,一种是从守护进程到插件,然后从插件到守护进程。下面的表格详细列出了每条消息所期望的内容。

Daemon -> Plugin

Name

类型

描述

用户

用户标识

身份验证方法

使用的验证方法

请求方法

HTTP方法(GET / DELETE / POST)

请求URI

包含API版本的HTTP请求URI(例如,v.1.17 / containers / json)

请求标头

mapstringstring

请求标头作为键值对(不含授权标头)

请求正文

[]字节

原始请求主体

响应状态码

INT

来自docker守护程序的状态码

响应标题

mapstringstring

响应标题作为键值对

响应机构

[]字节

原始码头守护程序响应正文

Plugin -> Daemon

Name

类型

描述

Allow

布尔

指示响应是被允许还是被拒绝的布尔值

Msg

授权消息(如果访问被拒绝,将返回给客户端)

Err

错误信息(如果插件遇到错误,将返回给客户端。提供的字符串值可能会出现在日志中,因此不应包含机密信息)

安全,授权,认证,码头,文档,插件,扩展

Docker 17

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。

主页 https://docker.com/
源码 https://github.com/docker/docker
版本 17
发布版本 17.06