Docker 授权插件示例
在处理 Docker 基线检查问题时,有一个检查项目为使用授权插件
,需要给 Docker 设置授权插件,限制客户端命令的使用。为了通过检查,写了一个脚本实现AuthZ
的授权接口,没有限制任何权限,全部返回允许,如果需要,可以增加限制逻辑。
需要完成的操作:
- 增加授权接口脚本
- docker 中增加插件配置
参考官方文档:
access-authorization-plugin
Docker Plugin API
授权接口脚本
使用 python 写的脚本,为了尽可能方便,不使用第三方库,使用 python 自带的 http 库。
- 实现
AuthZ
的授权需要的三个接口:- /Plugin.Activate:插件探活接口,返回插件的实现
authz
。 - /AuthZPlugin.AuthZReq:在 Docker 守护进程处理客户端请求之前调用此授权请求方法。
- /AuthZPlugin.AuthZRes:在响应从 Docker 守护进程返回到客户端之前被调用。
- /Plugin.Activate:插件探活接口,返回插件的实现
- docker 授权请求全为 POST
import json
from http.server import HTTPServer, BaseHTTPRequestHandler
class DockerAuthHandler(BaseHTTPRequestHandler):
def do_POST(self):
"""
处理 docker 授权请求
"""
content_length = int(self.headers['Content-Length'])
request_body = self.rfile.read(content_length).decode('utf-8')
# print(request_body)
if self.path == '/Plugin.Activate':
res = {'Implements': ['authz']}
else:
# 可以增加权限判断
res = {'Allow': True, 'Msg': '', 'Err': ''} # 允许所有的请求
self.send_response(200)
self.send_header('Content-type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps(res).encode(encoding='utf-8'))
def run_server():
host = '0.0.0.0' # 监听所有网络接口
port = 8080
server_address = (host, port)
httpd = HTTPServer(server_address, DockerAuthHandler)
print(f'Starting HTTP server on {host}:{port}')
try:
httpd.serve_forever()
except KeyboardInterrupt:
print('Stopping HTTP server...')
finally:
httpd.server_close()
if __name__ == "__main__":
run_server()
docker 插件配置
Docker 通过在插件目录中查找插件来发现插件,可以配置三种类型的文件到插件目录中:
- .sock
- .spec
- .json
这里使用 json 文件配置插件,在 docker 的默认插件目录(/etc/docker/plugins
或/usr/lib/docker/plugins
)下增加一个simple.json
文件,文件内容如下:
{
"Name": "simple",
"Addr": "http://127.0.0.1:28888/"
}
应用插件
在 docker 启动命令中增加参数--authorization-plugin=simple
。如果是使用 systemctl 启动 docker,可以修改/lib/systemd/system/docker.service
文件,在 docker 启动命令配置项ExecStart
中增加--authorization-plugin=simple
。修改完成后,执行systemctl daemon-reload
和systemctl restart docker
重启 docker 服务。