ProxySQL是当前最成熟SQL协议层防御中间件,支持协议解析、重写与拦截;MaxScale侧重路由高可用,SQL审计能力弱;Nginx等TCP代理无法识别SQL语义。

SQL代理中间件选型:为什么绕不开 ProxySQL 和 MaxScale
真正落地 SQL 协议层防御时,ProxySQL 是当前最成熟的选择——它不是简单转发,而是能解析、重写、拦截甚至模拟 MySQL 协议的中间层。相比之下,MaxScale 更侧重路由与高可用,SQL 审计和规则拦截能力弱于 ProxySQL;用 Nginx 或自研 TCP 代理则完全无法识别 SQL 语义,等于在防火墙上画窗户。
常见错误现象:SELECT * FROM users WHERE id = ? 被正常放行,但攻击者拼接 OR 1=1 -- 后仍抵达后端——说明代理没开启 query rewrite 或没配置匹配规则。
-
ProxySQL必须启用mysql-query_processor模块(默认关闭),否则所有规则不生效 - 规则匹配基于正则,不是字符串模糊匹配,
.*union.*select.*会漏掉换行或注释分隔的变体 - 生产环境务必关闭
mysql-have_ssl=0,否则 TLS 终止后明文 SQL 在代理内存中裸奔
SQL注入特征拦截:别只靠关键词黑名单
单纯匹配 UNION SELECT 或 OR 1=1 极易被绕过,真实攻击常使用大小写混写、内联注释 /*!50000SELECT*/、编码变形或函数嵌套。有效做法是结合语法结构识别 + 行为异常检测。
使用场景:用户输入直接拼入 WHERE 条件、ORDER BY 后的字段名、LIMIT 后的偏移量。
- 在
mysql_query_rules表中优先启用apply=1的高置信规则,例如匹配SELECT.*FROM.*WHERE.*[^\s]+=[^\s]+(?:\s+OR\s+\d+=\d+|\s+AND\s+\d+=\d+) - 对 ORDER BY / GROUP BY 后的字段名,强制要求白名单校验(如只允许
id、created_at),用mysql-query_processor的replace_pattern剥离非法内容 - 开启
stats_mysql_query_digest并设置digest_text阈值,自动标记高频变异 SQL(如同一模板下参数位置突变)
权限最小化落地:代理层不能替代 DB 用户隔离
很多人以为加了代理就能“一堵永逸”,结果发现 ProxySQL 以一个高权限账号连接后端 MySQL,一旦代理被绕过或配置出错,攻击者直接获得该账号全部权限。真正的最小化必须分两层控制。
性能影响:每条 SQL 经代理增加 0.2–0.8ms 延迟,但若在代理层做字段级脱敏(如自动 REPLACE(phone, '...', '**')),延迟可能翻倍,需权衡。
- 后端 MySQL 必须创建专用账号,仅授予必要库表的
SELECT/INSERT权限,禁用FILE、EXECUTE、PROCESS -
ProxySQL的mysql_users表中,为每个应用配独立用户名,并绑定default_hostgroup和max_connections - 禁止在代理配置中硬编码密码,改用
mysql-native_password+ 外部密钥管理服务(如 HashiCorp Vault 注入)
上线前必验的三个断点
很多团队卡在“规则写了但没生效”,问题往往出在协议握手阶段或缓存机制上,不是规则本身写错。
- 连上
ProxySQL管理接口(默认6032),查SELECT * FROM stats_mysql_query_rules;确认hits列是否增长,不增长说明流量根本没走规则链 - 用
mysql -h 127.0.0.1 -P 6033 -u test_user连代理,执行SELECT @@version_comment;,返回值应含ProxySQL字样,否则客户端直连了 MySQL - 修改规则后执行
LOAD MYSQL QUERY RULES TO RUNTIME;,但忘了SAVE MYSQL QUERY RULES TO DISK;,重启后规则丢失
最常被忽略的是:MySQL 8.0 默认开启 caching_sha2_password 插件,而旧版 ProxySQL(Access denied,实际是握手协议不匹配。

















