本文共 12690 字,大约阅读时间需要 42 分钟。
netfilter/iptables(简称为iptables)组成Linux平台下的包过滤防火墙,与大多数的Linux软件一样,这个包过滤防火墙是免费的,它可以代替昂贵的商业防火墙解决方案,完成封包过滤、封包重定向和网络地址转换(NAT)等功能。
规则(rules)其实就是网络管理员预定义的条件,规则一般的定义为“如果数据包头符合这样的条件,就这样处理这个数据包”。规则存储在内核空间的信息包过滤表中,这些规则分别指定了源地址、目的地址、传输协议(如TCP、UDP、ICMP)和服务类型(如HTTP、FTP和SMTP)等。当数据包与规则匹配时,iptables就根据规则所定义的方法来处理这些数据包,如放行(accept)、拒绝(reject)和丢弃(drop)等。配置防火墙的主要工作就是添加、修改和删除这些规则。
这是第一个要说的地方,Iptables和netfilter的关系是一个很容易让人搞不清的问题。很多的知道iptables却不知道netfilter。其实iptables只是Linux防火墙的管理工具而已,位于/sbin/iptables。真正实现防火墙功能的是netfilter,它是Linux内核中实现包过滤的内部结构。
① 当一个数据包进入网卡时,它首先进入PREROUTING链,内核根据数据包目的IP判断是否需要转送出去。
② 如果数据包就是进入本机的,它就会沿着图向下移动,到达INPUT链。数据包到了INPUT链后,任何进程都会收到它。本机上运行的程序可以发送数据包,这些数据包会经过OUTPUT链,然后到达POSTROUTING链输出。 ③ 如果数据包是要转发出去的,且内核允许转发,数据包就会如图所示向右移动,经过FORWARD链,然后到达POSTROUTING链输出。表(tables)提供特定的功能,iptables内置了4个表,即filter表、nat表、mangle表和raw表,分别用于实现包过滤,网络地址转换、包重构(修改)和数据跟踪处理。
链(chains)是数据包传播的路径,每一条链其实就是众多规则中的一个检查清单,每一条链中可以有一条或数条规则。当一个数据包到达一个链时,iptables就会从链中第一条规则开始检查,看该数据包是否满足规则所定义的条件。如果满足,系统就会根据该条规则所定义的方法处理该数据包;否则iptables将继续检查下一条规则,如果该数据包不符合链中任一条规则,iptables就会根据该链预先定义的默认策略来处理数据包。
Iptables采用“表”和“链”的分层结构。在REHL4中是三张表五个链。现在REHL5成了四张表五个链了,不过多出来的那个表用的也不太多,所以基本还是和以前一样。下面罗列一下这四张表和五个链。注意一定要明白这些表和链的关系及作用。1.filter表——三个链:INPUT、FORWARD、OUTPUT
作用:过滤数据包 内核模块:iptables_filter. 2.Nat表——三个链:PREROUTING、POSTROUTING、OUTPUT 作用:用于网络地址转换(IP、端口) 内核模块:iptable_nat 3.Mangle表——五个链:PREROUTING、POSTROUTING、INPUT、OUTPUT、FORWARD 作用:修改数据包的服务类型、TTL、并且可以配置路由实现QOS内核模块:iptable_mangle(别看这个表这么麻烦,咱们设置策略时几乎都不会用到它) 4.Raw表——两个链:OUTPUT、PREROUTING 作用:决定数据包是否被状态跟踪机制处理 内核模块:iptable_raw (这个是REHL4没有的,不过不用怕,用的不多)1.INPUT——进来的数据包应用此规则链中的策略
2.OUTPUT——外出的数据包应用此规则链中的策略 3.FORWARD——转发数据包时应用此规则链中的策略 4.PREROUTING——对数据包作路由选择前应用此链中的规则 (记住!所有的数据包进来的时侯都先由这个链处理) 5.POSTROUTING——对数据包作路由选择后应用此链中的规则 (所有的数据包出来的时侯都先由这个链处理)Raw——mangle——nat——filter
规则链之间的优先顺序(分三种情况):第一种情况:入站数据流向
从外界到达防火墙的数据包,先被PREROUTING规则链处理(是否修改数据包地址等),之后会进行路由选择(判断该数据包应该发往何处),如果数据包的目标主机是防火墙本机(比如说Internet用户访问防火墙主机中的web服务器的数据包),那么内核将其传给INPUT链进行处理(决定是否允许通过等),通过以后再交给系统上层的应用程序(比如Apache服务器)进行响应。
第二冲情况:转发数据流向
来自外界的数据包到达防火墙后,首先被PREROUTING规则链处理,之后会进行路由选择,如果数据包的目标地址是其它外部地址(比如局域网用户通过网关访问QQ站点的数据包),则内核将其传递给FORWARD链进行处理(是否转发或拦截),然后再交给POSTROUTING规则链(是否修改数据包的地址等)进行处理。第三种情况:出站数据流向
防火墙本机向外部地址发送的数据包(比如在防火墙主机中测试公网DNS服务器时),首先被OUTPUT规则链处理,之后进行路由选择,然后传递给POSTROUTING规则链(是否修改数据包的地址等)进行处理。管理和设置iptables规则
相关学习资料
https: // www.frozentux.net/iptables-tutorial/cn/iptables-tutorial-cn-1.1.19.html http: // zh.wikipedia.org/wiki/Netfilter http: // www.netfilter.org/projects/iptables/ http: // linux.vbird.org/linux_server/0250simple_firewall.php http: // linux.vbird.org/linux_server/0250simple_firewall.php http: // www.vpser.net/security/linux-iptables.html
目录
1 . Iptables/ Netfilter原理分析 2 . Linux数据包路由原理 3 . Iptables规则编写原则
1. Iptables/Netfilter原理分析
在文章的最开头,我们首先要明确一个概念,Iptables/Netfilter到底是什么,它们之间的关系是怎样的。
我们可以这样简单地理解:
1 . Netfilter是Linux操作系统核心层内部的一个数据包处理模块,它具有如下功能: 1 ) 网络地址转换(Network Address Translate) 2 ) 数据包内容修改 3 ) 以及数据包过滤的防火墙功能 Netfilter平台中制定了五个数据包的挂载点(Hook Point,我们可以理解为回调函数点,数据包到达这些位置的时候会主动调用我们的函数,使我们有机会能在数据包路由的时候有机会改变它们 的方向、内容),这5个挂载点分别是 1 ) PRE_ROUTING 2 ) INPUT 3 ) OUTPUT 4 ) FORWARD 5 ) POST_ROUTING 2 . Iptables Netfilter所设置的规则是存放在内核内存中的,Iptables是一个应用层(Ring3)的应用程序,它通过Netfilter放出的接口来对存放在内核内存中的Xtables(Netfilter的配置表)进行修改 (这是一个典型的Ring3和Ring0配合的架构)
Xtables
我们知道Netfilter是负责实际的数据流改变工作的内核模块,而Xtables就是它的规则配置文件,Netfilter依照Xtables的规则来运行,Iptables在应用层负责修改这个规则文件。
Xtables由"表"、"链"、"规则rule"组成
1 . Filter(表) filter表是专门过滤包的,内建三个链,可以毫无问题地对包进行DROP、LOG、ACCEPT和REJECT等操作 1 ) INPUT(链) INPUT针对那些目的地是本地的包 1.1 ) 规则rule .. 2 ) FORWARD(链) FORWARD链过滤所有不是本地产生的并且目的地不是本地(即本机只是负责转发)的包 2.1 ) 规则rule .. 3 ) OUTPUT(链) OUTPUT是用来过滤所有本地生成的包 3.1 ) 规则rule .. 2 . Nat(表) Nat表的主要用处是网络地址转换,即Network Address Translation,缩写为NAT。做过NAT操作的数据包的地址就被改变了,当然这种改变是根据我们的规则进行的。属于一个流的包(因为包 的大小限制导致数据可能会被分成多个数据包)只会经过这个表一次。如果第一个包被允许做NAT或Masqueraded,那么余下的包都会自动地被做相同的操作。也就是说,余下的包不会再通过这个表 ,一个一个的被NAT,而是自动地完成 1 ) PREROUTING(链) PREROUTING 链的作用是在包刚刚到达防火墙时改变它的目的地址 1.1 ) 规则rule .. 2 ) INPUT(链) 2.1 ) 规则rule .. 3 ) OUTPUT(链) OUTPUT链改变本地产生的包的目的地址 3.1 ) 规则rule .. 4 ) POSTROUTING(链) POSTROUTING链在包就要离开防火墙之前改变其源地址。 4.1 ) 规则rule .. 3 . Mangle(表) 这个表主要用来mangle数据包。我们可以改变不同的包及包 头的内容,比如 TTL,TOS或MARK。 注意MARK并没有真正地改动数据包,它只是在内核空间为包设了一个标记。防火墙内的其他的规 则或程序(如tc)可以使用这种标记对包进行过滤或高级路由。注意,mangle表不能做任何NAT,它只是改变数据包的TTL,TOS或MARK,而不是其源目地址。NAT必须在nat表中操作的。 1 ) PREROUTING(链) PREROUTING在包进入防火墙之后、路由判断之前改变 包 1.1 ) 规则rule .. 2 ) INPUT(链) INPUT在包被路由到本地之后,但在用户空间的程序看到它之前改变包 2.1 ) 规则rule .. 3 ) FORWARD(链) FORWARD在最初的路由判断之后、最后一次更改包的目的之前mangle包 3.1 ) 规则rule .. 4 ) OUTPUT(链) OUTPUT在确定包的目的之前更改数据包 4.1 ) 规则rule .. 5 ) POSTROUTING(链) POSTROUTING是在所有路由判断之后 5.1 ) 规则rule ..
Netfilter的Hook点
Netfilter的架构就是在整个网络流程的若干位置放置了一些检测点(HOOK)(或者说是回调函数),而在每个检测点上登记(callback)了一些处理函数进行处理(如包过滤,NAT等,甚至可以是 用户自定义的功能)
1 . NF_IP_PRE_ROUTING: 刚刚通过数据链路层解包,进入网络层的数据包通过此点(刚刚进行完版本号,校验 和等检测),目的地址转换在此点进行 2 . NF_IP_LOCAL_IN 经路由查找后,送往本机的通过此检查点,INPUT包过滤在此点进行 3 . NF_IP_FORWARD 要转发的包通过此检测点,FORWARD包过滤在此点进行 4 . NF_IP_POST_ROUTING 所有马上便要通过网络设备出去的包通过此检测点,内置的源地址转换功能(包括地址伪装)在此点进行 5 . NF_IP_LOCAL_OUT 本机进程发出的包通过此检测点,OUTPUT包过滤在此点进行
可以看到:
Iptables/Netfilter的工作是针对网络的数据包进行修改的,所以,Iptables/Netfilter在某种程度上可以算是一种网络层的路由器/防火墙
我们可以看到,通过"5个代表不同阶段的Hook点"、"表、链、规则"这种"松耦合"、"规则型"的结构,我们作为管理员可以获得最大程度的控制灵活性、可以有非常巨大的想象空间
2. Linux数据包路由原理
我们已经知道了Netfilter和Iptables的架构和作用,并且学习了控制Netfilter行为的Xtables表的结构,那么这个Xtables表是怎么在内核协议栈的数据包路由中起作用的呢?
网口数据包由底层的网卡NIC接收,通过数据链路层的解包之后(去除数据链路帧头),就进入了"TCP/IP协议栈(本质就是一个处理网络数据包的内核驱动)和Netfilter混合"的"数据包处理流程"中了。
数据包的接收、处理、转发流程构成一个有限状态向量机,经过一些列的内核处理函数、以及Netfilter Hook点,最后被转发、或者本次上层的应用程序消化掉
从这张图中,我们可以总结出以下规律:
1 . 当一个数据包进入网卡时,数据包首先进入PREROUTING链,在PREROUTING链中我们有机会修改数据包的DestIP(目的IP),然后内核的 " 路由模块 " 根据 " 数据包目的IP " 以及 " 内核中的路由表 " 判断是否需要转送出去(注意,这个时候数据包的DestIP有可能已经被我们修改过了) 2 . 如果数据包就是进入本机的(即数据包的目的IP是本机的网口IP),数据包就会沿着图向下移动,到达INPUT链。数据包到达INPUT链后,任何进程都会收到它 3 . 本机上运行的程序也可以发送数据包,这些数据包经过OUTPUT链,然后到达POSTROTING链输出(注意,这个时候数据包的SrcIP有可能已经被我们修改过了) 4 . 如果数据包是要转发出去的(即目的IP地址不再当前子网中),且内核允许转发,数据包就会向右移动,经过FORWARD链,然后到达POSTROUTING链输出(选择对应子网的网口发送出去)
我们在写Iptables规则的时候,要时刻牢记这张路由次序图,根据所在Hook点的不同,灵活配置规则
3. Iptables规则编写原则
我们前面说过,使用Iptables是一个非常灵活的过程,我们在写规则的时候,一定要时刻牢记上面的这张"数据包路由图",明白在5个Hook点,3种"表"分别所处的位置,以及结合在这个5个Hook点可以实现的功能,来理解规则。理解规则的原理比强记规则本身效果要好得多
0x1: 提出需求
在正式编写Iptables规则之前,我们一定是有一个实现某个功能、目的的需求,我们必须先将它整理出来,为下一步抽象化作准备,这里我以我项目中的需求为例,大家在自己的实验中可以举一反三
1 . 网口at0( 10.0 . 0.1 )是一个伪AP的网口,目标客户端连接到伪AP网口at0之后会发起DHCPDISCOVER过程,监听在at0上的DHCPD会进行回应,为客户端分配10. 0.0 .100的IP地址,并设置客户 端的默认网关为10. 0.0 . 1 (即at0的IP地址)、默认DNS服务器为10. 0.0 . 1 (即at0的IP地址) 2 . 需要将网口at0( 10.0 . 0.1 )的入口流量牵引到真正连接外网的网卡接口eth0( 192.168 . 159.254 )上,做一个NAT服务 3 . 对网口at0( 10.0 . 0.1 )的DHCP流量(目的端口67的广播数据包)予以放行,因为我们需要在伪AP所在的服务器上假设DHCP服务器 4 . 对网口at0( 10.0 . 0.1 )的DNS流量(目的端口53)予以放行,因为我们需要在伪AP所在的服务器上假设DNS服务器
0x2: 逐步抽象化我们的需求
我们根据我们的需求进行抽象化,即用规则来抽象化描述我们的目的,在编写的过程中要注意不同的Hook点所能做的修改是不同的
// 开启Linux路由转发开关,由于本机对数据包进行转发 echo " 1 " > /proc/sys/net/ipv4/ ip_forward // 将客户端的HTTP流量进行NAT,改变数据包的SrcIP,注意,是在POSTROUTING(数据包即将发送出去之前进行修改) iptables -t nat -A POSTROUTING -p tcp -s 10.0 . 0.0 / 24 --dport 80 -j SNAT --to-source 192.168 . 159.254 // 将远程WEB服务器返回来的HTTP流量进行NAT,回引回客户端,注意,是在PREROUTING(数据包刚进入协议栈之后马上就修改) iptables -t nat -A PREROUTING -p tcp -d 192.168 . 159.254 -j DNAT --to 10.0 . 0.100
我们在DHCP服务器中指定客户端的默认DNS服务器是10.0.0.1(本机),即伪DNS,但我目前还没有在本机架设DNS,所以目前还需要将53号端口的DNS数据包NAT出去,牵引到谷歌的DNS: 8.8.8.8上去
iptables -t nat -A PREROUTING -p udp -s 10.0 . 0.0 / 24 --dport 53 -j DNAT --to 8.8 . 8.8 iptables -t nat -A POSTROUTING -p udp -s 10.0 . 0.0 / 24 --dport 53 -j SNAT --to-source 192.168 . 159.254 ptables -t nat -A PREROUTING -p udp -d 192.168 . 159.254 --sport 53 -j DNAT --to 10.0 . 0.100 i ptables -t nat -A POSTROUTING -p udp -s 8.8 . 8.8 --sport 53 -j SNAT --to-source 10.0 . 0.1 i
转载地址:http://zchvi.baihongyu.com/