最近看了一些网络安全的东西,觉得网络的世界远远没有我们想象的那么简单。去年自己只是简单的看了一些关于iptables的简单使用规则,当然现在也只是对iptables有简单的了解而已,不能算上是熟悉,写这点东西的目的也只是简单的科普,很多东西只能简单的提下,因为这部分内容实在太多,无法一一列举。
iptables本身是Linux用来处理底层网络数据的一种方法,很多人都将iptables称作是Linux的防火墙(firewall),但我觉得最贴切的叫法应该是Netfilter/iptables这个机制才形成了Linux系统真实的firewall,用来针对Linux系统IP信息包进行过滤。虽然netfilter/iptablesIP 信息包过滤系统被称为单个实体,但它实际上由两个组件netfilter和iptables组成。netfilter组件也称为 内核空间(kernelspace),是内核的一部分,由一些信息包过滤表组成,这些表包含内核用来控制信息包过滤处理的规则集。iptables组件是一种工具,也称为用户空间(userspace),它使插入、修改和除去信息包过滤表中的规则变得容易。如果Linux系统连接到因特网或LAN、服务器或连接LAN和因特网的代理服务器,则该系统有利于在Linux系统上更好地控制IP信息包过滤和防火墙配置。
说iptables前必须说一下Netfilter,它是内核的一部分,但Netfilter并不是专业内核开发机构提供的,它是社区中一个开源组织所发起的项目www.netfilter.org,www.kernel.org会定时在内核中更新Netfilter的patch以及新的特性,并加到内核中。Netfilter以模块的方式存在于内核中,如果Netfilter多了一个特性模块,当然Linux的firewall就多了一条特性。好了就不再多说,至于这些关系的内容可以自己Google。
Netfilter的模块只是提供了某些对数据包过滤与匹配的功能。如果我们希望Netfilter能做一些事,就必须对他设定一些规则,这样它才可以知道那些数据包是必须丢掉的,那些是转发出去的,那些是需要接受的。对于Netfilter来说,它包含四张表分别是filter、nat、mangle、raw。具体的红能用途如下:
Filter::是Netfilter内最重要的机制,其任务为执行包的过滤工作,也是防火墙的主要功能。
Nat:是防火墙上的IP分享,转发器,可以针对数据进行IP和端口级别的转发。(目前我们一些实验室、小型公司上网基本都是通过Nat技术实现,因为共有IP十分稀有,还有它对于数据包的转发、隐藏IP,等都用到SNAT、DNAT技术,这里只需要简单有个概念就ok)
Mangle:经由它可以修改行经防火墙的数据包内容。
Raw:负责加快包穿越防火墙的速度,由此提高防火墙的性能。
(用途如果此时不是很明白,等会我们在讨论)
这四张table分别都有结构,而且都是链式的数据通路,它们每张表包含的链如下:
Table Chain
Filter INPUT,FORWARD,OUTPUT.
Nat PREROUTING,POSTROUTING,OUTPUT
Mangle PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
Raw PREROUTING,OUTPUT
关于chain(可以理解为数据包经过的通道、关卡)需要解释一下:
INPUT类型:是指网络上其他主机发给本机的数据包,即输入本机的数据。
OUTPUT类型:是指本机程序去访问网络上其他主机时产生的数据包,即输出的数据。
FORWARD类型:是指本机做为router时,也就是数据包经过本机,会有这种封数据 包产生。
PREROUTING和 POSTROUTING也经常用于NAT配置网关机进行网络地址转换使用(我只能简单解释如此,因为真正懂了之后你就知道是什么意思了,你可以简单理解位nat技术用到的数据包经过两个通道)。
Netfilter中每一个table都有对应的模块对属于该表的chain中经过的数据进行一定规则的限制通过(我这么说可能有些绕口)。那些模块都是开发人员写的针对底层数据的处理程序而作为.ko文件可以加入内核并投入使用。(这里只能简单说到这。)
现在说说iptables,我前面提到Netfilter需要一些规则来完成我们需要的功能,这里iptables就是那个设定规则的操作工具,通过iptables
,建立这些规则,并将其添加到内核空间的特定信息包过滤表内的链中以完成通过向防火墙提供有关对来自某个源、到某个目的地或具有特定协议类型的信息包要做些什么的指令,规则控制信息包的过滤。
关于添加/除去/编辑规则的命令的一般语法如下:
$iptables [-t table] command [match] [target]
[-ttable]
选项允许使用标准表之外的任何表。表是包含仅处理特定类型信息包的规则和链的信息包过滤表。有三种可用的表选项:
filter
、
nat
和
mangle
。该选项不是必需的,如果未指定, 则filter
用作缺省表。
filter表用于一般的信息包过滤,它包含
INPUT
、
OUTPUT
和
FORWARD
链。nat表用于要转发的信息包,它包含
PREROUTING
、
OUTPUT
和
POSTROUTING
链。 如果信息包及其头内进行了任何更改,则使用mangle
表。该表包含一些规则来标记用于高级路由的信息包,该表包含PREROUTING
和
OUTPUT
链。
注:PREROUTING
链由指定信息包一到达防火墙就改变它们的规则所组成,而POSTROUTING
链由指定正当信息包打算离开防火墙时改变它们的规则所组成。
上面这条命令中具有强制性的
command部分是
iptables
命令的最重要部分。 它告诉
iptables
命令要做什么,例如,插入规则、将规则添加到链的末尾或删除规则。以下是最常用的一些命令:
-
-A
或--append
: 该命令将一条规则附加到链的末尾。
示例:$iptables -A INPUT -s 205.168.0.1 -j ACCEPT
该示例命令将一条规则附加到
INPUT
链的末尾,确定来自源地址 205.168.0.1的信息包可以ACCEPT
。 -
-D
或--delete
: 通过用-D
指定要匹配的规则或者指定规则在链中的位置编号,该命令从链中删除该规则。下面的示例显示了这两种方法。
示例:$iptables -D INPUT --dport 80 -j DROP
$ iptables -D OUTPUT 3第一条命令从
INPUT
链删除规则,它指定DROP
前往端口 80的信息包。第二条命令只是从OUTPUT
链删除编号为 3的规则。 -
-P
或--policy
: 该命令设置链的缺省目标,即策略。所有与链中任何规则都不匹配的信息包都将被强制使用此链的策略。
示例:$iptables -P INPUT DROP
该命令将
INPUT
链的缺省目标指定为DROP
。这意味着,将丢弃所有与INPUT
链中任何规则都不匹配的信息包。 -
-N
或--new-chain
: 用命令中所指定的名称创建一个新链。
示例:$iptables -N allowed-chain
-
-F
或--flush
: 如果指定链名,该命令删除链中的所有规则,如果未指定链名,该命令删除所有链中的所有规则。此参数用于快速清除。
示例:$iptables -F FORWARD
$ iptables -F -
-L
或--list
: 列出指定链中的所有规则。
示例:$iptables -L allowed-chain
以上是iptables的规则是定,其中的match部分指定信息包与规则匹配所应具有的特征(如源和目的地地址、协议等)。匹配分为两大类: 通用匹配和特定于协议的匹配。这里,我将研究可用于采用任何协议的信息包的通用匹配。
-p
或--protocol
:该通用协议匹配用于检查某些特定协议。协议示例有
TCP
、UDP
、ICMP
、用逗号分隔的任何这三种协议的组合列表以及ALL
(用于所有协议)。ALL
是缺省匹配。可以使用!
符号,它表示不与该项匹配。
示例:
-
-s
或--source
: 该源匹配用于根据信息包的源IP地址来与它们匹配。该匹配还允许对某一范围内的IP地址进行匹配,可以使用!
符号,表示不与该项匹配。缺省源匹配与所有IP 地址匹配。
示例:$iptables -A OUTPUT -s 192.168.1.1
$ iptables -A OUTPUT -s192.168.0.0/24
$ iptables -A OUTPUT -s ! 203.16.1.89第二条命令指定该规则与所有来自192.168.0.0 到192.168.0.24的 IP地址范围的信息包匹配。第三条命令指定该规则将与除来自源地址 203.16.1.89外的任何信息包匹配。
-
-d
或--destination
: 该目的地匹配用于根据信息包的目的地IP 地址来与它们匹配。该匹配还允许对某一范围内 IP地址进行匹配,可以使用!
符号,表示不与该项匹配。
示例:$iptables -A INPUT -d 192.168.1.1
$ iptables -A INPUT -d192.168.0.0/24
$ iptables -A OUTPUT -d ! 203.16.1.89
$iptables -A INPUT -p TCP, UDP
$ iptables -A INPUT -p ! ICMP
在上述示例中,这两条命令都执行同一任务— 它们指定所有
TCP
和
UDP
信息包都将与该规则匹配。 通过指定
!ICMP
,我们打算允许所有其它协议(在这种情况下是TCP
和
UDP
), 而将
ICMP
排除在外。
对应的TARGET是由规则指定的操作,对与那些规则匹配的信息包执行这些操作。
ACCEPT
:
当信息包与具有ACCEPT
目标的规则完全匹配时,会被接受(允许它前往目的地),并且它将停止遍历链(虽然该信息包可能遍历另一个表中的其它链,并且有可能在那里被丢弃)。该目标被指定为
-jACCEPT
。
-
DROP
: 当信息包与具有DROP
目标的规则完全匹配时,会阻塞该信息包,并且不对它做进一步处理。该目标被指定为-jDROP
。 -
REJECT
: 该目标的工作方式与DROP
目标相同,但它比DROP
好。和DROP
不同,REJECT
不会在服务器和客户机上留下死套接字。另外,REJECT
将错误消息发回给信息包的发送方。该目标被指定为-jREJECT
。
示例:$iptables -A FORWARD -p TCP --dport 22 -j REJECT
-
RETURN
: 在规则中设置的RETURN
目标让与该规则匹配的信息包停止遍历包含该规则的链。如果链是如INPUT
之类的主链,则使用该链的缺省策略处理信息包。它被指定为-jumpRETURN
。示例:$iptables -A FORWARD -d 203.16.1.89 -jump RETURN
(需要注意的是RETURN
可以用于自定义的规则链中,具体还是需要自行Google
)。
建立基本的规则和链后,我们需要将它保存到内核,但是系统重新启动后,这些规则就会消失,当然你可以将该规则集保存在文件中。可以使用serviceiptables save命令来做到这一点,把所有的规则存储到/etc/sysconfig/iptables.接着使用chkconfigiptables on设置系统,现在,信息包过滤表中的所有规则都被保存在文件/etc/sysconfig/iptables中。无论何时再次引导系统,firewall规则都会存在了。但是我并不觉得这样很好,假设你的规则中每条都涉及到-d192.168.0.100这个条件,如果这个主机改动了IP,难道你需要手动去改么?我建议最好使用简单的shell脚本,在系统启动脚本中执行该shell文件。这样就ok了,我们批量修改完全可以使用shell的sed等文本编辑工具。
到这我都不知到该怎么写了,因为内容太多了,这篇东西反正我自己觉得很糟糕,很多问题都没有办法解释,我自己也没有截取一些实际操作的图贴上,更别说细节了,对NAT的SNAT、DNAT规则,以及mangle的功能,还有raw提升速度(最开始说的)的原因是因为它可以减少nf_conntrack模块对于数据包的跟踪(这个模块默认会对经过firewall的数据包进行连接跟踪并记录到它的数据库,所有连接都会被记录在/proc/net/nf_conntrack文件)等等有好多东西都没提到,当然我只是简单看过,了解一下,具体的机制不是太懂,也许这是为什么写到这里很混乱的原因。有时间以后再慢慢补充解释吧。网上找了一张我觉得最为贴切Netfiler完整机构的图,说明了数据包在Netfilter中在各个table chain的流经过程,如果对这些东西感兴趣那就结合自己Google各种相关内容慢慢看吧,就算是科普了。