前言
防火墙工作与主机或者网络边缘,对于进出本主机或本网络的报文根据事先的检查规则做匹配检查,对于能够匹配上的数据包做出相应处理动作。
在防火墙的工作范围可以分为“主机防火墙”和“网络防火墙”主机防火墙主要作用于在进入或流出本机的报文;网络防火墙通常设置在网关位置,对进出或流出本网络的数据包进行检验,现在很多的硬件防火墙,大部分都用作网络防火墙,用于保护本地整个网络,而网络防火墙也由硬件和软件之分,不差钱的看中效率的很多都会去选择硬件防火墙,但其实软件和硬件防火墙的作用和原理都是差不多的。
在链路层、网络层、传输层和应用层都可以使用防火墙进行判断是否处理。
在链路层,防火墙可以对MAC地址进行控制;在网络层,可以对源IP,目的IP,ICMP进行控制;在传输层,可以对源端口,目的端口,甚至TCP报文中的flags位的控制;在应用层中,可以对报文拆开检查后控制。
iptable和netfilter的关系
iptable工作在用户空间中,就iptable自身而言,它的工作就是定义规则,可以让内核空间当中的netfilter读取这些规则,并且实现让防火墙工作。
简单来讲,iptable工作在用户空间,用于编写规则,netfilter工作在内核,根据规则匹配数据包。
netfilter
netfilter简介
介绍netfilter之前应该先看看协议栈(TCP/IP协议栈)底层大致机制
![][1]
如图,数据从流入之后,经过A点,然后根据路由决策判断数据是否需要进入用户空间,如果是留入用户空间,会经过B点,如果仅仅是经由本机转发的则经过C点然后到达E点,最后流出;对于用户空间产生的数据包,先经由路由判决,决定从那个网卡出去,经过D点,然后到达E点,最后流出。
netfilter其实就是对这数据报必经的5个点, 做了5个钩子函数,分别是prerouting、input、output、forword、postrouting只要数据包到达某个点后,就去调用我们的钩子函数,我们在钩子函数中设定了各种表,表中有链,链中有规则。如果有数据包被表中的链内的规则命中,则执行相应动作。
netfilter的结构
netfilter作为内核模块运行在内存中,它自己维护这一块内存区域,这块区域中,保存着4张表
netfilter的4表5链
前面说了netfilter在数据包的必经之路上设置了5个钩子函数,对应着5条链,分别是PREROUTING、INPUT、OUTPUT、FORWORD、POSTROUTING
并且根据不同功能为其配备了4个表,分别是raw、mangle、nat、filter,这些表有先后顺序,顺序为:rwa-->mangle-->nat-->filter。举例说明,在PREROUTING链上,有3张表,分别是raw、mangle和nat,那么先由raw处理,然后再由mangle表处理。
三个用于防火的链:INPUT/OUTPUT/FORWORD
根据报文流向,报文分为三种情况
1.流入本机的报文
PREROUTING-->INPUT
2.由本机流出的报文
OUTPUT-->POSTROUTING
3.由本机转发的报文
PREROUTING-->FORWORD-->POSTROUTING
五表的作用
nat表:顾名思义network address translation,根据设定改变数据包地址,属于一个流的包只会经过第一个包被允许做NAT,那么余下的包都会自动地被做相同的操作,也就是说余下的包不会通过这个表,一个个地被NAT,而是自动完成。
mangle
raw
filter:内建三个链,INPUT、OUTPUT、FORWORD,其中FORWORD所过滤的不是本机接受或产生的,而是经过本机转发的数据包。
iptables
- 组成部分:根据规则匹配条件来尝试匹配报文,一旦匹配成功,就由规则定义的处理动作作出处理
- 匹配条件:有内建的匹配条件和需要模块的扩展匹配条件
- 处理动作:有内建的处理动作,如ACCEPT、DROP或需要模块的处理动作,如REJECT,还可以使用自定义链来处理。
iptable的链
iptables内置了5个链,对应着5个钩子函数,还可以自定义链用于内置链的扩展和补充,可实现更灵活的规则管理机制
iptable命令:
语法:iptables [-t table] COMMAND chain [-m match] -j target
-t是指明要操作那个表,操作由COMMAND指定,如增加、删除或修改、查看,作用与那个表中那个链上,如果是增加规则,则需要指明匹配条件,与匹配命中之后的动作
----------------------
#COMMAND: #有三类,对链管理的命令、对规则管理的命令和查看
#链管理命令
-N:new, 自定义一条新的规则链;
-X: delete,删除自定义的规则链;
注意:仅能删除 用户自定义的 引用计数为0的、空的链;
-P:Policy,设置默认策略;对filter表中的链而言,其默认策略有:
ACCEPT:接受
DROP:丢弃
REJECT:拒绝
-E:重命名自定义链;引用计数不为0的自定义链不能够被重命名,也不能被删除;
#规则管理命令
-A: append,追加,在链中追加一条规则;
-I:insert,插入,后面跟上序号,为空为插入第一条;
-D:delete,删除,可以用以下两种方法删除;
(1) 指明规则序号;
(2) 指明规则本身;
-R:replace,替换指定的规则;
-F:flush,清空指定规则链,为空则清空表中所有链
-Z:zero,置零;iptables的每条规则有2个计数器
(1) 匹配到的报文的个数;
(2) 匹配到的所有报文的大小之和;
----------------------
#match匹配条件
#如果是基本匹配条件,无需加载任何模块,有iptables/netfilter提供。
[!] -s, --source address[/mask][,...]:检查报文中的源IP地址是否符合此处指定的地址或范围;
[!] -d, --destination address[/mask][,...]:检查报文中的目标IP地址是否符合此处指定的地址或范围;
注意:如果要匹配所有IP,则可以使用0.0.0.0
[!] -p, --protocol protocol #protocol可以是tcp, udp, udplite, icmp, icmpv6,esp, ah, sctp, 或者使用all表示全部,也可以使用协议代码,协议代码和协议对应关系在/etc/protocols中可以查看
[!] -i, --in-interface name:数据报文流入的接口(网卡接口);只能应用于数据报文流入的环节,只能应用于PREROUTING,INPUT和FORWARD链;
[!] -o, --out-interface name:数据报文流出的接口;只能应用于数据报文流出的环节,只能应用于FORWARD、OUTPUT和POSTROUTING链;
iptables的匹配条件
iptables支持两种扩展匹配:隐式扩展和显示扩展,隐式扩展在使用-p选项指明了特定的协议时,无需再同时使用-m选项指明;显示扩展需要用-m来指定;扩展可以包含多个子选项。
#隐式扩展选项
-p tcp的子选项:
[!] --source-port, --sport port[:port]:匹配报文的源端口;可以是端口范围;
[!] --destination-port,--dport port[:port]:匹配报文的目标端口;可以是端口范围;
[!] --tcp-flags mask comp
匹配指定的flags,mask是需要检查的flags,comp是必须为1的flags,没在comp指定上的flags则必须为0
例如:“-p tcp --tcp-flags SYN,ACK,FIN,RST SYN”表示,要检查的标志位为SYN,ACK,FIN,RST四个,其中SYN必须为1,余下的必须为0;
[!] --syn:用于匹配第一次握手,相当于`--tcp-flags SYN,ACK,FIN,RST SYN`;
----------------
-p udp的子选项
udp
[!] --source-port, --sport port[:port]:匹配报文的源端口;可以是端口范围;
[!] --destination-port,--dport port[:port]:匹配报文的目标端口;可以是端口范围;
-----------------
-p icmp的子选项
[!] --icmp-type {type[/code]|typename}
echo-request:8 #icmp的请求类型代码
echo-reply:0 #icmp的回复类型代码
显式扩展必须使用-m选项指明要调用的扩展模块的扩展机制
1.multiport 以离散或连续的 方式定义多端口匹配条件,最多15个,注意:如45:800,虽然开放了45至800之间的所有端口,但Multiport只算2个
[!] --source-ports,--sports port[,port|,port:port]...:指定多个源端口;
[!] --destination-ports,--dports port[,port|,port:port]...:指定多个目标端口;
例如:
# iptables -I INPUT -d 172.16.0.7 -p tcp -m multiport --dports 22,80,139,445,3306 -j ACCEPT
//允许访问目标为172.16.0.7的tcp,22,80,139,445,3306。5个端口
-------------------
2.iprange 以连续地址块的方式来指定多个IP
[!] --src-range from[-to]
[!] --dst-range from[-to]
例如:
# iptables -I INPUT -d 172.16.0.7 -p tcp -m multiport --dports 22,80,139,445,3306 -m iprange --src-range 172.16.0.61-172.16.0.70 -j REJECT
//拒绝地址范围172.16.0.61-172.16.0.70的主机去访问目标172.16.0.7,tcp的22,80,139,445,3306端口
---------------------------
3.time 匹配指定时间范围
--timestart hh:mm[:ss] #开始时间
--timestop hh:mm[:ss] #结束时间
[!] --weekdays day[,day...] #也可以以周做单位来匹配
[!] --monthdays day[,day...]
--datestart YYYY[-MM[-DD[Thh[:mm[:ss]]]]] #以日期做单位
--datestop YYYY[-MM[-DD[Thh[:mm[:ss]]]]]
--kerneltz:使用内核配置的时区而非默认的UTC
------------------------
4.string 通过某中模式来匹配字符串,需要内核大于或等于2.6.14
--algo {bm|kmp} #指定匹配模式策略
[!] --string pattern
[!] --hex-string pattern
--from offset
--to offset
另外此模块对于加密传输的信息没办法匹配,所以只能用于明文匹配
例子:
~]# iptables -I OUTPUT -m string --algo bm --string "gay" -j REJECT
//在OUTPUT链上加入规则,拒绝string中包含有gay字符串的数据包。使用bm模式策略来匹配
-------------------
5.connlimit 匹配单个IP最大连接数
--connlimit-upto n
--connlimit-above n
例如:
~]# iptables -I INPUT -d 172.16.0.7 -p tcp --syn --dport 22 -m connlimit --connlimit-above 2 -j REJECT
//限制172.16.0.7的tcp 22单IP访问数,connlimit-above即超过2个就拒绝
6.limit 使用令牌桶来限制速率
--limit rate[/second|/minute|/hour|/day] #允许的平均数量,如1分钟我只允许10个包,则10/minute
--limit-burst number #令牌桶存储的令牌数量
例如
允许每分钟10次ping,但第一次可以ping 20次。20次之后按照RATE计算。所以,前20个ping包每秒能正常返回,从第21个ping包开始,每6秒允许一次ping:
#iptables -A INPUT -d ServerIP -p icmp --icmp-type 8 -m limit --limit 10/minute --limit-burst 20 -j ACCEPT
限制本机某tcp服务接收新请求的速率:--syn, -m limit
7.state “state”扩展是“conntrack”模块的一个子集,通过数据包的连接追踪状态来设置防火墙。
[!] --state state #有以下几种状态
INVALID, ESTABLISHED, NEW, RELATED or UNTRACKED.
NEW: 新连接请求;
ESTABLISHED:已建立的连接;
INVALID:无法识别的连接;
RELATED:相关联的连接,当前连接是一个新请求,但附属于某个已存在的连接;
UNTRACKED:未追踪的连接;
对于匹配条件,在匹配条件前面的[!]意思是取反。
iptables的处理动作
iptables的处理动作是指如果数据包被规则命中之后,做出什么样的动作,比如说,ACCEPT、DROP等,以下是比较常见的规则。
DNAT:目标地址转换
SNAT:源地址转换
REDIRECT:端口重定向
MASQUERADE:地址伪装(其实也是源地址转换),适用于动态源地址 RETURN:用于自定义链,自定义链中匹配完毕后返回到自定义的前一个链中继续向下匹配