
嘿,各位Linux服务器的“守门人”和“网络架构师”们!咱们在配置服务器安全的时候,防火墙绝对是第一道,也是最重要的一道防线。你可能已经很熟练地使用像UFW
(Uncomplicated Firewall) 这样简单易上手的工具,或者在CentOS/RHEL系上用firewalld
来管理端口开闭了。这些工具确实方便,点几下命令,就能让你的服务器“看起来”安全了不少。但是,你有没有好奇过,这些“傻瓜式”工具的背后,到底是谁在默默地为你“负重前行”,真正执行那些复杂的网络包过滤任务呢?
没错,它们背后的“大佬”通常就是大名鼎鼎的iptables
,或者是它的现代化继任者nftables
!它们才是Linux内核网络包过滤框架Netfilter的“御用大内总管”。今天,Hostol就来当一回“庖丁”,带你解开iptables
和nftables
的神秘“筋骨”,深入理解Linux网络包是如何在这套复杂的“规则迷宫”中穿梭、被检验、最终决定其“生死命运”的。别担心,我们会用最形象的比喻,让你也能轻松看懂这高深莫测的底层逻辑!
网络包过滤:十字路口的“智能交通警察”
在开始“解牛”之前,咱们得先明白啥是“网络包过滤”。想象一下,互联网上的所有数据,都是被打成一个个小“包裹”(数据包,Packet)来传输的。每个包裹上都贴着“快递单”,上面写着发件人地址(源IP)、收件人地址(目标IP)、里面装的是啥类型的“货物”(协议,如TCP/UDP/ICMP),以及要送到哪个“部门”的哪个“窗口”(源端口、目标端口)等等。
网络包过滤,就好比在服务器的每一个“网络入口”和“出口”都设置了一个超级智能的“交通警察”。 这个“警察”会检查每一个想通过的“包裹”,看看它的“快递单”信息是否符合预设的一系列“交通规则”(过滤规则)。如果符合某条“放行”规则,那就“欢迎光临”;如果符合某条“禁止”规则,那就“对不起,此路不通”(可能被直接丢弃DROP
,或者礼貌地拒绝REJECT
并告知对方)。
`iptables`:“久经沙场”的防火墙老将
iptables
是Linux历史上使用时间最长、应用也最广泛的防火墙管理工具。虽然现在nftables
正在逐步取代它,但理解iptables
的核心思想,对于理解整个Linux网络包过滤机制,乃至理解nftables
都大有裨益。很多现存的系统和脚本也依然在使用它。
iptables
的“世界观”主要由三个核心概念构成:表 (Tables)、链 (Chains)、规则 (Rules)。
1. 表 (Tables):各司其职的“功能部门”
你可以把“表”想象成“警察局”里的不同“部门”,每个部门负责处理特定类型的“案件”(网络包处理任务)。iptables
主要有这几个“部门”:
filter
表 (过滤部门): 这是最常用、也是默认的表,防火墙的“绝对主力”!它的主要职责就是根据规则对数据包进行“放行”(ACCEPT
)或“拦截”(DROP
,REJECT
)。我们平时说“开关某个端口”,主要就是在这个表的链上做文章。nat
表 (网络地址转换部门): 负责修改数据包的源IP/端口或目标IP/端口。比如,我们常说的端口转发(DNAT,让外网访问特定端口时,实际转发到内网某台机器的某端口)、源地址转换(SNAT,让内网多台机器共享一个公网IP上网,MASQUERADE是SNAT的一个特例)等“变身魔法”,都是这个部门的活儿。mangle
表 (数据包“美容/整形”部门): 负责对数据包的某些头部字段进行修改,比如修改IP头中的TOS(服务类型)字段来影响路由优先级、修改TTL(生存时间)等。这个部门比较高级,日常用得相对少。raw
表 (原始数据包“预检”部门): 这个部门的优先级非常高,在内核进行连接跟踪(Connection Tracking)之前就会处理数据包。主要用来对那些你不想被连接跟踪系统处理的包打上NOTRACK
标记。- (还有一个
security
表,通常用于配合SELinux等强制访问控制系统,更为复杂,我们入门先不展开。)
2. 链 (Chains):部门内部的“流水线”或“检查点”
每个“表”(部门)内部,又包含若干个“链”。“链”就像是部门内部的一条条“流水线”或者“检查点”,数据包会按照预设的路径流经这些链。链上排列着一条条具体的“规则”。
最重要的五个内置链(它们是Netfilter框架在内核中预设的“钩子点”,Hook Points):
PREROUTING
链: 所有进入网络接口的数据包,在进行路由判断(决定这个包是发给本机、还是需要转发给其他机器)之前,都会先经过这条链。nat
表的DNAT(目标地址转换,如端口映射)通常在这里操作。INPUT
链: 当数据包经过路由判断,确定其目标是服务器本机时,就会进入这条链。filter
表的“入站规则”(比如允许哪些外部IP访问本机的SSH服务)主要在这里设置。FORWARD
链: 如果数据包的目标不是本机,而是需要本机将其转发给其他网络(比如服务器作为路由器或网关时),那么这个包就会流经这条链。filter
表的“转发规则”在这里定义。OUTPUT
链: 从服务器本机应用程序产生并发往外部的数据包,在进行路由判断之前,会先经过这条链。filter
表的“出站规则”(比如禁止本机访问某些外部网站)在这里设置。POSTROUTING
链: 所有即将离开网络接口的数据包,在进行路由判断并准备发出去之后,会经过这条链。nat
表的SNAT(源地址转换,如共享IP上网)和MASQUERADE通常在这里操作。
数据包的奇幻漂流记 (简化版,以到达本机的数据包为例):
网卡收到包 -> PREROUTING
链 (可能经过raw
, mangle
, nat
表) -> 路由决策 (发现是给本机的) -> INPUT
链 (可能经过mangle
, filter
表) -> 本机应用程序
除了这些内置链,你还可以创建自定义链,把一组相关的规则组织在一起,然后在内置链里通过一个“跳转”(-j YOUR_CUSTOM_CHAIN
)规则把包导向自定义链处理,这样能让规则集更清晰、更模块化。
3. 规则 (Rules):具体的“交通法规”
链是由一条条规则组成的,规则是iptables
的核心。每条规则都包含两个主要部分:
- 匹配条件 (Matches): 定义了这条规则“关心”什么样的数据包。比如:
- 源IP地址/网络 (
-s 192.168.1.100
) - 目标IP地址/网络 (
-d 8.8.8.8
) - 协议类型 (
-p tcp
,-p udp
,-p icmp
) - 源端口/目标端口 (
--sport 12345
,--dport 80
,需要配合-p tcp
或-p udp
) - 进入/流出网络接口 (
-i eth0
,-o ppp0
) - 连接状态 (
-m state --state NEW,ESTABLISHED,RELATED
,这个非常重要,是实现“状态防火墙”的关键!) - 还有很多很多其他匹配模块……
- 源IP地址/网络 (
- 目标动作 (Target): 如果数据包的特征完全符合了匹配条件,那么就对它执行这个“动作”。比如:
ACCEPT
:放行!数据包可以继续它的旅程。DROP
:悄悄丢弃。数据包石沉大海,发送方不会收到任何回应(可能会超时)。REJECT
:明确拒绝。会给发送方返回一个错误信息(比如ICMP port-unreachable)。LOG
:记录日志。把匹配到的包的信息记录到系统日志(通常是/var/log/kern.log
或dmesg
),本身不影响包的命运,常用于调试或审计,通常需要配合其他目标动作。MASQUERADE
,SNAT
,DNAT
,REDIRECT
:这些是nat
表中常用的地址/端口转换动作。- 跳转到自定义链:
-j MY_CUSTOM_CHAIN
。
数据包在链中会从上到下依次匹配规则,一旦成功匹配到一条规则并执行了它的目标动作(除非那个动作是LOG
这种非终止性的),那么这个包的“命运”通常就定了,不再继续匹配链中后续的规则(某些特殊情况除外)。
链的默认策略 (Default Policy): 如果一个包流经了整条链,都没有匹配到任何一条规则,那它就会按照这条链的“默认策略”来处理。对于INPUT
和FORWARD
链,出于安全考虑,默认策略通常应该设置为DROP
或REJECT
,然后明确ACCEPT
你需要的流量;对于OUTPUT
链,默认策略通常是ACCEPT
。
状态防火墙:“认得熟客”的聪明门卫
如果你的INPUT
链默认是DROP
,那是不是所有进来的包都会被丢掉,连你正常访问网站的返回数据也进不来了?不会!这就是“状态防火墙”(Stateful Firewall)的功劳,它依赖于内核的连接跟踪系统(conntrack
)。
我们通常会在INPUT
链的顶部加上这样一条规则:
sudo iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
这条规则的意思是:如果进来的包属于一个已经建立的连接(ESTABLISHED
),或者是与某个已建立连接相关的连接(RELATED
,比如FTP的数据连接),那就直接放行!这就像门卫记得刚才有位客人(你发出的请求)进去了,现在他带着“回礼”(服务器的响应)出来,自然就认识了,直接放行,不用再盘问一遍。
`nftables`:“后起之秀”,统一江湖的野心家
iptables
虽然劳苦功高,但也存在一些设计上的“历史包袱”,比如规则管理复杂、性能在超大规模规则集下可能下降、IPv4和IPv6有两套独立的命令(iptables
和ip6tables
)、还有arptables
(ARP包过滤)、ebtables
(网桥包过滤)等等,工具太多太分散。
于是,nftables
应运而生,它的目标就是提供一个统一的、更高效、更灵活的下一代Linux网络包过滤框架。
`nftables`的核心理念:更简洁,更强大
- 统一管理: 一个
nft
命令就能管理IPv4、IPv6、ARP、网桥等所有类型的包过滤规则,告别工具混乱。 - 表和链的重新定义:
- 表 (Tables): 在
nftables
里,表只是一个简单的“容器”,用来存放链。创建表时你需要指定一个“地址族”(Address Family),比如ip
(IPv4),ip6
(IPv6),inet
(同时包含IPv4和IPv6,推荐!),arp
,bridge
,netdev
(用于入口流量处理)。 - 链 (Chains): 链依然是规则的有序列表。但创建链时,你需要明确指定链的“类型”(Type)和它要挂载到的“钩子点”(Hook)。
- 链类型:
filter
(用于过滤),nat
(用于地址转换),route
(用于修改路由,不常用)。 - 钩子点 (Hooks): 和
iptables
的内置链类似,如prerouting
,input
,forward
,output
,postrouting
,还有ingress
(更早期的入口钩子,在netdev
族表中使用)。你还需要为链指定一个“优先级”(Priority),数字越小,优先级越高,越先处理。
- 链类型:
- 表 (Tables): 在
- 规则语法更自然:
nftables
的规则语法更接近自然语言,也更紧凑。 - 内置高级数据结构: 支持集合(Sets)、映射(Maps)、计数器(Counters)、配额(Quotas)等,可以在规则中高效地匹配大量IP、端口,或者实现更复杂的逻辑。这在
iptables
里通常需要借助ipset
等外部工具。 - 事务性操作: 所有的规则更改都在一个“事务”中进行,要么全部成功,要么全部失败回滚,避免了
iptables
那种一条条加载规则可能导致中间状态不一致的问题。
nftables
基本操作一瞥 (`nft`命令):
# 创建一个用于IPv4和IPv6的表,名为 my_firewall
sudo nft add table inet my_firewall
# 在表中创建一个名为 my_input_filter 的链,类型是filter,挂载到input钩子,优先级为0
sudo nft add chain inet my_firewall my_input_filter { type filter hook input priority 0 \; policy drop \; }
# 这里我们还给链设置了默认策略为drop
# 添加规则:允许已建立和相关的连接
sudo nft add rule inet my_firewall my_input_filter ct state established,related accept
# 添加规则:允许SSH (TCP 22端口) 的新连接
sudo nft add rule inet my_firewall my_input_filter tcp dport 22 ct state new accept
# 添加规则:允许HTTP (TCP 80端口) 和 HTTPS (TCP 443端口) 的新连接 (使用集合)
sudo nft add set inet my_firewall allowed_web_ports { type inet_service \; flags interval \; }
sudo nft add element inet my_firewall allowed_web_ports { 80, 443 }
sudo nft add rule inet my_firewall my_input_filter tcp dport @allowed_web_ports ct state new accept
# 列出所有规则集
sudo nft list ruleset
是不是感觉nftables
的语法结构更清晰一些?连接跟踪(ct state
)依然是核心。
iptables
vs. nftables
:新手该何去何从?
这是一个常见的问题。
iptables
: 它是“老兵”,身经百战,网上关于它的教程、资料、脚本、工具多如牛毛。很多老系统、老环境还在用它。理解它的核心概念(表、链、目标、连接跟踪)对于理解任何基于Netfilter的防火墙都非常有价值。nftables
: 它是“新星”,是Linux防火墙的未来趋势。它更高效、更灵活、更统一。主流Linux发行版(如Debian 10+, RHEL/CentOS 8+, Ubuntu 20.04+的一些版本)已经默认使用nftables
作为后端防火墙框架(即使你用iptables
命令,也可能只是一个兼容层,最终转换成nftables
规则)。
Hostol给新手的建议:
- 先理解核心概念: 无论用哪个工具,网络包过滤的基本原理、表和链的逻辑流转、连接跟踪的重要性,这些都是相通的。把这些“内功”练好最重要。
- 如果你维护的是老系统,或者工作中大量接触
iptables
脚本,那深入学习iptables
是必须的。 - 如果你是在全新的、默认使用
nftables
的系统上从零开始配置防火墙,那么直接学习nftables
可能是更长远的选择。 它的学习曲线可能一开始稍微陡峭一点(因为新,中文资料相对少一些),但一旦上手,你会发现它的强大和优雅。 - 很多上层工具(如UFW, firewalld)会自动帮你处理后端是
iptables
还是nftables
,所以日常管理用这些工具依然方便。 但了解底层,能让你在遇到复杂问题或者需要精细控制时,更有底气。
你可以把iptables
想象成一套经典的、功能齐全但略显笨重的“传统机械工具箱”;而nftables
则像是一套现代化的、高度集成、可编程的“模块化电动工具系统”。老工具依然能干活,新工具则代表了更高的效率和未来的方向。
呼!一口气“解剖”了iptables
和nftables
这两头“Linux防火墙巨兽”,是不是感觉对服务器网络安全的底层运作清晰了不少?虽然它们看起来错综复杂,但只要你抓住了“表管功能,链定路径,规则把关,状态追踪”这几个核心脉络,再结合生动的比喻去理解数据包的“奇幻漂流”,你会发现它们其实也充满了逻辑之美。掌握了这些底层知识,你再去看UFW或firewalld生成的规则,或者自己动手写更高级的防火墙策略时,就能做到“知其然,更知其所以然”,成为真正的“防火墙驾驭者”!Hostol希望这篇“庖丁解牛”能为你打开一扇通往Linux网络安全更深层次理解的大门!