如今 HTTPS 证书不再是像以前那么昂贵、缓慢,HTTP/2 等协议的支持使 HTTPS 变得快速甚至比 HTTP 要快,本篇教程利用 Monit 监控 Shell 脚本配合 ssl-cert-check 实现证书过期的自动续签,续签失败邮件告警的解决方案
证书的申请
以互联网安全小组提供的 Let's Encrypt 证书为例,简单介绍从安装证书工具到申请证书的方法
安装 CertBoot 证书工具
从 Certbot 官方网站可取得各系统环境的安装教程,官方有列举的环境教程都比较简单,几乎都是通过系统的包管理工具即可顺利安装;这里以 Linux Debian9 / Nginx 举例
## 安装 CertBoot 证书工具 sudo apt-get install certbot -t stretch-backports
### Let's Encrypt 证书的申请
前面我们已经安装了 Let's Encrypt 的证书管理工具,现在我们通过这个管理工具取得证书。
申请证书过程中需要域名可以正常访问,证书管理工具需要访问网站下的
.well-known
目录## 申请 Let's Encrypt 证书(/web/domain.com 为网站根目录,domain.com 是要申请的域名) sudo certbot certonly --webroot -w /web/domain.com -d domain.com ## 成功提示 ... 略 ... IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/domain.com/fullchain.pem. ## 生成 ssl_dhparam sudo openssl dhparam -out /certificate/ser.domain.com/dhparam.pem 2048
取得的证书在
/etc/letsencrypt/live/ser.domain.com/
文件夹内,证书文件为: fullchain.pem
密钥文件为:privkey.pem
,直接在Nginx引用这两个文件就可以了,ssl_dhparam 证书假设存放在 /certificate 文件夹内。如何配置网站的 HTTPS 这里推荐一个生成配置的网站 Mozilla SSL Configuration Generator
下面是 NGINX 的配置举例
server { listen 80 default_server; listen [::]:80 default_server; # 310 跳转HTTP流量到HTTPS return 301 https://$host$request_uri; } server { listen 443 ssl http2; listen [::]:443 ssl http2; # 将上面生成的证书和密钥文件填到这里 ssl_certificate /etc/letsencrypt/live/ser.domain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/ser.domain.com/privkey.pem; ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; ssl_session_tickets off; # 将上面生成的ssl_dhparam证书填到这里 ssl_dhparam /certificate/ser.domain.com/dhparam.pem; # intermediate configuration. tweak to your needs. ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS'; ssl_prefer_server_ciphers on; # HSTS 证书缓存,务必确认能正常访问后再开启 (15768000 seconds = 6 months) #add_header Strict-Transport-Security max-age=15768000; # OCSP Stapling --- # fetch OCSP records from URL in ssl_certificate and cache them ssl_stapling on; ssl_stapling_verify on; ## verify chain of trust of OCSP response using Root CA and Intermediate certs #ssl_trusted_certificate /path/to/root_CA_cert_plus_intermediates; resolver <IP DNS resolver>; .... }
NGINX HTTP/2 的启用
NGINX 启用 HTTP/2 协议需要满足下面几个条件:
- NGINX V1.9.5 以上
- OpenSSL V1.0.2 以上
若系统的 OpenSSL 低于 V1.0.2 则需要更新系统 OpenSSL 或者编译 NGINX 的时候指定 OpenSSL 源码文件夹
## 指定 OpenSSL 编译 NGINX sudo ./configure --with-http_v2_module --with-http_ssl_module --with-openssl=/installed/openssl-1.0.2l
Let's Encrypt 证书自动续签
经过上面的安装生成后网站现在已经可以正常使用HTTPS协议,但是 Let's Encrypt 只有 90 天的有效期,90天一过就需要重新申请证书,虽说申请挺方便,但是总有忘记的时候。网上的自动签署教程几乎都是清一色的利用
CronTab
或者 SYSTemd
定时签署;感觉不妥,万一程序出问题签署失败了自己也不知道,索性写个简单脚本实时监控证书过期时间,以及利用 Monit 监控 Shell 返回的退出码判断是否成功续签了证书。Let's Encrypt 证书续签脚本
Debian 执行
sudo apt-get install ssl-cert-check
安装,ssl-cert-check 用来读取证书过期时间当证书还剩 30天过期,则运行
/usr/bin/certbot renew
进行续签证书成功续签、无需续签脚本返回 0 ;续签失败脚本返回 1
#!/bin/bash # 证书文件(有多少个证书就写多少个数组变量并指向证书文件) certificate[0]="/etc/letsencrypt/live/domain.com/fullchain.pem" certificate[1]="/etc/letsencrypt/live/domain.com/fullchain2.pem" upssl=0; sloop=${#certificate[@]} let sloop-=1; for k in $( seq 0 $sloop ) do ssl-cert-check -c ${certificate[$k]} -x 30 -n -q if [ $? == 1 ] then upssl=1; else echo "INFO: CertiFicate Newest" exit 0 fi done if [ $upssl == 1 ]; then /usr/bin/certbot renew if [ $? == 0 ] then echo "INFO: UPdate CertiFicate OK !" exit 0 else echo "Error: UPdate CertiFicate Fail" exit 1 fi fi
安装 Monit 程序
邮件告警实现于 Monit 监控程序,由于我的服务器的服务都是由 Monit 监控的,索性就直接拿来用了。
RedHat / CentOS / Fedora 安装
sudo yum install monit
Ubuntu / Debian / Linux Mint 安装
sudo apt-get install monit
配置 Monit 监控脚本
配置 Monit 邮件告警功能,修改配置文件
sudo nano /etc/monit/monitrc
## 设置邮件通知服务器,已阿里云服务器举例 #服务器地址与端口 set mailserver smtp.mxhichina.com port 465 #用户名 username "admin@domain.com" #密码 password "password" #验证加密方式 using TLSV1 #登陆超时 with timeout 30 seconds
添加一个脚本监控
sudo nano /etc/monit/conf.d/shell
# 监控 /shell/certificate 执行超时时间 300 秒 check program Certificate with path /shell/certificate timeout 300 seconds # 每 720 个周期执行一次脚本 every 720 cycles # 脚本返回码不为 0 发送一封告警邮件到 hscbook@domain.com # 360 个周期内多次报警只发送一次告警邮件 if status != 0 then alert alert hscbook@domain.com with reminder on 360 cycles
其他自动签署方案
官方 Let's Encrypt 看到的一款NGINX 插件 lua-resty-auto-ssl ,可以实现自动证书签署,过期自动续签,挺强大但是需要安装一些依赖环境,若没有其他环境用到 OpenResty LuaRocks 感觉有点小题大做了,各位看官视自己情况选着使用吧。