列加密规则自动化管理最佳实践

更新时间:
复制 MD 格式

数据库自治服务DAS提供列加密(数据脱敏)规则管理工具链,支持通过Python脚本批量创建、查询和管理列加密规则。本文介绍如何使用该工具链完成列加密规则的自动化管理。

工具链概述

业务场景

在数据库安全合规实践中,通常存在以下需求:

  • 批量加密:需要对多个实例、多个库表下的敏感列(手机号、身份证号、邮箱等)批量配置列加密规则。

  • 查询审计:需要查询已加密列列表、实例开通状态、额度使用情况、已授权用户及权限分组。

  • 策略管理:需要删除或更新加密策略、批量修改授权账号权限、修改实例加密算法、手动同步策略。

  • 安全合规:避免在控制台手动操作,通过脚本实现可审计、可回溯、可预览的标准化流程。

工具链架构

工具链包含四个Python脚本,通过阿里云Python V1 SDK的CommonRequest机制调用DAS OpenAPI。所有脚本复用同一套凭据加载逻辑,均支持--dry-run演练模式。

脚本

职责

写操作

create_data_masking_rule.py

创建列加密规则(核心脚本,含可复用凭据与请求库)

是

fetch_schema.py

连接数据库读取库表结构,导出列清单

否

describe_data_masking.py

只读查询(用户、算法、已加密列、实例、状态、额度统计)

否

manage_data_masking.py

写操作(删除/更新策略、批量改授权、改算法、手动同步)

是

配置文件设计

配置分为4类,每类提供真实文件与.example模板成对设计,职责独立:

类别

真实文件

模板

消费方

云API凭据

.aliyun.env

.aliyun.env.example

create / describe / manage

数据库连接

mysql.conf

mysql.example.conf

fetch_schema.py

列清单(CSV)

columns.csv

columns.example.csv

create

加密策略(JSON)

rule.json

rule.example.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": ""
}

关键字段说明:

字段

说明

ProductId

数据库产品类型。实例中的5代表RDS MySQL。同产品策略将该字段保留在顶层即可,跨产品混合策略时需要在columns.csv中逐行指定。

EncAlgorithm

加密算法,如AES_128_GCM、AES_256_GCM。

EncryptionKeyMode

加密密钥模式,如client_key。

CooperationChannel

固定为DAS。

BackendRegionId

后端处理地域,固定填cn-zhangjiakou。

UserList

授权用户列表。AccountId填数据库账号名(非云账号)。不指定InstanceId时表示该账号为共享用户。如指定InstanceId,则仅对该实例生效。

AuthRole取值说明:

取值

含义

fullAccess

可查看明文数据

restrictedAccess

仅可查看密文,且可用用户密钥解密

noneAccess

仅可查看密文,不可解密

说明

不要在策略顶层指定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",MySQL

ProductId列为可选列,跨产品混合时填,留空则回退到rule.json顶层值。

方式二:用fetch_schema.py自动导出

先复制模板并填写数据库连接信息:

cp mysql.example.conf mysql.conf

mysql.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-run

dry-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)

说明

必填参数

DescribeDataMaskingUsers

已授权用户及权限分组

无

DescribeDataMaskingAlgorithms

实例支持的加密算法

--product-id / --service-region-id / --instance-id

ListDataMaskingColumns

已加密列列表(支持分页与多维过滤)

可选过滤参数

ListDataMaskingInstances

列加密实例列表(支持分页与多维过滤)

可选过滤参数

CheckDataMaskingInstance

实例列加密开通状态

--product-id / --service-region-id / --instance-id

GetDataMaskingColumnCount

已加密列数量与额度统计

--product-ids

GetDataMaskingAccountCount

已授权账号数量统计

无

示例:

# 列出已授权用户
.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 5

List类接口支持的过滤与分页参数:--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)

说明

注意事项

DeleteDataMaskingRule

删除加密策略

SubRuleList[].ProductId为整数(int64)

ModifyDataMaskingRule

更新加密策略

SubRuleList[].ProductId为字符串(string);RegionId/ProductId/InstanceId/DbName/TableName/ColumnsName必填

BatchModifyDataMaskingUsers

批量修改授权账号权限分组

--auth-role必填,config提供UserList

ModifyDataMaskingEncryptionAlgorithm

修改实例加密算法

需指定--instance-id/--product-id/--service-region-id/--encryption-algorithm

ManualSyncMaskingRules

手动同步全部加密策略

无业务参数

示例(建议先--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-zhangjiakou
重要

RegionId: 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",属于业务约束,非脚本缺陷。如需更新自定义列加密规则,请先删除再重新创建。