iptables/nftables
在 Linux 中,最核心的防火墙管理工具是 Netfilter 框架,Netfilter 是 Linux 内核中的一个框架,它允许在网络数据包通过协议栈的不同阶段时进行截取、检查、修改和丢弃,而与它交互的主要命令行工具是 iptables 和 nftables。
许多 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
链:在数据包到达路由决策点之前处理(主要在nat
和mangle
表中使用)。POSTROUTING
链:在数据包离开路由决策点之后处理(主要在nat
和mangle
表中使用)。
规则(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
: 指定要操作的表(filter
、nat
、mangle
、raw
)。如果省略,默认为filter
。command
: 要执行的操作,如添加规则、删除规则、列出规则等。chain
: 要操作的链(INPUT
、OUTPUT
、FORWARD
等)。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 | # 允许所有已建立和相关连接进入和离开 |
1 | # 允许新连接和建立连接的用户,防止SYN flood攻击 |
2. limit
模块(速率限制)
用于限制匹配到的数据包的速率,防止某些类型的洪水攻击或资源滥用。
核心选项:
--limit <rate>
: 平均速率,例如5/minute
(每分钟 5 个包),1/s
(每秒 1 个包)。--limit-burst <number>
: 初始峰值,允许短时间内超过平均速率的包数。默认是 5。
典型应用场景: 防止 SSH 暴力破解尝试:限制来自同一源 IP 的 SSH 连接尝试速率。
1 | # 限制每分钟最多 5 个新的 SSH 连接尝试,峰值允许 10 个 |
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 | iptables -A INPUT -m mac --mac-source 00:11:22:33:44:55 -j ACCEPT |
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 | 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 |
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 | # 允许来自特定IP的SSH连接 |
1 | # 使用 -L 选项列出规则时,如果规则包含注释,注释信息会自动显示。 |
不同版本的 iptables
或内核可能对注释的长度有隐式或显式限制。通常,保持注释简洁明了是最佳实践。在部署任何新规则时,始终附带清晰的注释,说明规则的用途、相关的服务或应用程序、以及创建者/日期。
1 | # 允许公司内部子网访问Jenkins管理端口 |
可以使用 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
- Debian/Ubuntu:
2. nftables
nftables 是 Linux 内核中 Netfilter 的一个较新、更现代的包过滤框架,旨在最终取代 iptables。它提供了一个更统一和灵活的语法来处理 IPv4、IPv6、ARP 和桥接帧的规则。
- 优点:
- 统一的语法: 一个工具处理所有协议,简化了配置。
- 性能提升: 更高效的规则处理。
- 动态更新: 可以动态添加/删除规则,无需重新加载整个防火墙。
- 更强大的集合: 支持更复杂的匹配条件。
- 缺点: 相对较新,一些旧的教程或工具可能仍基于 iptables。
虽然 nftables
是推荐的未来方向,但由于 iptables
广泛存在且功能强大,许多系统仍然使用它或其前端。
3. 高级前端工具
为了简化防火墙管理,许多 Linux 发行版提供了更用户友好的工具,它们实际上在后台生成和管理 iptables
或 nftables
规则。
a. UFW (Uncomplicated Firewall)
UFW 是 Ubuntu 及其衍生版本上默认的防火墙管理工具,顾名思义,它旨在简化防火墙的配置。
- 优点:
- 非常简单: 命令行语法直观易懂。
- 适合桌面和服务器: 对于常见的防火墙需求非常方便。
- 集成应用配置文件: 许多应用(如 Apache, OpenSSH)提供 UFW 配置文件,方便一键开启/关闭端口。
- 缺点: 对于非常复杂的定制规则,可能不如直接使用
iptables
或nftables
灵活。
UFW 基本命令示例:
- 启用 UFW:
sudo ufw enable
- 禁用 UFW:
sudo ufw disable
- 查看状态:
sudo ufw status verbose
- 允许 SSH (端口 22):
sudo ufw allow ssh
或sudo ufw allow 22/tcp
- 允许 HTTP (端口 80):
sudo ufw allow http
或sudo ufw allow 80/tcp
- 允许 HTTPS (端口 443):
sudo ufw allow https
或sudo 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 是推荐的。
- 对于需要精细控制或处理复杂网络场景的资深用户/管理员: 直接使用 iptables 或 nftables 可能会更合适,但需要投入更多学习时间。
无论你选择哪种工具,防火墙都是保护你的 Linux 系统免受未经授权访问的关键一步。始终确保你的防火墙已启用并配置正确,只允许必要的流量通过。
你更倾向于使用哪种 Linux 发行版呢?我能根据你的发行版提供更具体的防火墙配置建议。