phpMyAdmin 无内置IP拦截功能,需通过日志联动iptables/nftables实现防爆破:启用错误日志、准确提取REMOTE_ADDR、频控拉黑、规则持久化及日志闭环验证。
phpMyAdmin 自带的 $cfg['LoginCookieValidity'] 和 $cfg['LoginCookieStore'] 不拦 IP
很多人误以为调低登录有效期或强制 cookie 存储就能“防爆破”,其实这只是控制会话生命周期,和 ip 拦截完全无关。phpmyadmin 本身没有内置 ip 黑名单机制,config.inc.php 里也找不到 ip_blacklist 这类配置项。所有基于 web 层的“拦截”(比如用 apache 的 mod_rewrite 或 nginx 的 deny)都容易被绕过——攻击者换 ua、加代理、用脚本轮询,规则一多还可能误杀合法用户。
真正起效的是把失败记录导出到系统防火墙(iptables / nftables)
核心思路是:让 phpMyAdmin 的登录失败日志变成防火墙规则的输入源。需要两步联动:
- 启用 phpMyAdmin 的错误日志,确保
$cfg['LogErrors'] = true;,且 Web 服务器(如 Apache)把phpMyAdmin/error_log写入可读路径(例如/var/log/phpmyadmin/error.log) - 写一个轻量级轮询脚本,用
grep找出含"Login failed"和真实客户端 IP 的行(注意:得从$_SERVER['REMOTE_ADDR']记录,不是X-Forwarded-For,后者不可信),再用iptables -I INPUT -s $IP -j DROP加规则 - 必须加频控和过期:同一 IP 5 分钟内失败 ≥3 次才拉黑,且规则带
--seconds 3600(用iptables-extensions的recent模块)或用nftables的@blacklistset 配超时
示例关键片段(watch-pma-fail.sh):
grep "Login failed" /var/log/phpmyadmin/error.log | \
awk '{print $(NF-1)}' | \
sort | uniq -c | \
awk '$1 >= 3 {print $2}' | \
while read ip; do
iptables -C INPUT -s "$ip" -j DROP 2>/dev/null || \
iptables -I INPUT -s "$ip" -m recent --set --name BLACKLIST --rsource
done
nginx + php-fpm 环境下,REMOTE_ADDR 经常不准
如果你用 nginx 反代,又没配透传,$_SERVER['REMOTE_ADDR'] 会固定是 127.0.0.1 或上游地址,导致黑名单全加错。必须确认两点:
- nginx 配置里有
fastcgi_param REMOTE_ADDR $remote_addr;(不是$http_x_forwarded_for) - phpMyAdmin 的
config.inc.php中未启用$cfg['AllowArbitraryServer'] = true;,否则攻击者可伪造server参数干扰日志 - 如果用了 CDN 或 WAF,要改用
$http_cf_connecting_ip(Cloudflare)或$http_true_client_ip(Akamai),并在 nginx 中显式赋给REMOTE_ADDR
别忽略 iptables 规则持久化和日志闭环
重启后规则消失是最常见的失效原因。CentOS 7+ 默认用 nftables,但很多脚本还写 iptables-save,结果根本没保存。必须明确:
立即学习“PHP免费学习笔记(深入)”;
- 用
nft list ruleset > /etc/nftables.conf并启用nftables服务,而不是依赖旧版iptables-services - 在防火墙规则里加
-j LOG --log-prefix "PMA-BL:",再用journalctl -t kernel | grep "PMA-BL"核对是否真生效 - 定期清理:写个 cron 清掉 24 小时前的
recent记录,或用nft的 timeout(如timeout 1h)自动剔除
最麻烦的其实是日志格式不一致——不同 phpMyAdmin 版本、不同 PHP SAPI(Apache module vs php-fpm)、不同错误触发路径(空密码 vs 错误用户名),输出的 IP 位置可能差 1–2 列。别指望一次正则通吃,先 tail -f 看几分钟真实日志再定提取逻辑。



















