1. 为什么你需要关心Let's Encrypt证书的到期时间?
如果你正在用Let's Encrypt的免费SSL证书,那你肯定知道它的最大特点:免费和自动化。但和那些动辄一两年的付费证书不同,Let's Encrypt证书默认只有90天的有效期。这其实是个安全上的好设计,能促使大家更频繁地轮换密钥,降低私钥泄露的风险。不过,这也意味着你得时刻惦记着它,否则一不留神,网站就会因为证书过期而亮起“不安全”的红灯,用户访问不了,面子工程和里子生意都得受影响。
我刚开始用的时候也觉得90天挺长的,手动续一下呗。结果有一次项目上线忙得昏天黑地,真就把这事儿给忘了。直到收到用户投诉说网站打不开,才手忙脚乱地去处理,那场面别提多尴尬了。所以,我的血泪教训是:千万别依赖你的记忆力来管理证书。尤其是当你手头管理着十几个甚至几十个域名时,靠人肉去记每个证书的到期日,那简直是灾难。
好在Let's Encrypt的设计初衷就是自动化,它提供了完整的工具链让我们可以轻松实现证书的申请、部署和续期。但“自动化”不等于“一劳永逸”。你需要先搭建好监控和自动化的流程,才能真正高枕无忧。这篇文章,我就结合自己踩过的坑和实战经验,给你掰开揉碎了讲清楚,怎么监控证书到期时间,以及如何搭建一个真正靠谱的、无人值守的自动化续期系统。
2. 三种实战方法,精准查看证书剩余天数
在谈自动化之前,我们得先知道怎么手动检查。这是基本功,也是后续写监控脚本的基础。方法有很多,我挑三个最常用、最直接的给你讲讲。
2.1 方法一:浏览器可视化查看(最直观)
这个方法最简单,不需要登录服务器,有浏览器就行。前提是你的网站已经正确配置了HTTPS并能正常访问。
- 用Chrome、Firefox或Edge等现代浏览器打开你的网站(比如
https://yourdomain.com)。 - 点击地址栏左侧的“锁”图标。
- 在弹出的菜单中,点击“连接是安全的”或类似选项。
- 再点击“证书有效”或“查看证书”。
这时,浏览器会弹出一个证书详情窗口,里面会清晰列出证书的颁发给、颁发者,以及最重要的有效期起始日期和到期日期。你一眼就能算出还剩多少天。这个方法适合临时快速检查,或者给不太懂技术的同事、老板演示,非常直观。
2.2 方法二:服务器端使用OpenSSL命令(最常用)
作为运维,我们大部分时间都在服务器上工作。用OpenSSL命令行工具检查,是最专业、最直接的方式。它不依赖Web服务是否运行,直接读取证书文件本身。
假设你的证书文件存放在Let's Encrypt的标准路径下,通常是在 /etc/letsencrypt/live/你的域名/ 目录里。打开终端,SSH连接到你的服务器,然后执行:
# 切换到你的证书目录
cd /etc/letsencrypt/live/yourdomain.com
# 使用openssl命令查看证书日期
openssl x509 -in fullchain.pem -noout -dates
执行后,你会看到类似这样的输出:
notBefore=Mar 15 00:00:00 2024 GMT
notAfter=Jun 13 23:59:59 2024 GMT
这里的 notAfter 就是证书的过期时间。你可以用脑子算,也可以写个简单的小脚本来计算剩余天数。我更喜欢用一条命令搞定计算:
# 一条命令计算剩余天数(在Linux bash环境下)
echo "scale=0; ($(date -d "$(openssl x509 -in fullchain.pem -noout -enddate | cut -d= -f2)" +%s) - $(date +%s)) / 86400" | bc
这条命令看起来有点复杂,其实原理很简单:它先提取证书的过期时间戳,再减去当前时间戳,然后除以每天的秒数(86400),最后用 bc 计算器算出整数天数。输出结果就是一个数字,比如 45,表示还剩45天到期。
2.3 方法三:编写脚本批量检查(最高效)
当你管理很多域名时,一个个登录服务器执行命令就太累了。这时,写一个脚本进行批量检查是唯一的选择。你可以用Shell脚本,也可以用Python、PHP等。这里我给你一个Python脚本的例子,它更灵活,也更容易处理复杂的逻辑。
#!/usr/bin/env python3
import ssl
import socket
import datetime
from OpenSSL import crypto
# 定义要检查的域名列表
domains = [
'example.com',
'www.example.com',
'api.example.com',
'blog.yourdomain.net'
]
def get_cert_expiry_date(hostname):
"""获取指定域名的SSL证书过期日期"""
try:
# 创建SSL上下文
context = ssl.create_default_context()
# 建立连接并获取证书
with socket.create_connection((hostname, 443), timeout=10) as sock:
with context.wrap_socket(sock, server_hostname=hostname) as ssock:
cert_bin = ssock.

3万+

被折叠的 条评论
为什么被折叠?



