《The BOOK Of PF》中文版 —— 20. 网桥式防火墙

内部资料,请勿转载,多谢。
主题已锁定
头像
whoami
铁 Fe
帖子: 76
注册时间: 2010-06-03 13:23

《The BOOK Of PF》中文版 —— 20. 网桥式防火墙

帖子 whoami » 2010-07-13 12:05

网桥式防火墙
一个以太桥由两个或更多个被配置为透明转发以太帧的网络接口构成,它并不对上一层(例如,TCP/IP堆栈)直接可见。 在过滤方面, 网桥配置也很诱人,这是因为可以在一台没有任何IP地址的机器上进行过滤。如果这台机器运行的是OpenBSD或其它有类似能力的操作系统, 它仍然可以过滤和重定向通讯。
这样设置的一个认定优势就是对这个防火墙的攻击更困难。缺点是所有管理任务必须在这个防火墙的控制台操作, 除非你配置了一个可通过某些加密网络或者串口控制台访问的接口。由此可以推论出没有配置IP地址的网桥不能被设置为一个网络的网关和不能在桥接接口上运行任何服务。 在一定程度上, 你可以认为一个网桥就是一个网线上的智能过滤分离器,它具有过滤和重定向的功能。




应用防火墙作为桥时的通用警告:
  • 接口处于混杂模式, 这意味着它们可以接收网络上的任何数据包。
  • 桥运行在以太层而且默认情况下, 它会转发所有类型的数据包, 并非仅限于TCP/IP。
  • 因为接口上没有IP地址,所以一些更有效的冗余特性是在网桥上无法实施的,例如carp。
如何配置网桥的具体细节在不同的操作系统上略有差异。下面都是很简单的例子,并未涵盖所有可能的细节, 但是它们也足以作为你的起点了。
在OpenBSD上设置基本的网桥
除非你自己编译了一个不带网桥代码的内核,OpenBSD的GENERIC内核已经包含了所有配置网桥和在网桥上过滤所需的代码,配置过程很简单明了。
要在命令行创建一个带有两个接口的网桥, 首选你需要创建这个桥设备。OpenBSD里通常某类设备的第一台编号为0, 所以我们用下面的命令创建网桥bridge0:

代码: 全选

$ sudo ifconfig bridge0 create
在运行下一个ifconfig命令前, 确认一下预设的成员接口 (在我们的例子中是 ep0 和 ep1) 可用但没有分配IP地址。

然后配置这个网桥

代码: 全选

$ sudo brconfig bridge0 add ep0 add ep1 blocknonip ep0 blocknonip ep1 up
OpenBSD的brconfig本身命令包含了不少的过滤代码, 在本例中我们为每个接口选择一个blocknonip选项,目的是阻止所有的non-IP通讯。
说明
OpenBSD的brconfig命令除了提供其它的配置选项外,还提供了自带的过滤选项。你可以参阅用户手册bridge(4)和brconfig(8)以获取更多的信息。这里值得一提的是,因为brconfig运行在以太层, 所以它可以过滤MAC地址。brconfig还可以通过tagged关键字给数据包打标记以便PF进行进一步的处理工作。
要是配置永远生效, 创建或编辑文件 /etc/hostname.ep0,然后再输入如下命令:

代码: 全选

up
对于另一个接口, 你需要在文件 /etc/hostname.ep1 里包含

代码: 全选

up
最后, 在文件 /etc/bridgename.bridge0 里输入桥设置:

代码: 全选

add ep0 add ep1 blocknonip ep0 blocknonip ep1 up
到这里你的桥已经可用了。接下来你就可以创建PF规则了。
在FreeBSD上设置基本的网桥
在FreeBSD中的过程稍微复杂一点。要使用网桥, 你运行的内核需要包含或可以导入if_bridge模块。 默认的内核配置已经编译了此模块, 所以一般情况下你可以直接创建这个接口。
如果你想将桥设备编译进内核里, 将这行

代码: 全选

device if_bridge
加入到内核配置文件里。如果你想在启动时导入这个设备,将下面这行

代码: 全选

if_bridge_load="YES"
加入到文件 /etc/loader.conf 内。
创建网桥设备,你需要运行如下的命令来创建bridge0接口:

代码: 全选

$ sudo ifconfig bridge0 create

还需要建立一系列与桥相关的sysctls:

代码: 全选

$ sudo sysctl net.link.bridge
net.link.bridge.ipfw: 0
net.link.bridge.pfil_member: 1
net.link.bridge.pfil_bridge: 1
net.link.bridge.ipfw_arp: 0
net.link.bridge.pfil_onlyip: 1

有必要检查一下这些sysctl值都可用。 如果确实可用, 则确认了这个桥已经被启用了。反之, 你需要回去查看一下什么地方错了和为什么。不过, 这些值用于桥接口本身的过滤, 所以我们无需修改这些值, 因为默认情况下已经在成员接口(管道的重点)上启用了IP层的过滤。
在运行下一个ifconfig命令前, 确认一下预设的成员接口 (在我们的例子中是 ep0 和 ep1) 可用但没有分配IP地址。

然后输入下面的命令配置网桥

代码: 全选

$ sudo ifconfig bridge0 addm ep0 addm ep1 up
要让配置永久生效, 将这面这行加入/etc/rc.conf:

代码: 全选

ifconfig_ep0="up"
ifconfig_ep1="up"
cloned_interfaces="bridge0"
ifconfig_bridge0="addm ep0 addm ep1 up"
到这里你的网桥已经可用并且你可以到这里你的网络已经可以正常工作了,你现在可以去配置PF规则了。请参阅用户手册if_bridge(4)以获取更详尽在FreeBSD的相关网桥的信息。
在NetBSD上设置基本的网桥
在NetBSD上, 默认的内核配置没有包含网桥的过滤支持。你需要编译一个定制的内核,你需要将

代码: 全选

options BRIDGE_IPF # bridge uses IP/IPv6 pfil hooks too
添加到内核配置文件里。一旦你有了包含桥代码的新内核, 剩下的设置也很简单。
要创建一个带有两个接口的桥, 首先创建桥设备bridge0:

代码: 全选

$ sudo ifconfig bridge0 create
在运行下一个ifconfig命令前, 确认一下预设的成员接口 (在我们的例子中是 ep0 和 ep1) 可用但没有分配IP地址。

接下来通过如下的命令配置桥

代码: 全选

$ sudo brconfig bridge0 add ep0 add ep1 up

然后在设备bridge0上启用过滤:

代码: 全选

$ sudo brconfig bridge0 ipf

要是配置永久生效, 创建或编辑文件 /etc/ifconfig.ep0 并输入下行:

代码: 全选

up
而另一块接口, 你需要编辑 /etc/ifconfig.ep1 并输入下行:

代码: 全选

up
最后, 在文件 /etc/ifconfig.bridge0 里进行桥设置:

代码: 全选

create
!add ep0 add ep1 up
到这里你的桥已经可用了。接下来你就可以创建PF规则了。详说明5
这里的桥规则集是我们在这章前面所说的PF为ulge-in-the-wire类型网桥准备的基本规则集。网络又有了一些变化,请参看图f5-3。
说明5
要了解更多的知识, 请参阅the PF on NetBSD documentation
附件
f5-3.PNG
未完待续、请勿转载、欢迎纠错、多谢!;)
[email]WHOAMi@点点儿[/email]

头像
whoami
铁 Fe
帖子: 76
注册时间: 2010-06-03 13:23

帖子 whoami » 2010-07-13 12:13

这些本地网络的机器共享一个公共的网关, 这个网关不是这个网桥,但是通常布置在网桥的内侧或外侧。

代码: 全选

ext_if = ep0
int_if = ep1
localnet= "192.0.2.0/24"
webserver = "192.0.2.227"
webports = "{ http, https }"
emailserver = "192.0.2.225"
email = "{ smtp, pop3, imap, imap3, imaps, pop3s }"
nameservers = "{ 192.0.2.221, 192.0.2.223 }"
client_out = "{ ssh, domain, pop3, auth, nntp, http, https, cvspserver, 2628, 5999, 8000, 8080 }"
udp_services = "{ domain, ntp }"
icmp_types = "{ echoreq, unreach }"
set skip on $int_if
block all
pass quick on $ext_if inet proto { tcp, udp } from $localnet to any port $udp_services
pass log on $ext_if inet proto icmp all icmp-type $icmp_types
pass on $ext_if inet proto tcp from $localnet to any port $client_out
pass on $ext_if inet proto { tcp, udp } from any to $nameservers port domain
pass on $ext_if proto tcp from any to $webserver port $webports synproxy state
pass log on $ext_if proto tcp from any to $emailserver port $email synproxy state
pass log on $ext_if proto tcp from $emailserver to any port smtp synproxy state
很明显,可能还有更复杂的规则设定, 尽管, 重定向规则可以正常工作, 但是你不能在这些没有IP地址的接口上运行任何服务。
处理来自其它地方不可路由地址
即使用一个正确配置的网关为你的网络处理过滤和可能的网络地址转换, 你可能还会发现由于其他人的错误配置,你自己处于“隐身”的状态。
一个令人郁闷的常见错误类型就是那种让那些带有不可路由地址的通讯出站至Internet。 来自不可路由地址的通讯也曾经作为拒绝服务(Dos)攻击的技术手段的一部分, 所以你也许要完全禁止那些来自不可路由地址的通讯进入你的网络。
一个可能的解决方案概述如下, 这个方案也足以阻止所有那些通过网关的对外接口发起的企图到不可路由地址的的通讯:

代码: 全选

martians = "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, \
10.0.0.0/8, 169.254.0.0/16, 192.0.2.0/24, \
0.0.0.0/8, 240.0.0.0/4 }"
block in quick on $ext_if from $martians to any
block out quick on $ext_if from any to $martians
这里的宏martians代表了那些 RFC 1918 地址以及那些由各种RFC保留的并非应用于Internet的地址。(译者注:这里还是解释一下吧,因为宏名称无法翻译,但如果你看到这个英文单词可能一下就明白作者的意思了,因为这里的martian的意思是火星人。) 所有来自这些地址的通讯将在网关的外接口上被直接丢弃。
即便没有其它的原因,由于大家的网络配置的不同,实施这种保护方法的具体细节也会因人而异。例如,你的网络规划里可能可能还包含了阻止一些其它的地址范围。
说明
值得一提的是,这里的宏可以用表格来表示。
未完待续、请勿转载、欢迎纠错、多谢!;)
[email]WHOAMi@点点儿[/email]

主题已锁定

在线用户

正浏览此版面之用户: 没有注册用户 和 25 访客