用FreeBSD建立拨号网关

发表于:2007-07-04来源:作者:点击数: 标签:
家庭 网络 结构如下: W2K(192.168.0.100) -----以太网----- FreeBSD(192.168.0.200) -----PPP拨号----- internet 实现要求如下: 在FreeBSD主机上使用调制解调器拨号上网,并对局域网内其它计算机提供该拨号连接的共享。 在FreeBSD主机上设置缓冲型的DNS系

  家庭网络结构如下: 
  
  W2K(192.168.0.100) -----以太网-----> FreeBSD(192.168.0.200) -----PPP拨号-----> internet 
  
  实现要求如下: 
  
       在FreeBSD主机上使用调制解调器拨号上网,并对局域网内其它计算机提供该拨号连接的共享。 
       在FreeBSD主机上设置缓冲型的DNS系统以避免对域名的重复查询,减轻网络流量。 
       在FreeBSD主机上设置Squid软件对局域网提供http代理服务并配置ipfw防止用户绕过代理服务器。 
       在FreeBSD主机上使用Fetchmail及Qpopper为局域网用户代收外部电子邮件。 
  
  安装PPP
  众所周知,在FreeBSD下有两种类型的PPP,在这里为简单起见使用用户级PPP(User-PPP),因为
  内核级PPP(Kernel-PPP)需要更多设定配置方面的工作。 
  
  当然在开始之前弄清设备所用的硬件资源可使工作事半功倍。为此,需要了解以下内容: 
  
       调制解调器所用端口及速率(我假设为所用端口为串口1、速率为115200) 
       上网的账号及口令 
       ISP分配的静态IP地址(如为动态分配则无须知道) 
  
  现在要根据这些资料来配置并编译新的内核以支持用户级PPP和防火墙功能,在内核配置文件中加入以下内容:
  
  
  options IPFIREWALL #防火墙功能
  options IPDIVERT #转移套接字(支持NAT)
  # 串(COM)口
  device sio0 at isa? port "IO_COM1" flags 0x10 tty irq 4
  # 伪设备 - 数字说明分配之单元数
  pseudo-device tun 1 # 分组隧道 
  
  编译完新内核后,就可以根据需要修改/etc/ppp/ppp.conf文件了(相应的防火墙功能稍后配置),该文件的样本如下:
  
  
  default: 
  
  set device /dev/cuaa0
  set log Phase Chat LCP IPCP CCP tun command
  set speed 115200
  set dial "ABORT BUSY ABORT NO\\sCARRIER TIMEOUT 5 \"\" AT OK-AT-OK ATE1Q0 OK \\dATDT\ \T
  TIMEOUT 40 CONNECT" 
  
  set timeout 120
  set ifaddr 10.0.0.1/0 10.0.0.2/0 255.255.255.0 0.0.0.0
  add default HISADDR
  enable dns
  nat enable yes 
  
  163: 
  
  set phone 163
  set authname 163
  set authkey 163 
  
  在此样本文件中,set device说明使用的端口,在此我用了串口1;set speed说明设备使用的速率,我用的是115200;set ifaddr说明PPP连接所用的IP地址,第一个地址为本地地址及网络掩码,而第二个地址为ISP处的拨号服务器地址及掩码。如果使用ISP动态分配的地址,就可以象我这样用掩码为0的地址,它说明可以接受任何地址。否则请指定您的ISP分配的静态地址。
  nat enable yes说明该PPP拨号连接可以让局域网络内的其它计算机共享。它使用NAT技术将网络内有连接请求的主机本身的本地IP转换为PPP连接所用的IP,从而可以访问外部互联网。 
  
  适当修改后可以用ppp命令来进行拨号测试了: 
  
  #ppp
  ppp > dial 163
  PPP > 
  
  当提示符由小写变为大写时说明已经拨号成功了,这时可以ping一下ISP处的DNS服务器地址,看是否能通。另外还可以用netstat命令检查网络状态: 
  
  # netstat -nr
  Routing tables 
  
  Internet:
  
  Destination         Gateway                 Flags     Refs   Use        Netif   Expire
  127.0.0.1            127.0.0.1                UH        10      389        lo0
  192.168               link#1                     UC        0        0            ed0
  192.100.53.23    202.102.141.141    UH        1        0            tun0
  192.168.0.100    52:54:4c:19:6d:d   UHLW   2        3968      ed0    1198
  
  要挂断退出可以在提示符下打quit命令,当然还可以用killall -INT ppp来中止当前的连接,否则如果空闲120秒就会自动挂断了(可以用settimeout参数进行调整)。这样,简单的PPP拨号连接配置就完成了。要更多的了解配置PPP方面的内容,可以参考Setting up User PPP(FreeBSD手册中关于用户级PPP的设定细节)。 
  
  使FreeBSD成为拨号网关
  前面提到在/etc/ppp/ppp.conf中使用nat enable yes可以让网络内其它主机共享此PPP拨号连接,当然要达到这样效果,还必须让FreeBSD成为网关以允许转发IP数据包,所以在/etc/rc.conf文件中加入: 
  
  gateway_enable=YES 
  
  然后重新启动系统使其生效,当然,如果不想重启,可以用以下命令: 
  
  sysctl -w net.inet.ip.forwarding=1 
  
  注意:PPP拨号会修改路由表,为使路由稳定,系统不能启动动态路由守护程序,如routed或 gated,因为它们会动态修改路由表。 
  
  设置缓冲型DNS
  为了对网内计算机查询域名进行缓冲,首先修改/etc/resolv.conf,因为PPP的enable dns参数会为系统设定从ISP处获得的域名服务器,要使系统优先使用本地域名服务器才能发挥缓冲型DNS的特性,这时可以把其它服务器作为后备: 
  
  domain meaculpa.net
  nameserver 127.0.0.1
  nameserver 202.102.14.141
  nameserver 202.102.15.162 
  
  以上添加127.0.0.1作为首域名服务器。然后用/etc/namedb/make-localhost产生适合本机的localhost.rev文件。注意,make-localhost脚本属性为644,需以root身份将其改为744才能运行。 
  
  接着修改/etc/namedb/named.conf,以使BIND运行为缓冲方式,样本如下: 
  
  options {
  directory "/etc/namedb";
  forward only;
  forwarders {
  202.102.14.141;
  };
  }; 
  
  zone "." {
  type hint;
  file "named.root";
  }; 
  
  zone "0.0.127.IN-ADDR.ARPA" {
  type master;
  file "localhost.rev";
  }; 
  
  如使用BIND4则修改named.boot,样本如下: 
  
  directory /etc/namedb
  primary 0.0.127.IN-ADDR.ARPA localhost.rev
  cache . named.ca
  forwarders 202.102.14.141
  options forward-only 
  
  最后就可以向/etc/rc.conf文件加入以下行使域名服务启动: 
  
  named_enable="YES" 
  
  这样重启后就拥有一个缓冲型的DNS系统了,这时可以设置局域网内其它计算机的TCP/IP属性,将DNS服务器指向该系统以利用其特性。 
  
  安装Squid
  为了改善慢速的拨号连接并阻塞内部计算机直接访问外部网站,可以安装一套代理/缓冲系统并添加一定的防火墙规则。 
  
  在FreeBSD上我用了Squid这套软件,当然可以有两种安装方法,一是用现成的tgz包,打pkg_add命令就可以方便地装好了;另外就是到http://squid.nlanr.net/下载合适的版本(这里用了squid21)到FreeBSD的ports目录里自己编译安装,如: 
  
  cd /usr/ports/www/squid21;make install 
  
  建立Cache系统
  接下来首先需要建立Cache目录。缺省会使用100M的磁盘空间,建议专门分一个区给它使用,如/cache。如果您想调整此Cache目录的大小,可以适当修改/usr/local/etc/squid/squid.conf文件。 
  
  在完成对其配置文件的修改后进行首次运行时,必须以root身份建立Cache目录: 
  
  # /usr/local/sbin/squid -z 
  
  如果得到“Permission denied”的出错信息,如: 
  
  09:09:29| Creating Swap Directories FATAL: Failed to make swap directory 
        /usr/local/squid/cache/00: (13) Permission denied
  Squid Cache (Version 2.1):Terminated abnormally. CPU Usage: 0.022 seconds 
        Maximum Resident Size: 1000 KB Page faults with physical i/o: 0 
  
  则可能是以下原因之一: 
  
       磁盘上没有空间了。
       (对此我无能为力) 
       没有建立/usr/local/squid/logs/目录。
       (手工建一个嘛) 
       您的/usr/local/squid/logs/cache.log文件属于root。
       (可以用这条命令“chown nobody.nogroup
       /usr/local/squid/logs/cache.log”改一下,另外../log和../cache目录里的
       所有文件都要有此属性。) 
  
  于是我查了一下这些目录中的文件,的确都属于root,所以我用了这两条命令: 
  
  # chown nobody.nogroup /usr/local/squid/logs
  # chown nobody.nogroup /usr/local/squid/cache 
  
  然后再试一下建立Cache目录: 
  
  # /usr/local/sbin/squid -z 
  2001/01/01 09:14:32| Creating Swap Directories 
  
  这次运行顺利! 
  
  测试
  在IE的选项->连接选项卡中设好代理服务器的地址和端口(3128),接着用squid的调试/测试模式进行试运行: 
  
  # /usr/local/sbin/squid -NCd1
  09:30:54| Starting Squid Cache version 2.1 for i386--freebsd3.2...
  09:30:54| Process ID 1026
  09:30:54| With 1064 file descriptors available
  09:30:54| Performing DNS Tests...
  09:30:54| Suclearcase/" target="_blank" >ccessful DNS name lookup tests...
  09:30:54| helperOpenServers: Starting 5 'dnsserver' processes
  09:30:54| Unlinkd pipe opened on FD 13
  09:30:54| Swap maxSize 102400 KB, estimated 7876 objects
  09:30:54| Target number of buckets: 157
  09:30:54| Using 8192 Store buckets, replacement runs every 10 seconds
  09:30:54| Max Mem size: 8192 KB
  09:30:54| Max Swap size: 102400 KB
  09:30:54| Rebuilding storage in Cache Dir #0 (DIRTY)
  09:30:54| Loaded Icons.
  09:30:54| Accepting HTTP connections on port 3128, FD 35.
  09:30:54| Accepting ICP messages on port 3130, FD 36.
  09:30:54| Ready to serve requests.
  09:30:54| storeRebuildFromDirectory: DIR #0 done!
  09:32:10| Finished rebuilding storage disk.
  09:32:10| 0 Entries read from previous logfile.
  09:32:10| 0 Entries scanned from swap files.
  09:32:10| 0 Invalid entries.
  09:32:10| 0 With invalid flags.
  09:32:10| 0 Objects loaded.
  09:32:10| 0 Objects expired.
  09:32:10| 0 Objects cancelled.
  09:32:10| 0 Duplicate URLs purged.
  09:32:10| 0 Swapfile clashes avoided.
  09:32:10| Took 76 seconds ( 0.0 objects/sec).
  09:32:10| Beginning Validation Procedure
  09:32:10| storeLateRelease: released 0 objects
  09:32:11| Completed Validation Procedure
  09:32:11| Validated 0 Entries
  09:32:11| store_swap_size = 21k
  09:32:31| parseHttpRequest: Unsupported method 'PROPFIND'
  09:32:31| clientReadRequest: FD 14 Invalid Request 
  
  (用Ctl+C中止squid) 
  
  09:33:44| Preparing for shutdown after 8 requests
  09:33:44| Waiting 0 seconds for active connections to finish
  09:33:44| FD 35 Closing HTTP connection
  09:33:45| Shutting down...
  09:33:45| FD 36 Closing ICP connection
  09:33:45| Closing unlinkd pipe on FD 13
  09:33:45| storeDirWriteCleanLogs: Starting...
  09:33:45| Finished. Wrote 0 entries.
  09:33:45| Took 0 seconds ( 0.0 entries/sec). 
  
  对/usr/local/etc/squid/squid.conf文件进行修改以允许适当的主机使用代理服务,
  为此加入以下三条: 
  
  acl ourhosts src 192.168.0.0/255.255.255.0 #定义可以使用代理服务的主机地址范围及组名
  http_access allow ourhosts    #允许此组访问http
  http_access deny all    #禁止其它所有主机访问http 
  
  重新启动squid,并用IE进行测试,结果很顺利: 
  
  # /usr/local/sbin/squid -NCd1 
  
  最后检查一下/usr/local/etc/rc.d目录中是否有它的启动脚本squid.sh,如没有可参照以下内容建一个: 
  
  #!/bin/sh
  if [ -x /usr/local/sbin/RunCache -a -f /usr/local/etc/squid/squid.conf ]; then
  (cd /tmp; /usr/local/sbin/RunCache >/dev/null 2>&1 &) ; echo -n ' squid'
  fi 
  
  防止用户绕过代理服务器
  好了,现在已经初步架好了squid(该服务器软件有非常之多的配置选项,可根据需要修改/usr/local/etc/squid/squid.conf配置文件),紧接着的问题就是如何让用户只能通过代理服务器访问互联网,而不能绕过它,也就是说要阻塞端口80。为此可以在系统的防火墙规则中加入一些内容,假定ed0是网卡设备,规则添加如下: 
  
  #/sbin/ipfw add 200 deny tcp from any to any 80 via ed0
  #/sbin/ipfw add 300 deny udp from any to any 80 via ed0 
  
  当然,可以将这些规则放入系统的启动文件中,FreeBSD已经具有载入过滤规则的相应文件/etc/rc.firewall,要使用它只要在/etc/rc.conf文件中设置以下参数:
  
  
  firewall_enable=YES
  firewall_type="UNKNOWN" 
  
  这时,除了把它们添加到已有的规则模板以适应少量修改之外,还可以把它们与其它一些您自定义的规则放入一个外部文件中,然后把firewall_type的值(默认的/etc/rc.firewall文件已定义了几种类型可作为此参数的值)改为此文件的全路径名,这样系统就会在启动时用ipfw自动执行这些规则。
  
  代收邮件
  通过安装并配置Fetchmail和Qpopper这两个软件可以为局域网中其它用户代收他们的外部电子邮件: 
  
  #pkg_add qpopper-2.53.tgz
  #pkg_add fetchmail-5.2.0.tgz 
  
  修改/etc/inetd.conf,去掉下面这条行首的#号: 
  
  pop3 stream tcp nowait root /usr/local/libexec/popper popper 
  
  然后用以下方法重启inetd以提供pop3服务: 
  
  #ps -acx | grep inetd
  165 ? I 0.12 inetd
  #kill -HUP 165 
  
  用户级PPP包含一个/etc/ppp/ppp.linkup这样的文件,用于在拨号成功之后运行一行东东,就象自动批处理文件一样,现在向这个文件中加入下面的内容: 
  
  163:
  !bg sh -c "fetchmail -f /root/.fetchmailrc" 
  
  这样就会在PPP拨号连接后自动后台运行Fetchmail收信了,至于收信的具体配置,需要在.fetchmailrc中定义,我把该文件放在/root目录下并chmod为700,以防止其它用户读取该文件中的信箱账号及口令。其具体设置样本如下:
  
  
  poll mail-meaculpa via pop.server1.com
  protocol pop3
  preauth password
  username meaculpa here is mea there
  password "123abc"
  pass8bits
  fetchall 
  
  poll mail-user via pop.server2.com
  protocol pop3
  preauth password
  username user here is mike there
  password "456def"
  pass8bits
  fetchall 
  
  其中via后的名称为pop3邮件服务器名;protocol用来说明使用的协议;authenticate用来说明验证方式;here前的名称为本地用户邮箱账号;there前的名称为远程用户邮箱账号;password说明远程账号对应的口令,其中如包含数字等特殊字符需要加引号;pass8bits说明收到的邮件中含有8位字符,这对于我们中文的邮件非常关键;最后的fetchall说明全部收取。关于Fetchmail的详细说明请用man fetchmail命令。 
  
  这样,当Fetchmail读取该配置文件后即会收取对应的两个用户的外部邮件,并转存到其本地邮箱中,用户可以在自己的计算机中使用pop3方式连到拨号网关计算机进行收信,以便于统一管理。 
  
  -- 错误在所难免,欢迎批评指正 
  
  -----------------------------------------
  对 "FreeBSD建立拨号网关" 一点补充
  -----------------------------------------
  "chengc" chengc@263.net
  
                                                
  在 FreeBSD 机器上设置如下规则,可使客户机只设置 FreeBSD 机器为网关就可以访问 iNET(透明代理)
   
  ipfw add 49  allow tcp from 192.168.0.200 to any
  ipfw add 50 fwd 127.0.0.1,3128 tcp from any to any 80
   
  修改 squid.conf
   
  http_port 3128
  httpd_accel_host virtual
  httpd_accel_port 80
  httpd_accel_with_proxy on
  httpd_accel_uses_host_header on

原文转自:http://www.ltesting.net