nginx 过滤post报文 防火墙_信息安全课程11:防火墙(iptables/netfilter)

这一次课程中我们开始讨论防火墙。主要介绍的内容是iptables和netfilter。从这一部分开始,我们从网络安全开始转入系统安全。当然,防火墙设置的基础是网络知识。

防火墙一词最早来源于建筑学,主要有防火材料构成,在两幢房屋之间,或者不同的房屋之间,这样有效防止不同的房屋之间火势的蔓延。网络中的防火墙一词,借用了类似的概念。防火墙置于内部网络和外部网络之间,是内部网络和外部网络通信的必经之地,通过在防火墙上设置各种规则,对流经的流量进行各种控制,如记录、通过、丢弃、修改、报警等,从而使得内部网络免于外部网络的攻击。

6b9fc3f2-7811-eb11-8da9-e4434bdf6706.png
https://www.zhihu.com/video/1092176463855443968

这里我们简单地将防火墙分为三类:1. 包过滤防火墙(packet filter);2. 应用层网关代理(Application level Gateway)3. 状态防火墙(stateful firewall)。课程中主要讨论的是前两种。

包过滤防火墙也可以成为无状态防火墙,静态防火墙。包过滤是通过ACL(Access Control List)规则控制数据流的。IP数据包中最明显最核心的五元素就是,源地址、目标地址、协议、源端口、目标端口dport。包过滤主要也就是根据这些包头部的元素进行判断。之所以叫做静态防火墙,是因为在一次会话中,这五个元素是不会变化的。

基于包过滤技术的防火墙,实现简单,规则也简单,所以包过滤防火墙的处理速度快,并且易于配置。这也是早期应用的最广的防火墙技术。

包过滤防火墙的缺点是1. 难以处理分片【IP碎片攻击】。2. 不支持某些复杂的协议。3. 不能防止应用层等恶意攻击,原因很简单,因为它根本不识别应用层的数据。

我们使用一个例子来具体讨论一下。

假如一家机构希望在断掉其他所有流量的情况下,使得内部主机可以访问外部的Web服务。

我们想一下,为了实现这个目标,在包过滤防火墙上可以怎么来设置规则。这里的难点在于,我们仅知道发起连接的源IP地址是机构内的网址,客户端的源端口不能确认;以及,外部的web服务器的IP地址也不能确定,仅能知道服务端口是80。这样的话,我们可能仅能根据源IP地址和目的端口来指定规则。

譬如我们可以指制定以下的规则:

6c9fc3f2-7811-eb11-8da9-e4434bdf6706.png

根据以上的五条规则,防火墙对数据包做出判断,如果符合条件就通过,不符合条件的就拒绝。

一眼看上去,这个防火墙也挺好的。但是从攻击者角度来看,这样的防火墙有什么问题呢?

  • 攻击者可以以源端口80向内某个内部主机特定端口发送有攻击性的数据包。上面的规则中,外网只要源端口是80,数据包就可以通过。这样,攻击者完全可以控制自己的数据包的源端口是80向内部网络发起连接,如果内部网络有FTP服务器、Web服务器就可以直接建立连接了。

6f9fc3f2-7811-eb11-8da9-e4434bdf6706.png

上图是对上面问题的改进,譬如规定源端口的范围,这样可以防止攻击者直接连入到数值端口的服务上。但是仍不能防止对非熟知端口的访问。

另外,还可以对这个规则进行改进。

719fc3f2-7811-eb11-8da9-e4434bdf6706.png

通过增加对标志位的检查,那么如果是外界来的SYN包,即使源端口是80,也不能通过防火墙。但是,即使不能建立连接,一些嗅探包也能够通过,可以探测网络主机的拓扑等。譬如,对于nmap,仍然可以使用-sA扫描。


包过滤之后出现的应用级网关代理防火墙。

使用这种代理防火墙,对于客户端来说,代理充当了服务器的角色,对于真正的服务器来说,充当了客户端的角色。所以通过使用代理主机,客户和服务器之间从不会有真正的连接。应用代理网关防火墙彻底隔断内网与外网的直接通信,内网用户对外网的访问变成防火墙对外网的访问,服务器返回的数据首先到达防火墙,经过安全策略检测,然后再由防火墙转发给内网用户。也即所有通信都必须经应用层代理软件转发。

这种方式的优点显而易见,对数据的控制直接上升到应用层,对数据包检测非常充分。缺点,同时为了实现这一点,对于每一个服务应用,写要编写特定的安全代理程序,也即相应的客户端与服务器端程序。因此,很多应用用得不到支持。


状态检测防火墙也称为动态包过滤防火墙。如何理解状态呢?从会话来看,通信过程中的会话数据包不是一个个完全独立的数据包,而是有前后连接状态的。譬如建立可靠的TCP三次握手连接,是按照SYN、SYN+ACK以及ACK的顺序来的,如果没有发送SYN报文,就收到对方的ACK报文,这个ACK报文就是一个应该丢弃的数据包。

状态检测防火墙在接收到连接建立请求是,就可以建立一张表,在表中存储相关的各个连接的信息,建立连接状态规则,基于这个表对进入和出去的数据包进行匹配。当然,状态防火墙同样可以实现包过滤防火墙的各种功能,进行网络层和传输层的各种检查。

因此,可以理解动态,在同一个会话中,五元组不会变化,但是各种状态标识、分片等都是可以变化的。通过结合状态进行过滤,可以实现比较好的效果。

通过下面的例子来体会一下状态防火墙和包过滤防火墙的区别。

首先看一下包过滤防火墙,

759fc3f2-7811-eb11-8da9-e4434bdf6706.png

这个规则主要是通过丢弃所有进入的SYN包来防止外部对内部的访问。

使用-sA来扫描目标主机,结果发现所有的端口都没有被过滤。

799fc3f2-7811-eb11-8da9-e4434bdf6706.png

使用-sF来扫描,

7d9fc3f2-7811-eb11-8da9-e4434bdf6706.png

或者,更贴近与之前讨论的场景。明确地规定外部的数据包只有源端口是80,并且标志位设置了ACK的数据包进入。

首先我们将INPUT的默认策略设置为DROP,然后修改规则,使得源端口为80,然后设置了ACK位的数据包可以进入。

7f9fc3f2-7811-eb11-8da9-e4434bdf6706.png

这时,对80端口的访问完全正常。

【补充关于--tcp-flags的用法:

--tcp-flags有两部分,第一部分表示:需要匹配报文tcp头中的哪些标志位,可以匹配报文tcp头中的6个标志位,这6个标志位分别为为"SYN、ACK、FIN、RST、URG、PSH",可以把这一部分理解成需要匹配的标志位列表。

第二部分表示:第一部分的标志位列表中,哪些标志位必须为1,譬如TCP三次握手的第一个SYN包,则第二部分为SYN,表示,第一部分需要匹配的标志位列表中,SYN标志位的值必须为1,其他标志位必须为0。

819fc3f2-7811-eb11-8da9-e4434bdf6706.png

上述两条命令,分别匹配三次握手的第一个和第二个包。【关于-m,表示match一个扩展模块;详细内容可以参考4】

还可以简写为:

839fc3f2-7811-eb11-8da9-e4434bdf6706.png

因为SYN包经常用,还有快捷方式

859fc3f2-7811-eb11-8da9-e4434bdf6706.png

此时,来扫描一下:

889fc3f2-7811-eb11-8da9-e4434bdf6706.png

后面的两个命令指定了nmap在扫描时使用默认的源端口号是80,此时,可以判断出端口未被过滤。

然后我们比较一下,使用状态防火墙的效果。

8a9fc3f2-7811-eb11-8da9-e4434bdf6706.png

使用-sA扫描:

8c9fc3f2-7811-eb11-8da9-e4434bdf6706.png

此时,所有的端口都显示为被过滤。


在了解了以上基础知识之后,我们来学习一下iptables/netfilter。

iptables/netfilter是Linux内置的防火墙,经过了一系列的发展, 从ipfirewall(墙)到ipchains(链)到iptables(表),整个架构越来越复杂,功能也越来越强。在2.0版内核中,包过滤机制是ipfw,管理工具是ipfwadm;2.2 版内核中,包过滤机制ipchain,管理工具是ipchains;2.4版及以后的内核中,包过滤机制是netfilter,管理工具iptables。用户空间的iptables制定防火墙规则,内核空间的netfilter则真正实现防火墙功能。

我们首先分析和讨论iptables的使用,在此之后,简单介绍一下netfilter的接口。我们先直接使用一下iptables,有一个直观的印象,然后讨论它的整体结构。

基本规则管理命令:

  • -A, --append chain rule-specification:追加新规则于指定链的尾部;
  • -I, --insert chain [rulenum] rule-specification:插入新规则于指定链的指定位置,默认为首部;
  • -R, --replace chain rulenum rule-specification:替换指定的规则为新的规则;
  • -D, --delete chain rulenum:根据规则编号删除规则;
  • -D, --delete chain rule-specification:根据规则本身删除规则;

基本链管理命令:

  • -F, --flush [chain]:清空指定的规则链上的规则;
  • -P, --policy chain target 制定链表的策略(ACCEPT|DROP|REJECT)
  • -L, --list [chain]:列出规则;

有了这几个命令,我们可以做一些事情。

譬如,直接使用

8e9fc3f2-7811-eb11-8da9-e4434bdf6706.png

可以查看到iptables显示的默认的表(filter),以及表中的三条链。从这里我们可以看到好几个有用的信息。譬如policy,策略,三条链都显示是ACCEPT。顾名思义,就是全部接受。那看到默认情况下,进入的包,朝外发的包以及转发包都是接受的。也即,不会丢弃任何数据包。这样的话,相当于防火墙并没有启动。

另外,注意每条链给出的规则的格式。主要包括target,也即决定数据包的命运;prot,协议;opt,选项,源和目的。这样看来,基础就是对数据包的头部进行判断。

好,譬如我们来试一下。

首先,如果我们让所有的数据包都进不来。丢弃所有,那么就直接把策略policy设置一下就行了。

919fc3f2-7811-eb11-8da9-e4434bdf6706.png

这样的话,数据包可以出去,但是因为收不到返回的数据包,所以基本就没有反应。不论是ping也好,telnet也好,啥都做不了了。

现在默认的策略是DROP,如果想要允许一些数据进来,可以添加一些规则。譬如,想让ping收到回复,那我们怎么做呢?

929fc3f2-7811-eb11-8da9-e4434bdf6706.png

这个时候ping就没问题了。

这时候,大家想一想,这样做了之后,别人ping我们能不能ping通?

如果我们的目的是只想要回复的ping的包,别人ping我们的时候不回复,可以怎么做呢?

可以继续修正。首先,先删掉之前的规则

939fc3f2-7811-eb11-8da9-e4434bdf6706.png

然后只接受icmp echo reply。

949fc3f2-7811-eb11-8da9-e4434bdf6706.png

想一下,除了这种方式之外,还可以怎么做?

类似地,我们多做几个练习。

假设现在我们希望能够建立telnet连接。应该添加什么样的规则呢?可以看到,因为设置了策略为丢包,telnet localhost都没有法子建立连接。

969fc3f2-7811-eb11-8da9-e4434bdf6706.png

【奇怪的是,如果telnet localhost不行;但是telnet外网没问题。去掉--sport 23的限制,telnet localhost也没问题。】

979fc3f2-7811-eb11-8da9-e4434bdf6706.png
https://www.zhihu.com/video/1250728764071665664

好,接下来我们做一些练习。我们先把INPUT链的限制拿掉,然后设为都可以进入;然后对OUTPUT链增加限制。

现在我们想实现的目的仍然是只允许内部访问外部,不允许外部访问内部。譬如我们可以ping别人,但是不让别人ping我们。

那么这个时候应该怎么做呢?

以及能建立到外部的telnet连接,但是不允许别人访问我们自己的telnet服务。


以上是iptables的基本使用。接下来我们来讨论下,iptables的一些更高级的用法。

  1. 一些攻击会采用发送大量无效的数据包给服务器,造成服务器资源浪费。iptables提供了一个limit扩展功能,可以限制单位时间内数据包的个数。譬如,可以可以限制每分钟接收的数据包的个数。

iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 5/min -j ACCEPT

989fc3f2-7811-eb11-8da9-e4434bdf6706.png
https://www.zhihu.com/video/1092370860018642944

从上面的视频中可以看出,在收到5个icmp echo reply之后,回复便停止了。

2. iptables本身属于三层包过滤防火墙,但也提供了string扩展功能,通过--string也可以根据关键词限制网络连接。使用下面两条规则,实现拒绝转发包含关键词/etc/passwd以及baidu的数据包,也就是防止/etc/passwd被复制出去,以及防止访问baidu网站。

sudo iptables -I OUTPUT -m string --algo bm --string "/etc/passwd" -j REJECT

sudo iptables -I OUTPUT -m string --algo bm --string "baidu" -j REJECT

上面的第二条,效果其实蛮好的。可以看到

9b9fc3f2-7811-eb11-8da9-e4434bdf6706.png

但是第一条其实蛮搞笑的。它能够防止的是"/etc/passwd"这个字符串,而不是这个文件。可以使用下面的命令来看一下之间的区别。

9c9fc3f2-7811-eb11-8da9-e4434bdf6706.png

3. 根据数据连接状态设置防火墙规则,放行所有的出站数据包。拒绝入站的新连接请求与无效链接,仅放行入站的回应请求。这个例子在上面我们已经看到过效果。

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT


接下来我们来分析一下iptables的整体结构。

9d9fc3f2-7811-eb11-8da9-e4434bdf6706.png

以上各表中,默认的是filter表。因为filter表应用最广泛。其他的表都有各自的用途。

filter主要和主机自身有关,主要负责防火墙功能 过滤本机流入流出的数据包是默认使用的表;

  • input :负责过滤所有目标地址是本机地址的数据包,就是过滤进入主机的数据包;
  • forward :负责转发流经主机但不进入本机的数据包,和NAT关系很大;
  • output :负责处理源地址的数据包,就是对本机发出的数据包;

NAT表负责网络地址转换,即来源于目的IP地址和端口的转换,一般用于共享上网或特殊端口的转换服务

  • snat :地址转换
  • dnat :标地址转换
  • pnat :标端口转换

mangle表负责拆解报文,修改并重新封装。

raw表可以关闭iptables中开启的连接追踪。

五条链:

9e9fc3f2-7811-eb11-8da9-e4434bdf6706.png

每个表都有自己相应的链。

数据包过滤匹配流程

如图,我们可以分析数据报文进入本机后应用了哪些表规则以及链规则,根据表规则和链规则分析数据包的过滤匹配流程。比如我们制定一个filter表的规则,filter表决定是否放行数据包通过,那如果通过,则必须经由INPUT链流入数据包,INPUT链是处理入站数据的,如果没问题,继续放行到用户空间,再经由OUTPUT链将数据包流出。

9f9fc3f2-7811-eb11-8da9-e4434bdf6706.png

以上各表中,我们已经对filter表有了直观的认识,其他的还不熟练,所以可能会比较疑惑。现在我们重点介绍一下NAT。其他的表用的不是很多。

看一张简化了的图,只包括了NAT和Filter表:

a19fc3f2-7811-eb11-8da9-e4434bdf6706.png

NAT英文全称是“Network Address Translation”,网络地址转换,它是IETF(Internet Engineering Task Force, Internet工程任务组)标准,使得一个整体机构以一个公用IP(Internet Protocol)地址出现在Internet上。顾名思义,它是一种把内部私有网络地址(IP地址)翻译成合法网络IP地址的技术。因此NAT在一定程度上,能够有效的解决公网地址不足的问题。

具体讲一下NAT的功能。譬如由于IPv4地址匮乏,一个机构中有十台主机需要上网,但是这个机构只分配到了一个公网IP。在局域网内部,这十台主机可以使用私有地址进行通信;但是为了获得公网中的服务,必须使用公网IP。NAT就可以用于解决这个问题。内网主机向外发出数据包时,NAT服务负责将数据包的源IP地址改成公网IP地址(SNAT);当外网对内网主机的回复到达时,NAT服务将回复包的目的IP再改成内网IP地址(DNAT)。现在,无线网络中也使用这种技术。

具体的例子,譬如,内网中有192.168.0.1的主机和192.168.0.2的主机都希望和百度进行通信,它们发出两个数据包,分别是【192.168.0.1:12345,百度:80】和【192.168.0.2:23456,百度:80】,那么NAT服务器会将这两个数据分别映射成【1.2.3.4:4567,百度:80】和【1.2.3.4:4568,百度:80】,然后转发出去。百度接收到这两个数据包,正常处理,然后发出回复。NAT服务收到百度的回复之后,再进行一次转换,分别将【百度:80,1.2.3.4:4567】转换为【百度:80,192.168.0.1:12345】,将【百度:80,1.2.3.4:4568】转换为【百度:80,192.168.0.2:23456】。

在iptables中,可以通过在PREROUTING链和POSTROUTING链上分别应用DNAT和SNAT实现这种内网IP和公网IP的转换。值得注意的是,不要想当然地把PREROUTING和SNAT相关联,以及将POSTROUTING和DNAT相关联。PREROUTING在外网的数据包到达内网,还未决定该数据包的去向时的动作,也即,此时的数据包,(一般而言)源IP是外网服务器,目的地址此时也是公网IP,需要转换成内网IP;POSTROUTING是内网数据包朝外发送,此时已经根据目的IP地址决定好了路由决定,源IP还是内网IP,需要转换成公网IP。因此,PREROUTING链上一般的动作是DNAT,而POSTROUTING链上的动作一般是SNAT。

先用一条命令来查看一下NAT的使用。

a29fc3f2-7811-eb11-8da9-e4434bdf6706.png

使用这一规则之后,在网页中输入的任何IP地址,都会返回192.168.116.159的主页。

a39fc3f2-7811-eb11-8da9-e4434bdf6706.png
https://www.zhihu.com/video/1092392306187005952

接下来看一下,NAT的具体使用。

a49fc3f2-7811-eb11-8da9-e4434bdf6706.png
SNAT封包传送示意图

由上图可知,需要将192.168.10.10转换为111.196.211.212,iptables命令如下:

iptables –t nat –A POSTROUTING –s 192.168.10.10 –o eth1 –j SNAT --to-source 111.196.221.212

外网IP地址不稳定的情况即可使用MASQUERADE(动态伪装),能够自动的寻找外网地址并改为当前正确的外网IP地址

iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j MASQUERADE

DNAT即目地地址转换,则能够让外网用户访问局域网内不同的服务器。(相当于SNAT的反向代理)

aa9fc3f2-7811-eb11-8da9-e4434bdf6706.png
DNAT封包传送示意图

由上图可知,目标地址192.168.10.6在路由前就转换成61.240.149.149,需在网关上运行iptables命令如下:

iptables –t nat –A PREROUTING –i eth1 –d 61.240.149.149 –p tcp –dport 80 –j DNAT --to-destination 192.168.10.6:80

eth1网口传入,且想要使用 port 80 的服务时,将该封包重新传导到 192.168.1.210:80 的 IP 及 port 上面,可以同时修改 IP 与 port。此为地址映射与端口转换。

还可以使用REDIRECT单独进行端口转换

例:将 80 端口的封包转递到 8080端口

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080

# 使用 8080 这个 port 来启动 WWW ,但是别人都以80来访问。


以上,是对NAT功能的介绍和演示。接下来,我们利用iptables的NAT表,实现一个Web代理。

在我们的VmWare虚拟系统中,有三台虚拟机,分别是192.168.116.1、192.168.116.141和192.168.116.160。其中,.1代表一台客户主机;.160代表真正的Web服务器;.141代表它们之中的代理。

什么时候需要代理呢?

很多情况都需要。譬如,如果.164是一台内网Web服务器,而.141是类似于网关或者对外的接口,希望把它给保护起来,不能让外界的主机得知它的存在,外界主机可以通过访问.141来获得对服务器的访问;或者,.1不能直接访问.141(被墙),只能通过代理来代为处理。

代理可以怎么工作呢?譬如,代理可以发布通知,在192.168.116.141:8123上提供Web服务。当然,在.141的8102端口本身并没有任何服务。但是.141可以通过进行网络地址转换,实现对.1而言它的服务器的功能。

具体而言:

当.141接收到.1对自己的8123端口的访问时,知道对方实际上想获得.164的Web服务,因此,需要将该包的目的IP改成是.164:80。另外,如果只进行了目的地址的修改,.164会将回复包直接发给.1,此时由于.1并没有建立与.164的访问,这个回复包会被回以RST,中断连接。因此,.141此时必须还将来自.1的对Web服务的请求包的源IP地址改成自己。由此,.164接收到的是来自.141的对80端口的访问,并作出回复。当.141收到回复的时候,再将来自.164得对自己的回复,再修改成从自己的8123端口发出的对.1的回复。

具体过程可见下图(感谢同学分享!):

ad9fc3f2-7811-eb11-8da9-e4434bdf6706.png

看一下效果。

b09fc3f2-7811-eb11-8da9-e4434bdf6706.png
https://www.zhihu.com/video/1249014698214490112

另外,这个思路可以用于对外网的IP的代理。譬如对202.38.64.3.

b29fc3f2-7811-eb11-8da9-e4434bdf6706.png

进行代理后效果如下:

b59fc3f2-7811-eb11-8da9-e4434bdf6706.png

但是对一般较大型的网站代理失败,通过wireshark抓包,似乎是被转到了

b99fc3f2-7811-eb11-8da9-e4434bdf6706.png

目前原因还不明。


上次课程之后,不少同学表示对于NAT和代理感到疑惑。因为上次课中这两部分是连着讲的;而且代理的时候又使用了SNAT和DNAT,所以造成了一些疑惑。这里我们简单讨论一下,NAT服务和代理的区别。

在NAT服务器之后的主机,一般没有公网IP,所以依赖于NAT,在数据包从内网进入外网的时候,将源IP从内网IP换成公网IP;以及在数据包从外网进入内网的时候,将目的IP从公网IP换到内网IP。而代理是主要目的是隔绝内网和外网。譬如,对于百度和知乎的访问,NAT服务器后面的内网主机,它们很清楚自己的最终访问目标是百度和知乎,目的地址也是相应的URL;而代理隔绝的内网主机,它们的访问目的就是代理主机本身,譬如代理会公布(IP:3128,可以获得知乎服务;IP:8123,可以获得百度服务),那么主机只需要记住这两个端口就行了。

参考:

  1. iptables 从入门到应用 - FrankB - 博客园
  2. Linux iptables用法与NAT
  3. http://www.zsythink.net/archives/1578
  4. http://www.zsythink.net/archives/1564
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值