iptables与安全组需分层协同:安全组为第一道门,在VPC网关过滤入向流量;iptables为第二道门,在系统内核层精细化控制,二者顺序不可颠倒、职责必须分明,且规则均需持久化。

直接用 iptables 配合安全组做双重拦截,不是简单叠加规则,而是分层协同:安全组拦在最外层(网络入口前),iptables 拦在系统内层(数据包进系统后)。两者缺一不可,但顺序和职责必须分清。
安全组是第一道门,必须先配好
云服务器(如阿里云、腾讯云)的流量,在到达你的 Linux 系统之前,先经过 VPC 网关上的安全组过滤。这意味着:
- 安全组规则不生效,iptables 再严也收不到包——连 SYN 都进不来
- SSH 端口(22)没放行,你就根本连不上服务器改 iptables
- MySQL(3306)、Web(80/443)等端口,必须在安全组里只开放可信来源,比如运维跳板机 IP、应用服务器内网段,而不是“0.0.0.0/0”
- 测试是否生效:从外网用 telnet 公网IP 3306 或 nc -zv 公网IP 3306,通不了说明安全组已起作用
iptables 是第二道门,负责兜底和细化
即使安全组开了某端口,iptables 还能再筛一次。重点不是“封死”,而是“精准控制”。以 MySQL 为例:
- 先放行本地回环:iptables -A INPUT -s 127.0.0.1 -p tcp --dport 3306 -j ACCEPT(否则 mysqld 启动失败)
- 再拒绝其他所有 3306 入向:iptables -A INPUT -p tcp --dport 3306 ! -s 127.0.0.1 -j DROP(注意 ! 前后有空格)
- 别用 REJECT,用 DROP:避免暴露服务存在(REJECT 会发 RST 包,扫端口时可识别)
- 规则顺序不能错:ACCEPT 必须写在 DROP 之前,iptables 自上而下匹配
- 测试是否生效:在服务器本地执行 nc -zv 127.0.0.1 3306 应通;从同VPC另一台机器连则应不通(除非安全组也放行了)
bind-address 和防火墙必须配合看
MySQL 的 bind-address = 127.0.0.1 只让服务监听本地,但这不是防火墙替代方案:
- 它只是让 MySQL 不监听 eth0,不代表外网绝对连不上——万一哪天配置被改成 0.0.0.0,又没配 iptables,就立刻暴露
- 正确做法是:bind-address 设为 127.0.0.1 + 安全组关闭 3306 + iptables 拒绝 3306 外部访问,三者形成冗余
- 同理,Web 服务若只供内网调用,bind-address 设为内网 IP,再配 iptables 限制 INPUT 来源 IP 段,比单纯靠 bind 更可靠
生产环境必须双控,且规则要持久化
安全组可能被误删或重置,iptables 规则重启后默认丢失,所以:
- CentOS/RHEL:用 service iptables save 或 iptables-save > /etc/sysconfig/iptables
- Ubuntu/Debian:用 iptables-persistent 工具保存规则
- 不要同时启用 firewalld 和手动 iptables:二者规则链冲突,查问题极难定位
- 定期检查:用 iptables -L -n -v 看计数器是否增长,确认规则真正在拦截

















