Reverse Proxy, IIS, X-Forwarded-Proto/X-Forwarded-Host/Host Header localhost / 127.0.0.1 URLs instead of ROOT_URL #14123

Closed
opened 2025-11-02 11:03:38 -06:00 by GiteaMirror · 7 comments
Owner

Originally created by @jannikjordan on GitHub (Feb 11, 2025).

Description

Avatar urls and default merge commit message in javascript content returns localhost url with the http_port port
ROOT_URL and LOCAL_ROOT_URL are set hardcoded and not built up with variables like in (https://docs.gitea.com/administration/config-cheat-sheet) because I dont use PROTOCOL in the config, its running localhost on http 8081 and the reverse proxy redirects to gitea

Tried following changes to the app.ini [server] section
https://github.com/go-gitea/gitea/issues/3361#issuecomment-432817286

why is the javascript responding with the 127.0.0.1:8081 url if ROOT_URL ald LOCAL_ROOT_URL have a value?

Gitea Version

1.23.3

Can you reproduce the bug on the Gitea demo site?

No

Log Gist

No response

Screenshots

Image
Image
Image
Image
Image

Git Version

2.47.0

Operating System

Windows Server 2019

How are you running Gitea?

NT Service in gMSA Usercontext
running on localhost:8081

IIS Reverse Proxy which rewrites the headers
iis server variables
HTTP_X_FORWARDED_FOR = {HTTP_X_FORWARDED_FOR}
HTTP_X_REAL_IP = {HTTP_X_FORWARDED_FOR}
HTTP_X_FORWARDED_PROTO = https
HTTP_X_FORWARDED_HOST = {HTTP_HOST}
HTTP_X_FORWARDED_SCHEME = https
HTTP_HOST = {HTTP_HOST}

app.ini for url settings
[server]
HTTP_ADDR = 127.0.0.1
HTTP_PORT = 8081

DOMAIN = mydomain.de
ROOT_URL = https://mydomain.de
LOCAL_ROOT_URL = https://mydomain.de

Database

MSSQL

Originally created by @jannikjordan on GitHub (Feb 11, 2025). ### Description Avatar urls and default merge commit message in javascript content returns localhost url with the http_port port ROOT_URL and LOCAL_ROOT_URL are set hardcoded and not built up with variables like in (https://docs.gitea.com/administration/config-cheat-sheet) because I dont use PROTOCOL in the config, its running localhost on http 8081 and the reverse proxy redirects to gitea Tried following changes to the app.ini [server] section https://github.com/go-gitea/gitea/issues/3361#issuecomment-432817286 why is the javascript responding with the 127.0.0.1:8081 url if ROOT_URL ald LOCAL_ROOT_URL have a value? ### Gitea Version 1.23.3 ### Can you reproduce the bug on the Gitea demo site? No ### Log Gist _No response_ ### Screenshots ![Image](https://github.com/user-attachments/assets/537c79b9-6ce3-408c-a700-be22dd91390d) ![Image](https://github.com/user-attachments/assets/5b1cdcc2-20f5-4b6a-8da4-50900030d21c) ![Image](https://github.com/user-attachments/assets/b8fad268-a6ef-4a3b-b370-004d15307f60) ![Image](https://github.com/user-attachments/assets/e6ee5c33-6237-4dd9-87b5-20c04f8c88f3) ![Image](https://github.com/user-attachments/assets/54878c27-891a-4d07-9121-1c4c44dc4e66) ### Git Version 2.47.0 ### Operating System Windows Server 2019 ### How are you running Gitea? NT Service in gMSA Usercontext running on localhost:8081 IIS Reverse Proxy which rewrites the headers iis server variables HTTP_X_FORWARDED_FOR = {HTTP_X_FORWARDED_FOR} HTTP_X_REAL_IP = {HTTP_X_FORWARDED_FOR} HTTP_X_FORWARDED_PROTO = https HTTP_X_FORWARDED_HOST = {HTTP_HOST} HTTP_X_FORWARDED_SCHEME = https HTTP_HOST = {HTTP_HOST} app.ini for url settings [server] HTTP_ADDR = 127.0.0.1 HTTP_PORT = 8081 DOMAIN = mydomain.de ROOT_URL = https://mydomain.de LOCAL_ROOT_URL = https://mydomain.de ### Database MSSQL
GiteaMirror added the type/bugissue/needs-feedback labels 2025-11-02 11:03:38 -06:00
Author
Owner

@jannikjordan commented on GitHub (Feb 11, 2025):

Found the function MakeAbsoluteURL in source code 06f1065636/modules/httplib/url.go (L91)

And GuessCurrentHostURL which guesses the hostname if X-Forwarded-Proto/Host Headers are not set correctly
06f1065636/modules/httplib/url.go (L61)

I started a debug powershell http server to display all sent headers, switched the proxy pass route to another localhost port in iis to check if header rewrite works as it should

Also idenfitfied the function getRequestScheme(req) which checks for headers X-Forwarded-Proto, X-Forwarded-Protocol, X-Url-Scheme
06f1065636/modules/httplib/url.go (L36)

"X-Forwarded-Proto": "https"
"X-Forwarded-Host": "git.mydomain.de"
"X-FORWARDED-PROTOCOL": "https"
"X-URL-SCHEME": "https"

But default merge commit message and avatar urls keep the localhost url with https scheme https://127.0.0.1:8081/

I didn't archive to replace directly the Host Header yet, for gitea it is 127.0.0.1:8081, but the Forwarded-Host and Forwarded-Proto Headers are set correctly.
I manipulated the local hosts file in windows to pass the proxy to git.mydomain.de:8081

127.0.0.1 git.mydomain.de

And now I get the result of https://git.mydomain.de:8081 from the MakeAbsoluteURL function. But that's still wrong, because the Port is just an internal of this machine, not public accessible. So even if I get it running changing the Host Header (which I did with the ghettofix of local hosts file), it would not correct the generated result of MakeAbsoluteURL function.
Any other thoughts here?

@jannikjordan commented on GitHub (Feb 11, 2025): Found the function MakeAbsoluteURL in source code https://github.com/go-gitea/gitea/blob/06f10656369c7e4274ae4e9f9edb21e1cac520d9/modules/httplib/url.go#L91 And GuessCurrentHostURL which guesses the hostname if X-Forwarded-Proto/Host Headers are not set correctly https://github.com/go-gitea/gitea/blob/06f10656369c7e4274ae4e9f9edb21e1cac520d9/modules/httplib/url.go#L61 I started a debug powershell http server to display all sent headers, switched the proxy pass route to another localhost port in iis to check if header rewrite works as it should Also idenfitfied the function getRequestScheme(req) which checks for headers X-Forwarded-Proto, X-Forwarded-Protocol, X-Url-Scheme https://github.com/go-gitea/gitea/blob/06f10656369c7e4274ae4e9f9edb21e1cac520d9/modules/httplib/url.go#L36 "X-Forwarded-Proto": "https" "X-Forwarded-Host": "git.mydomain.de" "X-FORWARDED-PROTOCOL": "https" "X-URL-SCHEME": "https" But default merge commit message and avatar urls keep the localhost url with https scheme https://127.0.0.1:8081/ I didn't archive to replace directly the Host Header yet, for gitea it is 127.0.0.1:8081, but the Forwarded-Host and Forwarded-Proto Headers are set correctly. I manipulated the local hosts file in windows to pass the proxy to git.mydomain.de:8081 `127.0.0.1 git.mydomain.de` And now I get the result of https://git.mydomain.de:8081 from the MakeAbsoluteURL function. But that's still wrong, because the Port is just an internal of this machine, not public accessible. So even if I get it running changing the Host Header (which I did with the ghettofix of local hosts file), it would not correct the generated result of MakeAbsoluteURL function. Any other thoughts here?
Author
Owner

@wxiaoguang commented on GitHub (Feb 12, 2025):

Please follow the official config:

https://docs.gitea.com/next/administration/reverse-proxies

4. Make sure Host and X-Fowarded-Proto headers are correctly passed to Gitea to make Gitea see the real URL being visited.
@wxiaoguang commented on GitHub (Feb 12, 2025): Please follow the official config: https://docs.gitea.com/next/administration/reverse-proxies ``` 4. Make sure Host and X-Fowarded-Proto headers are correctly passed to Gitea to make Gitea see the real URL being visited. ```
Author
Owner

@jannikjordan commented on GitHub (Feb 12, 2025):

Please follow the official config:

https://docs.gitea.com/next/administration/reverse-proxies

4. Make sure Host and X-Fowarded-Proto headers are correctly passed to Gitea to make Gitea see the real URL being visited.

Yes, i will reconfigure the iis today to pass the correct Host Header to Gitea. Didn't know that url rewrite module can't rewrite HTTP_HOST Variable on iis.
I'm using the default iis web.config from the guide you've mentioned. But that configuration is not passing the Host header either.

https://stackoverflow.com/questions/64722495/how-to-force-iis-to-use-a-specific-value-for-the-http-host-header-during-a-rewri

But X-Forwarded-Host and X-Forwarded-Proto is passed correctly.

Wouldn’t it be a better way to use req.Header.Get("X-Forwarded-Host") fist and fall back to req.Host if X-Forwarded-Host does not exist in the httplib function GuessCurrentHostURL?

@jannikjordan commented on GitHub (Feb 12, 2025): > Please follow the official config: > > https://docs.gitea.com/next/administration/reverse-proxies > > > ``` > 4. Make sure Host and X-Fowarded-Proto headers are correctly passed to Gitea to make Gitea see the real URL being visited. > ``` Yes, i will reconfigure the iis today to pass the correct Host Header to Gitea. Didn't know that url rewrite module can't rewrite HTTP_HOST Variable on iis. I'm using the default iis web.config from the guide you've mentioned. But that configuration is not passing the Host header either. https://stackoverflow.com/questions/64722495/how-to-force-iis-to-use-a-specific-value-for-the-http-host-header-during-a-rewri But X-Forwarded-Host and X-Forwarded-Proto is passed correctly. Wouldn’t it be a better way to use req.Header.Get("X-Forwarded-Host") fist and fall back to req.Host if X-Forwarded-Host does not exist in the httplib function GuessCurrentHostURL?
Author
Owner

@wxiaoguang commented on GitHub (Feb 12, 2025):

Wouldn’t it be a better way to use req.Header.Get("X-Forwarded-Host") fist and fall back to req.Host if X-Forwarded-Host does not exist in the httplib function GuessCurrentHostURL?

It is commented:

06f1065636/modules/httplib/url.go (L80-L81)

@wxiaoguang commented on GitHub (Feb 12, 2025): > Wouldn’t it be a better way to use req.Header.Get("X-Forwarded-Host") fist and fall back to req.Host if X-Forwarded-Host does not exist in the httplib function GuessCurrentHostURL? It is commented: https://github.com/go-gitea/gitea/blob/06f10656369c7e4274ae4e9f9edb21e1cac520d9/modules/httplib/url.go#L80-L81
Author
Owner

@jannikjordan commented on GitHub (Feb 12, 2025):

Wouldn’t it be a better way to use req.Header.Get("X-Forwarded-Host") fist and fall back to req.Host if X-Forwarded-Host does not exist in the httplib function GuessCurrentHostURL?

It is commented:

06f1065636/modules/httplib/url.go (L80-L81)

And here is the comment for the feature which lets the admin via config decide how to guess the current host url:

06f1065636/modules/httplib/url.go (L75)

Would be a great feature.

@jannikjordan commented on GitHub (Feb 12, 2025): > > Wouldn’t it be a better way to use req.Header.Get("X-Forwarded-Host") fist and fall back to req.Host if X-Forwarded-Host does not exist in the httplib function GuessCurrentHostURL? > > It is commented: > > https://github.com/go-gitea/gitea/blob/06f10656369c7e4274ae4e9f9edb21e1cac520d9/modules/httplib/url.go#L80-L81 And here is the comment for the feature which lets the admin via config decide how to guess the current host url: https://github.com/go-gitea/gitea/blob/06f10656369c7e4274ae4e9f9edb21e1cac520d9/modules/httplib/url.go#L75 Would be a great feature.
Author
Owner

@wxiaoguang commented on GitHub (Feb 12, 2025):

ps: actually if you use a reverse proxy and only use one domain, you could simply remove all these headers, and make Gitea only use "ROOT_URL".

These headers are for multiple-domain support, for example: some users would like to use https://external.git.com and https://internal.git.com at the same time.

@wxiaoguang commented on GitHub (Feb 12, 2025): ps: actually if you use a reverse proxy and only use one domain, you could simply remove all these headers, and make Gitea only use "ROOT_URL". These headers are for multiple-domain support, for example: some users would like to use `https://external.git.com` and `https://internal.git.com` at the same time.
Author
Owner

@jannikjordan commented on GitHub (Feb 12, 2025):

ps: actually if you use a reverse proxy and only use one domain, you could simply remove all these headers, and make Gitea only use "ROOT_URL".

These headers are for multiple-domain support, for example: some users would like to use https://external.git.com and https://internal.git.com at the same time.

Ye same thought. Went from bed to computer to test it.
I was passing the X-Forwarded-Proto=https hardcode header, which results in the problem that GuessCurrentHostURL gets a scheme other than ""
06f1065636/modules/httplib/url.go (L36-L54)

Only if scheme == "", the function would use the appurl (ROOT_URL i guess), but since I get anything (tried setting X-Forwarded-Proto="empty"), GuessCurrentHostURL will use Host Header (Found no way to fully remove the header via iis url rewrite module)
06f1065636/modules/httplib/url.go (L61-L83)

For my situation its my own fault cuz I have 2nd reverse proxy (security gateway) infront of the iis which actually passes the correct Host Header to the iis, otherwise routing in iis wouldn't work, but it also sets the X-Forwarded-Proto header.

Since that the only way is to pass correct Host Header from IIS to Gitea by configuring "system.webServer/proxy/preserveHostHeader = True" in the IIS Computer/Host Configuration (not Site Configuration, if anyone else who is reading this is looking for the correct location)

Image

Configured, everything works and /-/admin/self_check doesn't cry anymore cuz gitea sees localhost url which is not the same als ROOT_URL.
Learned a lot, thanks for your time and especially for the last comment.

@jannikjordan commented on GitHub (Feb 12, 2025): > ps: actually if you use a reverse proxy and only use one domain, you could simply remove all these headers, and make Gitea only use "ROOT_URL". > > These headers are for multiple-domain support, for example: some users would like to use `https://external.git.com` and `https://internal.git.com` at the same time. Ye same thought. Went from bed to computer to test it. I was passing the X-Forwarded-Proto=https hardcode header, which results in the problem that GuessCurrentHostURL gets a scheme other than "" https://github.com/go-gitea/gitea/blob/06f10656369c7e4274ae4e9f9edb21e1cac520d9/modules/httplib/url.go#L36-L54 Only if scheme == "", the function would use the appurl (ROOT_URL i guess), but since I get anything (tried setting X-Forwarded-Proto="empty"), GuessCurrentHostURL will use Host Header (Found no way to fully remove the header via iis url rewrite module) https://github.com/go-gitea/gitea/blob/06f10656369c7e4274ae4e9f9edb21e1cac520d9/modules/httplib/url.go#L61-L83 For my situation its my own fault cuz I have 2nd reverse proxy (security gateway) infront of the iis which actually passes the correct Host Header to the iis, otherwise routing in iis wouldn't work, but it also sets the X-Forwarded-Proto header. Since that the only way is to pass correct Host Header from IIS to Gitea by configuring "system.webServer/proxy/preserveHostHeader = True" in the IIS Computer/Host Configuration (not Site Configuration, if anyone else who is reading this is looking for the correct location) ![Image](https://github.com/user-attachments/assets/4eb5d689-4baf-4916-a257-afb93ae5216a) Configured, everything works and /-/admin/self_check doesn't cry anymore cuz gitea sees localhost url which is not the same als ROOT_URL. Learned a lot, thanks for your time and especially for the last comment.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/gitea#14123