在业务规模扩张之后,单节点数据库往往难以支撑吞吐与容量,团队会引入分布式数据库来分片存储数据。此时SQL请求可能经过代理层、协调节点再落到具体分片,安全问题不再只关乎某一个实例,而是横跨整个集群。我们需要从访问控制、语句审计与数据保护几个维度来设计SQL安全策略。

一、账号与权限的最小化分配
分布式数据库通常提供统一入口,但若给应用账号赋予所有分片的写权限,一旦凭证泄露影响面极大。建议按业务域创建账号,并利用协调层路由限制其可访问的逻辑库。
1.1 基于角色的权限模型
通过角色绑定常用权限集合,再赋给账号,可降低误操作概率。以下示例在MySQL兼容协议中创建只读角色:
-- 创建只读角色 CREATE ROLE 'app_ro'@'%'; -- 授予订单库查询权限 GRANT SELECT ON order_db.* TO 'app_ro'@'%'; -- 将角色赋予应用账号 GRANT 'app_ro' TO 'service_a'@'192.168.0.1';
二、SQL注入的防护与审计
分片代理如果直接拼接用户输入,攻击者可利用特殊字符改变语义。应使用预编译语句,并开启代理层SQL审计,记录来源IP与执行计划。
2.1 预编译示例
在Java应用中通过PreparedStatement避免拼接:
String sql = "SELECT user_id FROM user_tab WHERE phone = ?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setString(1, requestPhone); ResultSet rs = ps.executeQuery();
2.2 审计字段设计
审计日志建议包含下列核心字段,方便溯源:
| 字段 | 说明 |
|---|---|
| client_ip | 发起SQL的客户端地址 |
| sql_text | 实际执行的语句 |
| shard_id | 路由到的分片编号 |
| exec_time | 执行耗时毫秒 |
三、动态数据脱敏与传输加密
对于手机号、身份证等敏感列,可在代理层配置脱敏规则,普通账号查询时返回掩码。同时节点间应使用TLS,防止抓包窃取。
3.1 脱敏规则配置
以常见代理配置为例,对phone列做星号处理:
<mask-rule> <column>phone</column> <type>star</type> <show>3,4</show> </mask-rule>
3.2 启用TLS
在连接串中要求加密,避免明文传输:
ALTER INSTANCE ENABLE TLS; SET GLOBAL require_secure_transport = ON;
四、实践中的注意点
- 分片键尽量避免使用用户输入,减少越权跨片查询。
- 定期回收长期未用的账号与角色,降低闲置风险。
- 将SQL审计接入集中日志,设置异常频次告警。
安全策略不是一次性工作,应随集群扩容与业务变化持续调整,才能在分布式环境下守住SQL访问边界。
通过上述权限、注入防护、脱敏与加密的组合,团队可以在分布式数据库中建立可落地的SQL安全体系,既支撑弹性扩展,也满足合规要求。