在【nginx之正向代理与反向代理】一文中我们实现了将nginx服务器作为正向代理服务器和反向代理服务器,但美中不足的是仅支持http协议,不支持https协议。
我们先看看看http和https的区别:
- http协议:协议以明文方式发送数据,不提供任何方式的数据加密。不适合传输一些敏感信息,例如密码。其使用的端口是
80
。 - https协议:在http协议的基础上,加入了
ssl(secure sockets layer)
,用于对数据进行加密。其使用的端口为443
。
现在,我们要完成nginx对https协议的支持。
1.nginx正向代理(http)
我们来回顾一下nginx作为正向代理服务器支持http协议的配置。
代理服务器:192.168.110.101
- 代理服务器配置:
server { listen 8080; server_name localhost; # 解析域名时需要配置 resolver 8.8.8.8; location / { proxy_pass http://$host$request_uri; } }
- 客户端配置:
我们使用windows系统作为客户端环境。
- 访问
http://nginx.org/en/index.html
,可以正常访问。
- 访问
https://www.baidu.com
,则无法正常访问了。
- 查看代理服务器的error.log,发现其报400错误码。
这是因为,nginx作为正向代理服务器时,默认仅支持http协议,是不支持https协议的。
2.nginx正向代理(https)
那么怎么让nginx作为正向代理服务器的时候支持https协议呢?
我们可以使用第三方模块ngx_http_proxy_connect_module
。
下载地址:https://github.com/chobits/ngx_http_proxy_connect_module
我们知道如果要为nginx添加第三方模块,需要在配置configure
时添加--add-module
。从nginx1.9.11版本开始,支持load_module
指令来动态加载模块。
我们这里使用--add-module
进行模块的添加。
1)查看nginx版本以及configure信息
nginx -v nginx version: nginx/1.22.1 built by gcc 9.4.0 (ubuntu 9.4.0-1ubuntu1~20.04.1) configure arguments: --sbin-path=/usr/local/nginx/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/usr/local/nginx/nginx.pid --with-http_gzip_static_module
2)下载模块
下载地址:https://codeload.github.com/chobits/ngx_http_proxy_connect_module/zip/refs/heads/master
3)重新编译
这里我们两种添加第三方模块的方式都尝试一下。
- 使用
--add-module
cd /home/stone/nginx-1.22.1 # 1、添加patch patch -p1 < /home/stone/nginx-1.22.1/module/ngx_http_proxy_connect_module/patch/proxy_connect_rewrite_102101.patch # 2、configure ./configure --sbin-path=/usr/local/nginx/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/usr/local/nginx/nginx.pid --with-http_gzip_static_module --add-module=/home/stone/nginx-1.22.1/module/ngx_http_proxy_connect_module # 3、make make # 4、备份旧的nginx可执行文件,复制编译之后的可执行文件 mv /usr/local/nginx/nginx /usr/local/nginx/nginx.old cp objs/nginx /usr/local/nginx/nginx # 5、升级 make upgrade
- 使用
load_module
,需要将--add-module
替换为--add-dynamic-module
cd /home/stone/nginx-1.22.1 # 1、添加patch patch -p1 < /home/stone/nginx-1.22.1/module/ngx_http_proxy_connect_module/patch/proxy_connect_rewrite_102101.patch # 2、configure ./configure --sbin-path=/usr/local/nginx/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/usr/local/nginx/nginx.pid --with-http_gzip_static_module --add-dynamic-module=/home/stone/nginx-1.22.1/module/ngx_http_proxy_connect_module # 3、make make # 4 创建module文件夹,并将编译生成的ngx_http_proxy_connect_module.so拷贝过去 mkdir /usr/local/nginx/module cp /home/stone/nginx-1.22.1/objs/ngx_http_proxy_connect_module.so /usr/local/nginx/module # 5、备份旧的nginx可执行文件,复制编译之后的可执行文件 mv /usr/local/nginx/nginx /usr/local/nginx/nginx.old cp objs/nginx /usr/local/nginx/nginx # 6、升级 make upgrade
4)修改配置文件
# --add-dynamic-module动态添加第三方模块时使用 # load_module module/ngx_http_proxy_connect_module.so; http { server { listen 8080; server_name localhost; resolver 114.114.114.114 ipv6=off; proxy_connect; proxy_connect_allow 443 80; proxy_connect_connect_timeout 10s; proxy_connect_data_timeout 10s; # 指定代理日志 access_log logs/access_proxy.log main; location / { proxy_pass $scheme://$host$request_uri; } } }
此时访问https://www.baidu.com
,在access_proxy.log
产生如下日志,说明https代理成功。
3.nginx反向代理(http)
同样的,nginx作为反向代理服务器,默认也是只支持http协议,我们来回顾一下nginx作为反向代理服务器支持http协议的配置。
server { listen 80; server_name localhost; location /proxy { proxy_set_header x-real-ip $remote_addr; proxy_pass http://192.168.110.98; } }
可以看到,我们配置的server_name
为localhost
,但在实际项目中,我们是使用域名绑定nginx服务器的ip,并且使用https协议进行访问,配置的server_name
就是指定的域名,例如www.aaa.com
。
nginx为我们提供了ngx_http_ssl_module
来支持https协议,并且在提供的默认配置文件里已经给出了示例。
4.nginx反向代理(https)
添加ngx_http_ssl_module
的步骤和添加ngx_http_proxy_connect_module
的步骤一致,只是这是nginx提供的模块,因此在configure时使用--with-http_ssl_module
即可。
我们再来看看采用https协议时的配置:
server { listen 443 ssl; server_name www.aaa.com; # 申请ssl证书后,会提供cert.pem和cert.key ssl_certificate cert.pem; ssl_certificate_key cert.key; ssl_session_cache shared:ssl:1m; ssl_session_timeout 5m; ssl_ciphers high:!anull:!md5; ssl_prefer_server_ciphers on; location /proxy { proxy_pass http://192.168.110.98; } }
我们需要去为指定的域名申请ssl证书,然后将证书中的cert.pem
和cert.key
放到指定文件,并在配置文件中指定。例如我们这里指定的server_name
为www.aaa.com
,所以我们就需要为www.aaa.com
申请ssl证书。
后续我们访问https://www.aaa.com/proxy
就可以被代理到指定服务端了。
总结
以上就是nginx实现正向代理和反向代理支持https协议的全部内容,nginx是多模块化的,还有很多高级功能,我们后面继续探索。
这些仅为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论