BBS水木清华站∶精华区

发信人: ruster (尘埃*星辰*领悟), 信区: Linux        
标  题: 第八章 路由器和防火墙(下) 
发信站: BBS 水木清华站 (Thu Dec 21 13:48:45 2000) 
 
8.4 拨号网络连接 
 
   
  现在我们来研究另外一种网络连接工具,即调制解调器连接。对于许多用户,这是上 
网的基本手段。虽然不太可能有某个网站使用拨号网络连接internet,但用一台普通机 
器构成一个局域网的IP代理让所有网内机器一起上网的情况却是相当常见的。另外,一 
直到不久以前,很多ISP都利用Linux+多串口卡作为拨号服务器给客户提供网络服务。 
   
  我们将主要把精力聚焦在PPP(点对点协议)上,以前许多单位流行UUCP,还有不少人 
使用SLIP。但是随着时代的发展,Internet的推广使UUCP没有什么实际意义,而SLIP的 
优点也由于pppd管理的简化而失去了原有的意义。 
   
  8.4.1 拨号网络连接 
   
  我们首先来介绍使用PPP进行拨号网络连接的过程。Linux的PPP连接是通过pppd程序来 
完成的,实际上,这个程序的行为相当简单,就是将调制解调器信息映射成一个虚拟的 
网络接口。一般来说,建立PPP连接的过程需要这样几个步骤: 
   
  建立调制解调器连接 
   
  其实这个过程就是向调制解调器发送初始化和拨号命令,接受到命令后,调制解调器 
和对方系统建立电气连接。 
   
  登录网络 
   
  ISP将ip地址和路由信息传递到你的系统上,pppd程序将根据这个信息启动ppp0网络接 
口。 
   
  为了说明这个问题,我们现在来看一个实际的PPP配置例子,假设你的核心编译时允许 
了PPP支持,而且系统中已经安装了ppp-2.3.10(比如说)软件包,那么,在/usr/doc/pp 
p-2.3.10目录下应该有一个scripts目录,里面有类似这样的一些文件: 
   
  $ls 
   
  README    chat-callback  ip-down.local.add  ppp-off  ppp-on-dialer  secure 
-card 
   
  callback  chatchat       ip-up.local.add    ppp-on   redialer 
   
  这里,ppp-on是启动ppp程序的主要脚本,我们可以看一下它的内容: 
   
  #!/bin/sh 
   
  TELEPHONE=555-1212      # The telephone number for the connection 
   
  ACCOUNT=george          # The account name for logon (as in 'George Burns' 

   
  PASSWORD=gracie         # The password for this account (and 'Gracie Allen 
') 
   
  LOCAL_IP=0.0.0.0        # Local IP address if known. Dynamic = 0.0.0.0 
   
  REMOTE_IP=0.0.0.0       # Remote IP address if desired. Normally 0.0.0.0 
   
  NETMASK=255.255.255.0   # The proper netmask if needed 
   
  export TELEPHONE ACCOUNT PASSWORD 
   
  DIALER_SCRIPT=/etc/ppp/ppp-on-dialer 
   
  exec /usr/sbin/pppd debug lock modem crtscts /dev/ttyS0 38400 \ 
   
          asyncmap 20A0000 escape FF kdebug 0 $LOCAL_IP:$REMOTE_IP \ 
   
    noipdefault netmask $NETMASK defaultroute connect $DIALER_SCRIPT 
   
        容易看出来,真正的执行程序只有最后的exec程序,其他一些行只是一些设置 
参数。说实话pppd程序的参数实在太多,我们总是建议你在已有的脚本的基础上进行修 
改。其中,要注意的是pppd命令行中/dev/ttyS0的参数,这个是pppd程序拨号时的端口 
设备,显然,这里假定你的调制解调器接在com1。如果是接在com2,就使用/dev/ttyS1 
,以此类推。 
   
  我们首先必须说明一个关于身份认证的问题。如果你的机器已经有了一个以太网接口 
,并且发现按照下面的做法无法正确地建立连接的话,你需要把ppp-on脚本中的pppd的 
命令行选项auth改成noauth。这个选项和windows 9x类型的身份认证有关,由于我们使 
用的是用户名/口令的明文认证方式,所以选择noauth不会影响拨号的成功。当然,如果 
你发现不需要更改这个选项,那当然也行。 
   
  LOCALIP和REMOTEIP是你的本地机器以及ISP的IP地址,在我们的情况下,本地机器的 
IP是拨号时动态分配,在拨号之前是不知道的,这种情况下要设置成0.0.0.0。ISP的地 
址在拨号以前也是不知道的,所以也设置成0.0.0.0。 
   
  其他三个参数是在ppp-on-dial脚本里面使用的,从pppd的命令行中我们可以看到ppp 
d程序调用了这个脚本,我们看一看这个脚本的内容: 
   
  #!/bin/sh 
   
  exec chat -v                                            \ 
   
          TIMEOUT         3                               \ 
   
          ABORT           '\nBUSY\r'                      \ 
   
          ABORT           '\nNO ANSWER\r'                 \ 
   
          ABORT           '\nRINGING\r\n\r\nRINGING\r'    \ 
   
          ''              \rAT                            \ 
   
          'OK-+++\c-OK'   ATH0                            \ 
   
          TIMEOUT         30                              \ 
   
          OK              ATDT$TELEPHONE                  \ 
   
          CONNECT         ''                              \ 
   
          ogin:--ogin:    $ACCOUNT                        \ 
   
          assword:        $PASSWORD 
   
  容易看出,这个脚本实际上只是调用了chat程序。chat程序是一个自动的对话-应答程 
序,-v参数是启动调试信息纪录,这可以使你在测试的时候容易发现问题,(看看/var 
/log/messages文件就知道了),而其他的行定义了一些提示和对应的应答。例如,ass 
word: $PASSWORD在chat的参数后面出现,意味着每当chat程序收听到一个包含assword 
的提示的时候,就送出一个$PASSWORD字符串。每一行或者是一些控制选择,或者是这 
样的一个提示-应答对,也就是说,上面的这段指令稿可以这样解释: 
   
  TIMEOUT         3 
   
  这设定接收所期待的输入逾时时限为三秒。你可以考虑将它加大一些 
   
  ABORT           '\nBUSY\r' 
   
  如果接收到 BUSY 字串,中止执行。(也就是说,拨号程序发现对方的线路忙)。 
   
  ABORT           '\nNO ANSWER\r' 
   
  如果接收到 NO ANSWER 字串,中止执行.  
   
  ABORT           '\nRINGING\r\n\r\nRINGING\r' 
   
  如果接收到(重复的)RINGRING 字串,中止执行.这是因为某人正打电话给你!  
   
  (呵呵,对于经常拨BBS的朋友,这些内容再熟悉不过了)。 
   
   “              \rAT 
   
  不期待数据机传送任何讯息并且送出 AT 字串.  
   
  OK-+++\c-OK   ATH0 
   
  这是第一个提示-应答对。当pppd程序向调制解调器发出初始化命令时,它期待 OK , 
如果调制解调器正常,就会会应一个OK字符串;否则,没有期待到意味着拨出没有收到 
(因为数据机并不在指令模式下)那麽送出 +++ (使数据机返回指令模式的标准 Haye 
s 相容数据机字串)并且期待 OK;不管那种情况,一旦期待到OK,接著送出 ATH0 (数 
据机挂断字串).这主要是应付一些难以断线的意外情况。  
   
  TIMEOUT         30 
   
  设定下面的脚本执行的超时时限为 30 秒。 
   
  OK              ATDT$TELEPHONE 
   
  如果ATH0命令被正常执行,那么调制解调器应该返回一个OK,所以这里期待 OK,一旦 
得到就拨叫$TELEPHONE(前面在ppp-on里面定义的电话号码)。  
   
  CONNECT         ” 
   
  一旦拨号成功,与远端调制解调器建立了连接,我们的调制解调器应该返回一个CONN 
ECT,因此我们期待 CONNECT 字串并且不送出任回覆讯息。当然实际上我们根本不需要 
回应这个提示,问题是chat程序就是这么蠢,即使是一个“死行”也要回应一次,哪怕 
回应中什么也没有。顺便提一句,对于空字符串、带空格的字符串等等,我们要用单引 
号把它括起来,现在括起来的就是一个“空”。 
   
  ogin:--ogin:    $ACCOUNT 
   
  我们将期待登录提示(...ogin:),但是如果我们在超时前没有接收到,送出一个返回 
字元(return)然後再次找寻签入提示.当接收到提示时,送出使用者名称(存放在$ACC 
OUNT 环境变量里,在前面的ppp-on中定义)。 
   
  assword:        $PASSWORD 
   
  期待密码提示并且送出密码(存放在环境变量里)。 
   
  关于pppd程序,如果你想要作拨号的话,内容就是这些了;这里面最需要理解的是ch 
at程序,在上面的缺省脚本中,它使用的是login:和password:提示。你的ISP会使用什 
么样的指令对?这个很难说,解决问题的唯一方法是手工拨号到对方的服务器上面,然 
后看一看对方到底使用的什么样的配置,完成这个任务的最好方式是使用一个终端仿真 
程序,比如Windows 9x的超级终端或者Linux的Minicom。 
   
  让我们来解释一下minicom。假设你的系统已经安装了这个产品,你首先需要建立/de 
v/modem设备。在我们的一般情况下,系统中已经有了/dev/cua0,/dev/cua1,/dev/cu 
a2或者/dev/ttyS0,/dev/ttyS1等设备,你只需要将调制解调器连接到正确的端口上, 
然后建立符号连接就可以了,/dev/ttyS0和/dev/cua0都是COM1,/dev/ttyS1和/dev/cu 
a1是COM2,以此类推。假设你的调制解调器接在COM2上,那么首先将/dev/modem连接到 
/dev/cua1: 
   
  ln –s /dev/cua1 /dev/modem 
   
  然后启动minicom: 
   
  $ minicom 
   
  Welcome to minicom 1.82 
 
   
  OPTIONS: History Buffer, F-key Macros, Search History Buffer, I18n  
   
  Compiled on Sep 23 1999, 22:29:11. 
 
   
  Press CTRL-A Z for help on special keys 
   
                                                        
   
  AT S7=45 S0=0 L1 V1 X4 &c1 E1 Q0                      
   
  OK                                       
   
  出现这样的提示就可以拨号了,输入拨号命令: 
   
  at                                                    
   
  OK                                                    
   
  atdt 163 
   
  CONNECT 33600/V42BIS 
   
  *** Welcome To AnShan 163 Arc03 ***  
   
  login: test 
   
  Password: 
   
  容易看到,在CONNECT连接符号之后,对方的拨号服务程序要送出一个Welcome To An 
Shan 163 Arc03的字符串,所以我们要在对应的chat脚本里面加上对应的行-虽然这个行 
根本不需要应答。我们首先把scripts目录里面的ppp-on,ppp-on-dialer和ppp-off,o 
ptions文件复制到/etc/ppp,然后将/etc/ppp-on里面的TELEPHONE,ACCOUNT,PASSWOR 
D都设置成你自己的内容,REMOTE_IP和LOCAL_IP设置为0.0.0.0: 
   
  #!/bin/sh 
   
  TELEPHONE=163      # The telephone number for the connection 
   
  ACCOUNT=lnte          # The account name for logon (as in 'George Burns') 
   
  PASSWORD= lnte        # The password for this account (and 'Gracie Allen') 
   
  LOCAL_IP=0.0.0.0        # Local IP address if known. Dynamic = 0.0.0.0 
   
  REMOTE_IP=0.0.0.0       # Remote IP address if desired. Normally 0.0.0.0 
   
  NETMASK=255.255.255.0   # The proper netmask if needed 
   
  export TELEPHONE ACCOUNT PASSWORD 
   
  DIALER_SCRIPT=/etc/ppp/ppp-on-dialer 
   
  exec /usr/sbin/pppd debug lock modem crtscts /dev/ttyS0 38400 \ 
   
          asyncmap 20A0000 escape FF kdebug 0 $LOCAL_IP:$REMOTE_IP \ 
   
    noipdefault netmask $NETMASK defaultroute connect $DIALER_SCRIPT 
   
  然后设置ppp-on-dialer进行应答: 
   
  #!/bin/sh 
   
  exec chat -v                                            \ 
   
          TIMEOUT         3                               \ 
   
          ABORT           '\nBUSY\r'                      \ 
   
          ABORT           '\nNO ANSWER\r'                 \ 
   
          ABORT           '\nRINGING\r\n\r\nRINGING\r'    \ 
   
          ''              \rAT                            \ 
   
          'OK-+++\c-OK'   ATH0                            \ 
   
          TIMEOUT         30                              \ 
   
          OK              ATDT$TELEPHONE                  \ 
   
          CONNECT         ''                              \ 
   
          Arc     ''   \ 
   
          ogin:--ogin:    $ACCOUNT                        \ 
   
          assword:        $PASSWORD 
   
  注意我们用的是Arc而不是Arc03,因为我们面对的是一个多道连选的拨号服务器,拨 
163会随机地拨到服务器的某一个modem上,而每个的提示都是ArcXX,所以我们提取相同 
的信息,就是Arc。 
   
  最后是/etc/ppp/options,这个文件只有一行: 
   
  [root@wxd ppp]# cat options 
   
  lock 
   
  ppp-off文件可以保持原状: 
   
  !/bin/sh 
   
  ###################################################################### 
   

   
  # Determine the device to be terminated. 
   

   
  if [ "$1" = "" ]; then 
   
          DEVICE=ppp0 
   
  else 
   
          DEVICE=$1 
   
  fi 
 
   
  ###################################################################### 
   

   
  # If the ppp0 pid file is present then the program is running. Stop it. 
   
  if [ -r /var/run/$DEVICE.pid ]; then 
   
          kill -INT `cat /var/run/$DEVICE.pid` 
   

   
  # If the kill did not work then there is no process running for this 
   
  # pid. It may also mean that the lock file will be left. You may wish 
   
  # to delete the lock file at the same time. 
   
          if [ ! "$?" = "0" ]; then 
   
                  rm -f /var/run/$DEVICE.pid 
   
                  echo "ERROR: Removed stale pid file" 
   
                  exit 1 
   
          fi 
   

   
  # Success. Let pppd clean up its own junk. 
   
          echo "PPP link to $DEVICE terminated." 
   
          exit 0 
   
  fi 
   

   
  # The ppp process is not running for ppp0 
   
  echo "ERROR: PPP link is not active on $DEVICE" 
   
  exit 1 
   
  最后把ppp-on,ppp-on-dialer,ppp-off的属性都设置成700。 
   
  配置现在就完毕了,然后就可以执行PPP: 
   
  $ cd /etc/ppp 
   
  $ ./ppp-on 
   
  会听到拨号声音,一会拨号就连通了,连通后,用ifconfig命令可以看到ppp0设备及 
其IP地址。 
   
  当拨号网络连通的时候,ISP会向客户机器传递域名服务器的地址,对于Windows 95, 
拨号网络程序可以自动下载这个地址并且刷新名字服务器信息,不过对于Linux,我们一 
般自己直接在名字服务器解析文件/etc/resolv.conf中加入ISP提供的名字服务器地址。 
   
  使用完毕后,可以用ppp-off命令切断ppp连接: 
   
  上面的内容就是一般的启动拨号服务的办法。个别的ISP会使用所谓PAP认证方式,这 
个认证方式不使用username:/password:指令对,而是由拨号程序在建立连线时自动传输 
认证信息(换句话说,当你使用minicom拨号的时候并不出现要求你登录的提示)。如果 
是这样,那么设置ppp的方式和我们这里讲的有所不同,详细的资料可以参考Linux PPP 
-HOWTO,这部分内容已经被翻译成中文。 
   
  如同上面显示的那样,配置ppp的任务并不算困难但是却很讨厌,一般来说,人们总是 
希望使用简化的配置。最常用的拨号程序除了直接使用ppp-on之外,就是图形界面下的 
kppp。当然对于服务器,为了拨号而启动X Window有些不值得。kppp的配置与Windows下 
的拨号网络一样简单,因此我们不再详细叙述了。 
   
  另外一个基于命令行的拨号工具称为wvdial,它和ppp的配置其实差不多,但是不需要 
设置令人头痛的应答过程。(笔者当初配置邮电局的16道连选弄得晕头转向,作了两天 
还没有解决,而用wvdial十分钟就连通了。) 
   
  要使用wvdial,需要安装wvdial软件包,在新的Linux发行版本中有不少包含这个程序 
。安装后,你只要按照下面的格式生成一个配置文件/etc/wvdial.conf: 
   
  [Dialer Defaults] 
   
  Modem=/dev/ttyS0 
   
  #调制解调器在com1,com2=/dev/ttyS1 
   
  Baud=57600 
   
  #调制解调器的速度 
   
  Init = ATZ 
   
  Init2 = AT S11=50 
   
  #调制解调器的初始化命令 
   
  Phone=163 
   
  #ISP电话号码 
   
  Username=user 
   
  Password=user 
   
  #ISP给你的用户名和口令 
   
  然后执行wvdial ,就可以看到一连串内容在屏幕上滚过,最后出现starting pppd . 
...表示连线成功了。连线结束时,可以用^C退出wvdial程序,这时wvdial会自动切断线 
路。 
   
  wvdial工作时需要保持运行,如果你觉得把它放在前台影响工作,可以用wvdial &将 
它放到后台,结束时用killall wvdial 命令。 
   
  要记住,pppd可能因为稀奇古怪的原因挂掉,如果你拨号没有成功,可以察看/var/l 
og/messages文件(或者在/etc/syslog.conf里面定义的任何记账文件)找出问题何在。 
   
  8.4.2 拨号代理 
   
  拨号代理其实就是我们前面说的IP代理系统,只是它的代理出口是使用拨号网络接口 
。简单地说,拨号代理就是一台能够拨号连接到internet的机器,局域网内的其他机器 
可以通过它连接到internet。 
   
  说到这里,大家应该已经理解一个拨号代理应该怎么做了,首先要按照前面的方法配 
置拨号网络使得拨号机器能够访问internet;配置局域网的机器IP为私用网络的IP,比 
如说私用网络是10.0.0.0/24,拨号代理的机器网卡IP地址为10.0.0.1;配置私用网络客 
户机器的网关地址为10.0.0.1;配置拨号代理机器启动核心IP转发功能;然后只要在拨 
号代理的机器上: 
   
  ipchains -A forward -s 10.0.0.1/24 –i ppp0 –j MASQ 
   
  insmod ip_masq_ftp 
   
  现在整个局域网就可以通过这条电话线访问internet了。 
   
  实际上,作拨号代理确实十分简单,最多再加上身份鉴别,避免别的用户冒充为你的 
私用网络用户进入系统: 
   
  ipchains –A input –s 10.0.0.1/24 –i ppp0 –j REJECT 
   
  其他像禁止某些用户访问别的站点等等都可以按照前面讨论防火墙的方法去做。 
   
  如果你想用拨号网络连接两个局域网,那么做法仍然和这里是类似的,只是不再使用 
MASQ选项,而且要按照第一节的原则来考虑路由递送问题。特别是,现在我们需要使用 
静态IP地址,就是将ppp-on里面的LOCAL_IP和REMOTE_IP正确配置。另外,在ppp-on脚本 
中的pppd命令行选项defaultroute必须仔细考虑,这个参数表示将拨号连接当成缺省路 
由,如果你认为有问题的话,把它改成nodefaultroute并且手工用route命令设置路由。 
   
  在使用拨号代理的过程中,你很可能会感到在用户开始上网的同时进行拨号是很方便 
的,而一旦所有用户都已经停止连接就自动切断ppp连接。这个功能可以用diald程序来 
完成。diald并不包含在一般的Linux发行版本中,你需要自己去下载这个程序。 
   
  要使用diald,你需要在内核中编译加入SLIP支持(即使你仅仅准备使用ppp连接网络 
)。然后你可以编译并且安装diald。一般情况下,有几个文件设置了diald的行为,最 
主要的是/etc/diald.conf。 
   
  如果你按照我们上面说的那样已经配置好了ppp连接,ppp-on-dial脚本已经正常,那 
么你可以写这样一个非常简单的/etc/diald.conf: 
   
          mode ppp 
   
                connect /etc/ppp/ppp-on-dial  
   
                device /dev/ttyS1 
   
                speed 57600 
   
                modem 
   
                lock 
   
                crtscts 
   
                local 10.0.0.2 
   
                remote 10.0.0.1 
   
                dynmatic 
   
                defaultroute 
   
                include /usr/lib/diald/standard.filter 
   
  注意这个文件中的local和remote参数。这两个参数是设置拨号两端的IP的,现在因为 
使用的ip地址是ISP动态分配给你的,所以用dynmatic参数设置地址为动态地址。问题是 
如果在配置文件中不给出地址的话,diald程序就无法正确启动拨号脚本,所以你可以给 
它一对私用IP让diald程序自己去处理。剩下的任务就是启动diald,然后让服务器自己 
去拨号就可以了。 
   
  8.4.3 拨号服务器 
   
  现在我们来研究如何做一个拨号网络服务器。作拨号服务器仍然是利用pppd程序,不 
过,这一次我们必须解释一点东西。 
   
  在最简单的情况下,假如你是一个ISP管理者,你只需要让用户连接到你的系统中,就 
可以为他们提供网路服务。在这种情况下,客户的机器逻辑上是你的子网的一部分,为 
了是客户机器可以和同一子网的机器通讯,我们可以使用ARP代理功能,就是拨号服务器 
替客户应答ARP询问,因此其他机器会把应该送给客户机器的信息包交给服务器,服务器 
再转交给客户机器。这个和我们前面讨论分割地址空间时的ARP代理没有任何区别。这种 
情况下,客户机器到外界的联系完全由服务器代理,因此客户端几乎不需要设置任何东 
西。相反,如果你是要用电话线把两个子网连接起来,那么你需要的是在两个子网上建 
立缺省投递路径,内容就和我们第一节介绍的完全一样,甚至也可以用ipchains控制信 
息的流动。 
   
  当客户拨号到服务器上的时候,首先是调制解调器之间建立连接,为了实现这个功能 
,服务器的调制解调器必须设置为等待/应答方式,一旦有拨入就能接受服务。如果你仅 
仅是想把客户机器当成终端来使用服务器,那么这就足够了;否则,如果你使用拨号网 
络等windows 9x的ppp客户程序来拨入,它将向服务器传输PAP认证信息。你的拨号服务 
器接受到这些信息之后,对客户的身份进行验证并且去处理缺省的拨号脚本,启动pppd 
程序在两台机器之间建立起数据通路,这样,客户机器就被连接到服务器所在的网络上 
。 
   
  现在我们来介绍如何制作第一种情况下的PPP服务器,仍然假定你的内核编译的时候已 
经加入了PPP支持。我们首先建立一个下面形式的/etc/ppp/options文件: 
   
  asyncmap 0 
   
  netmask 255.255.255.0 
   
  proxyarp 
   
  lock 
   
  crtscts 
   
  modem 
   
  ms-dns 202.199.248.2 
   
  这个文件的详细含义请参考man ppp。proxyarp和netmask给出了PPP连接的工作方式为 
ARP代理。lock是锁定调制解调器避免拨号连接被其他程序干扰,crtscts设置调制解调 
器使用硬件流控制方式。需要特殊说明的只有最后一行,一般来说,作为拨号客户的总 
是windows 机器,而windows 9x期望从服务器上取得关于网关和DNS服务器的信息,这行 
就是起这个作用的,ms-dns将DNS服务器的地址传递给拨号客户。另外还有几个很常用的 
参数,其中最重要的是nodetach,它避免pppd复制出一个在后台运行的子进程,如果你 
发现在拨号连接被切断之后pppd程序没有正确退出,加入这样一行。另外,还有一对de 
faultroute和nodefaultroute选项,在我们现在的情况,缺省值nodefaultroute就可以 
满足要求了。 
   
  下一步,我们必须为每个拨入调制解调器准备一个配置文件,配置文件的名字规则是 
/etc/ppp/options.ttyXX,例如你的modem接在COM1上,就需要生成一个文件/etc/ppp/ 
options.ttyS0。以此类推。 
   
  options.ttyXX的内容非常简单,就是[本地IP]:[远端IP]。例如,我的PPP server的 
IP地址是202.199.248.8,名字是server,我想为从com1拨入的用户分配IP地址202.199 
.248.19,名字是dialclient。那么需要在/etc/ppp/options.ttyS0文件中写上: 
   
  202.199.248.8:202.199.248.19 
   
   或者 
   
  server:dialclient 
   
  接下来,需要作的是建立身份验证文件。一般情况下,我们在客户端用的是windows  
9x,而windows使用的是PAP验证,所以我们必须为PAP准备身份验证文件。这个文件的缺 
省名字是/etc/ppp/pap-secrets,而它的行的格式是: 
   
  [用户名] [远端机器名] [口令] [远端IP]。可以使用通配符"*"。 
   
  例如,我们希望允许用户user01可以从任何地方拨入,并且可以使用前面定义的远端 
IP地址202.199.248.18,口令是test01,那么使用这样的行: 
   
  user01 * test01 202.199.248.18 
   
  如果希望user01可以从任何地方拨入,而且可以使用所有定义在options.ttyXX中的远 
端IP地址,那么使用 
   
  user01 * test01 * 
   
  由于pppd程序需要控制网络接口(建立网络接口),所以需要使用root身份来执行, 
为了让所有拨号用户都能使用pppd,需要设置pppd为setuid程序: 
   
  # ls -l /usr/sbin/pppd 
   
  -rwxr-xr-x   1 root     root       138596 Sep 20  1999 /usr/sbin/pppd 
   
  pppd程序的拥有者是root,只要setuid就行了: 
   
  chmod u+s /usr/sbin/pppd 
   
  接下来是最困难的步骤了,启动调制解调器应答。为了驱动调制解调器,你的系统中 
必须有一个串行口管理程序。我们使用的是mgetty,它包含在大部分Linux发行版本中。 
假设你已经安装了mgetty程序,例如 
   
  $rpm -q mgetty 
   
  mgetty-1.1.14-9 
   
  就可以开始设置调制解调器应答了,进入到/etc/mgetty+sendfax目录,编辑mgetty. 
config文件。 
   
  下面是我们的mgetty.config文件,你可以按照这个方式自己编写: 
   
  # !mgetty.config 
   
  debug 4 
   
  speed 38400 
   
  port ttyS0 
   
  init-chat "" ATZ OK "AT M0E1Q0S0=0" OK 
   
  answer-chat "" ATA CONNECT \c \r 
   
        port ttyS1 
   
  init-chat "" ATZ OK "AT M0E1Q0S0=0" OK 
   
  answer-chat "" ATA CONNECT \c \r 
   
  这个文件的内容倒是十分简单的,debug 4将mgetty的纪录级别定义为4,在你调试正 
常之后可以将它改成一个合适得值;speed 38400设置了传输速度为33.6k;接下来的就 
是各端口连接的调制解调器的初始化段落,port ttyS0往下的段落定义了一个接在COM1 
上的调制解调器,而init-chat和answer-chat分别定义调制解调器的初始化和应答命令 
。port ttyS1则是COM2上的调制解调器,这样,每一个调制解调器都需要自己的段落。 
这里的init-chat和answer-chat中的命令可以适用于大部分调制解调器。不要问我这些 
命令从那里来的,你可以自己参考关于调制解调器的标准。必须注意缺省的mgetty.con 
fig文件中,有一行(fax_id ....)是用来设置缺省应答为传真的,你必须手工把它去掉 
。 
   
  如同我们说的,调制解调器的驱动是靠mgetty程序,我们可以手工启动mgetty程序, 
不过更常见的方法是修改运行级别。我们知道,缺省的/etc/inittab定义了所有的运行 
级别,在多用户级别,它利用mingetty程序开出了六个虚拟屏幕,我们可以用同样的方 
法开出一个虚拟终端,这只需要修改/etc/inittab文件的下面部分(加粗体的是我们加 
入的部分): 
   
  #!/etc/inittab 
   
  ……………… 
   
  1:2345:respawn:/sbin/mingetty tty1 
   
  2:2345:respawn:/sbin/mingetty tty2 
   
  3:2345:respawn:/sbin/mingetty tty3 
   
  4:2345:respawn:/sbin/mingetty tty4 
   
  5:2345:respawn:/sbin/mingetty tty5 
   
  6:2345:respawn:/sbin/mingetty tty6 
   
  sm1:35:respawn:/sbin/mgetty ttyS0 
   
  ………………………… 
   
  在运行级别三和五,对ttyS0启动mgetty。如果你有更多的调制解调器,启用更多的m 
getty行就可以了。 
   
  上面给出的是一个接在com1上的调制解调器的驱动方式,如果你有更多的调制解调器 
,为每个调制解调器在mgetty.config文件中加入一个段落,并且在/etc/inittab中开出 
一个mgetty进程。不过,我个人只实验过连接两个调制解调器,如果你需要接续8个或更 
多的同时连接,你多半需要某种多串口卡。据说,多串口卡上的串行口相应的设备名字 
是ttyCXX,你可以自己试试。也许要在核心中编译相应的支持。 
   
  在客户程序拨入的时候,mgetty程序将试图调用/etc/mgetty+sendfax/login.config 
,从中查找关于AutoPPP的内容,所以我们必须建立这个文件,如果你只是要使用PPP服 
务,可以将这个文件设置为只有下面这样一行:(实际上,你的缺省安装的mgetty里面 
已经有一个这样的模板了) 
   
  !#login.config 
   
  /AutoPPP/ -     a_ppp   /usr/sbin/pppd auth silent -chap +pap login 
   
  -chap +pap表示使用pap身份认证方式。为了避免输出不必要的垃圾信息,使用silen 
t选项。另外,如果你希望用户连接中的信息以用户的名字(而不是缺省的a_ppp)进行 
记录的话,将a_ppp改成一个"-"。 
   
  至此,我们配置好了调制解调器的行为,接下来,连接调制解调器,打开调制解调器 
电源,重新启动服务器以便确保inittab中开出的mgetty被正确执行,不要忘了打开核心 
IP转发,然后就可以接受客户机器的拨号呼叫了。 
   
  上面说的是基于ProxyARP的拨号服务,这个服务的最大特点是客户机器和服务器处在 
一个子网之内,如果你想要用拨号网络连接两个子网,那么你需要去掉/etc/ppp/optio 
ns文件中的proxyarp命令行,并且设置缺省路由递送路径。特别是,需要把拨号网络的 
服务器/客户的拨号网络接口当成一个缺省路由路径,这可以手工加入路由路径,但是更 
常用的方法是使用在/etc/ppp/options文件中加入defaultroute行(没有参数),这样 
ppp管理程序会自动将拨号连接作为一个缺省路由路径加入,在ppp被切断之后自动删除 
路径。注意服务器和客户端都必须使用这个选项。 
   
  ppp server是一种非常容易出现问题的东西,为此,缺省情况下,pppd产生的信息将 
会被存储到/var/log/messages中,而mgetty则对任何ttyXX产生一个/var/log/mgetty. 
log.ttyXX文件,如果你的ppp莫名其妙地当掉或者无法建立连接,请研究这些记录文件 
中的错误信息。 
   
  另外,也存在其他的拨号连接数据传递方式,例如uucp和slip。不过,由于本书是一 
本处理常规问题的教本,我不想在这里讨论这个问题。毕竟,ppp已经够用了,对吗? 
   
  最后我们要额外说明一句,有时某些人并不希望建立一个网络连接,相反,他希望能 
够以终端方式连接到服务器上。在这种情况下,你只要按照前面的方法设置好调制解调 
器应答,开出合适的mgetty进程,就会发现用户已经可以拨号连接到服务器上了。这个 
技术的一个古怪的应用是用Null-Modem连接来接通两台机器,详细的资料可以参考随mg 
etty提供的文档。 
   
  8.5 网络代理程序 
   
  在Apache服务器的部分我们已经接触到了浏览代理的概念。与IP代理不同,浏览器代 
理或者类似的其他代理程序通常只能对确定的应用程序进行代理。这类代理程序往往是 
为了减少网络流量,提高网络速度或者是绕过防火墙用。 
   
  我们在这里讨论最常用的代理程序。squid类似于apache的浏览代理,实际就是一个高 
速缓冲器,但是在某些方面,它比apache更容易管理。而socks5代理则是一个特殊的转 
发器,它利用某种特定的编程接口接受客户的请求并且代替客户处理请求。 
   
  8.5.1 squid代理程序 
   
  与Apache的proxy功能类似,squid也是一个接受客户请求,代替客户处理并且加以缓 
冲的产品。但是与apache不同的是,squid不需要forks自身。另外,squid可以配置成为 
利用用户名和口令来限制用户的身份,这在按照IP地址进行身份认证不适用的时候是很 
重要的。 
   
  squid是一个功能非常强大的程序,例如你可以将它配置成向“内”的服务器(提高你 
自己的服务器的响应能力),或者是用多个squid机器构成复杂的缓冲系统,如此等等, 
你可以自己参考squid的文档。作为一本教程,我们不想涉及到这一类过于专门的问题中 
去。我们将主要介绍如何配置一个可以通过密码验证用户的代理系统。实际上,很多防 
火墙的设计者都利用squid在不损害防火墙的可靠性的同时使得用户的应用更加简便。例 
如,你可以用防火墙将除了squid机器之外的所有内部机器全部挡住,然后让客户通过s 
quid访问外界,这样的方法比建立复杂的ipchains过滤规则更容易,而且除非防火墙机 
器被攻克,内部的机器是安全的。 
   
  要使用squid,首先必须安装这个程序,例如: 
   
  [root@wxd linux]# rpm -q squid 
   
  squid-2.2.STABLE4-5 
   
  然后就可以配置squid程序了。 
   
  squid的配置文件在/etc/squid/squid.conf,(编译时定义),实际上,你完全可以 
在缺省的配置文件上改动,不过,按照我们的一般方法,我们从一个适当构作的最小的 
squid.conf开始: 
   
  http_port 4444 
   
  acl LOCALDOMAIN src 202.199.248.0/255.255.255.0 
   
  acl test proxy_auth REQUIRED 
   
  acl all src 0.0.0.0/0 
   
  acl SSL_ports port 443 563 
   
  cache_mem  8 MB 
   
  cache_dir /var/squid/cache 100 16 256 
   
  cache_access_log /var/log/squid/access.log 
   
  cache_log /var/log/squid/cache.log 
   
  cache_store_log /var/log/squid/store.log 
   
  cache_dns_program /usr/bin/dnsserver 
   
  dns_children 5 
   
  authenticate_program /usr/bin/ncsa_auth /etc/squid/passwd 
   
  authenticate_children 5 
   
  authenticate_ttl 30 
   
  reference_age 1 month 
   
  acl Safe_ports port 80 21 443 563 70 210 1025-65535 
   
  acl CONNECT method CONNECT 
   
  http_access allow LOCALDOMAIN 
   
  http_access allow test 
   
  http_access deny !Safe_ports 
   
  http_access deny CONNECT !SSL_ports 
   
  http_access deny all 
   
  这个配置文件包含了squid的主要内容,首先,http_port 4444定义squid使用的代理 
服务端口。这里利用4444端口作为代理端口,注意由于squid是以nobody权限运行,这个 
端口必须大于1024。 
   
  接下来,acl是一种定义行,上面的定义可以这样解释: 
   
  acl all src 0.0.0.0/0将"all"定义为一个类,包含所有客户机器。src说明这里的定 
义是对源地址的,也可以用dest对目标地址进行定义,如acl sth dest 202.199.248.0 
/24。 
   
  acl LOCALDOMAIN src 202.199.248.0/255.255.255.0如上述是定义所有位于202.199 
.248.*处的客户机器为LOCALDOMAIN类。 
   
  acl SSL port 443 563 将所有目标端口是443或563的访问定义为SSL类。同样另外的 
一句acl safe_ports port 80 21 443 563 70 210 1025-65535定义连接到这些端口的访 
问为安全端口。 
   
  acl test proxy_auth REQUIRED定义所有需要身份验证的用户为test类。 
   
  acl CONNECT method CONNECT 定义所有使用TCP连接的用户为CONNECT类。 
   
  实际上,所有这些类的定义都是为了给后面的存取限制提供定义,我们可以在最后看 
到存取限制语句: 
   
  http_access allow LOCALDOMAIN 
   
  http_access allow test 
   
  http_access deny !Safe_ports 
   
  http_access deny CONNECT !SSL_ports 
   
  http_access deny all 
   
  允许202.199.248.0/24的用户使用代理;另外凡是通过了身份验证的用户也可以使用 
代理;其他的全部禁止。访问到非安全端口的全部禁止。 
   
  squid的用户身份验证是通过密码验证。要使用这个功能,首先必须编译squid的密码 
验证程序。这要求你安装了squid的源代码,然后在squid源代码的目录中 
   
  $make 
   
  gcc -g -O2 -Wall -I. -I../../include -I../../include    -c ncsa_auth.c -o  
ncsa_auth.o 
   
  gcc -g ncsa_auth.o -o ncsa_auth -L../../lib -lmiscutil -lcrypt -lm -lresol 
v -lbsd -lnsl 
   
  将会在当前目录下产生一个ncsa_auth程序。将它拷贝到/usr/bin下面。 
   
  我们可以通过Apache部分讲到的htpasswd程序生成身份验证需要的密码文件: 
   
  $htpasswd -c /etc/squid/passwd wanghy 
   
  New password:  
   
  Re-type new password:  
   
  Adding password for user wanghy 
   

   
  这样就加入了一个名叫wanghy的squid用户,然后就可以用上面的行来启用身份验证程 
序了: 
   
  authenticate_program /usr/bin/ncsa_auth /etc/squid/passwd 
   
  authenticate_children 5 
   
  说明用/usr/bin/ncsa_auth作为身份验证程序,验证密码文件为/etc/squid/passwd, 
注意这个文件必须全局可读,因为squid在工作的时候,是用一个属主为nobody的子进程 
来执行,相应地ncsa_auth的权限也是nobody。authenticate_children是身份验证程序 
的个数。设置了身份验证后,用户访问代理服务时会弹出这样的对话框: 
   
  
   
  图8.3 squid的身份验证 
   
  只有用户名和口令符合,才能通过代理访问外界。 
   
  authenticate_ttl 3600这样的行用来定义一次身份验证的有效期,如果超过了这个时 
间用户没有动作,再连接时squid会要求用户重新进行身份验证。 
   
  接下来的几行设置squid用的内存数量,使用的纪录文件,而最重要的是下面一行: 
   
  cache_dir /var/squid/cache 100 16 256 
   
  这个命令设置squid用来存贮cache文件的目录,这个目录必须是全局可写的;后面三 
个参数,第一个是目录的容量,或者说最大允许多大的cache;第二个和第三个则是第一 
层和第二层目录下允许有多少个子目录,你可以自己调节这些数字。 
   
  如果你处在防火墙内部,而名字服务器位于防火墙外,你可能希望代理服务器能同时 
对DNS进行代理,下面两行: 
   
  cache_dns_program /usr/bin/dnsserver 
   
  dns_children 5 
   
  启动了这个功能,dnsserver程序是缺省的dns代理程序,包含在squid软件包中。dns 
_children是缺省的DNS代理程序的个数。 
   
  最后的一个常用参数是reference_age,它表示一个无人访问的缓冲文件将在硬盘上保 
留多长时间,缺省是一个月,你可以自己调整。 
   
  当squid.conf配置正确之后,需要生成一下cache目录,这可以用-z参数完成: 
   
  $ /usr/sbin/squid -z 
   
  然后就可以启动squid了: 
   
  $/usr/sbin/squid 
   
  接下来,将客户机器的代理服务器添成你的squid机器,一切正常的的话就可以使用了 
,如果有什么问题,可以看定义的几个记录文件。一定要注意,squid真正的缓冲程序是 
以nobody身份执行。 
   
  关于squid,比较容易出现问题的是它的用户身份验证。实际上,这个身份验证可以用 
你自己写的程序完成。当squid接收用户身份认证信息的时候,它传递一个用户名/密码 
的字符串给squid.conf里面设定的密码验证程序,并且期望验证程序在密码正确时输出 
OK,否则输出ERR。这种行为可以用nsca_auth程序的工作方式来说明: 
   
  bash# ./ncsa_auth passwd 
   
  user1 password 
   
  OK 
   
  test testerror 
   
  ERR 
   
  这是个无限循环,如果输入正确的用户名 口令,输出OK,直到系统给它一个中止信号 
。你可以自己写一个类似的密码验证程序。 
   
  8.5.2 socks 5及其使用 
   
  socks代理是另外一种“在防火墙上钻孔”的常用程序。与前面提到的浏览器代理程序 
不同,socks代理是使用一种特殊的API,让客户机器和服务器进行对话,客户将数据包 
(而不是浏览器请求)提交给服务器,服务器代替客户机器与网络进行对话,并且返回 
结果。socks的最大优势是,几乎所有的正常TCP/IP程序都可以利用socks5的客户程序“ 
包装”来使用代理,即使这个程序本来并不支持socks5。由于透明的支持UDP proxy,s 
ocks5程序经常被用来让防火墙内的机器使用ICQ等聊天程序。目前最常用的socks代理协 
议是socks5。 
   
  要使用socks5代理,简单地取回socks5服务程序,例如我们用的是socks5-1.0r4,取 
回socsk5-v1.0r4.tar.gz,展开成源代码目录,进入后编译安装: 
   
  ./configure 
   
  make 
   
  make install 
   
  将会产生/usr/local/bin/socks5程序,启动socks5只要执行这个程序。 
   
  socks5的缺省配置文件是/etc/socks5.conf,我们在这里不想对socks5作太多的介绍 
,如果你想制作一个对某些客户可以使用的socks代理,参考下面的socks5.conf配置: 
   
  permit  -       -       202.199.248.0/255.255.255.0     -       -       - 
   
  auth -  -       - 
   
  这样就构成了一个对202.199.248.0/24的网络开放的socks代理。使用的时候,只要在 
IE的代理服务器的socks代理中添上你的socks5服务器地址就可以了,端口号是(缺省) 
1080。 
   
  IE/Netscape/ICQ都可以直接使用socks5代理,如果需要让一些不支持socks代理的客 
户程序能够使用socks5代理,你需要使用socks的专用客户程序。通常我们的客户机器是 
Windows 9X,对应的客户程序是sockscap程序,你可以自己下载这个程序,安装到客户 
机器上,使用方法很简单,这里不再叙述。 
   
   
 
 
-- 
当我越过无尽虚空的时候,我看见星辰的欲望,光荣和毁灭,这是光辉世界的宿命, 
一切的一切,最终必将落入黑暗和虚无。 
所以,我随着星光飞翔,去逃脱必然的终结,也许有一天,我将回到世界的原初, 
等待新的星辰的诞生。 
尘埃是星的起源,星的终结。 
 
 
※ 来源:·BBS 水木清华站 smth.org·[FROM: 202.112.90.20] 

BBS水木清华站∶精华区