一、背景
外网项目按要求欲添加SSL,虽然在 http 三次握手的基础上增加了 SSL 的安全级别的握手,性能上打了点小折扣,并且对服务器性能增加了一点点小压力,但是这些都是安全性的代价,是物有所值的体现。项目背景:项目是 SpringBoot 项目,运行是以 jar 包的形式运行的。
二、项目配置
1、在 resources 下添加证书
位置如下图所示2、application.properties 添加配置(证书信息)
server.port=443 server.ssl.key-store=classpath:214474081390288.pfx server.ssl.key-store-password=214474081390288 server.ssl.keyStoreType=PKCS12
3、applications.properties 端口配置
在第二点里面,我们将端口设置成了 443(https 默认端口),但是我们项目希望同时接受 http 请求,遂打算添加 80 端口,并将 80 端口的 http 请求全部转发至 443 端口的 http 请求,所以又添加了一条配置:server.port2=9090
4、启动类配置
启动类内需要添加相关 bean 配置:① 支持 https
@Bean public EmbeddedServletContainerFactory servletContainer() { TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory() { @Override protected void postProcessContext(Context context) { SecurityConstraint securityConstraint = new SecurityConstraint(); securityConstraint.setUserConstraint("CONFIDENTIAL"); SecurityCollection collection = new SecurityCollection(); collection.addPattern("/*"); securityConstraint.addCollection(collection); context.addConstraint(securityConstraint); } }; tomcat.addAdditionalTomcatConnectors(initiateHttpConnector()); return tomcat; }② 请求转发
@Value("${server.port2}") private int port2; @Value("${server.port}") private int port; private Connector initiateHttpConnector() { Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); connector.setScheme("http"); connector.setPort(port2); connector.setSecure(false); connector.setRedirectPort(port); return connector; }
三、nginx 配置
项目配置完成,但是请求是由 nginx 转发过来的,所以 nginx 的配置还需要进行一点点小调整,配置如下:server { listen 80; server_name crm.*********.com; location / { # proxy_next_upstream error timeout http_500 http_502 http_504; client_max_body_size 30m; proxy_redirect off; proxy_set_header Host $host:80; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #proxy_connect_timeout 90s; proxy_send_timeout 180s; proxy_read_timeout 180s; #proxy_buffers 32 4K; proxy_pass https://crm.*********.com; } } server { listen 443; ssl on; ssl_certificate /data/https-certificate/crm/*********.pem; ssl_certificate_key /data/https-certificate/crm/*********.key; server_name crm.*********.com; location / { proxy_next_upstream error timeout http_500 http_502 http_504; client_max_body_size 30m; proxy_redirect off; proxy_set_header Host $host:443; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #proxy_connect_timeout 90s; proxy_send_timeout 180s; proxy_read_timeout 180s; #proxy_buffers 32 4K; proxy_pass https://192.168.168.169; } }配置里面的 *.pem 和 *.key 文件是 SSL 的证书和秘钥。
四、采坑记
1、关于 nginx 服务器上的 SSL 证书存放路径,文件夹请逐层 mkdir,因为发现当我一次性嵌套新建的时候,文件配置不生效,ps:此坑和权限也没关系。至今未解之谜,叹气。
2、新增证书重启nginx,大概报如下错误:
NGINX SSL: error:0200100D:system library:fopen:Permission denied 很明显是权限问题,但是 ll 发现已经给了文件777的权限,文件权限没问题,所以后来想到了selinux,想到了文件策略问题,于是我们查看了 nginx 内置的 html 文件的策略: ls -lrtZ /usr/share/nginx/html 而我们自己的 SSL 证书的 selinux 策略为:
于是尝试着修改策略: chcon -R -u system_u /xxxx/ chcon -R -t usr_t /xxxx/ 当然,如我所愿,问题解决。
文章评论