核心是构建完整状态化过滤逻辑:先设iptables -P INPUT DROP,默认拒绝;再依次放行lo、ESTABLISHED/RELATED返回流量;最后显式开放NEW连接端口,缺一不可且顺序严格。

要让 Linux 防火墙只放行已建立连接的返回流量,核心不是“允许 ESTABLISHED”,而是构建一套完整的状态化过滤逻辑:默认拒绝入站、放行本地回环、明确授权新连接入口,并靠连接跟踪机制自动识别返回包。
必须设置默认 DROP 策略
仅加一条 ACCEPT 规则没用——如果 INPUT 链默认是 ACCEPT,那所有流量都通了。必须先执行:
- iptables -P INPUT DROP:把 INPUT 链默认策略设为丢弃
- 这条命令要放在规则添加之前,否则规则无效
- 执行后若 SSH 断连,说明没及时放行关键端口(如 22),需立即通过本地终端恢复
放行本地回环和已建立/关联连接
这两步缺一不可,顺序也不能颠倒:
- iptables -A INPUT -i lo -j ACCEPT:允许本地进程间通信(如数据库、监控服务)
- iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT:这是真正放行返回包的关键规则
- 必须同时包含 ESTABLISHED 和 RELATED —— FTP 数据连接、DNS 响应、ICMP 错误报文(如“目标不可达”)都属于 RELATED,漏掉会导致服务异常
显式开放新连接入口(按需)
出站请求(如 curl、ssh 到外部)本机可自由发起,但外部想连进来(如 SSH、HTTP),必须单独放行 NEW 连接:
- iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
- iptables -A INPUT -p tcp --dport 80 -m conntrack --ctstate NEW -j ACCEPT
- 注意:--ctstate NEW 必须和具体端口、协议一起用,不能单独写;它只匹配首次握手的 SYN 包
- 不开放 NEW,外部就无法发起连接,即使 ESTABLISHED 规则存在也无意义
验证与保存规则
配置完要检查是否生效:
- iptables -L INPUT -v -n:查看 INPUT 链详细计数,确认 ESTABLISHED/RELATED 规则有命中包
- conntrack -L:直接查看内核连接跟踪表,能看到活跃连接及其状态
- Ubuntu/Debian 用 iptables-save > /etc/iptables/rules.v4;CentOS/RHEL 用 service iptables save 或 iptables-save > /etc/sysconfig/iptables


















