数据库自治服务DAS提供列加密(数据脱敏)规则管理工具链,支持通过Python脚本批量创建、查询和管理列加密规则。本文介绍如何使用该工具链完成列加密规则的自动化管理。
工具链概述
业务场景
在数据库安全合规实践中,通常存在以下需求:
批量加密:需要对多个实例、多个库表下的敏感列(手机号、身份证号、邮箱等)批量配置列加密规则。
查询审计:需要查询已加密列列表、实例开通状态、额度使用情况、已授权用户及权限分组。
策略管理:需要删除或更新加密策略、批量修改授权账号权限、修改实例加密算法、手动同步策略。
安全合规:避免在控制台手动操作,通过脚本实现可审计、可回溯、可预览的标准化流程。
工具链架构
工具链包含四个Python脚本,通过阿里云Python V1 SDK的CommonRequest机制调用DAS OpenAPI。所有脚本复用同一套凭据加载逻辑,均支持--dry-run演练模式。
脚本 | 职责 | 写操作 |
| 创建列加密规则(核心脚本,含可复用凭据与请求库) | 是 |
| 连接数据库读取库表结构,导出列清单 | 否 |
| 只读查询(用户、算法、已加密列、实例、状态、额度统计) | 否 |
| 写操作(删除/更新策略、批量改授权、改算法、手动同步) | 是 |
配置文件设计
配置分为4类,每类提供真实文件与.example模板成对设计,职责独立:
类别 | 真实文件 | 模板 | 消费方 |
云API凭据 |
|
| create / describe / manage |
数据库连接 |
|
| fetch_schema.py |
列清单(CSV) |
|
| create |
加密策略(JSON) |
|
| create |
真实配置文件含敏感信息,请勿提交到版本管理系统,仅保留*.example模板。
适用范围
参与方 | 所需权限与资源 |
操作环境 | Python 3.8及以上,可创建venv虚拟环境。 |
阿里云RAM用户 | 拥有DAS列加密相关接口调用权限。 |
网络 | 操作源IP需在DAS列加密操作的允许网络范围内。 |
数据库实例 | 已开通列加密服务,且已购买列加密额度。 |
列加密属于敏感操作,即使RAM策略已授权,如果源IP不在白名单内,仍会被安全风控拦截。建议提前与安全团队确认网络白名单。
操作步骤
步骤1:下载并解压工具链
下载dbsec-skills.tgz工具链压缩包,并在本地解压:
tar xzf dbsec-skills.tgz
cd dbsec-skills/skills/column-encryption-rule/scripts步骤2:安装Python依赖
创建虚拟环境并安装依赖:
python3 -m venv .venv
.venv/bin/python -m pip install -r requirements.txt依赖文件(requirements.txt)内容:
aliyun-python-sdk-core>=2.16.0
PyMySQL>=1.1.0后续所有命令均使用项目venv执行:.venv/bin/python。
步骤3:准备云API凭证
复制模板并填写真实AccessKey:
cp .aliyun.env.example .aliyun.env.aliyun.env内容示例:
ALIBABA_CLOUD_ACCESS_KEY_ID=您的AccessKeyId
ALIBABA_CLOUD_ACCESS_KEY_SECRET=您的AccessKeySecret
# 仅使用STS临时凭证时需要,普通AK/SK可删除或留空
ALIBABA_CLOUD_SECURITY_TOKEN=您的STSToken该文件含真实凭据,请妥善保管,切勿泄露。
步骤4:准备加密策略模板
复制规则模板:
cp rule.example.json rule.json推荐将rule.json精简为纯共享策略模板,实例维度信息全部交给columns.csv提供:
{
"ProductId": 5,
"EncAlgorithm": "AES_128_GCM",
"EncryptionKeyMode": "client_key",
"CooperationChannel": "DAS",
"BackendRegionId": "cn-zhangjiakou",
"UserList": [
{
"AccountId": "shared_user",
"AuthRole": "fullAccess",
"EngineType": "MySQL"
},
{
"AccountId": "only_for_instanceB",
"InstanceId": "rm-instanceB",
"AuthRole": "restrictedAccess",
"EngineType": "MySQL"
}
],
"ResourceGroupId": ""
}关键字段说明:
字段 | 说明 |
| 数据库产品类型。实例中的5代表RDS MySQL。同产品策略将该字段保留在顶层即可,跨产品混合策略时需要在 |
| 加密算法,如 |
| 加密密钥模式,如 |
| 固定为 |
| 后端处理地域,固定填 |
| 授权用户列表。 |
AuthRole取值说明:
取值 | 含义 |
| 可查看明文数据 |
| 仅可查看密文,且可用用户密钥解密 |
| 仅可查看密文,不可解密 |
不要在策略顶层指定InstanceId和ServiceRegionId,请在CSV的每行中指定。
步骤5:准备列清单
您可以通过以下两种方式准备列清单:
方式一:手动编写columns.csv
复制模板:
cp columns.example.csv columns.csv逐列写入数据。示例:
RegionId,InstanceId,DbName,TableName,Column,EngineType,ProductId
cn-hangzhou,rm-instanceA,your_database,your_table,email,MySQL,
cn-hangzhou,rm-instanceA,your_database,your_table,phone,MySQL,
cn-beijing,rm-instanceB,another_db,users,id_card,MySQL,也可以将同一张表的多列写在Columns字段中(逗号分隔,加引号):
RegionId,InstanceId,DbName,TableName,Columns,EngineType
cn-hangzhou,rm-instanceA,your_database,your_table,"email,phone",MySQLProductId列为可选列,跨产品混合时填,留空则回退到rule.json顶层值。
方式二:用fetch_schema.py自动导出
先复制模板并填写数据库连接信息:
cp mysql.example.conf mysql.confmysql.conf内容示例(key:value格式):
url:rm-xxxxxxxxxxxxxxxxx.rwlb.rds.aliyuncs.com
user:your_user
pass:your_password查看库表结构(文本格式):
.venv/bin/python fetch_schema.py --config mysql.conf --database your_database直接导出兼容的columns.csv:
.venv/bin/python fetch_schema.py --config mysql.conf --database your_database \
--format csv --region-id cn-beijing --instance-id rm-xxxxxxxxxxxxxxxxx > columns.csv--region-id和--instance-id为CSV模式必填参数,因为它们是云资源信息,数据库schema查询无法获取。导出后通常需手动编辑columns.csv,仅保留需要加密的敏感列。
fetch_schema.py完整参数:
--config 数据库配置文件,默认mysql.conf
--database 只查询指定库,可重复传入;省略则枚举全部业务库
--include-system 包含系统库(information_schema等)
--format json | text | csv,默认text
--region-id csv格式必填:实例所在地域,如cn-beijing
--instance-id csv格式必填:实例ID,如rm-xxxx
--engine-type csv格式的EngineType,默认MySQL步骤6:dry-run演练
正式下发前务必先演练,确认请求体与批次拆分无误。
单次创建演练(不使用CSV):
.venv/bin/python create_data_masking_rule.py \
--env-file .aliyun.env --config rule.json --dry-run批量创建演练(使用CSV):
.venv/bin/python create_data_masking_rule.py \
--env-file .aliyun.env --config rule.json --columns-csv columns.csv --dry-rundry-run输出示例:
BatchCount: 批次数
TotalSubRuleCount: 聚合后的表规则数
TotalUniqueColumnCount: 唯一列数
Batches: 每批对应的InstanceId、ServiceRegionId、SubRuleCount、UniqueColumnCount可选:本地额度预检。如已知最多还能新增50列:
.venv/bin/python create_data_masking_rule.py \
--env-file .aliyun.env --config rule.json --columns-csv columns.csv \
--max-new-columns 50 --dry-run超过--max-new-columns限制时脚本会本地停止,不发请求。
步骤7:正式创建列加密规则
确认演练无误后,去掉--dry-run参数执行。
单次创建:
.venv/bin/python create_data_masking_rule.py \
--env-file .aliyun.env --config rule.json批量创建:
.venv/bin/python create_data_masking_rule.py \
--env-file .aliyun.env --config rule.json --columns-csv columns.csv可选:调整每批SubRule数量(最大100):
.venv/bin/python create_data_masking_rule.py \
--env-file .aliyun.env --config rule.json --columns-csv columns.csv --batch-size 50脚本按RegionId + InstanceId + ProductId自动分组,每个实例拆成独立请求,每批最多100条SubRuleList。请勿手动在一个请求中指定多个实例,否则可能出现规则创建成功但实例在资产中心仍显示灰色的问题。
步骤8:查询验证
使用describe_data_masking.py查询列加密状态。通过--action选择只读接口,均支持--dry-run。
接口(--action) | 说明 | 必填参数 |
| 已授权用户及权限分组 | 无 |
| 实例支持的加密算法 |
|
| 已加密列列表(支持分页与多维过滤) | 可选过滤参数 |
| 列加密实例列表(支持分页与多维过滤) | 可选过滤参数 |
| 实例列加密开通状态 |
|
| 已加密列数量与额度统计 |
|
| 已授权账号数量统计 | 无 |
示例:
# 列出已授权用户
.venv/bin/python describe_data_masking.py --env-file .aliyun.env \
--action DescribeDataMaskingUsers
# 查询某实例支持的加密算法
.venv/bin/python describe_data_masking.py --env-file .aliyun.env \
--action DescribeDataMaskingAlgorithms \
--product-id 5 --service-region-id cn-beijing --instance-id rm-xxxxxxxxxxxxxxxxx
# 分页查询已加密列
.venv/bin/python describe_data_masking.py --env-file .aliyun.env \
--action ListDataMaskingColumns \
--product-ids 5 --db-name your_database --page-size 20 --current-page 1
# 统计已加密列额度
.venv/bin/python describe_data_masking.py --env-file .aliyun.env \
--action GetDataMaskingColumnCount --product-ids 5List类接口支持的过滤与分页参数:--masking-status、--template-id、--risk-level-id、--model-tag-id、--instance-id、--db-name、--table-name、--column-name、--current-page、--page-size、--product-id、--product-ids、--risk-level-ids、--template-rule-ids、--engine-type。
步骤9:管理操作
使用manage_data_masking.py,通过--action选择写接口,全部支持--dry-run预览请求体。列表型参数通过--config指向的JSON文件提供,标量参数既可写在config中也可用CLI选项覆盖(CLI优先)。
接口(--action) | 说明 | 注意事项 |
| 删除加密策略 |
|
| 更新加密策略 |
|
| 批量修改授权账号权限分组 |
|
| 修改实例加密算法 | 需指定 |
| 手动同步全部加密策略 | 无业务参数 |
示例(建议先--dry-run预览,确认后去掉--dry-run执行):
# 删除策略:config提供SubRuleList,ProductId用整数
.venv/bin/python manage_data_masking.py --env-file .aliyun.env \
--action DeleteDataMaskingRule --config delete_rule.json --rule-name rule-demo --dry-run
# 批量修改授权账号权限分组
.venv/bin/python manage_data_masking.py --env-file .aliyun.env \
--action BatchModifyDataMaskingUsers --config batch_users.json \
--auth-role fullAccess --dry-run
# 修改实例加密算法
.venv/bin/python manage_data_masking.py --env-file .aliyun.env \
--action ModifyDataMaskingEncryptionAlgorithm \
--instance-id rm-xxx --product-id 5 --service-region-id cn-beijing \
--encryption-algorithm AES_256_GCM --dry-run
# 手动同步全部加密策略(无业务参数)
.venv/bin/python manage_data_masking.py --env-file .aliyun.env \
--action ManualSyncMaskingRules --dry-run标准工作流速览
完整流程可概括为6步:
1. 准备凭证 cp .aliyun.env.example .aliyun.env # 填写DAS OpenAPI的AK/SK
2. 准备规则模板 cp rule.example.json rule.json # 配置共享加密策略
3. 准备列清单 手动编写columns.csv;或用fetch_schema.py自动导出
4. dry-run演练 添加--dry-run确认请求体与批次
5. 正式下发 去掉--dry-run执行
6. 校验结果 使用describe_data_masking.py查询验证接口默认配置
脚本默认使用以下DAS调用配置:
Domain: das.cn-shanghai.aliyuncs.com
Version: 2020-01-16
Action: CreateDataMaskingRule
Method: POST / HTTPS
RegionId: cn-shanghai(POP接入地域,请勿修改)
CooperationChannel: DAS
BackendRegionId: cn-zhangjiakouRegionId: cn-shanghai是Python SDK与POP请求使用的接入地域,与业务上的ServiceRegionId不同。要加密实例所在地域请通过ServiceRegionId和SubRuleList[].RegionId指定(例如杭州填cn-hangzhou,北京填cn-beijing)。
安全最佳实践
凭据管理:
.aliyun.env、mysql.conf、rule.json、columns.csv均含真实凭据或业务信息,请勿提交到版本管理系统,仅保留*.example模板。最小权限:RAM用户仅授予DAS列加密相关接口权限,优先使用STS临时凭证。
网络管控:列加密属于敏感操作,确保操作源IP在DAS允许网络范围内。
操作前演练:所有写操作(create与manage)均支持
--dry-run,正式下发前务必先演练。额度预检:批量执行前先dry-run确认
TotalUniqueColumnCount,必要时配合--max-new-columns做本地保护。操作审计:脚本基于OpenAPI调用,所有操作均可通过操作审计(ActionTrail)审计。
常见问题
Q:dry-run通过了,但正式创建返回401 Deny怎么办?
A:dry-run只校验本地请求体是否正确,不代表服务端会放行。401 Deny的常见原因:该AccessKey对应的RAM用户缺少DAS列加密接口调用权限;操作源IP不在允许名单;AccessKey被安全风控规则拦截。排查方法:核对RAM策略是否授予对应Action;按提示携带RequestID、AccessKey、源IP联系安全团队;更换一个有权限且在允许网络环境中的AccessKey重试。
Q:批量创建时部分批次失败怎么办?
A:如果超过购买额度,接口会返回
sale_instance_quota_exception。脚本会提示是哪一批失败,已成功的前序批次不会自动回滚。建议批量执行前先dry-run确认TotalUniqueColumnCount,必要时配合--max-new-columns做本地保护。Q:rule.json里要不要写InstanceId?
A:推荐不写。将
rule.json精简为纯共享策略模板,实例维度信息全部交给columns.csv每行提供。这样一份rule.json可以配合任意实例的CSV复用,扩展到多实例时只需修改CSV,无需改动rule.json。Q:UserList怎么配置多个实例的不同授权?
A:通过
InstanceId区分:用户不写InstanceId为共享用户,自动套用到每个实例并回填实例信息;用户写了InstanceId则仅对匹配实例的批次生效,其它批次自动过滤。无需使用嵌套结构。Q:fetch_schema.py导出的CSV为什么缺少RegionId和InstanceId?
A:
RegionId、InstanceId、EngineType是云资源信息,数据库schema查询无法获取。CSV模式下--region-id和--instance-id为必填参数。导出后通常需手动编辑columns.csv,仅保留需要加密的敏感列。Q:BatchModifyDataMaskingUsers改授权后查询发现同一账号挂在两个分组?
A:改授权后
DescribeDataMaskingUsers可能短暂出现同一账号同时挂在两个分组、SyncStatus=1(同步中)。等同步完成(SyncStatus=0)后只保留目标分组,属于正常的服务端异步同步,无需脚本处理。校验时以稍后再查为准。Q:ModifyDataMaskingRule对自定义列加密规则报InvalidParameter?
A:
ModifyDataMaskingRule接口面向模板规则的更新场景。对于通过CreateDataMaskingRule创建的自定义列加密规则(RuleId=0),该接口会返回InvalidParameter "InstanceId",属于业务约束,非脚本缺陷。如需更新自定义列加密规则,请先删除再重新创建。