免费 Let's Encrypt 证书申请、部署全攻略与自动续期教程
免费 Let's Encrypt 证书申请、部署全攻略与自动续期教程
Last edited 2022-6-25
type
Post
status
Published
date
Mar 11, 2018
slug
code-autohttp
summary
如今 HTTPS 证书不再是像以前那么昂贵、缓慢,HTTP/2 等协议的支持使 HTTPS 变得快速甚至比 HTTP 要快,本篇教程利用 Monit 监控 Shell 脚本配合 ssl-cert-check 实现证书过期的自动续签,续签失败邮件告警的解决方案
tags
建站
Nginx
category
后端运维
icon
password
Property
Jun 25, 2022 11:00 AM
如今 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 协议需要满足下面几个条件:
  1. ngx_http_v2_module 模块
  1. ngx_http_ssl_module 模块
  1. NGINX V1.9.5 以上
  1. 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 感觉有点小题大做了,各位看官视自己情况选着使用吧。
  • 建站
  • Nginx
  • 树莓派音乐闹钟,定时播放网易云音乐每日推荐歌单歌曲及插播语音天气预报一个合格的服务器自动备份案例,闭环备份机制出错邮件报警