nginx proxy_pass rewrite of response header location
Add a trailing slash to your proxy_pass
target.
Update : The OP didn't precise the vhost was accepting https
. As the scheme is forwarded to the backend server with additionnal headers, then an issue occurs since proxy_redirect default;
orders nginx to expect http scheme by default when rewriting Location
headers in upstream replies, instead of https.
So, this had to be changed explicitely to a more generic form (the trailing slash is still necessary) :
location /gitlab/ {
proxy_pass http://127.0.0.1:9000/;
proxy_redirect $scheme://$host:$server_port/ /gitlab/;
}
Related videos on Youtube
hackncrack
Avid programmer & gamer. Allegiances PC Android
Updated on September 18, 2022Comments
-
hackncrack over 1 year
The aim of this nginx instance is to get GitLab and OpenWRT Luci to redirect through a reverse proxy. It's already working for several other websites, all which have a base url which seems to counter this issue.
- GitLab in this example is on the local server at port 9000.
- The nginx website is on port 8080.
- OpenWRT has the exact same issue, but with /cgi-bin/luci/
The relevant nginx config for the example location is;
location /gitlab/ { proxy_pass http://127.0.0.1:9000/; proxy_redirect default; }
- Note that the results are the same with and without a trailing slash.
There are some header proxy configuration options being applied to this location.
# Timeout if the real server is dead proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; # Basic Proxy Config proxy_set_header Host $host:$server_port; proxy_set_header Origin $scheme://$host:$server_port; proxy_set_header Connection $http_connection; proxy_set_header Cookie $http_cookie; proxy_set_header Upgrade $http_upgrade; proxy_set_header X-Forwarded-Protocol $scheme; proxy_set_header X-Scheme $scheme; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Ssl on; proxy_set_header X-Frame-Options SAMEORIGIN; # Advanced Proxy Config send_timeout 5m; proxy_read_timeout 300; proxy_send_timeout 300; proxy_connect_timeout 300; proxy_buffers 32 4k; proxy_buffer_size 4k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; proxy_http_version 1.1; proxy_cache_bypass $cookie_session; proxy_no_cache $cookie_session;]
- Commenting out #proxy_set_header Host instead redirects the browser to
https://127.0.0.1:9000/users/sign_in
When browsing to
https://website.com:8080/gitlab/
;GET /gitlab/ HTTP/1.1 Host: website.com:8080
The response incorrectly goes back to
/users/sign_in
instead of/gitlab/users/sign_in
HTTP/1.1 302 Found Cache-Control: no-cache Connection: keep-alive Content-Type: text/html; charset=utf-8 Location: https://website.com:8080/users/sign_in
Browsing manually to https://website:8080/gitlab/users/sign_in loads the page, but no assets as they fall until the same issue as above.
Reading nginx docs, it suggests that the default proxy behaviour should handle this scenario, though it seems to fail.
The logs don't seem to show much.
What additional steps should be taken to help diagnose why this might be happening?
-
hackncrack about 9 yearsHi Xavier, thanks for the reply. No luck there. That's one of the things I've be tried (matching the proxy_pass docs) but no change :(
-
hackncrack about 9 yearsI've added info about the proxy_set_header which was in another conf. Removing the host line does change things -- redirects to 127.0.0.1:9000/users/sign_in
-
Xavier Lucas about 9 yearsOk so the issue is the
scheme
(https) withproxy_redirect default
behaviour which expect http. Let the configuration as it was before commenting out the Host header and changeproxy_redirect
content to$scheme://$host:$server_port/ /gitlab/;
. Make sure you are not hitting browser cached headers (use cli tools or private navigation) when testing. -
hackncrack about 9 yearsOkay, cool, so it now heads to the right URL (at least GitLab does, OpenWRT still goes to /cgi-bin/luci -- one at a time though). Don't have any assets/images/etc however -- :8080/assets/application-5ec1aeb4604cbfbeff836f956308b0ed.js instead of :8080/gitlab/assets/application-5ec1aeb4604cbfbeff836f956308b0ed.js
-
Xavier Lucas about 9 years@ShadowXVII Assets links are generated by your application, you must change it there. Nginx will only rewrite redirects issued by your app, not page contents.
-
hackncrack about 9 yearsHmm, seems that's what is affecting OpenWRT too -- <meta http-equiv="refresh" content="0; URL=/cgi-bin/luci" />. Is there any way to proxy the response body with nginx? I imagine there is no native way to do that then.
-
Xavier Lucas about 9 years@ShadowXVII Well, there's no a clean way to do it in nginx. You can use the
sub
module to rewrite replies body but that should be handled by your backend since it will bring a performance hit that you should measure. Also, this module is not built-in by default and you will need to recompile nginx by hand. -
jojo over 8 yearswas having the same issue but @XavierLucas didn't seem to work at first. Well actually it did, just had to
sudo gitlab-rake cache:clear
.