防火墙之iptables/netfilter

  这篇博客的主要内容是介绍防火墙netfilter,在linux操作系统上,这是第三代防火墙。前两代是

ipfwadm和ipchains,netfilter的功能非常强大,它的地位绝不亚于其他收费系列的防火墙软件。


    首先,补充自己的知识,人们常说的iptables,并不是防火墙,其实真正的防火墙是netfilter,

是编译进内核的模块,而iptables只是为了方便用户去写规则的工具,iptables写好的规则,被netfilter

读取之后立即生效。

iptables包含5个链,4个表,每个链都包含表,具体情况看下图

4张表:

filter:filter是netfilter最重要的机制,其任务是执行数据包的过滤操作,也起到了防火墙作用

 

nat:nat也是防火墙不可或缺的机制,现在用的比较多的就是为了地址转换

 

mangle:mangle是一种特殊的机制,可以修改经过防火墙内的数据包

 

raw:负责加快数据包穿过防火墙的速度,提升防火墙的性能

5条链:

INPUT:指的是“网络上其他主机发送给本机进程的数据包”

 

OUTPUT:如果是“由本机进程”所流出的数据包,即为OUTPUT类型的包

 

FROWARD:如果数据包对本机而言只是路过,本机只是起到转发的作用,即转发

PREROUTING:发生在前半段路由决策之前,一般用于DNAT转换

POSTROUTING:发生在后半段的路由决策之后,一般用于SNAT转换

那么,iptables是如何工作的呢,先看下面的流程图

首先,客户端的请求的报文会到达PREROUTING这个链,这个链在DNAT的时候应用的多

然后,报文会到达路由选择,根据报文的信息判断,报文送到本机还是进行转发

     转发:报文会通过FORWARD这条链

     送达本机:报文先会经过INPUT这个链,规则会对报文进行处理

     通过本机内部,到达本机的进程进行处理,处理后输出

     报文流出时,经过OUTPUT链,会被这条链的规则匹配

之后,报文到达报文流出的路由选择,也有规则匹配,或是规定从哪个网卡流出

iptables的命令主要分为两个部分:

iptables的命令参数

iptables的规则语法

 

这里,我们主要介绍的filter表

iptables的基本语法

 

iptables [-t TABLE] COMMAND CHAIN CRETIRIA -j TARGET

 

-t TABLE:

    这里的TABLE主要指的就是上面的4个链,默认为filter

 

COMMAND:

 

  主要是对链的操作:

   -F:清空规则链,如果不指定的话,默认全部清空
        实例:[root@blog ~]# iptables -t filter -F    
        默认情况下为filter表,可以不加-t filter

 

   -N:用于自己新建一条新的规则链
        实例:[root@blog ~]# iptables -t filter -N ssh_in 
        新建一个自定义的链,链名为ssh_in

 

   -X:删除规则链,只对自定义规则链有效
        实例:[root@blog ~]# iptables -t filter -X ssh_in
       删除上面新建的自定义的链

 

   -Z:计数器归零

    一般查看计数:iptables -L -n -v -x

        计数主要分为pkts和bytes

           表示,已经匹配到的包数和字节数

        实例:[root@blog ~]# iptables -L -n -v -x 

        Chain INPUT (policy ACCEPT 239 packets, 19921 bytes)

        pkts    bytes target   prot opt in   out   source    destination

        我们先用iptables -L 进行查看,我们可以看到在INPUT链上,接收的包为239个,
        字节数为19921字节

        [root@blog ~]# iptables -Z

        [root@blog ~]# iptables -L -n -v -x

        Chain INPUT (policy ACCEPT 5 packets, 356 bytes)

          pkts   bytes target    prot opt in   out   source   destination 
        对filter链进行计数器清零,再次查看,包数减少,因为ssh的连接上,仍有包传输
 

   -P:设定默认的策略,对于filter表,默认为ACCEPT和DROP两种
        实例:将默认策略改为DROP,但是,之前,要放行ssh的连接
            [root@blog ~]# iptables -A INPUT -p tcp –dport 22 -j ACCEPT

           [root@blog ~]# iptables -A OUTPUT -p tcp –sport 22 -j ACCEPT
           [root@blog ~]# iptables -P INPUT DROP

           [root@blog ~]# iptables -P OUTPUT DROP

           [root@blog ~]# iptables -L -n -v -x

            Chain INPUT (policy DROP 23 packets, 1906 bytes)
            可以看出INPUT链上,DROP规则有数据,原因是局域网内的广播包

 

   -E:将自定义的规则链重命名
        实例:新创建一条自定义链httpd_in,然后重命名为web_in
            [root@blog ~]# iptables -N httpd_in 
            [root@blog ~]# iptables -E httpd_in web_in

 

   针对链中的规则

   -A:添加一条心的规则,一般情况下,是最后生效的
        实例:流经INPUT和OUTPUT的链的数据放行
        [root@blog ~]# iptables -A INPUT -j ACCEPT

        [root@blog ~]# iptables -A OUTPUT -j ACCEPT

        其实,这就相当于默认规则为ACCEPT
 

   -I:插入一条新的规则,默认情况下,会被插到最前面
        实例:插入一条让web通行的,查到第二条规则
        [root@blog ~]# iptables -I INPUT 2 -p tcp –dport 80 -j ACCEPT

        [root@blog ~]# iptables -I OUTPUT 2 -p tcp –sport 80 -j ACCEPT

        上面没有提到的,后面将会解释
     
    我们可以使用:iptables -L -n –line-numbers

        可以看出每条规则所对应的序号

   
    -D:删除规则链
        实例:删除上面的INPUT链上,匹配到web服务的规则
        [root@blog ~]# iptables -D INPUT 2

 

   -R:替换,将新的规则与旧的规则进行替换,要指定哪条链

       实例:将上面提到的OUTPUT链上,匹配到web的规则改为允许任意服务都匹配
        [root@blog ~]# iptables -R OUTPUT 2 -p tcp -j ACCEPT

     

   查询已经设定的规则:

    -L:list,列出已经设定的规则

         -n:以数字的形式显示主机和端口号,可以避免反解

         -v:详细的格式显示规则,还有-vv,-vvv

         –line-numbers:上面用过了,显示序号

         -x:不对计数器的结果做单位换算,从而可以显示精确值

 

匹配条件:

通用匹配:

   -s 地址:指定报文的源地址,地址可以为ip,网络地址

   可以用:–src ,–source
    实例:从211.70.160.0/24这个网络来访问我们web服务的主机都放行
    [root@blog ~]# iptables -A INPUT -s 211.70.160.0/24 -p tcp –dport 80 -j ACCEPT

 

   -d 地地:指定报文的目标地址,也可以是ip和网络地址

   可以用:–dst ,–destination

    实例:从211.70.160.0/24这个网络来访问我们web服务的主机都放行
   
 [root@blog ~]# iptables -A OUTPUT -d 211.70.160.0/24 -p tcp –sport 80 -j ACCEPT

   -p 协议:指定报文匹配的协议,有tcp,udp,icmp

    icmp协议:

        –icmp-type:指定icmp协议的匹配类型

        0:回显响应,ping的响应报文

        8:回显请求,ping的请求报文

    实例:不允许任何主机ping我们的web服务器
     [root@blog ~]# iptables -A INPUT -p icmp –icmp-type 8 -j DROP 
  

 

   -i 接口:指定数据报文流入的接口

   -o 接口:指定数据报文流出的接口
        实例:假设,数据包进入的方向为eth0,出去的方向为eth1,且访问web服务都放行
        [root@blog ~]# iptables -A INPUT -i eth0 -p tcp –dport 80 -j ACCEPT

        [root@blog ~]# iptables -A OUTPUT -o eth1 -p tcp –sport 80 -j ACCEPT

 

扩展匹配:只有在通用匹配是指定了协议时,才可以使用扩展匹配

   -p [tcp|udp]:

      –sport PORT[-PORT]:指定源端口

      –dport PORT[-PORT]:指定目标端口

      –tcp-flags:指定tcp的标志位,udp没有

        tcp的标志位有:SYN,ACK,FIN,RST
    实例:这里主要介绍–tcp-flags,如果tcp的报文不正常,标志位都为1时,不放行
    [root@blog ~]# iptables -A INPUT -p tcp –tcp-flags all all -j DROP
    第一个all是检查所有标志位,第二个all是指都为1的标志位

 

    实例:iptables -A INPUT -p tcp –tcp-flags all syn

    指的是匹配所有的标志位,而且syn必须为1,也可以使用–syn

    all表示所有位,none则表示不匹配

 

显示扩展:其必须要指明使用的是哪个模块进行扩展的,之后才有使用扩展选项

-m state –state

    
    multiport:支持多端口匹配

    可用于连续的或者是非连续的端口,一次最多指定15个端口

    专用选项:

    –source-ports,–sports port[,port,port:port]

        逗号表示离散的,分号表示连续的

    –distination-ports,–dports

    –ports

    实例:清除上面的规则后,将请求ssh和web服务的放行,前提是,更改默认规则为ACCEPT
    [root@blog ~]# iptables -A INPUT -p tcp -m multiport –dports 22,80 -j ACCEPT
    [root@blog ~]# iptables -A OUTPUT -p tcp -m multiport –sports 22,80 -j ACCEPT
    
    
 

  iprange:匹配指定范围内地址

    匹配一段连续的地址,而不是整个网络

    专用选项:

   –src-range IP[-IP]

   –dst-range IP[-IP]

 

  string:字符串匹配,能够检测报文应用层中的字符串

    匹配时,一定要指定其匹配的算法:kmp,bm

    专用选项:

   –algo {kmp|bm}:任选其中的一种算法

   –string "STRING" :指定匹配的字符串

   –hex-string  "HEX_STRING":HEX_STRING:编码为16进制的字符串

    实例:过滤网页中出现qq的字眼
    [root@blog ~]# iptables -A INPUT -p tcp –dport 80 -m string –algo bm –string "qq" -j DROP
 

  time:基于时间做访问控制:

    专用选项:

    –datestart YYYY[-MM][-DD[Thh[:mm[::ss]]]]

    –datestop YYYY[-MM][-DD[Thh[:mm[::ss]]]]

    上面两项匹配的是日期时间

 

   –timestart hh:mm:[:ss]

   –timestop hh:mm[:ss]

这两项指的是小时分钟上的时间

 

   –weekdays Mon,Tue,Wed,Thu,Fri,Sat,Sun

匹配的是星期几

    实例:规则网内的主机,在早上8:00到17:00不能上网,且是上班期间
    [root@blog ~]# iptables -I INPUT -p tcp –dport 80 -m time –timestart 08:00
    –timestop 15:00 ! –weekdays Sat,Sun -j DROP
    上面用到!表示取反,即上班时间
 

   connlimit:连接数目上的限制,对每个IP所能发起的并发数进行限制

    专用选项:

    –connlimit-above N

    实例:当单个ip的连接数目达到5个是,不允通行
    [root@blog ~]# iptables -A INPUT -m connlimit –connlimit-above 5 -j DROP
    规则中的意思是,大于等于5个的时候允许通行,其他情况就被默认规则匹配
 

   limit:对于数据传输速率的限制

    专用选项:

    –limit n[/second |/minute | /hour | /day]

    –limit-burst n:这是一个容器,对于之前没有发起请求的客户端,

  第一次可以发起的请求数
    实例:假设,对第一次发起请求的客户端,速率为5/second,一般的客户端3/second
    [root@blog ~]# iptables -A INPUT -m limit –limit 3 –limit-burst 5 -j DROP
    大于这个数的被DROP掉了,没达到的被默认规则匹配

 

   state:状态检查,这是iptables防火墙的特色所在

    专用选项:

    –state

  

 追踪的状态的:

    NEW:新建一个会话

    ESTABLISHED:已经建立的连接

    RELATED:有关联的关系连接,对于ftp这种服务特别适用

    INVALID:无法识别的连接

适用nat或是state时,都会使用到iptables的连接追踪功能,这对于请求量比较大的服务器上

最好关闭,连接追踪,否则会造成大量的用户请求失败,万一出现这种情况,

马上卸载追踪的模块:modprobe nf_conntrack

 

调整连接追踪功能所容纳的最大的连接数目

/proc/sys/net/nf_conntrack_max

 

当前追踪的所有连接

/proc/net/nf_conntrack

 

不同的协议或是连接类型追踪时的属性

/proc/sys/net/netfilter目录下

 

 

实例:放行被动模式下的ftp服务

 

在对我们的ssh连接的基础上,把默认规则设为DROP

 

首先,我们在主机上安装vsftpd的ftp软件:

[root@localhost ~]# yum install -y vsftpd

 

装载支持ftp的追踪模块:

modprobe nf_conntrack_ftp

 

放行请求的报文:

对于NEW状态的21号端口请求放行:

[root@localhost ~]# iptables -I INPUT -p tcp –dport 21 -m state –state NEW -j ACCEPT

 

对于已经建立NEW状态的ftp服务放行

[root@localhost ~]# iptables -A INPUT -p tcp -m state –state ESTABLISHED,RELATED -j ACCEPT

 

对于响应报文进行放行:

[root@localhost ~]# iptables -I OUTPUT -m state –state ESTABLISHED,RELATED -j ACCEPT

对于不同的服务,可以将同一个服务创建一个自定义链

 

自定义的链,默认情况是不生效的,只有调用时才会生效

 

创建自定义的链

iptables [-t TABLE] -N chain

 

实例:为httpd服务添加进入

[root@localhost ~]# iptables -t filter -N httpd_in 

[root@localhost ~]# iptables -A httpd_in -p tcp –dport 80 

-m iprange –src-range 211.70.160.10-211.70.160.30

 

[root@localhost ~]# iptables -A httpd_in -p tcp –dport 80 

-m state –state NEW -j ACCEPT

状态为NEW的报文被接受,ESTABLISHED状态的报文被主链的匹配

[root@localhost ~]# iptables -A INPUT -m state –state ESTABLISHED -j ACCEPT

 

这样的话,规则,就被优化了,不需要逐条定义,只需要定义一条httpd服务的自定义链

然后,在INPUT和OUTPUT上允许ESTABLISHED状态通行

 

调用自定义的链

[root@localhost ~]# iptables -A INPUT -p tcp –dport 80 -j httpd_in

Chain httpd_in (1 references)一次调用

 

 

自定义链的TARGET

RETURN:自定义的链没有匹配到任何报文时,将返回其主链

 

当规则不匹配时,跳回主链

[root@localhost ~]# iptabels -A httpd_in -j RETURN

 

 

删除自定义链,且引用数为0

iptables [-t TABLE] -X chain

 

删除被主链调用的关系

[root@localhost ~]# iptabels -D INPUT 4

 

清空自定义链的规则

[root@localhost ~]# iptables -F httpd_in

 

然后删除httpd_in的自定义链

[root@localhost ~]# iptables -X httpd_in

 

重命名自定义的链

iptables [-t TABLE] -E old_chain new_chain

 

[root@localhost ~]# iptables -E httpd_in web_

 

防火墙的应用是:主机防火墙+网络防火墙

处理目标:

内置目标:

DROP #丢弃报文,不返回任何信息,建议使用

REJECT #丢弃报文,并返回一定的信息

ACCEPT #接受报文

自定义的链:

RETURN  #退出自定义链,返回主链

 

 

写规则时的主要事项:

对服务端而言:报文是先进后出的

对客户端而言:报文是先出后进的

客户端的端口是随机的,一般不需要限定

 

优化规则:

尽量减少规则的条目,彼此不想管的匹配机会较多的放在上面

对于同一匹配规则,更严格的放在最上面

 

 

保存规则链:

iptables-save > /path/file_name #保存至指定位置

service iptables save  #保存至/etc/sysconfig/iptables-config

    

  总结:防火墙对于一个服务器的安全非常重要,好的规则,有着非常高的匹配效率,也能达到预定的期望,对于这些,我们还是要多记多练


本文出自 “牛叉的孩子光着屁屁” 博客,请务必保留此出处http://cshang.blog.51cto.com/6143980/1565664

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。