使用 Nginx 搭建 HTTPS 正向代理服务
NGINX 搭建 HTTP 正向代理
搭建一个代理服务器,要求当请求的请求头中包含dest_ip时,就将请求转发到这个目的地址,否则就正常请求。当自己用下面这种方式很快就实现 HTTP 正向代理,使用时,却发现这种配置无法正常代理 HTTPS 请求。
location / {
if ($http_dest_ip != "") {
proxy_pass http://$http_dest_ip/$request_uri;
}
proxy_pass https://$http_host$request_uri;
}
NGINX 代理 HTTPS 请求时 access 日志:
CONNECT acs.m.taobao.com:443 HTTP/1.1" 400 179 "-" "-" "-"
CONNECT acs.m.taobao.com:443 HTTP/1.1" 400 179 "-" "-" "-"
CONNECT acs.m.taobao.com:443 HTTP/1.1" 400 179 "-" "-" "-"
NGINX 的error 日志:
79953#1783043: *16 client sent invalid request while reading client request line, client: 192.168.73.26, server: localhost, request: "CONNECT gw.alicdn.com:443 HTTP/1.1"
79953#1783043: *16 client sent invalid request while reading client request line, client: 192.168.73.26, server: localhost, request: "CONNECT gw.alicdn.com:443 HTTP/1.1"
79953#1783043: *18 client sent invalid request while reading client request line, client: 192.168.73.26, server: localhost, request: "CONNECT acs.m.taobao.com:443 HTTP/1.1"
为什么 NGINX 不能做 HTTPS 正向代理服务器
HTTPS 现在已经被大范围的使用在网络数据安全传输领域,基于 HTTPS 的浏览器和服务器之间通信都是被加密的。所以,当浏览器通过代理发送一个 HTTPS 请求时,请求的地址和端口也是被加密的,代理服务器也无法知道这些信息。那么代理是如何知道请求是发到哪里呢?为了解决这个问题,浏览器会先发送一个明文的 HTTP 协议的 CONNECT 请求给代理服务器,告诉代理请求的目的地址和端口。CONNECT 请求的内容格式如下:
CONNECT ***:443 HTTP/1.1
Host: bayden.com:443
Connection: keep-alive
User-Agent: Chrome/47.0.2526.58
收到这个请求后,代理会和目标服务器建立一个 TCP 连接,并返回一个 HTTP 200 的响应给浏览器,告诉浏览器自己和目标服务器的 TCP 连接已建立。响应格式如下:
HTTP/1.1 200 Connection Established
Connection: close
之后,代理只会透明的来回传输浏览器和服务器之间经过 SSL 加密的数据包,并不知道也不需要知道传输的实际内容,直接通道关闭。
出现以上异常的具体原因是 NGINX 本身的设计就是作为一个反向代理服务器,而非正向代理服务器,并且在短期也没有打算支持正向代理,所以现在 NGINX 并不支持 CONNECT 请求方式,因此收到“CONNECT ***:443 HTTP/1.1”请求时会报“client sent invalid request while reading client request line”异常。这种情况并不是说 NGINX 无法处理 SSL,只是作为一个 forward proxy 不行。
安装扩展模块
那如何让 NGINX 可以正向代理 HTTPS 请求呢?我们需要借助一个第三方扩展模块 ngx_http_proxy_connect_module 来让 NGINX 支持 CONNECT 请求,建立一个 SSL 请求的通道。
ngx_http_proxy_connect_module 安装方式:
$ wget http://Nginx.org/download/Nginx-1.9.2.tar.gz
$ tar -xzvf Nginx-1.9.2.tar.gz
$ cd Nginx-1.9.2/
$ patch -p1 < /path/to/ngx_http_proxy_connect_module/patch/proxy_connect.patch
$ ./configure --add-module=/path/to/ngx_http_proxy_connect_module
$ make && make install
其中 “/path/to” 为 proxy_connect.patc

&spm=1001.2101.3001.5002&articleId=140867212&d=1&t=3&u=acb03f5c5a0c4af6b5ac2f04455f06fe)
3228

被折叠的 条评论
为什么被折叠?



