2026/10/27 3:27:48

MySQL安全排查:利用general_log定位异常访问

MySQL安全排查:利用general_log定位异常访问 1. 问题背景MySQL账号安全排查的痛点最近在排查数据库安全问题时发现了一个棘手的情况审计日志中频繁出现不明IP的访问记录但常规的排查手段无法快速定位问题源头。这种情况在MySQL运维中并不罕见——当系统突然出现性能波动或数据异常时我们常常需要回答两个关键问题谁在访问数据库和这些访问来自哪里传统的排查方法主要有三种查看information_schema.processlist只能看到当前连接历史记录无法追溯分析慢查询日志仅记录执行时间超过阈值的SQL信息不完整审计插件需要额外安装配置对线上环境有侵入性而general_log这个原生功能往往被忽视。它能完整记录所有MySQL服务端收到的请求包括客户端连接信息、执行的SQL语句以及时间戳是排查未知访问源的利器。下面我将结合实战案例详细说明如何利用这个数据库监控摄像头来锁定可疑访问。注意开启general_log会带来约5%-15%的性能开销建议仅在排查期间临时启用2. general_log的配置与启用2.1 检查当前日志状态首先连接MySQL执行SHOW VARIABLES LIKE general_log%;典型输出如下-------------------------------------------- | Variable_name | Value | -------------------------------------------- | general_log | OFF | | general_log_file | /var/lib/mysql/query.log | --------------------------------------------2.2 动态开启日志记录无需重启服务直接运行SET GLOBAL general_log ON; SET GLOBAL log_output TABLE; -- 可选FILE/TABLE/NONE推荐使用TABLE模式日志会存入mysql.general_log表方便SQL查询分析。FILE模式则直接写入文件系统适合大规模日志场景。2.3 关键参数说明参数名可选值推荐设置作用说明general_logON/OFF按需开启总开关log_outputFILE/TABLE/NONETABLE日志存储形式general_log_file文件路径自定义路径FILE模式下的日志文件位置3. 日志分析与可疑访问定位3.1 基础查询获取完整访问记录SELECT event_time, user_host, command_type, argument FROM mysql.general_log ORDER BY event_time DESC LIMIT 100;关键字段解析user_host格式为username[client_name] hostname [IP]command_typeConnect/Query/Quit等argument执行的SQL内容3.2 识别异常连接的特征通过以下特征筛选可疑记录非常规时间段的访问如凌晨2-4点使用默认账号或弱密码如root/空密码来自非常见IP段的连接高频的Connect/Disconnect操作执行敏感操作如DROP TABLE、GRANT等示例排查SQL-- 统计各IP的连接次数 SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(user_host,[,-1),],1) AS client_ip, COUNT(*) AS connection_count FROM mysql.general_log WHERE command_type Connect GROUP BY client_ip ORDER BY connection_count DESC; -- 查找执行过DROP/ALTER的操作 SELECT * FROM mysql.general_log WHERE argument LIKE %DROP% OR argument LIKE %ALTER%;3.3 高级分析技巧3.3.1 关联performance_schemaSELECT gl.event_time, gl.user_host, gl.argument, ps.HOST FROM mysql.general_log gl JOIN performance_schema.threads ps ON ps.PROCESSLIST_ID gl.thread_id WHERE gl.command_type Connect;3.3.2 使用正则过滤-- 匹配特定IP段 SELECT * FROM mysql.general_log WHERE user_host REGEXP 192\\.168\\.1\\.[0-9]{1,3};4. 实战案例定位恶意扫描行为某次安全审计中发现大量异常连接通过以下步骤锁定问题发现特征每分钟约30次Connect且user_host格式异常SELECT user_host, COUNT(*) FROM mysql.general_log WHERE command_type Connect GROUP BY user_host;输出显示大量1.1.1.%格式的连接1.1.1.x为示例IP追踪完整访问链SELECT * FROM mysql.general_log WHERE user_host LIKE %1.1.1.% ORDER BY event_time;发现攻击者在尝试常见账号组合root/空密码、admin/admin等应对措施立即防火墙封禁该IP段修改所有账号为强密码设置skip_name_resolve防止反向解析消耗资源5. 性能优化与注意事项5.1 日志清理策略长期开启general_log会导致日志表/文件体积暴涨写入性能下降磁盘空间占用建议的维护方案-- 定期清理旧日志TABLE模式 TRUNCATE TABLE mysql.general_log; -- 或按时间删除 DELETE FROM mysql.general_log WHERE event_time DATE_SUB(NOW(), INTERVAL 7 DAY); -- FILE模式需手动轮转 mv general.log general.log.old mysqladmin flush-logs5.2 生产环境最佳实践使用FILE模式时将日志放在独立磁盘分区高并发场景建议设置log_outputTABLE并定期导出配合脚本实现自动报警如检测到敏感操作#!/bin/bash alert_operations(DROP GRANT FLUSH PRIVILEGES) for op in ${alert_operations[]}; do mysql -e SELECT * FROM mysql.general_log WHERE argument LIKE %${op}% \ | mail -s MySQL敏感操作告警 adminexample.com done6. 延伸应用场景6.1 SQL审计合规满足GDPR等法规要求记录所有数据访问行为-- 创建审计视图 CREATE VIEW sql_audit AS SELECT event_time, user_host, argument FROM mysql.general_log WHERE argument NOT LIKE %general_log%; -- 排除日志查询自身6.2 性能问题排查分析特定时间段的SQL模式SELECT LEFT(argument, 50) AS short_sql, COUNT(*) AS execution_count, AVG(LENGTH(argument)) AS avg_length FROM mysql.general_log WHERE event_time BETWEEN 2023-01-01 14:00 AND 2023-01-01 15:00 AND command_type Query GROUP BY short_sql ORDER BY execution_count DESC;6.3 应用程序调试验证ORM框架生成的真实SQLSELECT argument FROM mysql.general_log WHERE user_host LIKE app_user%% AND argument LIKE %FROM orders%;我在实际使用中发现结合general_log与tcpdump能获得更完整的访问链路。例如当遇到SSL加密连接时可以先用tcpdump抓包获取原始IP再通过general_log分析具体操作。这种组合拳在应对高级威胁时特别有效。