分享
 
 
 

用IPIW实现BSD防火墙(中)

王朝other·作者佚名  2006-11-24
窄屏简体版  字體: |||超大  

我们已经通过安装带缺省的禁止所有数据包出入的策略的ipfw,使所有的IP信息包都不能出入我的计算机系统,下面,我们再创建一个能被ipfw读取的规则集,使所需要的信息包能够出入计算机系统。

由于在创建规则集方面没有所谓“最合适”的方法,因此我不能说明如何在规则集中添加“万能”的规则,而只能说明一下在创建规则集时需要遵循的原则。在这里,我假设你已经掌握了ipfw的语法,能够理解我创建的规则。如果对这些知识不大理解,请参阅相关的资料。

在创建规则集时需要注意的是,规则是按给定数字行号的顺序被系统读取的,直到信息包符合一条规则,ipfw才会停止读取规则,也就是说,如果规则400和规则800都适用于一个信息包,系统总是会用到规则400而不会读取规则800。因此,在添加新的规则之前,需要仔细地审查原来的规则,确保新的规则不会被原来的规则所覆盖。

此外,规则对所有的连接-也就是在ifconfig -a的输出中所列出的所有连接都是适用的。如果在象我这样只有一个连接的计算机上自然不会有什么问题,但如果在有多个连接的计算机上,就会有所不同。例如,你的机器上可能有二个连接,一个是互联网连接,一个是内部局域网连接,每个不同的连接需要不同的安全规则,这一点可以通过在ipfw的规则中指定连接的名字来实现。

我的机器是一台运行FreeBSD 4.2、配置有互联网连接的单台计算机。由于这是我在家里使用的计算机,因此可以对向互联网上发送的信息包的类型不作任何限制,而只需要它能够接收是对我发出的信息包有效响应的信息包。

要完成这一任务最好的方法之一是利用ipfw的动态功能。如果你对这一概念还不太熟悉,下面我将对它作一番详尽的解释。

如果使用“动态”的规则,当我向互联网上发送一个信息包时,ipfw将在其状态表中添加一个记录,其中包括有发送的信息包的目标计算机的IP地址和使用的目标计算机的端口。当有信息包从互联网上返回时,如果其IP地址、端口号与在状态表中记录得不一致,计算机就不会接收这一信息包。动态规则只适用于TCP信息包,而不适用于UDP信息包,原因是UDP不创建一个虚拟的连接,它被称作是“无状态”协议,也就不能使用“状态表”。

ipfw手册中的例子部分给出了三条用来创建这个动态信息包过滤装置的规则。由于我决定在/etc/ipfw.rules中创建自己的规则,因此,需要以超级用户的身份创建包含下面内容的文件:

# 只允许向外发送信息包

add 00300 check-state

add 00301 deny tcp from any to any in established

add 00302 allow tcp from any to any out setup keep-state

由于规则100和规则200是预先包含在/etc/rc.firewall中的,因此,我自己添加的规则将从行号300开始。我将给相关的规则以300、301、302等行号,等规则越来越多或创建不相关的规则时,我就会把行号跳到400。不过,从理论上说你可以任意给规则指定行号,只要该行号没有在该规则集文件中出现过就行。

你可能已经注意到规则集出现了几个在ipfw手册中定义的关健字:

check-state:检查信息包是否与动态规则集匹配。如果匹配则搜索中止,否则继续搜索下一条规则。

keep-state:根据匹配情况,防火墙将创建一条动态规则,其功能是在源、目的IP地址/端口之间使用同一协议的流量,这一规则是具有一定的生命周期的(由一系列sysctl(8)变量控制),每当发现匹配协议时其生命周期都会刷新。

established:只适用于TCP信息包,与有RST或ACK位的信息包进行匹配。

setup:只适用于TCP信息包,与有SYN位但不具有ACK位的信息包进行匹配。

换句话说,当有信息包到达网络连接后,ipfw将首先检查它是否在状态表中,如果在状态表中,则允许它进入系统(行号为300的规则执行这一检查工作)。如果它不在状态表中,而且设置了RST或ACK位,ipfw将不允许它进入系统,因为它不是我创建的连接的有效响应(规则301完成这一工作)。只有当ACK标志没有设置,(这意味着它要初始化连接)并且这一信息包是由系统向外发送的时,才允许它向外发送;如果有信息包符合这一规则,则它被加入状态表中。

我们来看看添加上这些规则后对系统有什么影响。对规则集进行检查没有错误后,保存文件,然后输入下面的命令:

killall init

敲Enter键,然后输入:

exit

然后仔细观察启动信息,确保规则在加载时没有出现出错信息。如果在规则加载过程中出现了错误信息,那么可能是系统的安全级别被设置为3或更高了,必须首先在/etc/rc.conf文件中找到下面的这行内容,将kern_securelevel改为较小的值:

kern_securelevel="3"

然后重新执行killall init命令。

重新登录后,我将尝试能否向外发送IP数据包并收到相应的应答数据包:

ping www.freebsd.org

ping: cannot resolve www.freebsd.org: Host name lookup failure

lynx www.freebsd.org

Alert!. Unable to access document.

也许是我的系统上没有安装DNA域名解析功能的缘故,我再使用IP地址试一下:

lynx 216.136.204.21

这次我发现自己在www.freebsd.org的主页上了。我们再来试着ping一下这个IP地址吧:

ping 216.136.204.21

PING 216.136.204.21 (216.136.204.21): 56 data bytes

ping: sendto: Permission denied

ping: sendto: Permission denied

ping: sendto: Permission denied

^C

--- 216.136.204.21 ping statistics ---

3 packets transmitted, 0 packets received, 100% packet loss

这里我来解释一下这一奇怪的现象吧。很明显的是,一些数据包进入或发出了计算机系统,但一些则没有。我们来仔细发分析一下我在上面的每个例子中使用的协议。

由于我只能使用其IP地址访问www.freebsd.org的网站,因此域名解析没有成功。当我使用DNS服务时,我会向我的ISP的DNS服务器发送域名查找请求,该DNS服务器应该向我的机器发送响应数据包。这些操作都是符合我们的规则的,由于我是在53端口发送请求的,也应该在端口53上接收到响应数据包。我将复查我发送请求的DNS服务器:

more /etc/resolv.conf

search kico1.on.home.com

nameserver 24.226.1.90

nameserver 24.226.1.20

nameserver 24.2.9.34

似乎问题不是出在这儿,因此应该仔细地搞清楚域名解析的工作原理。我们来看一下能否从在线手册上得到一点帮助:

apropos resolve

dnsquery(1) - 使用解析器查询域名服务器

res_query(3), res_search(3), res_mkquery(3), res_send(3), res_init(3), dn_comp(3), dn_expand(3) - 解析器例程

resolver(5) - 解析器配置文件

man resolver

通过多次查看,下面的内容引起了我的兴趣:RES_USEVC 在查询中使用TCP而不是UDP连接;RES_STAYOPEN RES_USEVC用它来在多次查询期间保持TCP连接。它只在需要进行多个查询的的软件中有用,UDP是最常用的模式。

我可能已经发现问题出在哪了。如果DNS使用的是UDP而不是TCP,而我的规则只允许TCP协议的数据包响应我的TCP连接,域名解析就会失败。

man dnsquery

<只显示我们感兴趣的部分>

-s 使用流格式而非信息包。它使用一个带名字服务器的TCP流式连接而不是UDP,这一选项会设置解析软件选项字段的RES_USEVC位。(缺省状态下使用UDP)

现在,我们来试试这个选项:

dnsquery -s www.freebsd.org

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 39772

;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 5, ADDITIONAL: 5

;; www.freebsd.org, type = ANY, class = IN

www.freebsd.org. 49m21s IN CNAME freefall.freebsd.org.

freebsd.org. 22m43s IN NS ns1.iafrica.com.

freebsd.org. 22m43s IN NS ns2.iafrica.com.

freebsd.org. 22m43s IN NS ns.gnome.co.uk.

freebsd.org. 22m43s IN NS ns0.freebsd.org.

freebsd.org. 22m43s IN NS ns1.root.com.

ns1.iafrica.com. 1h1m3s IN A 196.7.0.139

ns2.iafrica.com. 1h1m3s IN A 196.7.142.133

ns.gnome.co.uk. 12m37s IN A 193.243.228.142

ns0.freebsd.org. 11h9m9s IN A 216.136.204.126

ns1.root.com. 1h8m12s IN A 209.102.106.178

在我们使用TCP连接发出一个DNS请求时,名字解析过程运行得很好。我们再在没有带s选项的情况下看使用UDP时的情况如何:

dnsquery www.freebsd.org

Query failed (h_errno=2) : Host name lookup failure

现在我们明白了,DNS使用的是UDP数据包。由于我没有在规则集中允许使用UDP数据包,因此DNS名字解析过程不能完成。

现在既然已经解决了这个问题,我们再来看看即使在使用IP地址时也ping不通的原因何在。我们知道,ping在其数据包中使用的是ICMP而非TCP协议。如果用ping发送ICMP数据包,不在防火墙的规则面前碰一鼻子灰才怪呢。

在向规则集中添加任何新的规则前,必须以超级用户身份重新登录。我们来看看ipfw的输出:

su

Password:

ipfw show

00100 0 0 allow ip from any to any via lo0

00200 0 0 deny ip from any to 127.0.0.0/8

00300 0 0 check-state

00301 0 0 deny tcp from any to any in established

00302 21 15144 allow tcp from any to any out keep-state setup

65535 142 10531 deny ip from any to any

## 动态规则:

00302 19 15040 (T 0, # 147) ty 0 tcp, 24.141.119.162 2932 <-> 216.136.204.21 80

注意一下动态规则部分,这是一个状态表。当运行lynx 216.136.204.21命令与www.freebsd.org站点上的http端口(端口 80)进行连接时,Rule 00302允许发出setup数据包,并在状态表中添加一个条目。所有从216.136.204.21上的端口80发出或以它为目标地址的数据包都可以进入或者发出我的计算机。

你也许还注意到了标号为00302和65535的规则后面都跟有数字,其中第一个数字为数据包的数量,第二个数字为符合每条规则的字节数。被规则65535拒之门外的数据包都是失败的UDP和ICMP数据包。

向规则集中添加新规则时,需要使用ipfw中的zero命令将这些计数器清零,这样,当对新添加的规则进行测试时,就能知道哪些规则后面又出现了新的统计数字。

下面,我将添加一些允许进行DNS名字解析的规则。由于DNS使用UDP,UDP不进行连接,我不能指定只允许对我的连接的有效的响应数据包进入系统。但是,我可以限制DNS使用的端口(端口 53)进出的数据包,选择只接受来自我的ISP的DNS服务器的IP地址发出的数据包。运行more /etc.resolv.conf命令就能发现这些IP地址。我将在/etc/ipfw.rules文件中添加下面的内容:

#允许 DNS

add 00400 allow udp from 24.226.1.90 53 to any in recv ed0

add 00401 allow udp from 24.226.1.20 53 to any in recv ed0

add 00402 allow udp from 24.2.9.34 53 to any in recv ed0

然后,通过运行killall init命令重新加载规则集,看名字解析是否已经可以成功地运行了:

lynx www.freebsd.org

Alert!. Unable to access document.

怎么回事?我已经在规则集中添加了允许使用UDP数据包的规则,怎么名字解析服务仍然不行呢?我们运行ipfw show命令来看看哪条规则的后面跟有数据包计数字:

su

Password:

ipfw show

00100 0 0 allow ip from any to any via lo0

00200 0 0 deny ip from any to 127.0.0.0/8

00300 0 0 check-state

00301 0 0 deny tcp from any to any in established

00302 0 0 allow tcp from any to any keep-state setup

00400 0 0 allow udp from 24.226.1.90 53 to any in recv ed0

00401 0 0 allow udp from 24.226.1.20 53 to any in recv ed0

00402 0 0 allow udp from 24.2.9.34 53 to any in recv ed0

65535 30 2196 deny ip from any to any

## Dynamic rules:

后面跟有统计数字的唯一的规则是最后一条拒绝服务的规则,说明添加的允许UDP数据包的规则没有作用。现在我才明白,我还没有允许向外发送UDP数据包,没有UDP数据包返回来也就没有什么好奇怪的了。下面我们再往规则集中添加一行内容:

00403 allow udp from any to any out

这样,我的计算机就可以向外发送UDP数据包了。然后用ipfw zero清除规则后面的统计数字,运行killall init命令重新再试一次:

lynx www.freebsd.org

FreeBSD的主页终于出现了。如果我以超级用户的身份运行ipfw show命令,就会得到更令人满意的输出:

ipfw show

00100 0 0 allow ip from any to any via lo0

00200 0 0 deny ip from any to 127.0.0.0/8

00300 0 0 check-state

00301 0 0 deny tcp from any to any in established

00302 20 15061 allow tcp from any to any keep-state setup

00400 10 1882 allow udp from 24.226.1.90 53 to any in recv ed0

00401 0 0 allow udp from 24.226.1.20 53 to any in recv ed0

00402 0 0 allow udp from 24.2.9.34 53 to any in recv ed0

00403 10 591 allow udp from any to any out

65535 31 2577 deny ip from any to any

## Dynamic rules:

00302 19 15017 (T 0, # 236) ty 0 tcp, 24.141.119.162 4363 <-> 216.136.204.21 80

规则00403允许我的计算机发出DNS请求,规则00400允许接受DNS应答,规则00302建立HTTP连接,而且,我在状态表中有了一个与216.136.204.21之间HTTP连接的条目。

我们已经建立了一个可以运行的网络连接,但这个规则集仍然有很大的改进余地,下面我们将就这方面的问题进行更详细的讨论。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有