一、理论部分

    1、什么是防火墙?

    防火墙:(英文:Firewall),隔离工具

        防火墙其实就是一个组件,这个组件能够屏蔽来自于互联网,或来自于企业内部的用户的***操作(DDos***,端口扫描等等);主要目的是防范非授权的访问的!它工作于网络或主机的边缘(通信报文的进出口),对于进出本网络或主机的报文根据事先定义的检查规则做匹配检测,对于能够被规则匹配到的报文做出相应处理,时刻检查出入防火墙的所有数据包,决定拦截或是放行哪些数据包。

        它需要对我们主机上的或者是网络内的所有主机上的网络通信操作做一些防范性控制;根据这个防火墙到底是用于防护单台主机还是防护一个网络内的所有主机,通常分为网络防火墙主机防火墙

        网络防火墙:工作与一个网络的边缘,能够实现对进出本网络的所有主机报文加以防护;

        主机防火墙:主要是用来防范单台主机的进出报文;

        

        缺点

            (1)防火墙虽然可以过滤互联网的数据包,但却无法过滤内部网络的数据包。因此若有人从内部网络***时,防火墙没有作用。

            (2)电脑本身的操作系统亦可能因一些系统漏洞,使***者可以利用这些漏洞绕过防火墙过滤,从而***电脑

            (3)防火墙无法有效阻挡病毒***,尤其是隐藏在数据中的病毒。

            (4)正常状况下,所有互联网的数据包软件都应经过防火墙的过滤,这将造成网络交通的瓶颈。例如在***性数据包出现时,***者会不时寄出数据包,让防火墙疲于过滤数据包,而使一些合法数据包软件亦无法正常进出防火墙。

没有绝对安全的操作系统,虽然防火墙有这些缺点,但还是能阻挡大多数来自于外网的***!


        2、iptables/netfilter的区别及各自的功能;

         iptables:用户空间的应用程序,用于编写规则的接口;另外一层意思是内核模块里存放规则的地方也叫iptables;iptables分开的意思就是ip+tables,就是ip和表,存储ip相关的规则和表;

        netfilter:kernel,内核中的代码,hooks function:钩子函数,

        它作为一个通用的、抽象的框架,提供一整套的hook函数的管理机制,使得诸如数据包过滤、网络地址转换(NAT)和基于协议类型的连接跟踪成为了可能。

        netfilter内置的五个钩子

            prerouting:路由前,数据报文刚到达本机还哦没有路由的;

            input:路由完之后,要到达本机内部来的;

            forward:不到本机内部的,经由本机转发的;

            output:由本机内部向外发出的;

            postrouting:即将发出去,马上要离开本机网卡的报文;

        报文流向:

            流入本机:prerouting-->input==>用户空间进程;

            流出本机:用户空间进程==>output-->postrouting;

            转发:prerouing-->forward-->postrouting

            wKiom1cqC27glQItAAFT89ul0iM510.jpg

        netfilter功能:表(table);

            filter:过滤,防火墙;

            mangle:拆解报文,按需修改;

            nat:network address translation;网络地址转换(IP层、传输层地址);

            raw:关闭在nat表上启用的连接追踪机制;

        iptables:iptables编写的规则将应用在netfilter上的钩子函数上面;

            内置链:与钩子函数一一对应;

                PREROUTING

                INPUT

                FORWARD

                OUTPUT

                POSTROUING

            用户自定义链:用于内置链进行补充扩展。可实现更灵活的规则组织管理机制;


        表和链的对应关系,及优先级(由高到底:raw-->mangle-->nat-->filter);

           wKiom1cqCwqhtTugAADVNbTdCrA778.png

     添加规则时的考量点:   

        (1)要实现何种功能:判断添加规则至哪个表上;

        (2)报文流经的位置:判断添加规则至哪个链上;

    iptabels开启及关闭

        CentOS 7

            #systemctl stop firewalld.service

            #systemctl disable firewalld.service

        CentOS 6

            #service iptables stop

            #chkconfig iptables off

二、iptables命令详解

    命令格式:iptables  [-t table]  SUBCOMMAND  chain  [matches...] [target]

         -t table:指定表,不指默认是filter表;

            raw,mangle,nat,[filter]

        链管理:

            -N:new,新建一条自定义链;                             

# iptables -N lizonglun
[root@localhost ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
                         
Chain FORWARD (policy DROP)
target     prot opt source               destination   
      
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
                         
Chain lizonglun (0 references)
target     prot opt source               destination

            -X:delete,删除自定义的空链;

#iptables -X testing,  请确保链上没有规则
Chain INPUT (policy ACCEPT 84 packets, 9220 bytes)
pkts bytes target     prot opt in     out     source               destination         
 
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target     prot opt in     out     source               destination         
Chain OUTPUT (policy ACCEPT 21 packets, 1964 bytes)
pkts bytes target     prot opt in     out     source               destination

            -P:policy,设置默认链的规则;

                ACCEPT:接收

                DROP:丢弃

                REJECT:拒绝

                    #设置默认策略:把filter表中FORWARD修改成DROP

wKioL1crU2Hxk469AABMCYzXtIk223.png

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

             #iptables -E lizonglun testing

wKioL1crU5bi0hXWAABToyR-7TA824.png

        规则管理:

            -A:append,追加,默认为最后一个;

                #允许任何主机访问200.100主机上的80服务;

                # iptables -A INPUT -d 172.18.200.100/16 -p tcp --dport 80 -j ACCEPT

                # iptables -A OUTPUT -s 172.18.200.100/16 -p tcp --sport 80 -j ACCEPT

wKiom1crVvrCyu2GAABXWqvk83E374.png

            -I:insert,插入,默认为最开始处;

                #表示只允许15.1这台主机ssh连接200.100

                #iptables -I INPUT -s 172.18.15.1 -d 172.18.200.100 -p tcp --dport 22 -j ACCEPT

wKioL1crWeDCBtVBAABhWDPRoh0438.png

            -D:delete,删除;

                (1)rule,specification

                (2)rule number

                    #删除filter表中第一条规则;

                    # iptables -D INPUT  1

            -R:replace,替换

            -F:flush,清除规则;

                    #iptables -F  清除所有链上的规则;

            -Z:zero,置0;

                iptables的每条规则都有两个计数器;

                    (1)由本规则匹配到的所有报文数量(packets);

                    (2)由本规则匹配到的所有bytes;

            -S:selected,以iptables-save命令的格式显示链上的规则;

wKioL1crXUXhLvwtAAAnqbu8BYs661.png

       查看

           -L:list,列出规则;

                -n:numeric,以数字格式显示地址和端口;

                -v:verbose,显示详细信息;-vv,-vvv(显示更加详细的信息);

                -x:exactiy,显示计数器的精确值,而非单位换算后的结果;

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

                    常用组合:iptables -vnL

   wKiom1crXh-Sef5bAAA94-Pzpjg203.png

                    #也可查看某表上的某个链;

  wKioL1crXy_BYUNcAAAYD3oruLk902.png

        处理动作:

        wKiom1cqD8zACieaAABIhBM05bQ708.png

匹配条件

    基本匹配:

        [!]-s,--source address[/mask][,...]:源地址匹配;

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

            #允许来自172.18.15.1的主机访问本主机;-t不指表,默认为filter表;

            #iptables -t filter -A INPUT -s 172.18.15.1/16 -d 172.18.252.100/16 -j ACCEPT

            #iptables -t filter -A OUTPUT -s 172.18.252.100/16 -d 172.18.15.1/16 -j APPEPT

            #不允许来自172.18.15.1的主机访问本主机;

            #iptables -t filter -A INPUT ! -s 172.18.15.1/16 -d 172.18.252.100 -j ACCEPT

                

        [!]-i.--in-interfeace name:限制报文流入的接口;

        [!]-o,--out-interface name:限制报文流出的接口,只能用于OUTPUT,FORWARD及POSTROUTING;

    扩展匹配:经由扩展模块引入的匹配机制,需要加载扩展模块;-m matchname;

        隐式扩展:可以不用使用-m选项专门加载相应模块;前提是要使用-p选项可匹配何种协议;

            [!]-p,--protocol PROTOCOL PROTOCOL;

             协议:tcp,udo,icmp,icmpv6,esp,ah,sctp,mh or "all"

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

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

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

            规则允许访问本机80服务;

                # iptables -A INPUT -d 172.18.252.100-p tcp --dport 80 -j ACCEPT

                # iptables -A OUTPUT -s 172.18.252.100 -p tcp --sport 80 -j ACCEPT

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

                --tcp-flags  syn,fin,ack,rst,  syn;表示这四个是规则检查的,其中syn必须为1,剩余的三个必须为0; 这就是tcp三次握手中的第一次;

                --tcp-flags syn,fin,ack,rst   ack,fin;表示这四个是规则检查的,其中ack,fin必须为1,剩余的必须为0,这个是四次断开时请求断开的一方所发出的的报文;

            [!]--syn:

                --syn相当于“--tcp-flags syn,fin,ack,rst,  syn”; tcp三次握手的第一次;
            udp:

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

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

            icmp隐含指明了"-m icmp"有专用选项

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

                type/code:

                    0/0:echo reply:回显应答;

                    8/0:echorequest:回显请求,ping请求;

                允许本机ping报文出去;这两条命令表示自己可以ping别人,别人ping不通自己;

                    # iptables -A OUTPUT -s 172.18.252.100 -d 0/0 -p icmp --icmp-type 8 -j ACCEPT

                    # iptables -A INPUT -s 0/0 -d 172.18.252.100 -p icmp --icmp-type 0 -j ACCEPT

                允许别人ping自己;

                    # iptables -A INPUT -s 0/0 -d 172,。18.252.100 -p icmp --icmp-type 8 -j ACCEPT

                    # iptables -A OUTPUT -s 172.18.252.100 -d 0/0 -p icmp --icmp-type 0 -j ACCEPT



        显示扩展

             multiport:多端口匹配

                以离散方式定义多端口匹配,最多可以指定15个端口;

                [!]--source-ports,--sports port[,port|,port:port]...

                [!]--destination-ports,--dports port[,port|,port:port]...

                [!]--ports port[,port|,port:port]...

                    #iptables -I INPUT -s 0/0 -d 172.18.100.6 -p tcp -m multiport -dports 22,80 -j ACCEPT

                    #iptables -I OUTPUT -s 172.18.100.6 -p tcp -m multiport -sports 22,80 -j ACCEPT

            iprange:指明一段连续的ip地址范围作为源地址或目标地址匹配;

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

                [!]--dst-range from[-to]:目标地址范围

                    以下规则表示允许172.18.252.100-172.18.252.200范围的主机telnet至172.18.252.100

                    # iptables -A INPUT  -d 172.18.252.100 -p tcp --dport 23 -m iprange  --src-range 172.18.252.100-172.18.252.200 -j ACCEPT

                    # iptables -A OUTPUT -s 172.18.252.100 -p tcp --sport 23 -m iprange --dst-range 172.18.252.100-172.18.252.200 -j ACCEPT

            string:对报文中的应用层数据做字符串匹配检测;
                 --algo{bm|kmp}:检查时的算法

                    (bm = Boyer-Moore,kmp = Knuth-Pratt-Morris)

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

                [!]--hex-string  pattern:给定要检查的字符转模式;

                拒绝请求的报文中包含“old”字符串的报文出去;

                #iptables -I OUTPUT -s 172.18.100.6 -d 0/0 -p tcp --sport 80  -m string --algo bm --string "old" -j REJECT

             time:根据收到报文的时间/日期与指定的时间/日期范围进行匹配;

                --datestart YYYY[-DD[tHH[:mm[:ss]]]]:起始日期时间;

                --datestop  YYYY[-DD[tHH[:mm[:ss]]]]:结束日期时间;


                --timestart  hh:mm[:ss]:小时、分钟、秒,起始时间;

                --timestop  hh:mm[:ss]:小时、分钟、秒,结束时间;

     

                [!]--monthdays day[,day...]:匹配一个月中的哪些天;

                [!]--weekdays day[,day...]:匹配一周的哪些天;

                同时做了地址限定和时间限定:修改规则只工作时间周一到周五允许172.18.252.100-172.18.252.200范围内的主机并且在09:00:00-16:00:00时间范围内登陆;

                  # iptables -R INPUT 4 -d 172.18.252.100-p tcp --dport 23 -m iprange --src-range 172.18.252.100-172.18.252.200 -m time --timestart 09:00:00 --timestop 16:00:00 --weekdays 1,2,3,4,5 -j ACCEPT

            connlimit:根据每客户端主机做并发连接数限制,即每客户端最多可同时发起的连接数量;

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

                connlimit-above n:连接数量大于n则匹配;

                当客户机并发请求数量小于等于2的时候就允许telnet登陆;大于2个就拒绝;

                #iptables -A INPUT -s 0/0 -d 172.18.252.100-p tcp --dport 23 -m connlimit-upto 2 -j ACCEPT

                #iptables -A OUTPUT -s 172.18.252.100 -d 0/0 -p tcp --sport 23 -j ACCEPT

            limit:基于令牌桶算法对报文的速率做匹配;

                --limit rate[/second|/minute|/hour|/day]:速率限制;
                second:秒
                minute:分;
                hour:小时
                day:天   
            --limit-burst number:速率峰值,
            对来自客户端的ping请求潜质镀铝,1分钟ping20个,峰值3个;
           #iptables -A INPUT  -d 172.18.100.6 -p icmp --icmp-type 8 -m limit --limit 20/minute --limit-burst 5  -j ACCEPT

                        wKiom1craDiwQC_SAAIK3OBJkb0209.gif

          

            state:是conntrack的子集,用于对报文的状态做连接追踪;


                [!] --state state			   
                   INVALID:无法识别的连接;    
                    ESTABLISHED:已经建立的连接状态;连接追踪模板当中存在记录的连接;
                    NEW:新连接请求,连接追踪模板当中不存的连接请求;
                    RELATED:相关联的连接;
                    UNTRACKED:有意放行,未追踪的连接;
                        已经追踪到的并记录下来的连接:
                            /proc/net/nf_conntrack				
                        连接追踪功能所能够记录的最大连接数量(可调整):
                           /proc/sys/net/nf_conntrack_max                        设定追踪连接的最大值:
                           例如:                            sysctl -w net.nf_conntrack_max=300000                            echo  300000 > /proc/sys/net/nf_conntrack_max
                    conntrack所能够追踪的连接数量的最大值取决于/proc/sys/net/nf_conntrack_max的设定;
       已经追踪到的并记录下来的连接位于/proc/net/nf_conntrack文件中,超时的连接将会被删除;
       当模板满载时,后续的新连接有可能会超时;
           解决办法:

               (1) 加大nf_conntrack_max的值;
(2) 降低nf_conntrack条目的超时时长;
   不同协议的连接追踪时长:/proc/sys/net/netfilter/

                    如何放行被动模式的ftp服务?            
                        (1) 内核加载nf_conntrack_ftp模块;
                           modprobe  nf_conntrack_ftp


                       (2) 放行命令连接
                           #iptables  -A INPUT  -d  $sip -p tcp --dport 21  -m state --state NEW,ESTABLISHED -j  ACCEPT
                           #iptables  -A  OUTPUT  -s  $sip  -p tcp --sport  21  -m state --state  ESTABLISHED -j ACCEPT
                       (3) 放行数据连接
                           #iptables  -A INPUT  -d  $sip -p tcp  -m state --state RELATED,ESTABLISHED -j  ACCEPT
                           #iptables  -A  OUTPUT  -s  $sip  -p tcp  -m state --state  ESTABLISHED -j ACCEPT

        规则的检查次序:规则在链接上的次序即为其检查时的生效次序;因此,其优化使用有一定法则;
           (1) 同类规则(访问同一应用),匹配范围小的放前面;用于特殊处理;
           (2) 不同类的规则(访问不同应用),匹配范围大的放前面;
           (3) 应该将那些可由一条规则描述的多个规则合并为一;
           (4) 设置默认策略;

       规则的有效期限:
           iptables命令添加的规则,手动删除之前,其生效期限为kernel的生命周期;
       保存规则:
           CentOS 6:
               ~]# service  iptables  save
               ~]# iptables-save  > /etc/sysconfig/iptables
               ~]# iptables-save  >  /PATH/TO/SOME_RULE_FILE
       #service  iptables  restart
重启后会自动从/etc/sysconfig/iptables文件中重载规则;

           CentOS 7:
               ~]# iptables  -S  > /PATH/TO/SOME_RULE_FILE
               ~]# iptables-save  >  /PATH/TO/SOME_RULE_FILE

           重载预存的规则
               ~]# iptables-restore  <  /PATH/FROM/SOME_RULE_FILE

           自动生效规则文件中的规则:
               (1) 把iptables命令放在脚本文件中,让脚本文件开机自动运行;
                   /etc/rc.d/rc.local
                       /usr/bin/iptables.sh

               (2) 用规则文件保存规则,开机自动重载命令;
                   /etc/rc.d/rc.local
                       iptables-restore  <  /PATH/FROM/SOME_RULE_FILE

                不足之处还请大家多多提宝贵意见!!