mysql官方不提供关闭初始tcp握手banner版本号的机制,只能通过proxysql等代理修改mysql-server_version值,或用haproxy/iptables过滤,同时需关闭错误信息暴露、限制information_schema访问、禁用旧协议。

MySQL 服务端 banner 如何泄露版本号
MySQL 默认在 TCP 握手阶段(即未认证前)直接返回带版本号的 banner,例如 5.7.41-log 或 8.0.33。攻击者用 nc -v 127.0.0.1 3306 或 nmap -sV 就能拿到,无需登录。这不是配置项泄露,而是协议层固有行为。
禁用 version_banner 的正确方式(仅限 MySQL 8.0.22+)
新版 MySQL 提供了 version_tokens 插件配合 version_token_remove(),但真正起效的是 show_compatibility_56 和 version_comment 无关——关键参数是 version_tokens 插件本身不控制 banner,真正可干预 banner 的只有 version_tokens 启用后配合 version_token_remove('mysql_version'),但该操作对初始握手 banner 无效。
实际有效手段是:从 MySQL 8.0.22 起,可通过启动参数 --version-token-remove 或运行时设置 SET GLOBAL version_tokens_remove = 'mysql_version',但这仍不隐藏 banner。
结论:MySQL 官方**不提供关闭初始 banner 版本号的机制**。所谓“隐藏”只能靠中间层或网络层拦截。
- 确认当前 banner 泄露:执行
nc -w1 localhost 3306 | hexdump -C | head -n1,查看前几个字节是否含 ASCII 版本字符串 - MySQL 8.0.22+ 的
version_tokens插件仅影响SELECT VERSION()和SHOW VARIABLES LIKE 'version%',不影响 TCP banner - 试图修改源码或 patch mysqld 二进制文件属于高风险操作,不建议生产环境使用
真正可行的隐藏方案:TCP 层代理或防火墙过滤
既然 MySQL 服务自身不支持屏蔽 banner,就只能在外围做文章。最稳定、兼容性最好的方式是加一层轻量代理,把 banner 中的版本字段抹掉或替换为通用字符串。
- 用
haproxy做 TCP 代理,在frontend段启用tcp-request inspect-delay 5s,再用tcp-response content replace替换 banner 中类似5\.7\.[0-9]+的子串(需开启option tcp-check并谨慎测试) - 用
iptables + string module在 INPUT 链匹配并 DROP 含版本号的初始响应包(不推荐:易误杀、不可靠) - 更稳妥的做法是部署
mysql-proxy(已归档)或ProxySQL,在mysql_query_rules中无法改 banner,但可通过admin variables设置mysql-server_version为任意值(如5.5.55),该值会出现在 handshake packet 的 server_version 字段中 —— 这才是唯一可控点
例如 ProxySQL 启动后执行:
UPDATE global_variables SET variable_value='5.5.55' WHERE variable_name='mysql-server_version';<br>LOAD MYSQL VARIABLES TO RUNTIME;
配套必须做的最小加固动作
光改 banner 没用,攻击者仍可能通过 SQL 行为指纹、错误信息、information_schema 表结构等反推版本。以下三项必须同步执行:
- 关闭错误信息暴露:在 my.cnf 中设
log_error_verbosity = 1(MySQL 8.0+),并确保应用不将ERROR 1234 (HY000): Unknown error类原始报错直接返回给前端 - 限制 information_schema 访问:创建专用账号时用
REVOKE SELECT ON information_schema.* FROM 'appuser'@'%',MySQL 8.0+ 还可启用check_proxy_users插件做更细粒度控制 - 禁用旧协议和调试功能:确认
skip_show_database开启,local_infile = OFF,且未启用mysqlx插件(除非真需要 X Protocol)
banner 只是第一眼信息,真正的版本识别往往来自 SELECT @@version_compile_os, @@version_comment 或 SHOW PLUGINS 输出。别只盯着那个 nc 看到的字符串。











