Nginx使用经验之https代理

背景

公司某项目验收过程中,验收人说网站不安全,需要改成https。为了不动应用代码,快速实现该功能,决定在nginx上耍一把。

步骤

  1. 生成证书
    在centos上使用openssl工具生成证书,命令如下所示。生成证书的过程中,要求填写一些信息(国家,公司,姓名等),一律回车即可
#创建保存证书的目录
mkdir -p /usr/local/ssl
#创建2个证书文件
openssl req -x509 -nodes -days 36500 -newkey rsa:2048 -keyout /usr/local/ssl/nginx.key -out /usr/local/ssl/nginx.crt
  1. 安装ssl插件
    检查nginx是否已经安装http_ssl_module插件。 若未安装,则重新编译安装
#查看是否安装
cd /usr/local/nginx/sbin
./nginx -V
#若看不到--with-http_ssl_module,就表明未安装。
#进入源码目录
cd /usr/local/nginx-1.15.3
#配置时加上http_ssl_module
./configure --prefix=/usr/local/nginx --with-stream --with-http_ssl_module
#编译
make
#不需要重新install,否则会覆盖安装,丢失原配置
#备份原nginx
cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx_bak
#拷贝新nginx
cp /usr/local/nginx-1.15.3/objs/nginx /usr/local/sbin/
#查看安装情况
./nginx -V
#此时应该能看到--with-http_ssl_module
  1. 配置nignx并验证

先备份原配置

 cp /usr/local/nginx/conf/nginx.conf  /usr/local/nginx/conf/nginx.conf_backup

在当前配置文件nginx.conf中,添加如下内容

 #80自动跳转到443,根据需要配置
 #server { 
 #  listen	80;
 #  server_name www.yourdomain.com;
 #  rewrite ^(.*) https://$server_name$1 permanent; #http 跳转 https
 #}
 #https server
 server {
	listen 443 ssl;#注意,不能将80端口配置成https端口
	server_name www.yourdomain.com;
	ssl_certificate /usr/local/ssl/nginx.crt;
	ssl_certificate_key /usr/local/ssl/nginx.key;
	ssl_session_cache    shared:SSL:1m;
	ssl_session_timeout  5m;
	#禁止在header中出现服务器版本,防止黑客利用版本漏洞攻击
	server_tokens off;
	#如果是全站 HTTPS 并且不考虑 HTTP 的话,可以加入 HSTS 告诉你的浏览器本网站全站加密,并且强制用 HTTPS 访问
	fastcgi_param   HTTPS               on;
	fastcgi_param   HTTP_SCHEME         https;
	access_log /usr/local/nginx/logs/httpsaccess.log;
    #里面的location配置和http server完全一致 
    location /50x.html {
    	root html;
    }
}

配置完成后,检查是否正确

cd ../sbin
./nginx -t

若ok,则重启nginx

./nginx -s reload

最后通过页面验证,浏览器输入https://ip:port,能正常访问如下图所示:
在这里插入图片描述

  1. 衍生问题:websocket连接异常
    https是当前浏览器建议的安全协议,因而浏览器不希望使用https的网站里面,包含任何非安全的请求,http://ws:// 作为协议头的请求都会有问题。解决方法就是,在前端的js里,把他们都改成安全的请求,把ws://改成wss://。在nginx 配置文件,https对应的server里正常代理该websocket接口即可。样例如下图所示:
 server {
   listen 443 ssl;#注意,不能将80端口配置成https端口
   server_name www.yourdomain.com;
   ssl_certificate /usr/local/ssl/nginx.crt;
   ssl_certificate_key /usr/local/ssl/nginx.key;
   ssl_session_cache    shared:SSL:1m;
   ssl_session_timeout  5m;
   #禁止在header中出现服务器版本,防止黑客利用版本漏洞攻击
   server_tokens off;
   #如果是全站 HTTPS 并且不考虑 HTTP 的话,可以加入 HSTS 告诉你的浏览器本网站全站加密,并且强制用 HTTPS 访问
   fastcgi_param   HTTPS               on;
   fastcgi_param   HTTP_SCHEME         https;
   access_log /usr/local/nginx/logs/httpsaccess.log;
   #里面的location配置和http server完全一致 
   location /websocket {
   	       proxy_pass http://localhost:9085/websocket;
           proxy_redirect    off;
           proxy_set_header X-Real-IP $remote_addr;
           proxy_set_header Host $host;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

           proxy_http_version 1.1;
           proxy_set_header Upgrade $http_upgrade;
           proxy_set_header Connection "upgrade";
   }
}
  1. 衍生问题:内网地图服务异常
    上面有讲到,http://开头的请求在https的网站中也是不被允许的。因而我将网站改成https后,发现内网的地图服务不能用了。此时,若地图服务本身支持https,比如互联网上的百度、高德,那么直接按其API说明修改即可。然而,我当前内网使用的地图服务并未提供https支持,就只好让前端转而访问我用nginx代理后的https的地图服务。
    好消息——内网地图服务都是http请求,坏消息——用到了不止一个端口。能力有限,此时我能想到的方法就是将用到的端口及服务一个个代理掉。怎么知道内网地图用了哪些端口及服务?没有文档的情况下,就用最笨的方法,F12看前端浏览器网络请求!找到所有前端用到的地图相关http请求,根据端口及后面第一个斜杠的内容合并汇总一下,大概有4-5个服务需要代理,nginx配置样例如下:
  server {
	listen 443 ssl;#注意,不能将80端口配置成https端口
	server_name www.yourdomain.com;
	ssl_certificate /usr/local/ssl/nginx.crt;
	ssl_certificate_key /usr/local/ssl/nginx.key;
	ssl_session_cache    shared:SSL:1m;
	ssl_session_timeout  5m;
	#禁止在header中出现服务器版本,防止黑客利用版本漏洞攻击
	server_tokens off;
	#如果是全站 HTTPS 并且不考虑 HTTP 的话,可以加入 HSTS 告诉你的浏览器本网站全站加密,并且强制用 HTTPS 访问
	fastcgi_param   HTTPS               on;
	fastcgi_param   HTTP_SCHEME         https;
	access_log /usr/local/nginx/logs/httpsaccess.log;
    #里面的location配置和http server完全一致 
    location /as/ {
    	proxy_pass http://25.75.0.225:35001/as/;
    	proxy_redirect default;
    }
    location /v3/ {
    	proxy_pass http://25.75.0.225:35333/v3/;
    	proxy_redirect default;
    }
    location /v4/ {
    	proxy_pass http://25.75.0.225:35888/v4/;
    	proxy_redirect default;
    }
    location /jsmap/ {
    	proxy_pass http://25.75.0.225:35002/jsmap/;
    	proxy_redirect default;
    }
}

nginx配置生效后,更改前端访问地图的链接,发现地图功能基本可用。但仍然有些小问题:比如画圈的功能就没有反应,F12看浏览器请求,发现仍然存在向原地图地址的请求,但查看前端代码,已经没有向原地图请求的任何配置。经排查,发现是地图的部分js方法中,会返回或默认使用原来的http协议的ip及端口号,需要将其替换成代理后https的ip及端口。具体的前端代码怎么修改,可以在内网svn上找到文档,因为涉及安全保密问题,这里只给出思路,就不贴出来了。
7. 总结
使用nginx代理https相对并不复杂,复杂的是,要解决掉因此而衍生出来的问题,不能因为技术简单就掉以轻心。

参考链接

https://blog.csdn.net/smartdt/article/details/80027579

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值