Linux 防火墙 iptables 的简介和配置详解

〇、前言

**现代 Linux 发行版逐渐转向 nftables,但 iptables 仍是底层基础。**理解其原理对排查 Kubernetes 网络、云平台安全组问题至关重要。

配置时务必牢记:规则顺序 > 表链职责 > 持久化,三大核心逻辑。

本文将以 iptables 为主进行简单的介绍,并详解下配置方法。

一、什么是 iptables?

1.1 iptables 简介

iptables 是 Linux 内核 Netfilter 框架的用户空间管理工具,通过四表五链结构实现数据包过滤、网络地址转换(NAT)和流量控制

核心特点是规则按顺序匹配、匹配即执行、默认不持久化,配置错误可能导致服务中断或安全风险。

1.2 四张规则表(按数据包处理优先级排序)

表名 优先级 核心作用 典型场景 内置链
raw 最高 控制连接跟踪(conntrack)豁免 高性能服务(DNS/NTP)跳过状态跟踪 PREROUTING、OUTPUT
mangle 第二 修改数据包头部字段(TTL/TOS等) 流量标记、QoS策略、P2P限速 五链全覆盖
nat 第三 地址转换(SNAT/DNAT),不可过滤 端口转发、内网共享公网IP上网 PREROUTING、POSTROUTING、OUTPUT
filter 最低 访问控制过滤(默认表) 开放/拒绝端口、拦截非法访问 INPUT、OUTPUT、FORWARD

注意:nat 表处理地址转换,不决定数据包放行与否;filter 表决定放行/拒绝,不修改地址。若在 nat 表中添加 DROP 规则,规则不会生效。

1.3 五条规则链(数据包处理节点)

数据包在内核网络栈中的流动路径决定了其匹配的链:

链名称 触发时机 典型应用场景
PREROUTING(pre routing) 数据包刚进入网卡,路由决策前 DNAT、打标记
INPUT(input) 目标为本机进程的流量 SSH、Web 服务
FORWARD(forward) 需跨网卡转发的流量 NAT 网关
OUTPUT(output) 本机主动发出的流量 curl 请求
POSTROUTING(post routing) 数据包离开网卡前 SNAT、地址伪装

规则匹配逻辑:

数据包按顺序逐条匹配规则,一旦命中即执行动作,并终止后续检查

规则顺序决定逻辑成败若先配置 DROP 再配置 ACCEPT,ACCEPT 规则将永远不生效

二、Linux 环境配置

2.1 基础配置流程(以 filter 表为例)

复制代码
# 1)清空现有规则
# 生产环境避免直接清空,应先备份:
# iptables-save > /root/iptables-bak.sh
iptables -F          # 清空 filter 表所有链
iptables -t nat -F   # 清空 nat 表规则
# 2)设置默认策略(调试阶段建议先宽松)
# 调试完成后,再收紧策略:iptables -P INPUT DROP(效果:除非明确放行,否则一律拒绝)
iptables -P INPUT ACCEPT     # 先允许所有入站(调试用)
iptables -P FORWARD DROP     # 转发链默认拒绝
# 3)按逻辑顺序添加规则
# 顺序示例(Web 服务器):
## 1. 允许本地回环(必须最先配置):
iptables -A INPUT -i lo -j ACCEPT
## 2. 放行已建立连接(确保响应流量不被拦截):
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
## 3. 按需开放服务端口(如:SSH、HTTP):
iptables -A INPUT -p tcp --dport 22 -s 192.168.1.0/24 -j ACCEPT  # 仅允许指定内网网段的机器通过 SSH 连接到服务器
## -A INPUT:将规则追加(Append)到 INPUT 链的末尾。INPUT 链负责处理所有进入本机的数据包
## -p tcp:指定匹配的协议为 TCP。SSH 服务基于 TCP 协议,因此必须指定
## --dport 22:指定目标端口(Destination Port)为 22。这是 SSH 服务的默认端口
## -s 192.168.1.0/24:指定数据包的来源 IP(Source)
## 192.168.1.0/24 代表 192.168.1.1 到 192.168.1.254 这个整个 C 类子网,这意味着只有这个局域网网段内的机器才能匹配此规则
## -j ACCEPT:指定匹配到该规则后的动作(Jump)为接受(ACCEPT),即允许数据包通过
iptables -A INPUT -p tcp --dport 80 -j ACCEPT # 开放 HTTP 服务端口,允许任何来源的 IP 访问服务器的 Web 服务
## -A INPUT:同样将规则追加到 INPUT 链的末尾
## -p tcp:指定协议为 TCP,因为 HTTP 服务基于 TCP 协议
## --dport 80:指定目标端口为 80,这是 Web 服务的标准端口
## -j ACCEPT:允许匹配的数据包通过。由于这里没有使用 -s 参数限制来源 IP,因此它默认对所有来源 IP 生效
## 4. 最后添加兜底拒绝:
iptables -A INPUT -j DROP  # 必须放在末尾
# 注意:
# -A 表示追加到链尾,-I 表示插入链首(如:优先拦截恶意 IP:-I INPUT -s 1.2.3.4 -j DROP)。
# 状态模块写法:新系统用 -m conntrack --ctstate,旧系统用 -m state --state

2.2 NAT 配置示例

复制代码
# 1)端口转发
# 将外部访问 8080 端口转发到内网 192.168.1.50:80:
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.50:80
## -t nat:指定操作 nat 表(网络地址转换表)
## -A PREROUTING:在 PREROUTING 链追加规则。该链在数据包刚进入网卡、还未进行路由判断前生效
## -p tcp --dport 8080:匹配目标端口为 8080 的 TCP 协议流量
## -j DNAT --to-destination 192.168.1.50:80:执行目标地址转换(DNAT),将数据包的目标 IP 和端口改写为内网主机 192.168.1.50 的 80 端口
# 必须同步配置 filter 表的 FORWARD 链,否则流量被拦截:
iptables -A FORWARD -d 192.168.1.50 -p tcp --dport 80 -j ACCEPT
## -A FORWARD:在默认的 filter 表的 FORWARD 链追加规则。该链专门用于控制经过本机转发的数据包
## -d 192.168.1.50 -p tcp --dport 80 -j ACCEPT:明确允许目标为 192.168.1.50:80 的 TCP 流量通过
## 如果不加这条规则,即使 NAT 转换了地址,数据包也会因为默认防火墙策略被拦截
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
## -m conntrack --ctstate ESTABLISHED,RELATED:使用连接追踪模块,匹配状态为"已建立"或"相关"的连接
## 这确保了内网服务器返回给外部客户端的响应数据包能够顺利通过防火墙

# 2)共享上网(SNAT)
# 内网 192.168.1.0/24 通过公网 IP eth0 上网:
echo 1 > /proc/sys/net/ipv4/ip_forward  # 开启内核转发
## 临时开启 Linux 内核的 IP 转发功能
## 此命令重启后会失效。若需永久生效,需编辑 /etc/sysctl.conf 文件,写入 net.ipv4.ip_forward=1,并执行 sysctl -p 使其生效
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
## -A POSTROUTING:在 POSTROUTING 链追加规则。该链在数据包即将离开网卡前生效
## -s 192.168.1.0/24 -o eth0:匹配源网段为 192.168.1.0/24 且从 eth0 网卡(通常是外网接口)发出的数据
## -j MASQUERADE:执行源地址伪装(SNAT 的一种动态形式)
## 它会自动将内网数据包的源 IP 替换为 eth0 接口当前的公网 IP,这样外部网络才能正确将响应数据返回给这台网关服务器,再由服务器转发给内网主机

这套组合拳是构建 Linux 软路由和网关的标准范式:内核转发提供基础能力,NAT 表(DNAT/SNAT)负责改写数据包的源/目标地址,而 FORWARD 链则充当"交通警察",决定这些被改写地址的数据包是否被允许放行。

2.3 在现有规则指定位置加一条、末尾加一条

复制代码
# 【在指定的匹配规则后边新增一条】
# 1)查看当前规则及序号:使用 --line-numbers 参数查看现有规则的行号
iptables -L INPUT -n -v --line-numbers
# 2)在指定位置插入新规则
# 假设要在 INPUT 链的第 3 条规则之后添加新规则,那么你需要将新规则插入到第 4 个位置
# 在 INPUT 链的第 4 个位置插入一条允许 80 端口的规则
iptables -I INPUT 4 -p tcp --dport 80 -j ACCEPT
# 注:如果不指定具体序号,-I INPUT 默认会将规则插入到链的【最顶端】,即第 1 位

# 【在 INPUT 链的末尾追加一条规则】
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# 使用 -A 参数将新规则追加到整条链的末尾

三、特别注意事项

3.1 规则顺序与逻辑陷阱

默认策略风险:直接设置iptables -P INPUT DROP可能导致 SSH 断连(若未提前放行 SSH 规则)。安全做法:先添加 ACCEPT 规则,最后再设置默认拒绝。

状态跟踪依赖:ESTABLISHED 规则需放在服务端口规则之前,否则响应流量被拦截。

3.2 持久化配置(避免重启失效)

复制代码
# CentOS/RHEL:
iptables-save > /etc/sysconfig/iptables
systemctl enable iptables  # 确保服务开机自启
# Debian/Ubuntu:
iptables-save > /etc/iptables/rules.v4
apt install iptables-persistent -y  # 安装持久化工具
# 验证方法:重启后执行 iptables -L -n -v,检查规则是否加载。

3.3 常见错误排查

1)规则不生效

可能的原因:

规则顺序错误(如 DROP 在 ACCEPT 之前)。

表链混淆(如在 filter 表配置 DNAT)。

未启用连接跟踪模块(nf_conntrack)。

复制代码
# 诊断命令
iptables -L INPUT -n -v --line-numbers  # 查看匹配计数
lsmod | grep nf_conntrack               # 检查状态跟踪模块

2)紧急恢复方案

若配置错误导致断连,通过控制台执行:

复制代码
iptables -P INPUT ACCEPT    # 临时放行所有入站
iptables -F                 # 清空规则(谨慎使用)

3)尝试执行 iptables 脚本,报错:command not found

复制代码
// 【在执行 iptables 脚本前的准备工作】
// 1. 备份当前规则(以防万一需要回滚)
iptables-save > /tmp/iptables_backup.rules
// 2. 清空 filter 表(默认表)的所有规则和自定义链
iptables -F
iptables -X
// 3. 清空其他常用表(如 NAT 表)
iptables -t nat -F
iptables -t nat -X
// 4. 重置默认策略(建议先设为 ACCEPT,防止清空规则后自己断网)
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
// 【尝试执行 iptables 脚本,报错】
[root@localhost ~]# sudo /bin/iptables.sh
sudo: /bin/iptables.sh: command not found
// 检查文件存在
[root@localhost ~]# ls -l /bin/iptables.sh
-rw-r--r-- 1 root root 1484 Jul 13 13:49 /bin/iptables.sh
// 只有读(r)和写(w)权限,缺少了执行(x)权限。
// 在 Linux 中,如果一个脚本没有执行权限,直接运行它时系统就会提示 command not found。
// 【解决】:添加执行权限
[root@localhost ~]# chmod +x /bin/iptables.sh
[root@localhost ~]# ls -l /bin/iptables.sh
-rwxr-xr-x 1 root root 1484 Jul 13 13:49 /bin/iptables.sh
// 执行脚本
[root@localhost ~]# sudo /bin/iptables.sh
// 查看当前配置
[root@localhost ~]# sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  localhost            localhost           
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     tcp  --  x.x.x.x       anywhere             tcp dpt:mysql
。。。。

3.4 配置关键点

最小权限原则: 仅开放必要端口,并严格限制来源 IP(如:--dport 22 -s 192.168.1.0/24)。

先查后改:操作前用iptables -L -n -v --line-numbers查看当前规则。

避免直接修改默认策略: 优先用 DROP 规则兜底,而非iptables -P INPUT DROP

生产环境先测试:在非关键时段配置,并通过 ping、telnet 验证连通性。

备份与注释:为复杂规则添加注释(-m comment --comment "允许DBA访问"),并定期备份规则文件。

四、小小的总结

**iptables 作为 Linux 防火墙核心,通过四表五链实现数据包控制。**核心逻辑在于规则顺序决定生效结果,匹配即停止;四表(raw、mangle、nat、filter)按优先级处理,五链(如:PREROUTING、INPUT、FORWARD)对应数据包流向,需严格区分表链职责(如:nat 表仅转换地址,filter 表决定放行)。

配置实操需遵循"先清规则、设默认、添策略"流程:测试环境可清空规则,生产环境先备份;默认策略建议调试期设为 ACCEPT,完成后收紧为 DROP;规则顺序务必先放行基础流量(如:回环、已建立连接),再开放服务端口,最后兜底拒绝。NAT 配置需同时操作 nat 表(如:DNAT、SNAT)和 filter 表的 FORWARD 链,确保转发放行。

持久化与恢复也至关重要。通过 iptables-save 保存规则,不同系统用相应工具持久化 (如:CentOS 的 /etc/sysconfig/iptables,Ubuntu 的 iptables-persistent);配置错误时,可通过控制台快速恢复 (如:iptables -P INPUT ACCEPT 或 -F 清空规则)。

状态跟踪与细节方面需要注意,利用 conntrack 模块放行响应流量-m conntrack --ctstate ESTABLISHED,RELATED);严格限制来源 IP 与端口,添加注释提升可维护性;排查问题时用 -L -n -v --line-numbers 查看规则顺序及匹配数,检查模块加载(如:lsmod | grep nf_conntrack)。

**安全实践强调最小权限原则,先测试后上线,定期备份规则文件。**理解这些核心要点,可高效配置防火墙并规避常见风险。

相关推荐
橙子家2 年前
Linux 文本文件编辑相关命令简介【Linux 常用命令系列二】
operatingsystem