ipfilter有两个模块:网络地址翻译(network address translator,简称NAT)器与数据包过滤器(packet filter,简称IPF)。NAT用于地址伪装(隐藏单个外部IP地址后面的内部IP地址),还用于重定向主机和端口之间的数据包。包过滤器则按照规则集检查NAT或未NAT过的数据包,以决定丢弃或放行。
由于NAT首先处理数据包,因此我们先配置NAT。网络地址翻译及数据包重定向的规则一律存放在/etc/ipnat.rules文件中。
# 内网NAT规则 map tun0 192.168.1.0/24 -> x.x.x.x/32 portmap tcp/udp 10000:20000 map tun0 192.168.1.0/24 -> x.x.x.x/32 # DMZ NAT规则 map tun0 192.168.2.0/24 -> x.x.x.x/32 portmap tcp/udp 20001:30000 map tun0 192.168.2.0/24 -> x.x.x.x/32
这里"x.x.x.x"代表ISP分配外网接口的实际IP。tun0则是外网接口设备名。如果外部接口未使用串行端口,将tun0替换实际网络接口设备名即可。
这些规则的作用是让NAT模块映像所有在端口为10000-20000,从内网到地址"x.x.x.x"的连接。并映射所有端口为20001-30000,从DMZ到地址"x.x.x.x"的连接。
现在我们可以把内网和DMZ连接到Internet上了,但外网还不能访问DMZ中的服务。我们需要做一个重定向,下面仅仅是一个简单的重定向HTTP数据包的NAT规则:
# 重定向外网的HTTP服务请求 rdr tun0 x.x.x.x/32 port 80 -> 192.168.2.254 port 8080 tcp rdr tun0 x.x.x.x/32 port 80 -> 192.168.2.254 port 8080 udp # 重定向内网的HTTP服务请求 rdr fxp1 x.x.x.x/32 port 80 -> 192.168.2.254 port 8080 tcp rdr fxp1 x.x.x.x/32 port 80 -> 192.168.2.254 port 8080 udp # 重定向DMZ的HTTP服务请求 rdr fxp2 x.x.x.x/32 port 80 -> 192.168.2.254 port 8080 tcp rdr fxp2 x.x.x.x/32 port 80 -> 192.168.2.254 port 8080 udp
这里192.168.2.254是DMZ区HTTP服务器的IP地址。出于安全考虑,服务器监听于一个高端口8080。这些规则的作用是将各个接口接收的数据包重定向到"x.x.x.x"的80端口上,那儿才是真正的目的地。
其它服务的NAT规则以此类推,只要更改端口号与服务器的地址就行了。如邮件服务器的重定向规则如下:
# 重定向外网的SMTP服务请求 rdr tun0 x.x.x.x/32 port 25 -> 192.168.2.253 port 25 tcp rdr tun0 x.x.x.x/32 port 25 -> 192.168.2.253 port 25 udp # 重定向内网的SMTP服务请求 rdr fxp1 x.x.x.x/32 port 25 -> 192.168.2.253 port 25 tcp rdr fxp1 x.x.x.x/32 port 25 -> 192.168.2.253 port 25 udp # 重定向DMZ的SMTP服务请求 rdr fxp2 x.x.x.x/32 port 25 -> 192.168.2.253 port 25 tcp rdr fxp2 x.x.x.x/32 port 25 -> 192.168.2.253 port 25 udp
照此将设置好所有服务的重定向NAT规则。
下面可以开始考虑包过滤规则了。所有的包过滤规则都放在/etc/ipf.rules文件中。
先考虑lo0接口:lo0 是软件环路接口,在这里阻挡数据包会浪费大量的处理器周期,pass all吧!
pass out quick on lo0 all pass in quick on lo0 all
关键字quick指示过滤核心一旦数据包匹配上本条规则,立刻中止规则匹配,这样可加快处理速度,并简化了规则的书写。
接着考虑接口tun0。按照预先的设计,我们要在这里阻截所有目的地址不合法的数据包:
block out quick on tun0 from any to 192.168.0.0/16 block out quick on tun0 from any to 172.16.0.0/12 block out quick on tun0 from any to 127.0.0.0/8 block out quick on tun0 from any to 10.0.0.0/8 block out quick on tun0 from any to 0.0.0.0/8 block out quick on tun0 from any to 169.254.0.0/16 block out quick on tun0 from any to 192.0.2.0/24 block out quick on tun0 from any to 204.152.64.0/23 block out quick on tun0 from any to 224.0.0.0/3
这样就防止了有害数据包进入外网。
下面来添加让合法的数据包输出的规则。下面这三条规则允许所有从内网合法地址发往外网的数据流:
pass out quick on tun0 proto tcp from 192.168.1.0/24 to any keep state pass out quick on tun0 proto udp from 192.168.1.0/24 to any keep state pass out quick on tun0 proto icmp from 192.168.1.0/24 to any keep state
关键字keep state指示ipfilter记住连接状态,这样可以使此连接的后续数据包不再进行规则检查。关键字proto定义规则所使用的协议。
我们还需要将所有来自DMZ合法地址的数据包能顺利地发送到外网。这很容易做到:只需复制内网规则,更换一下网络地址即可(用192.168.2.0/24 代替192.168.1.0/24):
pass out quick on tun0 proto tcp from 192.168.2.0/24 to any keep state pass out quick on tun0 proto udp from 192.168.2.0/24 to any keep state pass out quick on tun0 proto icmp from 192.168.2.0/24 to any keep state
所有其它想通过tun0出外网的数据包均应阻断:
block out quick on tun0 all
以上规则定义了什么样的数据包可以由我们的网络连接外网。下面我们将定义阻断那些想进入防火墙内部的不受欢迎的数据包:
block in quick on tun0 from 192.168.0.0/16 to any block in quick on tun0 from 172.16.0.0/12 to any block in quick on tun0 from 10.0.0.0/8 to any block in quick on tun0 from 127.0.0.0/8 to any block in quick on tun0 from 0.0.0.0/8 to any block in quick on tun0 from 169.254.0.0/16 to any block in quick on tun0 from 192.0.2.0/24 to any block in quick on tun0 from 204.152.64.0/23 to any block in quick on tun0 from 224.0.0.0/3 to any block in log quick on tun0 from x.x.x.x/32 to any block in log quick on tun0 from any to x.x.x.0/32 block in log quick on tun0 from any to x.x.x.255/32
关键字log将使ipfilter记录所有匹配本条规则的数据包。
这样,所有非法数据包都将被丢弃。但去往DMZ的合法端口的数据包必须让行。以下规则过滤目的端口为80的数据包。
pass in quick on tun0 proto tcp/udp from any to x.x.x.x/32 port = 80 keep state pass in quick on tun0 proto tcp/udp from any to 192.168.2.254/32 port = 8080 keep state
注意ipf.rules中的地址/端口一定要与ipnat.rules一致。对其余服务如法炮制。
丢弃所有其它外网接口上的数据包:
block in quick on tun0 all
外网接口规则基本上差不多了。接着考虑内网与DMZ接口。
假设内网接口为fxp1上,先丢弃所有想连接内网的数据包:
block out quick on fxp1 all
再限制对内网DNS的访问(即列在/etc/resolv.conf 文件中的DNS服务器):
pass out quick on fxp1 proto tcp from 192.168.1.1 to 192.168.1.2/32 port = 53 keep state pass out quick on fxp1 proto udp from 192.168.1.1 to 192.168.1.2/32 port = 53 keep state
或者干脆用外部DNS服务器"y.y.y.y" 和 "z.z.z.z"来代替内部DNS服务器。在/etc/resolv.conf文件中:
lookup file bind nameserver y.y.y.y nameserver z.z.z.z
注意,关键字"out"定义了数据包的一种流向:从防火墙的上层协议进入底层协议,由接口输出(如流向外网的数据包);"in"定义了数据包的另一种流向:由接口输入,并从防火墙的底层协议进入上层协议(如流向内网的数据包)。
下列规则定义了什么样的数据包可以进入防火墙:
block in quick on fxp1 from 172.16.0.0/12 to any block in quick on fxp1 from 10.0.0.0/8 to any block in quick on fxp1 from 127.0.0.0/8 to any block in quick on fxp1 from 0.0.0.0/8 to any block in quick on fxp1 from 169.254.0.0/16 to any block in quick on fxp1 from 192.0.2.0/24 to any block in quick on fxp1 from 204.152.64.0/23 to any block in quick on fxp1 from 224.0.0.0/3 to any block in log quick on fxp1 from x.x.x.x/32 to any block in log quick on fxp1 from any to x.x.x.0/32 block in log quick on fxp1 from any to x.x.x.255/32 pass in quick on fxp1 proto tcp from 192.168.1.0/24 to any keep state pass in quick on fxp1 proto udp from 192.168.1.0/24 to any keep state pass in quick on fxp1 proto icmp from 192.168.1.0/24 to any keep state block in quick on fxp1 all
DMZ区与内网不同,它主要是一些对外开放的服务。首先,我们不限制内网到DMZ的通信:
pass out quick on fxp2 proto tcp from 192.168.1.0/24 to 192.168.2.0/24 keep state pass out quick on fxp2 proto udp from 192.168.1.0/24 to 192.168.2.0/24 keep state pass out quick on fxp2 proto icmp from 192.168.1.0/24 to 192.168.2.0/24 keep state
接下来,阻断所有其余的数据包:
block out quick on fxp2 from any to 192.168.0.0/16 block out quick on fxp2 from any to 172.16.0.0/12 block out quick on fxp2 from any to 127.0.0.0/8 block out quick on fxp2 from any to 10.0.0.0/8 block out quick on fxp2 from any to 0.0.0.0/8 block out quick on fxp2 from any to 169.254.0.0/16 block out quick on fxp2 from any to 192.0.2.0/24 block out quick on fxp2 from any to 204.152.64.0/23 block out quick on fxp2 from any to 224.0.0.0/3
然后,对来自外网的访问公开地址的数据包放行:
pass out quick on fxp2 proto tcp from any to 192.168.2.254/32 port = 8080 keep state pass out quick on fxp2 proto udp from any to 192.168.2.254/32 port = 8080 keep state pass out quick on fxp2 proto tcp from any to 192.168.2.253/32 port = 25 keep state pass out quick on fxp2 proto udp from any to 192.168.2.253/32 port = 25 keep state
最后,阻断其余的数据包:
block out quick on fxp2 all
到目前为止,我们还未设置由DMZ到外网的过滤规则,Internet上的数据包,我们将让所有从合法地址发送的数据包通过:
block in quick on fxp2 from 172.16.0.0/12 to any block in quick on fxp2 from 10.0.0.0/8 to any block in quick on fxp2 from 127.0.0.0/8 to any block in quick on fxp2 from 0.0.0.0/8 to any block in quick on fxp2 from 169.254.0.0/16 to any block in quick on fxp2 from 192.0.2.0/24 to any block in quick on fxp2 from 204.152.64.0/23 to any block in quick on fxp2 from 224.0.0.0/3 to any block in log quick on fxp2 from x.x.x.x/32 to any block in log quick on fxp2 from any to x.x.x.0/32 block in log quick on fxp2 from any to x.x.x.255/32 pass in quick on fxp2 proto tcp from 192.168.2.0/24 to any keep state pass in quick on fxp2 proto udp from 192.168.2.0/24 to any keep state pass in quick on fxp2 proto icmp from 192.168.2.0/24 to any keep state block in quick on fxp2 all
规则写完了,该加载生效了。
ipfilter规则文件的加载方式是:
ipf -Fa -f /etc/ipf.rules ipnat -FC -f /etc/ipnat.rules
如果想清空规则,则请运行:
ipf -Fa ipnat -FC
还可以用ipfstat、ipftest等工具进行简单的调试。
Copyright © 2006 WorldHello 开放文档之源 计划 |