最快最有效的方法是使用 iptables 或 firewalld 在系统网络层封禁 ip:iptables 用 -i input 插入 drop 规则,firewalld 用 --add-rich-rule 拒绝 tcp 3306 端口,并需 --permanent 生效。

iptables 或 firewalld 直接封禁 IP 最快最有效
MySQL 本身不提供“全局禁止某 IP 连接”的开关,靠 GRANT 权限只能控制登录后的操作,拦不住握手阶段的连接请求。真要阻止特定 IP 连入,得在系统网络层动手。
常见错误是只改 MySQL 的 bind_address 或以为 DROP USER 'user'@'192.168.1.100' 就能断连——其实只要该 IP 还能发 TCP 包到 3306 端口,MySQL 就会响应 SYN-ACK,甚至可能抛出 Access denied for user 错误,反而暴露服务存在。
- Linux 上优先用
iptables -I INPUT -s 203.0.113.45 -p tcp --dport 3306 -j DROP(注意-I插入最前,避免被其他规则放过) - firewalld 用户用
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.45" port port="3306" protocol="tcp" reject',别漏--permanent - 封禁后务必
telnet 203.0.113.45 3306测试是否真的无响应(不是 Connection refused,而是超时或直接拒绝)
GRANT 和 host 字段配合才能精准限制可连来源
GRANT 不是用来“禁止”,而是定义“谁可以从哪来连”。关键在用户名后面的 @'host' 部分——它匹配的是客户端发起连接时 MySQL 看到的源 IP 或主机名,不是你本地配的 hosts。
容易踩的坑:用 'user'@'%' 授予权限后,再执行 REVOKE ALL ON *.* FROM 'user'@'192.168.1.100' 是无效的,因为权限是按 user@host 组合存储的,REVOKE 只能撤销明确存在的那个组合,不会从通配符里剔除单个 IP。
- 想让某用户只允许从内网连:建
'app'@'10.0.0.%'并只给这个账号权限,删掉所有'app'@'%' - 禁止某 IP 使用 root:确认没有
'root'@'203.0.113.45'这条记录,如果有,用DROP USER 'root'@'203.0.113.45';别只REVOKE -
host字段支持 DNS 名,但解析依赖 MySQL 服务器的skip_name_resolve=OFF,开启后只认 IP,更可控
MySQL 8.0+ 的 CONNECTION_CONTROL 插件可临时限流,但不等于封禁
这个插件能对失败登录次数超限的 IP 延迟响应(比如加 1 秒延迟),目标是防暴力破解,不是阻止连接。它不拦截 TCP 握手,也不影响已建立连接,更不会让 IP 彻底连不上。
启用后如果看到 ERROR 1045 (28000): Access denied for user 响应变慢,那是它在起作用;但如果看到 Can't connect to MySQL server on 'x.x.x.x',说明根本没走到 MySQL,是防火墙干的。
- 插件需手动安装:
INSTALL PLUGIN connection_control SONAME 'connection_control.so' - 关键参数是
connection_control_failed_connections_threshold(默认 3)和connection_control_max_connection_delay(默认 2147483647 毫秒) - 它记录的是“认证失败”的 IP,如果攻击者用正确密码连,或连的是不存在的账号,这插件完全不触发
云环境(如阿里云 RDS、AWS RDS)必须走安全组,不能依赖本地 iptables
云数据库实例通常不给你 root shell,iptables 根本不可用。所有网络控制必须通过厂商提供的安全组(Security Group)或白名单机制实现。
典型错误:在 RDS 控制台只设置了 IP 白名单,却忘了自己本地出口 IP 是动态的,或者公司 NAT 出口 IP 改了没同步更新,结果把自己锁在外面。
- 阿里云 RDS 的白名单分“普通白名单”和“高安全白名单”,后者强制要求 SSL 连接,且不支持
%通配 - AWS RDS 安全组规则中,
Source填203.0.113.45/32才是封单 IP,填203.0.113.45可能被解释成 CIDR 导致意外放行 - 腾讯云 CDB 的“网络控制”里,禁止 IP 要选“拒绝”,不是删掉对应条目——删了只是恢复默认策略(通常是放行)
真正难的不是写那条 iptables 命令,而是确认封禁生效时,你的监控、备份、运维跳板机是否还连得上。IP 封禁一旦生效,连 mysqladmin ping 都收不到响应,排查窗口极小。











