使用nginx将https请求代理为http
Posted Riggs_Me
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用nginx将https请求代理为http相关的知识,希望对你有一定的参考价值。
使用nginx将https请求代理为http
背景
- 前端部署在公有云,但后台服务有两个,一个是部署在公有云,一个是部署在公司内网。
- 公有云上的服务无法访问公司内部的服务器。内部的服务器可以访问到公有云。
- 前端需要同时请求公有云上的后台和公司内部服务器的后台。对于公有云的访问,客户需通过浏览器访问前端,前端发送https的请求分别到公有云的后台及公司内部服务器的后台,须使用https请求,公司内部服务器启动的服务为http的服务,因此前端发送到内部服务器的请求报错。
- 考虑过通过前端的代理实现,但前端nginx服务器在公有云,后台服务在内网,公有云无法找到公司内部服务器的地址,网络不通,因此方案不通。
Error Msg:
Mixed Content: The page at ‘https://xxxx’ was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint ‘http://xxxxx’. This request has been blocked; the content must be served over HTTPS.
解决思路
通过在内部服务器上搭建nginx服务,使用nginx反向代理服务器,将发送到内部服务器的https请求转换为http,满足前端的请求。需有ssl证书,此证书是关键。
步骤
1. 通过docker安装nginx
1.1 下载镜像
docker pull nginx
1.2 编辑配置文件
- 本地创建目录, ~/nginx/conf
cd ~
mkdir nginx
cd nginx
mkdir conf
- 先将nginx镜像里面的配置文件拷贝到本地
docker run --name nginx_test nginx
docker cp nginx_test:/etc/nginx/nginx.conf ~/nginx/conf/
docker cp nginx_test:/etc/nginx/conf.d ~/nginx/conf/
- 下载证书,证书为公司颁发的,之前使用openssl生成的证书,但公司禁止使用私钥,所以一直调不通网络。
- 证书一共两个,存放路径/data/map_location/ca/2022_certificate/xxxx.com.pem和/data/map_location/ca/2022_certificate/xxxx.com.key
- 在目录~/nginx/conf/conf.d/下创建配置文件,maplocation.conf,编辑配置文件
server
listen 19898 ssl; # 前端页面访问的端口
server_name maplocation.xxxx.com; # 前端页面访问的域名
#证书位置
ssl_certificate /data/map_location/ca/2022_certificate/xxxx.com.pem; # 路径为证书生成的路径
ssl_certificate_key /data/map_location/ca/2022_certificate/xxxx.com.key; # 路径为证书生成的路径
ssl_verify_client off; # 关闭客户端验证,测试感觉没有用
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
#协议配置
# ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
# 转发到http
location /
proxy_pass http://10.15.70.2:29898; # 服务器启动的服务地址及端口
#proxy_pass http://10.15.70.2:29898;
#proxy_pass http://backend;
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-Forwarded-Proto $scheme;
- 启动容器,测试
docker run --name nginx_02 -p 19898:19898 -v /data/nginx/conf/conf.d:/etc/nginx/conf.d -v /data/nginx/log:/etc/nginx/logs/ -v /data/map_location/ca/2022_certificate:/data/map_location/ca/2022_certificate -d nginx
- 报错:Failed to load resource: net::ERR_NAME_NOT_RESOVED ,需要在客户端电脑,也就是浏览器运行的电脑上配置下域名,因为此域名非公共域名。配置方式:C:\\Windows\\System32\\drivers\\etc\\hosts , 增加 10.15.70.2 maplocation.xxxx.com
- 至此可以访问。
过程中遇到的问题
报错一:
当证书使用自签名ssl证书时,浏览器无法访问,curl命令增加参数-k后可以访问,不用-k参数报错。postman访问可以直接访问。
直接通过curl https://xxxx:19898报错如下,加上参数curl https://xxxx:19898 -k即可正常访问。
curl: (60) SSL certificate problem: self signed certificate
More details here: https://curl.haxx.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
原因为证书是自签名ssl证书,不安全,需要浏览器单独点击验证方能访问。
nginx将http请求代理为https请求
参考技术A 恰巧遇到上传文件时,后端服务器生成servlet http请求,提供给web端,使其能直接从浏览器通过http请求将流发送到后端服务器,不需进过web服务端,而web端的请求都为https,涉及https转http请求问题【问题描述还有一点】问题简而言之就是需要将后端的http请求变成https请求,这里有两种路子去处理:
1) 本身后端反馈给前端的是http的servlet,是否可以将servlet生成https的请求;
2) 能否通过其他代理手段,将后端http请求转换一下。
因时间紧,优先考虑代理方案。常用的代理服务手段nginx等,优先选择nginx,轻量与简单。
目标如下:
【客户端 --(https)-->nginx--(http)-->servlet容器】
选择nginx-1.20.0版本
代理https需要配置SSL,以如下命令生成SSL配置,加入到nginx配置中
1)生成密钥,使用openssl生成密钥private.key,长度为1024
openssl genrsa -out private.key 1024
2)使用密钥生成证书server.pem
openssl req -new -x509 -key private.key -out server.pem -days 365
证书信息可以随便填或者留空,只有Common Name要根据你的域名填写,即填写nginx所在服务器的IP或域名。
启动nginx即可
以上是关于使用nginx将https请求代理为http的主要内容,如果未能解决你的问题,请参考以下文章