Linux之netfilter(1)基础介绍
Author:Once Day Date:2025年11月11日
全系列文章请查看专栏 : Linux内核知识_Once-Day的博客-CSDN博客
漫漫长路,有人对你微笑过嘛...
参考文档:
- netfilter/iptables project homepage - Documentation about the netfilter/iptables project
- Linux防火墙:Netfilter的深度解析 - 知乎
- Netfilter 框架浅析 | Symbol Crash
- Netfilter技术深度解析:Linux内核网络过滤的核心框架_netfilter详解-CSDN博客
- 一图看懂Linux网络核心:Netfilter框架全景解剖Netfilter 框架由Rusty Russell 于 19 - 掘金
- Linux网络之 netfilter 框架学习研究netfilter 框架 netfilter 是 linux 内核中的 - 掘金
- 深入理解 netfilter 和 iptables - 知乎
- iptables与netfilter | 深入架构原理与实践
- 一图看懂Linux网络核心:Netfilter框架全景解剖 - 知乎
文章目录
-
-
- Linux之netfilter(1)基础介绍
-
- [1. netfilter概述](#1. netfilter概述)
- [2. 相关工具](#2. 相关工具)
- [3. 原理介绍](#3. 原理介绍)
- [4. 链接跟踪](#4. 链接跟踪)
- [5. iptables介绍](#5. iptables介绍)
- [6. 应用实例](#6. 应用实例)
-
1. netfilter概述
Netfilter是Linux 2.4 引入的一个子系统,它作为一个通用的、抽象的框架,提供一整套的hook函数的管理机制,使得诸如数据包过滤、网络地址转换(NAT)和基于协议类型的连接跟踪成为了可能, 在 Linux 系统中发挥着至关重要的作用。它是一个强大而灵活的网络包过滤框架,为系统管理员提供了对网络数据包的精细控制。
Netfilter 的出现有其历史背景。Linux 早期的网络过滤机制相对简单且分散:
-
ipfwadm:Linux 内核 2.0 时代的防火墙工具,基于 BSD 的 ipfw,功能相对有限。
-
ipchains:在 Linux 2.2 内核中引入,改进了 ipfwadm,提供了更灵活的链式结构,但仍存在架构局限性,特别是在处理 NAT 和状态跟踪方面。
Netfilter 项目始于 1998 年末到 1999 年初,主要由 Rusty Russell 领导开发,目标是为 Linux 提供一个更强大、灵活的网络过滤框架。Netfilter 在 Linux 2.4 内核(2000 年发布)中正式引入,替代了之前的 ipchains 系统。采用了模块化设计和钩子机制,将网络包处理和用户配置界面分离,使网络过滤系统更加灵活和可扩展。
Netfilter 相比前代系统有几个重要创新:
-
连接跟踪:引入了连接状态跟踪机制,使防火墙可以基于连接状态做决策,这是实现"状态防火墙"的基础。
-
分离架构:明确区分了内核空间框架(Netfilter)和用户空间工具(iptables),使系统架构更清晰。
-
可扩展性:设计了可扩展的框架,允许通过模块方式添加新功能,无需修改核心代码。
Netfilter 通过在内核中插入钩子点,实现对网络数据包的过滤、修改和转发。它在 IP 报文处理流程中插入了 5 个挂载点,分别是:PREROUTING(路由前) 、INPUT(输入) 、FORWARD(转发) 、OUTPUT(输出) 、POSTROUTING(路由后)。
在这些挂载点上,可以注册处理数据包的回调函数。当数据包进入 Linux 内核经过挂载点的时候,会执行回调函数来处理数据包。
回调函数有多种返回值,例如 NF_ACCEPT 表示继续正常的报文处理,NF_DROP 将报文丢弃,NF_STOLEN 表示由钩子函数处理了该报文,不要再继续传送,NF_QUEUE 将报文入队,通常交由用户程序处理,NF_REPEAT 表示再次调用该钩子函数。

网络数据包通过Netfilter时的工作流向图,引用自:Netfilter 框架浅析 | Symbol Crash
2. 相关工具

Netfilter框架全景图,引用自:一图看懂Linux网络核心:Netfilter框架全景解剖Netfilter 框架由Rusty Russell 于 19 - 掘金
-
iptables 作为 Linux 系统中最广泛使用的防火墙工具,负责处理 IPv4 网络流量的过滤和转换。它通过五个不同的链(PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING)拦截数据包,根据管理员设定的规则进行匹配和处理。iptables 不仅能够基于源/目标 IP、端口和协议进行过滤,还支持网络地址转换(NAT)、数据包修改(mangle)和流量控制等高级功能。在服务器、路由器和网络安全设备中,iptables 常作为第一道防线抵御网络攻击,限制未授权访问,并实现网络流量的精细控制。
-
ip6tables 与 iptables 共享相似的命令语法和规则结构,但专门处理 IPv6 协议的数据包。ip6tables 理解 IPv6 的扩展头部和新特性,能够处理 IPv6 特有的安全挑战,如邻居发现协议(NDP)保护和 ICMPv6 消息过滤。在双栈网络环境中,ip6tables 与 iptables 协同工作,确保无论使用哪个版本的 IP 协议,网络安全策略都得到一致执行。
-
ebtables 专注于链路层(第二层)的网络安全,处理以太网帧而非 IP 数据包。在虚拟化环境、软件定义网络和网络桥接场景中,ebtables 的作用尤为重要。它能根据 MAC 地址过滤流量,防止 MAC 地址欺骗,控制广播风暴,并实现透明防火墙功能。当 Linux 系统作为网桥使用时,ebtables 可以在数据包到达上层协议之前就进行拦截和控制,为网络提供更早期的安全防护。
-
arptables 瞄准了局域网中常见的 ARP 协议安全问题。ARP 欺骗是局域网攻击的常见手段,攻击者通过发送伪造的 ARP 响应,将自己的 MAC 地址与目标 IP 关联,从而截获网络流量。arptables 允许管理员精确控制系统如何处理 ARP 请求和响应,可以设置规则只接受来自特定 MAC 地址的 ARP 包,或拒绝可疑的地址映射请求,有效防止中间人攻击和网络嗅探行为。
-
nftables 代表了 Linux 网络过滤技术的新方向,旨在替代之前所有分散的 tables 工具。它引入了统一的语法和处理框架,简化了防火墙规则的管理。nftables 采用表达式引擎架构,使规则编写更加简洁直观,同时支持集合、映射和动态更新等高级特性。性能方面,nftables 减少了规则评估的开销,提高了数据包处理效率,特别是在规则数量庞大时。作为现代 Linux 系统的默认选择,nftables 正逐步接管传统工具的角色,同时保持与旧系统的兼容性。
-
conntrack 是 Netfilter 框架的核心组件,负责跟踪网络连接的状态。它为 Linux 防火墙提供了"有状态"功能,使防火墙能够理解数据包在会话中的上下文。conntrack 维护一个连接表,记录每个活动连接的源地址、目标地址、端口以及协议等信息,将连接分类为新建(NEW)、已建立(ESTABLISHED)、相关(RELATED)和无效(INVALID)等状态。这种状态感知使防火墙规则更加智能,例如允许回应包通过而阻止未经请求的连接,大大提高了安全性和性能。
-
nf_log 是 Netfilter 的日志子系统,负责捕获和记录网络事件。当防火墙规则指定 LOG 目标时,nf_log 会记录匹配该规则的数据包信息,包括时间戳、源/目标 IP、端口、协议类型等关键数据。这些日志对于网络故障排查、安全审计和攻击检测至关重要。nf_log 支持多种日志目标,可以将记录发送到系统日志(syslog)、内核环形缓冲区或通过 netlink 接口传递给用户空间程序,为管理员提供网络活动的完整视图。
-
nf_queue 提供了内核空间和用户空间之间的通信机制,允许将数据包临时发送到用户空间进行复杂处理。这一功能对于实现高级网络应用如入侵检测系统(IDS)、深度包检测(DPI)和自定义协议分析至关重要。当数据包通过 nf_queue 发送到用户空间后,应用程序可以执行详细检查,然后决定接受、修改或丢弃该数据包。这种设计平衡了内核处理的高效性和用户空间处理的灵活性,使 Linux 能够支持复杂的网络安全解决方案。
-
ulogd 是一个专门设计的用户空间守护进程,负责处理从 Netfilter 框架接收的日志信息。相比简单的系统日志记录,ulogd 提供了更多高级功能,如日志过滤、格式化和多目标输出。它支持将日志写入文本文件、SQL 数据库、PCAP 文件或通过网络发送到远程服务器。ulogd 的插件架构允许添加自定义的输入和输出模块,适应不同的日志需求。在企业环境中,ulogd 常用于网络流量分析、合规性审计和安全事件监控,为网络管理员提供丰富的数据分析能力。
3. 原理介绍
iptables是建立在 Netfilter 之上的数据包过滤器,通过向 Netfilter 的挂载点上注册钩子函数来实现对数据包过滤的。iptables 采用了"表-链-规则"的三层架构设计,这种结构使复杂的网络过滤需求得以清晰组织。在这一体系中,表是功能分类的集合,链定义了处理时机,而规则则是具体的匹配条件与动作。
内核态的网络协议栈在五个位置埋了钩子入口,俗称五链,允许用户干预协议栈工作过程:
-
接收数据:先进入
ip_rcv函数进行处理,若是本机包再进入ip_local_deliver中处理。涉及prerouting和input两个链。 -
转发数据:先进入
ip_rcv函数进行处理,发现是转发包则进入ip_forward。涉及prerouting和forward两个链。 -
发送数据:先进入
__ip_local_out在进入ip_output。涉及output和postroting两个链。

而这些规则根据用途的不同,又可以分为raw、mangle、nat和filter四种表:
- Raw表用于判定数据包是否被状态跟踪处理,可以作用于PREROUTING链、OUTPUT链。
- Mangle主要用来修改IP数据包头,比如修改TTL值,同时也用于给数据包添加一些标记,从而便于后续其它模块对数据包进行处理,可以作用在所有链上。
- NAT表用于对数据包的网络地址转换(IP、端口),分别可以挂载到PREROUTING链、POSTOUTING链、OUTPUT链。
- Filter表用于过滤数据包,是iptables的默认表,因此如果配置规则时没有指定表,那么就默认使用Filter表,Filter表可以作用于INPUT链、OUTPUT链、PORWARD链;

4. 链接跟踪
链接跟踪(Connection Tracking)是现代网络防火墙的核心技术,它使防火墙能够理解和记忆网络通信的上下文,从而做出更智能的过滤决策。在 Linux 系统中,这一功能由 conntrack(Connection Tracking)模块提供,作为 Netfilter 框架的关键组成部分。
传统的无状态防火墙仅能基于单个数据包的特征(如源/目标地址、端口号等)做出过滤决策,无法理解这些数据包在整个通信会话中的位置和意义。链接跟踪技术突破了这一限制,使防火墙能够识别数据包所属的通信会话,理解协议的状态变化,从而实现"状态防火墙"功能。
状态防火墙的核心优势在于:只需明确允许合法的连接建立,后续的相关数据包可以被自动识别并放行,大大简化了规则配置,同时提高了安全性和性能。例如,可以只允许从内部发起的连接,同时自动允许对应的响应流量,而阻止所有未经请求的外部连接尝试。
链接跟踪通过在内核中维护一个"连接表"(connection tracking table)实现其功能。这个表记录了系统中所有活动连接的信息,每条记录通常包含:
- 连接的标识信息:源/目标 IP 地址、端口号、协议类型。
- 连接的状态信息:当前状态、超时值、数据包计数器。
- 协议特定信息:如 TCP 序列号、预期的应答序号等。
- NAT 信息:如果连接经过了地址转换,则包含原始和转换后的地址/端口。
连接表本质上是一个动态哈希表,使用连接的关键属性作为查找键,确保数据包匹配效率。每个连接条目都有关联的计时器,超时未活动的连接会被自动清除,释放资源。
链接跟踪系统将网络连接划分为几种关键状态,这些状态是防火墙规则设计的基础:
- NEW:表示一个新的连接请求,如 TCP SYN 包或首个 UDP 数据包。
- ESTABLISHED:表示已建立的连接,双向通信已经开始。对于 TCP,这通常意味着三次握手已完成;对于 UDP,则是首个请求已有响应。
- RELATED:表示与现有连接相关但不属于该连接的新连接,如 FTP 数据连接或 ICMP 错误消息。
- INVALID:表示无法识别或不符合预期的连接,可能是异常或攻击流量。
- UNTRACKED:表示被明确标记为不进行连接跟踪的流量,通常用于特殊性能需求场景。
这种状态分类使防火墙规则可以针对不同阶段的通信采取不同策略,例如严格控制 NEW 状态的连接请求,同时放行 ESTABLISHED 状态的数据交换。
链接跟踪不仅记录基本的连接信息,还能理解各种协议的特性和行为模式。Netfilter 的 conntrack 模块包含多个协议辅助模块(helper),专门处理特定协议的复杂行为:
- TCP 跟踪:理解 TCP 三次握手、四次挥手等状态转换,跟踪序列号,识别连接重置和异常包。
- UDP 跟踪:虽然 UDP 是无连接协议,但通过源/目标信息和时间窗口仍可组织成"虚拟连接"进行跟踪。
- ICMP 跟踪:区分不同类型的 ICMP 消息,如 echo 请求/响应对、错误消息等。
- 复杂协议辅助:如 FTP helper 能够解析控制连接中的 PORT/PASV 命令,自动允许相关的数据连接建立。
这种协议感知能力使防火墙可以处理复杂的网络应用场景,而不仅限于简单的数据包过滤。
网络地址转换(NAT)与连接跟踪密不可分。NAT 需要准确记住每个连接的原始地址和转换后的地址,以便正确转发返回的数据包。在 Netfilter 中,NAT 功能直接建立在连接跟踪基础上:
- 当数据包首次通过 NAT 规则时,系统创建连接跟踪记录,同时保存原始和转换后的地址/端口映射。
- 返回数据包到达时,系统根据连接记录自动进行反向转换。
- 连接关闭或超时后,相关的 NAT 映射也会一并删除。
这种整合设计使得 NAT 配置大大简化,管理员只需关注连接的发起方向,而不必为返回流量编写镜像规则。
链接跟踪虽然功能强大,但也带来了额外的系统开销。维护连接表需要内存资源,检查和更新连接状态需要 CPU 处理时间。在高流量环境中,连接表可能迅速增长,甚至导致资源耗尽。为应对这一挑战,Linux 提供了多种优化机制:
- 可调整的连接表大小:通过 sysctl 参数控制最大连接数。
- 超时优化:为不同类型的连接设置合理的超时值,快速释放无用条目。
- 哈希表优化:调整哈希表大小和分布,提高查找效率。
- 选择性跟踪:对特定类型的高流量连接(如 DNS 查询)可以禁用跟踪。
- 分布式处理:在多核系统上分散连接表处理负载。
这些机制使链接跟踪系统在保持功能强大的同时,也能适应从小型设备到高性能网络设备的各种部署场景。
5. iptables介绍
iptables 作为 Linux 防火墙的管理工具,提供了一套结构化的命令行语法,让管理员能够精确控制网络流量。这套体系围绕表(table)、链(chain)、规则(rule)、匹配条件(match)和目标动作(target)五个核心概念展开,形成了灵活而强大的网络过滤框架。
(1)表(table) ,是 iptables 的顶层组织单元,根据处理功能将规则分门别类。每个表专注于特定类型的数据包处理,管理员通过-t参数指定操作的目标表。
bash
iptables -t filter [commands] # 操作 filter 表
表的选择决定了可用的链和目标动作范围。例如,只有在 nat 表中才能使用 DNAT 或 SNAT 目标,而 filter 表则专注于 ACCEPT 或 DROP 等过滤动作。
iptable 的所有操作都对指定的 table 执行,默认为 filter。
(2)链(Chain),数据包处理的时间点,定义了规则被应用的时间点,对应数据包在网络栈中的处理阶段。管理员还可以创建自定义链,作为主链的分支,用于组织复杂规则:
bash
# 创建自定义链
iptables -N MY_CHAIN
# 在 INPUT 链中跳转到自定义链
iptables -A INPUT -p tcp --dport 80 -j MY_CHAIN
(3)规则(Rule),具体的控制条目,是 iptables 的基本操作单位,定义了"对什么样的数据包做什么处理"。每条规则包含匹配条件和目标动作两部分,按照添加顺序排列在链中,从上到下依次检查。添加、删除和修改规则的基本命令:
bash
# 在链尾添加规则
iptables -A INPUT [match] -j [target]
# 在链首插入规则
iptables -I INPUT [match] -j [target]
# 删除规则(按规则内容)
iptables -D INPUT [match] -j [target]
# 删除规则(按规则序号)
iptables -D INPUT 3
# 替换规则
iptables -R INPUT 3 [match] -j [target]
# 清空链中所有规则
iptables -F INPUT
规则的管理还包括设置默认策略和查看当前规则集:
bash
# 设置链的默认策略
iptables -P INPUT DROP
# 列出规则
iptables -L -v
(4)匹配条件(Match),选择目标数据包,定义了规则适用的数据包特征,可以基于各种网络属性进行筛选。iptables 提供了丰富的匹配选项,从基本的协议头字段到复杂的连接状态和数据内容。
基础匹配条件:
bash
# 协议匹配
-p tcp
# 地址匹配
-s 192.168.1.0/24 # 源地址
-d 10.0.0.1 # 目标地址
# 接口匹配
-i eth0 # 进入接口
-o eth1 # 离开接口
扩展匹配模块:
bash
# TCP/UDP 端口匹配
-p tcp --sport 1024:65535 # 源端口范围
-p tcp --dport 80 # 目标端口
# 连接状态匹配
-m state --state ESTABLISHED,RELATED
# 连接速率匹配
-m limit --limit 10/minute
# 多端口匹配
-p tcp -m multiport --dports 22,80,443
# 数据包内容匹配
-m string --string "malware" --algo bm
# 时间匹配
-m time --timestart 09:00 --timestop 17:00 --weekdays Mon,Tue,Wed,Thu,Fri
多个匹配条件组合使用时采用逻辑与(AND)关系,只有满足所有条件的数据包才会触发规则:
bash
# 匹配来自 192.168.1.0/24 网段,访问本机 80 端口的 TCP 数据包
iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport 80 -j ACCEPT
(5)目标动作(Target) ,定义处理方式,目标动作决定了匹配成功的数据包如何被处理。iptables 支持多种内置目标和自定义目标,通过-j(jump)或-g(goto)参数指定。
终止类目标,这类目标会立即决定数据包命运,不再继续检查后续规则:
bash
# 接受数据包,允许通过
-j ACCEPT
# 丢弃数据包,不发送任何通知
-j DROP
# 拒绝数据包,返回错误信息
-j REJECT --reject-with icmp-port-unreachable
非终止类目标,这类目标会执行一定操作,然后继续后续规则检查:
bash
# 记录数据包信息到系统日志
-j LOG --log-prefix "IPT: "
# 设置数据包标记,用于后续处理
-j MARK --set-mark 1
NAT 类目标,专门用于修改数据包的地址信息:
bash
# 源地址转换(在 nat 表的 POSTROUTING 链中使用)
-j SNAT --to-source 203.0.113.1
# 目标地址转换(在 nat 表的 PREROUTING 链中使用)
-j DNAT --to-destination 192.168.1.100:80
# 端口转发(在 nat 表中使用)
-j REDIRECT --to-ports 8080
跳转类目标,将控制权交给其他链:
bash
# 跳转到自定义链(完成后返回)
-j MY_CHAIN
# 转到自定义链(不返回)
-g MY_CHAIN
# 返回上一级链
-j RETURN
6. 应用实例
下面通过几个典型示例展示表、链、规则、匹配和目标的协同使用。
(1)基本防火墙设置:
bash
# 清空所有规则
iptables -F
iptables -X
# 设置默认策略:默认丢弃进入的连接,允许出站连接
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# 允许已建立的连接
iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# 允许本地环回接口
iptables -A INPUT -i lo -j ACCEPT
# 允许 SSH 连接
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 允许 Web 服务
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# 记录并丢弃所有其他入站流量
iptables -A INPUT -j LOG --log-prefix "IPT-DROP: "
(2)NAT 和端口转发:
bash
# 启用 IP 转发
echo 1 > /proc/sys/net/ipv4/ip_forward
# 设置源地址转换,实现共享上网
iptables -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 203.0.113.1
# 设置端口转发,将外部 80 端口转发到内部服务器
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:80
iptables -A FORWARD -p tcp -d 192.168.1.100 --dport 80 -j ACCEPT
(3)复杂流量控制:
bash
# 创建自定义链处理 HTTP 流量
iptables -N HTTP_FILTER
# 跳转到自定义链
iptables -A INPUT -p tcp --dport 80 -j HTTP_FILTER
# 在自定义链中设置详细规则
iptables -A HTTP_FILTER -m string --string "GET /admin" --algo bm -j DROP
iptables -A HTTP_FILTER -m limit --limit 30/minute --limit-burst 10 -j ACCEPT
iptables -A HTTP_FILTER -j DROP