在 Linux 中,最核心的防火墙管理工具是 Netfilter 框架,Netfilter 是 Linux 内核中的一个框架,它允许在网络数据包通过协议栈的不同阶段时进行截取、检查、修改和丢弃,而与它交互的主要命令行工具是 iptablesnftables

许多 Linux 发行版还提供了更高级、更易于使用的前端工具,来简化防火墙的配置。 Ubuntu 及其衍生版本上默认的防火墙管理工具UFW, Red Hat 系列发行版(如 CentOS, RHEL, Fedora)上默认的动态防火墙管理工具Firewalld。

1. iptables

iptables 是一个非常强大且灵活的命令行工具,用于配置 Linux 内核中的 Netfilter 数据包过滤规则。它通过定义一系列的规则来决定如何处理网络流量。

工作原理: iptables 组织规则成**表 (tables),每个表包含多个链 (chains)**。数据包根据其类型(例如,传入、传出、转发)经过不同的链,并根据链中的规则进行匹配和处理。

表(Tables)

iptables 的规则被组织成不同的“表”,每个表处理特定类型的流量。主要的表有:

  • filter 表(默认):这是最常用的表,用于过滤数据包,决定是否允许数据包通过(ACCEPT)、丢弃(DROP)或拒绝(REJECT)。
  • nat 表(网络地址转换):用于修改数据包的源 IP 或目标 IP/端口。常用于端口转发、共享互联网连接(NAT)。
  • mangle 表(数据包修改):用于修改数据包的某些部分(如 TOS 字段),以便进行流量整形或 QoS。
  • raw:用于在数据包被连接跟踪(conntrack)处理之前进行操作,主要用于排除某些流量不被连接跟踪。
  • security表:用于 SELinux 安全策略(较少用)

链(Chains)

每个表都包含一些内置的“链”,它们代表数据包在通过 Netfilter 框架时可能经过的不同点。用户也可以创建自定义链。

  • INPUT:处理进入本机的数据包(目标是本机)。
  • OUTPUT:处理从本机发出的数据包。
  • FORWARD:处理经过本机转发到其他目的地的数据包(例如路由器或网关)。
  • PREROUTING:在数据包到达路由决策点之前处理(主要在 natmangle 表中使用)。
  • POSTROUTING:在数据包离开路由决策点之后处理(主要在 natmangle 表中使用)。

规则(Rules)

每条规则都定义了匹配数据包的条件和满足条件时要执行的动作(Target/Action)。规则是按顺序处理的,一旦数据包匹配了某条规则,并且该规则的动作是终结性的(如 ACCEPT, DROP, REJECT),那么数据包就不会再匹配同一链中的后续规则。

动作/目标(Targets/Actions)

当一个数据包匹配到一条规则时,就会执行一个动作。

  • **ACCEPT **:允许数据包通过。
  • **DROP **:默默地丢弃数据包,不给发送方任何响应。发送方会超时。
  • **REJECT **:拒绝数据包,并向发送方返回一个错误信息(例如 ICMP “Port Unreachable”)。发送方会立即知道被拒绝。
  • **LOG **:记录匹配数据包的信息到系统日志,然后继续匹配下一条规则。
  • **SNAT ** (Source NAT):修改数据包的源 IP 地址(在 nat 表的 POSTROUTING 链中使用)。
  • **DNAT ** (Destination NAT):修改数据包的目标 IP 地址(在 nat 表的 PREROUTING 链中使用)。
  • **MASQUERADE **:SNAT 的特殊形式,自动使用传出接口的 IP 地址(常用于动态 IP 地址的 NAT)。
  • **RETURN **:停止在当前链中处理,返回到调用它的上一个链。
  • **JUMP (跳转到自定义链) **:将数据包的处理权转移到用户自定义的链中。

iptables 命令基本语法

1
iptables [-t table] <command> [chain] [rule-specification] [target]
  • -t table: 指定要操作的表(filternatmangleraw)。如果省略,默认为 filter

  • command: 要执行的操作,如添加规则、删除规则、列出规则等。

  • chain: 要操作的链(INPUTOUTPUTFORWARD 等)。

  • rule-specification: 匹配数据包的条件。

  • target: 匹配成功后要执行的动作

基础操作命令(command)

  • -A--append:追加规则到链末尾
  • -I--insert:插入规则(默认在首位)
  • -D--delete:删除规则
  • -R--replace:替换已有规则
  • -L--list:列出规则
  • -F--flush:清空链中所有规则
  • -X--delete-chain:删除自定义链
  • -N--new-chain:新建自定义链
  • -P--policy:设置默认策略(ACCEPT / DROP)
  • -Z--zero:清空计数器

匹配条件(Match Conditions)

网络地址/端口相关:

  • -s--source:指定源 IP 地址

  • -d--destination:指定目标 IP 地址

  • -p--protocol:协议(如 tcp、udp、icmp、all.)

    • iptables -A INPUT -p tcp -j ACCEPT
  • --sport--source-port:指定源端口

  • --dport--destination-port:指定目标端口

    • iptables -A INPUT -p tcp --dport 22 -j ACCEPT # 允许ssh端
  • --icmp-type type: 指定 ICMP 类型(例如 echo-request for ping)。

    • iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT # 允许 ping

接口相关:

  • -i--in-interface:入接口名(如 eth0)

    • iptables -A INPUT -i eth0 -j DROP
  • -o--out-interface:出接口名(如 wlan0)

扩展模块调用:

iptables 中,-m 选项用于加载扩展匹配模块(Extension Matching Modules)。Netfilter 框架的强大之处在于其模块化设计。核心的 iptables 命令和内置的匹配条件(如 -p 协议、-s 源IP、--dport 目标端口等)是基础,但如果需要更复杂的匹配逻辑,就需要加载特定的模块。

这些模块允许你根据各种网络流量特性进行匹配,而这些特性是基本 iptables 规则无法直接识别的。当你使用 -m 选项时,你实际上是在告诉 iptables 加载一个特定的内核模块,该模块包含了额外的匹配条件。

1
iptables ... -m <module_name> [module_options] ...
  • -m <module_name>: 指定要加载的扩展匹配模块的名称。

  • [module_options]: 该模块特有的匹配选项。不同的模块会有不同的选项。

常用扩展匹配模块及其应用:

1. state 模块(连接跟踪)

这是最常用和最重要的模块之一,用于基于数据包的连接状态进行匹配。Netfilter 的连接跟踪(conntrack)机制会追踪所有网络连接的状态。

  • 核心选项: --state <state1>[,<state2>,...]
  • 状态类型:
    • NEW: 数据包是新连接的第一个数据包。
    • ESTABLISHED: 数据包属于已经建立的连接。
    • RELATED: 数据包是与现有连接相关的新连接(例如,FTP 数据传输连接,或 nf_conntrack_irc 等辅助模块识别的协议)。
    • INVALID: 数据包无法识别或无效,可能包含错误或无法跟踪。
  • 典型应用场景: 允许所有已建立和相关连接,只对新连接进行严格限制。这是构建安全防火墙的基础,因为你通常希望允许服务器已经主动发起的连接(例如,服务器访问外部数据库或下载更新)的响应流量返回。
1
2
3
4
5
6
7
# 允许所有已建立和相关连接进入和离开
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

# 允许特定端口的新连接(例如SSH)
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT
# 如果 INPUT 链默认策略是 DROP,则所有其他 NEW 连接都会被丢弃
1
2
3
4
# 允许新连接和建立连接的用户,防止SYN flood攻击
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
# 出站回应
iptables -A INPUT -p tcp --sport 22 -m conntrack --ctstate ESTABLISHED -j ACCEPT
2. limit 模块(速率限制)

用于限制匹配到的数据包的速率,防止某些类型的洪水攻击或资源滥用。

  • 核心选项:

    • --limit <rate>: 平均速率,例如 5/minute(每分钟 5 个包),1/s(每秒 1 个包)。
    • --limit-burst <number>: 初始峰值,允许短时间内超过平均速率的包数。默认是 5。
  • 典型应用场景: 防止 SSH 暴力破解尝试:限制来自同一源 IP 的 SSH 连接尝试速率。

1
2
3
4
5
# 限制每分钟最多 5 个新的 SSH 连接尝试,峰值允许 10 个
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m limit --limit 5/minute --limit-burst 10 -j ACCEPT
# 丢弃超过限制的 SSH 连接尝试
iptables -A INPUT -p tcp --dport 22 -j DROP

3. multiport 模块(多端口匹配)

允许你在一跳规则中匹配多个不连续的端口。

  • 核心选项:
    • --dports <port1>[,<port2>,...]: 匹配多个目标端口。
    • --sports <port1>[,<port2>,...]: 匹配多个源端口。
  • 典型应用场景: 开放常用 Web 服务端口:一次性允许 HTTP 和 HTTPS 流量。
1
iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
4. mac 模块(MAC 地址匹配)

根据数据包的源 MAC 地址进行匹配。通常用于局域网内部的访问控制。

  • 核心选项: --mac-source <MAC_address>
  • 典型应用场景: 只允许特定设备访问本机
1
2
iptables -A INPUT -m mac --mac-source 00:11:22:33:44:55 -j ACCEPT
iptables -A INPUT -j DROP # 拒绝其他所有MAC地址
5. time 模块(时间匹配)

根据一天中的时间或一周中的某天匹配数据包。

  • 核心选项:
    • --timestart HH:MM:SS
    • --timestop HH:MM:SS
    • --weekdays <Day1>[,<Day2>,...] (Mon, Tue, Wed, Thu, Fri, Sat, Sun)
    • --monthdays <Day1>[,<Day2>,...] (1-31)
  • 典型应用场景: 只允许在工作时间访问管理端口
1
2
3
iptables -A INPUT -p tcp --dport 2222 -m time --timestart 09:00:00 --timestop 17:00:00 --weekdays Mon,Tue,Wed,Thu,Fri -j ACCEPT
# 拒绝在非工作时间访问
iptables -A INPUT -p tcp --dport 2222 -j DROP
6. iprange 模块(IP 范围匹配)

允许你匹配一个 IP 地址范围,而不是单个 IP 或 CIDR。

  • 核心选项:
    • --src-range <IP-IP>: 源 IP 范围。
    • --dst-range <IP-IP>: 目标 IP 范围。
  • 典型应用场景: 允许一个连续 IP 范围访问服务
1
iptables -A INPUT -p tcp --dport 80 -m iprange --src-range 192.168.1.100-192.168.1.150 -j ACCEPT
7. comment模块 规则注释

在管理复杂的 iptables 规则集时,规则的可读性和维护性变得至关重要。comment 模块允许你为每条 iptables 规则添加一段描述性的文本注释。这些注释不会影响规则的匹配逻辑或性能,但它们对于理解规则的目的、创建者和修改日期等信息极其有用。

  • -m comment: 加载 comment 扩展匹配模块。

  • --comment "<your_comment_text>": 指定要添加到规则的注释文本。注释文本必须用引号括起来,以防包含空格或其他特殊字符。

当你添加一条新规则时,立即为其添加注释是一个好习惯。

1
2
3
4
5
6
7
8
# 允许来自特定IP的SSH连接
iptables -A INPUT -p tcp --dport 22 -s 203.0.113.100 -m comment --comment "Allow SSH from trusted_admin_ip" -j ACCEPT

# 允许Web服务HTTP和HTTPS流量
iptables -A INPUT -p tcp -m multiport --dports 80,443 -m comment --comment "Allow HTTP/HTTPS traffic" -j ACCEPT

# 默认拒绝所有其他入站连接,以增强安全性
iptables -A INPUT -j DROP -m comment --comment "Default DROP for all other INPUT traffic"
1
2
3
# 使用 -L 选项列出规则时,如果规则包含注释,注释信息会自动显示。
iptables -L -v
iptables -L -v --line-numbers

不同版本的 iptables 或内核可能对注释的长度有隐式或显式限制。通常,保持注释简洁明了是最佳实践。在部署任何新规则时,始终附带清晰的注释,说明规则的用途、相关的服务或应用程序、以及创建者/日期。

1
2
# 允许公司内部子网访问Jenkins管理端口
iptables -A INPUT -p tcp --dport 8080 -s 10.0.0.0/24 -m comment --comment "Allow Jenkins from internal dev network (Added by John Doe 2025-07-01)" -j ACCEPT

可以使用 man iptables-extensions 命令来查看所有可用的 iptables 扩展模块及其详细选项。

动作目标(Target)用 -j--jump

  • -j ACCEPT → 允许通过
  • -j DROP → 丢弃不响应
  • -j REJECT → 拒绝并返回错误响应(如 ICMP)
  • -j LOG → 记录日志信息到 /var/log
  • -j DNAT → 改变目标地址(通常用于 PREROUTING)
  • -j SNAT → 改变源地址(通常用于 POSTROUTING)
  • -j MASQUERADE → 自动伪装(适用于动态公网 IP)
  • -j RETURN → 结束当前链并返回上一链继续匹配

保存和恢复规则

iptables 配置是存储在内存中的,系统重启后会丢失。需要将规则保存到文件,并在系统启动时恢复。

  • iptables-save → 保存当前规则到 stdout(可重定向备份)
  • iptables-restore → 从文件中恢复规则
  • iptables -t nat -L → 指定 nat 表查看规则(-t--table
  • Ubuntu/Debian保存规则常用:
    • sudo netfilter-persistent save
    • sudo netfilter-persistent reload

保存路径可能因发行版而异。通常是 /etc/sysconfig/iptables (RHEL/CentOS) 或 /etc/iptables/rules.v4 (Debian/Ubuntu)。

实例命令(结合参数)

1
sudo iptables --append INPUT --protocol tcp --dport 22 --jump ACCEPT

等价于:

1
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

是否需要我提供参数速查 PDF 表格或常见防火墙规则模板(如 Web 服务器、内网网关等)?我可以为你定制。

基本 iptables 命令示例:

  • 列出所有规则: sudo iptables -L -v -n
  • 允许 SSH (端口 22): sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
  • 允许 HTTP (端口 80): sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
  • 允许 HTTPS (端口 443): sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
  • 允许已建立和相关的连接: sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
  • 设置默认 INPUT 策略为 DROP (非常重要,通常最后执行): sudo iptables -P INPUT DROP
  • 保存规则: 这取决于你的 Linux 发行版。
    • Debian/Ubuntu: sudo apt install iptables-persistent 后,规则会自动保存或在安装过程中提示保存。
    • CentOS/RHEL: sudo yum install iptables-services 后,使用 sudo /sbin/iptables-save > /etc/sysconfig/iptables

2. nftables

nftables 是 Linux 内核中 Netfilter 的一个较新、更现代的包过滤框架,旨在最终取代 iptables。它提供了一个更统一和灵活的语法来处理 IPv4、IPv6、ARP 和桥接帧的规则。

  • 优点:
    • 统一的语法: 一个工具处理所有协议,简化了配置。
    • 性能提升: 更高效的规则处理。
    • 动态更新: 可以动态添加/删除规则,无需重新加载整个防火墙。
    • 更强大的集合: 支持更复杂的匹配条件。
  • 缺点: 相对较新,一些旧的教程或工具可能仍基于 iptables。

虽然 nftables 是推荐的未来方向,但由于 iptables 广泛存在且功能强大,许多系统仍然使用它或其前端。


3. 高级前端工具

为了简化防火墙管理,许多 Linux 发行版提供了更用户友好的工具,它们实际上在后台生成和管理 iptablesnftables 规则。

a. UFW (Uncomplicated Firewall)

UFW 是 Ubuntu 及其衍生版本上默认的防火墙管理工具,顾名思义,它旨在简化防火墙的配置。

  • 优点:
    • 非常简单: 命令行语法直观易懂。
    • 适合桌面和服务器: 对于常见的防火墙需求非常方便。
    • 集成应用配置文件: 许多应用(如 Apache, OpenSSH)提供 UFW 配置文件,方便一键开启/关闭端口。
  • 缺点: 对于非常复杂的定制规则,可能不如直接使用 iptablesnftables 灵活。

UFW 基本命令示例:

  • 启用 UFW: sudo ufw enable
  • 禁用 UFW: sudo ufw disable
  • 查看状态: sudo ufw status verbose
  • 允许 SSH (端口 22): sudo ufw allow sshsudo ufw allow 22/tcp
  • 允许 HTTP (端口 80): sudo ufw allow httpsudo ufw allow 80/tcp
  • 允许 HTTPS (端口 443): sudo ufw allow httpssudo ufw allow 443/tcp
  • 拒绝所有传入连接 (默认行为): sudo ufw default deny incoming
  • 删除规则: sudo ufw delete allow 22/tcp

b. Firewalld

Firewalld 是 Red Hat 系列发行版(如 CentOS, RHEL, Fedora)上默认的动态防火墙管理工具。它引入了“区域 (zones)”的概念,允许你根据网络连接的信任级别应用不同的规则集。

  • 优点:
    • 动态管理: 规则可以在不中断现有连接的情况下进行更改。
    • 区域 (Zones): 方便管理不同网络环境(例如,家庭、公共、内部)。
    • 服务和端口: 可以通过服务名(如 ssh, http)或端口号进行配置。
    • 富规则 (Rich Rules): 支持更复杂的规则定义。
  • 缺点: 比 UFW 稍微复杂一些,但比直接使用 iptables 简单。

Firewalld 基本命令示例:

  • 启动 Firewalld: sudo systemctl start firewalld
  • 启用 Firewalld (开机自启): sudo systemctl enable firewalld
  • 查看状态: sudo firewall-cmd --state
  • 查看所有区域和规则: sudo firewall-cmd --list-all-zones
  • 查看活动区域: sudo firewall-cmd --get-active-zones
  • 允许 SSH 服务 (在公共区域): sudo firewall-cmd --zone=public --add-service=ssh --permanent
  • 允许端口 80 (TCP) (在公共区域): sudo firewall-cmd --zone=public --add-port=80/tcp --permanent
  • 重新加载 Firewalld 使规则生效: sudo firewall-cmd --reload
  • 删除规则: sudo firewall-cmd --zone=public --remove-service=ssh --permanent

如何选择?

  • 对于大多数桌面用户和简单的服务器: UFW 是一个很好的选择,因为它非常简单易用。
  • 对于 Red Hat/CentOS 用户或需要更灵活的“区域”管理: Firewalld 是推荐的。
  • 对于需要精细控制或处理复杂网络场景的资深用户/管理员: 直接使用 iptablesnftables 可能会更合适,但需要投入更多学习时间。

无论你选择哪种工具,防火墙都是保护你的 Linux 系统免受未经授权访问的关键一步。始终确保你的防火墙已启用并配置正确,只允许必要的流量通过。

你更倾向于使用哪种 Linux 发行版呢?我能根据你的发行版提供更具体的防火墙配置建议。