防火墙(一):防火墙基础知识了解

1.什么是防火墙,为什么需要防火墙?

对于没有防火墙存在的一条网络路线中,主机A发送给主机B的任何一个数据包,主机B都会照单全收,即使是包含了病毒、木马等的数据也一样会收。虽说害人之心不可有,但是在网络上,你认为是害你的行为在对方眼中是利他的行为。所以防人之心定要有,防火墙就可以提供一定的保障。
在这里插入图片描述
有了简单的防火墙之后,在数据传输的过程中就会接受"入关"检查,能通过的数据包才继续传输,不能通过的数据包则拒绝或者直接丢弃。
在这里插入图片描述
从上面的图中可以看出,防火墙至少需要两个网卡,其中一块控制流入数据包,另一块网卡控制流出数据包。即使是软件防火墙,要实现完整的防火墙功能,也需要至少两块网卡。
所谓防火墙就是"防火的墙",如果过来的是"火"就得挡住,如果过来的不是"火"就放行,但什么是"火",这由人们自行定制。
但无论如何,所谓的"火"都是基于OSI七层模型的,简单的划分为四层:最高的应用层(如HTTP/FTP/SMTP),往下一层是传输层(TCP/UDP),再往下一层是网络层,最后是链路层。可以基于整个7层模型的每一层来定制防火墙,但是默认防火墙(没有编译内核源码定制七层防火墙)一般认为工作在以上的4层中。

2.数据流传输过程

2.1网络数据传输过程

网络数据传输的基本流程。
在这里插入图片描述
数据从上层进入到传输层,加上源端口和目标端口成为数据段(如果是UDP则成为数据报),再进入网络层加上源IP和目标IP成为数据包,再进入链路层加上源MAC地址和目标MAC地址成为数据帧,这段过程是一种"加头"封装数据的过程。数据经过网络传输到达目标主机后,逐层"剃头"解包,最终得到data纯数据内容。

2.2本机数据路由决策

其实,进程间数据传输的方式有多种:共享内存、命名管道、套接字、消息队列、信号量等。上面描述的OSI通信模型只是数据传输的一种方式,它特指网络数据传输,是基于套接字(ip+port)的,所以既可以是主机间进程通信,也可以是本机服务端和客户端进程间的通信。
无论如何,网络数据总是会流入、流出的,即使是本机的客户端和服务端进程间通信,也需要从一个套接字流出、另一个套接字流入,只不过这些数据无需路由、无需经过物理网卡(走的是LoopBack)。(?有疑问)
当接收外界发送的数据时,在数据从网卡流入后需要对它做路由决策,根据其目标决定是流入本机数据还是转发给其他主机,如果是流入本机的数据,则数据会从内核空间进入用户空间(被应用程序接收、处理)。当用户空间响应(应用程序生成新的数据包)时,响应数据包是本机产生的新数据,在响应包流出之前,需要做路由决策,根据目标决定从哪个网卡流出。如果不是流入本机的,而是要转发给其他主机的,则必然涉及到另一个流出网卡,此时数据包必须从流入网卡完整地转发给流出网卡,这要求Linux主机能够完成这样的转发。但Linux主机默认未开启ip_forward功能,这使得数据包无法转发而被丢弃。Linux主机和路由器不同,路由器本身就是为了转发数据包,所以路由器内部默认就能在不同网卡间转发数据包,而Linux主机默认则不能转发。
如下图解释上面的过程:
在这里插入图片描述
注意:本文是为了介绍防火墙的,充当防火墙的主机需要至少两块网卡,所以有必要解释下数据流入和流出时,Linux主机是如何处理的。
首先要说明的是,IP地址是属于内核的(不仅如此,整个tcp/ip协议栈都属于内核,包括端口号),只要能和其中一个地址通信,就能和另一个地址通信(这么说不严谨,准确地说是能路由这两个地址),而不管是否开启了数据包转发功能。例如某Linux主机有两网卡eth0:172.16.10.5和eth1:192.168.100.20,某192.168.100.22主机网关指向192.168.100.20,它能ping通192.168.100.20,但也一样能ping通172.16.10.5,因为地址属于内核,从eth1进来的数据包被内核分析时,发现目标地址为本机地址,直接就产生新数据包回应192.168.100.22,根据路由决策,该响应包应从eth1出去,于是192.168.100.22能收到回复完成整个ping过程。在此过程中,没有进行数据包转发过程,因为流出的响应包是新产生的,而非原来流入的数据包。
如果流入和流出的包是一样的(或者稍作修改),则数据流入后不能进入用户空间,而是直接通过内核转发给另一个网卡。数据包从网卡1交给网卡2,这个过程就是转发。在Linux主机上由ip_forward进行控制。例如,网卡1所在网段主机ping网卡2所在主机时,数据包流入网卡1后就需要转交给网卡2,然后从网卡2流出。
关于网卡配置及转发:https://www.cnblogs.com/f-ck-need-u/p/7397146.html#auto_id_0

3.TCP三次握手、四次挥手及syn攻击

3.1三次握手建立TCP连接

每次TCP会话的建立都需要经过三次握手,断开时都需要四次挥手。
在这里插入图片描述
(1).客户端和服务端都处于CLOSED状态。(发起TCP请求的称为客户端,接受请求的称为服务端)
(2).服务端打开服务端口,处于listen状态。
(3).客户端发起连接请求。首先发送SYN(synchronous)报文给服务端,等待服务端给出ACK报文回应。发送的SYN=1,ACK=0,表示只发送了SYN信号。此时客户端处于SYN-SENT状态(SYN信号已发送)。
(4).服务端收到SYN信号后,发出ACK报文回应,并同时发出自己的SYN信号请求连接。此时服务端处于SYN-RECV状态(syn recieved,在图中显示的是SYN-RCVD)。发送的SYN=1 ACK=1,表示发送了SYN+ACK。
(5).客户端收到服务端的确认信号ACK后,再次发送ACK信号给服务端以回复服务端发送的syn。此时客户端进入ESTABLISHED状态,发送的SYN=0,ACK=1表示只发送了ACK。
(6).服务端收到ACK信号后,也进入ESTABLISHED状态。
此后进行数据的传输都通过此连接进行。其中第3、4、5步是三次握手的过程。这个过程通俗地说就是双方请求并回应的过程:①A发送syn请求B并等待B回应;②B回应A,并同时请求A;③A回应B。

3.2四次挥手断开TCP连接

断开之前,双方都处于ESTABLISHED状态。假设是客户端请求断开连接。
在这里插入图片描述
(1).客户端发送FIN(finally)报文信号,请求断开。此后客户端进入FIN-WAIT-1状态。
(2).服务端收到FIN信号,给出确认信号ACK,表示同意断开。此时服务端进入CLOSE-WAIT状态。此过程结束后表示从客户端到服务端方向的TCP连接已经关闭了,也就是说整个TCP连接处于半关闭状态。
(3).客户端收到服务端的ACK后进入FIN-WAIT-2状态,以等待服务端发出断开信号FIN。在客户端的FIN-WAIT-2状态的等待过程中,服务端再发出自己的FIN信号给客户端。此时服务端进入LAST-ACK状态。
(4).客户端收到服务端的FIN信号,给出回应信号ACK,表示接受服务端的断开请求,此时客户端进入TIME-WAIT状态,此时客户端已脱离整个TCP,只需再等待一段时间(2*MSL)就自动进入CLOSED状态。
(5).服务端收到客户端的回应ACK信号,知道客户端同意了服务端到客户端方向的TCP断开,直接进入CLOSED状态。
以上的1、2、3、4步是四次挥手阶段。从中可以看出,四次挥手和三次握手的过程其实是类似的,都是双方发出断开请求并回应对方,只不过四次挥手的过程是将服务端发送的ACK和FIN分开发送了,而三次握手的过程中服务端发送的ACK和SYN是放在一个数据包内发送的。
以上所述是客户端请求的断开,服务端也可以请求断开,这时过程是完全一致的,只不过角色互换了。还需注意的是,如果是客户端请求断开,那么服务端就是被动断开端,可能会保留大量的CLOSE-WAIT状态的连接,如果是服务端主动请求断开,则可能会保留大量的TIME_WAIT状态的连接。由于每个连接都需要占用一个文件描述符,高并发情况下可能会耗尽这些资源。因此,需要找出对应问题,做出对应的防治,一般来说,可以修改内核配置文件/etc/sysctl.conf来解决一部分问题。

3.3syn flood攻击

syn洪水攻击是一种常见的DDos攻击手段。攻击者可以通过工具在极短时间内伪造大量随机不存在的ip向服务器指定端口发送tcp连接请求,也就是发送了大量syn=1 ack=0的数据包,当服务器收到了该数据包后会回复并同样发送syn请求tcp连接,也就是发送ack=1 syn=1的数据包,此后服务器进入SYN-RECV状态,正常情况下,服务器期待收到客户端的ACK回复。但问题是服务器回复的目标ip是不存在的,所以回复的数据包总被丢弃,也一直无法收到ACK回复,于是不断重发ack=1 syn=1的回复包直至超时。
在服务器被syn flood攻击时,由于不断收到大量伪造的syn=1 ack=0请求包,它们将长时间占用资源队列,使得正常的SYN请求无法得到正确处理,而且服务器一直处于重传响应包的状态,使得cpu资源也被消耗。总之,syn flood攻击会大量消耗网络带宽和cpu以及内存资源,使得服务器运行缓慢,严重时可能会引起网络堵塞甚至系统瘫痪。
因此,防范syn flood攻击非常重要。当然,首先需要判断出是否受到了syn flood攻击。可以通过抓包工具或者netstat等工具获取处于SYN_RECV状态的半连接,如果有大量处于SYN_RECV且源地址都是乱七八糟的,说明受到了syn洪水攻击。
例如使用netstat工具判断的方法如下:

[root@xuexi ~]# netstat -tnlpa | grep tcp | awk '{print $6}' | sort | uniq -c
      1 ESTABLISHED
      7 LISTEN     
    256 SYN_RECV   

4.防火墙的判断范围

从设备上分类,防火墙分为软件防火墙、硬件防火墙、芯片级防火墙。后文所说的可能是软件防火墙、也可能是硬件防火墙,在理解上它们没什么区别,只是将防火墙剥离成了独自的服务器而已。
从技术上分类,防火墙分为数据包过滤型防火墙、应用代理型防火墙。这是因为四层模型的每一层都可以应用防火墙。

4.1从链路层来判断是否处理?

基于链路层的防火墙是控制MAC的。
例如,可以将公司内网员工电脑的MAC地址全部记录到防火墙上,从而限制他们上外网。再例如,可以将公司电脑的MAC地址全部记录到防火墙使他们能够上网,但是非本公司的电脑就无法从本公司上网。但是,基本上不会有公司这样做,这样的行为太死板,而且记录MAC地址本身就是一件很麻烦的事。

4.2从网络层来判断是否处理?

网络层的核心是IP(也包括icmp等)。
所以从网络层来判断,可以基于源IP、目标IP来指定防火墙的规则。例如,来自38.68.100.61的主机不能穿过防火墙;访问目标是192.168.109.19的服务器的请求不能让其穿过防火墙;还可以设置icmp协议作为判断依据,使得外网人员的ping包被挡住。
在网络层可以用来制定防火墙规则的内容有很多。如下表。最常用的也就是后三个而已,即端口,源IP、目标IP。
在这里插入图片描述

4.3从传输层来判断是否处理?

可以从TCP或者UDP来判断。
以TCP为例,例如限制目标端口是22端口的请求,这样SSH就无法连接上服务器了。
下表是TCP数据包中可以用来制定防火墙规则的字段。
在这里插入图片描述

4.4.从应用层来判断是否处理?

到了这一层的处理就属于应用代理型的防火墙了。他需要解开数据包并还原数据,也就是说它可以获取到数据包中的所有内容,但也因此负担很重,所需CPU和内存较大。它的适用面较窄。

4.5.特殊的防火墙判断

除了以上4种判定方式,还有几种特殊的判断方式也较为常用。
◇ 根据数据包内容判断
例如,不允许内网的客户端连上taobao.com上的任何主机,可以在防火墙上检查DNS的解析包中是否包含"taobao.com"这个字符串,如果有就丢弃,这样就可以让DNS对任何taobao.com上的主机解析失败达到限制上该网的目的。
注意:虽说数据部分是应用层的,但是有些防火墙在网络层就可以进行检查。Linux默认自带的iptables/netfilters就是其中一种。
◇ 根据关联状态判断
假如现在不允许任何internet上的主机进入到公司内部,但是允许企业内的计算机可以上网。这样的设定目的是为了防止来自外网的攻击。但是如果"禁止源地址为外网的所有地址穿过防火墙、允许源地址为公司内部的地址穿过防火墙"来设置防火墙,将导致一个问题:内网连上internet后请求某个网页,要能正常上网,内网计算机必然要接收外网网页的返回数据。但外网数据包无法穿过防火墙,这样并没有实现内网主机上网的目的。
现在假设内网某机器上外网时的套接字为192.168.100.8:9000,想要访问10.0.0.5:80,也即是说数据流向是192.168.100.8:9000→10.0.0.5:80,那么返回的数据包流向必定是10.0.0.5:80→192.168.100.8:9000。根据这种关联性,防火墙可以设定允许这样的数据包通过。
这属于连接跟踪的行为。FTP服务器对于防火墙的设置是一个考验,如果没有连接跟踪的功能,数据通道的端口不固定性将导致防火墙设置极其困难。

4.6.数据包过滤

以下是协议栈(TCP/IP协议栈)底层大致机制。数据包都要通过A流入,再根据路由决策决定数据包的流向(网络层)。如果是流入本机,则经过B进入用户空间层,对于每个从本机流出的数据包,也都要经过路由决策来决定从哪个网络接口出去,然后路经D,从E出去。如果不是流入本机则流向C,然后顺着E点出去。
在这里插入图片描述
上图有一处容易理解错误,从用户空间层出去的数据包是本机新产生的数据包,可能是对流入数据包的响应数据,也可能是本机应用向外发出的请求数据包。总之,数据包走不完A–>B点–>User Space–>D–>E这条路,在数据包进入用户空间层的时候已经被处理了,从用户空间层出来的数据已经不是原流入的数据,所以在上图中我将用户空间的两个箭头断开了。
用英文来说明ABCDE这5个点就比较浅显易懂:
A表示:altering packets as soon as they come in,(译:一进来就改变包)
B表示:destined to local sockets,(译:发往本地套接字)
C表示:be routed through the box,(译:穿过盒子)
D表示:locally-generated packets,and altering before routing(注:这个before routing是指路由出去之前,而不是路由决策之前),(译:本地生成的数据包,并在路由前更改)
E表示:altering packets as they are about to go out。(译:当包要出去的时候修改它们)
在上图中的ABCDE这五个点,其实就是防火墙发挥作用的点。在Linux主机上,防火墙是由内核空间的netfilter实现的,其中作用在ABCDE这五个点的分别称为PREROUTING链、INPUT链、FORWARD链、OUTPUT链和POSTROUTING链。这几个术语在后文会做非常详细的说明。
在这里插入图片描述

5.防火墙和iptables

5.1.iptables和Netfilter的关系

防火墙起作用的是Netfilter,而iptables只是管理控制netfilter的工具,同理centos7的firewalld也是如此,可以使用该工具进行相关规则的制定以及其他的动作。iptables是用户层的程序,netfilter是内核空间的,在netfilter刚加入到Linux中时,netfilter是一个Linux的一个内核模块,要实现其他的防火墙行为还需要加载其他对应的模块,到了后来netfilter一部分必须的模块已经加入到内核中了。
也就是说,iptables命令工具操作的netfilter,真正起"防火"作用的是netfilter。

5.2.netfilter与其模块

Linux是一个极其模块化的内核。netfilter也是以模块化的形式存在于Linux中,所以每添加一个和netfilter相关的模块,代表着netfilter就多一个功能。
但是有些模块是使用netfilter所必须的,所以这些模块已经默认编译到内核中而非需要时加载。
存放netfilter模块的目录有三个:

/lib/modules/$kernel_ver/net/{netfilter,ipv4/netfilter,ipv6/netfilter}。$kernel_ver代表内核版本号。

其中ipv4/netfilter/存放的ipv4的netfilter,ipv6/netfilter/存放的ipv6的netfilter,/lib/modules/$kernel_net/kernel/netnetfilter/存放的是同时满足ipv4和ipv6的netfilter。在最后一个目录中放入更多的模块,是netfilter团队发展的目标,因为要维护ipv4和ipv6两个版本挺累的。

5.3.netfilter的结构

要使netfilter能够工作,就需要将所有的规则读入内存中。netfilter自己维护一个内存块,在此内存块中有4个表:filter表、nat表、mangle表和raw表。在每个表中有相应的链,链中存放的是一条条的规则,规则就是过滤防火的语句或者其他功能的语句。也就是说表是链的容器,链是规则的容器。实际上,每个链都只是一个hook函数(钩子函数)而已。
说到这里,需要纠正一个概念,Linux上的防火墙是由netfilter实现的,但是netfilter的功能不仅仅只有"防火",一般可以认为"防火"的功能只是filter表的功能。
关于这4个表,它们的结构如下:
注意:该表是centos6的iptables工具与netfilter内存块的对应关系,centos7的firewalld与其的对应关系已有改变。
在这里插入图片描述
注:从内核2.6.34开始,NAT表支持操作INPUT链。它只为SNAT服务。和snat on postrouting类似,只不过snat on input用来转换"目标是本机的数据包"的源地址。
filter表:netfilter中最重要的表,负责过滤数据包,也就是防火墙实现"防火"的功能。filter表中只有OUTPUT/FORWARD/INPUT链。
nat表:实现网络地址转换的表。可以转换源地址、源端口、目标地址、目标端口。NAT表中的链是PREROUTING/POSTROUTING/OUTPUT。
mangle表:一种特殊的表,通过mangle表可以实现数据包的拆分和还原。mangle表中包含所有的链。
raw表:加速数据包穿过防火墙的表,也就是增强防火墙性能的表。只有PREROUTING/OUTPUT表。
由于这几个表中有重复的链,所以数据被不同链中规则处理时是由顺序的。下图是完整的数据包处理流程。

5.4.INPUT、OUTPUT、FORWARD链

每个链对应的都是同名称的数据包,如INPUT链针对的是INPUT数据包。
INPUT链的作用是为了保护本机。例如,如果进入的数据包的目标是本机的80端口,且发来数据包的地址为192.168.100.9时则丢弃,这样的规则应该写入本机的INPUT链。但是要注意,这个本机指的是防火墙所在的机器,如果是硬件防火墙,那么一定会配合FORWARD链。
OUTPUT链的作用是为了管制本机。例如,限制浏览www.taobao.com网页。
INPUT和OUTPUT链很容易理解,FORWARD链起的是什么作用呢?数据包从一端流入,但是不经过本机,那么就要从另一端流出。对于硬件防火墙这很容易理解,如下图,数据总要转发到另一个网卡接口然后进入防火墙负责为其"防火"的网段。也就是说,FORWARD链的作用是保护"后端"的机器。
在这里插入图片描述
前文说过,Linux主机自身也有ip_forward功能用于网卡间的数据包转发,这个ip_forward和netfilter的forward链有什么区别呢?这就是防火墙的意义,当数据包需要转发时,仅使用ip_forward时将不问是非对错总是进行转发,而使用forward链时可以筛选这些需要转发的数据包,以决定是否要被转发。显然,ip_forward的功能是转发数据包,而forward链是筛选允许转发的数据包,然后让ip_forward转发。
这也说明forward链要正常工作,要求开启ip_forward功能。

开启转发功能:
#echo 1 > /proc/sys/net/ipv4/ip_forward

5.5.防火墙布线示例

在这里插入图片描述
这样的布置不仅给了服务器对外的一层防火墙,也给了服务器对内的一层防火墙,可以防外人也可以防内贼。
图中的DMZ称为"非军事区",一般是放在两个防火墙中间做内网和外网的缓冲。有些必须对外提供服务的服务器应该放在这种区域,而不能直接放在内网,因为将其放入内网又对外提供服务,当它被外界攻击时就可以借助它(肉机)作为跳板攻陷其它内网主机。
一般构建DMZ区有以下几个要求:
内网可以访问外网。显然,内网用户需要自由地访问外网。
内网仅部分主机可以访问DMZ,此策略是为了方便内网用户使用和管理DMZ中的服务器。不应该全部放行内网访问DMZ,否则有内贼的风险。
外网不能访问内网。内网中存放的是公司内部数据,这些数据不允许外网的用户进行访问。
外网可以访问DMZ。DMZ中的服务器本身就是要给外界提供服务的。
DMZ不能访问内网。如果违背此策略,则当入侵者攻陷DMZ时,就可以进一步进攻到内网的重要数据。

6.filter表

只考虑filter表的时候,防火墙处理数据包的过程如下图。
在这里插入图片描述
当数据包流入时,首先经过路由判决该数据包是流入防火墙本机还是转发到其他机器的。对于流入本机的数据包经过INPUT链,INPUT链所在位置是一个钩子函数,数据经过时将被钩子函数检查一番,检查后如果发现是被明确拒绝或需要丢弃的则直接丢弃,明确通过的则放行,不符合匹配规则的同样丢弃。但是钩子函数毕竟是半路劫财的角色,所以不管怎么样都要告诉一声netfilter,说这个数据包是怎样怎样的,即使是拒绝或丢弃了数据包也还是会给出一个通知。
当用户空间产生的数据包要发送出去时,首先经过OUTPUT链并被此处的钩子函数检查一番,检查通过则放行,然后经过路由决策判决从哪个接口出去,并最终从网卡流出。
例如,当外界主机请求WEB服务的时候,请求数据包流入到本机,路经INPUT链被放行。进入到本机用户空间的进程后,本机进程根据请求给出响应报文,该响应报文的源地址是本机,目标地址是外界主机。当响应报文要出去时必须先流经OUTPUT,然后经过路由决定从哪个接口出去,最终流出并路由到外界主机。
再例如ping本机地址(如127.0.0.1)的时候,ping请求从用户空间发送后,数据包从用户空间流出,于是流经到OUTPUT,经过路由决策发现是某网卡的地址,然后从此网卡流出。但是由于ping的目标为本机地址,所以数据包仍从流出的网卡流入,并被INPUT链检查,最后返回ping的结果信息。
注意:是先经过OUTPUT,再经过路由决策。这样一来,对那些检查不通过的数据包会直接丢弃,而无需再消耗资源去做路由决策。

原文链接:https://www.cnblogs.com/f-ck-need-u/p/7397146.html#auto_id_25

  • 6
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值