'Docker Registry Authentication/Authorization - signed by untrusted key with ID
Honestly, it this point im begging for help
So im trying to add protection for my docker registry ( i do not wanna use htpassword ) which is run like this:
docker compose file
version: '3'
services:
registry:
restart: always
image: registry:2
ports:
- "5000:5000"
environment:
REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
REGISTRY_HTTP_ADDR: 127.0.0.1:5000
REGISTRY_AUTH: token
REGISTRY_AUTH_TOKEN_REALM: http://api.thechemicalworkshop.com/api/authorize_docker
REGISTRY_AUTH_TOKEN_ISSUER: "The Chemical Workshop"
REGISTRY_AUTH_TOKEN_SERVICE: "dockerhub.thechemicalworkshop.com"
REGISTRY_AUTH_TOKEN_ROOTCERTBUNDLE: /ssl/cert.dockerhub.crt
volumes:
- ./data:/data
- ./ssl:/ssl
network_mode: host
how it should work is that REGISTRY_AUTH_TOKEN_REALM handles the protection i tired self signed cetfiticates in REGISTRY_AUTH_TOKEN_ROOTCERTBUNDLE but same result (more below)
im using nginx as reverse proxy and ssl (should be self explanatory) (and the reason why i host it on localhost)
server {
client_max_body_size 2000m;
proxy_pass_request_headers on;
server_name dockerhub.thechemicalworkshop.com;
location / {
# Do not allow connections from docker 1.5 and earlier
# docker pre-1.6.0 did not properly set the user agent on ping, catch "Go *" user agents
if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) {
return 404;
}
proxy_pass http://127.0.0.1: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;
proxy_pass_request_headers on;
}
listen [::]:443 ssl; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/dockerhub.thechemicalworkshop.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/dockerhub.thechemicalworkshop.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
anyways every time i access the registry on server_name it should call REGISTRY_AUTH_TOKEN_REALM to accept/deny
the REGISTRY_AUTH_TOKEN_REALM on stuff is an API in python (quart) with following script:
raw_token = 'eyJ0eXAiOiJKV1Q'
if matti_check(request.headers["X-Real-Ip"]):
payload = {"expires_in": 360000,"issued_at": "2022-04-30T15:33:00Z"}
payload['token'] = raw_token
response = await make_response(payload)
return response
else:
print(request.headers)
return "ERROR", 500
token shortened due to space
ignore matti_check() it works fine basically im returning a token alongside some other stuff
to generate the token im using following script:
encoded = jwt.encode(\
{\
"iss": "The Chemical Workshop", \
"aud": "dockerhub.thechemicalworkshop.com",\
"exp": 1687927320000\
}, \
private_key, algorithm="RS256", headers={"kid": "MY4D:MNRW:GY2T:IZBS:HAZT:QZRS:MQ4G:IMBX:GA4D:AYJY:GBST:AMJX"})
print(encoded)
the kid header gets generated by me like this:
- first I convert the cerificate using
openssl x509 -in cert.dockerhub.crt -noout -outform der -pubkey - I take the key and I sha256 it, for testing I use https://emn178.github.io/online-tools/sha256.html
- in the third step I take the first 30 characters and base32 encode it, again using https://emn178.github.io/online-tools/base32_encode.html for testing
- then I whack
:between every 4 characters
Docker documentation says i should do this to get kid:
Take the DER encoded public key which the JWT token was signed against.
Create a SHA256 hash out of it and truncate to 240bits.
Split the result into 12 base32 encoded groups with : as delimiter.
so I think my approach is correct?
well, it does not work :/
I just get an error docker-registry-registry-1 | time="2022-04-30T17:10:56.438672709Z" level=info msg="token signed by untrusted key with ID: "MY4T:KNRU:GJSW:ENRU:GFRW:CYZW:GNRW:CMLC:GVTG:KM3D:MRSW:CZTD""
Could someone ( i dont know go ) look into portus/docker registry source how they generate a working key?
here is what i tried:
- asking on docker forum <-- more info
- asking on lowendtalk
- asking on like 8 discords
- trying self signed keys, as well as certbot keys
- create github issue/ask questions (no anwsers/solutions)
- ask some random dude from this project on twitter (no anwser)
- googling, trying to read go code (no luck/anwsers)
- trying different keys (same result)
- creating a "bounty" (5$ if you ask, im broke) on fiverr (no capable people or way way overbudget)
Can you guys fix this or give me some lead on how to fix this? my "project" would be opensource as i dont see an implementation in python
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
