Nginx vs Apache代理传递

Voj*_*ěch 5 nginx

我试图将我的apache配置转换为nginx.对于apache,我有以下内容:

<VirtualHost *:443>
    ServerName loc.goout.net
    <Location />
        ProxyPass http://localhost:8080/ retry=0
        ProxyPreserveHost On
    </Location>
    <Location /i/>
        ProxyPass https://dev.goout.net/i/ retry=0
        ProxyPreserveHost Off
    </Location>
    ...
Run Code Online (Sandbox Code Playgroud)

像这样,如果我取:

https://loc.goout.net/i/user/606456_001_min.jpg

它正确地从以下内容获取内容:

https://dev.goout.net/i/user/606456_001_min.jpg

所以对于nginx我正在尝试这个:

server {
    listen                  443 ssl;
    server_name             loc.goout.net;

    proxy_buffering         off;
    proxy_ssl_session_reuse off;

    proxy_redirect              off;
    proxy_set_header            Host            dev.goout.net;

    location /i/ {
        proxy_pass          https://dev.goout.net:443;
    }
Run Code Online (Sandbox Code Playgroud)

但是当我获取内容时,我将永远得到502.

在nginx日志中,我看到以下内容:

[error] 7#7: *5 no live upstreams while connecting to upstream, client: 127.0.0.1, server: loc.goout.net, request: "GET /i/user/606456_001_min.jpg HTTP/1.1", upstream: "https://dev.goout.net/i/user/606456_001_min.jpg", host: "loc.goout.net"
Run Code Online (Sandbox Code Playgroud)

请注意链接:https://dev.goout.net/i/user/606456_001_min.jpg - 它可以正常工作.在我看来,它仍然没有与SSL连接.我还尝试将上游部分定义为:

upstream backend {
    server dev.goout.net:443;
}
Run Code Online (Sandbox Code Playgroud)

但它没有效果.

注意服务器是CloudFlare网关的后面,我希望它不会阻止正确的连接,但我想这也不会在apache中起作用.

cns*_*nst 1

tl;dr:根据http://nginx.org/r/proxy_ssl_server_name ,SNI 在 nginx 中默认处于关闭状态,但 Cloudflare 需要这样做。

\n\n
\n\n

在 Cloudflare \xe2\x80\x94 之上使用自制代理通常不是最好的主意,它应该是相反的。

\n\n\n\n

但是,您忽略的是发出像curl -v localhost:3227/i/user/606456_001_min.jpg\xe2\x80\x94 这样的请求所导致的实际错误消息,当然它与 TLS 相关:

\n\n

2018/07/07 23:18:39 [error] 33345#33345: *3 SSL_do_handshake() failed (SSL: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure) while SSL handshaking to upstream, client: 127.0.0.1, server: loc.goout.net, request: "GET /i/user/606456_001_min.jpg HTTP/1.1", upstream: "https://[2400:cb00:2048:1::6818:7303]:443/i/user/606456_001_min.jpg", host: "localhost:3227"

\n\n

这是因为 nginx 并不是真的要用于通过 窃取别人的网站proxy_pass,因此,Cloudflare 确实需要的一些功能在 nginx 中默认关闭以供一般使用;具体来说,是 SNI (服务器名称指示对 TLS 的扩展)造成了差异。

\n\n

根据http://nginx.org/r/proxy_ssl_server_name,在您的确切配置中添加额外内容确实proxy_ssl_server_name on;可以解决问题(我自己测试过它 \xe2\x80\x94 它有效) \xe2\x80\x94 请注意这需要 nginx 1.7.0 或更高版本。

\n\n
+   proxy_ssl_server_name   on;     # SNI is off by default\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

此外,请注意,您还必须确保域名解析在运行时得到更新,因为默认情况下,只有在加载或重新加载配置时才会解析;您可以使用在http://nginx.org/r/proxy_pass中使用变量的技巧来使其适当地更新主机的分辨率,但这也要求您使用http://nginx.org/ r/解析器指令指定用于 DNS 解析的服务器(在运行时期间,加载配置后),因此,您的 MVP 将是:

\n\n
location /i/ {\n    resolver                1dot1dot1dot1.cloudflare-dns.com.;\n    proxy_ssl_server_name   on;     # SNI is off by default\n    proxy_pass              https://dev.goout.net:443$request_uri;\n}\n
Run Code Online (Sandbox Code Playgroud)\n