核心是“双保险”:先让数据库不听外网,再用iptables拦住漏网请求。必须先配置数据库仅监听内网或本地地址(如MySQL bind-address设为127.0.0.1、PostgreSQL listen_addresses设为'localhost,192.168.1.0/24'、Redis启用protected-mode并绑定内网IP),再通过iptables按接口(如-i eth0 -j DROP)或源IP范围(如! -s 192.168.1.0/24)严格限制3306等数据库端口的入向流量,并设置默认INPUT策略为DROP、持久化规则且验证生效。

核心是“双保险”:先让数据库不听外网,再用 iptables 拦住漏网请求。单靠其中一项都可能失效。
第一步:关闭数据库的公网监听
iptables 是网络层工具,不能代替服务本身的安全配置。必须先确保数据库只响应内网或本地请求:
-
MySQL:编辑
/etc/mysql/mysql.conf.d/mysqld.cnf,将bind-address改为127.0.0.1或具体内网 IP(如192.168.1.100),绝不能是0.0.0.0或* -
PostgreSQL:修改
postgresql.conf中的listen_addresses,设为'localhost,192.168.1.0/24',并确认pg_hba.conf中只允许可信网段连接 -
Redis:设置
bind 127.0.0.1或内网地址,并开启protected-mode yes;若需远程访问,务必配密码和 ACL
第二步:用 iptables 明确拦截外网对数据库端口的访问
即使数据库配置出错,iptables 也能兜底。以 MySQL 默认端口 3306 为例:
- 拒绝所有来自外网接口(如
eth0)的 3306 请求:iptables -A INPUT -i eth0 -p tcp --dport 3306 -j DROP - 如果服务器只有单网卡但有公网 IP,可按源 IP 范围拦截:
iptables -A INPUT -p tcp ! -s 192.168.1.0/24 --dport 3306 -j DROP(表示:只要来源不是内网段,就丢弃) - 注意规则顺序——这条拦截规则必须放在任何放行规则之后、默认 DROP 之前,否则会被跳过
第三步:加固基础规则,防止绕过
避免因基础策略疏漏导致数据库端口意外暴露:
- 确保默认 INPUT 策略为 DROP:
iptables -P INPUT DROP - 放行已建立连接(保障已有会话不中断):
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT - 允许本地回环(防止本地应用连不上):
iptables -A INPUT -i lo -j ACCEPT - 不单独开放 3306 给全网,也不依赖“封扫描 IP”这种被动方式——主动白名单才是可靠做法
第四步:保存并验证规则持久化
重启后规则消失等于没设。必须固化:
- Debian/Ubuntu:
iptables-save > /etc/iptables/rules.v4 - RHEL/CentOS 7+:
service iptables save(需先安装iptables-services)或写入/etc/sysconfig/iptables - 验证是否生效:从外网机器执行
telnet 公网IP 3306,应连接超时或被拒;从内网机器测试应正常连通


















