ALL in SSL 免费SSL,实现华为云WAF、ELB、CCE的SSL证书自动化更新,再也不用担心SSL证书过期!
把 SSL 证书续期彻底自动化(测试版,欢迎体验)
⚠️ 先说清楚三件事(请务必读完):
1. 这个华为云插件是我个人开发的,不是华为云官方产品,目前处于测试阶段,接口和参数还会变;
2. 请先在测试环境跑通,再考虑用在生产,用法和风险请自行评估;
3. 文中出现的账号、域名、项目 ID 都是示例。
测试插件下载链接:私信获取
30 秒看完怎么用:
- 把 huaweicloud 放进 ALLinSSL 的 plugins/ 目录,chmod 755;
- ALLinSSL → 授权 API → 新增 → 类型「插件」→ 插件名 huaweicloud → 填 AK/SK 两个框,完事;
- 授 IAM 权限(第三节抄 JSON)→ 跑一次「权限测试」看报告 → 建部署节点(配置模式记得切「自定义」)。
AK/SK 就在界面上填,不需要写任何配置文件。 只有 IAM 策略需要贴 JSON。
一、它解决什么问题
证书申请早就不难了,certbot、acme、ALLinSSL 都能自动续。真正烦的是续完之后:WAF 要传新证书再绑回防护域名,ELB 要更新证书内容,CCE 里 ingress 的 TLS Secret 也要换一份——三个控制台,每个季度来一次,还怕漏。
这个插件就是把最后这一段也交给程序:ALLinSSL 续期成功后,自动把证书推到华为云的 WAF / ELB / CCE,不用登录控制台。
它一共 4 个动作:
| 动作 | 干什么 |
|---|---|
| waf | 上传新证书 → 覆盖绑定到 WAF 防护域名 |
| elb | 原地更新 ELB 证书内容(监听器、SNI 完全不动) |
| cce | 更新 CCE 集群里的 Secret |
| ping(界面显示「权限测试」) | 只读自检,不改任何东西,按产品给结论(装完先跑这个) |
二、上手:4 步,10 分钟
第 1 步:把插件放进 plugins 目录
tar -xzf huaweicloud-linux-amd64.tar.gz
cp huaweicloud /www/allinssl/plugins/huaweicloud # 路径按你的实际安装位置
chmod 755 /www/allinssl/plugins/huaweicloud
ls -l /www/allinssl/plugins/huaweicloud # 必须是 -rwxr-xr-x
# 验证能跑(这个插件走 stdin/stdout 的 JSON 协议,没有 -h、没有 --version)
echo '{"action":"get_metadata"}' | /www/allinssl/plugins/huaweicloud
返回一大段 JSON,能看到 “version”:“1.7.2” 就说明插件正常。
三个注意点:
- 每次重传都必须重新 chmod 755。用 SFTP / 面板覆盖上传会丢掉执行位,文件变成 -rw-r–r-- 时 ALLinSSL 直接不识别插件(进程根本起不来),而且报错不明显;
- ARM 机器传 huaweicloud-arm64,改名为 huaweicloud;
- plugins/ 里只留一个 huaweicloud。ALLinSSL 是实时扫描这个目录的(放进去就识别、不用重启),旧版同名文件留着会被后注册、把新版覆盖掉,看起来就像「升级没生效」。
第 2 步:加授权 API,填 AK/SK(不用写配置文件)
ALLinSSL 控制台 → 授权 API → 新增,按下图填:
名称: 随便起,比如 华为云-证书部署
类型: 插件
插件名称: huaweicloud
配置模式: 默认
华为云 AK: 控制台 → 我的凭证 → 访问密钥 里的 Access Key ID
华为云 SK: 同一处的 Secret Access Key
就填 AK/SK 这两个框,不需要写任何配置文件(区域、项目 ID 都挪到部署节点表单里了,这里不出现)。填完点确认,跑一次权限测试(第 3 步)后,插件会把 AK/SK 加密保存到服务器本地(/www/allinssl/.huaweicloud-vault,权限 0600),之后两个框可以清空,插件自动解密使用。
这里的「配置模式:默认」指授权 API 这一处。部署节点里也有一个同名选项,作用是另一回事,见第 3、4 步。
AK/SK 建议用独立的 IAM 子账号,别用主账号,别给 admin。需要哪几条权限见第三节。
第 3 步:跑一次权限测试(只读,别跳)
工作流 → 部署节点 → 部署类型「插件」→ 选刚建的授权 → 方法选「权限测试」,填两项:
区域ID: cn-north-4 (只填区域 ID,不要带 .myhuaweicloud.com 后缀)
项目ID: 32 位 (我的凭证 → 项目列表,切到同一区域后查看)
⚠️ 保存前先把「配置模式」切到「自定义」,再点确定。 这一步不是可选项,原因见第 4 步。
报告是按产品给结论的,不用自己逐条猜:
✅ WAF 可以部署(4/4 通过)
⚠️ ELB 可以部署,但有 1 项降级
缺 elb:listeners:list → 无法判断证书是否被监听器引用
❌ CCE 无法部署
缺 cce:cluster:get → 换不到集群访问证书
【不影响】EPS 缺了只是效率变低,仍能部署
看到 ❌ 就照着提示补权限;看到「🔑 AK/SK 或签名校验失败」,那不是权限问题,先检查 AK/SK 有没有多空格、服务器时间是否偏差超过 15 分钟。
第 4 步:建真正的部署节点
方法选「部署到华为云 WAF / ELB / CCE」,区域和项目 ID 可以留空(自动用权限测试保存的值),部署域名是下拉框、实时从云上拉的,选一下就行,不用手打。
⚠️ 保存时同样把「配置模式」切到「自定义」,再点确定。
不切的话,执行时会报「插件参数错误:params」。这是 ALLinSSL v1.1.x 的已知问题:前端「默认」模式把参数存成对象,后端只接受字符串,而报错发生在调用插件之前,插件侧没法绕过。切换时前端会自动做 JSON 序列化,表单填的内容不会丢。
如果已经报错了,回头编辑这个部署节点,切「自定义」再保存一次就恢复。这一步我卡了很久,先写在这里帮你省时间。
三、IAM 授权:照抄一段 JSON 就行
要授哪几条
| 你要部署的目标 | 需要授 | 条数 |
|---|---|---|
| WAF / ELB / CCE 全都要 | 下面那份完整 JSON | 老版 16 / 新版 17 |
| 只 WAF | WAF 5 条 + EPS 1 条 | 6 |
| 只 ELB | ELB 9 条(日常只用其中 4 条) | 9 / 4 |
| 只 CCE(更新 Secret) | cce:cluster:get | 老版 1 / 新版 2 |
一次性讲清 17 条分别干什么:
| 产品 | 授权项 | 缺了会怎样 |
|---|---|---|
| WAF | waf:host:list | 无法部署(定位不到防护域名) |
| WAF | waf:certificate:get | 能部署但每次新建证书,云上会堆重复证书 |
| WAF | waf:certificate:create | 无法部署 |
| WAF | waf:certificate:apply | 无法部署(覆盖绑定用) |
| WAF | waf:certificate:delete | 只影响「清理旧证书」勾选框 |
| ELB | elb:certificates:list | 无法部署 |
| ELB | elb:certificates:show | 无法部署(更新前后都要查一次) |
| ELB | elb:certificates:update | 无法部署(原地更新) |
| ELB | elb:certificates:create / delete | 只影响 replace 模式 |
| ELB | elb:listeners:list | 能更新,但无法判断证书是否在用 |
| ELB | elb:listeners:show / update | 只影响 replace 模式 |
| ELB | elb:loadbalancers:show | 只影响 replace 模式预检 |
| EPS | eps:enterpriseProjects:list | 只查默认企业项目,域名不在 default 时找不到 |
| CCE | cce:cluster:get | CCE 无法部署(换不到集群证书) |
| CCE | cce:cluster:generateClientCredential | 新版身份策略才需要,和上一条一起给 |
完整 JSON(WAF + ELB + CCE 全功能)
先确认你的 IAM 是哪一版——控制台里是「IAM → 权限 → 策略」就是老版,是「IAM → 权限 → 身份策略」就是新版。差别只在 ELB 那几个动作名和 Resource:
| 差别 | 老版(1.1) | 新版(5.0) |
|---|---|---|
| Resource | 不写 | 必写 [“*”] |
| 查/改证书 | get / put | show / update |
| 查/改监听器 | get / put | show / update |
| 查负载均衡器 | get | show |
| WAF / EPS / CCE | 两版同名 | 两版同名 |
老版自定义策略(Version 1.1,16 条):
{
"Version": "1.1",
"Statement": [{
"Effect": "Allow",
"Action": [
"waf:host:list",
"waf:certificate:get",
"waf:certificate:create",
"waf:certificate:apply",
"waf:certificate:delete",
"elb:certificates:list",
"elb:certificates:get",
"elb:certificates:put",
"elb:certificates:create",
"elb:certificates:delete",
"elb:listeners:list",
"elb:listeners:get",
"elb:listeners:put",
"elb:loadbalancers:get",
"eps:enterpriseProjects:list",
"cce:cluster:get"
]
}]
}
新版身份策略(Version 5.0,17 条):
{
"Version": "5.0",
"Statement": [{
"Effect": "Allow",
"Action": [
"waf:host:list",
"waf:certificate:get",
"waf:certificate:create",
"waf:certificate:apply",
"waf:certificate:delete",
"elb:certificates:list",
"elb:certificates:show",
"elb:certificates:update",
"elb:certificates:create",
"elb:certificates:delete",
"elb:listeners:list",
"elb:listeners:show",
"elb:listeners:update",
"elb:loadbalancers:show",
"eps:enterpriseProjects:list",
"cce:cluster:get",
"cce:cluster:generateClientCredential"
],
"Resource": ["*"]
}]
}
老版比新版少 1 条,只是老版不需要 generateClientCredential,不是漏写。
只部署一个产品时的 JSON
只 WAF(6 条,两版同名):
{
"Version": "1.1",
"Statement": [{
"Effect": "Allow",
"Action": [
"waf:host:list",
"waf:certificate:get",
"waf:certificate:create",
"waf:certificate:apply",
"waf:certificate:delete",
"eps:enterpriseProjects:list"
]
}]
}
只 ELB(老版 9 条;★ 是日常原地更新必需的 4 条,其余 5 条只在 replace 模式用):
{
"Version": "1.1",
"Statement": [{
"Effect": "Allow",
"Action": [
"elb:certificates:list",
"elb:certificates:get",
"elb:certificates:put",
"elb:listeners:list",
"elb:certificates:create",
"elb:certificates:delete",
"elb:listeners:get",
"elb:listeners:put",
"elb:loadbalancers:get"
]
}]
}
新版把 get→show、put→update,加 “Resource”: [“*”],条数不变。
只 CCE(更新 Secret):
{"Version": "1.1", "Statement": [{"Effect": "Allow", "Action": ["cce:cluster:get"]}]}
新版改成:
{
"Version": "5.0",
"Statement": [{
"Effect": "Allow",
"Action": ["cce:cluster:get", "cce:cluster:generateClientCredential"],
"Resource": ["*"]
}]
}
只做 CCE 时,WAF 那 5 条、ELB 那 9 条、EPS 那 1 条一条都不用给。
两个最容易配错的点
① 企业项目(EPS):all_granted_eps 只能用于查询,写操作必须落到具体企业项目。域名不在默认企业项目时,除了授 eps:enterpriseProjects:list,还要把子账号加进那个企业项目,否则报「未找到防护域名」。这一步最容易漏。
② CCE 是两条路,二选一,不要叠加:
| 你的情况 | 表单填什么 | IAM 要给 |
|---|---|---|
| 只有 AK/SK | cluster_id | cce:cluster:get(新版 +1 条),不用配 K8s Role |
| 能拿到 kubeconfig | kubeconfig(文件路径 / base64 / 内联) | 0 条 cce:*,但要配 K8s RBAC |
cluster_id 换到的是集群管理员级证书,改 Secret 时 K8s 侧天然放行,不用配 Role——这就是「纯 IAM 路线」。
kubeconfig 方式插件完全不碰 CCE API,权限由这份 kubeconfig 的 RBAC 决定。注意 kubeconfig 本身就是凭证,控制台直接下载的那份是管理员级,风险比 cce:cluster:get 还大。推荐让管理员建一个 ServiceAccount + 单命名空间 Role 再签发:
apiVersion: v1
kind: ServiceAccount
metadata:
name: allinssl
namespace: yfsrm-test # 换成你的命名空间
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: allinssl-secret-writer
namespace: yfsrm-test
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list", "create", "update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: allinssl-secret-writer
namespace: yfsrm-test
subjects:
- kind: ServiceAccount
name: allinssl
namespace: yfsrm-test
roleRef:
kind: Role
name: allinssl-secret-writer
apiGroup: rbac.authorization.k8s.io
只需要 get / list / create / update 四个 verb,不需要 delete——插件从不删 Secret。
四、几个容易踩的坑(挑重点说)
WAF:不原地改旧证书,也不先删后传。
WAF 有 UpdateCertificate,能改,但改的那一瞬间所有绑着它的域名一起变,出问题没有缓冲期,也没法只给其中一个域名换证。所以插件的顺序是:上传新证书 → apply-to-hosts 覆盖绑定 → 复核。旧证书全程可用,删不删由你决定。
「清理被替换的旧证书」默认不勾。
勾了才会删,而且只删「本次替换下来、且此刻已无任何域名绑定」的那几张,删之前会重查一遍。私钥丢了找不回来,删证书不可逆——前几次建议先不勾。
ELB 更新时不能带 domain。
只 PUT certificate + private_key 两个字段,带上 domain 会报 409。监听器和 SNI 一律不动,这是默认的 in_place 模式。只有必须换证书对象 ID 时才用 replace(要在「自定义」里写 “mode”:“replace” 并给 listener_id)。
幂等靠指纹,不靠名字。
同名证书只有内容指纹完全一致才复用,名字相同内容不同一律新建——避免「名字对了但证书是旧的」这种最难查的问题。
五、出问题怎么查
| 现象 | 原因 | 怎么办 |
|---|---|---|
| 报「插件参数错误:params」 | 配置模式没切「自定义」,参数被存成对象 | 切「自定义」再保存(见第 3、4 步) |
| 授权界面选不到 huaweicloud | 二进制没有执行位,或 plugins/ 里有旧版同名文件 | chmod 755;删掉旧版只留一个,实时扫描不用重启 |
| ❌ 403 | 缺对应授权项 | 按权限测试报告里的 → 提示补 |
| 🔑 401 / 签名失败 | AK/SK 错、有多余空格、服务器时间偏差 >15 分钟 | 不是权限问题,先修凭证 |
| 🌐 域名解析失败 | 区域拼错(如 cn-north-d)或服务器 DNS 不可用 | 报告会列候选区域;确认区域无误再查出网 |
| WAF「未找到防护域名」 | 域名在非默认企业项目,或确实没接 WAF | 把子账号加进该企业项目 |
| CCE is forbidden | kubeconfig 的 RBAC 不够 | 补 Role 的 secrets 权限 |
| ELB 报 409 | 更新时带了 domain | 用默认 in_place,别自己拼 domain |
六、写在最后
技术上没什么高深的,难的都是细节:WAF 不能先删后传、ELB 不能带 domain、CCE 只改 data 别动别的字段、指纹要用 DER 而不是 PEM。每一条都是踩过才知道的。
再强调一次定位:这是个人自研的测试版插件,不是华为云官方能力,请自行测试、自行评估风险,别直接接到生产域名上。遇到问题欢迎在评论区交流,尤其是你踩到的坑——多一个环境验证过,这东西才更靠谱。
最省事的结论就三句:
三个产品全都要 → 抄第三节那份完整 JSON,注意老版/新版别抄错;
只做 CCE 更新 Secret → 只要 cce:cluster:get 一条(新版两条);
装完先跑一次「权限测试」,它会直接告诉你哪个产品能部署、缺什么;
建部署节点时记得把配置模式切「自定义」再保存。
- 点赞
- 收藏
- 关注作者
评论(0)