访问授权插件(引擎) | 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每个插件必须驻留在插件发现部分。
注意
:分别是缩写AuthZ
和AuthN
平均授权和认证。
默认用户授权机制
如果在Docker守护进程中启用了TLS
,则默认的用户授权流程会从证书主体名称中提取用户详细信息。即,User
字段设置为客户端证书主题公用名称,并且该AuthenticationMethod
字段设置为TLS
。
基本架构
您有责任将您的插件注册为Docker守护程序启动的一部分。您可以安装多个插件并将它们链接在一起。这条链可以订购。对守护进程的每个请求都按顺序通过链。只有当所有插件授予对资源的访问权时,授予的访问权才是。
当通过CLI或通过引擎API向Docker守护进程发出HTTP请求时,身份验证子系统会将请求传递给已安装的身份验证插件。该请求包含用户(调用者)和命令上下文。该插件负责决定是允许还是拒绝该请求。
下面的序列图描述了一个允许和拒绝授权流:
发送给插件的每个请求都包括经过身份验证的用户,HTTP标头和请求/响应主体。只有用户名和使用的认证方法被传递给插件。最重要的是,没有用户凭证或令牌传递。最后,并非所有的请求/响应主体都被发送到授权插件。只有那些请求/响应机构,其中Content-Type
或者是text/*
或application/json
被发送。
对于可能劫持HTTP连接(HTTP Upgrade
)的命令,例如exec
,授权插件仅针对初始HTTP请求进行调用。一旦插件批准了该命令,授权就不会应用于其余的流程。具体来说,流式传输数据不会传递给授权插件。对于返回分块HTTP响应的命令,比如logs
和events
,只有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 | 串 | 错误信息(如果插件遇到错误,将返回给客户端。提供的字符串值可能会出现在日志中,因此不应包含机密信息) |