博威---云架构决胜云计算

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 2285|回复: 0

Linux 组网---如何用老式奔腾机和 Linux 构建防火墙

[复制链接]
发表于 2007-5-13 21:54:20 | 显示全部楼层 |阅读模式
Linux 组网如何用老式奔腾机和 Linux 构建防火墙
级别: 初级
Rawn Shah ([email=rawn@rtd.com?subject=Linux 组网&cc=rawn@rtd.com]rawn@rtd.com[/email]), 技术专家和自由撰稿人

1999 年 9 月 01 日
嘿,我在说您那台老旧的奔腾计算机呢!别因为老奔腾机不如现今花哨的新硬件动力十足就把它抛弃。 它完全可以胜任小型商业或家庭办公室的网络防火墙工作。ipchains 是 Linux 下的防火墙软件,其源码可以免费获得,并能够在老式奔腾机的 T-1 连网环境下工作。与其花上几千美元从软件提供商处购买定制的防火墙软件,还不如试试这种最实惠的解决方案。下面,我将一步步地教您如何安装和配置 ipchains 软件。
老式奔腾机并不只是堵门搁脚的垃圾,它们仍可用来计算!实际上,一个装有 32MB 内存和 200-400MB 硬盘的的小机器就可以胜任小型办公网络防火墙的任务。 Linux 的紧凑版本只含有重要的系统应用程序,而没有图形用户接口和用户应用程序。安装了紧凑版本的 Linux 之后,您就可以漂亮地把老机器变成防火墙了。
完成这些只需要一个叫 ipchains 的公开源码的软件包,它是由 Paul "Rusty" Russell 提供的。这个软件具备了许多商业防火墙产品的特征:允许自定义网络通信量的流向,及哪些访问者可以获准进出。
早期的 ipfwadm (IP Firewall Administration) 可以运行在 2.0.X 及更低的版本的 Linux 上。后来 ipchains 取代了 ipfwadm,且能工作在所有 2.1.x 和 2.2.x 版本的 Linux 下。随着内核升级,它还将升级到 2.3.x 下的 netfilter 或其他更高版本。这么频繁更新的原因在于,防火墙的数据包过滤是基于内核本身的,因此防火墙软件就必须亦步亦趋地紧随内核变动。本文讨论了 ipchains 是什么,它能做什么以及如何应用于不同场合。
Ipchains 和防火墙
ipchains 本质上是包过滤器。它检查到达网络接口的 IP 包,根据事先定义好的规则进行修改,然后再转发给其它接口。
每个 IP 包都含有报头 ( header),里面含有该包的目的地、及如何处理等控制信息(参见下图)。需要传送的数据则放在有效段(或称为包体)中。通常情况下,有效段可以包含更高一级的包。例如,一个 TCP 包就总是包含于 IP 包的有效段中,该 TCP 包拥有自己的报头和有效段。我们将会看到,ipchains 软件可以改变 IP 报头、TCP 报头、UDP 报头(未显示)和 ICMP 报头内的一些域值.



ipchains 的名称来自其工作特点。它能够创建合理过滤步骤,根据用户定义的规则来处理包。这些步骤被"链接"在一起来创建包处理的完整规则体系。这个处理"链条"可以与具体的 IP 地址,或者网络地址相结合。如下所示,系统中可以有很多这样的"链条"来处理每个进入的 IP 包:



运行 ipchains 的机器可以拥有许多网络接口,每个接口都连接在不同的网络上。任何可用的防火墙至少应有两个独立的接口,一个连到内部网络,另一个连到外部网络。数据包从一个接口进入,经由过滤"链条" 传给另一个接口。
最简单的情况下,ipchains 只执行三种策略:接受、和拒绝。它能接受来自指定 IP 地址或网络的所有包,否决策略丢弃来自特定地方的所有包。拒绝策略则丢弃来自指定源头的包,并且通知该源头其请求的连接被拒绝.
有三类基本的链: 输入链正向链输出链 。输入和输出链分别处理对应于进入和流出接口的包的执行策略。正向链直接将通信量传送给另一机器(在其执行了输入链后)。这里的"另一"机器多数情况下是路由器。ipchains 本身并不希望成为完全的路由引擎,所以它把包转交给本机上的真正的软件路由器或者另一节点上的硬件路由器。完整的ipchains引擎处理流程图如下所示:



防火墙是可以那些能够操纵输入数据流和选择可流出数据流的设备的通称。在执行过程中,它可能会改变输入或输入数据流的状态,以此隐藏机器的具体信息或防止非法入侵。
ipchains 有两种运行方式:代理服务器和网络地址转换器。前者接收来自受防火墙保护的网络内部机器的数据流,使用用户定义的规则对其进行过滤处理,然后发送给外部网络。总之,内部哪些机器可以访问外部网络是由代理服务器控制的,反之亦然。
当您没有足够的网络地址,或者不愿对您的内部网络使用公共因特网址时,可以采用网络地址转换器 (NAT) 或是 IP 屏蔽 (Masqing) 的方法。它能把内部私有的地址转换成合法的公共地址,即将多个内部地址映射成唯一的外部地址。这样就不能从外部网络上直接访问到内部网络的某个机器,从而达到保护内部机器的目的。




回页首


安装防火墙
把一台 linux 机器配置成防火墙不是那么容易的。您应该重新安装稳定的 Linux 版本(即并非最新最强大的版本,可以试试 2.2.12),而不是转变已有的 Linux 机器。在安装过程中,最好只安装那些最基本的系统组件。除非不得已的情况,一般不要安装网络服务器、NFS服务器或者编译程序等其他组件,甚至不能运行Telnet服务器。如果您必须通过网络登录到本机,那就安装"SSH Secure Shell" (ssh) 远程登录系统吧。总之需要记住,防火墙永远不应该执行除了处理包和网络安全之外的任务。
您使用的 Linux 中可能附带着 ipchains 软件。如果您是偏执狂,可以在确认主要的Linux提供商已经认证其合格后,才使用该版本。
首先要做的事情是确认您的机器上是否已经安装了防火墙。请查看 /etc/rc.d/init.d 目录下有没有类似于 packetfilter、ipchains、pifwadm、firewall 或 proxy 等名字的"开始/关闭"脚本。如果存在这样的文件,并且有来自 /etc/rc.d/rc2.d 或 /etc/rc.d/rc3.d 的符号连接,那么该机器上很可能已安装了防火墙,也许它还正运行在没有任何具体防火墙策略的环境下呢。要验证这一点,可以敲入如下命令:
# cat /proc/sys/net/ipv4/ip_forward 如果找不到这个文件,说明防火墙尚未安装。如果返回值为0,则意味着防火墙已经安装但没有运行;返回值为1表示正在运行。
您也可以下载 ipchains 的源码 来自己编译。这么的时候,要运行校验和程序来确认这份源码是可靠的。(通常采用 md5sum <filename> 命令)。ipchains 网站上列出了校验和的有效值,您校验的结果应该和它们完全匹配。当前的 ipchains 版本是 1.3.9。
如果这些值全部无法匹配,就得查查编译内核时是否把 Masquerading 打开了。缺省情况下,这些选项在编译内核时是打开的。但如果您决定自己来编译 Linux 2.2.x 版本的内核,就必须对如下选项说 YES :
CONFIG_EXPERIMENTALCONFIG_MODULESCONFIG_NETCONFIG_FIREWALLCONFIG_INETCONFIG_IP_FORWARDCONFIG_IP_MASQUERADECONFIG_IP_MASQUERADE_IPPORTFW CONFIG_IP_MASQUERADE_IPAUTOFWCONFIG_IP_MASQUERADE_ICMPCONFIG_IP_ALWAYS_DEFRAGCONFIG_DUMMYCONFIG_IP_MASQUERADE_MFW

内核编译完毕,就要把防火墙安装为系统服务的一项。这样系统 初始化 时就会启动它。系统服务是系统启动过程中由系统初始进程执行的,不同的系统服务有不同的初始化优先级别。级别 0 表示系统完全卸载可以关断电源;级别 1 则表示没有网络支持的单用户模式;级别 2 和 3 一般用作网络支持的多用户模式,也就是多数机器的运行模式。还有一些其他的级别,但都不常用。
为了创建防火墙服务的开始脚本并安装在级别 2 和 3 下,首先要如下所示创建 ipchains 的系统"开始/关闭"脚本文件,并把它保存在 /etc/rc.d/init.d 或 /etc/init.d/ 目录下(保存在哪个目录据所使用 Linux 版本而定)。
#!/bin/sh# Firewalling with ipchains, startup/shutdown scriptPATH=/sbin:/bin:/usr/sbin:/usr/bin[ -f /etc/packetfiler.rules ] || exit 0     case "$1" in         start)             echo -n "Starting ipchains firewall:"             /sbin/depmod -a# Comment the following line if you do not intend to support # using FTP through the firewall             /sbin/modprobe ip_masq_ftp# Insert lines to support other application protocols here             /sbin/ipchains-restore < /etc/firewall.rules || exit 1             echo "1" > /proc/sys/net/ipv4/ip_forward# If you do NOT use PPP, SLIP or DHCP for any of your network # interfaces on this machine, comment the following line              echo "1" > /proc/sys/net/ipv4/ip_dynaddr             echo "."             ;;         stop)             echo -n "Shutting down ipchains firewall:"             echo "0" > /proc/sys/net/ipv4/ip_forward# Comment the following line if you do NOT use PPP, SLIP or DHCP             echo "0" > /proc/sys/net/ipv4/ip_dynaddr             /sbin/ipchains -X             /sbin/ipchains -F             /sbin/ipchains -P input ACCEPT             /sbin/ipchains -P output ACCEPT             /sbin/ipchains -P forward ACCEPT             echo "."             ;;         *)             echo "Usage: /etc/rc.d/init.d/packetfilter {start|stop}"             exit 1             ;;     esacexit 0

在要从不同级别执行包过滤服务之前,您得建立符号链接。网络已经启动的情况下,首先确认包过滤器已运行在初始级别2和3下。
# ln -s /etc/rc.d/init.d/packetfilter /etc/rc.d/rc2.d/S09packetfilter# ln -s /etc/rc.d/init.d/packetfilter /etc/rc.d/rc3.d/S09packetfilter

以上两条命令建立了符号链接,从而保证在 Red Hat Linux 的网络有效前启动包过滤器。某种网络服务的名称应该类似于 SXXnetwork,其中的 "XX" 指定了该服务的启动次序。请选择一个其他启动脚本内未指定的,比所有网络服务启动次序号都低的"XX"。上面的例子中,网络启动脚本命名为 "S10network" 。
类似的,在网络服务关闭后也应该停止包过滤器的符号连接。该例子中,网络接口关闭位于脚本 K90network,因此包过滤器脚本链接为 K91packetfilter。
# ln -s /etc/rc.d/init.d/packetfilter /etc/rc.d/rc0.d/K91packetfilter# ln -s /etc/rc.d/init.d/packetfilter /etc/rc.d/rc1.d/K91packetfilter

最后,在 Red Hat 系统中,您务必确保文件 /etc/sysconfig/network 中含有下列条目:
FORWARD_IPV4="yes"

一旦重新启动机器,包过滤器就启动了。到目前为止,您还没有制定任何过滤规则。下面我们将继续这个规则设置步骤。




回页首


配置防火墙
如果您用了防火墙,就可以使用公共因特网上无效的某段网址,或者用 NAT 。这样,主干网的主要路由器将视那些来自私人地址的包为非法而予以丢弃。这些段址已经定义并在文献 RFC 1918 列举出来(参看表 1)。这样的段址共有三套,但对于绝大多数公司来说,192.168.0.0 就足够了。在下面的例子中我们也将采用这套段址。
表 1: 分配给私有网络的 IP 地址
起始地址 结束地址 CIDR 段址前缀 地址数目
10.0.0.0 10.255.255.255 10.0.0.0/8 ~ 16,000,000
172.16.0.0 172.31.255.255 172.16.0.0/12 ~ 4,000,000
192.168.0.0 192.168.255.255 192.168.0.0/16 ~ 65,000

您的内部网的全部机器都应该用这些给定地址范围来标识。比如 192.168.1.22 防火墙的内部接口应占用第一个地址 192.168.0.1。以 .0.0、.0、.255 和 .255.255 结尾的是系统保留地址,所以不要把他们分配给任何机器。在起始地址和结束地址范围之内的其他 IP 地址可按个人喜好分配.
下面的例子包括四个台式机和四个服务器。名为 stranger 的台式机禁止进入防火墙保护的内部网络,而 familiar 则可以。名为 Freedom 的服务器位于公司内部网络,但不受防火墙保护,这对向公开的网站来说是常见的。分配给这些机器的网络地址是随便给定的,但是它们被划分成不同的网络地址集合 (192.168.x.x 分配给防火墙内部网, 216.19.15.x 分配给防火墙外部但仍处于公司内部的网络, 198.102.x.x 指的是公共因特网址)。



表 2: 链操作命令
命令 陈述
ipchains -N <chain-name> 创建一个新链
ipchains -X <chain-name> 删除已有链
ipchains -L <chain-name> 列出链中的所有规则
ipchains -F <chain-name> 删除链中的所有规则,但仍保留该链
ipchains -Z <chain-name> 删除与链相关的统计数据
ipchains -P <chain-name> <policy> 设置链的全部策略(接受 ACCEPT, 否决 DENY, 拒绝 REJECT, 屏蔽 MASQ, 改向 REDIRECT, 返回 RETURN 等)
ipchains -M -L 列出所有使用屏蔽的链
ipchains -M -S <timeout-values> 对所有使用屏蔽的链,根据协议不同而分配若干超时限制

表 3: 定义过滤规则的命令
命令 陈述
ipchains -A <chain-name> <rule> 将规则添加到链中
ipchains -D <chain-name> <rule-number> 根据规则在链中的位置,删除该规则
ipchains -R <chain-name> <rule-number> <rule> 根据规则在链中的位置,用新规则取代它
ipchains -I <chain-name> <rule-number> <rule> 将新规则插入到链中的指定位置
ipchains -C <chain-name> <protocol-info> 使用链中的规则来过滤 protocol-info 中的内容,从而测试该链

表 3 中的过滤规则命令需要指定源和目的地址、协议类型和相关的端口号、其他IP协议的标志、以及所施行于它们的规则。这些规则条目可以逐一列出,以便或含糊或准确的描述被过滤掉的包的类型。
源地址 (-s) 和目的地址 (-d) 具有相同的格式。您可以具体指定单个主机地址或某网络的一组主机地址。前一种情况,只需要插入主机地址;后一种情况则需要指定网络地址和网络地址掩码或比特掩码。比特掩码和网络掩码的作用是一样的,不同于网络掩码给定四组十进制数,它从网络掩码的左端开始计入比特数。例如,网络掩码 255.255.255.0 等效于比特掩码 24,255.255.224.0 等效于 19。不方便的是,您不能指定任意范围的网络地址,比如从 192.168.1.1 到 192.168.1.133 ―― 因为您无法用合适的网络掩码来表示它们。这个软件不得不这么工作,因为想要使它有效地过滤任意一段网络地址实在是太困难了。
规则 陈述
-d 192.168.1.24 -j ACCEPT 接受所有发送到 192.16.1.24 (Jane) 的包
-d 192.168.0.0/255.255.224.0 -j DENY 拒绝所有试图到达 192.168.1.0 到 192.168.31.255 范围中某个地址的数据包,这就意味着 Bob, Fred 和 Jane 的主机都被保护起来,而 Olivia 则没有。
-d 192.168.0.0/19 -j DENY 和上一命令相同,只是用比特掩码来表示范围的结束地址。
上面的例子展示了目的地址的细节(用 -d ),但和源地址的用法是相同的(只是代之以 -s )。下一个策略组件是协议类型。ipchains 支持三种常用的传输协议类型:TCP、UDP 和 ICMP。其他协议仍处于试用阶段,这里略过不谈。
-p TCP -s 192.168.1.24 -j ACCEPT 接受所有来自 Jane (192.168.1.24) 的包
-p TCP -d 192.168.0.0/19 -j DENY 否决所有到达 Bob, Fred 和 Jane 的 TCP 包
-p TCP -d 192.168.1.24 80 -j ACCEPT 接受到达 Jane 机器80端口的所有 TCP 包
-p TCP -d 192.168.1.24 www -j ACCEPT 和上一命令类似,但用 www 来表示缺省的 Web 服务器端口。在 /etc/services 文件中定义了此端口。
-p TCP -d 192.168.1.24 0:1024 -j DENY 否决所有要到 Jane 的0到1024范围中任何一个端口的 TCP 包。
-p TCP -d 192.168.1.24 www -j ACCEPT 接收要到 Jane 机器上 www 端口(缺省情况下即80端口)的所有 TCP 包。
-p TCP -d 192.168.1.24 ! www -j DENY D 否决要到 Jane 机器上 www 之外任何端口的 TCP 包。命令中的感叹后(!)表示对它后面的值取非,这里即用 ! www 来表示除了 www 之外的所有端口值。
-p TCP -d ! 192.168.1.24 www -j DENY 否决要到除了 Jane 之外的其他机器 www 端口的所有 TCP 包。注意这条命令与上一条并不相同。
-p TCP -d ! 192.168.1.24 ! www -j DENY 否决所有要到 Jane 之外的其他机器,并且非 www 端口的 TCP 包。也就是说,它允许那些到达 Jane 的 www 端口的 TCP 包。尽量不要用这样的规则,以免引起混乱。
-p ! TCP -d 192.168.1.24 -j DENY 否决所有要到 Jane 机器上的 TCP 之外的数据包。
对于 UDP 协议,其工作情况类似。而对于支持 ping 和 traceroute 的 ICMP 协议则需要指定端口.
-p ICMP -d 192.168.1.24 0 -j ACCEPT -p ICMP -d 192.168.1.24 8 -j ACCEPT 接受对 Jane 的 ping 包。为了让 ping 正常工作,这两条规则(ICMP 端口0 和 8)必须分开写。
-p ICMP -d 192.168.1.24 3 -j ACCEPT 如果 Jane 机器上的用户试图访问一个远程站点,所返回的“无法到达” ICMP 消息允许通过。访问一些远程机器的 telnet 或其他服务时,常有这种没有回应的情况发生,因此通常都会使用这条规则。
-p ICMP -d 192.168.1.24 11 -j DENY 否决来自防火墙外部 traceroute 命令的数据包。
除了地址和协议信息,您还可以指定通过包的网络接口驱动程序。如果要加入考虑数据包的来源,是比较容易的,在指定过滤规则应用的网络端口时也很有用。
-i eth0 -s 192.168.1.24 -j ACCEPT 使用第一块以太网卡 (eth0) 来接受所有来自 Jane 的数据包。
-i eth+ -s 192.168.1.24 -j ACCEPT 可以用任何一块网卡 (eth+) 来接受来自 Jane 的数据包。
-i ppp0 -p TCP -s 198.102.68.2 1025:65535 -j ACCEPT 通过 ppp 接口,来接受所有来自 familiar (198.102.68.2) 1025 到 65535 端口之间的 TCP 包。
有两种特殊的策略组件指定 TCP_SYN 标志 (-y) 和碎片包 (-f)。当 TCP 客户端第一次试图连接远程 TCP 服务器时,TCP_SYN 标志被设置。不幸的是,黑客会利用它攻击远程服务器,其做法是发送大量 TCP_SYN 消息而不真正连接服务器,从而锁住所有服务器进程,使其速度变慢或使服务器崩溃。只要为该组件指定 TCP 组件 -p,就可以阻止外部的 TCP_SYN 攻击。
碎片包过滤规则组件是必要的,因为 IP 包常常通过不同容量的的网络连接。有时他们不得不分成一些名为 碎片 的更小的包以便顺利通过小容量的连接通道。在 PPP 协议下用调制解调器连接网络时常发生这种情况。例如,以太网可以传送长为 1500 字节的 IP 包,而调制解调器(串行线)的包通常是 256 字节;以太网量级的包不得不分成六份以符合调制解调器量级的碎片包。到达目的机器后,这些碎片包就被组合起来。因此,在 PPP 或 SLIP 协议下使用调制解调器连接网络时,您应该指定这个规则组件,这样防火墙才会把包视作一体。也只有如此它才能正确辨识传输层协议( TCP, UDP, ICMP) 信息,从而实施其他规则。
在命令行下运行以上规则,并用 /sbin/ipchains -L 命令检查其顺序是否正确。接着还要按照"开始/关闭"脚本指定的文件名来保存这些规则(我们的例子中,该文件是 /etc/firewall.rules )。下次系统启动时就会使用这些规则了。需要注意的是,每次您定义新规则都必须运行以下命令:
# /sbin/ipchains-save > /etc/firewall.rules

接下来给出一些配置实例,您可以看到如何为防火墙制定规则。




回页首


一些配置实例
这个例子是最简单的防火墙模型,只允许位于保护范围内的机器访问外部网络,但禁止任何外部机器进入内部网络。您首先要拦截由任何接口流出的所有包,然后只让那些具有转换过的地址信息的包通过。
# /sbin/ipchains -P forward DENY# /sbin/ipchains -A forward -f -i ppp0 -j MASQ

采用以上两个规则,则在包流出之前,所有安装了防火墙的机器(Bob,Fred,Jane 和 Olivia)都被屏蔽了。同时禁止防火墙外部的机器接触任何内部设备。这里并没有涉及路由器,实际上本例中的防火墙是通过调制解调器建立到因特网 PPP 连接的。
嵌入路由器的防火墙代码并不少见。很多时候,防火墙和路由器可能位于同一机器。另一方面,利用 PPP 的调制解调器方案,防火墙就成为路由器,路由指令把所有非本地数据流转发到 PPP 端口。
您可能希望防火墙的功能复杂些,例如所有保护范围内的机器都可连到外部去,而只有指定的外部机器才能连接进来。下面的例子准许名为 familiar 的机器 (198.102.68.2) 连接到防火墙内部机器的某些指定端口 (telnet、FTP 和 WWW 等服务的公共端口)。
# /sbin/ipchains -P forward DENY# /sbin/ipchains -A forward -f -i eth0 -j MASQ# /sbin/ipchains -A input -i eth0 -s 198.102.68.2 -j ACCEPT# /sbin/ipchains -A output -i eth1 -s 198.102.68.2 -d 0/0 -j DENY# /sbin/ipchains -A output -i eth1 -s 198.102.68.2 -d 0/0 telnet -j MASQ# /sbin/ipchains -A output -i eth1 -s 198.102.68.2 -d 0/0 ftp -j MASQ# /sbin/ipchains -A output -i eth1 -s 198.102.68.2 -d 0/0 ftp-data -j MASQ# /sbin/ipchains -A output --i eth1 s 198.102.68.2 -d 0/0 www -j MASQ

在我们的例子中,有台名为 Freedom 的服务器位于防火墙网络外但处于公司网络内部。这是一台任何机器都可达的公共网页服务器,它和互联网上其他计算机一样,可能遭受外部世界的攻击和破坏。不过我们可以假定它足够安全,并允许其连接到防火墙内部网络。这就需要添加下列规则:
# /sbin/ipchains -A input -i eth0 -s 216.19.15.32 -j ACCEPT# /sbin/ipchains -A output -i eth1 -s 216.19.15.32 -d 0/0 -j MASQ





回页首


应用协议
有些应用要求协议包含正确的主机地址信息,否则无法工作。这些应用可能会将网络或主机地址信息嵌入到 TCP 或 UDP 包里,但包过滤器一般不深入探究这些包中的内容。
如此一来,为了过滤这些应用协议内核还需要加载另外的模块。这些模块包含某些协议,能够支持 FTP、RealAudio、IRC、VDO Live、CU SeeMe 甚至某些流行的游戏 Quake 等。
为了加载这些模块,可以在先前的"开始/关闭"脚本中加入以下用于特殊协议的代码行:
/sbin/modprobe ip_masq_raudio/sbin/modprobe ip_masq_irc/sbin/modprobe ip_masq_cuseeme/sbin/modprobe ip_masq_vdolive /sbin/modprobe ip_masq_quake/sbin/modprobe ports=ip_masq_quake 26000,27000,27910

ipchains 具有十分强大的功能,可以把几组规则一次"链接"。当您需要面对许多内部节点,并为它们分别定义网络数据包策略时,这种建立多链条的能力就更加重要。这些链条被指派给特定的网络接口,改变接口开关的安全规则(例如网络连接接通或断开)。
ipchains 将继续升级。随着下一内核版本 (2.3.x 和 2.4.x) 一起发布 ipchains 新版本,名为 netfilter 。新版本软件将能执行一些设计精巧的组件,例如逆向网络地址转换 (reverse NATs),用于使一组内部网机器为某个地址进行负载平衡。
一般情况下,有效使用 ipchains 可以让您的内部网络细节受到防火墙良好的保护。它赋予您那台"慢吞吞"的老机器以崭新的使命,变成网络里相当有用的一员。


参考资料


关于作者

Rawn Shah,是一名网络管理员、系统程序员、网络架构专家和因特网服务提供商。从 1993 年起他就为十来家以英语及其他语言发行的因特网杂志撰写文章。最近刚写完名为《UNIX和Windows 2000集成的套装工具包》( UNIX and Windows 2000 Integration Toolkit, John-Wiley &Sons,1999) 的书籍。现在他是亚利桑那州 Tucson 的一名技术专家,负责撰写有关网络和交叉平台集成的专题文章。您可以通过 [email=rawn@rtd.com?cc=rawn@rtd.com]rawn@rtd.com[/email]与他联系。





















防火墙非常有趣,但在需要对防火墙规则进行快速且复杂的更改时,您会做些什么?很简单。请使用本文中演示的 Daniel Robbins 的动态防火墙脚本。可以使用这些脚本来增加网络安全性和响应性,并激发您自己的创造性设计。
了解动态防火墙脚本好处的最佳方法是在运行时查看它们。要这样做,让我们假设我是一家 ISP 的系统管理员,最近我建立了基于 Linux 的防火墙,用于保护我的客户和内部系统免遭因特网上恶意用户的攻击。为了实现这个目的,我的防火墙使用新的 Linux 2.4 iptables 有状态功能,以允许我的客户和服务器建立新的外出连接,当然还允许新的进入连接,但仅限于“公共”服务,如 web、ftp、ssh 和 SMTP。由于我使用了缺省拒绝设计,因此会自动拒绝任何从因特网到非公共服务(如 squid 代理缓存或 Samba 服务器)的连接。现在,我有一个非常不错的防火墙,它为我公司的所有客户提供了非常好的保护。
在第一个星期左右,防火墙的工作非常出色,但在这之后却发生了件讨厌的事:我最大的对手 Bob(他为另一家 ISP 工作,是我们的竞争对手)决定用大量信息包攻击我的网络,试图阻止我向客户提供服务。糟糕的是,Bob 已经仔细研究了我的防火墙,他知道我在保护内部服务时,端口 25 和 80 必定是可以公开访问的,这样我才可以接收邮件和响应 HTTP 请求。Bob 决定利用这一点,他想用吸干带宽的方法来攻击我的 Web 和邮件服务器。
大约在 Bob 实施攻击一分钟之后,我注意到信息包逐渐占满了上行链路。在查看了 tcpdump 的情况之后,我确定这还是 Bob 实施的另一次攻击,我推算出他用于发起攻击的 IP 地址。现在我已经有了这个信息,我需要做的就是阻止这些 IP 地址,我想这大概能解决问题 -- 很简单的解决方案。
响应攻击
我迅速使用 vi 打开防火墙设置脚本,并开始改动 iptables 规则、修改防火墙,这样它就可以阻止那些 Bob 发出的恶意进入信息包。大约一分钟左右,我找到了添加合适 DROP 规则的确切位置,并添加了这些规则。然后,我启动防火墙,但又马上停止了它……哎,我在添加规则时犯了一个小错。我再次装入防火墙脚本,改正问题,30 秒之后,将已将防火墙调整成阻止这个月内 Bob 发起的所有攻击。起先,它似乎成功地挫败了攻击……直到问讯台的电话铃声响起。显然,Bob 已经中断我的网络大约 10 分钟,现在我的客户打电话来询问究竟发生了什么情况。更遭的是,几分钟后,我发现上行链路又被占满了。看来 Bob 这次使用了一组全新的 IP 地址来实施攻击。我也做出响应,立即开始修改防火墙脚本,只不过这次我有一点惊慌 -- 也许我的解决方案还不那么完美。
以下就是上述情况中出错的原因。虽然我有一个不错的防火墙,还迅速标识了网络问题的原因,但我无法修改防火墙的行为以使它能够及时应付威胁。当然,当网络受到攻击时,您希望能够立即响应,在紧急状态下被迫修改主防火墙设置脚本不仅在时间上很紧迫,而且效率非常低。




回页首



ipdrop
如果有一个特别设计的特殊 "ipdrop" 脚本,它可以插入阻止我指定的 IP 地址所需的规则,那么情况会好多了。有了这样的脚本,阻止防火墙就不再是两分钟的折磨;它只需 5 秒钟。由于这个脚本可以让我不必手工编辑防火墙规则,这就消除了出错的主要根源。我所要做的只是确定要阻止的 IP 地址,然后输入:
#                 ipdrop 129.24.8.1 onIP 129.24.8.1 drop on.            

ipdrop 脚本会立即阻止 129.24.8.1,这是本周 Bob 的当前恶意 IP 地址。这个脚本明显提高了您的防御能力,因为现在阻止 IP 并不是件费神的事。现在,让我们看一下 ipdrop 脚本的实现:


ipdrop bash 脚本
#!/bin/bashsource /usr/local/share/dynfw.shargs 2 $# "${0} IPADDR {on/off}" "Drops packets to/from IPADDR. Good for obnoxious                                  networks/hosts/DoS"if [ "$2" == "on" ] then    #rules will be appended or inserted as normal                APPEND="-A"    INSERT="-I" rec_check ipdrop $1 "$1 already blocked" on    record ipdrop $1elif [ "$2" == "off" ]then    #rules will be deleted instead                APPEND="-D"    INSERT="-D" rec_check ipdrop $1 "$1 not currently blocked" off    unrecord ipdrop $1else    echo "Error: \"off\" or \"on\" expected as second argument"    exit 1fi                 #block outside IP address that's causing problems#attacker's incoming TCP connections will take a minute or so to time out,#reducing DoS effectiveness.iptables $INSERT INPUT   -s $1 -j DROPiptables $INSERT OUTPUT  -d $1 -j DROPiptables $INSERT FORWARD -d $1 -j DROPiptables $INSERT FORWARD -s $1 -j DROPecho "IP ${1} drop ${2}."            





回页首


ipdrop:说明
如果留意最后突出显示的四行,您会看到将适当规则插入防火墙表的真正命令。可以看到,$INSERT 环境变量的定义随着运行方式是 "on" 还是 "off" 而变化。iptables 行执行时,会适当插入或删除特定规则。
现在,让我们看一下规则本身的功能,规则应该与任何类型的现有防火墙或甚至在没有防火墙的系统上正常工作;您所需要的只是 2.4 内核中的内置 iptables 支持。我们阻止来自恶意 IP(第一个以 iptables 开头的行)的进入信息包,阻止标题为恶意 IP(下一个以 iptables 开头的行)的外出信息包,然后关闭涉及这个特殊 IP(最后两个以 iptables 开头的行)的转发。一旦这些规则就位,系统就只废弃任何属于其中一个类别的信息包。
另一个简短注释:您还会注意到对 "rec_check"、"unrecord"、"record" 和 "args" 的调用。这些是在 "dynfw.sh" 中定义的 helper bash 函数。"record" 函数将被阻止的 IP 记录到 /root/.dynfw-ipdrop 文件中,而 "unrecord" 从 /root/.dynfw-ipdrop 中除去记录项。如果要重新阻止一个已被阻止的 IP,或者取消阻止当前未阻止的 IP,可以使用 "rec_check" 函数来放弃带错误消息的脚本。"args" 函数负责确保我们接收到正确数量的命令行自变量,它还负责打印有帮助的用法信息。我已经创建了包含所有这些工具的 dynfw-1.0.tar.gz;有关详细信息,请参阅本文结尾的 参考资料部分。




回页首



tcplimit
如果需要限制使用某个特定基于 TCP 的网络服务,可能是某些会在终端上产生大量 CPU 负载的服务,那么下一个动态防火墙脚本会非常有用。这个脚本称作 "tcplimit",它使用一个 TCP 端口、一个速率、一个比例和 "on" 或 "off" 作为自变量:
#                 tcplimit 873 5 minute onPort 873 new connection limit (5/minute, burst=5) on.            

tcplimit 使用新的 iptables "state" 模块(确保已经在内核中启用了这个模块或已经装入了这个模块),以在某个特定时间周期内只允许一定数量的新进入连接。在本示例中,防火墙只允许每分钟有 5 个新连接到 rsync 服务器(端口 873) -- 如有必要,可以指定您希望每秒/分钟/小时或每天有多少连接。
tcplimit 为限制非基本服务提供了一个好方法 -- 因此对非基本服务的大量通信量不会中断网络或服务器。在我遇到的情况中,我使用 tcplimit 来设置使用 rsync 的最大上限,以防止太多 rsync 连接占据我的 DSL 线路。限制了连接的服务都记录在 /root/.dynfw-tcplimit 中,如果我要关闭新连接限制,只要输入:
#                 tcplimit 873 5 minute offPort 873 new connection limit off.            

tcplimit 运行时会在 "filter" 表中创建一个全新的链。这个新的链将拒绝所有超出指定限度的信息包。然后,一个规则将插入 INPUT 链,该 INPUT 链将要发送到目标端口(本例中是 873)的所有进入 NEW 连接信息包重定向到这个特定链,这样便有效地限制了新的进入连接,但又不会影响所建立连接中的信息包。
关闭 tcplimit 时,INPUT 规则和该特定链将被删除。这是件奇妙的事,它真正体现了让经过精心测试的、可靠的脚本来为您管理防火墙规则的重要性。由于使用了 ipblock,tcplimit 脚本将与任何类型的防火墙,甚至 没有 防火墙的系统兼容,只要您在内核中启用了正确的 iptables 功能。




回页首



host-tcplimit
host-tcplimit 非常类似于 tcplimit,但它限制某些新的 TCP 连接,这些连接来自某个特定 IP 地址并且指向您的服务器上某个特定 TCP 端口。host-tcplimit 特别适用于防止某个人滥用您的网络资源。例如,假设您在运行 CVS 服务器,而您发现某个新的开发人员似乎建立了一个脚本来每隔 10 分钟就用资源库更新它的源码,这样每天就消耗了大量的多余网络资源。然而,当您给他发送电子邮件以指出他的错误行为时,却会收到一条进入消息,全文如下:
嗨,伙计!我很荣幸能参与您的开发项目。我刚创建了一个脚本,用来每隔 10 分钟更新一次代码的本地副本。我将出去旅游两个星期,但等到回来之后,我将会得到最新的源代码,那时我就可以交差了!现在我要出门了……两周后再见!谨启,Newbie(新手)对于这种情况,一个简单的 host-tcplimit 命令就可以解决问题:
#                 host-tcplimit 1.1.1.1 2401 1 day on                                   

现在,限定了 Newbie 先生(IP 地址 1.1.1.1)每天只能有一个 CVS 连接(端口 2401),这样就节省了许多网络带宽。




回页首



user-outblock
最后一个,也可能是所有动态防火墙脚本中最有趣的一个就是 user-outblock。这个脚本提供了一种理想的方式,它允许特定用户 telnet 或 ssh 到您的系统中,但不允许这个用户从命令行建立任何新的外出连接。以下的示例适合于使用 user-outblock。假设有一个特殊家庭在我的 ISP 拥有帐户。父母使用图形电子邮件客户机来阅读他们的邮件,偶尔也会在网上冲浪,但他们的儿子恰巧是位狂热的黑客,他经常使用 shell 访问来对他人的计算机搞一些恶作剧。
一天,您发现他与一些系统建立了 ssh 连接,而那些系统似乎属于巴基斯坦武装力量 -- 啊,天哪!您想要引导这个年轻人参加更有益的活动,所以应执行以下操作:
首先,应检查系统,确保已除去了所有网络二进制程序(如 ssh)中的 suid 位:
#                 chmod u-s /usr/bin/ssh                                   

现在,他试图用来与网络交互的任何进程都属于他自己的用户标识。现在您可以使用 user-outblock 阻止这个用户标识(恰巧是 2049)启动的所有外出 TCP 连接:
#                 user-outblock 2049 onUID 2049 block on.            

现在,他可以登录和阅读邮件,但不能使用您的服务器来建立 ssh 连接以及类似连接。现在,他可以在自己家的个人计算机上安装 ssh 客户机。然而,如果要限制他家的个人电脑到 Web、邮件和外出 ssh 连接(仅限于到您的服务器),建立这样的动态防火墙脚本也不太难。

参考资料
  • 您可以参阅本文在 developerWorks 全球站点上的 英文原文.
  • 由于我发现这些动态防火墙脚本如此实用,我已经创建了一个小巧的 tarball (dynfw-1.0.tar.gz) 文件,您可以将它下载并安装到您的机器上。 如果要安装,解开 tarball,运行其中的 install.sh 脚本。此脚本将一个共享的 bash 脚本安装到 /usr/local/share/dynfw.sh 中,并将动态防火墙脚本安装到 /usr/local/sbin。如果希望将它们安装到 /usr/share 和 /usr/sbin 中,在运行 install.sh 之前只要输入以下命令:
                                                                            # export PREFIX=/usr                                                            

    我还将动态防火墙脚本代码部分添加到 Gentoo Linux 网站上,您可以访问这个网站以获取最新版本的 tar 文件。我还要继续改进,并添加到这个集合中,以使全世界的系统管理员可以使用真正实用的资源。在我们的内核中已经有了 iptables,应该开始利用它!
  • tcpdump 是研究低级信息包交换和验证防火墙是否正常工作的必备工具。如果您还没有,想方法弄到它。如果已经有了,则应该使用它。如果已经使用它了……干得好!
  • netfilter 小组的主页 上有许多优秀的资源,包括 iptables 源码,有 Rusty 的优秀作品 "unreliable guides" 。这些作品包括基本网络概念 HOWTO、netfilter (iptables) HOWTO、NAT HOWTO 和适合于开发人员的 netfilter 修改 HOWTO。该网站上还有 netfilter 常见问题解答以及其它内容。
  • 网上还有许多好的 netfilter 资源;但是,不要忘了基础知识。iptables man 页面非常详细,并且它是 man 页面的范例。
  • 现在可以使用 高级 Linux 路由和流量控制 HOWTO 。它很好地显示了如何使用 iptables 来标记信息包,然后根据这些标记来使用 Linux 路由功能发送信息包。
  • 可以使用 netfilter (iptables) 邮件列表,而且 有一个适用于 netfilter 开发人员。使用这些 URL 还可以访问邮件列表档案。

关于作者

Daniel Robbins 居住在新墨西哥州的 Albuquerque。他是 Gentoo Technologies, Inc. 的总裁兼 CEO, Gentoo Linux (用于 PC 的高级 Linux)和 Portage 系统(Linux 的下一代移植系统)的创始人。他还是 Macmillan 书籍 Caldera OpenLinux UnleashedSuSE Linux UnleashedSamba Unleashed 的合作者。Daniel 自二年级起就与计算机结下不解之缘,那时他首先接触的是 Logo 程序语言,并沉溺于 Pac-Man 游戏中。这也许就是他至今仍担任 SONY Electronic Publishing/Psygnosis 的首席图形设计师的原因所在。Daniel 喜欢与妻子 Mary 和新出生的女儿 Hadassah 一起共度时光。可通过 [email=drobbins@gentoo.org?cc=drobbins@gentoo.org]drobbins@gentoo.org[/email] 与 Daniel 联系。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|boway Inc. ( 冀ICP备10011147号 )

GMT+8, 2024-11-25 04:56 , Processed in 0.101236 second(s), 16 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表