BBS水木清华站∶精华区

发信人: ruster (尘埃*星辰*领悟), 信区: Linux        
标  题: 第八章 路由器和防火墙(上) 
发信站: BBS 水木清华站 (Thu Dec 21 13:47:40 2000) 
 
第8章 路由器和防火墙 
   
  本章要点: 
   
  本章介绍如何进行网间互连,以及如何用Linux实现为廉价的路由器/防火墙。 
   
      本章具体包括以下内容。 
   
    基于Linux的路由器 
   
    基于Linux的防火墙系统 
   
    PPP连接和拨号服务器的配置 
   
    各种代理服务器 
   
  8.1 核心IP转发和Linux路由器 
   
  让我们首先从软件路由器开始。一般来说,Linux的软件路由器是非常容易使用的,并 
且效果也不错。通常在教育系统我们会经常看到基于软件的路由机器。许多人认为软件 
路由器速度比较慢,可靠性也比不上硬件路由器,不过,根据大部分使用者的经验,对 
于10MB的以太网,软件路由不会带来任何瓶颈问题。而大部分单位的接入速度只有256甚 
至64KB。对于100MB的系统,软件路由的速度有时跟不上网络的速度,不过考虑到正常路 
由器的速度,这也不是什么严重的问题。 
 
   
  8.1.1 Linux的IP转发功能 
 
   
  在配置内核中我们可以看到Linux内核本身就具有路由的功能,当然这些必须在编译内 
核时定义。在2.2.14的内核配置中,与之相关的配置项目有好几项,并且不少属于实验 
中的代码,所以如果你确实要使用Linux作为路由器或者防火墙你应该允许使用实验中的 
选项。在编译核心的时候,建议打开大部分与IP路由相关的选项,这些选项的含义可以 
从帮助中看到,例如IP路由,IP防火墙等等。当然你也可以用实验的方法,由于配置选 
项的名称在不断改变,我不想给出详细的说明,其实你只要自己看看那些选项的名字就 
应该差不多了,不是吗?当然,大部分发行版本的内核都是支持软件路由的,不过你还 
是自己编译一下比较好。 
   
  假设你已经正确地编译了内核,那么下一步就是启动IP转发(forwarding)功能了。IP 
转发的概念很简单,如果你的系统上有多片网卡,那么IP转发功能会把IP包在这些网卡 
接口之间传递,所以只要你开启了这个功能,Linux就可以正确地实现路由器的信息传递 
功能了。 
   
  启动IP转发的功能倒是十分简单,还记得我们在研究启动脚本的时候看到的那个直接 
在/proc文件系统下面生成文件来启动内核功能的例子吗?启动IP转发也是这样作: 
   
  echo '1' > /proc/sys/net/ipv4/ip_forward 
   
  这样,IP转发功能就被启动了。如果你需要自动启动IP转发,就把这一行添加到/etc 
/rc.d/rc.sysinit里面去。 
   
  另外一种方法是利用缺省的/etc/rc.d/init.d/network脚本,例如对于redhat,你会 
看到其中有这样的行: 
   
  if [ ! -f /etc/sysconfig/network ]; then 
   
   exit 0 
   
  fi 
 
   
  . /etc/sysconfig/network 
   
   ………………………… 
 
   
  ipv4_forward_set () 
   

   
  if [ -d /proc/sys/net/ipv4 ]; then 
   
  if [ ! -f /proc/sys/net/ipv4/ip_forward ] ; then 
   
   echo "/proc/sys/net/ipv4/ip_forward is missing --" \ 
   
                          "cannot control IP forwarding" >&2 
   
              else 
   
                  if [ "$FORWARD_IPV4" = "no" -o "$FORWARD_IPV4" = "false" ] 
; the 
   
                      value=0 
   
                      message="Disabling IPv4 packet forwarding" 
   
                  else 
   
                      value=1 
   
                      message="Enabling IPv4 packet forwarding" 
   
                  fi 
 
   
                  if [ $value != `cat /proc/sys/net/ipv4/ip_forward` ]; then 
   
                      action "$message"  /bin/true 
   
                      echo "$value" > /proc/sys/net/ipv4/ip_forward 
   
                  fi 
   
              fi 
   
          fi 
   

   
  显然,只要设置了FORWARD_IPV4这个变量并且让它等于true,系统启动的时候就会自 
动加入启动IP转发的项目,因此可以在/etc/sysconfig/network文件中加入这样一行: 
   
  FORWARD_IPV4="yes" 
   
  然后重新启动机器,就可以使用IP转发功能了。 
   
  假设我们的情况如下图所示: 
 
   
  
   
  图8.1 Linux路由 
   
  设eth0和eth1的网络地址分别是192.168.6.1和192.168.4.6,服务器接受到的IP数据 
包将自动在两个网络接口之间传递。eth0接受到的数据包将被送到内核,如果目标地址 
是192.168.6.1(eth0地址),那么服务器直接处理这个数据包;如果目标地址是192.168 
.4.x,那么数据包将被转发到192.168.4.6。然后,eth1接口根据核心的路由表,发现凡 
是192.168.4.x的数据包应该通过以太网设备直接广播出去,因此它会正确地把这个数据 
包发送出去。当192.168.4.x的机器发出一个到192.168.6.x的申请的时候,步骤正好颠 
倒过来。因此,只要把192.168.6.x和192.168.4.x的机器的路由路径中分别加入192.16 
8.6.1和192.168.4.6,就可以实现两个子网之间的正确互访。对于windows客户机,可以 
通过设置缺省网关为192.168.6.1(对192.168.6.x)和192.168.4.6(对于192.168.4.x) 
实现。 
   
  容易看到,这种互连并不对两个子网的IP地址有什么实际限制。 
   
  然而这只是实现了两个以太子网之间的互连,在实际的情况中,我们通常有不止一条 
的路由路径,或者需要实现多个网络的互连。最常见的情况是,网络系统中已经有了一 
个路由,某些子网已经能够通过它和外部网络互连,而我们现在需要增加IP地址或者分 
割子网,这时就需要在路由之间建立路径连接。也有这样的情况,我们需要通过Linux机 
器将本地局域网连接入Internet。这个时候,我们需要使用一些特殊的工具,典型的是 
IPChains。 
   
  8.1.2 Linux路由器 
   
  从上一节的内容很容易看到,用Linux实现路由功能是一件很容易的事情。路由器有多 
种,一种是我们在第一章中说的Proxy ARP类型的路由,曾经有一段时间,这种路由被用 
来分割网络;不过,目前已经很少有人使用了,毕竟分割B类地址远比不上重新构作网络 
拓扑可靠。另一种就是标准的路由器,我们用一个实例来说明这个问题。 
   
  我们有两个C类网络地址,分别是202.199.248.0/24和202.199.249.0/24。其中,202 
.199.248.0/24这个子网用专线接入internet,路由器是202.199.248.1。由于路由器上 
只有一个以太网接口,所以限制了系统中只能有一个以太网段,除非引入其他的路由器 
。现在,我们把202.199.248.0和202.199.249.0分别构成一个以太网段,然后用一个Li 
nux路由器来连接这两个网段。 
   
  Linux路由器上安装两片网卡,地址分别是202.199.248.6和202.199.249.2,首先用i 
fconfig配置两片网卡的IP地址: 
   
  ifconfig eth0 202.199.248.6 netmask 255.255.255.0 
   
  ifconfig eth1 202.199.249.2 netmask 255.255.255.0 
   
  配置网络的时候,会设置缺省的广播路由,可以用route命令显示: 
   
  root@mail /root]# route 
   
  Kernel IP routing table 
   
  Destination   Gateway      Genmask         Flags Metric Ref    Use Iface 
   
  202.199.248.6  *           255.255.255.255 UH    0      0        0 eth0 
   
  255.255.255.255 *          255.255.255.255 UH    0      0        0   eth0 
   
  202.199.249.0   *          255.255.255.0   U     0      0        0 eth1 
   
  202.199.248.0   *          255.255.255.0   U     0      0        0 eth0 
   
  127.0.0.0       *          255.0.0.0       U     0      0        0 lo 
   
  显然,到202.199.248.*和202.199.249.*的广播路径都已经正确了,下一步是按照上 
一节的办法启动IP转发: 
   
  echo "1" > /proc/sys/net/ipv4/ip_forward 
   
  现在要面对我们作软件路由器的一个主要问题了。如同我们说的那样,系统的主路由 
器是202.199.248.1,而202.199.248.x的机器都将其缺省网关指向了这个路由。这意味 
着,如果有一个数据包从202.199.249.x发送到202.199.248.y,那么发送过程中不会有 
什么问题,而当202.199.248.y回应这个信息的时候,它将数据包发送到202.199.248.1 
,但是202.199.248.1并不知道202.199.249.0的任何事情,它无法正确投递这个数据包 
。 
   
  解决的办法是将202.199.248.6加入到202.199.248.1的投递路径中去,设置202.199. 
248.1的缺省投递路径,使得它碰到目标地址是202.199.249.x的数据包就投递到202.19 
9.248.6: 
   
  route add –net 202.199.249.0 netmask 255.255.255.0 gw 202.199.248.6 
   
  (这里我把事情简化了。实际上,202.199.248.1是一个cisco路由器,它的配置要使用 
自己的语法,不过内容是一样的)。 
   
  现在两个子网已经可以正确地互相访问了,但是,为了使202.199.249.x的机器能够访 
问internet,需要定义202.199.248.6的缺省投递路径,让它把对外的访问投递到202.1 
99.248.1: 
   
  route add default gw 202.199.248.1 
   
  这样,就在系统中添加了一个子网。如果你需要作更复杂的网络连接,只要按照自己 
的设计定义递送路径,然后打开核心转发就可以了。 
   
  8.1.3 广播路由路径 
   
  很容易看出来,我们上面使用的是缺省路由传递的方式。整个配置中,我们使用的一 
直是静态路径。在很多情况下,让路由器动态广播它所知道的路径更好一些。 
   
  要广播路由路径,基本的方法是使用路由守护进程。最基本的路由守护进程是routed 
。它作为Linux的一部分提供,可以收听网络上的路由广播,或者自己发出路由广播。不 
过,routed的功能有限,同时又很占服务器资源。 
   
  要使用routed,方法很简单,在命令行下面直接使用routed: 
   
  routed [-s] [-q]  
   
  -s和-q是routed的两种工作模式,简单地说,-s是服务器模式,routed将不断地广播 
和接受各种路由信息,-q则是客户模式,routed将只是接受别的机器广播的路由信息, 
并且以此为根据修正自己的路由表。一般来说,routed会根据机器上的网络接口自动确 
定路由信息,因此不需要提供其他信息。有时,你的系统比较复杂,这时你需要用/etc 
/gateways文件来设定一下静态路由信息。关于gateways文件的信息详情可以参考route 
d的手册页面。 
   
  更常用的路由守护进程是gated。这个程序是一个路由外壳程序,可以插入各种路由通 
信协议的支持。例如RIP,HELLO,IGRP等等。 
   
  配置gated是一件很痛苦的事情,因为需要管理的事情实在是太多了。我们建议尽可能 
地使用静态路由路径,只有在迫不得已的时候才使用gated守护进程(或者routed)来通 
过广播动态设置路由路径。 
   
  再申明一次:routed和gated在Linux中仅仅起到了一个广播路由信息的作用,真正的 
路由工作是由Linux内核完成的。因此,如果你的网络配置全是静态路径,那么,你并不 
需要使用这种程序,简单地打开内核IP转发和正确地配置路由表就是你需要的一切。 
   
  8.2 IP过滤和代理 
   
  在前面我们已经看到,配置Linux作为一个静态路由其实是非常简单的事情,但是,在 
实际的情况中,问题也许会比较复杂,例如,你需要对Linux内核转发的IP进行过滤以便 
构造一个防火墙系统,或者你需要把你的私用网络接入到Internet。这一节我们就来讨 
论这方面的问题。 
   
  8.2.1 ipchains和IP过滤 
   
  正常情况下,内核会转发一切它认为应该转发的数据包,也许你想对这种转发加以控 
制,Linux的绝大部分发行版本中都包含了一个用于控制这种转发的工具,称为ipchain 
s。在早期版本的Linux中,有一个产品叫ipfwadm,两者在语法上是相当近似的,不过在 
现在版本的Linux中,使用的都是ipchains。 
   
  要使用ipchains,你必须首先安装这个产品,例如: 
   
  rpm –i ipchains-1.3.9-3.rpm 
   
  接下来就可以使用ipchains了。 
   
  链 
   
  要理解ipchains,首先应该知道它是基于所谓“链”的概念,所谓的“链”基本上是 
一个TCP/IP连接模式,可以在这个模式上运用各种过滤规则,在缺省情况下,ipchains 
定义了三个基本的链: 
   
  input  由网络接口进入本机 
   
  output  由网络接口输出 
   
  forward  在各个网络接口之间转发 
   
  你也可以建立自己的链,但是前面三个链不能更改,而且自己建立的链是没有缺省定 
义的。要建立自己的链,使用ipchains –N指令: 
   
  ipchains –N mychains 
   
  这样就建立了一个名为mychains的链。要删除某个链,使用ipchains –X指令,如 
   
  ipchains –X mychains 
   
  匹配模式 
   
  第二个需要理解的概念是匹配模式,匹配模式就是对TCP/IP连接的源/目的地址、端口 
、协议等进行匹配,例如,可以在连接请求中过滤所有源地址是202.199.240.2,目标地 
址是18.0.0.3的部分: 
   
  -s 202.199.240.2   –d 18.0.0.3 
   
  在匹配规则中可以使用下面的一些选项: 
   
  -s 源地址 -d 目标地址 
   
  这两个选项都可以使用网络地址,例如,要过滤源地址在子网202.199.248.0-202.19 
9.248.255中,目标地址在202.199.249.0-202.199.249.255中的请求,可以使用下面两 
种方法(等价) 
   
  -s 202.199.248.0/24 –d 202.199.249.0/24 
   
  -s 202.199.248.0/255.255.255.0 –d 202.199.249.0/255.255.255.0 
   
  如果在某个匹配规则中没有标出源地址或者目标地址,那么缺省是0.0.0.0/0,即 
   
  -s 202.199.248.0/24 等价于-s 202.199.248.0/24 –d 0.0.0.0/0 
   
  -p 连接协议 
   
  -p选项用来设置使用的连接协议,可以是TCP,UDP或者ICMP,例如: 
   
  -s 202.199.248.0/24 –p TCP 
   
  所有从C类子网202.199.248.0出发的TCP连接。 
   
  在ICMP连接的情况下有一个特殊情况,就是可以使用-icmp-type来指出ICMP的类型。 
  这个类型一般用数字标出,常用的有: 
   
   数值  含义     常见应用 
   
    0               网络回应               ping 
   
         3         网络不可达           TCP/IP寻址失败 
   
         5          路由重定向            静态路由主机 
   
         8              请求回应                ping 
   
         11         网络超时               traceroute 
   
  例如,-s 127.0.0.1 –p ICMP –-icmp-type 0 表示所有从127.0.0.1发出的ping回 
应。 
   
  端口号 
   
  直接在源/目的地址的后面加上的数字表示端口号,但是要注意端口号必须和协议类型 
一起使用,例如,通往C类网202.199.248.0内任何www服务器的连接可以表示成 
   
  -d 202.199.248.0/24 80 -p TCP 
   
  也可以使用名字代替端口号,例如上面的形式也可以写成 
   
  -d 202.199.248.0/24 www –p TCP 
   
  没有限定端口号的规则表示适用于任何端口。 
   
  端口号可以使用段落,方法是[最小端口号]:[最大端口号]。例如从A类网10.0.0.0/ 
8出发的所有源端口大于1024小于4096的UDP请求可以写成: 
   
  -s 10.0.0.0/8 1024:4096 –p UDP 
   
  上下界可以省略,例如所有大于64的端口可以写成64:,小于1024的端口号写成:1023 
等等。 
   
  也可以使用-source-port和-destination-port来标志端口号。 
   
  否定 
   
  !符号用于对地址规则取否定,例如-s !202.199.248.0/24代表所有源地址不是C类地 
址202.199.248.0的数据包。在端口、协议类型等处也可以使用!符号。 
   
  处理规则 
   
  下一个问题是对特定的链实行特定的处理规则,所谓规则就是对某种确定的链执行特 
定的操作。通常对于某个确定的链,我们用“跳转”使它进入另外一个链中,而在一切 
跳转的末端,有几个预先定义好的处理规则: 
   
  ACCEPT 允许这个请求正常通过,这时Linux表现的象一个普通的路由器 
   
  DENY 禁止这个请求通过,这个数据包会就此在网络上消失,表现得如同网络在这里断 
开一样 
   
  RETURN 正常情况下,ipchains会依次察看链中所有的规则,所以一个链后面的规则可 
以覆盖前面的规则,但是当遇到RETURN规则时,处理链将立即返回,即使下面还有与之 
相关的处理选项也会被忽略。这样,RETURN规则将强迫ipchains自动转向下一个链。 
   
  REJECT 这个选项跟DENY非常相似,所不同的是它在禁止这个请求的同时可以返回一些 
ICMP信息,使得请求者能够知道数据包在何处被禁止。如果客户是windows NT,将会看 
到一个“网络不可达”的错误信息。 
   
  REDIRECT 这个规则只能用于input或者output链,而且不能用于ICMP协议。它将使得 
Linux机器代替定义的目标机器收发信息报文。例如,ipchains –A input –d 202.11 
2.58.200 –j REDIRECT将使得客户机器向202.112.58.200发出的数据包在Linux网关处 
直接接受到并且截留下来。REDIRECT后面可以跟上端口号,例如把指向202.112.58.200 
的80端口的数据包重定向到网关的9090端口: 
   
  ipchains –A input –d 202.112.58.200 80 –p TCP –j REDIRECT 9090 
   
  MASQ 这个规则只能用于forward链,它用于对客户机器进行IP代理。 
   
  使用规则的方法是将它“加入”到某个链中,语法是ipchains –A [链] [地址匹配] 
 [规则]。例如,可以用ipchains –A指令对forward链建立一条新的规则集: 
   
  ipchains –A forward  -s 202.112.45.0/24 –d 13.0.0.0/8 –j REJECT 
   
  这条规则禁止了从202.199.45.0到13.0.0.0的所有数据包。 
   
  也可以用规则在链间跳转,例如,我们首先建立一个空链: 
   
  ipchains –N disable 
   
  然后将这条链设定为自动跳转到禁止: 
   
  ipchains –A disable –j DENY 
   
  接下来,我们可以让某些链跳转到这条链: 
   
  ipchains –A input –s 202.112.58.0/24 –j disable 
   
  那么效果和下面的指令: 
   
  ipchains –A input –s 202.112.58.0/24 –j DENY是一样的。 
   
  在不需要某一条规则时,可以将它删除,这可以使用命令ipchains –D。例如,要删 
除上面的链规则,使用 
   
  ipchains –D forward  -s 202.112.45.0/24 –d 13.0.0.0/8 –j REJECT 
   
  如果你要删除某条链中的所有规则,使用ipchains –F: 
   
  ipchains –F forward 
   
  这时forward链中所有的规则都被清除。 
   
  如果你不给出链的名字,那么ipchains –F将清除所有链中的规则。 
   
  如果想察看目前链的规则,使用ipchains –L: 
   
  $ipchains -L 
   
  Chain input (policy ACCEPT): 
   
  Chain forward (policy ACCEPT): 
   
  target     prot opt     source                destination           ports 
   
  ACCEPT     all  ------  202.199.249.0/24     anywhere              n/a 
   
  Chain output (policy ACCEPT): 
   
  对链的修改可以使用-R选项,即替换某一条规则,这需要知道规则的序号,例如: 
   
  [root@mail /root]# ipchains -L 
   
  Chain input (policy ACCEPT): 
   
  Chain forward (policy ACCEPT): 
   
  target     prot opt     source                destination           ports 
   
  DENY       all  ------  202.199.249.14       anywhere              n/a 
   
  Chain output (policy ACCEPT): 
   
  现在forward链中只有一条规则,因此这条规则的序号就是1,现在可以替换这条规则 
为: 
   
  ipchains -R forward 1 -s 202.199.249.14 -d 0.0.0.0/0 -j ACCEPT 
 
   
  然后可以看到 
   
  [root@mail /root]# ipchains -L  
   
  Chain input (policy ACCEPT): 
   
  Chain forward (policy ACCEPT): 
   
  target     prot opt     source                destination           ports 
   
  ACCEPT     all  ------  202.199.249.14       anywhere              n/a 
   
  Chain output (policy ACCEPT): 
   
  ipchains –D指令中也可以直接使用序号,如ipchains –D 1。 
   
  通常,加入的新规则会放在已有规则的后面,如果你想要把规则插入到某个特定的位 
置,使用ipchains –I [链] [序号] [规则] 
   
  Policy 
   
  这个词不太合适。ipchains的policy是指对链的缺省行为,例如,刚才的三个链的po 
licy都是ACCEPT,表示在对系统的三个缺省链没有定义规则时,所有的包都可以通过。 
   
  要设置Policy,使用ipchains –P指令: 
   
  ipchains –P forward DENY 
   
  log 
   
  可以设置ipchains对符合规则的包的信息进行记录。这可以通过-l选项来实现,例如 
,要记录从202.199.249.0/24出发的所有被转发的包的情况,使用: 
   
  ipchains –A forward –s 202.199.249.0/24 –l –j ACCEPT 
   
  然后在dmesg中就可以看到核心记录的包的信息了。如果要进一步分析这些信息,需要 
将其记录到系统的日志文件中(见系统记账部分)。 
   
  基本上,各种IP过滤型的防火墙都是利用上面解释的各种规则对IP包进行分析和监控 
。 
   
  接口 
   
  用-i选项可以明确地给出链所涉及的网络接口,例如-i eth0代表第一个网络连接,可 
以用+号来统配,例如 
   
  ipchains –A input –p ICMP –s 0.0.0.0/0 –d 202.199.248.11 –i eth0 –j  
DENY 
   
  关闭了通过eth0网络接口的ping回应。 
   
  当-i选项用于input和output链的时候,其意义是很简单的,如果用于forward链,那 
么它给出的是转发的目标接口。 
   
  保存和恢复链规则 
   
  在一个复杂的ipchains防火墙系统中,可能有许多规则。每次重新启动,这些规则都 
必须被重新启动。原则上,可以在系统启动脚本中直接写入相应的规则,不过实践中, 
我们一般采用首先测试规则是否正确的方法,在确定规则正确之后,使用ipchains-sav 
e和ipchains-restore命令完成链规则的保存和读入。 
   
  例如,我们已经有了下面形式的链: 
   
  $ipchains -L 
   
  Chain input (policy ACCEPT): 
   
  Chain forward (policy ACCEPT): 
   
  target     prot opt     source                destination           ports 
   
  ACCEPT     all  ------  202.199.249.0/24     anywhere              n/a 
   
  Chain output (policy ACCEPT): 
   
  那么,可以使用ipchains-save命令将现在的链设置保存起来: 
   
  $ipchains-save > mychains 
   
  Saving `forward'. 
   
  ipchains-save缺省的情况下在标准输出送出信息,所以要使用重定向的办法,现在m 
ychains文件中就包含我们的链的所有规则: 
   
  $cat mychains 
   
  :input ACCEPT 
   
  :forward ACCEPT 
   
  :output ACCEPT 
   
  -A forward -s 202.199.249.0/255.255.255.0 -d 0.0.0.0/0.0.0.0 -j ACCEPT 
   
  如果要从文件中读入ipchains的配置,使用ipchains-restore命令: 
   
  $ipchains-restore < mychains 
   
  同样,ipchains-restore从标准输入读取信息,因此需要使用重定向命令。 
   
  8.2.2 NAT和IP代理 
   
  现在我们来考虑一个重要的ipchains应用,即NAT(网络地址翻译),也称为IP代理。在 
第一章我们已经介绍过有关的概念,处于私用网络内的主机将自己的请求传递给代理机 
器,由代理机器重写源地址和端口,使得看上去数据包好像是从代理机器发出的,接受 
到的数据包也由代理机器转发给私用网络内的主机。在ipchains的术语中,这称为“伪 
装”(MASQ)。 
   
  要使用伪装功能,可以简单地使用-j MASQ命令。考虑一个典型的例子,eth0接到正常 
的internet中,地址是202.199.248.120,现在在eth1上连接一个私用网络,地址是192 
.168.254.0/24,eth1的地址是192.168.254.1,而且eth0已经能够正常访问internet, 
那么需要作的事情就是设置所有从192.168.254.0/24发出的请求包应该被伪装然后发送 
,因此,首先要按照前面的方法打开核心IP转发,然后设置对192.168.254.0的机器发出 
的数据包进行伪装: 
   
  ipchains –A forward –s 192.168.254.0/24 –d !192.168.254.0/24 –j MASQ 
   
  然后把私用网络中的机器的网关设置成eth1的地址(192.168.254.1)就可以让私用网 
络中的机器访问internet了。 
   
  这种技术也用于设置拨号网关,即用一个拨号网络连接让局域网内的所有机器都能连 
接到internet。 
   
  telnet,www等服务都可以简单地通过这种伪装方法代理出去,但是ftp有一个特殊的 
问题。在第一章中,我们已经指出,ftp依赖于两个连接,其中用来传输数据的连接通常 
由服务器发起。问题是远端服务器根本不知道关于私用网络的事情,因此连接不会成功 
,例如,当你通过我们这里介绍的网关让私用网络内的机器进行ftp请求时,会产生这样 
的情况: 
   
  C:\>ftp 
   
  ftp> o 202.199.248.3 
   
  Connected to 202.199.248.3. 
   
  220 asnt_1 Microsoft FTP Service (Version 4.0). 
   
  User (202.199.248.3:(none)): ftp 
   
  331 Anonymous access allowed, send identity (e-mail name) as password. 
   
  Password: 
   
  230 Anonymous user logged in. 
   
  ftp> ls 
   
  500 Invalid PORT Command. 
   
  150 Opening ASCII mode data connection for file list. 
   
  然后这个ftp程序就会挂起。 
   
  解决问题的第一个办法是使用被动(passive)模式,在被动模式下,所有的ftp连接 
和数据传输请求都由ftp客户发起,这样就可以避免服务器反过来连接私用网络的机器。 
通常基于GUI的ftp客户软件一般都是使用的被动模式(例如cute_ftp),而命令行ftp工 
具则使用的是主动模式。 
   
  不幸的是,最常用的浏览工具:Internet Explorer 用的正好是主动模式。显然,让 
你的客户了解这种晕头转向的概念显然无益于帮助他们使用internet。因此,ipchains 
提供了一个附加模块,专门用于解决ftp的问题,可以用insmod命令来加载这个模块: 
   
  insmod ip_masq_ftp 
   
  然后客户机器就可以正确地使用ftp了: 
   
  C:\>ftp 
   
  ftp> o 202.199.248.3 
   
  Connected to 202.199.248.3. 
   
  220 asnt_1 Microsoft FTP Service (Version 4.0). 
   
  User (202.199.248.3:(none)): ftp 
   
  331 Anonymous access allowed, send identity (e-mail name) as password. 
   
  Password: 
   
  230 Anonymous user logged in. 
   
  ftp> ls 
   
  200 PORT command successful. 
   
  150 Opening ASCII mode data connection for file list. 
   
  incoming 
   
  pub 
   
  226 Transfer complete. 
   
  ftp: 15 bytes received in 0.11Seconds 0.14Kbytes/sec. 
   
  ftp> 
   
  对于那些不想对客户解释什么是被动模式的管理者,这可能是唯一的方法了。 
   
  还有一些应用软件也需要类似的内核不定,其中最重要的应该是irc,要使得私用网上 
的用户能够使用irc程序,使用这个模块: 
   
  insmod ip_masq_irc 
   
  还有几个这一类的模块,都放在/lib/modules/2.2.14/ipv4目录下,你可以自己参考 
,例如连线对战quake用的模块等等。 
   
  8.3 基于IPChains的防火墙系统 
   
  现在我们可以考虑如何实现一个简单的防火墙了。在这里我们将考虑一个代理和包过 
滤混合的防火墙系统,尽管比较简单,但是它仍然包含通常所说的防火墙的主要内容。 
对于这样的防火墙,ipchains就是你需要的一切。技术上,更强大的防火墙系统(例如 
带有数据过滤功能)也是存在的,但是对于一般的单位,下面解释的防火墙强度已经足 
够了。 
   
  8.3.1 防火墙的设计 
   
  防火墙有两种,称为代理防火墙和包过滤型的防火墙。代理防火墙基本上就是前面说 
的NAT系统,或者是其他某种代理软件,客户机器把自己的请求提交给代理机器,然后由 
代理服务程序代替它进行网络访问。这种防火墙的主要优势在于其安全性,理论上,只 
要防火墙主机不出现问题,对客户机器进行非授权访问实际是不可能的。但是它的主要 
缺陷就是灵活性和功能,显然,页面服务是无法安装在私用网络中的(除非使用端口转 
发或者反向的NAT服务)。 
   
  包过滤型的防火墙是一个软件的路由器,由路由机器对通过的数据包进行检查,拦截 
所有非法的请求,并且对必要的情况进行记录。这种防火墙不会影响内部网络的正常功 
能,缺点则是不像代理防火墙那样可靠,必须记住,由于TCP/IP的实现,数据包可能会 
在你注意不到的地方穿过,而过分严厉的过滤策略又会影响网络的正常使用。 
   
  一般来说,设计防火墙的主要任务是确定哪些数据包可以透过,哪些数据包必须加以 
阻挡。这里,最重要的是熟知TCP/IP连接的性质和传输模式。 
   
  设计防火墙的策略有两种基本的思路,一种是一开始就禁止所有的数据包流通,然后 
根据需要打开的服务,依次开放各种端口;另外一种是一开始开放所有的服务,然后对 
不可靠的端口进行封锁。原则上,前一种方法比较可靠,但是对于不熟悉TCP/IP的用户 
,可能会导致一些困扰。 
   
  要使得防火墙起作用,显然必须将你的本地网络放在防火墙后面,这又存在许多的情 
况,最常见的情况,是将本地网络分成两部分,一部分使用正常的Internet地址,另一 
部分则使用私用的网络地址。这两部分可以正常相互通信。当与外部网络的机器对话的 
时候,使用正常地址的机器简单地通过防火墙,而私用网的机器则通过防火墙使用代理 
方式访问。 
   
  显然,这个系统需要有三个网络接口,一个用于连接到internet,另一个与正常地址 
的内部机器对话,另一个用来和私用网络地址的机器对话。其中,正常地址的内部机器 
是网络的中心部分,因为所有的本地服务器必须放在这个区域。在文献中,这个部分通 
常称为DMZ(停火区)。 
   
  在设计包过滤策略的时候,主要的应该是考虑TCP/IP连接的方式,如同我们知道的那 
样,TCP/IP连接是双向的,如果你要访问某台主机的www服务,那么这个连接涉及到的是 
:对方的主机地址;对方的www端口地址(80);自己的IP地址;除此之外,你的ftp程序 
还要申请一个端口地址用来通讯,本地机器的TCP/IP管理程序将为它分配一个大于1024 
的端口地址,这样才能实现连接。这样,通常为了避免对自己机器的非授权访问,你需 
要封禁对本地网络机器所有非必要的小于1024端口的访问,但是你仍然应该允许大于10 
24的端口的使用,否则本地机器无法使用internet。 
   
  从/etc/services文件可以查找到各种端口的定义,不过要注意ftp使用两个端口,即 
端口21(ftp)和20(ftp-data),分别用于发送ftp命令和发送ftp数据。另外,NFS服务要 
使用portmap端口。 
   
  ftp是一个几乎象是噩梦一样的东西,在主动模式中,除了我们说的两个端口之外,实 
际上,由于数据连接是从服务器发起,因此它是申请一个客户机器上的端口(同样>102 
4),然后构作这个连接。显然,这个端口的值是不固定的,因此你实际上没有办法来判 
断一个连接会不会是ftp主动模式的数据,这也就意味着如果你想允许主动模式,那么对 
大于1024的端口进行过滤实际是不可能的。如果你坚持要一个“可靠”的防火墙,那么 
唯一的方法是强制性地命令你的员工使用被动模式的ftp工具。这是过分严厉的管理政策 
使得工作效率降低的一个例子。 
   
  另外一个需要注意的内容是关于IP隧道。IP隧道可以让TCP/IP连接运行在别的协议之 
上,例如IPX。这样,如果你的系统允许IPX路由,就有可能有别的网络上的用户利用IP 
隧道功能穿透你的防火墙设置。这是危险的事情,解决的方法就是原则上不对TCP/IP以 
外的任何协议路由。如果你的路由器有多协议路由功能,将它禁止掉。 
   
  8.3.2 实例说明 
   
  现在我们用实例来说明一下一个上述的标准防火墙的配置过程,我们完全用ipchains 
来完成这个工作,首先我们可以考虑一下防火墙的基本构架: 
   
  防火墙通过一个网卡接入internet,这片网卡构成了所有internet访问的数据通路, 
不妨假定其地址是202.199.248.1,接口是eth0。(当然,实际情况中,我们更多地通过 
专用的路由器接入广域网,不过这不会影响我们的问题的本质)。 
   
  DMZ中包含了我们的所有对外服务主机,外部网络可以透过防火墙申请这些主机的服务 
。我们假设这些主机的地址在C类网202.199.248.0中,地址空间是从202.199.248.2到2 
02.199.248.255,或者说202.199.248.0/24。其中,我们有一台www主机,地址是202.1 
99.248.8,ftp主机的网络地址是202.199.248.9,电子邮件主机是202.199.248.10,DN 
S主机是202.199.248.11。另外,ftp主机也同时提供samba服务。为了使DMZ能够直接和 
防火墙主机通信,我们将DMZ用独立的一个以太网系统连接起来,并且在防火墙上加入第 
二块网卡与之通联,设为eth1,IP地址是202.199.248.2。所有DMZ区域中的机器的网关 
地址都设置为202.199.248.2。 
   
  第三个区域是私用网络(private),假设我们使用的私用网络是192.168.0.0/24,它 
们也用一个独立的以太网连接起来,然后在防火墙上加入第三片网卡,设为eth2,其地 
址为192.168.0.1,与私用网络连接在一起,所有私用网络内的主机网关设置为192.168 
.0.1。 
   
  整个网络体系如图所示: 
   
   图8.2 含有DMZ的防火墙 
   
  现在我们来考虑防火墙策略,首先要按照上一节的方法打开核心的IP转发,接下来, 
我们首先定义几个链,用来表示各种访问模式: 
   
  ipchains –N wan_DMZ 
   
  从外部网访问DMZ。 
   
  ipchains –N wan_private 
   
  从外部网访问私用网络 
   
  ipchains –N DMZ-wan 
   
  从停火区访问外部网 
   
  ipchains –N DMZ-private 
   
  从停火区访问私用网络 
   
  ipchains –N private_DMZ 
   
  从私用网络访问停火区 
   
  ipchains –N private_wan 
   
  从私用网络访问外部。 
   
  还要有一个链用来管理ICMP服务: 
   
  ipchains –N icmp_acct 
   
  然后,在设置任何防火墙之前,首先设置缺省行为,对于防火墙,主要是forward链: 
   
  ipchains –P forward DENY 
   
  接下来,我们的任务是正确地将各种连接请求归纳入对应的链。首先是从私用网发送 
到外部网上的数据包,显然这些包的源地址应该是192.168.0.0/24,转发的目标接口是 
eth0,因此可以将所有这些数据包“跳转”到链private_wan: 
   
  ipchains –A forward –s 192.168.0.0/24 –i eth0 –j private_wan 
   
  从私用网发送到停火区的数据包目标转发接口是eth1,所以 
   
  ipchains –A forward -s 192.168.0.0/24 –i eth1 –j private_DMZ 
   
  从停火区出发的数据包,其源地址是202.199.248.0/24,而送到私用网络或者外部网 
,目标转发接口应该是eth2或者eth0,所以: 
   
  ipchains –A forward –s 202.199.248.0/24 –i eth2 –j DMZ_private 
   
  ipchains –A forward –s 202.199.248.0/24 –i eth0 –j DMZ_wan 
   
  由于-j是“跳转”,所以如果经过了上面的几条链还没有跳走,那么显然数据包应该 
是从eth0进入的,所以 
   
  ipchains –A forward –i eth2 –j wan_private 
   
  ipchains –A forward –i eth1 –j wan_DMZ 
   
  然后定义行为规则,从私用网络到DMZ的连接是最简单的,所有访问非服务器端口的行 
为都是非法,应该禁止,标示目标端口可以用我们前面讲的办法: 
   
  ipchains –A private_DMZ –p TCP –d 202.199.248.8 www –j ACCEPT 
   
  ipchains –A private_DMZ –p TCP –d 202.199.248.9 ftp –j ACCEPT 
   
  ipchains –A private_DMZ –p TCP –d 202.199.248.9 ftp-data –j ACCEPT 
   
  ipchains –A private_DMZ –p TCP –d 202.199.248.9 137:139 –j ACCEPT 
   
  ipchains –A private_DMZ –p UDP –d 202.199.248.9 137:139 –j ACCEPT 
   
  ipchains –A private_DMZ –p TCP –d 202.199.248.10 smtp –j ACCEPT 
   
  ipchains –A private_DMZ –p TCP –d 202.199.248.10 pop-3 –j ACCEPT 
   
  ipchains –A private_DMZ –p TCP –d 202.199.248.11 domain –j ACCEPT 
   
  ipchains –A private_DMZ –p UDP –d 202.199.248.11 domain –j ACCEPT 
 
   
  显然这样的防火规则将使得你的员工只能使用被动ftp工具。注意域名服务和samba服 
务的协议都是TCP/UDP两用的,因此必须分别标出。接下来还有一个合法的请求就是pin 
g服务,所以 
   
  ipchains –A private_DMZ –p ICMP –j icmp_acct 
   
  不符合上述规则的显然就是非法请求: 
   
  ipchains –A private_DMZ –j DENY 
   
  再考虑从外部到DMZ的行为规则,这个规则与上述的很类似,但是显然不应该允许外部 
用户使用samba服务(不要忘了,netbios名字是靠广播来传递的,如果有个用户从外部 
网访问你的samba服务,可以肯定他使用了某些扫描程序)。因此: 
   
  ipchains –A wan_DMZ –p TCP –d 202.199.248.8 www –j ACCEPT 
   
  ipchains –A wan_DMZ –p TCP –d 202.199.248.9 ftp –j ACCEPT 
   
  ipchains –A wan_DMZ –p TCP –d 202.199.248.9 ftp-data –j ACCEPT 
   
  ipchains –A wan_DMZ –p TCP –d 202.199.248.10 smtp –j ACCEPT 
   
  ipchains –A wan_DMZ –p TCP –d 202.199.248.11 domain –j ACCEPT 
   
  ipchains –A wan_DMZ –p UDP –d 202.199.248.11 domain –j ACCEPT 
   
  ipchains –A wan_DMZ –p ICMP –j icmp_acct 
   
  ipchains –A wan_DMZ –j DENY 
   
  在这里我们看到了一些非常头痛的事情,由于我们使用了一个过分严厉的防火墙规则 
,所以外部世界的任何人都无法用IE从你的ftp服务器上下载软件了。也许你应该在你的 
主页上告诉你的访问者们用cute-ftp或者其他的任何能够使用被动模式的东西来下载, 
也许你应该使用一个宽松一些的防火墙规则,允许访问ftp服务器比较高的端口,例如用 
下面的规则替代: 
   
  ipchains –A wan_DMZ –p TCP –d 202.199.248.9 1024:5999 –j ACCEPT 
   
  ipchains –A wan_DMZ –p TCP –d 202.199.248.9 6010: –j ACCEPT 
   
  注意这个规则有些怪异,它允许了几乎所有比较高的端口,但是禁止了6000-6010之间 
的端口,原因是6000-6010之间的端口通常是用于X windows的远程服务。显然,让别人 
可以远地使用你的X window无助于你的系统安全。 
   
  下面需要定义从私用网络到外部网络的访问,这部分的规则,我们仍然使用偏于严厉 
的防火墙规则,毕竟说服你的员工使用被动模式ftp要容易一些: 
   
  ipchains -A private_wan -p tcp --destination-port www -j MASQ 
   
  ipchains -A private_wan -p tcp --destination-port ssh -j MASQ 
   
  ipchains -A private_wan -p tcp --destination-port telnet -j MASQ 
   
  ipchains -A private_wan -p tcp --destination-port pop-3 -j MASQ 
   
  ipchains -A private_wan -p tcp --destination-port smtp -j MASQ 
   
  ipchains -A private_wan -p tcp --destination-port ftp --j MASQ 
   
  ipchains -A private_wan -p tcp --destination-port ftp-data -j MASQ 
   
  ipchains -A private_wan -p icmp --icmp-type ping -j MASQ 
   
  ipchains -A private_wan -j REJECT -l 
   
  接下来是从DMZ到私用网络,这基本就是前面的内容的翻版: 
   
  ipchains –A private_DMZ –p TCP –-destination-port www –j ACCEPT 
   
  ipchains –A private_DMZ –p TCP –s 202.199.248.9 137:139 –j ACCEPT 
   
  ipchains –A private_DMZ –p UDP –s 202.199.248.9 137:139 –j ACCEPT 
   
  ipchains –A private_DMZ –p TCP -s 202.199.248.10 smtp –j ACCEPT 
   
  ipchains –A private_DMZ –p TCP –s 202.199.248.10 pop-3 –j ACCEPT 
   
  ipchains –A private_DMZ –p TCP –s 202.199.248.11 domain –j ACCEPT 
   
  ipchains –A private_DMZ –p UDP –s 202.199.248.11 domain –j ACCEPT 
   
  从DMZ到外部网络的规则是最难处理的,因为你的服务器也需要进行某些对外的通信, 
尤其是电子邮件。我们使用了一个类似下面的防火墙规则: 
   
         ipchains -A DMZ_wan -p tcp -s 202.199.248.10 --destination-port smt 
p -j ACCEPT 
   
         ipchains -A DMZ_wan -p udp -s 202.199.248.11 –destination-port dom 
ain -j ACCEPT 
   
         ipchains -A DMZ_wan -p tcp -s 202.199.248.11 -destination-port doma 
in -j ACCEPT 
   
         ipchains –A DMZ_wan –p tcp –destination-port www –j ACCEPT 
   
         ipchains –A DMZ_wan –p tcp –destination-port ftp –j ACCEPT 
   
         ipchains –A DMZ_wan –p tcp –destination-port ftp-data –j ACCEPT 
   
         ipchains -A DMZ_wan -p icmp -j icmp-acc 
   
         ipchains -A DMZ_wan -j DENY  
   
  最后的任务是确定那些从外部网络访问你的私用网络的企图,这几乎肯定是恶意的, 
因此: 
   
  ipchains -A wan_private –j DENY –l 
   
  不要忘记,还要处理ICMP信息,我们使用一个按照类型过滤的ICMP过滤规则: 
   
    ipchains -A icmp-acc -p icmp --icmp-type destination-unreachable -j ACCE 
   
         ipchains -A icmp-acc -p icmp --icmp-type source-quench -j ACCEPT 
   
         ipchains -A icmp-acc -p icmp --icmp-type time-exceeded -j ACCEPT 
   
         ipchains -A icmp-acc -p icmp --icmp-type parameter-problem -j ACCEP 

   
  对于上面的四种ICMP信息,我们的防火墙让它们通过,其他的需要处理,按照ipchai 
ns的缺省规则,其他的信息将会被阻挡。 
   
  我们接下来还可以定义对于防火墙主机自身的安全规则,这主要是禁止外部机器存取 
防火墙主机的较低端口(因为我们的防火墙机器就是起到包过滤和代理的作用,从外界 
连接它的请求可以肯定是有问题的): 
   
  ipchains –A input –i eth0 –d 202.199.248.1 :1023 –p TCP –j DENY 
   
  ipchains –A input –i eth0 –d 202.199.248.1 :1023 –p UDP –j DENY 
   
  ipchains –A input –i eth0 –d 202.199.248.1 -p ICMP –icmp-type 11 ACCEP 

   
  ipchains –A input –i ! eth0 –d 202.199.248.1 –j DENY 
   
  ipchains –A input –i ! eth1 –d 202.199.248.2 –j DENY 
   
  ipchains –A input –i ! eth2 –d 192.168.0.1 –j DENY 
   
  最后允许icmp-type 11的包通过是为了允许外界traceroute来测试路由路径。 
   
  这样,没有人可以从外部世界作对这台机器telnet,rlogin或是ftp之类的动作了。如 
果你愿意,当然也可以对其他的接口进行过滤。 
   
  现在我们有了一个强度足够的防火墙系统,事实上,对大部分单位,其强度已经过高 
了,以至于很多情况下你都会想在防火墙上打出一个洞来简化系统的使用,易用性和安 
全是一对矛盾,强调一个必定削弱另一个。 
 
   
   
 
-- 
当我越过无尽虚空的时候,我看见星辰的欲望,光荣和毁灭,这是光辉世界的宿命, 
一切的一切,最终必将落入黑暗和虚无。 
所以,我随着星光飞翔,去逃脱必然的终结,也许有一天,我将回到世界的原初, 
等待新的星辰的诞生。 
尘埃是星的起源,星的终结。 
 
 
※ 来源:·BBS 水木清华站 smth.org·[FROM: 202.112.90.20] 

BBS水木清华站∶精华区