11

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?

Jake Edwards
  • 267
  • 1
  • 2
  • 9

2 Answers2

6

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/;
}
Xavier Lucas
  • 13,095
  • 2
  • 44
  • 50
  • 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 :( – Jake Edwards Mar 28 '15 at 00:03
  • I've added info about the proxy_set_header which was in another conf. Removing the host line does change things -- redirects to https://127.0.0.1:9000/users/sign_in – Jake Edwards Mar 28 '15 at 00:38
  • 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. – Xavier Lucas Mar 28 '15 at 00:53
  • 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-5ec1aeb4604cbfbeff836f956308b0ed.js – Jake Edwards Mar 28 '15 at 01:08
  • 1
    @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. – Xavier Lucas Mar 28 '15 at 01:13
  • Hmm, seems that's what is affecting OpenWRT too -- . Is there any way to proxy the response body with nginx? I imagine there is no native way to do that then. – Jake Edwards Mar 28 '15 at 01:15
  • @ShadowXVII Well, there's no a *clean* way to do it in nginx. You can use the [`sub`](http://nginx.org/en/docs/http/ngx_http_sub_module.html) 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. – Xavier Lucas Mar 28 '15 at 01:17
  • 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`. – j-i-l Dec 28 '15 at 11:34
0

What @XavierLucas says is correct the backed should handle the links. The gitlab documentation has a guide under the heading Install GitLab under a relative URL. I ran into this problem recently while setting up an arch linux server with gitlab and nginx installed and this resolved my problem by recompiling all assets to have the correct relative path.

womble
  • 96,255
  • 29
  • 175
  • 230
Gun
  • 1
  • 3