shardingsphere-proxy是目前唯一开箱支持权限感知动态脱敏的代理,自5.3.0起可通过自定义maskencryptalgorithm实现字段级实时脱敏,并结合rbac控制不同角色的脱敏策略。

MySQL代理中间件本身不内置动态脱敏能力,必须配合规则引擎或自定义逻辑层才能实现——直接在 ProxySQL、MyCAT 或 ShardingSphere-Proxy 中启用“查询时脱敏”,本质是拦截 SELECT 语句、重写字段表达式、再转发执行。
ProxySQL 不支持原生动态脱敏,需绕行改写 SQL
ProxySQL 是纯 SQL 路由与负载均衡代理,没有字段级数据变形能力。想让它“返回脱敏后的手机号”,不能靠配置开关,只能靠 mysql_query_rules 表做正则替换:
- 它只能对整个查询文本做字符串替换(比如把
SELECT phone FROM users替换成SELECT CONCAT(LEFT(phone,3),'****',RIGHT(phone,4)) AS phone FROM users) - 这种替换极易出错:遇到子查询、
UNION、别名嵌套、函数包裹(如IFNULL(phone,''))就会失效 - 无法区分权限——所有走该规则的用户都看到同样脱敏结果,做不到“DBA 看明文、开发看星号”
- 不推荐用于生产环境的敏感字段脱敏,仅适合简单报表类只读场景临时应急
MyCAT 的 dataNode + 自定义函数方案有局限
MyCAT 支持在 schema.xml 中为字段绑定 function,例如用 sharding-by-md5-salt 做分片,但官方未提供身份证/手机号脱敏函数。你可以:
- 在 MyCAT 源码中新增一个 Java 类实现
PhoneMaskFunction,编译进mycat-server.jar - 在
rule.xml中注册该函数,并在table定义中指定column使用它 - 但该函数只在写入路由阶段生效,对
SELECT返回值无影响;若强行在select中调用函数,会因 MyCAT 不解析函数体内部逻辑而报错java.lang.UnsupportedOperationException: function not supported - 真正可行的做法仍是把脱敏逻辑下沉到视图或应用层,MyCAT 仅作透明转发
ShardingSphere-Proxy 是目前唯一开箱支持权限感知动态脱敏的代理
ShardingSphere-Proxy(非 JDBC 版)从 5.3.0 起正式支持 mask 功能,且能结合 rbac(基于角色的访问控制)做细粒度策略:
- 脱敏规则定义在
config-sharding.yaml的rules下,指定logic-column(如id_card)、plain-column(明文存哪)、cipher-column(密文存哪),以及encryptor-name - 关键点在于:它支持
query-with-cipher-column: false配置,即查的时候不走密文列,而是实时调用加密器的decrypt()——但注意,这是“解密”,不是“脱敏”;要实现“只显示前3后2”,得自定义MaskEncryptAlgorithm实现类,重写encrypt()为截取+填充逻辑,decrypt()直接返回原值(因为脱敏不可逆) - 权限控制需搭配 ShardingSphere 的
authority模块:为不同用户分配privilege,再通过mask规则中的props设置mask-type: partial或mask-type: full,最终由插件判断是否应用该规则 - 真实部署时,务必关闭
props.mask-algorithm-type: AES这类加密型算法,否则你会看到一串 Base64,而不是110****1234
动态脱敏最易被忽略的一点:代理层看到的是最终拼好的 SQL,它无法感知业务语义。比如 SELECT * FROM users WHERE id = ? 中的 ? 是用户 ID 还是身份证号?代理不知道。所以所有靠谱的动态脱敏方案,都要求你在建表时就约定好字段语义(如列名含 _masked 后缀),或强制使用逻辑列名(logic-column: phone),否则规则匹配就是盲人摸象。











