MySQL 与 Redis 监听地址核查:公网暴露排查、绑定回环与业务连通性回滚清单

枫少@KillBoy
枫少@KillBoy
枫少@KillBoy
管理员
431
文章
0
粉丝
安全运维221字数 2764阅读9分12秒阅读模式
AI智能摘要
MySQL 配置文件里明明写着 bind-address=127.0.0.1,用 ss 一查监听地址却是 0.0.0.0?启动参数、conf.d 追加配置和云安全组三层来源,任何一处都可能让数据库和 Redis 悄悄对公网敞开。改之前还得先摸清业务依赖——远程管理工具会不会失效、连接来源是否全在本机。怎样在不停业务的前提下,逐步把监听收回回环地址并备好回滚?
— AI 生成的文章内容摘要

先界定这次检查的范围:我们只关心 MySQL 和 Redis 这两个服务实际监听的网络地址,以及这个监听行为对 WordPress/LAMP 站点的影响。换句话说,要回答三个问题——服务在听什么地址、配置和启动参数是否一致、以及改动监听后业务是否还能正常走通。整个过程按“盘点、核对、小步调整、验证、回滚准备”的顺序推进,每一步都有明确的执行位置和预期现象,方便你边做边复核。

第一步:用 ss 定位实际监听地址,而不是猜

很多暴露问题的根源,是配置文件和实际运行状态不一致。比如 MySQL 的 bind-address 写的是 127.0.0.1,但启动参数里又叠加了 --bind-address=0.0.0.0,最终生效的是后者。所以第一步不要看配置文件,先看操作系统眼里这两个服务到底在听什么。

执行下面的命令,分别查看 MySQL(默认端口 3306)和 Redis(默认端口 6379)的监听状态:

ss -lntp | grep -E ':(3306|6379)\b'

预期你会看到两类结果。一类是 127.0.0.1:3306 或 ::1:3306,说明只监听回环地址,本机之外无法直接访问,这是安全状态;另一类是 0.0.0.0:3306 或具体的公网/内网 IP 地址,说明服务对所有网络接口或特定外部接口开放,这就是需要处理的对象。

如果 ss 输出为空,先确认服务是否在运行,再用 systemctl status mysql 或 systemctl status redis 查看进程状态。另外注意,如果服务器上有多个 PHP-FPM 池或 Docker 容器,ss 输出里可能有多条记录,逐一核对端口对应的进程 PID 和程序名,避免把容器内部的监听误判为宿主机暴露。

这里有一个容易忽略的细节:ss 显示的地址是内核视角的 socket 绑定结果,它已经综合了配置文件、启动参数和环境变量。所以只要 ss 显示 0.0.0.0,无论配置文件里写的是什么,实际就是暴露的。

第二步:核对配置、启动参数和云安全组三层来源

定位到监听异常后,需要找出是谁把地址设成了 0.0.0.0。常见来源有三个,按优先级排查:

排查来源MySQL 执行位置Redis 执行位置
主配置文件/etc/mysql/mysql.conf.d/mysqld.cnf 或 /etc/my.cnf 中的 bind-address/etc/redis/redis.conf 中的 bind 指令
启动参数/覆盖文件systemctl cat mysql 查看 ExecStart 行是否带 --bind-address;检查 /etc/mysql/conf.d/ 下的追加配置systemctl cat redis 查看 ExecStart 行;检查 /etc/redis/redis.conf 末尾的 include 或覆盖段
云平台安全组/防火墙云控制台的入站规则是否放行了 3306/6379同左

对 MySQL,执行 grep -r "bind-address" /etc/mysql/ 可以一次扫出所有配置文件里的设置;对 Redis,执行 grep -E "^(bind|protected-mode)" /etc/redis/redis.conf。注意 Redis 的 bind 指令可以跟多个地址,比如 bind 127.0.0.1 192.168.1.10,这表示同时监听回环和内网地址,是否要保留取决于你的业务拓扑。

云安全组的核查容易被漏掉。即使你把服务绑定了 127.0.0.1,如果云平台的安全组或主机防火墙(iptables/nftables)仍然放行了 3306/6379 的入站流量,外部请求虽然无法到达服务,但端口扫描依然会显示为“开放”,这会给攻击者留下错误印象,也可能掩盖其他配置问题。所以安全组的规则要一并检查和收敛。

第三步:判断业务依赖,别急着改

在动手改监听地址之前,先确认是否有业务确实需要从外部访问这两个服务。对 WordPress/LAMP 站点来说,最常见的依赖关系是:

  • Web 服务器(Nginx/Apache)和 PHP-FPM 进程需要连接 MySQL,通常通过 127.0.0.1:3306 或 Unix socket 连接;
  • Redis 作为对象缓存或会话存储,PHP 的 redis 扩展或 WordPress 的缓存插件(如 Redis Object Cache)通过 127.0.0.1:6379 连接;
  • 远程开发或管理工具,比如本地的 MySQL Workbench、RedisInsight,如果之前是通过公网 IP 直连的,改成回环后这些工具会失效,需要改用 SSH 隧道。

一个快速判断方法:在服务器上执行 lsof -i :3306 -i :6379 或 ss -tnp | grep -E ':(3306|6379)',看当前有哪些进程建立了到这两个端口的连接。如果连接来源全部是本机 IP(127.0.0.1 或内网地址),那基本可以确定业务只走本机回环,改成 127.0.0.1 不会影响现有访问。

如果确实存在远程连接需求,不要直接把监听改成回环,而是改成内网地址(如 192.168.x.x),并确保云安全组只放行来源 IP 为你办公网络或跳板机的规则。

第四步:小步调整,先改配置再重启

确认业务依赖后,按“先 MySQL 后 Redis”的顺序逐个调整,避免两个服务同时变动导致问题难以定位。

MySQL 调整步骤:

  1. 备份当前配置:cp /etc/mysql/mysql.conf.d/mysqld.cnf /etc/mysql/mysql.conf.d/mysqld.cnf.bak.$(date +%F)
  2. 编辑配置文件,将 bind-address 改为 127.0.0.1:
   [mysqld]
   bind-address = 127.0.0.1
  1. 如果之前是通过启动参数覆盖的,还需要检查 systemctl cat mysql 的 ExecStart 行,去掉多余的 --bind-address 参数。
  2. 执行 mysqladmin -u root -p ping 确认服务可用,再执行 systemctl restart mysql。
  3. 重启后立即执行 ss -lntp | grep 3306,确认监听地址已变为 127.0.0.1。

Redis 调整步骤:

  1. 备份配置:cp /etc/redis/redis.conf /etc/redis/redis.conf.bak.$(date +%F)
  2. 编辑配置文件,将 bind 指令改为 bind 127.0.0.1,并确认 protected-mode yes 已启用:
   bind 127.0.0.1
   protected-mode yes
  1. 执行 redis-cli ping 确认服务可响应,再执行 systemctl restart redis。
  2. 重启后执行 ss -lntp | grep 6379 确认监听地址。

注意:Redis 的 protected-mode 只有在没有设置密码且没有显式绑定地址时才会生效。如果你已经设置了 requirepass,protected-mode 的作用会减弱,但绑定回环仍然是第一道防线。

第五步:防火墙兜底,防止重启后配置回弹

配置文件的修改可能在服务升级或配置管理工具(如 Ansible、Puppet)重新下发时被覆盖。为了在配置回弹时仍能兜底,建议在主机防火墙层加一条临时规则,明确拒绝外部对 3306/6379 的访问。

以 nftables 为例(大多数现代发行版默认使用),添加两条规则:

nft add rule inet filter input tcp dport 3306 ip saddr != 127.0.0.1 drop
nft add rule inet filter input tcp dport 6379 ip saddr != 127.0.0.1 drop

如果服务器用的是 iptables:

iptables -A INPUT -p tcp --dport 3306 ! -s 127.0.0.1 -j DROP
iptables -A INPUT -p tcp --dport 6379 ! -s 127.0.0.1 -j DROP

执行后可以用 nft list ruleset 或 iptables -L -n 确认规则已生效。但要注意,这些规则是临时的,重启后不会保留。要持久化,需要根据发行版使用 nftables.service 的配置文件或 iptables-persistent 工具保存。

防火墙规则的意义在于:即使某天配置文件被改回 0.0.0.0,防火墙仍然会拦截外部流量,给你留出发现和修复的时间窗口。但不要把它当作长期的解决方案——它只是过渡期的兜底。

MySQL 与 Redis 监听地址从公网暴露收敛到回环的核查示意图

第六步:业务连通性验证,按访问路径逐项确认

改动监听地址后,最直接的后果是依赖这两个服务的业务可能断连。验证不能只看服务本身是否启动,要按实际业务路径逐项确认。

WordPress 站点访问验证:

  1. 用浏览器访问站点首页和一篇带数据库查询的文章页,确认页面正常渲染;
  2. 登录 WordPress 后台,确认登录、发布文章、上传媒体等操作正常;
  3. 如果启用了 Redis 对象缓存,检查缓存是否命中,可以执行 redis-cli -h 127.0.0.1 ping 确认连接,再观察 WordPress 的缓存插件状态页。

命令行连接验证:

# 本机连接 MySQL
mysql -h 127.0.0.1 -u wordpress_user -p -e "SELECT 1;"

# 本机连接 Redis
redis-cli -h 127.0.0.1 ping

PHP-FPM 连接验证:

WordPress 的 wp-config.php 里定义了数据库连接常量,确认 DB_HOST 是 127.0.0.1 或 localhost(使用 Unix socket)。如果之前用的是公网 IP,这里也要一并修改:

define('DB_HOST', '127.0.0.1');

对于 Redis 缓存插件,检查 wp-config.php 或插件设置中的连接地址是否也指向 127.0.0.1。

外部访问确认:

从另一台机器(比如你的办公电脑)执行 nc -zv 服务器IP 3306 和 nc -zv 服务器IP 6379,预期结果是连接被拒绝或超时。如果仍然能连通,说明防火墙规则没有生效,或者云安全组还在放行,需要回头检查。

第七步:回滚清单,给每个变更留一条退路

任何配置变更都可能引入新问题,所以回滚路径要提前准备好。把这次涉及的文件和命令整理成一张清单,放在服务器上的 /root/ 或运维文档里,方便随时取用。

变更项变更前状态回滚操作预期恢复
MySQL bind-address0.0.0.0恢复备份文件 cp mysqld.cnf.bak.日期 mysqld.cnf,执行 systemctl restart mysql监听恢复为 0.0.0.0,外部连接恢复
Redis bind 指令0.0.0.0恢复备份文件 cp redis.conf.bak.日期 redis.conf,执行 systemctl restart redis监听恢复为 0.0.0.0
防火墙规则无删除规则:nft delete rule inet filter input handle 编号 或 iptables -D INPUT ...外部流量不再被拦截
wp-config.php 的 DB_HOST公网 IP改回原值WordPress 恢复原连接方式

回滚的触发条件是:业务连通性验证失败,且无法在 15 分钟内定位原因。不要试图在回滚前反复调试——先恢复服务,再在维护窗口内排查。

监听地址变更后的验证与回滚双轨流程图

复盘:把这次核查固化成巡检项

完成变更和验证后,花几分钟把这次的经验固化下来。至少做三件事:

  1. 把监听地址核查加入月度巡检脚本,用一条命令输出所有非回环监听的服务端口:
   ss -lntp | awk 'NR>1 {print $4, $6}' | grep -v '127.0.0.1\|::1'

这个输出里出现的任何端口,都需要说明为什么监听在非回环地址上。

  1. 在云安全组里收敛入站规则,把 3306 和 6379 的放行规则删掉,或改为仅允许特定来源 IP。安全组是云环境下的第一道边界,它的状态比主机防火墙更直观,也更容易被审计。
  1. 检查是否有其他服务存在同样问题,比如 PostgreSQL(5432)、MongoDB(27017)、Elasticsearch(9200)。用同样的 ss 命令扫一遍所有监听端口,把暴露面清单完整拉出来。

数据库和缓存服务监听在回环地址上,是 Web 站点最基本的一条安全基线。这次核查的价值不在于改掉一个配置项,而在于你确认了“服务实际在听什么”和“业务真正需要什么”这两者之间是一致的。下次再做类似变更时,这套“盘点—核对—小步调整—验证—回滚”的流程可以直接复用。

 
枫少@KillBoy
评论  2  访客  2
    • 铜镜映月
      铜镜映月 1

      ss那条命令确实比看配置文件靠谱,之前就被启动参数坑过

      • 青出于蓝
        青出于蓝 1

        Redis的protected-mode和requirepass一起配才稳,光绑回环也不够

      匿名

      发表评论

      匿名网友

      拖动滑块以完成验证