nginx proxy_pass rewrite of response header location

49,432

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/;
}
Share:
49,432

Related videos on Youtube

hackncrack
Author by

hackncrack

Avid programmer & gamer. Allegiances PC Android

Updated on September 18, 2022

Comments

  • hackncrack
    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.

    GitLab Asset Fail

    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
    hackncrack about 9 years
    Hi 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
    hackncrack about 9 years
    I'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
    Xavier Lucas about 9 years
    Ok so the issue is the scheme (https) with proxy_redirect default behaviour which expect http. Let the configuration as it was before commenting out the Host header and change proxy_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
    hackncrack about 9 years
    Okay, 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-5ec1aeb4604cbfbeff836f956308‌​b0ed.js
  • Xavier Lucas
    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
    hackncrack about 9 years
    Hmm, 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
    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
    jojo over 8 years
    was 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.