一、背景
外网项目按要求欲添加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/ 当然,如我所愿,问题解决。


文章评论