ALL in SSL 免费SSL,实现华为云WAF、ELB、CCE的SSL证书自动化更新,再也不用担心SSL证书过期!

举报
HDC-Feng 发表于 2026/11/07 13:40:07 2026/11/07
【摘要】 ALL in SSL 免费SSL,实现华为云WAF、ELB、CCE的SSL证书自动化更新,再也不用担心SSL证书过期!

把 SSL 证书续期彻底自动化(测试版,欢迎体验)

⚠️ 先说清楚三件事(请务必读完):

1. 这个华为云插件是我个人开发的,不是华为云官方产品,目前处于测试阶段,接口和参数还会变;

2. 请先在测试环境跑通,再考虑用在生产,用法和风险请自行评估;

3. 文中出现的账号、域名、项目 ID 都是示例。

测试插件下载链接:私信获取

30 秒看完怎么用:

  1. 把 huaweicloud 放进 ALLinSSL 的 plugins/ 目录,chmod 755;
  2. ALLinSSL → 授权 API → 新增 → 类型「插件」→ 插件名 huaweicloud → 填 AK/SK 两个框,完事;
  3. 授 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 一条(新版两条);
装完先跑一次「权限测试」,它会直接告诉你哪个产品能部署、缺什么;
建部署节点时记得把配置模式切「自定义」再保存。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。