浏览器地址栏标志着 HTTPS 的绿色小锁头从心理层面上可以给用户专业安全的心理暗示,本文简单总结一下如何在 Nginx 配置 HTTPS 服务器,让自己站点上『绿锁』。
Nginx 配置 HTTPS 并不复杂,主要有两个步骤:签署第三方可信任的 SSL 证书 和 配置 HTTPS
签署第三方可信任的 SSL 证书
SSL 证书主要有两个功能:加密和身份证明,通常需要购买,也有免费的,通过第三方 SSL 证书机构颁发。由于可信的证书颁发机构只有那么几家,所以必须要从他们那里获取或者购买。我的https证书是从腾讯云那里免费获取的(网址:https://console.qcloud.com/ssl)。通过之后下载下来就可以了。
申请的都是一年的有效期,之前在腾讯云购买了云服务器、域名,域名已使用云解析服务,可自动添加DNS记录验证,很快就能验证通过。
通过后会用申请的域名为包名发送给你,打开后有
我们主要用到Nginx包里的文件
自签名ssl证书
也可以使用自己签名SSL证书配置HTTPS,使用自己签名SSL证书配置到服务器后,可以通过HTTPS正常访问应用,但是浏览器会提示该网站的安全证书不受信任,不会有绿锁标志。
使用openssl生成证书
openssl 是目前最流行的 SSL 密码库工具,其提供了一个通用、健壮、功能完备的工具套件,用以支持SSL/TLS 协议的实现。
官网:https://www.openssl.org/source/
1. SSH登录到服务器,使用下述命令创建根证书的私匙:
sudo openssl req -x509 -nodes -days 36500 -newkey rsa:2048 -keyout /root/project/ssl/nginx.key -out /root/project/ssl/nginx.crt
req: 配置参数-x509指定使用 X.509证书签名请求管理(certificate signing request (CSR))."X.509" 是一个公钥代表that SSL and TLS adheres to for its key and certificate management.
-nodes: 告诉OpenSSL生产证书时忽略密码环节.(因为我们需要Nginx自动读取这个文件,而不是以用户交互的形式)。
-days 36500: 证书有效期,100年
-newkey rsa:2048: 同时产生一个新证书和一个新的SSL key(加密强度为RSA 2048)
-keyout:SSL输出文件名
-out:证书生成文件名
它会问一些问题。需要注意的是在common name中填入网站域名,如wiki.xby1993.net即可生成该站点的证书,同时也可以使用泛域名如*.xby1993.net来生成所有二级域名可用的网站证书。
整个问题应该如下所示:
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:Fu jian
Locality Name (eg, city) []:Xia men
Organization Name (eg, company) [Internet Widgits Pty Ltd]:lin
Organizational Unit Name (eg, section) []:qiezi
Common Name (e.g. server FQDN or YOUR name) []:www.qeizi666.cn
Email Address []:363232233@qq.com
上面的命令会在`/root/project/ssl`目录下生成`nginx.crt`和`nginx.key`文件,创建了有效期100年,加密强度为RSA2048的SSL密钥key和X509证书文件。
配置 HTTPS
Nginx安装ssl模块
Nginx 默认安装的情况下ssl模块并未被安装,如果要使用该模块则需要在编译nginx时指定–with-http_ssl_module参数.
1.查看ngixn版本极其编译参数
/usr/local/nginx/sbin/nginx -V
我已经安装ssl模块,所以有ssl的一些信息
2.进入你自己的nginx源码目录
cd developer/nginx-1.13.9/
3.重新编译的代码和模块
./configure --prefix=/usr/local/nginx--with-http_stub_status_module --with-http_ssl_module --with-file-aio --with-http_realip_module
4.make,千万别make install,否则就覆盖安装了
make
5.备份旧的nginx程序
cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
6.复制objs下的nginx程序覆盖旧的
cp objs/nginx /usr/local/nginx/sbin/nginx
7.测试新的nginx程序是否正确
/usr/local/nginx/sbin/nginx -t
8.重启nginx
/usr/local/nginx/sbin/nginx -s reload
9.查看ngixn版本极其编译参数
/usr/local/nginx/sbin/nginx -V
Nginx上启用https
配置Nginx配置文件
编辑nginx.conf
vim /usr/local/nginx/conf/nginx.conf
在http下添加
include vhost/*.conf;
这是为了方便扩展和维护
在conf目录下创建vhost文件夹,里面专门存放nginx的配置,可以以域名为文件名存在配置
Nginx上启用https
#简单配置
server {
listen 443 ssl;
server_name www.****.com;#域名
ssl_certificate /root/project/ssl/nginx.crt;#证书路径
ssl_certificate_key /root/project/ssl/nginx.key;#key路径
ssl_session_cache shared:SSL:1m; #s储存SSL会话的缓存类型和大小
ssl_session_timeout 5m; #会话过期时间
#...
}
将http访问自动跳转到https
server{
listen 80 www.****.com;
rewrite ^/(.*)$ https://www.****.com/$1 permanent;
}
HTTPS服务器优化
激活 keepalive 长连接,一个连接发送更多个请求
复用 SSL 会话参数,在并行并发的连接数中避免进行多次 SSL『握手』
这些会话会存储在一个 SSL 会话缓存里面,通过命令 ssl_session_cache 配置,可以使缓存在机器间共享,然后利用客戶端在『握手』阶段使用的 seesion id 去查询服务端的 session cathe(如果服务端设置有的话),简化『握手』阶段。
1M 的会话缓存大概包含 4000 個会话,默认的缓存超时时间为 5 分钟,可以通过使用 ssl_session_timeout 命令设置缓存超时时间。下面是一個拥有 10M 共享会话缓存的多核系统优化配置例子:
server {
listen 443 ssl;
server_name www.****.com;#域名
ssl_certificate /root/project/ssl/nginx.crt;#证书路径
ssl_certificate_key /root/project/ssl/nginx.key;#key路径
ssl_session_cache shared:SSL:1m; #s储存SSL会话的缓存类型和大小
ssl_session_timeout 5m; #会话过期时间
ssl_ciphers HIGH:!aNULL:!MD5; #为建立安全连接,服务器所允许的密码格式列表
ssl_prefer_server_ciphers on; #依赖SSLv3和TLSv1协议的服务器密码将优先于客户端密码
#配置共享会话缓存大小
ssl_session_cacheshared:SSL:10m;
#配置会话超时时间
ssl_session_timeout10m;
#...
}
使用 HSTS 策略强制浏览器使用 HTTPS 连接
HSTS – HTTP Strict Transport Security,HTTP严格传输安全。它允许一个 HTTPS 网站要求浏览器总是通过 HTTPS 来访问,这使得攻击者在用戶与服务器通讯过程中拦截、篡改信息以及冒充身份变得更为困难。
只要在 Nginx 配置文件加上以下头信息就可以了:
add_headerStrict-Transport-Security"max-age=31536000; includeSubDomains;preload"always;
max-age:设置单位时间内強制使用 HTTPS 连接
includeSubDomains:可选,所有子域同时生效
preload:可选,非规范值,用于定义使用『HSTS 预加载列表』
always:可选,保证所有响应都发送此响应头,包括各种內置错误响应
加强 HTTPS 安全性
HTTPS 基础配置采取的默认加密算法是 SHA-1,这个算法非常脆弱,安全性在逐年降低,在 2014 年的时候, Google 官方博客就宣布在 Chrome 浏览器中逐渐降低 SHA-1 证书的安全指示,会从 2015 年起使用 SHA-2 签名的证书,可参阅 Rabbit_Run 在 2014 年发表的文章:《为什么Google急着杀死加密算法SHA-1》
为此,主流的 HTTPS 配置方案应该避免 SHA-1,可以使用 迪菲-赫尔曼密钥交换(D-H,Diffie–Hellman key exchange)方案。
首先在目录 /root/project/ssl 运行以下代码生成 dhparam.pem 文件:
一般网站使用的SSL证书都是RSA证书,这种证书基本都是2048位的密钥,但是证书密钥交换密钥必须要比证书密钥更长才能安全,而默认的只有1024位,所以我们需要手动生成一个更强的密钥。所以配置之前,如果没有DH-key就需要做下面的步骤
有screen则跳过,没则安装
yum -y install screen
生成4096位的DH-Key(证书密钥交换密钥)
screen -S DH
openssl dhparam -out dhparam.pem 4096
执行之后需要等很长时间,总之慢慢等,网路出现中断,可以执行下面命令重新连接安装窗口
screen -r DH
熬过漫长的等待时间后,建议生成的dhparam.pem文件最好跟SSL证书放在一起方便管理。
然后加入 Nginx 配置:
#优先采取服务器算法
ssl_prefer_server_ciphers on;
#使用DH文件
ssl_dhparam /root/project/ssl/dhparam.pem;
ssl_protocols TLSv1 TLSv1.1TLSv1.2;
#定义算法
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4";
一般情況下还应该加上以下几个增强安全性的命令:
#减少点击劫持
add_headerX-Frame-Options DENY;
#禁止服务器自动解析资源类型
add_headerX-Content-Type-Options nosniff;
#防XSS攻击
add_headerX-Xss-Protection1;
优化后的综合配置
server {
listen 443 ssl;
server_name www.****.com;#域名
ssl_certificate /root/project/ssl/nginx.crt;#证书路径
ssl_certificate_key /root/project/ssl/nginx.key;#key路径
ssl_session_cache shared:SSL:1m; #s储存SSL会话的缓存类型和大小
ssl_session_timeout 5m; #会话过期时间
#设置长连接
keepalive_timeout 70;
#HSTS策略
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
#优先采取服务器算法
ssl_prefer_server_ciphers on;
#使用DH文件
ssl_dhparam /root/project/ssl/dhparam.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#定义算法
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4";
#减少点击劫持
add_header X-Frame-Options DENY;
#禁止服务器自动解析资源类型
add_header X-Content-Type-Options nosniff;
#防XSS攻擊
add_header X-Xss-Protection 1;
#......
}
配置完成
测试新的nginx程序是否正确
/usr/local/nginx/sbin/nginx -t
重启Nginx!
/usr/local/nginx/sbin/nginx -s reload
总结
OK,我们简单总结一下在 Nginx 下配置 HTTPS 的关键要点:
获得 SSL 证书
通过第三方可靠证书颁发机构获取,或者通过 OpenSSL 命令获得 example.key 和 example.csr 文件
HTTPS优化
减少 CPU 运算量
使用 keepalive 长连接
复用 SSL 会话参数
使用 HSTS 策略强制浏览器使用 HTTPS 连接
添加 Strict-Transport-Security 头部信息
使用 HSTS 预加载列表(HSTS Preload List)
加强 HTTPS 安全性
使用迪菲-赫尔曼密钥交换(D-H,Diffie–Hellman key exchange)方案
添加 X-Frame-Options 头部信息,减少点击劫持
添加 X-Content-Type-Options 头部信息,禁止服务器自动解析资源类型
添加 X-Xss-Protection 头部信息,防XSS攻击
其实简单的个人博客,如果没有敏感数据交互的话,使用 http 协议通讯,一般都夠用了,页面速度还会更快,但正如文章开头所说,戴上『绿锁』,更专业更安全~~有兴趣的同学可以去深入了解折腾下:)