未分类
docker registry auth权限认证搭建
docker registry官方默认的权限认证是pull和push都需要密码. 线上私有镜像仓库有个需求, pull不需要密码, 仅push需要密码, 这样线上应用不用更新逻辑, 从而增加registry的安全性, 不会被人使黑删除或覆盖镜像. 参考了 https://medium.com/@maanadev/authorization-for-private-docker-registry-d1f6bf74552f https://github.com/cesanta/docker_auth 搭建过程中间有一些坑. 首先搭建go环境,
1 2 3 4 5 6 7 |
cat >> /etc/profile <<EOF export GOROOT=/usr/local/go export GOPATH=/opt/goProject export GOBIN=$GOPATH/bin export PATH=$PATH:$GOROOT/bin export PATH=$PATH:$GOPATH/bin EOF |
注意: go项目要放到/opt/goProject/src/目录下
1 2 3 4 5 6 7 8 9 10 11 12 |
mkdir $GOPATH/src/cesanta cd $GOPATH/src/cesanta && \ git clone https://github.com/cesanta/docker_auth.git && \ cd docker_auth/auth_server make deps git clone https://github.com/ThilinaManamgoda/docker_registry_auth.git cd docker_registry_auth mkdir ssl # 然后将线上证书文件放到这里 # build executables in the conf/extensions folder cd conf/extensions && \ GOOS=linux GOARCH=386 go build ../../main/authentication.go && \ GOOS=linux GOARCH=386 go build ../../main/authorization.go |
安装docker-compose后, 这是我的compose文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
cat docker-compose.yml version: "2" services: registry: image: registry:2.6.2 container_name: ycr-registry-srv volumes: - ./ssl:/ssl - /ali-nas/ycr-xxx-com/registry-srv/data:/var/lib/registry restart: always network_mode: "host" environment: - TZ=Asia/Shanghai - REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY=/var/lib/registry - REGISTRY_AUTH=token - REGISTRY_AUTH_TOKEN_REALM=https://ycr.xxx.com:5001/auth - REGISTRY_AUTH_TOKEN_SERVICE="Docker registry" - REGISTRY_AUTH_TOKEN_ISSUER="Auth Service" - REGISTRY_AUTH_TOKEN_ROOTCERTBUNDLE=/ssl/domain.crt - REGISTRY_HTTP_TLS_CERTIFICATE=/ssl/domain.crt - REGISTRY_HTTP_TLS_KEY=/ssl/domain.key dockerauth: image: cesanta/docker_auth container_name: ycr-registry-auth network_mode: "host" volumes: - ./auth-config:/config:ro - ./ssl:/ssl - ./extensions:/extensions command: -alsologtostderr=true -log_dir=/logs /config/extAuth.yml restart: always registry-web: image: hyper/docker-registry-web container_name: ycr-registry-web ports: - "8080:8080" volumes: - /ali-nas/ycr-xxx-com/registry-web/conf:/conf:ro - /ali-nas/ycr-xxx-com/registry-web/db:/data environment: - TZ=Asia/Shanghai restart: always networks: extnetwork: ipv4_address: 192.168.200.2 networks: extnetwork: ipam: config: - subnet: 192.168.200.0/24 gateway: 192.168.200.1 |
这是docker-auth配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
cat auth-config/extAuth.yml # A simple example. See reference.yml for explanation for explanation of all options. # # auth: # token: # realm: "https://127.0.0.1:5001/auth" # service: "Docker registry" # issuer: "Acme auth server" # rootcertbundle: "/path/to/server.pem" server: addr: ":5001" certificate: "/ssl/domain.crt" key: "/ssl/domain.key" token: issuer: "Auth Service" # Must match issuer in the Registry config. expiration: 900 users: # Password is specified as a BCrypt hash. Use `htpasswd -nB USERNAME` to generate. "admin": password: "$2y$05$NFnGYEh0k.xxxxxxxxxx/xxxxxx.xxxxxxx" #"test": # #password: "$2y$05$WuwBasGDAgr.QCbGIjKJaep4dhxeai9gNZdmBnQXqpKly57oNutya" # 123 # password: "$2y$05$ysDWI8R3Lfn6gKFS6xvwSOtK5c1sw7l.fYehfAzWWCMP1b1rbkKqy" # 123 "": {} # Allow anonymous (no "docker login") access. acl: - match: {account: "admin"} actions: ["*"] comment: "Admin has full access to everything." #- match: {account: "test"} # actions: ["pull"] # comment: "User \"user\" can pull stuff." - match: {account: ""} actions: ["pull"] comment: "Anonymous users can pull stuff." # can pull by default. ext_auth: command: "/extensions/authentication" # Can be a relative path too; $PATH works. args: [""] ext_authz: command: "/extensions/authorization" args: [""] |
这是compose根目录文件结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
[root@optdocker18-iuap-hb2-ali docker_registry_auth]# tree . ├── auth-config │ └── extAuth.yml ├── bak │ ├── docker-compose.yml.2019-05-24 │ ├── docker-compose.yml.bridge │ ├── docker-compose.yml.host │ ├── docker-compose.yml.online │ └── extAuth.yml.bak ├── docker-compose.yml ├── extensions │ ├── authentication │ └── authorization └── ssl ├── domain.crt └── domain.key 4 directories, 11 files |
其中: registry-web是做web端管理界面 详细的权限控制(https://github.com/cesanta/docker_auth/blob/master/examples/reference.yml):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 |
# This config lists all the possible config options. # # To configure Docker Registry to talk to this server, put the following in the registry config file: # # auth: # token: # realm: "https://127.0.0.1:5001/auth" # service: "Docker registry" # issuer: "Acme auth server" # autoredirect: false # rootcertbundle: "/path/to/server.pem" server: # Server settings. # Address to listen on. addr: ":5001" # URL path prefix to use. path_prefix: "" # TLS options. # # Use specific certificate and key. certificate: "/path/to/server.pem" key: "/path/to/server.key" # Use LetsEncrypt (https://letsencrypt.org/) to automatically obtain and maintain a certificate. # Note that this only applies to server TLS certificate, this certificate will not be used for tokens letsencrypt: # Email is required. It will be used to register with LetsEncrypt. email: webmaster@example.org # Cache directory, where certificates issued by LE will be stored. Must exist. # It is recommended to make it a volume mount so it persists across restarts. cache_dir: /data/sslcache # Normally LetsEncrypt will obtain a certificate for whichever host the client is connecting to. # With this option, you can limit it to a specific host name. # host: "docker.example.org" # If neither certificate+key or letsencrypt are configured, the listener does not use TLS. # Take client's address from the specified HTTP header instead of connection. # May be useful if the server is behind a proxy or load balancer. # If configured, this header must be present, requests without it will be rejected. # real_ip_header: "X-Forwarded-For" # Optional position of client ip in X-Forwarded-For, negative starts from # end of addresses. # real_ip_pos: -2 token: # Settings for the tokens. issuer: "Acme auth server" # Must match issuer in the Registry config. expiration: 900 # Token must be signed by a certificate that registry trusts, i.e. by a certificate to which a trust chain # can be constructed from one of the certificates in registry's auth.token.rootcertbundle. # If not specified, server's TLS certificate and key are used. # certificate: "..." # key: "..." # Authentication methods. All are tried, any one returning success is sufficient. # At least one must be configured. If you want an unauthenticated public setup, # configure static user map with anonymous access. # Static user map. users: # Password is specified as a BCrypt hash. Use `htpasswd -nB USERNAME` to generate. "admin": password: "$2y$05$LO.vzwpWC5LZGqThvEfznu8qhb5SGqvBSWY1J3yZ4AxtMRZ3kN5jC" # badmin "test": password: "$2y$05$WuwBasGDAgr.QCbGIjKJaep4dhxeai9gNZdmBnQXqpKly57oNutya" # 123 "": {} # Allow anonymous (no "docker login") access. # Google authentication. # ==! NB: DO NOT ENTER YOUR GOOGLE PASSWORD AT "docker login". IT WILL NOT WORK. # Instead, Auth server maintains a database of Google authentication tokens. # Go to the server's port as HTTPS with your browser and follow the "Login with Google account" link. # Once signed in, you will get a throw-away password which you can use for Docker login. google_auth: domain: "example.com" # Optional. If set, only logins from this domain are accepted. # client_id and client_secret for API access. Required. # Follow instructions here: https://developers.google.com/identity/sign-in/web/devconsole-project # NB: Make sure JavaScript origins are configured correctly, and that third-party # cookies are not blocked in the browser being used to login. client_id: "1223123456-somethingsomething.apps.googleusercontent.com" # Either client_secret or client_secret_file is required. Use client_secret_file if you don't # want to have sensitive information checked in. # client_secret: "verysecret" client_secret_file: "/path/to/client_secret.txt" # Where to store server tokens. Required. token_db: "/somewhere/to/put/google_tokens.ldb" # How long to wait when talking to Google servers. Optional. http_timeout: 10 # GitHub authentication. # ==! NB: DO NOT ENTER YOUR GITHUB PASSWORD AT "docker login". IT WILL NOT WORK. # Instead, Auth server maintains a database of GitHub authentication tokens. # Go to the server's port as HTTPS with your browser and follow the "Login with GitHub account" link. # Once signed in, you will get a throw-away password which you can use for Docker login. github_auth: organization: "acme" # Optional. If set, only logins from this organization are accepted. # client_id and client_secret for API access. Required. # You can register a new application here: https://github.com/settings/developers # NB: Make sure JavaScript origins are configured correctly, and that third-party # cookies are not blocked in the browser being used to login. client_id: "1223123456" # Either client_secret or client_secret_file is required. Use client_secret_file if you don't # want to have sensitive information checked in. # client_secret: "verysecret" client_secret_file: "/path/to/client_secret.txt" # Either token_db file for storing of server tokens. token_db: "/somewhere/to/put/github_tokens.ldb" # or google cloud storage for storing of the sensitive information. gcs_token_db: bucket: "tokenBucket" client_secret_file: "/path/to/client_secret.json" # How long to wait when talking to GitHub servers. Optional. http_timeout: "10s" # How long to wait before revalidating the GitHub token. Optional. revalidate_after: "1h" # The Github Web URI in case you are using Github Enterprise. # Includes the protocol, without trailing slash. Optional - defaults to: https://github.com github_web_uri: "https://github.acme.com" # The Github API URI in case you are using Github Enterprise. # Includes the protocol, without trailing slash. - defaults to: https://api.github.com github_api_uri: "https://github.acme.com/api/v3" # Set an URL to display in the `docker login` command when succesfully authenticated. Optional. registry_url: localhost:5000 # LDAP authentication. # Authentication is performed by first binding to the server, looking up the user entry # by using the specified filter, and then re-binding using the matched DN and the password provided. ldap_auth: # Addr is the hostname:port or ip:port addr: ldap.example.com:636 # Setup tls connection method to be # "" or "none": the communication won't be encrypted # "always": setup LDAP over SSL/TLS # "starttls": sets StartTLS as the encryption method tls: always # set to true to allow insecure tls insecure_tls_skip_verify: false # set this to specify the ca certificate path ca_certificate: # In case bind DN and password is required for querying user information, # specify them here. Plain text password is read from the file. bind_dn: bind_password_file: # User query settings. ${account} is expanded from auth request base: o=example.com filter: (&(uid=${account})(objectClass=person)) # Labels can be mapped from LDAP attributes labels: # Add the user's title to a label called title title: attribute: title # Add the user's memberOf values to a label called groups groups: attribute: memberOf # Special handling to simplify the values to just the common name parse_cn: true mongo_auth: # Essentially all options are described here: https://godoc.org/gopkg.in/mgo.v2#DialInfo dial_info: # The MongoDB hostnames or IPs to connect to. addrs: ["localhost"] # The time to wait for a server to respond when first connecting and on # follow up operations in the session. If timeout is zero, the call may # block forever waiting for a connection to be established. # (See https://golang.org/pkg/time/#ParseDuration for a format description.) timeout: "10s" # Database name that will be used on the MongoDB server. database: "docker_auth" # The username with which to connect to the MongoDB server. username: "" # Path to the text file with the password in it. password_file: "" # Enable TLS connection to MongoDB (only enable this if your server supports it) enable_tls: false # Name of the collection in which ACLs will be stored in MongoDB. collection: "users" # Unlike acl_mongo we don't cache the full user set. We just query mongo for # an exact match for each authorization # External authentication - call an external progam to authenticate user. # Username and password are passed to command's stdin and exit code is examined. # 0 - allow, 1 - deny, 2 - no match, other - error. # In case of success, if any output is returned, it is parsed as a JSON object. # The "labels" key may contain labels to be passed down to authz, where they can # be used in matching. See ext_auth.sh for an example. ext_auth: command: "/usr/local/bin/my_auth" # Can be a relative path too; $PATH works. args: ["--flag", "--more", "--flags"] # Authorization methods. All are tried, any one returning success is sufficient. # At least one must be configured. # ACL specifies who can do what. If the match section of an entry matches the # request, the set of allowed actions will be applied to the token request # and a ticket will be issued only for those of the requested actions that are # allowed by the rule. # * It is possible to match on user's name ("account"), subject type ("type") # and name ("name"; for type=repository this is the image name). # * Matches are evaluated as shell file name patterns ("globs") by default, # so "foobar", "f??bar", "f*bar" are all valid. For even more flexibility # match patterns can be evaluated as regexes by enclosing them in //, e.g. # "/(foo|bar)/". # * IP match can be single IP address or a subnet in the "prefix/mask" notation. # * ACL is evaluated in the order it is defined until a match is found. # Rules below the first match are not evaluated, so you'll need to put more # specific rules above more broad ones. # * Empty match clause matches anything, it only makes sense at the end of the # list and can be used as a way of specifying default permissions. # * Empty actions set means "deny everything". Thus, a rule with `actions: []` # is in effect a "deny" rule. # * A special set consisting of a single "*" action means "allow everything". # * If no match is found the default is to deny the request. # # You can use the following variables from the ticket request in any field: # * ${account} - the account name, currently the same as authenticated user's name. # * ${service} - the service name, specified by auth.token.service in the registry config. # * ${type} - the type of the entity, normally "repository". # * ${name} - the name of the repository (i.e. image), e.g. centos. # * ${labels:<LABEL>} - tests all values in the list of lables:<LABEL> for the user. Refer to the labels doc for details acl: - match: {ip: "127.0.0.0/8"} actions: ["*"] comment: "Allow everything from localhost (IPv4)" - match: {ip: "::1"} actions: ["*"] comment: "Allow everything from localhost (IPv6)" - match: {ip: "172.17.0.1"} actions: ["*"] comment: "Allow everything from the local Docker bridge address" - match: {account: "admin"} actions: ["*"] comment: "Admin has full access to everything." - match: {account: "test", name: "test-*"} actions: ["*"] comment: "User \"test\" has full access to test-* images but nothing else. (1)" - match: {account: "test"} actions: [] comment: "User \"test\" has full access to test-* images but nothing else. (2)" - match: {account: "/.+/", name: "${account}/*"} actions: ["*"] comment: "Logged in users have full access to images that are in their 'namespace'" - match: {account: "/.+/", type: "registry", name: "catalog"} actions: ["*"] comment: "Logged in users can query the catalog." - match: {account: "/.+/"} actions: ["pull"] comment: "Logged in users can pull all images." - match: {account: "", name: "hello-world"} actions: ["pull"] comment: "Anonymous users can pull \"hello-world\"." - match: {account: "/^(.+)@test.com$/", name: "${account:1}/*"} actions: [] comment: "Emit domain part of account to make it a correct repo name" - match: {labels: {"group": "VIP"}} actions: ["push"] comment: "Users assigned to group 'VIP' is able to push" - match: {labels: {"group": "/trainee|dev/"}} actions: ["push", "pull"] comment: "Users assigned to group 'trainee' and 'dev' is able to push and pull" - match: {name: "${labels:group}-shared/*"} actions: ["push", "pull"] comment: "Users can push to the shared namespace of any group they are in" - match: {name: "${labels:project}/*"} actions: ["push", "pull"] comment: "Users can push to any project they are assigned to" - match: {name: "${labels:project}-{labels:tier}/*"} actions: ["push", "pull"] comment: "Users can push to a project-tier/* that they are assigned to" - match: {labels: {"title": "Developer"}} actions: ["*"] comment: "If you call yourself a developer you can do anything (this ACL is an example for LDAP labels as defined above)" - match: {labels: {"groups": "Admin"}} actions: ["push"] comment: "If you are part of the admin group you can push. (this ACL is an example for LDAP labels as defined above)" # Access is denied by default. # (optional) Define to query ACL from a MongoDB server. acl_mongo: # Essentially all options are described here: https://godoc.org/gopkg.in/mgo.v2#DialInfo dial_info: # The MongoDB hostnames or IPs to connect to. addrs: ["localhost"] # The time to wait for a server to respond when first connecting and on # follow up operations in the session. If timeout is zero, the call may # block forever waiting for a connection to be established. # (See https://golang.org/pkg/time/#ParseDuration for a format description.) timeout: "10s" # Database name that will be used on the MongoDB server. database: "docker_auth" # The username with which to connect to the MongoDB server. username: "" # Path to the text file with the password in it. password_file: "" # Enable TLS connection to MongoDB (only enable this if your server supports it) enable_tls: false # Name of the collection in which ACLs will be stored in MongoDB. collection: "acl" # Specify how long an ACL remains valid before they will be fetched again from # the MongoDB server. # (See https://golang.org/pkg/time/#ParseDuration for a format description.) cache_ttl: "1m" # External authorization - call an external progam to authorize user. # JSON of authz.AuthRequestInfo is passed to command's stdin and exit code is examined. # 0 - allow, 1 - deny, other - error. ext_authz: command: "/usr/local/bin/my_authz" # Can be a relative path too; $PATH works. args: ["--flag", "--more", "--flags"] |