原创文章,如需转载,请注明来自:https://bigzuo.github.io/
NGINX 搭建 HTTP 正向代理
最近帮同事搭建一个代理服务器,要求当请求的请求头中包含dest_ip
时,就将请求转发到这个目的地址,否则就正常请求。当自己用下面这种方式很快就实现 HTTP 正向代理,信心满满的交给同事使用时,却发现这种配置无法正常代理 HTTPS 请求。
1 | location / { |
NGINX 代理 HTTPS 请求时 access
日志:
1 | 192.168.73.26 - - [06/Dec/2018:19:42:27 +0800] "CONNECT acs.m.taobao.com:443 HTTP/1.1" 400 179 "-" "-" "-" |
NGINX 的error
日志:
1 | 2018/12/06 19:42:27 [info] 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" |
为什么 NGINX 不能做 HTTPS 正向代理服务器
HTTPS 现在已经被大范围的使用在网络数据安全传输领域,基于 HTTPS 的浏览器和服务器之间通信都是被加密的。所以,当浏览器通过代理发送一个 HTTPS 请求时,请求的地址和端口也是被加密的,代理服务器也无法知道这些信息。那么代理是如何知道请求是发到哪里呢?为了解决这个问题,浏览器会先发送一个明文的 HTTP 协议的 CONNECT 请求给代理服务器,告诉代理请求的目的地址和端口。CONNECT 请求的内容格式如下:
1 | CONNECT ***:443 HTTP/1.1 |
收到这个请求后,代理会和目标服务器建立一个 TCP 连接,并返回一个 HTTP 200 的响应给浏览器,告诉浏览器自己和目标服务器的 TCP 连接已建立。响应格式如下:
1 | HTTP/1.1 200 Connection Established |
之后,代理只会透明的来回传输浏览器和服务器之间经过 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 安装方式:
1 | wget http://Nginx.org/download/Nginx-1.9.2.tar.gz |
其中 “/path/to
” 为 proxy_connect.patch 文件在服务器的存放地址。需要注意的是,对于使用 Mac 的同学,我目前还没有找到使用 brew install nginx
的方式安装 ngx_http_proxy_connect_module 扩展的方法。
编译安装完 ngx_http_proxy_connect_module 扩展模块后,使用如下配置即可以使 NGINX 正常代理 HTTPS 请求。
NGINX HTTPS 代理完整配置:
1 | http { |
NGINX proxy for docker
当然,如果你会使用 docker,那么可以直接使用已经编译了 ngx_http_proxy_connect_module 模块的 NGINX 镜像 Nginx forward proxy 快速搭建一个 HTTPS正向代理服务器。
参考文档
ngx_http_proxy_connect_module: A forward proxy module for CONNECT request handling
NGINX SSL Forward Proxy Config
Understanding Nginx HTTP Proxying, Load、Balancing, Buffering, and Caching