iptables:包过滤型的防火墙

Firewall:防火墙,隔离工具;工作于主机或网络边缘,对于进出本主机或本网络的报文根据事先定义的检查规则作匹配检测,对于能够被规则匹配到的报文做出相应处理的组件;

       主机防火墙

       网络防火墙

 

       软件防火墙(软件逻辑)

       硬件防火墙(硬件和软件逻辑)

ipfw(firewall framework)

ipchains(firewall framework)

 

iptables(netfilter)

       netfilter:kernel

       iptables:rules until

 

       hook function

              input

              output

              forward

              prerouting

              postrouting

链(内置):

       PREROUTING

       INPUT

       FORWARD

       OUTPUT

       POSTROUTING

功能:

       filter:过滤,防火墙;

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

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

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

功能<-> 链

       raw:PREROUTING, OUTPUT

       mangle:PREROUTING  ,  INPUT , FORWARD,OUTPUT ,POSTROUTING

       nat:PREROUTING, [INPUT], OUTPUT, POSTROUTING

       filter:INPUT  ,  FORWARD , OUTPUT

报文流向:

       流入本机:PREROUTING à INPUT

       由本机流出:OUTPUT à POSTROUTING

       转发:PREROUTING à FORWARD à POSTROUTING

路由功能发生时刻:

       报文进入本机后;

              判断目标主机是?

       报文离开主机前:

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

 

Iptables/netfileter

规则:

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

              匹配条件:

                     基本匹配条件

                     扩展匹配条件

              处理动作:

                     基本处理动作

                     扩展处理动作

                     自定义处理机制

       iptables的链:内置链和自定义链

              内置链:对应于hook function

              自定义链接:用于内置链的扩展和补充,可实现更灵活的规则管理机制;

添加规则时的考量点:

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

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

 

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

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

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

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

4)      设置默认策略;

 

iptables命令:

       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,自定义一条新的规则链;

                                   Linux自学笔记——iptables_第1张图片

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

                                   Linux自学笔记——iptables_第2张图片

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

                                   ACCEPT:接受;

                                   DROP:丢弃

                                   REJECT:拒绝

                                   Linux自学笔记——iptables_第3张图片

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

                     规则管理:

                            为了掩饰方便我们设默认策略为DROP;

                                   Linux自学笔记——iptables_第4张图片

                            -A:append,追加;

                                   Linux自学笔记——iptables_第5张图片

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

                                   Linux自学笔记——iptables_第6张图片

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

                                   Linux自学笔记——iptables_第7张图片

                            -D:delete,删除:

                                   1) 指明规则序号;

                                   2) 指明规则本身;

                                   Linux自学笔记——iptables_第8张图片

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

                                   Linux自学笔记——iptables_第9张图片

                            -Z:zero,置零;

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

                                    1)      匹配到的报文的个数;

                                    2)      匹配到的所有报文大小之和;

查看:

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

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

             Linux自学笔记——iptables_第10张图片

             -v:verbose,详细信息;

                    -vv,-vvv

             Linux自学笔记——iptables_第11张图片

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

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

              chain

                     PREROUTING , INPUT , FORWARD , OUTPUT , POSTROUTING

              匹配条件:

                     基本匹配条件:无需加载任何模块,由iptables/netfilter

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

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

                            [!] –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链;

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

                     扩展匹配条件:需要加载扩展模块,方可生效;

隐式扩展:不需要手动加载扩展模块;因为他们是对协议的扩展,所以,但凡使用-p指明了协议,就表示已经指明了要扩展的模块;

tcp

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

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

        [!] --tcp-flages  mask  comp

mask is the flags which we should examine,  written as a comma-separated list,例如 SYN,ACK,FIN,RST

               comp is a comma-separated list  of  flags  which must be set,例如SYN

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

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

                                   udp

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

                                   icmp

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

                                                 echo-request:8

                                                 echo-reply:0

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

              处理动作:

                     -j  targetname  [per-target-options]

                            ACCEPT

                            DROP

                            REJECT

                            RETURN:返回调用链;

                            REDIRECT:端口重定向;

                            LOG:记录日志;

                            MARK:做防火墙标记;

                            DNAT:目标地址转换;

                            SNAT:源地址转换;

                            MASQUERADE:地址伪装;

                            …

                            自定义链;

       防火墙(服务):

              Centos6:

                     service  iptables  {start|stop|restart|status}

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

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

                            status:显示生效的规则;

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

                           

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

                            Linux自学笔记——iptables_第12张图片

              Centos7:

                     systemctl  start|stop|restart|status  firewalld.service

                    

                     systemctl disable  firewalld.service       设置iptables开机不自启;

                     systemctl  stop   firewalld.service

 

iptables(2)

显示扩展:必须显示地指明使用的扩展模块进行的扩展;

       使用帮助:

              Centos6:man iptables

              Centos7:man iptables-extensions

1.      multiport扩展;

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

[!] --source-ports,--sports port[,port|,port:port]…:指定多个源端口;

[!] --destination-ports,--dports port[,port|,port:port]…多个目标端口;

[!] --ports port[,port|,port:port]…多个端口;

Linux自学笔记——iptables_第13张图片

2.      iprange扩展

指明连续的(但一般不包整个网络)ip地址范围;

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

[!] --dst-range from[-to]:目标ip地址;

14.png

3.      string扩展

对报文中的应用层数据做字符串模式匹配检测;

--algo {bm|kmp}:字符串匹配检测算法;

bm:Boyer-Moore

kmp:Knuth-Pratt-Morris

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

[!] --hex-string pattern:腰间的字符串模式,16进制格式;

15.png

4.      time扩展

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

--datastart  YYYY[-MM[--DD[Thh[:mm[:ss]]]]]

--datestop YYYY[-MM[-DD[Thh[:mm[:ss]]]]]

 

--timestart hh:mm[:ss]

--timestop hh:mm[:ss]

 

[!] --monthdays day[,day...]

[!] --weekdays day[,day...]

 

--kerneltz:使用内核上的时区,而非默认的UTC;

Linux自学笔记——iptables_第14张图片

5.      connlimit扩展;

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

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

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

17.png

6.      limit扩展;

基于收发报文的速率做匹配;

令牌通过过滤器;

--limit rate[/second|/minute|/hour|/day]

--limit-burst number

Linux自学笔记——iptables_第15张图片

7.      state扩展

根据“连接追踪机制”去检查连接的状态;

Conntrack机制:追踪本机上的请求和响应之间的关系;状态有如下几种;

NEW:新发出的请求;连接追踪模板中不存在此链接的相关信息条目,因此,将其识别为第一次发出的请求;

ESTABLISHED:NEW状态之后,连接追踪模板中为其建立的条目失效之前期间内所进行的通信状态;

RELATED:相关联的连接;如ftp协议中的数据连接与命令连接之间的关系;

INVALID:无效的连接;

UNTRACKED:未进行追踪的连接;

[!] --state   state

Linux自学笔记——iptables_第16张图片

调整连接追踪功能所能够容纳的最大连接数量;

/proc/sys/net/nf_contrack_max

20.png

已经追踪到的并记录下的连接;

/proc/net/nf_conntrack

21.png

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

/proc/sys/net/netfilter/

Linux自学笔记——iptables_第17张图片

Note:iptables的连接跟踪表最大容量为/proc/sys/net/ipv4/ip_conntrack_max,链接碰到各种状态的超时后就会从表中删除;当模板满载时,后续的连接可能会超时;

 

解决方法一般有两个:

1)      加大nf_conntrack_max的值

vim /etc/sysctl.conf

net.ipv4.nf_conntrack_max = 393216

net.ipv4.netfilter.nf_conntrack_max = 393216

2)      降低nf_conntrack timeout时间;

vim /etc/sysctl.conf

net.ipv4.netfilter.nf_conntrack_tcp_timeout_established = 300

net.ipv4.netfilter.nf_conntrack_tcp_timeout_time_wait = 120

net.ipv4.netfilter.nf_conntrack_tcp_timeout_close_wait = 60

net.ipv4.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120

 

问题:如何开放被动模式的ftp服务?(server地址为192.168.19.130)

1)      装载ftp连接追踪的专用模块;

~]# modproble  nf_conntrack_ftp

2)      放行命令连接

~]# iptables -A INPUT -d 192.168.19.130 -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT

~]# iptables -A OUTPUT -s 192.168.19.130 -p tcp --sport 21 -m state --state ESTABLISHED -j ACCEPT

3)      放行数据连接;

~]# iptables -A INPUT -d 192.168.19.130 -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT

~]# iptables -I OUTPUT -s 192.168.19.130 -m state --state ESTABLISHED -j ACCEPT

规则优化:

       服务器端规则设定:任何不允许的访问,应该在请求到达时给予拒绝;

1)      可安全放行所有入栈的状态为ESTABLISHED的状态的连接;

2)      可安全放行所有出站状态为ESTABLISHED状态的连接;

3)      谨慎放行入栈的心情求;

4)      有特殊目的限制访问功能,要于放行规则之前加以拒绝;

如何使用自定义链:

       自定义链:需要被调用才能生效;自定义链最后需要定义返回规则;

       返回规则使用的target叫做RETURN

规则的有效期限:

       使用iptables命令定义的规则,手动删除之前,其生效期限为kernel存活期限;

保存规则:

       保存规则至指定的文件中:

              Centos6

                     service  iptables  save:将规则保存至/etc/sysconfig/iptables文件中;

                     iptables-save  >  /path/ro/some_rules_file:将规则保存指定的文件中;

              centos7

                     iptables-save  >  /path/to/some_rules_file

       重新载入预存规则文件中的规则:

              iptables-restore   <  /path/from/some_rules_file

 

              Centos6

                     Service  iptables  restart

自动生效规则文件中的规则;

1)      用脚本保存各iptables命令:让此脚本开机后自动运行;

/etc/rc.d/rc.local文件添加脚本路径;

/path/to/some_script_file

2)      用规则文件保存各规则,开机时自动载入此规则文件中的规则;

/etc/rc.d/rc.local文件添加;

Iptables-restore  <  /path/from/iptables_rules_file

 

CentOS 7

       引入了新的iptables前端管理工具firewalld,其管理工个有:firewalld-cmd,  firewalld-config

 

网络防火墙:

       netfilter在INPUT和OUTPUT链上表现其作为主机防火墙的角色,而其在FORWARD链上则表现是作为网络防火墙的角色;

  下面通过实例演示网络防火墙:

       centos7主机有两块网卡,并且这两块网卡的地址位于不同的网络中,地址分别为192.168.19.130和172.16.23.1;centos6test作为服务器,地址为172.16.23.2;centos6作为客户端,地址为192.168.19.134;

Linux自学笔记——iptables_第18张图片

要求:通过centos7主机扮演网络防火墙,在FORWARD链上生成过滤规则,规则要求如下;

1)      放行客户端对服务器端的ftp服务的访问;

2)      放行客户端对服务器端的远程连接ssh服务;

3)      放行客户端对服务器端的web服务的访问;

4)      放行客户端对服务器端的ping操作;

Centos7主机上;

1.      开启转发功能;

24.png

2.      设置ip地址为如下地址;

Linux自学笔记——iptables_第19张图片

3.      清空规则链,新建规则;

Linux自学笔记——iptables_第20张图片

 

Centos6test主机上:

1.      设置其ip地址为如下地址;

Linux自学笔记——iptables_第21张图片

2.      设置路由指向centos7主机;

Linux自学笔记——iptables_第22张图片

 

Centos6主机上:

1.      设置ip地址为如下;

Linux自学笔记——iptables_第23张图片

2.      删除原有的路由,设置新的路由指向centos7主机;

Linux自学笔记——iptables_第24张图片

 

iptables(3)之nat

netfilter:nat table

       nat:network  address  translation

              snat:source  nat

              dnat:destination  nat

              pnat:port nat

       snat:POSTROUTING , OUTPUT

              让本地网络中的主机用过某一特定地地址访问外部网络时,

       dnat:PREROUTING

              把本地网络中的某一主机上的某服务开放给外部网络中的用户访问时,

       nat表的target

              SNAT

                     --to-source  [ipaddr [-ipaddr]][:port[-port]]

              DNAT

                     --to-destination [ipaddr[-ipaddr]][:port[-port]]

              MASQUERADE

                     --to-ports port[-port]

                     --random

       SNAT示例:

1.      在上面的网络防火墙示例中,用centos6主机访问centos6test主机的web服务并做ping操作;

Linux自学笔记——iptables_第25张图片

2.      在centos6test主机上使用tcpdump命令抓包,并且查看httpd的访问日志,可以发现地址都是192.168.19.134;

Linux自学笔记——iptables_第26张图片

3.      在网络防火墙centos7主机上添加net规则;

33.png

4.      再一次重复第1步,第2步操作,测试,发现抓包的地址和日志文件中地址都变成了192.168.115.32;

Linux自学笔记——iptables_第27张图片

       DNAT示例:

1.      添加规则;

35.png

2.      在centos6主机上再次访问centos6test的web服务,发现访问的是centos7主机的web,这里的目的地址发现了转换;

Linux自学笔记——iptables_第28张图片

3.      当然也可以在转换目的地址的同时转换端口;

37.png

 

       MASQUERADE示例:地址伪装

1.      添加规则;

38.png

2.      在centos6主机上对centos6test作ping操作;

Linux自学笔记——iptables_第29张图片

3.      在centos6test主机抓包测试;

Linux自学笔记——iptables_第30张图片

REDIRECT:端口重定向;

       Web:8080

       80 —> 8080

1.      将centos6test主机的httpd服务监听端口改为8080;

Linux自学笔记——iptables_第31张图片

2.      在centos6test主机上添加规则;

42.png

3.      此时通过centos6主机访问centos6test主机的httpd服务;

Linux自学笔记——iptables_第32张图片

Note:必须要加端口访问,访问80端口,自动重定向为8080端口;

 

补充:利用iptables的recent模块来抵御DOS***: 22,建立一个列表,保存有所有访问过指定的服务的客户端IP

       以ssh( 远程连接)为例:

1.      利用connlimit模块将单IP的并发设置为3;会误杀使用NAT上网的用户,可以根据实际情况增大该值;

iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 3 -j DROP

 

2.      利用recent和state模块限制单IP在300s内只能与本机建立2个新连接。被限制五分钟后即可恢复访问。

iptables -I INPUT  -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH

iptables -I INPUT  -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j LOG --log-prefix "SSH Attach: "

iptables -I INPUT  -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j DROP

       下面对最后两句做一个说明:

1.第二句是记录访问tcp 22端口的新连接,记录名称为SSH

                     --set 记录数据包的来源IP,如果IP已经存在将更新已经存在的条目

2.第三句是指SSH记录中的IP,300s内发起超过3次连接则拒绝此IP的连接。

                     --update 是指每次建立连接都更新列表;

                     --seconds必须与--rcheck或者--update同时使用

                     --hitcount必须与--rcheck或者--update同时使用

              3.iptables的记录:/proc/net/xt_recent/SSH

       也可以使用下面的这句记录日志:

iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --name SSH --second 300 --hitcount 3 -j LOG --log-prefix "SSH Attack"