Linux因为其强大的防火墙功能而闻名,它主要依靠于iptables,一个运行在用户空间的应用软件,它可以通过控制Linux内核netfilter模块,来管理网络数据包的流动与转送。它解决了网络中很多***,比如网络中常见的端口扫描、用户密码暴力破解等。

一、防火墙模型

  主机通信基本模型:报文进入主机后进入接受缓冲区缓冲,内核从中取报文处理,拆开数据帧检测是否是目标地址时本机地址,如果是则再拆TCP或UDP报文找到对应目的端口,发送给注册在内核的用户端进程;如果目标地址不是本机地址那么就查看是否转发,能转发的情况下检查路由,从那个端口发出去,再次封装IP数据包,封装数据帧,转化为物理层信号发到对应网卡;另外还有流出的数据包,从应用层程序封装应用层报文到内核,内核通过路由转发到对应端口。

  netfilter模块中在数量包流经各个关键处添加钩子(hook),对数据包进行控制。netfilter主要内置了五个hook:

    1.input 

    2.output 

    3.forward 

    4.prerouting

    5.postrouting

三种报文流向:

    流入本机:PREROUTING --> INPUT==>用户空间进程

    由本机流出:用户空间进程==>OUTPUT --> POSTROUTING

    转发:PREROUTING --> FORWARD --> POSTROUTING

iptables(netfilter):四张表、五链


功能:对应四张表(tables),其中主要功能基础是filter完成的防火墙功能

  filter:过滤,防火墙功能;

  nat:network address translation;用于修改源IP或目标IP,也可以改源端口或目的端口;

  mangle:拆解报文,做出修改,并重新封装起来;

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


iptables 链:iptables中的称呼

    链(内置):

   PREROUTING

   INPUT

   FORWARD

    OUTPUT

    POSTROUTING

    自定义链:手动添加关联关系,用于内置链的扩展和补充,可实现更灵活的规则管理机制;

功能和链对应实现(表<-->链):

    raw:PREROUTING, OUTPUT

    mangle:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING

    nat:PREROUTING,INPUT,]OUTPUT,POSTROUTING

    filter:INPUT,FORWARD,OUTPUT

    各个功能是有优先级的,逐类生效,如OUTPUT可定义5个功能:按次序实现;功能中规则有次序,同一个链上的不同表规则的应用优先级(由高到低)

路由功能发生的时刻:

报文进入本机后:

判断目标主机是不是本机?

      是:INPUT    

      否:FORWARD

报文离开本机之前:

判断经由哪个接口送往下一站?

    iptables服务就是:将iptables定义的脚本开机执行。规则写入后立即在内核生效。

二、iptables/netfilter 规则

规则:

  组成部分:匹配条件和处理动作---根据规则匹配条件来尝试匹配报文,一旦匹配成功,就由规则定义的处理动作作出处理,不再匹配;

   匹配条件:match,多个条件默认逻辑为--与

     基本匹配条件

     扩展匹配条件:由于netfilter是模块化的

   处理动作:target,

     基本处理动作

     扩展处理动作

     自定义处理机制

链上的规则次序,即为检查的次序;因此,隐含一定的应用法则:

    (1) 同类规则(访问同一应用),匹配范围小的放上面;

    (2) 不同类的规则(访问不同应用),匹配到报文频率较大的放在上面;

    (3) 将那些可由一条规则描述的多个规则合并起来;

    (4) 设置默认策略;

        相互包含的以最先匹配为准

添加规则时的考量点:

    (1) 要实现哪种功能:判断添加到哪个表上;

    (2) 报文流经的路径:判断添加到哪个链上;


三、iptables命令: 

iptables — administration tool for IPv4 packet filtering and NAT

  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...]  [target]

  match = -m matchname [per-match-options]

  target = -j targetname [per-target-options


主要格式:iptables   [-t table]   COMMAND   chain   [-m matchname [per-match-options]]   -j targetname [per-target-options]

-t table:

    raw, mangle, nat, [filter]

COMMAND:

链管理:

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

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

  -P:Policy,设置默认策略;对filter表中的链而言,其默认策略有:

    ACCEPT:接受

    DROP:丢弃 不会返回结果

    REJECT:拒绝 会返回结果

  -E:重命名自定义,未被引用的链;引用计数不为0的自定义链不能够被重命名,也不能被删除;

iptables -N testchain 
iptables -nL
iptables -E testchain mychain
iptables -nLiptables -X mychain
iptables -nL
iptables -L
iptables -L |grep policy

规则管理:

  -A:append,追加;

  -I:insert, 插入,要指明位置,省略时表示第一条;

  -D:delete,删除;

    (1) 指明规则序号;

    (2) 指明规则本身;

  -R:replace,替换指定链上的指定规则;

  -F:flush,清空指定的规则链;

  -Z:zero,计数器置零;

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

    (1) 匹配到的报文的packages;

    (2) 匹配到的所有报文的Bytes;

# iptables -nL INPUT
Chain INPUT (policy ACCEPT)target     prot opt source               destination

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

    所有命令的命令格式,可以用来保存规则保存到某个文件,以备恢复.

查看:


  -L:list, 列出指定鏈上的所有规则;

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

  -v:verbose,详细信息;

  -vv, -vvv

  -x:exactly,显示计数器结果的精确值; 

  --line-numbers:显示规则的序号;

   组合: -nvL ,组合情况下只能将L放在最右侧,-nL -nvL

chain:

  PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING

匹配条件:

基本匹配条件

  无需加载任何模块,由iptables/netfilter自行提供;

    [!] -s, --source  address[/mask][,...]:检查报文中的源IP地址是否符合此处指定的地址或范围;

    [!] -d, --destination address[/mask][,...]:检查报文中的目标IP地址是否符合此处指定的地址或范围;

    [!] -p, --protocol protocol,限制协议

protocol: tcp, udp, udplite, icmp, icmpv6,esp, ah, sctp, mh or  "all"

{tcp|udp|icmp}

    [!] -i, --in-interface name:数据报文流入的接口;只能应用于数据报文流入的环节,只能应用于PREROUTING,INPUT和FORWARD链;

    [!] -o, --out-interface name:数据报文流出的接口;只能应用于数据报文流出的环节,只能应用于FORWARD、OUTPUT和POSTROUTING链。


扩展匹配条件

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

隐式扩展

   可以不用-m选项加载专门加载扩展模块;因为它们是对协议的扩展,所以,但凡使用-p指明了协议,就表示已经指明了要扩展的模块;

    [!] -p, --protocol protocol

        协议:tcp, udp, udplite, icmp, esp, ah, sctp or all 

    tcp:隐含指明了 “-m tcp”,有专门选项:

    [!] --source-port, --sport port[:port]:匹配tcp报文的源端口;可以是端口范围(起始,结尾);

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

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

mask is the flags which we should examine,  written as a comma-separated list,

例如:“--tcp-flags  SYN,ACK,FIN,RST  SYN”表示,要检查的标志位为SYN,ACK,FIN,RST四个,其中SYN必须为1,余下的必须为0;

    “--tcp-flags  SYN,ACK,FIN,RST  ACK,FIN”表示,要检查的标志位为SYN,ACK,FIN,RST四个,其中ACK,FIN必须为1,余下的必须为0;

        “--tcp-flags  SYN,ACK,FIN,RST ALL NONE” 表示,要检查的标志位为SYN,ACK,FIN,RST四个,必须全部为0;

    “--tcp-flags  SYN,ACK,FIN,RSTSYN,ACK,FIN,RST ALL” 表示,要检查的标志位为SYN,ACK,FIN,RST四个,必须全部为1;

  [!] --syn:用于匹配第一次握手,相当于“--tcp-flags  SYN,ACK,FIN,RST  SYN”;

    udp 隐含指明了 “-m tcp”,有专门选项:

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

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

    icmp 

  [!] --icmp-type {type[/code]|typename} :使用时可以只指定type就可以了。type0,8也仅仅只有一个code

  echo-request:8/0 ping请求

  echo-reply:0/0 对方应答


说明:DNS服务器,为客户端提供服务:开放自己53号端口;为客户端递归,开放对端端口53;    

     ping别人是icmp8出去,0回来

     别人ping自己是icmp8进来,0出去


显式扩展

    必须要手动加载扩展模块, [-m matchname [per-match-options]]; 

处理动作:


  -j targetname [per-target-options]

    ACCEPT

    DROP

    REJECT

    RETURN:返回调用链;

     REDIRECT:端口重定向;

    LOG:记录日志;

    MARK:做防火墙标记;

    DNAT:目标地址转换;

    SNAT:源地址转换;

    MASQUERADE:地址伪装;

    ...

    自定义链:

四、防火墙服务

CentOS 6:

  service  iptables  {start|stop|restart|status}

  start:读取事先保存的规则,并应用到netfilter上;

  stop:清空netfilter上的规则,以及还原默认策略等;

  status:显示生效的规则;

  restart:清空netfilter上的规则,再读取事先保存的规则,并应用到netfilter上;

  默认的规则文件:/etc/sysconfig/iptables

CentOS 7:

  systemctl  start|stop|restart|status  firewalld.service

  systemctl  disable  firewalld.service

  systemctl  stop  firewalld.service

五、简单实例

  开放DNS服务的防火墙,要求能够正常提供DNS服务,但其他任何端口都不开放。

首先,修改默认策略,将INUT、OUTPUT默认策略修改为DROP,丢弃所有报文;

iptables -P INPUT DROP
iptables -P OUTPUT DROP

其次,主机开放DNS服务

iptables -A INPUT -d 172.18.100.67 -s 0/0 -p tcp --dport 53 -j ACCEPT
iptables -A OUTPUT -s 172.18.100.67 -d 0/0 -p tcp --sport 53 -j ACCEPT

再次,考虑到DNS服务器可能为主机递归查询DNS,所以也要开放DNS服务器作为DNS客户端访问根DNS服务器的端口;

iptables -A INPUT -s 0/0 -d 172.18.100.67 -p tcp --sport 53 -j ACCEPT
iptables -A OUTPUT -s 172.18.100.67 -p tcp --dport 53 -j ACCEPT

默认可能还需要开启sshd服务,可以添加

iptables -A INPUT -d 172.18.100.67 -s 0/0 -p tcp --dport 22 -j ACCEPT
iptables -A OUTPUT -s 172.18.100.67 -d 0/0 -p tcp --sport 22 -j ACCEPT

   篇幅关系,这里仅仅介绍基础的主机防火墙设置,下篇博文介绍主机防火墙高级扩展应用。