gerrit proxyed by nginx only works if "hosted" on top level directory

Viewed 828

I'm having a super weird issue. I'm trying to use nginx to wrap gerrit in SSL/HTTPS, and it's only working if I let dev.company.com/ point to gerrit (I'd prefer dev.company.com/gerrit/ as the web server should also host other services.)

This is the only working solution I've been able to find.

gerrit's etc/gerrit.config:

[gerrit]
    canonicalWebUrl = https://dev.company.com/
[httpd]
    listenUrl = proxy-https://127.0.0.1:8081/
(snip)

nginx's configuration in sites-available:

server {
  listen 443 ssl;
  server_name dev.company.com;

  ssl on;
  (ssl certificates blah blah)

  location / {
    proxy_pass        http://127.0.0.1:8081;
    proxy_set_header  X-Forwarded-For $remote_addr;
    proxy_set_header  Host $host;
  }
}

If I change to the following:

gerrit.config:

[gerrit]
    canonicalWebUrl = https://dev.company.com/gerrit/
[httpd]
    listenUrl = proxy-https://127.0.0.1:8081/
(snip)

nginx config:

server {
  listen 443 ssl;
  server_name dev.company.com;

  ssl on;
  (ssl certificates blah blah)

  location /gerrit/ {
    proxy_pass        http://127.0.0.1:8081/;
    proxy_set_header  X-Forwarded-For $remote_addr;
    proxy_set_header  Host $host;
  }
}

(Note the trailing slash on the proxy_pass.)

Things work except requests with escaped characters (such as %2F, which gerrit has a lot of.) So, gerrit, as a site, will halfway work.

I feel that this answer should lead in the right direction, but I simply couldn't get things to work.

Edit: I think this discussion hits the same bug.

2 Answers

It is only about configuration of correct context path (/gerrit in your case).

Please try:

gerrit.conf:

[gerrit]
    canonicalWebUrl = https://dev.company.com/gerrit/
[httpd]
    listenUrl = proxy-https://127.0.0.1:8081/gerrit/

listenUrl also allows to configure context path - https://gerrit-review.googlesource.com/Documentation/config-gerrit.html#httpd.listenUrl

nginx config:

server {
  listen 443 ssl;
  server_name dev.company.com;

  ssl on;
  (ssl certificates blah blah)

  location /gerrit/ {
    proxy_pass        http://127.0.0.1:8081/gerrit/;
    proxy_set_header  X-Forwarded-For $remote_addr;
    proxy_set_header  Host $host;
  }
}

Edit:

Try this proxypass to avoid decoding:

proxy_pass    http://127.0.0.1:8081/gerrit$request_uri;

The last discussion you link, https://groups.google.com/forum/#!topic/repo-discuss/iSHHa4krRLo, actually does contain a resolution:

However, for the record, I give a try to nginx with a proxy_pass directive without /gerrit and it worked.

This is because you should not be using a trailing slash, or any other path specification within proxy_pass, as per https://stackoverflow.com/a/49702013, that you and they both reference, in order to avoid the path from being normalised and decoded.


gerrit.config:

[gerrit]
    canonicalWebUrl = https://dev.example.com/gerrit/
[httpd]
    listenUrl = proxy-https://127.0.0.1:8081/gerrit/

nginx.conf:

server {
  listen 443;
  server_name dev.example.com;

  ssl  on;
  ssl_certificate      conf/server.crt;
  ssl_certificate_key  conf/server.key;

  location ^~ /gerrit/ {
    proxy_pass        http://127.0.0.1:8081;
    proxy_set_header  X-Forwarded-For $remote_addr;
    proxy_set_header  Host $host;
  }
}

This whole thing is really straight out of https://gerrit-review.googlesource.com/Documentation/config-reverseproxy.html, TBH.

It would seem that a trailing /gerrit/ in httpd.listenUrl, and a lack of trailing / in proxy_pass, are the changes you need to make to your config for things to work properly.

The issue you're having with escaped characters being decoded is, indeed, described over at https://stackoverflow.com/a/49702013, and is precisely due to the trailing slash in proxy_pass that you were using without a good reason.

Related