SSL证书

SSL证书独立应用

版本 v1.0.0· 胡思乱想 · 0 次获取 · 独立应用
面向 ZsAdmin 的 SSL 证书自动续签插件:与社区账户体系打通,前台用户登录后可自助申请 Let's Encrypt 证书,HTTP-01 证书到期自动续签;同时提供在线证书检测、域名监控与告警。后台支持证书签发、域名管理、检测日志与定时巡检。
20.00原价
一次购买,永久使用

详情介绍

SSL证书 · 使用说明

面向 ZsAdmin 的 SSL 证书自动续签插件:与社区账户体系打通,前台用户登录后可自助申请 Let's Encrypt 证书,HTTP-01 证书到期自动续签;同时提供在线证书检测、域名监控与告警。后台支持证书签发、域名管理、检测日志与定时巡检。

  • 插件标识:ssl
  • 当前版本:1.0.00
  • 作者:kuakeba.cn
  • 前台入口:/ssl
  • 用户控制台:/ssl/console(需登录社区账户)
  • 后台入口:后台菜单「SSL证书」,默认 /admin/ssl

一、功能说明

前台(/ssl)

  1. 自动续签落地页:Hero、关键指标、工作原理、安全说明(CNAME 委派对比全局密钥)、套餐与常见问题。
  2. 在线证书检测:输入域名后与目标完成真实 TLS 握手,展示签发机构、证书主体、生效/到期时间、剩余天数、TLS 协议、加密套件、证书链、签名算法、序列号与 SAN 覆盖情况。
  3. CNAME 委派自检:检测 _acme-challenge.域名 是否存在 CNAME,并比对配置的委派目标是否一致。
  4. 域名监控:访客可添加域名(默认每浏览器 2 个),添加后立即检测;列表支持刷新与删除,按剩余天数展示进度条,临期/过期/异常状态高亮。
  5. 用户控制台(/ssl/console):与 community 插件账户打通,未登录跳转社区登录并回跳。登录后可自助申请证书(HTTP-01 / DNS-01)、查看自动续签状态、下载证书链与私钥、续期或删除证书;支持按验证方式筛选、勾选多张批量下载 ZIP(含 IIS 用 .pfx),并展示证书品牌、加密方式、下次续签与最近续签、备注等健康信息。侧栏提供 API Token,用于调用开放接口。
  6. 未登录时首页监控按浏览器 Cookie 隔离,访客互不可见;登录后自动认领同一浏览器已添加的监控域名,并按会员 ID 跨设备同步。
说明:自动续签是插件主功能。HTTP-01 证书由定时巡检在到期前 30 天自动续签并替换文件;DNS-01 证书(含通配符)续期时需重新添加 TXT 记录。域名监控与在线检测用于观察现有证书状态,属于辅助能力。证书文件保存在 runtime/ssl/certs/,不对外公开。

后台(/admin/ssl)

  • 概览:监控总数、有效/临期/过期/异常数量、今日检测与失败数、近 14 天检测趋势图、即将到期列表、最近检测记录。
  • 域名监控:搜索、按证书状态/监控状态筛选、添加、编辑、单条检测、全部检测、启停监控、删除。
  • 检测日志:按域名、证书状态、成功/失败筛选;支持清理 30 天前日志或清空日志。
  • 证书签发:基于 Let's Encrypt ACME v2 自助签发与续期,支持 HTTP-01 自动验证与 DNS-01 手动验证;可下载完整证书链、叶子证书与私钥。
  • 定时巡检:通过带密钥的 URL 触发,自动跳过未到巡检间隔的域名,并对临近到期的 HTTP-01 证书自动续期。
说明:前台负责检测、监控与告警;证书签发与续期在后台「证书签发」完成,证书文件保存在 runtime/ssl/certs/,不对外公开。签发要求服务器能访问 Let's Encrypt ACME 接口,且域名可通过 HTTP-01 或 DNS-01 完成验证。

二、安装

  1. 将 plugins/ssl 目录放入站点 plugins 目录。
  2. 后台进入「应用中心 → 插件」,找到「SSL证书」点击安装。
  3. 安装会自动:

  - 创建数据表 ssldomain、sslchecklog、sslcertificate、sslapitoken;

  - 注册后台菜单与权限节点;

  - 复制静态资源到 public/static/ssl;

  - 生成定时巡检密钥(可在插件设置中查看/修改)。

  1. 安装完成后访问 /ssl 查看前台。

环境要求:PHP 8.0+,启用 openssl 与 streamsocketclient;域名解析推荐启用 dnsgetrecord(用于 CNAME 自检)。邮件告警依赖服务器的 mail()。

三、插件设置

后台「应用中心 → 插件 → SSL证书 → 设置」:

配置项说明
启用插件关闭后前台 /ssl 返回 404,定时巡检也不会执行
站点标题 / 副标题前台品牌名与 Hero 描述
SEO 关键词 / 描述前台页面 meta 信息
主色调 / 强调色前台 CSS 变量,格式 #RRGGBB
临期阈值(天)剩余天数 ≤ 该值标记为「临期」并触发告警,默认 15
检测超时(秒)TLS 连接超时,默认 8
巡检间隔(小时)定时巡检时距上次检测超过该时长才重新检测,默认 12
每访客监控数同一浏览器可添加的域名上限,默认 2
允许前台添加关闭后仅后台可添加域名
控制台自助签发关闭后前台控制台仅可查看与下载,签发与续期需管理员在后台完成
每会员证书上限单个社区会员在前台可持有的证书数量,默认 10(1-100)
检测频率(次/分钟)同一 IP 每分钟最多发起的在线检测与 CNAME 自检次数,默认 20(1-120)
展示套餐区块关闭后首页隐藏套餐与价格区块,并移除导航中的「套餐」入口
展示页脚赞助商关闭后页脚不展示赞助商链接
开放接口开启后会员可用 API Token 调用 /ssl/api/v1 接口;关闭后接口统一返回提示
CNAME 委派目标用于 _acme-challenge 自检比对,默认 ssl.inurl.link
ACME 联系邮箱Let's Encrypt 账户邮箱,用于到期提醒,可留空
ACME 环境生产环境签发受信任证书;测试环境仅用于调试(浏览器不信任)
HTTP-01 根目录自动写入验证文件的站点根目录,相对项目根或绝对路径,默认 public
自动续期巡检时自动续期即将到期的 HTTP-01 证书
续期阈值(天)剩余天数 ≤ 该值时自动续期,默认 30
启用告警通知关闭后只更新状态,不发送通知
告警 Webhook状态变为临期/过期/异常时 POST JSON
告警邮箱接收告警的邮箱(依赖 mail())
定时巡检密钥访问巡检 URL 所需密钥,安装时自动生成
卸载时清除数据开启后卸载插件将删除该插件的 4 张数据表

四、定时巡检

后台概览页可直接复制巡检地址,格式:

https://你的域名/ssl/cron/refresh?key=你的巡检密钥

参数:

  • key:必填,与插件设置中的「定时巡检密钥」一致,否则返回 403。
  • force=1:忽略巡检间隔,立即检测所有启用监控的域名(单次最多 60 个)。

返回示例:

{"code":1,"msg":"巡检完成","data":{"total":10,"checked":10,"failed":0,"notified":1,"renew":{"renewed":0,"failed":0,"skipped":0}}}

配置方式(任选其一):

  • Linux / 宝塔计划任务:每小时访问一次上述 URL。

 ```bash

 0 curl -s "https://example.com/ssl/cron/refresh?key=密钥" >/dev/null

 ```

  • Windows 计划任务:创建每小时执行的任务。

 ```

 powershell -NoProfile -Command "Invoke-WebRequest -UseBasicParsing 'https://example.com/ssl/cron/refresh?key=密钥'"

 ```

  • 宝塔面板:计划任务 → 访问 URL → 每小时执行。

建议巡检频率与「巡检间隔(小时)」保持一致。证书通常 90 天有效,临期阈值 15 天可保证充足的处理时间。

五、告警通知

当域名状态发生变化且变为「临期 / 已过期 / 检测失败」时触发一次通知;恢复正常后静默重置,避免重复轰炸。

Webhook 请求体示例:

{
  "event": "ssl_alert",
  "domain": "example.com",
  "port": 443,
  "status": "expiring",
  "status_text": "临期",
  "days_left": 12,
  "not_after": "2026-12-01 08:00:00",
  "issuer": "Let's Encrypt",
  "error": "",
  "checked_at": "2026-11-09 22:30:00"
}

邮件标题格式:【SSL证书告警】example.com · 临期。

六、证书自动签发(Let's Encrypt ACME)

后台「SSL证书 → 证书签发」与前台控制台均支持两种验证方式:

  1. HTTP-01(自动):插件把验证文件写入 HTTP-01 根目录/.well-known/acme-challenge/,要求域名已解析到本站且 80 端口可访问;验证通过后自动提交 CSR 并下载证书。
  2. DNS-01(手动):页面会给出 _acme-challenge 的 TXT 记录名与值,添加后等待生效(通常 1-10 分钟),点击「验证并签发」。通配符域名(*.example.com)只能使用该方式。

6.1 HTTP-01 具体配置

前置条件

  1. 域名的 A / AAAA 记录指向本服务器公网 IP(ping 域名 或 nslookup 域名 确认)。
  2. 公网可访问 80 端口(不能只放行 443);云服务器安全组、系统防火墙、宝塔/面板防火墙都要放行。
  3. 该域名的站点根目录就是插件配置中「HTTP-01 根目录」指向的目录。
  4. 若使用 Cloudflare 等 CDN:验证期间建议关闭代理(DNS only)或确保 /.well-known/ 未被 WAF、强制 HTTPS、页面规则拦截。

插件设置

后台「插件设置 → HTTP-01 根目录」填写站点真实根目录:

  • 相对路径:相对项目根目录,默认 public,最终为 项目根/public。
  • 绝对路径:Windows 例 D:\wwwroot\example\public,Linux 例 /www/wwwroot/example/public。
  • 该目录下必须能创建 .well-known/acme-challenge/,且 PHP 运行用户有写权限。

Nginx 配置

server {
    listen 80;
    server_name example.com;

    # 让 CA 直接读取验证文件,不要跳转 HTTPS
    location ^~ /.well-known/acme-challenge/ {
        root /www/wwwroot/example/public;
        default_type text/plain;
        try_files $uri =404;
    }

    # 其余请求再跳转 HTTPS
    location / {
        return 301 https://$host$request_uri;
    }
}

注意:如果站点已有 return 301 https://... 或面板「强制 HTTPS」,必须把 /.well-known/acme-challenge/ 的 location 放在跳转规则之前,否则 CA 拿到 301 会验证失败。

Apache 配置

<VirtualHost *:80>
    ServerName example.com
    DocumentRoot "/www/wwwroot/example/public"

    <Directory "/www/wwwroot/example/public/.well-known">
        Require all granted
        Options -Indexes
    </Directory>
</VirtualHost>

确认 DocumentRoot 指向 public,且 AllowOverride 允许 .htaccess 生效;若 .htaccess 中有全站 HTTPS 跳转,同样需要排除 .well-known。

权限

  • Linux:chown -R www:www public/.well-known && chmod -R 755 public/.well-known(用户组按实际 PHP-FPM 用户调整)。
  • Windows:给 IIS_IUSRS 或 PHP 运行账户授予 public 目录「修改」权限。

验证是否就绪

签发前可手动测试(把 test.txt 放入 public/.well-known/acme-challenge/):

curl -I http://example.com/.well-known/acme-challenge/test.txt
# 期望 200,Content-Type 为 text/plain

返回 301/403/404 时先修好站点配置再申请,否则 ACME 会报 Invalid response 或 unauthorized。

说明:HTTP-01 不支持通配符;每个需要证书的子域都必须独立解析到本站并单独签发。

6.2 DNS-01 具体配置

第一步:获取记录

在控制台或后台选择「DNS-01」提交后,页面会显示:

  • TXT 记录名:acme-challenge.example.com(通配符 *.example.com 同样是 acme-challenge.example.com)
  • TXT 记录值:一串 base64url 字符(每次申请/续期都会变化)

第二步:在 DNS 服务商添加记录

字段填写内容
记录类型TXT
主机记录acme-challenge(部分服务商需填完整 acme-challenge.example.com)
记录值页面显示的 TXT 值,整串复制,不要加引号或空格
TTL60 ~ 600 秒(越小生效越快)

同一名称已有多条 TXT 时,保留原有记录并新增,不要覆盖或删除(多域名/多验证可能同时存在)。

第三步:确认生效

nslookup -type=TXT _acme-challenge.example.com 8.8.8.8
# 或
dig +short TXT _acme-challenge.example.com @1.1.1.1

返回内容包含页面上的 TXT 值后再继续;未生效时等待 1-10 分钟(受 TTL 与递归缓存影响)。

第四步:验证签发

回到控制台点击「验证并签发」,CA 会直接查询权威 DNS 校验 TXT。验证通过后自动签发;失败时列表会显示具体原因。

常见失败原因

  • TXT 值复制不完整、带引号、带换行;
  • 添加到了错误的子域(如给 acme-challenge.www.example.com 而不是 acme-challenge.example.com);
  • 该名称已存在 CNAME,与 TXT 冲突(同一名称不能同时存在 CNAME 与 TXT);
  • DNS 尚未同步或本地缓存未过期;
  • 使用代理/第三方 DNS 面板未真正保存记录。

通配符说明

  • *.example.com 只能使用 DNS-01,且不覆盖 example.com 本身;需要两者都在证书里时请分别申请。
  • DNS-01 证书续期时,点「续期」会生成新的 TXT 值,需要重新添加并验证,无法全自动完成。

关于 CNAME 委派

若把 _acme-challenge.example.com CNAME 到证书平台,则由平台写入 TXT;本插件是手动 DNS-01 模式,不会自动修改你的 DNS,也不依赖该委派。前台「CNAME 自检」仅用于检查委派是否已指向配置的目标。

签发成功后可在列表下载完整证书链(Nginx/Apache 使用)、叶子证书与私钥;文件同时保存在 runtime/ssl/certs/<md5>/,不对外公开。

自动续期:开启后,定时巡检会对剩余天数 ≤ 续期阈值的 HTTP-01 证书自动续期;DNS-01 证书需人工添加 TXT,请在列表点击「续期」重新获取记录值。

注意事项:

  • 服务器需能访问 https://acme-v02.api.letsencrypt.org;若请求超时,请在服务器或网络层放行,必要时配置出网代理。
  • Windows 下 PHP 未设置 OPENSSL_CONF 时,插件会自动查找 PHP 目录的 extras/ssl/openssl.cnf。
  • Let's Encrypt 有签发频率限制,调试请使用「测试环境」,避免触发生产环境限流。
  • 私钥仅保存在 runtime 目录,请限制目录权限并做好备份。

七、开放接口(API Token)

控制台右侧「API Token」卡片会自动生成会员专属 Token(ssl_ 前缀),用于脚本调用;点「重置」后旧 Token 立即失效。鉴权方式(二选一):

  • 请求头:X-SSL-Token: ssl_xxx
  • 查询参数:?token=ssl_xxx
接口方法参数说明
/ssl/api/v1/certsGET—当前会员的证书列表
/ssl/api/v1/cert/issuePOSTdomain、challenge(http/dns)、email、remark申请签发
/ssl/api/v1/cert/verifyPOSTidDNS-01 添加 TXT 后验证签发
/ssl/api/v1/cert/renewPOSTid续期
/ssl/api/v1/cert/downloadGETid + type(fullchain/cert/key/pfx)下载单个文件
/ssl/api/v1/cert/downloadGETtype=zip + ids[]批量打包下载

示例:

# 列表
curl -H "X-SSL-Token: ssl_xxx" https://example.com/ssl/api/v1/certs

# 申请 HTTP-01 证书
curl -X POST -H "X-SSL-Token: ssl_xxx" \
  -d "domain=example.com&challenge=http&email=you@example.com&remark=主站" \
  https://example.com/ssl/api/v1/cert/issue

# 下载证书链 / PFX
curl -H "X-SSL-Token: ssl_xxx" -o fullchain.pem \
  "https://example.com/ssl/api/v1/cert/download?id=1&type=fullchain"
curl -H "X-SSL-Token: ssl_xxx" -o cert.pfx \
  "https://example.com/ssl/api/v1/cert/download?id=1&type=pfx"

返回与前台接口一致:{"code":1,"msg":"ok","data":{...}},失败时 code=0 并给出原因;Token 无效返回 401。接口只能操作当前会员自己的证书。

八、套餐与定价(展示文案)

前台「套餐」区块按参考站(ssl.inurl.link)的档位展示,文案与权益已按本插件实际能力对齐:

套餐价格有效期域名额度续签方式通知方式支持
免费版¥0永久2到期手动续签无社区支持
个人版¥591 年10到期自动续签邮件人工客服
专业版¥1991 年30到期自动续签邮件 + Webhook优先人工客服
企业版¥6991 年100到期自动续签邮件 + Webhook专属人工客服

说明:

  • 以上为展示文案,插件本身不包含支付、订单与额度校验;如需真实售卖,请自行接入支付与授权系统,或由运营方人工开通。
  • 所有套餐的证书均由 Let's Encrypt 免费签发,价格对应的是平台托管、续签与告警服务,而非证书本身的费用。
  • 自动续签=定时巡检在到期前自动重新签发并替换证书;手动续签=在后台「证书签发」列表点击「续期」。
  • 未实现的能力(自动部署到宝塔 / CDN、私钥不变续签等)未写入套餐权益,避免与实际功能不符。

九、安全与限制

  • 在线检测仅允许公网域名:先解析 A/AAAA 记录,命中内网或保留地址(如 127.0.0.1、10.x、192.168.x、fc00::/7)直接拒绝,避免被利用探测内网。
  • 前台接口带简易频率限制:检测默认 20 次/分钟/IP(可在插件设置「检测频率」调整),添加 10 次/5 分钟/IP,证书申请 5 次/5 分钟/IP。
  • 前台自助签发、接口调用与每会员证书额度均可在插件设置中关闭或调整。
  • 访客监控使用 32 位随机 Cookie 隔离,不展示邮箱等隐私字段。
  • 证书读取关闭了信任校验,仅用于展示信息;过期的自签证书同样可以读取详情,状态会标记为「已过期」。
  • CNAME 自检依赖服务器 DNS 解析能力;若服务器无法解析外部 DNS,会显示「未检测到 CNAME」。
  • 邮件告警依赖服务器 mail() 或本地 MTA,未配置时建议使用 Webhook。

十、目录结构

plugins/ssl/
├── SslPlugin.php              # 插件入口:安装、配置、菜单、资源同步
├── plugin.json
├── install.sql                # 数据表
├── routes.php                 # 前台 / 后台 / 巡检路由
├── controller/
│   ├── FrontBase.php          # 前台基类(配置、视图、频率限制、访客标识)
│   ├── FrontCert.php          # 控制台证书接口(列表 / 签发 / 续期 / ZIP / Token)
│   ├── FrontApi.php           # 开放接口(Token 鉴权,/ssl/api/v1)
│   ├── Index.php              # 落地页、检测、CNAME、监控接口
│   ├── Cron.php               # 定时巡检入口(含自动续期)
│   └── admin/                 # 概览、域名、证书签发、日志
├── service/
│   ├── CertChecker.php        # TLS 证书读取、CNAME 检测、公网校验
│   ├── AcmeClient.php         # ACME v2 协议客户端(JWS、订单、挑战、下载)
│   ├── CertService.php        # 签发流程、证书落盘、ZIP/PFX 导出、自动续期
│   ├── SslApiToken.php        # 会员 API Token 生成与鉴权
│   ├── DomainService.php      # 监控域名、检测记录、统计
│   └── Notify.php             # Webhook / 邮件告警
├── view/front/                # 前台布局、落地页与用户控制台
├── view/admin/                # 后台页面
└── static/                    # ssl.css / ssl.js

十一、常见问题

Q:检测提示「域名解析失败」?

确认域名已正确解析、服务器可访问外部 DNS,且目标已开启 HTTPS。

Q:CNAME 自检一直显示未检测到?

确认记录名为 _acme-challenge.你的域名,类型为 CNAME,值为插件设置中的「CNAME 委派目标」;DNS 生效可能需要几分钟。

Q:前台看不到刚添加的域名?

监控列表按浏览器 Cookie 隔离,清除 Cookie 或更换浏览器后会看不到原列表;可让管理员在后台查看。

Q:定时巡检返回 403?

检查 URL 中的 key 是否与插件设置中的「定时巡检密钥」完全一致,或插件是否已启用。

Q:用户控制台需要注册登录吗?

需要。控制台已与 community 插件账户体系打通:未登录会跳转社区登录页并回跳;登录后按会员 ID 展示证书与监控域名,可跨设备同步。未安装 community 插件时自动降级为浏览器访客模式,仅保留监控功能。

Q:前台签发的证书如何自动续签?

使用 HTTP-01 签发的证书由定时巡检在到期前 30 天自动续签并替换本地文件,全程无需操作;DNS-01 证书(含通配符)续期时必须重新添加 TXT 记录,无法全自动完成。定时巡检仍需配置系统计划任务访问 /ssl/cron/refresh?key=密钥。

十二、更新日志

  • 1.0.00:首个正式版本。包含前台落地页与在线证书检测、CNAME 委派自检、访客/会员域名监控、后台概览/域名管理/检测日志、定时巡检与 Webhook/邮件告警;基于 Let's Encrypt ACME v2 的 HTTP-01 / DNS-01 证书签发与自动续期;与 community 社区账户打通的前台控制台(自助签发、续期、删除、下载);证书健康信息(品牌、加密方式、下次续签、最近续签、备注)与按验证方式筛选;批量下载 ZIP(含 IIS 用 .pfx)与单独 .pfx 导出;会员 API Token 与 /ssl/api/v1 开放接口(列表 / 签发 / 验证 / 续期 / 下载);新增「控制台自助签发」「每会员证书上限」「检测频率」「展示套餐区块」「展示页脚赞助商」「开放接口」等配置项;补充 HTTP-01 / DNS-01 具体配置说明与前台「验证配置」区块;蓝色科技风主题与图标。


更新记录 (1)

  • v1.0.0 2026-11-10
    正式发布
微信客服 微信客服 QQ官方交流群 QQ官方交流群