docker-registry-ui
docker-registry-ui copied to clipboard
Registry authentication only for pushing and deleting images
Is it possible to set up registry authentication in such a way where pulling images does not require any authentication but pushing and deleting images requires valid credentials? I have the following Nginx configuration where I try to limit the auth_basic
to everything except for GET
requests.
/etc/nginx/conf.d/default.conf
server {
listen 443 ssl;
server_name registry.kemptech.net;
root /usr/share/nginx/html;
ssl_certificate /etc/nginx/conf.d/domain.crt;
ssl_certificate_key /etc/nginx/conf.d/domain.key;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
client_max_body_size 0;
chunked_transfer_encoding on;
location /v2/ {
if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) {
return 404;
}
limit_except GET {
auth_basic "Registry realm";
auth_basic_user_file /etc/nginx/auth/.htpasswd;
}
proxy_pass http://registry:5000;
proxy_set_header Host $http_host; # required for docker client's sake
proxy_set_header X-Real-IP $remote_addr; # pass on real client's IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 900;
}
}
server {
listen 80;
location / {
return 301 https://$host$request_uri;
}
}
Pulling images with docker pull
works as expected, i.e. without any authentication.
$ docker pull localhost/alpine:3.12
3.12: Pulling from alpine
Digest: sha256:a9c28c813336ece5bb98b36af5b66209ed777a394f4f856c6e62267790883820
Status: Image is up to date for localhost/alpine:3.12
localhost/alpine:3.12
Deleting images from the UI also works as expected. I get prompted for credentials and the image is deleted only when a valid username and password is provided (the one from the .htaccess
file).
The problem seems to be with pushing images with docker push
. It is failing with authentication error even after a successful docker login localhost
command.
$ docker push localhost/alpine:3.12
The push refers to repository [localhost/alpine]
32f366d666a5: Layer already exists
unauthorized: authentication required
I tried limit_except GET HEAD
too but the same issue is seen.
Logs from the registry and UI when doing a docker push
registry_1 | time="2021-05-05T08:09:20.2269273Z" level=info msg="response completed" go.version=go1.11.2 http.request.host=registry.kemptech.net http.request.id=c925e1fa-7fd7-4340-9886-ed3665db41e4 http.request.method=GET http.request.remoteaddr=172.20.0.1 http.request.uri="/v2/" http.request.useragent="docker/20.10.5 go/go1.13.15 git-commit/363e9a8 kernel/4.19.84-microsoft-standard os/linux arch/amd64 UpstreamClient(Docker-Client/20.10.5 \(windows\))" http.response.contenttype="application/json; charset=utf-8" http.response.duration=1.1056ms http.response.status=200 http.response.written=2
ui_1 | 172.20.0.1 - - [05/May/2021:08:09:20 +0000] "GET /v2/ HTTP/1.1" 200 2 "-" "docker/20.10.5 go/go1.13.15 git-commit/363e9a8 kernel/4.19.84-microsoft-standard os/linux arch/amd64 UpstreamClient(Docker-Client/20.10.5 \x5C(windows\x5C))" "-"
registry_1 | 172.20.0.3 - - [05/May/2021:08:09:20 +0000] "GET /v2/ HTTP/1.0" 200 2 "" "docker/20.10.5 go/go1.13.15 git-commit/363e9a8 kernel/4.19.84-microsoft-standard os/linux arch/amd64 UpstreamClient(Docker-Client/20.10.5 \\(windows\\))"
ui_1 | 172.20.0.1 - - [05/May/2021:08:09:20 +0000] "HEAD /v2/alpine/blobs/sha256:339de151aab4bc06eed8409daae147c408478cb538dacb90cc63f19ad4eba80b HTTP/1.1" 200 0 "-" "docker/20.10.5 go/go1.13.15 git-commit/363e9a8 kernel/4.19.84-microsoft-standard os/linux arch/amd64 UpstreamClient(Docker-Client/20.10.5 \x5C(windows\x5C))" "-"
registry_1 | 172.20.0.3 - - [05/May/2021:08:09:20 +0000] "HEAD /v2/alpine/blobs/sha256:339de151aab4bc06eed8409daae147c408478cb538dacb90cc63f19ad4eba80b HTTP/1.0" 200 0 "" "docker/20.10.5 go/go1.13.15 git-commit/363e9a8 kernel/4.19.84-microsoft-standard os/linux arch/amd64 UpstreamClient(Docker-Client/20.10.5 \\(windows\\))"
registry_1 | time="2021-05-05T08:09:20.2736337Z" level=info msg="response completed" go.version=go1.11.2 http.request.host=registry.kemptech.net http.request.id=4405b63d-3d7e-466f-93a9-ac891cf71037 http.request.method=HEAD http.request.remoteaddr=172.20.0.1 http.request.uri="/v2/alpine/blobs/sha256:339de151aab4bc06eed8409daae147c408478cb538dacb90cc63f19ad4eba80b" http.request.useragent="docker/20.10.5 go/go1.13.15 git-commit/363e9a8 kernel/4.19.84-microsoft-standard os/linux arch/amd64 UpstreamClient(Docker-Client/20.10.5 \(windows\))" http.response.contenttype="application/octet-stream" http.response.duration=1.4251ms http.response.status=200 http.response.written=0
registry_1 | time="2021-05-05T08:09:20.2821575Z" level=info msg="response completed" go.version=go1.11.2 http.request.host=registry.kemptech.net http.request.id=06d27277-2a26-4581-afb9-984e38ca350f http.request.method=HEAD http.request.remoteaddr=172.20.0.1 http.request.uri="/v2/alpine/blobs/sha256:13621d1b12d4d0d4ad6699d220cd46f26764a9daf26a95f792ab2ce0715df366" http.request.useragent="docker/20.10.5 go/go1.13.15 git-commit/363e9a8 kernel/4.19.84-microsoft-standard os/linux arch/amd64 UpstreamClient(Docker-Client/20.10.5 \(windows\))" http.response.contenttype="application/octet-stream" http.response.duration=1.3505ms http.response.status=200 http.response.written=0
registry_1 | 172.20.0.3 - - [05/May/2021:08:09:20 +0000] "HEAD /v2/alpine/blobs/sha256:13621d1b12d4d0d4ad6699d220cd46f26764a9daf26a95f792ab2ce0715df366 HTTP/1.0" 200 0 "" "docker/20.10.5 go/go1.13.15 git-commit/363e9a8 kernel/4.19.84-microsoft-standard os/linux arch/amd64 UpstreamClient(Docker-Client/20.10.5 \\(windows\\))"
ui_1 | 172.20.0.1 - - [05/May/2021:08:09:20 +0000] "HEAD /v2/alpine/blobs/sha256:13621d1b12d4d0d4ad6699d220cd46f26764a9daf26a95f792ab2ce0715df366 HTTP/1.1" 200 0 "-" "docker/20.10.5 go/go1.13.15 git-commit/363e9a8 kernel/4.19.84-microsoft-standard os/linux arch/amd64 UpstreamClient(Docker-Client/20.10.5 \x5C(windows\x5C))" "-"
ui_1 | 172.20.0.1 - - [05/May/2021:08:09:20 +0000] "PUT /v2/alpine/manifests/3.12 HTTP/1.1" 401 179 "-" "docker/20.10.5 go/go1.13.15 git-commit/363e9a8 kernel/4.19.84-microsoft-standard os/linux arch/amd64 UpstreamClient(Docker-Client/20.10.5 \x5C(windows\x5C))" "-"
Looks like the PUT
request from UI is returning a 401 error.
When I remove the limit_except
from the Nginx config then docker push
works with valid credentials but authentication is also required for docker pull
which I do not want.
Hi there, thank you for your issue.
I tried your example and I'm facing the same issue.
I think what you want to do is impossible or complicated. To know if it should connect or not, docker engine makes a first GET
request on /v2
. If the response is 401 it will try to your credentials.
That means, for a PULL or PUSH, it will always do a GET request on /v2 first...
Maybe you can try keycloak auth, it uses scopes on every requests, maybe we can configure it ?
Hi, I close this issue due to inactivity.