MySQL 8.0+ audit_log插件必须配对audit_log_policy=ALL、audit_log_format=NEW、audit_log_connection_policy=ON三项参数,缺一不可;仅加载插件不设策略默认只记录失败连接,无法捕获成功SQL注入等攻击行为。

MySQL 8.0+ audit_log 插件必须配对的三个关键参数
只启用 audit_log 插件但不设策略,等于没开——它默认只记录失败连接,而大多数 SQL 注入攻击是成功执行的。必须在 my.cnf 里硬编码以下三项(不能靠 SET 动态修改):
-
audit_log_policy=ALL:否则SELECT类查询全被忽略 -
audit_log_format=NEW:旧格式不记录绑定参数值,看不出实际传入了什么数据 -
audit_log_connection_policy=ON:否则日志里没有客户端 IP 和账号,无法定位攻击源
漏掉任意一项,日志就只剩“谁连上了”,而不是“谁干了什么”。
PostgreSQL pgAudit 的会话级权限陷阱
CREATE EXTENSION pgaudit 只是第一步,真正生效取决于当前会话的角色权限。pgAudit 默认只审计超级用户操作,普通应用账号的查询根本不会进日志。
必须显式给应用账号授权:
- 运行
GRANT pgaudit TO your_app_role - 在
postgresql.conf中设pgaudit.log='all'(不是read或write) - 若用了
pgbouncer,所有连接都显示为pgbouncer用户——得配合pgbouncer的client_hostname日志才能溯源
没做这三步,你看到的只是数据库自己的心跳,不是业务行为。
日志里真正要盯住的异常特征,不是关键词
盯着 UNION SELECT 或 SLEEP(5) 做规则匹配,会被绕过。真实攻击更隐蔽:
- 同一个账号 1 分钟内查了
information_schema.tables+pg_class+sqlite_master(跨库探测) - 正常只查
orders表的接口,突然执行SELECT * FROM users WHERE id = ?(字段名和表名不匹配业务路径) - 查询耗时突增 300% 且返回行数为 0(
BENCHMARK()或盲注试探)
重点不是语句里有什么,而是“这个账号为什么现在查这个东西”。行为建模比字符串匹配管用得多。
监控进程读不了 audit.log?权限和路径得一起改
MySQL 默认把 audit.log 写到 /var/lib/mysql/audit.log,权限是 root:root 600。你的监控脚本如果用 www-data 身份跑,直接被拒——连 cat 都打不开。
解决方法只有两个,缺一不可:
- 在
my.cnf里指定audit_log_file=/var/log/mysql/audit.log(可写目录) - 运行
chown www-data:www-data /var/log/mysql/audit.log并设audit_log_rotate_on_size=100M防止撑爆磁盘
别信“加个 sudo 就行”,生产环境不允许监控进程提权。路径和权限必须同步处理。
真实有效的监控不是堆日志,是让每条记录都带上下文:谁、从哪来、查了什么、花了多久、返回多少行。少一个维度,就可能漏掉一次真正的注入尝试。

















