【问题标题】:Nginx proxy pass to reverse proxyNginx 代理传递给反向代理
【发布时间】:2023-03-24 10:17:01
【问题描述】:

我对 nginx 还很陌生,坚持使用当前配置。

我还检查了ssl - nginx does redirectnginx as proxy for web appnginx proxy_passnginx proxy rewriteanother post related to my question

我还查看了其他一些目前对我没有帮助的帖子。我没有阅读关于主题 nginxproxy 的大约 21500 条帖子。

Google 也未能将我引导至解决方案。

当前设置是:

[CMS (Plone in LAN)]<--->[Reverse-Proxy (Apache / http://oldsite.foo)]

这是旧网站设置。基本上我们需要重新设计 CMS。但它已经成长为至少有两个开发人员(他们从未见过彼此)的大量依赖项和自行编写的模块。将其正确更换将是仅一年的任务。 Apache 配置中也有一些奇怪的东西,所以我们现在不能避免使用 Apache。

很遗憾,我们需要尽快进行光学重新设计。

因此我们萌生了在 Nginx 中使用 Diazo/XSLT 重新设计旧网站并向我们的评估人员展示一些结果的想法。

因此我尝试以下设置:

[Plone]<--->[Apache]<--->[Proxy (XSLT in Nginx / https://newsite.foo)]

这是我的xslt_for_oldsite 配置文件(Cache-Control 仅用于调试):

add_header Cache-Control no-cache;

server {
  server_name newsite.foo;
  server_tokens off;

  listen b.b.b.b:80;

  return 301 https://$server_name$request_uri;

  access_log /var/log/nginx/newsite.port80.access.log;
  error_log /var/log/nginx/newsite.port80.error.log;
}

server {
  server_name newsite.foo;
  server_tokens off;

  listen b.b.b.b:443 ssl;

  access_log /var/log/nginx/newsite.port443.access.log;
  error_log /var/log/nginx/newsite.port443.error.log;

  ssl_certificate /etc/ssl/certs/nginx.crt;
  ssl_certificate_key /etc/ssl/private/nginx.key;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
  ssl_ciphers HIGH:!aNULL:!MD5:!ADH:!AECDH;
  ssl_session_cache shared:SSL:5m;

  proxy_http_version 1.1;

  #proxy_set_header X-Forwarded-Host $host:$server_port;
  #proxy_set_header X-Forwarded-Server $host;
  #proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

#  proxy_set_header Connection "";
#  proxy_ignore_headers Expires;

#  proxy_set_header X-Real-IP $remote_addr;
#  proxy_set_header X-forwarded-host $host;

  sub_filter_types *;
  sub_filter_once off;
  sub_filter "http://oldsite.foo" "https://newsite.foo";

  location / {
    proxy_pass http://oldsite.foo/;
    proxy_redirect off;
    #proxy_redirect http://oldsite.foo/ https://newsite.foo/;
    proxy_set_header Host $host;
  }
}

如果我启动浏览器以连接到http://oldsite.foo,那么它会加载:

  • 来自旧网站的 1 个 HTML 文档
  • 来自旧网站的 3 个 CSS 文件
  • 来自旧站点的 9 个 JS 文件
  • 来自旧网站的 10 个图形文件

但是如果我使用我的浏览器获取https://newsite.foo 然后它会加载:

  • 来自新闻网站的 1 个 HTML 文档
  • oldsite 中只有 5 个图形文件(来自我的浏览器的直接请求)
  • 其他一切都不见了

虽然使用wget https://newsite.foo -o index.html 收到的 HTML 文档的所有链接都已修改为 https://newsite.foo(正确地将 http://oldsite.foo 替换为 https://newsite.foo),但浏览器会显示所有未修改的链接:http://oldsite.foo 而不是 https://newsite.foo

我得到以下带有curl -I https://newsite.foo 的服务器标头:

HTTP/1.1 200 OK
Server: nginx
Date: Fri, 11 Sep 2020 10:28:15 GMT
Content-Type: text/html
Connection: keep-alive
Accept-Ranges: none
Accept-Ranges: bytes
X-Varnish: 1216306480
Age: 0
Via: 1.1 varnish
Set-Cookie: I18N_LANGUAGE="de"; Path=/
Via: 1.1 oldsite.foo
Vary: Accept-Encoding
Cache-Control: no-cache

我玩过add_headerproxy_set_headerproxy_redirect。我也试过了

location ~* .* {
  proxy_pass http://oldsite.foo$request_uri;
  proxy_redirect off;
  proxy_set_header Host $host;
}

但我的任何更改都没有改变 nginx 的行为,它将 GET 请求重定向到 http://oldsite.foo 并显示答案,就好像它们来自 https://newsite.foo 一样。

我对这些问题没有答案:

  • 为什么我的浏览器一直连接到http://oldsite.foo?它应该连接到https://newsite.foo
  • 为什么wget 的版本和我的浏览器的 HTML 中的链接不同?
  • 为什么超过一半的网站没有通过https://newsite.foo到达浏览器?
  • 我该如何解决这个问题?

有没有人可以指出我正确的方向?

提前致谢。至少感谢您阅读我的帖子。

最好的问候。

【问题讨论】:

    标签: ssl nginx redirect proxy


    【解决方案1】:

    同时我找到了解决方案。

    Apache 发送了 gzip 压缩的数据,但 sub_filter 无法处理(请参阅 official documentation: sub_filter)。

    确实,我试图通过使用proxy_set_header Accept-Encoding ""; 来避免这种情况,但它不起作用。 原因是这部分必须设置在location context中。

    因此,在撰写本文时(2020-09-15),Ubuntu 20.04 LTS、Nginx 1.14.0 的正确配置是:

    ...
    server {
      server_name newsite.foo;
      server_tokens off;
      
      listen b.b.b.b:443 ssl;
    
      access_log /var/log/nginx/newsite.port443.access.log;
      error_log /var/log/nginx/newsite.port443.error.log;
    
      ssl_certificate /etc/ssl/certs/nginx.crt;
      ssl_certificate_key /etc/ssl/private/nginx.key;
    
      # Double check and modify this part BEFORE using in production:
      ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
      ssl_ciphers HIGH:!aNULL:!MD5:!ADH:!AECDH;
      ssl_session_cache shared:SSL:5m;
    
    location / {
      proxy_http_version 1.1;
      proxy_set_header Accept-Encoding "";  # MUST be written HERE in this context!
      proxy_set_header Host $http_host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_pass http://oldsite.foo;
      proxy_redirect off;
      sub_filter_types text/html text/css text/javascript;  # If unsure you may use '*'
      sub_filter_once off;
      sub_filter http://oldsite.foo https://newsite.foo;
    }
    ...
    

    感谢adrianTNT 为我指出了关键部分(见the missing detail)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-28
      • 1970-01-01
      • 2011-08-09
      • 2013-02-18
      相关资源
      最近更新 更多