公司给客户做的系统突然不能访问了,查询系统一切正常,只是外网不能访问。联系客户IT,排查发现系统请求被防火墙拦截掉了,原因:
这样下去是不行的。
分析了一下,应该是项目没开启https的原因。
那么需要把现在的http方式访问的项目改为https访问。
目标确定了,就开始动手吧。
涉及技术:
1、spring-boot;
2、node;
3、nginx;
4、openssl;
平台:
windows7
步骤:
一、后台http转https:
1、SSLConfig.java中加入以下代码:
1 @Bean 2 public TomcatServletWebServerFactory servletContainer() 3 { 4 5 TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() 6 { 7 8 @Override 9 protected void postProcessContext(Context context) 10 { 11 12 SecurityConstraint securityConstraint = new SecurityConstraint(); 13 securityConstraint.setUserConstraint("CONFIDENTIAL"); 14 SecurityCollection collection = new SecurityCollection(); 15 collection.addPattern("/*"); 16 securityConstraint.addCollection(collection); 17 context.addConstraint(securityConstraint); 18 } 19 }; 20 tomcat.addAdditionalTomcatConnectors(initiateHttpConnector()); 21 return tomcat; 22 } 23 24 private Connector initiateHttpConnector() 25 { 26 Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); 27 connector.setScheme("http"); 28 connector.setPort(38080); 29 connector.setSecure(false); 30 connector.setRedirectPort(8443); 31 return connector; 32 }
2、application.properties中开启ssl验证
1 server.ssl.ciphers=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_RC4_128_SHA,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,SSL_RSA_WITH_RC4_128_SHA,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 2 server.ssl.client-auth=want 3 server.ssl.enabled=true 4 server.ssl.key-alias=spinfosec 5 server.ssl.key-store= classpath:keystore.p12 6 server.ssl.key-store-password=%密码 7 server.ssl.key-store-type=PKCS12 8 server.ssl.protocol=TLS
3、浏览器访问swagger,可以正常访问。配置完成。
二、前端服务器http转https:
1、node服务端创建cert文件夹,用于存放证书相关文件:
2、使用openssl工具创建相关文件:
openssl下载地址:https://slproweb.com/products/Win32OpenSSL.html
命令行生成证书:
#生成私钥key文件:
$ openssl genrsa -out privatekey.pem 1024
#通过私钥生成CSR证书签名
$ openssl req -new -key privatekey.pem -out certsign.csr
# 通过私钥和证书签名生成证书文件
$ openssl x509 -req -in certsign.csr -signkey privatekey.pem -out certificate.crt
3、生成的证书文件:
4、app.js中引用证书文件(以下为代码片段):
1 var https = require(\'https\'); 2 3 //证书配置 4 var options = { 5 key: fs.readFileSync(\'./cert/privatekey.pem\', \'utf8\'), 6 cert: fs.readFileSync(\'./cert/certificate.crt\', \'utf8\') 7 }; 8 var httpsServer = https.createServer(options, app); 9 10 //启动 11 var SSLPORT = 8180; 12 httpsServer.listen(SSLPORT, function() { 13 console.log(\'HTTPS Server is running on: https://localhost:%s\', SSLPORT); 14 });
5、浏览器访问项目,可以正常访问。配置完成。
三、使用https域名访问项目:
前提配置:
1、支持开启https的域名(需要备案);
2、能访问百度云服务的windows电脑一台。
步骤:
1、打开百度云SSL服务:https://cloud.baidu.com/product/ssl.html
2、点击购买,选择免费dv型证书,证书有效期一年;
3、点击证书申请,选择文件验证;
4、在域名对应服务器上新建fileauth.txt,放入指定的字符串,等待百度云服务器自动扫描,成功后会收到邮件;
5、认证成功后下载证书;
6、因为使用的是nginx反向代理,所以选择PEM_Nginx下载;
7、下载后的证书放在nginx目录下;
8、nginx.conf
1 server { 2 listen 8843; 3 server_name memory.mynatapp.cc; 4 5 ssl_certificate memory.mxxxxxp.cc.crt; 6 ssl_certificate_key memory.mxxxxxp.cc.key; 7 8 ssl_session_cache shared:SSL:1m; 9 ssl_session_timeout 5m; 10 11 ssl_ciphers HIGH:!aNULL:!MD5; 12 ssl_prefer_server_ciphers on; 13 14 location / {#wechat 15 proxy_pass https://localhost:8181/; 16 } 17 location /web/ {#web 18 proxy_pass https://localhost:8180/; 19 } 20 location /api/ {#api 21 proxy_pass https://localhost:28443/; 22 proxy_http_version 1.1; 23 proxy_set_header Upgrade $http_upgrade; 24 proxy_set_header Connection "Upgrade"; 25 } 26 }
9、重启nginx,打开浏览器查看效果;
10、登录系统,api请求正常。配置完成。
注:
1、项目开发期间使用跨域的接口调试方式,在正式上线之后需要关闭,确保浏览器的同源策略以保证安全性。
2、最近对安全方面知识很感兴趣,有没有推荐的web安全相关书籍?
注2:此处可能是我使用的natapp域名主动附带的https,并不一定是我的配置正确并且生效使能够访问https