一、iptables简介


iptables 的前身叫ipfirewall (内核1.x时代),这是一个从freeBSD上移植过来的,能够工作在内核当中的,对数据包进行检测的一款简易访问控制工具。但是 ipfirewall工作功能极其有限(它需要将所有的规则都放进内核当中,这样规则才能够运行起来,而放进内核,这个做法一般是极其困难的)。当内核发 展到2.x系列的时候,软件更名为ipchains,它可以定义多条规则,将他们串起来,共同发挥作用,而现在,它叫做iptables,可以将规则组成一个列表,实现绝对详细的访问控制功能。

iptables和netfilter的关系是一个很容易让人搞不清的问题。很多的知道iptables却不知道 netfilter。其实iptables只是Linux防火墙的管理工具而已,位于/sbin/iptables。真正实现防火墙功能的是 netfilter,它是Linux内核中实现包过滤的内部结构。



二、iptables基础


规则(rules)其实就是网络管理员预定义的条件,规则一般的定义为“如果数据包头符合这样的条件,就这样处理这个数据包”。规则存储在内核空间的信息 包过滤表中,这些规则分别指定了源地址、目的地址、传输协议(如TCP、UDP、ICMP)和服务类型(如HTTP、FTP和SMTP)等。当数据包与规 则匹配时,iptables就根据规则所定义的方法来处理这些数据包,如放行(accept)、拒绝(reject)和丢弃(drop)等。配置防火墙的 主要工作就是添加、修改和删除这些规则。



三、iptables传输数据包的过程


① 当一个数据包进入网卡时,它首先进入PREROUTING链,内核根据数据包目的IP判断是否需要转送出去。 
② 如果数据包就是进入本机的,它就会沿着图向下移动,到达INPUT链。数据包到了INPUT链后,任何进程都会收到它。本机上运行的程序可以发送数据包,这些数据包会经过OUTPUT链,然后到达POSTROUTING链输出。 
③ 如果数据包是要转发出去的,且内核允许转发,数据包就会如图所示向右移动,经过FORWARD链,然后到达POSTROUTING链输出。

wKioL1cht9TxIUWkAAFDRpSsZJI919.png



四、iptables的规则和链


上图中的五个位置也被称为五个钩子函数(hook functions),也叫五个规则链。

1.PREROUTING (路由前)

2.INPUT (数据包流入口)

3.FORWARD (转发管卡)

4.OUTPUT(数据包出口)

5.POSTROUTING(路由后)

 这是netfilter规定的五个规则链,任何一个数据包,只要经过本机,必将经过这五个链中的其中一个链。

iptables包含4个表,5个链。其中表是按照对数据包的操作区分的,链是按照不同的Hook点来区分的,表和链实际上是netfilter的两个维度。      

(1)4表:

   filter,nat,mangle,raw,默认表是filter(没有指定表的时候就是filter表)

    filter:一般的过滤功能

    nat:用于nat功能(端口映射,地址映射等)

    mangle:用于对特定数据包的修改

    raw:有限级最高,设置raw时一般是为了不再让iptables做数据包的链接跟踪处理,提高性能

(2)5链:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING。

    PREROUTING:数据包进入路由表之前

    INPUT:通过路由表后目的地为本机

    FORWARDING:通过路由表后,目的地不为本机

    OUTPUT:由本机产生,向外转发

    POSTROUTING:发送到网卡接口之前。


(3)规则表:
1.filter表——三个链:INPUT、FORWARD、OUTPUT
作用:过滤数据包  内核模块:iptables_filter.
2.Nat表——三个链:PREROUTING、POSTROUTING、OUTPUT
作用:用于网络地址转换(IP、端口) 内核模块:iptable_nat
3.Mangle表——五个链:PREROUTING、POSTROUTING、INPUT、OUTPUT、FORWARD
作用:修改数据包的服务类型、TTL、并且可以配置路由实现QOS内核模块:iptable_mangle(别看这个表这么麻烦,咱们设置策略时几乎都不会用到它)
4.Raw表——两个链:OUTPUT、PREROUTING
作用:决定数据包是否被状态跟踪机制处理  内核模块:iptable_raw


(4)规则链:
1.INPUT——进来的数据包应用此规则链中的策略
2.OUTPUT——外出的数据包应用此规则链中的策略
3.FORWARD——转发数据包时应用此规则链中的策略
4.PREROUTING——对数据包作路由选择前应用此链中的规则
(记住!所有的数据包进来的时侯都先由这个链处理)
5.POSTROUTING——对数据包作路由选择后应用此链中的规则
(所有的数据包出来的时侯都先由这个链处理)

wKioL1chub7SfmmGAAI092k6rK8143.jpg(5)规则表之间的优先顺序:

raw——mangle——nat——filter



五、iptables的命令管理



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

如图示

   wKiom1chufPynWrRAAGdfGiCmc0986.jpg

   wKioL1chu2GD8Y_yAAJuOfLjfic539.jpg

详细介绍:


(1)链管理
    -N: new,新增一条自定义链;
    -X:delete,删除自定义的空链;
    -P:policy,设置链的默认策略;
         ACCEPT:接受
         DROP:丢弃
         REJECT:拒绝
    -E:rename,重命名自定义的未被引用(引用计数为0)的链;


(2)规则管理
    -A:append,追加,默认为最后一个;
    -I:insert,插入,默认为第一个;
    -D:delete,删除
        (1) rule specification
        (2) rule number 
    -R:replace,替换
    -F:flush,清除规则
    -Z:zero,置0;
        iptables的每条规则都有两个计数器:
             (1) 由本规则匹配到的所有的packets;
             (2) 由本规则匹配到的所有的bytes;
    -S:selected,以iptables-save命令的格式显示链上的规则;


例:虚拟机ip地址为192.168.1.108,已安装httpd服务,编写一条规则让所有主机不可访问

1
[root@bogon ~]# iptables -t filter -A INPUT -d 192.168.1.108 -p tcp --dport 80 -j REJECT

此时再通过浏览器就不能访问apache测试页面了

再编写一条规则,让192.168.1.X网段内的主机可以访问

1
2
3
4
5
6
7
8
9
10
11
12
[root@bogon ~]# iptables -t filter -D INPUT 1 #先删除之前的规则
[root@bogon ~]# iptables -t filter -I INPUT -s 192.168.1.0/24 -d 192.168.1.108 -j ACCEPT #添加规则
[root@bogon ~]# iptables -nvL --line-number #查看
Chain INPUT (policy ACCEPT 3 packets, 840 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1       72  5308 ACCEPT     all  --  *      *       192.168.1.0/24       192.168.1.108       
 
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
 
Chain OUTPUT (policy ACCEPT 51 packets, 5708 bytes)
num   pkts bytes target     prot opt in     out     source               destination

修改本规则,让本网段内的不能访问apache测试页面

1
[root@bogon ~]# iptables -t filter -R INPUT 1 -s 192.168.1.0/24 -d 192.168.1.108 -j REJECT

(3)查看
    -L: list,列出规则
    -n:numeric,以数字格式显示地址和端口;
    -v:verbose,详细信息;-vv, -vvv
    -x:exactly,显示计数器的精确值而非单位换算后的结果;
    --line-numbers:显示链上的规则的编号;            
    组合:-nvL

1
2
3
4
5
6
7
8
9
[root@bogon ~]# iptables -nvL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
 
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
 
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

    
匹配条件
(4)基本匹配:netfilter自带的匹配机制
    [!] -s, --source address[/mask][,...]:原地址匹配
    [!] -d, --destination address[/mask][,...]:目标地址匹配
    [!] -i, --in-interface name:限制报文流入的接口,只能用于PREROUTING,INPUT及FORWARD;
    [!] -o, --out-interface name:限制报文流出的接口,只能用于OUTPUT,FORWARD及POSTROUTING;

(5)扩展匹配:经由扩展模块引入的匹配机制,-m matchname
    隐式扩展:可以不用使用-m选项专门加载响应模块;前提是要使用-p选项可匹配何种协议;

        tcp、udp、icmp

    显式扩展:必须由-m选项专门加载响应模块;
        multiport
        iprange
        string
        time
        connlimit
        limit
        state


(5.1)隐式扩展
    [!]  -p, --protocol PROTOCOL PROTOCOL:
    协议:tcp, udp, icmp, icmpv6, esp, ah, sctp, mh or "all"
                    
    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
        --tcp-flags  syn,fin,ack,rst  ack,fin 
    [!] --syn:
        --syn相当于“--tcp-flags  syn,fin,ack,rst  syn”;tcp三次握手的第一次                       
    udp:隐含指明了“-m 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   别人可以ping自己
            8/0:echo request 自己可以ping别人    

例:将虚拟机192.168.1.108设置为,自己可以ping别人,而别人不能ping自己

对于ping这个协议,进来的为8(ping),出去的为0(响应).我们为了达到目的,需要8出去,允许0进来

1
2
[root@bogon ~]# iptables -t filter -A INPUT -d 192.168.1.108 -p icmp --icmp-type 8 -j DROP #设置别人ping自己的数据包不能通过
[root@bogon ~]# iptables -t filter -A OUTPUT -s 192.168.1.108 -p icmp --icmp-type 0 -j ACCEPT #设置自己ping别人的数据包可以通过

               

       
(5.2)显式扩展          
5.2.1 multiport:多端口匹配
    以离散方式定义多端口匹配,最多可以指定15个端口;           
    [!] --source-ports,--sports port[,port|,port:port]...
    [!] --destination-ports,--dports port[,port|,port:port]...
    [!] --ports port[,port|,port:port]...

1
2
 [root@bogon ~]# iptables -I INPUT -s 0/0 -d 192.168.1.108 -p tcp  -m multiport --dports 22,80 -j ACCEPT #允许所有主机访问192.168.1.108的22和80端口
 [root@bogon ~]# iptables -I OUTPUT -d 0/0 -s 192.168.1.108 -p tcp  -m multiport --sports 22,80 -j ACCEPT #允许192.168.1.108的主机可以通过22和80端口发送数据包

5.2.2 iprange:指明一段连续的ip地址范围做为源地址或目标地址匹配;
    [!] --src-range from[-to]:源地址范围 
    [!] --dst-range from[-to]:目标地址范围

1
 [root@bogon ~]# iptables -A INPUT -p tcp -m iprange --src-range 192.168.0.100-192.168.0.105 --dport 22 -j ACCEPT #匹配一组ip地址192.168.0.100-192.168.0.105

                
5.2.3 string:对报文中的应用层数据做字符串匹配检测;
        --algo {bm|kmp}:指明算法
            (bm = Boyer-Moore, kmp = Knuth-Pratt-Morris)
    [!] --string pattern:给定要检查的字符串模式;
    [!] --hex-string pattern:给定要检查的字符串模式;
                

1
[root@bogon ~]# iptables -I OUTPUT -s 192.168.1.108 -d 0/0 -p tcp --sport 80 -m string --algo bm --string "old" -j REJECT #有"old"字符串的拒绝访问