天天看点

iptables浅析

    防火墙一般是指由软件和硬件设备组合而成、在内部网和外部网之间、专用网与公共网之间的界面上构造的保护屏障,通过设置防火墙规则来保护我们的内网。

    防火墙的类型有两种:

    1,网络层的包过滤防火墙:

    工作在网络层,可以定义特定的规则禁止或允许某些特定的数据包通过,例如利用封装包的多样属性进行过滤:来源ip,目的ip,来源端口号,目的端口号,通信协议等。

    2,应用层防火墙

    工作在应用层,应用层防火墙可以拦截进出某应用程序(例如qq,迅雷等)的所有封包,并且封锁其他的封包(通常是直接将封包丢弃)。

     什么是iptables呢?

    它是一种基于包过滤的防护墙,已经静态编译进了kernel中,需要linux kernel 2.4以上的版本支持。但是,可以通过给kernel打补丁,使我们的iptables具有应用层防火墙的功能。

下面是包过滤防火墙的相关原理及配置:

包过滤防火墙一般包含有3个表(还有一个raw表):

1,filter table:过滤表(默认使用的就是filter表)

   包含三个链:

   INPUT:处理输入数据包

   FORWARD:处理转发数据包

   OUTPUT:处理输出数据包     

2,NAT table:用于网络地址转换

   POSTROUTING:处理路由后的数据包

   OUTPUT :处理输出数据包

   PREROUTING:处理路由前的数据包

3,mangle table:矫正表,针对策略路由(不做讲解)

我们用下图来说明iptables的工作原理(netfilter的原理):

首先,我们要知道:iptables只是linux用户态下的命令行前台程序,用于操作netfilter,而netfilter真正完成内核态下的数据包的过滤处理。我们可以认为iptables完成了这些工作。

TCP/IP是内置在kernel中的,而iptables又工作在网络层,故包过滤是在kernel空间中实现的。如果目的ip是本机的话,即从kernel空间转到用户空间,进行处理。如果访问的不是本机,则不进入用户空间,直接在kernel空间进行处理。TCP/IP是在内存中完成工作,而用户空间中的工作也是在内存中。故内存也是分区的,一部分用于用户空间,另一部分用于内核空间。

<a href="http://blog.51cto.com/attachment/201203/220339201.jpg" target="_blank"></a>

netfilter通过自己的五个钩子函数,来实现包过滤,而五个钩子函数分别应用在如图所示的五个地方,五个钩子函数为:

1, NF_IP_LOCAL_IN

2, NF_IP_LOCAL_OUT

3, NF_IP_FORWARD

4, NF_IP_PRE_ROUTING

5, NF_IP_POST_ROUTING

1, filter table:

filter表格不会对数据报进行修改,而只对数据报进行过滤,它是通过钩子函数NF_IP_LOCAL_IN, NF_IP_FORWARD及NF_IP_LOCAL_OUT来实现过滤。

2,NAT table:

监听三个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来实现

3, mangle table:

在NF_IP_PRE_ROUTING和NF_IP_LOCAL_OUT中监听。使用mangle表,可以实现对数据报的修改或给数据报附上一些带外数据。

而对与iptables的规则,优先级和规则的写入顺序是非常重要的:

处理优先级:mangle&gt;nat&gt;filter

规则:从上到下进行匹配,匹配到了就不在向下继续匹配

iptables的用法:(规则的顺序是非常重要的,下面的例子只是说明相对应命令的用法)

1, iptables的命令语法:

# iptables [-t table] sub_command [chain]  [num] [cretiria] [-j acction]

-t:用于指定要进行操作的表

    filter :包过滤(默认表)

nat:nat转换

mangle:策略路由

sub_command:子命令

  -A:在所选择的链末尾添加一条规则

 例:iptables –t filter –A INPUT –j ACCEPT

在filter表的INPUT链追加一条规则配置所有访问本地的数据包,匹配后丢弃

 -D:从所选链中删除一条规则。有两种方法:把被删除规则指定为链中的序号(第一条序号为1),或者指定为要匹配的规则内容;

例:iptables –D INPUT 1  (不写-t,默认是对filter表操作)

删除filter表的INPUT链的第一条规则

iptables –D INPUT –s 192.168.0.1 –j DROP

删除filter表中INPUT链内容为” –s 192.168.0.1 –j DROP”的规则

-R:从选中的链中替换一条规则。规则序号从1开始;

例:iptables –R INPUT 3 –j ACCEPT

将原来的第三条规则内容替换成”-j ACCEPT”

-I:根据给出的规则序号,向所选链中插入一条规则。默认插入成第一条规则

例:iptables –I INPUT –j DROP

在filter表的INPUT链插入一条规则,插入成第一条

    iptables -I INPUT 3 -j DROP

在filter表的INPUT链插入一条规则,插入成第三条

  -F:清空所选链的所有规则(不包括默认规则)

例:iptables –t flter –F INPUT

清空filter表INPUT链中所有规则

iptables –F

清空filter表中所有规则

-N:创建自定义的链

例:iptables -N clean_in

在filter表上创建一个新链clean_in

-X :删除用户自定义的空链,若不空,先清空,再删

例:iptables –X clean_in

-P:设置链的默认规则,即数据包在规则中都没有匹配到,就用默认规则处理(默认情况下,链的默认规则都死ACCEPT)

例:iptables –P INPUT DROP

设置filter表INPUT链默认规则为DROP(丢弃)

iptables –P INPUT REJECT (直接拒绝)

iptables –P INPUT ACCEPT  (接受)

 查看命令:

-L:显示所选表的所有链的所有规则

例:iptables –L

显示filter表中所有链的所有规则

   -n :只显示IP地址,不反解析成FQDN,一般与-L合用

   例:iptables –L –n

   -v:显示详细信息

   例:iptables -t nat –L -vn

   显示nat表所有链的详细信息

   -x:显示精确值,不进行单位换算

   --line-numbers:显示的时候显示规则的行号

   例:iptables   -L -n --line-numbers

   cretiria(匹配条件):

通用匹配:

    -s IP/network    表示某ip包的源地址

    -s ! IP/network   取反

    -d IP/network    表示目标IP

    -d ! IP/network   取反

    -i interface  (input interface)流入接口

    -o interface  (output interface)流出接口

扩展匹配:

隐式扩展:一般指对-p选项中指定的协议进行扩展

-p (tcp|udp|icmp)指定协议

   --sport  指定源端口

   可以指定一个端口范围,用:隔开

   例:--sport 1000:3000 匹配源端口1000到3000的数据包

   --dport  指定目的端口

例:iptables –P INPUT  DROP

iptables –A INPUT -d 1.1.1.1 -p tcp --dport 80 –j ACCEPT

这两条意思为:仅允许任意主机访问本机1.1.1.1的web服务

如果指定的是icmp协议的话,有如下的类型:

   -p icmp –icmp-type 8

   指定icmp的请求包

   -p icmp –icmp-type 0

   指定icmp的应答包

   例:iptables –A INPUT –s 192.168.1.0/24 –d 1.1.1.1 –p icmp –icmp-type 8 –j DROP

禁止192.168.1.0网络的主机ping主机1.1.1.1

显式扩展:一般必须指定-m选项明确指定要加载的扩展

-j TARGET     调转到指定的目标进行处理

    ACCEPT  直接接受

    DROP    直接丢弃

    REJECT  指接拒绝

state:连接状态 

     --state state

     NEW:表示是新建立的连接请求

  #iptables –A OUTPUT –o eth1 –m state --state NEW –j DROP     

  禁止本机发送建立连接的请求

    ESTABLISHED :表示所有已建立的连接

   #iptables –P OUTPUT DROP

   #iptables –A OUTPUT –s 172.16.100.1 –m state --state ESTABLISHED –j ACCEPT

   这两条的意思为:仅允许本机回应状态是已建立连接的请求

   iptables –P INPUT DROP

   iptables –A INPUT –d 172.16.100.1 –p tcp --dport 80 –m state --state NEW,ESTABLISHED –j ACCPT

   这两条的意思为:允许目标地址是172.16.100.1,目标端口是80,状态是新建和已建立连接的请求进入

RELATED:   主要用于ftp服务;

INVALIED:   无法识别的状态

多端口匹配:

-m(mport|multiport) 多端口匹配

 --source-ports [!] port,port,port...    源端口,加“!”取反

 --desrination-ports [!] port,port,port... 目标端口

 --ports [!] port,port,port...        多个端口,用“,”隔开

--ports:表示源和目的端口

例:iptables -P INPUT DROP

iptables -A INPUT -d 172.16.100.1 -p tcp -m mport --destination-ports 80,22,23 -m state --state NEW,ESTABLISHED -j ACCEPT

只允许使用tcp协议,目标端口是80,22,23,状态是新建和已建立的连接的请求进入

多地址匹配:

-m iprange   IP地址范围的扩展,指定了如何限定某个特定地址范围内的IP

    [!] --src-range ip-ip

    [!] --dst-range ip-ip

例:iptables -A INPUT -d 172.16.100.1 -m iprange --src-range 192.16.1.9-192.168.1.200 -p tcp --dport 80 -m state --state NEW -j DROP

不允许192.16.1.9到192.168.1.200范围内的主机访问172.16.100.1主机的web服务

connlimit:用于限制某个地址并发连接请求的个数

[!] --connlimit-above n   放行没超出范围的

limit:数据包的发送速率的限制

--limit rate    平均每单位时间内匹配多少个数据包

--limit-burst number   默认是5,峰值,突发限制数量的上限

例:

对进来的数据包接受目标地址是172.16.100.1目标端口是80的请求,每秒只能有1个,最大并发请求量为3个

# iptables -I INPUT 1 -p tcp -d 172.16.100.1 --dport 80 -j ACCEPT

# iptables -I OUTPUT 1 -m state --state ESTABLISHED -j ACCEPT

# iptables -R INPUT 1 -d 172.16.100.1 -p tcp --dport 80 -m limit --limit 10/second --limit-burst 30 -j ACCEPT

-m time:用于指定在什么时间段放行请求:

--timestart value   

--timestop value    

--days listofdays     (format: Mon, Tue, Wed, Thu, Fri, Sat, Sun ; default everyday)

--datestart date      

--datestop date       (  format: YYYY[:MM[:DD[:hh[:ss]]]]  )

2月18日-26日,每天的8:30到14:30之间能访问web服务:

iptables -A INPUT -d 172.16.100.1 -p tcp --dport 80 -m time --timestart 08:30:00 --timestop 14:30:00 --datestart 2012:02:18 --datestop 2012:02:26 -j ACCEPT

-m string:做字符串匹配(对中文的匹配非常有限)

  --algo bm|kmp  匹配算法,这个是一个应用层的算法

  --string pattern 

由于在网页上显示的内容,是经过编码的,故要使用某一个字算法把对应的字符串编码之后再进行匹配。这两个选项都是必须的

允许请求中,如果有访问Web的都不允许访问:

# iptables -A OUTPUT -s 172.16.100.1 -p tcp --sport 80 -m --algo bm --string "web" -j DROP

下面是利用iptables实现网络地址转换,需要对NAT表进行操作:

SNAT:源地址转换,实现代理内网客户端访问互联网的

--to-source ipaddr(, ipaddr, ipaddr...)

转换到的某个源地址上(当有多个网关时,指定多个源地址才有意义)

例:iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -m iprange -src-range 192.168.10.1-192.168.10.100 -j SNAT --to-source 1.1.1.1

将192.168.10.1-192.168.10.100网段数据包的源地址转换成1.1.1.1来访问外网

 MASQUERADE: 地址伪装,当前主机自动选一个能够访问互联网的ip地址作为SNAT。因此不用使用--to-source了。若地址是静态获得的,一定不要使用这个,因为效率比较低。

例:iptables -t nat -A POSTROUTING -m iprange --src-range 192.168.100.1-192.168.100.100 -j MASQUERADE

DNAT:目标地址转换,可以实现多个服务器通过一个公网地址提供服务,并能保证安全性

--to-destination

 例:iptables -t nat -A PREROUTING -d 1.1.1.1 -p tcp --dport 80 -j DNAT --to-destination 192.168.10.6(:8080)

当有用户访问1.1.1.1主机的80端口时,把请求装换成访问内网主机192.168.10.6的8080端口

启动iptables服务:

#service iptables start|stop|restart

iptables本身定义的规则立即生效,但是重启iptables服务就会失效。故要用

#service iptables save 来保存规则,这样会永久生效,规则会写在/etc/sysconfig/iptables

项目:如下图所示,192.168.1.0/24是“狼窝”,在要求为172.16.x.1写规则,满足以下求:

1、filter表所有链接的默认规则为DROP;

2、lo接口上进出的所有数据包均放行;

3、Web和ssh开放给非“狼窝”的主机;

       1)ssh仅允许在工作时间(每周一至周五的9:00-18:00)被访问,但172.16.0.0/16网络中的主机可在任意时段访问;

       2)web服务全时段可被访问,但每秒种接收的新请求的个数不能超过100个;

4、发往本机的ping请求,每秒只响应两个数据包,且最高每秒只响应3个;拒绝来自“狼窝”的ping请求;本机可向任意主机发送Ping请求;

5、本机出口仅将已经建立的连接放行;

<a href="http://blog.51cto.com/attachment/201203/220311916.jpg" target="_blank"></a>

# iptables -P INPUT DROP

# iptables -P FORWARD DROP

# iptables -P OUTPUT DROP

# iptables -i lo -j ACCEPT

# iptables -o lo -j ACCEPT

# iptables -A INPUT -s 0.0.0.0/0.0.0.0 -j clean_in

# iptables -A INPUT -s 192.168.1.0/24 -d 172.16.100.1 -j DROP

# iptables -A INPUT -d 172.16.100.1 -p tcp --dport 80 -m state --state ESTABLISHED -j ACCEPT

# iptables -A INPUT -d 172.16.100.1 -p tcp --dport 80 -m state --state NEW -m limit --limit 100/second -j ACCEPT

# iptables -A INPUT -s 172.16.0.0/16 -d 172.16.100.1 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT

# iptables -A INPUT -d 172.16.100.1 -p tcp --dport 22 -m time --timestart 09:00:00 --timestop 18:00:00 --days Mon,Tue,Wed,Thu,Fri -m state --state NEW,ESTABLISHED -j ACCEPT

# iptables -A INPUT -d 172.16.100.1 -p ICMP --icmp-type 8 -m limit --limit 2/second --limit-burst 3 -j ACCEPT

# iptables -A INPUT -d 172.16.100.1 -p ICMP --icmp-type 0 -j ACCEPT

# iptables -A OUTPUT -m state --state ESTABLISHED -j ACCEPT

# iptables -A OUTPUT -s 172.16.100.1 -p ICMP --icmp-type 0 -j ACCEPT

# iptables -A OUTPUT -s 172.16.100.1 -p ICMP --icmp-type 8 -j ACCEPT

# iptables -N clean_in

# iptables -A clean_in -d 255.255.255.255 -p icmp -j DROP

# iptables -A clean_in -d 172.16.255.255 -p icmp -j DROP

# iptables -A clean_in -p tcp ! --syn -m state --state NEW -j DROP

# iptables -A clean_in -p tcp --tcp-flags ALL ALL -j DROP

# iptables -A clean_in -p tcp --tcp-flags ALL NONE -j DROP

# iptables -A clean_in -d 172.16.100.1 -j RETURN

本文转自 leejia1989 51CTO博客,原文链接:http://blog.51cto.com/leejia/816182,如需转载请自行联系原作者

继续阅读