A Brief History of Linux Networking
你是否曾疑惑过,为何Linux网络管理如此令人困惑?只需粗略回顾一下Linux网络工具的发展历史,你就会明白这一切是如何形成的。
考虑到Linux网络路由功能的发展方式,许多人试图理解它们时感到困惑并不奇怪。一些重要命令和进程的名称与其他属于完全不同工具世代的项目几乎相同。
在Linux中,遗留代码往往能存在非常长的时间。网络代码也不例外。
从20世纪90年代中期到2001年,Linux网络代码经历了架构的巨大扩展。直到2014年,这些代码基本保持不变,而即便是那时,里程碑式的变化也仅限于内核接口的全面革新。其核心部分几乎未曾改变。快进到2019年,我们仍然在Linux服务器中使用着超过20年历史的网络代码!想想自那以来,诸如网络安全、身份验证和区块链等领域的众多技术演进,这确实令人惊叹。
基于用户的Linux网络工具历史时间线:
图1: iptables历史时间线首个可配置的Linux防火墙
Linux内核1.2.1——发布于1996年——首次推出了一个命令行驱动的防火墙管理工具,名为ipfwadm,即“IP防火墙管理”(IP FireWall ADMinistration)的缩写。作为Linux首个数据包级别的筛选接口,系统管理员可通过它调整内核处理网络数据包的方式。几年后(1999年),ipfwadm被ipchains取代(而ipchains自身在次年又被iptables替代)。
快进到2014年。Nftables被引入,旨在替代并整合古老的 iptables 以及其他几个鲜为人知的网络工具,如 arptables 和 ebtables。Nftables(技术上称为nf_tables)将这些工具的功能整合到一个单一接口中,然后挂接到netfilter(存在于Linux内核2.4及更高版本中的基于内核的数据包过滤框架)。Nft的主要优势在于,它将上述工具及其扩展(例如CONNTRACK)整合进了一个单一的应用程序中。
具有讽刺意味的是,nftables推出时在Linux网络社区中反响平平——并且至今依然如此。
请允许我在此稍作停顿,反思一下目前涉及到的术语:
- chains(链)是网络数据包路由路径和处理流程,根据网络流量的目的地对其进行分段
- ipchains是 Linux 防火墙的一个版本;虽然它使用了链的概念,但它与“链”本身并非同一事物
- netfilter是现代(版本2.4+)Linux内核中内置的防火墙
- nf_tables代表“NetFilter表”,是 Linux 内核中 netfilter 子系统的名称
- nftables是一个命令行接口驱动的管理工具的名称,可用于添加、删除和编辑 nf_tables 中的防火墙规则
- nft是执行以启动 nftables 的命令行语句
到目前为止,您跟上了吗?读者或许开始明白为什么Linux网络术语如此令人困惑了吧。
链(Chains)与ipchains
Linux 网络中的链概念非常原始。更让新手雪上加霜的是,Linux包含了一个基于网络处理流程的概念,称为chains(也称为ip chains),但同时还有一个名为 ipchains 的 Linux 防火墙版本(发音完全相同,拼写也几乎一样)。Linux 网络新手在交谈中常常搞不清楚对方指的是哪一个,或者不清楚它们之间存在明显的区别,这并不少见。
网络链的概念在 Linux 内核1.3.66(1996年)中被引入,并标志着网络逻辑的一个里程碑式分支。它以 ipfwadm 版本2的形式被整合。旧版 ipfwadm 采用线性路由系统。所有网络数据包都通过同一段代码块。新的链概念根据任何给定网络数据包的目的地,将网络流量划分为三条不同的路径:
- IN:入站 IP 数据包,其目的地址是当前主机的 IP 地址或本地主机适配器地址
- FORWARD:非源自本地主机适配器,且目的 IP 地址并非当前网络适配器 IP 地址的出站 IP 数据包
大多数时候,当网络管理员讨论 chains 或 ipchains 时,他们谈论的并非这个旧的 Linux 防火墙。他们通常指的是“链”的另一个定义。
很容易与ipchains(Linux网络核心的一次重大革新,于1999年首次亮相)混淆的“链”概念本身,可以追溯到1996年的Linux内核1.3.66,当时只有三条链:IN、OUT和FORWARD。ipchains中的“链”概念涵盖了通过服务器路由网络数据包的三个主要过程中的每一个。这些数据包要么是进入本地目标的入站数据,要么是从本地服务发出到另一台设备的出站数据,要么是非源自本地服务但发往另一台设备的出站数据。
您可以将链视为服务器内部的高速公路。它们能够引导流量沿特定方向流动,但无法修改数据包。尽管与更近期的路由处理机制相比显得原始,但 ipchains 仍然是 Linux 网络 DNA 中根深蒂固的一部分。
随着 ipfwadm2 链概念的出现,IP数据包的处理变得更加有条理,并为 iproute 的引入铺平了道路。
RPDB 革命
1997 年发布的 Linux 内核 2.0 对 Linux 社区而言是一次划时代的事件。它彻底重写了网络后端,并推出了一款全新的网络管理工具——iproute,由此诞生了路由策略数据库(Routing Policy DataBase,简称 RPDB)。
RPDB 引入了“路由表的表”这一概念,可以理解为一个“主(master)路由表”。在 2.0 内核之前,Linux 采用的是传统的单一路由表模型。不久之后,随着 2.2 内核的发布,ipchains 问世;1999 年 9 月,iproute 的第二版(即 iproute2)正式发布。这套最初由 Alexey Kuznetsov 编写的工具扩展了 RPDB 的能力,新增了一层规则(rules)——也就是今天我们所熟知的过滤规则。这项颇具争议的改动使得 RPDB 能够复现部分 ipchains 的功能,进而引发了关于网络数据包修改(packet mangling)和网络地址转换(NAT)究竟应由何处、以何种方式处理的哲学分歧,也引发了关于哪些工具应当与 netfilter(Linux 的网络管理内核层)交互的争论。
时至今日,当你使用 ip route 和 ip rule 命令时,实际上就是在使用 iproute2 的功能。它取代了多个早期的网络工具,包括 route、ifconfig 和 netstat。
大约六个月后,另一个名为 iptables 的项目随内核 2.3 版本上线。它以更健壮的解决方案取代了 ipchains,并在很大程度上重新从 iproute 手中夺回了多项功能的控制权。随后不久,Linux 2.4 和 2.6 内核相继发布,其中许多 iproute2 的功能被弃用,从而巩固了 iptables 在数据包修改和 NAT 功能方面的主导地位。虽然 ipchains 的“链”(chains)概念得以保留,但 iptables 将其扩展为五个内置链,并允许用户在网络管理过程中添加自定义的新链。
netfilter
另一个容易引起混淆的概念是 netfilter。这或许是因为尽管人们经常提及它,却并不存在一个名为 netfilter 的命令。netfilter 是一个负责网络数据包管理和网络地址转换(NAT)的内核程序,可视为你服务器内部的“网络流量警察”。
netfilter 由两部分组成:
各种 xx-tables 工具(如 iptables、arptables 等)正是通过与 netfilter 的“翻译组件”进行交互来实现功能的。
iptables
Linux 网络数据包管理的下一个重要演进是 iptables。作为 ipchains 的继承者,iptables 至今仍被广泛使用。它本身无法控制流量的流向,但可以修改网络数据包。
在 iptables 中,链(chains)会调用表(tables),而表则提供更精细的包过滤能力。这种设计的好处在于,所有过滤规则都集中在一个地方。数据包的流向控制由链负责,链再根据需要调用相应的表。表包含一组包过滤指令,但不能改变数据包的传输方向。
需要特别注意的是,尽管 ipchains 命令在 Linux 中已被弃用,但“链”这一概念依然存在,并且是 iptables 的核心组成部分。
nftables
nftables 旨在取代 iptables、ip6tables1、arptables2 和 ebtables3。
nftables 自 Linux 内核 3.13 起可用,但并非强制使用——iptables 仍然有效。
nftables 的工作方式与 iptables 及其扩展完全不同:它完全绕过了 netfilter 的“翻译工具”,直接将数据传递给 netfilter 的内核接口。换句话说,即便移除 netfilter 的翻译层,nftables 仍能正常工作,而 iptables 及相关的 xx-tables 命令则会失效。
nftables 绕过了传统的 iptables 钩子和 netfilter API,直接接入内核中的 nf_tables 子系统。
图 2:NetFilter 顶层钩子:NFTables 与 UFW尽管 nftables 未来可能最终取代 iptables,但目前 iptables 仍是事实上的 Linux 防火墙管理工具。无论你选择哪种工具,鉴于 iptables 的广泛应用和深厚根基,短期内它消失的可能性微乎其微。
nftables 相较于 iptables 的优势包括:
- 链完全可配置:与 iptables 不同,nftables 没有固定的“基础链”;
- 表达式(expressions)取代并融合了“匹配(matches)”与“目标(targets)”的概念;
从 iptables 迁移到 nftables 不仅在实践上,更在理念上是一次范式转变。在 nftables 出现之前,Linux 的网络设计理念是将所有控制逻辑嵌入操作系统内核。而 nftables 则引入了一个虚拟机,在将最终数据包提交给内核前,独立完成所有数据包修改操作。
未来 Linux 若想彻底弃用 iptables 代码,只有两条路径:一是硬分叉(hard fork),即完全移除所有 iptables 代码;二是软分叉(soft fork),即新系统保留对旧系统的兼容性钩子。截至目前,我们仍处于后者阶段。若没有强有力的推动促使开发者从 iptables 转向 nftables,甚至很难称之为“软性推动”——更像只是提供了一个替代选项。事实上,iptables 及其变体凭借其惯性与用户熟悉度,依然是 Linux 网络工具的“黄金标准”,尽管其接口和命令结构常常显得笨拙。netfilter 的翻译代码已深深嵌入 Linux 内核,若要真正实现 nftables 的终极目标(即废弃 iptables),将需要付出巨大努力来解耦这些代码。
撰写本文时(nftables 发布已逾五年),当前的 Linux 内核版本为 4.19,尚无任何迹象表明 iptables 即将被淘汰。
iptables 代码文档完善,尽管效率不高,但确实有效。除非有人强力推动变革,否则继续使用已有 20 年历史的代码,远比进行一场浩大的重写工程更简单——后者极有可能在问题暴露并修复前,导致大量功能中断。随着世界对“云计算”等基于网络的应用依赖日益加深,实现一次优雅迁移所需的努力也前所未有地巨大。这也印证了我在引言中的观点:可靠性胜过创新。Linux 网络的发展路线图,正是这一设计哲学的明证。
UFW
仿佛 Linux 网络数据包管理的基础还不够复杂,Ubuntu 又通过引入 ufw(Uncomplicated FireWall,即“简易防火墙”)工具,增加了另一层复杂性和混淆。ufw 最初随 Ubuntu 8.04 LTS 于 2008 年 4 月发布,官方宣称其为“Ubuntu 的默认防火墙配置工具”(UFW, 2017)。尽管号称“默认”,但它默认却是禁用的。事实上,UFW 仅仅是在 iptables 之上增加了一个前端抽象层。
IPv4 与 IPv6
任何关于网络的讨论,若不简要提及 IPv6,都是不完整的。netfilter 能同时处理 IPv4 和 IPv6 的地址转换与路由。但在 iptables 体系中,两者却被分开处理:IPv6 由 ip6tables 管理,而 iptables 仅处理 IPv4。Ubuntu 的默认路由配置中内置了少量 IPv6 路由功能(仅提供一些非常宽泛的能力,确保 IPv6 数据包不会被 IPv4 路由流程阻断)。然而,鉴于 IPv6 与 IPv4 在地址复杂性上的显著差异,本指南将不深入探讨 IPv6 路由细节,尽管其基本概念是相同的。
注释
1 ip6tables 是 iptables 的 IPv6 对应版本。本文仅讨论仅支持 IPv4 的 iptables。2 ARP(地址解析协议)数据包过滤规则属于 Linux 内核防火墙模块的一部分,本文不予讨论。3 ebtables 是一种过滤工具,可用于透明地过滤通过 Linux 网桥的网络流量,超出本文范围。
Src
https://datahacker.blog/industry/technology-menu/networking/a-brief-history-of-linux-networking