我正在尝试将我的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>
...
要是这样的话,
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;
}
但是当我获取内容时,我总是会得到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"
请注意链接:https://dev.goout.net/i/user/606456_001_min.jpg -可以正常工作。在我看来,它仍然无法与SSL连接。我还尝试将上游部分定义为:
upstream backend {
server dev.goout.net:443;
}
但是没有效果。
请注意,该服务器位于CloudFlare网关后面,我希望它不会阻止正确的连接,但是我想这在apache中也不起作用。
答案 0 :(得分:1)
tl; dr:根据http://nginx.org/r/proxy_ssl_server_name,nginx中SNI默认为关闭,但是Cloudflare要求SNI。
在Cloudflare之上放置自制代理通常不是最好的主意-相反,应该相反。
但是,您忽略的是发出诸如curl -v localhost:3227/i/user/606456_001_min.jpg
之类的请求所产生的实际错误消息-当然,它与TLS相关:
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"
这是因为nginx并不是真正旨在通过proxy_pass
来窃取他人站点,因此,Cloudflare确实需要的某些功能默认情况下在nginx中已关闭,以用于一般用途;具体来说,就是SNI, Server Name Indication extension to TLS,在这里与众不同。
根据http://nginx.org/r/proxy_ssl_server_name,在您的确切配置中添加额外的 proxy_ssl_server_name on;
确实可以解决该问题(我已经对此进行了测试-可以正常工作)-请注意,这要求nginx 1.7.0或更高版本。
+ proxy_ssl_server_name on; # SNI is off by default
此外,请注意,您还必须确保在运行时更新域名解析,因为默认情况下,只有在加载或重新加载配置时才能解析该域名。您可以使用trick,在http://nginx.org/r/proxy_pass中使用变量来使其适当地更新主机的分辨率,但这还需要您使用http://nginx.org/r/resolver指令来指定服务器用于DNS解析(在运行时,加载配置后),因此,您的MVP为:
location /i/ {
resolver 1dot1dot1dot1.cloudflare-dns.com.;
proxy_ssl_server_name on; # SNI is off by default
proxy_pass https://dev.goout.net:443$request_uri;
}
答案 1 :(得分:-2)
如果要通过主机名而不是IP指定上游服务器,则必须为Nginx定义resolver
指令以进行DNS查找。
dev.goout.net是否在其他远程计算机上?
您的proxy_ssl_certificate
和proxy_ssl_certificate_key
指令在哪里?这种连接不仅可以保护自己。