默认nginx是没有安装ssl模块的,需要编译安装nginx时加入--with-http_ssl_module
选项。
nginx下配置了SSL,tomcat no SSL,项目使用https协议
nginx中配置ssl如下
##xxx项目
upstream clas{
##意思是在fail_timeout时间内失败了max_fails次请求后,则认为该上游服务器不可用,然后将该服务地址踢除掉。
##fail_timeout时间后会再次将该服务器加入存活列表,进行重试。
server localhost:8088 weight=1 max_fails=3 fail_timeout=30s;
}
server {
listen 443;
server_name x.y.com;
##配置ssl开始
ssl on;
##证书路径,其实是个公钥,它会被发送到连接服务器的每个客户端
ssl_certificate /usr/local/nginx/conf/cert/xxx.pem;
##私钥路径,私钥是用来解密的
ssl_certificate_key /usr/local/nginx/conf/cert/xxx.key;
ssl_session_timeout 5m;
##选择加密套件
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
##设置协商加密算法时,优先使用我们服务端的加密套件,而不是客户端浏览器的加密套件。
ssl_prefer_server_ciphers on;
##配置ssl结束
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
access_log /usr/local/nginx/logs/xxx_access.log;
proxy_connect_timeout 600;
proxy_read_timeout 600;
proxy_send_timeout 600;
proxy_buffer_size 256k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 512k;
proxy_temp_file_write_size 512k;
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;
proxy_pass http://clas;
}
#配置Nginx动静分离,静态资源可以单独指定服务器。
location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css)$ {
proxy_pass http://clas;
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; ##使用https协议必须加上这行
}
}
server {
listen 80;
server_name x.y.com;
rewrite ^(.*)$ https://$host$1 permanent;
}
配置SSL,使用https协议的时候,在nginx中必须加上 proxy_set_header X-Forwarded-Proto $scheme;
这样在jsp页面使用request.getScheme()
得到的是https 。如果不把请求的$scheme协议设置在header里,后端jsp页面会一直认为是http,将导致响应异常。ps:在我的项目中一开始没有加上这个配置的现象就是,后台请求都没有问题,但是静态页面加载的时候全部是http开头,导致不能加载,造成页面排版混乱。
配置Tomcat server.xml 的 Host下配置一个 Valve:
<Valve className="org.apache.catalina.valves.RemoteIpValve"
remoteIpHeader="x-forwarded-for"
remoteIpProxiesHeader="x-forwarded-by"
protocolHeader="x-forwarded-proto"/>
配置双方的 X-Forwarded-Proto 就是为了正确地识别实际用户发出的协议是 http 还是 https。
PS:HTTPS服务器优化
众周所知网站启用https后,会加剧服务器的负担。传统的http使用TCP三次握手建立连接,而SSL和TLS在这个基础上还需要9个握手包,所以这个负担显而易见。
通过重用Session提高https的性能:
https存在一个缺点:每次新的TLS连续都需要握手,以便创建共享的加密密钥,在TCP三次握手之上还需要两个来回。
但是TLS有几个特点可以抵消额外的握手:重用一个Session。有两个标准会话重用机制:session IDs (RFC 5246) 和 session tickets (RFC 5077),使用其中一个技术,一个客户端可以重用之前创建的会话,这个会话是之前和服务器进行握手成功的,这样可以减少一次来回过程。基于SessionID的会话重用适合现代所有浏览器,FireFox和Chrome甚至还支持 session tickets。
SSL操作需要消耗CPU资源,所以在多处理器的系统,需要启动多个工作进程,而且数量需要不少于可用CPU的个数。
最消耗CPU资源的SSL操作是SSL握手,有两种方法可以将每个客户端的握手操作数量降到最低:
第一种是保持客户端长连接,在一个SSL连接发送多个请求,
第二种是在并发的连接或者后续的连接中重用SSL会话参数,这样可以避免SSL握手的操作。会话缓存用于保存SSL会话,这些缓存在工作进程间共享,可以使用ssl_session_cache指令进行配置。1M缓存可以存放大约4000个会话。默认的缓存超时是5分钟,可以使用ssl_session_timeout加大它。
Nginx之ssl_session_cache详解:
Nginx官网对ssl_session_cache选项的说明
Syntax:ssl_session_cache off | none | [builtin[:size]] [shared:name:size];
默认:
ssl_session_cache none;
Context:http, server
设置存储session参数的缓存的类型和大小。缓存可以是以下任何一种类型:
off
严禁使用session缓存:nginx明确告诉客户端session可能不会被重用。
none
session缓存的使用被禁止:nginx告诉客户端session可能会被重用,但实际上并不会将session参数存储在缓存中。
builtin
在OpenSSL中构建的缓存;仅由一个工作进程使用。缓存大小在session中指定。如果没有给出大小,则等于20480个会话。使用内置高速缓存可能导致内存碎片。
shared
所有工作进程之间共享缓存。缓存大小以字节为单位指定;一兆字节可以存储大约4000个session。每个共享缓存都应该有一个任意名称。具有相同名称的缓存可以用于多个虚拟服务器。
两种类型的缓存可以同时使用:配置案例:
ssl_session_cache builtin:1000 shared:SSL:10m;
但是只使用shared缓存,而不使用built-in缓存性能应该会更高。
Nginx配置ssl_session_cache:
目前使用较多的配置是built-in和shared同时使用:
ssl_session_cache builtin:1000 shared:SSL:10m;
但是Nginx官方说只使用shared,性能会更高,配置方法为:
ssl_session_cache shared:SSL:10m;
下面是一个针对4核系统的配置优化的例子,使用10M的共享会话缓存:
worker_processes 4;
http {
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
server {
listen 443;
server_name www.example.com;
keepalive_timeout 70;
ssl on;
ssl_certificate www.example.com.crt;
ssl_certificate_key www.example.com.key;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
...
设置较长的keepalive_timeout也可以减少请求ssl会话协商的开销,但同时得考虑线程的并发数了。
下面这篇博文可以参考
http://www.cnblogs.com/interdrp/p/4881785.html
https://segmentfault.com/a/1190000002866627
https://blog.csdn.net/leo_soul/article/details/50800512