使用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://101.152.70.2:29898; # 服务器启动的服务地址及端口
#proxy_pass http://101.152.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 , 增加 101.152.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证书,不安全,需要浏览器单独点击验证方能访问。