部署内容包分析
部署前应该拿到「安装包」和配套的「授权配置」,授权配置中包含授权包的授权码,完整性校验码等内容。
安装包
安装包是一个压缩文件,里面包含了一个安装工具和一个加密压缩之后的部署包。安装工具利用授权码对部署包进行处理,并按授权码携带的信息进行部署。
完整性校验码
完整性校验码用于校验安装包的完整性。
授权码的结构
部署授权码用于协调部署安装过程。
授权码考虑使用具备授权信息的json文本,利用非对称加密的方法,加密出来的字符串作为授权码,授权码的结构包括但不限于 授权的模块,部署包的解压密码等;
受商业模式的影响,还可以增加其他的授权内容用于做到不同程度的限制,如下:
1、授权码可能会被多次使用,特别是在内网的情况下,无法限制其部署的次数,可以考虑增加「授权码的过期时间或授权码生效的MAC地址」参数来限制授权码的反复使用。
2、如果授权码被滥用,为了便于后续查看是哪家泄漏的授权码,可以在授权码的原始json中增加「授权对象名称」字段。
3、平台如果是按年收费等,可以增加 「平台的授权时间范围」 字段,用来限制平台的使用时间。
4、平台如果考虑按用户数量等收费,也可以增加 「授权的用户数」 字段,用来限制平台创建用户的数量限制等。
下面是一套授权码的 JSON 结构示例,涵盖了授权信息,如授权模块、部署包解压密码、授权对象、MAC 地址绑定、授权时间范围等。
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
{
"license_id": "123e4567-e89b-12d3-a456-426614174000",
"issued_at": "2024-10-22T12:00:00Z",
"expires_at": "2025-10-22T12:00:00Z",
"licensee": {
"company": "某某科技有限公司",
"contact": "admin@example.com"
},
"authorized_modules": [
"asset",
"vulnernable",
"notice"
],
"deployment": {
"unpack_password": "s3cr3tP@ssw0rd",
"allowed_macs": [
"00:1A:2B:3C:4D:5E",
"00:1A:2B:3C:4D:5F"
],
"instance_type": 0
},
"usage_restrictions": {
"valid_from": "2024-11-01T00:00:00Z",
"valid_to": "2025-11-01T00:00:00Z",
"max_users": 100
},
"security": {
"signature": "base64-encoded-signature"
}
}
说明
- 「license_id」:唯一的授权码 ID,可用于追踪授权。
- 「issued_at / expires_at」:授权码的签发时间和到期时间。
- 「licensee」:授权对象(企业或个人)。
- 「authorized_modules」:被授权的功能模块列表。
- 「deployment」:
- unpack_password:部署包的解压密码。
- allowed_macs:受限的 MAC 地址列表,可用于防止无限制使用授权码。
- nstance_type:授权部署实例的类型(0表示单节点授权部署,1表示三节点授权部署)
- 「usage_restrictions」:
valid_from / valid_to:平台的授权有效期。
max_users:授权的最大用户数。
「security」:
signature:授权码的数字签名(使用私钥对整个 JSON 加密的哈希值,验证时使用公钥校验)。
使用非对称加密(如 RSA、ECC)对 JSON 进行加密,并将其转换为 Base64 字符串,作为最终的授权码。
缺陷问题
为了得到足够的授权信息,授权码会比较长:“我们的客户场景基本为内网部署,无法通过给简单授权码然后请求远程授权信息的方式来代替”。
虚拟化或云环境下,MAC 地址可能频繁变动,影响授权验证:“在这种情况下,可以修改变化的MAC地址为其他不变的参数”。
用户可能会修改系统时间,绕过授权时间限制
在内网部署的情况下,授权码盗用和滥用的方法比较多,我们现目前没有很好的方案从技术上完全限制。
部署流程设计
校验和配置
完整性校验
用户拿到 「安装包、校验码、授权码」 后,需使用完整性校验工具对 「安装包」 进行完整性校验,确保安装包未被篡改。「示例命令(SHA256 校验):」
ounter(line
sha256sum -c install_package.sha256
「若校验失败,则终止安装并提示用户重新获取安装包。」
解压安装包
校验通过后,用户手动解压安装包,得到以下内容:
- 「加密部署包(encrypted_package.tar.gz)」
- 「部署工具(deploy_tool,可执行二进制)」
- 「部署配置文件(deploy_config.yaml)」
「示例解压命令:」
ounter(line
tar -xzf install_package.tar.gz
deploy_config.yaml 包含:
- 「版本信息」(当前包版本号)
- 「依赖信息」(是否依赖其他组件)
- 「可选配置参数」(如端口、数据库连接等)
配置参数
用户可根据需求修改 deploy_config.yaml,未配置的参数采用默认值。
开始部署
启动部署工具
用户运行部署工具:
ounter(line
./deploy_tool
部署工具会要求用户输入 「授权码」。
授权码校验
- 「解密授权码」
- 使用预设的 「私钥」 解密授权码,获得授权信息。
- 「校验授权信息」
确认授权信息是否与本次部署的 「版本、环境」 匹配。
授权有效 → 继续安装
授权无效 → 终止安装,提示用户检查授权
自动读取当前环境信息
部署工具会自动检测系统中是否已有相同组件:
- 若已有 「相同版本」,提供 「仅安装」 或 「覆盖安装」 选项:
a.「仅安装」:保留用户数据,使用当前版本进行安装
b.「覆盖安装」:不保留旧版本数据,重新安装
- 若已有 「旧版本」,提供 「升级」 或 「覆盖安装」 选项:
「升级」:保留用户数据,更新至新版本
「覆盖安装」:不保留旧版本数据,重新安装
「示例命令(检查已安装版本):」
ounter(line
./deploy_tool --check-version
执行安装部署步骤
依赖检查通过之后,利用授权码解密得到的部署包密码对部署包进行解密。
解密成功之后,进入安装步骤,安装工具会使用授权码解密得到的安装实例类型参数,如果参数值为0,表示该授权码是单实例部署的授权;如果参数值为1,表示该授权码是三节点实例部署的授权;
如果是单实例部署,会提示用户输入当前服务的外部IP地址和服务名(可选);
如果是三实例部署,会提升用户需要输入master节点的IP地址和服务名(可选);其他节点的IP地址和服务名(可选)。
用户也可以在安装前,将IP地址和服务名以配置的方式写入到 deploy_config.yaml 中。
例如:
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
master:
ip: "192.168.1.10"
host_name: "master-10"
nodes:
- ip: "192.168.1.11"
host_name: "node-11"
- ip: "192.168.1.12"
host_name: "node-12"
如果是单实例部署中,IP地址用户也可以缺省,按照工具默认使用127.0.0.1进行部署,host_name默认为master;
在三实例部署中,host_name可以缺省,系统会自动以 **master-主节点IP(三四位)**为主节点;「node-从节点IP(三四位)为各个从节点」。
在所有的部署情况中,IP地址(和主机名)是变化概率比较大的内容,所以这几个参数还是会保留以交互式的方式让用户进行输入。其他组件和应用的配置参数,则以缺省的方式进行配置(即默认值填充)。
安装包的命名
「目标」:通过文件名即可识别 「包类型」、「版本」、「发布时间」 及 「其他关键信息」。
****「命名格式」
ounter(line
<产品名称>-<包类型>-<客户标识>-<发布版本>-<包类别>-<发布日期>.tar.gz
例如:
ounter(line
MyApp-Custom-ABCCorp-V2.3.1-Patch-202440.tar.gz
****「详细字段说明」
「字段」 | 「示例」 | 「说明」 |
「产品名称」 |
| 产品或系统名称 |
「包类型」 |
/ | 「通用包」 、「定制化包」、「Beta 版本」 |
「客户标识」 |
| 「仅定制化包」 需要加客户名称(若通用包/Beta包则省略) |
「发布版本」 |
| 「产品版本号」 ,遵循 |
「包类别」 |
/ | 「完整包」 ( |
「发布日期」 |
| 「轮胎命名方式」 , |
****「命名示例」
「文件名」 | 「含义」 |
| 「通用完整包」 ,版本 |
| 「XYZCorp 客户的定制完整包」 ,版本 |
| 「XYZCorp 客户的定制补丁包」 ,版本 |
| 「Beta 测试版完整包」 ,版本 |
****「额外可选字段」
如果需要进一步细化,可以增加:
- 「架构类型」(x86_64 / arm64)→ MyApp-General-V2.3.1-Full-202440-x86_64.tar.gz
- 「加密方式」(Enc 表示加密)→ MyApp-Custom-ABC-V2.3.1-Full-202440-Enc.tar.gz
「这样一眼就能看出这个包的类型、客户、版本和发布时间」
实现方案
部署场景的文件结构
- checksum.txt
- listence.txt
- MyApp-Custom-XYZCorp-V1.5.0-Full-202438-x86_64.tar.gz
a.部署工具,二进制
- 部署配置文件
- 加密的部署包
- MyApp-Custom-XYZCorp-V1.5.0-Full-202438-x86_64-Enc.tar.gz
- deploy_config.yaml
- deploy_tool
checksum.txt中存放MyApp-Custom-XYZCorp-V1.5.0-Full-202438-x86_64.tar.gz的完整性校验码。
listence.txt中存放授权码,是加密并编码之后的授权信息。
安装工具对授权码进行解密
当用户手动解压 MyApp-Custom-XYZCorp-V1.5.0-Full-202438-x86_64.tar.gz 之后,得到 deploy_tool 部署工具,该工具首先读取并解密listence.txt,得到授权信息。
生成加密的授权码
目标是:
- 「确保授权码只能被安装工具解密」(即防止他人随意解密)。
- 「防止私钥泄露,同时保持安全性」。
- 生成一对 「RSA 公私钥」:
a.「公钥(public_key.pem)」 用于加密 listence.txt,并内置在 部署包 内。
b.**私钥(private_key.pem)**「仅存储在部署工具(deploy_tool)内部」,用于解密授权码。
- 这样,**即使别人知道公钥,他们也无法解密 ****listence.txt**。
「加密流程(生成授权码)」
ounter(line
openssl rsautl -encrypt -pubin -inkey public_key.pem -in raw_license.txt -out listence.txt
「解密流程(在 deploy_tool 中)」
ounter(line
openssl rsautl -decrypt -inkey private_key.pem -in listence.txt -out license_decoded.txt
这样,「只有」**deploy_tool**** 具备私钥,才能解密授权码**。
风险
把 「私钥」 放到 deploy_tool 里面存在 「反编译泄露风险」,如果攻击者能够获取 deploy_tool 并反编译,就有可能提取私钥,从而解密 listence.txt。我们「可以考虑动态生成固定私钥」的方法,通过「代码中的特定计算规则」,在运行时生成私钥,计算过程隐藏在复杂的数学运算、位运算、哈希计算等逻辑中。
授权信息的结构
在前面的章节中,提到过授权信息的结构。授权信息是一个json结构的内容,里面包含了所有用户不能看或者不能篡改的内容。
用户填写好IP和主机名之后的执行逻辑
用户可以手动在 deploy_config.yaml 中填写好IP等必填参数信息,也可以通过脚本交互式填写(如果deploy_config.yaml 没有),格式为:
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
master:
ip: "192.168.1.10"
host_name: "master-10"
nodes:
- ip: "192.168.1.11"
host_name: "node-11"
- ip: "192.168.1.12"
host_name: "node-12"
在此之后,一键化脚本会调用现目前的交互式部署工具V1进行细化的部署工作,V1工具为下面每个组件定义了完整的部署逻辑:
biz base
datax
dinky
dolphinschedul
doris
flink
fluentd
grafana
jdk11
jdk17
jdk8
kafka
knowledge
log_audit
minio
mysql
nginx
nmap
pgsql
prometheus
redis
supervisord
zookeeper
配置前优化
同时V1工具也为每一个可变参数,sql都定义了执行流。
一键化部署工具V2会根据授权信息中的授权的大业务组件,「对需要的小组件进行安装和校验」,如果用户在外部没有为组件定义缺省参数,则各组件会依照原有自动化部署中的默认参数进行配置和部署。
缺省的参数清单
在上面的描述中,我们在 deploy_config.yaml 配置了部署的IP信息。在某些情况下,我们需要手动配置一些部署的参数,那么这个时候就需要用户手动在deploy_config.yaml设置参数。
安装进度展示
用户可以看到安装的进度、输出的安装正确日志或者错误日志和输出最终访问的方法等。
辅助文档输出
在上述一键化部署方案实施的前提下,在本方案交付时还应该提供出缺省的参数清单、可能出现的问题&解决清单、一键化部署用户使用、授权码申请模版等文档。