HTTPS 目前已经逐渐成为标配,利用 Lets Encrypt 可以免费实现网站的 HTTPS,保证传输安全。关于 Lets Encrypt 的使用问题可以查看官方的FAQ,目前不支持泛解析的域名,但是在将来可能会实现。以下环境使用 CentOS 7。
letsencrypt 安装和配置
安装 letsencrypt
1 | yum update |
创建 Nginx 配置文件
1 | server { |
如果不存在 /var/www/html 文件夹则创建
mkdir -p /var/www/html
重启 Nginx
service nginx restart
验证域名所有权并申请证书
1 | sudo letsencrypt certonly -a webroot --webroot-path=/var/www/html -d www.example.com |
会自动创建一个文件,同时访问当前服务器的80端口,来验证域名的所有权
1 | http://www.example.com/.well-known/acme-challenge/p1jaEziikiiKer311uQ9fh03_pJmiPSCG0vYahUtWVA |
可以让多个域名使用相同的证书
1 | sudo letsencrypt certonly -a webroot --webroot-path=/var/www/html -d www.example.com -d example.com |
目前不支持通配符域名,*.sub.domain.com
生成强 Diffie-Hellman 组
To further increase security, you should also generate a strong Diffie-Hellman group. To generate a 2048-bit group, use this command:
1 | sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 |
这一步需要花一些时间,完成后有一个强 DH 组在 /etc/ssl/certs/dhparam.pem
配置 nginx 代码段,来指向 SSL Key and Certificate
sudo vim /etc/nginx/snippets/ssl-www.example.com.conf
文件内容
1 | ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem; |
创建 Nginx 强加密配置的代码段
sudo vim /etc/nginx/snippets/ssl-params.conf
文件内容
1 | # from https://cipherli.st/ |
配置 Nginx 支持 HTTPS
1 | server { |
这里配置了 http2,要求 Nginx 版本要大于 1.9.5。HTTP2 具有更快的 HTTPS 传输性能,非常值得开启。开启 HTTP2 的前提是要先开启 HTTPS.
重启 Nginx
service nginx restart
证书有效期是3个月,三个月后需要刷新证书。由于执行更新操作的时候,只有当过期时间小于30天时,才会真的更新。因此一个实际的方式是每星期或者每天执行一次更新操作。
执行这个命令就会刷新
sudo letsencrypt renew
添加 Ctrontab 任务
sudo crontab -e
在 crontab 文件中添加以下任务
1 | 30 2 * * 1 /usr/bin/letsencrypt renew >> /var/log/le-renew.log |
每星期1的2点30分执行更新操作,2点35分执行Nginx 重启(这样新的证书就会启用),然后输出日志到 /var/log/le-renew.log
在其他服务器上验证域名所有权
也可以在另外一台服务器上执行 letsencrypt,来验证域名的所有权,这时用手动模式
letsencrypt certonly --manual -d www.example.com
会要求去运行命令的服务器上创建一个验证文件,让 letsencrypt 去访问80端口来验证。验证文件还是放在 .well-known 目录下,具体根据提示。
如果需要部署HTTPS的服务器80端口被占用,或者防火墙那边不开放80端口,只能是采用这种手动的方式,先将域名指定到一台有80端口的服务器上,验证通过后,再将域名指定回来真正的服务器上面。
手动模式获取的证书,如何刷新证书
但是通过手动模式获取的 letsencrypt 证书是无法通过执行 /usr/bin/letsencrypt renew 来刷新,会出现如下问题
1 | Could not choose appropriate plugin: The manual plugin is not working; there may be problems with your existing configuration. |
因为 letsencrypt 的 manual 插件不支持非交互形式,因此通过 manual 插件获取的证书,需要再次执行此前获取该证书时输入的命令,也就是
letsencrypt certonly --manual -d www.example.com
这样的话,就没办法将这条命令放到 crontab 中去自动运行了。如果是在其他服务器上执行的,那么又得重新配置一次域名的IP。
安装最新的 openssl
如果 openssl 版本小于1.0.2,是无法启用 http2 的,查看 openssl 版本
openssl version
openssl 在大于1.1.0版本已经支持了对移动端更友好的 Google 的 ChaCha20 加密方式(针对ARM的手机端进行优化,使其更快更省电),因此尽可能选择最新的版本。
编译安装
1 | cd /usr/src |
查看 openssl 版本的时候
openssl version
会出现错误 ./openssl: error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such file or directory
使用如下方式解决
1 | ln -s /usr/local/lib64/libssl.so.1.1 /usr/lib64/libssl.so.1.1 |
创建新版本的符号链接
1 | # 删除旧的符号链接 |
查看 openssl 版本
openssl version
重启一下 Nginx 就可以支持了,可以在 Chrome 中,网络那边,查看协议是否为 h2
查看 Nginx 版本信息
nginx -V
如果看到是 openssl 1.01 的版本编译的,还需要重新编译 Nginx
平滑升级 Nginx 到最新的稳定版
下载 Nginx 最新稳定版
cd /root
wget http://nginx.org/download/nginx-1.10.3.tar.gz
解压源码
tar zxvf nginx-1.10.3.tar.gz
进入源码目录
cd nginx-1.10.3
使用 cloudflare 的 TLS nginx__dynamic_tls_records 补丁来优化 TLS Record Size
下载
wget https://raw.githubusercontent.com/cloudflare/sslconfig/master/patches/nginx__dynamic_tls_records.patch
打补丁
patch -p1 < nginx__dynamic_tls_records.patch
如果提示 patch 命令找不到的话,则先安装 patch
yum install patch
加上所需参数开始编译
1 | ./configure \ |
编译安装
1 | # 执行 make 编译,但是不要执行 make install |
升级后 Nginx 会自动重启,这时在 Chrome 中查看,验证是否支持 H2,具体在开发者工具,网络中选择显示协议。