iptables之一


Netfilter/Iptables的官方网站: http://www.netfilter.org

术语概念

Iptables 工作在网络层和传输层,还可以工作在应用层。

连接(Connection) - 指相互之间有关联的一系列数据包。所有的这些报文链接在一起形成一种稳定的连接。换句话讲,一个连接就是一系列报文交换。例如 TCP,在三次握手之后就构成了一个连接,这样在关闭之前他们都可以被看作一个连接。
DNAT - destination network address translation 目的网络地址转换。DNAT 是一种改变数据包目的 IP 地址技术,这种技术经常应用于将内部网络的服务器通过公有的可路由 IP 地址发布到 internet 上,通过对同一 IP 地址分配不同的端口,来决定数据的流向。
IPSEC - 安全网络协议是一种加密IPv4 报文,并且通过internet把他们安全分发的协议。
内核地址空间 Kernel space - 内核空间 ,与用户空间相对,指那些发生在内核内部。
报文(Packet) – 包含包头和数据部分,并且在网络上传输的单一结构。例如 IP 报文或者 TCP 报文。但是在 RFC 里面,报文的定义不像这么宽泛,相反 IP 报文叫做数据包,TCP 报文叫做数据段。
服务质量(QOS)- QOS定义了如何处理报文的一种方式以及收发报文时候应该提供的服务质量。
数据段(Segment) - 一个 TCP 数据段等同于一个报文,是一种更正式的称呼。
(Stream) - 流就是一条连接上面收发的相关数据包。根本上来说,我用流来描述有双向收发的任何类型的连接。对于 TCP,流意味着发送一个 SYN 收到 SYN/ACK 的连接,它也可能是发送 SYN 但是接收到 ICMP error 的连接。换句话讲,这个词我用的很宽泛。
SNAT - source network address translation 源网络地址转换。这是一种改变数据包源 IP 地址的技术,经常用来使多台计算机机分享一个 internet 地址。这只在IPv4 中使用,因为IPv4 的地址已快用完了,IPv6 将解决这个问题。IPv6 使得地球上每一粒沙子大小的空间都能够分配到一个IP地址,因此IPv6 不存在地址空间短缺的问题。
State - 状态 指明数据包【报文】处于什么状态。状态在RFC 793 - Transmission Control Protocol中定义,或由用户在Netfilter/iptables中自定义。需要注意的是Netfilter设定了一些关于连接和数据包的状态,但没有完全使用使用RFC 793 的定义。
User space - 用户空间,指在内核外部或发生在内核外部的任何东西。例如,调 iptables -h 发生在内核外部,但iptables -A FORWARD -p tcp -j ACCEPT(部分地)发生在内核内部,因为一条新的规则加入了规则集。
VPN(virtual private network) - 虚拟私有网络是一种在公共网络上创建虚拟私有网络的技术,例如 IPSec 是一种创建 VPN 的技术,而 OpenVPN 是另外一种技术。
target - 这个词在后文中有大量的应用,它表示对匹配的数据包所做的操作,如ACCEPT、DROP、RED IRECT等等。

OSI 层次模型

  1. 应用层
  2. 表示层
  3. 会话层
  4. 传输层
  5. 网络层
  6. 数据链路层
  7. 物理层
    我们所发送的报文,从 OSI 模型的最上层传输到最底层,每一层都加上自己的头到报文上面,这个就是我们所谓的封装过程。当这个报文发送到了目的地址后,它的解封装过程和上面恰恰相反,每一次都剥离自己的头部。每一个报文头部都包含了它最终需要到达的应用程序或者其他它应该到得地方。

TCP/IP 协议模型

  1. 应用层
  2. 传输层
  3. 网络层
  4. 链路层

编译内核

在一般情况下,我们采用的Linux的distribution比如Redhat都会帮我们安装好Iptables,而且netfilter 的核心层也被以模块(Modules)的方式编译进了核心,所以,在绝大多数的情况下,我们是不需要对核心进行重新编译的。
为了弄清楚,我们还是来描述一下如何编译核心以使Linux在核心层能够支持数据包过滤。

下载Linux Kernel的源代码
cd linux-2.4
make menuconfig
在图中高亮显示的地方回车进入Networking options的核心配置页面,将高亮显示的部分编译进核心,在该配置页面内,还有一处需要注意,就是Netfilter Configuration的配置页面,在该处回车即可进入配置界面:
从图中可以看到,左面尖括号内的“M”代表该选项被编译成核心模块,仅在系统需要时才被装载入核心空间,由于模块化的核心是不占用核心本身的空间的,因此,对于这些选项,除非肯定不会用到的以外,其他的都可以选择编译成核心模块,但有些是必须的,如
Connection tracking——用于支持状态链接跟踪功能
FTP protocol support——用于支持对Ftp协议的连接跟踪机制
IP tables support——用于支持包过滤
Connection state match support——用户支持连接状态匹配
MASQUERADE target support——支持地址伪装功能
Multiport match support——支持多端口匹配,这对于设置过滤规则非常有好处
REDIRECT target support——如果你想使用iptables将特定的流量交给特定的代理程序如squid来处理,这个选项需要被编译进核心模块
这些选项选择完成后,按照核心编译的方法对配置好的核心进行编译即可:
#make dep
#make bzImage
#make install
#make modules
#make modules_install 

iptables 编译安装

yum install gcc-c++
wget ftp://ftp.netfilter.org/pub/iptables/iptables-1.4.14.tar.bz2
tar xvf iptables-1.4.14.tar.bz2
cd iptables-1.4.14
./configure --prefix=/usr/local/iptables

iptables 工作原理

iptables被分为两部分:
核心空间 - iptables从底层实现了数据包过滤的各种功能,比如 NAT、状态检测以及高级的数据包的匹配策略等;
用户空间 - iptables为用户提供了控制核心空间工作状态的命令集。无论如何,一个数据包都会经过下处理。

首先,当一个包进来的时候,也就是从以太网卡进入防火墙,内核首先根据路由表决定包的目标。如果目标主机就是本机,则如下图直接进入INPUT链,再由本地正在等待该包的进程接收,否则,如果从以太网卡进来的包目标不是本机,再看是否内核允许转发包(可用 echo 1 > /proc/sys/net/ipv4/ip_forward ) 打开转发功能如果不允许转发,则包被DROP掉,如果允许转发,则送出本机,这当中决不经过INPUT或者OUTPUT链,因为路由后的目标不是本机,只被转发规则应用,最后,该linux防火墙主机本身能够产生包,这种包只经过OUTPUT链被送出防火墙。

iptables 中共有三类表,分别是mangle、nat和filter。

  • mangle表从目前来看,他的作用对于满足常规的防火墙应用作用不大,我们在这里不进行具体的描述。
  • nat表的作用在于对数据包的源或目的IP地址进行转换,这种应用也许只会在IPv4 的网络中适用,nat表又可主要分为三条链,如下:
    • DNAT:DNAT操作主要用在这样一种情况下,你有一个合法的IP地址,要把对防火墙的访问重定向到其他的机子上,比如 DMZ。也就是说,我们改变的是目的地址,以使包能重路由到某台主机上。
    • SNAT: SNAT改变包的源地址,这在极大程度上可以隐藏你的本地网络或者DMZ等。一个很好的例子是我们知道防火墙的外部地址,但必须用这个地址替换本地网络地址。有了这个操作,防火墙就能自动地对包做SNAT,以使 LAN 能连接到Internet。如果使用类似192.168.0.0/24 这样的地址,是不会从 Internet 得到任何回应的。因为RFC1918 定义了这些网络为私有的,只能用于LAN内部。
    • MASQUERADE: MASQUERADE的作用和SNAT完全一样,只是计算机的负荷稍微多一点。因为对每个匹配的包,MASQUERADE都要查找可用的IP地址,而不象SNAT用的IP地址是配置好的。当然,这也有好处,就是如果我们使用诸如PPPOE等拨号的方式连接Internet,这些地址都是由ISP的随机分配的,这时使用MASQUERADE是非常好的一个解决方案。
  • filter 表用来过滤数据包,我们可以在任何时候匹配包并过滤它们。我们就是在这里根据包的内容对包做DROP或ACCEPT的。当然,我们也可以预先在其他地方做些过滤,但是这个表才是设计用来过滤的。几乎所有的target都可以在这儿使用。

状态机制

状态机制是iptables中较为特殊的一部分,运行状态机制(连接跟踪)的防火墙称作带有状态机制的防火墙,以下简称为状态防火墙。状态防火墙比非状态防火墙要安全,因为它允许我们编写更严密的规则。
在iptables上一共有四种状态,分别被称为NEW、ESTABLISHED、INVALID、RELATED,这四种状态对于TCP、UDP、ICMP三种协议均有效。下面,我们来分别阐述四种状态的特性。

  • NEW:NEW说明这个包是我们看到的第一个包。意思就是,这是conntrack模块看到的某个连接的第一个包,它即将被匹配了。比如,我们看到一个SYN 包,是我们所留意的连接的第一个包,就要匹配它。
  • ESTABLISHED: ESTABLISHED已经注意到两个方向上的数据传输,而且会继续匹配这个连接的包。处于ESTABLISHED状态的连接是非常容易理解的。只要发送并接到应答,连接就是ESTABLISHED的了。一个连接要从NEW变为ESTABLISHED,只需要接到应答包即可,不管这个包是发往防火墙的,还是要由防火墙转发的。ICMP的错误和重定向等信息包也被看作是ESTABLISHED,只要它们是我们所发出的信息的应答。
  • RELATED: RELATED是个比较麻烦的状态。当一个连接和某个已处于ESTABLISHED状态的连接有关系时,就被认为是RELATED的了。换句话说,一个连接要想是RELATED的,首先要有一个ESTABLISHED的连接。这个ESTABLISHED连接再产生一个主连接之外的连接,这个新的连接就是 RELATED的了,当然前提是conntrack模块要能理解RELATED。ftp是个很好的例子,FTP-data 连接就是和FTP-control有关联的,如果没有在iptables的策略中配置RELATED状态,FTP-data的连接是无法正确建立的,还有其他的例子,比如,通过IRC的DCC连接。有了这个状态,ICMP应答、FTP传输、DCC等才能穿过防火墙正常工作。注意,大部分还有一些UDP协议都依赖这个机制。这些协议是很复杂的,它们把连接信息放在数据包里,并且要求这些信息能被正确理解。
  • INVALID:INVALID说明数据包不能被识别属于哪个连接或没有任何状态。有几个原因可以产生这种情况,比如,内存溢出,收到不知属于哪个连接的ICMP错误信息。一般地,我们DROP这个状态的任何东西,因为防火墙认为这是不安全的东西。

每个状态相对于不同的第四层协议来讲,稍微有些区别,对于TCP协议来说,当防火墙收到第一个数据包,也就是SYN报文时,将该会话标记为NEW状态,在系统的/proc/net/目录下,可以查阅文件ip_conntrack,这是在内存空间里存放防火墙当前状态表的临时文件,对于NEW状态的记录如下:
tcp 6 117 SYN_SENT src=192.168.1.5 dst=192.168.1.35 sport=1031 dport=23 [UNREPLIED] src=192.168.1.35 dst=192.168.1.5 sport=23 dport=1031 use=1
从上面的记录可以看出,SYN_SENT状态被设置了,这说明连接已经发出一个SYN包,但应答还没发送过来,这可从[UNREPLIED]标志看出,当服务器端回应了SYN/ACK包后,状态表改写为:
tcp 6 57 SYN_RECV src=192.168.1.5 dst=192.168.1.35 sport=1031 dport=23 src=192.168.1.35 dst=192.168.1.5 sport=23 dport=1031 use=1
现在我们已经收到了相应的SYN/ACK包,状态也变为SYN_RECV,这说明最初发出的SYN包已正确传输,并且SYN/ACK包也到达了防火墙。 这就意味着在连接的两方都有数据传输,因此可以认为两个方向都有相应的回应。
接下来,TCP三次握手的随后一个报文ACK包也到达了防火墙,防火墙上的状态表变成了:
tcp 6 431999 ESTABLISHED src=192.168.1.5 dst=192.168.1.35 sport=1031 dport=23 src=192.168.1.35 dst=192.168.1.5 sport=23 dport=1031 use=1
现在,我们来看看UDP协议的状态描述方法,从协议本身的特性来看,UDP连接是无状态的,因为它没有以对UDP连接设置状态。我们来看看是如何跟踪UDP连接的,以及在核心目录 /proc/net/ip_conntrack的相关记录。

当第一个UDP的数据包到达防火墙后,防火墙在他的状态表中留下了这样的记录:
udp 17 20 src=192.168.1.2 dst=192.168.1.5 sport=137 dport=1025 [UNREPLIED] src=192.168.1.5 dst=192.168.1.2 sport=1025 dport=137 use=1
UNREPLIED代表这是一个状态为NEW的数据包,当这条连接的回应数据包到达防火墙后,防火墙立即将修改这条状态记录:
udp 17 160 src=192.168.1.2 dst=192.168.1.5 sport=137 dport=1025 src=192.168.1.5 dst=192.168.1.2 sport=1025 dport=137 use=1
在这条新的状态记录中,UNREPLIED被删除了,这代表现在防火墙已经建立了一条UDP协议的会话,但这里并没有象TCP协议那样显示 ESTABLISHED标记,这是TCP的状态记录和UDP的状态记录稍微不同的一个地方,当然,还有一个地方需要注意,在测试中,还需要有一些数据包经过,防火墙才会将状态记录改写成:
udp 17 179 src=192.168.1.2 dst=192.168.1.5 sport=137 dport=1025 src=192.168.1.5 dst=192.168.1.2 sport=1025 dport=137 [ASSURED] use=1
ASSURED状态表示当前有数据在进行传输,表面当前连接的状态是ACTIVE的。如果,在这个状态下数据停止了传输,则这条记录会有一个计时器,也就是记录中的第三个字段,上面这条记录的第三个字段是 179,代表当前的ASSURED状态还能够保持 179 秒,如果还有新的数据包经过,那么计时器会被重新设置成缺省的 180 秒,如果在 180 秒内都没有流量,那么这条状态记录就会从状态表中被删除。

最后,我们在来看看Linux kernel是如何标示ICMP协议的状态的,ICMP也是一种无状态协议,它只是用来控制而不是建立连接。ICMP包有很多类型,但只有四种类型有应答包,它们是回显请求和应答(Echorequest and reply),时间戳请求和应答(Timestamp request and reply),信息请求和应答(Information request and reply),还有地址掩码请求和应答(Address mask request and reply),这些包有两种状态,NEW和ESTABLISHED 。时间戳请求和信息请求已经废除不用了,回显请求还是常用的,比如ping命令就用的到,地址掩码请求不太常用,但是可能有时很有用并且值得使用。看看下面的图,就可以大致了解ICMP连接的NEW和ESTABLISHED状态了。

如图所示,主机向目标发送一个回显请求,防火墙就认为这个包处于NEW状态。目标回应一个回显应答,防火墙就认为包处于ESTABLISHED了。当回显请求被发送时,ip_conntrack里就有这样的记录了:
icmp 1 25 src=192.168.1.6 dst=192.168.1.10 type=8 code=0 id=33029 [UNREPLIED] src=192.168.1.10 dst=192.168.1.6 type=0 code=0 id=33029 use=1

可以看到,ICMP的记录和TCP、UDP的有点区别,协议名称、超时时间和源、目地址都一样,不同之处在于没有了端口,而新增了三个新的字段:type,code和id。字段type说明ICMP的类型。code说明ICMP的代码,这些代码在附录ICMP类型里有说明。id是 ICMP包的ID。每个ICMP包被发送时都被分配一个ID,接受方把同样的ID 分配给应答包,这样发送方能认出是哪个请求的应答。

[UNREPLIED] 的含义和前面一样,说明数的传输只发生在一个方向上,也就是说未收到应答。再往后,是应答包的源、目地址,还有相应的三个新字段,要注意的是type和code是随着应答包的不同而变化的,id和请包的一样。和前面一样,应答包被认为是ESTABLISHED的。然而,在应答包之后,这个ICMP连接就不再有数据传输了。所以,一旦应答包穿过防火墙,ICMP的连接跟踪记录就被销毁了。因此,要想在/proc/ip_conntrack文件中抓到 ICMP协议的状态记录实在不是一件容易的事。您可以用如下的命令来尝试获取这些记录:

#cat /proc/net/ip_conntrack | grep icmp
如果没有输出,那么就不停的重复这个命令,直到发现icmp的记录为止。以上各种情况,请求被认为NEW,应答是ESTABLISHED。换句话说,就是当防火墙看到一个请求包时,就认为连接处于NEW状态,当有应答时,就是ESTABLISHED状态。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值