项目每日需执行FLUSH HOSTS的原因及永久解决方法
问题根因
这个报错是MySQL/MariaDB的内置防护机制触发:数据库会统计每个来源IP的累计连接错误次数(包括密码错误、连接中途中断、握手超时、解析失败等情况),当次数超过max_connect_errors参数设定的阈值时,就会直接拉黑对应IP,拒绝所有后续连接。手动执行FLUSH HOSTS;只是临时清空错误计数,没有解决触发计数的根源问题,必然会反复报错。
永久修复步骤
1. 先封堵外部恶意访问(最高优先级)
LEMP栈的PHP和MySQL默认部署在同一台服务器,不需要对外暴露3306数据库端口,绝大多数反复触发连接错误的原因是公网爬虫、端口扫描工具反复发无效连接请求,直接用防火墙限死端口权限即可:
ufw deny 3306 ufw allow in from 127.0.0.1 to any port 3306 ufw reload
2. 排查业务侧的连接错误
执行以下命令查看MySQL错误日志,定位具体的错误来源:
grep -E "Access denied|Aborted connection" /var/log/mysql/error.log
常见的业务侧问题及修复方式:
- 项目数据库配置错误:如果日志里大量出现对应数据库用户的密码错误记录,直接去项目配置文件修正密码即可(WordPress对应
wp-config.php,Laravel对应根目录.env,其他PHP项目参考对应框架的数据库配置项),修改后可以用mysql -u 你的数据库用户名 -p在命令行测试密码是否能正常登录。 - 连接未正常释放:如果日志里大量出现Aborted connection记录,检查PHP脚本是否存在未主动关闭数据库连接的问题,也可以在
php.ini中开启mysqli.reconnect = On自动重连。 - 反向解析超时:MySQL默认会对连接来源做DNS反向解析,公网IP解析失败时会计入连接错误,后续配置参数时直接关闭该功能即可。
3. 调整MySQL配置做兜底防护
- 编辑MySQL配置文件,DigitalOcean的LEMP镜像默认配置路径为
/etc/mysql/mysql.conf.d/mysqld.cnf(如果用的是MariaDB,路径为/etc/mysql/mariadb.conf.d/50-server.cnf),在[mysqld]配置段添加以下两行:# 调高连接错误阈值,避免偶发错误触发拉黑 max_connect_errors = 10000 # 关闭DNS反向解析,减少连接错误和建连延迟 skip_name_resolve = ON - 保存配置后重启MySQL服务生效:
# MySQL执行这条 systemctl restart mysql # MariaDB执行这条 systemctl restart mariadb - 重启后登录MySQL执行以下命令,确认参数已经生效:
SHOW VARIABLES LIKE 'max_connect_errors'; SHOW VARIABLES LIKE 'skip_name_resolve';
注意事项
不要直接把max_connect_errors设为无限大,先完成防火墙规则配置和业务侧错误修复,调大阈值只是兜底手段,避免完全丢失暴力破解防护。所有配置生效后不需要再手动执行FLUSH HOSTS;,正常观察1-2天即可确认问题完全解决。
内容的提问来源于stack exchange,提问作者rootShiv
相关产品推荐
相关产品推荐

