防火墙(Firewalld)是一种隔离工具,防范与非授权的访问,使主机更安全。它主要工作与网络或主机的边缘,对于进出本网络或主机的通信报文根据事先定义好的规则进行匹配检测;对于能够被规则所匹配到的报文做出相应的处理。

    防火墙的分类:

    主机防火墙:工作范围是单个主机

    网络防火墙:工作范围是整个网络;网络防火墙中还可以包含主机防火墙

    防火墙的实现方式:

      硬件防火墙:NetScreen、CheckPoint

      软件防火墙:iptables


本文所介绍的iptables就是Linux的软防火前的实现。

 iptables最主要的特点就是4表5链,以及每种不同的表所对应不同的链;  

    5链:prerouting、input、output、forward、postrouting

    4表:filter、mangle、nat、raw

      filter:主要功能是过滤;对应的链为:input、output、forward

      mangle:主要功能是拆解报文、做出修改、重新封装;对应的链为:prerouting、input、output、forward、postrouting

      nat:主要功能是网络地址转换;对应的链为:prerouting、postrouting、output

      raw:在限定的时间范围内,关闭在nat表上的启用的连接追踪机制;对应的链为:output、prerouting

    同一链上的不同表的应用优先级:raw、mangle、nat、filter


报文在主机内的流向示意图:

                

wKiom1coYOmxbp51AAAvrAMGLCE317.png

报文流向有两种:

    流入本机的报文:报文流入-->prerouting-->input-->output-->postrouting-->报文流出

    由本机转发报文:报文流入-->prerouting-->forward-->postrouting-->postrouting

    注意:报文是由本机处理,但是是否转发是由路由来决定的;在报文流入本机之后,路由1会判断报文的目标地址是否为本机,如果是,则流入input;如果不是,则流入forwrad,在报文离开本机之前路由2会判断报文经由那个接口送往下一个网关(下一跳),同时在转发之前,要确保转发功能是开启的;1表示开启,0表示关闭:

            

[root@wtc ~]#vim  /etc/sysctl.conf
[root@wtc ~]#net.ipv4.ip_forward = 0  ## 把0更改为1即为开启
[root@wtc ~]#/sbin/sysctl -p      ##修改之后立即生效

               

  iptables的规则:根据规则匹配条件尝试匹配检查报文,对成功匹配的报文做出相应的处理

       组成部分:匹配条件、处理动作

        匹配条件:基本匹配、扩展匹配

        处理动作:基本处理动作、扩展处理动作、自定义处理动作

        注意:添加规则时的考量点;

        (1)要实现什么样的功能;判断添加至那个表上

        (2)报文流经的位置;判断添加至那个链上

        (3)同类的规则,匹配范围小的放在前面,用于特殊处理

        (4)不同类的规则,匹配范围大的放在前面

        (5)将那些可由一条规则描述的多个规则合并为一个

        (6)设置默认策略


  iptables的相关命令:   

    iptables [-t table] {-A|-C|-D} chain rule-specification

    

    iptables [-t table] {-A|-C|-D} chain rule-specification

    

    iptables [-t table] -I chain [rulenum] rule-specification

    

    iptables [-t table] -R chain rulenum rule-specification

    

    iptables [-t table] -D chain rulenum

    

    iptables [-t table] -S [chain [rulenum]]

    

    iptables [-t table] {-F|-L|-Z} [chain [rulenum]] [options...]

    

    iptables [-t table] -N chain

    

    iptables [-t table] -X [chain]

    

    iptables [-t table] -P chain target

    

    iptables [-t table] -E old-chain-name new-chain-name


    rule-specification = [matches...] [ -j target]


 实现对链管理:管理一整条链

      -N:新增一条自定义链

      -X:删除一条自定义链(删除时要确保链下没有规则)

      -P:设置链的默认策略

      -E:重命名于未被引用的自定义链(引用计数为0,即references为0)

        

实现对规则管理:管理链上的某条规则     

     -A:追加一个规则;默认为末尾

     -I:插入一个规则;默认为最开始处

     -D:删除某条规则

     -R:指明修改第几条规则

     -F:清空所有的规则

                    

查看某表上的规则:

     -L:列出规则

     -n:以数字格式显示地址个端口

     -v:显示详细信息

     --line-numbers:显示链上的规则和编号

     -x:显示计数器的精确值


匹配条件:

    基本匹配:netfilter自带的匹配机制                   

      [!] -s, --source address[/mask][,...]:原地址匹配(!s是取反)

      [!] -d, --destination address[/mask][,...]:目标地址匹配

      [!] -i, --in-interface name:限制报文流入的接口(只能用于prerouting、input、forward这三个链)

      [!] -o, --out-interface name:限制报文流出的接口(只能用于output、forward、postrouting这三个链)

      [!] -p{tcp|udp|icmp}:限制协议;指明用哪一种协议

[root@wtc ~]#iptables  -A   INPUT  -s  172.18.0.0/18  -d 172.18.42.200  -p  tcp  -j  ACCEPT
[root@wtc ~]#iptables  -A   OUTPUT -s  172.18.42.200  -d 172.18.0.0/16  -p  tcp  -j  ACCEPT


  扩展匹配:经由扩展模块引入的匹配机制;-m  matchname

      隐式扩展:无需指明,可以不适用-m选项专门加载响应模块;前提要使用-p选项可匹配何种协议

      显示扩展:需要指明,必须由-m选项专门加载响应模块


      隐式扩展:                        

         tcp:隐含指明了“-m  tcp",有专用选项:

          [!]  --source-port,--sport  port[:port]:匹配报文中的tcp首部的源端口;可以是端口范围

          [!] --destination-port,--dport  port [:port]:匹配报文中的tcp首部的目标端口;可以是端口范围

          [!] --tcp-flags  mask comp:检查报文中mask指明的tcp标志位,而要这些标志位comp必须为1

            例如:--tcp-flags  syn,fin,ack,rst   syn

                  此时: syn必须为1

          [!] --syn:

            --syn相当于"--tcp-flags  syn,fin,ack,syn“,tcp中的第一次握手

[root@wtc ~]# iptables -A INPUT -s 0/0 -d 10.0.1.2 -p tcp --dport 80 --tcp-flags SYN,ACK,FIN,RST SYN  -j ACCEPT
[root@wtc ~]# iptables -A INPUT -d 0/0 -s 10.0.1.2 -p tcp --sport 80 -j ACCEPT


        udp:                    

           [!]  --source-port,--sport  port[:port]:匹配报文中的tcp首部的源端口;可以是端口范围

           [!] --destination-port,--dport  port [:port]:匹配报文中的tcp首部的目标端口;可以是端口范围

        
        icmp:隐含指明了“-m icmp”,有专用选项

               [!] --icmp-type  {type[/code][typename]

             type/code:

             0/0:表示响应

             0/8:表示请求

[root@wtc ~]#iptables  -A INPUT  -s 0/0 -d 172.18.42.200 -p icmp --icmp-type 8 -j ACCEPT
[root@wtc ~]#iptables  -A OUTPUT -s 172.18.42.200 -d 0/0 -p icmp --icmp-type 0 -j ACCEPT

     显示扩展:                       

    (1)multiport扩展:以离散方式定义多端口匹配;最多指定15个端口; 

        [!] --source-ports,--sports port[,port|,port:port]...:指定多个源端口;

        [!] --destination-ports,--dports port[,port|,port:port]...:指定多个目标端口;

        [!] --ports port[,port|,port:port]...:同时匹配多个端口(指明多个端口;)

[root@wtc ~]#iptables  -A INPUT  -s 0/0 -d 172.18.42.200 -p tcp -m multiport --dports 80,22 -j ACCEPT
[root@wtc ~]#iptables  -A OUTPUT -s 172.18.42.200 -d 0/0 -p tcp -m multiport --sports 80,22 -A ACCEPT

                

    (2)iprange扩展:指明一段连续的ip地址范围作为源地址或目标地址匹配 

        [!] --src-range from[-to]:源IP地址;

        [!] --dst-range from[-to]:目标IP地址;

[root@wtc ~]#iptables -A INPUT  -d 172.18.42.200 -p tcp -dport 80 -m iprange --src-range 172.18.42.1-172.18.42.100 -j ACCEPT
[root@wtc ~]#iptables -A OUTPUT -s 172.18.42.200 -p tcp -sport 80 -m iprange --dst-range 172.18.42.1-172.18.42.100 -j ACCEPT


    (3)string扩展:对报文中的应用层数据做字符串模式匹配检测;

        --algo {bm|kmp}:字符串匹配检测算法;

        bm:Boyer-Moore

        kmp:Knuth-Pratt-Morris

        [!] --string pattern:要检测的字符串模式;

        [!] --hex-string pattern:要检测的字符串模式(16进制格式);

[root@wtc ~]#iptables -I OUTPUT -s 172.18.42.200 -d 0/0 -p tcp -sport 80 -m string --algo bm --string "wtc" -j A DROP

        注意:要求越严格的越要放在前面;之所以使用“OUTPUT”是因为在接受了报文之后才能够响应输出;如果直接是“INPUT”使用“DROP”,则报文会被直接拒绝,根本不会流入本机内部

                    

                

    (4)time扩展:根据将报文到达的时间与指定的时间范围进行匹配;

        --datestart YYYY[-MM[-DD[Thh[:mm[:ss]]]]]:起始日期时间

        --datestop YYYY[-MM[-DD[Thh[:mm[:ss]]]]]:结束日期时间

        --timestart hh:mm[:ss]:起始时间

        --timestop hh:mm[:ss]:结束时间

        [!]--monthdays day[,day...]:匹配1-12月中的某些天

        [!]--weekdays day[,day...]:匹配一个周中的某些天

        --kerneltz:使用内核上的时区,而非默认的UTC;

[root@wtc ~]#iptables -A INPUT -s 0/0 -d 172.18.42.200 -p tcp -dport 80 -m time --timestart 08:30:00 --timestop 18:00:00 --weekdays 1,2,3,4,5 -j ACCEPT


     

    (5)connlimit扩展:根据每客户端IP做并发连接数数量匹配;即每客户端最大可同时发起的连接数量

        --connlimit-upto n:连接的数量小于等于n时则匹配;

        --connlimit-above n:连接的数量大于n时匹配

[root@wtc ~]#iptables -A INPUT -s 0/0 -d 172.18.42.200 -p tcp -dport 80 -m connlimit --connlimit-upto 20 -j ACCEPT


    (6)limit扩展:基于收发报文的速率做匹配;

        --limit rate[/second|/minute|/hour|/day]

        --limit-burst number 

[root@wtc ~]#iptables -A INPUT -s 0/0 -d 172.18.42.200 -p tcp -dport 80 -m limit --limit 20/second --limit-burst 5 -j ACCEPT


        

      (7)state扩展(conntrack的子集):用于对报文的根据”连接追踪机制“去检查连接的状态(但是对服务的连接数量会有很大的影响)

        连接模板:占用内存空间中的一段空间(内核空间)

        [!] --state state 

        conntrack机制:追踪本机上的请求和响应之间的关系;状态有如下几种:

        NEW:新发出请求;连接追踪模板中不存在此连接的相关信息条目,因此,将其识别为第一次发出的请求;

        ESTABLISHED:NEW状态之后,连接追踪模板中为其建立的条目失效之前期间内所进行的通信状态;

        RELATED:相关联的连接;如ftp协议中的数据连接与命令连接之间的关系;

        INVALID:无法识别的连接(一般不会放行)

        UNTRACKED:未进行追踪的连接(在连接模板中没有相关记录)                          

[root@wtc ~]#iptables -A INPUT  -m state --state ESTABLISHED -j ACCEPT
[root@wtc  ~]#iptables  -A OUTPUT  -s 172.18.42.200 -d 0/0 -p tcp -sport 80 -m state --state NEW -j ACCEPT

        查看连接追踪功能所能够容纳的最大连接数量:

        /proc/sys/net/nf_conntrack_max

        修改链接追踪功能所能够容纳的最大连接数量

        echo  Num  >  /proc/sys/net/nf_conntrack_max

        sysctl  -w  net.nf_conntrack_max=Num

        缺点:如果连接模板超载,当有一个新的请求时,web网页会显示连接超时同时conntrack所能够连接数量的最大值取决于/proc/sysnet/nf_conntrack_max的设定;已经追踪到的记录并记录在/prco/net/nf_conntrack文件中,但当模板满载时,后续的新连接可能会被超时,而连接超时的时长将会被删除;解决的办法有两个

    (1)加大nf_conntrack_max的值

                                

[root@wtc ~]# vim /proc/sys/net/netfilter/nf_conntrack_max

    (2)降低nf_conntrack_timeout文件的的时间(不同协议的连接追踪时长不同)

[root@wtc ~]#vim /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_time_wait
[root@wtc ~]#vim /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established
[root@wtc ~]# vim /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_fin_wait
[root@wtc ~]# vim /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_close_wait



    开放主/被动模式的ftp服务:

        主动:

[root@wtc ~]#iptables  -A INPUT -d 172.18.42.200 -p tcp --dport 21 -m state --state ESTABLISHED -j ACCEPT
[root@wtc ~]#iptables -A OUTPUT -s 172.18.42.200 -p tcp --sport 21 -m state --state ESTABLISHED -j ACCEPT

        被动:

  

[root@wtc  ~]#modprobe nf_conntrack_ftp  ##内核加载nf_conntarck_ftp模块
[root@wtc  ~]#iptables -A INPUT -m state --state ESTABLISHED RELATED -j ACCEPT
[root@wtc  ~]#iptables -A OUTPUT -s 172.18.42.200 -p tcp --sport 21 -m state --state NEW -j ACCEPT



        保存编写好的规则并开机启动

[root@wtc ~]#server iptables save 
[root@wtc ~]#iptables: Saving firewall rules to /etc/sysconfig/iptables:[  OK  ]  ##系统默认的保存路径
[root@wtc ~]#iptables-save > /path/to/rule_file  ## 可自己指明保存的路径
[root@wtc ~]#chkconfig  iptables on  ##设置为当前规则可开机启动
[root@wtc ~]#service  iptables  restart  ##会自动从系统默认的保存路径中重载规则


处理动作

    (1)LOG:匹配报文中的日志功能

       --log-level  level:(emerg, alert, crit, error, warning, notice,info or debug.

            --log-prefix  prefix:说明报文的日志信息是由谁产生的

                    

[root@wtc ~]iptables -A FORWARD -m state --state ESTABLISHED -j ACCEPT
[root@wtc ~]iptables -A FORWARD -s 0/0 -d172.18.42.200 -p tcp -m multiport --dports 80,21,23,22 -m state -state NEW -j LOG --log-prefix "(wtc's log)"



    (2)REDIRECT:端口重定向(之后在报文流入本机前才有用:prerouting)

        --to-ports port[-port]:映射到某个端口上

[root@wtc ~]iptables -t nat -A PREROUTING -d 172.18.42.200 -p tcp 80 -j REDIRECT --to-ports 172.18.42.201:8080
## 此命令是把80的端口映射在8080上,虽然访问的是80,但正真提供服务的是8080


    (3)SNAT(本地主机请求远程服务器):源地址转换;发生在postrouting

        修改IP报文中的源IP地址

        使用场景:本地网络中的主机可使用统一地址与外部主机通信,从而实现地址伪装

        请求:由内网主机发起,修改源IP,如果修改则由管理员定义

        响应:修改目标IP,由nat自动根据会话表中追踪机制实现相应的修改

        --to-source [ipaddr[-ipaddr]][:port[-port]]

[root@wtc ~]iptables -t nat -A POSTROUTING -s 172.18.42.200 -d 172.18.42.201 -p tcp --dport 80 -j SNAT --to-source 172.18.42.202
##请求80端口的是172.18.42.202主机,但正在请求的却是172.18.42.200主机

    (4)DNAT(远程主机请求本地服务器):目标地址转换;发生在prerouting            

        修改IP报文中的目标IP

        使用场景:让本地网络中的吴福气使用统一的地址想外提供服务,但隐藏了自己的真实地址

        请求:有外网主机发情,修改其目标地址,由管理员定义

        响应:修改源地址,但由nat自动根据会话表中的追踪机制来实现相对应的修改

        --to-destination  [ipaddr[-ipaddr]] [:port[-port]]

[root@wtc ~]iptables -t nat -A PREROUTING -s 172.18.42.200 -d 172.18.42.201 -p tcp --dport 80 -j DNAT --to-destination 172.18.42.202
##请求的是172.18.42.201的80端口,但真正提供服务的却是172.18.42.202的80端口
[root@wtc ~]iptables -t nat -A PREROUTING -s 172.18.42.200 -d 172.18.42.201 -p tcp --dport 80 -j DNAT --to-destination 172.18.42.202:8080
##真正提供服务的是172.18.42.202的8080端口


    (5)MASQUERADE:源地址转换;发生在postrouting

        当源地址为动态获取的地址时,MASQUERADE会自动判断要转换为的地址

[root@wtc ~]iptables -t nat -A POSTROUTING -s 0/0 -d 172.18.42.201 -j MASQUERADE