Iptables 详解

Iptables的历史

历史版

Linux内核各版本集成的防火墙历史版本:

2.0.X内核:ipfwadm

2.2.X内核:ipchains

2.4.X内核:iptables

iptables的工作原理

iptables由用户空间的命令行程序和位于内核中的tcp/ip协议栈的报文处理框架两部分组成。工作在用户空间中,定义规则,让在内核空间当中的netfilter来读取,并且实现让防火墙工作。而放入内核的地方必须是tcp/ip的协议栈经过的地方。而这个tcp/ip协议栈必须经过的地方,可以实现读取规则的地方就叫做 netfilter.(网络过滤器)

内核空间中的五个位置:

  • 内核空间中:从一个网络接口进来,到另一个网络接口去的

  • 数据包从内核流入用户空间的

  • 数据包从用户空间流出的

  • 进入/离开本机的外网接口

  • 进入/离开本机的内网接口

        

iptables的工作机制

iptables有五个子函数(hook function)也叫做规则链

  • PREROUTING(路由前)

  • INPUT(数据包流入口)

  • FORWARD(转发管卡)

  • OUTPUT(数据包出口)

  • POSTROUTING(路由后)

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

 

iptables的策略

iptables的四个表的功能

  • filter定义过滤(允许或不允许)

  • nat 定义地址转换的(修改报文的源地址或目标地址) 

  • mangle功能:修改报文原数据 (拆解报文,做出修改,并重新封装超来)

  • raw 关闭nat表上启用的连接追踪机制


它们所关联的规则链

 

 

iptables规则

iptables规则介绍

iptables规则是根据指定的匹配条件来尝试匹配每个流经此处的报文,一旦匹配成功,就由规则后面指明的处理动作进行处理。

 

匹配条件

       基本匹配条件

              简单检查IPTCPUDP等报文的某属性进行匹配的机制

       扩展匹配条件

              需要借助于扩展模块进行的匹配条件指明即为扩展匹配

处理动作

       基本动作

              ACCEPT  DORP  REJECT …

       扩展动作

              需要借助扩展模块进行的动作

添加规则时需要考量的问题

(1)  报文的流经路径,判断添加规则至哪个链上

(2)  确定要实现的功能,判断添加规则至哪个表上

(3)  要指定的匹配条件,以用于匹配目标报文

iptables使用的命令格式

man iptables

 

      iptables [-t table] {-A|-C|-D} chain rule-specification
 
      ip6tables [-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...] [target]
 
      match = -m matchname [per-match-options]
 
target = -jtargetname [per-target-options]
 
       table
              默认为filter表,其它可用的有nat,mangle, raw

      

              -P    policy 策略,定义默认策略,一般有两种选择,ACCEPTDROP

              -N   new 新建一条自定义的规则链,被内建链上的规则调用才能生效

              -Xdrop 删除自定义的引用计数为0的空链

              -Fflush  清空指定的链

              -E重命名自定义的引用计数和0的链

       规则

              -A:append 追加,在指定链的尾部追加一条规则

              -I:insert  插入,在指定的位置(省略位置时表示链首)插入一条规则

              -D:delete删除,删除指定的规则

-R: replace 替换,将指定的规则替换为新规则,不能仅修改规则中的部分,而是整条规则全部替换

       查看

-L: list 列出表中的链上的规则

-n: number 以数值格式显示

-v: verbose 显示详细格式信息,支持-vv–vvv

-x: exactly 计数器的精确结果

--line-numbers 显示链中的规则编号

       计数器

              -Zzero  重置规则计数器

iptables匹配规则

基本匹配条件

[!] -s, --source address[/mask][,...]  检查报文中的源IP地址是否符合此处指定的地址或范围
[!] -d, --destination address[/mask][,...] 检查报文中的目标IP地址是否符合此处指定的地址或范围
 
[!] -p, --protocol protocol: protocol {tcp|udp|icmp}
[!] -i, --in-interface name 数据报文的流入接口; INPUT, FORWARD and PREROUTING
[!] -o, --out-interface name 数据报文的流出接口; FORWARD, OUTPUT and POSTROUTING


扩展匹配条件

隐式扩展

不用-m选项指出matchname即可使用此match的专用选项进行匹配;

-p tcp 隐含了-m tcp
[!] --source-port, --sport port[:port] 匹配报文中传输层的源端口
[!] --destination-port, --dport port[:port] 匹配报文中传输层的目标端口
[!] --tcp-flags mask comp SYN, ACK, FIN, RST, URG, PSH
        --tcp-flagsSYN,ACK,FIN,RST SYN 检查第一次握手,SYN=1
--tcp-flags SYN,ACK,FIN,RST SYN,ACK 检查第二次握手,SYN=1,ACK=1
mask 要检查的标志位列表,以逗号分隔
comp 必须为1的标志位,余下的出现在mask列表中的标志位则必须为0
[!] –syn 相当于检查第一次握手,SYN=1 --tcp-flags SYN,ACK,FIN,RST SYN
-p udp 隐含了-m udp
    [!] --source-port --sport port[:port] 匹配报文中传输层的源端口
    [!] --destincation-port --dport port[:port] 匹配报文中传输层的目的端口
-p icmp
    [!] --icmp-type {type[/code]|typename}
        8: echo-request
        0: echo-reply


显式扩展

必须使用-m选项指出matchname; 有的match可能存在专用的选项

  • multiport扩展

    以离散或连续的方式定义多端口匹配条件

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


    举例:

    iptables -A INPUT -d 172.16.100.67 -p tcp -m multiport --dports22:23,80 -j ACCEPT
    iptables -A OUTPUT -s 172.16.100.67 -p tcp -m multiport --sports22:23,80 -j ACCEPT
    iptables -A INPUT -d 172.16.100.67 -j DROP
    iptables -A OUTPUT -s 172.16.100.67 -j DROP


  • iprange扩展

    以连续的IP地址范围指明连续的多地址匹配条件;

    [!] --src-range from[-to]
    [!] --dst-range from[-to]


举例:

  

  iptables -I INPUT 2 -d 172.16.100.67 -p tcp --dport 3306 -miprange --src-range 172.16.100.61-172.16.100.70 -j ACCEPT
    iptables -I OUTPUT 2 -s 172.16.100.67 -p tcp --sport 3306 -miprange --dst-range 172.16.100.61-172.16.100.70 -j ACCEPT

 

  • string扩展

    对报文中的应用层数据做字符串检测

    [!] --string pattern
        要检测字符串模式
    [!] --hex-string pattern
        要检测的字符串模式,  16进程编码
     --algo {bm|kmp}
        字符串匹配算法
    iptables -I OUTPUT -s 172.16.100.67 ! -p tcp --sport 80 -miprange ! --dst-range 172.16.100.61-172.16.100.70 -m string --string"admin" --algo kmp -j REJECT


  • time扩展

    根据报文到达的时间与指定的时间范围进行匹配检测

     

--datestartYYYY[-MM[-DD[Thh[:mm[:ss]]]]]
        起始日期时间
    --datestop YYYY[-MM[-DD[Thh[:mm[:ss]]]]]
        结束日期时间
    --timestart hh:mm[:ss]
        起始时间
    --timestop hh:mm[:ss]
        结束时间
     [!] --monthdays day[,day...]
     [!] --weekdaysday[,day...]


        iptables -I

        只允许周二、周四、周六的工作时间访问telnet服务(因为前面有一个大的范围是放开的,现在要取反)应该先定义时间  然后再日期

      

  (1) iptables -I INPUT -d 172.16.100.67 -p tcp --dport 23 -mtime --timestop 18:00:00 --timestop 08:59:59 -j REJECT
  (2) iptables -I INPUT -d 172.16.100.67 -p tcp --dport 23 -mtime ! --weekdays Tue,Thu,Sat -j REJECT
  iptables -I INPUT -d 172.16.100.67 -p tcp --dport 23 -m time--timestart 09:00:00 --timestop 18:00:00 --weekdays Tue,Thu,Sat -j ACCEPT


  • connlimit扩展



    根据每客户端IP做并发连接数匹配

   

--connlimit-upto n
        连接数数量小于等于n,此时应该允许
    --connlimit-above n
        连接数数量大于等于n,此时应该拒绝


    需要先添加22端口放行 只允许23号端口放行2个连接

     

   iptables -A INPUT -d 172.16.100.67 -p tcp --dport 22 -j ACCEPT
   iptables -A INPUT  -d 172.16.100.67 -p tcp --dport 23 -m --connlimit-upto 2 -j ACCEPT


  • limit扩展

    基于收发报文的速率进行匹配

 

    --limitrate[/second|/minute|/hour|/day]
        平均速率
    --limit-burst number
        峰值速率
iptables -I INPUT -d 172.16.100.67 -p icmp --icmp-type 8-m limit --limit-burst 5 --limit 20/minute -j ACCEPT


        第一次5个最大的,然后后面3秒一个

    OUTPUT默认为开放

    使用hping工具测试

  • state扩展

    状态检测,连接追踪机制(conntrack)

     INVALID

        无法识别的状态

    ESTABLISHED

        已建立的连接

    NEW

        新连接

    RELATED

        相关联的连接

    UNTRACKED

        未追踪的连接

    modinfo nf_conntrack 追踪模块

    modprobe nf_conntrack

        装载追踪模块

    lsmod

        显示所有装载的模块

    cat /proc/net/nf_conntrack

    nf_conntrack内核模块

        追踪到的连接/proc/net/nf_conntrack文件中

        能追踪的最大连接数量定义在/proc/sys/net/nf_conntrack_max

             此值可自行定义,建议必要时调整到足够大

        不同协议的连接追踪的时长

             ls /proc/sys/net/netfilter/

    [!] --state STATE

    示例

      

  iptables -A INPUT -d 172.16.100.67 -m state --stateESTABLISHED -j ACCEPT
  iptables -A OUTPUT -s 172.16.100.67 -m state --stateESTABLISHED -j ACCEPT
  iptables -A INPUT -d 172.16.100.67 -p tcp -m multiport--dports 22,23,80,3306 -m stat --state NEW -j ACCEPT
  iptables -A INPUT -d 172.16.100.67 -j DROP
  iptables -A OUTPUT -s 172.16.100.67 -j DROP
  iptables -I INPUT 3 -d 172.16.100.67 -p icmp --icmp-type 8 -mstate --state NEW -j ACCEPT


        因为出去的ESTABLISHED已经放行

        放行被动模块的ftp

             modprobe nf_conntrack_ftp  装载ftp追踪模块

       

 iptables -R INPUT 1 -d 172.16.100.67 -m state --state ESTABLISHED,RELATED -j ACCEPT


如何开放被动模式的ftp服务

   

(1) 装载追踪ftp协议的模块
        modprobe nf_conntrack_ftp
(2) 放行命令连接
        iptables -A INPUT -d 172.16.100.67 -p tcp -m state --stateESTABLISHED -j ACCEPT
        iptables -A INPUT -d 172.16.100.67 -p tcp --dport 21 -m state--state NEW -j ACCEPT
(3) 放行数据连接
        iptables -A INPUT -d 172.16.100.67 -p tcp -m state --stateESTABLISHED,RELATED -j ACCEPT


规则的保存

    CentOS 7

        iptables-save > /path/to/some_rule_file

        iptables-restore </path/from/some_rule_file

    CentOS 6

        保存规则

             service iptables save

             自动保存规则至/etc/sysconfig/iptables文件中

        重载规则

             service iptables restore

             /etc/sysconfig/iptables文件中重载规则

规则优化

    (1) 可安全放行所有入站及出站,且状态为ESTABLISHED的连接

    (2) 服务于同一类功能的规则,匹配条件严格的放前面,宽松的放后面

    (3) 服务于不同类功能的规则,匹配报文可能性较大的放前面,较小放后面

    (4) 设置默认策略

        (a) 最后一条规则设定

        (b) 默认策略设定

 

 

 

练习:INPUTOUTPUT默认策略为DROP

    iptables准备工作(默认策略修改为DROP,开放ssh策略)

iptables –X 清空所有自定义空链
iptables –t nat –F
iptables –t raw –F
iptables –t filter–F
iptables –t mangle-F
iptables -IINPUT -p tcp --dport 22 -j ACCEPT  //开放22端的INPUT链
iptables -I OUTPUT -p tcp --sport 22 -j ACCEPT//开放22端口的OUTPUT链
iptables-P INPUT DROP  //修改INPUT链的默认规则为DROP
iptables-P OUTPUT DROP //修改OUTPUT链的默认规则为DROP
  1. 1.  限制本机主机的web服务器在周一不允许访问;新请求的速率不能超过100个每秒;web服务器包含了admin字符串的页面不允许访问;web服务器仅允许响应报文离开本机

iptables -I INPUT -d 192.168.99.54 -p tcp--dport 80 -m state --state ESTABLISHED -j ACCEPT
iptables -I INPUT -d 192.168.99.54 -p tcp --dport 80 -mstate --state NEW -m limit --limit 100/second -m time ! --weekdays Mon -jACCEPT
iptables -A OUTPUT -s 192.168.99.54 -p tcp --sport 80 -mstate --state ESTABLISHED -m string ! --string "admin" --algo kmp -jACCEPT


  1. 2.  在工作时间,即周一至周五的8:30-18:00,开放本机的ftp服务给192.168.0.0网络中的主机访问,数据下载请求的次数每分钟不得超过5

[root@centos7 ~]# lsmod | grepnf_conntrack_ftp
[root@centos7 ~]# modprobe nf_conntrack_ftp
[root@centos7 ~]# lsmod | grep nf_conntrack_ftp
nf_conntrack_ftp       18638 0 
nf_conntrack          105745  8nf_nat,nf_nat_ipv4,nf_nat_ipv6,xt_conntrack,nf_nat_masquerade_ipv4,nf_conntrack_ftp,nf_conntrack_ipv4,nf_conntrack_ipv6
iptables -I INPUT 4 -d 192.168.99.54 -s192.168.99.0/24 -p tcp --dport 21 -m state --state NEW,ESTABLISHED -m time --weekdaysMon,Tus,Wed,Thu,Fri --timestart 08:30:00 --timestop 18:00:00 -j ACCEPT
iptables -A INPUT -d 192.168.99.54 -s192.168.99.0/24 -p tcp -m state --state RELATED -m limit --limit 5/min -jACCEPT
iptables-A INPUT -d 192.168.99.54 -s 192.168.99.0/24 -p tcp -m state --stateESTABLISHED -j ACCEPT
iptables -A OUTPUT -d 192.168.99.54 -s192.168.99.0/24 -p tcp -m state --state ESTABLISHED -j ACCEPT


  1. 3.  开放本机的ssh服务给192.168.99.1-192.168.99.100中的主机,新请求建立的速率一分钟不得超过2个,仅允许响应报文通过其服务端口离开本机

iptables -A INPUT -p tcp -m iprange --src-range192.168.99.1-192.168.99.100 -m limit --limit 2/min --dport 22 -j ACCEPT
iptables -A OUTPUT -p tcp -m iprange --dst-range192.168.99.1-192.168.99.100 -m state ! --state NEW --sport 22 -j ACCEPT


然后删除开始准备的ssh规则

iptables –-line-numbers -L
iptables –D INPUT [num]
iptables –D OUTPUT [num]


  1. 4.  拒绝TCP标志位全为1及全部为0的报文访问本机

iptables -A INPUT -d 192.168.99.54 -p tcp --tcp-flags ALLALL -j DROP
iptables -A OUTPUT -s 192.168.99.54 -p tcp --tcp-flagsALL NONE -j DROP


  1. 5.  允许本机ping别的主机,但不开放别的主机ping本机

iptables -A INPUT -p icmp --icmp-type 0 -d192.168.99.54 -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type 8 -s192.168.99.54 -j ACCEPT


显示iptables 规则

[root@centos7 ~]# iptables -vnL --line-numbers
Chain INPUT (policy DROP 280 packets, 53114 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1       33  1992 ACCEPT     tcp  --  *      *       0.0.0.0/0            192.168.99.54        tcp dpt:80 state NEW limit: avg 100/sec burst 5 TIME on Tue,Wed,Thu,Fri,Sat,Sun UTC
2      226 22265 ACCEPT     tcp  --  *      *       0.0.0.0/0            192.168.99.54        tcp dpt:80 state ESTABLISHED
3        0     0 ACCEPT     tcp  --  *      *       192.168.99.0/24      192.168.99.54        tcp dpt:21 state NEW,ESTABLISHED TIME from 08:30:00 to 18:00:00 on Mon,Tue,Wed,Thu,Fri UTC
4        0     0 ACCEPT     tcp  --  *      *       192.168.99.0/24      192.168.99.54        state RELATED limit: avg 5/min burst 5
5     1630  165K ACCEPT     tcp  --  *      *       192.168.99.0/24      192.168.99.54        state ESTABLISHED
6        2   120 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            source IP range 192.168.99.1-192.168.99.100 limit: avg 2/min burst 5 tcp dpt:22
7        3   252 ACCEPT     icmp --  *      *       0.0.0.0/0            192.168.99.54        icmptype 0
8        0     0 DROP       tcp  --  *      *       0.0.0.0/0            192.168.99.54        tcp flags:0x3F/0x3F

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy DROP 30 packets, 2152 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1      100  5907 ACCEPT     tcp  --  *      *       192.168.99.54        0.0.0.0/0            tcp spt:80 state ESTABLISHED STRING match ! "admin" ALGO name kmp TO 65535
2      825  142K ACCEPT     tcp  --  *      *       192.168.99.54        192.168.99.0/24      state ESTABLISHED
3        0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            destination IP range 192.168.99.1-192.168.99.100 ! state NEW tcp spt:22
4        3   252 ACCEPT     icmp --  *      *       192.168.99.54        0.0.0.0/0            icmptype 8
5        0     0 DROP       tcp  --  *      *       192.168.99.54        0.0.0.0/0            tcp flags:0x3F/0x00