TCP实现之:iptables原理
一、前言
提到防火墙,大家都不陌生。防火墙技术是通过有机结合各类用于安全管理与筛选的软件和硬件设备,帮助计算机网络于其内、外网之间构建一道相对隔绝的保护屏障,以保护用户资料与信息安全性的一种技术。通俗的讲,防火墙就是计算机操作系统中的一种对网络报文进行监控、筛选和过滤以达到保护操作系统免受攻击的机制。
防火墙常用的功能包括以下几点:
- 包过滤功能。包过滤指的是防火墙对进入(入站)或者发出(出站)的网络数据包按照预先定义好的规则进行过滤,对于不符合规则的包进行丢弃等操作,这也是防火墙最常用的功能;
- NAT地址转发。准确的说,NAT并不属于防火墙的功能,单由于在Linux内核中NAT也属于防火墙的一个子模块,这里将其也作为一个防火墙功能;
- 包监控功能。对系统中的网络数据包进行统计以及日志记录等功能;
二、防火墙内核配置
Linux内核提供了对网络防火墙的支持,防火墙的功能被集成到了netfilter
模块,内核配置路径为:
Networking support > Networking options > Network packet filtering framework (Netfilter)
下图为防火墙模块的内核配置界面,其中Core Netfilter Configuration
是防火墙的主要配置目录,防火墙的各个子功能模块基本上都是在这个配置项下面的。Advanced netfilter configuration
表示一些最新加入但不是很常用的防火墙模块,该选项默认关闭,打开后Core Netfilter Configuration
下会出现一些新的(带有NEW
标志)模块项,如tcpmss
模块等。IP: Netfilter Configuration
为IP协议相关的防火墙模块,如NAT等。
IPTABLES
是linux中使用最为广泛的防火墙子模块之一,该模块是针对IP协议簇的防火墙,通过用户态提供的iptables
工具使用者可以很方便的创建防火墙的过滤规则,能够对IP报文(包括TCP、UDP等L4的报文)进行过滤,该子模块的内核配置如下图。
三、iptables基本原理及使用
说起iptables
,大家应该都不陌生,它是用来管理linux系统防火墙配置的命令行工具。举个例子,对于iptables -A INPUT -p icmp -j DROP
这条命令,它会将所有的接收到的ICMP
报文丢弃。想要充分理解这条规则,我们要理解五个概念:Rule(规则)、Table(表)、Chain(链)、Match(匹配器)和Target(目标)。
IP收发包流程
首先我们来简单分析一下IP报文的收包和发包流程,其流程图的简图如下图所示。IPTABLES
是针对IP协议的防火墙功能模块,因此其作用范围就在下图中的“IP协议”框框里。试想一下,我们想要对流经这个框框的网络报文进行过滤、检查甚至修改,我们该怎么做?
规则链
很简单!首先我们要选择在流程中的某个或者某些点设置“关卡”,即对报文进行检查的地方。当报文到达这个“关卡”的时候我们对其进行检查并判断其是否能够通过,关卡的设置如下图所示,共设置了五个关卡,分别是:
PREROUTING
:该关卡设置在对IP报文进行路由之前,即判断这个报文的目的地址是不是自己的IP之前;INPUT
:如果目标IP是本机,那么IP协议会将收到的报文传递给上层协议,如TCP、UDP等。INPUT
关卡设置在IP协议将报文传递给L4协议之前;FORWARD
:如果IP报文的目标地址不是本机,并且内核开启了IP转发功能,则IP协议会对该报文进行转发。FORWARD
关卡设置在对报文进行转发之前;OUTPUT
:这个关卡与INPUT
关卡类似,设置在L4协议将报文传递给IP协议的时候;POSTROUTING
:这个关卡设置在已经对报文完成了路由设置,将要将报文交给网卡驱动来发送出去的时候。
既然现在有了“关卡”,下一步我们要对途经关卡的报文进行验证。如何验证呢?我们可以在每个关卡上设置一些Rule(规则),各个规则按照放置的先后顺序排列,然后分别用每一个规则对报文进行过滤,过滤通过后再将报文传递给下一跳规则处理。从这里我们可以看出,关卡上的规则之间组成了一条“链”,这里将其称为“规则链”。在使用iptables
管理防火墙规则时,我们更习惯直接用“链”的概念来取代“关卡”的概念,因此上面的五个关卡其实也是iptables
中的五条规则链。
表
防火墙最大的作用可能是包过滤,即判断哪些数据包需要丢弃、哪些可以通过。但是防火墙的功能不仅仅是包过滤,它还可以用于其他的用途,如对报文的某些属性进行修改、对报文的地址进行篡改等。如果将所有的这些不同目的的规则都放到一条链中,势必会不利于维护和管理,因此就有了“表”的概念。
通俗的说,“表”是同一类规则的集合,这些规则有着相同或者相似的目的,每张表中可以有多条链(可以包含以上五条链,也可以只包含一部分)。目前,iptables
中常用的表有以下三张:
filter
:这张表执行的作用就是传统意义上的防火墙,即包过滤。这张表中的规则只会判断报文是否需要丢弃、是否允许通过等操作,不会对报文内容进行修改。根据这一目的,filter
表中所包含的规则链有:INPUT
、FORWARD
和OUTPUT
,即只关注了报文接收和发送的“关卡”;nat
:这张表是为了进行NAT
,即网络地址转发。nat
表中包含的规则链有:PREROUTING
、INPUT
、OUTPUT
和POSTROUTING
;mangle
:这张表主要作用为对报文的属性进行修改。由于在任何关卡中都有可能需要修改报文,因此这张表包含了上述所有的规则链。
规则
简单的来说,一条规则可以由两部分组成:Match(匹配器)和Target(目标)。其中,Match指的是这条规则要针对哪些报文,即如何命中要匹配的报文;Target,我觉得用Action(动作)来表述更准确,指的是匹配到报文后要如何处理。以上述的那条iptables
命令为例,-p icmp
是Match部分,代表这条规则应用于所有icmp协议的报文;-j DROP
代表是Target,即执行“DROP”丢弃动作。
Match
匹配器分为标准匹配器和扩展匹配器。其中,标准匹配器是内核预定义好的根据IP报文的一些常用属性进行匹配的匹配器,如:
-p
:匹配报文的协议,如tcp
、udp
、icmp
等;-s
:匹配报文的源IP地址;-d
:匹配报文的目标IP地址;-i
:匹配收到报文的网卡名称;-o
:匹配发送报文的网卡名称- …
标准匹配器还是很有限的,当我们想根据其他的一些条件对报文进行筛选时该怎么办呢?别担心,我们还有扩展匹配器。不同于标准匹配器,扩展匹配器一般都是单独成模块的,即每一种匹配器都是一个独立的内核模块,可以单独配置到内核中。下图为内核中可配置的一些匹配器。扩展匹配器的使用方法与标准匹配器略有不同,它需要通过-m
参数指定所用的匹配器名称。以tcpmss
扩展匹配器为例,该匹配器的作用是匹配指定的mss
的TCP报文,使用方法为:iptables -A INPUT -m tcpmss --mss 0:100 -j DROP
,这条命令会将mss
在[0,100]的TCP报文丢弃。
Target
与匹配器类似,Target也分为标准动作(这里我们还是叫它动作吧)和扩展动作。常用的标准动作包括:
DROP
:丢弃报文;ACCEPT
:接受报文,即允许该报文通过该关卡;LOG
:对该报文进行日志记录;REJECT
:拒绝该报文。与DROP
不同的是,该动作在丢弃报文时会反馈一条ICMP给发送方;- …
扩展动作的概念与扩展匹配器基本相同,其会对匹配到的报文执行扩展动作模块自定义的钩子函数。这里以TCPMSS
动作为例来介绍一下其使用。TCPMSS
动作的的作用是对TCP报文的mss
属性进行修改,命令为:iptables -t mangle -A POSTROUTING -p tcp -j TCPMSS --set-mss 1400
。这条命令的意思是将所有TCP报文的mss
修改为1400。由于这条规则对报文属性进行了修改,因此它需要被添加到mangle
表。
四、iptables的内核实现
正如前面所说的,iptables
是针对INET协议族的防火墙功能模块,该功能由linux内核中的IPTABLES
模块实现。说到IPTABLES
模块就不得不说一下XTABLES
模块了,XTABLES
是netfilter
中一种较为底层的内核模块,它不提供具体的防火墙功能实现,而是提供了防火墙其他功能模块所使用的数据结构,并构建了一种防火墙实现的架构。因此,可以理解为IPTABLES
是基于XTABLES
实现的。
XTABLES模块
正如前面所说,XTABLES
提供的是一种框架,因此需要了解XTABLES
就要先清楚它的框架结构。
IPTABLES模块
未完待续…