docker registry v2认证备忘

来源:互联网 发布:智通预算软件 编辑:程序博客网 时间:2024/05/15 13:12

docker registry v2认证过程

https://docs.docker.com/registry/spec/images/v2-registry-auth.png1、尝试从docker regisry中push/pull镜像2、如果docker registry需要授权,将会返回401 Unauthorized的http响应,并在返回的头信息中提供到哪认证的信息3、客户端向授权服务请求获取token。4、认证服务到数据库或ldap中验证用户信息,跟据验证结果生成token5、docker client携带token令牌再次尝试访问docker registry.6、docker registry验证用户提交的token,判断是否有有权限进行操作,如果有则进行相应的pull或push。

docker registry 配置文件中的auth

auth:  silly:    realm: silly-realm    service: silly-service  token:    realm: token-realm    service: token-service    issuer: registry-token-issuer    rootcertbundle: /root/certs/bundle  htpasswd:    realm: basic-realm    path: /path/to/htpasswd

过程

例如当用户尝试向registry push镜像samalba/my-app时,为了完成当前操作,用户需要对repository samalba/my-app具有push的权限,registry将会返回401 Unuthorized信息例如我们执行命令curl -i  https://docker.test/v2/_catalog1、HTTP/1.1 401 UnauthorizedServer: nginxDate: Fri, 11 Aug 2017 02:43:09 GMTContent-Type: application/json; charset=utf-8Content-Length: 134Connection: keep-aliveDocker-Distribution-Api-Version: registry/2.0Www-Authenticate: Bearer realm="https://auth.docker.io/token",service="container_registry",scope="registry:catalog:*"X-Content-Type-Options: nosniff{"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":[{"Type":"registry","Name":"catalog","Action":"*"}]}]}2、Docker Client提供用户输入用户名和密码后向auth server发送请求:https://auth.docker.io/token?service=registry.docker.io&scope=repository:samalba/my-app:pull,push同时在http head中包含用户相关的登录信息authorized: Basic YWtaW46cGzc3dvmcQ=3、auth server只需要从http head中通过base64获取登录的用户名和密码,并且验证登录信息的合法性,同时根据业务数据返回用户的实际权限(pull, push)即可.4、当docker client获取到token之后,client会将得到的token作为http请求头信息再次尝试访问registry,registry使用公钥解密并验证token内容,并根据token包含的权限信息完成实际的操作

加密

通过公钥私钥加密auth:  token:    realm: https://auth.docker.io/token    service: Docker registry    issuer: Auth Service    rootcertbundle: /certs/auth.crt

token的生成

JWT(Json web token)的构成第一部分我们称它为头部(header),第二部分我们称其为载荷(payload, 类似于飞机上承载的物品),第三部分是签证(signature).1、生成jwt的Header信息{    "typ": "JWT",    "alg": "ES256",    "kid": "PYYO:TEWU:V7JH:26JV:AQTZ:LJC3:SXVJ:XGHA:34F2:2LAQ:ZRMK:Z7Q6"}typ: 当使用JWT时,typ固定为“JWT”alg: 对应私钥文件的加密方式,本示例中即对应auth.key文件的加密方式,可以通过代码读取私钥文件获取kid: 根据docker提供的规则生成公钥文件的kid,registry会根据同样的算法获取公钥的kid,如果匹配失败则认证失败2、设置jwt的payload信息{    "iss": "Auth Service", //需要注意必须与auth.token.issuer配置保持一致    "sub": "some id", //根据业务系统的规则自定义生成即可    "aud": "Docker registry",// 从请求的service参数获取    "exp": 1415387315, //过期时间    "nbf": 1415387015, // not before 可选参数    "iat": 1415387015, // 正式发行时间    "jti": "tYJCO1c6cnyy7kAn0c7rKPgbV1H1bFws", //随机生成即可    // access根据请求的scope获取,当然业务系统要判断用户的实际权限并在actions中放回    "access": [        {            "type": "repository",            "name": "samalba/my-app",            "actions": [                "pull",                "push"            ]        }    ]}3、使用私钥进行签名

参考资料

https://docs.docker.com/registry/spec/auth/token/#how-to-authenticatehttps://yunlzheng.github.io/2016/11/29/docker-registry-details/