SSL证书自动续签
申请 HTTPS 证书(比如 Let’s Encrypt)之前,CA 必须确认一件事:
认证原理
认证方式
申请 HTTPS 证书(比如 Let’s Encrypt)之前,CA 必须确认一件事:
你真的控制这个域名
这个过程叫 域名控制验证(DCV, Domain Control Validation)。 DNS-01、HTTP-01、TLS-ALPN-01 都是 不同的验证手段。
HTTP-01 的思路最直观。CA 会给你一段随机字符串,让你把它作为一个文件放到网站目录里,路径固定在 /.well-known/acme-challenge/。随后 CA 通过普通的 HTTP 请求访问你的域名,如果能访问到这个文件并且内容正确,就认为你控制了这个域名。它的前提条件是域名必须能被公网通过 80 端口访问,而且访问路径不能被反向代理、CDN 或跳转破坏。因为验证的是具体主机名,所以它不支持泛域名。
DNS-01 的思路完全不同,它不关心你的服务器和端口,而是只看 DNS。CA 会要求你在域名的 DNS 里添加一条特定的 TXT 记录,记录名一般是 _acme-challenge.域名,值是一串校验字符串。CA 从公网 DNS 查询这条记录,只要查得到,就说明你能控制这个域名的 DNS,因此验证通过。由于泛域名的控制权本身就是通过 DNS 体现的,所以 DNS-01 是唯一支持 *.example.com 泛域名证书的方式。它的代价是需要 DNS 提供商的 API 权限,并且要等待 DNS 解析在公网生效。
TLS-ALPN-01 则介于两者之间。CA 会直接连接你的域名的 443 端口,在 TLS 握手阶段通过 ALPN 扩展请求一个特殊的协议标识。你的 ACME 客户端需要在这一瞬间临时提供一个只用于验证的证书,如果 CA 在 TLS 层验证成功,就认定你控制了该域名。这种方式不需要 80 端口,但要求 443 必须直连你的服务,不能被很多 CDN、七层代理或证书托管平台拦截,因此实际使用范围比较小,同样不支持泛域名。
下面是一张对照表,把三种方式的差异压缩到一起,方便快速判断使用场景:
| 认证方式 | CA 验证你什么 | 需要的网络条件 | 是否支持泛域名 | 典型适用场景 |
|---|---|---|---|---|
| HTTP-01 | 能否访问指定 HTTP 文件 | 公网 80 端口直达 | 否 | 普通直连网站 |
| DNS-01 | 能否查到指定 DNS TXT | 只需能改 DNS | 是 | 泛域名、CDN、内网、反代 |
| TLS-ALPN-01 | TLS 握手阶段响应 | 公网 443 端口直达 | 否 | 无法开 80 的直连服务 |
自动续订
证书自动续订的本质其实只有一句话: ACME 客户端定期尝试重新做一次“同样的域名验证”,成功就续,不成功就失败。 三种方式的差别不在“续不续”,而在于续订时依赖的外部条件是否还成立。
HTTP-01 的自动续订逻辑是这样的:acme.sh(或 certbot)通过 cron / systemd 定期运行,当证书快到期时,它再次在服务器上生成 /.well-known/acme-challenge/ 里的校验文件,然后 CA 通过 HTTP 访问你的域名。如果 80 端口还能直连到这台服务器、路径没有被改写、没有被 CDN/代理拦截,那么续订会悄无声息地成功;一旦中途网络结构变了,比如加了 CDN、端口被封、跳转到 HTTPS 或转发到别的地方,续订就会在你没注意时失败。这也是 HTTP-01 最容易“过几个月突然挂”的原因。
DNS-01 的自动续订逻辑最干净。acme.sh 到期前运行时,会再次调用 DNS API,自动添加新的 TXT 记录,等待解析生效,然后让 CA 去查,成功后再把 TXT 删掉。只要三件事没变:域名还在你手里、DNS 还是这个服务商、API Key 没过期,续订就可以长期全自动运行,哪怕服务器本身是内网、关机、换 IP,证书依然能续。泛域名证书的续订也完全一样,不需要额外操作。
TLS-ALPN-01 的自动续订逻辑依赖 443 端口。续订时,ACME 客户端会临时监听 443,准备一个专门用于验证的证书,CA 发起 TLS 连接并检查 ALPN 响应。如果你的 443 端口始终直连、没有被 CDN、ESA、Cloudflare 这类平台接管,续订可以自动完成;但只要中间多了一层代理、证书托管、四层转发不透明,CA 的验证请求就到不了你的 ACME 客户端,续订会直接失败。
脚本使用
先说通用规律:acme.sh 的签发命令核心是 --issue,域名用 -d(可写多个),验证方式用 --dns / --webroot / --alpn(三选一),签发后用 --install-cert 把证书落到你服务需要的位置,并配合 --reloadcmd 重载服务。自动续订一般不需要你每次手动执行,acme.sh 默认会安装定时任务(cron 或 systemd timer),到期前自动跑 --cron 去续。
一、脚本基本使用(通用)
1)签发(一次性)
--issue:申请/签发证书-d example.com:要签发的域名;多个域名就写多个-d
2)安装证书(落地到固定路径,供 Nginx/Caddy/面板读取)
--install-cert:把证书复制到你指定的路径(不会改变 acme.sh 自己的存储)--key-file:私钥路径--fullchain-file:完整链(最常用)--cert-file/--ca-file:有些程序要分开(多数用不到)--reloadcmd:安装/续订后执行的命令,比如重载 nginx
3)续订(一般自动)
--renew -d example.com:手动续订某个域名--cron:acme.sh 定时任务实际跑的入口(你也可以手动跑验证续订链路是否通)
二、常用参数解释(你会经常见到这些)
| 参数 | 作用 | 什么时候用 |
|---|---|---|
--issue | 申请/签发证书 | 第一次申请、或强制重签 |
-d | 指定域名(可多次) | 单域、多域、含 www |
--force | 强制重新签发 | 调试/更换验证方式/不想等到期 |
--debug 2 | 输出更详细日志 | 出错排查 |
--log / --log /path | 写日志(默认/指定文件) | 需要留存排查证据 |
--server letsencrypt | 指定 CA(默认就是 LE) | 换 ZeroSSL/自建 CA 时 |
--keylength ec-256 / 2048 | 指定密钥类型/长度 | 想用 ECC 或 RSA |
--dnssleep 60 | DNS-01 等待解析生效秒数 | DNS 传播慢时必备 |
--install-cert | 把证书安装到你的路径 | 给 Nginx/面板用 |
--reloadcmd "..." | 安装或续订后重载服务 | nginx/caddy/apache |
--set-default-ca | 设置默认 CA | 多环境统一 |
--list | 列出已签发证书 | 检查现状 |
--ecc | 使用 ECC算法生成证书 RSA:2048 位密钥 ECC:256 位密钥(安全级别相当甚至更高) | 更快、更省资源、证书更小,而且对现在的浏览器和系统来说几乎没有兼容性问题。 |
--standalone | 当你用 --standalone 时,acme.sh 会在本机 临时监听端口 | 不用现有的 Web 服务器,服务器没有web的时候,可以使用独占 |
-k | 选择具体证书算法 | 使用-k ec-256 指定使用 ECC P-256 椭圆曲线证书在 acme.sh 里,它和 --ecc 的效果基本等价。 |
--set-default-ca | 当前指定的 CA(server)写入配置作为默认值 | 需要和--server参数一起使用才有作用 |
--server | 指定申请证书的 ACME 服务端(CA) | letsencrypt |
可以使用
acme.sh --info查看配置信息

三、三种验证方式:脚本怎么写、参数怎么选
1)DNS-01(你现在的 --dns dns_ali)
核心点:用 DNS API 自动加 TXT 记录完成验证。以阿里云为例要先准备环境变量(只要做一次):
export Ali_Key="你的AccessKeyId"
export Ali_Secret="你的AccessKeySecret"签发示例:
~/.acme.sh/acme.sh --issue -d example.com --dns dns_ali --dnssleep 60泛域名示例:
~/.acme.sh/acme.sh --issue -d example.com -d "*.example.com" --dns dns_ali --dnssleep 60DNS-01 续订为什么稳:到期前自动再走一遍“加 TXT → 验证 → 删 TXT”。你要确保的只有:域名 DNS 仍在阿里云、Ali_Key/Ali_Secret 没失效。
你这条命令里的 --dns dns_ali 具体含义就是:选择 acme.sh 内置的 “Aliyun DNS 插件”,用阿里云 DNS API 做 TXT 校验。
2)HTTP-01(webroot 模式最常见)
核心点:CA 通过 80 访问你站点某个目录下的挑战文件。你需要告诉 acme.sh:挑战文件应该写到哪个目录(也就是网站的 webroot)。
签发示例(假设网站根目录是 /var/www/html):
~/.acme.sh/acme.sh --issue -d example.com --webroot /var/www/html多域名示例:
~/.acme.sh/acme.sh --issue -d example.com -d www.example.com --webroot /var/www/htmlHTTP-01 自动续订的关键条件:80 必须能访问到这台机器且路径不被改写;很多“过几个月突然续不上”就是因为后来上了 CDN/反代/强制跳转,把 /.well-known/acme-challenge/ 搞坏了。
3)TLS-ALPN-01(alpn)
核心点:CA 直接连 443,通过 TLS 握手的 ALPN 扩展验证。要求 443 必须直连到运行 acme.sh 的地方,且不能被很多 CDN/证书托管平台接管。
签发示例:
~/.acme.sh/acme.sh --issue -d example.com --alpnTLS-ALPN-01 自动续订的关键条件:443 必须始终直连、且 acme.sh 在续订时能接管/响应对应握手验证;一旦前面有 ESA、Cloudflare 这类托管证书的东西,通常会失败。
TLS-ALPN-01(
--alpn)需要临时占用 443 端口;如果 443 已经被 Nginx 监听,通常必须先停掉 Nginx(或让 Nginx 把 443 完整让出来)
四、落地安装与续订后的自动重载(强烈建议你加上)
以 Nginx 为例(DNS-01/HTTP-01/TLS-ALPN-01 都一样用这段安装):
~/.acme.sh/acme.sh --install-cert -d example.com \
--key-file /etc/nginx/ssl/example.com.key \
--fullchain-file /etc/nginx/ssl/example.com.fullchain.pem \
--reloadcmd "systemctl reload nginx"这样证书续订成功后会自动更新到你指定的位置并 reload nginx,你不用手动管。
具体执行脚本
1、把 acme.sh 的安装脚本下载下来并立刻执行,安装一个 ACME 客户端(acme.sh)
curl https://get.acme.sh | sh(get.acme.sh 在 GitHub / raw.githubusercontent.com 上)
加速:
把官方安装脚本的下载地址换成镜像:
curl -fsSL https://ghproxy.com/https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh | sh
或:
curl -fsSL https://ghproxy.net/https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh | sh2、安装 socat 这个网络“端口转发/套接字工具”。
apt install socat因为刚开始安装acme.sh安装会警告:
[2025年12月27日 20:40:45] It is recommended to install socat first.
[2025年12月27日 20:40:45] We use socat for the standalone server, which is used for standalone mode.
[2025年12月27日 20:40:45] If you don't want to use standalone mode, you may ignore this warning.3、添加软连接
ln -s /root/.acme.sh/acme.sh /usr/local/bin/acme.sh4、执行证书
如果直接执行:
acme.sh --install-cert -d maluyao.top会告诉你
[2025年12月27日 20:46:29] The domain 'maluyao.top' is not a cert name. You must use the cert name to specify the cert to install.
[2025年12月27日 20:46:29] Cannot find path: '/c/Users/maluyao/.acme.sh/maluyao.top'因为这是安装证书命令不是申请证书
可以使用acme.sh --list查看本机已经拥有的证书
--register-account:这台机器“认领一个 CA 身份”
--issue:给某个域名“发证”
--install-cert:把证书放到程序真正用的地方
接下来执行途中:
acme.sh --issue -d maluyao.top要求选择模式:

直接使用还是需要前置条件:

也就是先执行注册账户:
acme.sh --register-account -m my@example.com然后就直接注册好了
--nginx实际上会执行nginx命令,所以需要先安装nginx
sudo apt update
sudo apt install -y nginx事实上--nginx 的前提是:nginx 已经有一个站点配置里写了 server_name jocker.me;
否则 acme.sh 不知道该改哪个 vhost 来放挑战文件,所以报这句。然后换成--standalone模式了
不管咋样成功之后:
使用crontab -l可以看到自动续订程序:
系统每天早上 6 点 40 分,都会悄悄运行一次 acme.sh,让它看看你现在的证书有没有快过期。如果没快过期,它什么都不干;如果快到期了,就自动去续期。整个过程是后台执行的,你平时完全感觉不到。
--cron 代表“我现在是定时任务模式”,不是给你手动签新证书用的,而是专门负责续期的。
--home "/root/.acme.sh" 是告诉它:证书、配置、账号都在这个目录里。
最后的 > /dev/null 就是把所有输出丢掉,不在终端显示,也不给你发邮件,所以你看起来它一直很“安静”。
强制更新会安装到指定目录:
其他
证书标准:
--key-file(私钥):
| 常见后缀 | 在哪些软件/场景里常见 |
|---|---|
.key | nginx / apache / haproxy(最常见) |
.pem | 通用 PEM 格式(OpenSSL / acme.sh 默认) |
.privkey | acme.sh / certbot 有时用 |
.ecdsa.key | ECC 私钥(人为命名,便于区分) |
--fullchain-file(完整证书链)
| 常见后缀 | 在哪些软件/场景里常见 |
|---|---|
.crt | nginx / apache(非常常见) |
.pem | OpenSSL / 通用 |
.cer | Windows / Java 生态 |
.fullchain.pem | acme.sh / certbot 习惯命名 |
Tomcat(Java)最常用的是 keystore:.p12/.pfx 或 .jks。所以后缀怎么选,本质取决于你走哪条路。
对 Tomcat 来说无所谓,.pem、.key、.crt 都只是名字。关键是文件内容分别是私钥和证书。
推荐:
私钥:叫 privkey.pem(或 privkey.key 也行)
完整链:叫 fullchain.pem(或 fullchain.crt 也行)
不过,Tomcat 最省事、最标准的做法是把它们合成一个 PKCS12 文件给 Tomcat 用:
openssl pkcs12 -export \
-inkey /path/privkey.key \
-in /path/fullchain.pem \
-name tomcat \
-out /path/tomcat.p12
openssl pkcs12 -export -inkey privkey.key -in fullchain.pem -name springboot -out server.p12
->让后让你输入密码
可以添加参数取消密码:
-passout pass:ChangeMe123
#这里 .p12 后缀就是标准选择(.pfx 也可以,本质一样)。
# -name 的真实含义是给导入到 PKCS#12(.p12/.pfx)里的“私钥 + 证书”起一个“别名(alias)”
# keystore(JKS / PKCS12)是 可以同时装多套证书的
# 👉 一个 server.p12 里可以同时包含多组「私钥 + 证书链」
# 👉 每一组通常对应 一个域名 / 一张证书
# 👉 用 alias(别名) 来区分
#然后在 Tomcat server.xml 里通常这么配(不同版本写法略有差异,但核心是 keystore):
keystoreFile=".../tomcat.p12"
keystoreType="PKCS12"
keystorePass="你导出时设置的密码"
server:
port: 443
ssl:
enabled: true
key-store: classpath:server.p12
key-store-type: PKCS12
key-store-password: ChangeMe123
key-alias: springboot查看工具:
查看 p12 里包含什么(证书链/私钥/alias 等)
openssl pkcs12 -info -in server.p12不显示私钥(更安全)
openssl pkcs12 -info -in server.p12 -nokeysopenssl pkcs12 -info -in server.p12 -noout keytool -list -v -keystore server.p12 -storetype PKCS12
三方托管

阿里云的DNS验证
1.登录阿里云后右上角头像点击AccessKey

2.点击使用RAM用户 AccessKey
3.直接点击执行配置即可,会自动创建出Key和Secret

Linux定时任务
Linux 里其实不止一种“定时任务系统”,而是好几套并存的,各自解决不同场景的问题。下面我按人类理解的方式,一口气给你讲清楚它们是干嘛的、用什么命令加/删/看。
最传统、最常见的是 cron(crontab)。 它适合“每天几点几分”“每周一次”“固定周期”的任务,比如你看到的 acme.sh 自动续期。
cron 的特点是: 只要机器开着,到点就执行;机器如果关机错过了时间,它不会补跑。
你常用的命令是:
crontab -l —— 查看当前用户的定时任务
crontab -e —— 编辑(增加 / 修改 / 删除)当前用户的定时任务
crontab -r —— 直接删除当前用户的全部定时任务(很危险,一般不用)
cron 是“按用户分的”,root 和普通用户互不影响。
acme.sh 默认就会自动装一条 crontab
root@instance-20251220-091822:~# crontab -l
0 0 * * * root bash ~/.acme.sh/acme.sh --cron -f >/dev/null 2>&1执行命令:
# 1. 看证书文件本身在服务器上是不是新的
~/.acme.sh/acme.sh --list
# 2. 强制续一次
~/.acme.sh/acme.sh --renew -d google.cogrise.top --force
# 3. 手动重启服务,强制吃新证书
systemctl restart xray评论
评论加载中……