参考:​​https://www.cnblogs.com/guanshan/p/guan2022-7-26_001.html​

​https://blog.csdn.net/weixin_41560737/article/details/123287073​

​https://www.jianshu.com/p/cd813d68ed25​

由于工作需要访问​​https://tpay.test.95516.com​​ 进行测试,而内网服务器禁止访问互联网,须通过代理或者NAT实现访问。

该域名在外网通过域名能正常访问,但是解析成IP就无法访问(该站点使用了nginx)。

为什么正向代理处理HTTPS流量需要特殊处理
作为反向代理时,代理服务器通常终结 (terminate) HTTPS加密流量,再转发给后端实例。HTTPS流量的加解密和认证过程发生在客户端和反向代理服务器之间。

而作为正向代理在处理客户端发过来的流量时,HTTP加密封装在了TLS/SSL中,代理服务器无法看到客户端请求URL中想要访问的域名,如下图。所以代理HTTPS流量,相比于HTTP,需要做一些特殊处理。

nginx代理访问互联网https有两种方式:

一、HTTP CONNECT隧道 (7层解决方案)

1.客户端给代理服务器发送HTTP CONNECT请求。

2.代理服务器利用HTTP CONNECT请求中的主机和端口与目的服务器建立TCP连接。

3.代理服务器给客户端返回HTTP 200响应。

4.客户端和代理服务器建立起HTTP CONNECT隧道,HTTPS流量到达代理服务器后,直接通过TCP透传给远端目的服务器。代理服务器的角色是透传HTTPS流量,并不需要解密HTTPS。

​阿里的@chobits提供了ngx_http_proxy_connect_module模块,来支持HTTP CONNECT方法,从而让NGINX可以扩展为正向代理。

二、NGINX stream (4层解决方案)

ngx_stream_ssl_preread_module模块

要在不解密的情况下拿到HTTPS流量访问的域名,只有利用TLS/SSL握手的第一个Client Hello报文中的扩展地址SNI (Server Name Indication)来获取。NGINX官方从1.11.5版本开始支持利用ngx_stream_ssl_preread_module模块来获得这个能力,模块主要用于获取Client Hello报文中的SNI和ALPN信息。对于4层正向代理来说,从Client Hello报文中提取SNI的能力是至关重要的,否则NGINX stream的解决方案无法成立。同时这也带来了一个限制,要求所有客户端都需要在TLS/SSL握手中带上SNI字段,否则NGINX stream代理完全没办法知道客户端需要访问的目的域名。

三、外网https通过代理转成http

在​​ngx_http_proxy_module​模块的​proxy_pass​指令需要在location段加上请求头proxy_set_header

nginx之正向代理访问互联网_HTTP

 proxy_set_header       Host $http_host;

 proxy_set_header       X-Real-IP $remote_addr;

 proxy_set_header       X-Forwarded-For $proxy_add_x_forwarded_for;

$http_host:代理服务器本身IP

​$remote_addr:前一节点的IP,并不一定是用户的真实IP。

​$proxy_add_x_forwarded_for:获取的是前一节点的X-Forwarded-For的值

​X-Forwarded-For 对应不同值:

proxy_set_header X-Forwarded-For $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

 当只有一层代理服务器的情况下,两者的X-Forwarded-For值一致,都是用户的真实IP。