1、简介

IPTABLES 是与最新的 3.5 版本 Linux 内核集成的 IP 信息包过滤系统。如果 Linux 系统连接到因特网或 LAN、服务器或连接 LAN 和因特网的代理服务器, 则该系统有利于在 Linux 系统上更好地控制 IP 信息包过滤和防火墙配置。(百度百科)

  • 防火墙起到数据包过滤作用。
    SNAT 私网用户到公网 源NAT是我们出去
    DNAT 公网用户到私网 目标NAT是公网进来

  • 硬件防火墙有三个接口
    内网接口
    外网接口
    DMZ接口 DMZ是英文“demilitarized zone”的缩写,中文名称为“隔离区”,也称“非军事化区”。

firewalld 与 iptables的比较:

    1.firewalld可以动态修改单条规则,动态管理规则集,允许更新规则而不破坏现有会话和连接。而iptables,在修改了规则后必须得全部刷新才可以生效;
    2.firewalld使用区域和服务而不是链式规则;
    3.firewalld默认是拒绝的,需要设置以后才能放行。而iptables默认是允许的,需要拒绝的才能限制;
    4.firewalld并不具备防火墙的功能,和iptables一样需要通过内核的netfilter来实现。只不过firewalld和iptables的使用方法不一样!

firewalld是iptables的一个封装,可以让你更容易地管理iptables规则。它并不是iptables的替代品,虽然iptables命令仍可用于firewalld,但建议firewalld时仅使用firewalld命令。

学习iptables不得不提的几个概念,首先我们应该了解什么是四表五链:

1.Filter 表[过滤]
filter表用来过滤数据包,我们可以在任何时候匹配包并过滤它们。我们就是在这里根据包的内容对包做DROP或ACCEPT的。当然,我们也可以预先在其他地方做些过滤,但是这个表才是设计用来过滤的。几乎所有的target都可以在这儿使用。大量具体的介绍在后面,现在你只要知道过滤工作主要是在这儿完成的就行了。

2.nat 表[伪装]
此表仅用于NAT,也就是转换包的源或目标地址。注意,就象我们前面说过的,只有流的第一个包会被这个链匹配,其后的包会自动被做相同的处理。实际的操作分为以下几类:
• DNAT
• SNAT
• MASQUERADE
DNAT 操作主要用在这样一种情况,你有一个合法的IP地址,要把对防火墙的访问重定向到其他的机子上(比如DMZ)。也就是说,我们改变的是目的地址,以使包能重路由到某台主机。
SNAT 改变包的源地址,这在极大程度上可以隐藏你的本地网络或者DMZ等。一个很好的例子是我们知道防火墙的外部地址,但必须用这个地址替换本地网络地址。有了这个操作,防火墙就能自动地对包做SNAT和De-SNAT(就是反向的SNAT),以使LAN能连接到Internet。如果使用类似 192.168.0.0/24这样的地址,是不会从Internet得到任何回应的。因为IANA定义这些网络(还有其他的)为私有的,只能用于LAN内部。
MASQUERADE 的作用和MASQUERADE 完全一样,只是计算机的负荷稍微多一点。因为对每个匹配的包,MASQUERADE 都要查找可用的IP地址,而不象SNAT 用的IP地址是配置好的。当然,这也有好处,就是我们可以使用通过PPP、 PPPOE、SLIP等拨号得到的地址,这些地址可是由ISP的DHCP随机分配的。

3.mangle 表[改包]
这个表主要用来mangle包,你可以使用mangle匹配来改变包的TOS等特性。
强烈建议你不要在这个表里做任何过滤,不管是DANT,SNAT或者Masquerade。
以下是mangle表中仅有的几种操作:
• TOS
• TTL
• MARK
TOS操作用来设置或改变数据包的服务类型域。这常用来设置网络上的数据包如何被路由等策略。注意这个操作并不完善,有时得不所愿。它在Internet上还不能使用,而且很多路由器不会注意到这个域值。换句话说,不要设置发往Internet的包,除非你打算依靠TOS来路由,比如用iproute2。TTL操作用来改变数据包的生存时间域,我们可以让所有数据包只有一个特殊的TTL。它的存在有一个很好的理由,那就是我们可以欺骗一些ISP。为什么要欺骗他们呢?因为他们不愿意让我们共享一个连接。那些ISP会查找一台单独的计算机是否使用不同的TTL,并且以此作为判断连接是否被共享的标志。MARK用来给包设置特殊的标记。iproute2能识别这些标记,并根据不同的标记(或没有标记)决定不同的路由。用这些标记我们可以做带宽限制和基于请求的分类。

4.RAW 表[链路跟踪]
RAW表只使用在PREROUTING链和OUTPUT链上,因为优先级最高,从而可以对收到的数据包在连接跟踪前进行处理。一但用户使用了RAW表,在某个链上,RAW表处理完后,将跳过NAT表和 ip_conntrack处理,即不再做地址转换和数据包的链接跟踪处理了。
RAW表可以应用在那些不需要做nat的情况下,以提高性能。如大量访问的web服务器,可以让80端口不再让iptables做数据包的链接跟踪处理,以提高用户的访问速度。

其次我们应该熟悉iptables的工程流程:

最后我们再来看一下规则匹配流程:

路由发生的时刻:
    报文进入本机后:
        判断目标主机;
    报文发出之前:
        判断经由哪个接口送往下一跳;

iptables:四表五链
    添加规则时的考量点:
        (1) 要实现哪种功能:判断添加在哪张表上;
        (2) 报文流经的路径:判断添加在哪个链上;

    链:链上规则的次序,即为检查的次序;因此隐含一定的法则
        (1) 同类规则(访问同一应用),匹配范围小的放上面;
        (2) 不同类规则(访问不同应用),匹配到报文频率较大的放上面;
        (3) 将那些可由一条规则描述的多个规则合并为一个;
        (4) 设置默认策略;【如果用不到连接追踪功能应该关闭】

2、命令使用语法

   iptables命令:

   iptables [-t table] {-A|-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

   -t table:
        filter, nat, mangle, raw

    链管理:
        -F:flush,清空规则链;省略链,表示清空指定表上的所有的链;
        -N:new, 创建新的自定义规则链;
        -X:drop, 删除用户自定义的空的规则链;
        -Z:zero,清零,置零规则计数器;
        -P:Policy,为指定链设置默认策略;对filter表中的链而言,默认策略通常有ACCEPT, DROP, REJECT; 
        -E: rEname,重命名自定义链;引用计数不为0的自定义链,无法改名,也无法删除;
    规则管理:
        -A:append,将新规则追加于指定链的尾部;
        -I:insert,将新规则插入至指定链的指定位置; 【不指定rulenum插入为第一条】
        -D:delete,删除指定链上的指定规则;
            有两种指定方式:
                (1) 指定匹配条件;
                (2) 指定规则编号;
        -R:replace,替换指定链上的指定规则;
    查看:
        -L:list,列出指定链上的所有规则;
            -n: numberic,以数字格式显示地址和端口号;  【不进行反解,和route、netstat一样】
            -v: verbose,显示详细信息;  【包括计数器信息】
                -vv, -vvv
            --line-numbers:显示规则编号;
            -x: exactly, 显示计数器计数结果的精确值;

    匹配条件:
        基本匹配:
            [!] -s, --src, --source IP|Netaddr:检查报文中源IP地址是否符合此处指定的地址范围;
            [!] -d, --dst, --destination IP|Netaddr:检查报文中目标IP地址是否符合此处指定的地址范围;
            -p, --protocol {tcp|udp|icmp}:检查报文中的协议,即ip首部中的protocols所标识的协议;
            -i, --in-interface IFACE:数据报文的流入接口;仅能用于PREROUTING, INPUT及FORWARD链上;
            -o, --out-interface IFACE:数据报文的流出接口;仅能用于FORWARD, OUTPUT及POSTROUTING链上;

        扩展匹配:-m macth_name --spec_options
                例如:-m tcp --dport 22

            隐式扩展:对-p protocol指明的协议进行的扩展,可省略-m选项;
                -p tcp
                    --dport PORT[-PORT]:目标端口,可以是单个端口或连续多个端口;  【#注意:不连续的端口号不可以】如:[1024:65535]
                    --sport PORT[-PORT]
                    --tcp-flags LIST1 LIST2:检查LIST1所指明的所有标志位,且这其中,LIST2所表示出的所有标志位必须为1,而余下的必须为0;没有LIST1中指明的,不作检查;
                        SYN, ACK, FIN, RST, PSH, URG

                        --tcp-flags SYN,ACK,FIN,RST SYN
                    --syn: 
                               【--tcp-flags ALL ALL】 检查所有标志位每一个都为1
                               【--tcp-flags ALL NONE】检查所有标志位每一个都为0
                -p udp
                    --dport
                    --sport

                -p icmp
                    --icmp-type
                        可用数字表示其类型:
                            0:echo-reply
                            8: echo-request

            显式扩展: 必须使用-m选项指定使用的扩展;

管理规则
-A:附加一条规则,添加在链的尾部
-I CHAIN [num]: 插入一条规则,插入为对应CHAIN上的第num条;
-D CHAIN [num]: 删除指定链中的第num条规则;
-R CHAIN [num]: 替换指定的规则;

管理链:
-F [CHAIN]:flush,清空指定规则链,如果省略CHAIN,则可以实现删除对应表中的所有链
-P CHAIN: 设定指定链的默认策略;
-N:自定义一个新的空链
-X: 删除一个自定义的空链
-Z:置零指定链中所有规则的计数器;
-E: 重命名自定义的链;

查看类:
-L: 显示指定表中的规则;
-n: 以数字格式显示主机地址和端口号;
-v: 显示链及规则的详细信息
-vv:
-x: 显示计数器的精确值
--line-numbers: 显示规则号码

动作(target):
ACCEPT:放行
DROP:丢弃
REJECT:拒绝
DNAT:目标地址转换
SNAT:源地址转换
REDIRECT:端口重定向
MASQUERADE:地址伪装
LOG:日志
MARK:打标记

3、常用命令

    #!/bin/bash
#   默认filter链策略是ACCEPT======》可以将它们设置成DROP 【默认策略通常有ACCEPT, DROP, REJECT】
#   注意默认规则是DROP的时候,远程连接时千万不要执行 iptables -F 会瞬间掉线,因为chain的规则是立即生效!
#   注意【防掉线策略】iptables -L -n -v && sleep 10 && iptables -P INPUT ACCEPT;iptables -P OUTPUT ACCEPT;iptables -F 或者设置crontab 5分以后自动清空iptables规则sh test.sh && sleep 10 && iptables -P INPUT ACCEPT; iptables -P OUTPUT ACCEPT; iptables -F
#[iptables -P INPUT ACCEPT]
#[iptables -P OUTPUT ACCEPT]

    #iptables -F
    #service iptables save
    service iptables stop #清除所有规则,恢复默认策略ACCEPT
    iptables -A INPUT -i lo -j ACCEPT
    iptables -t filter -A INPUT -s 172.16.0.0/16 -d 172.16.100.22 -p tcp --dport 22 -j ACCEPT
    iptables -t filter -A OUTPUT -s 172.16.100.22 -d 172.16.0.0/16 -p tcp --sport 22 -j ACCEPT
    iptables -P INPUT DROP
    iptables -P OUTPUT DROP
    iptables -P FORWARD DROP
    service iptables save
    service iptables restart

放行本机的tftp服务:

    iptables -A INPUT -s 172.16.0.0/16 -d 172.16.100.7 -p udp --dport 69 -j ACCEPT
    iptables -A OUTPUT -s 172.16.100.7 -d 172.16.0.0/16 -p udp --sport 69 -j ACCEPT

放行本机dns服务:

    iptables -A INPUT -s 172.16.0.0/16 -d 172.16.100.7 -p udp --dport 53 -j ACCEPT
    iptables -A OUTPUT -s 172.16.100.7 -d 172.16.0.0/16 -p udp --sport 53 -j ACCEPT
    iptables -A OUTPUT -s 172.16.100.7 -p udp --dport 53 -j ACCEPT
    iptables -A INPUT -d 172.16.100.7 -p udp --sport 53 -j ACCEPT

放行ping其它主机

    iptables -A OUTPUT -s 172.16.100.7 -p icmp  --icmp-type 8 -j ACCEPT
    iptables -A INPUT -d 172.16.100.7 -p icmp --icmp-type 0 -j ACCEPT

放行其它主机ping

    iptables -A INPUT -d 172.31.33.200 -p icmp --icmp-type 8 -j ACCEPT
    iptables -A OUTPUT -s 172.31.33.200 -p icmp  --icmp-type 0 -j ACCEPT

放行来自于172.16.0.0/16网络的主机对本机ssh服务的请求

    iptables -t filter -A INPUT -s 172.16.0.0/16 -d 172.16.100.7 -p tcp --dport 22 -j ACCEPT
    iptables -t filter -A OUTPUT -s 172.16.100.7 -d 172.16.0.0/16 -p tcp --sport 22 -j ACCEPT

多端口匹配

    iptables -I INPUT -s 172.16.0.0/16 -d 172.16.100.9 -p tcp -m multiport --dports 22,80 -j ACCEPT
    iptables -I OUTPUT -d 172.16.0.0/16 -s 172.16.100.9 -p tcp -m multiport --sports 22,80 -j ACCEPT

ip地址范围匹配

    iptables -I INPUT -d 172.16.100.9 -p tcp -m multiport --dports 22:23,80 -m iprange --src-range 172.16.100.1-172.16.100.120 -j ACCEPT
    iptables -I OUTPUT -s 172.16.100.9 -p tcp -m multiport --sports 22:23,80 -m iprange --dst-range 172.16.100.1-172.16.100.120 -j ACCEPT

报文中字符串匹配

    iptables -I OUTPUT -m string --algo bm --string 'movie' -j REJECT

速率限制匹配

    iptables -A INPUT -d 172.16.100.9 -p icmp --icmp-type 8 -m limit --limit-burst 5 --limit 30/minute -j ACCEPT
    iptables -A OUTPUT -s 172.16.100.9 -p icmp --icmp-type 0 -j ACCEPT

启用连接追踪

    iptables -I INPUT -m state --state ESTABLISHED -j ACCEPT
    iptables -I INPUT 2 -d 172.16.100.9 -p tcp -m multiport --dports 22,80 -m state --state NEW -j ACCEPT
    iptables -I OUTPUT -m state --state ESTABLISHED -j ACCEPT

    最优条目
         iptables -I INPUT 2 -d 172.31.33.200 -p tcp -m multiport --dports 21,22,80 -m state --state NEW -j ACCEPT
         iptables -I OUTPUT -s 172.31.33.200 -m state --state ESTABLISHED -j ACCEPT

如何保存及重载规则:

    保存规则至指定文件:
        iptables-save > /PATH/TO/SOMEFILE

    从指定文件重载规则:
        iptables-restore < /PATH/FROM/SOMEFILE

    CentOS 6:
        service iptables save 
            iptables-save > /etc/sysconfig/iptables

        service iptables restart
            iptables-restore < /etc/sysconfig/iptables

    CentOS 7:
        引入了新的iptables前端管理服务工具:firewalld
            firewalld-cmd
            firewalld-config
                 【systemctl disable firewalld.service】禁止开机启动
                 【systemctl stop firewalld.service】停止服务

4、总结

iptables防火墙并不能阻止DDOS,建议在项目实施中采购硬件防火墙,置于整个系统之前,用于防DDOS和端口映射;如果对安全有特殊要求,可再加上应用层级的防火墙。在项目实施中建议关闭Linux服务器的iptables防火墙或FreeBSD的ipfw,目的为:①更好的提高后端服务器网络性能;②方便数据流在整个业务系统内部流通,安全方面工作由硬件防火墙来承担。目前主要将iptables用于内部作NAT防火墙,它的性能和方便管理性确实强悍,经迅雷测试可发现,公司内部的10M带宽能被利用得一丝无余;强烈推荐的是让iptables作NAT路由转发,事实证明效果很好。繁忙的服务器不要启用ip_conntrack【centos6是nf_conntrack】连接跟踪模块,否则会导致后续的用户请求被丢弃。如果是使用远程来调试iptables防火墙,最好是设置crontab作业是定时停止防火墙,以防自己被锁定,5分钟停止一次iptables即可,等整个脚本完全稳定后再关闭此crontab作业。如果是机房租赁的服务器,在没有配置前端硬件防火墙的情况下,Linux主机一定要开启iptables防火墙。