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):
当一个数据包匹配到一条规则时,就会执行一个动作。用 -j
或 --jump
- **
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
:清空计数器
常用命令操作:
1 | # 列出所有规则(默认filter表) |
注意: 在设置 DROP
策略之前,请确保你已经添加了允许 SSH 连接的规则,否则你可能会将自己锁在服务器之外!最佳实践是先设置允许 SSH,再设置 DROP
策略。
匹配条件(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
扩展模块及其详细选项。
NAT表
nat
表在 iptables
中专门用于执行网络地址转换(Network Address Translation, NAT)操作。NAT 是一种网络技术,用于修改 IP 数据包的源 IP 地址或目标 IP 地址(有时也包括端口号),从而实现 IP 地址的复用、隐藏内部网络结构或进行服务重定向。尤其在内网设备访问外网、透明代理、端口转发、负载均衡等场景中扮演极为关键的角色。
它不会过滤或阻止数据包,只会在特定阶段修改数据包头部信息。
nat
表的核心功能
nat
表的主要功能就是修改数据包的 IP 地址和/或端口。它通常用于以下场景:
共享互联网连接(MASQUERADE/SNAT):
让多个内部私有 IP 地址的设备通过一个公共 IP 地址访问互联网。这是家庭路由器和小型办公室网络中最常见的 NAT 用途。
端口转发/端口映射(DNAT):
将来自外部网络的特定端口请求重定向到内部网络的特定主机和端口。这允许外部用户访问内部服务器(如 Web 服务器、SSH 服务器),即使这些服务器没有公共 IP 地址。
负载均衡(LVS/HAProxy 等通常也会用到 NAT 模式):
虽然 iptables 本身不提供完整的负载均衡功能,但 DNAT 可以作为底层机制之一,将请求分发到后端服务器。
nat
表的链(Chains)
nat
表有三条内置链,它们在数据包生命周期的不同阶段执行 NAT 操作:
PREROUTING
链:- 何时处理? 在数据包到达防火墙并进行路由决策之前。
- 主要用途:用于目标地址转换(DNAT)。它在数据包被路由到本地进程或转发到其他网络之前,修改数据包的目标 IP 地址和/或端口。这意味着数据包的目标在进入防火墙后立即被改变,后续的路由决策将基于这个新的目标地址。
OUTPUT
链:- 何时处理? 处理由本机生成的数据包。
- 主要用途:用于修改本机进程发出的数据包的目标 IP 地址和/或端口。例如,如果本机上的服务需要连接到某个外部地址,但希望连接到另一个地址,可以在这里进行 DNAT。这个链相对不那么常用,因为大部分 DNAT 都是针对外部入站流量的。
1
iptables -t nat -A OUTPUT -p tcp --dport 80 -d 1.1.1.1 -j DNAT --to-destination 127.0.0.1:8080
POSTROUTING
链:- 何时处理? 在数据包即将离开防火墙并经过路由决策之后。
- 主要用途:用于源地址转换(SNAT 或 MASQUERADE)。它在数据包被路由到传出接口之后,修改数据包的源 IP 地址和/或端口。这是实现内网共享外网的主要链,因为数据包离开防火墙时,其源 IP 已经被修改为防火墙的公共 IP。
nat
表的常用动作/目标(Targets/Actions)
在 nat
表中,最常用的动作是:
DNAT (Destination Network Address Translation):
修改数据包的目标 IP 地址和/或端口。通常在 PREROUTING 链中使用。
- 选项:
--to-destination [ipaddr[-ipaddr]][:port[-port]]
示例:将所有访问本机 80 端口的请求转发到内部服务器
192.168.1.100
的 8080 端口。1
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:8080
- 选项:
SNAT (Source Network Address Translation):
修改数据包的源 IP 地址和/或端口。通常在 POSTROUTING 链中使用。主要用于将私有 IP 地址转换为公共 IP 地址,以便访问外部网络。
- 选项:
--to-source [ipaddr[-ipaddr]][:port[-port]]
示例:将所有从内部网络
192.168.1.0/24
发出的数据包的源 IP 修改为本机公共 IP203.0.113.1
。1
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to-source 203.0.113.1
这里的
eth0
是连接到互联网的接口。- 选项:
MASQUERADE:
这是 SNAT 的一个特殊形式,当防火墙的公共 IP 地址是动态分配时(如 ADSL 拨号或 DHCP 获取 IP)使用。它会自动选择传出接口的当前 IP 地址作为源地址,现代更常用。
- 没有
to-source
选项,因为它会自动获取 IP。
示例:允许内部网络共享通过
eth0
接口的动态 IP 访问互联网。1
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
- 没有
nat
表与 filter
表的关系(重要!)
理解 nat
表和 filter
表的工作顺序至关重要,因为它们处理数据包的阶段不同:
PREROUTING
(nat):在路由前进行 DNAT,改变数据包的目标。- 路由决策(Routing Decision):系统根据数据包的当前目标 IP(可能已被 DNAT 修改过)决定是将其转发到其他主机(经过
FORWARD
链)还是交付给本地进程(经过INPUT
链)。 - **
INPUT
(filter)**:处理目标是本机的数据包。 - **
FORWARD
(filter)**:处理目标是其他主机的数据包。 - **
OUTPUT
(filter)**:处理本机发出的数据包。 POSTROUTING
(nat):在路由后进行 SNAT,改变数据包的源。
关键点:
- DNAT 发生在路由之前:这意味着在
INPUT
和FORWARD
链中,数据包的目标 IP 已经是经过 DNAT 修改后的内部 IP。 - SNAT 发生在路由之后:这意味着在
OUTPUT
和FORWARD
链中,数据包的源 IP 仍然是原始的内部 IP,只有在数据包即将离开时才被 SNAT 修改。
实际应用场景
场景 1:端口转发(Port Forwarding / DNAT)
你有一台 Web 服务器 192.168.1.100
在内网运行,希望外部用户通过你的公共 IP 203.0.113.1
访问它。
确保 IP 转发已启用:
编辑 /etc/sysctl.conf 文件,将 net.ipv4.ip_forward 设置为 1。
Code snippet
1
2# /etc/sysctl.conf
net.ipv4.ip_forward = 1然后执行
sudo sysctl -p
使其生效。添加 DNAT 规则(PREROUTING 链):
将所有进入 eth0 接口(你的公共网络接口)的、目标端口为 80 的 TCP 请求,其目标 IP 修改为 192.168.1.100,端口修改为 80。
1
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:80
添加 filter 规则(FORWARD 链):
允许这些被 DNAT 后的数据包通过防火墙进行转发。
1
2iptables -A FORWARD -p tcp -d 192.168.1.100 --dport 80 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
# 注意:如果 FORWARD 链的默认策略是 DROP,这条规则必不可少。添加 SNAT/MASQUERADE 规则(POSTROUTING 链,可选但强烈推荐):
确保内网服务器 192.168.1.100 返回的响应能够正确回到客户端。如果没有这条规则,Web 服务器可能会直接将响应发回给客户端,而客户端只知道公共 IP,导致连接中断。
1
2
3
4
5# 使用 SNAT 如果你的公共IP是固定的
iptables -t nat -A POSTROUTING -o eth0 -p tcp -d 192.168.1.100 --dport 80 -j SNAT --to-source 203.0.113.1
# 或者使用 MASQUERADE 如果你的公共IP是动态的 (更常见)
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE这里的
POSTROUTING
规则将内部 Web 服务器发出的响应包的源 IP 修改为防火墙的公共 IP,这样客户端就能正确接收到响应。
场景 2:共享互联网连接(MASQUERADE)
你有一台 Linux 服务器作为网关,内部网络 192.168.1.0/24
的机器需要通过它访问互联网。
确保 IP 转发已启用(同上)。
添加 MASQUERADE 规则(POSTROUTING 链):
将所有从内部网络 192.168.1.0/24 发出,并准备通过 eth0 接口(连接外部网络的接口)的数据包,其源 IP 地址动态修改为 eth0 的当前 IP 地址。
1
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
添加 filter 规则(FORWARD 链):
允许内部网络的数据包通过防火墙进行转发。
1
2iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT # eth1 是内网接口
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT # 允许已建立和相关连接的回包
还可以透明代理(拦截 HTTP 到代理端口):
1 | # 将所有 80 端口流量转发到本地 3128(Squid) |
查看规则:
1 | iptables -t nat -L -v --line-number |
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)。
mangle 表
iptables
的 mangle
表是用于修改网络包内容或标记网络包的高级功能表,专注于对数据包的深度处理,常用于 流量标记(mark)、TOS/DSCP 设置、TTL 修改、丢弃流量等操作。
它不像 filter
表那样控制是否允许数据包通过,也不像 nat
表那样做地址转换,而是对包本身的某些字段做修改或添加信息(比如打标记),供后续内核模块(如 tc
流控、策略路由)使用。
mangle
表比 filter
或 nat
表拥有更多的内置链,因为它需要在数据包的整个生命周期中进行更细粒度的修改,它拥有所有 5 条内置链。
mangle
表的常用动作/目标(Targets/Actions)
在 mangle
表中,最常用的动作是:
TOS (Type of Service) / DSCP (Differentiated Services Code Point):
修改 IP 头中的 TOS 字段(或更现代的 DSCP 字段)。
选项:
--set-tos <value>
或--set-dscp <value>
示例:将 SSH 流量的 DSCP 值设置为
EF
(Expedited Forwarding),以获得优先级。1
iptables -t mangle -A PREROUTING -p tcp --dport 22 -j DSCP --set-dscp 46
TTL (Time To Live):
修改 IP 头中的 TTL 值。
选项:
--ttl-set <value>
(设置为特定值),--ttl-inc <value>
(增加),--ttl-dec <value>
(减少)示例:将所有出站数据包的 TTL 值设置为 64。
1
iptables -t mangle -A POSTROUTING -o eth0 -j TTL --ttl-set 64
(这有时用于使服务器的流量看起来像来自普通的 Linux 桌面,而不是专业的路由器或服务器,因为它会将 TTL 重置到操作系统的默认出站 TTL。)
MARK:
在数据包上设置一个 Netfilter 标记(一个整数值)。这个标记不会实际修改数据包的 IP 头,它只存在于内核内部,用于策略路由 (ip rule) 或 tc (Traffic Control) 等后续处理。
选项:
--set-mark <value>
(设置标记),--and-mark <value>
(按位与),--or-mark <value>
(按位或)示例:标记所有来自特定内部 IP 的 Web 流量,以便后续策略路由将其路由到特定的出口。
1
2# 在 PREROUTING 链标记数据包
iptables -t mangle -A PREROUTING -s 192.168.1.10 -p tcp --dport 80 -j MARK --set-mark 10然后,你可以在策略路由中使用这个标记:
1
2ip rule add fwmark 10 table 100
ip route add default via <gateway_ip> dev <interface> table 100
CONNMARK:
对整个连接设置一个标记,而不是仅仅针对单个数据包。一个连接中的所有数据包都会继承这个标记。这非常有用,因为它允许你根据连接的初始数据包来标记整个会话。
选项:
--set-mark <value>
,--save-mark
(从数据包标记保存到连接标记),--restore-mark
(从连接标记恢复到数据包标记)示例:将所有来自某个源 IP 的新连接标记为 20,并对该连接的所有后续数据包都应用此标记。
1
2
3
4
5
6# 在 PREROUTING 链,对 NEW 状态的连接打上标记
iptables -t mangle -A PREROUTING -s 192.168.1.20 -m state --state NEW -j CONNMARK --set-mark 20
# 在后续的规则中,可以恢复这个标记到数据包,然后根据数据包标记进行处理
iptables -t mangle -A PREROUTING -m connmark --mark 20 -j CONNMARK --restore-mark
# 然后可以在策略路由中使用 mark 20
mangle
表的执行顺序
mangle
表的规则在数据包通过 Netfilter 框架时,会在 raw
表之后,nat
表和 filter
表之前或之后执行,具体取决于它们所在的链:
入站数据包顺序:
raw -> mangle (PREROUTING) -> nat (PREROUTING) -> 路由决策 -> mangle (INPUT) -> filter (INPUT) -> 本地进程
转发数据包顺序:
raw -> mangle (PREROUTING) -> nat (PREROUTING) -> 路由决策 -> mangle (FORWARD) -> filter (FORWARD) -> mangle (POSTROUTING) -> nat (POSTROUTING)
出站数据包顺序:
本地进程 -> raw -> mangle (OUTPUT) -> nat (OUTPUT) -> 路由决策 -> mangle (POSTROUTING) -> nat (POSTROUTING)
关键点:
- **
PREROUTING
**:最先处理入站数据包,常用于标记或修改在路由或 NAT 前需要处理的数据包。 - **
POSTROUTING
**:最晚处理出站数据包,常用于修改离开系统前的数据包(如 TTL)。 - **
MARK
和CONNMARK
**:这些标记主要在内核内部使用,并不会改变数据包的物理内容,但在策略路由和流量控制中非常强大。
实际应用场景
为 VoIP 流量设置高优先级(QoS):
如果你在服务器上运行 VoIP 服务,可以标记 SIP/RTP 流量,让路由器优先处理。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34# 标记SIP信令流量
iptables -t mangle -A PREROUTING -p udp --dport 5060 -j DSCP --set-dscp 46
# 标记RTP媒体流
iptables -t mangle -A PREROUTING -p udp -m multiport --dports 10000:20000 -j DSCP --set-dscp 46
(然后在路由器或其他 Qos 设备上配置根据 DSCP 值进行优先级转发)
2. 实现策略路由:
让来自特定源 IP 或特定服务的流量走不同的出口或路由表。
```bash
# 在 mangle 表的 PREROUTING 链中为来自特定源 IP 的流量设置标记
iptables -t mangle -A PREROUTING -s 192.168.1.50 -j MARK --set-mark 100
# 将标记保存到连接,以便回包也能匹配(可选,但通常推荐)
iptables -t mangle -A POSTROUTING -j CONNMARK --save-mark
# 然后在 ip rule 中添加规则:
sudo ip rule add fwmark 100 table 10
# 定义路由表 10
sudo ip route add default via <gateway_for_table_10> dev <interface_for_table_10> table 10
3. 防止 TTL 泄漏/修改:
在某些特定场景下,你可能不希望服务器的流量暴露其真实的操作系统类型(因为不同的操作系统有默认的 TTL 值),或者需要修改 TTL 以绕过某些网络设备。
```bash
# 将所有出站TCP流量的TTL设置为64(Linux桌面默认值)
iptables -t mangle -A POSTROUTING -p tcp -j TTL --ttl-set 64负载均衡或连接亲和性(结合 ipvs 或 conntrack):
mangle 表可以通过 MARK 和 CONNMARK 与 ipvs(IP Virtual Server)或更复杂的连接跟踪机制结合,实现更精细的负载均衡和会话保持。
查看 mangle
表规则
1 | iptables -t mangle -L -v --line-numbers |
iptables
的 mangle
表是一个高级且强大的工具,它允许你在数据包通过 Linux 内核协议栈的不同阶段时,对其 IP 头部进行细粒度的修改(如 TOS/DSCP、TTL)或内部标记(MARK
/CONNMARK
)。它本身不用于过滤或地址转换,而是作为流量控制和策略路由的预处理阶段。理解 mangle
表以及其与其他表和 Linux 网络子系统(如 ip rule
、tc
)的交互,是实现复杂网络流量管理和 QoS 策略的关键。
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 系统免受未经授权访问的关键一步。始终确保你的防火墙已启用并配置正确,只允许必要的流量通过。