文档库 最新最全的文档下载
当前位置:文档库 › 深入理解netfilter

深入理解netfilter

深入理解Netfilter技术内幕

庞耀洋

pangyaoyang2011@https://www.wendangku.net/doc/5a14207603.html,

目录

第一章、简介 (3)

一、在内核中包括的防火墙子模块 (3)

二、数据的组织关系: (3)

三、IPv4模块防火墙的简介 (4)

第二章、iptables的使用 (6)

一、iptables命令: (6)

二、规则参数详解: (9)

三、系统定义的Target (11)

四、扩展的Match (11)

五、扩展Target: (13)

第三章、NAT的设置 (16)

IPv4地址的划分 (16)

SNAT:源IP地址转换 (16)

DNAT:目的IP地址转换 (17)

NAT的弊端 (17)

应用层网关(ALG) (17)

使用iptables来配置NAT (18)

第四章、Netfilter的基本框架 (21)

一、Netfilter的Hook机制 (21)

二、Netfilter规则(rule)的组织框架 (25)

1、大蓝图: (25)

2、table(表) (26)

3、rule在内核中的定义和存储 (28)

4、报文在表中的处理 (33)

第五章、Ipv4Netfilter中hook点的分布 (36)

第六章、报文过滤的实现 (38)

1、表的初始化和注册 (38)

2、HOOK函数的实现和注册 (39)

第七章、应用层和Netfilter的通信 (42)

1、通信机制 (42)

2、Netfliter提供的框架 (43)

(1)、数据结构定义: (43)

(2)、注册nf_sockopt_ops (44)

(3)、查找对应命令字的处理nf_sockopt_ops (44)

3、Iptable和Netfilter的通信 (45)

(1)、注册的nf_sockopt_ops (45)

(2)、用户空间配置的rule在内核中的转换 (46)

第八章、扩展Match length的实现 (52)

第九章、Target REJECT的实现 (54)

第十章、状态防火墙和Netfilter连接跟踪简介 (57)

第十一章、conntrack的标识和存储 (59)

一、conntrack的标识 (59)

二、conntrack的定义 (61)

三、conntrack的存储 (62)

第十二章、Netfilter中连接的建立过程 (64)

一、一般连接的建立过程 (64)

二、期望连接的建立过程 (67)

第十三章、Netfilter中conntrack功能扩展机制 (73)

第十四章、Netfilter中conntrack helper实现 (78)

第十五章、L3和L4层提供的conntrack处理方法 (82)

1、L3处理conntrack的函数 (82)

2、L4对conntrack的处理函数 (83)

第十六章、conntrack的HOOK点 (87)

第十七章、Nefilter中conntrack核心函数详解 (90)

1、Netfilter入口对conntrack的处理 (90)

2、Netfilter出口对conntack的处理 (93)

第一章、简介

Natfilter是集成到linux内核协议栈中的一套防火墙系统,用户可通过运行在用户空间的工具来把相关配置下发给Netfilter。

Netfilter提供了整个防火墙的框架,各个协议基于Netfilter框架来自己实现自己的防火墙功能。每个协议都有自己独立的表来存储自己的配置信息,他们之间完全独立的进行配置和运行。

一、在内核中包括的防火墙子模块

1、链路层的防火墙模块,对应协议栈是在软桥(bridge)中对报文进行处理。对应用户空间的配置工具是ebtables。

2、网络层中ipv4的防火墙模块,对应协议栈是在Ipv4协议栈中对报文进行处理,对应用户空间的配置工具是iptables

3、网络层中ipv6的防火墙模块,对应协议栈是在Ipv6协议栈中对报文进行处理,对应用户空间的配置工具是ip6tables

4、对ARP处理的防火墙模块,该处理是在协议栈的IPv4部分,但是自己有独立的表来存放自己的配置,对应用户空间的配置工具是arptables。

二、数据的组织关系:

一个可爱的机器人,呵呵。上图说明了各个数据的包含关系。

1、Netfilter中有包含一些表(table),不同的表用来存储不同功能的配置信息。

2、每个table里有多个chain,chain表示对报文的拦截处理点。

3、每个chain包含一些用户配置的匹配规则(match),一个或多个匹配规则后都必须有一个执行动作(target),如果报文符合匹配规则后,需要根据该执行动作(target)来处理报文。

三、IPv4模块防火墙的简介

本文主要讲解Netfilter整体实现和ipv4协议的防火墙系统。结合其配置工具iptables的使用来讲解防火墙内部的具体实现。在内核源码级上进行详细分析。

Ipv4防火墙有四大功能:

1、对报文的过滤(对应filter表)

2、对报文的修改(对应mangle表)

3、对会话的连接跟踪(connection track)

4、网络地址转换(NAT)

首先我们先来看看在linux协议栈中网络层IPv4对报文的出来流程。如图

Iptables默认实现了五个chain,定义如下:

1、PREROUTING:在报文路由前进行对报文的拦截

2、INPUT:对到本机的报文进行拦截

3、FORWARD:对需要本机进行三层转发的报文进行拦截

4、OUTPUT:对本机生成的报文进行拦截

5、POSTROUTIN:路由后对报文进行拦截

表的定义:

Iptalbes默认创建了四张表,还可以由用户自己来创建自己的表。

1、filter表:该表用来存储对报文过滤的配置信息,并且该表是iptables默认的表,如果命令没有指定表的话,就默认使用该表来存储配置信息。

该表里包含了三个chain,,分别为IPUT,OUTPUT,FORWARD

2、mangle表,该表用来存储那些对报文修改的配置信息,该表包含了上面所说的五个chain。

3、raw表,直译为原始的意思,该表主要是来在协议栈入口处对原始报文进行跟踪和处理的,该表包含了2个chain,分别为OUTPUT(本机生成的报文进入Ipv4协议栈的入口),PREROUTING(目的ip是到本机的报文进入Ipv4协议栈的入口)。

4、nat表,该表用来存储网络地址转换的相关配置信息。NAT功能分SNAT(源地址转换)和DNAT(目的地址转换),SNAT是在协议栈出口进行转换,DNAT是在协议栈入口进行转换。该表包含了三个chain,分别为DNAT的PREROUNGIN和OUTPUT,SNAT的POSTROUTIN。

Match:

Match代表了对报文的匹配规则,根据用户设置的匹配元素值来对报文进行匹配。具体匹配元素由用户根据自身需要来自由组合。在iptables中有标准的匹配元素,还有一些扩展的匹配元素。标准的匹配元素包括源/.目的IP地址,接收/发送设备传输层协议这五个元素,扩展的匹配元素分两类,一类是由不同的传输层协议自己定义,比如tcp/udp/icmp协议自己定义的一些匹配元素。还有一些根据特性来定义的匹配元素,比如IP地址的类型,跟连接跟踪结合的一些匹配元素等。

4、Target:

Target,执行动作,如果报文被匹配后,就根据该匹配规则后定义的target来对报文进行处理,标准的target有如下几种ACCEPT,DROP,QUEUE,RETURN。还有一些扩展的target,详见下章内容。

第二章、iptables的使用

首先我们要学会使用netfilter,熟悉其实现的一些功能,才能有目的的去阅读源码。这里我们介绍一下iptables的使用。

Iptables:ipv4防火墙及NAT功能的配置工具。

命令行格式:

iptables[?t table]{?A|?D}chain rule-specification

iptables[?t table]?I chain[rulenum]rule-specification

iptables[?t table]?R chain rulenum rule-specification

iptables[?t table]?D chain rulenum

iptables[?t table]?S[chain[rulenum]]

iptables[?t table]{?F|?L|?Z}[chain[rulenum]][options...]

iptables[?t table]?N chain

iptables[?t table]?X[chain]

iptables[?t table]?P chain target

iptables[?t table]?E old-chain-name new-chain-name

rule-specification=[matches...][target]

match=?m matchname[per-match-options]

target=?j targetname[per?target?options]

一、iptables命令:

1、显示netfilter中配置的规则

iptable-L

iptable-t nat-L

iptable-t nat-L-v

iptable-t nat-L-vv

-v显示详细信息,-vv显示的更详细一些。不指定表就显示默认表filter的信息

??line?numbers显示时带上行号

例:

2、追加规则

?A,??append chain rule-specification

把一条或多条规则添加到所选chain的尾部,如果源/目的地址是多个时,为每种地址组合单独添加一条规则。

例:iptables-A INPUT-d1.1.1.1,1.1.1.2-s2.2.2.2,2.2.2.3-j DROP

添加后规则如下:

3、删除规则

?D,??delete chain rule-specification

?D,??delete chain rulenum

例:iptables-D INPUT1

例:iptables-D INPUT-s2.2.2.3-d1.1.1.1-j DROP

4、插入规则

?I,??insert chain[rulenum]rule-specification

插入规则,如果没有指定行号,就默认加入到chain头部

例:iptables-I INPUT-s9.9.9.9-j ACCEPT

例:iptables-I INPUT3-s5.5.5.5-j ACCEPT

5、替换规则

?R,??replace chain rulenum rule-specification

例:iptables-R INPUT2-s3.3.3.3-d5.5.5.5-j REJECT

6、清空所有规则

?F,??flush[chain]

例:iptables-t mangle-F INPUT//删除mangle表中INPUT chain中所有规则例:iptables-t mangle-F//删除mangle表中所有规则

7、清空规则的统计计数

?Z,??zero[chain[rulenum]]

例:iptables-Z INPUT1

8、修改chain的默认target

?P,??policy chain target

该命令只能修改系统自带的chain的默认target,不能修改用户自定义的chain。

如果报文被该chain截获,如果该chain中没有规则匹配该报文,就是要默认target来处理该报文。

例:iptables-P INPUT DROP

9、用户自定义chain

?N,??new?chain chain

例:iptables-N pang

10、删除用户自定义chain

?X,??delete?chain[chain]

11、重命名用户自定义chain

?E,??rename?chain old?chain new?chain

二、规则参数详解:

1、[!]?p,??protocol protocol

传输层协议类型,可以正向/反向匹配

2、[!]?s,??source address[/mask][,...]

源IP地址

3、[!]?d,??destination address[/mask][,...]

目的IP地址

4、[!]?i,??in?interface name

报文接收设备

5、[!]?o,??out?interface name

报文发送设备

6、[!]?f,??fragment

只配置分片报文的第二及后续片报文

例:iptables-A INPUT-s1.1.1.1-d2.2.2.2-p udp!-i eth0-f-j DROP

7、?c,??set?counters packets bytes

设置初始的报文统计值

例:iptables-A INPUT-p udp-c12900-j ACCEPT

8、?j,??jump target

给规则设置target,target可以是系统定义的和一些扩展的,还可以指定用户自定义的chain。指定用户自定义的chain就会跳到chain里去处理报文,如果chain里没有定义匹配报文的规则,会从用户自定义的chain里返回原来的chain中继续执行。

9、?g,??goto chain

跳到用户自定义的chain中执行,如果没匹配规则就退出执行,不再返回原来的chain中继续执行。

例:

iptables-N pang

ptables-A INPUT-p icmp-g pang

iptables-A INPUT-p icmp-j DROP

配置如上,这时从外部ping本机是可以ping的。

接着执行如下命令

iptables-R INPUT1-p icmp-j pang

这时是无法ping本机的。

三、系统定义的Target

Netfilter系统默认定义了四个target:ACCEPT,DROP,QUEUE or RETURN

ACCEPT:表示允许报文通过

DROP:表示不允许报文通过,并且丢弃该报文

QUEUE:把报文放入netlink定义的队列里,通过netlink来把报文送给用户空间相应程序处理,QUEUE只能放入0号队列中,还有一种扩展的NFQUEUE,可以指定把报文放入那个队列中。

RETURN:停止在当前chain中的执行并返回上一个chain中继续执行,如果该执行不存在上一个chain,就使用当前chain的默认target来处理报文

四、扩展的Match

使用扩展Match有些需要使用参数-m,该参数会让iptables动态的加载相关动态库来进行相应的规则设置,并且如果该match在内核是以模块形式编译的,会让内核加载相应的模块。

1、comment

允许给每条规则加一个最大长度256的字符串,用字符串来命名该规则。该match其实只是根据netfilter提供的框架来实现的一个给规则命名的功能,并不对报文进行匹配。具体实现详见后续章节。

??comment comment

例:iptables-A INPUT-p icmp-m comment--comment"my first rule"-j DROP

2、icmp

对icmp协议进一步进行匹配

[!]??icmp?type{type[/code]|typename}

例:iptables-A INPUT-p icmp--icmp-type echo-request-j DROP

3、udp

[!]??source?port,??sport port[:port]

[!]??destination?port,??dport port[:port]

对udp报文的进一步匹配,当规则里使用-p udp时可以使用上面的参数来制定端口号。

例:iptables-A INPUT-p udp--sport60:80--dport10-j DROP

4、tcp

tcp协议比较复杂,匹配的元素较多,这里不详细讲解了。

主要使用源/目的端口号

[!]??source?port,??sport port[:port]

[!]??destination?port,??dport port[:port]

5、ttl

根据ip头部的ttl字段进行匹配

??ttl?eq ttl//相等的ttl

??ttl?gt ttl大于的ttl

??ttl?lt ttl小于的ttl

例:iptables-A INPUT-p icmp-m ttl--ttl-eq50-j DROP

这时从外部windows主机使用ping host-i50就无法ping通本机了。

6、iprange

Ip地址范围

[!]??src?range from[?to]

[!]??dst?range from[?to]

例、iptables-A INPUT-p udp-m iprange--src-rang192.168.3.100-j DROP

不设置to就指匹配一个ip地址。

例、iptables-A INPUT-p udp-m iprange--src-rang192.168.3.100-192.168.3.200-j DROP

这时源ip在192.168.3.100到192.168.3.200之间的报文就会被丢弃了。

7、Length

根据报文长度来匹配报文,该长度是按IP层的净荷来算的(不算IP头的长度)。

[!]??length length[:length]

例、iptables-A INPUT-p udp-m length--length50-60-j DROP

这时打入长度为50到60的报文就被丢弃了。

8、mac

[!]??mac?source address

源MAC匹配,MAC地址格式必须是XX:XX:XX:XX:XX:XX,可以在INPUT FORWARD,PRERONGING这三个chain中使用

例、iptables-A INPUT-m mac--mac-source00:01:00:02:00:03-j LOG--log-level error

从外部打入源MAC是00:01:00:02:00:03的报文,就会有log在串口打印出来了。

9、Multiport

端口范围匹配

[!]??source?ports,??sports port[,port|,port:port]...//源端口

[!]??destination?ports,??dports port[,port|,port:port]...//目的端口

[!]??ports port[,port|,port:port]...//源端口和目的端口都会匹配

该匹配规则只能用在udp和tcp报文,必须指定-p udp或-p tcp

使用逗号最多可指定15个端口范围。

例、iptables-A INPUT-p udp-m multiport--sport50:70-j DROP

打入端口是60的udp的报文,该报文就会被丢弃。

这里介绍了一些常用的扩展Match,还有一些更高级的match这里就先不介绍了。

五、扩展Target:

1、REJECT

拒绝连接,和DROP不同之处是REJECT把报文丢弃后会给发送方返回一个连接失败的回应。具体的回应报文类型可以指定。

??reject?with type

type值可以是:

icmp?port?unreachable,(默认值)

icmp?net?unreachable,

icmp?host?unreachable,

icmp?proto?unreachable,

icmp?net?prohibited,

icmp?host?prohibited or

icmp?admin?prohibited

例、iptables-A INPUT-p icmp-j REJECT--reject-with icmp-host-unreachable

从外部ping主机时现象如下:

2、NOTRACK

对特定的报文关闭连接跟踪,该TARGET只能用在raw表里

例、iptables-t raw-R PREROUTING1-p icmp-j NOTRACK

关闭所有对icmp报文的连接跟踪,这时执行

cat/proc/net/nf_conntrack|grep icmp将看不到任何icmp报文的连接跟踪信息。删除该规则后,ping本机,就会看有icmp报文的连接跟踪了。

3、LOG

用于记录报文信息,可以通过dmesg来查看

??log?level level//log级别

??log?prefix prefix//log前加一个前缀

??log?tcp?sequence//log中的报文信息中包含tcp sequence,默认不包含

??log?tcp?options//同上

??log?ip?options//同上

??log?uid//log信息中打印产生该报文进程的uid号

例、iptables-A INPUT-p icmp-j LOG--log-level error--log-prefix"abc"

4、NFQUEUE

通过netlink来把报文直接送到用户空间进行处理,该TARGET和QUEUE的区别就是可以指定netflter中实现的netlink队列号。用户空间的处理程序需要用户自己实现。

??queue?num value//队列号

??queue?balance value:value//指定队列号的范围,netfilter会均匀的分给多个队列

扩展的TARGET有一些是要结合高级路由和流量控制来使用,这里就不介绍了,后续用到再介绍

NAT的设置详见下一节

第三章、NAT的设置

NAT,网络地址转换,该技术是为了应对IPv4地址耗尽的问题而产生的。他的产生几乎使IPv4起死回生。在IPv4已经被认为行将结束历史使命之后近20年时间里,人们几乎忘了IPv4的地址空间即将耗尽这样一个事实。

IPv4地址的划分

在弄明白NAT的具体功能前,我们先来看一看IPv4地址的划分。

IPv4协议为了路由和管理方便,43亿的地址空间被按照不同前缀长度划分为A,B,C,D类地址网络和保留地址。其中,A类网络地址127段,每段包括主机地址约1678万个。B类网络地址16384段,每段包括65536个主机地址。

RFC1918规定了三个保留地址段落:10.0.0.0-10.255.255.255;172.16.0.0-172.31.255.255;192.168.0.0-192.168.255.255。这三个范围分别处于A,B,C类的地址段,不向特定的用户分配,被IANA作为私有地址保留。这些地址可以在任何组织或企业内部使用,和其他Internet地址的区别就是,仅能在内部使用,不能作为全球路由地址。这就是说,出了组织的管理范围这些地址就不再有意义,无论是作为源地址,还是目的地址。对于一个封闭的组织,如果其网络不连接到Internet,就可以使用这些地址而不用向IANA提出申请,而在内部的路由管理和报文传递方式与其他网络没有差异。

SNAT:源IP地址转换

平时说起NAT,一般指的是SNAT。

对于有Internet访问需求而内部又使用私有地址的网络,就要在组织的出口位置部署NAT 网关,在报文离开私网进入Internet时,将源IP替换为公网地址,通常是出口设备的接口地址。一个对外的访问请求在到达目标以后,表现为由本组织出口设备发起,因此被请求的服务端可将响应由Internet发回出口网关。出口网关再将目的地址替换为私网的源主机地址,发回内部。这样一次由私网主机向公网服务端的请求和响应就在通信两端均无感知的情况下完成了。依据这种模型,数量庞大的内网主机就不再需要公有IP地址了。

DNAT:目的IP地址转换

DNAT主要有两大用处

1、发布内部服务器,让外面的internet用户能访问到内网的服务器。

2、网络重定向

NAT的弊端

NAT的存在破坏了IP端到端模型。NAT通过修改IP首部的信息变换通信的地址。但是在这个转换过程中只能基于一个会话单位。当一个应用需要保持多个双向连接时,麻烦就很大。NAT不能理解多个会话之间的关联性,无法保证转换符合应用需要的规则。当NAT网关拥有多个公有IP地址时,一组关联会话可能被分配到不同的公网地址,这通常是服务器端无法接受的。更为严重的是,当公网侧的主机要主动向私网侧发送数据时,NAT网关没有转换这个连接需要的关联表,这个数据包无法到达私网侧的主机。这些反方向发送数据的连接总有应用协议的约定或在初始建立的会话中进行过协商。但是因为NAT工作在网络层和传输层,无法理解应用层协议的行为,对这些信息是无知的。NAT希望自己对通信双方是透明的,但是在这些情况下这是一种奢望。

图形来自(网路之路-NAT篇)

因为NAT的工作依赖于传输层协议的的端口号,这样NAT网关就无法处理ip分片报文,所有通过NAT网关的ip分片报文必须在网关重组后NAT转换后再分片发出去,严重影响了转发速度。

应用层网关(ALG)

应用层网关(ALG)是解决NAT对应用层协议无感知的一个最常用方法,成为NAT 设备的一个必需功能。因为NAT不感知应用协议,所以有必要额外为每个应用协议定制协议分析功能,这样NAT网关就能理解并支持特定的协议。ALG与NAT形成互动关系,在一个NAT网关检测到新的连接请求时,需要判断是否为已知的应

用类型,这通常是基于连接的传输层端口信息来识别的。在识别为已知应用时,再调用相应功能对报文的深层内容进行检查,当发现任何形式表达的IP地址

和端口时,将会把这些信息同步转换,并且为这个新连接创建一个附加的转换表项。这样,当报文到达公网侧的目的主机时,应用层协议中携带的信息就是NAT 网关提供的地址和端口。一旦公网侧主机开始发送数据或建立连接到此端口,NAT 网关就可以根据关联表信息进行转换,再把数据转发到私网侧的主机。很多应用层协议实现不限于一个初始连接(通常为信令或控制通道)加一个数据连接,可能是一个初始连接对应很多后续的新连接。比较特别的协议,在一次协商中会产生一组相关连接,比如RTP/RTCP协议规定,一个RTP通道建立后占用连续的两个端口,一个服务于数据,另一个服务于控制消息。此时,就需要ALG分配连续的端口为应用服务。ALG能成功解决大部分协议的NAT穿越需求。但是,出于安全性需要,有些应用类型报文从源端发出就已经加密,这种报文在网络中间无法进行分析,所以ALG无能为力。

Netfilter提供了ALG的基础框架,后续会以ftp协议为例来讲解ALG的具体实现。

使用iptables来配置NAT

Iptables中nat功能时有target来实现的。分为SNAT和DNAT。

还有一些NAT的功能MASQUERADE,NETMAP,REDIRECT

1、SNAT

源IP地址转换,只能用在nat表中的POSTROUTING chain中

??to?source ipaddr[?ipaddr][:port[?port]]//指定转换后的源IP地址,如果是udp/tcp的报文,可以指定转换后的端口号

??random//端口号映射时采用随机的映射

??persistent//端口号映射时采用连续的端口号映射

如图所示:

在NAT网关上配置

iptables-t nat-A POSTROUTING-p udp-j SNAT--to-source9.9.9.9

在client上发源ip和源端口号为192.168.3.227:60的udp报文,在server上抓包结果如下:

源IP地址已经改变为9.9.9.9,但源端口号没有改变

iptables-t nat-A POSTROUTING-p udp-j SNAT--to-source9.9.9.9:100

在client上发源ip和源端口号为192.168.3.227:60的udp报文,在server上抓包结果如下:

源端口号已经改变为100了。

iptables-t nat-A POSTROUTING-p udp-j SNAT--to-source9.9.9.9:100-200

在client上分别发一个源ip为192.168.3.227的,源端口号分别是50和70的udp报文,在server上抓包结果如下:

发现端口号映射是连续映射的

iptables-t nat-A POSTROUTING-p udp-j SNAT--to-source9.9.9.9--random

在client上分别发一个源ip和源端口号为192.168.3.227:50的udp报文,在server上抓包结果如下:

发现源端口号发生了改变,并且是随机分配了一个

2、MASQUERADE

地址伪装,本质跟SNAT一样,都是替换源IP地址。SNAT是通过命令行给定IP地址,MASQUERADE是用NAT网关的发送报文的三层的IP地址来替换报文的源IP地址,主要用在NAT网关通过DHCP动态获取IP地址的应用场景

iptables-t nat-A POSTROUTING-j MASQUERADE

通过client ping server,在server端抓包看到如下结果:

发现报文的源IP已经被替换成了NAT网关接口的IP地址。

相关文档
相关文档 最新文档