【问题标题】:gerrit proxyed by nginx only works if "hosted" on top level directory由 nginx 代理的 gerrit 仅在“托管”在顶级目录上时才有效
【发布时间】:2019-06-27 12:05:38
【问题描述】:

我遇到了一个非常奇怪的问题。我正在尝试使用 nginx 将 gerrit 包装在 SSL/HTTPS 中,并且只有当我让 dev.company.com/ 指向 gerrit 时它才有效(我更喜欢 dev.company.com/gerrit/,因为 Web 服务器也应该托管其他服务。)

这是我能找到的唯一可行的解​​决方案。

gerrit 的 etc/gerrit.config:

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

nginx在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;
  }
}

如果我更改为以下内容:

gerrit.config:

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

nginx 配置:

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;
  }
}

(注意 proxy_pass 的尾部斜杠。)

除了带有转义字符的请求(例如 %2F,gerrit 有很多)之外,其他东西都可以工作。因此,gerrit 作为一个站点,将工作一半。

我觉得this answer 应该朝着正确的方向前进,但我根本无法让事情发挥作用。

编辑:我认为this 讨论遇到了同样的错误。

【问题讨论】:

    标签: ssl nginx gerrit


    【解决方案1】:

    你链接的最后一个讨论,https://groups.google.com/forum/#!topic/repo-discuss/iSHHa4krRLo,实际上确实包含一个决议:

    但是,作为记录,我尝试使用不带 /gerrit 的 proxy_pass 指令对 nginx 进行尝试,并且成功了。

    这是因为您不应该在 proxy_pass 中使用尾随斜杠或任何其他路径规范,根据 https://stackoverflow.com/a/49702013,您和他们都引用,以避免路径被规范化和解码。


    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;
      }
    }
    

    这整件事真的是直接来自https://gerrit-review.googlesource.com/Documentation/config-reverseproxy.html,TBH。

    看起来httpd.listenUrl 中的尾随/gerrit/ 和proxy_pass 中缺少尾随/ 是您需要对配置进行更改才能正常工作。

    您在解码转义字符时遇到的问题确实在https://stackoverflow.com/a/49702013 中进行了描述,并且正是由于您在没有充分理由的情况下使用了proxy_pass 中的斜杠。

    【讨论】:

    • 有效!我想我之前已经尝试过您的设置,但是某些内容被缓存在 chrome 中,这会导致重定向循环和一个非常奇怪的 404,其中“未找到”是唯一发送的文本。 (从来没有弄清楚这是由 nginx 还是 Gerrit 发送的。)该站点以隐身方式工作,因此清除缓存(可能还有 cookie)似乎可以解决问题。再次感谢!
    【解决方案2】:

    这只是关于正确配置context path(在您的情况下为/gerrit)。

    请尝试:

    gerrit.conf:

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

    listenUrl 还允许配置上下文路径 - 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;
      }
    }
    

    编辑:

    试试这个proxypass 以避免解码:

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

    【讨论】:

    • 感谢您的回答,Jan Garaj。通过您的设置,一切正常,除了其中包含转义字符的 URL(在 Gerrit 中有很多)。这导致网站上出现大量 404,类似于我在 Google Groups 讨论的链接中所经历的问题。使其工作的唯一方法是确保 nginx 配置中 proxy_pass 指令中的端口号之后没有任何内容。
    • 再次感谢 Jan Garaj,我尝试了一些 $request_uri 技巧的变体,但无法成功,这并不是说它没有。
    猜你喜欢
    • 2021-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-26
    • 1970-01-01
    • 1970-01-01
    • 2012-01-17
    相关资源
    最近更新 更多