今天,又把Netfilter回顾了一遍,发现经常容易遗忘,就写一篇博客总结一下。其实说起来总结,也都是参考网上大神的文献,文献已经在文章的末尾给出。
1. 概述
首先,说一下这两个是什么东西吧。netfilter是Linux内核中用于包过滤的框架,而iptables是在其之上设置的软件。它有五个钩子(Hook)去控制包的流动,总的来说就是我们可以在这5个钩子上设置过滤规则去控制包的流入/流出/转发等:
- INPUT:进入本机
- OUTPUT:本机输出
- FORWARD:转发
- PREROUTING:输入控制
- POSTROUTING:输出控制
其次,介绍一下这个框架到底能做些什么东西:
- 建立一个基于有状态和无状态的包过滤规则的因特网防火墙。
- 部署高度可用的有状态和无状态防火墙集群。
- 当公网ip不够用时,可以进行ip伪装,属于NAT模块。
- 使用NAT来实现透明代理。
- 辅助内核网络模块中的tc和iproute2去构造一个复杂的QoS和路由策略。
- 做进一步处理比如比如更改IP包头中的TOS/DSCP/ECN参数。
2. 框架介绍
这里所说的iptables是ipchains的后继工具,但具有更强的可扩展性。内核模块可以注册一个新的规则表(table),并要求数据包流经指定的规则表。这种数据包选择用于实现数据报过滤(filter表),网络地址转换(NAT表)及数据报处理(mangle表)。Linux 2.4内核及其以上版本提供的这三种数据报处理功能都基于netfilter的钩子函数和IP表,都是相互间独立的模块,完美地集成到了由netfilter提供的框架中,如下面两个图所示。Netfilters提供主要以下三个功能:
- 包过滤:filter表格不会对数据报进行修改,而只对数据报进行过滤。iptables优于ipchains的一个方面就是它更为小巧和快速。它是通过钩子函数NF_IP_LOCAL_IN、NF_IP_FORWARD及NF_IP_LOCAL_OUT接入netfilter框架的。
- NAT:NAT表格监听三个netfilter钩子函数:NF_IP_PRE_ROUTING、NF_IP_POST_ROUTING及NF_IP_LOCAL_OUT。NF_IP_PRE_ROUTING实现对需要转发数据报的源地址进行地址转换,而NF_IP_POST_ROUTING则对需要转发的数据报目的地址进行地址转换。对于本地数据报目的地址的转换,则由NF_IP_LOCAL_OUT来实现。
- 数据报处理:mangle表格在NF_IP_PRE_ROUTING和NF_IP_LOCAL_OUT钩子中进行注册。使用mangle表,可以实现对数据报的修改或给数据报附上一些外带数据。当前mangle表支持修改TOS位及设置skb的nfmard字段。
上面两个图介绍了Netfilter里面的结构,包括tables,chains,rules以及处理包的大概关系。下图更好的说明了这些chains之间的关系:
其中的5个标号就是5个钩子函数所在:
- 首先包从左边进来后,它们进行一些基本的包头检测(并不是截断,比如IP包头检验和,抛弃了一些不符合的包),然后它们被递交给Netfilter里面的第一个钩子:NF_IP_PRE_ROUTING [1] 。
- 其次进入[ROUTE]路由代码检测,这部分代码会检测包是递送给本机还是转发到其他端口。这部分代码会检测包能否路由,对于无效的包将会进行抛弃。
- 如果包是递送给本机的,将会先传给第二个钩子:NF_IP_LOCAL_IN\ [2],然后再由它地交给本机进程。
- 如果包是递送给其他端口的,将会传给第三个钩子:NF_IP_FORWARD [3] 。
- 最后包在出网卡之前将会经过第四个钩子:NF_IP_POST_ROUTING [4] 。经由这个钩子送往网络。
- 最后一个钩子:NF_IP_LOCAL_OUT [5]表明包是由本地创建的,它在送往网络之前也会经过第四个钩子NF_IP_POST_ROUTING [4] 。
下图是综合以上两个图,即tables和chains的关系:
3. iptables使用方法
通过向防火墙提供有关对来自某个源、到某个目的地或具有特定协议类型的信息包要做些什么的指令,规则控制信息包的过滤。通过使用Netfilter/iptables系统提供的特殊命令iptables,建立这些规则,并将其添加到内核空间的特定信息包过滤表内的链中。关于添加/除去/编辑规则的命令的一般语法如下:
iptables [-t table] command [match] [target]
不难看出,一条iptables规则包含如下4个基本元素:
- 表
- 命令
- 匹配
- 目标
3.1 表(table)
[-t table]选项允许使用标准表之外的任何表。表是包含仅处理特定类型信息包的规则和链的信息包过滤表。有三种可用的表选项:filter、nat和mangle。该选项不是必需的,如果未指定,则filter用作默认表。filter表用于一般的信息包过滤,包含INPUT、OUTPUT和FORWAR链。nat表用于要转发的信息包,它包含PREROUTING、OUTPUT和POSTROUTING链。如果信息包及其头内进行了任何更改,则使用mangle表。该表包含一些规则来标记用于高级路由的信息包以及PREROUTING和OUTPUT链。
3.2 命令(command)
command部分是iptables命令的最重要部分,它告诉iptables命令要做什么,例如,插入规则、将规则添加到链的末尾或删除规则。主要有如下表所示的命令。
命令 | 说明 | -A或--append | 该命令将一条规则附加到链的末尾 |
-D或--delete | 通过用-D指定要匹配的规则或者指定规则在链中的位置编号,该命令从链中删除该规则 |
-P或--policy | 该命令设置链的默认目标,即策略。所有与链中任何规则都不匹配的信息包都将被强制使用此链的策略 |
-N或--new-chain | 用命令中所指定的名称创建一个新链 |
-F或--flush | 如果指定链名,该命令删除链中的所有规则,如果未指定链名,该命令删除所有链中的所有规则。此参数用于快速清除 |
-L或--list | 列出指定链中的所有规则 |
-R或--replace | 替换指定链中一条匹配的规则 |
-X或--delete-chain | 删除指定用户的的定义链,若没有指定链,则删除所有的用户链 |
-C或--check | 检查数据包是否与指定链的规则相匹配 |
-Z或--zero | 将指定链中所有规则的byte计数器清零 |
3.3 匹配(match)
iptables命令的可选match部分指定信息包与规则匹配所应具有的特征(如源和目的地地址、协议等)。匹配分为两大类:通用匹配和特定于协议的匹配。这里,将研究可用于采用任何协议的信息包的通用匹配。下面是一些重要的且常用的通用匹配及其说明,如下表所示。
通用匹配 | 说明 | -p或--protocol | 该通用协议匹配用于检查某些特定协议。协议示例有TCP、UDP、ICMP、用逗号分隔的任何这三种协议的组合列表以及ALL(用于所有协议)。ALL是默认匹配。可以使用!符号表示不与该项匹配 |
-s 或 --source | 该源匹配用于根据信息包的源IP地址来与它们匹配。该匹配还允许对某一范围内的IP地址进行匹配,可以使用!符号,表示不与该项匹配。默认源匹配与所有IP地址匹配 |
-d 或 --destination | 该目的地匹配用于根据信息包的目的地IP地址来与它们匹配。该匹配还允许对某一范围内IP地址进行匹配,可以使用!符号表示不与该项匹配 |
--sport | 指定匹配规则的源端口或端口范围 |
--dport | 指定匹配规则的目的端口或端口范围 |
-i | 匹配单独的网络接口或某种类型的接口设置过滤规则 |
3.4 目标(target)
前面已经讲过,目标是由规则指定的操作,对与那些规则匹配的信息包执行这些操作。除了允许用户定义的目标之外,还有许多可用的目标选项。下面是常用的一些目标及其示例和说明,如下表所示。
目标项 | 说明 | ACCEPT | 当信息包与具有ACCEPT目标的规则完全匹配时,会被接受(允许它前往目的地) |
DROP | 当信息包与具有DROP目标的规则完全匹配时,会阻塞该信息包,并且不对它做进一步处理。该目标被指定为-j DROP |
REJECT | 该目标的工作方式与DROP目标相同,但它比DROP好。和DROP不同,REJECT不会在服务器和客户机上留下死套接字。另外,REJECT将错误消息发回给信息包的发送方。该目标被指定为-j REJECT |
RETURN | 在规则中设置的RETURN目标让与该规则匹配的信息包停止遍历包含该规则的链。如果链是如INPUT之类的主链,则使用该链的默认策略处理信息包。它被指定为-jump RETURN |
LOG | 表示将包的有关信息记录入日志 |
TOS | 表示改写数据包的TOS值 |
4. iptables简单应用
4.1 基本规则应用
下面将给出运用上述框架理论形成规则的一些简单示例,以供读者在实际的应用过程中进行模仿和使用:
接受来自指定IP地址的所有流入的数据包:
#iptables -A INPUT -s 203.159.0.10 -j ACCEPT
只接受来自指定端口(服务)的数据包:
#iptables -D INPUT --dport 80 -j DROP
允许转发所有到本地(198.168.10.13)smtp服务器的数据包:
#iptables -A FORWARD -p tcp -d 198.168.10.13 --dport smtp -i eth0 -j ACCEPT
允许转发所有到本地的udp数据包(诸如即时通信等软件产生的数据包):
#iptables -A FORWARD -p udp -d 198.168.80.0/24 -i eth0 -j ACCEPT
拒绝发往WWW服务器的客户端的请求数据包:
#iptables -A FORWARD -p tcp -d 198.168.80.11 --dport www -i eth0 -j REJECT
允许目的为指定端口的tcp数据包进入:
#iptables -A INPUT -p tcp -m multiport --destination-port 21,53,80,25,110 ACCEPT
允许来源为指定端口的tcp数据包进入:
#iptables -A INPUT -p tcp -m multiport --source-port 21,53,80,25,110 ACCEPT
丢掉SYN和ACK标志位置位的数据包:
#iptables -A INPUT-p tcp --tcp-flags ALL SYN,ACK DROP
4.2 碎片检测及流量控制
4.2.1 检查IP碎片
在TCP/IP网络中,链路层具有最大传输单元MTU这个特性,它限制了数据帧的最大长度,不同的网络类型都有一个上限值。以太网的MTU是1500。如果IP层有数据包要传,而且数据包的长度超过了MTU,那么IP层就要对数据包进行分片(fragmentation)操作,使每一片的长度都小于或等于MTU,这些被分段的片段就成为IP碎片。那么,如果在防火墙处不对IP碎片进行特别处理的话,那么有可能部分IP碎片会被防火墙拦截,从而影响到接受端对这些碎片的还原,并最终影响到信息的完整性和可用性问题,所以,下面的例子给出防火墙允许IP碎片通过的规则:
#iptables -A FORWARD -p tcp -f -s 172.168.96.0/24 -d 172.168.97.18 -j ACCEPT
需要特别留意上述规则中的-f选项,它指定了第二个以及以后的IP碎片将由防火墙来处理通过,否则的话,考虑下面的规则,防火墙有可能对其第二个及其以后的IP碎片进行拦截,从而影响正常的信息流通:
#iptables -A FORWARD -p tcp -s 172.168.96.0/24 -d 172.168.97.18 -j ACCEPT
4.2.2速率限制
iptables提供了非常健全的速率控制机制,主要用来限制由外向内的单位时间内通过的数据包个数,这样做的一个直接的好处就是尽可能地抑制前面多次提到的拒绝服务攻击或者是分布式拒绝服务攻击,因为这两种攻击的一个非常典型的表现就是单位时间内有很多数据包涌向目的地。所以,我们可以使用下面的规则来限制单位时间内允许通过防火墙,从而进入被保护网络的数据包个数:
#iptables -A INPUT -m limit --limit 200/second
#iptables -A INPUT -m limit --limit 10000/minute
上述两条规则分别限制1秒内和1分钟内通过的数据包个数不能超过200和10000个。当然,在实际应用中,也可以通过/second、/minute、/hour、/day这样的时间间隔来进行设定,并且,其中诸如200和10000这些具体数值的设定需要用户根据具体情况和经验来进行设定,没有规定的数值可循。
另外,在设定速率限制后,还可以设定超过该限制所触发的一些处理事件,比如说直接丢弃。下面的规则表示当速率超过200限制后,将直接对后续数据包进行丢弃:
#iptables -A INPUT -m limit --limit-burst 200
本部分内容也可以由tc命令直接做。
参考:
http://www.netfilter.org/
http://www.netfilter.org/documentation/HOWTO/netfilter-hacking-HOWTO-3.html
http://os.51cto.com/art/201107/273443_all.htm
http://os.51cto.com/art/201107/275664.htm
http://download.csdn.net/download/nokia6100/4802726