WWW-Authenticate Bearer realm different than host #12004

Closed
opened 2025-11-02 09:54:10 -06:00 by GiteaMirror · 17 comments
Owner

Originally created by @demom on GitHub (Nov 14, 2023).

Description

I have Gitea setup on a local server due to not willing to publish it to the internet. I have Gitea Actions setup, building containers that publish to Giteas container repository.

No problems there.

The issue comes when using servers not on the local network. So what I want to do is to SSH into the servers with a RemoteForward for the gitea host mapping dev.company.int port 443 to 127.0.0.1 port 10443 on the external server (port 443 is occupied by a web server) I'm deploying the containers to (using Podman, not Docker) and pull an image. I have also added dev.company.int in the external server host file, pointing to 127.0.0.1.

But I'm running into problems, and after a lot of troubleshooting it's because Podman - when unauthorized and trying to get a token - uses the WWW-Authenticate response from Gitea to do this.

And Gitea is using the ROOT_URL setting to compose the WWW-Authenticate response, not the requested host. And to make things clear: Podman is not in fault here, the client SHALL use the www-authenticate response header.

Below is an excerpt from debugging the podman client, and I have marked the relevant lines in the excerpt:

...
DEBU[0000] No credentials matching dev.company.int:10443/company/project found in /root/.dockercfg
DEBU[0000] No credentials for dev.company.int:10443/company/project found
DEBU[0000] No signature storage configuration found for dev.company.int:10443/company/project:latest, using built-in default file:///var/lib/containers/sigstore
DEBU[0000] Looking for TLS certificates and private keys in /etc/docker/certs.d/dev.company.int:10443
DEBU[0000] crt: /etc/docker/certs.d/dev.company.int:10443/ca.crt
DEBU[0000] GET https://dev.company.int:10443/v2/
DEBU[0000] Ping https://dev.company.int:10443/v2/ status 401
DEBU[0000] GET https://dev.company.int/v2/token?scope=repository%3company%2Fproject%3Apull&service=container_registry
DEBU[0000] Accessing "dev.company.int:10443/company/project:latest" failed: Get "https://dev.company.int/v2/token?scope=repository%3Acompany%2Fproject%3Apull&service=container_registry": tls: failed to verify certificate: x509: certificate is valid for xxxxxxxxxxxxxxxx.traefik.default, not dev.company.int
...

Also, here is a curl from dev.company.int, showing the response header:

  • [HTTP/2] [1] OPENED stream for https://dev.company.int:10443/v2/
  • [HTTP/2] [1] [:method: GET]
  • [HTTP/2] [1] [:scheme: https]
  • [HTTP/2] [1] [:authority: dev.company.int:10443]
  • [HTTP/2] [1] [:path: /v2/]
  • [HTTP/2] [1] [user-agent: curl/8.4.0]
  • [HTTP/2] [1] [accept: /]

GET /v2/ HTTP/2
Host: dev.company.int:10443
User-Agent: curl/8.4.0
Accept: /

< HTTP/2 401
< content-type: application/json
< date: Mon, 13 Nov 2023 14:58:56 GMT
< docker-distribution-api-version: registry/2.0
< www-authenticate: Bearer realm="https://dev.company.int/v2/token",service="container_registry",scope="*"
< content-length: 50

So, my primary question is: is this a bug? Is there some kind of setting to allow Gitea to reply with request host instead of ROOT_URL as base for bearer realm?

Gitea Version

1.19.1

Can you reproduce the bug on the Gitea demo site?

No

Log Gist

No response

Screenshots

No response

Git Version

No response

Operating System

Ubuntu

How are you running Gitea?

I'm running Gitea as a container in Podman using the docker.io/gitea/gitea:latest image.

Database

MySQL/MariaDB

Originally created by @demom on GitHub (Nov 14, 2023). ### Description I have Gitea setup on a local server due to not willing to publish it to the internet. I have Gitea Actions setup, building containers that publish to Giteas container repository. No problems there. The issue comes when using servers not on the local network. So what I want to do is to SSH into the servers with a RemoteForward for the gitea host mapping dev.company.int port 443 to 127.0.0.1 port 10443 on the external server (port 443 is occupied by a web server) I'm deploying the containers to (using Podman, not Docker) and pull an image. I have also added dev.company.int in the external server host file, pointing to 127.0.0.1. But I'm running into problems, and after a lot of troubleshooting it's because Podman - when unauthorized and trying to get a token - uses the WWW-Authenticate response from Gitea to do this. And Gitea is using the ROOT_URL setting to compose the WWW-Authenticate response, not the requested host. And to make things clear: Podman is not in fault here, the client SHALL use the www-authenticate response header. _Below is an excerpt from debugging the podman client, and I have marked the relevant lines in the excerpt:_ ... DEBU[0000] No credentials matching dev.company.int:10443/company/project found in /root/.dockercfg DEBU[0000] No credentials for dev.company.int:10443/company/project found DEBU[0000] No signature storage configuration found for dev.company.int:10443/company/project:latest, using built-in default file:///var/lib/containers/sigstore DEBU[0000] Looking for TLS certificates and private keys in /etc/docker/certs.d/dev.company.int:10443 DEBU[0000] crt: /etc/docker/certs.d/dev.company.int:10443/ca.crt DEBU[0000] GET https://dev.company.int:10443/v2/ DEBU[0000] Ping **https://dev.company.int:10443/v2/ status 401** DEBU[0000] GET **https://dev.company.int/v2/token?scope=repository%3company%2Fproject%3Apull&service=container_registry** DEBU[0000] Accessing "dev.company.int:10443/company/project:latest" failed: Get "https://dev.company.int/v2/token?scope=repository%3Acompany%2Fproject%3Apull&service=container_registry": tls: failed to verify certificate: x509: certificate is valid for xxxxxxxxxxxxxxxx.traefik.default, not dev.company.int ... _Also, here is a curl from dev.company.int, showing the response header:_ * [HTTP/2] [1] OPENED stream for https://dev.company.int:10443/v2/ * [HTTP/2] [1] [:method: GET] * [HTTP/2] [1] [:scheme: https] * [HTTP/2] [1] [:authority: dev.company.int:10443] * [HTTP/2] [1] [:path: /v2/] * [HTTP/2] [1] [user-agent: curl/8.4.0] * [HTTP/2] [1] [accept: */*] > GET /v2/ HTTP/2 > Host: dev.company.int:10443 > User-Agent: curl/8.4.0 > Accept: */* > < HTTP/2 401 < content-type: application/json < date: Mon, 13 Nov 2023 14:58:56 GMT < docker-distribution-api-version: registry/2.0 < www-authenticate: Bearer realm="https://dev.company.int/v2/token",service="container_registry",scope="*" < content-length: 50 So, my primary question is: is this a bug? Is there some kind of setting to allow Gitea to reply with request host instead of ROOT_URL as base for bearer realm? ### Gitea Version 1.19.1 ### Can you reproduce the bug on the Gitea demo site? No ### Log Gist _No response_ ### Screenshots _No response_ ### Git Version _No response_ ### Operating System Ubuntu ### How are you running Gitea? I'm running Gitea as a container in Podman using the docker.io/gitea/gitea:latest image. ### Database MySQL/MariaDB
GiteaMirror added the type/proposal label 2025-11-02 09:54:10 -06:00
Author
Owner

@KN4CK3R commented on GitHub (Nov 14, 2023):

Isn't every other displayed url wrong too? (clone url, ...)

@KN4CK3R commented on GitHub (Nov 14, 2023): Isn't every other displayed url wrong too? (clone url, ...)
Author
Owner

@demom commented on GitHub (Nov 15, 2023):

@KN4CK3R Normally I access Gitea via the correct ROOT_URL host, this is only for pulling containers from Gitea container repository.

Personally I think that forcing/rewriting to ROOT_URL is generally a bad idea, it's better to use the request host since the server knows that the client managed to establish a connection.

Or make ROOT_URL an array (for example Nextcloud to it this way), don't rewrite but only allow if request host is any of the accepted ROOT_URL:s.

@demom commented on GitHub (Nov 15, 2023): @KN4CK3R Normally I access Gitea via the correct ROOT_URL host, this is only for pulling containers from Gitea container repository. Personally I think that forcing/rewriting to ROOT_URL is generally a bad idea, it's better to use the request host since the server knows that the client managed to establish a connection. Or make ROOT_URL an array (for example Nextcloud to it this way), don't rewrite but only allow if request host is any of the accepted ROOT_URL:s.
Author
Owner

@KN4CK3R commented on GitHub (Nov 15, 2023):

It's a possible duplicate of #19345
The problem here is you configure Gitea with url A and expect it to handle it correctly with url B. That's just not supported at the moment.

@KN4CK3R commented on GitHub (Nov 15, 2023): It's a possible duplicate of #19345 The problem here is you configure Gitea with url A and expect it to handle it correctly with url B. That's just not supported at the moment.
Author
Owner

@wxiaoguang commented on GitHub (May 7, 2024):

This could be fixed by Refactor AppURL usage #30885 , and it will be backported to 1.22

@wxiaoguang commented on GitHub (May 7, 2024): This could be fixed by Refactor AppURL usage #30885 , and it will be backported to 1.22
Author
Owner

@avber commented on GitHub (Jun 7, 2024):

I'm using a custom HTTPS port with the following config

ROOT_URL = https://domain.com:8443/gitea/

The app is working fine on https://domain.com:8443/gitea,
container registry response from https://domain.com:8443/gitea
is as expected

{
    "errors": [
        {
            "code": "UNAUTHORIZED",
            "message": ""
        }
    ]
}

However, docker login doesn't work. I guess it's due to invalid realm

Bearer realm="https://domain.com/gitea/v2/token",service="container_registry",scope="*"
@avber commented on GitHub (Jun 7, 2024): I'm using a custom HTTPS port with the following config ROOT_URL = https://domain.com:8443/gitea/ The app is working fine on https://domain.com:8443/gitea, container registry response from https://domain.com:8443/gitea is as expected ``` { "errors": [ { "code": "UNAUTHORIZED", "message": "" } ] } ``` However, docker login doesn't work. I guess it's due to invalid realm ``` Bearer realm="https://domain.com/gitea/v2/token",service="container_registry",scope="*" ```
Author
Owner

@wxiaoguang commented on GitHub (Jun 7, 2024):

What does the admin panel -> self check page say?

What's your reverse proxy config? Maybe you should pass "domain.com:8443" as Host header to Gitea.

@wxiaoguang commented on GitHub (Jun 7, 2024): What does the admin panel -> self check page say? What's your reverse proxy config? Maybe you should pass "domain.com:8443" as `Host` header to Gitea.
Author
Owner

@avber commented on GitHub (Jun 7, 2024):

admin panel -> self check page says no problem after passing "domain.com:8443" as Host header to Gitea

However, realm is still invalid

Bearer realm="https://domain.com:8443/gitea/v2/token",service="container_registry",scope="*"

Nginx config was taken from https://docs.gitea.com/administration/reverse-proxies#nginx-with-a-sub-path

@avber commented on GitHub (Jun 7, 2024): admin panel -> self check page says no problem after passing "domain.com:8443" as Host header to Gitea However, realm is still invalid Bearer realm="https://domain.com:8443/gitea/v2/token",service="container_registry",scope="*" Nginx config was taken from https://docs.gitea.com/administration/reverse-proxies#nginx-with-a-sub-path
Author
Owner

@wxiaoguang commented on GitHub (Jun 7, 2024):

However, realm is still invalid

Hmm, the problem is "sub-path" now. See the reverse proxy document: the container registry doesn't support sub-path. So you could only use https://domain.com:8443/ for docker login.

@wxiaoguang commented on GitHub (Jun 7, 2024): > However, realm is still invalid Hmm, the problem is "sub-path" now. See the reverse proxy document: the container registry doesn't support sub-path. So you could only use `https://domain.com:8443/` for docker login.
Author
Owner

@avber commented on GitHub (Jun 7, 2024):

Yes, I'm using

docker login domain.com:8443

and getting the message

INFO[0000] Error logging in to endpoint, trying next endpoint error="Get "https://domain.com:8443/v2/"

My guess it's due to invalid realm (the gitea sub-path shouldn't be there)

[https://domain.com:8443/gitea/v2/token]

@avber commented on GitHub (Jun 7, 2024): Yes, I'm using docker login domain.com:8443 and getting the message INFO[0000] Error logging in to endpoint, trying next endpoint error="Get \"https://domain.com:8443/v2/\" My guess it's due to invalid realm (the gitea sub-path shouldn't be there) [https://domain.com:8443/gitea/v2/token]
Author
Owner

@wxiaoguang commented on GitHub (Jun 7, 2024):

My guess it's due to invalid realm (the gitea sub-path shouldn't be there)

[https://domain.com:8443/gitea/v2/token]

The sub-path is there for a long time ... actually it doesn't look right to me but I didn't touch it because I don't know whehter it really causes problem

image

Maybe it is the time to fix it. Will propose a new PR.

@wxiaoguang commented on GitHub (Jun 7, 2024): > My guess it's due to invalid realm (the gitea sub-path shouldn't be there) > > [https://domain.com:8443/gitea/v2/token] The sub-path is there for a long time ... actually it doesn't look right to me but I didn't touch it because I don't know whehter it really causes problem ![image](https://github.com/go-gitea/gitea/assets/2114189/57dd1ed7-78ec-45c5-86a8-5fe02b1baa6e) Maybe it is the time to fix it. Will propose a new PR.
Author
Owner

@avber commented on GitHub (Jun 7, 2024):

Thank you

@avber commented on GitHub (Jun 7, 2024): Thank you
Author
Owner

@KN4CK3R commented on GitHub (Jun 7, 2024):

The sub-path is there for a long time ...

What do you mean?

@KN4CK3R commented on GitHub (Jun 7, 2024): > The sub-path is there for a long time ... What do you mean?
Author
Owner

@wxiaoguang commented on GitHub (Jun 7, 2024):

The sub-path is there for a long time ...

What do you mean?

Since Add Package Registry (#16510) : ctx.Resp.Header().Add("WWW-Authenticate", `Bearer realm="`+setting.AppURL+`v2/token"`), the sub-path is in the realm, because AppURL contains the sub-path.

@wxiaoguang commented on GitHub (Jun 7, 2024): > > The sub-path is there for a long time ... > > What do you mean? Since Add Package Registry (#16510) : ``ctx.Resp.Header().Add("WWW-Authenticate", `Bearer realm="`+setting.AppURL+`v2/token"`)``, the sub-path is in the realm, because `AppURL` contains the sub-path.
Author
Owner

@avber commented on GitHub (Jun 7, 2024):

What if REGISTRY_ROOT_URL setting is introduced?

If it's set, get the url from it. Otherwise, call the existing code.

@avber commented on GitHub (Jun 7, 2024): What if REGISTRY_ROOT_URL setting is introduced? If it's set, get the url from it. Otherwise, call the existing code.
Author
Owner

@wxiaoguang commented on GitHub (Jun 7, 2024):

-> Remove sub-path from container registry realm #31293

@wxiaoguang commented on GitHub (Jun 7, 2024): -> Remove sub-path from container registry realm #31293
Author
Owner

@wxiaoguang commented on GitHub (Jun 9, 2024):

What if REGISTRY_ROOT_URL setting is introduced?

If it's set, get the url from it. Otherwise, call the existing code.

Introducing new config options might be an approach, but I think we should avoid doing so, because there are many cases that Gitea needs to know the real full URL, not only "package registry", but also "actions artifact" and more, there will be a lot.

@wxiaoguang commented on GitHub (Jun 9, 2024): > What if REGISTRY_ROOT_URL setting is introduced? > > If it's set, get the url from it. Otherwise, call the existing code. Introducing new config options might be an approach, but I think we should avoid doing so, because there are many cases that Gitea needs to know the real full URL, not only "package registry", but also "actions artifact" and more, there will be a lot.
Author
Owner

@wxiaoguang commented on GitHub (Jun 11, 2024):

The 1.22-nightly build is ready (which will be 1.22.1 soon), could you try it?

@wxiaoguang commented on GitHub (Jun 11, 2024): The 1.22-nightly build is ready (which will be 1.22.1 soon), could you try it?
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/gitea#12004