太平洋软件资讯

关于本文档的说明

本文档由太平洋软件资讯栏目制作，版权归太平洋软件资讯站 及文档作者所有。制作该文档的目的是为了方便广大网友。因此任何人都可以自由复制，或在网络中散布该文档。但不允许将该文档用于出版或其它商业用途，同时使用该文档的过程中，未经允许，不得对该文档进行修改及反编译。如有问题请与我们联系谢谢！


太平洋软件咨询，http://www.pcsoftware.com.cn 在这里你将找到你想要的东西。来看看吧，每天都有大量更新，不会让朋友们失望的。

FreeBSD连载：FreeBSD使用大全目录

王波

作者自序

第1章 引言

  • FreeBSD的起源
    Unix的历史发展
    FreeBSD的起源和发展
    当前FreeBSD的版本
  • FreeBSD的功能特点
    FreeBSD的特点和应用范围
    使用FreeBSD的实例
  • 其他相关系统和组织
    GNU’s Not Unix
    GNU/Linux
    其他BSD系统
  • FreeBSD的相关资源
    联机文档
    出版物
    Internet资源
    商业服务和支持

第2章 安装与配置

  • 安装之前的准备
    硬件设备
    安装介质
    准备硬盘和软盘
  • 安装FreeBSD
    启动安装程序
    安装系统
  • 基本系统配置
    设置网络
  • 其他安装问题

第3章 系统管理和维护

  • 系统的启动与关闭
    系统启动过程
    系统启动脚本
    系统登录与退出
    关闭系统
  • 用户管理
    增加用户
    超级用户root
    登录类别
    shell设置
  • 文件系统与磁盘操作
    文件的属性
    设备文件
    安装文件系统
    软盘操作
  • 维护文件系统
    检查硬盘
    调整文件系统的目录结构
    建立文件系统
    管理交换设备
  • 调整系统设置
    调整控制台设置
    配置系统时间
  • 进程管理
    查看系统状态
    定时执行程序
    进程的权限
  • 安装应用软件
    应用软件的类别
    Packages Collection
  • 打印机配置
    系统结构
    配置打印机
  • 系统日志与备份
    系统日志
    系统备份

第4章 网络配置与使用

  • DOD参考模型
  • 基本网络设置
    手工配置网络
  • 拨号网络
    串口和modem
    PPP协议
  • DNS服务
    DNS的体系结构
    配置缓冲或转发方式的named
    定义自己的名字服务
  • 电子邮件
    邮件服务器
    在FreeBSD上查看邮件
  • 网络文件系统（NFS）
    NFS客户支持
    NFS服务器

第5章 设置和使用X Window

  • 安装和设置X服务器
    X Free86的硬件要求
    安装XFree86
    使用XF86Setup配置X服务器
    使用xf86config配置X服务器
  • 使用和配置X Window
    X Window的基本概念
    进入X Window
    定制X Window的基本方法
  • X Window下的中文环境
    中文X应用软件
    外挂式中文显示与输入软件
    中文X服务器
  • 配置文件XF86Config

第6章 定制应用软件与系统内核

  • 编译应用软件
    Ports Collection
    手工编译安装程序
    可执行程序格式
  • 配置FreeBSD内核
    为编译内核准备源代码
    编译安装新内核
    缺省内核配置选项
    其他内核设置选项
  • 升级系统

第7章 与Windows系统集成

  • 集成Unix和Windows的方式
  • NetBIOS与SMB/CIFS协议
    NetBIOS名字解析
    SMB/CIFS协议
  • 配置和使用Samba
    安装samba
    配置samba
    根据Windows网络设置Samba
  • 访问Windows系统资源
    使用smbclient访问Windows资源
    使用SharityLight安装SMB文件系统
  • 设置DHCP
    DHCP的工作过程
    设置和使用DHCP

第8章 系统与网络安全

  • 网络安全概念
    认证与加密
    安全问题
    防火墙技术
  • 增强安全设置
    设置基本系统
    安全工具
  • 设置防火墙功能
    设置和使用ipfw/natd
    设置和使用ipfilter
    构建防火墙

第9章 设置WWW服务

  • 基本概念
    超文本传输协议HTTP
    数据处理方式
  • 安装和设置Apache
    基本安装
    配置Apache服务器
  • 服务器的安全控制
    对IP地址和域名的控制
    基于用户的访问控制
    安全连接方式SSL
    CGI和SSI的安全性
  • 调整服务器性能
    单服务器性能调整
    提升静态网页服务能力的综合方式
  • 负载均衡技术
    基于DNS的负载均衡
    反向代理负载均衡
    基于NAT的负载均衡技术

光盘内容及说明


FreeBSD连载：作者自序

王波
感谢作者同意转载

    决定为自己的稿子写序是一件非常愉快的事情，因为在这里就不必太关心技术细节，而可以由得自己的性子胡言乱语 一番，而读者一般也不会介意这些，但假使真的介意的话，也大可以将这部分略去不看，而直接翻看后面的实际内容。

    写这么一本书的想法始于去年六月，那时国内媒体对Linux的宣传刚刚开始，那个时候我就在想，其实Inte rnet上的宝贝绝不止Linux一样。Linux之所以突然走红，除了它本来就相当流行之外，还与它被反微软的诸多 厂商选中是分不开的，OS/2、Netware分别在不同的领域败下阵来，他们只好到Internet上寻找新力量。 然而，仅仅跟随国外媒体进行亦步亦趋的宣传，也容易淹没Internet中的其他宝藏，Linux并不是唯一的自由操 作系统，在某些领域它也不是最好的，这也就是我向大家介绍FreeBSD的原因。

    说到这里，我想起了一件事情。我曾和一家免费邮件网站的管理员谈天，他告诉我他们使用的是Linux系统，当 时我很惊讶，在我的印象里，这一批免费邮件站点都应该为FreeBSD系统才对。然而当我有机会到他们机房去的时候， 我就了解到了他错误的根源，所有服务器的登录提示都被改为Linux！当我请求管理员帮助登录上系统之后，系统的真实 面目就显示出来了，此后我还发现那个销售免费邮件的公司将该系统中的另一些软件的名字也进行了更改。这件事情让我百思 不得其解，为了借用Linux的大名吗？事实上在针对Linux的宣传开始之前，这家公司的系统已经非常有名了。为了 保守技术秘密吗？只要对FreeBSD有一定了解的使用者，很快就可以确认系统使用的操作系统类型了。假如那家公司的 技术人员能够看到我的疑问的话，我很希望他们能解开我的疑惑。

    有一个好的想法只是一个开端，而将其实现却困难重重。我最初想完成一本包括Unix入门知识在内的FreeB SD入门书籍，然而随后就改变了想法。毕竟，Unix的入门书籍到处都有，重复这些工作虽然工作任务相对简单一些，但 很难让读者得到更重要的内容：学会在实际网络中应用FreeBSD系统。最后我决定包括FreeBSD入门和具体应用 等内容。因此阅读本书应该具备Unix的基本操作知识，以及一台PC以便进行实验。

    在本书的写作过程中，FreeBSD进行了重要的版本升级，从原有的2.2.x版本到3.0-RELEASE 、3.1-RELEASE和3.2-RELEASE，书中的例子大部分来自3.0-RELEASE和3.1-RELE ASE，因此就有极少例子与3.2-RELEASE中会有所不同。事实上差异相当小，并不影响具体的操作，我也会在存 在差异的地方给出提示。

    写到这里，心里又有些忐忑，很有些担心有的人读完本书之后会抱怨太难，而另一些人又会认为废话太多。唯一的希 望是，我的文字不要太差劲。然而，当你读完本书之后，无论你认为本书如何，我都愿意收到评论，不管是鼓励还是批评。假 如你是一个入门者，因而不很理解本书中提到的一些概念，不要着急，当你接触到相关具体应用的时候，就会发现书中提到内 容的用处。当你是一个FreeBSD高手，习惯于阅读英文原版资料，那也不妨翻阅一下本书，帮助寻找书中的错误以免误 导其他读者，我相信一个喜欢FreeBSD的使用者也乐于看到更多的人喜欢并使用FreeBSD的。如果你是一个Li nux迷，我也很希望这本书能为你介绍另一个优秀的操作系统，顺便提一下，我的计算机中也安装有一套RedHat，不 过我不太喜欢它，比较而言，Debian和Slackware更干净一些。

    希望你在读完本书之后，再考虑Web服务器或软件防火墙的时候，能自觉不自觉的想起FreeBSD系统。相信 我，在PC平台中的这些领域下，它是No.1。

    本书成书过程中得到宋健（不是那位老先生）的大力帮助，在此表示感谢。

    王波

    九九年七月

    wb@email.online.ha.cn


FreeBSD连载(01)：FreeBSD的起源

王波

     第1章 引言

    在计算机领域，Unix一直是作为高端平台而出现的。几年以前，只有在大型机构的专用机房中才能接触到它们， 甚至稍小一些的机构也负担不起购买Unix工作站的费用。只有很少的使用者才有机会接触和使用Unix，能管理和维护 Unix系统的计算机专业人员就更少了，这就使得Unix总是披着一层神秘的面纱，在普通使用者面前，Unix属于一 种难于使用、十分昂贵的操作系统。然而，当运行在个人电脑上的自由Unix系统出现之后，这种情况已经改变了。

    事实上，今天的Unix已经不能说是一个单一的操作系统，它包括了非常多的种类，有高端的HP、SUN服务器 ，也有中、低端的运行在Intel平台上的Unix系统。Unix不再是普通使用者可望而不可及的操作系统了，每个喜 爱Unix的人都可以在自己的PC机中安装上一套Unix系统，学习它、使用它。而中小企业也可以使用PC服务器来运 行Unix系统，充分利用Unix系统的强大处理能力。

    FreeBSD就是一种运行在Intel平台上、可以自由使用的Unix系统，它可以从Internet上免 费获得。而它又具备极其优异的性能，使它得到了计算机研究人员和网络专业人士的认可。因此，不但专业科研人员把它用作 个人使用的Unix工作站，很多企业，特别是ISP（Internet服务提供商）都使用运行FreeBSD的高档P C服务器来为他们的众多用户提供网络服务。

  • FreeBSD的起源

    自从1969年AT&T Bell实验室研究人员创造了Unix之后，Unix就不断发展，逐渐成为 了主流操作系统。虽然当前Windows系列已经占据了桌面计算机的领域，其中Windows NT服务器也在网络服 务器领域得到了部分用户的承认，但在高档工作站和服务器领域，Unix仍然具有无可替代的作用。尤其在用作Inter net服务器方面，Unix的高性能、高可靠性、以及高度可扩展的能力仍然不是其他操作系统所能够代替的。

    虽然Unix由AT&T创造，但它如此流行却并不能完全归功于AT&T自己的功劳。现代Un ix不是一个厂家的单独产品，在它长期的发展过程中形成了多种不同的版本。惟其丰富多样，才使得Unix具有强大的生 命力。FreeBSD正是Unix众多分支中相当优秀的一支，它的发展历史也相当悠久，是著名的BSD Unix的一 个继承者，因此要了解FreeBSD发展的历史，首先就要了解Unix发展的历程。

  • Unix的历史发展

    Unix操作系统的历史漫长而曲折，它的第一个版本是1969年由Ken Thompson在AT& T贝尔实验室实现的，运行在一台DEC PDP-7计算机上。这个系统非常粗糙，与现代Unix相差很远，它只具有操 作系统最基本的一些特性。后来Ken Thompson和Dennis Ritchie使用C语言对整个系统进行了再 加工和编写，使得Unix能够很容易的移植到其他硬件的计算机上。从那以后，Unix系统开始了令人瞩目的发展。

    由于此时AT&T还没有把Unix作为它的正式商品，因此研究人员只是在实验室内部使用并完善它。正 是由于Unix是被作为研究项目，其他科研机构和大学的计算机研究人员也希望能得到这个系统，以便进行自己的研究。A T&T以分发许可证的方法，对Unix仅仅收取很少的费用，大学和研究机构就能获得Unix的源代码以进行研 究。Unix的源代码被散发到各个大学，一方面使得科研人员能够根据需要改进系统，或者将其移植到其他的硬件环境中去 ，另一方面培养了懂得Unix使用和编程的大量的学生，这使得Unix的普及更为广泛。

    由于操作系统的开发相当困难，只有少数的计算机厂商，如IBM、Digital等大型公司，才拥有自己的操作 系统，而其他众多生产计算机的硬件厂商则采用别人开发的操作系统。因为Unix不需要太多的花费，因此很多厂商就选择 了Unix作为他们生产的计算机使用的操作系统。他们把Unix移植到自己的硬件环境下，而不必从头开发一个操作系统 。

    到了70年代末，在Unix发展到了版本6之后，AT&T认识到了Unix的价值，成立了Unix系 统实验室（Unix System Lab,USL）来继续发展Unix。因此AT&T一方面继续发展内部使 用的Unix版本7，一方面由USL开发对外正式发行的Unix版本，同时AT&T也宣布对Unix产品拥有 所有权。几乎在同时，加州大学伯克利分校计算机系统研究小组（CSRG）使用Unix对操作系统进行研究，因此他们的 研究成果就反映在他们使用的Unix中。他们对Unix的改进相当多，增加了很多当时非常先进的特性，包括更好的内存 管理，快速且健壮的文件系统等，大部分原有的源代码都被重新写过，以支持这些新特性。很多其他Unix使用者，包括其 他大学和商业机构，都希望能得到CSRG改进的Unix系统。因此CSRG中的研究人员把他们的Unix组成一个完整 的Unix系统──BSD Unix（Berkeley Software Distribution），向外发行。

    BSD Unix在Unix的历史发展中具有相当大的影响力，被很多商业厂家采用，成为很多商用Unix的基 础,而AT&T与其同时存在的Unix版本的影响就小得多。同时很多研究项目也是以BSD Unix为研究系 统，例如美国国防部的项目─ARPANET，ARPANET今天发展成为了Internet，而BSD Unix中最 先实现了TCP/IP，使Internet和Unix紧密结合在一起。

    而AT&T的Unix系统实验室，同时也在不断改进他们的商用Unix版本，直到他们吸收了BSD Unix中已有的各种先进特性，并结合其本身的特点，推出了Unix System V版本之后，情况才有了改变。从 此以后，BSD Unix和Unix System V形成了当今Unix的两大主流，现代的Unix版本大部分都是 这两个版本的衍生产品。

    Unix的版本号表示方式比较复杂，各种不同的Unix版本有自己的版本标识方式，如最早AT&T开 发的内部Unix使用简单的顺序号来标识版本，从V 1到V 7。

    BSD使用主版本加次版本的方法标识，如4.2BSD，4.3BSD，在原始版本的基础上还有派生版本，这些 版本通常有自己的名字，如4.3BSD-Net/1，4.3BSD-Net/2。

    AT&T使用罗马数字来标识他们的对外发布的Unix版本，用Release来表示次版本。如Sys tem V Release 4（简写为SVR4）标识AT&T的Unix System V的第四次发布的 版本。

    其他商业公司的Unix使用自己的版本标识，如Sun的Solaris 2.6，IBM的AIX 4.0等。

    虽然AT&T的Unix System V也是非常优秀的Unix版本，但是BSD Unix在Un ix领域内的影响更大。AT&T的Unix系统实验室一直关注着BSD的发展，在1992年，Unix系统实 验室指控BSDI── 一家发行商业BSD Unix的公司，违反了AT&T的许可权，发布自己的Unix版 本，并进一步指控伯克利计算机系统研究组泄漏了Unix的商业机密（此时的4.3BSD中来自AT&T Un ix的代码已经不足10%）。这个官司影响了很多Unix厂商，使他们不得不从BSD Unix转向Unix Sys tem V,以避免法律问题。以至于当今大多数商业Unix版本都是基于Unix System V的。

    这件有关Unix版权的案子直到Unix系统实验室被AT&T卖给了Novell公司后才得以解决， Novell不打算陷入这样的法律纷争中，因此就采用了比较友好的做法。伯克利的CSRG被允许自由发布BSD，但是 其中来自于AT&T的代码必须完全删除。因此CSRG就对他们最新的4.4BSD进行了修改，删除了那些来自 于AT&T的源代码，发布了4.4 BSD Lite版本（该系统是不完整的，尤其对于英特尔386体系的计 算机系统）。由于这个版本不存在法律问题，4.4BSD Lite成为了现代BSD系统的基础版本。

    Novell的比较友善的做法还不止对BSD，他把自己的Unix改名为Unixware， 而将Unix商 标赠送给X/Open── 一个由众多Unix厂家组成的联盟，这样这个联盟内的所有成员均可使用Unix商标。从此 之后，Unix不再是专有产品了。后来Novell由于自身的经营问题，又将Unixware卖给SCO公司。同时， 由于BSD系统已经十分成熟，作为对操作系统进行研究的目标已经达到，伯克利计算机系统研究组（CSRG）在发布了4 .4BSD-lite2之后就解散了，小组的科研人员有些进入了Unix商业公司，有些继续进行其他计算机领域的研究 。此时，严格意义上的Unix System V和BSD Unix都不复存在了，存在的只是他们的各种后续版本。

    回顾Unix的发展，可以注意到Unix与其他商业操作系统的不同之处主要在于其开放性。在系统开始设计时就 考虑了各种不同使用者的需要，因而Unix被设计为具备很大可扩展性的系统。由于它的源码被分发给大学，从而在教育界 和学术界影响很大，进而影响到商业领域中。大学生和研究者为了科研目的或个人兴趣在Unix上进行各种开发，并且不计 较金钱利益，将这些源码公开，互相共享，这些行为极大丰富了Unix本身。很多计算机领域的科学家和技术人员遵循这些 方式，开发了数以千计的自由软件，包括FreeBSD在内。正因为如此，当今的Internet才如此丰富多采，与其 他商业网络不同，才能成为真正的全球网络。开放是Unix的灵魂，也是Internet的灵魂。

    由于Unix的开放性，另一方面就使得存在多个不同的Unix版本。由于不同的Unix使用稍有差别的文件、 目录结构，提供略有不同的系统调用，因此对系统管理、以及为Unix开发可移植的应用程序带来一定的困难。例如Sys tem V和BSD的很多系统调用就存在不同。在Unix历史发展中也存在将Unix完全统一的努力，例如POSIX 规范就是各个Unix厂商经过协商，达成的Unix操作系统应该遵循的一套基本系统调用的规定。然而由于存在多个Un ix系统，各个厂商的意见很不统一，因此POSIX规范制定的很宽松，甚至Windows NT中也存在一个POSI X子系统。事实上，只要各个Unix之间协调发展，不故意为了商业目的而人为的制造系统差异，就能够保持各个Unix 之间不致具有太大的差别，保持Unix系统的多样性比只有唯一的一个Unix系统更能够促进技术的进步和发展，企图人 为的统一Unix的想法只能是某一个Unix厂商的一厢情愿。

    有时为了避免法律纠纷，表明自己的程序代码是完全重写的，一个软件厂商会故意将一些函数声明的与其他系统的中 的同类函数不同，例如使用不同的函数参数或改变函数参数的顺序等。Unix System V中的很多系统调用与BS D Unix不同的部分原因也在于此。这些差异人为造成了不同系统的源程序的差异。

  • FreeBSD的起源和发展

    Unix的魅力不仅在于其功能的强大性，还在于其优秀的可扩展性，它提供了高级语言C和各种解释语言 可用于编写程序。利用这些系统提供的工具，使用者就能按照自己的需要和兴趣对原有系统进行扩展，满足相当一部分计算机 研究人员和使用者的需要，这样Unix就具备更强大的能力，完成各种复杂的任务。一旦用熟了Unix，体会到Unix 的强大功能，使用者就会希望一直使用它，而不是仅具备有限能力的其他计算机系统。企业也希望能在其可以承受的条件下， 利用Unix系统的强大处理能力。

    由于Unix是多用户操作系统，作为系统的普通使用者只能使用系统提供的有限功能，而只有Unix系统管理员 才能充分利用其的全部能力。因而拥有自己的Unix系统也是一个普通Unix使用者的愿望。但是在那些时候，能够满足 这些愿望的计算机并不是每个人都能买得起的。昂贵的硬件，以及Unix逐渐商业化趋势，都使得拥有自己的Unix对大 多数人只是美好的愿望，而使用Unix的地方主要为一些要求较高的科研和大中型公司机构。

    到80年代，个人计算机的出现，使得硬件的价格能被个人和小企业接受了，给拥有一个Unix系统的愿望带来了 一线曙光。但是使用8086芯片的个人计算机能力比较差，在其上不能实现真正正常工作的多用户系统。进入九十年代之后 ，英特尔公司推出的80386芯片使个人计算机的计算能力大大提高，在个人计算机上构建一个可以真正使用的Unix也 成为了可能。

    事实上此时能运行在X86平台上的Unix相当有限，Mircosoft的Xienx是一种（后来发展成为S CO Unix），但不能指望能自由、免费使用这个商用系统。要移植Unix到PC平台上便需要Unix的源代码，而 此时受AT&T的许可权的限制，Unix代码还不能被自由获得（但在BSD与AT&T的法律纠纷之后 的4.4 BSD Lite不再受这个限制了，可以在BSD许可下自由使用）。很多计算机爱好者为了实现一个可以自由 使用的操作系统，不但进行着努力。自由软件基金会的GNU计划的目的就是打算创建一个自由的、与Unix类似的操作系 统，为了实现这个目的，GNU开发了很多非常有效的工具、包括编译器和很多系统命令，然而GNU计划中的操作系统内核 ──HURD，却进展缓慢，从而无法构建一个完整的操作系统。很快，就有计算机爱好者开始考虑在个人计算机平台上构建 一个Unix内核。芬兰一位计算机研究生Linus Torvalds开始了这个工作，他通过学习Minix──一个 用于教学目的的简单Unix系统，在x86平台上构建了Linux内核，这个内核和GNU的系统工具结合起来，取得了 相当大的成功，成为当前非常流行的GNU/Linux系统。

    与这些努力相比，BSD方面的研究人员的行动则比较迟缓，一个原因是Unix技术上已经相当成熟，计算机系统 研究组的大部分成员已经把注意力转向了其他研究项目，另外AT&T与BSD的法律纷争也使得BSD发展受到了 阻碍。但是还是有两个将BSD移植到80386平台的开发工作同时进行，一个是BSD/386小组，他们的研究结果为 商业版本的BSD/OS，属于商业公司BSDI。另一个就是386BSD计划，后来发展成为FreeBSD。

    CSRG研究人员的条件比较优越，拥有足够的Unix系统，因此对个人计算机平台上的Unix系统没有太急迫 的要求。

    386BSD计划由Bill Jolitz等研究人员发起，将4.3BSD Net/2移植到80386平台 上，并使用386BSD的名称发布。但是移植工作是一个复杂的任务，直到386BSD 0.5版本，系统中仍然存在相 当多的问题没有解决。于是在1993年，另一些研究者决定加入这个计划，打算和Bill Jolitz一起修正系统中 存在的问题。但是这时计划的组织者Bill Jolitz突然决定退出，使得386BSD计划面临停止的危险。Bil l Jolitz作为计划的发起者和负责者并没有对这个计划以后该如何发展给出具体意见，因此386BSD计划是到此 为止还是继续发展，就取决于其他开发者的决定。幸运的是，该项目的另三个参与者Nate Williams, Rod Grimes和Jordan K. Hubbard决定继续这项非常有意义的工作，他们采用由David Green man创造的名字FreeBSD作为系统的新名字，从此有了一种任何人都可以自由使用的Unix操作系统 ── Fr eeBSD。

    BSD Unix使用 一个神话中的精灵形象作为其吉祥物，这个吉祥物标志被FreeBSD、NetBSD继续使用，但不同BSD系统的精灵 略有不同，右图为FreeBSD的BSD精灵形象。当用户浏览Internet时，会在很多与FreeBSD相关的网 站上看到这个可爱的精灵标志。

    1993年12月对于FreeBSD来讲是非常重要的日子，FreeBSD 1.0版本于这个月正式发布。这 次FreeBSD的开发者找到了一家出版商Walnet Creek提供支持，来发布FreeBSD的光盘和提供高速 Internet网络服务，使得任何人都可以通过购买光盘或者通过Internet下载的方法，自由获得FreeBS D系统，使得FreeBSD取得了很大成功。而Walnet Creek也使用FreeBSD建成了Internet 上最大、最繁忙的匿名文件服务器──ftp.cdrom.com。

    FreeBSD虽然可以自由获得，然而BSD与AT&T的法律纠纷仍然威胁着FreeBSD系统的合 法性。就在FreeBSD得到相当多用户欢迎的时候，Unix系统实验室（此时已经卖给了Novell）与伯克利计算 机系统研究小组的法律纷争有了结论。虽然最后不必进行赔偿，但是BSD Unix系统中必须去除原来来自AT& ;T的源码。伯克利计算机系统研究小组去除了这些不到10%源码，发布了4.4BSD Lite，其他基于BSD的U nix，包括FreeBSD在内，都被要求立即转换到4.4 BSD Lite上去。

    这对FreeBSD是一次相当严重的打击，虽然4.4 BSD Lite只删除了一小部分代码，但尤其对于英 特尔80386平台，缺乏这些代码，系统就不能正常运转。FreeBSD小组必须解决两个任务，首先是将FreeBS D从原本的4.3BSD迁移到4.4BSD上，再将删除的源码完全重写。这些任务相当于将4.4BSD Lite重新 移植到80386上，因此这花费了FreeBSD核心小组很大的精力。因此直到1995年1月他们才发布了FreeB SD 2.0，这次就是一个完全的4.4BSD Lite的系统了。但是在大约一年时间之内，FreeBSD不能在原 有1.0基础上进行改进并推出新版本，而这个时期正是Internet进一步发展的阶段，FreeBSD错过了一个发 展壮大的好时机。而其竞争对手，如Linux，则取得了巨大的成功。

    接下来，FreeBSD加快了开发节奏，2.1、2.2、3.0相继推出，这个系统在Internet上的应 用也越来越多，尤其是对于要求高性能、高可靠性的网络服务器系统，FreeBSD提供了一个极具诱惑的选择。

    由于Unix商标属于X/Open组织，而FreeBSD只是一个自由操作系统，从法律角度上看FreeBS D不能被叫作Unix（不能使用Unix做商标）。但是基于Unix本身的历史，FreeBSD可以算最原汁原味的U nix，在有的方面，它更具传统特色──或者说BSD Unix的学院特色。当前，Unix商标其实是只具有象征性的 含义，没有人介意到底那些系统是X/Open的成员，可以被称作Unix，那些不是。Unix已经成为一个广泛的概念 ，只要是按照Unix为模板进行开发，所有的应用程序在C源程序级与其他Unix相互兼容，也同样被所有使用者承认为 Unix系统。因此这里的Unix包括BSD和System V在内的各种系统，也包括像Linux这样的兼容系统。

  • 当前FreeBSD的版本

    由于FreeBSD十分关心系统的性能和稳定性，同时FreeBSD的开发又非常活跃并十分开放。因此在系统 开发中支持几个版本的FreeBSD系统并行发展，一些版本用于提供一个最具稳定性的操作系统，另一些版本逐渐融合进 各种新特性，使FreeBSD不断发展。当前主要使用的FreeBSD有三个分支版本：

    FreeBSD2.2.x-stable：这个分支是当前Internet上大部分网络服务器上使用 的FreeBSD版本，经过无数实践验证，具有高稳定性的特点。但是由于3.0版本已经正式发布，FreeBSD的开 发者已经于1999年1月决定停止对这个版本的开发，这个FreeBSD的分支版本进入维护状态，将仅仅进行修补一些 可能存在的系统漏洞等工作。因此除非是现存的FreeBSD系统，或者为了特殊目的要使用一些基于2.2.x开发的特 殊软件，新安装的FreeBSD系统应该使用FreeBSD-3.x版本。这个系列中最后一个正式发布的光盘版本为F reeBSD 2.2.8-release。

    FreeBSD3.x-stable：这个版本的第一个正式版本3.0-release，它于199 8年10月正式发布，随后就成为了稳定版本。它与2.2相比增加了对很多新硬件的支持，并进一步提高了性能。对于安装 新的FreeBSD系统来讲，应该选用这个版本。当前已经发布了FreeBSD 3.2-release。

    FreeBSD4.0-current：于1999年1月产生，同时FreeBSD 3.x-cur rent分支转变为FreeBSD 3.x-stable分支。当前还没有任何正式发布版本，需要通过Interne t获得源代码进行安装。

    可以看到，FreeBSD的版本使用current或stable后缀进行修饰，其中使用stable修饰的 版本是一个稳定的版本，它不是FreeBSD的最新版本，主要关心系统的性能和使用的连续性，同一个stable分支 中的下一个版本主要是修订系统问题，因此stable分支得到很多商业用户的欢迎。current表示这个版本是正在 开发的版本，还不成熟，它更关心新特性，每种可能的特性都被开发者尝试加入进FreeBSD中，但并不保证以后的正式 发布版本会支持所有的特性，一些特性会因为不成熟或对大部分用户无益，即使曾经加入也可能从正式版本中去除。通常Fr eeBSD的爱好者和开发者使用这个分支，或者一些需要某些FreeBSD的新特性的用户，就必须使用这个分支。

    FreeBSD选用current和stable来修饰FreeBSD不但是因为FreeBSD是一个不断发 展、更新的系统，而且FreeBSD还是一个由Internet上的用户参与开发、使用Internet交流开发工作 的系统。这与商业软件不同，商业软件的开发工作在公司内部，外界不能访问正在开发的版本，不能对要开发的软件发表意见 和提出建议。而FreeBSD则相反，任何人只要通过Internet，都可以访问到FreeBSD的源码，并且Fr eeBSD开发者鼓励别人访问当前正在开发的源程序，鼓励提建议和进行自己的FreeBSD开发计划，如果这个计划的 确不错，那么这个开发者就能被邀请进入FreeBSD开发组，他的计划就能被合并到正式的FreeBSD开发中去。但 是，如果一个系统老是处于不断开发的过程，没有一个稳定的版本，显然得不利于希望将FreeBSD用在日常业务处理任 务的普通用户。因此FreeBSD并存着两个同时发展的版本，stable版本为稳定版本，相当于商业软件中的对外发 行的版本，current版本为正在开发的版本。当一个current版本已经足够稳定，这个版本就转变为stabl e版本，而FreeBSD开发组将转入下一个current版本的开发工作。

    除了current和stable之外，还有另外两个后缀用来修饰FreeBSD的二进制发行版本。一个是r elease，如FreeBSD 3.0-release，表示这是一个正式发行的FreeBSD版本，但这个版本可 以处于current分支或stable分支。但如果一个FreeBSD的current分支发布了release版 本，这将表示它离进入stable状态不远了，此后该版本实际上不会再作太大的改动，已经是一个完全可用、足够稳定的 FreeBSD版本了。另一个后缀是snapshot，如FreeBSD 4.0-snapshot，表示这是一个预 览版本，用于FreeBSD爱好者提前查看current分支当前的开发状态，尝试新特性用的。FreeBSD的光盘 发行版本常常使用这两个词进行修饰。

    因此对于FreeBSD用户，需要根据情况选择使用不同的版本。对于正式使用，应该选择stable版本，而 对于进行学习、研究、开发FreeBSD，可以考虑使用current版本。


FreeBSD连载(02)：FreeBSD的功能特点

王波

    FreeBSD的运行环境是使用英特尔x86系列处理器的个人计算机，当然在AMD和Cyrix等公司的兼容 芯片上运行也毫无问题（FreeBSD也被移植到使用sparc和alpha芯片上的RISC工作站环境上，然而这些 平台不是FreeBSD的主要运行平台，相应的移植版本也不太完善）。

    从FreeBSD的起源和发展过程可以看出，FreeBSD是一种自由Unix系统，它是由计算机科学家、软 件工程师等志愿者通过Internet合作开发的，目的是为所有的使用者提供没有任何附加条件的自由Unix操作系统 。初次接触自由软件的人，也许会怀疑软件的应用功能、性能等问题。但免费获得的方式和使用个人计算机硬件环境并不意味 着FreeBSD系统仅仅是个人用户的玩具，事实上FreeBSD能够完成几乎所有其他Unix能完成的工作，应用范 围十分广泛，并且性能非常优秀。在网络上使用FreeBSD用作网络服务器操作系统非常普遍，FreeBSD也是使个 人计算机成为高性能Unix工作站的一条捷径。

  • FreeBSD的特点和应用范围

    FreeBSD主要特点是它的高性能和高可靠性，除了BSD Unix本身已经是一个非常成熟的操作系统，F reeBSD开发小组也基于实际工作任务，花费了相当多的时间进行系统调试，以取得最大性能和最高可靠性。它的性能和 可靠性并不逊于任何商用Unix系统，甚至更为优秀。

    --FreeBSD是真正的32位操作系统，不是任何16位操作系统的升级版本。它是十分成熟的BSD Un ix向英特尔386体系的处理器进行移植的结果，系统核心不包含任何16位代码，也不需要兼容任何16位软件，从而提 高了系统稳定性。

    --FreeBSD具有可调整的动态优先级抢占式多任务能力。使多个应用程序能够十分平滑的共享系统资源，即 使在高负载下仍然能在不同任务间平缓切换，而不会发生由于个别任务独占系统资源，其他任务因此而发生停顿、死锁现象， 也决不会造成整个系统死锁。

    --FreeBSD是多用户操作系统，可以支持多个使用者同时使用FreeBSD系统，共享系统的磁盘、外设 、处理器等系统资源。每个用户也可以同时启动多个任务，使得工作效率更高。

    --FreeBSD全面支持TCP/IP协议。FreeBSD能够十分方便的和其他支持TCP/IP的系统集 成在一起，用作Internet/Intranet服务器，提供NFS,ftp,email,www,路由和防火墙能 力。

    --其操作系统内部的存储器保护机制使每个应用程序和用户互不干扰。一旦一个任务崩溃，其他任务仍然照常运行 。由于FreeBSD中不存在任何16位代码，这使得这一点能够真正实现，保证了系统的强壮性。

    --FreeBSD中使用另一个著名自由软件，XFree86，来提供工业标准的X窗口系统（X11R6）， 在X上可以运行多种图形界面软件提供方便用户使用的图形界面和应用软件。

    --它也支持在英特尔的386芯片上运行的其他Unix操作系统的二进制执行文件，包括SCO Unix,B SD/OS,NetBSD,Linux等。能够直接运行这些系统的二进制应用程序而不需重新编译，这极大的丰富了Fr eeBSD下的可使用的应用软件。

    --FreeBSD的Ports Collections包括了成千个立即可以使用的应用程序，使得安装应用 程序十分简便。FreeBSD与其他多种Unix在源码级兼容，并且由于BSD在Unix和Internet发展中的 巨大影响，大多数软件是在类似BSD的系统下开发的，因此FreeBSD是最容易移植的平台，在Internet上有 很多的软件很容易移植到FreeBSD上。

    --高效的虚拟存储器管理结构，可以按照需要合理分配内存空间，只有在必要的时候，内存中的数据才被交换到交 换设备上去。并且磁盘缓冲区不是单独划分出来的，而是和虚拟存储器结合为一体，使FreeBSD既能够高效的满足要求 大量内存的应用程序，又能最大效率的利用内存来缓冲硬盘数据，提高读、写硬盘效率。

    --具有动态共享连接库的能力，使应用程序能够共享库函数（类似Windows下的DLL），充分利用内存和 磁盘空间。

    --FreeBSD下包括了各种高级语言和各种开发工具，C, C++, Fortran, perl, T cl/Tk, cvs 等。这使得软件开发和移植非常方便。

    --FreeBSD提供系统的全部源代码，这样可以按需定制系统和进一步更改系统，提供了对应用环境的最大控 制。另一方面这些源代码会经过世界范围内的程序员的检验和测试，避免系统中内嵌未知的恶意病毒代码。

    --提供了在线文档和手册等丰富的技术资料。

    FreeBSD的主要应用范围可以在网络服务器方面，但是FreeBSD的应用并不局限于此，具体怎样使用F reeBSD完全依赖于用户的目的，FreeBSD能够满足各种不同的需要。

  • 网络服务器

    Internet应用是FreeBSD使用最广的领域之一，因为Internet的前身，APPRNET的开 发者，正是使用BSD Unix来实现的TCP/IP协议。因此FreeBSD具有最成熟、最稳定的TCP/IP实现 ，非常适合用作FTP服务器，WWW服务器，电子邮件服务器，域名服务器，USENET新闻服务器以及电子公告牌系统 等网络服务器系统，此外，FreeBSD也能将廉价的个人计算机改变为软件路由器，防火墙设备。

    用做网络服务器最重要的要求是稳定性，因此一般要安装FreeBSD的stable分支。FreeBSD 2 .2.x-stable分支在实际使用中已经证明了它具备非凡的稳定性，在网络上关于操作系统崩溃的调查中，对Fre eBSD崩溃次数的报道却很少，因此被称为 ”Rock-stable performance” （坚如磬石）。考 虑到大部分个人计算机硬件的稳定性比专用的Unix网络服务器硬件的稳定性要差，就可以看出FreeBSD操作系统的 稳定性是如何优秀了。FreeBSD 3.x-stable分支继承了2.2.x-stable的优点，虽然还没有经 过足够时间的考验，但也可推断其性能和稳定性相当优秀。

  • 个人工作站

    FreeBSD的另一个方面的应用是将FreeBSD作为个人工作站的操作系统。专业Unix工作站价格昂贵 ，但FreeBSD充分利用了个人计算机硬件价廉的优势，以自己具备的优秀性能，使个人拥有高性能的Unix工作站成 为可能。个人工作站要求工作在图形环境下，这需要运行X服务器软件，FreeBSD下有免费的XFree86和另一些 商业X服务器软件，此外还包括X Window操作环境，例如免费的KDE或商业操作环境CDE等。

    使用FreeBSD个人工作站时，除了性能要求之外，还必须有合适的应用软件进行支持。FreeBSD下可以 运行大量的Unix程序，包括用于研究的各种软件包、软件开发所需的高级语言编译器、提供图形界面的Xwindow和 Xwindow下的各种应用等。这些软件通常是在不同的Unix下进行开发的，但由于不同的Unix均不同程度受到B SD的影响，FreeBSD都是这些软件可以移植的首选平台，而FreeBSD本身也提供了很好的机制用于简化软件的 安装和配置。

    上面提到的软件通常是提供源程序的Unix软件，这些软件可以很容易移植到FreeBSD系统中。但绝大多数 商业软件不提供源程序，仅仅提供在某些平台下运行的二进制文件。在不同Unix下运行的二进制程序，即使都是英特尔平 台下的程序，但操作系统对执行程序的处理略有不同，造成了执行程序格式的差异。FreeBSD提供了支持其他在英特尔 平台上运行的商业Unix执行程序能力，如BSD/OS、SCO Unix、SCO UnixWare、Solari s x86和Linux。通过支持这些Unix的执行代码，FreeBSD下的应用程序更为丰富。

    还可以将FreeBSD工作站代替昂贵的专用X终端，或者使用FreeBSD进行Unix下的软件开发等，将 FreeBSD系统用作不同的目的。

  • 使用FreeBSD的实例

    在熟悉了FreeBSD之后，就不会有人怀疑这个系统的性能了，因为这已经被Internet上无数使用Fr eeBSD作服务器的实例所证明过的。FreeBSD是Internet上非常流行的一种网络操作系统，应用实例很多 。下面给出了一些著名的站点实例，当然FreeBSD的实际应用不只是这些例子中使用的范围。

  • Yahoo

    作为Internet上具有传奇色彩的成功网站的典范，众人了解的Yahoo通常是它具备丰富的内容、年轻的 亿万富翁传奇等内容。很少有人关心到底Yahoo是使用什么技术来构建他们的网站，也许很多人潜意识里认为它一定是由 昂贵的专用服务器组成的，其实Yahoo是使用多台普通Pentium个人计算机来提供这么大的访问能力的，而在这些 计算机上运行的就是FreeBSD系统。

    可以在Yahoo中搜寻 “Yahoo and FreeBSD” ，就能搜寻到一篇由Yahoo的创始人之 一David Filo写的介绍Yahoo为什么使用FreeBSD的文章 “Yahoo! and FreeBSD ”(http://www.freebsdmall.com/newsletter1/yahoo_and_freebsd.phtml)

    他写道： “……但不久就发现我们使用的操作系统在设计时都不具备处理大量 HTTP请求的能力。事实上，当 时还没有任何商业系统可以解决我们所面临的扩展问题，这也是身处网络技术最前沿所必须面对的无奈现实。

    “…….我们又用过几种平台，包括 SGI IRIX，Linux 和 BSDI，但性能和稳定性都不能令人 满意，我们只得继续寻找。随着 Yahoo 的日渐流行，平台的可扩展能力和稳定性是最关键的。那时我们 FreeB SD 还一无所知，但当读到有关介绍时，我决定试它一试。

    “……几天之后我将一台FreeBSD系统加入我们的Web服务器集群中去，结果它的性能明显优于其它机器， 而且运行更稳定。试验时间持续了几个星期，我们对FreeBSD很满意。这主要应归功于FreeBSD的稳定性、运行 性能和允许访问源代码的特点，它还具备诱人的价格优势。从此，我们的产品和开发环境就几乎离不开它了。”

  • 国内的163.net等免费邮件系统

    在国内，虽然FreeBSD还不是广为人知，事实上它的应用却非常有名。网易公司基于FreeBSD开发的免 费邮件系统，已经运行在www.163.net、www.263.net、www.371.net等网站上。

    在网易的主页上（http://www.163.com），有网易公司丁磊的一篇文章 “PC不只是便宜的工 作站” ，介绍网易为何选择FreeBSD。

  • 关于网络服务器操作系统的调查

    前面提到的例子，只是FreeBSD应用实例的几个，事实上在国外使用免费操作系统用做网络服务器非常普遍和 流行。虽然由于它属于非商业产品，媒体一般不太关心它，但在Internet服务器领域中，它的重要性是无可否认的。 为了了解Internet中的服务器到底都运行了那些系统，就需要对整个Internet进行调查。

    显然有很多种不同的调查方式，例如使用抽样调查，或者发放调查表格等等，然而这些方法都有其局限性。而Int ernet Operating System Counter (ios++)是一次比较特别的调查，它的基本思路 是对互联网上所有服务器使用的操作系统进行识别并统计结果。iso++使用一个程序自动收集互联网上的计算机地址，查 询计算机并判断其使用的操作系统，虽然无法保证iso++能识别所有种类的操作系统，但毫无疑问它能识别绝大多数流行 的操作系统。

    遗憾的是，这次调查并没有彻底完成，但这是由于人为而非技术的原因而不得不停止的。由于这个系统会扫描网络中 的所有主机，因此其行为类似于黑客程序的做法。在它对意大利的计算机进行网络查询时被一家以色列网络安全公司怀疑为黑 客入侵。然而即使如此，这次调查也运行了大约10天，扫描了上百万台服务器，其结果也能真实反应网络操作系统的真实面 貌。

    这次网络调查的主页为：http://www.hzo.cubenet.de/ioscount/

对Internet上的Web服务器使用的操作系统的调查

调查日期: 从1998年9月9日到9月19日

排名 | 操作系统 | 主机数量 | 占识别出的主机比率
1. | Linux | 171623 | 26.3%
2. | Windows 95/98/NT | 152682 | 23.4%
3. | BSD Family | 147602 | 22.6%
4. | Solaris/SunOS | 94230 | 14.4%
5. | IRIX | 29384 | 4.5%
6. | Mac/Apple | 13736 | 2.1%
7. | AIX | 10865 | 1.7%
8. | HP/UX | 10237 | 1.6%
9. | Reliant Unix/Sinix | 3971 | 0.6%
10. | Digital Unix | 3775 | 0.6%
11. | SCO Unix | 2507 | 0.4%
12. | Novell Netware | 2285 | 0.4%
总数 |  | 642899 | 98.6%

    上表是其对Internet上Web服务器的调查结果，可以看出，以FreeBSD为主的BSD家族的操作系统（还包括BSD/OS、NetBSD和OpenBSD，但这些系统的使用者要少于FreeBSD的使用者），在网络服务器中占据第三名的位置，而其百分比与前两名不相上下。如果要考虑到相应Web服务器的重要性，使用FreeBSD等Unix系统的Web服务器，无论从其服务的重要性还是提供网络数据的流量来讲，都是使用Windows操作系统的服务器无法相比的。


FreeBSD连载(03)：其他相关系统和组织
王波

其他相关系统和组织

    自由使用和免费是FreeBSD的特征，在英文里都可以使用 “free” 来表示。这表示使用者不仅仅可以 免费使用这个系统，还可以对软件进行适合自己需要的改动，并能够影响这个软件的发展等等，这正是free这个词更深一 层的含义。

    支持自由软件的人通常认为，每个计算机的使用者都有自己特定的需要，不可能有一个包罗万象、适合所有需求的软 件系统。因此软件开发者和系统管理员希望了解软件内部的情况，以便可以对软件进行定制和扩展。而商业软件只提供软件的 二进制代码，将软件内部的操作完全封闭起来，使用者就丧失了对软件的主动权。另外，任何软件产品都存在各种BUG，商 业软件的使用者在遇到软件产品的这些问题时，就只能被动的等待厂商的补丁程序，整个软件系统不得不停顿或冒一定的风险 继续使用。第三，计算机的使用者并不会完全信赖商业软件，某些软件厂商会故意在软件中加入恶意代码，或加入某种未公开 的后门，对使用者造成危害。即使这些软件中的后门或恶意代码是打着防止盗版、提供更方便的功能等旗号加入的，但也可能 被偶然触发，危害使用者的利益。而在提供软件源代码的软件中，就不会存在这种恶意的行为。

    这些问题对于一个普通用户或者不重要，但对于一个较大的系统或要求较高安全性的系统中，就能表现出重要性了。 支持自由软件的人认为，如果一个软件提供了源代码，那么使用者就能根据情况自己修改或请他人修改软件，从而适合自己的 最终需要，并修正系统中因为有意或无意导致存在的问题。当前，开放源代码已经得到越来越多的计算机使用者和厂商的认可 ，他们组成了开放源代码组织（Open Source），来进一步推动这个思想。

    另一方面，由于某些种类的商业软件中不存在竞争，垄断的结果就造成软件的价格昂贵，使得这些软件不是任何有需 要的人都能够用得起的。而软件最大的价值是被人使用，因此有很多人认为软件开发者要允许别人使用他的软件，应该从软件 服务中获得收益，而不是从软件本身中谋取暴利。他们认为计算机应该属于大众，而不应该由某些公司垄断。因此这些崇尚自 由软件的人员就想为所有用户开发一整套系统，使用户在现有商业软件之外还可以进行选择，而不至于必须为商业软件支付额 外的费用。这些人包括FreeBSD的开发人员、Linux的开发人员、GNU计划的开发人员以及其他众多的自由软件 开发者，他们开发的软件构成了计算机领域内多姿多彩的一面，使得即使不使用任何商业软件，使用者也同样能够在计算机上 以更好的性能完成所有的工作。

  • GNU's Not Unix

GNU不是Unix，采用这种递归方式定义的GNU计划是由Richard Stallman提出的，他建立自由软件基金会（FSF）并提出GNU计划的目的是开发一个完全自由的，与Unix类似但功能更强大的操作系统，以便为所有的计算机使用者提供一个功能齐全，性能良好的基本系统。GNU HURD为GNU操作系统的内核，但是当前还没有正式发布，仍处于测试阶段。很多人使用Linux内核和GNU的应用软件组成了GNU/Linux系统。右图为GNU的标志。

    FSF开发了大量的自由软件来达到这个目的，这些软件与Unix上原有的软件功能相同，但由于GNU开发软件 的时候硬件的处理能力更强了，因此GNU软件充分利用计算机的硬件能力，比Unix中的同样的软件功能更强，因此非常 流行。这些软件在GNU通用公共许可的保护下允许任何人免费使用和传播（但必须同时提供源程序），因此被大量的用在其 他的Unix中，FreeBSD上也提供了很多GNU软件。

    Stallman创造了一个词copyleft，由于通常意义上的版权copyright是用来限制别人在没 有许可的条件下不能使用和传播软件，而copyleft则鼓励任何人可以使用和传播软件。copyleft限制妨碍使 用和传播GNU软件的行为，例如不提供GNU软件的源代码。然而copyleft与copyright并不冲突，因为 copyleft是针对软件的传播者而非针对最终使用者的。GNU软件必须使用copyleft保护，限制将GNU软 件本身用于牟利目的，而其他软件仍然可以使用copyright保护版权不被侵犯。Stallman进一步使用GNU 通用公共许可来详细阐述copyleft的观念，要求传播GNU软件必须同时传播其源代码。由于GNU通用公共许可十 分流行，因此很多非自由软件基金会的自由软件也使用GNU通用公共许可来保护自己软件，不被商业公司用于获利。

    GNU软件许可相当宽松，有很多公司利用GNU软件进行商业活动，但只要同时提供了GNU软件的源代码，就没 有违反GNU软件许可。

    FreeBSD本身是在BSD许可的保护下，BSD许可权与GNU通用公共许可略有不同，一些方面的限制甚至 更为宽松。GNU通用公共许可要求传播（包括销售）任何符合GNU软件应该包括源代码，反对利用保守GNU软件的源代 码的方式牟利，而BSD许可则允许以二进制形式发布软件，对于某些不打算公开源代码的商业运用并没有进行限制。

  • GNU/Linux

    FreeBSD并不是唯一的免费 “Unix” 操作系统，也不是最流行的Unix系统，这个荣誉属于Lin ux。这主要由于Linux出现得早两年，那时BSD的源代码还受AT&T许可权的限制，不能自由获得，而I ntel的32位处理器386的普及已经使Internet上诸多Unix爱好者对PC平台上的免费Unix系统提出 了需求，Linux应时而生。近来在Netscape等商业公司的倡导下，Linux得到众多商业公司的支持，无形中 成为了反Microsfot联盟的一杆旗帜，声势更为浩大。

    Linux是由芬兰人Linus Torvalds编写的Unix兼容系统。由Linus Torvalds 负责核心开发和维护，其他组织和商业公司负责将Linux的核心和应用程序组织在一起发布，由于大部分程序为GNU软 件，因此更严格的说Linux应该被称为GNU/Linux。当前流行的Linux版本有slackware 3.6 ，Debian 2.0，RedHat 5.1等。

    Linux和FreeBSD同为英特尔平台上的Unix操作系统，因此有很多相似之处。几乎所有的自由软件都 同时支持Linux和FreeBSD，因此在应用方面他们也很相似。但Linux和FreeBSD也有相当大的不同之 处，可以说各具特色。

    从历史渊源上讲，FreeBSD继承了BSD Unix的代码，因此代码相当成熟和稳定。而Linux是一个 全新的系统，是遵循POSIX规范开发的一个独立操作系统，但又提供了与BSD Unix或Unix System V的兼容性。因此Linux完全没有受到1992年的AT&T诉讼的影响，结果成为了最流行的自由操作系统。 虽然今天那次法律纠纷已经解决，4.4BSD Lite的代码可以自由获得，但FreeBSD的使用者仍要少于Lin ux的使用者，FreeBSD的使用者多数为网络和计算机专业人士，普及程度较低。

    出于这个历史渊源的原因，FreeBSD是一个完整的系统，从系统核心到系统提供的程序均来自BSD Uni x，部分GNU软件是用于代替BSD Unix中的一些老版本软件。而Linux仅仅只是一个操作系统的内核，其应用 程序大部分为GNU软件，然后由不同的组织或个人将这些GNU软件与Linux内核整合在一起的。因此就存在多个不同 的Linux版本,而且不同的Linux版本使用不同的组合方式，因此各种Linux版本之间有很大的差异，并且可以 预计这些版本会随着发展进一步增大彼此的差异。而FreeBSD的版本比较整齐清晰，只有一个FreeBSD版本。

    通常FreeBSD更关心稳定性，而Linux具备的各种新特性更多。由于Linux得到了更多的商业公司支 持，因而Linux下的商业软件也更多。但是这些商业软件均可以通过FreeBSD对Linux执行文件的支持，也能 够运行在FreeBSD上。这个不同主要是由于Linux和FreeBSD的开发过程的差异造成。

    虽然FreeBSD和Linux的开发过程都是非常开放的方式，每个开发者独立进行自己的工作，通过Inte rnet来互相交流。任何对系统开发有兴趣的人都能贡献新的想法，并组建一个开发队伍或加入现有开发队伍将自己的想法 实现。但是FreeBSD与Linux开发方式的不同是，FreeBSD有一个开发者组成的核心小组（FreeBSD core team）对整个FreeBSD负责。任何人都可以利用FreeBSD提出自己的开发计划，但只有Free BSD核心小组认为这个计划对整个FreeBSD发展有益，这个计划才能列入FreeBSD计划本身。所有的Free BSD开发者共享同一个源代码树，使用并发版本维护工具CVS进行维护。有了FreeBSD核心小组从整体上规划Fr eeBSD，并邀请其他开发者加入核心小组，因此FreeBSD显的更简洁和干净，版本发展也比较稳定。而Linux 仅由Linus对内核进行维护，任何人都可以组织自己的计划，贡献自己的代码，没有一个统一的源代码树，只是在最后由 Linus进行整合和发布正式内核。由于没有严格的控制，并且Linux的开发者很多，因此Linux中虽然有更多的 新特性，却显得略为杂乱，并且有些新特性的代码没有经过时间验证，可能存在有问题。

    一个新功能没有进入FreeBSD正式版本的原因很多，有的是由于这个功能不够成熟，有的是由于核心小组认为 这个特性意义不大，还有的是因为正式内核已经有类似功能，或者由于专利或版权问题（例如，该软件的作者不打算让该软件 成为自由软件），使得十分成熟的功能也不能被列入正式发行的版本。

    由于Linux和FreeBSD互为竞争对手，在Internet上关于Linux和FreeBSD的争论很 多，然而这种争论一般不会得到什么明显的结果。事实上他们都能完成各种应用需求，但各有自己的侧重点，至于那种系统最 适合自己，需要根据具体情况而定，使用者的个人喜好也是影响选择的一个重要因素。一般FreeBSD的使用者也曾经（ 或同时）是Linux的使用者，然而有Linux的使用经验对学习和使用FreeBSD也有不少帮助。只有竞争才能促 进发展，Linux和FreeBSD不但是竞争的关系，也是相互学习的关系，只有如此各自才能不断发展。

    在作者个人的使用经验中，FreeBSD仅有过一次崩溃，并且这种崩溃不是随机出现的，其原因是使用了所有优 化选项来编译内核，编译器某项优化造成了内核的BUG，结果就在执行某项操作时就被触发。在降低了优化级别之后，问题 就消失了。因此这个问题应归结为编译器的问题而非内核的问题。在Linux中，问题更为严重一些，过于求新求功能的多 样性，使得系统崩溃更频繁，并且很多系统崩溃无法找到原因。

    注意：系统崩溃和系统死锁不同，一些情况下一些应用软件死锁会造成键盘或显示没有响应，然而仍然可以通过网络 或其他终端设备登录进系统杀死死锁进程。例如在FreeBSD下执行Linux的X Server时，进行切换虚拟控 制台的操作就会导致键盘死锁。

    当前Linux的一个发展热点是各个商业公司的参与，这的确丰富了Linux下的软件。然而另一方面，商业公 司也试图把专有设计引入Linux，将原有开放的环境变为商品化的环境，以便从中牟利。当前不同版本的Linux之间 的差异已经相当大了，很多人已经意识到了Linux面临的分裂危险，可以想象以后某个版本的Linux会与其他版本存 在兼容性问题。而FreeBSD有统一的源代码树，不存在分裂的问题。

  • 其他BSD系统

    商业版本的BSD/OS也是一个非常优秀的操作系统，它是由原BSD Unix的部分开发人员组成的BSDI 公司的产品。由于存在商业支持，因此在某些方面具备免费的FreeBSD不具备的优势。例如某些硬件厂家不愿意公开自 己的硬件资料（或者是有条件的公开），因而使得FreeBSD无法支持他们的硬件，而他们可以为BSDI提供资料以供 开发驱动程序。一些不能理解自由软件、要使用FreeBSD不支持但BSDI支持的硬件，或对服务和技术支持提出较高 要求的使用者，可以选择使用BSDI。

    NetBSD和OpenBSD也是基于4.4BSD的自由Unix操作系统，可以算是FreeBSD的兄弟。 甚至在最初，NetBSD和FreeBSD的大部分开发者都完全相同，同样的开发者同时为两个系统进行开发。而开发者 和使用者都是将这两个系统作为BSD Unix在不同硬件平台的实现来看待的，FreeBSD用于Intel平台，而 NetBSD用于多硬件平台，主要用于RISC工作站硬件。随着两个系统的不断发展，两者逐渐相分离，而OpenBS D是从NetBSD分出的一个分支。但FreeBSD是为个人计算机平台设计的，后来才尝试移植到其他平台上（已经有 Alpha和Sparc芯片下的FreeBSD系统，但还不十分成熟），因此更适合个人计算机用户，而NetBSD和 OpenBSD一开始就设计为能够运行在多系统平台上，包括各种RISC工作站，因而NetBSD和OpenBSD的 使用范围就更窄一些。

    以上这些BSD Unix系统的使用数量要少于FreeBSD系统。FreeBSD由于专注于Intel平台 ，支持Intel平台上的硬件种类最多，并对易用性作了很大改善，因而使用范围更广泛，是最常见的BSD Unix系 统。但是由于这些系统同属BSD来源，在开发过程中常常相互交流，因此使用方法和管理基本相同。在FreeBSD、N etBSD、OpenBSD之间进行选择的决定性因素常常是安装BSD系统的硬件平台。


FreeBSD连载(04)：FreeBSD的相关资源
王波

FreeBSD的相关资源

    有关FreeBSD的资源相当丰富，一方面旧有的BSD Unix资源也适合FreeBSD，包括大量的书籍 、出版物和Internet上的资源。另一方面FreeBSD拥有大量用户和开发者，直接有关FreeBSD的资源也 相当丰富。

  • 联机文档

    FreeBSD用户最常使用的参考资料是系统联机手册，可以使用man命令查看常用命令、系统调用、C库函数 、设备驱动以及系统配置文件的详细信息。系统的手册位于/usr/share/man目录，此外一些应用软件的手册位 于/usr/local/share/man目录下，X Window程序的手册位于/usr/X11R6/man目 录下。用户可以更改环境变量MANPATH来更改手册的查找路径。

    对于使用man来查询某个关键词时，由于某个关键词既可能是常用命令，又可能是系统调用，一般情况下man只 返回第一个与关键词匹配的内容。由于手册是按种类分为9个不同部分，例如普通命令位于第一部分，C库函数位于第三部分 ，要查找手册后面的内容就必须使用参数指定查找手册的某个部分，或查找手册中所有匹配这个关键词的内容。

    GNU的info命令也能用于查看联机手册，并且具有前后翻页、相关命令的连接等更强的功能。自由软件基金会 的GNU软件除了联机手册之外，还提供info格式的文档，更适合使用info阅读。Info文档通常位于/usr/share/info目录下。

    除了联机手册和联机info文档之外，FreeBSD还在安装介质中提供了其他的各种文档资料，包括4.4B SD的各个文档和FreeBSD的文档，这些文档在系统安装时被放到/usr/share/doc目录下。其中最有用 的是FreeBSD的使用手册（FreeBSD handbook）和常见问题解答（FreeBSD FAQ），对于 FreeBSD用户来讲，它们是非常有用学习和参考材料。这两种资料均提供了超文本html格式用于在线阅读，PS格 式和标准纯文本格式用于打印输出。如果在安装FreeBSD时安装了文档，这些文档将被放在/usr/share/doc/handbook和/usr/share/doc/FAQ目录中。这些联机文档均可在FreeBSD的主页ht tp://www.freebsd.org中找到。

  • 出版物

    最重要的正式出版物算是FreeBSD的安装光盘了，用户可以使用这些安装光盘来安装FreeBSD系统。F reeBSD的每次正式发行的光盘都是由Walnet Creek负责发行的，一般FreeBSD的正式发行光盘共4 张，除了基本安装系统之外还包括了大量软件、软件的源代码和相关资料。另外还有一家Cheapbyte的光盘出版公司 ，以更便宜的价格出售FreeBSD的光盘。这些光盘出版物在国内的书店中还不能直接买到，只能直接和他们联系订购。 如希望得到完整的光盘，可以从它们的网址上进行联系。

    Walnet Creek CDROM： http://www.cdrom.com

    CheapByte : http://www.cheapbyte.com

    FreeBSD是BSD Unix的继承者，凡适用于BSD Unix的书也完全适于FreeBSD。由于B SD Unix的影响，特别它是对教育界和学术界的影响，使得很多Unix的书均基于BSD Unix，因此可以使用 出版的Unix书籍来学习和使用FreeBSD。即使是针对Unix System V的书籍，其基本的Unix使用 和操作也是一致的，对FreeBSD的使用者也有帮助。只是要注意在较深入的系统管理和Unix的编程方面，Unix System V和BSD Unix有所差异。因此在阅读这些Unix书籍中，要了解这些书籍是针对那种Unix的， 以了解它与FreeBSD差异的大小。

    为Unix编写的书籍，不会包括FreeBSD的安装、设置等与具体的系统密切相关的内容。直接与FreeB SD相关的内容只在FreeBSD使用手册或直接为FreeBSD读者写作的参考书中包括。在FreeBSD领域中， 英文书中最著名的为Greg Lehey的《The Complete FreeBSD》，这是一本相当完整的英文F reeBSD指导书籍，同样由Walnet Creek出版。中文的FreeBSD书籍有台湾李建达的《FreeBS D入门与应用》。这两本书均没有在国内正式出版，很难买到。

  • Internet资源

    FreeBSD是利用Internet进行开发的一整套系统，很多开发者彼此之间只通过Internet相互 联系，甚至从来没有见过面。因此只有通过Internet，才能获得最丰富的FreeBSD资源。

    文件资源：FreeBSD的文件服务器为ftp://ftp.freebsd.org，这台服务器本身就是由 FreeBSD建成，是世界上最大、最繁忙的匿名ftp文件服务器（它的另一个名字就是ftp.cdrom.com） 。这个服务器中放置了最完整的FreeBSD完整安装文件和源文件。有关FreeBSD的部分在很多其他ftp站点上 还有镜象，使用这些FreeBSD的文件服务器，就可以仅仅使用启动软盘来安装FreeBSD系统。

    Web资源：FreeBSD的主Web服务器为http://www.freebsd.org，这台服务器上 保存了有关FreeBSD的大量相关资料和有关连接，它在很多国家也有镜象站点，如www.au.freebsd.org、www.jp.freebsd.org、www.tw.freebsd.org等。这些镜象站点使用地区代码来 区分来自不同国家或地区的FreeBSD服务器，其中www.tw.freebsd.org为台湾的机器，这里包括了 一些与中文相关的连接和有关FreeBSD的中文文章。

    以下给出一些较有用的Web资源列表，显然通过这个列表不可能给出所有的资源连接，但可以通过它们，进一步获 得其他相关网上资源的位置。

http://www.freebsd.org

FreeBSD的主页，包括很多有用的资源，例如使用手册和常见问题解答等。

http://www.freebsd.org/zh/FAQ/

FreeBSD的常见问题的中文解答，台湾BIG5版。

http://www.freebsd.org/tutorials/

一个简单但对新手十分有用的FreeBSD入门教程。

http://www.vmunix.com/fbsd-book/

一本图文并茂的FreeBSD电子图书，包括对安装和简单设置的解释说明。

http://flag.blackened.net/freebsd/

包括一些FreeBSD的资料，教用户如何一步步的解决问题。

http://www.mckusick.com/courses/

BSD的设计者之一Kirk McKusick在伯克利开的一门Unix课程，他使用FreeBSD为教学系统。无缘进入伯克利学习的读者可以购买这个课程的录象带。

http://www.daemonnews.org/

这个网址是BSD新闻的发布站点。

http://www.freebsdzine.org/

每月更新一次的FreeBSD电子刊物。

http://www.freebsddiary.com/freebsd/

每天都会更新的FreeBSD资料，是网站设定者的个人学习日记。描述安装、设置各种软件的具体解决过程，对于遇到同样问题的使用者不无裨益。

http://www.freebsdmall.com/

介绍有关FreeBSD的各种商业产品，从商业X Server到印有FreeBSD吉祥物的衣服。

http://www.freebsdrocks.com/

有关FreeBSD的新闻、资源、讨论区和技术文档.

http://fbsdboard.lynxcom.net/

一个讨论FreeBSD相关内容的讨论区。

http://dmoz.org/Computers/Operating_Systems/Unix/FreeBSD/

一个收集了很多其他FreeBSD连接的网址。

http://freebsd.csie.nctu.edu.tw

台湾交通大学的FreeBSD网站，有很多台湾FreeBSD使用者的讨论内容，从此处可以连接到台湾的其他FreeBSD的站点上去。

    Usenet资源：直接有关FreeBSD的新闻组有comp.unix.bsd.freebsd.misc ，comp.unix.bsd.freebsd.annouce，还有很多讨论BSD Unix的新闻组也讨论Fre eBSD的问题。可以与本地的NNTP服务器连接读取这些新闻组，如果本地没有NNTP服务器，可以通过以下两个We b网站读取Usenet的新闻：

    http://www.dejanews.com

    http://www.supernews.com

    邮件列表： FreeBSD.org上提供有关FreeBSD的各种邮件列表，事实上邮件列表在FreeBS D用户之间起到的交流作用非常重要，使用它可以直接与FreeBSD的各个开发者联系，获得帮助。可以通过向majo rdomo@freebsd.org发送请求，订阅相关邮件列表，例如向majordomo发送一个内容仅仅包括一行 “subscribe freebsd-current” 的邮件将订阅freebsd-current列表，然后m ajordomo会发送一封确认邮件，一旦得到确认，以后每个发送到这个列表的信件都发送给这个用户。邮件列表是一个 与其他FreeBSD使用者交流的相当有用的工具，例如，可以向freebsd-questions@freebsd .org发送疑难问题，那么就能得到包括大多数开发人员在内的其他使用者的帮助。下面是一些十分有用的邮件列表：

    freebsd-announce--------宣告FreeBSD开发中重要的升级及其他事件

    freebsd-bugs------------报告FreeBSD的Bug

    freebsd-chat------------谈论非技术性的FreeBSD话题

    freebsd-isp-------------ISP使用FreeBSD的一些高级问题

    freebsd-newbies---------新手的一些问题及讨论

    freebsd-questions-------问题及答复，可以在这里获得技术支持

    freebsd-current---------讨论使用current版本的一些问题

    freebsd-stable----------讨论使用stable版本的一些问题

    freebsd-doc-------------FreeBSD文档的讨论列表

    freebsd-hackers---------有关FreeBSD技术的话题

    freebsd-ports-----------讨论向FreeBSD上移植软件

    freebsd-security--------FreeBSD的安全

    freebsd-net-------------讨论网络技术及其在FreeBSD上的实现

    IRC通道：还可以通过IRC上的FreeBSD通道得到其他FreeBSD用户的实时帮助，这对于正遇到问 题、调试系统的使用者非常有用，可以立即可其他FreeBSD使用者讨论自己碰到的问题，得到实时帮助。

  • 商业服务和支持

    虽然FreeBSD是免费操作系统，然而仍然有提供FreeBSD服务的计算机公司。国外可以从FreeBS D Inc.和Walnut Creek CDROM那里得到服务和支持，在FreeBSD的主页中还有收集了很多对 FreeBSD提供支持的商业公司的连接。国内还没有专门提供这类服务的商业机构，然而随着FreeBSD影响的扩大 ，必然会出现对FreeBSD提供支持的系统集成商。


FreeBSD连载(05)：安装之前的准备
王波

第2章 安装与配置

    Unix给人的印象一向是比较专业，难以安装，但是FreeBSD的表现却并非如此。这是因为FreeBSD 主要支持最流行的个人计算机平台，由于多平台问题不是主要考虑对象，FreeBSD的开发者就集中精力建立了一整套适 用于个人计算机的高级安装与配置工具 ── Sysinstall。因此与其他Unix系统不同（包括NetBSD和 FreeBSD），FreeBSD的安装过程相对简单和容易理解，只需要安装软盘或安装光盘启动安装程序，就能顺利完 成安装FreeBSD的任务。

    FreeBSD的安装程序支持最流行的网络安装和光盘安装方式，也支持传统的磁带和软盘等其他几种安装方式， 支持大多数的流行硬件以及这些硬件的标准配置，并能对系统进行基本配置，如主机名、键盘和屏幕字体、网络设置等。

    但是通常个人计算机上最常使用的还是微软的Windows 9x系列的操作系统，使用者常常习惯用来自于DO S的一些概念来分析系统，这些概念与Unix对同样事物的理解方式有所不同。而FreeBSD是一个完整的Unix操 作系统，因此要求使用者要使用Unix的方式去了解个人计算机系统的各个方面。正如一个没有任何DOS/Window s基本概念的使用者，无法正确安装DOS/Windows一样，一个没有任何Unix的基本概念的使用者，也无法正确 安装FreeBSD。

  • 安装之前的准备

    安装之前应该了解要安装FreeBSD的计算机硬件配置和Unix的一些基本概念，以及FreeBSD软件的 载体 ── 安装介质。这些信息能帮助用户了解这台计算机是否适合安装FreeBSD，是否具备安装FreeBSD的 条件。绝大多数情况下使用安装光盘（或软盘）直接进行安装，就能完成安装任务，但了解更多的信息可以帮助安装者处理在 特定条件下发生的安装问题。所以建议读者不要忽略安装的准备阶段，充分了解自己要安装的系统的硬件和FreeBSD中 的常用概念，可以避免安装过程中出现问题。

  • 硬件设备

    个人计算机上的硬件种类千差万别，对于用于不同目的的系统，应该会选用不同的硬件。有些硬件对FreeBSD 系统比较重要，如硬盘和网络设备，而有些硬件不太重要，属于可选配置，如用于多媒体系统的声卡等。要安装FreeBS D系统，必须保证这台计算机中包括最基本的硬件设备，如用于安装系统的硬盘，读取要FreeBSD安装介质的设备：软 盘驱动器、光盘驱动器或网络等。

    然而也有特定配置的FreeBSD系统，可以仅使用软盘启动和运行，或者是无盘的网络工作站。这些系统用于特 定目的，如用作专用防火墙设备或X终端。这些特殊配置的FreeBSD系统不使用标准的安装方式。

  1. FreeBSD支持的硬件

        标准的FreeBSD最小能够安装在一台只有5MB内存，40MB硬盘，使用Intel 80386芯片的机 器上。事实上运行FreeBSD只需4MB就足够了，只是FreeBSD的安装程序要将软盘上的数据首先展开到内存中 的MFS文件系统中（相当于虚拟磁盘），因此要求至少5MB的存储空间。如果要求系统能运行X Window图形界面 ，那么就应该至少有8MB内存，250MB硬盘。

        FreeBSD在这种低配置的计算机中仍然能完成相当多的任务，然而处理器的速度和内存的大小也限制了它的任 务处理能力，显然更高配置的计算机能表现出更出色的性能，完成更复杂的处理任务。例如，安装软件需要额外的硬盘空间， 而复杂的软件会要求更大的内存和处理器速度提供支持。通常太低配置的计算机对于用作个人工作站并不适合，但其处理能力 也能满足完成某些处理专有任务的特定用途方面。例如用作拨号访问Internet的网关，一台软盘启动的386也就能 满足其56Kbps流量的处理要求。

        不同的工作用途，对硬件的要求也不相同，也应该选用不同种类的硬件。如果用作个人工作站或专用X终端，至少应 该拥有大屏幕、高清晰的图形显示器。如果是用作支持数百人同时访问的Internet服务器，就必须考虑使用最高级P entium II处理器，SCSI硬盘以及大量的内存。将FreeBSD系统用作软件路由器、防火墙或网桥设备时， 就应该根据网络结构和数据流量采用高性能的网卡，例如采用ATM网卡或千兆以太网卡。

        FreeBSD支持ISA、EISA和PCI总线的硬件设备，包括标准的IDE/EIDE硬盘驱动器，各种S CSI控制器，IDE和SCSI界面的磁带驱动器和光驱，其他的一些ATAPI界面的光驱，标准串口、并口，各种类型 的鼠标，与SoundBlaster兼容的声卡，VGA兼容的显示卡等个人计算机上使用的大部分硬件。只有一些太古老 的，或者使用很少的硬件，或者生产厂家不愿公开其技术资料的硬件，FreeBSD不能提供支持。对于这样的情况，就必 须更换硬件设备才能安装FreeBSD。同时也必须注意到，由于FreeBSD下的硬件支持并不是由硬件厂商提供支持 的，而是由FreeBSD开发者根据硬件厂商提供的资料开发的。因此当一种新设备出现之后，并不会立即出现FreeB SD下的驱动程序，而需要一定的滞后时间。

        字符模式下，只需要标准VGA显示设备就可以了，但在X Window下，显示卡的VGA兼容方式只能提供1 6色及640x480的分辨率，而大多数显示卡能显示更高的分辨率及更丰富的色彩，这需要显示卡的驱动程序提供支持， 这种支持是由X Server来完成的，因此对不同种类显示卡的支持应该检查X Free86的硬件支持列表。

        在每个FreeBSD安装介质中，都包括一个该版本的FreeBSD支持硬件的列表文件──HARDWARE .TXT，也可以到FreeBSD的往页中获得各个版本的硬件支持列表文件。然后可以对比这个文件中的硬件列表，来判 断自己计算机上的硬件是否满足安装FreeBSD的要求。在订购计算机硬件时，也可以参考这个文件的内容来选择购买F reeBSD支持的硬件。

        但是，FreeBSD支持的硬件并不一定是FreeBSD的标准安装程序支持的硬件，由于要在安装软盘中不可 能包括所有硬件的驱动程序，而只放置了对安装系统所必要的一些驱动程序。有的硬件设备对于系统安装来讲用处不大，如声 卡等多媒体设备，那么其驱动程序就不包括在安装软盘和标准内核中。支持这些硬件便需要重新定制FreeBSD内核，安 装盘支持的硬件也在HAREWARE.TXT中进行了描述。

        当前计算机硬件发展速度非常迅猛，当前Intel平台的计算机完全能满足不同用途FreeBSD的要求。然而 由于硬件发展很迅速，新型硬件不断出现，就使得这些硬件从出现到被FreeBSD支持，需要经过一段时间。如果某些硬 件在最新的release版本中不支持，可以查看FreeBSD-current分支是否支持该硬件，因为-curr ent分支通常包括更多新硬件的驱动。

  2. 硬件资源及配置

        个人计算机的硬件由主板和多个的板卡组成，每种硬件必须占用不同的硬件资源。这些资源包括端口号（ports ），中断请求号（IRQ），直接内存访问通道号（DRQ），输入/输出存储器地址（I/O memory），硬件使用 的资源不能够相互冲突，否则冲突的硬件就无法正常工作，甚至会影响整个系统的正常运转。

        在个人计算机中，硬件资源的分配遵循一定的习惯，这样在使用的板卡数量较少时就不会形成冲突。但是在硬件较多 时，缺省配置就不一定十分合适。为了避免硬件冲突，就需要对板卡使用的资源进行设置。而不同的板卡，采用三种不同的资 源设置方式：

    • 跳线或DIP开关，板卡上有几个不同的跳线，选择不同的跳线方式使板卡使用不同的硬件资源；

    • 软件设置，板卡厂商附送设置软件（一般是DOS程序），能够对板卡使用的资源进行设置。有的板卡还提供驱动程序， 可以自动探测空余的资源，并重新更改板卡使用的资源设置，这种能通过软件驱动改变资源设置的板卡被称为无跳线板卡（ Jumpless）。只是其提供的驱动基本都是DOS/Windows驱动；

    • 即插即用（PNP, Plug & Play），板卡遵循PNP标准由系统分配空余资源；

        对于这三种不同的硬件类型，更改板卡资源配置的方式也不同，对于前两种方式的板卡，可以直接更改跳线或DIP 开关，或者在DOS下使用设置软件来设置它占用的资源。即使是Jumpless的板卡，由于硬件厂商提供的驱动只是D OS/Windows驱动，因此只能使用其缺省资源设置而不能利用其自动探测的优势，当然设置程序可以帮助更改其缺省 的资源设置。

        而对于Plug and Play的ISA板卡，问题较为复杂，因为PNP板卡要求系统为其分配资源设置。有 些板卡的设置软件，可以设置这个板卡不使用Plug and Play方式,而直接指定占用的硬件资源。这样就将PN P类型的板卡用作软件设置的板卡，由安装者来保证没有硬件设置冲突存在，这是一种思路简单的解决办法。

        如果使用Plug and Play的方式为板卡分配资源，可以选择两种不同的分配方式，一种是由BIOS设 置硬件的资源，BIOS在自检时就分配资源给PNP卡，然后当操作系统启动时根据这个设置分配板卡占用的资源。另一种 方式完全由操作系统分配PNP卡占用的资源，BIOS不给PNP卡分配硬件资源。

        FreeBSD能够支持Plug and Play，但是由于ISA总线的PNP卡通常是某种标准ISA板卡 的兼容产品，驱动程序不会自动分配资源，因此就需要在UserConfig中进行手工设置或调整，PCI PNP卡就 不存在这个问题。为了避免烦琐的手工调整，可以使用BIOS给Play and Play板卡分配初始资源，如果必要 再手工调整设置。支持PNP卡的主板BIOS中通常有一个Plus & Play OS选项（或类似描述词句 ），这个选项用于决定是否为PNP板卡分配资源，应该将该选项关闭（选择 “Disable” ， “No” ， “ non-Win95” 等），让BIOS为板卡分配初始资源。

        通过更改硬件的设置，来解决硬件冲突问题。此后将这些硬件配置信息记录下来，用来解决安装过程中的问题。即使 计算机上不存在硬件冲突问题，记录下这些配置信息也是非常有用的。可以通过查看各个硬件的手册或硬件提供的设置软件来 了解这些硬件的配置情况，如果计算机上已经安装有操作系统，可以使用这个操作系统上的软件来辅助了解硬件的配置信息， 例如DOS下的MSD，Windows 95下控制面板中的系统选项等，这些软件中将显示出当前计算机已经配置过的硬 件信息。

        对于PNP卡，由于系统资源是计算机启动后才获得的，因此使用DOS/Windows下的软件能更快捷的获得 必要的信息。虽然PNP中资源是动态分配的，但是这个值仍然能起到非常有用的参考作用，尤其对于使用BIOS来分配资 源的板卡，这个资源设置就更有意义一些。

  • 安装介质

        为了安装FreeBSD，必须还要有FreeBSD系统的安装介质，FreeBSD支持的安装介质有以下几种 ：

    • CD-Rom

          由于光驱已经成为个人计算机的标准配置，因此使用FreeBSD的安装光盘来安装FreeBSD是最容易也最 常见的安装方式。并且当个人计算机系统支持CD-Rom启动时，就可以直接使用光驱来安装FreeBSD，而不需要启 动软盘的帮助。使用CD-Rom做安装介质要求计算机配有FreeBSD可以识别的光盘驱动器。

    • 网络服务器

          安装文件位于网络服务器上，安装程序通过ftp或者nfs，远程访问网络安装服务的相应服务器上，获得安装所 需的各个文件。网络安装要求系统必须连接到网络上，而且网络的传输速度也要比较稳定才合适。被安装的计算机必须具有网 卡或广域网接口，以支持网络。

    • 磁带

          这是一种较老式的安装方法，但十分有效。如果有tar格式的安装磁带，安装过程十分简单。使用这种安装方式， 计算机必须拥有一台磁带机。

    • 软盘

          也是一种较古老的安装介质，除非条件限制，很少有人有耐心使用软盘作安装介质，因为这需要太多的软盘，并且软 盘是不可信赖的存储介质，很难保证复制的软盘没有错误。FreeBSD之所以支持这种方式，是因为软盘驱动器是个人计 算机的标准配置，这使得FreeBSD能够在最恶劣的特殊条件下也能进行安装。

    • 硬盘

          将FreeBSD的安装文件预先拷贝到计算机系统中已有的硬盘分区中，该分区的类型可以是DOS分区或者 FreeBSD分区。这要求计算机中有足够的硬盘空间并已有格式化后的分区。这种方式是前面几种方式的折中方式，如果网络 不稳定，或者光盘质量有问题，或者要保留安装介质以便再次安装，都可以先复制必需的内容到硬盘上。

    • 安装介质中的内容

          无论哪种安装介质，其中都是存储了要构建一个FreeBSD系统所需要的系统软件，由于CD-Rom和Internet 越来越普及，CD-Rom和网络安装方式是最常用的方法。这里就以FreeBSD的安装光盘为例，简单介绍 FreeBSD安装介质上的主要内容。

          FreeBSD使用的安装光盘是标准的ISO 9660格式的光盘，这种格式缺省只支持8.3格式的文件名（ 8个字符的基本文件名，3个字符的扩展名，不区分大小写），由于Unix下的文件名比较长，且区分大小写，因此Fre eBSD及其他Unix通常使用Rock Ridge方式对文件名进行映射，在每个目录下使用一个文件TRANS.TBL 记录8.3格式的文件名与Unix使用的长文件名之间的对应关系。

          FreeBSD安装光盘中的内容可分为三类：

      第一类为安装说明文件，这些文件位于安装介质中的根目录下：

      ABOUT.TXT： 关于FreeBSD的简单信息
      HARDWARE.TXT： FreeBSD支持的硬件列表
      INSTALL.TXT： 介绍如何安装FreeBSD的说明
      README.TXT： 介绍安装介质上其他文件，应该首先阅读
      RELNOTES.TXT： 发行这个版本的FreeBSD系统时的一些通知
      LAYOUT.TXT： FreeBSD安装系统的文件分布的说明
      UPGRADE.TXT： 进行升级FreeBSD的一些注意事项

      第二类是进行安装时能用到的DOS工具程序，主要用于制作启动软盘。

      tools目录： 准备安装所需要的DOS工具程序，包括制作启动软盘的DOS程序，以及帮助整理硬盘的 工具，从DOS下启动FreeBSD的程序等。
      floppies目录： 包含安装软盘、启动软盘、系统修正软盘的镜象文件的目录

      第三部分就是FreeBSD系统的安装文件

      XF86333目录： 包含XFree86软件的目录，其中版本号会随着系统升级而提升到更新的版本
      bin目录： 系统基本文件的安装目录，这是安装FreeBSD所需的必备目录
      catpages目录： 格式化后的普通文本方式的系统手册
      compat1x、 compat20、 compat21 和compat22目录： 包含与以前各个版本的FreeBSD相兼容的库
      des目录： 由于美国法律的限制，包含DES算法的软件未经许可不能出口到美国和加拿大之外， 因此FreeBSD缺省使用MD5算法以避开这个问题，这个目录中包含与des算法的相关软件，以便需要这个 算法的使用者可以从北美之外的Internet上获得并安装。
      dict目录： 系统字典安装目录
      doc目录： 系统文档安装目录
      games目录： 包含一些Unix小游戏
      info目录： GNU info文档的安装目录
      manpages目录： 系统手册的安装目录
      packages目录： 包含最常用的软件
      ports目录： Ports Collection的源代码
      proflibs目录： 系统运行库
      src目录： 系统源代码的目录

          这些安装文件可分为三类，一类是系统软件，用于构建基本的FreeBSD系统。这些软件存储在安装介质下的b in, des, dict, doc, games, info, manpages,catpages, com pat1x, compat20, compat21, XF86333和proflibs目录中。为了便于管理，这 些文件使用tar和gzip进行打包压缩，其中前六个目录下的文件被分割为大小为240,640字节的文件，这样在需 要的时候，可以拷贝到软盘上进行安装。然而并不是所有的内容都必须安装，可根据不同的安装选项，有选择的安装不同目录 下的不同内容，只有bin目录下的系统软件才是必须的。

          另一类是可选软件，如果说基本系统是骨架，那么应用软件就是血肉。没有应用软件，一台FreeBSD系统就不 能充分发挥它的全部功能。FreeBSD使用Ports Collection的机制来管理应用软件，将应用软件移植 到FreeBSD下，每个移植的软件被预编译为一个个的二进制软件包，称为Package，存储在安装介质的pack ages目录下，因此二进制软件包的管理机制又称为Packages Collection。由于空间的限制，安装光 盘上并不能包含所有软件的二进制形式的Packages，但在FreeBSD的ftp站点上提供了所有最新的软件包。

          此外就是系统的源代码，包括内核的源代码、各个程序的源代码以及Ports Collection的源代码。 一个正常的FreeBSD系统至少应该安装内核的源代码，以便根据自己计算机的实际情况来定制内核。这些安装文件位于 src和ports目录下。

          其他安装方式下的安装介质内容与CD类似，但在内容上也略有不同。因为安装组件都是可选的，因此不同的安装介 质将可以选择不同的安装组件。例如软盘安装介质可能只包括最基本的系统（bin目录下的文件），而FreeBSD的主 ftp站点ftp.freebsd.org上，包括了所有的安装文件。

          要根据不同情况和条件，来选择不同安装介质。如果计算机系统具备网络界面并与Internet的连接快速且稳 定，那么就可以使用网络安装方式，这仅仅需要制作启动软盘（如果计算机上已经安装有DOS，甚至可以连启动软盘都不需 要了），以启动FreeBSD和安装过程。如果购买了FreeBSD的安装光盘，就可以选用光盘安装方式等等。

          当前由于硬件发展非常迅速，因此光驱对于个人计算机已经是标准配置，因此使用光盘作安装介质应该是最为方便的 首选安装方式。

  • 准备硬盘和软盘

        在IBM兼容的个人计算机上使用的硬盘控制器有以下种类：

    • 最古老类型的ST-506以及ESDI，当前已经很少人使用这些驱动器，但是FreeBSD的wd驱动程序仍然支持它们；

    • IDE和增强型IDE（EIDE），是当前最流行的个人计算机硬盘控制器，每台计算机能接两个控制器，每个控制器可 以接两个设备（硬盘或光驱），分别为这个控制器上的主设备和从设备。FreeBSD的wd驱动程序支持EIDE，wd驱动程序探 测到的第一个IDE控制器的主硬盘为wd0，第一个IDE控制器的从硬盘为wd1，第二个IDE驱动器的主硬盘为wd2，从硬盘为wd3；

    • SCSI控制器，由于SCSI控制卡承担了大量的处理任务，降低了中央处理器的负载，更适合用做服务器和高性能工 作站的磁盘驱动器。早期的SCSI控制器能接7个设备，而Wide SCSI控制器可以接15个设备。SCSI板卡种类繁多，对不同 的SCSI控制器，FreeBSD需要使用不同的驱动程序来进行支持。与IDE驱动器相同，SCSI硬盘驱动器也按检测到的顺序排列 或在内核中规定的顺序，从da0向后，依次类推。

        在FreeBSD 2.2.x版本中使用的SCSI驱动程序为与3.x版本不同，旧版本驱动程序使用的SCSI 硬盘设备名为sd0等。

    1. 硬盘分区方式及命名

          在个人计算机中，每个硬盘可以分为四个磁盘分区，其分区信息存储在该硬盘前部的分区表中，而每个分区可以由不 同的操作系统进行管理。常见的分区分为基本分区和扩展分区，又根据使用的不同文件组织格式，可以分为DOS的FAT分 区，FreeBSD的UFS分区、NT的NTFS分区，Linux的EXT2FS分区等。

          一个硬盘上可以划分一个扩展分区，扩展分区与基本分区不同，它实际上不直接在上面存储实际数据，而是在上面再 划分逻辑分区，这样又可以划分四个逻辑分区。使用DOS/Windows操作系统的计算机必须拥有一个使用DOS的F AT文件系统的基本分区，这个将对应于DOS下的C盘，然后将其他空间划分到扩展分区中，在扩展分区中再划分DOS逻 辑分区，相应的FAT分区依次对应于D盘、E盘等。当其他的操作系统使用硬盘时，这个操作系统应该单独占用一个分区， 在这个分区上使用自己的文件组织格式。

          DOS只能使用C、D等盘符来标志FAT格式的磁盘分区，它不能标识其他文件组织格式的磁盘分区，如果一个硬 盘上没有FAT格式的磁盘分区，那么就不会存在C盘、D盘等。然而其他更强大的操作系统通常能识别多种文件组织格式， 通常按照分区在分区表中的顺序来标识他们。例如FreeBSD将记录在分区表上的分区，分别称作wd0s1，wd0s 2，wd0s3，wd0s4，wd0为第一个IDE硬盘，使用s1标识第一个分区等。如果某个分区（例如第二个分区w d0s2）为扩展分区，那么其上面的逻辑分区，其顺序就从5算起，为wd0s5，wd0s6，wd0s7，wd0s8 。因此一个磁盘上最多只能有8个不同的分区同时存在。

          然而毕竟扩展分区上的逻辑分区和基本分区还有所差别，因此不是所有类型的文件组织方式都可以适合在逻辑分区中 使用。FAT、NTFS和EXT2FS类型可以被在逻辑分区上使用，但是FreeBSD使用的UFS不能被逻辑分区使 用，只能是在基本分区中使用UFS文件组织格式。这是由于FreeBSD是一个完全独立的操作系统，使用的分区方式继 承自BSD Unix，早在个人计算机出现之前，BSD就已经形成了自己的管理硬盘和分区的方式了。

          BSD Unix传统的使用硬盘方式是独占整个硬盘，只有文件系统或交换空间而没有分区的概念，也不使用硬盘 的分区表来保存分区信息，因此也不存在基本或扩展分区。BSD使用Slice来表示硬盘上的一个部分，一个Slice 是硬盘的一个部分，它可以是一个文件系统也可以是一个交换空间。Slice的概念与个人计算机传统使用的Partit ion（分区）概念类似，因此也可以使用分区来称呼它。BSD方式的管理方法能管理多达8个Slice，BSD按字母 顺序依次命名他们为wd0a，wd0b等。按习惯用法，wd0a用于根文件系统 “/” ，wd0b用于交换空间，w d0c用于表示整个硬盘空间，wd0e用于/usr文件系统等。

          然而FreeBSD毕竟是运行在个人计算机平台上的操作系统，其他操作系统使用Partition，而Fre eBSD使用Slice，就必须采用一种折中的方式，使得FreeBSD能和其他操作系统相互协作，处理磁盘分区。F reeBSD的磁盘管理方式就是一种兼容的硬盘使用方式。每个FreeBSD系统将占用一个独立的UFS基本分区，这 个分区与其他操作系统使用分区的方式相同。在基本分区内再使用BSD的Slice方式进行管理，这种方式就类似于DO S在扩展分区内分割逻辑分区的方式。

          假设FreeBSD使用了第三个分区wd0s3，则在这个分区内划分的相应Slice就被称为wd0s3a， wd0s3b等，其中wd0s3a缺省被用做根文件系统等。这时仍然可以使用传统的名字wd0a来称呼wd0s3a， 使用wd0b称呼wd0s3b，以与BSD传统方式兼容的方式称呼这些Slice，但条件是wd0s3应该是wd0硬 盘上第一个UFS类型的基本分区（或唯一的UFS基本分区），wd0盘上的其他UFS分区中的Slice就只能使用全 称了。由于Slice和Partition都是用于分隔磁盘（或分区），以更方便的利用磁盘空间，为了简捷，可以将在 UFS基本分区中划分的Slice，如wd0s3a，称作wd0s3分区的子分区。

          下面为DOS和FreeBSD（多操作系统并存）下常用硬盘分割的方式。

    2. 准备硬盘

          如果不是在新系统中安装FreeBSD，安装系统之前需要备份相应硬盘上的重要数据。因为安装过程将直接操作 硬盘，对硬盘进行分区和格式化（在Unix下称为建立文件系统），虽然在一定条件下安装者能够不破坏原有的数据，但是 有可能由于某次误操作，导致重要数据的无法恢复。因此建议对该计算机上的所有硬盘数据做一次完整备份。这些数据的备份 任务要使用计算机已经安装好的操作系统来完成。

          然后需要确定将系统安装在何处，FreeBSD必须独占一个基本分区，要保留出自由空间就行了。硬盘上的自由 空间包括两个含义，一是分区表中的位置上的空间，四个分区表没有占满，另一个是硬盘空间，现有的分区没有占满所有的硬 盘。然而，安装程序也能删除现有分区，并重新分割硬盘。

          如果是在一个新硬盘上安装FreeBSD系统，但又打算以后还安装DOS等其他操作系统，最好使用DOS程序 fdisk.exe先划分出一个基本分区。这个分区的大小都没有什么意义，它只是用来给FreeBSD安装程序提示B IOS的硬盘数据映射方式的，否则FreeBSD安装程序就不考虑BIOS的映射方式。由于这个分区只起到提示作用， 可以在安装过程中删除，重新按照原有的考虑分割硬盘。如果没有这样的分区，FreeBSD安装程序中的硬盘映射数据可 能和BIOS中的设置不一致，当然安装者可以进入BIOS，记录下硬盘的柱面、磁道和扇区映射数据，在安装过程中手工 更改映射数据设置。

          硬盘映射数据不一致的问题，来源于个人计算机BIOS与Unix对硬盘的理解不同。个人计算机使用柱面、磁道 和扇区的概念来理解硬盘上数据的位置，而Unix只将硬盘等存储设备理解为分为一个个块的简单线形设备。这就导致Fr eeBSD中的Slice和BIOS中的Partition划分时的不同。如果计算机上只有FreeBSD一种系统独 占硬盘，FreeBSD只需要知道每个Slice的大小就行了，按块读取数据，不会出现任何问题。但如果与另一种操作 系统共享硬盘，那么就必须首先确定相应的Partition位置，这就受到BIOS的限制。一旦FreeBSD对柱面 、磁道和扇区理解与BIOS设置的不同，必然就发生不能找到分区的正确位置问题。

          一般情况下，找不到分区位置的情况不会发生，因为FreeBSD系统能够侦测到硬盘的数据。但是个人计算机上 的BIOS会对柱面、磁道和扇区数据重新进行映射，导致BIOS以与硬盘本身并不一致的方式来分割硬盘上的Parti tion。因此对于在一个新硬盘上安装FreeBSD，BIOS又对磁盘数据进行了重新映射的情况下，就需要记录下B IOS映射的数据用于纠正可能出现的映射数据问题。BIOS对硬盘数据进行映射发生于两种情况下，一种情况为使用SC SI硬盘时，SCSI硬盘本身使用线性地址，而BIOS必须要求柱面、磁道和扇区的概念，因而BIOS就对SCSI硬 盘进行映射。另一种情况是对EIDE硬盘，由于个人计算机BIOS的设计问题（系统调用仅支持1024柱面的限制）， 支持大硬盘的BIOS也要将EIDE硬盘重新映射为合法的硬盘数据（使用LBA或其他映射方式）。因此即使在安装系统 之后，如果随意更改BIOS中的硬盘映射方式，就会使得分区的位置被映射到一个错误的位置上，发生启动错误。

          FreeBSD本身并不使用任何BIOS调用来处理硬盘存取，而是使用自己内部的硬盘驱动程序。因此，只要启 动程序将控制权交给FreeBSD系统之后，BIOS中的硬盘映射方式就没有意义了。但是，启动系统的任务是由BIO S或使用BIOS调用的启动管理程序来完成的，BIOS必须能找到操作系统的启动部分才能载入相应的操作系统。这样就 有两种有趣的情况发生，第一种情况下，虽然BIOS的映射数据可能被改动了，但是改动之后的数据中操作系统分区的初始 位置没有变化，这样BIOS仍然能载入操作系统的启动部分，来启动FreeBSD。这种情况最常发生在让FreeBS D系统独占整个硬盘的情况时，这样操作系统的启动就基本不受BIOS的映射数据的影响了，这种情况就是传统的BSD的 硬盘管理模式，硬盘中不存在Partition。

          另一个情况发生在FreeBSD分区的位置在1024柱面之后，由于BIOS的1024柱面限制，它不能引导 1024柱面之后的分区。因此给FreeBSD留的空间要位于1024柱面之内，才能使安装后的FreeBSD系统能 够正常启动。在系统启动之后，FreeBSD就不再使用BIOS进行任何操作，则此时就可以处理1024柱面之后的硬 盘了。在这种情况下，BIOS的硬盘映射能起到帮助作用，因为如果BIOS使用了LBA或其他方式重新映射了硬盘数据 ，每个硬盘分区就将保留在1024柱面之内，就不存在这个问题了。因此，如果大硬盘使用的是LBA等模式，就不存在启 动问题，如果BIOS没有映射硬盘数据，就要注意分区的位置，以便系统能正确启动。但是，在硬盘上已有分区的情况下， 不应该调整硬盘的映射数据，因为这将丢失已有的分区数据。

          因此如何处理分割分区就需要安装者仔细考虑。对于一个新系统，可以选择让FreeBSD独占整个硬盘或者保留 一个小的DOS分区。让FreeBSD独占整个硬盘的好处是硬盘不受BIOS的影响，因此这个硬盘可以立即安装到其他 FreeBSD系统下，而不需要考虑不同BIOS的不同映射方式。但是保留一个小DOS基本分区也存在相当多的好处， 因为Intel平台下的多数硬件配置和诊断程序为DOS程序，将这些配置程序保留在DOS分区内，便于更改硬件配置和 诊断故障。具体如何选择依赖于安装者的考虑，一般建议保留一个DOS分区。

          对于在已安装有操作系统的硬盘上安装FreeBSD系统，处理分区就更需要小心。大多数预装DOS/Wind ows的个人计算机通常使用DOS基本分区和扩展分区占满了整个硬盘空间，没有空余的自由硬盘空间留给FreeBSD 。因此就需要将一个分区留给FreeBSD，就需要在安装之前把这个分区中的数据都进行备份。此外还需注意如果是要将 扩展分区留给FreeBSD，就必须将整个扩展分区留给FreeBSD，FreeBSD不能在扩展分区中的某个逻辑分 区上安装。如果使用者想保留已有分区和数据，情况就比较复杂了，有一些软件能够在不损失数据的条件下，更改已有分区大 小，这样就能从现存分区中挤出空余空间来安装FreeBSD，这些软件有自由软件FIPS（在安装光盘中提供），商业 软件PartitionMagic等。

          FIPS能够将FAT类型的DOS基本分区分割为两个分区，第一个分区保留原有数据，而可以使用FIPS分出 的第二个分区安装FreeBSD。然而这种操作直接操作硬盘，具有非常大的危险性，如果操作失误，很可能导致分区错误 及数据丢失。建议在FIPS操作之前，备份硬盘上的重要数据。此外，还应该首先使用磁盘整理工具来整理磁盘上的文件。 长期使用计算机，使硬盘上的文件被零零碎碎的放在硬盘的不同位置上，因此必须将所有的文件都移动到硬盘的前面，以减少 错误发生的可能性。微软的Defrag工具以及其他第三方厂商的工具，如Norton SpeedDisk，都提供了 这个能力。

          Defrag程序不移动系统和隐藏文件，因此对于可能位于磁盘后部的系统和隐藏文件，必须在运行Defrag 之前使用微软的attrib命令去除这些属性（包括Windows的交换文件），由于有这些属性的DOS系统文件IO .sys和MSDOS.sys总是位于磁盘的前部，因此不需要对它们进行处理。运行Defrag不能使用 “Defr ag File Only” （只整理文件碎片）选项，因为该选项并不把所有的文件都移动到硬盘前部。

          运行了Defrag之后，最好使用Scandisk来检查一下是否存在磁盘错误，如果一切正常，并且分区表还 没有占满（总计不到四个分区），就可以运行FIPS来分割DOS基本分区了。FIPS执行程序位于安装介质下tool s目录中，由于FIPS是一个DOS程序，直接访问硬盘，因此应该在DOS模式运行它。它在运行时能将原有分区表保存 到软盘上，命名为RESTORRB.000（如果多次运行FIPS，文件名将依次增加为RESTORRB.00x）， 可以使用随FIPS一起提供的RESTORRB来恢复原有分区数据。

    3. 准备软盘

          常用的启动FreeBSD安装程序方式主要有三种，光盘启动、DOS启动和软盘启动。如果计算机的不支持光盘 启动，并且没有安装有DOS系统或没有DOS启动程序fbsdbot.exe和kernel文件，那么就需要使用启动 软盘启动。

          在安装介质的floppies目录中保存有启动软盘的镜象文件boot.flp，使用者可以在其他计算机中的 DOS或者Unix下制作出这张软盘。然而，在新版本下这个镜象文件是2.88MB的高密度软盘镜象，必须要求计算机 支持2.88MB的软盘驱动器才可以，因此一般不使用这个镜像文件，它更常用来作为启动光盘的启动盘镜像。系统也提供 了两个1.44MB的普通磁盘镜象文件kern.flp和mfs.flp，其中kerm.flp为系统内核，mfs. flp为将被读到内存中MFS文件系统中的root文件系统，一般需要制作这两个软盘，用来启动安装系统。由于磁盘镜 像要占满整个磁盘，因此对软盘要求很高，软盘中不能有坏块。如果制作的软盘不能正常启动，最大的原因就是使用了非10 0%完好的软盘，

          制作启动软盘必须使用一个现存Unix或DOS系统。

          在DOS下，使用程序rawrite.exe或fdimage.exe（tools目录下）来将一个软盘镜象 文件复制到软盘中。可以使用它来制作启动软盘、fixit软盘等。

          E:\TOOLS:> FDIMAGE E:\FLOPPIES\KERN.FLP

          在FreeBSD或其他Unix中要使用dd命令制作启动软盘，然而要注意在不同的Unix下，软驱对应的设 备文件名字是不同的，FreeBSD下为rfd0。


FreeBSD连载(06)：安装FreeBSD

王波

安装FreeBSD

    当准备工作完成之后，安装FreeBSD实际是一个非常简单的过程，简单到将光盘插入计算机启动，回答几个问 题，一切将很快完成。或者将启动软盘放入并启动，输入FreeBSD安装服务器的网址和路径。然而对于初次接触Fre eBSD的使用者，安装过程还可能有些陌生，下面将介绍安装系统和进行基本配置的过程。

  • 启动安装程序

    FreeBSD的安装程序不是DOS或者Windows程序，而是必须在FreeBSD下运行的FreeBSD 程序。如何从一台裸机或者DOS下进入FreeBSD的安装程序，是安装过程的第一步。

    有四种启动FreeBSD安装程序的方法：

  • 从现有FreeBSD中启动安装程序sysinstall，用于系统升级和配置；

  • 从CD-Rom中启动安装程序，要求计算机支持光盘启动；

  • 从DOS分区中启动，要求计算机已经安装有DOS系统；

  • 从启动软盘启动，需要制作一张启动软盘；

    使用启动软盘（boot disk）的方法，使计算机从软盘重新启动，进入FreeBSD系统和安装程序，对 于系统要求最少，并可以从一个裸机上安装FreeBSD系统，因此是比较常用的方式。如果使用了光盘作安装介质，并且 计算机的BIOS支持光盘直接启动，最简单的启动方式是光盘直接启动，这样就不需要制作启动软盘。

    当前大部分计算机的BIOS支持光盘直接启动，这样就只需要在启动时进入系统BIOS的Setup程序，更改 启动顺序为光盘优先，然后存储退出即可。不同的BIOS版本，进入Setup和更改启动顺序的方法不同。对于常用的 AWARD BIOS，在启动系统自检时按Del键进入Setup程序，更改启动顺序为CDROM,A,C，这样就使用 IDE光驱启动，或者设为SCSI,A,C并且设置SCSI控制卡的启动设备ID为光驱ID，来使用SCSI光驱启动 （需要SCSI控制卡支持光驱启动）。

    然而，最标准的启动安装程序的方式还是软盘启动，这就需要按照前面叙述的步骤制作启动软盘，将软盘插入A驱， 并更改启动顺序为软盘优先。这样万一计算机的BIOS不支持光驱启动或者使用了其他种类的安装介质，均能够正常启动安 装进程。

    使用DOS程序fbsdboot.exe，可以可以直接从DOS下启动FreeBSD系统。由于fbsdboot 只能在标准的DOS模式下运行，因此就不能在Windows下执行，因此Windows需要先退出到DOS。并且 某些TSR程序也会影响引导过程。fbsdboot仅仅是一种启动方式，仍然需要其他安装介质，如光盘等，以放置 FreeBSD的安装文件。从DOS下启动FreeBSD除了fbsdboot.exe之外，还需要FreeBSD的某个 内核文件kernel，依赖于这个内核文件，fbsdboot启动FreeBSD系统的安装界面，或者进入系统中已经 安装好的FreeBSD系统。

    E:TOOLS> fbsdboot -D e: oolskernel.inst

    fbsdboot.exe缺省使用c:kernel作为内核文件，如果需要使用其他内核文件，就需要使用- D参数，并指定内核文件的路径。fbsdboot不但能用于进入安装系统，还能够在DOS下启动正常的FreeBSD 系统，这就使得在FreeBSD启动过程出现问题时，仍然能够进入FreeBSD系统。fbsdboot由于是在DOS 下启动的，因此一些硬件的行为就与加电启动时略有不同，因此最好还是通过软盘启动的方式进入FreeBSD系统， fbsdboot只用作一种备份启动方式。

    当使用启动软盘或其他介质启动之后（使用软盘启动时需要根据提示插入第二张root软盘），首先将启动 FreeBSD的bootstrap程序，屏幕将显示一些FreeBSD bootstrap信息，然后安装程序将提示使用 者配置内核参数。这个过程主要用于设置FreeBSD内核中的各个驱动程序使用的资源值，必须将这些资源设置修改为与 具体硬件实际使用的资源值相一致，FreeBSD才能正常检测并使用这些硬件设备。这种可以在系统启动时更改硬件参数 设置的机制称为UserConfig，FreeBSD使用UserConfig提供了更大程度的灵活性。

    Skip kernel configuration and continue with installation
    Start kernel configuration in full-screen visual mode
    Start kernel configuration in CLI mode

    使用者可以使用上下箭头键来在三种不同的方式下进行选择，第一项表示忽略配置过程，这表示使用者计算机硬件的 配置参数与FreeBSD通用内核的缺省配置基本一致，不需要更改内核设置，这是因为一般情况下计算机重要硬件使用的 资源设置都是非常标准的设置。当然使用者也可以选择下面的选项，对资源的设置参数进行更改或确认的操作。其中第二项是 使用比较方便的全屏幕操作方式更改设置参数，这适合一般情况。第三个选项是使用命令行的操作方式更改系统参数，能够用 来设置比较复杂的参数，包括一些在全屏幕方式下无法设置的参数，如ISA PNP卡的资源分配和设置。命令行方式的硬 件资源设置方式只适合对FreeBSD了解较深的使用者。

    FreeBSD的内核（kernel）中包含各种硬件的驱动程序，负责构建操作系统和硬件之间的通道。在启动 之后，系统首先将内核程序装载到内存中，然后由内核负责探测各种硬件。每种硬件驱动程序都将最常使用的资源值作为了它 的缺省配置，在编译的时候写入了内核程序内部，只有通过UserConfig才能进行更改。当使用UserConfi g来更改硬件的资源设置的时候，前面准备过程中记录的硬件配置信息就十分有用了，可以参考这些信息来设置正确的硬件占 用的资源。

    FreeBSD就使用这些最常使用的资源配置做参数去判断系统中是否存在这种硬件，如果探测到了，才使用这些 资源激活这个硬件驱动程序。因此如果硬件的资源设定与FreeBSD核心配置的参数不相符，硬件探测就会失败。这时就 需要更改内核的配置数据与板卡设置相同，才能正确探测到该硬件。

    对于要更改内核的配置参数的情况，一般可以选用第二个选项，使用全屏幕的操作方式进行系统参数的更改工作。

    进入UserConfig的全屏幕界面之后，整个屏幕被分为三个部分。上部为Active Drivers部 分，表示内核中激活的设备驱动程序，这些硬件将在启动时进行检测，中部为Inactive Drivers部分，表示 内核中存在的驱动程序，但却被屏蔽了，因此在启动时就不检测这些硬件。下部是操作提示区域，用于提示操作命令和输入具 体的参数设置。

    Active Drivers中的Conflicts表示在所有要检测硬件的配置中存在多少个资源冲突，由于 不是所有的硬件都存在并真正占用这些资源，因此不必理会这个冲突现象。系统内核按照硬件检测的顺序（这在内核编译时就 已经确定了），如果第一个硬件的确存在，占用了资源，那么其他与它的配置相冲突的硬件就应该不会存在于这个资源上了， 因此就被系统略过而不探测这个硬件了，除非是已经指明可以共享这个资源的硬件。Dev对应的列为驱动程序的名字，IRQ 和Port对应的列为相应的硬件参数。

    Collapsed表示该项表示这是一组相关的硬件，可以将光标移动到这个选项上并使用Enter键打开这组 硬件，显示组内的具体硬件，例如上图中的Network类中就存在两个网络设备ed0和ed1。选择相应的设备之后， 可以使用Delete键将这个硬件移入Inactive Drivers部分（在Inactive Drivers中 选择相应的设备，进行同样的操作可以将其放入Active Drivers中），也可以使用Enter打开硬件的配置 参数，进行更改操作，此时就在下面的第三部分中提示各个硬件参数，如IRQ、port等，并允许用户输入新的设置值。

    在UserConfig中，有些设备，如PCI设备，不能被放入Iactive Drivers部分被屏蔽， 然而这并不影响系统探测。

    将硬件的配置参数进行了重新配置之后，要使用Q键来退出UserConfig，然后内核将会按照新配置侦测硬 件。内核侦测硬件的时候，将探测结果显示到屏幕上。这些信息能够告诉使用者是否配置的硬件被正确的探测到，该硬件占用 的系统资源以及该硬件的其他信息。但是自动探测不可能完全正确，因为很多硬件虽然声称相互兼容，但事实上仍存在细微的 差别。万一出现问题，就要求使用者针对硬件配置参数的差异，在UserConfig中按照计算机的配置修改内核配置。 为了避免问题，可以使用排除法，将自己计算机中不存在的设备都先屏蔽了，以免出现偶然的错误。

  • 硬件探测问题

    使用者的计算机可能配置有很多种硬件，有可能在第一次启动时没有将所有的硬件全部配置正确，这并不是一个重要 的问题，因为有的硬件不影响安装过程，可以在安装好系统以后，再使用UserConfig或重新编译内核来配置硬件参 数。但是有些硬件对于系统安装非常重要，必须被正确探测到，否则就无法继续安装过程，如要安装系统的硬盘驱动器、用于 读取安装光盘的光驱、使用网络安装时的网卡等。这时就需要在启动时进入UserConfig更改内核设置，而从硬件的 文档或者从Windows的控制面板获得的硬件信息就十分重要了。

    编译操作系统内核对于Windows用户也许是不可想象，但对于FreeBSD的使用者来说，是非常普通和标 准的做法。并且编译内核决不是什么难事，FreeBSD提供了十分方便的方法让使用者来定制自己的内核。

    硬盘：不管使用何种安装介质，内核必须将目标硬盘探测出，否则无法继续安装。因此使用者必须清楚自己计算机使 用的是何种硬盘驱动器。由于IDE驱动器使用的资源比较标准，也都使用wd这一种驱动程序，一般都能被正确探测到。而 SCSI驱动器则由于存在不同的标准和制造厂家，使用的驱动程序也各不相同，如果计算机上的SCSI控制卡兼容性不强 ，就有可能出现检测错误。这有可能是厂商设定的资源设置与常用设置不同造成的，就需要用户使用UserConfig重 新配置。为了增加系统检测的速度和减少错误发生的几率，可以在UserConfig中尽量屏蔽不必要的驱动程序，仅留 下正确的驱动并配置了正确的资源。

    CD-Rom：如果安装介质是光盘，则内核必须要探测到光盘驱动器。探测光盘驱动器首先要探测到合适的IDE 或者SCSI控制器，这与探测硬盘要求一致。如果使用的光驱不是IDE或SCSI控制器接口的，而是另外的ATAPI 接口方式，就需要查看通用内核的硬件支持列表，看看内核是否支持这种光驱，并根据相关文档配置内核参数支持这种控制器 。由于这些老式光驱的控制器常常是和声卡作在一起，设置起来比较困难，并且FreeBSD系统也不支持所有种类的老型 号光驱，幸好当前非IDE或SCSI接口的光驱型号已经基本淘汰了。因此最好的解决方法是安装一台新的IDE或SCSI 接口的光盘驱动器。

    IDE光驱可能会发生的另一个安装问题是光驱的主/从问题（Master/Slave），通常在一个IDE控 制器上能串接两个IDE设备，一个要设为主设备，另一个要设为从设备。在仅有一个设备时，将该设备设为从设备是不正确 的，设备不应该正常工作。但是在DOS/Windows下直接使用光驱驱动程序访问光盘，这就使得某些光驱在第二个控 制器上仅接一个IDE光驱，并且光驱也设为从设备时，仍然能够正常工作。但是FreeBSD下不是这样，必须严格按照 主从方式进行设置，否则就不能正确探测到光盘驱动器。此外，光驱出错时也应检查有没有插入光盘，以及光驱是否能够读取 插入的光盘。

    网卡：网卡由于种类繁多，并且厂商彼此存在兼容性问题，因此必须考虑不同类型的网卡在缺省资源设置方面的不同 。某些时候网卡设备会出现设备超时（Device timeout）故障，一个可能的原因是总线接口的网卡没有终结， 另一个原因是硬件IRQ参数配置错误。

    此外还需要为网卡选择正确的驱动程序，当前网络设备的发展快速，而FreeBSD对新型网卡提供支持则需要一 定的时间。例如，3COM 905B型网卡在FreeBSD 2.2.6中还没有提供支持，但到FreeBSD 2. 2.8之后就能很好的支持。因此，必须经常查看FreeBSD支持的硬件列表，以获得对新型硬件的驱动程序。

    配置硬件的另一些问题是避免资源冲突，有些硬件本身设计的就存在问题，不能正确更改其资源设置，此时可以让与 它冲突的其他硬件避开使用相应资源。另外，一些设计得比较糟糕的设备，如果系统对它占用的端口进行了不正当的探测操作 ，就可能造成系统死机。这也是为什么尽量减少要探测的设备，并且不能在所有的资源上对硬件进行地毯式全面探测的原因之 一，因此也不应该随便改动硬件探测的顺序。很多情况下发生这些冲突等问题，常常是因为使用了兼容性不好的硬件或配置了 不太适合的硬件参数造成的。所以使用者应利用自己对系统硬件的了解，减少系统探测的硬件数量和设置正确的资源。

安装系统

    在内核载入内存之后，内核就启动初始化进程init启动系统，系统启动完毕之后就运行安装程序Sysinstall 。Sysinstall是一个位于安装盘上的FreeBSD的执行程序，是一个非常有用的安装和维护工具程序。 即使在系统安装完毕之后，这个程序还可以被用于管理和维护系统。在一个安装好的FreeBSD系统中，这个程序被放在 /stand目录下，就可以使用/stand/sysinstall命令来再次启动这个管理工具。

安装程序Sysinstall

    系统安装时将自动进入sysinstall开始安装系统的过程，在个人计算机的屏幕上（控制台），安装程序表 现为全屏幕的彩色安装菜单，然而也可以在标准字符终端上启动Sysinstall程序，根据字符终端的类型其外观也略 有不同，下图为Sysinstall主菜单。

    这里使用的菜单图片均为3.0-release中的选项，在3.1-release之后，对菜单选项的顺序进 行了调整，以便更适合安装时使用的顺序。不同只在于菜单的顺序，而设置内容则是一样的。

    Sysinstall程序是一个对话框方式的菜单程序，不同于Windows系统中安装程序常用的 “ Wizard” 引导方式的安装形式，菜单形式能提供安装者更大的选择自由，但需要安装者对需要用到的选项有一定的了解。其 主菜单提供了12个选项提供选择，可供安装者进行选择。

    选项 “Usage“ 给出了Sysinstall的使用方法，一般可以使用上 下方向键来选择不同的选项，使用Enter确认，使用Tab在Sysinstall中的不同按钮上切换，而使用 Space键选择或不选择某个检查框选项。

    选项 “Doc“ 给出了在正式安装系统之前浏览安装介质上的文档的机会，当然 安装之前也可以直接查看安装介质中文档。这个选项主要用于对裸机直接进行安装的使用者，或者熟练用户临时查看一些安装 信息时使用的。下图为Doc选项中的可以选择查看的文档内容。

    通过这个菜单中的选项，可以在安装系统时实时阅读安装介质上的README.TXT、HARDWARE.TXT 、INSTALL.TXT、COPYRIGT.TXT、RELNOTES.TXT等文档，以及在安装系统之后，创建 Sysinstall的快捷方式，阅读/usr/share/doc目录下的HTML格式的使用手册和问题解答。对于 裸机安装，阅读相关文档的功能十分有用，但在安装好系统之后就没有必要通过Sysinstall来阅读手册了。

    选项 “Keymap“ 提供了更改键盘规格的机 会，这个选项对于一些欧洲用户比较有用，因为它们使用的是非英文键盘。对于使用101标准键盘或104键标准键盘的使 用者不需要更改。指定一个键盘规格文件之后，可以通过更改这个文件来定制自己的键盘映射方式，指定某些非标准的功能键 。

    选项 “Options“ 提供了更改Sysinstall 本身使用的某些变量的机会，这些变量将由Sysinstall程序使用。这里的一些参数用于确定安装过程的 行为，如NFS的相关参数用于NFS网络安装方式时访问NFS服务器，FTP相关参数用于设置FTP网络安装方式，因 而只有在使用相应的安装过程的时候，才需要根据服务器的设置更改这些选项，一般情况下不必改动。还有一些参数是用于标 识安装过程需要的程序和目录的位置的，例如Packeges Temp参数是用于设置安装和管理Packages的临 时目录。

    上图显示了正在更改Editor的参数，FreeBSD缺省使用/usr/bin/ee做编辑器，这个编辑器 是一个小巧的编辑工具。但很多人更喜欢功能更强的编辑器，那么可以在系统安装完毕之后，修改这个参数，设置为使用 vi或emacs（应该使用完整路径）。而在安装时不应改动这个配置，因为安装软盘中只是一个小系统，没有提供足够的应用 程序。此外还可以设置浏览器等其他应用程序的位置，这些设置都是在系统安装之后，用于维护系统时使用的。

    可供选择的安装方式有 “Novice“ , “Express “ 和 “Custom“ 三种不同的安装方式。Novice方式适合初 次安装FreeBSD的使用者使用，它引导安装者按照安装过程的每一步进行安装，并且每一个步骤都使用对话框进行操作 提示，类似于一个安装引导程序。Express方式与Novice使用同样的安装流程，但省略了提示，因此较为快捷， 适合熟练的安装者。而Custom方式没有引导过程，而是提供一个菜单，安装者可以不按照次序来处理安装过程的每个步 骤，这样就提供了更多的选择机会。三种方式只是安装步骤方面的不同，而并无实质上的差别，每种安装方式均要进行以下几 步操作：

  • 硬盘分区

  • 设置文件系统和交换分区

  • 选择安装组件和安装介质

  • 安装系统

  • 系统初始设置

    在Novice和Express方式中，将顺序进行以上的步骤，而Custom方式则列出对应以上每项工作的 菜单，每完成一步都返回这个菜单等待安装者的下一步指示。这样安装者能按照自己的需要，安排进行相关操作，因此就有更 大的自由度，但如果不熟悉安装程序的话，也许会遗漏一些必需的操作步骤。因此，一般情况下可以选择Novice选项， 由sysinstall安排每一步的任务。

    主菜单的 “Fixit“ 选项将启动一个应急处理命令行界面，处理安装过程中 出现的问题。

    启动应急处理界面需要一个Fixit光盘或软盘，Walnet Creek正式发行光盘中的第二张为Fixit 光盘，或者可以在现有DOS或FreeBSD系统下从安装介质上制作Fixit软盘，它的磁盘镜象文件为resume.flp 。当然Fixit软盘上提供的处理、诊断工具没有光盘上丰富。这个选项将提示安装者插入Fixit盘。然后 使用第三个选项将在第四个虚拟控制台上启动一个应急交互Shell程序，进行各种系统操作（使用Alt-F4可以切换 到这个虚拟控制台上）。如果没有Fixit盘，选择第三项也可以启动应急界面，但是由于没有Fixit盘上的应用程序 ，基本上无法进行操作，完成修复系统的任务。

    菜单选项 “Upgrade“ ，用于系统升级时使用，这个升级过程将使用安装 介质上的二进制文件覆盖原有系统上的文件。由于升级过程有可能破坏原有的FreeBSD系统，因此系统将提示安装者进 行确认。尤其对于从2.2.x向3.x升级，由于应用程序的格式从a.out转向了ELF，因此升级还要保证兼容问题 。相比较而言，使用源代码进行升级的方式更为安全和有效。

    主菜单中的 “Configure“ 选项，用于对FreeBSD系统进行基本 配置，这是Sysinstall中非常有用的一部分。通常Unix进行系统设置需要执行各种命令和修改配置文件，而 Sysinstall在这里能提供了一个设置系统参数的友好界面。在这里就能完成设置一个能够正常运行的FreeBSD 基本系统的操作，当然更复杂的设置还是要通过修改配置文件来完成的。

    如果使用Novice或Express安装方式，将引导安装者进行这个Configure菜单中的各项必需的 配置任务，如果使用Custom方式进行安装，就需要手工执行这个选项中的各个功能。在FreeBSD正常运行之后， 也能使用这个选项来维护系统、更改系统配置。

    假如安装过程中更改了安装选项（Options），但想恢复缺省状态，或者打算使用某个定制的安装选项，就可 以使用主菜单中的 “Load Config” 选项，从软盘中载入安装选项。对于大量 安装同样配置的FreeBSD系统有一定的帮助。

    主菜单的最后一个选项为 “Index” ，选择这个菜单项将弹出一个子菜单， 子菜单中按照字母顺序列出了Sysinstall中的所有的功能。这个菜单项在系统安装时并没有实际的用处，但在系统 安装之后使用sysinstall管理和维护系统时就非常有用。系统管理员不必一级一级寻找某个功能在Sysinstall 多级菜单中的位置，而能依据其名字迅速找到所需要的功能。

安装过程

    无论安装者使用何种安装方式，所需进行的安装步骤是相同的，对于新手来讲，还是应该选择Novice安装方式 ，以免遗漏需要执行的安装步骤。需要注意的是Novice方式中执行过程不能向后回溯，因而没有更正失误的机会。必须 保证每个步骤都执行正确，否则就需要重新执行整个步骤。选择好安装方式之后，Sysinstall将引导安装者一步步 进行每个步骤的安装任务。

  • 硬盘分区

        安装过程的第一步就是要指定将FreeBSD安装到何处，FreeBSD需要占用一个单独的基本分区。因此就 需要进入Fdisk对硬盘进行分区处理，这个工具中可以完成维护硬盘分区的各项操作，包 括指定活动分区，增加和删除分区等功能。

        如果计算机中有多个硬盘存在，Sysinstall中的Fdisk程序将首先询问安装者要处理的哪个硬盘，使 用空格键选中所有需要进行处理的硬盘，然后使用Enter确认，就能依次对各个硬盘进行分区操作。注意，如果要将系统 安装到非启动硬盘上（例如wd1），那么也需要在系统的启动硬盘（wd0）上安装启动管理软件Boot Manager （或其他种类启动管理软件，只是那些软件需要独立的安装过程），否则无法启动非启动硬盘上的系统。

        在Fdisk中显示的前两行为它报告的硬盘信息，包括硬盘的名字，以及柱面、磁头和扇区等硬盘参数。柱面、磁 头和扇区参数对于在一个硬盘上划分多个分区的情况下非常重要，因为系统启动程序要依赖计算机的BIOS来找到FreeBSD 分区。因此必须保证Fdisk中的这些数据和BIOS中的数据一致，以使Fdisk划分出的分区被BIOS识别 。缺省情况下，FreeBSD是直接从硬盘驱动器上探测这些硬盘参数的，因此当BIOS重新映射硬盘参数时，就有可能 使FreeBSD探测的真实参数与BIOS的映射参数不一致。

        在硬盘上已经有分区存在的情况下，Fdisk可以从已有分区中找到硬盘参数，将硬盘参数更改为与划分已有分区 时使用的硬盘参数相一致，以避免它划分的分区与已有分区冲突。这就是要迫使FreeBSD使用BIOS的映射参数，就 可以预先划分一个硬盘分区的原因。例如本例中非空硬盘wd1的硬盘数据为782柱面，128磁头，63扇区，实际是经 过BIOS使用LBA方式映射过的数据，Fdisk从已有的DOS分区中检测到。

        虽然重新映射硬盘参数，无论对于FreeBSD或BIOS，都不会影响数据的存储，但是使用硬盘的真实参数能 避开不同计算机BIOS的不一致性。当硬盘仅用于FreeBSD系统而不需要划分分区时，就可以保持硬盘参数不作任何 更改。因此只有对于空硬盘并希望在安装FreeBSD以后还要安装DOS分区的情况，才需要检查硬盘数据，当发现映射 信息与BIOS不一致时，就需要使用G（Set BIOS Geometry）命令重新设置。

        即使安装了FreeBSD系统之后，当更改了BIOS中的硬盘映射方式的时候，同样也可能发生系统启动程序不 能找到FreeBSD分区，载入FreeBSD系统的情况。

        硬盘信息下面的第二部分是各个分区的列表，每个分区包括它的起始位置（Offset），大小（Size），结 束位置（End），分区的名字，类型，描述，子类型和标志等信息。其中分区中的第一项虽然标记为unused，也不能 为其他分区所占用，因为这是系统主引导区（MBR）占据的空间，虽然主引导区只有一个扇区，然而按照分区习惯，每个分 区必须从一个柱面的起始扇区开始，因此就会在引导区之后留下一些未使用的扇区。但这些空余空间可以被FreeBSD的 启动管理程序Boot Manager或其他类似的启动管理程序所使用。

        分区工具的下部为可使用的命令提示。如果只打算安装启动管理程序Boot Manager而不打算对硬盘进行 分区处理，可以直接使用Q键退出。如果要将整个硬盘都用作FreeBSD使用，可以使用A（Use Entire Disk ）就可以将整个硬盘留给FreeBSD。当要将FreeBSD和其他操作系统共享硬盘时，就要具体使用不同的命 令来划分分区了。

        命令C（Create Partition）在未使用的空间上创建分区（首先将光标移动到非使用的磁盘空间上 ），此后需要输入这个分区的大小，和UFS分区类型165，以划分出FreeBSD使用的UFS类型的分区。如果要创 建其他系统使用的分区，需要输入其他类型号，如DOS使用的类型为6。在上面的例子中已经存在两个分区，一个基本 DOS分区和一个扩展分区（第一个部分为系统主引导区），最后剩余的未使用空间太小，已经不足以建立分区了，因此就需要先 删除已有分区（D, Delete Slice），或改变原有分区类型（T, Change Type）的命令，直接 将硬盘上已有的分区改变为UFS类型，分配给FreeBSD使用。

        当存在多个的分区时，可以使用S（Set Bootable）设置哪个分区是启动分区，用来告诉标准主引导程 序启动该分区内操作系统，对于使用多操作系统引导管理程序的时候，如FreeBSD带的Boot Manager，就 不需要进行这个设置。一般如果在安装FreeBSD之前已经安装了DOS/Windows系统的情况下，启动分区是 DOS的基本分区。

        在确信完成所有的分区操作，并没有任何错误之后，才能使用W（Write Changes）来将改变真正写入 硬盘分区表，否则使用U（Undo All Changes），恢复到操作之前的状态。然后可以使用Q来退出分区工具 。分区工具接下来将询问这个硬盘使用的启动引导方式，即如何启动这个硬盘上的FreeBSD或其他操作系统。

        当安装启动选项的时候，对于每个硬盘都有三个选择。第一种BootMgr是使用FreeBSD的Boot Manager 作为多操作系统启动管理程序，来选择启动不同磁盘及不同分区上的多个操作系统。系统将在启动时提示使用者 使用功能键F1、F2等来启动对应分区的操作系统，Boot Manager将被安装到磁盘的主引导区及其后的自由空 间内，对硬盘分区没有影响。可以在每个硬盘上都安装Boot Manager，这样就能从第一个磁盘上启动其他磁盘上 的Boot Manager，然后再启动该非启动硬盘上的操作系统。安装Boot Manager，是在一台计算机上 管理多个操作系统的很好选择，是将FreeBSD安装到非启动硬盘上的一种有效的启动方式。

        第二种选择为Standard，即使用标准的主引导区启动系统，这种方法由主引导区引导程序将控制权交给位于 启动分区开始位置上的操作系统引导程序，然后再载入操作系统。因此这要求启动分区必须设置正确，需要在前面的操作中要 将FreeBSD分区设置为启动分区。选择此项就将主引导区恢复为标准主引导区，相当于DOS下的fdisk /mbr命令。

        第三种None方式是不改变主引导区，也不安装任何系统引导程序。当使用其他种类的操作系统引导软件时，如 Linux LILO，避免更改主引导区而使得那些操作系统引导程序不能正常运行。因为此时主引导区被其他引导程序使用 ，不需要改变。而此时引导FreeBSD的任务就交给了其他引导软件。

        因为安装程序要更改主引导区，因此需要在BIOS中将主板中用于防病毒的主引导区写保护功能关掉。

        当要在一台计算机使用多个操作系统时，确定系统引导的方式是一个复杂的情况，因为这与要使用的其他操作系统有 关，一般情况下都可以使用FreeBSD的Boot Manager对多操作系统进行管理。但也可以使用Linux LILO、Windows NT OS Loader、OS/2 Boot Manager来管理多操作系统。但是在 多操作系统的条件下，每个操作系统中的一些操作都会重写主引导区，从而造成引导程序出现问题。尤其DOS/Windows 系统，每次重新安装都会不加任何提示重写主引导区，将引导程序恢复为标准引导程序。

  • 创建文件系统和交换空间

    在硬盘分区之后，安装者将进入FreeBSD风格的文件系统管理工具Disklabel，用于管理文件系统和交换空间。这个工具将对UFS分区进行操作，将它们分割为不同的文件系统上或用作交换空间的部分。

        Disklabel整个屏幕也划分为三部分，上部显示要进行处理硬盘及和UFS分区，本例中为wd1和wd1s1 ，中部为文件系统和交换空间的列表，下部为使用到的各个命令。对于大多数情况时，wd1s1中还没有文件系统和交 换空间存在的条件下，可以让disklabel来决定各个文件系统和交换空间的大小，这仅需要使用A（Auto Defaults for all）命令即可。如果已经有划分好的部分存在，可先使用D命令删除。即使安装者打算自己确定 各个部分的大小，使用A来看看Disklabel的缺省设置情况也能起到参考作用。

        手工使用C（Create）命令分割磁盘时，首先决定是创建交换空间或文件系统。FreeBSD系统需要使用 交换空间来提供比实际内存更大的虚拟内存空间，这样系统就能支持更多、更复杂的进程。交换空间的大小要根据具体需求而 定，有些程序，如X11,GNU C++等，需要大量的内存，因此要配置较多的交换空间，一般交换空间不应小于系统的 物理内存，用作服务器的系统需要更多的交换空间，但过多的交换空间又没有必要。可根据系统在最高负载下用户和同时运行 进程的多少，在物理内存的1-2.5倍范围内调整交换分区的大小。

        在多个磁盘的情况下，可在不同的磁盘中设置多个交换空间，以均衡磁盘的负载。然而对于IDE接口的硬盘，在同 一根电缆上连接的主从硬盘上分布交换空间没有意义，因为同一个驱动器上的两个硬盘不能并发存取。交换空间也应该尽量设 置在高速硬盘上，如Ultra SCSI接口的硬盘，以提高系统的性能。

        对于用于文件系统的子分区，除了设定大小之外，还要设定它在文件系统中的安装位置，即将其安装到目录树的哪个 位置上。虽然原则上仅使用一个安装到根目录的完整文件系统就能满足系统要求，但是由于文件系统中不同目录将用于不同目 的，将其划分为不同部分，分别安装到目录树上，更有利于管理、维护，也增强了万一系统崩溃时，减低数据丢失的可能性。 这是由于不同的子分区在物理上相互分隔，一个子分区写满或出现问题不影响其他文件系统上的内容。例如根目录所在的文件 系统很少需要进行写操作，那么系统崩溃就不会影响这个文件系统中的系统数据，或者当某个进程产生了非常巨大的数据文件 时，这个数据文件只能填满某个子分区，而不致于影响其他需要存取系统中其他分区的重要系统进程。因此，由于对于用作服 务器的FreeBSD系统，应该使用多个文件系统以提升系统可靠性。

        通常应将文件系统划分为 “/” 文件系统， “/usr” 文件系统， “/var” 文件系统。 “/” 文件系统中只保留系统内核及其他非常重要的文件，当系统进入单用户模式也只安装这个文件系统，一般需要30-40M空 间。 “/usr” 文件系统放置系统日常使用的文件，应该尽量大，甚至还会在这个目录之下再安装新的文件系统。 “ /var” 文件系统用于系统运行时的数据文件，根据不同系统的情形，所需要的大小也不一样，用户和提供的服务越多， 越需要 “/var” 空间。

        如果要自己手工调整缺省设置，就要求安装者处理进行分割分区空间的全部细节。使用Create命令来完成创建 每个子分区的任务，首先需要设置划分的子分区的大小，可以直接输入扇区数（512字节为单位）或更容易理解的用MB为 单位（在数字之后加上MB单位），此后设置该子分区是用作文件系统（UFS类型）还是交换空间（Swap类型），如果 要该分区用做文件系统，则系统会接着问该文件系统的安装（Mount）位置。

        在升级系统或其他情况下，硬盘或分区系统中已经有FreeBSD子分区存在，但这些子分区的安装位置信息已经 丢失。此时可以使用M（Mount Pt），将现存子分区按照原来的安装状态，设置它的安装目录。此时可以使用T（Newfs Toggle），在对不对该子分区进行格式化（Newfs）的选项上进行转换，设置为不进行格式化就能保留 上面的原有数据。

        当分区完成以后，使用W（Write）确认设置，使用Q（Finish）退出disklabel系统，然后就 可以向选定的分区上安装操作系统软件本身了。

  • 选择安装组件

        由于操作系统本身由不同的部分组成，不同的使用者可以根据自己的需要进行选择，因此，安装程序将显示出一个 Distributions 选择菜单，提示不同种类的使用者选择自己需要的系统组件。

        对于一个完整的系统，所有的这些内容都十分有用。如果不是为了节约硬盘空间的原因，应该选择All全部安装。 但全部安装就需要相当多的磁盘空间，一般情况下为了节约磁盘空间，可以选择不同的安装选项。但即使要安装一个精简的 FreeBSD系统，仍然建议安装内核源代码，这样才能按照机器的具体硬件来定制一个更高效的内核。因此至少应该选择 Kern-Developer选项，此外也可以选择多个部分，例如同时选择Kern-Developer和X-User ，或者使用定制方式（Custom），使组件的选择更为灵活。

        当选择了Custom之后，则Sysintall将显示出所有可选择安装组件的详细列表，供安装者选择需要的 组件。

        在Custom菜单下，可以逐项选择要安装的组件，为了方便起见，可以在上一级菜单中先选择好某类组件，然后 再在这里略加修改。

        注意，由于DES算法受美国法律的出口限制，需要进行审批，因此FreeBSD缺省使用的加密算法为MD5算 法。DES算法只在某些特定的软件中是必须的，例如当使用NIS与其他使用DES算法的计算机共享口令文件时。

        如果需要安装DES组件，可以选择DES组件，名义上这个组件不是直接从美国出口，而是来自欧洲或其他非北美 地方的，从形式上避免这个问题。此后的安装过程中FreeBSD还会使用一个对话框警告安装者，可以简单确认即可。

        FreeBSD还将询问是否安装Ports Collection的源码，Ports Collection 是用于帮助用户编译、安装、维护应用程序的一个非常有效的工具。它是FreeBSD系统的一部分，是FreeBSD的 诸多开发者将应用软件移植到FreeBSD上的努力，比起预编译好的Packages，它更为灵活。因此最好安装Po rts Collection，以方便以后定制应用软件。

        如果要想使用图形界面，就应该选用的XFree86相关的安装组件。由于XFree86也是由多个部分组成， 也可以选择各个部分进行安装，以节约磁盘空间。

        XFree86中包括基本组件Basic，不同的X Server组件，字体组件。一般情况下应该进入各个组 件内部，在缺省设置的基础上修改选择的内容。Basic菜单下的设置一般不必改动，在Fonts菜单下可以选择增加中 文字体。最重要的选择是Server菜单中的选项，应该选择适合自己显示设备的X Server。

        在X Server的选择菜单中，除了选择自己显示卡对应的X Server以外，还应该选择VGA16的X Server，这用于运行XFree86的设置程序XF86Setup。如果不能十分确定自己显示卡的类型，应该多选 择几种X Server，等设置X Windows时再确定哪个X Server适合自己的显示设备。

        当选择好Basic、Fonts和Servers中的选项之后，就可以使用Exit菜单退出这个菜单选项，进 入真正的复制系统的安装过程。

    安装系统文件

        在安装程序Sysinstall正式复制系统文件之前，安装程序将询问安装介质位于何处。

        最常用的方式是使用CDROM进行安装，这时不需要额外的配置。进行网络安装（NFS或两种ftp方式），则 要求首先配置网络界面、远程服务器的IP地址及安装文件所在的目录。从DOS分区下安装要输入安装文件所在的DOS目 录名，从现存文件系统下安装可以允许从已经安装的目录下（可以是NFS、UFS、MSDOS或CD9660系统）进行 安装，此时需要先使用Fixit盘启动应急界面，预先安装上相应的安装介质。软盘和磁带安装方式也不需额外的配置。

        这个菜单内还有一个Options选项，可以启动Sysinstall主菜单中Options菜单，主要用于 设置使用NFS和FTP时候的相关连接选项，以便安装能顺利进行。当完成安装介质的确认之后，就开始拷贝文件的安装过 程了。

        由于系统中有多个虚拟控制台，在安装程序的拷贝过程中，可以使用Alt-F2切换到第二个虚拟控制台上观察 sysinstall程序的输出信息，使用Alt-F4切换到第四个虚拟控制台上，这里启动了一个shell，可以接受 安装者的输入指令，这使安装者可以在必要的时候，干预安装过程或处理可能的问题（缺省情况下没有任何命令可供安装者执 行，必须在安装系统之前使用Fixit光盘或软盘，才能提供可执行的命令）。正常情况下并不需要这些额外的工作，使用 Alt-F1回到sysinstall安装界面，等上约20分钟（具体时间将依赖具体机器的硬件和选择的安装组件）， 基本系统将安装完毕。


FreeBSD连载(07)：基本系统配置

王波

基本系统配置

    在系统软件复制到硬盘上之后，安装只能是完成了一半，还需要继续使用Sysinstall进一步配置系统环境 。如果使用Novice 或Express 安装方式，配 置过程将连续进行，执行主菜单Configure 选项下的每个配置功能。如果是 Custom 方式，就需要安装者自己选择Configure 菜单，然后分别选择子菜单，如Console、Network、TimeZone等进行配置。
  • 设置网络
        需要配置的第一个重要部分是网络，在FreeBSD中网络功能的地位非常重要。通过Sysinstall下的 Network配置，可以配置网络的基本设置内容，如IP、域名、缺省网关等，也可以设置基本的网络应用，如Free BSD是否用作NFS Client、NFS Server、匿名ftp服务器，以及是否启动路由交换软件route d或gated等等。使用Sysinstall就能设置一个正常运行的网络客户计算机，并能对FreeBSD系统提供 的几种基本网络服务进行设置，非常简便和直观。如果使用Custom方式，就需要手工选 择Configure菜单，执行Interface等子菜单中的设置。
    • 设置网络界面
        如果安装方式是NFS或ftp等网络安装方式，这一步应该在选择安装方式之后就需要进行设置，否则无法完成复 制系统文件的过程。
        设置网络界面时首先要选择进行设置的网络界面，FreeBSD将列出内核探测出所有的网络界面，包括网卡、串 口和并口等网络界面。一般这里只对网卡对应的网络界面进行设置，对应于并口、串口的网络界面常常需要较复杂的设置过程 ，需要在启动系统之后在额外设置。本例中系统有一个3C905B的网卡，网络界面名字为xl0。
        对选定的网络界面xl0，可以配置主机名、域名网关、名字服务器、IP地址和子网掩码等基本的网络设置。配置 好这个界面之后，不需要重新启动系统就可以立即使其发挥作用，从而使得在安装过程中就可以连接到网络上。 Sysinstall弹出下面对话框提示安装者启动这个网络界面：
        然后在该对话框中选择Yes，使xl0这个网卡以前面设置的内容正常运行。
    • 基本网络服务
        配置好网络界面之后，还可以配置这台FreeBSD提供的基本网络服务功能，如Ftp服务、NFS服务、是否 支持NIS、是否运行路由交换软件等。需要根据计算机实际要求的功能，设置相应的选项。加入使用者对这些选项不是很清 楚，可以忽略这个步骤，因为这些设置选项可以在任意时候重新设置，没有必要一定在初始安装的时候将全部设置都设置的无 可挑剔。FreeBSD的可伸缩性使得，可以在任意时候改动系统设置，不需要重新启动系统就能使得改动生效。
    • 定制控制台
        此外，安装程序也将帮助安装者正确设置其他的一些设置选项。比如可以进行控制台的一些配置。可以配置控制台上 使用的字体，键盘的映射方式，键盘的重复率，字符模式的屏幕保护和屏幕映射等。
        字体设置中，可以选择安装自己喜爱的字体，常用的字体为8x16大小，如果选择了安装8x8（或8x14）的 控制台字体，以后可以通过手工设置，使控制台的显示模式更丰富，例如可以设置为132列、60行的显示模式。
        键盘的映射方式只有在使用非标准键盘时才有用，一般欧洲用户需要更改这个设置，使用标准101/102/10 4键盘的使用者，不需要改动。但明确选择一个键盘映射文件也有好处，比如重新定义一些功能键的位置等。
        键盘重复率也能根据用户的具体要求而定，系统也提供了几种不同字符模式屏幕保护程序，如黑屏、BSD吉祥物等 以供选择，还可以定制不同的屏幕组织方式。Screenmap则用于指定绘制字符界面的窗口时使用的特殊伪图象字符， 这主要由于其他字体的伪图象字符与标准VGA字体的伪图象字符不同。这用于改变了字体设置的时候。
    • 时间和时区
        由于FreeBSD是一种网络操作系统，需要频繁和其他计算机打交道，正确的时间对于网络上计算机互相通信来 讲非常重要，因此必须设置的时区信息。
        此时系统将询问，当前计算机CMOS中的时间是按照标准格林威士时间进行设置的，还是按照本地时间来设置的。 习惯上在BIOS设置时，是将COMS时钟按照本地时间进行设置，因此一般选择No。如果选择错误也没有关系，只要在 设置完好再重新修改系统时间就可以了，但是会影响系统中共存的其他操作系统的时间。
        然后就能按照洲、国家和地区选择时区，我国大多数地区应选择China coast。
    • 控制台鼠标设置
        FreeBSD也提供在控制台中使用鼠标的能力，能用鼠标器在控制台上进行复制/粘贴工作，并提供了一个伪鼠 标接口sysmouse，其他需要使用鼠标的程序，如X，就能配置为使用这个逻辑设备而不必关心真实的鼠标类型，使得 设置X Window更为简易。这个配置程序对鼠标进行设置简单且方便。
        鼠标类型Type可以选择鼠标的真实类型，或者简单使用Auto让FreeBSD自动检测，然后选择鼠标端口 Port，这个端口设置必须正确，对串口鼠标必须指定具体的串口，其他种类鼠标使用相应的鼠标端口等。然后就使用 Enable来激活moused守护进程，如果鼠标指针移动正常，说明设置正确。那么以后系统都在启动时就自动启动mou sed守护进程，在控制台的文本状态下进行鼠标操作。
    • 其他设置
        如果安装了X组件，安装程序还会提示用户设置X Window图形界面，然而X Window的设置是另一项 复杂的任务，将在后面章节中单独进行介绍。
        还需要做的工作包括为root用户设置口令，以保证系统的安全性，进行添加用户和组等基本的系统管理。使用 sysinstall添加用户和组非常简单直观，当然操作步骤麻烦一些，但全屏幕操作方式就存在这个问题。
        如果这台计算机连接到了Internet上，并在前面配置好了网络界面，此时就可以登记到FreeBSD的用 户群体中。
        由于FreeBSD是一个免费操作系统，登记只是为了FreeBSD用户之间，用户和开发者之间加强联系的一 种方式。而且FreeBSD用户一般不选择商业性的服务和技术支持，而是通过用户之间、与系统开发者之间相互联系、相 互支持的自支持方式来提供技术支持。实践证明，通过Internet得到技术支持是最有效的方式。
        如果安装者使用的是Novice或Express 安装方式，安装程序还会提示安装者安装安装介质上提供的软件包，熟练用户可以按需要选择安装不同的应用程序进行。由于 这个步骤可以在系统运行的任何时候使用sysinstall程序进行，第一次安装系统时也可以略过这个步骤。
        在所有的步骤完成之后，就能够重新启动系统，此时，一个完整的FreeBSD系统就将展现在使用者的面前了。


FreeBSD连载(08)：其他安装问题

王波

其他安装问题

    安装系统是一个复杂的过程，原因之一就是个人计算机硬件种类繁多，可组合的方式也是多种多样，因此就会引起复 杂的安装问题。

  • 网络安装方式

    除了使用安装光盘来安装FreeBSD之外，还有其他几种安装介质可供选择，其中网络安装方式同样也是一种非 常方便的安装方式。

    如果使用者是直接连接到Internet上的，就不需要安装光盘，而只需要制作启动软盘（磁盘镜象文件同样可 以通过Internet下载），然后使用启动软盘就可以直接从Internet上安装FreeBSD系统，因此如果使 用者的本地网络与Internet有稳定且快速连接的时候，也可以选择网络安装方式。

    网络安装方式包括ftp、ftp passive、和NFS方式，需要根据安装服务器提供的服务方式来选择网 络安装方式。通常NFS方式更适合本地连接，用户自己设定的安装服务器才提供NFS安装服务（或者本地FreeBSD 爱好者之间也会相互共享资源），面向Internet的公共服务器通常提供更可靠的ftp服务，因此ftp安装方式更 为常见。而ftp安装方式和ftp passive安装方式的区别是ftp passive方式在下载文件时使用ft p的passive模式，以克服大多数防火墙对端口的限制，因此如果要安装的系统不是直接与Internet相连，而 通过防火墙连接到Internet，就需要使用ftp passive安装方式。

    使用网络安装方式时的一个重要问题是必须配置好网络界面，因此Sysinstall将在选择好安装介质之后、 选择安装组件之前，就提示用户配置网络界面。由于Sysinstall设置的网络界面为永久连接型的网络接口，如网卡 ，而另一些网络界面为要求预先连接的网络接口，如拨号连接的ppp0界面，不能直接通过Sysinstall设置，因 此不适合使用网络安装方式。

    上面为ftp安装方式的菜单，除了提供Internet上的多个现有FreeBSD的ftp安装站点之外，还 可以选择手工输入URL（第二项），由用户输入一个距离最近的安装服务器的ftp站点。这个站点可以由用户自己维护， 使得在一个网络中安装多台系统更为简易。

    如果网络连接比较慢，直接使用网络安装方式会由于网络速度的原因而造成安装过程不能正常进行。那么就可以先将 FreeBSD安装文件下载到本地硬盘上，再选择DOS安装介质或预先安装好的文件系统作安装介质，进行安装。

    当使用DOS基本分区作安装介质时，需要按照安装文件的原有目录结构，将安装文件复制到DOS分区中根目录下 的FreeBSD目录中。安装光盘tools目录中的setup.exe工具，能在DOS下用于使用安装光盘来设置D OS安装介质。这种情况一般只用于系统光驱型号太老，不为FreeBSD识别，或者要安装的系统没有光驱或网卡，因而 必须预先将安装文件拷贝到它的硬盘上。

    选择了这种安装方式，安装程序将询问FreeBSD安装文件位于哪个DOS分区中。

    无论安装系统是放置在DOS基本分区，还是以前安装好的FreeBSD分区中、光盘上，或者是放置在网络上的 NFS服务器上，都可以使用手工方式预先将这些文件系统安装到系统的目录树上，再选择File System安装介质 选项进行安装。当然这需要首先打开一个应急Shell进行操作。通常这种方式主要用于安装好系统之后的系统维护，而在 初始安装时用到的较少。

    此外，也可以使用软盘或磁带做安装介质，但实际使用中较为少见。

  • 升级系统

    可以在安装程序的主菜单中选择Upgrade方式进行系统升级。系统升级的好处是可以保留以前系统中的各种设 置，以及用户的配置信息和数据文件。然而，这种使用安装程序的升级方式并不是最佳的升级方法，因为FreeBSD是一 种极具活力的操作系统，而光盘等传统媒体的安装介质是静态的，使用这种方式升级系统并不能得到最新的系统。另一个原因 是FreeBSD的源代码是公开的，使用源代码进行升级也十分方便，并且发生危险丢失数据的风险更小。

  • 手工安装系统组件

    FreeBSD的安装软件由不同的组件组成，例如bin、manpages等。这些组件通常被分割为较小的文 件，以便它能被保存到软盘上，也能减少从网络下载时的可能会出现的网络故障。

    由于系统被分为不同的组件，很可能在系统安装过程中遗漏了某种非常有用的组件，或者由于偶然的原因，被某些组 件被破坏了。此时就需要在安装系统之后，再来安装这些组件。这可以使用安装程序/stand/sysinstall来 完成，然而手工进行安装这些组件却更为方便。

$ ls /cdrom/bin

CHECKSUM.MD5 bin.ao    bin.be    bin.bu    bin.ck

TRANS.TBL    bin.ap    bin.bf    bin.bv    bin.cl

bin.aa       bin.aq    bin.bg    bin.bw    bin.cm

bin.ab       bin.ar    bin.bh    bin.bx    bin.cn

bin.ac       bin.as    bin.bi    bin.by    bin.co

bin.ad       bin.at    bin.bj    bin.bz    bin.cp

bin.ae       bin.au    bin.bk    bin.ca    bin.cq

bin.af       bin.av    bin.bl    bin.cb    bin.cr

bin.ag       bin.aw    bin.bm    bin.cc    bin.cs

bin.ah       bin.ax    bin.bn    bin.cd    bin.ct

bin.ai       bin.ay    bin.bo    bin.ce    bin.inf

bin.aj       bin.az    bin.bp    bin.cf    bin.mtree

bin.ak       bin.ba    bin.bq    bin.cg    install.sh

bin.al       bin.bb    bin.br    bin.ch

bin.am       bin.bc    bin.bs    bin.ci

bin.an       bin.bd    bin.bt    bin.cj

    这些以bin开头，以两个字母为后缀的文件事实上是对一个使用tar和gzip打包压缩后的大文件进行分割得 到的，因此可以使用gzip和tar进行解开，并安装到合适的位置。这个目录中也提供了一个脚本程序install. sh，能自动进行这一步工作。如果使用者想手工重新安装某一组件，可以运行相应目录下的install.sh脚本程序 。例如，如果在初始安装时没有安装manpages组件（或者该组件被无意中破坏了），想要重新安装manpages 组件，可以运行：

    # /cdrom/manpages/install.sh

    注意：由于这样做会覆盖原有系统中的文件，主要是更改过的系统设置文件，因此这样安装某些系统相关的组件（例 如bin组件）就非常危险！除非必要，不要重新安装bin组件（包括使用Sysinstall程序）！

    以MD5为后缀的CHECKSUM.MD5是根据这些文件生成的校验文件，用于检查这些文件是否在传输过程中 出现错误。可以在一个安装好的FreeBSD系统下使用md5命令来生成文件的校验，与这个文件中保存的数据进行比较 ，如果校验数据一致，就说明文件没有在传输过程中出现问题。

    还有的组件，如X Free86组件没有被分割为小文件保存，是几个tar和gzip处理过的压缩文件，该目 录下同样提供了脚本程序install.sh，以便来进行安装。ports目录下的组件Ports Collecti on也是一个单独的压缩包。

  • 使用其他启动引导程序

    在个人计算机上安装FreeBSD系统，常常会遇到与其他操作系统共存的问题，一般情况下使用FreeBSD 的Boot Manager来管理多个操作系统。但在某些情况下使用者可能希望使用其他种类的引导程序，无论使用哪个 操作系统引导程序，都需要这些引导程序相互协作，而不发生冲突现象。

    对于同时使用FreeBSD与Linux共存的个人计算机，在使用FreeBSD Boot Manager 引导时，需要将Linux的引导程序LILO放在其自己分区的最前端（Super Block），而不能放到主引导区 中。FreeBSD Boot Manager可以直接启动Linux分区上的LILO程序。但如果使用者是将Lin ux安装在扩展分区上的逻辑分区上，（这是一种很糟糕的分区设置方式，极度增加了系统的不安全性，至少不应该将根文件 系统放置在逻辑分区上），就必须使用Linux LILO引导。因此就需要在FreeBSD安装时，安装BootMa nger选择None，而将LILO安装到主引导区，通过在Linux中编辑lilo.conf文件对FreeBSD 分区进行设置，更新LILO后，就可以通过LILO启动FreeBSD分区。建议使用Boot Manager来启动 Linux，因为Boot Manager不需要进行配置，使用起来最简单和方便。

    对于同时使用Windows NT的系统，如果使用FreeBSD Boot Manager引导，那么在F reeBSD Boot Manager的选择之后，会再有Windows NT的OS Loader的选择菜单，从 而需要进行两次选择。因此也可以使用Windows NT OS loader来引导FreeBSD系统，此时不能安 装Boot Manager，而应使用标准主引导区，此外，还需要FreeBSD基本分区的第一个扇区，以便OS L oader能用来启动FreeBSD。首先将激活分区设置为FreeBSD分区启动FreeBSD系统，使用dd命令 将FreeBSD分区的第一个扇区写到一个文件中（假设FreeBSD安装到了第三分区wd0s3中）

    # dd if=/dev/rwd0s3 of=bootsect.bsd bs=512

    然后将这个命名为bootsect.bsd的文件拷贝到NT启动分区的根目录中，如果NT启动分区（假设为第 一个分区wd0s1）为FAT文件系统，则可以在FreeBSD下拷贝。

    # mount -t msdos /dev/wd0s1 /mnt

    # cp bootsect.bsd /mnt/bootsect.bsd

    然后编辑C盘根目录下的boot.ini，增加一项c:\bootsect.bsd="FreeBSD"，然 后将启动分区更改为DOS的启动分区，则系统重起之后，在OS loader的启动菜单中就增加了一项启动FreeB SD的选择。

    注意，系统升级会导致第一个扇区的内容改变，因此需要及时更新启动扇区文件。


FreeBSD连载(09)：系统启动过程

王波

第3章 系统管理和维护

    当使用安装程序Sysinstall完成了系统安装和基本配置任务之后，系统需要重新启动。在系统从硬盘上重 新启动之后，一个完好的FreeBSD系统就展现在使用者面前了。系统将出现登录提示，允许使用者登录进入FreeB SD操作系统。

    Unix是一种多用户、多任务的操作系统，它支持并能管理多个用户使用系统，其用户分为普通用户和管理员两类 。普通用户只能使用系统提供的具体应用功能，而只有管理员才能更改系统的配置、维护整个系统。FreeBSD系统的拥 有者不但是仅仅使用系统的普通用户，同样也是整个系统的管理员，要负责系统维护的任务。

    Unix下系统维护的任务具有相当大的伸缩性，按照不同的系统的要求，可以非常简单，仅仅使用系统初始提供的 管理策略即可，也能是一种相当复杂的任务，对访问的客户进行更严格、更全面的限制。无论如何，FreeBSD的使用和 维护都是一件富有挑战性的任务。

  • 系统的启动与关闭

    不象个人计算机上的其他几种操作系统，FreeBSD被设计为一种可以永久运行的系统，正常情况下不需要也不 应该频繁的启动和关闭。然而，FreeBSD的启动过程从计算机系统自检到载入FreeBSD系统内核，其中经过了几 个不同的阶段，这些阶段的操作都涉及到系统维护，因此相当重要，需要系统管理员加以了解。同样，由于FreeBSD是 一个多用户系统，在后台运行着相当多对系统而言非常重要的进程，系统关闭时就需要首先关闭这些进程，因而FreeBS D的关闭过程也必须按照一定的要求来操作，否则就会对系统造成破坏。

  • 系统启动过程

        普通个人计算机的启动过程相当简单，首先是系统BIOS自检，自检之后将载入启动硬盘上的主引导区，由主引导 区上的引导程序再载入具体操作系统。标准的主引导区将按照启动分区的设置，引导该分区上的操作系统，FreeBSD也 可以使用这种方式。但更常见的引导FreeBSD的方式，是使用FreeBSD Boot Manager，来管理和 负责引导包括FreeBSD在内的多个操作系统。

    • 多操作系统引导程序

        按照计算机启动硬盘第一个扇区的系统主引导程序的不同，计算机有不同的启动过程。FreeBSD最常使用 FreeBSD Boot Manager，它可以让使用者在系统中共存的不同操作系统进行选择。

        如果使用了Boot Manager用于多操作系统的引导，则系统自检后首先进入Boot Manager的 引导界面。

        F1: FreeBSD

        F2: Dos

        F5: Disk 2

        Default F1

        Boot Manager使用计算机的功能键来启动各个分区的操作系统，使用F1将启动第一个分区wd0s1 上的操作系统，F2启动wd0s2，F3对应wd0s3，等等，F5启动另一个硬盘上主引导区的引导程序。这样可以在 第二个磁盘上也安装Boot Manager，由它来引导自己硬盘上各分区的操作系统。只有在分区的确存在的情况下， Boot Manager才显示相应的启动热键，并从分区的类型判断它是那种操作系统。在使用者选择了某个选项，或者 经过了一定的延迟时间之后，Boot Manager就启动FreeBSD系统。

        使用Boot Manager作多操作系统引导需要注意的是：一旦在这台计算机中重新安装Dos/Windo ws系统，则主引导区就被重写，需要重新安装BootManager。

        当不想使用Boot Manager引导系统，而打算回到标准引导区的方式（不再需要引导多操作系统）时，可 以使用DOS程序fdisk.exe来恢复主引导区的内容。也可以使用FreeBSD的sysinstall程序来重 新安装标准主引导区。

        A:> fdisk /mbr

        但是，Boot Manager仍然使用BIOS调用来获得分区上的数据，由于BIOS只能访问硬盘1024 柱面内的分区，因此FreeBSD的引导分区必须在1024柱面以内才能正常启动系统。新的BIOS中使用LBA等方 式对硬盘数据进行了重新映射，来避免这个问题。然而就需注意不能随意更改BIOS中的硬盘映射方式不可随便更改，必须 与硬盘进行分区时的设置一致，否则BIOS就不能正确找到以前设置的分区。

    • boot loader

        无论是标准引导程序，还是FreeBSD Boot Manager，都将载入FreeBSD基本分区的第一 个扇区，这里放置着FreeBSD的启动程序Boot Block，它将载入FreeBSD文件系统中的boot l oader程序，不需进行任何操作，boot loader程序将引导系统内核来启动系统。但在这个过程中也可以中断 自动启动进程，进入交互模式，从而更改启动内核、进行硬件设置、甚至提供了选择不同的boot loader程序的机 会。

        FreeBSD 3.1-release中更新了系统的boot loader程序，这个新boot loa der程序与FreeBSD 2.2.x和3.0版本使用的boot loader不同，升级的原因之一是老版本的b oot loader不能启动ELF格式的内核,此外新版本的boot loader功能更强大。因此老版本的boo t loader的行为与下面描述的不同。

        通常没有必要改变Boot Loader，如果要更改使用的Boot Loader程序，就要在启动屏幕最先 印出一个简单的斜线 “/” 时，在几秒时间内按下空格键，否则启动过程将略过这个步骤，直接进入下一步。如果按下空 格，则系统将出现boot提示符。

        /

        >>FreeBSD/i386 BOOT

        Default: 0:wd(0,a)/boot/loader

        boot:

        此时输入 “?” ，可以列出对应的硬盘分区中根目录下的所有文件。这时可以在boot提示符下输入另一个b oot loader程序，启动该boot loader程序，也可以直接输入某个内核文件名，从而略过boot l oader而直接启动相应的内核。然而，通过boot loader能完成更多的任务，包括进行硬件资源设置。

        此时也可以列出、选择不同的硬盘分区上的不同启动文件，正如之前的提示信息，0:wd(0,a)用于一个包含 FreeBSD根文件系统的子分区，其中第一个0为硬盘控制器的序号，而wd(0,a)为硬盘分区wd0a，根据硬盘 分区情况，这对应第一个UFS分区上的根文件系统。而后面可以跟随目录和文件名，以及可以使用？来列出目录下的文件， 当然选择启动内核的任务可以在boot loader内部中更好的完成，一般情况下不需要进入这个阶段改变boot loader程序。

        此后系统将进入Boot Loader程序中，由Boot Loader将内核/kernel和内核模块载入 内存，接着Boot Loader就等待10秒间隔，在这个时间内可以让用户按下了除回车之外的其他任意键，进入Bo ot Loader的交互模式。

        /

        BTX loader 1.00 BTX version is 1.01

        Console: internal video/keyboard

        BIOS drive A: is disk0

        BIOS drive C: is disk1

        BIOS drive D: is disk2

        FreeBSD/i386 bootstrap loader, Revision 0.5 638/64512kB

        (wb@email.online.ha.cn, Web Mar 3 02:54:38 CST 1999)

        /kernel text=0x1697f2 data=0x168d0+0x1f17c syms=[0x4+0x1eb70+0x4+0x2014a]

        /modules/splash_bmp.ko text=0x1025 data=0xc+0x634 syms=[0x4+0x400+0x4+0x213]

        Hit [Enter] to boot immediately, or any other key for command prompt.

        Booting [kernel] in 8 seconds...

        Type ‘?’ for a list of commands, ‘help’ for more detiled help.

        disk1s3a:>

        新的Boot Loader使用BIOS的硬盘表示顺序，没有区分SCSI硬盘da和IDE硬盘wd，而直接 使用disk0、disk1、disk2按BIOS中的顺序表示硬盘。本例中的提示符为disk1s3a，由于本例中 使用的硬盘为IDE接口，因此这实际就代表wd1s3a分区。

        在boot loader提示符下有很多相当有用的命令，例如使用ls命令可以列出disk1s3a中各级目 录下的文件，使用lsdev可以列出当前内核中的设备驱动，使用lsmod可以列出已经载入的内核模块，使用load 可以载入另外的需要载入的内核模块，使用autoboot可以在给定时间之后启动系统，而使用boot命令可以立即启 动系统内核，或者使用pnpscan命令扫描当前系统中的PNP卡。一般boot命令比较常用，例如使用 “boot -s” 命令，将启动系统并进入单用户模式，在这个模式下可以执行系统维护任务。通常由于只有可以信任的管理人员才能 访问控制台，因此缺省状况下进入单用户模式不需要使用口令认证。

        在boot命令之后使用其他内核名字作参数，用来使用缺省内核/kernel之外的其他内核来启动系统。每个 FreeBSD系统都至少具备一个备用的通用内核kernel.GENERIC，在当前系统内核被破坏的情况下可以使 用它来启动系统。因此在引导程序被破坏而系统完好的情况下（通常是由于重新安装了Windows的原因），可以使用安 装软盘或光盘启动，进入Boot Loader的交互模式，选择硬盘上的内核启动，然后进行修复而不需要重新安装。当 在boot loader提示符下使用 “boot -c” 命令，在其后的启动过程中将进入UserConfig中 ，用于对内核中的硬件资源参数进行配置。与系统初始安装时进入UserConfig的方式不同，这将直接进入User Config的命令行模式，内核将出现UserConfig的提示符：

        config>

        此时可以使用help命令查询可以使用的UserConfig命令，如果输入visual指令，表示使用vi sual方式配置系统硬件，则会进入UserConfig的全屏幕界面，否则就使用这个命令行方式进行硬件参数配置。 命令行模式中可以使用ls命令列出不同的设备驱动程序，使用irq、drq、iomem等命令查看硬件的相应资源设置 。

        命令行模式比全屏幕界面更强大的地方是能够对ISA PNP设备进行控制，这是通过pnp命令进行的。当IS A PNP卡由BIOS分配资源的时候，内核能以非PNP的驱动去探测它，这也是为何要在BIOS中关闭相关的PNP 选项的原因。但如果在编译内核支持了PNP控制器，也可以在BIOS中设置为由OS（即FreeBSD）来管理硬件资 源，这就需要使用pnp命令手工为ISA PNP硬件分配资源，以便非PNP的驱动能检测并正确设置资源。但是手工设 置要求对PNP卡硬件相当了解，否则还是让BIOS来完成资源的分配更为适合。

        当退出UserConfig之后，或者在boot loader的交互模式下执行了boot命令，或者在bo ot loader提示进入交互模式的时候10秒钟内没有任何输入，则boot loader就会载入内核，并自动将 控制权交给已经载入的FreeBSD内核程序，由内核探测计算机中的各个硬件，并将探测结果打印到屏幕上。使用键盘右 上角的Pause键可以暂停屏幕输出，并可以使用Page Up，Page Down键上下滚动屏幕上的信息进行查看 ，最后再使用一次Pause键将打开屏幕输出，继续系统启动过程。内核的启动信息也可以在登录系统之后使用dmesg 命令查看。

        FreeBSD 3.0以前的FreeBSD版本使用的Boot Loader为一个较老的版本，因此提示信 息与命令输入方式也略有不同，但基本实现同样的功能，旧Boot Loader程序的提示符直接就为 “boot:” ，可以直接输入 “-s” 、 “-c” 等参数进入单用户模式或进入UserConfig。启动时boot loa der都会在屏幕上打印提示信息，解释了基本用法和具体参数对应的含义。

        FreeBSD 3.1之后可以设定系统启动标志图象（如同Windows9x的启动标志），那么内核的探测 信息就不会显示在屏幕上，而是被这个启动图象遮住。


FreeBSD连载(10)：系统启动脚本

王波

系统启动脚本

    内核探测过系统硬件之后，就启动进程0和进程1，进程0用于清除内存，将所有的内存单元置零，进程1为init 进程，将负责启动系统和各种守护进程。init将系统带入多用户状态，并按照/etc/rc启动脚本启动服务程序。

    /etc/rc启动脚本将完成很多非常重要的工作，包括设置磁盘交换、检查磁盘错误、设置网络界面，启动网络 服务程序等非常重要的工作。/etc/rc文件将也将执行另外的rc文件，如执行rc.conf用于大部分系统参数的 设置，rc.network用于网络设置，rc.firewall用于设置防火墙，以及rc.local，用于管理员 对本机特定的启动设置等。其中rc.conf文件中包含了用户能够更改的很多设置参数，这些设置参数在其他rc文件中 使用，用于配置系统的参数，因此对系统管理来讲最为重要。

    由于大部分服务器程序都是网络程序，因此如果系统的网络设置不正确，这些服务程序将不能正常执行（例如 sendmail）。而且有些程序的超时设置的很长，因此出现错误时会出现系统停留在某个程序上不再继续执行。一般可以不必 理会，等待程序超时退出即可，或者可以尝试使用Ctrl-C中断该程序。如果启动脚本真的出现无法继续执行的错误，如 果能够通过网络登录，可以先登录进系统再更改启动脚本,而大部分正在执行启动脚本的情况下，网络服务并没有启动，那么 就必须重新启动系统进入单用户状态，再修改启动脚本来纠正错误。

    #! /bin/sh

    swapfile="NO" # Set to name of swapfile if aux swapfile desired.

    apm_enable="NO" # Set to YES if you want APMenabled.

    pccard_enable="NO" # Set to YES if you want to configure PCCARD devices.

    pccard_mem="DEFAULT" # If pccard_enable=YES, this is card memory address.

    pccard_ifconfig="NO" # Specialized pccard ethernet configuration (or NO).

    local_startup="/usr/local/etc/rc.d /usr/X11R6/etc/rc.d" # startup script dirs.

    上面是/etc/rc.conf的部分内容，可以看出参数的设置形式，相应的设置值都给出了提示，使得更改这 些参数设置非常容易。rc.onf中的大部分设置可以通过/stand/sysinstall系统安装程序来进行设置 ，但也有部分参数不能通过sysinstall进行设置，必须通过手工修改这个文件来完成。按照FreeBSD的习惯 ，这些rc文件，rc.conf用于参数配置，可以由sysinstall安装程序和管理员更改，rc.local中 定义这台计算机特定的启动命令，可以由管理员重新设置，而其他rc文件应该保留不变。这只是一种习惯做法，而非硬性规 定，然而遵从习惯的好处是系统设置比较清晰，便于系统维护和管理，并且当管理员进入一个新系统中，能立即找到需要的配 置文件。

    在版本3.1-release之前，/etc/rc.conf中包括了所有参数设定，这样在系统长期运行之后 ，就无法区分哪个参数为缺省值，哪个参数为管理员更改过的值。在3.1-release中，rc.conf划分为两个 文件，/etc/default/rc.conf和/etc/rc.conf，其中/etc/default/rc. conf是设置各个参数的系统缺省值，而/etc/rc.conf仅仅设置本地系统在安装和运行过程中更改的参数，例 如hostname等，因此3.1-release之后的/etc/rc.conf文件中的内容较少。事实上 /etc/default/rc.conf中不但设置了读取/etc/rc.conf文件中的设置，还包括读取 /etc/rc.conf.local文件的设置，以适应更复杂的计算机设置情况。对于一般的情况，用不到那么复杂的设置文件，仅仅 注意/etc/rc.conf中的设置就满足设置要求了。

    BSD Unix传统上只使用rc.local来维护本机特定的启动命令，这样如果系统在启动时需要配置的内 容过多，这个文件就会变得相当庞大，不利于系统维护。Unix System V风格的系统使用启动目录而非文件来维 护启动命令，每个启动一个特定功能的设置被放入一个单独脚本中，然后将所有的脚本都放入启动目录中，系统启动时逐项检 查这个目录中的执行脚本，自动执行这些命令。

    System V和BSD的启动管理有很大不同，System V引入了启动级别的概念，可以有6种不同的启 动级别，而BSD只简单的分为多用户状态、单用户状态和停机状态3种。在启动的管理方面，System V比BSD更 友好一些。

    因此FreeBSD吸取System V中的启动目录的思想，在rc.conf中定义了本计算机的系统启动文 件存放的目录local_startup参数，缺省使用/usr/local/etc/rc.d目录存放服务器程序的 启动脚本，使用/usr/X11R6/etc/rc.d目录存放本地X Window相关的程序启动脚本。这些目录中 的以sh结尾并具备执行属性的shell脚本程序将在启动时被自动执行。这两个目录中的脚本程序也是由系统管理员设置 和修改的，必须以 “.sh” 结尾，其他后缀的文件将被忽略。习惯上这两个目录里的脚本程序负责启动服务器程序，而 rc.local主要用于调整系统的一些非标准参数设置（rc.conf中没有涉及的设置）。


FreeBSD连载(11)：系统登录与退出

作者：王波

系统登录与退出

    系统执行完rc启动脚本之后，FreeBSD将读取/etc/ttys文件，按照配置启动多个虚拟控制台，在 控制台上启动登录进程login，以接受用户登录。使用者可以使用Alt-F1、Alt-F2和Alt-F3等功能键 在不同的控制台之间进行切换。缺省条件下有4个虚拟控制台（其中第四个没有提供登录服务），最多到有12个虚拟控制台 （受标准PC的12个功能键的限制）。

    系统在控制台上印出login提示，此时可以使用root用户和安装时设置的root口令登录系统。

    FreeBSD/i386 wb.online.ha.cn (ttyv0)

    login: root

    Password:

    用户通过口令认证之后，系统将/etc/motd中的内容显示到屏幕上，这个文件中通常放置系统管理员想通知 每个用户的通告内容，从而通知正在登录的用户有关信息。然后login程序启动用户的登录shell，由登录shell 执行/etc/profile为用户设置好使用环境。

    当登录到系统之后，用户就能输入各种命令，以使用FreeBSD系统处理各项任务。

    当工作完成之后，可以使用logout命令退出当前会话。使用exit，或使用键Ctrl-D（^D），都能 结束当前会话，退出登录过程。

    # logout

  • 关闭系统

    由于FreeBSD是多任务系统，同时有多个进程在运行，并且使用了磁盘缓冲技术以提供更佳的系统效率，因此 使用直接关闭电源的方法关闭计算机会对系统造成破坏。在非正常关机之后的再次启动过程中，系统将侦测到上次没有正确关 闭系统，并自动运行硬盘检查程序fsck（由rc文件启动），来检查并修复硬盘的错误。

    关机需要在以root身份登录进入系统之后，使用shutdown命令来进行关闭系统，需要使用-h参数，表 示halt，停机操作：

    # shutdown -h now

    Feb 4 12:18:26 wb shutdown: halt by root:

    Feb 4 12:18:29 wb syslogd: exiting on signal 15

    syncing disks... done

    The operating system has halted.

    Please press any key to reboot.

    一些情况下，如更新了系统内核时，要重新启动系统。则应使用-r参数，表示reboot，重新启动系统：

    # shutdown -r now

    如果没有使用-h或-r参数，shutdown命令将试图进入单用户状态，这与在启动时在boot loader 中下输入boot -s命令进入单用户模式略有差别，由于在多用户状态时系统中有多个进程运行，当进入单用户状态 时可能有些进程不能正常退出，同时文件系统的状态也有差别。

    而参数now为一个时间参数， “now” 表示立即执行shutdown操作。由于FreeBSD是多用户 系统，在执行shutdown时会有其他用户通过网络使用这个系统，正常情况下应该延迟一端时间再执行shutdown 操作，给那些正在连接的用户一定的时间用于保存数据并退出系统，就需要使用其他时间参数来启动shutdown。例 如：下面命令将使系统在2分钟后停机，同时也将向正在登录的用户发送广播信息，将后面参数中的信息通知当前登录的各个 用户：

    # shutdown -h +2 “Hi guys! please logout”

    时间参数除了这种增量形式，也可以使用不用”+”号的绝对形式来表示，那么时间参数就为hhmm的格式，如 0120表示1:20等。

    在系统还没有停机或重起的时间间隔内，shutdown将产生/etc/nologin文件，而系统中的 login程序将检查是否存在这个文件，当发现存在这个文件时就阻止非root用户登录系统。正常情况下shutdown 执行真正的停机或重起操作时会删除这个文件，如果这个文件因为某些原因而没有被删除，那么系统login进程将不允许 普通用户登录。

    用于立即启动和停机的命令还有reboot和halt，相当于使用-r或-h参数的shutdown指令。因 为这是立即执行的命令，没有提供警告登录用户的功能。由于命令相对简单，因此单人使用的系统中可以很方便的使用。

    如果使用者没有使用root登录进系统，但是可以接触到控制台，那么仍然可以正常关机而不破坏系统。使用者可 以使用Ctrl-Alt-Del热键重起计算机，就在计算机进入BIOS自检时，再关闭计算机的电源。这种方法在系统 屏蔽了Ctrl-Alt-Del热键的启动能力之后就不再有效。

    在重新定制内核时使用 “options SC_DISABLE_REBOOT” 可以屏蔽系统控制台 的热启动功能。


FreeBSD连载(12)：用户管理-增加用户

作者： 王波

用户管理

    为了使用多用户的FreeBSD操作系统，必须是系统的登记用户。用户信息保存在/etc目录下passwd 文件中，在这个文件中定义的一个FreeBSD用户应具有以下属性：

    用户名（Username）：在系统中使用这个用户名来标识用户，每个用户名不超过8个字符， 且是大小写敏感的。习惯上用户名只使用小写字母，通常根据用户真实名字的缩写来选择合适的用户名。

    用户标识号（User ID）：由于计算机中处理数字比处理字符串更容易，因而使用数字方式的 用户标识号来区分不同用户更为适合。事实上Unix系统就是使用唯一的用户标识号来区分用户的，在某些特定目的下，可 以存在多个有不同用户名、但用户标识号相同的用户，这表示这些不同用户名的用户实际上是同一个用户。

    口令（password）：系统用它来验证用户是否合法。超级用户root可以使用系统程序 passwd来更改每个用户的口令，用户也可以使用passwd来更改自己的口令。较老的Unix系统中直接在 passwd文件中保存口令的密文，由于passwd文件是系统中的每个用户都可以读取的，只通过加密来保证口令的安全性。然 而现代计算机的发展使得情形发生了变化，高速计算能力使得通过猜测的方式来破译口令成为可能。因此现在Unix中口令 均不再直接保存在passwd文件中了，而passwd文件中的口令域使用一个 “*” 来代替。FreeBSD使用 /etc/master.passwd作为真正的口令文件，保存包括个人口令在内的数据，但这个文件不能被普通用户读 取。

    命令解释程序（shell）：用户登录后启动这个程序来接收用户的输入并执行输入相应命令，标 准的shell有sh和csh，更复杂易用的shell有bash和tcsh等，但它们不是基本系统的一部分，必须额 外安装。shell程序是一个标准的Unix程序，但系统在/etc/shells文件中定义了一些标准shell的 名字，很多应用程序检查这个文件中内容和用户的shell来判断这个用户是普通用户，还是用于特定目的而创建的用户。

    个人目录（home directory）：由于FreeBSD是多用户系统，每个用户都要有 自己的独立使用环境，不同用户的文件不能相互交叉存放，因此Unix中为每个用户配置了自己的个人目录，用户的文件都 放置在各自的目录下，从而互不干扰。习惯上FreeBSD下用户的个人目录位于/home目录下，使用用户名作为子目 录名，多数shell中使用波浪符号~，来代表该用户的个人目录。

    组标识号（Group ID）：具有相似属性的多个用户可以被分配到一个组内，每个组都有自己 的组名，且以自己的组标识号相区分（组标识号和组的对应关系在/etc/group文件中给出），用户的组标识号保存 在passwd文件中。早期的Unix中，每个用户只能属于一个组，而现代Unix中每个用户可以同时属于多个组，除 了在passwd文件中指定了其归属的基本组之外，还可以在文件/etc/group中，明确指定一个组包括某个用户 ，使得该用户能属于多个组。

    除此之外，用户还有其他属性，例如登录类别，这些信息记录在另一个口令文件：/etc/master.passwd中。

  • 增加用户

    虽然可以使用系统安装程序/stand/sysinstall中的Add User选项来增加用户和组，但熟 练的管理员并不喜欢这种全屏幕操作方式。Unix下的习惯做法是使用命令行方式，如使用adduser命令来或pw命 令添加用户。

    adduser命令使用配置文件/etc/adduser.conf来保存添加用户使用的缺省数据，如果没有 这个配置文件，第一次执行adduser时会询问缺省设置，以自动生成这个设置文件。这样对于很多基本一致的用户数据 就设置了正确的缺省值，以减少输入的工作量。

    # adduser

    Use option ``-silent'' if you don't want see all warnings & questions.

    Check /etc/shells

    Check /etc/master.passwd

    Check /etc/group

    Enter your default shell: bash csh date no sh [sh]:

    Your default shell is: sh -> /bin/sh

    Enter your default HOME partition: [/home]:

    Copy dotfiles from: /usr/share/skel no [/usr/share/skel]:

    Send message from file: /etc/adduser.message no

    [/etc/adduser.message]:

    Use passwords (y/n) [y]:

    Ok, let's go.

    在前面的过程中生成了配置文件之后，还可以使用编辑器来修改它的内容以更改adduser的配置。虽然生成了 配置文件，但每次启动adduser还会询问这些缺省参数是否需要更改，使得操作不太简便。为了让adduser直接 进入用户数据输入状态，可以使用 “adduser -quiet” 减少提示信息，-quiet的缩写方式为-q， -silent和-s参数也有同样的效果。更一劳永逸的方式是直接修改adduser.conf文件，将其中的 verbose参数改为0，表示尽量减少提示。这个参数的缺省值为1，将进行设置缺省值的提示，而设置为2能提供更多的配置 参数。

    # adduser -s

    Use option ``-verbose'' if you want see more warnings & questions

    or try to repair bugs.

    Enter username [a-z0-9_-]: user22

    Enter full name []:

    Enter shell bash csh date no sh [sh]:

    Enter home directory (full path) [/home/user22]:

    Uid [1007]:

    Enter login class: default []:

    Login group user22 [user22]:

    Login group is ``user22''. Invite user22 into othergroups: guest no

    [no]:

    Enter password []:

    Use an empty password? (y/n) [y]:

    Name: user22

    Password: ****

    Fullname: user22

    Uid: 1007

    Gid: 1007 (user22)

    Class:

    Groups: user22

    HOME: /home/user22

    Shell: /bin/sh

    OK? (y/n) [y]:

    Added user ``user22''

    Send message to ``user22'' and: no root second_mail_address

    [no]:

    your account ``user22'' was created.

    Have fun!

    See also chpass(1), finger(1), passwd(1)

    Add anything to default message (y/n) [n]:

    Send message (y/n) [y]:

    Add another user? (y/n) [y]:n

    因此可以使用-s参数使adduser直接进入增加用户的操作步骤，这将询问增加用户的必要数据，包括用户名 、口令等数据。adduser将使用adduser.conf中的一些内容作为缺省提示，通常有提示的步骤可以直接利 用缺省提示进行操作。

    比adduser命令功能更复杂的命令为pw，管理员能使用它来完成各种复杂的用户管理任务，包括增加、删除 用户，以及修改用户的各项参数设置。

    另一种更直接的管理用户的方式是直接编辑口令文件的内容。这是Unix早期常见的做法，但随着Unix的发展 ，当前的Unix使用shadow的方法保存加密口令数据，用户数据不仅保存在passwd文件中，而真实的口令等内 容被系统保存在另一个口令文件中，必须同时修改这两个口令文件，使其保持一致才可以。因此不能直接使用vi等编辑器来 编辑一个/etc/passwd文件，而应该使用系统提供的vipw命令修改这口令文件，并同时写入两个文件。出于安 全的考虑，vipw将使用一个内部编辑器（与vi相同）编辑master.passwd文件，保存时同步这两个口令文 件。事实上master.passwd文件才是真正的口令文件，单独改变/etc/passwd文件，对用户数据没有 影响。

    由于系统中会反复读取用户口令，而在普通文本形式的passwd文件中查找用户的速度与用户数量是一种线性关 系，当用户数量一多，查找效率就急剧下降。而数据库的形式更适合这些经常发生的查找任务，因为数据库将自动维护数据的 索引，这些索引可以用来提高查找效率。FreeBSD中提供了一种简单的的标准数据库文件格式，口令文件可以使用这种 db数据格式来提高性能。因此口令文件有对应的数据库形式：/etc/pwd.db和/etc/spwd.db，用来 获得用户信息的系统调用事实上首先查询这两个数据库文件，而由系统来自动维护这两个数据库文件与前两个passwd文 件同步。系统管理者可以使用pwd_mkdb来从文本形式的口令文件来生成数据库文件。通常，普通文本形式的passwd 文件只适合于有几百帐号的系统，而db数据库形式适合一万以上帐号的系统。

    在其他Unix系统中，第二个口令文件的名字与bsd系统使用的文件名不同，大部分Unix System V 系统使用/etc/shadow文件。使用不同的名字只是习惯的问题，文件格式都是passwd文件格式。因此如果 要求兼容，可以为/etc/master.passwd建立一个叫shadow的符号连接。

    组能帮助权限的分配，与管理用户类似，管理组也可以通过sysinstall来完成，或直接改动/etc/group 文件。用户除了属于passwd文件中定义的组之外，还可以被邀请进入其他组中。adduser添加用户时会 询问是否将用户加入其他组，如果在用户生成之后在将用户加入其他组，就需要直接改动/etc/group文件。例如 group文件中有这样一行：

    wheel:*:0:root,admin

    admin:*:100:admin

    这表示用户admin不但属于自己在passwd中规定的组，还属于wheel和admin组。可以使用groups 命令来获得用户的属组列表。


FreeBSD连载(13)：超级用户root、登录类别

作者：王波

  • 超级用户root

    超级用户是Unix的所有者，拥有所有的权利，因此也具有很大的危险性，不当使用超级用户权力能对系统造成不 可挽回的破坏。即使对于个人使用的FreeBSD系统，尽管不需要将系统与其他人共享，但是仍然不要使用root用户 作日常处理工作。通常管理员在正常情况下仅仅使用普通帐户进行操作，只有在执行系统管理的必要时候才使用超级用户权限 。

    从普通用户成为超级用户的标准方法是使用su命令：

    $ su

    Password:

    #

    正确输入root的口令之后，就成为了超级用户，系统提示符也从标准的 “$” 变为root专用的 “#” 提示。

    在FreeBSD上要使用su命令成为root用户，不但要知道root的口令，还需要经过特别设置，否则就 不能成功使用这个命令。这是因为FreeBSD对执行su命令的用户进行了更严格的限制，能使用su命令的用户必须属 于wheel组（root的基本属组，组ID为0），否则就不能通过这个命令成为root用户。因此需要编辑组设置文 件/etc/group，将需要超级用户权力的管理成员加入到wheel组中。

    如果仅仅要用户执行部分需要超级用户权力的操作，而不想将root的口令泄露出去，更简单的做法是使用sudo ，然而这属于基本系统之外，需要另外安装的管理工具。

  • 登录类别

    从 4.3 BSD Net/2开始，BSD Unix引入了登录类别这种分类机制来管理用户使用的资源、记 账和环境设置。FreeBSD系统使用/etc/login.conf中描述的数据来将用户按照登录环境、强制性的资 源限制以及记账管理等分为不同的登录类别，每个用户的登录类别记录在/etc/master.passwd中的该用户 的设置中。

    default:\

    :cputime=infinity:\

    :datasize-cur=64M:\

    :stacksize-cur=64M:\

    :memorylocked-cur=10M:\

    :memoryuse-cur=100M:\

    :filesize=infinity:\

    :coredumpsize=infinity:\

    :maxproc-cur=64:\

    :openfiles-cur=64:\

    :priority=0:\

    :requirehome@:\

    :umask=022:\

    :tc=auth-defaults:

    上面设置了default登录类别中的几个参数，如果没有在master.passwd文件中明确指定用户的 登录类别，就使用这个缺省类别来作为用户的登录类别。

    cputime设置了用户的每个进程可以使用的CPU时间，缺省是无限制（infinity）。如果加以限制 ，有些需要大量CPU时间进行运算的进程就不能正常执行到结束。

    datasize-cur设置了用户使用的数据段最大为64M，但-cur设置不是强制的，用户实际使用的数 据有可能超过这个值，但最大不能超过datasize-max设置的值（缺省没有设置）。如果没有-cur和-max 后缀，仅仅定义datasize，则表示datasize-cur和datasize-max同样都为datasize 设置的值。同样stacksize定义了对栈的限制。

    memorylocked-cur设置了用户每进程可以锁定的最大内存。

    memoryuse-cur设置了每进程使用的最大内存。

    filesize-cur设置了用户产生的文件大小。

    coredumpsize设置了在应用程序发生问题时产生的core dump文件的大小。

    maxproc-cur设置了用户可以同时执行的最大进程数。

    openfiles-cur设置了每进程最多打开的文件数。

    priority设置用户进程的优先级。

    requirehome设置用户登录时是否需要主目录，@符号表示不需要主目录。

    umask项设置缺省的umask，用于用户创建文件的属性。

    tc设置系统认证策略为使用缺省的认证策略。

    如果要创建新类别，并不需要对每个值都重新设置，系统缺省先应用default类别的设置，然后再应用具体类 别的设置，因此只需要设置与default类别不同的项就可以了。

    users:\

    :manpath=/usr/share/man /usr/X11R6/man /usr/local/man:\

    :cputime=4h:\

    :openfiles=32:\

    :maxproc=48:\

    :tc=default:

    上面是设置了一个新类users，可以看出它为用户设置了环境变量MANPATH，并重置了cputtime 、openfile、maxproc和tc的值。每次更改login.conf之后，都要进行更新登录类别数据库的操 作。

    # cap_mkdb /etc/login.conf

    由于登录类别保存在master.passwd文件中，通常在使用adduser添加用户的时候设置用户的登 录类别。如果要进行更改，必须使用vipw来修改/etc/master.passwd文件的第5个域。下面为master.passwd 中的一行，该行指定这个用户的登录类别为user:

    wb:FPRKMMNuZ3Pfk:1001:1001:users:0:0:Wang Bo:/home/wb:/bin/sh


FreeBSD连载(14)：shell设置

王波

shell设置

    命令解释程序shell是与用户关系最密切的应用程序，用户主要通过shell使用系统。在每次登录系统之后 ，就启动了一个与用户交互的shell，这个shell将给出一个提示符等待用户输入，（sh为 “$” ，csh为 “%” ，如果是使用root用户，登录提示符将是 “#” ），然后对用户的输入进行解释执行。

    FreeBSD的基本系统中可以使用的shell有两个：sh和csh。这两个基本shell的风格不太相同 ，不同的使用者常常会根据喜好来在两者之间进行选择。当然当前有更好的shell程序可供使用者选择，这些后续的 shell均是根据sh或csh的风格进一步发展出的，因此可以说在shell中，也有两种风格，需要使用者根据自己的使 用习惯进行选择。

    对于管理员来将，要为使用不同shell的用户都设置好基本的环境，就必须了解这两种风格的shell设置方 式。系统登录时，sh将首先执行/etc/profile文件，为每个用户设置最基本的环境，而csh将使用 /etc/csh.cshrc，csh.login和csh.logout作为系统csh资源文件。执行了系统级别的登录文件 之后，每个用户的shell就在该用户的主目录下寻找该用户个人的资源文件：sh使用.profile文件，csh使 用.login和.cshrc文件。这些资源文件均使用相应的shell语言，/etc/profile和个人目录下 的.profile使用sh风格的控制语言，/etc/cshrc和个人目录下的.login、.cshrc使用csh 风格的控制语言。系统管理员可以改动这些资源文件，为用户提供一个最方便的使用环境。当然，系统管理员没有必要直接 去修改个人主目录下的资源文件，这些文件应该由用户自己管理，但是系统管理员可以在生成帐号时为用户产生缺省的资源文 件，以减轻用户设置资源文件的麻烦。adduser命令缺省使用/usr/share/skel下的文件为用户提供各 种资源文件的缺省设置，这个目录下除了可以放入shell的资源文件之外，还可以放入其他应用程序的资源文件。由于这 些资源文件都是以点开头的隐藏文件，为了表示清楚，在skel目录下使用了一种转换方式，如使用dot.profile 作为.profile的模板。

    # ls /usr/share/skel

    dot.cshrc dot.mail_aliases dot.rhosts

    dot.login dot.mailrc dot.shrc

    dot.login_conf dot.profile

    在/usr/share/skel中为用户设置的缺省配置文件，在用户生成之后，就不会对用户产生影响了。因 此对系统登录文件进行修改更有效和直接。对于sh风格的用户，可以更改/etc/profile文件，对csh应更改 /etc/csh.cshrc文件。在这些文件中可以改动shell使用的环境变量，这样来改变shell的行为方式 ，或者执行一系列自动操作，完成一些用户登录时需要自动执行的任务。

常用的环境变量：

EDITOR | 设置用户常用的编辑器，很多程序查看这个变量来启动具体的编辑器，可以 根据系统的情况更改
HOME | 用户的主目录的名字，这个变量由login程序设置，一般不需要更改
DISPLAYX | 使用这个环境变量来标识具体的显示位置，格式为“计算机名字：X服务 器序号.显示屏 序号” ，例如：xt1:0.0，它不需要在资源文件中进行定义
LANG | 系统使用的语言，用于系统的本地化，缺省为 “C” ，具体的设置可以查看 /usr/share/locale 目录，那里定义了不同的语言，可以将其设置为zh_CN.EUC来使得一些软件使用中文字符。
MAIL | 用户mail文件的位置，也不需要改动
PATH | 使用冒号分隔的一系列路径，系统用它来查找具体可执行程序，因此这个变量非常重要， 可以根据具体的情况改动其值。为了安全的原因，不要将当前目录作为执行程序的搜寻路径， 尤其对于root用户。这样在当前目录下启动程序，需要加上路径，例如启动当前目录下的a.out 程序，输入 “./a.out” 。
MANPATH | 使用冒号分隔的一系列路径，系统用它来查找具体命令的在线手册，设置方法与PATH相同。
PS1sh | 风格的shell使用这个变量的值作为提示符，缺省值为 “$”（root为 “#” ）。更现代 的sh就增强了提示符的灵活性，可以在提示符中加入当前目录、用户名、机器名，命令的序号等。
PS2sh | 风格的shell使用这个变量的值作为后续提示符，提示命令还没有完全输入，缺省为 “>“
TERM | 终端的类型，对于需要全屏操作的程序，非常重要。有时要根据情况对设置进行调整。
TZ | 时区设置，具体的时区信息位于/usr/share/zoneinfo目录下，需要设置为适合本地时区 的标准值

    可以将用户的shell设置为特殊的应用程序，来达到对特殊用户进行限制的目的。例如，仅仅给予用户一个电子 邮件信箱，但不想给他终端使用权，可以将用户的shell更改为/bin/true或者其他立即退出的程序。为了安全 起见，用户shell应该是一个不存在漏洞的二进制程序，最好不要使用解释性语言脚本作为登录shell。由于系统认 可的shell程序是在/etc/shells文件中列出的程序，将特殊用户的shell设置为特殊的应用程序，但这 些应用程序没有列入shells文件，那么这个用户就会被一些应用程序区分出与普通用户的差异，从而拒绝提供服务。例 如ftp服务器程序ftpd，通过检查用户的shell是不是标准shell，来区分这个用户是普通用户还是用于特定 目的的用户。

    注意，不能轻易更改root用户的shell，因为这可能会造成root无法正常登录，而使得无法正常执行系 统维护。即使是将root的shell更改为其他更新、更强功能的标准shell，例如bash或tcsh，也是不应 该。虽然这些shell也是非常成熟的shell程序，仍然不应该使用它们作为root的shell。主要原因是这些 shell一般没有被安装到根分区中，那么当系统进入单用户状态时就会发生问题。另外这些shell可能会由于进行版 本升级等原因，而偶然形成故障，造成root无法正确登录。此外，由于这些非标准shell不一定来自于系统的安装盘 ，因此也存在对shell来源的安全信任问题，必须保证这些shell不是经攻击者更改过的版本。如果要使用它们 shell提供的方便特性，可以在系统登录之后再使用全路径执行它们。

  • 配置用户shell

    事实上sh与csh，并不是普通用户的最佳选择，因为这两个shell在易用性方面做的不够好，例如命令行编 辑功能不强、不能利用热键重复执行命令等。较新的shell，如bash和tcsh都具有这些方便用户使用的功能，但 必须安装了这些shell程序之后，才能更改普通用户的shell设置以使用这些shell程序。更改用户的shell 可以使用pw、vipw或chsh。

    这两个shell分别遵照sh和csh的风格，因此喜好csh风格的可以选择tcsh，而喜欢sh风格的选择 bash。除了这两种shell之外，还有ksh、zsh等shell可供选择。如果对两种shell没有偏好，可以 选择bash，它是一个GNU软件，比标准sh功能强大的多。

    使用了这两些增强型shell之后，用户就可以使用shell提供的命令行编辑功能。按照习惯的不同，可以选 择vi风格的编辑方式或emacs风格的方式，缺省为emacs方式，这种方式使用方向键来回溯执行过的命令，并进行 修改，而vi风格使用字母命令作编辑键，例如使用h、j、k、l四个键来移动光标，vi风格的好处是不使用基本键盘之 外的控制键，因而可以适用于任何终端设备，并且进行编辑时手不需离开基本键盘，熟练操作之后最为快捷。emacs风格 比起vi风格更适合从个人计算机转向Unix的使用者的习惯。bash, ksh ,zsh下使用下面的命令在emacs 风格和vi风格切换：

    bash$ set -o emacs

    bash$ set -o vi

    tcsh中使用不同的命令：

    % bind emacs

    % bind vi

    还可以为常用的命令设置别名，简化用户输入，例如：

    bash$ alias ec=”echo This is a alias”

    bash$ ec

    This is a alias

    shell用于方便用户操作的另一项能力是自动补全命令或文件名的功能，因为FreeBSD下的文件名可能很 长，将它们全部输入比较麻烦。事实上可以输入部分名字，然后按Tab键（在vi风格下是连续两次按Esc键），shell 将自动补全文件名的剩余部分。如果已经输入的这部分名字不能确定具体的命令或文件，那么shell只将能确定的部 分补上，然后响铃通知使用者继续输入以明确具体的文件。

    事实上即使在基本的sh或csh下，也可以使用 “*” 等特殊字符，用模式匹配的方式来简化输入。

    bash$ cd /usr/loca*

    bash$ pwd

    /usr/local

    Unix中的多数程序都具备模式匹配的处理能力，而shell的模式匹配功能最为常用。shell可以使用这 些特殊模式来配置多个文件，达到简化操作的目的。如果要熟练掌握Unix，必须掌握模式匹配。

    当试图在bash下输入汉字的时候，除了必须设置终端属性能接受8位字符之外（执行stty pass8命令 ），还需要设置bash的输入输出转换，可以在登录脚本.profile文件中包括以下设置：

    bind 'set convert-meta off'

    bind 'set meta-flag on'

    bind 'set output-meta on'


FreeBSD连载(15)：文件的属性

王波

文件系统与磁盘操作

    文件在Unix下是一个非常重要的概念，Unix下不但使用文件来保存数据，而且使用文件来保存目录信息、表 示硬件设备等。Unix的文件名对大小写敏感，例如 “FOO” 和 “foo” 是两个不同的文件，而且文件名可长 达255个字符。

    文件是按照分级的形式组织起来，每一级称为一个目录，其内容使用一个特殊的目录文件保存，而第一级目录为根目 录，这就形成了一种树状结构，最下面是根目录 “/” ，根目录下放有普通文件和其子目录，如： “/usr/” 、 “/var/” 等，而在不同的子目录下又有自己的文件和子目录。

    /目录：目录树的根，用于保存系统的内核文件和系统启动文件，它所在的文件系统为根文件系统。

    /dev目录：用于保存系统的设备文件，占用大致固定的硬盘空间，位于根文件系统中。

    /etc目录：用于保存系统的配置文件，包括passwd,rc等非常重要的文件，也被放置到根文件系统中。

    /bin和/sbin目录：保存了用于系统维护目的的执行文件，其中/sbin中的文件通常直接用于系统维护 ，/bin为提供管理员使用系统的基本工具。也必须放置在根文件系统上，在系统运行在单用户模式时，只有根文件系统安 装到系统上时，就能够运行这些程序进行系统维护任务。

    /tmp目录：用于存放程序运行产生的临时文件，这个目录也是每个用户都可写的，在系统启动时将自动清空这个 目录。当系统运行较大型的服务程序时，会要求较大的/tmp空间，会超过根文件系统的空间，因此可以在其他文件系统中 创建另一个临时文件目录，使用符号连接等方法进行维护。

    /usr目录：用于保存系统正常运行时使用的多种文件，其中/usr/bin放置系统执行文件，/usr/sbin 放置系统维护程序，/usr/local放置非标准的应用程序，/usr/share放置系统中的文档和其他数 据文件，/usr/src中放置系统的源代码，/usr/X11R6放置X Window系统、应用程序和数据文件。 由于这些内容非常多，/usr目录通常为一个单独安装的文件系统，占用一个硬盘分区，称为usr文件系统。随着系统任 务的增长，/usr目录中的内容也会迅速增多，还要考虑将其较大的子目录分离出来，例如/usr/local目录。

    /var目录：用于保存系统运行时产生和使用的数据文件，例如/var/log目录用于放置系统日志，/va r/db/pkg目录用于放置系统软件包的安装记录。很多应用程序也使用它来放置数据文件，如news服务器等。这个 目录下文件会随系统的运行而不断变化，其中的很多文件会不断增大，占用大量的磁盘空间。应该将这个目录分离出来，这样 即使某个进程在这个目录下没有限制的产生数据文件，填充整个文件系统，也不会影响其他目录下的数据存储，例如用户在自 己目录下的数据存储。由于/var目录的大小会随着应用程序的需要改变，对于提供网络服务的服务器，/var占用磁盘 分区应该大一些。

    /home目录：使用它用于维护用户的个人目录，它的大小由用户数量及用户的活跃程度决定，也需要有足够的空 间才能提供正常的服务。通常这个目录保存在usr文件系统中，而在根目录下使用连接来维护。当用户数量增加的很多的时 候，应该让它位于一个单独的文件系统中。

    这些目录开始就设计为保存不同的数据，而各个目录会使用不同的磁盘分区。习惯于DOS/Windows的使用 者会不习惯这种使用多个文件系统的方式，而只使用一个文件系统，这种做法是不对的。多文件系统可以用于分隔不同的任务 ，分隔系统风险，增加可靠性，对于用作服务器的FreeBSD系统是必需的。

    Unix的树状目录结构十分标准，那类文件应该放置到那个目录中都有一定的习惯。当然在不同的Unix中，具 体文件的位置也有细微的差别，事实上在Unix发展的过程中，标准目录树结构的也有几次较大的改动，但是基本结构是相 同的。由于FreeBSD有统一的版本，所有的开发者都使用同一个源代码树，而且使用统一的Packages Collection 机制来维护应用软件，因此FreeBSD的目录结构更为整齐、干净。

  • 文件的属性

    由于FreeBSD是一个多用户系统，不同的用户对不同的文件就应该有不同的处理权力，通常创建文件的用户就 拥有这个文件，成为这个文件的属主。同样，文件也有自己的属组，这是一个文件的两个重要属性。由于文件的属主和组涉及 到对文件的访问控制，因此只有root能更改文件的这两个属性，更改文件属主的命令为chown，更改文件属组的命令 为chgrp。

    由于不可能为每个用户都单独提供完全独立的文件系统，多用户操作系统必须提供一种安全的访问控制机制，使得用 户既能和其他用户共享某些文件，又能保证各个用户的文件不会被非法存取或破坏。Unix分别针对属主、同组用户和其他 用户共三种不同的用户，分别设置了存取控制权限，这个权限分别为：读、写和执行，使用英文字母r（Read）、w（Write） 和x（eXecute）来表示。由于对属主、组和其他用户均有这三种权限设置，因此每个文件共有九个权限参 数。使用 “ls -l” 命令就能看到文件的权限设置：

$ ls -l

drwx------ 4 user  wheel    512 Nov 25 17:23 Mail

-rw-rw-r-- 1 user  wheel    149 Dec  4 14:18 Makefile

-rwxr-xr-x 1 user  wheel   3212 Dec  4 12:36 a.out

drwxr-xr-x 1 user  wheel    512 Dec 14 17:03 bin

-rw-r--r-- 1 user  wheel    143 Dec  4 12:36 hello.c

drwxr-xr-x 2 user  wheel   1024 Oct 16  1997 public_html

drwxrwxrwx 2 user  wheel    512 Jan  3 14:07 tmp

    从上面的例子中，可以看到文件的权限设置在列出的数据的第一列中显示，例如文件a.out的属性是-rwxr-xr-x， 共显示了十个字母的位置。其中第一个位置是用于标识文件的种类，而非权限设置，其余九个位置分别表示三组 的三种权限设置。第二个到第四个位置表示属主的权限分别设置为读、写和执行，第五个到第七个位置设置同组用户的权限， 第八个到第十个位置设置其他用户的权限。当指定位置上没有显示对应的权限，而是 “-” ，则表示不允许对应的权限。 因此a.out的权限设置为，对于属主user的权限为读写和执行，对于同组用户为读和执行权限，对于其他用户也是读 和执行权限。对于目录来讲，拥有读权限意味着用户可以列出这个目录下的文件内容，写权限使用户可以在这个目录下增、删 文件和更改文件名，执行权限保证用户可以使用cd进入这个目录。

    ls输出结果的第一个位置表示类别，例如 “d” 表示目录， “c” 表示该文件为字符设备文件， “b” 表示为块设备文件， “l” 表示为一个符号连接。

    Unix系统内部使用数值来表示这些属性，每一个属性与文件属性中的一个二进制位相对应，如果该存取权限设置 了，对应的二进制位就是1，如果该存取权限没有设置，对应的二进制位是0。这样a.out的权限属性rwxr-xr-x 用二进制来表示就是111101101，Unix下常使用八进制的形式表示，这样这个权限是755。

    文件的属主和管理员可以使用命令chmod来设置或改变文件的权限。chmod有几种不同的使用方法，可以直 接使用八进制的权限表示方式设置属性，或者使用属性字母来设置或更改文件的属性，不同的使用方法要求不同的 chmod参数，下面是使用chmod的一些例子：

    chmod 750 a.out ：改变a.out的权限为750；

    chmod a+x a.out ：对所有用户增加a.out的执行权限，
    a（All）表示所有用户；

    chmod u=rwx a.out ：设置属主的权限为读、写和执行
    u（user）表示属主用户；

    chmod g+rw a.out ：增加同组用户的读写权限，
    g（group）表示同组用户；

    chmod o-w a.out ：减少其他用户的写权限，
    o（others）表示其他用户；

    chmod go= a.out ：清除同组和其他用户的所有权限；

    chmod o=u-w a.out ：设置其他用户的权限为减去写权限的属主权限；

    权限755是最常见的文件权限设置，这种属性的文件允许其他用户可以访问这个文件，但不可以更改，如果不打算 让其他用户访问文件，文件的存取权限可以设置为700。文件在创建的时候，系统使用掩码来决定文件的权限，掩码的二进 制对应位为1的，文件属性的对应位就设置为0，例如当掩码的八进制表示为022时（二进制为000010010），创 建的文件权限就为755（111101101）。文件掩码使用umask命令来设置，例如使用 “umask 027 ” 设置掩码为027，则创建的文件权限为750，其他用户将对这个文件没有任何权限。可以在启动资源文件或者在登录 类别中设置中设置用户的掩码。

    目录需要设置执行位，以允许用户能使用cd命令进入这个目录中

    当一个文件的权限设置完毕之后，在一个进程试图访问这个文件时，系统就比较这个进程的属主和属组与文件的属主 和属组，判断这个进程是否具备访问权限。由于每个进程的属主和属组标识是由启动这个进程的用户决定的，因此一个用户启 动的进程就具备其本身对文件的访问权限。

    除了读、写和执行权限以外，对于可执行的程序还有另外两个非常重要的属性：设置属主身份（setuid, Set User ID） 权限和设置组身份（setgid, Set Group ID）权限，这两个属性允许某个程序 可以更改自己的进程标识为程序文件属主或组，因而就可以具备该程序文件属主或属组的访问权限，而不再仅仅是启动进程的 用户的访问权限，这样就能完成特定的任务。很多系统程序，例如su，就是通过这个特性来完成从执行进程时的普通用户身 份到root用户身份的转化的，因此这两个属性对于系统安全至关重要。不是必要的系统程序，不能具备这些属性。

    可以使用 “chmod +s file” 或 “chmod g+s file” 来设置这两个属性，或者 使用 “chmod 4755 file” 、 “chmod 2755 file” 八进制方式来设置setuid 或setgid属性。

  • 文件的连接和符号连接

    Unix中使用i节点（i node）来记录真实的物理文件及其位置，文件名只是指向i节点的一个连接。因此 每个文件可以有多个名字，每个名字就称为文件的一个连接，而同一个文件的所有连接所指向的i节点件完全相同。但在删除 时只有全部删除这个i节点的全部连接，才能删除i节点、即删除这个文件本身。

$ ln l1 l2

$ ls -l l*

-rwxr-xr-x  2 user  wheel   53212 Dec  4 12:36 l1

-rwxr-xr-x  2 user  wheel   53212 Dec  4 12:36 l2

$

    上面的例子使用ln创建了一个连接，然后在ls的结果中可以看到第二列的数字为2，这表示这个文件有两个连接 。这样的连接可以建立在不同的目录中，但所有连接所在的目录必须在同一个文件系统中，才能使用同样的i节点。由于连接 是直接指向标识物理文件的i节点，因此这种连接又称为硬连接。

    另一种更灵活的连接方式是符号连接，它没有指向物理文件的i节点，而是直接指向目录树上的另一个入口，那么当 系统访问这个文件时，就沿着它指向的目录树的位置去查找具体文件。这样就能对任何文件系统中的文件和目录建立连接，因 此称为软连接。符号连接可以跨越文件系统，灵活性很大，能够突破物理文件系统的限制维护目录树的一致性，对于系统管理 和维护很有用。但是这种连接方式需要对目录树进行多次查找，增加了文件操作的额外步骤，因此效率较低，因此不应该使用 多级连接，及某个符号连接指向的目录还是一个符号连接，甚至发生符号连接的循环。应该尽量少用符号连接，并避免多级符 号连接及符号连接的循环。

$ ln -s l1 /root/files

$ ls -l l*

lrwxrwxrwx  1 user  wheel  12 Dec  4 12:36 l1 -> /root/files

$


FreeBSD连载(16)：设备文件

王波

设备文件

    对于每种硬件设备，系统内核有相应的设备驱动程序负责对它的处理。而在Unix中，使用设备文件的方式来表示 硬件设备，每种设备驱动程序都被抽象为设备文件的形式，这样就给应用程序一个一致的文件界面，方便应用程序和操作系统 之间的通信。所有的设备文件都放置在/dev目录下。

$ ls -l /dev/rfd0 /dev/fd0

brw-r-----  9 root operator 2, 0 Nov 12 13:32 /dev/fd0

crw-r-----  9 root operator 9, 0 Nov 12 13:32 /dev/rfd0

    在上面的列表中可以看到原来显示文件大小的地方，现在改为显示两个用逗号分隔的数字。这是系统用来表示设备的 两个重要的序号，第一个为主设备号（major number），用来表示设备使用的硬件驱动程序在系统中的序号；第 二个为从设备号（minor number），硬件驱动程序使用它来区分不同的设备和判断如何进行处理。FreeBSD 下主设备号用8位表示，而从设备号用24位来表示。事实上设备文件的名字并不重要，重要的是这两个设备号，操作系统 使用它确定硬件驱动程序，并与硬件驱动程序进行通信。

  • 磁盘和块设备文件

    在Unix下将设备分为两种，块设备和字符设备，其中块设备主要用于随机存取的目的，磁盘为这一类设备的代表 ，而字符设备用于顺序存取的目的，例如磁带或终端设备。

    磁盘设备的命名方式在前一章中提到过，磁盘设备由磁盘名、磁盘的序号、分区的序号、以及FreeBSD子分区 的序号来表示，例如在设备wd0s1a中，wd为驱动程序，此后为设备序号，0表示为这个驱动程序的第一个设备，Unix 习惯上从0开始计数，第三部分的分区序号为s1，注意这里为第一个分区，因为s1是从1开始向下排列的，与一般Unix 的习惯不同，这是因为分区的概念是一个DOS概念，因此这里也使用与DOS相对应的顺序，最后一个a为FreeBSD 子分区的顺序，每个UFS基本分区可以有8个子分区，这8个分区按照习惯用于不同的目的，例如wd0s1a用于 根文件系统，wd0s1b用做交换分区，使用wd0s1c表示整个硬盘分区wd0s1。因此可以将fd0c用于对整个 软盘fd0进行存取，wcd0c用于对整个光盘wcd0进行存取等。

    传统名字，例如wd0a，可以用于表示第一个UFS分区上的a子分区，如wd0s1a。一般一个硬盘上只有一 个UFS分区，因此可以直接使用传统名字标识磁盘分区。

    在使用ls命令列表时，系统使用c（character）标识一个字符设备文件，使用b（block）标识块 设备文件。

$ ls -l /dev/*wd0s1

crw-r----- 1 root operator 3, 131072 Oct 31 19:59 /dev/rwd0s1

brw-r----- 1 root operator 0, 131072 Oct 31 19:59 /dev/wd0s1

    虽然硬盘设备为块设备，用于随机存取的目的。但它也可以被顺序存取，这种方式称为raw方式。使用raw方式 存取硬盘，就需要一个对应的字符类型的设备文件，对应wd0s1硬盘设备的字符类型硬盘设备为rwd0s1，设备名中 第一个字母使用r表示对硬盘的raw方式顺序存取。

    由于设备文件就代表了整个设备，就可以使用FreeBSD的标准命令以raw方式直接操作设备文件，从而直接 访问硬件设备。利用这种方式，能完成很多有用的工作，但是这种方式也非常危险，例如对硬盘设备文件的操作失误会破坏整 个硬盘的数据。幸好大部分直接访问设备的操作都为读取相应数据的操作，而不需要写入磁盘设备。

    当某个设备不可使用，则其对应的设备文件也不能正常访问，因此直接访问设备文件可以判断对应的设备是否真正正 常。例如，判断连接到第一个串口，ttyd0上的鼠标是否正常工作，使用命令 “cat </dev/ttyd 0” 来查看ttyd0上的输入数据，如果连接的有鼠标且工作正常，那么在移动鼠标的同时屏幕上就会显示出接收到的杂 乱数据。如果没有反应，说明鼠标工作不正确。但这也可能是其他程序接管了这个设备，例如系统运行了moused。如果 moused控制了鼠标端口，那么 “cat < /dev/sysmouse” 会给出答案。

    cat或其他命令，没有控制具体接收到数据的多少，更有效的系统工具是dd，它能精确输入输出一定数量的数据 。例如：# dd if=/dev/rwd0 of=mbr count=1 bs=512

    这将以512字节为单位，读取硬盘wd0上一个单位的数据，保存到名字为mbr的文件中，通常这是硬盘wd0 上的主引导扇区。

  • 终端设备

    终端设备文件为标识用户与系统连接的终端设备的设备文件，这是一种典型的字符设备文件。普通的终端一般使用串 口和主机相连接，系统使用终端文件来描述这个连接的终端。通常第一个串口连接的设备为ttyd0（标准个人计算机第一 个串口连接的常常是鼠标），第二个串口为ttyd1，依次类推。

    如果用户是使用telnet或其他远程登录的方式，那么系统使用一个伪设备文件与用户的伪终端相对应，这些伪 终端设备文件为ttyp0到ttysv，ttyP0到ttySv。这样就能支持相当多用户同时登录系统。

    Unix是多用户、多任务系统，但是个人计算机仅仅有一个屏幕，熟练Unix用户喜欢同时进行几个工作，例如 在一边下载文件，一边进行编程等，对于直接使用控制台的FreeBSD用户来讲，FreeBSD提供的虚拟终端能完美 的解决这个问题。

    对于在控制台上的虚拟终端，对应的终端设备文件为ttyv0、ttyv1、ttyv3等，与键盘上的12个功 能键相对应。控制台设备被系统用来输出很多必要的信息，包括各种登录信息等对系统安全非常相关的信息。由于在控制台上 操作就是在个人计算机前面操作，因此通常在控制台上能完成许多在其他终端上不能完成的操作，例如：使用Ctrl+Alt+Del 重起系统等。为了保证系统安全，必须限制对控制台的物理访问。

    对于不在控制台的用户，就需要额外的应用程序的支持，在X终端上能使用X Window系统开出多个窗口，每 个窗口对应一个伪终端。在字符终端上，也可以通过应用程序screen打开几个伪终端，但这需要安装相应的软件。这些 伪终端都使用ttyp0等伪设备文件。

    与终端相关的另一个问题为不同的终端设备分为不同的终端类型，这是因为虽然终端是字符型设备，但又要求它能够 具备更复杂的功能，例如进行全屏幕操作等。这样就要求终端设备能接受和识别一些控制字符，而不同的终端设备具备不同的 控制字符。登录用户可以使用TERM环境变量来告诉应用程序当前使用的终端类型，常用的终端类型有vt100，ansi 等，FreeBSD控制台的终端类型为cons25，但是其他Unix中一般不识别这个类型，因此如果在FreeBSD 上通过telnet等连接到其他Unix上之后，应该改变TERM变量的值为ansi。

    在FreeBSD中，终端类别对应的控制字符使用termcap的方法定义，而System V中使用ter minfo的方式。所有的终端类型记录在/usr/share/misc/termcap文件中，并定义这些终端对应 的控制字符。

    登录到系统之后，将有一个终端设备文件与用户的这个登录过程相联系。这个终端设备文件在控制台上登录时可能是 /dev/ttyv0，如果从网络上远程登录可能是/dev/ttyp0，但无论是那种情况，系统总使用/dev/t ty来代表用户当前使用的终端，直接访问/dev/tty将对当前的终端进行直接操作。

    除了这些与设备相联系的设备文件之外，还有一些特殊的设备文件。例如/dev/zero文件代表一个永远输出 0的设备文件，使用它作输入可以得到全为空的文件。因此可用来创建新文件和以覆盖的方式清除旧文件。下面使用dd命令 将从zero设备中创建一个10K大小（bs决定每次读写1024字节，count定义读写次数为10次），但内容全 为0的文件。

    # dd if=/dev/zero of=file count=10 bs=1024

    10+0 records in

    10+0 records out

    10240 bytes transferred in 0.001408 secs (7267903 b ytes/sec)

    另一个特殊设备文件为/dev/null，永远无法写满，写入的内容被系统立即丢弃。如果不想看到程序的输出 ，可以使用它作输出。

    # make world > /dev/null

    去除了屏幕输出，使整个程序执行过程非常平静。

  • 设备文件的创建

    通常情况下，安装系统时已经创建了常用的设备文件，可以直接访问这些设备文件来访问设备。但在用户重新定制内 核，并添加了新硬件驱动程序之后，新驱动程序对应的设备文件就可能不存在。在FreeBSD中，最常见的例子就是在内 核中增加声卡的驱动程序时，就需要创建相应设备文件。

    创建设备文件可以使用/dev目录下的shell程序MAKEDEV来完成，首先进入/dev目录，然后再执 行MAKEDEV。

    # cd /dev

    # ./MAKEDEV snd0

    MAKEDEV将使用设备名作参数创建设备文件，同时也创建这个设备文件依赖的其他相关设备文件。MAKEDEV 的参数，并不一定为创建的设备文件名。例如建立 “MAKEDEV vty8” 将建立ttyv0到ttyv7共 8个设备文件，使用 “MAKEDEV wd1s1a” 命令，将建立wd1、wd1s1、wd1s2等，以及wd1s1a、wd1s1b 等设备文件。也可以使用all做MAKEDEV的参数，这将首先清除/dev目录下的所有设备文 件，然后MAKEDEV创建所有预设的设备文件。一般情况下这将创建足够多的设备文件，其中的大部分设备文件在具体的 系统中不会用得到。

    如果对一个系统中没有（或者内核没有探测到）的设备对应的设备文件进行操作，则系统返回Device not configured 的错误信息。

    MAKEDEV将使用mknod和对应设备的正确参数，包括字符或块设备、主设备号和从设备号来建立相应的设 备文件。管理员也可以直接使用mknod创建设备文件，但这就必须将这些设备参数统统指定正确才行。因此除非对系统中 的硬件驱动程序特别熟悉，一般不直接使用mknod来创建设备文件。


FreeBSD连载(17)：安装文件系统
王波

安装文件系统

    FreeBSD将文件保存在磁盘等存储设备上，由操作系统来具体处理访问硬件设备的问题，用户只需要面对操作 系统，就能进行具体的文件操作。操作系统首先将用于存储的设备进行格式化之后，该设备才能用于存储文件，这个设备可以 是软盘，可以是一个硬盘分区，或者其他允许随机存取的块设备存储介质。在Unix上将格式化后的存储设备统称为文件系 统，格式化的过程称为创建文件系统。（由于磁带是一种顺序存取的设备，因此在磁带上不能创建文件系统。）

    对于不同介质、不同的操作系统对磁盘进行格式化和管理的方式也不同，这样就形成了不同类型的文件系统。但操作 系统给用户提供了一种标准的通用存取方式，这样在存取文件时就不需要考虑是在对哪种文件系统进行操作。但是不同的文件 系统仍然有一些差异，例如光盘文件系统是只读介质，还有一些文件系统并非为Unix系统而设计的，因此文件名、文件属 性等标准就与Unix不同，FreeBSD在访问这些文件系统时尽量转换这些差别，补充这些文件系统没有、但Unix 标准文件系统需要的属性。这样这些文件系统就与标准文件系统看起来完全相同，只是某些操作受文件系统本身的物理限制， 例如企图将光盘上文件加上写属性，显然无法完成。FreeBSD支持多种文件系统，其中最常见的有：

    UFS文件系统：是FreeBSD上的标准文件系统，它实现了所有的标准文件属性，如文件属主和组、存取权限 等属性。

    cd9660文件系统：支持ISO 9660格式的CD-Rom，这种格式只支持8位基本长度3位扩展长度、 不区分大小写的文件名，但FreeBSD支持它的Rock Ridge扩展，使其能使用Unix风格的长文件名。

    NFS文件系统：网络文件系统，通过它Unix能在网络上共享文件系统。

    msdos文件系统：DOS和Windows使用的FAT文件系统，基本上是使用8.3的文件名，Windows95 之后扩展了文件名的长度，但仍然不区分大小写。FreeBSD支持Windows95的长文件名扩展和FAT 32格式的分区。

    ext2fs文件系统：Linux使用的文件系统，这个类型不是缺省支持的文件系统，需要重新配置内核。

    NTFS文件系统：Windows NT使用的文件系统，这个类型同样需要重新配置内核。

    在个人计算机的硬盘管理方式中，文件是直接放在硬盘的分区中，而FreeBSD使用的UFS文件系统则又在基 本分区中进行了划分，文件系统建立在BSD风格的子分区中。这样每个UFS分区中能有多个文件系统，每个文件系统或交 换空间各有一个标签（DiskLabel），来标识其本身的起始和结束。当真正要使用文件系统时，就需要获得硬盘上文 件系统（UFS分区和分区内部各个文件系统的DiskLabel）的具体信息。这些硬盘上文件系统的信息应该由管理员 维护，同时也记录在硬盘上，可以使用FreeBSD中的系统工具fdisk和disklabel，或者安装程序Sysinstall ，来获得保存在硬盘本身中的信息。

    当使用Sysinstall中的Fdisk和Disklabel来分区和划分磁盘空间时，当用户完成操作之后 ，应该使用W命令将改变写入磁盘之后再退出Fdisk或Disklabel。

    与Sysinstall不同，命令行的fdisk和disklabel为交互模式，而非sysinstall 的全屏幕界面，因此较为难用一些。使用硬盘名称作为fdisk的参数，fdisk将报告硬盘上所有四个分区的详细信息 ：

# fdisk wd0

******Working on device /dev/rwd0 ******

parameters extracted from in-core disklabel are:

cylinders=525 heads=255 sectors/track=63 (16065 blks/cyl)

parameters to be used for BIOS calculations are:

cylinders=525 heads=255 sectors/track=63 (16065 blks/cyl)

Media sector size is 512

Warning: BIOS sector numbering starts with sector 1

Information from DOS bootblock is:

The data for partition 1 is:

sysid 6,(Primary ‘big’ DOS (>32MB))

   start 16065, size 2056320 (1004Meg), flag 80

      beg: cyl 1/ sector 1/ head 0;

      end: cyl 128/ sector 63/ head 254

The data for partition 2 is:

sysid 7,(OS/2 HPFS, QNX or Advanced UNIX)

   start 2072385, size 1044225 (509Meg), flag 0

      beg: cyl 1/ sector 1/ head 0;

      end: cyl 128/ sector 63/ head 254

The data for partition 3 is:

sysid 165,(FreeBSD/NetBSD/386BSD)

   start 3116610, size 2024190 (988Meg), flag 0

      beg: cyl 1/ sector 1/ head 0;

      end: cyl 128/ sector 63/ head 254

The data for partition 4 is:

sysid 5,(Extended DOS)

   start 5140800, size 3293325 (1608Meg), flag 0

      beg: cyl 1/ sector 1/ head 0;

      end: cyl 128/ sector 63/ head 254

    从这个fdisk的执行结果中可以看出这个硬盘的四个分区分别为不同的操作系统所占用，第一个分区为DOS基 本分区，第二个标识为HPFS，事实上它是NTFS分区，第三个分区wd0s3为BSD分区，而第四个分区为扩展分区 。因此就可以针对第三个FreeBSD系统分区，使用disklabel来检查其上的BSD子分区信息。

# disklabel  wd0s3

# /dev/rwd0s3c:

type: ESDI

disk: wd0s3

label:

flags:

bytes/sector: 512

sectors/track: 63

tracks/cylinder: 255

sectors/cylinder: 16065

cylinders: 126

sectors/unit: 2024190

rpm: 3600

interleave: 1

trackskew: 0

cylinderskew: 0

headswith: 0           # milliseconds

track-to-track seek: 0     # milliseconds

drivedata: 0

8 partitions:

#     size   offset   fstype  [fsize bsize bps/cpg]

  a:  65536      0    4.2BSD    0  0  0  # (cyl.  0 - 4*)

  b: 151248  65536      swap             # (cyl.  4*- 13*)

  c:2024190      0    unused    0  0  0  # (cyl.  0 - 125)

  e:  61440 216784    4.2BSD    0  0  0  # (cyl.  13*- 17*)

  f:1745966 278224    4.2BSD    0  0  0  # (cyl.  17*- 125*)

    可以看出disklabel除了显示各个子分区a-f之外，还显示了硬盘的参数。事实上BSD的分区管理工具 要早于个人计算机的分区概念，而disklabel是BSD的分区管理工具，并不需要fdisk的帮助就能完成所有的 磁盘管理操作。fdisk是用于将FreeBSD与其他操作系统进行兼容的目的，它是使用个人计算机分区概念的系统工 具。如果一个硬盘不被其他个人计算机操作系统访问，完全可以抛弃fdisk，而仅仅使用disklabel和BSD传 统风格的设备文件，来运行FreeBSD。

  • 文件系统的安装

    在存储设备上建立的文件系统必须安装到Unix目录树上，用户才能访问上面的文件。目录树只是一种逻辑概念， 而具体的文件都保存在安装到目录树上的各个文件系统中。由于每个文件都保存的自己的目录中，这样目录中保存的是相对位 置，一旦将一个文件系统安装到一个目录下，则这个文件系统中的所有文件和目录，都位于目录树中的这个目录的下方，可以 选择将这个文件系统安装到不同的目录下。

    安装文件系统要使用命令mount，这个命令必须以root身份执行，例如安装光盘文件系统的命令（IDE光 驱）使用：

# mount -t cd9660 /dev/wcd0c  /cdrom

    参数指明了不同的选项，-t后面跟文件系统的类型，这个命令中使用cd9660，用于光盘使用的ISO 9660 文件系统，同样也可以根据文件系统的不同而选用ufs、nfs、msdos等，其中ufs类型是缺省的文件系统类 型；根据文件系统的类型不同，可使用的选项也不同。/dev/wcd0c是指定CD-Rom设备文件，也可以使用/dev/wcd0 来安装光盘，BSD的习惯做法是除了raw方式访问设备之外，最好使用子设备c来表示整个设备，主要原 因是使用子设备c，那么就能通过访问分区的disklabel，来获得存储设备的信息，虽然现代BSD下这个因素的影 响已经很小，但使用子设备更符合BSD习惯。/cdrom指定了安装目录，此后光盘上的所有文件都位于/cdrom目 录下，但是在执行这个命令前必须创建这个/cdrom目录。

    Mount命令可以通过-o参数指定相关的安装选项，例如-o ro指定了使用只读（Read Only）选 项，由于CD-Rom是只读介质，即使不使用这个选项指明这个介质是只读类型的，系统也会将这个文件系统设置为只读。 对于以只读方式安装的文件系统，任何时候企图写这个目录下的文件都会得到错误信息。对于物理上可写的文件系统，可以使 用ro选项将能保护数据不被改变，因而十分有用。

    同样安装一个DOS格式的软盘应该使用：

# mount -t msdos /dev/fd0 /floopy

如果安装顺利，则就可以访问这个软盘上的DOS文件了。同样也可以访问硬盘上FAT格式的文件系统，包括DOS基本分区和扩展分区上的逻辑盘（逻辑盘在FreeBSD下的设备文件从5开始，例如wd1扩展分区上的第一个逻辑盘为wd1s5）。

安装一个其他计算机通过NFS共享出的文件系统应该使用：

# mount -t nfs remote:/directory /mnt

    与安装其他文件系统的不同在于，本地硬盘上的文件系统使用设备文件，但NFS使用远程主机的名字和目录来确定 文件系统的位置，其格式为主机名与该主机上目录名，中间使用 “：” 分隔开。

    将文件系统安装到目录上之后，使用这个介质上的文件就非常简单了。FreeBSD将假定存储设备将一直停留在 这个安装位置上由系统使用，因此FreeBSD使用内存来为这些文件系统建立缓冲区，以最高效的使用文件系统，这种方 式为异步模式的文件安装方式（async）。这样磁盘上的内容与内存中是非同步的，系统定期或在需要的时候，才去更新 磁盘上的物理信息。（sync命令将强迫系统更新磁盘）这种非同步的方式就使得管理员要移去文件系统必须通过系统来完 成卸载，而不应该直接取出（如软盘等可移动介质）。如果直接移去软盘，或者因为系统突然掉电而造成没有正确卸载文件系 统，就会直接造成磁盘上的数据不正确，从而不得不使用fsck来检查和修复这些文件系统。也可以在执行mount命令 的时候使用sync的安装选项，使硬盘数据和内存缓冲区保持同步，这样虽然降低了存取效率，但更适合对数据的完整性提 出较高要求的系统。

    即使对于一个只读类型的介质，FreeBSD仍然使用这种控制机制，直到卸载才释放对文件系统的控制权。因此 在FreeBSD下使用mount命令安装了光盘之后，光驱前面板上的eject键将不再起作用，直到将这个文件系统 卸载下来。

    使用命令umount可以卸载一个安装到确定目录下的文件系统。

# umount /cdrom

    执行这个命令将文件系统与其安装到的目录相脱离，对于异步模式安装的文件系统还将同步缓冲区和磁盘上的数据。 以后该目录就能用来安装另一个文件系统了。而直到此时才能使用eject键退出光盘，更换或拿开盘片。

# cd /cdrom

# umount /cdrom

umount: /cdrom : Device busy

# cd /

# umount /cdrom

    在执行这个命令时如果系统报告 “Device busy” 错误信息，说明有其他程序仍然正在使用这个文件 系统中的文件，很可能是某个shell的当前路径仍然位于这个文件系统的目录中，造成这个文件系统的目录文件没有关闭 。检查所有的登录界面，保证没有shell的当前目录在/cdrom的目录下。

  • 设置fstab文件

    在系统启动时，系统将自动安装上必需的文件系统。而管理员所要做的是告诉FreeBSD应该安装那个文件系统 、安装到那个目录上和有关安装参数选项。所有的这些信息都必须写入文件/etc/fstab中。在安装FreeBSD 时，这个文件已经具有必要的文件系统了，此后所需要作的只是这个文件中再增加其他的文件系统。

# Device         Mountpoint   FStype  Options     Dump  Pass#

/dev/wd0s3b      none         swap    sw          0     0

/dev/wd0s3a      /            ufs     rw          1     1

/dev/wd0s3f      /usr         ufs     rw          2     2

/dev/wd0s3e      /var         ufs     rw          2     2

proc             /proc        procfs  rw          0     0

/dev/wcd0c       /cdrom       cd9660  ro,noauto   0     0

/dev/wd0s1       /dos         msdos   rw,noauto   0     1

    这个文件中的每一行为一种文件系统或交换设备定义对应的设备文件及安装选项。其中根文件系统具备一定的特殊之 处，因为这个文件/etc/fstab以及FreeBSD的内核文件，其实是在根文件系统中的，因此系统必须首先安装 了根文件系统，才能正常访问这些文件。事实上根文件系统在FreeBSD内核中已经有了设置，启动时先以只读方式安装 根文件系统，并读取根文件系统中相关文件的内容，然后再根据文件内容装载各个文件系统。

    这个文件的第一列为设备文件名字，或者NFS使用的远程文件系统的名字。第二列为文件系统的安装位置，第三列 为文件系统的类型，其中UFS是FreeBSD使用的标准本地文件系统的类型，procfs是FreeBSD用于管理 进程的进程文件系统。第四列为安装的选项，rw表示该文件系统能进行读写操作，ro表示该文件系统是只读的，sw用于 交换分区，noauto表示启动时并不立即安装这个文件系统，而是由管理员在以后手工安装。第五列和第六列的数字是系 统程序dump和fsck程序使用的标志，通常不需要改变，这个标志对根文件系统都是1，而对其他UFS类型的文件系 统都是2，其他类型的文件系统为0。

    注意，由于fstab文件非常重要，如果这个文件有错误，就有可能造成系统不能正常启动，因此向fstab添 加数据应非常小心。不是必须安装的文件系统就不应该进行自动装载，例如上面将CDROM对应的行参数设置为noauto ，表示这个文件系统不是启动时自动装载的系统。

    在使用了fstab文件之后，mount命令的写法就可以简化了。mount命令将查看fstab文件中的内 容以进行匹配，来选定正确的参数。例如，使用下列命令均可以安装上CD-Rom。

# mount /dev/wcd0c /cdrom

# mount /dev/wcd0c

# mount /cdrom

    在安装了文件系统之后，可以使用不加参数的mount命令或df命令查看当前已安装的文件系统信息。

# mount

/dev/wd0s3a on / (local, writes: sync 117 async 796)

/dev/wd0s3f on /usr (local, writes: sync 1189 async 4948)

/dev/wd0s3e on /var (local, writes: sync 362 async 1354)

procfs on /proc (local)

/dev/wd1s2e on /disk2 (local, writes: sync 4 async 41)


FreeBSD连载(18)：软盘操作
作者：王波

软盘操作

    FreeBSD支持软盘操作，虽然当前计算机上软盘的重要性已经大大减小，但在少量传送数据时，软盘仍不失为 一种有效的工具。在软盘上可以使用UFS文件系统或msdos文件系统。

    在软盘上建立UFS文件系统，便需要使用fdformat作软盘的低级格式化，使用disklabel建立文 件系统的标签，然后使用newfs初始化文件系统，最后才使用mount将它安装到目录树上：

# fdformat /dev/rfd0

Format 1440K floppy `/dev/rfd0'? (y/n): y

Processing VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV done.

# disklabel -r -w fd0 fd1440

# newfs /dev/rfd0

Warning: Block size restricts cylinders per group to 6.

Warning: 1216 sector(s) in last cylinder unallocated

/dev/rfd0:      2880 sectors in 1 cylinders of 1 tracks, 4096 sectors

        1.4MB in 1 cyl groups (6 c/g, 12.00MB/g, 736 i/g)

super-block backups (for fsck -b #) at:

 32,

# mount /dev/fd0 /A

    当操作完毕之后必须使用umount /A卸载软盘。

    也可以直接安装和卸载已有的msdos格式的软盘，并进行访问。

# mount -t msdos /dev/fd0 /A

# ls /A

# umount /A

    使用mtools工具能在软盘上建立msdos文件系统，并进行访问，此时软盘设备并没有安装到目录树上， mtools是使用raw方式对软盘进行访问的。mtools的命令与对应的DOS命令用法相同，只是每个命令以m开头 ，并且都是小写形式。如mdir对应DOS下的DIR命令，mcd对应DOS下的CD命令，mcopy对应DOS下的 COPY，并且能在FreeBSD的文件系统与DOS的软盘之间传递文件，等等。

# mformat A:

# mdir A:

# mcopy hello.c  A:

    但是DOS的文本格式和Unix是不同的，Unix下只使用换行字符来表示换行，而DOS下同时使用换行和回 车字符。因此如果将DOS的文件复制到Unix下时，有时候会造成一些小麻烦。如果在vi下打开这种文件，可能会看到 这样结果：

main(){ ^M

printf(“Hello! World!”); ^M

}^M

    ^M代表换行字符，在mcopy中加上-t参数，就可以消除在不同文件系统之间复制文件时的这些问题。如果对 已有的文件去除换行字符，可以直接在vi中使用模式替换将这个特殊字符消除（使用^V^M来表示这个特殊字符，即在按 下Ctrl键的同时输入V和M），或者使用tr命令：

$ tr -d “\015” < hello.c > hello.unix.c


FreeBSD连载(19)：检查硬盘调整文件系统的目录结构
作者：王波

维护文件系统

    由于文件系统是系统中非常重要的部分，因此维护文件系统的任务也非常重要。这个任务包括检查、修复文件系统， 以及调整目录树以适合系统的变化，增添新存储设备等。

  • 检查硬盘

    正常情况下使用FreeBSD的时候，文件系统不会出现问题。然而在某些情况下，如没有正常关机操作就切断了 计算机的电源，就会造成文件系统出现问题。此外，出于系统维护的目的，也需要经常检查磁盘的正确性。这就需要使用文件 系统检查工具fsck。

# fsck /dev/wd0s3e

** /dev/rwd0s3e

** Last Mounted on /var

** Phase 1 - Check Blocks and Sizes

** Phase 2 - Check Pathnames

** Phase 3 - Check Connectivity

** Phase 4 - Check Reference Counts

** Phase 5 - Check Cyl groups

573files,3387used,26340free(132frags,3276blocks,0.4%fragmentation)

    fsck使用raw方式存取磁盘，因此即使使用普通块设备/dev/wd0s3e为参数，fsck也将使用对 应的raw方式设备文件/dev/rwd0s3e进行操作。为了避免与当前磁盘的存取操作冲突，因此要求在进行检查之 前先将文件系统卸载，否则文件系统的状态总是不正确（没有被正确的卸载）。

    为了不影响系统中正运行的进程，进行磁盘维护，最好首先进入单用户状态。这个状态下将关闭所有不必要的进程， 系统也只安装了根文件系统，其他文件都没有安装，而且即使是根文件系统，也是以只读方式安装的，这样能保证不会发生存 取冲突，导致文件系统出现错误。

    一旦磁盘被检查出错误，fsck将提示管理员是否进行修改，可以使用 “-y” 参数，使得fsck自动进行 修复工作，而不进行任何提示。系统每次启动的时候，都会使用这个参数自动检查和修复文件系统。

  • 调整文件系统的目录结构

    系统安装时在目录树上安装了不同的文件系统，随着时间的推移，有些目录使用的文件系统就会被文件数据占满，而 有些目录下的文件系统却很少使用，使得文件系统不太适合系统的需求，此时或者增加新的硬盘设备，或者将文件在不同文件 系统中进行调整。

    例如，如果FreeBSD系统被用作一台News服务器，读者发表文章将保存在/var目录所在的文件系统， 而缺省情况/var目录空间有限，那么这个目录就会被占满。如果不断在系统中安装各种应用软件，那么/usr/loc al目录所在的文件系统会被占满，等等。管理者就需要根据实际情况进行调整，可以使用df命令来查看文件系统的当前状 态信息。

# df

Filesystem  512-blocks     Used     Avail  Capacity  Mounted on

/dev/wd0s3a      63550    50822      7644     87%    /

/dev/wd0s3f    1693228   977436    580334     63%    /usr

/dev/wd0s3e      59454     6772     47926     12%    /var

profs                8        8         0    100%    /proc

/dev/wd0s1     2055744  2032096     23648     99%    /mnt/dosc

    df报告的信息包括这个文件系统的大小和剩余空间（包括使用大小、剩余大小和已使用空间的百分比），如果一个 文件系统中的剩余空间不足，而另一个文件系统还剩余足够的空间，就可以通过调整来充分利用现有空间。

    有时，df报告已使用空间的百分比会超过100%，这是由于UFS文件系统中有一些冗余空间可用。这样就给用 户一个机会，可以不必因为文件系统满而中断当前正在写文件的操作，而清除同一个文件系统中其他不必要的文件，在这个文 件系统中腾出存储空间，从而保证数据最后能被可以正确的保存在文件系统中。

    调整文件系统空间的基本方法是使用符号连接，可以先将该文件系统中的一个子目录中数据全部转移或复制到其他文 件系统中的另一个目录中，然后将原有目录改名或删除，再建立一个对新目录的符号连接来达到目的。例如可以将/usr/local 目录转移到另一个安装到/disk2的文件系统中：

# cd /usr/local

# tar cf - * | (cd /disk2; tar xf -)

# mv /usr/local /usr/local.old

# ln -s /disk2/local /usr/local

    为了保证数据安全，这里例子中没有使用mv直接移动数据，而是使用tar将数据复制到另一个目录中，之所以使 用tar而非cp -R命令，是为了保证复制文件和目录时保留它们的属主、权限控制属性的一致性。


FreeBSD连载(20)：建立文件系统

作者：王波

建立文件系统

    当系统负载逐步增加，仅仅依靠原有文件系统的空间是不够的，更有效的方式是增加新的硬盘设备。这首先需要改动 硬盘及其控制器的硬件设置，以及FreeBSD内核配置，以便硬盘能安装到计算机上并能被FreeBSD内核正确识别 。接下来就需要在新硬盘上创建新的文件系统。

    在系统安装过程中，已经接触了在FreeBSD下管理硬盘和分区的方式，FreeBSD需要两个步骤才能为文 件系统分配一个硬盘空间，第一步是为FreeBSD创建一个UFS系统分区，这个分区只由FreeBSD来使用，然后 在第二步中从这个分区中，为各个文件系统划分空间，在FreeBSD下称为创建文件系统的DiskLabel标签。

    最容易和直观的创建新文件系统或交换空间方式是使用安装程序sysinstall，以便系统启动能够自动安装 上这个文件系统。使用Sysinstall来安装新文件系统的方式在系统安装的过程中已经有了详细描述，以root权 限执行/stand/sysinstall就能进入Sysinstall，然后选择Partition进行分区，选择 Label创建和维护BSD文件系统。

  • 建立文件系统的命令行方式

    除了使用sysinstall之外，还可以使用命令行的方式来完成这些操作。相比较而言，命令行的方式更困难 ，也更容易出错，因此一般不需要使用这种方式，然而命令行方式能带来更大的灵活性，在一些系统维护情况下更为有效。

    命令行方式建立文件系统需要使用fdisk命令进行硬盘的分区工作，fdisk能查看系统分区表上的分区信息 ，并更改其分区设置；然后disklabel命令可以在分区中划分不同子分区空间并标记各个空间的DiskLabel ；使用newfs建立新文件系统，或者使用swapon命令增加交换设备。

    创建新文件系统，首先要使用交互式的fdisk命令（使用-i参数）对硬盘进行分区，不带参数的fdisk命 令仅仅显示该硬盘的分区设置，而不能更改设置。fdisk均使用它检测到的硬盘设置作为缺省设置，如果不需要改变，就 可以直接使用这些缺省设置回应其询问。在fdisk中可以修改的数据有硬盘映射数据，以及四个分区的起始位置和类型。

# fdisk -i wd1

******* Working on device /dev/rwd1 *******

parameters extraced from in-core disklabel are:

cylinders=525 heads=255 sectors/track=63 (16065 blks/cyl)

parameters to be used for BIOS calculations are:

cylinders=525 heads=255 sectors/track=63 (16065 blks/cyl)

Do you want to change our idea of what BIOS thinks ? [n]

    fdisk能检测硬盘的真实映射数据和BIOS的映射数据，由于FreeBSD不使用BIOS存取硬盘数据， 因此这两个数据有可能不一致，但这不影响FreeBSD系统对硬盘的访问。但BIOS的映射数据必须与BIOS中的设 置一致，否则fdisk使用错误数据划分的分区，系统的引导和其他使用BIOS的操作系统就无法正确识别。当硬盘上没 有硬盘分区时，fdisk无法获得正确的BIOS映射数据（因为FreeBSD不访问BIOS），此时就需要在询问是 否更改BIOS映射方式时回答yes，以进行更改。一般在硬盘上已有分区或不需要兼容的情况下，不需要更改这个设置， 直接回车选择no略过这个设置。

The data for partition 1 is:

UNUSED>

Do you want to change it? [n] y

    然后，fdisk会针对每个分区询问是否更改其数据，此时按需要更改分区的设置。由于使用fdisk可以直接 指定分区的起始和结束，因此具有很大的灵活性，也很容易出现错误，如分区的划分出现重叠。由于多操作系统引导程序 Boot Manager占用了硬盘主引导区后面的几个空余扇区，按照DOS/Windows的标准，虽然主引导区仅占用 了一个扇区，同一柱面中的其他扇区（一般为64或32个）也不能被分配给其他分区，而要保持为空余，这些扇区可以为 Boot Manager占用。这样就在fdisk指定分区的起始时，是不能从0开始的，而要从下一个柱面的起始位置开 始。

    然后按照要求回答分区的类型，（FreeBSD分区为165，DOS分区为6），分区的开始位置和大小，注意 单位应该为512字节（扇区大小）。后面的大部分参数可以使用缺省值回应询问，或者设定激活分区。

    更改分区设置并保存退出fdisk之后，还需要检查系统中是否具有对应的设备文件，必须在/dev目录下拥有 相应的设备文件才能访问物理设备。

    划分了UFS基本分区之后，就可以使用disklabel创建文件系统或交换空间的disklabel了，为 了方便起见，可以先为这个分区建立空的disklabel，然后再进行修改。

# disklabel -r -w wd1s3 auto

# disklabel -e wd1s3

    在使用-w参数为分区wd1s3生成缺省的disklabel时，就必须给定磁盘的类型，通常可以使用auto ，让系统自动检测。除了自动侦测之外，在/etc/disktab文件中也给出了很多标准磁盘类型数据，这些数据中 包括包括软盘在内的各种磁盘类型，对于这个文件中不存在的新型磁盘，可以根据原有类型进行修改而生成新数据。通常很少 需要利用这个文件中提供的磁盘类型数据来生成disklabel，使用auto参数能让系统自动检测磁盘的类型。极少 数情况下，例如在配置伪存储设备vn的时候，才需要使用具体磁盘类型参数。

    直接生成的disklabel仅仅包括磁盘的类型信息，以及一个使用c表示整个系统分区的空disklabel ，而没有具体文件系统的disklabel。要真正划分文件系统，需要再使用disklabel -e编辑更改disklabel 配置，例如增加两个子分区，b和e，就需要为b设置类型swap的disklabel，为e设置类型4.2BSD的disklabel， 而c使用的unused类型表示这个disklabel不用做文件系统或交换空间， 可用于特定目的，如raw方式存取硬盘。

    注意由于要使用手工计算文件系统的大小，因此很容易发生重叠等错误。各个不同空间的disklabel允许重 叠，例如缺省产生的以c代表的disklabel表示整个FreeBSD系统分区就会与其他disklabel的空间 重叠。但是具体用做文件系统或交换空间的部分就不能重叠，否则会导致存取错误发生。

    保存退出后，就可以使用disklabel -r wd1s1来查看新建的代表文件系统或交换空间的label 。下面为增加之后的disklabel的最后一部分。

#     size   offset    fstype   [fsize bsize bps/cpg]

b:    61440        0    swap

c:   409536        0    unused        0     0

e:   348096    61440    4.2BSD        0     0     0

然后在新建的disklabel为4.2BSD类型的空间上真正建立文件系统，需要使用newfs命令。

# newfs /dev/rwd1s1e

执行fsck检查刚建立的磁盘分区有无错误

# fsck -y /dev/rwd1s1e

然后就可以将这个建立好的文件系统安装到系统中了，如果建立的是交换空间，可以使用swapon命令可使 该交换分区立即生效。

# mount /dev/wd1s1e /mnt

# swapon /dev/wd1s1b

    为了在启动时自动安装上这个文件系统，需要编辑/etc/fstab文件，将文件系统和交换设备加入系统，那 么下次系统启动之后，就能使用新的磁盘分区和新的交换设备了。例如新磁盘为wd1，相应FreeBSD的分区为wd1s3e （文件系统）和wd1s3b（交换分区），文件系统要安装到系统的/disk2目录下，则fstab应为：

# Device      Mountpoint  FStype  Options  Dump    Pass#

/dev/wd0s3b   none        swap    sw       0       0

/dev/wd0s3a   /           ufs     rw       1       1

/dev/wd0s3f   /usr        ufs     rw       2       2

/dev/wd0s3e   /var        ufs     rw       2       2

proc          /proc       procfs  rw       0       0

/dev/wd1s1e   /cdrom      cufs    rw       2       2

/dev/wd1s1b   none        swap    sw       0       0

    然后就可以使用新硬盘来调整空间紧张的磁盘上的文件和目录。此时，除了可以使用符号连接这种方式之外，还可以 直接将该新建的文件系统安装到需要的目录下。这也是推荐的方式，因为符号连接会对文件操作的性能造成少许影响。

# cd /usr

# mv local local.old

# mkdir local

# mount /dev/wd1s1e /usr/local

# mv /usr/local.old/* /usr/local/


FreeBSD连载(21)：管理交换设备

王波

管理交换设备

    在FreeBSD系统中，交换设备的作用非常大，需要为FreeBSD留下足够的交换空间。在系统负载非常大 的时候，交换空间不够也会影响系统的执行进程。通常应该将系统交换空间的大小设置为物理内存的1-2.5倍。由于交换 空间是用作虚拟存储器，和物理内存进行交换数据的，因此应该设置到高速硬盘上，或者将交换空间分布到多个硬盘中，以均 衡负载。FreeBSD是以交错的方式使用各个不同的交换分区，因此如果在不同的硬盘上分布交换分区，就能提高交换设 备的存取速度。通常FreeBSD使用disklabel为b的设备用做交换设备，在系统运行过程中可以为FreeBSD 增加其他磁盘上的交换设备，或者使用文件用做交换。

    要增加交换设备，首先要沿着上面的过程创建一个新的disklabel，按照习惯做法，使用b作交换空间的 disklabel。再修改/etc/fstab文件，加入一行有关这个交换设备的描述。或者使用swapon立即使分 配的交换空间生效。

    如果要使用文件来用做交换空间，首先要在系统中产生一个用作交换的文件，然后更改/etc/rc.conf， 将swapfile参数指向这个文件即可。

# dd  if=/dev/zero of=swapfile bs=10240 count=1024

    事实上，交换文件要首先映射为伪存储设备vn，然后才能安装到系统中的。因此要使用交换文件，就需要内核支持 伪存储设备vn，缺省内核支持一个vn设备vn0。可以直接访问这个伪存储设备，手工完成增加交换文件的工作。首先要 将交换文件和伪设备相联系，然后就能像处理真实设备一样处理这个伪设备了。将文件和伪设备联系起来需要使用vncon fig命令。

# vnconfig /dev/vn0c swapfile

# vnconfig -u /dev/vn0c

    可以再次使用使用-u参数的vnconfig将已经与文件相联系的伪存储设备，脱离与现有文件的联系，首先要 求这个伪设备不被系统使用，如vn0c没有用作交换设备或已经从系统中卸载了。通过在vnconfig命令中使用-e 参数，就可以直接使用vnconfig加入交换，而没有必要再次使用swapon命令：

# vnconfig -e /dev/vn0c swapfile swap

伪存储设备的用处不止用于交换文件，也可以用来安装虚拟文件系统。因此就可以使用它来管理软盘或光盘的 镜象文件。

# dd if=/dev/rfd0 of=imgfile

# vnconfig vn0c imgfile

# mount -t msdos /dev/vn0c /mnt

    如果不是象上面例子那样从软盘中生成的镜象文件，而是而是要重新建立文件系统，那么需要注意的是磁盘的类型。 由于伪设备的大小是由生成的文件决定的，那么这个伪设备对应的磁盘种类显然不是标准磁盘种类，系统显然也无法从伪设备 中检测到磁盘类型，因此在生成磁盘的disklabel和进行newfs格式化时就需要指定磁盘类型。一般由于镜象文 件的大小与标准磁盘数据对应的大小不一定一致，那么为了充分利用伪设备的大小，就需要在/etc/disktab中生 成新磁盘类型的数据。

# vnconfig /dev/vn0c imgfile

# disklabel -r -w vn0 fd1440

# newfs -T fd1440 vn0c

# mount /dev/vn0c /mnt

[上一页][返回] [下一页]


FreeBSD连载(22)：调整控制台设置
王波

调整系统设置

    在FreeBSD系统中，很多设置都需要直接更改设置文件，例如系统启动脚本rc.conf，控制终端设置文 件/etc/ttys等。虽然大部分很多系统的参数可以通过安装程序Sysinstall来设置，但是改动配置文件更 为直接。并且对于管理员来讲，只有了解配置文件是如何控制系统的表现，才能从根本上解决在实际操作中遇到的各种问题。

  • 调整控制台设置

    控制台是个人用FreeBSD系统使用者最常进行操作的位置，因此应该调整控制台设置，使其最适合使用者的习 惯。可以在控制台上调整显示使用的字体、键盘映射、屏幕保护、虚拟终端等设置。其中一些设置可以通过安装程序sysinstall 来进行，然而有的设置必须通过命令方式或更改配置文件来完成，而且命令行方式具有更大的灵活性。

  • 虚拟终端与ttys设置

    FreeBSD的控制台上有多个虚拟终端，可以在系统启动之后使用Alt键加上功能键来切换虚拟终端。系统缺 省只激活四个虚拟终端，这已经满足绝大多数的需要。其中第四个虚拟终端在缺省情况下没有运行登录程序，这是因为X Server 运行时也需要一个虚拟终端，因此必须将一个没有进程占据的控制台终端留给X Window使用。

    而通过更改内核的设置，FreeBSD可以支持16个虚拟终端设备，由于通常个人计算机只有F1-F12共12 个功能键，事实上只能使用12个虚拟终端。其设备文件从ttyv0到ttyv15，可以使用MAKEDEV来创建这 些设备文件。为了增加虚拟终端的数量，除了更改内核设置、创建设备文件之外，还需要编辑系统文件/etc/ttys。 这个文件中有下面的内容是与此相关的：

# name  getty                           type    status          comments

#

# This entry needed for asking password when init goes to single-user mode

# If you want to be asked for password, change "secure" to "insecure" here

console none                            unknown off secure

#

ttyv0     "/usr/libexec/getty Pc"       cons25    on  secure

ttyv1     "/usr/libexec/getty Pc"       cons25    on  secure

ttyv2     "/usr/libexec/getty Pc"       cons25    on  secure

ttyv3     "/usr/libexec/getty Pc"       cons25    off secure

    ttyv3对应的行的第四列为 “off” ，这说明这个终端并没有运行getty程序，不会出现登录提示。 增加虚拟终端就意味着在这个文件中增加相应的设置行，例如要增加一个虚拟终端，就应该修改这个文件中的相应项为：

ttyv3  "/usr/libexec/getty Pc"   cons25  on  secure

ttyv4  "/usr/libexec/getty Pc"   cons25  off secure

    修改完这个文件之后需要重起系统，在内核支持的条件下，系统将增加一个虚拟终端。

    如果用户在控制台上运行了X Window，由于X Server也需要控制Alt加功能键这样的组合键，因 此控制台将这类组合键留给X Window，不再使用它们来切换到其他虚拟终端。此时切换到其他虚拟终端的热键为Ctrl 加Alt再加上相应功能键，而从其他虚拟终端切换回X Window仍然为Alt+功能键F4。这样的方式甚至不 限于X Server，也适用于其他直接使用控制台、截留键盘的程序。

    在/etc/ttys文件中，可以看到每个虚拟终端最后一个参数为 “secure” ，这表示这个终端位于 安全可信赖的物理位置上，因此在这个终端上可以允许直接使用root帐号登录，如果将其改为 “insecure” ，那么root用户将不能在这个终端上直接登录。由于控制台为系统最基本的终端设备，一般只有管理员或其他可信赖的用 户才能使用，因此对应于这些虚拟终端，设置都为 “secure” 。

    这样一旦控制台的物理安全受到危害，系统安全就受到严重的影响。正由于系统信赖控制台，当系统使用单用户模式 启动时，不会询问root的口令，这个设置是由ttys文件中的console项来进行控制的，可以将ttys文件中 的console项中对应的 “secure” 改为 “insecure” ，就表示控制台是不能信赖的，那么系统 在进入单用户状态时，将验证root的口令。在控制台的物理访问控制不能保证的情况下，这个设置虽然不能完全保证非法 使用者不能进入单用户状态并获得系统的控制权，但提供了相当重要的保护能力。

    ttys文件中，除了针对虚拟终端的设置之外，还对串行终端ttys0等，用于网络连接的伪终端ttyp0等 ，提供了设置。要增加相应终端，与控制台虚拟终端类似，除了更改系统内核、设备文件之外，还需要在ttys文件为相应 设备提供入口。

  • 控制台键盘设置

    kbdcontrol命令就用于更改键盘设置，包括键盘的映射方式、击键的重复率等，键盘的映射文件保存在 /usr/share/syscons/keymaps/目录下，通常的标准101/102键盘可以使用us.iso.kbd文件。以下例子中使用 “-l” 参数指定键盘映射文件，使用 “-r” 参数指定键盘速度。

# kbdcontrol -l /usr/share/syscons/keymaps/us.iso.kbd

# kbdcontrol -r fast

    除了可以用fast来表示键盘速度之外，还可以精确指定键盘击键的间隔和重复时间，例如fast模式就等同于 250.34，表示击键间隔为250ms，重复时间为34ms，normal模式对应于500.126，slow对应 于1000.504。

    指定键盘映射文件的好处是可以自己定义键盘的映射方式，例如可以使用更改键盘配置文件的方法来屏蔽Ctrl-Alt-Del 热键，就可以使用编辑器打开us.iso.kbd文件，将Ctrl-Alt-Del对应的功能由boo t改为nop，表示输入这个击键序列时不进行任何操作。或者可以为boot功能定义其他组合键。

  • 控制台显示设置

    控制台的字体文件均保存在/usr/share/syscons/fonts目录下，通常使用的字体有8x8大小、8x14大小和8x16大 小，可以指定使用那些字体文件作为系统使用的这些大小的字体。将这些字体文件载入需要使用vidcontrol命令：

# vidcontrol -f 8x8 /usr/share/syscons/fonts/cp437-8x8.fnt

其中cp437指的是字体代码页为437，这是英文编码，中文编码为Code Page 936（GB）。由于中文为双字节文字，控 制台驱动程序处理起来比较困难，还没有对应中文编码的控制台字体文件。

vidcontrol不仅用于载入字体文件，还可以改变屏幕的模式，例如可以将屏幕更改为80x50大小：

# vidcontrol 80x50

    由于80x50模式需要使用8x8字体，因此这需要首先载入8x8字体。如果内核编译时选择了VESA支持选 项，并且使用的显示卡也兼容VESA显示模式，还可以将屏幕模式设置为132x60大小，充分利用计算机系统大屏幕显 示器的优势。可以使用vidcontrol -i mode来查看当前硬件支持的显示模式。由于不同的显示模式使用的 不同大小的字体，必须载入必要大小的字体才能改换到相应模式下。

    vidcontrol还可以用于设置控制台下激活屏幕保护的时间间隔，使用 “-t” 参数指定激活时间。

    而控制台屏幕保护则是通过一个载入可加载模块的方式设置的，在/modules目录中已经安装了几个不同的屏 幕保护模块，如black_saver_mod.ko、green_saver_mod.ko、daemon_saver_mod.ko、logo_saver_mod.ko等，这些 模块可以使用kldload命令载入内存，kldstat查看各个内核模块的状态，或者kldunload命令将其卸载。载入不同的 屏幕保护模块，就将激活不同的屏幕保 护。在系统启动时Boot Loader的提示下，可以使用load命令载入模块，也可以通过Boot Loader 的资源文件/boot/loader.rc，用于指定在启动时应该自动执行那些操作。

    通常，可以使用logo_saver_mod作屏幕保护，这是一个FreeBSD吉祥物的图标。

    在FreeBSD 3.0-Release之前，FreeBSD使用/lkm目录下，后缀为.o的可加载模块 ，而管理模块的命令相应为modload、modstat和modunload。这些模块为a.out格式内核使用的 可加载模块，而.ko为ELF内核使用的模块。使用那种格式的内核，就应该载入那种格式的可加载模块，3.1之后如果 仍然使用a.out格式的内核，也可以仍然使用这些模块。

    在3.1-Release之后，FreeBSD引入了系统启动时显示启动图标的能力，如同Windows系统 在启动时显示蓝天白云图案一样，FreeBSD系统也能够在启动时显示一个预设的图像文件，而启动时产生的检测信息隐 藏在图象后面，这个功能称为splash。这个系统启动标志是和新版本的控制台屏幕保护能力是紧密相结合的，当载入这 个splash模块而使得启动显示相应的图标之后，每当空闲时间到达而屏幕保护被激活时，就会显示这个图像作为屏幕保 护。

    为了设置启动标志及其屏幕保护，首先要内核支持splash伪设备（需要pseudo-device splash配置行），再 生成一个小于640x480，256色的非压缩的bmp图象文件，然后将其复制到/boot目录下，更改/boot目录下的loader.rc文 件，设置boot loader载入处理图象文件的模块splash_bmp。

# cp logo.bmp /boot

# cat  /boot/loader.rc

load kernel

load -t splash_image_data logo.bmp

load splash_bmp

这也是使用boot loader的资源文件loader.rc的一个例子，可以定制这个资源文件，指定boot loader自 动载入相关模块，以及执行其他boot loader的命令。

  • 控制台鼠标设置

    FreeBSD使用一个守护进程moused来接管对鼠标的控制，它可以通过sysinstall很方便的进 行设置。moused就能将鼠标的输入传递给控制台驱动程序，这样就可以在文本状态下使用鼠标进行操作，例如在普通情 况下可以进行粘贴操作，在应用程序支持的条件下，还能和应用程序进行交互。缺省条件下仅有第一个虚拟控制台支持这种鼠 标操作，在这个控制台上使用 “vidcontrol -m off” 就能关闭鼠标指针，禁止这种操作，以后仍然可 以使用 “vidcontrol -m on” 许可鼠标的操作能力。

    系统缺省只在第一个控制台虚拟终端设备上打开鼠标指针，因此为了在其他虚拟终端上使用鼠标，必须在相应的控制 台上使用vidcontrol -m on命令。

    执行moused，必须要指定鼠标连接的端口和类型，这样moused才能和鼠标通信。常用的鼠标有连接到串 口的鼠标，它使用的设备为串口设备/dev/cuaa0（串口1）或/dev/cuaa1（串口2），如果使用ps/2接口的鼠标，使 用的设备为/dev/psm0，如果使用总线类型接口的鼠标，使用的设备为/dev/mse0。为了 使用相应的端口，首先要保证相应的设备被内核正确探测，这可以使用dmesg来查看系统的硬件检测信息，检查设备驱动 sio0,sio1（串口设备），psm0,或者mse0等是否被内核检测到。然后就能启动moused了：

# vidcontrol -m on

# moused -p /dev/cuaa0 -t auto

    使用auto作为鼠标类型的参数，让moused来决定鼠标使用的协议，一般情况下moused能够侦测出正 确的协议。一般ps/2鼠标使用ps/2协议，普通总线鼠标使用busmouse协议，串口鼠标使用的协议类型较多， 通常标记为MS-2key两键的鼠标使用microsoft协议，PC-3key三键鼠标使用mouse syste m协议，此外还有intellimouse等不同的协议。

    由于Unix下习惯使用三键鼠标进行操作，因此个人计算机上常用的两键鼠标就有些不合适，此时可以使用同时按 下左右两键来模拟第三个键，对于moused，这需要使用参数 “-3” 支持，这是全屏幕的moused设置程序不 能进行设置的。moused还能更改鼠标的另一些属性，例如滚动速度、点按速度等。

    此外在使用了moused之后，moused将维护一个伪设备文件/dev/sysmouse，这个设备文件 行为就如同一个鼠标端口设备，能被其他要使用鼠标的程序，如X Server所使用，简化了这些程序的设置任务。

    一些Linux二进制格式的程序与这个设备文件不兼容，如果需要使用Linux的访问鼠标的应用程序，如X Server，就不能使用moused，而要让Linux程序直接访问物理鼠标设备文件。

    如果要保留这些键盘、显示、鼠标设置，就需要更改系统启动配置文件rc.conf中的相关参数设置，这样每次 启动系统将自动使用必要的命令载入正确的设置，以下为与这些设置相关的项，这些项均被被作为参数传递给上述的设置命令 ，因此需要根据具体设置更改下列选项。

keymap="NO"		# keymap in /usr/share/syscons/keymaps/* (or NO).

keyrate="NO"		# keyboard rate to: slow, normal, fast (or NO).

keybell="NO"		# bell to duration.pitch or normal or visual (or NO).

keychange="NO"		# function keys default values (or NO).

cursor="NO"		# cursor type {normal|blink|destructive} (or NO).

scrnmap="NO"		# screen map in /usr/share/syscons/scrnmaps/* (or NO).

font8x16="NO"		# font 8x16 from /usr/share/syscons/fonts/* (or NO).

font8x14="NO"		# font 8x14 from /usr/share/syscons/fonts/* (or NO).

font8x8="NO"		# font 8x8 from /usr/share/syscons/fonts/* (or NO).

blanktime="NO"		# blank time (in seconds) or "NO" to turn it off.

saver="NO"		# screen saver: blank/daemon/green/snake/star/logo/NO.

moused_enable="NO"	# Run the mouse daemon.

moused_type="auto"	# See man page for rc.conf(5) for available settings.

moused_port="/dev/cuaa0" # Set to your mouse port.

moused_flags="-3"		# Any additional flags to moused.


FreeBSD连载(23)：配置系统时间
王波

配置系统时间

    对于网络操作系统来讲，由于要向多个客户提供服务，因此必须拥有一个精确的系统时间。可以使用date命令来 显示当前的时间：

$ date

1999年 4月10日 星期六 18时51分39秒 CST

    date命令按中文方式输出的前提是指定环境变量LC_ALL为zh_CN.EUC，这是用于本地化的一种标 准方式。

    由于用于Internet上的网络操作系统的客户可能来自世界的不同地区，因此时间系统必须能标识出不同的时 区。计算机中的CMOS时间能设置为两种不同的时间，一种是将CMOS时间设置为格林威治标准时间，使用时区修正给出 本地时区的正确时间，另一种方法是将CMOS时间设置为本地时区时间，再使用本地时区修正得到格林威治标准时间。这样 系统和其他计算机通信时就能使用标准时间，避免不同时区的计算机时间的差异。

    系统安装程序在进行时区设置时将询问用户使用那种时间设置方式及时区设置，系统安装完成之后，也可以直接使用 tzsetup命令来设置时区信息。所有的时区信息保存在/usr/share/zoneinfo目录中，而本机的时 区设置信息保存在/etc/localtime文件中。此外，每个用户也可以使用环境变量TZ来设置与系统不同的时区 ，这个设置将覆盖系统的设置。

    root用户可以使用带参数date来更改系统时间，例如以下命令将时间设置为1999年3月1日，下午1点54分。

# date 9903011354

1999年 3月 1日 星期一 13时54分00秒 CST

    可以看出时间格式为年、月、日、时、分，每个各占两个数字，其形式即为yymmddhhmm，大部分情况下是 对时间进行小调整，可以略去前面的年月日部分，而仅使用四位数字表示时、分，形如hhmm。

  • 通过Internet同步时间

    手工设置时间一方面不方便，另一方面也依赖于本地管理员的时钟的正确性，那么网络上不同的管理员管理的计算机 时间必然有偏差，不同计算机的时间偏差就会对一些要求时间同步的服务产生影响。解决这种问题的方法很简单，连接到一个 能提供精确时间的服务器上进行时间同步。

    当计算机连接到了Internet之后，那么就能同Internet上存在的很多时间服务器通信，以获得精确 的时间。TCP/IP协议中，用于同步时间的协议为ntp协议，在Internet上提供ntp服务的站点有clepsydra.dec.com 、 ben.cs.wisc.edu、truechimer.waikato.ac.nz 等，虽然ntp协议本身考虑了网络延迟，然而网络延迟毕竟会对时间的精确性造成影响，因此应该选用一个离本地计算机最 近的时间服务器。

    使用/stand/sysinstall也能设定时间同步，可以根据地域来选择合适的时间服务器，然而由于网 络连接并不一定和地域相一致，因此不能完全根据地域的远近来选择时间服务器。

    使用ntp协议更新自己计算机上的时间的一个简单的应用程序为ntpdate，同样这也需要使用root权限 执行：

# ntpdate clepsydra.dec.com

10 Apr 19:26:49 ntpdate: step time server 204.123.2.5 offset 517.837146

    ntpdate运行过之后就退出了，为了保持时间的正确性，就要每隔一段时间自动进行时间同步，可以将ntpdate 放入cron中，每隔一段时间就执行一次。然而系统提供了另一个守护进程，xntpd，能够自动周期进行时间 同步的工作，这更为适合与Internet有永久连接的计算机。为了运行xntpd守护进程，首先要创建/etc/ntp.conf 文件，其中应包括时间服务器的名字和一个临时文件名。

server		clepsydra.dec.com

driftfile	/etc/ntp.drift

    然后就需要运行这个守护进程，进行时间同步。

# xntpd -c /etc/ntp.conf -p /var/run/xntpd.pid

    其中-c参数指定了ntp.conf作配置文件，用xntpd.pid记录xntpd的进程标识序号。ntpdate和xntpd都可以通 过更改rc.conf中的选项，在启动时自动执行。

xntpd_enable="YES"      # Run xntpd Network Time Protocol (or NO).

xntpd_program="xntpd"   # path to xntpd, if you want a different one.

xntpd_flags="-c /etc/ntp.conf -p /var/run/xntpd.pid"
 # Flags to xntpd (if enabled).

    如果要想让本地网络上的多台计算机都进行时间同步，那么每个计算机都与外部时间服务器连接的方法并不是一个好 主意。更好的想法是使用一个计算机与外部时间服务器同步，那么它的时间就成为了标准时间，可以用作本地时间服务器，而 其他计算机与这台本地时间服务器同步就可以了。xntpd就是设计为这个目的，它能够用作提供时间的ntp服务器。用 作时间服务器的xntpd的配置文件应该为：

server		clepsydra.dec.com

driftfile	/etc/ntp.drift

broadcast	192.168.1.255

    其中增加了一项广播地址：192.168.1.255，定期向局域网上的其他计算机广播正确的时间。这个广播 地址要根据自己的网络进行修改，或者使用对应于NTP协议的D类组播（multicast）网址224.0.1.1， 但用户的网络必须支持组播能力。由于使用了广播或组播，这样网络内的其他计算机可以不配置ntp.conf，直接启动 xntpd，xntpd就能通过听服务器的广播信息来得到精确的时间。当然也可以不设定广播地址，而配置每个计算机中 的ntp.conf文件，指定所有的计算机都访问这台时间服务器。


FreeBSD连载(24)：查看系统状态

作者：王波

进程管理

    在系统shell提示下，使用者可以输入各种命令来执行相应的工作。每个命令通常从终端键盘中获取输入，将输 出打印到终端屏幕上，Unix使用标准输入stdio和标准输出stdout，来表示每个命令的输入和输出，还使用一 个标准错误输出stderr用于输出错误信息。这三个标准输入输出系统缺省与终端设备相联系在一起，但是也可以使用管 道的概念将它们重新定向，从一个文件或另一个命令中获取输入，输出到另外的文件中或作为另一个命令的输入等。

$ ls > ls.out

$ cat < ls.out

$ ls -l | grep mbox

    FreeBSD可以同时运行多个进程，在shell下直接输入命令十，shell将进程放到前台执行。如果要 将进程放到后台执行，需要在命令行的结尾加上一个 “&” 符号。下面的命令从后台执行，从ftp.isc. org下载文件。

$ wget  ftp://ftp.isc.org/pub/inn/inn-1.7.2.tar.gz  &

    当程序已经在前台执行的时候，可以使用^Z将这个程序挂起，暂停执行。然后可以使用bg命令将这个挂起的程序 放到后台执行，或者使用fg将某个在后台或挂起的进程放到前台执行。

    当在后台运行了程序的时候，可以用jobs命令来查看后台作业的状态。在有多个后台程序时，要使用来参数的fg 命令将不同序号的后台作业切换到前台上运行。

$ jobs

[1]+  Running   wget ftp://ftp.isc.org/pub/inn/inn-1.7.2.tar.gz &

$ fg %1

wget ftp://ftp.isc.org/pub/inn/inn-1.7.2.tar.gz

    在启动了多个程序之后，可以使用ps命令来查看这些进程及其状态。

$ ps

  PID  TT  STAT      TIME COMMAND

  501  p2  Ss     0:00.24 -bash (bash)

  988  p2  R+     0:00.00 ps

  765  p3  Is+    0:00.28 -bash (bash)

  230  v0  Is+    0:00.14 -bash (bash)

    显示的结果包括进程的标识号PID，控制终端TT（p0表示控制终端为ttyp0），进程的状态STAT，进 程使用的处理器时间TIME和具体的命令。

    可以给ps命令加上参数，来获得更多的输出内容，以下命令将输出系统中所有的进程：

$ ps waux

USER     PID %CPU %MEM   VSZ  RSS  TT  STAT STARTED      TIME COMMAND

wb       989  0.0  0.4   400  236  p2  R+    5:48PM   0:00.00 ps -aux

root       1  0.0  0.1   496   72  ??  Is   10:12PM   0:00.02 /sbin/init --

root       2  0.0  0.0     0    0  ??  DL   10:12PM   0:07.05  (pagedaemon)

root       3  0.0  0.0     0    0  ??  DL   10:12PM   0:00.20  (vmdaemon)

root       4  0.0  0.0     0    0  ??  DL   10:12PM   0:04.27  (syncer)

root      27  0.0  0.0   204    0  ??  IWs  -         0:00.00 (adjkerntz)

root      91  0.0  0.5   820  328  ??  Is    2:12PM   0:00.82 syslogd

daemon   100  0.0  0.0   792    0  ??  IWs  -         0:00.00 (portmap)

root     131  0.0  0.3   864  164  ??  Is    2:12PM   0:00.06 inetd

root     134  0.0  0.3   980  192  ??  Is    2:12PM   0:00.11 cron

root     138  0.0  0.6  1252  380  ??  Is    2:12PM   0:00.11 sendmail: accepti

wb       230  0.0  1.1  1540  668  v0  Is+   2:12PM   0:00.14 -bash (bash)

root     231  0.0  0.0   824    0  v1  IWs+ -         0:00.00 (getty)

root     232  0.0  0.0   824    0  v2  IWs+ -         0:00.00 (getty)

root     500  0.0  0.9   876  524  ??  Ss    4:19PM   0:01.78 telnetd

wb       501  0.0  1.4  1540  888  p2  Ss    4:19PM   0:00.24 -bash (bash)

root     698  0.0  1.5  1644  900  ??  Is    4:49PM   0:00.02 /usr/local/sbin/s

root     700  0.0  1.2  1308  748  ??  Ss    4:49PM   0:00.22 /usr/local/sbin/n

root     702  0.0  3.4  2900 2112  ??  S     4:49PM   0:00.32 /usr/local/sbin/s

root     764  0.0  0.9   880  540  ??  Is    5:10PM   0:00.22 telnetd

wb       765  0.0  1.7  1536 1052  p3  Is+   5:10PM   0:00.28 -bash (bash)

root       0  0.0  0.0     0    0  ??  DLs  10:12PM   0:00.02  (swapper)

    当用户启动一个进程的时候，这个进程是运行在前台，使用与相应控制终端相联系的标准输入、输出进行输入和输出 。即使将进程的输入输出重定向，并将进程放在后台执行，进程仍然和当前终端设备有关系。正因为如此，在当前的登录会话 结束时，控制终端设备将和登录进程相脱离，那么系统就向所有与这个终端相联系的进程发送SIGHUP的信号，通知进程 线路已经挂起了，如果程序没有接管这个信号的处理，那么缺省的反应是进程结束。因此普通的程序并不能真正脱离登录会话 而运行进程，为了使得在系统登录后还可以正常执行，只有使用命令nohup来启动相应程序。

    从上面的ps的输出结果可以看出，有些程序没有控制终端，这些程序通常是一些后台进程。使用命令nohup当 然可以启动这样的程序，但nohup启动的程序在进程执行完毕就退出，而常见的一些服务进程通常永久的运行在后台，不 向屏幕输出结果。在Unix中这些永久的后台进程称为守护进程（daemon）。守护进程通常从系统启动时自动开始执 行，系统关闭时才停止。如果偶然某个守护进程消失了，那么它提供的服务将不再能被使用。

    在守护进程中，最重要的一个是超级守护进程inetd，这个进程接管了大部分网络服务，但并不是对每个服务都 自己进行处理，而是依据连接请求，启动不同的服务程序与客户机打交道。inetd支持网络服务种类在它的设置文件 /etc/inet.conf中定义。inet.conf文件中的每一行就对应一个端口地址，当inetd接受到连接这个 端口的连接请求时，就启动相应的进程进行处理。使用inetd的好处是系统不必启动很多守护进程，从而节约了系统资源 ，然而使用inetd启动守护进程相应反应会迟缓一些，不适合用于被密集访问的服务进程。

    当用户希望要停止一个进程时，如果进程在前台运行并接收输入的条件下，可以输入^D，告诉进程输入结束，通常 这意味着需要进程进行的处理要结束了，从而通知进程结束。对于有些不以文件输入结束作为结束标志的进程，那么就可以使 用^C来向进程发送信号中断进程。

    如果上述方式均无效，或者进程运行在后台或者是一个守护进程，则需要手工向进程发送信号，这可以通过kill 命令来做到。使用 “kill PID” 来向进程发送终止信号SIGTERM，这个信号告诉进程需要退出。但是这些 发送的信号都能被程序通过编程的手段捕获并对其进行处理，一旦程序在这个处理过程中没有退出，而是忽略这个信号的情况 下，就无法杀死进程。这时只能使用 “kill -9 PID” 向PID代表的进程发送SIGKILL信号，这个信 号不能被进程本身捕获，从而无条件杀死进程。但是最好先首先发送SIGTERM信号终止进程。而很多守护进程能够捕获 SIGHUP挂线信号，会根据这个信号进行处理，例如重新读入配置文件，重新刷新进程本身等，因此可以再更改进程的配 置文件之后，使用 “kill -HUP pid” 刷新进程的配置。

    kill命令需要使用进程的标识号PID，因此需要首先运行ps以得到这个标识号。而FreeBSD下可以使 用程序的名字来给进程发送信号，这个命令为killall，对于大部分情况，它使用起来更为方便。

  • 查看系统状态

    FreeBSD下提供了相当丰富的工具可以用来查看系统的状态，使用者可以通过它们来了解系统状态，从而优化 系统性能。这些工具通常读取/dev/mem、/dev/kmem来获得内存中的系统信息，使用/kernel将这些 信息中的变量转换为名字。最基本的查看系统状态的命令为ps，用于报告当前系统中运行的进程的状态。

    pstat能显示系统中打开的文件数量、交换设备的使用率等系统信息。pstat缺省使用/dev/mem设 备文件，从系统内存中读取这些数据，或者可以指定一个core文件，那么pstat从这个文件中读取数据。还需要给pstat 一个参数来告诉pstat应该显示那种系统信息，通常使用 “pstat -f” 显示出当前打开文件的列表 ， “pstat -s” 显示交换设备的当前状态， “pstat -t” 显示当前使用的终端设备文件的状态， “pstat -v” 显示激活的v节点的当前状态。 “pstat -T” 显示这几个系统表的状态，包括当前使用 的和可以利用的系统表空间，因此可以用来检查系统在当前负载下是使用多大的系统表，帮助进行优化系统性能。

$ pstat -T

 69/8232 files

4M/137M swap space

    vmstat报告内核的统计信息，包括进程、虚存、处理器、磁盘等。可以使用 “-w” 参数指定每隔几秒时 间，报告一次系统状态。

$ vmstat

 procs      memory     page                   disks        faults      cpu

 r b w     avm   fre  flt  re  pi  po  fr  sr wd0 wd1 fd0   in   sy  cs us sy id

 0 0 0    3752 30476  643   0   0   0  19  43   0   0   0  262 2599  85 56  3 41

    其他与vmstat类似的命令还有，fstat报告系统中打开文件的信息，可以使用文件名、进程号、用户名， 以及指定文件所在的文件系统来限制要显示的文件。iostat报告内核的输入输出统计信息，包括磁盘、终端等设备的I/O 状态。netstat报告网络的有关统计信息。nfsstat显示NFS的统计信息。

    除此之外，systat以全屏幕方式显示各种系统统计信息，缺省情况下systat是报告处理器的使用率，包 括总利用状态、空闲使用率和各个进程的使用率。通过指定参数，systat也能进行I/O的统计、虚存的统计、网络的 统计等，这些参数包括-iostat, -vmstat, -mbufs, -netstat, -ip, -icmp, -tcp, -swap等。

        /0   /1   /2   /3   /4   /5   /6   /7   /8   /9   /10

     Load Average   ||

        /0   /10  /20  /30  /40  /50  /60  /70  /80  /90  /100

              XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

root     XF86_S3.cx XXXXXXX

wb           kpanel XXX

wb              kfm XX

wb          kbgndwm XX

wb       kblankscrn

wb          krootwm

wb              kwm

    除了这些系统提供的命令之外，FreeBSD也提供多种有效的系统工具，如综合ps、systat和vmst at功能的top等。这些软件通常可以在多种Unix系统中使用，也是十分常用的工具。也可以在FreeBSD系统中 安装网络管理代理snmpd，然后使用网络管理系统通过网络来获得FreeBSD主机的各种系统信息。


FreeBSD连载(25)：定时执行程序

王波

定时执行程序

    Unix系统提供了cron和at命令，使系统和用户可以定时运行一定的程序，而不需手工启动。

    使用cron用于周期性的执行一个命令，为了使用它，必须编辑crontab文件。系统缺省的/etc/crontab 文件为：

# /etc/crontab - root's crontab for FreeBSD

#

# $Id: crontab,v 1.13 1996/01/06 22:21:37 ache Exp $

# From: Id: crontab,v 1.6 1993/05/31 02:03:57 cgd Exp

#

SHELL=/bin/sh

PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin

HOME=/var/log

#

#minute	hour	mday	month	wday	who	command

#

*/5     *       *       *       *       root	/usr/libexec/atrun

#

# rotate log files every hour, if necessary

0	*	*	*	*	root	/usr/sbin/newsyslog

#

# do daily/weekly/monthly maintenance

0       2       *       *       *       root    /etc/daily 2>&1 | sendmail root

30      3       *       *       6       root    /etc/weekly 2>&1 | sendmail root

30      5       1       *       *       root    /etc/monthly 2>&1 | sendmail root

#

# time zone change adjustment for wall cmos clock,

# does nothing, if you have UTC cmos clock.

# See adjkerntz(8) for details.

1,31	0-4	*	*	*	root	/sbin/adjkerntz	-a

    在这个crontab文件中首先设置了几个环境变量，cron执行这个文件时先设置这些环境变量，然后按照每 列规定的时间来执行相应的命令。第一列为分钟，规定每小时的第几分执行相应的程序，第二列为每天第几小时执行程序，， 第三列为每月的第几天，第四列为第几周，第五列为每周的第几天，第六列为执行该文件的用户身份，第七列为要执行的命令 。

    普通用户也可以使用crontab命令来创建和维护自己的crontab文件。由于是用户不能更改执行程序的 标识的，因此用户的crontab就不需第六列──执行程序的用户身份，而只要直接跟随要执行的命令。使用 “crontab -e” 命令，使用编辑器按照相应的格式编辑自己的crontab文件，或者使用 “crontab -l ” 列出现有crontab文件的内容，当然只有root用户才能查看其他用户的crontab文件：

$ crontab -l

12 0 * * * /home/wb/bin/getfiles

    所有用户的crontab设置文件都放在/var/cron/tabs目录下，文件名与每个用户的用户名相同 。cron中的命令执行结果将被系统使用mail寄给每个用户。在/var/cron目录下还有crontab执行的 记录文件，系统管理员可以按照这个文件来检查系统安全性，检查是否有影响系统安全的程序被执行。

    与cron不同，at命令用于在一定的时间后或在一定的时刻执行设置好的命令。at命令使用一个时间参数表示 何时执行命令，然后就从标准输入中读入要执行的命令，此时就如同在shell下操作一样输入要执行的命令，最后使用^D 退出输入命令的模式。用户不必担心真正执行命令时是否能够找到正确的程序，at会将当前shell的设置，包括环境 变量，保留起来，以便在执行命令时创造一个与启动at时完全相同的执行环境。

$ at 1:00am +2days

wget ftp://ftp.cdrom.com/pub/FreeBSD/packages/All/netscape.tgz

^D

    上面命令将在两天后的凌晨1:00时启动进程下载文件，当然at命令并不是十分精确，其执行时间只是表示大概 时间，可能与标准时间存在一两分钟的差异。at也支持各种复杂的时间表示方法，可以使用hhmm，hh:mm，或者加 上am或pm结尾的12小时制方式。还可以使用年月日，规定程序运行的日期：

$ at 1:00am Mar 5

echo Hello | mail root

^D

Job 5 will be executed using /bin/sh

$ atq

Date                    Owner   Queue   Job#

01时00分00秒 00/03/05   root    c       5

$ atrm 5

    用户的at程序执行结果也被系统邮寄给该用户，用户可以使用mail来查看程序的输出结果或执行错误。当用户 启动at命令之后，可以使用atq命令来查看自己还没有执行的at命令，如果atq是由root执行，则将列出系统中 所有没有执行的at命令。然后可以使用atrm命令根据atq输出Job号来删除at作业。

    系统使用/var/at/at.allow和/var/at/at.deny文件来配置可以使用at命令的用 户，和不可以使用at命令的用户。其中at.allow的优先权更高，如果存在at.allow，就只允许这个文件中 列出的用户使用at，而不考虑任何不在这个文件中列出的用户。因此可以使用一个空at.allow文件禁止所有用户使 用at。当不存在at.allow文件的时候，那么凡不在at.deny文件中列出的用户都可以使用at。


FreeBSD连载(26)：进程的权限

作者：王波

进程的权限

    由于FreeBSD是多用户系统，因此进程必须要受到权限的控制和保护。出于安全性的考虑，一个用户不可能杀 死其他用户启动的进程，一个进程也不能非法存取其他用户的文件数据。只有超级用户和超级用户启动的进程才有最大的权限 ，普通进程就只与进程的执行者相关，只具有这个用户的权限。

    一些情况下（特别是执行系统维护任务时），要求普通用户也能完成特殊权限的任务，那么就必须在进程执行过程中 改变进程的身份。改变进程的身份则必须同时具备两个要求：程序文件本身具有SetUID或SetGID属性，同时程序 中需要相应调用setuid()或setgid()系统调用，这两个系统调用能够检查文件的属性，并完成更改进程权限 的操作。

    通常只有系统程序才需要利用这两个属性，例如系统程序su允许普通用户成为root用户，就使用的是这个能力 。

$ ls -l a*

-rwxr-xr-x   1 user  wheel  3212 Dec  4 12:36 a1

-rwxr-xr-x   1 user  wheel  3212 Dec  4 12:36 a2

$ chmod u+s a1

$ ls -l a*

-rwsr-xr-x   1 user  wheel  3212 Dec  4 12:36 a1

-rwxr-xr-x   1 user  wheel  3212 Dec  4 12:36 a2

$ chmod g+s a2

$ ls -l a*

-rwsr-xr-x   1 user  wheel  3212 Dec  4 12:36 a1

-rwxr-sr-x   1 user  wheel  3212 Dec  4 12:36 a2

    上面第一个chmod（chmod u+s a.out）为a.out增加设置属主身份权限，然后列表中对应 属主的执行权限位的 “x” 标志将改变为 “s” （文件属性显示为rwsr-xr-x）。第二个c hmod （chmod g+s a.out）为a.out增加设置组身份权限，则列表中对应组的执行权限位的 “x ” 标志将改变为 “s” （文件属性显示为rwxr-sr-x）。同样，SetUID和SetGID 属性也都有相应的八进制表示方式，SetUID为04000，后面的三个八进制位属于文件的读写访问属性设置，相应S etGID为02000，它们两个属性位处于读写属性位之前。下面是一个更改属性设置的例子：

# ls -l /bin/ps

-r-xr-sr-x  1 bin  kmem 163840 May  6 06:02 /bin/ps

# chmod a=r /bin/ps

# su user

$ ps

bash: ps: Permission denied

$ ^D

# chmod a+x /bin/ps

# su user

$ ps

ps: /dev/mem: Permission denied

$ ^D

# chmod g+s /bin/ps

# su user

$ ps

  PID  TT  STAT      TIME COMMAND

  226  p2  S      0:00.56 bash

  239  p2  R+     0:00.02 ps

$

    第一次以user身份执行ps时，ps的文件属性被改为对所有用户只有读权限，因此不能执行，shell报告 Permission denied；第二次以user身份执行ps时，ps报告不能打开/dev/mem文件，这是 因为普通用户无权存取内存映象文件。而第三次执行ps时，由于设置了setgid位，和kmem同组的进程就能够打开 /dev/mem文件，从而正确执行了ps程序。

    具有SetUID或SetGID属性的程序，能够在进程执行中调用系统调用setuid()或setgid() ，调用成功后这个进程就具有了程序文件属主和组的权限，就可以完成以前改变身份之前不能完成的任务。因为通过它们程 序可以改变进程的用户标识，绕过系统的权限设置，因此这两个属性对于系统安全非常重要。尤其是属于root的文件，并 设置了SetUID属性的程序，更是系统安全中值得注意的地方。为了保证系统安全，必须保证没有非法的SetUID或 SetGID程序的存在，通常管理员可以使用find命令来完成这个任务，例如查找具有SetUID的程序，则执行：

# find / -perm 4000 -print


FreeBSD连载(27)：应用软件的类别

王波

安装应用软件

    FreeBSD下拥有多种预编译好的软件包，包括了从数学运算到系统维护，从图象处理到Internet服务 程序等大量的软件。之所以能拥有如此丰富的软件，除了Unix本身就是一个非常流行的开发平台之外，另一个重要原因就 是每种Unix中均提供了高级语言C作为了标准开发语言，而C语言具有高度可移植性，并且随着Unix的流行它成为了 最重要的一种程序设计语言。

    由于Unix运行在多种不同的平台上，而不同平台上的二进制执行文件只包含本平台上的机器指令，因此造成一个 平台上的应用程序不能直接在另一个平台上运行。但是在Unix的世界中，有着通用的编程语言C和相同的系统调用，使得 不同的Unix平台上程序的C代码基本相同，为一种Unix开发的应用程序，很容易就能移植到其他Unix系统中。传 统上在Unix上安装各种应用软件一般使用源代码的形式，需要管理员手工编译安装，这就要求管理员需要熟悉C语言及其 开发工具。然而这样操作毕竟是一个繁琐的任务，尤其对于不太熟悉C语言的使用者更为困难。因此各种Unix各自发展了 一些直接安装二进制程序的机制，FreeBSD中也提供了Packages Collection── 一种管理和安 装预编译好的软件包机制，来帮助使用者管理各种应用软件，使得用户不需要了解C语言及其开发工具，也能正常进行应用软 件的安装和管理。

  • 应用软件的类别

    在安装和使用应用软件的时候，正版和盗版等版权问题总是计算机使用者需要考虑的话题之一。很多计算机使用者总 以为软件的版权问题与光盘、磁带类似，不是正版就是盗版。然而情形并非绝对如此，绝大多数软件的开发者倾向于让自己开 发的程序被尽可能多的人使用，当软件开发者不以软件作为获利的目的时，对软件的使用就没有采取任何限制，或者是很宽容 的限制。其他使用者就可以自由使用这些软件，而不需要考虑版权问题。

    正由于软件开发者的目的不同，因此对他们的软件使用的版权保护方法也不同。有的开发者出于自己的个人兴趣、需 要或信仰而开发软件，希望自己的软件为更多的人使用，没有或暂时没有从软件中获利的目的，因此就鼓励其他人使用这个软 件。有的开发者出于盈利的目的开发软件，因此就使用了严格的版权限制。按照不同软件的版权限制，可将应用软件可以分为 两类：

  • 公共域软件与自由软件

    这些软件的作者对版权不加任何限制或者限制很少，属于这一类的软件通常提供源程序，允许使用者自由使用软件并 任意修改。FreeBSD系统中包括的软件均属于这一类，因此使用者不需要考虑使用FreeBSD的版权问题。其中公 共域软件对版权没有任何限制，可以认为是属于放弃版权的软件。很多公共域软件是科研机构和大学开发的，但也被商业公司 用于自己的系统中，此时商业公司就使用了自己的版权声明，而用户却无法自由使用该软件。

    为了保护软件不被商业机构滥用，自由软件基金会的Stallman使用了GNU版权许可来保护用户自由使用软 件的权利，这个版权许可允许将自由软件用于商业目的，但必须允许用户有自由使用、拷贝、修改的权利。根据这个许可，可 以销售GNU软件，但必须同时包括它的源程序以便用户根据情况修改（或者在用户要求时提供）。

    GNU软件许可并不是唯一的自由软件许可权声明，FreeBSD使用的BSD许可也是另一个重要的版权许可。 与GNU许可相比，BSD许可更宽松一些。BSD许可只要求必须保持显示的相关作者的声明信息，对商业使用限制更少。 此外还有X的版权许可等。由于GNU软件许可最为著名，并且也比较完善，因此很多非自由软件基金会的软件也使用这个许 可权，用来保护自己软件的版权。

    事实上这一类软件在计算机发展中起了很重要的作用，它们常常最先实现很多新想法、新功能，推动软件技术的发展 。自由软件的功能、效率和可靠性并不比商业软件差，有的软件甚至要好于同类的商业软件，唯一的问题是自由软件不提供技 术服务，仅仅随同软件提供一些电子文档，需要使用者自己去学习安装和使用。当然，自由软件通常也有相应的商业版本，差 别就在于提供了商业技术服务支持。

  • 共享软件与专有软件

    这些软件通常是基于商业目的开发的软件，这些软件通常使用严格的版权规定。这些软件中的大部分不允许使用者免 费使用。但出于商业目的，一些软件允许使用者免费使用，但对软件的自由使用提出了一定的条件和限制。

    一些共享软件不提供源代码，一些商业软件的演示版本提供了较弱的功能和使用时间限制。还有一些软件的限制更宽 松，允许个人用户自由使用软件，但不许可自由分发、拷贝软件。

    一些FreeBSD安装介质中，在基本系统之外也提供了一些共享软件，供使用者手工安装（不能使用安装程序安 装）。这些软件允许使用者在一定条件下，并按照软件本身的声明使用这些软件。由于版权问题，系统不会将这些软件包括进 系统内部，使用者只有在保证软件版权条件下才能运行这些软件。

  • 开放源码观念

    由于在Unix世界中，软件的标准为C语言，有了C源代码就能将应用程序移植到其他Unix上，因此在Uni x传统上，就有一种提供软件的同时也应该提供源码的观念。

    发布软件的源代码对用户有很多好处，一方面用户能够了解他们使用的软件是可以信赖的，即使存在问题，也能够及 时发现错误，并依据源码及时纠正，这些修正返回到开发者那里，同样起到促进软件发展的目的。另一方面毕竟通用软件并不 一定完全适合用户的需要，发布软件的源码使得用户能够按照自己的需求定制软件。

    因此在Internet上很多软件的作者都认同这种观念，这种观念还得到了包括Netscape等商业公司的 支持，进而组织了开放源码组织（Open Source）来支持这种观念。FreeBSD的众多开发者就是这个组织的 坚定支持者。其网址为http://www.opensource.org

    当前开放源码得到了一些商业公司的支持，如netscape公司就公开了它们的浏览器的源代码。出于技术的发 展，软件本身已经不再包括太多的技术秘密了，在Internet上可以找到各类程序的源代码，依靠未公开接口保持软件 秘密的做法基本被大家抛弃。当程序设计从 “艺术” 转变为 “工程” ，重要的就不再是程序设计的秘密，而是软件工 程了。商业公司也可以从开放源代码的情况下，获得使用者更多的建议，使得它的软件能进一步完善。


FreeBSD连载(28)：Packages Collection

作者：王波

Packages Collection

    FreeBSD中提供了上G字节大小的预编译并打好包的二进制应用软件包，这些软件包能够立即安装使用。在软 件包中不但记录了二进制软件的内容，还包括这些软件的安装位置、软件包的描述信息，以及软件包之间的依赖关系，这种管 理软件的机制称为Packages Collection。通常安装介质提供的这些Packages位于安装介质中的 packages目录下，使用安装程序sysinstall就能够很容易的安装和卸载这些安装好的软件包。（由于空间 的限制，安装光盘上并不能包括所有的软件包，可以从Internet上下载，在Walnet Creek发布的FreeBSD 光盘中的第三张也包括了大量预编译好的软件包）。

    在FreeBSD下，每个预编译的软件包是使用tar和gzip进行打包压缩后的文件，其文件名中的前面为这 个Package的名字（包括版本号），并使用tgz后缀，例如navigator浏览器的Package文件为netscape-navigator-4.07.tgz。。

    使用root权限执行sysinstall，然后选择Configure菜单项中的Packages选项，系 统将按不同的应用软件的类别，显示出相应的菜单选项，每个选项对应一类应用软件，其中All项中包括所有可用的应用软 件。

    这些软件也被放置到安装介质中的packages目录下对应的不同存储子目录中，子目录和菜单选项是一一对应的。

# ls -l /cdrom/packages

All          converters   kde     print      x11

INDEX        databases    lang    security   x11-fonts

Latest       deskutils    mail    shells     x11-toolkits

archivers    devel        math    sysutils   x11-wm

audio        editors      misc    tcl81

benchmarks   emulators    net     textproc

chinese      gnome        news    tk81

comms        graphics     perl5   www

    如果进入了一个种类的子菜单，那么就可以看到，已经安装的软件有一个 “X” 标记，可使用空格键反选择这个 已安装的软件，系统将立即卸载这个软件。或者选择一个未安装软件，然而此时并没有立即进行这个软件的安装，而是要等到 全部选择了所有想要安装的软件包之后，再回到上级菜单，选择 “Install” 按钮才开始进行安装。

  • Packages的相互依赖关系

    各个软件包之间并不是孤立的，而是在相互之间存在一定的依赖关系。例如，所有的X Window应用软件都在 X Window下运行，那么如果没有安装X Window服务器软件，也不能正确安装这些应用软件。此外，Pack ages中也并不全是应用软件，它也包括各种函数库及其他种类的支持文件，那么有的应用软件包就依赖于这些库文件和支 持文件。

    由于存在各种相互依赖关系，必然对软件包的安装和卸载发生影响。当安装一个软件包时，FreeBSD将会首先 安装这个软件包依赖的其他软件包，然后才能安装这个软件包本身。如果没有安装它所依赖的软件包，则就不能正常安装这个 软件包本身。同时，当删除一个软件包时，必须预先删除依赖这个软件包的所有其他软件包，否则就不能正常完成删除任务。 FreeBSD对这个依赖关系限制比较严格，即使是同一个软件，但版本不同，依赖于这个软件另一个版本的其他软件包也 不能正确安装，必须保证版本的一致性。

    使用Packages Collection来安装和管理应用软件，可以维持软件安装文件结构的一致性，因为 Packages Collection安装的软件其文件目录结构符合FreeBSD的习惯，清晰明了。此外软件包之 间的依赖关系对于同时维护多种软件也很有效，因此最好不要绕过Packages Collection手工安装软件。 当需要重新定制软件的时候，可以通过Ports Collection来完成，它在编译好软件之后，可以使用软件包的 方式安装和维护软件。

    每个软件包的安装信息被放置在/var/db/pkg目录下维护，这个目录下的每个子目录都对应于一个安装过 的软件包，如果某个子目录被破坏，那么相应的软件包的信息就不复存在了。

  • 管理Packages

    虽然使用sysinstall来管理软件比较直观，但是这需要一个标准的安装介质，适合大量安装软件包时使用 。而在不使用安装介质的时候，仅仅需要添加某个独立的软件包或进行维护时，sysinstall就不适合了。FreeBSD 提供了十分简单的几个管理命令来完成这个任务。

    pkg_add 安装一个Package，其参数为要安装Package的文件名或获得这个文件的URL 。当使用URL来指定Package的位置时，pkg_add首先使用fetch程序下载该软件包，然后进行安装。 通常可以使用 “-v” 参数，使pkg_add显示出进行的操作过程。

    pkg_delete 删除一个软件包，其参数为软件包的名字，由于此时软件包已经被安装到系统中了 ，因此名字中不必使用tgz后缀。同样也可以使用 “-v” 参数。

    pkg_info 获取一个软件包的安装信息和简短描述，参数为软件包名字时，将参看当前已安装的软件 包中是否存在它，当使用的参数为带tgz后缀的文件名时，将查看当前目录中是否存在这个软件包文件。或者可以使用 -a参数列出当前安装的所有软件包的信息：

# pkg_add netscape-communicator-4.5.tgz

# pkg_delete netscape-communicator-4.5

    但在实际应用的过程中，值得注意的问题常常发生在升级软件包时。由于同一软件的不同版本通常使用同样的文件名 ，因此在安装一个版本时将覆盖掉另一个版本的文件，但是同时新版本的Packages并不会自动删除老版本Packages 的安装信息。因此如果再一次卸载旧版本时就会将新版本中具有同样文件名的文件删除掉。解决问题的方法是先卸载老 版本，再安装版本的Packages。一旦出现问题，可以再次将新版本Packages重新安装一次即可。


FreeBSD连载(29)：打印机配置：系统结构

作者：王波

打印机配置

    FreeBSD是多用户操作系统，因此可能有多个用户同时发出打印请求，如果每个请求都直接访问打印机，那么 必然就会发生冲突问题。为了使打印机能为所有的用户服务，FreeBSD使用伪脱机的打印服务方式。在这种方式下，每 个使用FreeBSD的打印用户并不直接访问打印机，而是通过一系列伪脱机打印程序来使用打印机。

    FreeBSD的打印系统提供了以下功能：

  • 控制用户对打印机的访问，包括本地的打印机和网络打印机；
  • 允许用户提交打印作业，并允许用户可以管理自己的打印作业；
  • 维护一个打印队列，防止多个用户同时使用打印机的现象发生；
  • 可以选择在文档的开始打印标志，使打印出的文档至于混淆；
  • 能通过过滤器支持不同的打印机；
  • 提供记帐功能；

  • 系统结构

    通常用户使用程序lpr进行打印，但lpr并没有直接将所有打印的文件发送到打印机上，而是将其放到打印缓冲 目录中。通常这个缓冲区在/var/spool目录下，每个打印机有自己的spool目录，打印文件就被放到这里，存 储为一个临时文件。而系统使用守护进程lpd监视spool目录，当发现一个缓冲目录中有需要打印的文档时，lpd就 复制自身，为这个打印任务产生一个lpd进程，这个进程负责处理这个打印缓冲目录的文档，将其发送到这个目录对应的打 印机中进行打印。由于一个打印机对应一个缓冲目录，并且由一个lpd进程管理，因此就不会发生多个打印任务同时访问打 印机，发生资源冲突问题。

    在这种打印方式将普通的打印系统分为三个部分：

  • 用户接口：打印命令lpr等是用户用来实施打印和管理的程序，可以通过它将要打印的文件放到本地或远程的打印缓冲区中；
  • 打印缓冲区：每个打印机有自己的缓冲区，用户或管理员可以通过一系列命令进行维护；
  • 打印机管理程序：打印守护进程lpd是打印系统的中心，负责监视缓冲区，并将缓冲区中的打印作业送到打印机上进行打印；

    这种方式虽然与直接访问打印机相比看起来比较复杂，但是这样能够支持多用户和多打印机；而且使用打印缓冲区和 后台打印守护程序使打印工作放到后台进行，用户不需等待打印结束。此外，这样也可以使得打印系统可以很好的和网络相结 合，可以通过lpd将打印到其他主机上的打印作业通过网络发送出去，或者监视网络上发送来的打印文档，将其放入打印缓 冲区中进行处理。

    将打印过程分为三个部分的另一个优点是可以使用过滤程序，对放置在打印缓冲区中的打印作业进行处理，这样可以 完成转换格式、统计信息等很多功能，充分发挥了易管理的特点。

    这种BSD风格的打印系统是FreeBSD缺省提供的，为了支持多种打印机，以及支持对中文和图形的打印，还 需要安装额外的软件包。包括ghostscript, psutils, apsfilter, gb2ps等，这些 软件都通过Packages Collection进行安装。

    为了使用这个打印系统，就必须启动打印守护进程lpd，rc.conf中有一个选项lpd_enable就用 于这个目的。


FreeBSD连载(30)：配置打印机

王波

配置打印机

    本地打印机通常连接到计算机的并口上，因此在安装打印机之前，首先要查看并口的状态是否正常。正常情况下，缺 省的硬件配置将能够自动侦测到计算机的并口，那么在启动时，系统将在控制台上显示下面的信息，如果由于滚屏太快而没有 看到这一行的话，可以使用dmesg命令进行查看：

$ dmesg | grep lpt

nlpt0:  on ppbus 0

nlpt0: Interrupt-driven port

    在FreeBSD 3.0之前使用lpt作为打印机的驱动程序，这个老驱动程序对于现有具备多个模式的并口硬 件支持能力不足。3.1之后系统的并口驱动程序更新了，使用了nlpt作为新的驱动程序名字，但设备文件的名字仍然为 /dev/lpt0。以后当老版本的驱动程序彻底从FreeBSD中消失之后，驱动程序名字会恢复为lpt。

    通常不需任何配置，并口就能正常工作。此时就可以通过设备文件/dev/lpt0来直接访问并口（0表示第一 个并口，依次类推），如果并口和打印机的电缆连接也正常，就能测试打印机是否正常，此时需要root权限。

# lptest > /dev/lpt0

    如果对于普通行式打印机，这将打印出一页测试信息，但如果打印机是使用PostScript或其他页面描述语 言，打印机并不一定进行打印，但打印机的状态指示灯将闪烁。如果打印机是PostScript打印机，可以使用下面命 令来测试：

# lptest | a2ps -q -o - > /dev/lpt0

    这需要预先通过Packages Collection安装好a2ps软件，其中使用的-q参数表示不输出a2ps 的状态信息，-o -参数表示向标准输出输出转化后的PS数据，如果没有使用这个参数，则a2ps直接将PS数 据发送给lpr命令，由于此时打印系统还未设置完毕，因此需要直接输出到打印机端口上以进行测试。

    当这个测试正常之后，就可以尝试使用lpr命令来打印文档了。当然此时打印系统的设置还没有完成，缺省的设置 并不一定适合每个计算机。应该调整打印设置，使得打印系统适合本系统。

  • 打印机配置文件printcap

    当并口和打印机连接正确之后，可以进行下一步配置/etc/printcap文件了。在BSD打印系统中，使 用这个printcap文件来定义打印机，包括命名打印机、将打印缓冲区和具体的打印机相联系等。下面的例子中配置了 两个打印机，一个为本地的LaserJet 6P型打印机，另一个为远程FreeBSD计算机printersvr上 的打印机。

lp|lj|ps|HP LaserJet 6P:\

     :lp=/dev/lpt0:sd=/var/spool/lpd/lp:lf=/var/log/lpd-errs:sh:mx#0:\

     :if=/usr/local/libexec/lpfilter:

rlp|remote printer:\

     :rm=printersvr:rp=lp:sd=/var/spool/output/lpd/printersvr:
     lf=/var/log/lpd-errs:

    从上面的例子可以看出printcap文件的格式：

    printcap中的每行描述由多个部分组成，每个部分用 “:” 分隔；由于对打印机的描述一行写不下，必 须使用反斜杠 “\” 分隔，这是Unix和C语言的标准做法。为了避免出现配置错误等问题，不要在同一个描述部分的 中间续行；

    每行中的第一个描述部分定义打印机的名字，通常可以用多个名字来称呼一个打印机，例如本例中第一个HP LaserJet 6P又有另外的名字lp、lj和ps，这些名字方便用户和不同的程序使用打印机。这些名字之间使用竖线 “|” 分隔，习惯上使用最后一个名字作为打印机的全名；

    每个打印机的各个定义部分定义了打印机的不同属性，定义方式就是上例中使用的方式，定义字符串使用 “=“ ，定义数值使用 “#” 。一个打印机应该具备下面的不同属性：

    lp（local printer）定义本地打印机使用的设备，通常为并口设备/dev/lpt0。

    rm（remote machine）定义远程计算机的名字，这在使用远程打印机时有用。

    rp（remote printer）的值应该为rm定义的远程计算机上的一个打印机名。远程打印机不需要l p来定义打印机端口，但需要使用rm和rp定义，以将打印文件发送到远程计算机上的正确打印机中。这个打印机名应该在 远程计算机中/etc/printcap中进行了定义。如果没有使用rp定义而只使用了rm定义，则使用该计算机上的 缺省打印机。

    sd（spool directory）定义这个打印机使用的缓冲区目录，这个目录一般放在/var/spo ol的下面，并拥有合适的权限设置，以使得打印系统能正确处理缓冲区。系统缺省使用/var/spool/lpd目录 来放置要打印的文件，不同的打印机应使用这个目录下的不同子目录，习惯上这个目录名与前面定义的打印机名字相一致。

    lf（log file）定义与这个打印机相联系的日志文件，记录出现的错误信息，习惯上放在/var/lo g目录下。

    mx（maximum size）定义缓冲区中打印文件的最大尺寸，单位为千字节，缺省值为0，表示不限制打 印文件的大小。

    if（input filter）定义一个输入打印过滤器，过滤器程序用于将用户打印作业的格式转变为打印机 能够识别的格式。

    of（output filter）定义输出过滤器，这也是一个打印过滤器，习惯上使用if的多些，使用of 的少些。如果if和of都没有定义，打印系统则使用缺省的过滤器/usr/libexec/lpr/lpf。

    sh（suppress header），不打印标题页。

    mc（maximum coyies）定义最大的打印份数，缺省为0不限制打印份数。

    br（baud rate）定义串口波特率，只有在使用串口打印机时才有用。

    当将prinrcap文件设置正确之后，就能够使用打印命令lpr来打印文本文件了，由于没有设置打印中文或 图形的过滤器，打印系统只能打印英文文件，它将处理过的文件直接发送到打印机上进行打印。

  • 在PostScript打印机上打印

    大多数打印机不但能打印字符，也能够打印图形，应用软件通过输出控制字符对打印机进行控制。这些控制字符就被 称为打印机控制语言。为了将字符和图形文件输出到打印机上，就需要过滤器将打印文件转化为打印机识别的打印语言。

    打印过滤器是打印程序的一个重要部分，使Unix的打印系统更为灵活，从而能适合各种不同的打印机。除了将文 档转换为打印机识别的语言之外，还可以对要打印的文件做其他处理，例如某些行式打印机需要文档同时使用回车和换行，而 Unix的文本文件只使用换行，此时直接打印文档就会造成行列不齐，这些情况下就需要一个过滤器进行转换。

    打印机控制语言可以分为两类，一种将操纵打印机进行绘图的命令及其他控制命令通过特殊字符（或特殊字符引导的 命令）来表示，对普通字符文件不作处理，直接发送到打印机。此时普通英文字符文件可以直接发送到打印机上打印，但要打 印包括图形在内的文件就是包括特殊控制字符的二进制文件，不能用文本方式进行查看。另一种为Postscript语言 ，它使用页面描述语言来描述要打印的内容，可以直接打印的文件就是一个符合一定语法规则的文本文件，因此对于一个Po stScript打印机来讲，一个普通文本文件只是一个不合乎语法的PostScript语言文件，不能被直接打印。

    因此如果要在仅支持PostScript的打印机上打印普通文档，也必须使用识别PostScript的过滤 器进行转换，首先将普通文本文件转换为PostScript语言，再发送给PostScript打印机进行打印。Fr eeBSD的Packages Collection中专门有一个类别print，提供了很多打印相关的软件包，其中 包括很多种将文本文件转换为PostScript文件的过滤器程序，如a2ps等。其中gb2ps能将GB编码的文本 转换未内嵌中文的PostScript文件，从而能在PostScript打印机上将中文文件打印出来。

    因此首先应该安装这些转换软件包，当安装了这些转换程序之后，最简单的使用方式是先使用他们将文档转换为Po stscript文件，再发送给打印命令lpr，这可以通过管道来实现。一些打印工具内部就包括了使用管道，自动将生 成的Postscript数据发送给lpr命令的指令，下面的a2ps指令就直接将PostScript文件发送给l pr命令。

    $ a2ps file

    或者可以在printcap文件中设置if参数，以自动使用这些过滤器，此时要设置过滤程序从标准输入上读入 数据，将PostScript数据从标准输出上输出。

     :if=/usr/local/bin/a2ps -q -o -:

    对于要使用gb2ps来打印中文文件的情况，由于gb2ps使用参数读入源文件、并输出PostScript 中文文件，不使用标准输入输出，因此不能直接使用gb2ps作过滤器程序，而需要自己使用临时文件保存中间结果，生成 PostSript文件之后再打印。此外，gb2ps输出的PostScript文件都包括一页gb2ps的版权信息 ，对于打印来讲没有必要每次都打印这个版权页，可以使用psutils中包括的psselect程序，从原有文件中去 除第一页，再进行打印。

    高级的过滤器程序应该能够识别各种不同格式的文档文件，并依据文档的格式，使用不同的过滤器功能来进行处理， 最后生成符合打印机描述语言的打印文件。

  • PostScript与Ghostscript

    PostScript使用命令来描述页面，虽然也是文本文件，但这里都是绘图指令，需要一个PostScript 语言解释器对文件中描述的指令进行解释操作，才能得到正确的结果。因此PostScript文件在普通打印机上只 能打印出源文件，同样普通文档在PostScript打印机上也不能正确解释、打印出来。下面是一个PostScript 文件的开始部分：

%!PS-Adobe-3.0

%%Creator: gb2ps

%%CreationDate: Fri Oct 31 18:36:45 1998

%%DocumentNeededResources: font Symbol

%%+ font Courier

%%+ font Times-Roman

%%DocumentSuppliedResources: file images/file.ps

%%Pages: 32

%%PageOrder: Ascend

%%Orientation: Portrait

%%EndComments

%%BeginProlog

    如果要查看PostScript的内容，则需要一个页面语言解释器。虽然存在不少商业PostScript解 释器，但大部分并不见得比Ghostscript好，虽然GhostScript只是一个免费的PostScript 解释器。GhostScript能在X Window下正确显示PostScript文件的内容，并能实现各种强大的 PostScript处理能力。Ghostscript是一个相当复杂的程序，如果仅仅是要查看Postscript 文件的内容，可以使用命令 “gs psfile.ps” ，退出时在Ghostscript提示下输入 “quit ” 即可。

$ gs psfile.ps

Aladdin Ghostscript 5.50 (1998-9-16)

Copyright (C) 1998 Aladdin Enterprises, Menlo Park, CA.  All rights reserved.

This software comes with NO WARRANTY: see the file PUBLIC for details.

GS> quit

    另外，Ghostscript有一个前端程序Ghostview，能使用Ghostscript来浏览PostScript 文件，但使用了比较简单的图形操作方式。Ghostscirpt和Ghostview都可以通过Packages Collection 安装。

  • 在非PostScript打印机上打印

    通常非PostScript打印机使用特殊的ESC序列来表示命令，而对普通文本不做特殊处理，因此文本文件 仍然被看作文本文件，能够直接打印文本文件，因此这些非PostScript的打印机能够直接设置为普通的文本打印机 来使用。

    然而要想充分发挥打印机的能力，打印包括图形在内的文档，就必须有能理解这台非PostScirpt打印机使 用的控制语言的过滤器。这些过滤器就相当于Windows下的打印机驱动，应该由生产这台打印机的厂商提供。但是很多 低档打印机是专门为使用DOS或Windows的计算机生产的，没有为Unix配置过滤器，因此在这些打印机上打印图 形就遇到了困难。幸运的是，Ghostscript能够识别很多种打印机，并能将PostScript文件在指定的设 备上打印出来。

    因此在前面的操作中生成了Postscript文件之后，就可以使用Ghostscript在一台非Post Script打印机上打印PostScript文件，下面文件将在一台Laserjet4打印机上打印test.ps 文件。

# gs -sDEVICE=ljet4 -sOutput=/dev/lpt0  test.ps

使用gs -help能列出一系列Ghostscrit支持的设备文件，有些是打印机设备，
有些是代表不同的图形格式的伪设备。

$ gs -help

Aladdin Ghostscript 5.50 (1998-9-16)

Copyright (C) 1998 Aladdin Enterprises, Menlo Park, CA.  All rights reserved.

Usage: gs [switches] [file1.ps file2.ps ...]

Most frequently used switches: (you can use # in place of =)

 -dNOPAUSE           no pause after page   | -q       `quiet', fewer messages

 -gx  page size in pixels   | -r  pixels/inch resolution

 -sDEVICE=  select device         | -dBATCH  exit after last file

 -sOutputFile= select output file: - for stdout, |command for pipe,

                                         embed %d or %ld for page #

Input formats: PostScript PostScriptLevel1 PostScriptLevel2 PDF

Available devices:

   appledmp iwhi iwlo iwlq hl7x0 bj10e bj200 bjc600 bjc800 lbp8 lips3 m8510

   uniprint la50 la70 la75 la75plus lj250 declj250 ln03 ap3250 epson eps9mid

   eps9high lp8000 lq850 epsonc st800 stcolor lp2563 dnj650c deskjet djet500

   cdeskjet djet500c cdjcolor cdjmono cdj500 cdj550 cdj670 cdj850 cdj890

   cdj1600 laserjet ljetplus ljet2p ljet3 ljet3d ljet4 lj4dith cljet5

   lj5mono lj5gray pj pjetxl pjxl paintjet pjxl300 pxlmono bbox pxlcolor

   ibmpro jetp3852 imagen cp50 necp6 oce9050 oki182 okiibm r4081 sj48 xes

   bmpmono bmp16 bmp256 bmp16m ccr cgmmono cgm8 cgm24 sxlcrt dfaxhigh

   dfaxlow faxg3 faxg32d faxg4 bit bitrgb bitcmyk cif miff24 inferno jpeg

   jpeggray mgrmono mgrgray2 mgrgray4 mgrgray8 mgr4 mgr8 pcxmono pcxgray

   pcx16 pcx256 pcx24b pcxcmyk pdfwrite plan9bm pbm pbmraw pgm pgmraw pgnm

   pgnmraw pnm pnmraw ppm ppmraw pkm pkmraw pngmono pnggray png16 png256

   png16m psmono psgray psrgb pswrite epswrite sgirgb t4693d2 t4693d4

   t4693d8 tek4696 tiffcrle tiffg3 tiffg32d tiffg4 tiff12nc tiff24nc tifflzw

   tiffpack x11 x11alpha x11cmyk x11cmyk2 x11cmyk4 x11cmyk8 x11gray2

   x11gray4 x11mono nullpage

Search path:

   . : /usr/local/share/ghostscript/5.50 :

   /usr/local/share/ghostscript/fonts

For more information, see /usr/local/share/ghostscript/5.50/doc/Use.htm.

Report bugs to ghost@aladdin.com, using the form in Bug-form.htm.

    从这些简单的名字中很难判断那个设备对应于自己的打印机型号，为了找出正确的设备文件名，需要阅读Ghost script的文档device.txt，或者选择相近的设备名并反复尝试。如果万一找不到自己的文件名，也许要升级 Ghostscript的版本，或者更新自己Ghostscript的设备驱动之后再重新安装Ghostscript 。

    当能够使用Ghostscript打印文档之后，就需要将它和FreeBSD的打印过滤器集成在一起了，因此 首先要将打印的文档转换为PS文档，然后将PS文档转换为打印机支持的格式，因此就需要更改过滤程序。例如在一个EP SON行式打印机上输出文档，使用的标准过滤应该是，最后两个短横线表示标准输出和标准输入：

#! /bin/sh

a2ps -q -o - | \

gs -sDevice=epson -sOutfile=- -

  • 使用 apsfilter配置打印机

设置打印机要手工编辑/etc/printcap文件，安装并配置各种过滤器，安装Ghostscript等。这些操作都非常烦琐，幸好FreeBSD通过Ports Collection提供了一种自动配置打印机的apsfilter程序。

Ports Collection的机制、用法将在后面讨论。

为了使用apsfilter设置打印机并配置过滤器，就需要执行下列命令：

# cd /usr/ports/print/apsfilter/

# make install

    然后，系统将自动下载、编译安装必要的过滤器软件，此后将自动启动一个设置程序，通过菜单提示让用户选择打印 机的各种属性，包括打印机的类型、端口、分辨率、纸张大小等等。最后将自动生成合适的printcap文件和各种过滤 器。这些过滤器能分辨要打印文件的类型，进行正确的处理。

    apsfilter生成的过滤器是调用包括ghostscript在内的大量其他软件，因此上面的make过 程就需要从网络上下载必要软件包，可以通过预先安装相应的Packages以减少下载任务。如果网络太慢，下载过程可 能会出现问题导致软件安装问题，后面会讲到如何为Ports Collection手工下载必要的软件包。

  • 使用和控制打印机

    当一切都配置正确之后，使用打印机就非常简单了。为了自动启动lpd守护进程，需要将/etc/rc.con f文件中的lpd_enable项设置为lpd_enable=”Yes”，FreeBSD在下次系统启动时会自动启 动lpd。当lpd没有启动时，也不需要重起计算机，简单使用root身份执行lpd就可以启动这个守护进程。有了l pd守护进程，打印系统就能正常进行打印工作，并能针对整个网络上的用户，提供打印服务了。

    使用者可以直接使用lpr命令打印文件，或者通过管道来使用lpr命令。

$ lpr hello.c

$ ls | lpr

    如果系统中某个打印机没有配置打印过滤器，用户可以直接使用自己的打印过滤器，通过管道将输出送到lpr中。 这提供了一种较灵活的配置方式，使得用户不需要root权限，也能使用合适的打印机过滤器。下面是一个使用gs打印文 件的例子：

$ gs -dNOPAUSE -q -sljet4 -sOutputFile=\|lpr -- tt.ps

    注意这个例子中使用反斜线取消竖线的特殊含义，将其和紧随其后的lpr一起作为参数发送给gs，gs再将其解 释为管道操作。可以将上面的文件编制成shell程序，这样每次就能更方便的使用。

    当使用lpr将打印作业放入打印缓冲区之后，就能使用lpq命令来查看打印队列的内容：

$ lpq

waiting for lp to become ready (offline ?)

Rank   Owner   Job  Files                 Total Size

1st    user    1    hello.c                151 bytes

2nd    user    2    (standard input)      3359 bytes

3nd    user    3    (standard input)     43765 bytes

    在这个例子中，由于打印机lp没有被正常连接到系统上，因此lpq在第一行提醒使用者当前打印机不正常。由于 这台打印机工作不正常，因此用户可能不想使用这个打印机进行打印了，而想通过其他打印机进行打印。为了避免在这台打印 机正常之后，仍然打印这个作业，需要将这个打印作业删去。这可以通过命令lprm加上作业序号（显示在lpq中第三列 ）来完成：

$ lprm 1

dfA001freebsd.domain dequeued

cfA001freebsd.domain dequeued

    或者使用all作参数，这将删除该用户的所有打印作业。用户只能删除自己的打印作业，只有root才能删除其 他用户的作业。如果root使用all参数，那么将会将这个打印机缓冲区中的所有打印作业全部清空。

    作为系统管理员，需要进一步的能力来管理打印守护程序。BSD风格的打印系统使用lpc来执行这个功能，以 root身份启动lpc，则进入lpc的交互模式，然后使用help命令可以得到管理命令的列表。一般可以使用start all 命令来启动所有的打印机，或者使用stop lp命令来停止一台名为lp的打印机。

# lpc

lpc > start all

    也可以用命令行的方式使用lpc，例如重新启动所有的打印机，使用带参数的lpc发出以下命令：

# lpc restart all


FreeBSD连载(31)：系统日志

王波

系统日志与备份

    由于FreeBSD是一个多用户系统，那么就需要管理员进行日常维护，特别是用做网络服务器的系统，一旦因为 缺乏维护而造成停机故障，就会造成很大损失。即使对于单用户的FreeBSD系统，同样也要执行这些不可缺乏的维护任 务，只是由于系统归个人使用，那么对维护的要求就不必那么高，维护任务就轻松一些。

  • 系统日志

    系统的日志记录提供了对系统活动的详细审计，这些日志用于评估、审查系统的运行环境和各种操作。对于一般情况 ，日志记录包括记录用户登录时间、登录地点、进行什么操作等内容，如果使用得当，日志记录能向系统管理员提供有关危害 安全的侵害或入侵试图等非常有用的信息。

    BSD提供了详细的各种日志记录，以及有关日志的大量工具和实用程序。这些审计记录通常由程序自动产生，是缺 省设置的一部分，能够帮助Unix管理员来寻找系统中存在的问题，对系统维护十分有用。还有另一些日志记录，需要管理 员进行设置才能生效。大部分日志记录文件被保存在/var/log目录中，在这个目录中除了保存系统生成日志之外，还 包括一些应用软件的日志文件。当然/var目录下的其他子目录中也会记录下一些其他种类的日志记录文件，这依赖于具体 的应用程序的设置。

$ ls /var/log

adduser            maillog.5.gz     sendmail.st.1

dmesg.today        maillog.6.gz     sendmail.st.10

dmesg.yesterday    maillog.7.gz     sendmail.st.2

httpd-access.log   messages         sendmail.st.3

httpd-error.log    messages.0.gz    sendmail.st.4

kerberos.log       messages.1.gz    sendmail.st.5

lastlog            messages.2.gz    sendmail.st.6

lpd-errs           messages.3.gz    sendmail.st.7

maillog            messages.4.gz    sendmail.st.8

maillog.0.gz       messages.5.gz    sendmail.st.9

maillog.1.gz       news             setuid.today

maillog.2.gz       ppp.log          setuid.yesterday

maillog.3.gz       sendmail.st      userlog

maillog.4.gz       sendmail.st.0    wtmp

  • 系统登录日志

    系统会保存每个用户的登录记录，这些信息包括这个用户的名字、登录起始结束时间以及从何处登录入系统的等等。 它们被保存到/var/log/lastlog、/var/log/wtmp和/var/run/utmp文件中，这 三个文件以二进制格式保存了这些用户的登录数据。

    其中/var/run/utmp文件中保存的是当前系统用户的登录记录，因此这个文件会随着用户进入和离开系 统而不断变化，而它也不会为用户保留很长的记录，只保留当时联机的用户记录。系统中需要查询当前用户状态的程序，如 who、w等就需要访问这个文件。utmp可能不包括所有精确的信息，某些突发错误会终止用户登录会话，当没有及时更新 utmp记录，因此utmp的记录不是百分之百的可以信赖的。

    而/var/log/wtmp保存了所有的登录、退出信息，以及系统的启动、停机记录，因此随着系统正常运行 时间的增加，它的大小也会越来越大，增加的速度依赖于系统用户登录次数。因此可以利用这个日志用来查看用户的登录记录 ，last命令就通过访问这个文件来获得这些信息，并以反序从后向前显示用户的登录记录，last也能根据用户、终端 tty或时间显示相应的记录。ac命令同样也使用wtmp中的数据产生报告，但它的显示方式不同。它可以根据用户（ac -p） ，或按日期（ap -d）显示信息，这样管理员就能获得一些非常有用的反常信息，如一个平时不太活跃的用户 突然登录并连接很长时间，就有理由怀疑这个帐户被窃取了。

    注意：X Window由于会同时打开多个终端窗口，因此会使得用户登录连接时间迅速增加。

    lastlog文件保存的是每个用户的最后一次登录信息，包括登录时间和地点，这个文件一般只有login程 序使用，通过用户的UID，来在lastlog文件中查找相应记录，然后报告其最后一次登录时间和终端tty。然后， login程序就使用新的记录更新这个文件。

    这三个文件是使用二进制格式保存的，因此不能直接查看其中的内容，而需要使用相关命令。当然也可以通过程序来 访问这三个文件，这就需要了解它们使用的数据结构。其中utmp和wtmp使用同样的数据结构，而lastlog使用 另外一个数据结构，可使用man来进行查询具体结构。如果系统的用户数量很多，那么wtmp文件的大小会迅速增加，在 系统/var文件系统空间紧张的情况下，就导致这个文件系统被占满。系统不会主动控制这个文件的大小，因此这需要管理 员的干预，需要手工及时清除，或编写shell脚本定期保存和清除。

    系统还可以提供记账统计的功能，要打开系统的计账功能，需要使用accton命令，注意，accton必须跟 随记账日志文件的名字作参数，而不带参数的accton将关闭记账进程。

    当打开了记账功能后，可以使用lastcomm来检查在系统中执行的所有命令的信息，包括执行的命令、执行命 令的用户、用户使用的终端tty，命令完成的时间，执行时间等。从lastcomm的输出也能帮助管理员检查可能的入 侵行为。

    此外可以使用ac命令来查询用户的连接时间的报告，sa命令来查询用户消耗的处理器时间的报告。

  • Syslog日志记录

    最初，syslog只是为了sendmail而设计的消息日志工具，由于它提供了一个中心控制点，使得sys log非常好用和易配置，因此当今很多程序都使用syslog来发送它们的记录信息。syslog是一种强大的日志记 录方式，不但可以将日志保存在本地文件中，还可以根据设置将syslog记录发送到网络上的另一台主机中。

    支持syslog方式的系统启动了syslogd守护进程，这个程序从本地的Unix套接字和监听在514端 口（UDP）上的Internet套接字，来获得syslog的记录。本机中进程使用syslog系统调用发送来sy slog记录，然后由syslogd将他们保存到正确的文件或发送到网络上另一台运行syslogd主机中去。

    syslogd的设置文件为/etc/syslog.conf，定义消息对应的相应目标，一条消息可以达到多 个目标，也可能被忽略。

#       $Id: syslog.conf,v 1.9 1998/10/14 21:59:55 nate Exp $

#

#       Spaces are NOT valid field separators in this file.

#       Consult the syslog.conf(5) manpage.

*.err;kern.debug;auth.notice;mail.crit          /dev/console

*.notice;kern.debug;lpr.info;mail.crit;news.err /var/log/messages

mail.info                                       /var/log/maillog

lpr.info                                        /var/log/lpd-errs

cron.*                                          /var/cron/log

*.err                                           root

*.notice;news.err                               root

*.alert                                         root

*.emerg                                         *

!ppp

*.*                                             /var/log/ppp.log

    syslog.conf的配置可以分为两个部分，第一部分用于区分消息的类型，另一个用于设置消息发送的目的 地。通常，消息的类型包括消息的产生者，例如kern表示内核产生的消息，auth表示认证系统产生的消息，等等，还 包括消息的级别，例如emerg表示非常重要的紧急信息，alert表示系统告警状态，crit表示关键状态，err 表示一般的错误信息，warning表示警告信息，notice表示提示信息，但还不是错误，info表示一般信息， debug表示调试信息等，因此一个消息的类型可能为：kern.debug、mail.info等，但页可以使用通 配符*进行匹配。

    从上面的syslog.conf的设置可以看出，系统正常运行中的很多重要的信息，如错误信息*.err、内 核调试信息kern.debuf、认证报告auth.notice等被直接输出的console中，另外还有一些比较 重要的信息被输出到/var/log/messages文件中，发送邮件的记录将被保存在/var/log/mail log文件中，打印记录为/var/log/lpd-errs等，使得管理员可以根据这些文件来查询相关记录，进行统 计或寻找系统问题。其中使用syslog记录的messages文件中包括root登录的信息、用户多次登录失败的尝 试等对系统安全相当重要的信息，因此也是系统遭受攻击之后，攻击者会根据syslog.conf中设置试图清除相关文 件中自己的登录记录。因此对于安全性要求更高的系统，可以尝试将syslog发送到另一台计算机上，或者输出到一些设 备文件中，如在打印机上立即打印输出。

    系统会使用newsyslog定期检查syslog输出的messages文件和maillog文件，将旧数 据压缩保存为备份文件，如messages.1.gz等。

  • 其他日志

    除了系统登录记录和syslog记录之外，其他还有一些应用程序使用自己的记录方式。

    系统每天都会自动检查系统的安全设置，包括对SetUID、SetGID的执行文件的检查，其结果将输出到/ var/log/security.today文件中，管理员可以与/var/log/security.yeste rday文件对比，寻找系统安全设置的变化。

    如果系统使用sendmail，那么sendmail.st文件中以二进制形式保存了sendmail的统计 信息。

    在系统启动的时候，就将内核的检测信息输出到屏幕上，这些信息可以帮助用户分析系统中的硬件状态。一般使用d mesg命令来查看最后一次启动时输出的这个检测信息。这个信息也被系统保存在/var/log/dmesg.tod ay文件中，系统中同时也存在另一个文件dmesg.yesterday，是上次的启动检测信息，对比这两个文件，就 可以了解到系统硬件和内核配置的变化。

    lpd-errs记录了系统中lpd产生的错误信息。

    此外，各种shell还会记录用户使用的命令历史，它使用用户主目录下的文件来记录这些命令历史，通常这个文 件的名字为.history（csh），或.bash-history等。


FreeBSD连载(32)：系统备份

王波

系统备份

    不管系统是多么可靠，总会发生一些意想不到的事情，致使系统数据丢失。例如硬件故障或人为操作失误等。因此使 用备份来保护数据不丢失是一种非常重要的手段，尤其在系统数据非常重要的时候。经常进行数据备份能够减少偶然破坏造成 的损失，保证系统能够从错误中恢复正常运行。

  • 备份策略

    在进行备份之前，首先要选择使用的备份策略，这将决定何时需要进行备份，以及出现故障时进行恢复的方式。通常 使用的备份方式有三种：

    完全备份：每隔一定时间就对系统进行一次全面的备份，这样在备份间隔期间出现数据丢失等问题，可以使用上一次 的备份数据恢复到前次备份时情况。这是最基本的备份方式，但是每次都需要备份所有的数据，并且每次备份的工作量也很大 大，需要太多的备份介质，因此这种备份不能进行的太频繁，只能每隔一段较长时间才进行一次完整的备份，例如以一个月为 一个备份周期。但是这样一旦发生数据丢失，只能恢复到上次备份的数据，这个月内更新的数据就有可能丢失。

    增量备份：首先进行一次完全备份，然后每隔一个较短时间进行一次备份，但仅仅备份在这个期间更改的内容。当经 过一个较长的时间后再重新进行一次完全备份，开始前面的循环过程。由于只有每个备份周期的第一次进行完全备份，其他只 进行改变的文件的备份，因此工作量小，就能够进行更频繁的备份。例如以一个月为一个周期，一个月进行一次完全备份，每 天晚上0点进行这一天改变的数据备份。这样一旦发生数据丢失，首先恢复前一个完全备份，然后按日期一个一个恢复每天的 备份，就能恢复到前一天的情况。这种备份方法比较经济。

    更新备份：这种备份方法与增量备份相似，首先每月进行一次完全备份，然后每天进行一次更新数据的备份。但不同 在于，增量备份是备份该天更改的数据，而更新备份是备份从上次进行完全备份后更改的全部数据文件。一旦发生数据丢失， 可以使用前一个完全备份恢复到前一个月的状态，再使用前一个更新备份恢复到前一天的情况。这样做的缺点是每次作小备份 工作的任务比增量备份的工作量要大，但好处在于，增量备份每天都有备份，因此要保存数据备份数量太多，而更新备份则不 然，只需保存一个完全备份和一个更新备份就可以恢复故障以前的状态。另外在进行恢复工作时，增量备份要顺序进行多次备 份的恢复，而更新备份只需两次恢复，因此它的恢复工作相对简单。

    增量备份和更新备份都能以比较经济的方式对系统进行完全备份，在这些不同的策略之间进行选择不但与系统数据更 新的方式相关，也依赖于管理员的习惯。通常在系统数据更新不是太频繁的话，可以选用更新备份的方式。但是如果系统数据 更新太快，使每个备份周期后面几次更新备份的数据量已经相当大，这样使用更新备份已经不太经济了。这时候可以考虑增量 备份或混用更新备份和增量备份的方式，或者缩短备份周期。

  • 操作磁带设备

    FreeBSD下SCSI接口的磁带设备文件名为/dev/rsa0或/dev/nrsa0，其中n代表非回 卷类型，每次在nrsa0上存储数据之后磁带没有回卷，这样就能在磁带中保存多次备份。而rsa0设备在每次保存数据 并关闭磁带时会回卷，这样只能存储一次备份。由于磁带容量大，一次不会用完一个磁带的容量，因此一般使用nrsa0设 备，以进行多次备份。

    3.1-release之前使用老SCSI驱动程序的磁带设备为st，对应的设备文件就为rst0和nrst 0，而非SCSI的磁带设备有rwt0，rft0，分别为IDE和软盘控制器接口的磁带设备。

    n表示非回卷模式，r代表raw方式，代表字符设备。而sa为磁带设备的驱动程序名。0表示设备序号，如果有 多个磁带，下一个设备将为rsa1。

    一般使用/dev/nrsa0作为备份设备，因为这个设备是非回卷的，那么每次备份之后磁带仍然停留在最后移 动的位置上，这样就可以在下次备份时接续往磁带中写入，使用一个磁带进行多次备份。但是如果读取具体的备份，必须使磁 带卷到具体备份的起始位置才行。需要回卷磁带要使用mt命令来完成。

    # mt /dev/nrsa0 rewind

    回卷磁带到最开始地方；

    # mt /dev/nrsa0 reten

    先向前卷到尾部再回卷磁带，保持磁带前后松紧一致；

    # mt /dev/nrsa0 fsf 1

    跳到下一个备份文件，使用2将跳到下面第二个文件；因此要定位一个磁带上第4次备份的文件，可以使用rete n回卷磁带，再使用fsf 4跳到第4个备份。

    每次使用mt均需使用mt来确定磁带的位置，一般的应用程序并不能自动确定文件的开头，而在磁带上每两个备份 文件当中必然有一段无用的数据，如果再读完一个备份之后立即去读取下一个备份文件，就不能识别这些备份文件之间的无用 信息，必然导致报告错误。

  • 使用tar进行备份

    选定了备份方式之后，可以使用tar、cpio、dump等备份工具软件将数据备份到磁带上。对于一般的备份 ，使用tar就足够了。tar的参数有：

    参数c是创建备份（Create）

    参数v表示回显模式（Verbose），将产生一系列所备份的文件列表

    参数f指定使用的备份文件，它后面的参数为输出的备份文件名

    参数x是展开备份文件

    参数t是显示备份文件的内容

    参数T后面跟随一个文件参数，指定从这个文件中读取要备份的各个文件的路径

    参数z是使用压缩方式创建和解开备份文件，这是GNU的新版tar的功能，需要同时安装gzip

    如果不使用T参数，那么就需要一个参数，指明进行备份文件和目录的路径

    这些选项参数可以使用Unix下的标准参数符号 “-” 进行引导，如 “-c” 、 “-f” 等，大部分 参数都是单独使用的参数，而有些如 “-f” 、 “-T” ，其后面还要跟随一个文件名作参数。因此可以将单独的参 数写在一起，如 “-cv” 就等同于 “-c -v” ，也可以与一个需要参数的选项写在一起，如 “-cvf f ilenam” 就等同于 “-c -v -f filename” 。如果不使用 “-” 引导参数，tar也能识 别这些命令选项。如 “tar tvf filename” 就等同于 “tar -cvf filename” 。 tar能够创建备份文档，能够备份到磁带上或者产生一个文件，如：

    # tar cf root.tar /root

    将/root目录下的所有文档备份到root.tar文件中，root.tar指定输出的备份文件，/roo t指出要做备份的目录。如果要备份到磁带上，将输出的备份文件指定为磁带设备文件即可：

    # tar cf /dev/nrsa0 /root

    如果设置了环境变量TAPE，则可以不使用参数f指定输出磁带设备名字。

    # TAPE=/dev/nrsa0; export TAPE

    # tar c /root

    从备份文档中解出所有文件或某个文件，只需要使用x选项替换前面的c选项，例如从磁带中解出hello.c文 件：

    tar xv hello.c

    列出tar备份文档中的内容，可以使用t选项，tar tv将列出磁带上的所有文件内容，而tar tf r oot.tar将root.tar文件上的内容列出。

    tar本身不支持文件压缩，因此创建的文件要比较大。但tar可以和GNU的压缩软件gzip合作，直接生成 压缩文件，所需要的是在参数中增加z选项。压缩的备份文件和普通tar备份是不同的，因此凡是压缩的备份操作，均需使 用z参数。如：

    # tar czvf root.tar.gz /root

    # tar xzvf root.tar.gz hello.c

    # tar tzvf root.tar.gz

    要进行增量备份和更新备份，必须找出那些文件在这个期间进行更新。这个任务可以由程序find来完成，例如查 找过去七天更改的文件，并使用tar的-T参数制定进行备份的文件，进行备份：

    # find / -mtime -7 -print > /tmp/filelist

    # tar -c -T /tmp/filelist -f /dev/nrsa0

    由于要使用find来找出需要备份的文件列表，那么就需要使用文件的修改时间进行查询，需要使用-mtime 参数。另一个更有用的参数是-newer，可以查找出所有比某个文件更新的文件，由于备份是周期进行的，因此可以在完 全备份之后生成一个标记文件，那么所有比这个文件新的文件都需要进行更新备份。

    # find / -newer full_back_tag_file -print > /tmp /filelist

    进行备份需要定期执行，不能完全依赖于管理员手工进行备份。备份也应该选择在系统比较空闲时进行，以免影响系 统的正常处理任务。通常可以选择半夜0:00点之后进行备份，这样更不能将这个任务由管理员手工完成了。Unix提供 了定时服务cron，能够在确定的时间中执行一系列任务，因此备份必须和cron合作来完成，或者使用/etc下的d aily，weekly，monthly文件定时操作。


FreeBSD连载(33)：DOD参考模型

王波

第4章 网络配置与使用

    60年代末，美国国防部（DOD）对建立分组交换的广域网很感兴趣，其基本想法是通过连接多个地域的分散网络 ，那么局部地区的网络故障不影响其他部分网络的正常运行。主要是由于当时正处于冷战的形势下，他们要求建立能够在部分 地区被袭击的情况下，仍正常运行的军事网络。

    研究机构ARPA开始了这个称为ARPAnet的网络项目的研究，由于这个项目要求在不同的计算机之间进行通 信，而不同的计算机上会运行不同的操作系统，因此就存在不同系统之间如何按照同样的规则进行交流的问题。因此最重要的 问题就是开发所有的系统都遵守的标准协议，让它来实现应用程序对应用程序的通信，并独立于具体的计算机平台。因此，他 们开发了独立于特定计算机系统的标准协议，以实现各种计算机之间的通信。

    由于存在多种应用程序，因此协议也并非一个，而是一组协议。而TCP协议和IP协议就是他们开发的这些协议中 最重要的两个，因此通常就以TCP/IP来称呼整个协议族，称为TCP/IP协议，这正是当前流行的Internet 使用的协议标准。

    TCP/IP的成功与BSD Unix分不开的，由于TCP/IP是平台独立的，而当时大学的研究机构主要使 用BSD Unix，因而加州大学伯克利分校最先在BSD Unix中实现了TCP/IP。于是这一技术很快推广到使 用BSD Unix的大学中，TCP/IP得到迅速推广，越来越多的网络使用这个协议，越来越多的网络也通过这个协议 进行了互联，逐渐形成了今天的Internet。

  • DOD参考模型

    参考模型是关于计算机之间如何进行通信的一种形象化表示方式，它将进行通信所需要的每一步骤按照层次的概念组 织起来。如果一个步骤处理的事情是负责物理线路的具体传输，就认为属于模型中的低层，反过来，如果一个步骤是与具体的 应用程序打交道，就认为属于模型中的高层，在高层和低层之间按照逻辑关系，还有一些中间层次。

    将通信过程划分为不同层次的原因是因为通信过程是一个复杂的过程，对于用户来讲，能使用WWW浏览信息，能发 送电子邮件就能满足需要，他们只关心这些应用程序，而不关心具体的通信过程；另外一些软件驻留在后台处理通信过程中必 要的任务，如建立连接，发送数据等，而不关心数据是如何发送出去的；还有一些硬件专门用来负载信号的传递；这样不同的 软硬件有着层次分明的调用关系，自然就形成了层次的概念，而参考模型正是对这些层次进行区分和定义。

    在参考模型中，数据的物理传送是由应用程序──属于模型的最高层，向低层传送，直至具体传输数据的传输协议层 ，由这个层将数据通过物理介质──如电缆、光缆、微波等传送到目的计算机。当数据到达目的计算机时，它沿模型向上传递 ，最终到达目的计算机中的应用程序。这个过程就是传送数据的物理过程。

    可以使用一个简单例子来解释这个通信过程。例如朋友之间互相传递信函是另一种较容易理解的通信过程，这个过程 中有寄信者、收信者、邮递员、邮车等等。由寄信者将信交给邮递员，邮递员处理信件之后将信通过邮车发到对方的城市，对 方城市的邮递员再将信交给收信者。这样就可以将这个过程按层次划分，寄信者和收信者可以看作一个层次，他们使用邮政服 务，可以看成应用层；所有层次的邮政员工是一个层次，进行具体的处理通信工作，可以称为通信层；而邮车可以看成另一个 层次，处理具体发送邮件工作，称为传输层；这只是一个简单例子，具体网络通信过程则要复杂的多。

    从上图可以看出，虽然物理数据的传送是先从上到下，再从下到上回到另一台计算机的应用程序中，如果不考虑低层 是如何进行具体处理的，就可以将通信看成在每一层与另一个计算机中的相应层之间进行的。这样在每层与另一台计算机相应 层之间就存在逻辑上的连接通信和传递数据的能力。如果还使用前面的寄信的例子来说明的话，就是寄信者只考虑收信者，收 信者也只考虑寄信者，而不管邮递员是如何处理信件的，在逻辑上就是朋友之间的通信关系。

    这样用逻辑通信的方式将数据传送归结到各层中的协议上，每一个协议只定义了完成通信的一个任务，成功的完成整 个通信过程要求多个协议协同进行，这些协议将分属参考模型的不同层次，而且每个协议只与对方相应的协议通信，而不需考 虑整个通信过程，这样复杂的通信过程就得到了简化，从而能更容易实现。

    按照对网络的不同理解，可以有不同的参考模型，将通信分为不同的层次结构，其中影响最大的就是国际标准化组织 开发的OSI标准七层模型和TCP/IP中使用DOD四层模型。

    DOD模型的四层分别为：

    • 应用层（Application）

    • 主机到主机层（Host to Host）

    • 网络互连层（Internet）

    • 网络访问层（Network Access）

  • 网络访问层

    TCP/IP并没有定义任何网络访问层的协议，这个层的协议大部分是由其他通信组织定义的，这反而使TCP/IP 能适合几乎全部硬件平台。网络访问层和硬件相关，负责基本的通信，这一层最常见硬件的是以太网和使用普通电话线的 拨号连接。对于以太网，这一层定义了介质访问控制地址（MAC地址），用于标识不同的计算机。有了网络访问层，计算机 之间就有了物理连接，计算机之间就为相互交换数据提供了条件。

    在FreeBSD下，网络硬件是以网络界面（Interface）的形式存在的，如果计算机的网卡被正确探测 到的话，则就有一个相应的网络界面。例如第一个3C905网卡的网络界面是xl0，第一个Ne2000兼容网卡网络界 面是ed0，使用内核级PPP驱动的ppp网络界面为ppp0等。这些网络界面都对应于内核中的硬件驱动程序，只有在 硬件被检测到之后，这些网络界面才能被正常使用。除此之外，还有一个本地环路网络界面lo0，这使得即使没有任何网络 界面的硬件存在，也能使用FreeBSD运行网络程序为本机提供网络服务。

  • 网际层（Internet层）

    Internet层负责确定一台计算机能在网络上的位置，并找出通向它的路径，然后才能够相互交换数据。这种 路径选择功能既复杂又重要，因此实现这个功能的IP协议是整个TCP/IP协议组中的最基本协议。

  • IP地址

    IP协议给每个计算机都分配了一个唯一的IP地址，这个地址是一个分为四部分的32位长的数，每个部分为8位 ，使用点将其分开，例如192.168.1.64，这样IP地址就表示的比较清晰；每个IP地址被划分为两个部分，一 个为网络地址（Network Address），用于表示计算机所在的子网络，一个为节点地址（Node Addr ess），用于标识计算机在子网络中的位置；网络地址和节点地址通过网络掩码（netmask）进行区分，对应网络掩 码二进制位为一的IP地址部分为网络部分，其他的为节点部分。

    例如网络掩码255.255.255.0（16进制形式为0xffffff00）将192.168.1.64 的网络部分分为192.168.1和64两部分，因此其网络地址为192.168.1.0，节点部分为0.0.0.6 4。这个IP地址在FreeBSD下可以写作192.168.1.64/255.255.255.0或者192.16 8.1.64/24，后面一种形式和前一个是等价的，表示子网掩码的二进制位中前面为1的位共有24位，即255.2 55.255.0。

    同一个网络中的网络地址应该相同，但节点地址应该不同，因而子网掩码可以决定这个网络中可以拥有的TCP/I P主机的数量，即节点地址的范围减2，其中节点地址二进制位全为0的地址为网络地址，表示这个网络本身，而节点地址二 进制位全为0的地址为广播地址，用于在网络中发送广播包。

    在IP协议中，为了便于管理，为不同种类的IP地址定义了缺省的网络掩码，而定义的具备不同网络掩码的IP地 址就组成不同的网络类别。

    A类网络：1.0.0.0到127.0.0.0，缺省网络掩码为255.0.0.0，每个网络可以容纳16, 777,214台计算机；

    B类网络：128.0.0.0到191.0.0.0，缺省网络掩码为255.255.0.0，每个网络可以容 纳65,534台计算机；

    C类网络：192.0.0.0到223.0.0.0，缺省网络掩码为255.255.255.0，每个网络只 能容纳254台计算机；

    其他的IP地址属于D、E、F类地址，被IP协议保留用在了mutlicast等其他方面。

    这样划分的目的是为了让IP地址可以同时满足要求不同IP地址数量的大型网络和小型网络的需要。然而随着In ternet的发展，IP地址开始变得紧张起来，当前已经提出了IPv6标准，以扩展IP地址的范围，解决地址紧张的 问题。当前绝大多数网络还没有支持IPv6，因此完全转向IPv6还是一个漫长的过程，这也是FreeBSD不将比较 成熟的FreeBSD IPv6计划──KAME，包括入FreeBSD发行版本的原因之一。当前主要使用另一种IP 地址转换技术（NAT, Network Address Translete）来解决IP地址紧张的问题。

  • 路由

    有了IP地址，计算机就能确定在它在网络上的位置。当一台计算机要和另外计算机通信时，它首先必须知道对方的 IP地址，如果该IP的网络地址和它相同，两台计算机就处在同一个子网上，能通过网络访问层进行通信。直接通过IP地 址请求获得对方的MAC地址，以通过网络访问层进行通信，这需要通过另一个协议──ARP协议，从IP地址获得对方的 MAC地址。

    如果两台计算机不在同一个网络内，就需要一些特殊的计算机──路由器的帮助，才能将IP数据包发送到对方计算 机上。当两台计算机不在同一个网络内时，计算机将查看自己的路由表，找出通往对方的合适路由器的IP地址，将IP数据 包发送给这台路由器，由各级路由器负责将IP包发送到目的地。因此一台计算机要想和子网外的计算机通信，至少要知道一 台路由器，由这台路由器负责将数据发送到子网外，通常称这台路由器为缺省网关（default Gateway）。

    那么，路由器就必须了解到通往其他子网的通路，这些路径可以通过route命令由管理员手工加进去，也可以通 过路由器之间相互交换数据，使路由器学习到更多的路由信息。路由器之间交换路由数据的协议主要有RIP、OSPF、B GP等协议。FreeBSD也能很好的支持这些路由交换功能，因此FreeBSD也是用做软件路由器的最佳选择。

  • DNS与名字解析

    通常IP地址不易记忆，实际使用中是通过使用主机名来标记一台计算机，而主机名可以自动转换为IP地址，再进 行实际的连接。主机名与IP地址的对应关系可以配置在主机名配置文件/etc/hosts中，但在网络上更普遍的是通 过DNS协议，将对应关系保存在网络上多台名字服务器（DNS server）中，这样就能通过名字服务器来维护自己 组织机构的名字解析数据。

    由于网络上不同的计算机属于不同的网络和组织机构，因此计算机的名字可以分为区分组织的域名（Domain Name）和在组织内区分计算机的主机名，形成一种多级的结构。例如一台计算机的名字为wb.example.com .cn，其中wb为主机名，example.com.cn为域名，其中example代表工作的单位，com是类别代 码，代表这个单位是公司机构，cn是国别代码，代表这个机构位于中国。

  • 主机-主机层

    这一层负责维护不同计算机上的两个进程的通信，它的主要作用就是将应用程序与网络的复杂性相隔离，应用层只需 发出请求，而不必顾及任务是如何完成的。这一层包括两个协议：传输控制协议TCP和数据报协议UDP。

    TCP协议是一种面向连接、有分组顺序控制和差错控制的安全准确的协议，因此必须在网络上传送额外的维护信息 ，网络开销大，但也是最常用的网络协议。TCP协议在不同机器之间建立了虚拟连接，它使用一个16位的端口地址（po rt number）来区分不同连接。应用程序必须使用一个或几个端口地址用来提供网络服务，因此对于常用的网络服务 ，其使用的端口地址就是固定的。FreeBSD下在/etc/services就定义了一些常用的端口地址。

    UDP协议不建立连接，因此也不保证数据正确完整，相对来讲网络开销小，然而对于不可靠的网络连接，数据完整 性无法保证。UDP也使用端口地址发送和接受属于不同应用程序的数据。

  • 应用层

    应用层就是为了让应用程序在不同的计算机上运行并相互通信而实现的多种协议，每种协议都对应一类应用程序。并 且随着Internet上的应用程序的不断增加，应用协议的种类也越来越多。在/etc/services文件中定义 的每一行就对应一个固定端口，就可能对应于一种应用程序类型。除此之外还有很多非标准应用程序，当然一个系统中并不会 同时运行所有种类的应用程序。

    大部分TCP/IP应用程序是属于客户机/服务器类型的，这种类型的应用程序包含两个部分，其中服务器程序通 常运行在服务器系统的后台，称为守护程序（daemon）。守护进程运行在后台，随时接受客户连接以提供服务；客户软 件就是应用程序的用户接口，用户通过它使用服务器上的资源。

    由于希望在需要的时候服务器能立即提供服务，这样就需要启动大量并不常用的守护进程运行在系统中，就浪费了系 统资源。因此Unix使用一个超级守护程序inetd来监控这些不常用到的服务请求。只有在inetd接到客户程序的 连接请求后，才启动相应的应用服务程序进行处理，这样系统中就不必运行过多的守护进程了，从而节约系统资源。inet d的配置文件为/etc/inetd.conf，管理员必须配置这个文件，以便指定系统提供那种服务。

#

# Internet server configuration database

#

#	@(#)inetd.conf	5.4 (Berkeley) 6/30/90

#

ftp	stream	tcp	nowait	root 	/usr/libexec/ftpd	ftpd -l

telnet	stream	tcp	nowait	root 	/usr/libexec/telnetd	telnetd

shell	stream	tcp	nowait	root 	/usr/libexec/rshd	rshd

login	stream	tcp	nowait	root 	/usr/libexec/rlogind	rlogind

finger	stream	tcp	nowait	nobody	/usr/libexec/fingerd	fingerd -s

#exec	stream	tcp	nowait	root 	/usr/libexec/rexecd	rexecd

#uucpd	stream	tcp	nowait	root 	/usr/libexec/uucpd	uucpd

#nntp	stream	tcp	nowait	usenet	/usr/libexec/nntpd	nntpd

comsat	dgram	udp	wait 	root 	/usr/libexec/comsat	comsat

ntalk	dgram	udp	wait 	root 	/usr/libexec/ntalkd	ntalkd

#tftp	dgram	udp	wait 	nobody	/usr/libexec/tftpd	tftpd /tftpboot

    inetd.conf中的第一列为使用的端口地址，通常在/etc/services中进行定义，第二列和第 三列为连接种类，stream为tcp连接，dgram为udp，第四列可以为非daemon方式启动的进程配置为n owait，为以daemon方式启动的进程设置为wait。然后为执行程序的用户，要执行的程序位置和要执行的程序 命令及其参数。


FreeBSD连载(34)：手工配置网络
王波
基本网络设置

    在FreeBSD系统中，网络能力十分重要，对于一个标准的FreeBSD系统，至少要有一个网络界面以便与 其他计算机通信。最常见的网络界面为以太网卡。此外FreeBSD也支持Token Ring和FDDI，以及普通电 话拨号连接、ISDN、ATM等广域网连接方式。在计算机网络领域内最常使用的连接方式是本地多台计算机使用局域网互 联，再通过一台专用计算机与广域网连接，因此一个计算机最常使用的是局域网连接方式，并且局域网是永久连接方式，设置 十分简单。

    FreeBSD对网卡的支持是在系统内核中实现的，要使一个网卡工作正常，就需要系统内核拥有这个网卡的驱动 ，并配置好它占用的硬件资源。为了保证网卡被正确的检测到，应该使用dmesg来查看系统的检测信息。

    使用sysinstall可以完成最基本的网络配置，可以配置主机名、域名、IP地址、缺省网关、DNS服务 器等。配置的这些内容被写入系统的配置文件rc.conf中保留下来。当系统安装完成之后，在sysinstall的 网络配置界面下试图重新配置网络时，由于网络正在运行，sysinstall将提示 “Running multi- user, assume that the network is already configured?” 此 时需要回答No，表明需要重新设置网络，才会进入配置界面。

  • 手工配置网络

    使用sysinstall进行网络配置的优点是所有的网络数据将在同一个界面下进行设置，不容易发生错误和遗 漏现象。但熟练的Unix用户在平时维护系统的时候更喜欢使用手工配置，因为手工配置有很多优点：

  • 熟悉命令之后，手工配置更快速，并且不需要重新启动；

  • 能够使用配置命令的高级特性；

  • 更容易维护配置文件，找出系统故障；

  • 能更深刻的了解系统配置是如何进行的。

    仅仅使用sysinstall进行设置，不可能对系统设置有深刻的了解，因而一旦发生问题，就容易束手无策。 对于管理员来讲，不能被动的仅仅停留在能够使用和操作的阶段，而是要了解系统是如何进行工作的，才能更好的进行系统维 护和管理。因而需要使用命令行方式。一旦熟悉之后，就会发现命令行才能提供全部灵活的操作能力，而全屏幕方式限制很多 ，过于呆板。

  • 配置计算机名字

    每个系统都应该有一个名字，这个名字通常在系统安装时确定，可以使用hostname命令来获得当前系统的名 字。同样设置计算机的名字也需要使用hostname命令，但这需要root权限：

# hostname wb.example.com.cn

# hostname

wb.example.com.cn

  • 配置网络界面

    网络界面实际就是网卡的驱动程序，操作系统使用它与网络硬件打交道，而配置网络界面的操作应该通过 命令ifconfig来完成。理解了IP协议之后，使用ifconfig设置网络界面相当简单。

# ifconfig  xl0  inet  192.168.1.64  netmask  255.255.255.0 up

    其中xl0标识一个3c905B的网络界面，inet为inetnet的简写，标识IP协议，FreeBSD也支持其他几种协议， 如ipx、atalk等。设置本网络界面地址为192.168.1.64，网络掩码为255.255.255.0，up表示将这个网络界面运行 起来。通常不需要这么复杂的写法，简单的使用下面命令将使用缺省网络掩码配置这个网络。

# ifconfig  xl0  192.168.1.64

    使用down参数可以简单停止网络界面的工作：

# ifconfig xl0 down

    此外，还可以在一个网络界面上捆绑上多个IP地址，第二个及其之后的IP地址可以使用alias参数 指定，如果不再想使用这个地址，可以使用delete命令删除这个ip别名。

# ifconfig xl0 192.168.100.100 alias

# ifconfig xl0 delete 192.168.100.100

    ifconfig的另一个重要的作用是用来观察当前网络的所有界面的配置状态，-a参数将列出所有界面 的配置信息。更改配置之后最好使用这个命令查看效果。

# ifconfig -a

xl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500

        inet 192.168.1.64 netmask 0xffffff00 broadcast 192.168.1.255

        ether 00:90:27:4e:f6:67

        media: autoselect

        supported media: autoselect 100baseTX <full-duplex> 100baseTX
10baseT/UTP <full-duplex> 10baseT/UTP

lp0: flags=8810<POINTOPOINT,SIMPLEX,MULTICAST> mtu 1500

tun0: flags=8050<POINTOPOINT,RUNNING,MULTICAST> mtu 1500

sl0: flags=c010<POINTOPOINT,LINK2,MULTICAST> mtu 552

ppp0: flags=8010<POINTOPOINT,MULTICAST> mtu 1500

lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384

        inet 127.0.0.1 netmask 0xff000000

    上图显示的信息包括各个网络界面，如以太网界面xl0，并行口界面lp0，用于ppp拨号的tun0和ppp0界 面，用于slip拨号的sl0界面等各个网络界面的设置数据。

    对于点对点的PPP界面，ppp0或tun0，通常要求指定另一端的IP地址，如果没有另一端的IP地址，就不 能正常设置网络，事实上PPP软件会自动完成这些设置，而不需手工执行ifconfig。

# ifconfig  tun0 inet 10.10.1.42 10.10.1.29

  • 配置路由表

    在同一个局域网上的计算机是直接连通的，但是不同的网络上的计算机并没有直接相连，只能通过一 台特殊的专用计算机-路由器来完成连通。路由器连接有多个网络界面，每一个网络界面连接到一个相应的网 络上，有一个相应的IP地址。而网络内部的计算机要向外连接，必须通过路由器进行转接，因此计算机必须知 道路由器的IP地址。

    缺省网关就是一个网络中的最基本的路由器，负责几乎所有的向外连接任务。假设缺省网关的地址为 192.168.1.254，则设置缺省网关的命令为：

# route add default 192.168.1.254

    更复杂的情况下，网络中可以有多个路由器，每个路由器负责到一些网络的转发任务，因此应该在计算机 中配置这个网络上所有路由器及这些路由器负责的网络的路由数据。可以使用route命令增加到各个网络的静态路 由数据，其中-net参数是一个可选参数，否则route从所给予的IP地址中判断它是网络还是计算机，同样可以指定 -host参数为一个远程计算机指定路由。

# route add -net 192.168.10.0/24 192.168.1.253

# route add -net 192.168.20.0 192.168.1.253

    这个语句将在路由表中增加到网络192.168.2.0和192.168.3.0的路由，其中ip地址后面的24用于指示网 络掩码，它代表二进制方式的网络掩码前面非0位的长度，24个非0位的掩码等价于255.255.255.0。如果没有指 定网络掩码，route就使用该ip对应的缺省网络掩码。

    设置完路由表之后，可以使用netstat -r命令来查看当前的路由表的内容。

# netstat -r

Routing tables

Internet:

Destination        Gateway            Flags     Refs     Use     Netif Expire

default            192.168.1.254      UGSc        1      941      xl0

127.0.0.1          127.0.0.1          UH          1      644      lo0

192.168.1          link#1             UC          0        0      xl0

192.168.1.254      0:e0:1e:ce:85:a9   UHLW        2        0      xl0

192.168.1.64       0:90:27:4e:f6:67   UHLW        1        6      lo0

192.168.1.253      link#1             UHLW        2        0      xl0

192.168.10         192.168.1.253      UGSc        0        0      xl0

192.168.20         192.168.1.253      UGSc        0        0      xl0

    除了显示到达其他网络的路由器之外，路由表中，还能显示出到达本地网段计算机的方式，例 如link#1表示通过第一个网络界面，也能显示直接连接的其他主机的MAC地址。

  • 保存配置

    上面的命令都是立即生效的命令，但是并没有将信息写入配置文件中，因此要想让系统重起之后配置仍 然有效，就必须更改配置文件/etc/rc.conf。这里可以设置主机名，各个网络界面的属性，以及各个路由设置等。

hostname="wb.example.com.cn"

network_interfaces="xl0 ppp0 lo0"

ifconfig_xl0="inet 192.168.1.64  netmask 255.255.255.0"

ifconfig_ppp0="inet 10.10.1.42  10.10.1.29"

ifconfig_lo0="inet 127.0.0.1"

defaultrouter=”192.168.1.254”

static_routes=”static_route1 static_route2”

static_route1=”-net 192.168.10.0/24 192.168.1.253”

static_route2=”-net 192.168.20.0/24 192.168.1.253”

    其中network_interfaces定义了多个网络界面的名字，此后相对应的ifconfig_xl0等项的值是相应的 ifconfig的参数。同样static_routes参数也使用相同方式，来定义多个静态路由。

  • 配置名字解析

    在Inetnet发展的早期，仅仅使用主机名配置文件来作主机名/IP之间的映射，这对于互连的计算机较 少时十分有效，而随着相连的计算机的增多，hosts文件会越来越大，如果用当前Internet上的计算机数量去 衡量的话，使用hosts文件根本不可能。

# cat /etc/hosts

127.0.0.1	 	localhost

192.168.1.64 	wb.example.com.cn  wb

192.168.1.254 	gateway

192.168.1.253	gateway2

192.168.1.252	gateway3

202.102.245.49	www.online.ha.cn

    因此人们发展了一种分级的方式管理名字与IP地址对应关系，称为域名解析系统。在这个系统中采用 一种分级结构，每个组织负责自己的域及通过这个域内的名字服务器，对域内的计算机名字和IP地址的对应关 系进行维护，每个域内还可以划分为几个不同的子域，子域由子域内的名字服务器负责解析，这样就降低了维 护任务的复杂程度。通过标准协议DNS，Internet上所有的名字服务器可以相互交换数据，这样每台计算机都能 通过查询名字服务器来查询Internet上所有的计算机名字。

    要使用域名解析系统DNS，当用作普通的DNS客户时，只需配置/etc/resolv.conf文件，指出所使用的名 字服务器。

# cat /etc/resolv.conf

domain example.com.cn

nameserver  192.168.1.250

nameserver  192.168.2.210

    这个配置文件指出本机使用的域为example.com.cn，这样如果查名字www，将会首先使用 www.example.com.cn作为全名。这里定义了两个名字服务器，第一个为192.168.1.250，第二个为 备用名字服务器192.168.2.210。

    注意，因为此时还不能通过DNS查询名字，因此这里要使用IP地址而非主机名来指定名字服 务器。

    由于可以同时使用/etc/hosts主机文件和/etc/resolv.conf中配置的DNS服务器都能进行计算机名字与IP 地址之间的转换，就可以规定查找的顺序，在/etc/host.conf文件中规定了进行名字转换时查找的顺序。

bind

hosts

    系统缺省设置的顺序如上，第一行为bind，（Berkeley Internet Name Domain）这是DNS域名系统 的标准实现，第二行为hosts，因此这表示先查找DNS服务器，然后再查找本机中的文件hosts。由于从DNS 服务器上查找名字可以得到域名的全部信息，因此如果本机具备DNS名字的情况下，应该设置为查找DNS服 务器优先。

    虽然一般DNS名字解析速度并不会造成太大的影响，但如果本地的DNS反应较慢或者这台FreeBSD计 算机的名字没有登记到DNS服务器上，那么服务器试图查找本机名字的行动就影响网络应用程序的连接速 度，造成很多依赖于主机名的应用程序启动非常缓慢，为了加速计算机名字解析速度，可以更改这个文件 设置为先查找本机文件优先。

  • 使用基本网络工具

    当配置好网络之后，就可以使用系统提供的网络程序来访问网络，如使用ftp来从远程计算机上下载 文件、telnet登录上远程系统等。FreeBSD下不但提供了这些普通的网络应用程序，而且还提供了相当丰富网 络工具，帮助进行判断网络状态，发现网络故障。

    最基本的查看本地网络设置的程序，包括前面提到的设置程序ifconfig、route，以及查看网络状态 的程序netstat。还有另外的一些程序，可以用来判断网络连接状态。

    前面提到的netstat的用法是使用-r参数来获得路由器的信息，而不使用这个参数启动netstat将报告 当前的连接状态，包括TCP/IP连接和Unix socket连接。

# netstat

Active Internet connections

Proto Recv-Q Send-Q  Local Address          Foreign Address        (state)

tcp        0      2  wb.online.ha.cn.telne www.1030                ESTABLISHED

tcp        0      0  wb.online.ha.cn.49157 wcarchive.cdrom..20    ESTABLISHED

tcp        0      0  wb.online.ha.cn.1139  wcarchive.cdrom..ftp   ESTABLISHED

tcp        0      0  wb.online.ha.cn.telne www.1029                ESTABLISHED

tcp       56      0  wb.online.ha.cn.1138  wcarchive.cdrom..ftp   CLOSE_WAIT

tcp        0      0  wb.online.ha.cn.telne www.1028                ESTABLISHED

tcp        0      0  wb.online.ha.cn.telne www.1027                ESTABLISHED

tcp        0      0  wb.online.ha.cn.1101  email.9999             ESTABLISHED

Active UNIX domain sockets

Address  Type   Recv-Q Send-Q    Inode     Conn     Refs  Nextref Addr

f458af00 dgram       0      0        0 f4571fc0        0 f458ae40

f458ae40 dgram       0      0        0 f4571fc0        0 f458af40

f458af40 dgram       0      0        0 f4571fc0        0 f458af80

f458af80 dgram       0      0        0 f4571fc0        0 f458afc0

f458afc0 dgram       0      0        0 f4571fc0        0        0

f4571fc0 dgram       0      0 f45705c0        0 f458af00        0 /var/run/log

    可以使用ping来判断与远程计算机是否能够连通。

$ ping ftp.freebsd.org

PING wcarchive.cdrom.com (209.155.82.18): 56 data bytes

64 bytes from 209.155.82.18: icmp_seq=1 ttl=240 time=520.726 ms

64 bytes from 209.155.82.18: icmp_seq=2 ttl=240 time=773.465 ms

^C

    要想知道这台计算机是怎样和远程计算机相连接的，可以使用traceroute来获得从本机达到远 程计算机所经过的路由器，以及到达各个路由器的开销等信息。

$ traceroute www.pku.edu.cn

traceroute to sun1000e.pku.edu.cn (162.105.254.12), 30 hops max, 40 byte packets

 1  202.102.245.1 (202.102.245.1)  1.078 ms  0.862 ms  0.850 ms

 2  202.102.235.165 (202.102.235.165)  157.337 ms  157.957 ms  174.054 ms

 3  202.97.26.217 (202.97.26.217)  134.037 ms  57.994 ms  55.602 ms

 4  1S7-rtr1-r-1-hbwh.cn.net (202.97.26.165)  274.626 ms  120.154 ms  580.097 ms

 5  202.97.10.113 (202.97.10.113)  623.421 ms  888.556 ms  794.748 ms

 6  6A05-rtr2-c-1-bjbj.cn.net (202.97.1.189)  411.728 ms  247.819 ms  245.688 ms

 7  202.97.9.1 (202.97.9.1)  762.538 ms  945.893 ms  920.904 ms

 8  202.97.8.254 (202.97.8.254)  1181.508 ms  1107.783 ms  374.649 ms

 9  1F0-rtr1-r-1-bjbj.cn.net (202.97.2.14)  960.674 ms  635.770 ms  700.182 ms

10  202.97.16.190 (202.97.16.190)  391.926 ms  214.433 ms  721.839 ms

11  * 202.112.63.100 (202.112.63.100)  313.066 ms *

12  * * *

13  * * beijing-rgw-lan.cernet.net (202.112.1.66)  434.928 ms

14  * * *

15  * 202.112.5.194 (202.112.5.194)  282.973 ms  340.009 ms

16  sun1000e.pku.edu.cn (202.112.7.12)  827.202 ms * *

    由于traceroute会在网络上产生大量的数据流，因此一般不要频繁使用这个命令，以免造成无谓的 网络流量。

    为了获得从一个计算机名字获得其IP地址，或者从IP地址得到计算机名字，可以直接使用nslookup来 查询DNS服务器。

$ nslookup ftp.freebsd.org

Server:  ns.hazzptt.net.cn

Address:  202.102.224.68

Non-authoritative answer:

Name:    wcarchive.cdrom.com

Address:  209.155.82.18

Aliases:  ftp.freebsd.org

$ nslookup 209.155.82.18

Server:  ns.hazzptt.net.cn

Address:  202.102.224.68

Name:    wcarchive.cdrom.com

Address:  209.155.82.18

    nslookup不仅能用于查询普通的IP地址，还可以查询其他更复杂的DNS信息，如某个域的名字服务 器的地址，邮件服务器地址等。


FreeBSD连载(35)：串口和modem

王波

拨号网络

    局域网上的FreeBSD要和Internet（或其他广域网）连接，就需要使用广域网界面。对于一般用户， 采用普通电话线进行拨号的方式，是比较常见的做法。这就需要首先使用计算机的串口连接到modem（调制解调器）上， 再通过modem连接到Internet上。

  • 串口和modem

    因此如果采用拨号方式连接一台计算机到远端，则必须配置好计算机的串口和modem。

    个人计算机一般有两个串口，在DOS下称为COM1、COM2，FreeBSD使用Unix的习惯从0开始排 列数字，相应的串口硬件为sio0、sio1。启动时系统将自动检测这些硬件，检测结果显示在屏幕上，可以在登录后使 用dmesg来查看这些启动信息，判断硬件是否真的被检测到了。如果串口被检测到，就能使用连接到相应串口上的外置 modem进行连接。

    如果使用内置modem卡，卡上将包括一个串口设备，根据这个卡的设置，这个串口设备可以为sio2或sio3 ，因此必须保证内核支持第三、第四个串口设备sio2和sio3。但与DOS不同的是，modem卡使用的IRQ不 能与已有串口共享硬件资源。由于DOS是单任务操作系统，不可能同时使用两个串口，共享IRQ是可以的，因此COM1 与COM3共享IRQ 4，COM2与COM4共享IRQ 3。但是对于多用户操作系统FreeBSD来讲，同时会有 多个进程访问设备，每个设备必须单独占有IRQ，因此必须在内核中将modem卡的IRQ设为另外的空闲值。

    要更改卡上的跳线或在DOS下运行设置程序更改卡上的设置，以使硬件上设置与内核配置相一致。通常PNP的 modem卡能正确设置硬件资源，也可以通过UserConfig重新设置。

    当FreeBSD的内核检测到串口设备之后，就能够通过相应的设备文件来访问这些串口了。对应第一个串口sio0 的设备文件为/dev/ttyd0和/dev/cuaa0，对应第二个串口sio2的设备文件为/dev/tty d1和/dev/cuaa1，依次类推。

    FreeBSD对一个串口提供了两个设备文件，事实上它们对应同样的硬件，只是属性略有不同。cuaa0主要 用来拨出，ttyd0主要用于拨入和直接连接。设置这两个设备文件的原因是计算机与modem相互通信的数据有两类， 一种为计算机通过串口发送给modem的控制指令，常用的为Hayes的AT指令，这些数据是发送给modem的，而 另一种数据是计算机通过modem发送到电话网上的传输数据，这些数据只需要让modem进行调制解调即可。而对于应 用程序来讲，要想非常简单的来区分这两种数据，就可以使用两个初始状态不同的设备文件。

    当外部拨入内部时，电话连接已经设置好了，数据传输是在计算机与电话网之间，modem只进行调制解调，此时 就使用ttyd0。而当向外拨号时，modem还没有建立连接，计算机应该向modem发送指令，控制modem执行 拨号等操作，此时就使用设备文件cuaa0。一旦连接建立之后，系统将重置设备文件的属性，使得cuaa0同样也是将 数据发送向电话网上。

    因此ttyd0和cuaa0这两个设备文件，只是初始状态不同，而并没有本质的差别。事实上大多数拨号软件会 重置设备文件的状态，使用哪个设备都可以正确完成拨号过程。然而习惯的做法仍然是使用cuaa0用于拨出，ttyd0 作为拨入，这样能避免某些软件不能正确重置设备文件的状态的问题。


FreeBSD连载(36)：PPP协议

王波

PPP协议

    通过电话连接使用IP协议有两种协议，一种为SLIP协议，另一种为PPP协议，FreeBSD支持这两种协 议，但是SLIP协议已经过时，当前已经很少有ISP使用这种方式提供接入服务了，而PPP协议则成为了标准。

    建立一个PPP连接需要以下过程：

  • 在PPP的两端建立一条物理连接，通常为电话连接，但也有直接电缆连接或虚拟的tunnel连 接的形式。具体如何建立连接，例如拨号等，并不属于PPP协议本身的任务。

  • 由PPP的服务器端对客户端进行验证，可以有最简单登录的验证方式、PAP或CHAP等验证方式 。由于PAP和CHAP并不在线路上传输口令本身，因此更为安全，不必担心口令会泄露出去。

  • 验证完毕之后，PPP服务器将按照配置，分配给客户IP地址，并将网关地址和其他的一些配 置信息传送给客户。如果是Microsoft客户，还可以按照MS的扩展协议分配给客户NetBIOS名字服务 器的地址。这样就建立了一条PPP连接。

    FreeBSD对PPP提供了两种不同方式的支持，一种为内核级PPP，它将PPP协议代码编译进内核，并运 行一个PPP守护进程pppd，提供对PPP的支持，这是一种传统的方法，但配置起来较困难。另一种为用户级PPP， 它使用一个应用程序ppp，通过通用tunnel设备传递PPP数据，配置较为容易。一般情况下可以使用用户级PPP 来建立拨号方式的Internet连接。

    要建立PPP连接，首先要检查串口、modem和电话线连接是否正确。可以使用一些通信软件来帮助进行诊断， 例如minicom，如果使用minicom能正常拨号，并在拨ISP的拨号服务器时能出现username和password 提示，就说明串口和modem的配置正确无误。接下来就可以配置PPP连接。

  • 用户级PPP设置

    用户级PPP使用tunnel设备进行PPP数据的传递，因此内核中必须支持相应的tunnel设备，通常为 tun0。缺省内核中支持这个伪设备（pesudo-device tun），/dev目录下也具备相应的设备文件t un0。如果同时需要多个拨号连接，就可以增加内核中支持的伪设备数量和相应的设备文件。

    要使用ppp，还需要设置它的配置文件，这些文件位于/etc/ppp目录中。缺省情况下，/etc/ppp 目录下安装了这些文件的例子：

# ls -l /etc/ppp

  total 21

  drwxr-xr-x   2 root     wheel         512 Aug 17 16:18 .

  drwxr-xr-x   8 root     wheel        1536 Aug 29 18:31 ..

  -rw-r--r--   1 root     wheel        5112 May 20 20:06 ppp.conf.sample

  -rw-r--r--   1 root     wheel        1130 May 20 20:06 ppp.conf.server.sample

  -rw-r--r--   1 root     wheel        1894 May 20 20:06 ppp.deny

  -rw-r--r--   1 root     wheel        1665 May 20 20:06 ppp.dialup.sample

  -rw-r--r--   1 root     wheel        1402 May 20 20:06 ppp.linkdown.sample

  -rw-r--r--   1 root     wheel        1422 May 20 20:06 ppp.linkup.sample

  -rw-r--r--   1 root     wheel        1705 May 20 20:06 ppp.pap.dialup.sample

  -rw-r--r--   1 root     wheel         313 May 20 20:06 ppp.secret.sample

    这些以sample结尾的文件都给出了最常用的配置，因此只需复制生成正确的设置文件，再稍加修改， 就能用于使用者自己的拨号连接。

  • 手工拨号

    ppp.conf是用户级PPP的主要配置文件，可以从ppp.conf.sample生成适合自己的ppp.conf。ppp.conf 文件使用带有冒号的标签标识不同的选项，第一项标签通常为default：，用于设置缺省的选项。

default:

 set log Phase Chat Connect Carrier LCP IPCP CCP tun command

 set device /dev/cuaa2

 set speed 115200

 deny lqr

 set dial "ABORT BUSY ABORT NO\\sCARRIER TIMEOUT 5 \"\"
 AT OK-AT-OK ATE1Q0 OK \\dATDT\\T TIMEOUT 40 CONNECT"

    注意default:为这一项的标签，必须位于一行的开始，而其他的行是这一项的具体配置，因此使用一个空白 字符开头。否则语法错误就造成不能ppp不能正常建立连接的问题。

    第一个设置set log用于设置连接过程中要记录的日志内容，这有助于帮助解决连接过程中出现的故障；第二 项设置set device设置连接使用的串口设备，本文件中设为第三个串口cuaa2；第三项设置了串口与mode m的连接速度，115200为PC常用的串口通信芯片UART 16550的最大通信速率；第四项在该medom上屏 蔽线路质量请求lpr；最后一项为发送到medom的一些命令和相应的回应，通常称这些为交谈脚本（chat script ），上例中这个设备跨越了两行，实际上它应该位于同一行内。

    设置了default项之后，就可以进入ppp程序测试这些设置是否正确了。

# ppp

ppp > term

atdt 163

username: pppuser

password:

PPP >

    进入ppp程序之后，输入term命令可以进入终端模式，这个模式下用户可以直接输入modem认可的AT指 令控制modem，本例中使用atdt 163拨接163，连接之后系统将进行提示输入用户名和口令，此后ppp就建 立起PPP连接，而ppp的提示符改变为大写的PPP。

  • 设置拨号连接

    使用手工输入的连接方法不很方便，而且也不适合使用PAP或CHAP等安全认证方式的连接，因此 最好在ppp.conf对指定的连接进行配置。这要求对每个要连接的ISP，都配置相应的设置。例如对CHINANET 的接入，使用下列chinanet标签配置：

chinanet:

 set phone 163

 set login "TIMEOUT 5 ogin:--sername: pppuser word: key123"

 set timeout 120

 set ifaddr 10.0.0.1/0 10.0.0.2/0 255.255.255.0 0.0.0.0

 delete ALL

 add 0 0 HISADDR

    这个例子中使用chinanet作为设置的标签，设置了电话号码为163，登录时使用sername匹配对用 户名的提示Username，接收到这个字符串后自动输入用户名pppuser，使用word匹配对口令的提示Pas sword，然后自动输入口令。这里只使用了提示信息的一部分来进行匹配，这是为了避免匹配时出现问题。对于不同的系 统，这些提示还有所不同，对于使用Unix作登录服务器的提示为通常的Login，而大多数专用拨号服务器的提示为U sername。

    set ifaddr用于设置本地PPP连接的IP地址，由于PPP协议在客户和服务器之间协商客户的IP地 址，通常由拨号服务器从自己控制的自由IP地址池中分配给拨号的计算机一个动态IP地址，因此这里的设置只是客户端对 地址协商进行的限制。可以针对本地要申请的IP地址，和远端计算机的IP地址进行限制，本地的IP地址和网络掩码为s et ifaddr的第一个参数，而远端的IP地址和网络掩码为set ifaddr的第二个参数，前两个参数的网络 掩码是用于限制IP地址所在的网络，可以是真实网络的网络掩码，也可以不是，第三个参数才是用来指定PPP界面使用的 网络掩码。

    一般情况下，不需要对双方的IP地址范围进行限制，拨号之后可以接受任意的IP地址，就如上例中设置本地IP 地址和远端IP地址的限制网络掩码长度都为0，由于网络掩码长度为0使得任意IP地址都符合要求，此时掩码前面的IP 地址就没有意义了。

    如果想让拨号的计算机拥有一个静态IP地址，就必须设置网络掩码为32，明确指定IP地址，此时也可以省略掩 码，直接使用IP地址本身。例如，本地每次连接都使用静态IP地址192.168.1.98，另一端的IP地址为19 2.168.1.64，那么这一项就应为：

    set ifaddr 192.168.1.98 192.168.1.64 255.255.255.0

    使用静态IP地址就能使FreeBSD使用固定的IP地址，从而能使用DNS域名，以方便提供更多的服务。然 而，这个set ifaddr的配置命令可以更灵活，可以在协商IP地址时指定本机使用的IP地址范围，或者指定对方 所在的IP地址范围，进行地址限制。例如：

    set ifaddr 192.168.1.98/24 192.168.1.64/24 255.255. 255.0

    这种限制拨号网络IP地址范围的机制对于使用自动拨号的情况十分有用，通常可以使用带参数的命令ppp -a uto将ppp程序放入后台，一旦有网络请求就立即拨号建立连接。但是FreeBSD上有多个网络界面，就需要判断这 个网络请求需要使用哪个拨号网络界面进行网络传输，否则如果使用错误的拨号网络进行拨号，即使建立了连接，也不能找到 目的计算机建立连接。由于每个连接请求中都具备目的IP地址，便需要根据这个IP地址来进行判断。然而普通的拨号网络 在建立连接之前是没有分配IP地址的，因此还是无法确定对这个IP地址的连接请求应该通过那个拨号网络界面进行传输。 但是，如果指定了ppp网络界面的IP地址范围，就可以根据这个地址范围来判断连接请求中的IP地址是否在这个范围内 ，以决定是否使用这个网络界面进行拨号。

    delete all指出删除不必要的路由配置，add 0 0 HISADDR指出将缺省路由设为对方的地 址，由于使用动态IP时，在建立连接前对方的IP是未知的，因此使用HISADDR代替。如果已知拨号服务器的IP地 址，也可以直接填上这个IP地址。也可以不将拨号服务器作为缺省路由，而只将它作为对某个子网的路由，那么在这个配置 中就不可以使用0作为IP地址和网络掩码，必须使用正确的IP地址和子网掩码进行设置。例如add 192.168. 1.0 255.255.255.0 HISADDR，就将对方作为通向192.168.1子网的路由器。事实上这些 设置路由的指令等价于执行对应的route指令，以设置路由，如route add 192.168.1.0 HIS ADDR -netmask 255.255.255.0。

    然而对于动态分配IP的情况，问题在于在ppp进行拨号的时候，对方的IP地址HISADDR还没有确定，因 此这些设置路由的指令往往不能正确执行。必须在拨号完成，建立了PPP连接之后，HISADDR才能确定，因此设置路 由的命令应该放在更合适的位置：ppp连接建立之后立即执行的文件ppp.linkup中。

MYADDR:

 delete 0

 add 0 0 HISADDR

192.168.1.98:

 add 192.168.1.0 0 HISADDR

chinanet:

 delete ALL

 add 0 0 HISADDR

 !bg /etc/ppp/ppp.fetchemail

    ppp.linkup文件格式与ppp.conf文件相同，它在PPP连接建立后执行，执行与拨号使用的标签 相同的项，以及客户获得的地址为标签的项。通常使用MYADDR表示本机得到的IP地址，因此这个标签下的内容都将执 行；而192.168.1.98项表示获得这个地址时增加下面的路由，最后一项以chinanet为标签，与ppp. conf相同，表示进行这个chinanet拨号后执行的相关动作，其中包括在后台执行的取邮件的脚本ppp.fet chmail。

    如果拨号服务器要求使用PAP或CHAP认证，而不是普通的登录认证方式，则要在ppp.conf中的使用不 同的配置选项：

chinanet:

 set phone 163

 set login

 set authname pppuser

 set authkey key123

 set timeout 120

 set ifaddr 10.0.0.1/0 10.0.0.2/0 255.255.255.0 0.0.0.0

 delete ALL

 add 0 0 HISADDR

    使用authname和authkey来定义PAP或CHAP认证方式下的用户名和口令，就能连接到使用PAP或CHAP 的拨号服务器，而具体使用哪种认证方式则由拨号服务器决定。

  • 进行拨号连接

    设置了针对具体拨号连接的配置之后，拨号就非常方便了，直接使用该拨号服务的标签进行操作。

# ppp

ppp > dial chinanet

PPP >

    使用ppp的dial命令发起连接之后，ppp连接被建立，提示符也由原来的小写ppp>变为大写PPP>， 这就表示PPP连接已经正确设立了。这个时候如果使用ifconfig进行查看，就可以看到网络界面tun0 已经设置正确，并可以使用了。

    当要结束连接时，使用close或quit命令关闭连接。结束连接时将执行/etc/ppp目录下的ppp.linkdown 脚本。ppp.linkdown脚本和ppp.linkup格式相同，都会依据相同的标签执行操作。

    如果使用者租用了一条模拟专线，专门用于Internet连接。这样就不希望每次传输时都重新进行连接，而希 望建立一条永久连接，ppp在后台自动拨号连接到Internet上，并一直维护这个连接。这样就可以使用-ddial 参数启动ppp。

# ppp -ddial chinanet

    -ddial参数使得ppp立即使用相应参数对应标签设置的拨号连接建立永久连接，而不管有没有实际的 数据传输。而绝大多数情况下，使用者并没有租用专线，还是希望在有数据传输时才建立网络连接，在没有 数据传输时断开网络连接，以减少电话连接时间。这样就可以使用-auto参数启动ppp。

# ppp -auto chinanet

    这样启动的ppp将一直停留在后台，但并不立即进行连接，而是在应用程序发出网络请求时才进行拨 号，这个网络请求的目的地址应该在chinanet标签定义的网络地址范围内。而如果一段时间内没有任何数据 传输，就断开连接（这个时间由set timeout命令设置，单位为秒）。

# ppp -backgroud chinanet

    -background选项使PPP立即进行拨号，并停留在后台。但与-auto不同在于，在一段没有数据传输的 时间间隔后ppp将断开连接，但是ppp程序也停止执行，而不象auto参数那样，ppp一直驻留在后台监视网络 连接，要再次建立连接必须重新执行ppp程序。这个选项适合最普通的网络客户，使用户能明确什么时候才 建立连接。

# ppp -alias -ddial chinanet

    ppp程序的另一个有用的选项是alias。如果拨号用户内部有自己的局域网，用户或许希望让整 个网络内的计算机共享一个拨号连接。使用ppp的alias选项能使FreeBSD将局域网上的网络连接请求中的 本地IP地址替换为FreeBSD系统的ppp网络使用的IP地址，从而使其他用户也能访问外部网络。-alias参数 应该和auto或ddial参数联合使用，以驻留在后台提供服务。这种方式比较简洁、易用，当然代理服务器 和网络地址转换的方法能提供更多的控制能力。

    当使用这些参数执行ppp程序时，ppp程序将切换在后台维护PPP连接。然而由于ppp程序在后台运行，就 无法输入指令以控制ppp程序的执行。为了方便使用者控制后台运行的ppp程序，ppp提供了通过socket连接 的方式来接受外部输入。为了支持这个特性，便需要设置set server选项。

    set server 6670 MySecretpassword

    这个选项将使ppp程序监听6670端口，并使用MySecretpassword作为连接时认证的口令，以免ppp程序 被非法控制。此后，就可以使用pppctl向ppp程序发送指令，这些指令都是ppp的标准指令。

# pppctl -p MySecretpassword 6670 set timeout 300\; dial

    除了使用标准的Intenet套接字接收pppctl的连接之外，ppp还能通过本地Unix套接字来接收输入。这 就需要设置一个套接字使用的文件及其访问属性，具备更好的安全性。

    set server /tmp/ppp MySecretPassword 0177

    而在pppctl中应该使用对应的参数以指明相应的Unix套接字：

# pppctl -p MySecretpassword /tmp/ppp set timeout 300\; dial

  • 内核级PPP及拨号程序

    PPP协议只是定义了两台计算机之间如何进行通信的方式，并没有定义如何进行拨号建立连 接。用户级PPP由于以应用程序的方式来实现了PPP协议，因此它可以集成拨号程序，使用起来很方 便。但内核级PPP并非如此，它使用一个守护进程pppd来实现ppp协议，因而必须首先使用外部拨号 程序建立连接。内核级PPP比较难以使用，因此FreeBSD使用者通常使用用户级ppp。

    但是pppd是实现PPP协议的最早方式，其他继承BSD Unix网络代码的Unix系统中也使用这种 PPP实现方式，这样pppd使用的广泛性就不仅局限于FreeBSD。很多使用者对内核级PPP进行封装， 实现了多种图形化的连接工具，假如想使用这些图形化拨号连接工具的话，就需要对pppd有一定了 解。因此这里只对pppd的拨号方式加以简单介绍，事实上使用ppp程序建立连接更为常用和方便。

    用来配合pppd的拨号程序有很多，最常使用的是chat，此外如kermit、tip也可以用于和 pppd进行配合。由于拨号程序要和pppd相互配合，因此需要将要发送给拨号程序的命令放入一个 文件中，而在启动拨号程序时使用相关参数告诉它到该文件中读取命令。

    对于chat拨号程序，通常将它的拨号程序命名为chat.script，放在/etc/ppp目录下。

ABORT BUSY
ABORT 'NO CARRIER'
# Wait up to 5 seconds for the reply to each of these
TIMEOUT 5
'' ATZ
OK ATDT163
# Wait 40 seconds for connection
TIMEOUT 40
CONNECT
TIMEOUT 5
serrname:-\\r-sername: pppuser
assword: 123456

    使用chat -f /etc/ppp/chat.script可以启动chat进行拨号，chat程序等待PPP服务器发送 Username:提示，发送用户名，等待PPP服务器发送Password:提示，发送用户口令。然而，chat程序 只能负责拨号，至于拨号完成之后的任务，就必须由pppd来负责了。

    pppd使用网络界面ppp0，当然可以在内核配置中增添配置值并重新编译核心，就可以根据需 要增加可使用的ppp界面的数量。例如将可以使用的ppp界面改变为3个，则内核配置文件应包括 “ pseudo-device ppp 3” ，这样在重新编译内核，建立相应的设备文件并重新启动后，就可 以使用ifconfig命令来查看可以利用的网络界面：

# ifconfig -a

ppp0: flags=8010<POINTOPOINT,MULTICAST> mtu 1500

ppp1: flags=8010<POINTOPOINT,MULTICAST> mtu 1500

ppp2: flags=8010<POINTOPOINT,MULTICAST> mtu 1500

lo0: flags=8008<LOOPBACK,MULTICAST> mtu 16384

        inet 127.0.0.1 netmask 0xff000000

    内核还可以配置ppp界面在传输时对ppp数据进行压缩，事实上用户级ppp和内核级ppp都支持 传输压缩，但内核级ppp多支持两种方式，一种是ppp的BSD压缩标准，另一种为delalte压缩标准。一 般都可以在内核配置中加上这两个选项，使ppp连接中可以使用这些选项，以提供更高的传输效率。 那么内核配置文件中的ppp相应配置应包括：

pseudo-device   ppp     3

options PPP_BSDCOMP

options PPP_DEFLATE

    内核级ppp使用的配置文件也放在/etc/ppp目录下，文件名为options，此外各个用户可以使 用自己的配置文件~/.ppprc。

# cat /etc/ppp/options

defaultroute

domain example.com.cn

crtscts

modem

deflate 12,12

idle 300

lock

    defaultroute项将在ppp连接设定之后，将缺省网关设置为PPP服务器上；domain设置本机的 域名；crtscts告诉ppp使用modem的硬件流量控制，如果硬件不支持这种方式，就只好使用另一种软 件流量控制方式为xonxoff；modem行使ppp使用DCD信号来判断连接是否正常，有无掉线现象；deflate 使pppd使用defalte压缩方式；idle设置了一个时间限制，当在300秒的时间内没有数据传送，就断 开连接；lock则创建一个锁定文件，其他程序在发现存在这个文件后，就能得知相应的串口已经被使用。

    配置好配置文件之后，就可以使用pppd进行连接了：

# pppd /dev/cuaa1 57600 connect 'chat -f /etc/ppp/chat.script' user pppuser

    缺省情况下，使用pppd命令立即进行拨号连接，在超过idle参数设定的时间内没有数据传送的条 件下断开连接并退出。然而在options文件中可以使用persist参数告诉pppd建立一条永久连接，或者使 用demond参数告诉pppd停留在后台，监视网络数据，一旦有要求就立即进行连网，超时后就断开连接， 但pppd仍然停留在后台等待下次数据传送。这两种形式分别等价于ppp程序的ddial和auto模式。

  • 拨号访问FreeBSD

    FreeBSD不但能够能通过PPP协议和远程拨号服务器相连接，也能够提供拨号服务，让其他计算 机能够拨入本机。事实上PPP协议本身，并不没有区分客户机和服务器，PPP服务器只需要比客户机多完 成一些额外的工作，如用户认证、分配IP等。然而PPP必须建立在已经设定好的连接上，而为了设定连 接，拨号服务器和客户端的设置就有不同的地方。首先在硬件上，服务器上的modem必须能接受连接， 建立物理连接，然后服务器和客户软件要进行额外的验证过程，最后双方才启动ppp，设定ppp连接。

  • 接受拨号终端访问

    早期的Unix使用字符终端访问主机，将字符终端通过串口连接到计算机上之后，就能通过这些 终端登录进Unix系统了。但是FreeBSD下缺省屏蔽了串口的终端登录过程，要完成这个任务，管理员还 必须更改/etc/ttys文件，为串口指定一个getty进程，以监视串口，一旦发现有连接请求，便立即启动 登录进程login接受用户的登录。

    在/etc/ttys中有下面的行是与串行端口相关的，对应于个人计算机的四个串口，使用getty进程 进行监控，但缺省状态为off，并没有打开这个功能。如果要使用某个串口进行终端连接，就需要改变相 应行的设置为on，同时还可以改变第三列中的终端类型设置及最后一列的安全设置。

ttyd0     "/usr/libexec/getty std.9600" unknown   off secure

ttyd1     "/usr/libexec/getty std.9600" unknown   off secure

ttyd2     "/usr/libexec/getty std.9600" unknown   off secure

ttyd3     "/usr/libexec/getty std.9600" unknown   off secure

    getty的第一个参数std.9600指明了串口的各项参数，这个参数在/etc/gettytab中定义 ，定义了如波特率、校验方式、数据位、停止位以及流控方式等。缺省使用9600，指明了连接速率为9600bps，现 代串口连接通常使用的连接速率要比这个设置高，因此要根据自己的串口和modem的型号，选择gettytab中的更 高速率，如std.19200或std.57600。

    更改系统之后，可以使用kill -1 1使FreeBSD重新读取ttys文件，或者重起计算机，才可以使 用终端连接。这时在连接在串口上的终端键盘上按下几次回车键后，字符终端将连接到计算机上，会出现登录提示。如果没有 出现提示，就说明终端设置和使用的gettytab文件中的设置项不匹配，可以更改终端设置或gettytab文件中 的设置，使两者使用的校验、停止位、流控等设置选项保持一致。

    如果没有专用的字符终端设备，可以使用终端仿真软件，如Windows下的超级终端，Unix下的minicom 等，都能通过串口登录到FreeBSD下。

    可以看到，使用串口连接，那么再加上modem和电话，就能够使得远程计算机能连接到这个FreeBSD系统 上了。对于提供登录服务的计算机来讲，并不会注意一个连接是从串口直接相连的，还是通过modem建立的。然而这就要 设置服务器的modem，必须设置为能进行应答，以接通客户计算机打入的电话来设定连接。因此必须首先初始化modem ，需要使用AT命令AT&C1&D2&S0=1&R2&W。可以通过mi nicom或ppp的term模式，直接输入这个AT指令设置modem。

    当双方都配置好串口，连接设置好modem，并且连接上电话线之后，两台远程计算机相连接的准备工作就完成了 。这时可以使用通信软件，例如minicom或kermit，从一台计算机远程登录到另一台计算机上，除了需要拨号， 与本地连接没有什么两样。

  • 设定PPP服务器

    如果远程计算机能正常登录进入FreeBSD，那么说明拨号连接没有问题，那么下一步就是分别配置PPP客 户端和服务器端。事实上对于PPP来讲，建立连接之后，客户端和服务器端就没有区别了，区别在于建立连接的 过程中，服务器要验证用户的登录并为其分配IP地址等。

    使用用户级PPP和内核级PPP均可实现PPP服务器，由于用户级PPP配置起来更为容易，因此更为常用。同样，这 也需要更改配置文件/etc/ppp/ppp.conf。

dailserver:

 allow users

 enable proxy

 set ifaddr 192.168.1.64 192.168.1.123

    以上是一个ppp程序做拨入服务器的设置例子，这个例子中允许普通可以启动这个ppp程序，并打开了代 理ARP功能，使其他计算机能通过这个计算机同客户正常通信，为连接上的客户计算机分配IP地址。

    当ppp客户计算机连接到ppp服务器上之后，通过ppp服务器的路由能力，ppp客户就能和外部计算机通信了。 并且两个ppp客户机之间的通信也必须经过ppp服务器转发。由于在每个ppp客户看来，其他的ppp客户是与它自己位于 同一个网段内，因而它就广播ARP请求询问对方的MAC地址，以便进行直接通信。而在事实上，ppp客户之间并没有物理 连接，它们之间无法直接通信，因而广播的ARP请求也不可能传送给目的计算机。此时，具备代理ARP能力的ppp服务器 就能代替某个客户，回应发送ARP请求的客户。此后这个客户就以为ppp客户的物理地址就为ppp服务器的物理地址，所 有的数据包都先转发给ppp服务器，然后它再转发到另一个ppp客户机中。这个代理内部的计算机回应ARP请求的功能就 被称为Proxy ARP，它能够对外隐藏内部的网络结构，如内部子网或ppp连接。

    同时配置PPP用户的登录脚本为立即启动使用服务器标签的ppp程序，因此一个简单PPP用户登录脚本应为：

#! /bin/sh

exec /usr/sbin/ppp -direct dialserver

    direct参数就用于在标准Unix认证之后，立即启动ppp进程，使客户端直接与服务器端ppp交谈，以建立ppp 连接。这个文件应该是一个可执行的文件，最简单的登录脚本可以让不同的PPP用户共同使用一个拨号服务器标签， 更复杂的情况应该为每个拨号用户都设置独立的选项，并在登录脚本区分用户，启动不同的拨号选项。

    由于getty在接收到连接请求之后，就立即执行login认证过程，因此系统认证提示为Login，而与前面ppp客 户设置中使用Username的认证提示不同，需要修改前面的设置，才能使用前面的认证登录上服务器。但也由于getty 必须执行login认证，因此使用getty作为ppp服务器的端口监控进程，就无法进一步支持PAP或CHAP认证。为了支持这 些复杂的认证方式，就需要使用mgetty或类似的端口监控进程来监视是否有连接请求。

    在FreeBSD的Handbook中有使用mgetty设置ppp服务器的例子。

  • PPP程序的其他功能

    除了最常见拨号连接上Internet之外，还可以利用ppp程序的功能来完成其他几种任务。在缺省的ppp.conf中 给出了几个例子，这些例子能帮助使用者进一步了解ppp程序的能力。

  • 串口线连接

    使用串口线直接连接与使用medom除了不需要拨号之外并无不同，但是通常要在两端都使用LQR，用于 帮助判断电缆的连接情况。此时客户端的ppp.conf中的设置应为：

direct-client:

 set dial ""

 set line /dev/cuaa0

 set sp 115200

 set timeout 900 10 3

 set log Phase Chat LQM

 set login "TIMEOUT 5 ogin:--ogin: ppp word: ppp HELLO"

 set ifaddr 10.0.4.2 10.0.4.1

 enable lqr

 accept lqr

    而ppp服务器应该设置为：

direct-server:

 set timeout 900 10 3

 set log Phase LQM

 set ifaddr 10.0.4.1 10.0.4.2

 enable lqr

 accept lqr

  • TCP上的PPP通道

    可以将PPP建立在TCP网络连接之础上，而非通过电话网络，这样就在TCP/IP网络上建立了一条 PPP通道。tcp-client为客户端计算机的设置，这里使用一个网络连接作为连接设备，tcpsrv为远程计 算机的主机名，1234为tcpsrv上的TCP端口：

tcp-client:

 set device tcpsrv:1234

 set dial

 set login

 set escape 0xff

 set ifaddr 10.0.5.1 10.0.4.1 255.255.255.0

    tcp-server为服务器端计算机的设置：

tcp-server:

 set escape 0xff

 set ifaddr 10.0.4.1 10.0.5.1 255.255.255.0

    当ppp客户端使用tcp-client进行连接时，它将向tcpsrv的1234端口发送ppp连接请求。这就要求 tcpsrv能侦测到对1234端口的连接请求，并启动ppp服务器来建立连接。因此就可以使用inetd监听上面 定义的端口1234，并负责启动ppp服务器。就需要在/etc/services中应该增加相应的端口：

pppsrv		  1234/tcp

并在/etc/inetd.conf中增加相应的选项：

pppsrv 	stream	tcp	nowait	root	/usr/sbin/ppp ppp -direct tcp
-server

    修改好inetd.conf之后，向inetd发送SIGHUP信号使得其重读设置文件。然后就可以使用ppp建 立虚拟连接了。在ssh等加密传输软件的帮助下，还可以进一步设定为安全的虚拟通道连接。

  • 数据包过滤

    在ppp的auto模式下，需要根据超时设置断开连接，但是网络中一些协议会定时发送一些数 据包，这些数据包主要用于保持网络数据的及时更新，大部分情况下不影响网络应用。但是这些数 据包会引起ppp刷新时间设置，从而使得ppp一直保持拨号连接。

    这时可以使用ppp的过滤机制中的afilter过滤器，它定义了在auto模式时应滤掉的数据包， 使得数据包不会影响超时时间。下面的三行分别不允许ICMP包和DNS包通过，最后一行允许其余的包 通过。

    set afilter 0 deny icmp

    set afilter 1 deny udp src eq 53

    set afilter 2 deny udp dst eq 53

    set afilter 3 permit 0/0 0/0

    使用dial参数的情况下，也有相似的限制，这时使用dfilter主要来限制icmp数据包。

    set dfilter 0 deny icmp

    set dfilter 1 permit 0/0 0/0

    另外，还可以使用包过滤能力，按照端口、地址来允许或屏蔽某些TCP数据包。

    set ifilter 0 permit tcp dst eq 80

    set ofilter 0 permit tcp src eq 80

    set ifilter 1 permit 192.168.1.0/24 0/0

    set ofilter 1 permit 0/0 192.168.1.0/24

    ifilter表示对进入的数据包进行过滤，ofilter表示对出去的数据包进行过滤，因此上 面的设置允许进行WWW浏览（80端口），并允许与192.168.1.0这个网段内的计算机进行连接。每 一个过滤器最多可以定义20个规则。

  • 拨号网关

    当一个局域网上的一台FreeBSD通过PPP连接到Internet上之后，其他计算机也能通过这台FreeBSD 访问Internet，从而共享同一条拨号线路。这必须使用ppp的alias选项启动ppp，这样当内部计 算机的数据包到达这台FreeBSD之后，由ppp将这些数据包中的IP地址更换为本机ppp界面上的IP，同时也会 对端口地址进行调整，再发送到外部的Internet上。

    要完成这个任务，还需要将这台FreeBSD配置为允许转发IP数据包，在/etc/rc.conf中配置 gateway的值为YES。但为了使得路由保持正确，不能启动routed或gated等动态路由程序，因为这些程序 会动态更改路由表，如果改动与ppp相关的路由数据，就会使得FreeBSD不能正确路由数据包。

    使用这种连接方式，再加上ppp的简单过滤能力，FreeBSD就能作为一个简易的具备一定防火墙能力的 Internet访问网关，能够提供整个内部网络访问Internet的能力，并将内部网与Internet相隔离。然而 这个简易的拨号网关仅限于使用ppp界面，并且功能也有限。FreeBSD提供了更强大的防火墙能力，能完成要求更为 复杂的各种任务。


FreeBSD连载(37)：DNS的体系结构

王波

DNS服务

    通常，一台计算机只需要配置域名解析就可以了，不需要自己运行名字服务器守护进程，然而有些时候需要设置自己 的名字服务器，这就需要FreeBSD下配置名字服务器BIND（Berkeley Internet Name D omain）。BIND也是由伯克利开发的一个著名软件，它的执行程序为named，运行在Internet上几乎所 有的名字服务器上，构成Internet的名字系统。

    由于普通的客户计算机并不需要运行named，因此在其/etc/rc.conf配置文件中，named_enable 应为NO。当需要运行named以提供DNS服务的时候，就要将这个参数的值改为”YES”。

  • DNS的体系结构

    Internet上的DNS名字服务为一种分布式的体系，由分布在Internet各地的DNS服务器上的named 守护进程为整个Internet提供本域内计算机的名字解析服务。DNS域名结构为分级方式，例如www.online.ha.cn 中最后面的cn为顶级域名，由后向前分别划分为不同级别的域。

    Internet上的顶级域名有两种，一种象cn这样的国别代码，另一种是如同edu、org、net、com 等分类代码。国别顶级域下的次级域名同样可以按照地域或组织结构来分类划分。

    那么要进行名字解析，就需要从域名的后面向前，一级级查找这个域名。因此Internet上就有一些DNS服 务器为Internet的顶级域提供解析任务，这些DNS服务器称为根DNS服务器。知道了根DNS服务器的地址，就 能按级查找任何具有DNS域名的主机名字，BIND代码中就包括了这些根DNS服务器的地址。

    名字服务使用zone的概念来表示一个域内的主机，然而zone与域也有所区别，zone只是域的一部分，而 不是整个域。因为zone中不包括域下的子域。例如域名www.example.org.cn的域为example.org.cn ，这是一个独立的zone。这个域下可由子域组成，例如www.sub.example.org.cn就 属于其子域sub.example.org.cn，子域也是一个独立的zone，并不包括在example.org.cn 这个zone之内，作为域的example.org.cn中就包括sub.example.org.cn子域。

    除了从名字查找主机的IP地址这种正向的查找方式之外，另外还有从IP地址反查主机域名的解析方式。很多情况 下网络中使用这种反向解析来确定主机的身份，因此也很重要。查找名字的反向解析是从前面的网络地址向后面的节点地址， 逐级查找，因此IP地址zone是IP地址的前面部分。然而由于一个主机的域名可以任意设置，并不一定与IP地址相关 ，因此正向查找和反向查找是两个不同的查找过程，需要配置不同的zone。

  • 使用DNS查询工具

    用来进行DNS查询的一个非常有用的工具是nslookup，可以使用它来查询DNS中的各种数据。除了可以 在命令行下直接进行基本的DNS查询之外，直接启动nslookup将进入一个交互模式，这里能查询各种类型的DNS 数据。

    的名字解析数据可以有各种不同的类型，有设置这个zone的参数的SOA类型数据，有设置名字对应的IP地址 的A类型数据，有设置从IP地址反向解析DNS名字的PTR数据，有定义服务与这个zone的DNS服务器的NS数据 ，以及定义主机别名的CNAME数据。这些不同类型的数据均可以通过nslookup的交互模式来查询，需要使用 set type命令设置相应的查询类型。

$ nslookup

Default Server:  ns.hazzptt.net.cn

Address:  202.102.224.68

> set type=ns

> yahoo.com

Server:  ns.hazzptt.net.cn

Address:  202.102.224.68

Non-authoritative answer:

yahoo.com       nameserver = NS2.DCA.yahoo.com

yahoo.com       nameserver = NS5.DCX.yahoo.com

yahoo.com       nameserver = NS.EUROPE.yahoo.com

yahoo.com       nameserver = NS1.yahoo.com

Authoritative answers can be found from:

NS2.DCA.yahoo.com       internet address = 209.143.200.34

NS5.DCX.yahoo.com       internet address = 216.32.74.10

NS.EUROPE.yahoo.com     internet address = 195.67.49.25

NS1.yahoo.com   internet address = 204.71.200.33

>

    这个例子就使用nslookup来查询yahoo.com这个zone的名字服务器，需要将类型设置为ns来执行查询。用 来帮助获得DNS数据的工具还有很多，如dig能迅速返回整个zone的名字解析数据，dnswalk可以用来帮助查询名字 服务器的设置。这些工具都可以用来帮助查找DNS的设置问题。


FreeBSD连载(38)：配置缓冲或转发方式的named

王波

配置缓冲或转发方式的named

    在Internet中主要使用名字进行连接，因此网络中的DNS查询会十分频繁。很多情况下，会有大量且重复 的DNS查询。尤其在使用拨号连接的条件下，由于名字服务器位于ISP端，即使是曾经查询过的名字，其信息仍然保存在 线路的另一端的名字服务器的缓冲区内，重复的DNS查询将占据宝贵的线路带宽。并且DNS查询还往往使得网络连接软件 不能正确获得超时信息，不能适时断开连接以节省电话连接时间。

    因此，最好的办法是将查询结果保存在本地计算机上，以避免重复查询造成的无谓的网络流量。虽然很多TCP/IP 客户机能够在本机内保存一个名字解析缓冲区，但这个缓冲区相对来讲太小了，起不到很有效的作用，然而如果要将这个缓 冲区设置的较大，又不能及时刷新名字解析数据。要想很好的缓冲DNS数据，最好的缓冲区还是DNS服务器本身，因为DNS 的实现方式就是一种经常刷新的缓冲方式，并且named可以根据不同zone的不同设置，来实现数据刷新。

    因此，最简单的办法就是设置一个具备缓冲能力的名字服务器，它将能够用做名字解析的缓冲，这就要需要设置名字 服务器的过程。

  • 在/etc/resolv.conf中，将127.0.0.1作为第一个可选服务器，其他DNS服务器作为备份，使得名字查询通过本地的名字服务器进行，以利用它的缓冲机制；

  • 在/etc/rc.conf中，将named_enable设置为”YES”，允许启动named，rc.conf中有关named的其他选项不需改变；

  • 改变到/etc/namedb目录下，运行make-localhost程序，这将产生针对本计算机的解析数据localhost.rev文件；

  • 修改/etc/namedb/named.conf文件，使其符合一个转发系统的要求。

  • 启动名字服务器，可以使用root身份直接执行named守护进程，并在rc.conf中更改named_enable的设置值。

  • 设置named.conf

    要成功配置named，最重要的一步就是改变配置文件named.conf，一个用于转发的设置文件应为：

options {
        directory "/var/namedb";
        datasize 20M;
        forward only;
        forwarders {
            202.102.224.68
        };
};
zone "." {
        type hint;
        file "named.root";
};
zone "0.0.127.in-addr.arpa" {
        type master;
        file "localhost.rev";
};

    这个设置文件中去除了任何注释项，named中使用与C++相同的注释方式，即用两个斜线来表示一行注释，而 设置语句也类似C的语法。

    第一个语句options用于设置named的参数，directory指明named的工作目录为/etc /namedb，datasize用于设置缓冲区的大小，forward only和forwarders用于指明这 个服务器只是一个转发服务器，并设置转发的名字服务器的地址。这两个转发选项不是必须设置的，不进行设置时named 就能很好的适应解析和缓冲任务。这样名字服务器初始时就从根名字服务器中获得信息，这些信息将保存在named的缓冲 区内，此后就可以查询缓冲区内的相关服务器来获得进一步的名字解析。

    第二个语句用于设置根zone，这用于设置Internet上的根名字服务器，一切本地无法解析的数据将发送 给那些根名字服务器进行解析，设置了工作目录下的named.root文件中记录了这些根名字服务器的地址，记录根名 字服务器的文件名字也可能为root.hints。第三句定义了对127.0.0.0的反向查询的数据，0.0.12 7.in-addr.arpa为一个反向解析zone，其IP地址也是反序排列的，并且使用in-addr.arpa 后缀，而对应的反向解析数据在localhost.rev文件中定义。

    BIND的当前版本为8，之前的版本为4.9.x，它们使用named.boot作为named的配置文件。 大多数Unix版本，包括大多数商业Unix在内，还没有更新他们的名字服务器到当前的BIND 8，仍然运行老版本 的named。但必须注意named.boot文件的格式与named.conf不同，不能混用。BIND 8提供了 很多优秀的特性，因此最好立即升级到新版本。

    named.root文件给出了Internet上的多个根名字服务器，用于初始化named的缓冲区。借助 这些名字服务器的帮助，一台名字服务器能对整个Internet进行查询。一般不需要改变这些文件的内容，但是如果要 建设一个内部网，不与Internet连接，就不需要named.root中的这些根名字服务器的地址，而要更改为自 己网络内的根名字服务器的地址。事实上，没有任何内部网络能和Internet相比拟，需要使用多台根名字服务器来维 护其域名解析系统，直接设置一台或几台名字服务器，并指定客户计算机使用这些名字服务器就满足要求了。

  • zone数据文件的格式

@	IN	SOA	freebsd.example.org.cn. root.freebsd.example.org.cn.  (
                1998012314	; Serial
                3600	; Refresh
                900	; Retry
                3600000	; Expire
                3600 )	; Minimum
    IN	NS	freebsd.example.org.cn.
1	IN	PTR	localhost.

    这是根据计算机的名字和域名产生的localhost.rev文件，这个文件定义了对127.0.0.0这个 反向zone的反向名字解析数据，可以用于从IP地址查询主机的名字。

    第一个设置定义了一个SOA记录，这个类型的记录定义了包含一个zone的开始，并用于设置zone中数据刷 新时间等参数。在这个记录中，@代表一个zone，由于这个设置文件中没有设置它的值，那么它就是named.con f中的定义语句中zone的值，这里就为0.0.127.in-addr.arpa。空白字符分隔之后为IN，这是用 于表示定义的关键字，SOA表示这一行的类型为SOA记录，接下来的freebsd.example.org.cn. 为这台主机的全名，注意，这里以 ”.” 结尾，如果在名字解析配置文件中不以点结尾，named将自动附加上当前 zone的值；此后给出了一个联系用的email地址，这里为root@freebsd.expampleorg.or g.cn，但是由于@在设置文件中有特殊含义，因此使用点代替；

    再后面就是SOA记录的参数，这些参数使用了括号，并分在几行分别设置，这主要是为了使得设置更为清楚，将它 们放在同一行内也可以。SOA记录的参数有序列号，用于标识SOA记录数据 ── 其他名字服务器使用这个数据与自己 缓冲区内的数据对比，来判断这个zone的数据是否更新，否则就没有必要传输全部zone的数据。因此可以使用日期来 表示不同的序列号，以使得更改过SOA记录之后，其他名字服务器能即使刷新数据；刷新时间 ── 用于告诉其他名字服 务器何时来检查zone中的数据是否更新，这里配置为1小时（3600秒），这个时间间隔对于不经常改变的服务器来讲 太小了，应该配置为一天或更大；第三个参数为连接的尝试次数；然后是过期时间，表示一旦某个zone的正式名字服务器 不能提供其服务，其他名字服务器在其缓冲区中保存多久该zone的缓冲数据；最后一个参数指出其他名字服务器缓冲这个 文件内容的最小时间间隔，在这个间隔内不应该刷新该zone的名字解析数据。

    当括号结束之后，这个SOA设置项就结束了。而第二项设置定义了一个名字服务器记录，这个设置直接用空格和IN 开头，表示这一项仍然使用上一项中的设置，这里就是@。NS代表这一项定义是名字服务器类型，最后给出了名字服务器 的名字freebsd.example.org.cn.，表示这个zone的名字解析数据位于这个名字服务器中。

    第三项定义了一个反向查询指针记录PTR，第一列为1，由于没有使用点结尾，因此其全形式应为127.0.0.1 ，第三列PTR表示这个记录为PTR记录，是给定IP地址返回名字的查询形式，最后一列即是127.0.0.1的 名字localhost。


FreeBSD连载(39)：定义自己的名字服务

王波

定义自己的名字服务

    缓冲形式的名字服务只能用于名字查询，但没有定义任何名字数据。如果要想让自己 的网络有一个域名，并为其他计算机都提供服务，就必须使用完整配置的名字服务器。

  • 正向解析zone

    第一步要为自己的子域在/etc/namedb/named.conf文件中定义zone，并修改设置文件 named.conf。在named.conf文件中，首先要删除forward的相关设置，使服务器不仅用于转发 请求，也能拥有自己的名字解析数据库。然后再增加一项新zone的定义：

 zone "bsdgroup.example.org.cn" {
        type master;
        file "db.bsdgroup";
};

    这一项描述了bsdgroup.example.org.cn的zone对应的配置文件为db.bsdgroup。其中 type master表示这台DNS服务器为这个zone的主服务器，对于一个zone来讲，可以由多个DNS 服务器提供服务，以提供一定的备份能力。当为一个zone使用多个DNS服务器的时候，通常可 以设置一个主服务器，而其他服务器为辅服务器，辅服务器将从主服务器上获得zone的解析 数据，而本地文件只是用于万一主服务器出现故障的情况。

    更改过named.conf中的zone设置项，就能创建zone的解析数据文件db.bsdgroup，用于 保存zone内的解析数据。

@           IN   SOA  ns.bsdgroup.example.org.cn. admin.example.org.cn. (
                         1999010801 ; Serial (date, 2 digits version of day)
                         86400   ; refresh (1 day)
                         7200    ; retry (2 hours)
                         8640000 ; expire (100 days)
                         86400 ) ; minimum (1 day)
            IN   NS   ns.bsdgroup.example.org.cn.
            IN   NS   ns1.bsdgroup.example.org.cn.
            IN   MX   10  ns
            IN   MX   20  ns1

ns          IN   A    192.168.4.21
ns1         IN   A    192.168.4.22
www         IN   CNAME  freebsd.example.org.cn.

    这个设置文件中首先为这个zone定义了SOA记录，接下来定义了服务于这个zone的两个 名字服务器。当为一个zone定义名字服务器时，有的管理员以为将名字服务器设置的越多越能 提供备份，其实并不是这样。如果定义的一台名字服务器，其named.conf（或named.boot）设 置文件中并没有设置它为这个zone服务，那么该名字服务器上就没有这个zone的解析数据，这 就导致一些客户从这个名字服务器中查询这个zone的数据失败。这个配置错误就是Internet中 经常发生的Lame Server错误，一些老版本的named不能检测并纠正这个错误，就会导致网络上 部分客户计算机不能解析这个zone。同样，多个名字服务器之间还应该保持zone数据一致，正 确划分好主/辅服务器可以很好的解决这个问题。

    然后又针对这个zone定义了两个MX记录，表示对应于这个zone的邮件服务器为ns和ns1， 这样在电子邮件中的地址中，就不需要使用具体的计算机名字ns.bsdgroup.example.org.cn， 而可以直接使用bsdgroup.example.org.cn。其中ns的参数为10，ns1的参数为20，用于标识不 同邮件服务器的优先级，一个邮件总是首先向低优先级的邮件服务器发送，只有当这个服务器 出现故障时，才会尝试其他的邮件服务器。

    这个文件中还定义了几个A记录，这个记录具体定义ns和ns1的IP地址，然后定义了一个 www的计算机，但这只是freebsd.example.org.cn的一个别名。

    这个zone是对该zone中的计算机进行正向名字查询，从名字返回相应的IP地址，进一步 可以配置反向查询zone，输入要查询的IP地址，返回正确的主机名字。

  • 反向解析zone

    前面提到的localhost.rev就是一个反向查询zone文件。因此要定义其他反向解析zone， 就与它相似。首先在named.conf中增加一个设置语句：

zone "4.168.192.in-addr.arpa" {
        type master;
        file "bsdgroup.rev";
};

    网络地址以反方向的方式写出，并使用in-addr.arpa后缀，表示一个反向查询zone为192.168.4。 然后创建反向解析数据bsdgroup.rev：
@	IN	SOA	ns.bsdgroup.example.org.cn. admin.example.org.cn.  (
                1998012314	; Serial
                3600	; Refresh
                900	; Retry
                3600000	; Expire
                3600 )	; Minimum
    IN	NS	ns.bsdgroup.example.org.cn.
21	IN	PTR	ns.bsdgroup.example.org.cn.
22	IN	PTR	ns1.bsdgroup.example.org.cn.

    注意，这里正向解析和反向解析位于同一台服务器上，这只是一种较简单的情况，但对 Internet上更广泛的复杂情况，并不总是如此。

  • 维护名字服务器

    当完成了这一步之后，就可以把本网络上所有计算机的解析数据，使用A记录增加到 db.bsdgroup中，使用PTR记录增加到bsdgroup.rev文件中去，并重新启动named守护进程，或者 向named发送SIGHUP信号（使用kill或killall），使其重新读取设置文件。那么所有使用这台计 算机作名字服务器的计算机将能正确查询相应的名字和IP。

    但是，外部的计算机并不知道有这个名字服务器的存在，因此外部计算机还无法查找到 正确的结果。因此就需要将这个名字服务器，及其提供服务器的域，登记到Internet上的正式名 字服务器上，以便这个名字服务器上的zone数据通过正式服务器发布到整个Internet。最方便的 做法是将这个名字服务器登记到其上一级名字服务器上，如在example.org.cn的名字服务器中可 以指定bsdgroup.example.org.cn子域的zone设置及名字服务器。

bsdgroup.example.org.cn.	IN	NS	192.168.4.21

    此后，外部计算机才能查找bsdgroup这个域的内容。

这个例子中使用了两个名字服务器ns和ns1，为了保持两个服务器中的数据一致，两个服务器 一个需要作为主服务器，另一个必须作为辅服务器。主服务器ns在配置文件named.conf中使用 type master来说明，而辅服务器ns1使用type slave来说明：

zone "bsdgroup.example.org.cn" {
        type slave;
        file "db.bsdgroup";
};

    这使得ns1首先尝试从ns（192.168.4.21）中获得zone的配置数据，如果不能成功再从本 机配置文件中获得。这样既能起到备份作用，又能保持解析数据尽量一致。

    named在启动和运行的过程中将不断向控制台打印信息，这些信息也被写入/var/log/messages 文件中。查看这些文件可以判断是否有错误发生。

Feb 15 01:26:17 roke named[6091]: starting.  named 8.1.1 Sat Feb 14 \
       00:18:20 MET 1998 ^Iwb@example.org.cn:/var/tmp/bind-8.1.1/src/bin/named
Feb 15 01:26:17 roke named[6091]: cache zone "" (IN) loaded (serial 0)
Feb 15 01:26:17 roke named[6091]: master zone "0.0.127.in-addr.arpa" \
       (IN) loaded (serial 1)
Feb 15 01:26:17 roke named[6091]: listening [127.0.0.1].53 (lo)
Feb 15 01:26:17 roke named[6091]: listening [129.240.230.92].53 (ppp0)
Feb 15 01:26:17 roke named[6091]: Forwarding source address is [0.0.0.0].1040
Feb 15 01:26:17 roke named[6092]: Ready to answer queries.

    此外，随着Internet的发展，根DNS服务器也会不断更新，因此保持自己的DNS服务器中 root.hints（或named.root）文件与Internet上的真实根文件服务器同步也是非常重要。通常可 以使用dig来从一个根文件服务器上取得这个文件：

# cd /etc/namedb
# dig @rs.internic.net . ns >root.hints.new

    如果一切正常，就可以将root.hints.new复制为named.root，并重新启动named。此外还 有一些常用的工具程序有nslookup，dig，dnswalk，named-xfer等，能用来分析DNS设置，帮助解 决设置问题。


FreeBSD连载(40)：邮件服务器

王波

电子邮件

    FreeBSD支持在Internet上收发电子邮件，也能被用作一台功能强大的邮件服务器，为众多使用不同 操作系统的客户机服务。

  • 邮件服务器

    Internet上与电子邮件相关的协议主要有SMTP、POP3和IMAP，其中SMTP是邮件传输协议，用于计算 机之间交换电子邮件，POP3和IMAP是用于客户计算机远程访问邮件主机上时使用的。

    FreeBSD系统缺省即包括了sendmail程序，它按照SMTP协议在Internet上接收和发送E mail。sendmail在缺省设置下就已经能够正常工作，一般情况不需要进行改动。如果更改sendmail的配置， 就需要更改sendmail的配置文件sendmail.cf，这个文件相当复杂、难于设置。因此如果希望设置邮件服务 器的一些特殊属性，就需要小心更改sendmail，讨论sendmail的设置不在本书的范围之内，并且，还有其他 的邮件服务器能用来代替sendmail，来完成接收和发送Internet邮件的任务。通常这些sendmail的代替者具 备更高的性能、易于更改设置，并且没有sendmail中经常报告的安全漏洞，因此如果需要定制邮件服务器， 推荐使用这些sendmail的代替产品，例如qmail或postfix。

    如果系统的用户经常使用其他计算机，如运行Windows9x的个人计算机，来访问自己的电子邮件，可 以在服务器端安装支持POP3或IMAP4的服务程序，这样Windows9x中的电子邮件客户软件就能访问服务器中的 邮件。pop3协议比较简单，因此Windows下一般的电子邮件处理软件都支持pop3协议，相对而言IMAP协议更复 杂一些，对电子邮件的支持能力更强，但支持imap协议的软件就较少。比较流行的电子邮件软件可以支持这 两种协议，如netscape messager、Eudro等。因此服务器可以有选择的支持这两种协议。

    如果仅需要提供POP3支持，可以使用qpopper，而要同时支持POP3和IMAP，就可以安装imap-uw（uw指 University of Washington，IMAP协议和这个服务器程序的开发者）。安装imap-uw之后，还需要更改 inetd.conf，增加以下行：

pop3	stream	tcp	nowait	root	/usr/local/libexec/ipop3d	ipop3d
imap4	stream	tcp	nowait	root	/usr/local/libexec/imapd	imapd

    重起inetd，则远程用户就能在其客户软件中处理电子邮件了。


FreeBSD连载(41)：在FreeBSD上查看邮件
王波
在FreeBSD上查看邮件

    FreeBSD上的用户可以通过mail程序来查看自己的Email，mail是一个最基本的交互式Unix 命令，可以运行在任何类型的终端上，然而使用它来处理邮件也很不方便。使用者常常安装其他更 为便利的电子邮件客户程序来处理自己的邮件，这些软件有elm、mutt、pine，以及只用于X下的 netscape messager、kmail等。

    虽然基于X的邮件处理软件比较方便和易于学习，然而通过网络远程直接使用这些X程序比 较麻烦，不是任何计算机上都运行了X服务器的。而几乎所有的计算机系统中都支持telnet等字符 终端连接软件，使用支持字符终端的邮件处理程序就使得使用者无论身在何处，只要连接到自己的 主机上就能处理自己的电子邮件。

    在远端访问自己的电子邮件的另一种方式是：首先在远端的客户机上安装、配置电子邮件 软件，再使用这些软件访问自己主机上的邮件。这些远程访问邮件服务器的软件使用POP3协议或者 IMAP协议，让用户查看远程计算机上的邮件。

    这两种方式的不同在于邮件处理软件的安装位置，安装在主机上的邮件处理程序基于X或字 符终端，不需要改动客户计算机上的任何配置，因此适用于经常改变客户机的使用者。安装在客户 机上的用户可以充分发挥客户计算机的优势，例如MS Windows的用户界面，这种方式适用于拥有固 定个人用计算机的使用者。这两种方式并不相互冲突，而是相互补充的，适合不同情况的使用者。

  • 邮件处理程序pine

    由于基于字符终端的邮件软件启动快捷，能通过telnet等防真终端使用，而不需改变客户计 算机的任何配置。因此Unix的使用者至少都会选择安装一种基于字符终端的邮件处理软件，以作为 最基本的邮件处理软件。pine就是其中之一，它提供了简洁的字符菜单界面，功能强大且易于操作， 易用性超过很多图形接口的邮件处理程序。

    在Pine的主菜单下，可以执行发送电子邮件（Compose message），查看当前文件夹的内容 （Message index），选择不同的文件夹（Folder list），使用和维护地址簿（Address Book）， 使用S（Setup）用于设置Pine，使用Q（Quit）退出pine回到shell提示下。正常情况下，不需要对 pine进行任何设置，就能正常使用pine阅读和发送电子邮件。

    然而当使用pine来发送中文邮件时，pine会对中文进行重新编码，以适应7位传输，虽然大 部分电子邮件客户都会识别这些标准的编码格式，但还是有一些电子邮件程序不能识别出这些编码 ，造成阅读问题。此时就可以重新设置pine直接使用8位编码。

    在主菜单下选择Setup，当出现提示时，使用Config进入配置部分。就可以搜寻包含enable-8-bits 的两个选项，配置自己使用的字符集（由于pine中不直接支持中文字符集，可以设置为ISO-8858-1） ，以支持8位字符。

    还可以在这里设置Pine来阅读Usenet新闻，这就要在nntp-server的选项中填写本地新闻服 务器的域名，并配置news-collections选项，例如本地新闻服务器的名字为news，那么news-collections 就应设为 ”*{news/nntp}/[]”。也可以设置远程文件夹，使得Pine能访问远程主机上的邮件。

    Pine缺省支持使用IMAP协议访问远程主机上的邮箱，但它对POP3的支持未在其文档中公布， 不能使用设置程序来完成。可以手工更改用户个人目录下的配置文件.pinerc中的选项incoming-folders， 以支持POP3，下面为一个例子：

incoming-folders="imapfolder" {imaphost}INBOX,
     "pop3folder"	{pop3host/pop3/user=wb}INBOX

    这个例子中配置了两个远程帐户，一个为imaphost上的邮箱，使用IMAP协议进行访问，在 pine中的文件夹名为imapfolder，第二个为pop3host上的邮箱，后面使用/pop3指明使用pop3协议 ，/user=wb指明使用wb作帐户名，其文件夹的名字为pop3folder。使用这样的格式就能使pine来管 理多个计算机上的多个邮箱。

    那么再次启动pine就能有位于不同主机上的相应incoming和nntp文件夹，用户打开相应的文件 夹就能使用imap、pop3或nntp等不同协议，访问相应的邮件或新闻了。

  • 使用fetchmail管理多邮件帐户

    尽管使用pine能非常方便的管理多个POP3或IMAP邮箱，但是如果邮箱主机与当前FreeBSD系 统的网络连接很慢，使用pine来阅读这些邮箱中的邮件就非常迟缓。此时更好的办法是先在后台将 邮件取到回本地邮箱中，然后使用pine或其他邮件处理程序进行处理。

    fetchmail就是一个非常方便的从远程邮件主机下载邮件的应用软件，它支持pop3、imap， 以及对pop3的一些扩展协议。当安装好fetchmail之后，使用者可以直接启动fetchmail，来取得邮 件的方法为：

$ fetchmail -p pop3 -u wangb email.online.ha.cn
password for wangb@email.online.ha.cn:

    在输入正确的口令之后，fetchmail将使用pop3协议访问主机email.online.ha.cn，并取回 用户wangb的电子邮件，取回的电子邮件将发送到本地邮箱中。也可以用更复杂的方式在后台运行 fetchmail，则需要设置个人目录下的.fetchmailrc文件。

$ cat ~/.fetchmailrc
poll email-wangb via email.online.ha.cn
    protocol pop3
    authenticate password
    username wb here is wangb there
    password "1111"
    smtphost localhost
    pass8bits
    stripcr
    fetchall
$ chmod 700 ~/.fetchmailrc

    设置文件中第一行poll email-wangb via email.online.ha.cn中设置了要下载邮件的邮件 服务器为email.online.ha.cn，其中email-wangb为对应这一个帐号的标签名字，用于区分多个不同 的邮箱。然后指定使用的协议为pop3，认证方式为标准的Unix口令认证，然后，定义了远端主机上 的邮件帐户名为wangb（用there表示远端主机设置），邮件下载到本地用户wb的邮箱中（使用here 指明本地主机设置）。

    smtphost定义了fetchmail用来转发邮件时使用的smtp主机，passsword定义了远程邮件服务 器中帐户的口令，在口令中使用了数字或特殊字符时，就需要使用双引号将口令括起来。pass8bits 允许下载邮件中存在8位字符，stripcr用于过滤额外回车字符，由于DOS和Unix在文本定义上的不同 ，这一项用于兼容一些不识别这个差异之处的Windows系统的邮件服务器，fetchall表示取回全部邮 件，否则就只取回最新的邮件。

    此外，这个文件因为包括了远端服务器的口令，因此必须具备属性700，以避免其他用户能读 取这个文件，否则fetchmail不会运行。

    这样，就可以不使用任何命令行参数，直接在后台运行fetchmail了。每个用户可以使用cron来运 行自己的fetchmail命令，来管理自己的邮件，而拨号用户可以在拨号后，使用ppp.linkup启动fetchmail ，取回自己的邮件。

  • 使用Procmail设置邮件过滤

    由于Internet的使用者不但使用电子邮件和朋友、同事联系，而且还通过maillist与Internet 上的其他使用者讨论共同感兴趣的话题，用户收到的电子邮件越来越多，并且还会受到广告、宣传品 等垃圾邮件的骚扰。使用Promail、maildrop等邮件过滤程序就能帮助使用者阻挡这些广告和宣传品， 并帮助管理用户接收到的邮件。Procmail就是一个用于过滤用户接收到的电子邮件，并能对其自动分类 、处理的一个应用软件。对于每天都会收到大量电子邮件的Internet使用者，这是一个非常有用的工具。

    为了使用Procmail，必须在用户接收到Email时，启动Procmail进行处理。这个任务可以使用 两种不同的方式来完成，一个是将Procmail配置为系统的邮件分发代理（Mail Deliery Agent），系 统的邮件服务器使用porcmail代替其本身原有的邮件分发功能，来分发用户的邮件。这种方式需要由 系统管理员根据邮件服务器的不同，而进行不同的设置。

    另一种方法是使用个人目录下的.forward文件，系统邮件服务器在给某个用户分发邮件的时候， 如果发现他的个人目录中存在.forward文件，那么就会按照这个文件中的内容来进行处理。因此就可以 在.forward文件中启动procmail处理用户接收到的邮件，与更改系统MDA的设置方式相比，这种方式更为 灵活，并且可以由每个用户来决定是否使用这个过滤处理能力。

    .forward文件可以按照需要设置三种不同的处理方式：定义存储邮件的邮箱文件名、进行转发 的目的地址或者对电子邮件进行处理的外部应用程序，显然启动Procmail是应使用第三种方法。

    .forward文件应该属于这个用户（或root），并且其权限设置应该为不能被其他或同组用户可写。

$ cat ~/.forward
"|IFS=' '&&exec /usr/local/bin/procmail -f-||exit 75 wb"

    这个.forward的例子里，使用"|"字符设置括号内的参数为一个执行命令，这样 sendmail就能启动一个shell执行设置的命令，并使用管道的方式读取sendail的输出。执行命令中首 先定义了IFS环境变量（用于分隔不同的域），然后执行procmail，如果procmail执行失败就执行 exit 75 wb告诉sendmail，邮件分发失败，需要更改wb为使用者自己的登录名。

    procmail使用用户个人目录下的.procmailrc文件，来设置对收到的Email进行处理的过滤规 则。最简单的.procmailrc文件为：

:0c:
* ^FROM.*@freebsd.org
$HOME/mail.backup

    第一行首先使用冒号开始定义一个过滤规则，紧随其后的应该是一个数字，这个数字规定了这 个规则占用的配置行数，一般使用0表示没有限制配置行，此后的c表示复制（copy），表示下面的规则 只是用于处理邮件的副本，而邮件本身仍然会被其他的过滤处理规则处理。这一行最后的冒号，用于表 示在处理过程中进行加锁，防止同另一个procmail进程处理同一个文件时发生冲突，通常这个机制在存 储邮件文件时非常有帮助。

    第二行就开始了一个过滤规则的定义，过滤规则使用*字符开头。一个规则中使用模式匹配来匹 配电子邮件信头或内容中的特定行。上面例子里的这个规则匹配所有来自于freebsd.org的电子邮件。 在第三行定义了对符合上面规则的邮件的处理方法，由于给出了一个文件名mail.backup，因此将所有 来自于freebsd.org的电子邮件添加到mail.backup文件中保存。如果使用!开头定义规则处理办法，表 示进行转发处理，!后面就为进行转发的电子邮件的地址，或者以|开头，表示启动后面的命令进行邮件 处理。

    procmail不区分大小写，它使用Unix最常用的模式匹配方式进行匹配特定的邮件。因此使用这 些匹配模式和procmail规则，可以定义一个更复杂的.procmailrc：

PATH=$HOME/bin: /usr/bin: /usr/ucb: /bin: /usr/local/bin:.
SHELL=/bin/sh
MAILDIR=$HOME/mail
DEFAULT=$MAILDIR/mailbox
LOGFILE=/dev/null
SENDMAIL=/usr/lib/sendmail

:0:
* ^From.*badguy
/dev/null/

:0c:
* ^(From|Cc|To).*freebsd.org
| gzip >> freebsdmail.gz

:0:
* ^From.*@hotmail.com
* ^Subject:.*(joke|funny)
{
   :0 c
   ! friend1@hotmail.com friend2@usa.net
   :0
   joke
}

:0
* ^Subject:.*order
* !^FROM_DAEMON
* !^X-Loop: marketing@company.com
{
   :0 h c
   | (formail -r -A"X-Loop: marketing@company.com " ; \
   cat /market/acknowlegement.txt ) | $SENDMAIL -t
   :0 c
   ! market2@company.com
   :0
   market
}

    这个配置文件的第一部分中设置了几个环境变量，用于设置procmail的运行环境，其中将 MAILDIR设置为~/mail，与pine使用的目录相同，因此这将使pine能直接读取procmail处理过的邮 件。

    第二部分中为邮件定义了三个不同的过滤规则及相应的处理操作，第一个规则将来自badguy 的邮件滤掉（输出到/dev/null）；第二个规则将与freebsd.org的通信使用gzip保存到freebsdmail.gz 中，用于保存相应maillist的邮件；第三个规则将某个使用hotmail帐号的朋友，并使用joke或funny标 题给自己发送笑话的邮件同时转给其他几个朋友，并同时保存在joke文件夹中；最后一个规则是设置了 一个自动回复邮件系统，对于使用order做标题，并且没有FROM_DAEMON行（自动邮件回复程序使用FROM_DAEMON 作标记，通常不需要回复这些的邮件，否则会造成回复循环），并且没有包括X-Loop行的邮件进行处理：

    首先将X-Loop行添加到邮件中（使用formail将它们添加到mail的信封上），以免造成对同一个邮件的 循环处理，然后将文件/market/acknowlegement.txt发回给发送者；并以及转发邮件，在market中保存邮件。

    根据这些规则，使用Procmail就能完整的处理各种邮件，减轻电子邮件不断增多而造成的困扰。


FreeBSD连载(42)：NFS客户支持

作者：王波

网络文件系统（NFS）

    NFS是一种Unix之间通过网络共享文件的标准方式。使用NFS，就能够透明的安装和 访问网络上远程主机上的文件系统，将其安装到本机的文件系统中。

  • NFS客户支持

    安装NFS服务器上的文件系统的方式与安装本机磁盘文件系统非常相似，同样是通过 mount命令：

# mount  nfssrv:/exports  /mnt

    这个命令将nfssrv主机上的/exports目录安装到本机的/mnt目录下。可以看到安装 NFS与本地磁盘文件系统的不同在于 ── 文件系统的描述方法不同。本地磁盘文件系统使 用/dev下的设备文件来描述，而NFS文件系统使用远程主机名和主机上的共享目录名（中间 使用:分隔）来描述。当然其执行的实质是不同的，事实上mount根据文件系统的类型，执 行mount_nfs来真正安装nfs文件系统。

    /mnt应该是本地文件系统上的一个空目录，没有安装其他文件系统。如果这个目录 非空，那么使用mount之后，原有的本地文件系统中的内容将不可被访问，只能看到新安装 上的文件系统中的内容。

    由此来看，NFS客户不需要进行复杂的配置，只需知道NFS服务器的主机名和共享出 的目录名即可。事实上，知道了NFS服务器的主机名，就可以使用showmount命令，来查看这 台服务器共享出的目录名和访问限制。

# showmount -e nfssrv

    使用NFS文件系统只需要内核支持，而不需其他额外设置,但是同时使用nfsiod进程 能够提供高效的缓冲机制，从而改善nfs文件系统的性能，应该可以在装载NFS文件系统之前 执行这个守护进程。

# nfsiod -n 4

    参数-n 4用于限制nfsiod的副本数量，每一个nfsiod用于辅助处理一次I/O操作，因 此如果通过NFS文件系统进行频繁的I/O操作，就要考虑增加nfsiod的副本数量。

    由于使用nfsiod能够提升系统性能，对于NFS客户计算机，就可以在系统启动时执行 这个守护进程。这需要在FreeBSD的系统配置文件rc.conf中设置nfs_client_enable参数的 值为"YES"，系统启动时就自动执行nfsiod。

  • 使用fstab

    对于经常用到的NFS文件系统，并且提供NFS服务的Unix主机也非常可靠。那么就可 以将这些系统加入/etc/fstab文件中，在系统启动时自动安装该NFS文件系统。由于NFS文件 系统不在本地，因此在服务器不能提供NFS服务时就会造成故障，系统会遇到启动障碍，而 不同正常启动。因此对于一台不稳定的服务器系统，最好不要使用/etc/fstab来装载NFS文 件系统，或者在/etc/fstab的设置参数选项中使用noauto参数，不让系统自动装载这个文件 系统。

# Device                Mountpoint      FStype  Options         Dump    Pass#
/dev/wd0s3b             none            swap    sw              0       0
/dev/wd0s3a             /               ufs     rw              1       1
/dev/wd0s3f             /usr            ufs     rw              2       2
/dev/wd0s3e             /var            ufs     rw              2       2
proc                    /proc           procfs  rw              0       0
/dev/wcd0c              /cdrom          cd9660  ro,noauto       0       0
nfssrv:/exports         /nfs            nfs     ro,noauto       0       0

    /etc/fstab文件中的第四列为安装文件系统时使用的安装参数，如果增加了noauto选 项，这样系统启动时并不立即安装这个文件系统，而是直到管理员输入mount命令之后才进行 安装。但是此时mount命令的参数就可以比较简单，对应前面安装nfssrv的命令，可以简化为 mount /nfs，mount会查看fstab文件寻找匹配的行，以使用正确的参数安装文件系统。

  • 自动安装守护进程AMD

    为了更方便的使用NFS，可以使用自动安装软件amd（automounter daemon，自动安装 守护进程）自动维护文件系统，这就使在访问具体目录时能够立即安装该文件系统，而经过一 端时间间隔内没有任何访问发生，再自动卸载这个文件系统。

    amd需要指定一个进行监视的空目录，所有要安装的文件系统与这个目录下的子目录 一一对应；它还需要一个维护用的空目录，用于安装远程文件系统，而监视目录中的子目录 将是正确安装的文件系统的符号连接。这些子目录和符号连接并不需要管理员创建，而是要 在映射文件中指明，由amd来创建和维护。当监视子目录被访问时，amd守护进程就会安装相 应的文件系统并建立正确的连接，使得目录和文件能被正常访问。

    通常使用/etc/amd.map用作amd的映射文件，这个文件就用于告诉amd子目录与文件系 统的对应关系。下面是一个最简单的映射文件amd.map：

# cat /etc/amd.map
/defaults       type:=host;fs:=${autodir}/${rhost};rhost:=${key}
nfssrv	         typs:=nfs;rhost:=nfssrv;rfs:=/exports

    第一行使用/defaults定义缺省的设置，type参数用于定义维护的文件系统的类型， host类型为通过NFS安装远程服务器中直接在exports文件中输出的目录，fs参数为amd安装文 件系统使用的安装位置，变量autodir为amd维护安装文件系统的目录，而rhost变量为远程计 算机的名字，需要进行设置。缺省的rhost变量设置为${key}的值，当用户访问amd监视目录的 子目录时，key就被设置为这个子目录的名字。通过这个缺省设置，当用户访问amd监视目录的 任意一个子目录时，这个子目录名就被转换为远程NFS服务器的名字，amd就自动将这个服务器 共享的目录安装到fs定义的安装位置上。

    第二行设置一个专有的映射关系，第一列也是amd设置的key值，当访问对应的子目录 时就启动这个设置，这一个安装点为nfs类型，nfs类型与host略有不同，host类型只需要rhost 定义，而查询服务器上的共享出的目录来自动安装，而nfs类型则要配置者手工指定远程主机共 享的目录，这就需要设置rfs参数。通常在自动维护的计算机数量较少时，使用nfs类型更明确 ，否则可以使用host类型以简化配置工作。

    设置好映射文件之后，就可以运行amd守护进程了。

# amd -a /net -c 1800 /host /etc/amd.map
# ls /host
# cd /host/nfssrv
# ls -l /host
nfssrv

    上面的amd的命令参数为，第一个-a参数告诉amd将真实的文件系统安装到/net这个临时 目录下，在执行amd之前必须建立这个空目录，这个目录将被amd作为autodir变量设置映射关系 ；-c参数用于指明超时参数，经过这个时间间隔内没有访问这个文件系统上的内容，就卸载已 安装的文件系统，设置为1800秒；而/host目录为amd监视用户访问的目录，访问这个目录中的 子目录，就会触发amd守护进程，例如上例中使用cd /host/nfssrv访问nfssrv子目录，那么amd 就将启动，将nfssrv设置为key值，因此amd就读取/defauts设置的缺省参数和nfssrv这个key值 对应的参数，然后执行自动安装过程。最后一个参数就是指定映射文件为/etc/amd.map。

    因此，amd的处理过程可以总结为：用户首先访问/host目录下的子目录，触发amd；amd 使用子目录的名字作为key值，读取相应映射文件中的设置，将文件系统安装到/net目录下的相 应目录上（fs定义的目录）；最后amd在/host目录下以key值建立符号连接，指向已经安装到/net 目录下的真实文件系统，使得用户访问子目录的操作能够正常完成。

    amd主要是和NFS结合使用，用于维护多台服务器的用户和文件目录的一致性，然而amd 不仅仅能用于维护NFS文件系统，同样也可以用于维护其他种类的文件系统，如CD9660、本地文 件目录的连接，以及扩展到运行一个程序等方式自动安装相应的文件系统，对于这些非NFS文件 系统，就需要使用不同的type参数定义不同的类型。例如可以使用amd将所有用户的个人目录维 护在同一个路径下，而不是事实上分布在不同目录和主机上，等等。此时，amd.map应为：

/defaults	 opts:=rw,grpid,nosuid,nodev

wb   host==wb;type:=link;fs:=/home/wb

cd   opts:=ro;host==wb;type:=cdfs;dev:=/dev/wcd0c

dos  host==wb;type:=program;mount:="/sbin/mount_msdos
mount_msdos /dev/wd0s1 focus/FreeBSD/"

    这个映射文件中的缺省设置中首先使用opts设置了几个安装选项，用于安装文件系统时 使用。由于这个例子中维护的文件系统NFS文件系统，因此没有使用变量定义相应的参数，而且 在维护的文件系统不多的条件下，可以直接定义各个自动安装所需要的各个参数。

    第一个设置为是一个link类型，它必须在主机为wb（本地主机的名字，amd将自动设置 host变量）时才有效。这个类型只是用于建立连接，因此就没有必要定义rhost和rfs，而通过 fs定义需要建立连接的目标。因此当访问/host/wb目录时，amd就自动建立一个到/home/wb的 符号连接。

    第二个设置为cdfs类型，这用于访问时自动安装CDROM，它通过dev参数设置安装使用的 设备文件。第三个设置为program类型，当访问/host/dos目录时，amd会自动执行后面的mount_msdos 程序，装载上dos分区，安装点被使用变量path传递给外部程序的参数。

    为了在启动时自动执行amd，需要修改rc.conf中的设置，更改其中的选项amd_enable为”YES”， amd的执行参数在amd_flags项中设置，缺省为：

amd_flags="-a /net -c 1800 -k i386 -d my.domain -l syslog /host /etc/amd.map"

    这个参数使用了另一些有用的参数，-k参数用于运行amd的计算机内核体系，-d参数用 于定义计算机的domain名，修改这个参数可以帮助amd侦测计算机所在的domain名字，因此要修 改为计算机实际的域名，-l参数定义审计记录文件，缺省使用syslog。amd的设置相当复杂，这 里只是通过一个映射文件来提供针对一个目录的自动安装维护，实际上amd可以同时维护多个目 录，这就需要设置一个配置文件，来定义多个监视目录。对于一般的目的，使用命令行指定一 个映射就够用了。


FreeBSD连载(43)：NFS服务器

王波

NFS服务器

    为了使得其他系统能使用FreeBSD上的硬盘空间，就需要运行NFS服务进程。NFS服务器 使用了几个守护进程用于提供NFS服务。最基本的提供NFS服务的系统至少要运行nfsd和mountd 守护进程，nfsd用于处理NFS协议，而mountd用于处理客户的mount请求。此外，由于NFS使用RPC 远程调用，因此portmap、rpc_lockd、rpc_statd等RPC守护进程都可以用来帮助提供更高效的 服务。

    这些守护进程一般应该在系统启动时载入，因此需要在rc.conf中更改相关的参数： nfs_server_enable, rpc_statd_enable, rpc_lockd.enable和portmap_enable参数将对应相应 的守护进程。

    那么系统重起之后，就有了能共享文件出去的能力，余下的工作只是用来配置需要共享 那些目录，以及进行何种限制以保证安全性，这些设置工作需要更改/etc/exports文件：

# cat /etc/exports
/usr/src/sys -maproot=daemon ns host2
/usr/ports -ro -network 192.168.1.0

    从这个例子中可以看出exports文件的格式，首先是定义要共享出去的文件目录，必须 使用绝对路径，而不能使用是符号连接。后面就是对这个目录进行访问限制的参数，用于保证 安全性。第一行设置中，将/usr/sys/src目录共享出去，但限制客户机上的root用户等价于本 机上的daemon用户，以避免客户机上的root用户拥有这个服务器上的root权力，进行非法操作 ，此后的ns和host2参数是主机名，这就限制只有ns和host2才能共享这个/usr/sys/src目录。 第二行设置共享了/usr/ports目录，但限制为只允许读取，并且也只有192.168.1.0网络上的 计算机才能访问这个共享目录。

    目录的访问限制中具有多种选项，这些选项对于保证NFS的安全性相当重要。

    -ro---以只读形式输出文件系统，远程客户只能读不能写这个目录

    -maproot---将客户机上的root用户映射为服务器中的某个用户和族，也可以使用UID 和GID的形式，如maproot=root，maproot=10，或maproot=10:1。这个设置选项可以用来保护 服务器上的文件系统不被客户中的使用者非法访问。

    -mapall---将客户上的所有用户都映射为本机的某个用户，使用形式与maproot相同 。它同样也是用于保护服务器文件系统的安全性的。

    -alldirs---允许安装该目录下的所有子目录。

    -network---允许一定网络上的计算机可以装载这个文件系统。

    -mask---用于修订 network中的网络号使用的缺省掩码，可定义对网络的一部分开放 文件系统。

    当更改了exports文件之后，需要向mountd发送SIGHUP信号，使其重读exports文件的 内容。


FreeBSD连载(44)：X Free86的硬件要求

王波

第5章 设置和使用X Window

    当将FreeBSD系统用作服务器的时候，其正常工作并不依赖于任何图形界面， 只使用字符界面就能完成几乎的全部服务器端任务。然而，图形界面具有更大的灵活 性，可以同时打开多个窗口、执行一些字符界面无法完成的任务（如图形处理）、使 FreeBSD系统更容易使用等，图形界面的处理能力是打算将FreeBSD系统用做个人工作 站平台的必备能力。

    FreeBSD通过X Window系统来支持图形界面，X Window是由MIT开发的一套标 准图形接口，其当前版本是X11R6.3。与MS Windows或Macintosh的图形界面不同，X Window是一套平台独立的基本图形功能调用接口，它不包括具体的硬件实现和具体的 显示风格，因此X Window具备高度可配置性，有多种多样的显示风格。如果将图形界 面分为涉及应用程序的显示管理能力、进行图形处理的图形接口和低层的显示硬件接 口三个部分，那么X Window就是中间层和低层的一套图形处理协议。

    但是MIT发布的X Window源代码并不包括低层代码，即系统在具体显示硬件上 的实现，为了使X Window能在计算机的具体硬件上运行起来，还需要开发相应的驱动 程序。除了专有厂商开发了各种硬件驱动程序以提供真正可用的X Window系统之外， 另一个具备多种硬件驱动程序并可以自由使用的X Window系统为XFree86。它是由很多 志愿者组织的，利用X Window的源代码为各种显示硬件开发可供自由使用的X服务器， 使得X Window系统能够在具体的操作系统硬件上真正运行起来。FreeBSD以及其他几种 自由操作系统均使用Xfree86系统作为图形系统。

  • 安装和设置X服务器

    FreeBSD中使用XFree86作为基本X Xindow系统，然而也有专业厂商为FreeBSD 系统制作X服务器，例如Xi Graphics公司，商业公司开发的X服务器通常能够支持更多 、更新的显示硬件，并能支持新型硬件的各种特性。XFree86由于为志愿者进行开发， 不能得到显示硬件生产厂商的技术支持和技术资料，因此对新硬件的支持要差一些。 一般情况下，如果没有使用太新的显示硬件，XFree86即能满足建立图形系统的需要。 因此这里就介绍设置和使用XFree86系统的方法。

  • X Free86的硬件要求

    当前XFree86最新发布的版本为XFree86 3.3.3，支持多种类型的显示卡。但是 图形界面比文本界面需要更多的系统资源，尤其是内存空间。通常要正常运行X Window 的FreeBSD系统，至少需要8MB内存，并且还应有8MB的交换空间，以运行其他X应用程序 。然而要想获得更高的性能，还应该有更好的硬件条件，如带有硬件加速能力的显示卡。

    显示卡：XFree86支持多种显示卡，从普通的VGA显示卡到专用图形加速 卡。一般的个人计算机均使用某一种VGA兼容的显示卡，这就满足XFree86的最低要求。 但如果XFree86支持显示卡的具体类型，就可以用256色或更高的真彩色、更大的分辨率 的显示模式来运行X Window系统，否则就只能使用16色的标准VGA模式。而且使用图形加 速卡的硬件功能会明显改善图形界面的显示速度。

    显示器：由于Unix的使用者和开发者用惯了专业工作站，所以他们设计的 图形界面是为了大屏幕而设计的。在小显示器上使用X Window，往往会觉得按钮过大、边 框过粗等等，因此显示器最好能达到1024x768的分辨率，甚至更高，才能更好的发挥X Window下的各种界面风格的优势。

    键盘：常用的Unix工作站键盘也与PC键盘的排列不太一样，但是一般的使 用者更习惯PC风格的键盘。XFree86可以重新映射键盘，缺省情况下键盘的映射为PC风格的 键盘，但对于更熟悉工作站键盘使用者可以重新定义键盘上的排列。

    鼠标：MS Windows使用的是2键鼠标，在X Window中更习惯使用3键鼠标， 对于只有2键鼠标的计算机，XFree86能提供一种模拟第三键操作的功能。使用风格也不太 相同，例如在Windows95中使用双点 “double click” 来执行程序，在X下一般只需单点即 可，因为使用X Window的用户通常是长期使用计算机的专家，他们认为双点操作使得手指 处于紧张的状态，长期进行双击操作会对手指造成损伤。

    安装XFree86之前，首先需要了解计算机的显示卡是否被XFree86所支持，XFree86支 持大量常见的显示卡硬件，然而由于X服务器的驱动不是由硬件厂商开发的，那么一个硬件 从出现到被XFree86支持需要一段时间，很多硬件厂商出于保护商业机密的考虑，没有公开 他们硬件的详细资料，这就对开发对他们硬件的驱动程序提供了额外的阻碍。安装了XFree86 之后，可以查看其文档目录中的README文件（FreeBSD下这个文件的路径为/usr/X11R6/lib/X11/doc/README ），来查看Xfree86支持的显示卡芯片的种类。


FreeBSD连载(45)：安装XFree86

王波

安装XFree86

    FreeBSD将XFree86作为了操作系统的基本组件，可以在安装系统时选择安 装。在安装系统时进行的组件选择时，按照对不同组件的选择，例如选择X-User 或X-Developer选项，将安装Xfree86系统。系统安装时还会提示用户立即设置 XFree86，但是由于FreeBSD的初始运行与图形界面关系并不大，因此这个设置工 作可以在安装系统之后的任何时候进行，而并非必须在初始安装时进行。

    如果在初始安装时没有安装XFree86，也能够在整个安装系统安装完成之 后再进行安装。此时可以从安装介质中手工安装二进制组件，或者自己从Xfree86 主页（http://www.xfree86.org）或FreeBSD站点种下载XFree86的最新版本，重 新编译并安装。XFree86的安装文件放置在安装介质根目录的/XF86333目录中，安 装时仅仅需要将相关文件解开到/usr/X11R6目录下就行了。可以使用sysinstall 或这个目录下的install.sh程序来帮助安装。

    在XFree86的较早版本中，其设置是一个十分困难的问题。因为显示卡种 类很多，而且每个卡的参数种类也繁多，要正确设置XFree86，就必须对这些硬件 有较深的了解。最早的时候需要手工更改配置文件，后来XFree86提供了一个交互 式的命令行配置程序xf86config，来帮助使用者配置X Window。但是这个程序只 是简单的提示使用者输入相关信息，并且一个选项一旦确定，就不能回溯回去进 行修正。因此，如果是第一次使用xf86config来配置XFree86的话，毫无疑问将 会遇到种种问题。

    幸而在后来的XFree86中，XFree86的开发者又提供了另一个配置程序： XF86Setup，它首先启动16色的标准VGA模式的X Window，再执行图形界面的设置 程序，通过图形界面提供了一种更为容易的方式来设置XFree86的服务器。

    当使用sysinstall程序来设置X Window（选择Configure菜单中的Xfree86） ，那么它将提示使用者选择XF86Setup和xf86config这两种不同的设置方法。注意这 个选项中的PC98是指日本生产的一种特殊计算机硬件类型，而非标准硬件中的主板 PC98规范，因此使用标准PC的使用者不需要使用这个设置选项。

    如果不使用sysinstall来启动设置程序，也可以手工在命令行中输入（ 必须是以root权限）相应的命令：

    # /usr/X11R6/bin/XF86Setup

    或

    # /usr/X11R6/bin/xf86config

    使用不同的命令将启动相应的设置程序。


FreeBSD连载(46)：使用XF86Setup配置X服务器

作者：王波

使用XF86Setup配置X服务器

    XF86Setup是在图形界面下运行的设置程序，它运行在图形界面下，如果系统没有启动 X Window系统，那么它会自动启动一个标准VGA模式的X服务器，因此这就要求FreeBSD系统内 必须安装了XFree86的VGA模式的服务器XF86_VGA，XF86Setup首先使用缺省设置启动这个16色 、640x480分辨率的X服务器，然后再运行XF86Setup设置程序本身。

    但如果已经启动了X服务器，使用这个设置程序进行重新设置X服务器的话，那么就会 使用现有的X服务器。XF86Setup还会询问是否以现有设置为基础进行设置，如果X Window运行 正常的情况下，应该以现有设置为基础进行修改，而不必完全重新进行设置。

    XF86Setup配置程序的显示如上图显示，它显示了可供操作的六个选项，设置鼠标的 Mouse选项，设置键盘的Keyboard，设置显示卡的Card选项，设置显示器的Monitor选项，设 置显示模式 ── 分辨率和刷新频率的Modeseletion选项，以及设置一些其他X服务器的选项 Other，除了最后一个选项之外，每个选项都需要重新设置。

    在XF86Setup中可以使用鼠标或键盘进行操作，通常键盘都是标准键盘，因此不需要 额外设置，而鼠标需要额外的检测和设置。设置程序会试图检测计算机上所使用的鼠标类型 和端口，以对鼠标进行探测。如果FreeBSD系统配置并运行了moused，XF86Setup就毫无问题 的检测出这个伪鼠标设备，供使用者使用鼠标进行操作。如果没有使用moused，就有检测鼠 标就可能失败，使用者就只能使用键盘进行操作。

    在这个设置界面下，首先可以使用回车，首先进入鼠标选项的设置界面，这样可以 首先设置鼠标，鼠标设置完毕之后就能使用鼠标进行下面的各项操作了。与大部分应用程序 相同，键盘操作使用的基本键是Tab与Enter，Tab用于在各个设置选项之间切换，Enter用于 选择相应的选项。

    第一次进行操作时将出现上图所显的对话框，阅读过其显示的信息之后，就可以确 认，以进入各项设置的操作过程。

  • 设置鼠标

    设置X服务器的第一步就是要配置鼠标，鼠标是X Window的必需设备，如果没有设置 鼠标，X服务器就不能正确启动。如果已经使用Sysinstall配置好了控制台鼠标守护进程moused ，那么鼠标就能被正确侦测到，这就能略过设置鼠标的步骤，直接进入下一个设置选项。

    moused守护进程在后台维护着/dev/sysmouse这个伪设备，将鼠标物理端口送来的鼠 标移动和点击数据转化为这个伪设备上的鼠标操作数据，那么X服务器就能使用/dev/sysmouse 这个设备文件作为鼠标设备，使用SysMouse作为鼠标类型，而不必管真实的鼠标端口和类型。 使用moused的一大好处就是鼠标设备由moused维护，而与X服务器无关，因此不会因为鼠标的 问题造成X服务器的故障。因此一般情况下，应该使用moused来维护鼠标设备。

    如果不打算运行moused来管理鼠标设备，此时就需要根据鼠标的具体类型和连接到 的具体端口，来选择对应的正确设备文件，来为X服务器设置鼠标。如果鼠标是接在第一个 串行端口sio0上，那么对应的设备为/dev/ttyd0，第二个串口设备为ttyd1，而常用的串口 2键鼠标为Microsoft类型。其他设备文件包括对应PS/2鼠标的psm0，对应总线鼠标的mse0等 。但是在moused正常启动的条件下，真实的物理端口就不能正常工作了。

    当没有使用moused的时候，就需要使用键盘进行操作。键盘操作就比较繁琐，但设 置完毕之后，可以立即选择右边的按钮 “Apply” ，使鼠标可以立即发挥作用，此后就能使 用鼠标进行其他操作了。如果鼠标设置正确，该界面上右边的鼠标图形中的按键会随鼠标按 键而闪动，其位置坐标会随鼠标移动而改变。

    除了基本的鼠标类型和端口之外，鼠标选项中还有很多参数可以调整，其中一个重 要的参数为 “Emulate3Button” ，因为X Window系统习惯上使用3键鼠标进行操作，很多功 能用到了鼠标的第三个键。而普通个人计算机鼠标是2键鼠标，那么就需要使用2键模拟中键 的功能，选择这个选项就使得在同时按下鼠标的左右2键时，X服务器将这个动作解释为按下 了第三个键 ── 中键。当然如果计算机上本来就是使用3键鼠标，就不必考虑这个问题了。 鼠标还有一些其他设置，如解析率、移动速率等，一般使用缺省值，不需要改动。

    注意：在使用moused的情况下，映射的sysmouse伪设备本身就为一个3键鼠标，因此 Emulate3Button选项就会失效。需要使用moused的 “-3” 参数，在moused中打开双键模拟第 3键的功能。

  • 键盘设置

    接下来就需要配置键盘，缺省设置为标准101键的PC键盘，就在标准个人计算机下正 常工作，因此对于快速配置X服务器，可以略过这一步配置。当然也可以根据实际选择102键 标准键盘或104键Windows95标准键盘，其他种类的键盘在个人计算机平台上很少见到。

    这个部分中的其他设置是为了与Unix工作站使用的键盘相兼容，而对键盘上的功能 键Ctrl、Shift等重新映射它们的位置和定义。主要是因为专用工作站键盘中的控制键的位 置与标准PC键盘不同，使用这些设置就能使标准PC键盘适合习惯于专用工作站键盘的使用者 。这些设置一般根据使用者的个人习惯而定，对于习惯个人计算机键盘的使用者，一般不需 要改变这些设置。

  • 设置显示卡

    对于X Server的设置来将，最重要、也最困难的一步就是设置正确的显示卡类型， 当前的X服务器已经相当完善，有能力自行检测显示卡的硬件种类，因此甚至可以不配置这 个选项，而留给设置系统来确定。此时就可以跳过这个设置步骤。

    然而对于个人计算机平台来讲，硬件种类过多，并且不同的号称兼容的硬件事实上 存在细微兼容性问题，自动检测并不能保证百分之百检测正确，因此如果自动检测的结果 不能使X服务器正常工作，就需要手工指定显示卡硬件的类型，及相应的参数。显然手工设 置这些参数不是一个简单的事情，需要对自己计算机的硬件有相当了解，最好阅读README 文件（左边按钮），并进一步阅读/usr/X11R6/lib/X11/doc目录下的相关文档，以了解清 楚硬件配置。

    此时，XFree86的自动检测信息也对了解硬件配置信息很有帮助，XFree86提供的程 序SuperProbe可以用来来检测当前计算机使用的硬件，这个程序将探测显示卡的硬件设置， 并将结果返回给用户，帮助用户设置系统。

# /usr/X11R6/bin/SuperProbe

SuperProbe Version 2.18 (22 December 1998)
        (c) Copyright 1993,1994 by David Wexelblat
        (c) Copyright 1994-1998 by The XFree86 Project, Inc

        This work is derived from the 'vgadoc2.zip' and
        'vgadoc3.zip' documentation packages produced by Finn
        Thoegersen, and released with all appropriate permissions
        having been obtained.  Additional information obtained from
        'Programmer's Guide to the EGA and VGA, 2nd ed', by Richard
        Ferraro, and from manufacturer's data books

Bug reports are welcome, and should be sent to XFree86@XFree86.org.
In particular, reports of chipsets that this program fails to
correctly detect are appreciated.

Before submitting a report, please make sure that you have the
latest version of SuperProbe (see http://www.xfree86.org/FAQ).

WARNING - THIS SOFTWARE COULD HANG YOUR MACHINE.
          READ THE SuperProbe.1 MANUAL PAGE BEFORE
          RUNNING THIS PROGRAM.

          INTERRUPT WITHIN FIVE SECONDS TO ABORT!

First video: Super-VGA
        Chipset: ATI 264GT3 (3D Rage III) (Port Probed)
        Memory:  2048 Kbytes
        RAMDAC:  ATI Mach64 integrated 15/16/24/32-bit DAC w/clock
                 (with 6-bit wide lookup tables (or in 6-bit mode))
                 (programmable for 6/8-bit wide lookup tables)
        Attached graphics coprocessor:
                Chipset: ATI Mach64
                Memory:  2048 Kbytes

    XF86Setup提供的显示卡设置界面有两种，一种是以各种具体不同的显示芯片列表的 方式进行显示的，如上图所示，但显示卡上的其他硬件设置都是通过自动检测进行探测。另 一种依据X服务器的种类进行划分，可以指定芯片的具体类型、显存的容量等一些参数的设 置。一般可以选择Detailed Setup按钮，设置X服务器的具体参数。

    在这个Detail Setup的设置方式中，能选择不同的X服务器，并设置芯片、显存、时 序等具体的硬件参数，由于X服务器能够自动探测到系统中的这些参数，一般不必设置这些 值。最重要的是要在选择要使用的正确X服务器，这是因为每一种X服务器只能支持部分种类 的显示芯片，如果选择的X服务器不支持实际使用显示芯片，那么肯定不能正确检测出显示 硬件的各个参数。因此需要根据显示芯片来确定X服务器，而XFree86的文档中提供了那种X 服务器支持那些显示芯片的相关信息。

    必须注意的是，这里选择的X服务器一定要在安装过程中安装到系统中了，否则就找 不到正确的X服务器程序，也不可能正确启动X Window系统。

  • 显示器类型

    接下来要确定显示器的类型，当前使用的显示器都为多频显示器，需要选择正确的 水平和垂直同步频率范围。显示器的水平和垂直同步频率范围决定了显示器的分辨率和刷新 频率能力，超过这个频率范围将使显示器不能正常工作，甚至损坏显示器。实际上显示器的 分辨率和该分辨率下刷新频率这两个参数才是使用者最关心的数据，也是用来判断显示器能 力的最基本参数，此外还有一些参数，如色差、辐射等，属于对显示器的更高要求，但它们 对于X服务器的设置没有影响。

    一个显示器的水平和垂直同步频率范围决定显示器在某个分辨率下的最高刷新频率， 反过来，一个给定的分辨率和在此分辨率下的给定刷新频率也能确定显示器的同步频率范围， 因此可以在图上给出的可选的分辨率和刷新速率选项中，选择自己显示器支持的分辨率与刷新 频率的最高值。选择的值太低就不能充分发挥显示器的能力，太高会造成不能正确显示的问题 。因为这个设置比较重要，因此需要查看显示器手册以得到正确的参数设置（另一种方式是通 过从低到高的尝试，来确认正确的设置）。

    当选定了一个显示器的类型时，就也确定了该显示器使用的显示模式，即分辨率和相 应的刷新频率。因此X Window就会使用的相应显示模式，这个模式就可以用于下面的设置。然 而显示器实际能支持的模式要多于这里设置的显示模式，XF86Setup中并没有提供在同步频率 范围内支持的全部分辨率，只是提供了在某个同步频率范围内值得推荐使用的显示模式。虽然 显示器的最小点大小和显示器本身的大小决定了一个显示器最适合的显示分辨率，例如在小显 示器下使用太高的分辨率就没有太大意义（因为实质上并不能区分出两个近邻的点），但是提 供更多的显示模式能适应一些特殊需要。通常对于15英寸显示器最好使用800x600或1024x768 分辨率，17”显示器可以使用1024x768或1280x1024分辨率。

    另一方面，由于一定显示器的水平和垂直同步范围一定，因此如果分辨率提高了，则刷 新频率就不得不降下来，甚至降到隔行扫描的方式，这样显示器将闪烁的厉害，不适合长时间 使用。当分辨率和刷新频率的设置超出水平和垂直同步频率范围，则显示器将不能正常显示。

  • 设置显示模式

    另外一个设置是选择正确的显示模式，XF86Setup从低到高列出一系列分辨率模式和 多个颜色深度供选择。这一步能选择的显示分辨率模式要受上一步设置的显示器支持的显示模 式的限制。在上一步设置中，有的显示器设置中同时设置了多个显示模式选项，此时就能在这 里选择相应的多个显示分辨率，而有的设置仅仅支持部分显示模式，这里就只能使用对应的分 辨率。同时设置多个显示模式的好处是能够动态切换显示模式，但对于正常使用并没有太大必 要。选择的最大分辨率模式将决定X服务器虚屏大小的设置。

    然后可以选择运行X的颜色数，缺省为8bpp，即256色，但由于硬件的发展，显示内存一 般都比较充裕，因此更常使用16bpp、24bpp等设置，使X能使用更丰富的颜色。这个颜色数主要 由显示内存和显示虚屏的大小来决定，虚屏中的每个象素都占用一个颜色深度大小的显示内存 （8bpp为1个字节，16bpp为2个字节等等），而虚屏的大小为该颜色深度下的最大分辨率模式的 大小（可以在以后更改），那么所有虚屏上的象素占用的空间，不能操作显存的大小。一般来将 ，也不应该将虚屏（或颜色深度）设置的占满显存，因为硬件加速卡内部操作会使用空余显存作 缓冲区，占满显存就会影响硬件加速能力。

  • 其他设置

    其他选项中主要设置一些X服务器的属性标志，如是否可以使用Ctrl-Alt-BackSpace热键 退出X服务器，是否允许动态切换显示分辨率，是否捕获各种信号，是否允许从其他计算机上使用 xvidtune或类似程序改变当前显示分辨率模式，是否许可从其他计算机的X客户程序更改服务器的 键盘和鼠标设置等。

    一般均使用缺省设置，如果管理员要提供更大的限制，例如不允许使用热键退出而必须使 用正常的退出方式等，就应该改动缺省设置。

  • 保存设置启动X服务器

    所有的选择结束之后，就可以选择这个对话框最下端的Done按钮，XFree86将按所配置的 参数重新启动相应的X服务器。如果配置正确，那么X服务器将会正确启动，进入设置好的图形系 统。

    这个时候选择菜单的第一项可以运行xvidune，XF86Setup在这里提供了一个对显示模式 进行微调的机会。显示器出厂设置的时候，只有最常用的显示模式才被调整到最佳设置，其他模 式的设置并不位于最佳设置，在宽、窄、高、低等方面均不是最佳设置。这样在显示器的显示模 式切换的时候，常常会发生显示器所显示的内容不在屏幕正中，或者高度、宽度不正常，这种问 题一般可以通过调节显示器下面的按钮来纠正。然而对较早的模拟式显示器来讲，调整一个显示 模式的设置，就会影响其他显示模式（例如字符模式）的显示，这样就不适合经常切换显示模式 的情况。对于数字式显示器就不存在这个问题，因为显示器能记忆多个显示模式的设置数据，因 此现在一般不需要使用这个调节程序，而直接使用显示器的调整按钮。

    然而xvidtune也能帮助纠正显示模式的偏差，而且无须调整显示器下的任何旋钮，这尤其 对于旧式显示器就更为重要。它通过微调显示模式使用的扫描频率，直接纠正这个问题。因此就可 以执行xvidtune调整显示，当一切正常之后，退出xvidtune时，设置程序将从xvidtune中获得当前 使用的扫描频率，并将其保存到设置文件中。如果在设置程序之外执行xvidtune，不会自动保存调 整结果，而需要手工更改设置文件。

    xvidtune能改变显示模式，也可能超出显示器支持的能力之外，早期的固定频率的显示器 可能会因此造成损坏，现代多频显示器不会因为短时间的模式超范围使用，造成过于严重的后果。 但仍然需要小心操作。xvidtune窗口中显示有调节参数的按钮，每点按一次改变一些参数之后， 应该先使用Test来看看有无问题，再使用Apply来确认改变。一旦显示内容变的不可分辨，表示设 置超出了显示器的能力，就应该迅速使用Ctrl、Alt和Backspace组合键将X杀死，以避免长时间超 范围使用显示器，而对显示器造成损坏。

    使用xvidtune或数字式显示器的调节键将模式调节正确之后，然后选择第二项，将结果保 存到前面指出的配置文件中，缺省为/etc/XF86Config，这就是XFree86的X服务器使用的配置文件 。退出XF86Setup之后，就可以使用startx来启动X Window了。

    X服务器如果不能正确启动，说明前面的配置中出现了错误。此时可以重新进入设置程序， 并重新开始进行设置。需要更仔细的修改相应的配置，以避免错误再次发生。配置错误主要发生在 显示卡硬件的设置上，但也要注意显示器的设置不要超过显示器的实际显示能力。

    当确信XFree86的当前版本不支持所使用计算机的显示硬件，就只能使用16色的标准VGA模 式，或者购买Xi Graphics等商业公司X服务器。一些Linux版本，具备新型显示硬件的XFree86的补 丁或X服务器，FreeBSD的使用者可以从补丁出发重新编译支持新硬件的X服务器，或者直接运行Linux 的X服务器，所需要作的只是调整相应的设备文件的不同。


FreeBSD连载(47)：使用xf86config配置X服务器

作者：王波

使用xf86config配置X服务器

    除了XF86Setup之外，XFree86还提供了另一个交互式的设置 程序xf86config。使用xf86config来配置X服务器是一个比较繁琐的 过程，因为X的配置过程本来就比较复杂，而xf86config使用命令行 交互方式，不能向后返回前一步的设置，因此一旦出现失误，就没 有机会进行纠正，只能重新启动xf86config再次进行设置。正因为 如此，一般情况下不必使用这个设置程序对X Window进行设置，而 应该使用更容易使用的XF86Setup。只有在特定的情况下，才需要使 用xf86config。

    当然进行XFree86的设置，所使用的概念是相同的，因此只要 详细了解了计算机的显示硬件，并有足够的细心和耐心，使用xf86config 同样也能成功的完成设置任务。


FreeBSD连载(48)：X Window的基本概念

作者：王波

使用和配置X Window

    设置好X服务器之后，就可以使用startx启动图形界面，以使用其他图形界 面的经验来使用X Window，但使用者常常会发现这个界面相当简单和粗糙。这是因 为X Window具有很大的灵活性和可配置性，其最基本的系统只提供了最基本设置， 如果要真正得到好用的界面，还需要进一步的设置。

    为了设置和使用X Window系统，首先就需要了解相关的X Window概念。

  • X Window的基本概念

    第一次接触X Window系统的使用者很容易混淆X Window系统中的客户机/服 务器的概念，初次接触X Window的使用者会认为X Window下的客户机/服务器的概念 与普通网络中的客户机/服务器的概念不太相同。通常的观念中，使用者使用客户工 作站，使用远端服务器提供的文件或打印服务，而在X Window下，使用者使用X服务 器进行操作，而客户程序可以运行在本地或者远端计算机上。

    如果进一步理解客户/服务器的概念，就会了解客户/服务器的概念指的是具 体运行的进程，而非计算机或使用者。不是与使用者联系最密切的计算机就是客户， 而是首先要明确服务资源，然后再以资源提供者和资源占用者来进行区分。在一般 的客户/服务器方式的应用中，一般是客户程序直接与使用者交互，因此就容易造成 错误的概念，以使用者为中心来区分客户和服务器。

    但在X Window下，服务资源为X服务器的显示处理能力，X客户程序要显示图 形图象，但它不能直接控制显示硬件，只能使用由用户面前的X服务器提供的显示资 源，同样它也不能接受用户输入，也只能使用X服务器控制的键盘或鼠标资源来接受 输入。在这里，X服务器是硬件的控制者，X客户只是单纯的执行程序，只能使用X服 务器提供的服务进行输入输出。

  • X服务器（X Server）是一个管理显示的进程，必须运行在一个有图形 显示能力的计算机上。理论上，一台计算机上可以同时运行多个X服务器，每个X服 务器能管理多个与之相连的显示设备。

  • X客户程序（X Client）是一个使用X服务器显示其数据的程序，它可以运行 在与X服务器不同的计算机上。

  • X协议（X protocol）是X客户程序和服务器进行通信的一套协议，X协议支持 网络，能在本地系统中和网络实现这个协议，支持的网络协议有TCP/IP、DECnet等。

    X的这种任务划分有几个优点：

客户程序可以在远程计算机上执行计算任务，而使用的X服务器仅负责复杂的图形 显示，充分发挥X服务器在显示上的优势。

    只有X服务器与硬件打交道，所有的客户程序都是硬件无关的，很容易在不同 的平台上移植。

    客户程序可以在不同的计算机上运行，从巨型机到个人计算机，充分发挥网络 计算的优越性。

    尽管每个X客户程序都可以对整个屏幕范围内进行显示操作，但标准的做法是先 创建一个显示窗口，此后客户程序的所有显示都相对于这个窗口进行操作。这样在同一 屏幕内，就能同时显示多个独立的客户程序，通过对窗口的管理在不同的程序之间进行 切换。每个窗口应该位于屏幕的哪个位置，何时显示，何时隐藏，以及窗口的标题、四 周如何显示，这些都不应该由产生这个窗口的客户程序自己控制和维护，否则就不能达 到简化设计的目的。X Window并没有自己实现这些任务，在X的设计原则中，这些代表 GUI风格的任务仍然是客户程序的任务，因此X将管理窗口的任务给予了一个特殊客户程 序 ── 窗口管理器，使用不同的窗口管理器将使X Window的外观看起来截然不同。

    X系统只负责显示图形，并不限制显示和操作的风格，因此不同的X Window的风 格并不相同，使用者可以根据自己的喜好进行选择。

    因此X Window上，所有的窗口形成了一个树状结构。X Window的窗口管理程序运 行在根窗口上，所有的其他窗口为根窗口的子窗口，而其他窗口上也有相应的按钮、对话 框等组件，这些是它的子窗口。

    由于X Window系统只提供了最基本的系统调用，而具体的窗口都有很多共性，因 此要开发X应用程序，应该首先使用开发工具包，而没有必要直接使用最基本的X Window 的系统调用，以简化写作程序的工作量。不同的公司或组织开发了各种工具包来提供创建 和管理具体窗口的构件，例如Motif套件，OpenLook套件等。每种套件都提供了菜单、按 钮、对话框等图形界面的标准构件，还提供基本的窗口管理器。使用不同套件开发的程序 ，其显示风格也不相同，因此就在不同程序之间形成了不同的GUI风格。Motif和Openlook 就是两种不同的图形界面风格，当前Motif成为了商业X Window的一个标准，很多商业软 件均基于Motif进行开发，而Openlook则没有获得更普遍的支持。


FreeBSD连载(49)：进入X Window

作者：王波

进入X Window

    X服务器的执行程序位于/usr/X11R6/bin目录中，并且使用一个符号 联接 “X” ，指向具体的执行程序，如XF86_VGA16或XF86_S3V等。因此直接输 入X命令就能启动设置好的X服务器，系统将进入图形状态，并出现一个可以 移动的X形鼠标指针，但并没有其他反应。这是因为X服务器只负责处理输入 和显示，具体对使用者的输入进行处理则由其他X客户负责，而直接启动X服 务器没有启动任何X客户，因而不能处理用户的任何输入。

  • 手工启动X Window

    因此为了利用图形界面的处理能力，在启动X服务器的同时还应该启 动X客户程序来负责回应用户的输入。这个任务可以通过shell程序startx或 xinit来作到，这两个程序能在启动X的同时，启动X Window的窗口管理程序 和其他X程序。

    startx和xinit缺省查看使用者个人目录下的.xinitrc文件，在这个 文件内应该包含启动各个X客户程序的命令。最简单的.xinitrc可能只包含 一个命令来启动一个仿真终端xterm，也可以包含一系列命令来启动多个程 序，创建出漂亮的X环境。想自己定制X Window操作环境的使用者可以手工 创建和修改这个文件，以得到不同的用户界面。

xmodmap -e 'keysym Alt_L = Meta_L Meta_L'
xterm &
xearth &
twm

    在这个例子中执行了 xmodmap用于修改X的键盘定义，然后在后台执 行xterm提供一个仿真终端，执行xearth设置X Window的背景，最后在前台执 行一个简单的窗口管理器twm。窗口管理器被放到前台执行，这样当退出窗口 管理器时将退出整个X服务器的执行。

    缺省情况下，用户并没有创建这个.xinitrc文件，这样xinit命令就 只能启动一个xterm终端仿真程序，而没有执行任何其他的X程序，也没有执 行窗口管理器。因此，直接使用xinit启动的X Window仅仅具备一个终端窗 口，将鼠标移动到它上面之后，才能输入命令执行其他操作。用户如果想要 启动窗口管理器或其他程序，必须在终端窗口中输入相应的命令。

    由于X Window中存在多个窗口，但只有一个称为 “焦点” 的窗口才能 接收输入。X Window缺省使用鼠标的位置来选择输入焦点窗口，当然另一些窗 口管理器也可以通过键盘来切换输入焦点窗口。

    但是即使不存在.xinitrc文件，使用startx也能启动窗口管理器和几个 X客户程序，这是由于startx发现用户个人目录下不存在.xinitrc文件之后，就 使用系统中的/usr/X11R6/lib/X11/xinit/xinitrc作为xinit程序的启动文件 （startx只是调用xinit的一个shell脚本）。因此更改系统的xinitrc文件，就 能使所有没有创建.xinitrc的用户仍然享有启动文件来启动X Window系统。由 于FreeBSD是一个多用户系统，这样配置启动文件就能简化每个用户的初始配置 任务。在用户对X Window的了解加深之后，就能进一步配置自己的启动文件来 定制自己使用的X Window风格。

  • XDM系统登录方式

    startx或xinit必须先在控制台下登录之后，输入相应命令才能进入X Window 环境。另一种方法为预先启动X Window系统，在X Window下登录进系统。这种 方式是使用xdm来实现的。

    以root用户登录之后，在命令行输入xdm，则系统立即启动X服务器，并 启动相应的登录管理程序，在X Window上出现一个登录窗口，允许各个用户登 录入系统。

    在用户通过登录认证之后，xdm就需要为用户启动登录会话。xdm就以用 户身份执行/usr/X11R6/lib/X11/xdm/Xsession文件，然后再执行用户个人目录 下的.xsession文件。个人目录下的.xsession文件与.xinitrc文件类似，也是一 个标准shell脚本，以下是一个例子。

PATH=/usr/bin:/usr/sbin/:/usr/X11R6/bin:/usr/local/bin
xrdb -load .Xdefaults
xterm &
xearth &
twm

    这个文件与.xinitrc文件的不同之处在于，由于.xinitrc是在用户登录之 后由xinit使用的，因此包括PATH在内的环境变量都已经在用户的.profile等文件 中设置正确了，而通过xdm登录的用户并没有执行.profile等设置文件，因此必须 在.xsession中设置PATH等环境变量，才能正确找到各个执行文件，否则就必须使 用绝对路径来启动应用程序。

    另一个不同之处在于，个人目录下的.xsession文件必须存在，用户才能 通过XDM正常进入X Window，否则登录过程就会发生错误。而对于xinit来讲，.xinitrc 不是必需的如果.xsession的执行有问题，用户就不能从xdm的登录界面上登录进系 统。此时可以检查相应用户目录下的.xsession-errors文件，这个文件中将包含执 行.xsession的错误信息。

    在FreeBSD 3.1-RELEASE中存在一个小问题，.xsession必须具备有可执行 属性，否则就不能正确执行，这个问题在3.2-RELEASE中已经修正。可以从.xsession-errors 中的错误信息中来发现这个错误。

    先使用root登录系统，再手工执行xdm显然只是一个调试时的执行方式， 如果要真正使用xdm让用户登录系统，应该在系统启动时自动执行xdm，最简单的 方法是在/usr/X11R6/etc/rc.d目录下增加一个可执行的文件，例如命名为xdm.sh， 并使用chmod +x xdm.sh使其可以被执行，最简单的xdm.sh可以为以下的形式：

#! /bin/sh
echo “Enter xdm”
/usr/X11R6/bin/xdm

    这样系统将在启动后直接启动xdm，进入X Window并展示一个登录界面等待 用户登录。xdm以一种守护进程的方式运行在后台，每次用户退出之后会自动重新 启动另一个登录界面，允许用户登录。

    当然也可以将xdm命令放入rc.local文件中，然而使用单独的启动文件使得 启动文件更为整齐、清晰。

    启动Xdm的另一种方式是更改/etc/ttys中的设置，系统会根据ttys文件中 的配置在相应终端上启动相应的程序，因此可以在一个空余的控制台终端上，通常 是第四个虚拟控制台ttyv3，启动xdm。

ttyv3     "/usr/X11R6/bin/xdm -nodaemon"       xterm    on secure

    ttys中指定的进程具备再产生的特性，每个进程退出之后立即被重新执行。 因此可以不必使用xdm本身的守护进程功能，而让系统来维护Xdm自动执行。就需要使 用-nodaemon参数，使xdm以普通进程的方式运行。

  • 远程启动X客户程序：

    X Window本身的X协议支持网络，是一种分布式的体系结构。如果使用者的 FreeBSD与其他Unix通过网络相连接，就能在一个计算机上运行X客户程序，而将窗 口显示在另一个运行X服务器的计算机上。

    由于一台计算机上可以运行多个X服务器，每个服务器会支持多个显示屏， 那么X客户程序必须确认在计算机上的某一个服务器的某一个显示屏上进行显示，因 此必须包括计算机地址、X服务器序号和显示屏号来唯一确定一个显示资源的位置， 例如xserver:0.0，通常一台计算机中并没有过多的X服务器，该X服务器也不具备多 个显示屏，因此就可以对显示资源的位置进行简化，一般使用xserver:0的表示方式。

    这种表示方式就可以标志远程X服务器的显示位置，当执行X客户程序时， 就需要在命令行上使用display选项，来告诉X客户程序这个显示位置的参数。

xclient $ xterm -display xserver:0&

    或者通过设置DISPLAY环境变量来达到同样的目的。

xclient $ DISPLAY=xserver:0; export DISPLAY
xclient $ xterm &

    这两种方法都向名为xserver的计算机上的X服务器发出了请求，但能否正 常开出窗口还必须得到这个X服务器的许可。缺省情况下X服务器具备访问控制能力 ，标准访问控制方法使得只有具备访问许可的X客户，及其子程序才能访问X服务器 的资源，而其他X客户程序不能使用X服务器资源。当使用者使用startx和xinit启动 X服务器时，或者通过xdm登录进系统时，其后启动的X客户程序就继承了原有的访问 权限。然而通过网络启动的X客户程序，使用X服务器资源就受到了这个访问控制的 限制，不能正常启动。

    控制X服务器的访问控制能力的命令为xhost，为了使得xserver的显示资源 能被xclient上的X客户程序所使用，就必须在已经具备X服务器访问能力的X仿真终 端下执行以下指令：

xserver $ xhost xclient

    上面的xhost命令允许xclient计算机上的X客户程序使用这个X服务器，也可 以执行使用+作为xhost的参数，这将允许任意X客户程序访问X服务器，因此就存在 一定的安全性问题。如果通过网络使用X服务器的情况比较多，就可以将相应的xhost 指令放入.xinitrc或.xsession中，自动进行设置。

xserver $ rsh xclient /usr/X11R6/bin/xterm -display xserver:0
wb’s password:

    上面是一个使用rsh在一个远程计算机上执行X程序，而将窗口开回X服务器上 的例子，在执行这个命令之前应该执行了xhost client以打开访问权限。


FreeBSD连载(50)：定制X Window的基本方法

王波

定制X Window的基本方法

与其他图形界面相比，X Window是高度可配置的，这是因为X Window 本身只是定义了一系列最基本的显示功能调用，而并没有规定图形窗口应该是 什么样子的，因此大批程序员为X Window开发了各种不同风格的开发工具包和 窗口管理程序，使得X Window的风格多种多样。因此X Window的使用者有多种 选择，可以根据自己的喜好来定制工作站的图形界面。

  • 颜色深度、分辨率与字体配置：

    在前面的设置过程中可以设置X服务器使用多种色彩深度，如8bpp、 16bpp、24bpp和32bpp，一般来讲色彩深度越大，所能表现的色彩越丰富，而 24bpp就被称为真彩色，能真实的表现图象的色彩（32bpp实际也只是24bpp， 它是为了让每个象素都占据独立的32位双字，以对齐象素边界，加速处理速度） 。缺省的色彩深度为对应于256色的8bpp，显然这不足于表现图象的色彩，在硬 件能力满足的条件下应该使用更高的色彩深度（要受显存大小和分辨率大小的 限制）。例如要设置X服务器工作在16bpp的准真彩色下，可以使用带参数的 startx或xinit。

    $ startx -- -bpp 16

    其中前面的两个--线表示将后面的参数不加改变的传递给X服务器。另 一种设置缺省色彩深度的方法是在X的设置文件XF86Config中设置DefaultColorDepth 选项。由于X Window中的色彩深度是可以改变的，为了帮助客户程序使 用具体的色彩，X客户程序中使用的色彩将通过X服务器映射为真实的色彩。X中 还定义了多种标准色的名字，在X程序或资源定义文件中直接使用色彩名字，如 Red、Blue，就得到常用的颜色。X服务器也可以同时支持多种分辨率， 并能够在运行时刻动态切换它所支持的分辨率。在前面XF86Setup设置程序中的 显示器设置选项中，有部分显示器能同时设置了几个显示模式，然而这些分辨率 并不是该显示器能支持的分辨率的全部，如果是使用xf86config或者手工更改设 置文件，还能设置更多的分辨率。当设置了多个分辨率模式的时候，就能在X Window下使用热键

、和<+>向后切换模式，使用 、

和<->向前切换分辨率模式，其中<+>和 <->是小键盘上的键，主键盘上的<+><->并不能用来切换分辨 率

。　　虽然存在不同的分辨率模式，但是X服务器显示的虚屏大小仍然相同，虚拟 显示屏大于实际显示屏，但可以通过鼠标的移动，在实际显示屏上显示虚拟显示屏 的不同部分。因此在有多个分辨率的时候，虚拟显示屏至少应该等同于最大分辨率 的大小，这样不论切换到哪个分辨率，应用程序的窗口仍然保持原有的样子，只是 窗口有可能位于真实的显示屏外，需要通过移动鼠标来移动虚拟显示屏，看到应用 程序窗口的全貌。由于移动虚拟显示屏是通过直接控制显示卡上的寄存器来进行的 ，不需要在显存或内存中进行额外的移动或复制操作，因此几乎不消耗资源，也不 影响任何显示速度

。　　虽然XFree86缺省已经支持了相当丰富的字体，但是还是有可能需要安装新 的字体，例如某种中文字体。X Window的字体应该在配置文件中设置其搜寻路径， 但在启动X Window之后，也可以使用xset命令来重新设置字体的搜寻路径。　　xset fp+ ：增加一个字体搜寻目录。

    xset fp- ：删除一个字体搜寻目录。　　xset fp= ：重新设置字体搜寻目录。

    xset fp rehash：更改某个字体目录中的内容后，强迫系统刷新字体搜寻路径。

    要想使用一些使用者自己设置的字体，就要按下面的步骤将这些字体加入 到X Window的搜寻路径。

  • 　　将这些字体单独放在一个目录下，或者放到系统原有的字体目录下。
  • 　　运行 “mkfontdir 该字体目录” ，构建这个字体目录（将按照所有的字体， 重新生成fonts.dir文件）。
  • 　　使用 “xset fp+ 该字体目录” 或 “xset fp rehash” ，使设置生效。
    fonts.dir文件中包含该字体目录下所有字体的名字，以下为一个例子的部分 内容，该文件每一行都给出一个字体的名字。
gb16st.pcf.gz -isas-song ti-medium-r-normal--16-160-72-72-c-160-gb2312.1980-0
gb24st.pcf.gz -isas-song ti-medium-r-normal--24-240-72-72-c-240-gb2312.1980-0
10x20.pcf.gz -misc-fixed-medium-r-normal--20-200-75-75-c-100-iso8859-1
gb16fs.pcf.gz -isas-fangsong ti-medium-r-normal--16-160-72-72-c-160-gb2312.1980-0

    可以看出font.dir中的内容分为两部分，第一部分为字体文件的名字，第二部 分为字体的名字。每个字体的名字用 “-” 将不同的部分分隔开了，这些相互分隔的部 分包括字体的开发者、字体的类别、字体本身的尺寸（磅数）、倾斜度和点的大小，字 符间距的类型、字体所为的字符集，以及字符的风格。

    可以看出，每个字体的名字相当复杂，然而可以通过定义别名的方式来简化具 体字体的名字，在一个字体目录下，都有一个对应的fonts.alias的文件，这里就登记 了很多字体的别名，使用者也可以自己根据需要增添。

fixed        -misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso8859-1
variable     -*-helvetica-bold-r-normal-*-*-120-*-*-*-*-iso8859-1
5x7          -misc-fixed-medium-r-normal--7-70-75-75-c-50-iso8859-1
5x8          -misc-fixed-medium-r-normal--8-80-75-75-c-50-iso646.1991-irv
    上面就是某个font.alias的一部分，它的第一列就为简单易记的别名。在运行 X Window时，可以使用xlsfonts来查看系统中可以使用的字体信息，使用xfontsel来 查看每种字体的外观。
  • 定制客户桌面基本方法

    根窗口的特征可以使用xsetroot命令来设置，可以使用它来定制窗口的颜色（背 景色和前景色），或者使用一个位图作为背景等。也可以使用”xset s seconds”来定义屏 幕保护的激活时间，”xset s default”将屏幕保护设为系统的缺省配置。

    还有很多更强大的X程序能用来定制X的根窗口，设置壁纸和屏幕保护。例如可以使 用xv来将gif或jpg等类型的图片设置为壁纸，这些程序都可以在FreeBSD的Packages Collection 和Ports Collection中找到。

    X客户程序通常使用标准的构件，通常这些构件都有一些标准的参数来定义它们使 用的字体、文字的前景色、背景色、滚动条等。这些参数可以通过更改构件的资源设置， 来改变其设置。一般使用用户个人目录下的.Xdefaults或.Xresoures作为用户的个人资源 文件，资源文件在启动时在.xinitrc文件中由xrdb命令载入系统。

    除了资源设置之外，标准X客户程序中的构件也支持标准的命令行选项，可以用来 改变窗口构件的属性：

    -borderwith或-bw，框架的宽度，以像素为单位

    -foreground或-fg，前景色

    -background或-bg，背景色

    -display，客户程序要使用的X服务器的显示位置

    -font或-fn，显示特殊文字使用的字体

    -geometry，窗口的几何结构，包括位置和大小

    -iconic，以图标方式启动

    -title，标题栏的标题

  • 选择窗口管理器和桌面环境

    在FreeBSD安装好XFree86之后，缺省的窗口管理器是twm，这是一个比较简单的 窗口管理器，会使得第一次接触X Window的使用者对X Window产生不好的印象，但是如 果进一步了解X Window系统，就会知道X Window本身并没有包括真正好用的窗口管理器 ，但是却存在很多种优秀的窗口管理器能达到这个目的，使X Window变得更华丽、更易 用。

    因此必须从Packages Collection中选择安装相应的窗口管理器或桌面环境，可 供选择的有fvwm95、AfterStep、KDE等。

    fvwm95是从另一个窗口管理器fvwm2的进行改进之后的版本，它被设置为与Windows95 的桌面非常相似，因此习惯于Windows95界面的个人计算机使用者常常会选择这个窗口管 理器，然而既然使用的是X Window，没有必要一定还要使用Window95的显示风格，使用 fvwm2、AfterStep等其他窗口管理器来尝试其他风格更为有益。一般情况下使用者还是 会安装一个fvwm95，fvwm95使用的配置文件是用户主目录下的.fvwm2rc95文件，而缺省 配置文件为/usr/X11R6/lib/fvwm95/system.fvwm2rc95文件。使用fvwm95时最简单的启 动文件.xinitrc应包括：

    /usr/X11R6/bin/fvwm95　　AfterStep是模仿NextStep的窗口管理器，这个窗口管理器精巧而且漂亮，如果 不是过于沉迷于Windows95的操作方式，不妨使用这个窗口管理器，它还有几个派生的管 理器，如WindowMaker、enlightenment等。为了充分发挥AfterStep的华丽，X的显示屏 应该大于800x600的分辨率，并至少使用16bpp的色彩深度。AfterStep的所有配置文件均 放置在用户主目录下的GNUStep目录中，相应的启动文件为：　　/usr/X11R6/bin/AfterStep　　与前面两者不同，gnome和KDE不仅仅是一个窗口管理器，还包括大量的应用程序 和相关工具（gnome使用enlightenment作为其缺省窗口管理器）。这些桌面环境包括各种 应用程序、控制条、图形化的设置程序等，使用它们能够全面享受到图形桌面环境的优 点，但它们占用的系统资源也相对较多。如果是将安装FreeBSD的计算机用做一台工作站 ，那么就应该选择其中一种桌面环境，用户可以根据自己的喜好来选择安装gnome或者KDE。　　如果选择安装了KDE时，在.xinitrc及.xsession中应该包含的相应启动命令为：　　/usr/local/bin/startkde　　在3.2=RELEASE之后，FreeBSD能通过Sysinstall来设置不同的桌面环境，Sysinstall 能安装相应的软件包，并在/usr/share/skel中添加dot.xinitrc和dot.xsession文件，这样 在生成用户时就自动生成.xinitrc和.xsession文件。

  • 配置和使用KDE

    KDE不单单是一个窗口管理程序，它包括了使用X Window图形界面进行操作所 需要的各种应用程序。它的主要部分为一个拥有任务条、工具条、快捷图标的桌面环 境，并包括可用于浏览WWW网页的文件管理器、编辑器、计算器、CD播放器、邮件处 理程序、新闻组阅读程序等等大量的应用程序。

    KDE的另一个特点就是包括了对图形界面外观的定制程序，一般情况下Unix中进 行配置需要修改对应的配置文件，虽然这种方式提供了很大的灵活性，但对于很多不重 要的设置，并不需要这么灵活的方式，而要求方便、简易。在KDE下不需要使用手工更 改配置文件，而是通过图形界面的设置程序进行设置，因此更容易使用。下面为一个KDE 界面的例子：

    由于KDE是为了高性能的图形界面开发的，因此为了获得较好的观感，至少应该 以800x600分辨率运行X Window，建议使用1024x768以上的分辨率，以充分发挥KDE的显 示效果。　　KDE图形桌面由桌面背景、快捷图标、工作栏和任务条组成，每个可以点击的位 置上通常使用左键一次点击启动相应的功能，使用右键点击出现一个菜单，可以进行相 关设置。上图为进行工作栏和任务条的外观设置，设置它们显示的不同的大小和位置。 此外，在桌面上使用右键可以配置桌面外观，包括墙纸和屏幕保护。点击左下角的K图标 可以弹出一个菜单，菜单中包括了KDE环境提供个多种应用程序，也可以添加对其他应用 程序的连接。　　与MS Windows不同，KDE（以及大部分X窗口管理器），使用一次点击启动应用程 序，而不是双击。KDE下切换窗口的热键与Windows相同为Alt-Tab。　　KDE界面低部工作栏上的各个按钮都对应一个相应的应用程序，而其中并列的四 个按钮，对应四个不同虚拟屏幕，每个屏幕上的内容各不相同，可以分别配置。KDE最 多可支持八个虚拟屏幕，每个窗口只显示在一个屏幕上，除非使用鼠标将窗口左上角的 图钉标志打开，这样操作之后这个窗口总显示在屏幕上，而不管如何切换虚拟屏幕。　　KDE的配置工作全部可以通过KDE配置中心（KDE Control Center）来完成。点中 左下角的 “K” 图标，在菜单中选中KDE Control Center或使用工作栏上的快捷图标，就 可以启动它对KDE的外观进行配置。

    KDE控制中心可以设置KDE桌面环境的排列方式，如工作栏、任务栏的大小和位 置，窗口的风格，使用的颜色，屏幕保护以及其他一些应用程序的相关设置。这些设置 也可以在KDE桌面环境中，使用鼠标右键弹出的菜单中的选项来启动。　　由于KDE是一种国际化的应用程序，因此可以使用上面的设置程序将KDE使用的字符 设置为中文。当将KDE使用的语言设置为中文时，那么所有KDE的菜单都使用中文，但是这 需要中文X服务器或其他中文系统的中文显示能力的支持，否则KDE虽然显示的是中文字符， 但是显示的却会是乱码。　　对于使用XDM登录方式的系统，需要使用xdm以提供系统登录。虽然用户登录后可以 从.xsessin中启动KDE，但仍然摆脱不了xdm过于简陋的登录画面。而KDE的另一个特点就是 提供一个xdm的替代程序kdm，这使得系统管理员可以替换掉简单的xdm界面，使用kdm来提 供更漂亮的XDM登录界面，这使得X Window系统表现得更为华丽。 　　上图就是一个kdm的外观，它同样也是在KDE控制中心中来进行配置的，只是由于 kdm属于系统程序，因此只有root运行的KDE控制中心才能选择这一项配置功能。设置KDM ，需要选择KDE配置中心的第一个选项Desktop Manager。 　　这个选项中可以设置kdm的图标、出现在kdm的用户列表中的用户、或者不出现在kdm 的用户列表中的用于，以及在会话结束时用于关闭系统的指令等。

  • 将工作站用作专用X终端

    专用机房中常常使用X终端为公共使用者提供服务，使用者可以通过这些终端以XDM 方式登录到机房中的Unix主机上去。X终端不允许使用者登录到自己系统中，而只能使用本 地X服务器的处理能力，登录到其他主机上进行使用。

    由于个人计算机硬件更为便宜，并且由于硬件的发展其性能也并不落后，使用个 人计算机作X终端也是一种在使用专用X终端之外很不错的选择。可以使用FreeBSD作操作 系统，Xfree86支持X Window系统，就能将FreeBSD系统用作专用X终端，这样的优势是所 有的软件都可以免费得到，就使得在实现几乎同样的性能的条件下，却减少了大量的资金 投入。

    同样也可以通过设置使得用户不能登录进本地系统，而是直接登录到网络上的其 他Unix主机中去。这需要那台提供登录服务的Unix主机运行xdm，这样X终端就能通过xdmcp 协议在网络中通过广播或者直接查询的方式，查找到运行xdm的主机，并连接上来提供登录 登录画面，就如同在本地系统一样。用作X终端的FreeBSD系统需要以使用特别的参数运行X， 以查找XDM主机。

    如果运行XDM的Unix主机和用作X终端的FreeBSD系统在同一个以太网段上，可以使 用广播的方式寻找运行XDM的主机，此时启动X的命令为：

    # /usr/X11R6/bin/X -broadcast　　这样系统上将列出本地所有运行XDM的Unix主机，供使用者选择登录。或者可以直 接查询方式，通过query参数直接与某台Unix主机相连接，这可以用在客户机和服务器不在 同一个网段上的时候。

    # /usr/X11R6/bin/X -query Unixhost

    为了使系统一启动就进入这个登录状态，可以将这个命令写入shell脚本，并放入 系统启动目录/usr/X11R6/etc/rc.d中。然而此时使用ttys文件进行设置更佳，因为此时可 能同时想关闭虚拟控制台，以防止X终端使用者切换到虚拟控制台上。


FreeBSD连载(51)：中文X应用软件

王波

X Window下的中文环境

    Unix的中文化对于Unix的推广使用一向是个难题，对于象FreeBSD这 样的操作系统来讲，中文化工作比较零乱，虽然有不少X下的中文软件，但是 由于国内软件发展的水平还不高，自由软件的开发水平更是如此，并且自由 软件的开发者之间也没有被有效的组织起来，因此还没有出现一个很完整的 中文系统。

    然而中文相关的软件却相当丰富，在Ports Collection中，有一个类 别就是chinese，专门收集中文相关的处理软件，但其中绝大多数是台湾的BIG5 版本。因为台湾在FreeBSD领域的发展相当快，很多软件都是先由台湾出现相 应BIG5版本之后，再出现GB版本。

bash-2.02$ ls /usr/ports/chinese
CJK             big5fonts       gbfonts         nvi-big5        ted
CVS             c2t             gbscript        nvi-euc-cn      tin
Makefile        celvis          hc              nvi-euc-tw      xcin
README.html     cless           hztty           pine3
Wnn             cnsfonts        kcfonts         pine4
bg5ps           cxterm          lunar           pkg
big5con         gb2ps           mule-wnn4       rxvt

  • 中文X应用软件

    在X Window下使用中文的基本条件之一就是需要安装合适的中文字库。 当前的XFree86发行版本中带有一些基本中文字库，在系统安装选择X组件的设 置时需要将其包括在内，然而中文存在不同的编码方式，使用不同编码的应用程 序就使用不同的字体文件，XFree86中提供的中文字体对于另外一些中文程序还 是不够的。

    Packages Collection中的chinese类别中也提供了其他的一些BIG5和GB 编码的字体，如gbfonts、kcfonts、big5fongs等软件包，需要使用pkg_add命令 将其安装入系统。在真正执行中文X应用程序时，可以使用xlsfont命令可以查 看系统中是否有相应字库，如：

$ xlsfonts *gb*
-cc-song-medium-r-normal-jiantizi-0-0-75-75-c-0-gb2312.1980-0
-cc-song-medium-r-normal-jiantizi-40-400-75-75-c-400-gb2312.1980-0
-cc-song-medium-r-normal-jiantizi-48-480-75-75-c-480-gb2312.1980-0
-isas-fangsong ti-medium-r-normal--0-0-72-72-c-0-gb2312.1980-0
-isas-fangsong ti-medium-r-normal--16-160-72-72-c-160-gb2312.1980-0
-isas-song ti-medium-r-normal--0-0-72-72-c-0-gb2312.1980-0
-isas-song ti-medium-r-normal--16-160-72-72-c-160-gb2312.1980-0
-isas-song ti-medium-r-normal--24-240-72-72-c-240-gb2312.1980-0
hanzigb16fs
hanzigb16st
hanzigb24st

    当一个字体不存在但同时存在同样编码的其他字体的时候，可以通过在 fonts.alias中定义别名的方法来帮助解决这个问题。

    除了Packages Collection提供的字体之外，从网络上也可以得到其他的 一些中文字体。在ftp://ftp.ifcss.org站点中收集了很多自由或共享中文字体 和中文软件。

  • cxterm

    cxterm是一个使用非常广泛的中文X终端程序，已经被移植到很多种类 的Unix系统中。它已经被FreeBSD的爱好者做成Packages，因此安装起来非常简 单。cxterm支持GB、BIG5以及日、韩文等编码和多种输入法。

    直接启动cxterm只能用于浏览中文而不能进行输入，这是由于cxterm需 要X系统的一些资源设置，以使用快捷键切换不同输入法，并根据设置寻找其输 入法对应的数据文件。要输入中文必须进行设置，将资源文件预先载入，指定热 键、输入法和输入字典所在的目录。cxterm软件包中提供了一个缺省的资源文件 CXterm.ad，一些使用者将这个文件中的相应资源定义放入~/.Xdefault中，用户 登录进入X Window时就载入这些资源。另外，cxterm还提供了一个shell脚本 ── CXterm，可以在启动cxterm之前完成相应的资源设置工作，所以一般应该 用如下CXterm命令来启动cxterm，这种启动方式更为简易。

    $ CXterm &

    在中文的仿真终端下使用bash作为shell时，会发现在命令行中无法输入 中文，这是因为bash对输入进行了额外处理，可以在~/.bashrc中设置bash让其 通过中文（另一个可能的因素为stty的终端设置）：

stty pass8
bind 'set convert-meta off'
bind 'set meta-flag on'
bind 'set output-meta on'

    在FreeBSD下的预编译的cxterm软件包中，cxterm的输入法及输入字典放 在了/usr/X11R6/lib/X11/cxterm.dic目录中。由于cxterm的影响，它的输入法被 相当多的X Window下的中文软件所使用。

    标准的CXterm是黑白的，但也存在一个补丁，使CXterm能显示彩色。然 而，Packages Collecion中预编译好的CXterm为标准程序，要使用彩色CXterm就 需要自己下载补丁并重新编译CXterm。

  • Xcin与crxvt

    crxvt是另一个中文X仿真终端软件，与cxterm相比，它更小巧，占用更少 的内存，并能以ANSI标准显示彩色。Xcin是一个独立的输入服务器，它独立于具体 的X程序之外来提供中文输入功能，X应用程序可以使用其接口支持中文输入。crxvt 就使用Xcin作输入系统。与cxterm的将输入与仿真终端集成在一起的方式不同， Xcin在crxvt外打开一个单独的窗口，但在crxvt中可以使用Ctrl-Space进行Xcin 下的中英文输入切换。可以看出Xcin的设计目的是作为一个通用输入模块来实现 的，以便多个应用软件都能使用同一个输入模块来进行中文输入，而不是象cxterm 一样，每个程序使用自己的输入模块。

    FreeBSD的Packages Collection中，也包括了Xcin与crxvt，但遗憾的是，他 们是台湾big5版本。当然这也容易理解，这个软件本来就是由台湾人开发的。其中 crxvt可以通过使用hztty使其能显示gb数据，但使用者显然不会使用台湾的输入法输 入中文。幸好这个软件已经被移植到GB环境下，并也有编译好的软件包形式（未被正 式FreeBSD发行版本收录），这样就可以使用pkg_add等工具进行管理，而不再需要手 工编译。

    执行时，需要启动xcin和cxrvt，注意要使用Xcin而不是xcin启动Xcin，主要 是Xcin能使用正确的输入法参数启动真正的xcin程序，直接启动xcin由于没有指定输 入模块的设置，就会导致程序启动失败。

$ Xcin &
$ cxrvt &

  • 其他支持中文的软件与中文本地化

    除了cxterm、cxrvt之外，Ports Collection还包括其他一些软件，如hztty 用于终端上hz、big5、gb等不同编码的动态转换，big5con用于在控制台上显示中文 big5码（在hztty的帮助下可以显示gb码），cvi用于替换vi进行中文编辑工作，cless 用于替换more显示中文，gb2ps用于中文文本文件的打印处理等。

$ LANG=zh_CN.EUC; export LOCALE
$ LC_ALL=zh_CN.EUC; export LC_ALL

    对于支持多语言的软件，使用环境变量LANG和LC_ALL来标识不同的语言、及 不同的环境。缺省情形下使用的语言LANG被设置为C，如果要支持中文，应该设置为 zh_EUC.GB，同样LC_ALL用于设置不同语言使用的信息格式的不同，如日期、时间的 表示方式等。虽然当前不是每个应用程序都支持这些环境变量，但随着FreeBSD系统 的升级，应用程序国际化程度的提高，以后的软件越来越多会对各种语言提供更完善 的支持。

    另外，FreeBSD下的一些传统工具程序不支持国际化的语言，应该使用较新的 GNU工具代替。例如标准的ls命令不能显示中文文件名，可以安装gnuls软件包，使用 gnuls -N命令来代替缺省的ls命令，可以通过shell中的alias设置，使得用户感觉不 同执行命令的差异。


FreeBSD连载(52)：外挂式中文显示与输入软件

王波

外挂式中文显示与输入软件

    对于支持中文的软件，可以使用自己的方式处理中文的显示与输 入。然而更一般的软件中，都没有直接提供中文支持，有些能够部分识 别中文但无法处理中文输入，如Netscape Navigator。有些根本不能识 别中文，有些甚至将8位字符作为非法字符来看待。对于最后一种过滤8 位字符的情况，是没有办法能使其正常显示、输入中文，但对于前两种 情况，就有变通的方式使其正常显示和输入汉字。

  • 动态连接库的wrap技术

    X Window下的客户程序要显示字符，需要调用libX11.so.6动态 连接库中的XDrawString()等函数进行具体处理显示，如果这个函数能够 区分出中文字符，并自动使用合适的中文字体进行显示，那么客户程序 就能正常显示中文。因而最基本的想法是修改X11R6中这些相关的显示处 理函数，使它们能正常显示中文。当然这可以通过直接修改XFree86发行 版本中这个函数的源代码，并通过重新编译、安装库函数来做到。然而 这需要更改原有的正式发行版本，不是每个用户都愿意并且能够重新编 译X系统的，并且这种方法对于不具备源代码的商业X服务器系统就不使 用。而且更改libX11.so.6也不太安全，缺乏灵活性，因此最好不更改原 有的连接库，就能达到正确处理中文的目的。

    由于一般的应用程序使用动态连接的方式，在应用程序载入内存 时，系统才将具体的动态连接库连接上。因此如果在系统载入标准的库 之前，预先载入一个包含同样名字函数的动态连接库与应用程序连接， 那么程序会使用先连接的第一个库中的同名函数库，而非原有的标准库 函数，这种方式就称为包装（wrap）的方法。

    现代Unix都支持这种预连接动态连接库的能力，系统在载入动态 连接库之前，首先查看LD_PRELOAD环境变量，如果这个变量定义了一个动 态连接库，那么就在连接其他标准动态连接库之前先连接这个变量定义的 动态连接库。因此如果这个预载入的动态库中有XDrawString()等函数的 定义，那么它们就覆盖了系统中libX11.so.6库中的原有定义，而这个包 装库可以通过直接访问libX11.so.6库来找到原有的标准函数，以真正处 理显示。

    出于系统安全的考虑，系统不允许SetUID或SetGID的程序载入LD PRELOAD变量设置的动态连接库，这主要是避免用户通过定义自己动态连 接库，在setuid等系统调用之后取得root权限。因此包装技术不适合具有 SetUID或SetGID属性的二进制执行文件。此外，静态连接的执行程序在程 序内部查找显示函数，也不适合使用包装技术（可以使用ldd命令来查看 执行程序的动态连接关系，来判断其连接类型），除了这两种情况之外的 其他X应用程序，就能支持中文包装技术。

    在使用包装技术时，另一个重要的问题是FreeBSD系统中存在两种 不同的执行文件格式，a.out和ELF格式，它们分别使用a.out和ELF格式的 动态连接库。因此对于不同格式的执行文件，必须使用相应格式的包装库 来包装不同的libX11.so动态连接库，不同格式的库不能相互连接。3.0版 本以上，缺省格式为ELF，缺省库也为ELF格式的动态连接库。因此3.0版 本以后要支持对a.out格式进行包装，一方面包装的动态连接库的位置就 改变为/usr/X11R6/lib/aout/libX11.so.6.1，同时也需要使用编译器的 -aout选项生成a.out格式的动态连接库，以进行包装。当前发行的标准 Packages均已经转向ELF，仍使用a.out格式主要是一些商业软件，如 Netscape Navigator。

  • Xcin AnyWhere

    XA（Xcin AnyWhere）是一个较早的使用包装技术的中文输入软件 ，它原来仅仅是用于中文输入，为Xcin提供一个标准接口，后来被加入了 中文显示能力。具备中文显示能力的XA被称为XA+CV版本。

    XA是由台湾开发者开发的，当前版本为XA-0.4b，它具备GB显示能 力的国标版本为xa-1.04。它能够在FreeBSD下编译执行。对于这些包装方 式的外挂中文系统，可以使用它提供的shell脚本xa来启动应用程序。

    $ Xcin&

    $ xa kvt&

    或者自己设置LD_PRELOAD变量为wrap动态库的全路径，再启动相 应的应用程序。

    $ LD_RELOAD=/usr/X11R6/lib/wrap.so; export LD_PRELOAD

    $ kvt&

    在启动了它的输入服务器Xcin之后，那么就能在xa启动的程序中就 能使用热键切换Xcin的中英文输入了。

  • Chinput与ZhXwin

    Chinput是另一个使用了包装技术的中文输入和显示软件，它是使 用了cxterm的输入源代码模块在Linux下开发的，在FreeBSD下也能够正常 编译运行。Chinput的作者在其正式发布1.4.1版本中包括了几个与中文显 示和输入无关的软件，虽然单个软件都还很有用，但是将几个软件捆在一 起，使得应用程序管理比较混乱，还是应该将每个单独的应用程序独立出 来，Chinput就专门用于中文的输入和管理。FreeBSD中可以使用Packages 的管理机制来管理应用程序之间的关系。

    Chinput使用资源文件Chinput.ad，并需要Cxterm的输入法，因此 需要预先安装Cxterm包。它还提供了一个脚本run来运行应用程序。但直接 设置LD_PRELOAD变量的方法也不复杂（移植到FreeBSD后的package中的执 行脚本被更名为crun），Chinput的输入服务器为chinput，因此可以使用 下面的命令来启动Chinput。

    $ chinput &

    $ crun kvt &

    ZhXWin的输入服务器也使用Chinput的chinput，并加上一个比较简 单却有效的用于处理显示的包装库，它可能是基于Chinput的一个早期版本 发展的。ZhXWin的优点是简单、有效，标准Chinput使用了几种不同大小的 字体进行显示，而ZhXWin仅仅使用一种字体，然而除了一些字符间距的处理 方面，其显示效果还不错。

    $ LD_RELOAD=/usr/X11R6/lib/libst.so; export LD_PRELOAD; kvt&

  • 使用包装软件

    每个包装软件由两个部分组成，一个部分为输入模块，需要单独运 行。XA使用Xcin作输入模块，Chinput和ZhXwin使用chinput作输入模块。 另一个部分为包装库，需要使用LD_PRELOAD环境变量进行设置。

    如果要让窗口管理器，如KDE，也显示中文，就需要在启动这些窗口 管理程序之前设置好包装库，这就需要在.xinitrc或.xsession文件中的最前 面增加LD_PRELOAD变量的定义：

$ mv ~/.xinitrc ~/.xinitrc.orig
$ cat > ~/.xinitrc
LD_PRELOAD=/usr/X11R6/lib/wrap.so
export LD_PRELOAD
chinput &
^D
$ cat ~/.xinitrc.orig >> ~/.xinitrc

    然而由于这些中文包装软件需要处理键盘，以用于输入中文，直接让包 装软件接管窗口管理器，就使得它也影响窗口程序的键盘控制，就使得一些热 键不能正常使用。虽然通过包装KDE，使KDE能显示中文菜单和中文提示，但为 了使用正常的键盘操作，还是推荐对每个需要中文能力的软件分别进行包装， 而不要直接对窗口管理器进行包装。

    所有的这些中文包装库都比较新，没有经过足够的实践考验或测试，因 此存在问题是难免的。当包装了窗口管理器时，如果包装库出现问题，就可能造 成X服务器的键盘死锁，对使用者的操作没有反应。然而此时系统并没有停止运 行，可以使用网络连接上去，杀死X服务器，更改包装设置。


FreeBSD连载(53)：中文X服务器

王波

中文X服务器

    除了在X11的库函数级汉化，以支持显示中文的能力之外，另一种使 X Window系统显示中文的方法是在X服务器级进行汉化。汉化X服务器就使得 所有的西文软件能正常显示中文，当然它必须没有对8位字符进行特殊的过 滤处理。并且由于是在服务器低层对中文进行支持，因此速度和兼容性也很 好。XFree86的汉化版本称为CXwin，也是由台湾开发者首先进行开发，当前 移植到GB的版本为CXwin 0.5。

    为了安装CXwin，必须重新编译X Server，这样首先就要下载XFree86 的服务器源程序，展开后使用Patch命令打上CXwin的补丁后，重新编译X服务 器。最后才能生成针对不同硬件的中文X服务器，那么就可以使用CXwin的X 服务器代替原有的同样硬件的X服务器，在X Window下就能够正常显示中文 了。

    X服务器被放到/usr/X11R6/bin目录下，例如S3显示卡对应的X服务 器为XF86_S3，需要使用同名的CXwin服务器替换原有的程序。除了标准的 XFree86的设置文件之外，CXwin还使用配置文件/etc/X11/ChineseConfig来 设置中文字体等设置，一般缺省设置文件就能满足正确显示中文的要求。由 于CXWin是直接替换原有的X服务器，因此必须保证安装CXwin之前XFree86已 经安装和设置正常了。

    从显示效果来看，CXwin 0.5有最佳的显示效果，会根据不同英文字 体大小而选择对应大小的中文字体，因此除了有时由于汉字字体过大而使得 字体被切去一部分之外，对于字体的大小和间距处理的最好。然而中文输入 还要依靠XA或Chinput。因此最佳的效果应该是使用CXwin用于基本显示，XA 或Chinput用于包装某个应用程序，提供中文输入，并设置了中文为缺省语 言的KDE作桌面环境。有了这些之后，FreeBSD系统就具有了中文桌面操作环 境的基本中文处理能力了。

    为了利用CXwin的显示，而不被包装软件截去中文显示能力，最好使 用不带中文显示能力的xa（无CV代码）来管理中文输入。此外，Chinput也 使用了多种不同大小的字体来提供输出，其显示效果也不错。带CV能力的xa 使用字体缩放技术来产生合适大小的字体，但字体缩放会消耗额外的系统资 源。ZhXwin最简单，适合简单浏览中文的情况 。

    由于CXwin需要针对每个不同的X服务器进行修改，因此对于不同的X 服务器，其显示效果存在差异，有的X服务器具有相当不错的显示效果，而有 的效果较差，或不能正常显示，而有的X服务器还不支持中文显示能力。需要 随着CXwin的进一步发展，各个问题才会被逐渐解决。


FreeBSD连载(54)：配置文件XF86Config

王波

配置文件XF86Config

    位于/etc目录下的XF86Config文件是XFree86的X服务器的配置文件，XF86Setup 或者xf86config在配置完后就将配置信息保存在这个文件中。XFree86也提供了一个配置 文件的样例文件，/usr/X11R6/lib/X11/XF86Config.eg，可以用作参考。很多情况下需 要对X的行为进行微调，而并不想重新启动设置程序重复进行整个设置过程，这样手工修 改配置文件就更为方便。

    有一些X服务器的参数使用配置程序并不能进行配置，必须在原有XF86Config上 手工更改配置文件。

    下面将以一个简单的配置文件为例进行简单介绍XFree86的设置选项。

  • 文件搜寻路径

Section "Files"
    RgbPath    "/usr/X11R6/lib/X11/rgb"
    FontPath  "/usr/X11R6/lib/X11/fonts/75dpi/:unscaled"
    FontPath  "/usr/X11R6/lib/X11/fonts/100dpi/:unscaled"
    FontPath   "/usr/X11R6/lib/X11/fonts/misc/"
    FontPath  "/usr/X11R6/lib/X11/fonts/75dpi/"
    FontPath  "/usr/X11R6/lib/X11/fonts/100dpi/"
#    FontPath   tcp/fontserver:7000
#    ModulePath	"/usr/X11R6/lib/modules"
EndSection

    上面是配置文件的第一部分 “Files” ，这个文件部分定义了 X Window使用的搜索文件路径，如调色板文件的路径RGBPath，字体路径FontPath，以 及ModulePath用来设置X服务器的动态可加载模块的路径。

    其中字体路径可以使用多行来设置多个路径，也可以在一行之内设置多个路径， 路径之间使用逗号分隔。字体路径也能定义为网络上的字体服务器，这需要指定协议、 主机名和端口地址，例如tcp/fontserver:7000表示一台名为fontserver的字体服务器使 用tcp端口7000提供字体服务。Unscaled用于修饰表示对这个路径下的字体不进行缩放处 理，处理固定字体可减少系统资源的消耗。使用字体服务器可以让多个服务器同享字体， 从而达到节约磁盘空间的目的。

    在行首使用符号 “#” ，表示这一行为注释，并不被X服务器处理。

  • 可加载模块

# Section "Module"
# Load "xf86Jstk.so"
# EndSection

    如果前面Files部分定义了ModulePath，这个"Module"部分就用 来装载相应路径下具体的模块。一般情况下，并不需要使用这个功能，除非是使用了一 些非标准的功能，需要可加载模块的支持，如xf86Jstk.so就是一个游戏杆的驱动程序。

  • X服务器选项

Section "ServerFlags"
#    NoTrapSignals
#    DontZap
#    DontZoom
#    DisableVidModeExtension
#    AllowNonLocalXvidtune
#    DisableModInDev
#    AllowNonLocalModInDxev
EndSection

    "ServerFlags"部分设置一些X服务器的运行参数，对应于XF86Setup 中的Other选项中所设置的内容，一般不需改变。

    NoTrapSignals选项使得X服务器程序不去处理发送到X服务器的各个信号， 正 常情况下不设置这个选项，X服务器应该接收并处理这些信号，当接收到某些信号时就释放X服 务器占用的资源，切换显示模式并退出X服务器的执行。因此打开这个选项就使得发送到X服务 器的信号没有得到处理，在错误不严重的情况下，X程序仍将继续执行而不退出。因此可以用 于调试X服务器，观察X的出错原因及其影响。

    DontZap选项用于屏蔽Crtl-Alt-BackSpace热键，通常不设置这个选项时，使用 者能够使用这个组合热键退出X服务器。当要将XFree86系统用作公用X终端时，最好使用这个选 项屏蔽退出热键，让用户使用正常的退出方式退出登录会话。

    DontZoom这个选项用于屏蔽<Crtl><Alt><小键盘 “+” >或< 小键盘 “-” >两个用于动态切换分辨率模式的组合键，当然X服务器必须同时设置了多个分辨率 模式，这两个组合键才有意义。

    xvidtune能实时改变X服务器的显示模式，例如调整显示区域位于显示器中的位置等。然 而一旦针对某个显示器的显示模式调整正确之后，就没有必要动态改变了，因此可以使用DisableVidModeExtension 选项屏蔽xvidtune实时改变显示模式的能力，以保证显示器的安全。一般只有本服务器上的 xvidtune可以完成这个操作，在当前X服务器上运行远程计算机上的xvidtune不允许改变本服 务器的状态。但是，也可以通过设置AllowNonLocalXvidtune选项， 使得非本服务器 上的xvidtune也有能力和本地的X服务器进行通信。第二个选项必须在第一个没有设置的条件 下才能设置。为了安全的原因，不应该允许远程系统上的xvidtune获得本服务器的硬件设置信 息，不要设置这个选项。

    使用DisableModInDev选项，可以屏蔽客户程序对输入设备（鼠标或键盘）的动 态改变。 而AllowNonLocalModInDxev选项可以许可非本地的程序（xset）能动态改变 键盘或鼠标的设置。同样，这两个选项是冲突的。

  • 键盘设置

Section "Keyboard"
    Protocol   "Standard"
#    Protocol  "Xqueue"
AutoRepeat 500 5
#    ServerNumLock
#    Xleds      1 2 3
     LeftAlt     Meta
     RightAlt    ModeShift
     RightCtl    Compose
     ScrollLock  ModeLock
#    XkbDisable
 XkbKeycodes     "xfree86"
 XkbTypes        "default"
 XkbCompat       "default"
 XkbSymbols      "us(pc101)"
 XkbGeometry     "pc"
 XkbRules        "xfree86"
 XkbModel        "pc104"
     XkbLayout       "us"
EndSection

    "Keyboard"用于定义键盘的参数，指定了键盘使用的协议、重复率以及对 一些功能键的重映射。通常在XF86Setup下就可以设置这些选项，而不必手工修改这些设置。

    "Standard"和"Xqueue"是两种不同的键盘协议，一般应该使用Standard协 议，Xqueue是一种同时支持键盘和鼠标的硬件使用的协议，在个人计算机平台上很少使用。

    "AutoRepeat"用于定义键盘的重复速度，"ServerNumLock"让X服务器处理 NumLock的状态，否则是由系统的键盘驱动程序处理这个状态。有些X客户程序不能从系统键盘驱 动程序中获得小键盘的情况，此时就需要设置这个选项。”Xleds”允许X程序，如xset，能 够改变键盘上三个LED状态灯NumLock、CapsLock和ScrollLocal的状态。

    下面的"LeftAlt"等设置，用于将个人计算机键盘上的键重新映射为一些传统Unix 工作站的键盘上使用的键，如Meta、Compose等，由于传统X程序大多数是在工作站上开发的，因此 这些程序需要这些特殊的功能键来完成操作，就需要映射这些键的定义以保证兼容性。

    "XkbDisable"选项可以用于屏蔽X服务器对键盘的扩展能力， 通常不应该屏蔽这个 能力，而不设置这个参数。这样就可以在设置文件中使用下面的设置选项重新定义键盘的类型、排 列方式、符号类型、型号、编码等等。当然一般情况下可以不重新定义这些参数，缺省设置为101 键PC键盘，适用于绝大多数的情况。

  • 鼠标设置

Section "Pointer"
    Protocol  "Sysmouse"
     Device	   “/dev/sysmouse”
#    Protocol   "Microsoft"
#    Device     "/dev/ttyd0"
#    BaudRate  1200
#    SampleRate     150
#    Emulate3Buttons
#    Emulate3Timeout     50
#    ChordMiddle
EndSection

    "Pointer"部分用于定义鼠标的参数，最重要的内容是定义鼠标的类型 和使用的设备文件。对于使用moused来管理鼠标的情况，鼠标配置相当容易，首先在控制台下 设置好鼠标，然后使用/dev/sysmouse作设备文件，Sysmouse作为鼠标类型即 可。如果不打算使用moused来管理鼠标，而想直接使用鼠标设备，就需要正确指定鼠标类型及 其设备文件。例如最常见的MS两键串口鼠标使用/dev/ttyd0（或ttyd1串口），使用 Microsoft鼠标类型，等等。

    注意必须保证系统内核识别出所使用的鼠标设备（或者串口设备）。

    此外，BaudRate与SampleRate参数定义鼠标驱动程序与设备通信的波 特率和采样率，Emulate3Buttons和Emulate3Timeout让两键鼠标能模拟三键鼠 标， 然而伪设备Sysmouse的模拟三键能力的设置需要在moused的启动参数中设置，这里的设 置是无效的。ChordMiddle与上面参数意义相反，定义按下三键鼠标的中间键，等价于 同时按下左右两键。

  • 显示器设置

Section "Monitor"
    Identifier  "Hyundai DeluxScan 15G+"
    VendorName  "Unknown"
    ModelName   "Unknown"
    HorizSync   30-70
    VertRefresh 50-150
#    ModeLine "1024x768i" 45 1024 1048 1208 1264 768 776 784 817 Interlace
#    Mode "1024x768i"
#        DotClock	45
#        HTimings	1024 1048 1208 1264
#        VTimings	768 776 784 817
#        Flags		"Interlace"
#    EndMode
# 800x600 @ 72 Hz, 48.0 kHz hsync
Modeline "800x600"     50     800  856  976 1040   600  637  643  666 +hsync +vsync
# 1024x768 @ 70 Hz, 56.5 kHz hsync
Modeline "1024x768"    75    1024 1048 1184 1328   768  771  777  806 -hsync -vsync
# 1280x1024 @ 87 Hz interlaced, 51 kHz hsync
Modeline "1280x1024"   80    1280 1296 1512 1568  1024 1025 1037 1165 Interlace
EndSection

    "Monitor"部分定义了显示器的各种属性，其中前三项设置Identifier 、VendorName、ModelName起到的只是标识显示器的作用， 如果具备多个显示器定义 选项的时候可以用来区分不同的定义选项，因此这三个设置主要用在配置文件内部，并不重要。 后 面的水平同步HorizSync与垂直刷新VertRefresh的数据才是真正定义显示器属性的参 数，应该与具体的硬件相一致，这将决定显示器能否工作在具体的显示模式下。

    ModeLine或Mode定义了具体显示模式使用的时序等参数，只有在这里定义了相 应模式，X服务器才能使用对应的模式，并在各种模式之间动态切换。然而XF86Setup并没有设置在显 示器的同步频率范围内支持的全部模式，因此会需要手工增加所需要的模式。而xf86config能将很多 显示模式都加进设置文件中，其中很多是不必要的，例如320x200等低分辨率，需要手工删除。此外一 个分辨率可能会有多个显示模式相对应，但不同模式的刷新频率不同，显然应该保留一个显示器支持 的非隔行扫描、并具备最高刷新频率的模式。这些显示模式受到水平同步和垂直刷新数据的限制，X服 务器会在启动时屏蔽超过前面定义的水平同步和垂直刷新数据范围的模式，一避免损坏显示器。

    显然，Modeline和Mode选项中的设置数据是一般使用者无法正确设置的，因此就需要从XFree86 的文档中查询各种常见的显示器和及其常用的显示模式数据，来决定最接近自己显示器的显示模式，在 复制到自己的设置文件中。XFree86的文档位于在/usr/X11R6/lib/X11/doc目录下，Readme.Config和 VideoModes.doc文件描述了各种显示模式的对应数据，Monitors文件中收集了各种常见显示器的水平 同步和垂直刷新数据。

    如果没有定义多个模式，就不能使用X Server提供的动态切换分辨率模式的功能。

  • 显示卡设置

Section "Device"
    Identifier "Generic VGA"
    VendorName "Unknown"
    BoardName  "Unknown"
    Chipset    "generic"
#    VideoRam  256
#    Clocks    25.2 28.3
EndSection
Section "Device"
    Identifier  "ViRGE/DX or /GX"
    VendorName  "Unknown"
    BoardName   "Unknown"
    #VideoRam    2048
EndSection

    "Device"部分定义显示卡设备的参数，同样Identifier、 VendorName、ModelName起到标识作用，具体设置如使用的芯片、显示内存 等设置应与所使用的硬件相一致，但也可以不配置，留给X服务器自动探测。同样，也可以 定义多个Device设置，某个具体的X服务器程序只使用某个选项中的设置。

    如果要针对某个显示卡更改具体参数，除了查阅显示卡手册之外，还要阅读 /usr/X11R6/lib/X11/doc/目录下的Devices、modeDB.txt和AccelCards等文档，在其中查找 与具体显示卡相关的数据信息。

屏幕设置

    Section "Screen"
    Driver     "vga16"
    Device     "Generic VGA"
    Monitor     "Hyundai DeluxScan 15G+"
    Subsection "Display"
        Modes      "640x480"
        ViewPort    0 0
        Virtual     800 600
    EndSubsection
EndSection
Section "Screen"
    Driver      "accel"
    Device      "ViRGE/DX or /GX"
    Monitor     "Hyundai DeluxScan 15G+"
    DefaultColorDepth 16
    Subsection "Display"
        Depth       24
        Modes       "800x600" "640x480"
        ViewPort    0 0
        Virtual     800 600
    EndSubsection
    Subsection "Display"
        Depth       8
        Modes       "800x600" "640x480"
        ViewPort    0 0
        Virtual     800 600
    EndSubsection
    Subsection "Display"
        Depth       16
        Modes       "1024x768" "800x600" "640x480"
        ViewPort    0 0
        Virtual     1024 768
    EndSubsection
EndSection

        “Screen”部分将具体定义X服务器的显示属性，以及具体使用的 设备和显示模式。同时可以存在多个Screen部分，而每个screen部分对应一种X服务器。 虽然一般情况下都只使用一个X服务器，然而也可能会使用标准VGA模式的X服务器（如使 用XF86Setup时），因此一般配置文件中都至少有两个Screen部分的定义，一个由标准VGA 的X服务器XF86_VGA16使用，在其中的Driver项中指定了vga16类型，另一个Screen 定义由支持更高模式的具备硬件加速能力的显示卡X服务器使用，如XF86_S3V，Driver 项为accel类型。X服务器根据Driver项的设置来寻找正确的Screen部分设置参数。

        除了在Driver选项中指定了Screen选项与具体X服务器的联系之外， 接下来的Device设置选项将指出这个Screen部分（也就是对应的X服务器）使 用哪个显示设备，这个选项的值与设置文件前面定义的某一个Device部分中Identifier值相 同，这就将X服务器和指定的显示设备相联系起来（会存在多个定义显示卡设备的Device部分） 。同样，Monitor项将Screen部分与某个Monitor部分描述的显示器相联系。

        在一个Screen部分中也可以定义多个Display子部分，每个Display子 部分为对应一种色彩深度的显示模式设置，颜色深度Depth可以使用的值有8位（256色） 、16位伪真彩色、24位真彩色和32位真彩色（实际只用了24位），DefaultColorDepth用 于设置缺省使用的色彩深度。X服务器不能动态切换显示颜色深度，只能在同一个颜色深度下切换 不同的显示模式。这个颜色深度下可供使用的分辨率模式需要使用Modes定义，缺省的分 辨率为第一个模式，然后可以使用热键向前或向后切换。

        动态切换分辨率不影响应用程序的显示，应用程序的显示内容也不变，XFree86提供 了虚屏能力。虚屏提供了比实际屏幕更大的显示范围，例如使用800x600的显示模式，虚屏的 大小可以是1024x768，这样可以显示更多的数据，实际屏幕之外的数据可随鼠标的移动而显示 出来。这样在切换模式的时候，虚屏的大小却不变，可以移动鼠标来查看应用程序切换到虚屏 之外的部分。缺省情况下，虚屏的大小为最大的分辨率模式，也可以使用Virtual参数 定义更大的虚屏。可设置的虚屏大小受显示卡内存和所显示的色彩深度限制，色彩深度和虚屏 大小的乘积不能超过显示内存的大小。为了达到最佳效果，还有一些其他考虑。例如加速卡内 有自己的处理器进行图形加速处理，就要使用一些显存作为缓冲区，因此将所有的显存都用做 虚屏会影响显示卡的加速处理。


FreeBSD连载(55)：Ports Collection

王波

第6章 定制应用软件与系统内核

    为了充分发挥系统的性能，便需要对系统进行各种维护和配置工作。前面进 行的管理和维护还是基于最初安装的FreeBSD系统，以及FreeBSD安装介质中提供的二 进制软件包。这样的系统适用于大多数情况，但不是最适合特定要求的系统设置。根 据系统的具体情况来定制FreeBSD的各种设置，就需要进一步的工作。主要是由于 FreeBSD是一个自由软件系统，它提供了软件的源代码可以供用户定制，可以来适应 系统的具体环境。如果不能充分利用这些FreeBSD提供的源代码，就不能真正发挥 FreeBSD的最大能力。

    FreeBSD系统提供的源代码包括三个部分，内核源代码、应用程序源代码和软 件Ports的源代码。其中内核源代码用于定制内核、提高系统性能、维护硬件配置以及 更新系统软件，根据需要升级硬件和保持系统不断升级以避免系统安全等方面的漏洞 等任务，因此最为重要，一个系统在初始安装之后都需要重新编译内核；应用程序源 代码包括安装到/bin、/sbin、/usr/bin、/usr/sbin目录中的各个应用程序的源代码 ；软件Ports的源代码并不是各个软件的源代码，而是各个软件的编译、安装方法的代 码，这可以用来安装和管理各种应用程序。

    这些源代码均包括在FreeBSD的安装介质中，并能通过安装程序进行安装。除 了在初始安装时安装这些组件之外，系统正常运行时也能通过sysinstall或手工运行 相关目录下的安装脚本install.sh来添加他们。

  • 编译应用软件

    在Internet上有很多软件包，它们遵循GPL、BSD或相似的版权许可，允许用户 编译运行这些软件。正常情况下，安装一个应用软件的过程是：

  • 获得源代码文件，这通常是一个使用tar打包，并使用compress或gzip压缩后 的文件。一般通过ftp等网络下载工具从Internet上得到。

  • 将文件解开，得到源代码文件，一般需要使用tar和gzip进行解包处理。

  • 根据系统情况进行配置，通常这些软件提供了自动配置程序，能根据系统环境 自动进行配置，或者可以手工更改设置文件。

  • 然后就进行编译，创建可执行的程序。

  • 接下来就需要将应用程序安装到系统的指定位置。

  • 最后一步是配置应用程序的参数，使其能很好的执行。

    虽然软件的作者通常已经将源代码编写相当完善，适合在多个平台上编译， 但是将源代码编译成最终可执行的文件，仍然是一个花费时间且需要繁琐操作的过程 。尤其是当用户对系统不是很了解的情况下，往往就可能在某一步遇到了问题，结果 就会导致整个安装过程不能正常完成。

    因此FreeBSD提供了Ports Collection机制来管理、安装软件。每种要被移植 到FreeBSD上软件被称为一个Port，由某个FreeBSD的开发者维护。这个Port的维护者 首先将软件移植到FreeBSD上，并将他所完成的这些移植工作按照Ports Collection 的要求进行设置，编写相关的脚本，使下载软件、配置、编译、安装的全过程能够自 动完成，不需人工干预。每个Port中并没有保存软件包的源代码或者二进制代码，而 只是提供了搜索它的源代码或者二进制软件包的方法。有了Ports Collection，编译 、安装应用程序的过程就相当容易了。

    Ports Collection和Packages Collection是紧密相关的，大部分Port都会有 对应的二进制软件包，除非这个软件的许可权对以二进制格式分发有所限制。通常每 个源代码形式的Port使用tar.gz结尾，而相应的软件包使用.tgz结尾。因此可以使用 后缀来区分Port和软件包。可以从Port中直接生成对应的二进制软件包。

  • Ports Collection

    对于一般的使用者，有了FreeBSD提供的众多预编译好的软件包，就可以直接 安装这些应用软件的二进制版本，而不需要使用Ports Collection重新编译软件。然 而安装介质上附带的软件包是按照缺省配置生成的，适合大多数用户的需要，但并不 一定最适合特定用户的特定需求。如果需要对某个软件进行定制安装，就需要使用 Ports Collection，进行修改后重新编译安装。

    在启动这个软件的安装与管理机制之前，必须安装 ── Ports Collection的 源代码ports.tgz，它在安装介质中提供，系统的初始安装过程中，安装程序将提示使 用者安装Ports Collection，系统安装之后也能直接从安装介质上重新安装或更新。

    Ports Collection的源代码被安装到/usr/ports目录中，这个目录称为Ports 树，以树状结构保存了各个应用程序的Ports。与Packages Collection的目录结构相 同，Ports中也按类别进行相关分类，/usr/ports下的每个子目录都包含某一类软件， 在下一级的每个子目录下就放置各个Port。

$ cd /usr/ports
$ ls
CVS             archivers       devel           math            textproc
INDEX           astro           distfiles       mbone           vietnamese
LEGAL           audio           editors         misc            www
Makefile        benchmarks      emulators       net             x11
Mk              biology         games           news            x11-clocks
README          cad             german          palm            x11-fm
README.html     chinese         graphics        print           x11-fonts
Templates       comms           japanese        russian         x11-toolkits
Tools           converters      korean          security        x11-wm
WWW_SITE        databases       lang            shells
YEAR2000        deskutils       mail            sysutils

    因为每个Port的代码位于自己的目录中，如果仅仅只想安装某个软件包的port， 在解压缩中只解某个具体的软件就可以了。

# tar zxvf /cdrom/prts/ports.tgz ports/www/netscape4.07

    由于Ports Collection是随着应用程序的发展而常常更新的，当某个软件升级造 成软件的源代码文件的名字或位置改变，因此部分Port中有关下载软件源代码的位置的设 置，就很可能不再适用，从而造成某些Ports不能正常编译安装。因此当应用软件更新之 后，就需要从ftp.freebsd.org更新对应这个Port的源代码。可以下载某个Port的代码并 放置到正确的位置上，就能完成该port的更新，而不必更新整个Ports Collection。或 者使用cvsup来同步源代码，更新Ports Collection。

    由于Ports Collection中收集的软件相当多，因此要想了解每个软件的用途并找 出有用的软件就有些困难。如果一个一个去看软件的文档，需要花费大量的时间。因此 FreeBSD提供了一些简单的索引和搜索能力。下面操作将产生所有port信息的索引文件。

# cd /usr/ports
# make print-index > index.txt

    例如要搜寻pine相关的port信息，可使用：

# cd /usr/ports
# make search key=pine

    也可以产生所有Ports的描述文件，在/usr/ports目录下产生一系列HTML超文本文件， 然后通过netscape或lynx等浏览器查看各个软件的描述内容。

# cd /usr/ports
# make readmes

    Ports Collection与系统版本息息相关，因此如果要使用新版本系统的Ports Collection ，不但要升级Ports，而且要升级系统中的有关程序。FreeBSD提供了一些Packages来提供在 不升级系统的情况下支持高版本的Ports Collection。例如从3.1Release升级到3.1stable就 存在一个升级Package为：31Upgrade.tgz，可以查看http://www.freebsd.org/ports中的信 息，来查看在现有系统版本下如何支持最新的Ports。

  • 使用Ports Collection来编译安装软件

    每个Port单独占据一个子目录，在这个目录中就是Port的代码，包括使用make编译、 安装这个软件所必须的Makefile文件，软件的描述文件README.html、用于版本维护的CVS目 录、保存软件包安装信息的files目录，以及保存软件源代码的补丁文件的pkg目录等。

$ ls -al /usr/ports/security/ssh
total 13
drwxr-xr-x   7 root  wheel   512 Apr 19 01:18 .
drwxr-xr-x  53 root  wheel  1024 Apr 19 01:18 ..
drwxr-xr-x   2 root  wheel   512 Apr 14 16:36 CVS
-rw-r--r--   1 root  wheel  4974 Apr 19 01:18 Makefile
-rw-r--r--   1 root  wheel   715 Feb 15 17:06 README.html
drwxr-xr-x   3 root  wheel   512 Apr 14 16:36 files
drwxr-xr-x   3 root  wheel   512 Apr 19 01:18 patches
drwxr-xr-x   3 root  wheel   512 Apr 19 01:18 pkg

    由于Ports Collection就是用来简化应用软件的安装过程的，因此安装起来非常简单， 例如要安装一个播放mp3的软件mpg123，则可以首先进入这个Port对应的目录，然后使用make 命令进行处理。

# cd /usr/ports/audio/mpg123
# make install

    在这台计算机连接到Internet上的条件下，在这个过程中系统将顺序完成下载、编 译、安装几个步骤。

    make fetch: 每个Port中并没有保存应用软件的原始源代码文件，它保存的 是如何获得软件的源代码，并产生可执行文件的操作过程。每种软件的源文件通常保存在其 他介质上（一般位于Internet上），那么当通过Ports Collection来安装一个软件时，第一 步就是要获得相关的文件。这个下载文件的功能是Ports Collection的一部分功能，如果这 台计算机联接到Internet上了，它能够到网络上找到该文件并使用fetch命令将文件下载到本 机内，所有的步骤都是完全自动完成的，需要使用者操作的仅仅是使用make命令来启动这个 过程。

    如果使用的是make fetch命令，fetch参数将使得make仅仅完成下载任务，而不进行 编译和安装处理过程。

    即使计算机没有联接到Internet上，也不必担心，因为Ports Collection将所有下载 的文件都保存在/usr/ports/distfiles目录中，而make命令将首先检查该目录中是否已经存在 了要下载的源文件，当发现存在这个文件之后，就不再重新下载。因而可以手工将这个应用软 件的源代码文件拷贝到这个目录下，make时就不会再重复下载过程了。如果不能确定源文件的 位置，可以从Makefile文件中获得源文件的位置，Makefile中将给出该源文件存在几个不同的 网络地址，供fetch命令连续尝试下载，一般最新Ports Collection对应的软件的源文件都能 从ftp.freebsd.org中下载得到。

    make: 不带任何参数的make命令在完成上述下载工作之后，就开始编译软件了 。make程序首先在这个Port目录下建立一个工作子目录，命名为work，此后将源代码展开到这 个目录下，再应用这个软件的各个补丁文件，并启动自动配置和编译过程。在这里，每进行一 步操作，就在work目录下生成一个空文件，这些文件用于标记编译、安装port的工作进行到哪 一步了。

$ ls -al /usr/ports/security/ssh
total 8
drwxr-xr-x  3 root  wheel   512 Apr 14 16:57 .
drwxr-xr-x  7 root  wheel   512 Apr 19 01:18 ..
-rw-r--r--  1 root  wheel   768 Apr 14 16:57 .PLIST.mktmp
-rw-r--r--  1 root  wheel     0 Apr 14 15:56 .build_done
-rw-r--r--  1 root  wheel     0 Apr 14 15:56 .configure_done
-rw-r--r--  1 root  wheel     0 Apr 14 15:55 .extract_done
-rw-r--r--  1 root  wheel     0 Apr 14 16:57 .install_done
-rw-r--r--  1 root  wheel     0 Apr 14 15:55 .patch_done
drwxr-xr-x  4 root  wheel  4608 Apr 14 15:56 ssh-1.2.26

    make展开应用软件包时会检查下载软件包的完整性，这是通过验证下载文件产生的MD5 数据是否与记载在Port中的数据相一致，来保证了下载软件的正确性。

    每个Port的Patch是一些补丁程序，它包括这个软件本身存在问题，用于修正或升级的 补丁，或者是维护这个Port的FreeBSD开发者用于修正系统差异而制作的Patch。所有的补丁程 序被放置在该Port目录下的patches目录中。

    要对这个软件进行定制时候，应该首先使用make命令，保证源代码展开到正确的目录下 并编译完毕。这样能保证make应用了所有的补丁程序对源代码进行修正，然后才能在此目录中 修改相应配置,并删除work子目录中的相应标记文件.build_done，使得可以重新开始编译过程 ，重新编译软件。

    make install: 如果使用的是make install命令，那么make先完成编译过程， 然后还将自动安装这个Port，此时不但将软件的各个部分安装到正确的位置之外，还将执行Port 中附带的shell脚本进行软件的基本配置。当然这个配置过程是不完整的，完整的配置属于这个 应用程序本身的功能。

    安装完毕之后，还可以针对自己定制的Port生成对应的软件包，使用make package命令 将自动完成这个过程。

    安装每个Port的同时也就等同于安装相应的Package，安装过程同时也将在/var/db/pkg 目录下记载下相应Package的安装记录。由于软件包之间存在相互依赖关系，Ports Collection 中也使用同样的原则来处理软件之间的依赖关系，必须使用预先安装这个Port依赖的所有其他 Packages之后，才能安装（不影响编译）这个Port。这个过程也将在make install中自动完成的 ，系统就会检查依赖关系，自动使用Ports Collection安装它所依赖的Port，最后才能继续这个 Port的安装过程。

    由于安装过程依赖于软件包之间的依赖关系，因此可能会出现比较复杂的情况。例如 Ports Collection的源代码不完整，缺乏它所依赖的软件包的信息，这样安装就不能正常完成 。还有就是Ports Collection之间不一致，由于软件的版本不同，就可能造成依赖关系不完整 ，安装过程不能继续进行。这就需要使用者检查依赖关系，更新整个Ports Collection来纠正 问题。

    有的软件，本来就是提供的二进制形式的软件，例如Netscape Communicator，因此并不 需要编译过程。所需要的仅仅是将它们下载并安装。即便如此，使用Ports Collection仍然能够 帮助使用者更方便的完成这项工作。因为Ports Collection仍然维护着一些有用的信息，例如要 下载的应用软件版本号和应用软件的下载位置，应用软件的安装目录和配置文件所在的目录等非 常有用的信息。使用包的方式进行安装和管理，将保证应用软件之间的依赖关系的完整性，方便 在不用的时候将包卸载，此外Ports Collection还将按照FreeBSD的习惯来组织文件和目录，便于 将要安装的文件放置到合适的位置中。

    通常FreeBSD将应用软件安装到/usr/local目录下（X Window应用软件安装到/usr/X11R6 目录下），其执行程序位于/usr/local/bin中，配置文件位于/usr/local/etc中，而应用软件如 果需要在系统启动时自动启动，相应的启动文件被放置到/usr/local/etc/rc.d目录中。


FreeBSD连载(56)：手工编译安装程序

王波

手工编译安装程序

    虽然使用Ports Collection编译和安装软件非常简便，然而仍有两个理由来使用手工编译安装方式。一方面是Ports Collection中并不能涵盖所有的软件，有很多软件没有收入Ports Collection中。有很多原因使得一些很优秀的软件没有被收集入Ports Collection，例如，版权因素，或者没有志愿者对它移植到FreeBSD进行维护。另一方面，即使是通过Port来定制软件，仍需要了解了手工编译安装的过程和各种编译工具的使用，才能正常进行定制工作。

    通常在FreeBSD下编译并安装应用程序并不困难，因为FreeBSD是一种非常标准的Unix，为Unix开发的标准C程序很容易就能在它上面编译运行。

  • 编译和软件工具

    为了编译和安装一个应用程序，必须要了解编译和运行软件的一般方法。对于大型程序和要求高效率的软件，通常用高级语言C来开发，使用C语言编译器将C源程序编译成执行程序。由于使用高级语言不依赖于硬件结构，这使得软件非常容易移植。Unix不仅提供了编译器，而且还提供了众多的工具来帮助进行编译和维护，最有用的工具为make。

  • GNU C与编译连接过程

    C作为一种编译型的高级语言，这就是说运行C程序之前要将其先编译成可执行的由机器指令构成的执行程序，因此就需要使用一个编译器来对C源代码进行处理，FreeBSD使用的是GNU的C编译器。

$ cc hello.c
$ ./a.out
Hello, world!

    UNIX下缺省使用a.out作为生成的文件名，可以使用-o参数指出生成的执行文件名。

    事实上前面的编译生成执行文件的过程由两步组成，一是生成目标文件，通常使用.o为后缀，然后进行连接生成执行文件。因此，可以使用ar将多个目标文件组合成一个函数库文件，而可以使用nm来查看库文件的内容。

$ cc -c f1.c
$ cc -c f2.c
$ ar c mlib.a f1.o f2.o
$ nm mlib.a

    FreeBSD使用的C语言编译器gcc是一种非常流行的，多平台、高效率的C语言编译器，它提供了多种选项用于生成应用软件。以下为常用的一些选项：

-L | 定义连接库文件的目录
-I | 定义C源码的头文件的目录
-o | 后面跟的参数为要生成的执行文件的名
-O | 进行编译优化，可以指定使用不同的优化级别，从O2到O6，每个不同的级别使用的优化设置不同。 相关的选项还有定义生成的指令码类型的参数，如-m486生成486指令，缺省的gcc版本（2.7.2）不支持Pentium代码。
-g | 加入调试代码，可以在完成后使用strip命令删除用于调试的信息
-c | 仅仅进行编译而不进行连接，生成目标文件
-fPic | 生成相对地址的代码，用于最后生成动态连接库
-static | 强制生成静态连接的程序
-aout | 生成a.out格式的执行文件、目标代码等，缺省使用ELF格式
-elf | 3.0之后为缺省设置，生成ELF格式的目标和执行代码

    可以通过命令行参数查看当前使用的GNU C编译器的版本：

$ cc –version
Gcc version 2.7.2.1

    FreeBSD当前使用GNU的C编译器gcc的版本为gcc 2.7.2.1，这不是
              gcc编译器的最新版本，但稳定性非常好。虽然当前新版本的gcc 2.8已经很稳定了，但是由于编译器在系统中的重要性，编译器出现问题会造成系统的稳定问题，因此FreeBSD还没有转向gcc
              2.8。另一个没有完全使用 gcc 2.8的重要原因是生成的执行文件格式问题，gcc 2.8不再支持生成a.out 执行格式的二进制程序。但完全转向gcc
              2.8版本是必然趋势，在当前正在开发的FreeBSD 4.0-current中，已经使用了gcc 2.8作为标准配置。

    在3.1系统中，如果想使用gcc 2.8，就需要安装Packages Collection
              中提供的gcc-2.8软件包（或者使用Ports Collection对源代码进行编译）。事实上还有另外两个更强大的根据gcc进一步开发的编译器，pgcc支持Pentium
              代码（标准的gcc只支持生成486代码），egcc除了支持Pentium代码之外，还提供了更大的优化能力。这些版本是商业公司依据gcc进行的开发，但根据GPL
              许可，任意使用者都可以根据需要选择使用，使用这些编译器版本能进一步发挥系统的能力。

  • make

    通常应用程序都比较复杂，那么其源程序就不仅包括一个文件，而是由多个文件构成，这样应用程序的编译和连接过程就相对复杂得多。最简单的情况下可以使用shell程序来自动完成这个任务，然而由于并不是每次都更改了所有的文件，每次都完全重新编译所有的代码，不但浪费了处理器资源，也使得每次作一次小改变就得编译所有得文件，效率低下。最好是能够按照需要，编译改动过的代码文件，而对没有更新过的文件就不必重新编译，这样就节约了系统的处理能力。

    如果要使用shell脚本来处理这些依赖关系来，则要求根据文件的更新时间进行维护，需要的shell脚本就比较复杂。Unix提供了一个程序──make，来帮助按照代码之间的时间依赖关系来进行维护工作。

    make与其他解释语言不同，不是直接告诉make需要执行的命令，而是给定一些依赖规则，即在什么条件下应该执行什么处理，那么make就自动分析文件的更新时间，完成剩下的工作。规定make规则的文件一般命名为Makefile，这是一个make指令的集合，这个文件中包括目标定义、执行命令、宏定义和make
              伪指令。下面为一个简单的Makefile：

CC = /usr/local/bin/egcc
hello:	hello.c
        $(CC) -o hello hello.c
clean:
        echo delete files!
        rm hello

    这个例子中首先定义了一个宏CC，然后定义一个执行目标hello，这个目标依赖于hello.c文件，一旦hello.c更新，就需要执行下面的编译指令。注意，位于定义目标之后的执行命令应该使用一个
              “Tab” 制表符引导，而不是其他空白字符。执行命令中首先将宏替换为它的值，再执行egcc命令编译程序。

    一个Makefile文件中可以定义多个目标，如上面例子中的hello和clean，如果不使用任何命令行参数来启动make，那么缺省使用第一个目标。为了应用其他的make目标，则必须使用make的命令行参数。

$ make clean
delete files!

    make使用的缺省文件名为当前目录下的makefile或Makefile，如果使用其他文件，必须使用命令行参数-f指定文件名。

$ make -f newmakefile

    GNU的make命令首先查看的文件名为GNUmakefile。

    使用了make，对大型的应用软件进行维护就会容易一些。然而不同的系统有一些与系统相关的定义，这些定义需要在Makefile中依据不同的系统重新设置，例如X
              Window的目录等，这样要完成可以适合多个不同系统的Makefile文件，仍然具有困难。有一些工具能帮助进行这些系统相关的设置，并生成Makefile
              文件，例如X Window系统使用xmkmf命令和imake模板文件来产生本地的Makefile 文件，这样就能正确侦知本地系统中有关X
              Window的正确设置，但软件开发者首先要完成Imakefile文件，以使用xmkmf。而GNU的软件使用autoconf工具，它使用configure命令用来侦测很多系统相关的设置，如编译器、头文件、库函数等等，然后使用预设置的Makefile.in模板文件来产生相应的Makefile。有了这些工具，进行编译各种多平台的应用程序都不再是困难的了。


FreeBSD连载(57)：可执行程序格式
王波

可执行程序格式

    在FreeBSD下的可执行程序通常可分为两类，一类为使用各种解释语言编写的脚本，如sh、awk、perl、Tcl等，这些程序需要解释程序进行解释执行，小巧方便，对于实现不常使用、不要求效率的程序非常有用；另一类就是使用C等高级语言编译后产生的可执行二进制程序。

    Unix之所以功能强大，原因之一就在于它提供了强大的再开发能力。这不仅与提供了高级语言C的编译器有关，而且也与提供了很多种能以解释方式执行的简单脚本语言有关。解释程序脚本的特点是方便性、简单灵活，而且也比较容易学习入手。很多情况下，需要完成的工作任务功能比较单一，并不需要频繁运行，而且要求快速编写出来，这就适合使用解释型语言编写，并且解释程序本身就具备处理文本和字符串的便捷性，并能够和很多现有程序通过系统提供的管道、环境变量等方式结合起来，使得它们非常适合实现文本处理功能。

    解释语言的缺点是每次运行程序时都要载入语言的解释器，解释执行程序，因而效率较低，并且不能直接操纵内存和I/O设备，不适合编写大型程序和对效率要求较高的场合。

    每个解释脚本程序的第一行指出该脚本程序使用的解释器，例如一个普通的shell程序的第一行为：

#! /bin/sh

    不同的解释语言可用在不同的方面，最常用的有shell解释程序，依据使用shell的不同，也分为不同的shell脚本，基本上也分为sh和csh
              两种不同的风格。系统管理中经常使用shell程序来执行一些日常管理任务，很多软件也使用shell程序来提供辅助安装和设置任务。perl也是一种常用的、功能强大的解释语言，它兼有解释性程序的方便性和高级编程语言的强大功能，使程序员能在很短的时间内写出非常有效的程序。因此perl得到了众多程序员的支持，通过为perl开发了更多的程序模块，进一步使得perl的处理能力变得更为强大。当前perl已经成为了最流行的一种解释语言，尤其在编写Web服务器上的CGI程序方面，更是处于无可争议的地位。Tcl/tk是另一种解释语言，它能用在X
              Window系统下，使用描述语言显示不同的X控件，因此很多X应用程序使用它来建立自己的图形接口。

  • 二进制执行程序

    •

    使用高级语言编写、并经过编译得到的二进制执行程序执行效率更高，并且只有二进制格式的执行文件才能充分利用Unix系统提供的全部功能。同样系统内核也是一个特殊格式的二进制执行文件。

    早期的Unix使用a.out格式作为它的执行文件格式，随着Unix的发展，又出现了其他几种执行文件的格式，当前最重要的执行文件格式为ELF
              格式，采用这种格式的最初想法是为了在不同平台间采用相同的执行文件格式，并实现动态共享连接库。虽然ELF文件格式并没有达到AT&T最初设想的全部目的，但这种文件格式却成为最流行的执行文件格式。除此之外，实际使用的文件格式还有一种较老的COFF格式，这种格式是在Unix
              System V R3.2中使用的，当前只有老版本的SCO Unix中还在使用它，而 SCO也正逐渐转向ELF格式。

    FreeBSD可以同时支持这两种执行文件的格式，FreeBSD 2.2.x之前的版本使用a.out格式作为缺省的执行文件格式，到FreeBSD
              3.x之后ELF格式成为缺省的执行文件格式，并且以后会彻底转向ELF。事实上在FreeBSD 下的a.out格式具备了相当多的特性，如动态连接等ELF格式具备的特性，也有一些ELF格式不具备的特性，如压缩执行文件格式。但由于FreeBSD中使用的编译器gcc决定不再支持a.out格式的缘故，因此FreeBSD也必须转向
              ELF格式。这也是当前还支持a.out格式的FreeBSD版本缺省使用较老版本编译器的原因之一。

    在FreeBSD中，a.out格式的执行文件可以支持压缩执行格式，这使得使用gzip压缩过的a.out格式的执行文件也能立即执行，当前还不能对ELF
              格式的文件提供这种支持。

    FreeBSD的文件格式从aout到ELF的转变是渐变的，首先是在3.0-RELEASE
              中将执行程序的缺省格式转变为ELF格式，内核文件还保持aout格式，直至 FreeBSD-3.1，全部执行文件格式才缺省设置为ELF格式。

    转向ELF也造成很多相关程序的转变，如原有的Boot Loader不支持 ELF格式的内核，3.1-RELEASE就升级到新Boot
              Loader；而原有的可加载模块lkm为aout格式，也需要转向ELF格式的modules。新可加载模块的位置为 /modules目录，并使用kldload、klduload、kldstat来进行管理。（aout格式的模块管理命令为modload、modstat和modunload）。

    a.out和ELF格式使用的库文件也是不同的，使用ELF执行文件格式的 FreeBSD
              3.x中，/usr/lib下为ELF格式的函数库，而用一个子目录/usr/lib/aout 存放a.out格式的函数库，用于兼容2.2.x之前版本的FreeBSD程序。但这给一些使用包装技术的软件（一些中文外挂系统）造成了一些小麻烦。对不同格式的执行文件要使用不同的包装库，系统不会将与程序本身格式不同的连接库连接到程序上，对应的错误信息为
              “bad magic”，指出文件格式的不同。

    由于3.x之后的缺省格式为elf格式，为了生成a.out格式的文件，必须在编译和连接时使用
              -aout参数，告诉编译器gcc和连接器ld使用不同的格式生成执行文件。

  • 静态连接和动态连接

    •

    在操作系统发展的早期，除了内核提供的接口，所有的库函数都要连接到程序中，这样所有的程序都可以直接在系统内核下运行。然而事实上大部分程序都会使用一些相同的库函数，尤其是在使用高级语言编程的时候，通常都使用同样的库。例如，C语言编写的程序通常都使用printf函数进行输出，使用scanf读入用户输入内容。如果每个库函数都连接到用户程序中，这样每个程序都会包括这个函数的一个拷贝，就浪费了内存空间。

    因此，现代操作系统使用动态连接的技术，不将常用的库直接编译进每个程序中，而是保留相应的接口，在内核载入程序时，再使用动态连接程序将库载入并和执行程序连接起来。这就是动态连接的技术，由于库和程序是分别载入的，因此多个程序可以共享一个库的同一个拷贝，节约了资源。

    不论对于a.out格式还是ELF格式，FreeBSD均支持动态连接，因此应用程序缺省就使用动态连接的方式。如果想使用静态连接，可以在应用程序编译连接时，指定-static连接选项，将目标程序连接成静态连接的执行文件。由于库代码被连接进执行文件中，静态连接的执行文件要比动态连接的执行文件要大。

$ cc -static -o a1 hello.c
$ cc -o a2 hello.c
$ ls -l  a1 a2
-rwxr-xr-x  1 wb  wheel  45017 Apr 18 16:26 a1
-rwxr-xr-x  1 wb  wheel   2540 Apr 18 16:27 a2

    在FreeBSD下，共享库被放到/etc/ld-config设定的目录下，通常为
              /usr/lib，每个库文件使用.so和库的版本号结尾。例如，libc.so.3.1为一个标准C库函数的动态共享库文件。对于a.out格式的执行文件，其动态库文件位于/usr/lib/aout目录下。

    可以使用程序ldd来确定一个程序使用的动态连接库：

bash-2.02$ ldd /usr/bin/vi
/usr/bin/vi:
        libcurses.so.2 => /usr/lib/libcurses.so.2 (0x2808e000)
        libtermcap.so.2 => /usr/lib/libtermcap.so.2 (0x2809a000)
        libc.so.3 => /usr/lib/libc.so.3 (0x2809f000)

  • 其他系统的执行文件

    •

    很多其他Unix系统，例如BSD/OS和Linux，也是运行在Intel平台上的系统，那么执行程序中的处理器指令是完全相同的，不同之处只在于应用程序的格式、应用程序与操作系统的接口、库文件等。事实上由于同为Unix系统，这些差异也很小，因此通过调整内核的一些参数设置，FreeBSD完全可以直接运行这些系统下的执行程序。

    FreeBSD能够同BSD/OS、NetBSD和OpenBSD的Intel平台上的应用程序相兼容，同为BSD家族的成员，他们非常类似。NetBSD、OpenBSD和FreeBSD同为免费系统，并且具有同样的起源，与FreeBSD的关系非常密切，因此FreeBSD能直接运行NetBSD和OpenBSD的Intel平台下的执行程序。然而NetBSD和OpenBSD
              也是自由操作系统，因此它们中的应用程序也会有相应的FreeBSD版本，因此这个功能一般很少用到。BSDI是一个商业公司，因此会提供BSD/OS下的二进制执行文件，但不提供源代码。FreeBSD能够完美的运行BSD/OS下的a.out格式的执行文件，ELF执行格式的程序也能执行，但偶尔会有问题发生，因此就需要调整系统设置。

    FreeBSD也能够执行SCO Unix的执行文件，这需要使用内核的ibcs2（
              Intel binary compatibility system 2）选项。这需要载入一个内核可加载模块，这需要使用root身份执行ibcs2命令以载入ibcs2模块。

# ibcs2

    可以在rc.conf中设置 “ibcs2_enable=YES” ，使开机后立即载入这个模块。

    但是要执行SCO的应用程序，仅有内核支持还是不够的，还需要有SCO Unix的函数库。但SCO
              Unix的库函数是SCO Unix的一部分，受版权保护的。如果使用者拥有合法的SCO共享库和应用程序，就可以运行SCO Unix上的大型商业应用程序。

    同样，FreeBSD也能够运行Linux的可执行程序，与执行SCO程序类似，这也要求内核支持并载入相应的模块。rc.conf中的相应参数为
              “linux_enable” 。

# linux

    但是与SCO不同的是，Linux是一种自由操作系统，其库函数为GNU开发的函数库，使用GNU通用许可保护自由使用的权利。因此FreeBSD在Packages
              Collection中提供了Linux的共享库，安装了这些Linux的库函数之后，就可以执行Linux的执行程序了。

# pkg_add /cdrom/packages/All/linux_lib-2.6.tgz

    FreeBSD也能执行Solaris x86和SCO Unixware的ELF格式执行程序，只是这个功能还没有加入正式发行版本。同样，这也需要相应的系统动态连接库文件，但是这些库是商业产品，因此使用起来就会受到限制。

  • 运行Linux应用程序

    •

    在运行Linux应用程序时，会遇到一些程序不能正确执行的情况，很多情况下并不是FreeBSD本身的问题，而是由于系统的设置不正确造成的，必须作一些设置和调整。

    由于Linux使用Elf文件格式，有些时候FreeBSD不能分清一个ELF执行文件是那种系统的执行文件，而误认为是FreeBSD的执行文件，导致不能正确执行程序。此时就需要使用brandelf命令来指定需要执行的ELF执行文件的类型，Linux
              的ELF执行文件为Linux：

$ brandelf -t Linux linux_application

    另一种差异是系统文件名字的差异，例如Linux的加密口令文件为shadow，而FreeBSD使用master.passwd，Linux的控制台终端设备文件为/dev/tty0，FreeBSD
              为/dev/ttyv0，对于一些要使用这些系统文件的应用程序，就造成无法正确读取相应文件的问题，这种情况可以使用符号连接来解决。

# cd /etc
# ln -s master.passwd shadow
# cd /dev
# ln -s ttyv0 tty0

    此外，Linux动态连接库的版本不合适，也是很多Linux程序不能正常运行的主要原因。Linux使用GNU开发的glib作为库函数，编译器gcc首先实现了glibc1
              ，用于兼容标准的C库函数libc5。随着gcc的发展，它发展到了glibc 2，也被称为libc6。这两个不同版本的库有一定的差异，glib2功能更强，但由于出现时间还短，不是所有的Linux版本都使用glibc2。有的Linux版本还在使用glibc1，如
              Slackware 3.6，而另一些Linux如RedHat 5.0，Debin 2.0都使用glibc2，因此运行Linux应用程序的时候，首先就要确认其使用的C库函数版本。除了标准的C库之外，Linux应用程序使用的其他动态连接库也会存在不一致的问题。

    因此如果Linux应用程序使用的库和FreeBSD安装的Linux共享库版本不一致，那么就不会正常执行这些Linux程序。Linux是一个非常活跃的开发系统，某些版本的Linux常常等不及系统稳定就将应用程序及其使用的库升级，因此为了运行要求新动态连接库的Linux应用程序，就必须及时更新Linux的共享库。除了及时更新FreeBSD正式发行的Linux共享库（这个共享库通常为一个稳定版本，不会一味求新）之外，为了跟上Linux升级的脚步，还必须手工安装Linux的库和其他执行文件。

    当前FreeBSD提供的Linux动态连接库为Linuxlib-2.6，提供了对glibc2库及其他一些共享库的支持，然而众多的应用程序还会使用其他各种动态连接库。
              FreeBSD的软件库只能支持常用的Linux应用程序，为了彻底解决Linux应用程序的动态连接库更新问题，并不能依靠FreeBSD提供的软件包。还是应该使用Linux的方式，按照Linux的方式安装所需要的Linux动态连接库。

    FreeBSD下用于与Linux相兼容的程序和库文件统统位于/usr/compat/linux
              目录下（根目录下有它的一个连接/compat/linux，compat目录为兼容其他系统执行文件的目录），为了安装新的Linux文件，首先要将这个目录清除。

# cd /usr/compat/linux
# rm -fr *

    安装新的Linux兼容文件可以通过多种方式来完成，由于当前最流行的 Linux系统通常使用RPM的包管理方式，因此可以使用RPM包来安装Linux文件。这需要首先安装包管理程序rpm，这个程序有FreeBSD版本（此时还无法运行Linux程序）。可以在Packages
              Collection中找到这个软件。

    然后就要为安装Linux的RPM包初始化rpm，使rpm不使用根目录作为系统的起始路径，而使用/usr/compat/linux作为所有的rpm包的根进行安装，这就要使用
              --root参数指定相对的根目录，以将Linux执行程序与FreeBSD执行执行程序区分开。rpm在/usr/compat/linux/var/local/lib/rpm中记录包的安装信息。

# mkdir -p /usr/compat/linux/var/local/lib/rpm

# rpm --initdb --dbpath /usr/compat/linux/var/local/lib/rpm

# rpm -i --ignoreos --root /usr/compat/linux ld.so-1.9.5-7.i386.rpm

# rpm -i --ignoreos --root /usr/compat/linux ldconfig-1.9.5-3.i386.rpm

# rpm -i --ignoreos --root /usr/compat/linux glib-1.0.1-3.i386.rpm

# rpm -i --ignoreos --root /usr/compat/linux glibc-2.0.7-17.i386.rpm

    当使用rpm -I安装好所有必须的系统支持文件，以及需要执行的应用程序，这样安装完毕之后，在通过调整一些参数，Linux程序就能正常执行了。主要需要根据应用程序的错误提示，修改FreeBSD和Linux在文件和目录结构上的不同，如Linux
              执行程序的位置，应该更改为/usr/compat/linux/usr/bin目录或其他相应的路径，而非原有根目录下的路径，以使得Linux程序内部只调用Linux执行程序。只有一些对执行程序的格式不敏感的程序，可以使用/bin或/usr/bin下的相应FreeBSD执行程序。通过这样的设置之后，在FreeBSD下就能运行包括Oracle
              8 for Linux在内的大型应用软件。

    但是FreeBSD并不可能运行所有的Linux程序，有的应用程序程序对Linux内核有一定要求，需要内核的特定版本的支持。一般来讲，对于这些对Linux特定内核有要求的应用程序，FreeBSD也就无法提供支持了。

    不管怎样，虽然在FreeBSD下运行Linux执行程序没有太大的问题，然而毕竟 Linux是一个独立的操作系统，处理问题的风格与FreeBSD不同，因此除了较小的程序之外，安装支持文件、必要的目录结构等参数的调整是免不了的。


FreeBSD连载(58)：为编译内核准备源代码

王波

     配置FreeBSD内核

    安装好FreeBSD之后，便需要根据硬件和计算机的应用需求重新配置FreeBSD的内核。标准内核已经能够满足正常运行FreeBSD的需要，但是不建立针对自己计算机的内核，就不能说完全完成了FreeBSD的配置任务。虽然FreeBSD提供了UserConfig可以来更改内核中硬件资源的，并通过可加载模块以扩展内核能力，但仍然有几个重要的原因使得FreeBSD使用者重新定制内核：

    通用内核不能对所有的硬件都进行支持，某些对安装和运行不是至关重要的硬件，如声卡，或者较少用到的硬件，如 ATM卡，就没有被编译到通用内核中去。如果用户的计算机上使用了这些硬件，就需要重新编译内核。

    某些应用程序和FreeBSD的功能对内核的参数有特殊要求，例如Windows的模拟器Windows E mulation等。重新编译内核能满足这些应用程序对内核参数的特殊要求。

    通用内核中有很多不必要的硬件驱动程序，这些程序不仅使启动时自动检测硬件需要的时间变长，并且占用了内存空间。由于内核是系统最重要的部分，将一直驻留在内存中，而不会置换到硬盘上，因此多余的内核驱动程序浪费了宝贵的物理内存，对于系统性能有一定影响。

    重新生成内核也可以根据自己的硬件和需求优化内核参数，例如用作服务器和系统和用于工作站的FreeBSD系统的最优参数是不同的，并且通用核心是使用386指令集，而当前计算机一般都是Pentium级，因此可以使用最新的编译器和最优化的编译选项，提高系统性能。

    定制内核能够按照硬件和需求量体裁衣，使内核简洁、干净，这是一个提供高效率系统的重要因素。而且在Free BSD下，定制内核并不困难，即使是对系统不太熟悉的使用者，也能够完成定制内核的任务，所需要的只是耐心等待编译过程。在安装好系统之后，应该及时进行定制内核的操作。

  • 为编译内核准备源代码

    FreeBSD系统提供内核的源代码，在安装系统时是否安装内核代码与使用的不同安装选项有关。安装后的源代码位于/usr/src/sys目录中，如果这个目录不存在或者为空目录，则说明源代码没有安装。此时就必须重新安装内核源代码。

    仍然可以使用/stand/sysinstall程序，选择Distribution选项来安装源代码；也可以运行安装介质中src目录下的install.sh来安装。安装FreeBSD内核源代码之后，习惯上还创建了一个符号连接/sys，指向/usr/src/sys目录，以方便使用。

    在拥有了源代码之后，就可以编辑配置文件，进行配置工作了。源代码目录/usr/src/sys下有多个目录，每个FreeBSD支持的设备、文件系统都有自己的目录，以存放相关的源代码。在定制内核的时候，所关系的目录是内核配置文件所在的目录：/sys/i386/conf，i386目录表示是Intel 386体系的计算机，其下的c onf目录下就放置着内核的配置文件。


FreeBSD连载(59)：编译安装新内核

王波

编译安装新内核

    在/usr/src/sys/i386/conf目录下，可以看到一系列内核配置文件的样例。

bash-2.02$ ls /sys/i386/conf
GENERIC   Makefile.i386   files.i386     majors.i386
LINT      PICOBSD-N.2000  ipfilter       options.i386
LKM       devices.i386    kernel.script

    目录中最重要的文件有GENERIC和LINT，名为GENERIC的文件就是通用内核kernel.GENERIC的配置文件，而LINT文件中包括FreeBSD支持的几乎所有配置参数，并逐一加以解释。另一些文件则是其他硬件配置下，用于特定目的的配置文件的例子。因此GENERIC和LINT文件是在设置内核时的必备参考。有了这些文件作参考之后，就可以生成针对某个计算机具体设置的配置文件就更为简单了，并执行编译内核的任务。

  • 修改内核的一般原则

    •

    要定制内核，就必须要生成配置文件。一般都是通过更改已有配置文件的方法来生成特定的配置文件，以简化设置工作。但直接修改已有的配置文件的方式，如修改GENERIC文件，并不可取，而应该先复制生成一个新的配置文件，这样就可以使用多个配置文件，维护多个不同配置的内核。这些内核可以是为一台计算机准备的，也可以是为多台计算机准备的。新配置文件可以很方便的从对已有配置文件，如GENERIC，进行复制得到。例如：

# cd /usr/src/sys/i386/conf
# cp GENERIC mykernel

    然后再修改mykernel这个配置文件，第一步需要完成的任务是先删除不必要的硬件支持选项，这是因为通用内核支持的硬件设备通常要多于计算机系统中实际存在的硬件设备，不必要的硬件驱动代码会占用不必要的内核内存空间。除了根据管理员对计算机硬件配置的了解来进行删除不必要的硬件驱动选项之外，比较简便的方法是根据FreeBSD的通用内核在启动时报告的信息来判断哪个设备已经探测到，哪个设备没被探测到。使用系统命令dmesg可以查看系统启动时的信息，因此没被探测到的设备可以使用命令来得到：

# dmesg | grep “not found”

    这个命令输出的结果，或者是计算机中并不存在的设备，或者是驱动程序的参数没有配置正确，没有正确检测到硬件设备的情况。如果确认没有这个硬件设备，就可以在配置文件中将其删除。

    有些硬件设置的缺省参数与系统中的硬件设置并不一致，可以通过更改配置文件中的配置参数来改变设置，以达到正确检测硬件的目的。

    有些设备在GENERIC配置文件中并没有提供支持，例如声卡设备，以及多处理器支持能力。如果要想支持这些设置，就要将相应的设置参数增添到配置文件中，可以要参考文件LINT中的相应设置来完成增添硬件的过程。

    为了得到一个合适的内核，或许需要不止一次的更改设置。当对计算机的某些硬件设置不是很清楚，为了节约编译内核次数，可以先通过
              UserConfig更改确定正确的硬件设置，再重新编译内核的这种循序渐进方式，逐步获得硬件的正确配置。

    重新定制内核不但是为了获得硬件配置的正确性，还可以通过更改内核设置支持一些FreeBSD支持的特定功能、优化现有能力，以发挥系统的最大能力，从而达到将硬件具备的最大能力，充分发挥FreeBSD具备的强大处理能力。

  • 编译和安装内核

    •

    在生成自己的内核配置文件mykernel之后，就可以进入下一步编译安装过程了。在配置文件所在的目录中，输入：

# /usr/sbin/config mykernel
Removing old directory ../../compile/mykernel:  Done.
Kernel build directory is ../../compile/mykernel

    这个命令将产生一个/usr/src/sys/complie/mykernel的目录，其中目录名对应于内核的名字，这样就使得系统中可以同时维护多个不同的内核，不同的内核相互独立而互不干扰。这个目录中就包括了编译内核所需的源文件。

    如果这个过程出现错误，就说明配置文件中存在语法错误，config程序将会提示出错的行，以便使用者进行修改。但是config不会发现配置文件中存在的逻辑错误，这些逻辑错误只能在编译内核时才能发现。

    下一步就是进入生成的目录中进行编译和安装。

# cd ../../compile/mykernel
# make depend
# make

    编译过程需要一些时间以进行编译，这时候就可以作些其他任务等待编译结束。但如果配置文件存在逻辑错误，在编译时会形成错误。因为内核配置选项不是相互无关的，而是存在相关依赖关系，有些设置项会依赖于另外的设置项。当发生这些逻辑错误的时候，当所有需要的源文件都存在时，就说明配置文件中缺少一些基本参数定义的代码，需要重新加入。例如所有的EISA设备依赖于controller
              eisa0定义的EISA控制器，那么删除controller eisa0设置项就会造成编译EISA设备时，缺少controller
              eisa0对应的源程序中定义的函数和变量，就会造成编译失败。确定没有EISA设备的时候，就要删除所有的 EISA相关选项，以避免逻辑错误。

    内核编译成功之后，就可以进行安装了：

# make install

    这将原有内核更改为/kernel.old，然后将编译后产生的新内核移到根目录下，命名为/kernel。此后可以重起系统，检查新内核是否正确。

# reboot

    如果新内核的配置不正确，造成某些硬件不能正确检测造成不能正常启动。此时就需要重新用老内核进入系统，以重新进行编译纠正错误。选择不同内核必须通过Boot
              Loader的交互界面进行，需要在启动时进入Boot Loader，然后可以输入load kernel.old命令，使用老内核启动系统，或者使用kernel.GENERIC
              通用内核启动系统。

    为了避免第二次编译内核时，将错误的内核保存为kernel.old，覆盖原有的正确设置，也可以先将正确的内核拷贝为根文件系统中的另一个文件，进行备份保存，只有放置在根分区上的内核才能正常启动系统，因此备份到其他文件系统中内核意义不大。


FreeBSD连载(60)：缺省内核配置选项

王波

缺省内核配置选项

    通用内核的设置文件中包含了很多比较重要的设置选项，这里的设置选项也是最常用的配置选项，为了编译出适合自己计算机的设置，就需要了解这个文件中的设置选项。

#
# GENERIC -- Generic machine with WD/AHx/NCR/BTx family disks
#
# For more information read the handbook part System Administration ->
# Configuring the FreeBSD Kernel -> The Configuration File.
# The handbook is available in /usr/share/doc/handbook or online as
# latest version from the FreeBSD World Wide Web server
# <URL:http://www.FreeBSD.ORG/>
#
# An exhaustive list of options and more detailed explanations of the
# device lines is present in the ./LINT configuration file. If you are
# in doubt as to the purpose or necessity of a line, check first in LINT.
#
#	$Id: GENERIC,v 1.143.2.2 1999/02/15 02:50:07 des Exp $

machine		"i386"
cpu		"I386_CPU"
cpu		"I486_CPU"
cpu		"I586_CPU"
cpu		"I686_CPU"
ident		GENERIC
maxusers	32

     machine行定义了系统所使用的计算机体系结构，对于运行在个人计算机平台上的FreeBSD，此参数值只能是i386，运行在其他平台上的BSD系统将使用其他相应设置。注意由于这个配置参数中混用了字母和数字，因此需要用引号将其括起来。这种情况在配置文件中经常会碰到，如果不使用双引号括起来，配置程序就不能区分它是用于标识字符串还是用于数值设置，造成语法错误。

    可以多个cpu参数描述了处理器类型，可以使用 ”I386_CPU”
              、 “I486_CPU” 、 “I586_CPU” 、 “I686_CPU” 四种类型。 “I386_CPU” 是最低配置，缺省的GENERIC配置文件中将这些类型全部列出，这使得这个通用内核在任何个人计算机系统下都能正常运行，但最好根据处理器类型进行针对配置。由于处理器是向下兼容的，但不能向上兼容，因此如果配置的参数高于计算机实际处理器类型，内核就不能正常启动和工作。

    对于586以上的处理器，各个兼容厂商的标记方法各不相同，因此必须小心选择正确的处理器类型，以避免选择错误。可以使用系统启动时的检测信息来判断处理器的类型：

# dmesg | grep ^CPU

     ident用于标识内核，每个内核都应该具有自己的标识，GENERIC内核的标识为GENERIC，而自己定制的内核可以在这一行中定义自己的标识。由于系统中可能存在有多个内核，因此使用这个标识来帮助区分不同的内核。这个标识在系统启动时将显示在启动屏幕上。

     maxusers这个值并不直接限制FreeBSD的用户数目，而是定义了内核中的一些非常重要的系统表格大小，这些表格会随系统中进程的增加和资源的被占用会逐渐被填满，而系统中的用户和进程数量有一定的关系，因此这个值大概等于系统同时允许的用户数目。但是当用户使用X
              Winodw或其他产生了大量进程和应用程序时，即使只有很少的用户，系统表格也很容易被填满。因此这个值不能设置的太小。尤其是要将FreeBSD
              用作服务器的时候，服务器会启动大量的进程，往往要增大这个值以提升系统对高负载的支持能力。

    系统的进程表的大小为：20+16*maxusers，去除系统启动时自动启动的一些守护进程数目，因此可以大致估计出系统中空余的进程表项。进而估计出系统中还可以容纳的进程数目，因此就可以根据需求改变这个值的设置。

options		MATH_EMULATE		#Support for x87 emulation
options		INET			#InterNETworking
options		FFS			#Berkeley Fast Filesystem
options		FFS_ROOT		#FFS usable as root device [keep this!]
options		MFS			#Memory Filesystem
options		MFS_ROOT		#MFS usable as root device, "MFS" req'ed
options		NFS			#Network Filesystem
options		NFS_ROOT		#NFS usable as root device, "NFS" req'ed
options		MSDOSFS			#MSDOS Filesystem
options		"CD9660"		#ISO 9660 Filesystem
options		"CD9660_ROOT"		#CD-ROM usable as root. "CD9660" req'ed
options		PROCFS			#Process filesystem
options		"COMPAT_43"		#Compatible with BSD 4.3 [KEEP THIS!]
options		SCSI_DELAY=15000	#Be pessimistic about Joe SCSI device
options		UCONSOLE		#Allow users to grab the console
options		FAILSAFE		#Be conservative
options		USERCONFIG		#boot -c editor
options		VISUAL_USERCONFIG	#visual boot -c editor

config		kernel	root on wd0

     MATH_EMULATE选项是一个x87浮点运算模拟器，当计算机中没有x87协处理器时才需要使用。当前586级以上处理器的处理器内部均已集成了浮点运算器件，因此除非使用386芯片或部分低档486芯片，内核配置并不需要这种模拟功能。此外，另一个具有相同功能的选项为GPL_MATH_EMULATE，这个选项性能更好，只是它使用GNU的数学函数代码，而GNU公用许可比BSD许可要求更严格。因为这个版权的原因，缺省使用
              MATH_EMULATE，这保证FreeBSD可以只以二进制形式向外发布，而不违反GNU许可。由于两个选项功能相同，只能任选一种，不能同时使用这两个选项。

     INET选项定义了基本的TCP/IP支持，由于FreeBSD是网络操作系统，因此这是最基本的选项。

     FFS为BSD快速文件系统，即UFS文件系统，这是FreeBSD使用的基本文件系统。FFS_ROOT用于在UFS系统上启动系统，
              允许将UFS文件系统用作根文件系统。由于UFS是FreeBSD使用的最基本的文件系统，因此应该设置FFS_ROOT，以使系统能够从磁盘上正常启动。

     NFS为Sun公司开发的网络文件系统，它是Unix之间共享文件系统一种事实标准。NFS文件系统也可以用作根文件系统，这通过NFS_ROOT选项进行定义，使得可以配置FreeBSD无盘工作站，无盘的FreeBSD系统可以用于专用X终端等特殊场合。

     "CD9660"为ISO 9660 格式的CD-Rom文件系统，使用它访问CD-Rom上的文件系统。"CD9660_ROOT"使得可以用光盘作根文件系统。

     MFS为内存映射文件系统，可以将内存映射为文件系统，改善文件系统的性能，当然这只适合有大量物理内存和交换空间的系统。也可以使用mfs类型来将交换分区安装到某个目录上，保存一些临时文件。例如，系统的交换分区为wd0s3b，那么可以使用
              “mount -t mfs /dev/wd0s3b /tmp” ，将交换分区安装到/tmp目录上。由于tmp是临时目录， 被程序用来交换数据，使用mfs文件系统能提高访问速度，这是拥有大量内存的计算机使用
              mfs较常用的方式。MFS_ROOT用于将内存映射文件系统用作根文件系统，FreeBSD的安 装软盘就是使用的这种根文件系统，此外，使用MFS_ROOT也用于将FreeBSD系统用作专用防火
              墙的嵌入式操作系统。

    当安装了系统源代码之后，可以很容易生成能运行在一张软盘上的FreeBSD系统，叫做
              PicoBSD，它主要被用做路由器、防火墙等专用服务器等。

     MSDOSFS选项定义了msdos的fat文件系统，这不是必要的文件系统选项，使用它来访问本地硬盘上的msdos文件系统。如果要访问软盘上的msdos文件系统，使用mtools软件更为方便。

     PROCFS是一个伪文件系统，它被安装到/proc目录，用于访问与相应的进程相关的信息，一些系统程序如ps，使用它来获得进程的信息。

    此外，"EXT2FS"选项为Linux所使用Ext2fs类型的文件系统，如果用户的计算机上还运行着Linux，并希望使用FreeBSD访问本地硬盘上的Linux文件系统，就需要这个选项。

    FreeBSD 2.x以后版本是从4.4BSD发展来的，但FreeBSD 1.x是来自于4.3BSD的。4.3BSD是一个非常重要的BSD版本，很多应用程序也是依照4.3BSD开发的。因此需要使用这个"COMPAT_43"
              选项保持和基于4.3BSD（包括FreeBSD 1.x）应用程序的兼容性。

    SCSI设备在设置时需要一定的延迟时间，以便使SCSI控制卡能正确的和SCSI设备通信。因此需要定义SCSI_DELAY=15000选项，与其他选项不同，这个选项为数值设置，使用了赋值符号和数字。这个值的单位为毫秒

     UCONSOLE选项使用户能接管console，通常在使用X Window时比较有用，这样就能在
              X Window下接管console输出的与系统相关的信息。FAILSAFE选项使得配置程序对待内核更为谨慎和保守，从而增加了系统的安全性。

     USERCONFIG和VISUAL_USERCONFIG这两个选项使用户可以在启动时进入内核参数设置程序UserConfig，配置硬件参数。USERCONFIG参数只提供基本命令行配置功能，而
              VISUAL_USERCONFIG进一步提供全屏的编辑功能。

     config行指定内核文件名及其位置，它指定内核名为kernel，并且内核所在的根文件系统位于wd0硬盘上，根文件系统即为wd0a。FreeBSD习惯上使用kernel作为内核的文件名，不应改变。而它的位置wd0可能会根据硬件设置的不同而不同，例如：如果将FreeBSD安装到了SCSI硬盘上，则内核和根文件系统的位置就为da0中的分区。

# To make an SMP kernel, the next two are needed
options 	SMP				# Symmetric MultiProcessor Kernel
options 	APIC_IO			# Symmetric (APIC) I/O
# Optionally these may need tweaked, (defaults shown):
#options	NCPU=2			# number of CPUs
#options	NBUS=4			# number of busses
#options	NAPIC=1			# number of IO APICs
#options	NINTR=24			# number of INTs

    如果用户的计算机有多个处理器，就需要取消注释，使用这几个选项以进行支持。一般 SMP和APIC_IO是最基本的两个设置选项，SMP选项是用于支持对称多处理器SMP结构的基本代码，APIC_IO支持APIC
              IO方式对称I/O。使用这两个选项之后，系统就能自动检测出所使用的处理器个数以及其他系统资源。当然也可以手工指定这些资源设置，这用于不能正确侦测处理器数目时使用。缺省内核不支持多处理器，因此对于多处理器系统必须重新生成内核。

    由于只有586以上的芯片才支持SMP，因此这需要在cpu行的设置中删除386和486行的设置，明确指定处理器的类型。否则就会发生逻辑冲突。

controller	isa0
controller	eisa0
controller	pci0

    这三行定义了三种控制器的基本支持代码：ISA、EISA和PCI总线控制器。

     ISA总线类型是个人计算机的标准配置，很多驱动程序代码都基于ISA控制器的代码，因此系统必须对ISA总线进行支持。EISA总线类型是ISA的扩展，使用在一些较老型号的服务器中，今天已经逐渐被PCI总线代替，它是可选的。PCI选项支持PCI总线设备的通用代码，当前PCI总线主板是个人计算机的主流，这个选项也是必须的。

    如果用户的计算机不存在EISA总线，可以删除对EISA选项的支持。但是，由于后面设置的一些设备是EISA总线类型的设备，依赖这个选项的支持，必须同时也必须删除所有的EISA总线类型的设备，否则就存在逻辑错误。配置程序并不会自动删除那些并不存在的设备选项，这样就导致直到编译时才会发现EISA总线设备的驱动程序发生编译错误，编译不能正常完成。

controller	fdc0	at isa? port "IO_FD1" bio irq 6 drq 2
disk		fd0	at fdc0 drive 0
disk		fd1	at fdc0 drive 1

    控制器fdc0是支持标准软盘控制器的基本代码，一般个人计算机能支持两个软盘驱动器，
              fd0和fd1设备。 通过drive参数的值可以指定这两个软盘的顺序。fdc0使用的资源是个人计算机缺省设置，因此不存在系统探测问题。此外，虽然让内核自动探测软盘的数量没什么坏处，但删除不必要的选项可以略微加快系统启动的速度

options		"CMD640"	# work around CMD640 chip deficiency
controller	wdc0	at isa? port "IO_WD1" bio irq 14
#controller	wdc0	at isa? port "IO_WD1" bio irq 14 flags 0x00ff8004
disk		wd0	at wdc0 drive 0
disk		wd1	at wdc0 drive 1

controller	wdc1	at isa? port "IO_WD2" bio irq 15
disk		wd2	at wdc1 drive 0
disk		wd3	at wdc1 drive 1

options		ATAPI		#Enable ATAPI support for IDE bus
options		ATAPI_STATIC	#Don't do it as an LKM
device		acd0		#IDE CD-ROM
device		wfd0		#IDE Floppy (e.g. LS-120)

    前面的这些选项是用于支持IDE驱动器及硬盘的配置，事实上这些设置不但支持IDE驱动器，还支持一些较老的ST506或ESDI界面的硬盘设备，虽然那些硬盘设备已经淘汰，没有人再使用它们了。

     "CMD640"用于修正使用CMD640控制芯片的系统主板的问题，wdc0是第一个IDE接口控制器，wdc1为第二个IDE控制器，一个个人计算机系统中只能存在两个标准IDE控制器，并且一个IDE驱动器能带两个硬盘设备，因此wdc0上能连接两个硬盘wd0和wd1，wdc1能连接wd2和wd3。其中wd0和wd2为主硬盘，wd1和wd3为从硬盘。当然可以通过指定磁盘的参数at和drive参数的设置，改变硬盘号的顺序。

    由于IDE经过了一个长期的发展，控制器是由不同的制造厂商制造的，因此在一些细微的方面也存在有差异，主要是新的控制器能够支持更强的传输模式，当然它也支持原有的兼容模式。为这些细小的差异没有必要重写驱动程序，只需要更改配置行中的参数设置，就能支持某些IDE控制器的高级功能。

    每个控制器都有长32位的flags标志位，用于定义IDE硬盘的I/O类型，其中前16位定义
              drive 1的标志，后16位定义drive 0的标志。例如wdc0的标志为0x00ff8004，表示定义了wd0的标志为0x8004，使用32位I/O每次传送4个扇区，而wd1设置为0x00ff，不探测32位传输而使用兼容模式。这个标志也可以分割为两个16位的部分，也在每个磁盘设备的标志中定义。

    IDE控制器中还支持光盘驱动器，首先需要ATAPI提供IDE界面使用的ATAPI类型光驱基本代码，
              ATAPI_STATIC这一选项使ATAPI代码直接编译到内核文件中，而不编译为可加载模块。而acd0就为IDE光驱的驱动程序。由于光驱就是连接在IDE控制器上，因此IDE接口的光驱还需要相应IDE驱动器的支持，例如光驱接在第二个IDE控制器上，则必须增加wdc1控制器选项。如果光驱上的主/从（master/slave）跳线不正确，就不能正确侦知IDE光驱，很多IDE光驱出厂设置位从设备，在该IDE总线上没有其他设备的情况下，应该将光驱跳为主设备。

    2.2和3.0release版本使用wcd0作光驱的驱动程序，而acd0是3.1-stable使用的新CD-ROM驱动，因此从2.2.x或3.0-release升级到3.1-stable时，要更改设置文件中的原wcd0项为acd0项。以后随着系统的发展，老wcd0的代码会完全删除，新代码的驱动名字会恢复为wcd0。

    wfd0为IDE接口的软盘驱动器，某些zip驱动器需要这个驱动器的支持。

# A single entry for any of these controllers (ncr, ahb, ahc) is
# sufficient for any number of installed devices.
controller	ncr0
controller	ahb0
controller	ahc0
controller	isp0

# This controller offers a number of configuration options, too many to
# document here  - see the LINT file in this directory and look up the
# dpt0 entry there for much fuller documentation on this.
controller      dpt0

controller	adv0	at isa? port ? cam irq ?
controller	adw0
controller	bt0	at isa? port ? cam irq ?
controller	aha0	at isa? port ? cam irq ?
#controller	aic0	at isa? port 0x340 bio irq 11

controller	scbus0
#controller  scbus1 at ahc1 bus 0

device		da0
#disk  da0 at scbus0 target 0 unit 0

device		sa0
device		pass0
device		cd0	#Only need one of these, the code dynamically grows

    对于网络服务器来讲，SCSI控制器是理想的选择，因为SCSI设备不需要占用计算机处理器的处理能力，因此适合经常发生并发存取的服务器系统。FreeBSD
              3.0之后的SCSI驱动代码已经完全重写，新的代码更高效，并支持更多新设备。

    对于不同的SCSI设备，需要不同的SCSI控制器驱动程序，例如aha0为支持使用Adaptec
              154x 芯片SCSI控制器的驱动程序，内核配置文件LINT和安装介质中的HARDWARE.TXT中也列出了FreeBSD支持的
              SCSI控制器对应的各个选项。需要根据自己计算机上的SCSI卡的具体型号进行选择。确定了具体的驱动之后，可以删除和添加相应的控制行，但需要注意最好不要改变配置文件中控制器的前后顺序，因为配置顺序决定系统检测硬件的顺序，那么配置顺序不正确有可能造成错误的检测结果。

     scbus0控制器提供基本的SCSI总线驱动代码，当不使用参数的时候，这个控制器将自动和检测到的某个SCSI控制器联系起来。在已经了解系统拥有的控制器的条件下，可以使用at参数手工指定某个序号的SCSI总线位于哪个SCSI控制器上，一般一个SCSI控制器可以有几个SCSI总线通道。上例中注释中的
              scbus1总线控制器被指定为ahc1控制卡上的第一个总线，注意自动分配SCSI总线序号的方式与手工指定 SCSI总线的方式不应该混用，以避免出现冲突错误。

     da0就用于标识SCSI硬盘设备，不同的SCSI磁盘的SCSI总线scbus0，总线上的target号和逻辑单元号unit这三个参数是不同的，可以用来标识不同的SCSI硬盘。如果忽略这三个配置参数，FreeBSD按检测的顺序分配硬盘的序号。但是也可以手工指定这三个参数，确定硬盘序号。同样，手工指定和自动分配序号不能混用。

    指定总线序号并指定硬盘序号的益处是硬盘序号的顺序将与内核自动检测的顺序无关。由于每个系统中会同时存在多个SCSI总线，每个总线上可以有安装有多个SCSI设备和逻辑单元，因此在增加、移去某个磁盘时，会使其他磁盘自动分配的序号发生改变，从而使FreeBSD安装文件系统出现问题，严重的会影响正常启动。解决办法就是应该手工指定SCSI硬盘与总线、控制器的关系。

     sa0为SCSI磁带驱动器，cd0为SCSI光驱，pass0为新SCSI驱动程序CAM中的通道驱动程序。

device		wt0	at isa? port 0x300 bio irq 5 drq 1
device		mcd0	at isa? port 0x300 bio irq 10

controller	matcd0	at isa? port 0x230 bio

device		scd0	at isa? port 0x230 bio

    上面这些驱动是一些老式的ATAPI界面的光驱，这些光驱控制器一般都和声卡作在一起，当前已经很少使用这些光驱了。

# atkbdc0 controlls both the keyboard and the PS/2 mouse
controller	atkbdc0	at isa? port IO_KBD tty
device		atkbd0	at isa? tty irq 1
device		psm0	at isa? tty irq 12

device		vga0	at isa? port ? conflicts

# splash screen/screen saver
pseudo-device	splash

# syscons is the default console driver, resembling an SCO console
device		sc0	at isa? tty
# Enable this and PCVT_FREEBSD for pcvt vt220 compatible console driver
#device		vt0	at isa? tty
#options		XSERVER			# support for X server
#options		FAT_CURSOR		# start with block cursor
# If you have a ThinkPAD, uncomment this along with the rest of the PCVT lines
#options		PCVT_SCANSET=2		# IBM keyboards are non-std

device		npx0	at isa? port IO_NPX irq 13

     atkbdc0为键盘控制器，atkbd0为相应的键盘设备，psm0为ps/2
              类型的鼠标设备。vga0为显示驱动程序，标准的控制台程序需要它的支持。vga0的 conflicts标志指出这个驱动程序会和其他设备共享某些资源，告诉内核不要因为这个硬件发生资源冲突而认为是这个设置不正确。FreeBSD为多用户系统，一般情况下各个设备不应该相互共享资源，以避免访问冲突。除非设备不能被使用者直接访问的情况下，硬件才能共享系统资源。

    如果要取得更好的显示效果，可以使用VESA选项（options VESA），来支持800x600的控制台显示模式（能支持132x60的字符模式）。只是VESA选项不能和多处理器选项SMP共存，它也要求系统内核提供对虚拟86模式的支持，以便VESA显示子系统就能控制显示卡，所以同时需要
              “options VM86” 选项。

     splash伪设备用于支持splash屏幕图象和屏幕保护功能，这能使得系统启动时展示一个图象启动标志，并能提供控制台下的屏幕保护功能。

    全称为syscon的sc0驱动程序定义了缺省的控制台设备，支持彩色和虚拟控制台模式。vt0是可以用来替换sc0驱动另一个控制台驱动程序，只有在使用有些特殊的与sc0
              不兼容的硬件的时候，才需要使用这个pcvt控制台驱动程序。如果使用vt0驱动，那么或者会需要设置XSERVER、FAT_CURSOR等选项以提供更完善的支持。

     npx0为浮点协处理器的接口，这是用于支持浮点协处理器必需的选项。没有浮点协处理器的计算机必须配置数学防真MATH_EMULATE或者GPL_MATH_EMULATE以支持浮点运算。如果同时使用了这两类选项，则按照系统检测结果，当npx0被检测到时npx0就发挥作用。

#
# Laptop support (see LINT for more options)
#
device		apm0    at isa?	disable	flags 0x31 # Advanced Power Management

# PCCARD (PCMCIA) support
#controller	card0
#device		pcic0	at card?
#device		pcic1	at card?

    上面这些选项用来支持便携计算机，apm0用于支持高级电源管理功能，card0
              控制器对PCMCIA接口的设备进行支持，需要指定相应的设备如pcic0等。

    标准的FreeBSD内核代码支持的便携计算机设备并不丰富，因此FreeBSD中有一个PAO的开发计划，专门为用于支持便携计算机。

device		sio0	at isa? port "IO_COM1" flags 0x10 tty irq 4
device		sio1	at isa? port "IO_COM2" tty irq 3
device		sio2	at isa? disable port "IO_COM3" tty irq 5
device		sio3	at isa? disable port "IO_COM4" tty irq 9

# Parallel port
device		ppc0	at isa? port? net irq 7
controller	ppbus0
device		nlpt0	at ppbus?
device		plip0	at ppbus?
device		ppi0	at ppbus?
#controller	vpo0	at ppbus?

     sio0、sio1、sio2和sio3为四个标准串口设备，其中sio0还可以用做终端控制台，这样专用服务器就可以不使用显示器、键盘而使用一个普通字符终端来完成控制任务，这样多个FreeBSD系统能放在专用机架上，用做专用服务器。sio0的flags规定了这个串口用做控制台的优先级，通常使用0x10就足够了，使用0x20或0x40会妨碍对这个串口进行其他正常操作。

    3.0之前的FreeBSD系统使用COMCONSOLE设置选项来达到同样的目的，这个选项在新系统中不再有效，使用sio0的flags就能达到同样的目的。

    要使用串口作控制台，还需要在/etc/ttys中定义相应的配置行，使得系统在sio0对应的ttyd0
              设备上执行相应的getty命令。Packages Collection中的comconsole-0.1.tgz软件包能帮助进行这些设置。

    设备ppc0、控制器ppbus0用于支持并口设备，nlpt0为并口打印机设备，plip0为并口网络界面，ppi0用于一般目的的输入输出。vpo0为某些并口SCSI设备的控制器，因此除了并口驱动之外，也需要SCSI总线控制器scbus0和SCSI硬盘da0的支持。这些并口设备是3.1版本之后更新的并口驱动，原有的驱动为lpt0，只能支持最标准的并口模式，不能并口的新模式。

# Order is important here due to intrusive probes, do *not* alphabetize
# this list of network interfaces until the probes have been fixed.
# Right now it appears that the ie0 must be probed before ep0. See
# revision 1.20 of this file.
device ax0
device de0
device fxp0
device mx0
device pn0
device rl0
device tl0
device tx0
device vr0
device vx0
device wb0
device xl0

device ed0 at isa? port 0x280 net irq 10 iomem 0xd8000
device ie0 at isa? port 0x300 net irq 10 iomem 0xd0000
device ep0 at isa? port 0x300 net irq 10
device ex0 at isa? port? net irq?
device fe0 at isa? port 0x300 net irq ?
device le0 at isa? port 0x300 net irq 5 iomem 0xd0000
device lnc0 at isa? port 0x280 net irq 10 drq 0
device ze0 at isa? port 0x300 net irq 10 iomem 0xd8000
device zp0 at isa? port 0x300 net irq 10 iomem 0xd8000
device cs0 at isa? port 0x300 net irq ?

    由于FreeBSD是网络操作系统，因此通常计算机常常通过以太网卡或广域网卡与网络相连接。对于每个网卡设备，必须在内核配置中进行相应的配置。上述选项就用于设置不同的网络设备的驱动程序。FreeBSD缺省内核包括了对很多网卡设备的支持，这些设备的驱动程序都被编译入系统内核中，占据了大量不必要的空间。因此在定制系统内核时，最好删去计算机上不存在的网卡类型的驱动，这样也可以加快系统的硬件探测过程。如果在缺省内核中，网卡已经能正常运行，就可以使用dmesg找出正确的网卡类型。当不能确定网卡类型的时候，更改内核配置文件一定要注意顺序，因为检测顺序非常重要，由于不同的网卡驱动相互有影响，正确的检测顺序可以避免出现探测错误。

    较老的ISA网卡还需要配置参数和硬件设置相一致，就要调整网卡使用的端口地址，irq
              和iomem等参数与网卡使用的真实资源相一致。这是由于生产兼容网卡的厂商太多，因此各种兼容网卡的缺省设置却并不相同，而较老的驱动程序不能自动探测设备使用的资源。新的PCI网卡就不存在这个问题，驱动程序支持PNP，可以自动探测硬件资源。

pseudo-device	loop
pseudo-device	ether
pseudo-device	sl	1
pseudo-device	ppp	1
pseudo-device	tun	1
pseudo-device	pty	16
pseudo-device	gzip		# Exec gzipped a.out's

    伪设备并不与具体的物理设备有关，但外在表现为一种设备。通常伪设备用于支持系统中与某类操作相关的基本代码。

     loop定义TCP/IP使用的loopback网络设备，这将使计算机能够通过TCP/IP堆栈内部，以127.0.0.1（通常名字定义为localhost）的IP地址访问自身。由于FreeBSD为网络操作系统，这个选项是必须的。不管计算机上有没有网络设备，FreeBSD都提供了这个loopback的伪网络设备，以提供最基本的网络功能。网络功能是FreeBSD系统的基本功能，FreeBSD上的很多程序需要网络支持才能正常运行。很多程序能使用这种网络支持，进行本机内部进程间的连接。

     ether伪设备定义了支持Ethernet协议的基本代码，Ethernet是最流行的局域网标准，如果计算机通过Ethernet网卡互相连接，就需要这个选项的支持。

     sl为支持SLIP协议的伪设备，其后的数值参数为支持的sl伪设备的数目。SLIP协议已经逐渐被PPP协议取代。因此一般可以删除这个选项。

     ppp是在内核中实现PPP协议的驱动程序，之后的数字指定了可同时使用的PPP会话的数量。用户使用这个伪设备便能使用pppd，使用PPP协议通过modem与另一台计算机相连接。

     tun为tunnel伪设备，用于建立直接的通道。它也被常用来支持PPP协议，不同在于它在内部没有实现PPP协议，而支持PPP协议的代码是在应用软件ppp中实现的。这是用户模式的PPP
              支持，与伪设备ppp相比，它较容易配置和使用。

     pty是伪终端设备，在远程登录等需要以终端方式进行连接，但又并非真实终端的应用程序中必须使用这种设备，如telnet或xterm等程序。这里定义的限制是内核允许同时创建的伪终端数，缺省设置对于个人使用还能基本满足，但如果将系统用于提供远程登录服务，例如用做BBS服务器，16个伪设备就远远不够。此外，X
              Window用户也会占用大量的pty设备。

    伪设备gzip是FreeBSD的另一种特性，它使FreeBSD能够运行用gzip压缩过的a.out格式执行文件，因此能节约磁盘空间。但是这种特性只支持传统的a.out格式执行文件，而FreeBSD自3.0以后，虽然仍然支持a.out格式，但标准执行程序的格式转为ELF格式。因此这个特性带来的好处就大大降低了。为了利用这个特性，可以将应用程序编译为a.out格式（使用-aout编译连接选项）。

# KTRACE enables the system-call tracing facility ktrace(2).
# This adds 4 KB bloat to your kernel, and slightly increases
# the costs of each syscall.
options		KTRACE		#kernel tracing

# This provides support for System V shared memory and message queues.
#
options		SYSVSHM
options		SYSVMSG

    配置KTRACE选项使内核允许系统调用跟踪程序ktrace能正常运行。

     SYSVSHM、SYSVMSG这个选项提供FreeBSD与System
              V的兼容性，其中第一个选项SYSVSHM 提供了进程间共享内存的机制，X Window系统就需要这种共享内存机制，以提高管理图形的性能。
              SYSVMSG用于支持System V的消息队列，只在特定的程序中用到，如Windows 9x的模拟器wine。

#  The `bpfilter' pseudo-device enables the Berkeley Packet Filter.  Be
#  aware of the legal and administrative consequences of enabling this
#  option.  The number of devices determines the maximum number of
#  simultaneous BPF clients programs runnable.
#pseudo-device	bpfilter 4	#Berkeley packet filter

     bpfilter即Berkeley Packet Filter，通常计算机只接收与本机有关的数据包或广播包。在网上传播的数据包，如果与本机无关，计算机将不予理会，这样的好处是减轻了处理器负担。如果要让计算机能够捕获经过网卡的所有数据包，就要让网卡工作在混杂模式，此时就需要使用这个伪设备。后面的数字指定能同时使用这个功能的程序的数目。

    使用这个选项的目的是使计算机能捕获数据包并进行分析，监测网络、寻找故障，一些特殊功能如DHCP的客户程序，也需要这个伪设备的支持。但这种功能如果被不正当使用，将对整个局域网的安全造成威胁，尤其是使用共享式以太网连接方式的网络，网络上传播的信息将被这台计算机所窃听。需要注意的是，不是所有的网卡都支持混杂模式，只有支持混杂模式的网卡才能使用这个功能。

# USB support
#controller    uhci0
#controller    ohci0
#controller    usb0
#
# for the moment we have to specify the priorities of the device
# drivers explicitly by the ordering in the list below. This will
# be changed in the future.
#
#device        ums0
#device        ukbd0
#device        ulpt0
#device        uhub0
#device        ucom0
#device        umodem0
#device        hid0
#device        ugen0

#
#options       USB_DEBUG
#options       USBVERBOSE

    这些设置选项是用来支持USB控制器和USB设备，当前USB设备还不是很流行，但它是未来发展的一个趋势。


FreeBSD连载(61)：其他内核设置选项

王波

其他内核设置选项

    了解了最基本的GENERIC设置文件的内容，使用者就能根据实际情况，将不必要的设置删除，配置一个适合自己硬件的内核。然而GENERIC内核并不能包括更丰富的设置，包括很多支持的硬件种类，或者特定的内核特性等。

    除了上面提到的这些较常用到的选项之外，FreeBSD中还支持一些不常使用的设备和选项，例如一些老式的连接到声卡上的光驱、游戏杆等，FreeBSD甚至也支持IP over ATM协议和ATM网卡，千兆以太网卡等最新的网络设备和协议。

    所有的选项均可以在LINT文件中找到对应配置的例子，就需要根据具体硬件将配置增加到用户自己的配置文件中。

    无论增加哪种硬件设备之后，都要检查系统中是否有相应的设备文件存在。通用内核中不存在的设备，缺省也没有生成对应的设备文件。因此需要进入/dev目录中，使用/dev/MAKEDEV命令来产生相应的设备文件。

  • 调整内核性能

    当运行一台高性能服务器的时候，缺省设置并不能充分发挥内核的所有能力。为了调整系统性能，便需要考虑更多的设置选项。

maxusers		256
options         "MAXMEM=(256*1024)"
options         "MAXDSIZ=(256*1024*1024)"
options         "DFLDSIZ=(256*1024*1024)"
options         NMBCLUSTERS=4096
options         CHILD_MAX=512
options         OPEN_MAX=512
options		SMP
options		APIC_IO
options		SOFTUPDATES

    由于服务器系统运行在高负载下，需要产生数量巨大的进程数目，并打开相当多的文件。为了提供更好的支持就需要增加系统中表格的大小，这应该增加maxusers设置参数。

    系统启动时首先通过BIOS来检测系统中的内存，但是一般的BIOS最多只能报告64M内存，因此FreeB
              SD需要自己检测系统中的内存数量。然而系统内存检测并不一定检测到系统中的所有内存，因此需要在内核设置中指定内存大小，MAXMEM选项就用来指定系统物理内存的容量。上例中将系统内存设置为256MB。

    此外，缺省情况下FreeBSD限制每个应用程序使用128MB的内存，这对于一般的应用程序是满足的。但是对于特定的应用程序的服务器，如大容量的新闻组服务器，将占用大量内存，因此就需要增加相应的参数。内核选项MAXD
              SIZ为最大限制，DFLDSIZ为这个限制的缺省值，那么将应用程序的内存使用限制设为256MB的配置项为上例所示。

    为了增加FreeBSD的网络性能，可以增加NMBCLUSTERS的值，这个设置决定网络界面接收数据时的缓冲mbuf的大小，增加这个值就能使系统能同时响应更多的并发请求，这对于Web等高负载服务器特别重要。CHIL
              D_MAX定义一个进程能打开的最多子进程数数目，而OPEN_MAX定义一个进程能同时打开的文件描述字的数目，这三个参数为继承自4.4BSD中的设置参数，在FreeBSD下一般不需要调整，因此并没有写在LINT配置文件中，一般情况下，NMBCLUSTERS的缺省值对于高负载服务器略小一些，而CHILD_MAC和OPEN_MAX的缺省值能满足一般的高负载服务器的要求。

    通常这些数值参数需要根据实际情况进行调整，而不应该一味的增大。使用vmstat，netstat，top
              等系统工具可以观察系统在实际情况下的运行状态，以决定需要进行哪些调整。

    SOFTUPDATES选项能增加UFS类型的文件系统存取速度，对于大部分种类的网络服务器，系统瓶颈在于磁盘访问速度，而使用这个选项可以改善文件系统的存取性能。这个选项之所以没有被作为缺省设置，主要是因为版权原因。然而为了编译带有SOFTUPDATES选项的内核，还必须手工建立一些符号连接，因为SOFTUPDATES使用的源代码并不直接位于正确的编译路径下，而是位于一个非标准路径下，FreeBSD使用这种方法提醒FreeBSD用户，表示这个部分的版权与BSD版权许可不同，需要单独处理。

# cd /usr/src/sys/ufs/ffs
# ln -s /usr/src/contrib/sys/softupdates/*.[ch] .

    当建立了上述连接之后，带有SOFTUPDATES选项的内核才能被正确编译，然而即使内核支持这个选项，还需要在文件系统中设置softupdate选项，相应文件系统才能真正使用这个功能，这需要对相应的文件系统使用tunefs命令：

# tunefs -n enable /dev/rda0s1d

    这个命令只需执行一次就行了，为了避免出现问题，请在系统的单用户模式下执行这个命令。同样可以使用tune
              fs -n disable可以屏蔽这个功能。

    此外，对于多处理器的服务器系统，还可以使用SMP选项和APIC_IO选项以支持多处理器。

    可以在编译内核时打开更多的优化选项，缺省情况的只能提供十分基本的优化，而且是使用标准版本的gcc
              2. 7.2.1来编译系统的。可以安装egcc，并指定更高的优化选项，如-O6和-mPentium，来获得更高级别的优化和利用Pentium芯片专用指令。由于egcc仅仅支持ELF格式的执行文件，因此不能用于3.0之前（包括3
              .0-REKLEASE）使用a.out格式内核的系统。

    当使用egcc编译内核时，需要更改执行config后产生的内核目录下的Makefile，需要重新定义C
              C选项为/usr/local/bin/egcc，并更改优化选项-O为-O -mpentium，但是由于egcc 不支持gcc的编译选项-fformat_externsion，因此还需要更改Makefile引用的/usr/s
              rc/share/mk/bsd.kern.mk文件，删除这个文件中这个编译选项的定义。

    虽然理论上编译器优化不影响编译结果，但是编译器本身也会存在问题，使得在某些情况下发生错误。尤其对于系统内核，它决定系统的稳定性。因而在编译时采用过高的优化时就要特别小心，极其偶然的情况下会过高优化的内核会造成系统崩溃。因此在正式使用一个优化内核之前，应该保留一个原有的、使用普通优化选项的内核。新内核经过一定时间实际运行的考验，确认没有问题之后才能放心用于正式使用。

  • 声卡设备

    通常对于SoundBlaster兼容的声卡，可以使用的以下配置选项：

controller     pnp0
controller     snd0
device sb0 at isa? port 0x220 irq 7 conflicts drq 1 vector sbintr
options  SBC_IRQ=5
device   sbxvi0  at isa? drq 5
device   sbmidi0  at isa? port 0x330
device   opl0     at isa? port 0x38a

    其中pnp0控制器是帮助设置ISA接口的PNP声卡的资源，这主要用于使用BIOS为ISA
              PNP设备分配资源的情况下。但如果不是ISA PNP的声卡，就不需要这个设置，而且如果ISA PNP声卡能设置为非PNP类型，最好将其设置为非PNP类型，ISA总线下的PNP声卡比较难以设置。

    如果系统中安装有DOS的话，可以启动到DOS下，使用该卡的设置程序或一些系统硬件分析软件寻找BIOS分配给ISA
              PNP卡的资源。

    snd0提供最基本的声卡支持代码，sb0为SoundBlaster兼容声卡驱动程序，要根据声卡的配置参数更改sb0驱动程序的IRQ、DMA以及port数值。改变IRQ值的时候，不仅应该在sb0的配置行中改变，还应该使用SBC_IRQ配置选项。

    sbvxi0也是SoundBlaster 16所需的代码，大部分声称与SoundBlaster兼容的声卡并不能做到完全兼容SoundBlaster
              16，最多兼容SoundBlaster或SoundBlaster Pro，因此就不能支持这个设备，只有真正的SoundBlaster
              16才能使它发挥作用。sbmidi0为So undBlaster声卡的MIDI接口的驱动程序，很多兼容声卡也不支持这个设备。opl0为SoundBlast
              er兼容声卡使用的Yamaha OPL-2和OPL-3芯片使用的驱动。

    使用上面的配置选项，设置正确的资源参数，就可以支持soundblaster兼容声卡。但是不同声卡对So
              undblaster的兼容性不同，因此系统检测时就不能检测到所有的设备，如midi设备或sbvxio0设备，但一般都可以检测到sb0设备，这就能提供基本的声卡设备支持。

    声卡设备还需要相应设备文件snd0的支持：

# cd /dev
# ./MAKEDEV snd0

    当使用这些选项重新编译好内核，并启动之后，就可以查看声卡系统是否工作正常。首先应使用
              dmesg命令查看系统是否侦测出了声卡设备，如果没有侦测出，就可能是硬件参数配置的问题，需要使用 UserConfig更改配置。

# dmesg | grep snb0
snd0: <SoundBlaster 16 4.16>
snd0: <SoundBlaster 16 4.16>
snd0: <SoundBlaster MPU-401>
snd0: <Yamaha OPL3 FM>

    通过直接读取设备文件sndstat可以查看出当前声卡的状态，根据系统检测出的设备不同，sndstat
              报告的系统中安装的驱动也不同，至少应该报告一个soundBlaster设备：

# cat /dev/sndstat
VoxWare Sound Driver:3.5-alpha15-970902
(Wed Aug  6 22:58:35 PDT 1997 Amancio Hasty@rah.star-gate.com)
Config options:

Installed drivers:
Type 1: OPL-2/OPL-3 FM
Type 2: SoundBlaster
Type 6: SoundBlaster16
Type 7: SB16 MIDI

Card config:
SoundBlaster at 0x220 irq 5 drq 1
SoundBlaster16 at 0xffffffff irq 1 drq 5
SB16 MIDI at 0x330 irq 1
OPL-2/OPL-3 FM at 0x388 irq 1

Audio devices:
0: SoundBlaster 16 4.16

Synth devices:
0: Yamaha OPL-3

Midi devices:
0: SoundBlaster 16 Midi

Timers:
0: System clock

Mixers:
0: SoundBlaster

    设备文件audio用于声音的输入、输出，如果声卡没有IRQ/DRQ冲突，就能正常使用这个设备，从而可以通过这个设备进行录音和播放声音文件，可以通过标准的操作命令来操作这个设备文件。

# dd if=/dev/audio of=out.au bs=1024 count=10
# cat out.au > /dev/audio

    此后就可以安装相关的声音应用软件了，这些软件通常位于ports的软件包目录下，例如播放mp3格式的音乐文件的软件mpg123：

# cd /usr/ports/audio/mpg123
# make install
# mpg123 test.mp3

  • 其他的声卡驱动程序

    除了SoundBlaster声卡之外，FreeBSD还可以支持SoundBlaster
              AWE 32/ 64、Gravis Ultrasound、Microsoft Sound System、Roland MPU 401、ProAudioSpectrum等声卡。支持这些声卡的驱动也在LINT文件中给出了范例，但这些驱动程序不是单独使用的，需要与上面提到的基本设备sb0相互合作。

    如果计算机上没有声卡，也可以使用个人计算机的喇叭模拟声卡。这样的音响效果并不令人满意，而且也会消耗大量处理器时间，因此应该尽量使用，模拟声卡的设备驱动为pca0。

    有些情况下某些soundblaster声卡使用以上的sd0声卡设备选项并不能正常工作，会遇到IRQ/D
              RQ的冲突问题。此外还可以使用另一个驱动程序pcm0，这个驱动程序能支持一些sb0不支持的SoundBlast er兼容声卡。当然pcm0的功能相对弱一些，不能支持midi功能。设备sb0能和其他几个设备同时发挥作用，而p
              cm0设备不能和前面提到的其他设备相互协作，使用pcm0的配置文件应该为：

controller     pnp0
controller     snd0
device pcm0 at isa? port 0x220 irq 7 drq 1 vector pcmintr

    有时由于pnp设置资源的问题，使得pcm驱动将声卡识别为第二个设备pcm1，而报告pcm0与pcm1存在冲突，此时可以简单的建立设备snd1，而忽略pcm0的冲突信息，此后就一直使用snd1作为声卡设备。

  • 设置ISA PNP声卡

    为了给PNP声卡设置正确的资源值，可以在UserConfig中的命令行方式下搜寻PNP设备、配置PNP
              设备的硬件参数。如同在前面提到的，对PNP设备需要在UserConfig的命令行方式下使用pnp命令进行设置。为了保留这个设置，每次启动时都自动进行设置，就需要将设置写入根文件系统中的一个设置文件中，例如/kernel.config，例如对于Soundblaster
              Vibrx16，执行的pnp命令及写入kernel.config的内容包括：

pnp 1 0 os enable irq0 5 drq0 0 drq1 1 port0 0x220 port1 0x300 port2 0x388
pnp 1 1 os enable port0 0x201
quit

    由于pnp命令就为pnp设备分配了资源，那么内核配置文件中的pcm0使用的参数设置就要与它相一致。

    当设置完kernel.config中，还需要设置Boot Loader的资源文件/boot/boot.rc文件，使其能在启动时自动执行设置命令。

load /kernel

load -t userconfig_script /kernel.config
autoboot

    由于个人计算机上的声卡种类相当多，而FreeBSD支持的声卡类型相对较少，如果用户计算机使用的声卡与FreeBSD支持的类型都不兼容，也可以考虑使用FreeBSD下的商业声卡驱动，商业驱动程序能够支持更多类型的硬件。Opensound是FreeBSD下的一种商业声卡支持驱动，其主页是http://www.4front.com。

  • 磁盘设置

    FreeBSD提供了对磁盘上的文件系统和交换空间的管理能力，可以供使用者进行设置。
              FreeBSD的使用者可以设置对用户的磁盘空间设置，建立伪磁盘设备等，以更好的方式管理磁盘和文件。

  • 磁盘空间限制

    FreeBSD提供了强大的系统管理功能，除了可以在/etc/login.conf中使用登录类别对用户占用的处理器资源进行限制之外，还可以对用户占用的磁盘资源进行限制。用户磁盘空间的限制是通过quota来完成的。这样就可以控制用户对硬盘资源的使用，防止硬盘空间被无意或恶意用光而造成系统故障。这对于提供公共访问的计算机比较重要。quota需要内核支持，在编译内核时必须加入选项：

options  QUOTA

    接下来是决定对哪个文件系统使用quota来限制用户磁盘资源，要更改/etc/fstab中该文件系统对应的行，从而更改分区安装时使用的参数，例如要对wd0s1e进行限制，则更改fstab中的对应行为：

/dev/wd0s1e	 /usr		ufs  rw,userquota,groupquota
    1 	1

    然后更改/etc/rc.conf中的有关quota的设置check_quotas的值为”YES”，使用新内核重新启动计算机之后，就可以使用下列命令打开用户磁盘设置。

# quotacheck  -av
# repquota  -a

    这些命令在第一次启动支持quota的系统时使用，用来检查磁盘上的quota状态。如果一切正常，就可以使用edquota来更改每个用户的磁盘限制了。

# edquota  -u user1
# edquota  -p user1  user2  user3

    第一个命令就为更改user1的磁盘空间限制，第二行将user1的quota限制复制给user2和user3。

    日常维护要使用quota命令，例如来检查user1的quota设置可以使用下面的命令。

# quota -v user1

    为了避免出现问题，需要每天执行一次quotacheck命令，来检查全部设定是否正常，因此这个命令可以放入/etc/daily或crontab中，定期执行。

# quotacheck -a

  • 伪磁盘设备

    交换设备的数量是受内核设置的限制，内核中的NSWAPDEV的值就确定了最多可使用的交换设备的数量，而NO_SWAPPING选项可以用来屏蔽任何交换设备。

options  NSWAPDEV=20
#options	NO_SWAPPING
pseudo-device	vn	4
pseudo-device	ccd	4

    当增加了交换设备的数量之后，就能增加交换空间，更好的发挥FreeBSD的虚拟内存机制。

    FreeBSD支持的vn伪磁盘设备可用于设置交换文件。缺省内核支持的vn伪设备数量为一个，因此仅可以设置一个交换文件。一般仅需要更改/etc/rc.conf文件中的swapfile选项为交换文件的名字，系统自动使用vnconfig命令来将文件和虚拟设备联系在一起。

    为了增加对多个交换文件或多个镜像文件的支持，可以增加内核中伪设备vn的数量，然后还需要创建相应数量的v
              n设备。此后就可以使用这多个伪磁盘设备，并使用vnconfig命令管理多个磁盘镜像文件或交换文件。

    除了伪磁盘设备vn之外，FreeBSD系统还提供一个将多个磁盘文件系统映射为一个磁盘的伪设备ccd，这样原有的小磁盘分区就能联合起来，形成一个大的文件系统。ccd要求内核中支持ccd这个伪设备，当内核中支持了cc
              d伪设备之后，就可以通过设备文件/dev/ccd0c等来使用这个伪磁盘了（缺省/dev下只有ccd0的设备文件，可以根据需要建立其他的设备文件）。

    将多个磁盘分区与单一的ccd设备联系起来，还需要使用ccdconfig进行配置，最基本的ccdconf
              ig使用例子为：

# ccdcofnig -c ccd1 0 0 /dev/da0s2g /dev/da1s2e

    这个例子使用-c参数对ccd1设备进行配置，指出ccd1由/dev/da0s2g和/dev/da1s2e两个分区联合组成。如果这两个磁盘分区都是100M大小，那么新的设备/dev/ccd1c就有200M大小。然后就可以在ccd1设备上建立文件系统，并使用这个设备了。

# newfs /dev/ccd1c

# mount /dev/ccd1c /mnt

    这是一个对ccd进行配置并使用的最简单的例子，这里没有对ccdconfig命令中紧跟ccd设备的两个数字参数的意义进行解释。而通过选择这两个参数的不同数值，能将多个磁盘文件系统采用不同的RAID方式映射为单个设备。

    RAID为冗余磁盘阵列的简称，它意味着物理上使用多个磁盘，而逻辑上却只有一个磁盘设备。RAID之所以流行，是因为它使用了分段（strip）和冗余的概念，就是说通过RAID映射的逻辑磁盘上的数据是以分段的方式保存的，例如一个文件的第一段数据保存在第一个物理磁盘上，第二段数据保存在第二个物理磁盘上，依次类推。这样在存取这一个文件上的连续数据时，多个磁盘可以同时进行存取操作，因此增加了磁盘访问速度。而冗余则是物理磁盘的空间大于逻辑磁盘的大小，通过物理磁盘上多余的磁盘空间，保存冗余信息，这样一旦多个磁盘中的某一些出现问题，数据能通过冗余数据得到恢复，而不会丢失。

    按照不同的冗余组织方式，RAID被分为不同的级别。最简单的RAID称为RAID 0，这个级别中没有冗余，多个磁盘只是以分段的方式组织起来，由于使用分段的方式存取，可以同时访问这两个磁盘，因此存取单个文件的速度会有所改善。更高一级的RAID级别为RAID
              1，它同时使用两个磁盘，每个磁盘都是另一个磁盘的镜像，这样一旦一个磁盘出现问题，还可以在另一个磁盘找到数据，保证了数据完整性，但这样设置，有一半的磁盘空间都用做了冗余，浪费了磁盘空间。此外还有RAID
              3级别，至少要使用3个物理磁盘，前两个磁盘中分段存储数据，第三个磁盘的冗余空间中并不是直接保存原有的数据，而是保存根据前两个磁盘中对应分段中的数据进行计算得到一个校验和。在前面某一个磁盘被破坏后能通过冗余磁盘中保存的校验和来恢复原有数据。由于RAID
              3中校验和是单独保存在一个物理磁盘上的，不能充分发挥分段存取的优势，因此RAID 5中将校验和与其他数据一起分段、分布保存在各个磁盘上，提供了更好冗余效果。因此当前常用的RAID级别为RAID
              0, RAID 1和RAID 5，可根据不同的需要进行选择使用。

    当在ccdconfig中使用两个0作为参数来设置ccd伪设备时，ccd是以最普通的直接连接方式来连接多个磁盘的，当数据写满第一个磁盘后，才接着写入第二个磁盘，这里没有使用任何分段存储策略，因此这是一种不完善的RA
              ID 0方式。然而也可以设置ccd以使用分段存储策略，以大来存取速度的优势，这就需要设置分段存储中的段的大小，即设置交错因子的大小，因此就需要改变第一个数字参数，例如：

# umount /mnt
# ccdconfig -u ccd1
# ccdconfig -c ccd1 32 0 /dev/da0s2e /dev/da1s2g

    上面第一条命令是卸载已安装的ccd文件系统，第二条命令是将原有的ccd1设备释放出来，使用这两条命令是因为前面操作中已经将ccd1设置过并安装到文件系统中了。第三条命令为重新设置ccd1的命令，其参数中紧随ccd
              1设备的参数设置为32，这个参数代表交错因子为32个磁盘块，即数据每隔32个磁盘块大小，进行分段保存到不同的磁盘上，显然前面的参数设置为0表示不进行分段存储。

    由于ccd使用的磁盘设备为预分配的磁盘分区空间，那么这些分区的大小很可能不一致。当一个磁盘设备用光，而另一个较大的设备还有空余的时候，分段策略就不再有效了。此时ccd可以有两种选择，一个是尽量利用磁盘空间，必要时不再进行分段存储，顺序存储数据；另一种选择是不使用这些不能进行分段存储的空间，以保证分段存储带来的优势。当cc
              d命令的第二个数字参数设置为0时，将尽量利用磁盘空间，因此就ccd伪设备就混合使用分段存储和顺序存储。但也可以将其设置为2，这样ccd只使用分段存储策略，忽略分区不一致的空间。推荐在建立磁盘文件系统时为ccd划分大致相等的空间，这样就可以充分利用分段带来的好处，并且不浪费磁盘空间。

    当使用分段存储之后，理论上在两个磁盘上同时分段存储，存取速度可以加快。这种速度的提高是针对单次数据存取而言的，例如在读取一个大文件时，ccd可以同时从两个磁盘读取。可以看出ccd所作只是改变数据存取的位置，通过将可能会同时访问的数据放置到可以同时访问的多个磁盘上，来提高存取速度。然而而由于ccd是使用软件方式实现的分段，软件方式不能提高磁盘I/O的硬件限制，而高负荷的服务器，同时会有多个进程对多个磁盘进行I/O操作，ccd的作用就不太明显了。此时使用硬件RAID的方式更为有效。

    FreeBSD支持DPT的硬件RAID卡，很多服务器附带的RAID卡均是OEM这家厂商的产品，虽然它们使用其他厂商的商标，但实质还是同一个厂家的产品。因此在使用RAID卡时，需要检查其手册或卡上的芯片标识，判断其是否为OEM产品，以获得RAID卡的真实型号。

    此外，还有一些SCSI-to-SCSI的RAID卡，因此只要该卡使用SCSI控制芯片为FreeBSD所支持，该卡就能在FreeBSD下使用。

    虽然ccd设备能够提高存取速度，但对于建立交换磁盘空间意义不大，一般也并没有必要将交换空间建立在ccd
              设备上。这是因为FreeBSD对交换设备本身也采用了交错存取的策略，如果在多个磁盘上设定了多个交换空间，系统会自动使用交错方式使用交换空间，而不必依赖ccd设备的帮助。

    对于IDE磁盘，尤其对于连接在同一条IDE线上的IDE磁盘，使用分段策略是无益的。因为同一条IDE总线上不能进行并发存取数据，分段存储反而影响速度。即使是连接在两个IDE总线上的两个IDE磁盘，由于IDE磁盘的存取十分占用CPU的处理时间，因此分段存储带来的益处也极为有限，只有SCSI磁盘才能充分发挥分段存储的带来的好处。

    ccd也支持RAID 1，这种方式又称为磁盘镜像方式，主要用于保护磁盘数据不会因为偶然损坏而丢失数据，但同时多使用一倍的磁盘空间。此时需要将ccdconfig中的第二个数字参数设置为4，它将强制使用相同大小的各个物理磁盘的空间并使用RAID
              1方式。当前的ccd还不支持RAID 5。

# ccdconfig -c ccd1 32 4 /dev/da0s2e /dev/da1s2g

    虽然ccd能够支持RAID 1，但通常并不使用它来进行RAID 1。主要原因是ccd并没有提供相应的软件工具，使得能够在系统出现问题时，能从镜像磁盘中恢复出数据。由于ccd设备和物理磁盘的存储格式存在差异，并不能直接安装上ccd镜像磁盘其中的一个，要恢复存储的数据就需要其他工具的帮助。由于ccd本身并没有提供这种工具，就只能依靠从原始磁盘上读取数据的方式恢复，就使得恢复数据比较困难，所以很少有使用者真正利用ccd来进行磁盘镜像。

    如果需要使用RAID 1以增强系统的可靠性，可以考虑使用vinum，这个软件使用一个内核可加载模块，能提供RAID
              0、RAID 1和RAID 5，但由于版权的原因（产生校验和的算法被其专利保护），其中的RAID 5代码没有被直接放入FreeBSD系统中，随同FreeBSD一起提供的vinum只提供RAID
              0和RAID 1能力。由于ccd用于RAID 0更容易，而vinum提供了相当完善的RAID 1功能，因此习惯上使用ccd来提供RAID
              0，而使用vinum提供RAID 1。具备RAID 5能力的vinum版本可以从Cybernet 公司获得(http://www.cybernet.com)，或者与vinum的开发者联系获得测试版。vinum
              是一个相当复杂的软件，这里就不再讨论其设置和使用方法了。

    当设置好ccd之后，就可以将其配置放入配置文件中。使用ccdconfig -g命令可以将当前的配置显示出来，把这些设置放入/etc/ccd.conf中之后，使用ccdconfig
              -C将直接读取这个设置文件，来设置ccd的各个设备，启动时也将自动执行这个设置任务。

# ccdconfig -g > /etc/ccd.conf

    由于ccdconfig及vinum会直接和内核中的伪设备交谈，因此使用它们具备一定的危险性,对它们进行设置时就有造成系统当机的可能性。因此进行设置不要运行其他进程，最好进入单用户状态进行操作，在设置完毕之后，系统就会正常运行了。如果在设置时连续出现当机问题，可以尝试改变设置时使用的ccd设备及其顺序，例如本来使用ccd0
              的改变为使用ccd1，再进行重新配置，以避开ccd驱动中可能存在的问题。

  • 非标准配置

    标准系统内核配置均列在配置文件LINT中，这对于绝大多数情况是足够的。然而很多新特性并没有包括在这些标准内核配置中，如果要使用这些独立特性，就需要单独安装这些非标准配置。

    在FreeBSD的开发模式中，可以有任意多个项目组，这些项目组开发的结果要合并到正式的FreeBSD源码中的时候，就必须被FreeBSD
              core team认可。与Linux的开发方式相比，这种方式较为保守。因此虽然FreeBSD中能够支持很多种特性，但很多都没有包括在FreeBSD的正式版本中。因此使用者要了解Free
              BSD具备的其他新特性，就必须检查标准配置之外的各种配置。今天的非标准配置，可能就是明天的标准配置。

    在FreeBSD的主页中，介绍了基于FreeBSD的各种商业和自由的开发计划，例如System
              V系统防真功能、实现IPv6和IPSec的KAME计划等。

    除了正在开发的功能之外，新特性不能被合并到标准配置中的另一个原因是版权原因，很多软件有较严格的版权声明，不能直接放到FreeBSD系统中。另一个原因是FreeBSD的核心小组认为这个特性没有太大的需求，不需要被支持。


FreeBSD连载(62)：升级系统

王波

升级系统

    通过CD-Rom或Internet能够很方便的获得FreeBSD的新版本，由于每一次版本升级都修正了原有版本中存在的问题，并增加了一些新特性。因此保持系统与最新版本相一致是十分有益的事情。

    升级内核的最直接想法是直接编译新内核，可以将新版本的内核展开到系统中的目录中，然后按照前面的步骤编译安装新内核。这个方法在同一版本分支中作子版本的升级十分方便，例如从FreeBSD 2.2.7release升级到 2.2.8release。如果要从2.2.x版本升级到3.x版本，由于升级了主版本号，基本系统有了较大改动，因此不仅要升级内核，还需要升级系统中的应用程序。此时一般应使用sysinstall中的Upgrade选项进行升级。

  • 使用源码升级系统

    除了使用sysinstall直接升级之外，另一种升级方法是从系统的源代码中升级系统。这要安装要升级版本的全部源码，从而能重新编译整个系统，包括系统内核和各个应用程序。可以通过下面的办法手工安装系统源码。

# cd /cdrom/src
# ./install.sh

    重新编译整个系统是一个漫长的时间，根据使用的系统硬件不同，将需要几个小时的时间或更长时间来完成这个任务。这个编译命令被称为
              “make world” ，表示重新编译构建整个FreeBSD系统。

# cd /usr/src
# make world

    如果是从2.2版本或3.0-release升级到3.1-stable，那么直接这样make
              world会遇到问题。主要原因是3.0-stable之后，系统的执行文件格式从原有的a.out转向了ELF（3.0-release的执行文件虽然是
              ELF格式的，但其内核还保持a.out格式）。make world就提示用户使用make upgrade进行升级，因此使用者就应该按照make
              world的提示进行操作：

# make upgrade

    其他的make目标有：

    buildworld：编译所有的源代码；

    installworld：安装buildworld编译产生的结果；

    world：执行buildworld和installworld，重新编译安装整个系统；

    aout-to-elf-build：编译从aout到elf升级系统所需的源代码；

    aout-to-elf-install：在aout-to-elf-build的基础上升级系统；

    aout-to-elf：依赖于aout-to-elf-build和aout-to-elf-install，进行a.out系统到elf系统的升级转换；

    update：进行系统升级，对于3.1-stable来讲即包括aout-to-elf；

    reinstall：在以前已经编译好的基础上，不重新编译而再次安装编译产生的结果；

    当使用源代码的方式重新编译系统时，由于需要使用编译工具和这些工具的缺省设置，这些工具就需要预先更新。编译工具一般不需要升级，但编译工具的设置常常需要更新。当更新所有的源代码时，就不存在这个问题，但如果只是更新部分源代码，就会出现这个问题。如果不打算更新所有的源代码，可以通过预安装的一个很小的系统升级软件包来解决编译工具设置更新问题。例如需要更新Ports
              Collectin，但不打算更新全部源代码（从3.1-release升级到 3.1-stable），就需要安装31Upgrade.tgz。

  • 使用CVSup维护系统源码

    FreeBSD的源代码可以从安装介质上或从网络上下载得到。然而FreeBSD的开发是非常活跃的，系统更新速度相当迅速，只有通过网络更新，才能保持源代码和其他FreeBSD使用者和开发者一致。但如果每次系统更新都从网络下载全部源代码，不仅浪费了网络带宽，而且也没有必要，因为系统中的绝大部分代码并不会更新，每次系统升级更新的只是其中很小的一部分。FreeBSD的全部源代码相当大，尤其对于慢速Internet连接的使用者，下载一次并不是一件简单的任务。所以需要一种方法，使用户每次都只需要下载源代码的更改部分。

    软件开发中的版本维护工具是一种维护同一个软件的不同版本的方法，程序员可以通过这个工具同时维护不同的软件版本。但虽然版本维护工具同时维护多个版本，但并不是将这些版本都独立保存一份，而只是保存一个基本版本及其他版本与它的差异。因此，基于这种版本维护工具的方式，FreeBSD就提供了更新部分源代码的方法，使得用户每次只需要下载更改过数据，这样使用者就能通过Internet与FreeBSD源代码树保持一致，保持最新版本的源代码，并节约了网络带宽。

    为了维护FreeBSD的源代码树，需要一个版本控制软件包CVSup和用于维护源代码的300M硬盘空间。

    FreeBSD的所有源代码本来就是通过CVS（Concurrent Versions
              System）版本维护系统进行维护的，所有的使用者都能读取同样的源代码，但只有FreeBSD的开发者能够更改这些源代码，这样就保持了FreeBSD源代码的一致性。

    为了使用CVSup，首先要安装这个应用软件。这个软件被收录在Packages Collection中，因此安装非常容易。可以使用pkg_add来完成这个任务：

# pkg_add cvsup-bin-16.0.tar.gz

    安装好CVSup软件之后，下一步就是配置一个配置文件，告诉cvsup从哪个服务器上同步源代码树，以及同步哪些源代码。在安装CVSup的时候，还将安装cvsup的配置文件例子到/usr/share/examples/cvsup
              目录下。

$ ls /usr/share/examples/cvsup
README           ports-supfile           secure-supfile
cvs-supfile      secure-cvs-supfile      stable-supfile
gnats-supfile    secure-stable-supfile   standard-supfile

    这个目录下的每个文件都用于一个特定目的，用来同步某个源代码树。其中standard-supfile用于同步FreeBSD
              -current分支的源代码树，stable-supfile用于同步FreeBSD -stable分支的源代码树， ports-supfile用于同步Ports
              Collection的源代码，等等。通常这些例子文件中需要修改的只是需要连接的cvsup服务器的名字，例如一个用于同步3.1-stable的配置文件supfile如下，这个文件是根据stable-supfile
              生成的，仅仅修改了host的设置，以指向正确的主机。

*tag=RELENG_3_1
*default host=cvsup.FreeBSD.org
*default prefix=/usr
*default base=/usr/src/cvsup
*default release=cvs delete use-rel-suffix compress
src-all

    配置文件中使用tag的值用来标识要同步的不同源代码树。FreeBSD有多个版本，可以根据使用者的选择来获得不同的版本的源代码。最常用的源代码是
              -current分支的源代码和-stable分支的源代码，通常对于- current分支的源代码，需要设定 “tag=.” ，而stable分支就要指定版本号，这里为RELENG_
              3_1（或者使用RELENG_3表示3.x分支中的最新版本）。

    host的值用于指明用于同步源代码的服务器的名字，出于速度的考虑，最好使用离用户最近的CVSup服务器。

    base指明用于放置cvsup的状态文件的目录，prefix指明用于放最终的源代码文件的目录。由于最终的源代码和cvsup均要占用大量的磁盘空间，因此需要注意为其留下足够的空间。

    release指明源代码树是使用cvs进行版本维护的，后面为从服务器上传输源代码及处理本地文件时使用的参数。

    src-all用于同步所有的源代码，为了节约磁盘空间和同步时间，可以只同步部分源代码。配置文件中给出了同步部分源代码的配置情况，但被注释了。需要使用#符号将src-all注释掉，指明其他要同步的源代码，如port
              s-all。

    如果这个配置文件名为stable-supfile，那么就能使用下列命令启动cvsup：

# cvsup -L2 stable-supfile

    参数-L2标识使用第2级记录方式在屏幕上打印出cvsup同步源代码的同步过程，如果系统位于防火墙内，会需要-P
              m参数以使用被动方式越过防火墙。

# cvsup -P m stable-supfile

    cvsup可以在X Window下运行，此时它使用图形界面。

    通常对于不太经常更新系统的管理员来讲，手工启动cvsup来更新系统源代码就够用了，如果要经常更新源代码，就需要将cvsup命令放入crontab中执行。

    除了cvsup，FreeBSD也可以通过Email来提供源代码同步，这种方式称为CTM，与cvsup不同在于，cvsup
              必须由本地系统启动以从远端下载，CTM是由远端服务器发送回来的。CTM对于网络连接比较慢，或只能通过Email 访问Internet的系统最方便，对于与Internet直接相连的系统，一般不需要使用CTM。

    由于使用了cvsup，所有的FreeBSD用户和开发者都能访问同一个源代码树，这样就维护了系统的一致性，就使得只存在一个单一的FreeBSD系统，不致造成不同的版本混乱。


FreeBSD连载(63)：集成Unix和Windows的方式

王波

第7章 与Windows系统集成

    在局域网中，由于Windows是为最流行的桌面操作系统，它使用的网络协议也占据重要地位。而 FreeBSD性能非常优秀，除了被用做Internet/Intranet服务器之外，使用者也希望它能用做文件/打印等传统的局域网服务器，为局域网内（或高速连接的网络之间）的客户计算机提供文件和打印服务。因而将FreeBSD和Windows 系统这两种不同的操作系统在同一个网络上相互，就成为一件很有意义的事情。

    将FreeBSD和Windows系统进行集成有几种不同的方式，一种为设置Windows系统，使其遵从 Unix中的标准方式访问FreeBSD服务器，或者在Windows NT服务器安装网关软件，使其成为在 FreeBSD相应服务和Windows相应服务之间进行转换的网关。此外也能配置FreeBSD支持MS Windows下的标准协议，与Windows系统相互通信。

  • 集成Unix和Windows的方式

    TCP/IP协议族中提供了多种标准的程序，能让支持TCP/IP的计算机进行互连。Windows系列的计算机同样也支持TCP/IP协议及其中一些常用的应用程序，例如远程登录程序telnet，文件传输程序ftp等，使用这些应用程序能实现异种系统互连的基本方式。如果要使用这些最基本程序功能之外的功能，例如文件和打印资源的共享，就必须使用其他软件来达到目的了。

    为了让Windows计算机以最常见的文件共享等方式使用Unix上的资源，Unix计算机必须提供相应的文件共享服务。Unix之间共享文件系统的协议为NFS，然而由于个人计算机上没有严格意义上的用户和权限的概念，因此 Unix不能信任个人计算机上的使用者，而需要对用户进行验证，这就需要pcnfsd提供的认证和共享能力。Dos/Windows 系统可以安装pcnfsd的客户程序，来访问Unix系统上的资源。

    在FreeBSD上安装pcnfsd非常容易，可以使用sysinstall安装程序中的Networkin g菜单中的选项来安装pcnfsd，也可以直接通过Packages Collection来安装它。pcnfsd软件将在/usr/local/libexec下安装一个rpc.pcnfsd程序，如果Unix被配置为nfs服务器，那么rpc.pcnfsd就能为pcnfs客户机提供认证及共享服务，客户能通过它使用Unix系统上的文件和打印资源。

    Sun和其他开发者提供了几种pcnfs的客户程序，然而由于pcnfs在个人计算机领域并没有得到大家的认可，使用它的网络很少。因而pcnfs也就没有得到进一步发展，当前已经成为了一种过时的技术，因此不推荐使用pcnfs 来集成Windows和Unix。

    Windows系统也能够通过Windows NT作应用网关，使用Unix上的资源，这方面的一个例子是Windows NT 系统中支持的TCP/IP网络打印服务，由于这个服务可以支持LPD协议，因此Windows NT 也能作为一个打印机网关，将其他Windows客户的打印请求转换为lpd请求，发送给Unix计算机，或者从Unix 上打印到Windows NT计算机上。然而，应用网关是一种单独的软件，必须具备一种应用网关软件才能集成一种网络服务，因此除了打印服务之外，并不存在其他种类的应用网关系统。

    通过配置Windows计算机与Unix进行集成的方法，对Windows客户并不是最方便的方式。原因之一是由于Windows计算机之间的互连更为常见，所以Windows方式在个人计算机用户中占据主流，而另一个更为重要的原因是用户的问题，要让多数不熟悉Unix系统的Windows使用者以Unix的方式访问Unix系统资源，困难就相当大。而与此相比，Unix系统管理员一般都具备Unix和Windows的丰富经验，并了解各种网络协议，这样就能在Unix计算机上安装支持Windows网络系统的软件，而众多Windows系统用户不需其他额外配置就能使用Unix系统的资源了。显然这种方式能够利用Windows系统现有软件的友好界面，又能利用Unix系统的强大功能，并且不需要Windows用户进行额外的设置，因此就成为了集成Windows和Unix的最流行的方式。


FreeBSD连载(64)：NetBIOS名字解析
王波

NetBIOS与SMB/CIFS协议

    在个人计算机和局域网发展的早期，为了在个人计算机上实现网络能力，Microsoft和IBM合作开发了一套协议NetBIOS，这是一套用于网络通讯的调用接口，开发者IBM认为这套协议将如同它们设计的计算机BIOS一样成为最基本的网络访问接口，因此使用了NetBIOS这个名字。而Microsoft就使用NetBIOS接口开发网络服务器及相应的客户软件。

    然后IBM在Token Ring和Ethernet上直接实现了NetBIOS驱动，实现了位于NetBIOS 和物理网络层之间的各种具体接口，这些程序遵循的标准被称为NetBEUI。NetBEUI直接控制Token Ring和Ethernet驱动程序，因此它只能运行在局域网上。但是NetBIOS本身并没有对下层使用的协议进行限制，因此它除了可以在NetBEUI支持下运行之外，也可以在其他协议支持下运行。其他的网络开发者在另外的一些协议的基础上也实现了NetBIOS接口，例如TCP/IP，IPX以及Decnet等。其中NetBIOS over IP由于使用TCP/IP协议，因而在低层与Unix计算机相容，成为Unix和个人计算机系统通信的基础。

    Windows系列计算机并不一定使用IP作它的网络传输协议，它也能使用IPX或NetBEUI作传输协议，但是FreeBSD不支持IPX或NetBEUI上的NetBIOS，必须为Windows客户配置IP协议，才能与FreeBSD相互共享资源。

  • NetBIOS名字解析

    由于NetBIOS事实上是一种与TCP/IP独立发展的标准，虽然它可以使用TCP/IP作为传输协议，但是由于概念上的不同，它并没有利用TCP/IP提供的全部能力，而是使用自己的方式来完成类似的工作。其中最大的区别就在于名字解析方式上，NetBIOS具备自己独立的名字解析概念和能力，因此它使用的名字解析方式就与TCP/IP 中标准解析方式 ── DNS不同。在必须经过NetBIOS名字解析获得了一台命名相应的IP地址之后，NetBIOS 会话就可以建立在普通TCP连接的基础上了。因此在NetBIOS中，名字解析是NetBIOS会话与普通TCP 连接最大的不同之处。

    NetBIOS名字解析与DNS名字解析的最大不同在于NetBIOS是动态的，计算机需要首先注册自己的名字，然后才能解析到该名字。动态解析虽然带来的很大的方便性，但却复杂和低效的多，因此只能用于小范围的局域网上。

    每个NetBIOS的名字可以多达16个字符，第16个字符用来标识输入名字时使用的程序类型。当NetBIOS 的计算机进行通信时，它必须基于NetBIOS名字，而不能基于IP地址。一个NetBIOS服务程序必须首先注册自己的NetBIOS名字，而一个应用程序则需要查询所需要的NetBIOS名字。例如每台Windows计算机在启动之后初始化网络时就使用所配置的计算机名字来初始化其使用的NetBIOS名字。

  • NetBIOS名字解析方式

    从NetBIOS名字查找相应的节点地址（TCP/IP协议中为IP地址）有几种不同的查找方式。

  • 本地广播： 在本地网络上发送广播，通过广播某设备的NetBIOS名字，查找其对应的IP地址。广播方式也能用于注册自己的NetBIOS名字，例如一台计算机可以通过广播本机的名字，向其他计算机宣告自己使用了这个NetBIOS名字。

  • 缓冲： 每个支持NetBIOS的计算机中，维护一个NetBIOS名字和相应IP地址的列表，这些对应的名字都有一定的生存期，以便能及时更新。

  • NetBIOS名字服务器：使用一个名字服务器来提供名字与IP之间的解析任务，这个NetBIOS 名字服务器被称为NBNS（NetBIOS Name Server），Miscrosoft实现的NBNS名字服务器为WINS（Windows Internet Name Service）。NetBIOS计算机首先要向NBN S登记自己的NetBIOS名字，完成名字的注册过程。

  • 预定义文件lmhosts：Microsoft Windows能通过查找存放在本地文件lmhos ts中的数据，来识别网络上NetBIOS名字和IP的关系，这个方式不是NetBIOS名字识别的标准，但它是Microsoft 的实现方式，因此是一种事实标准。

  • 通过DNS和hosts文件解析：DNS服务器和本地hosts文件中存放的数据是用于标准TCP/IP 协议中名字和IP之间转换使用的方式，但使用其他方式查找不出对应的节点地址时，Microsft Window s中通常也能通过标准的TCP/IP名字解析方式，进行名字和IP的转换。同样这也不是NetBIOS的标准，而是Micorsoft 的扩展。

        从这五种NetBIOS识别方式，以及其中的不同的名字注册方式出发，进行不同的组合方式，就构成不同的名字识别策略。在NetBIOS标准中，将使用不同名字识别策略的模式称为不同的NetBIOS节点类型。

        B-node：通过广播方式来进行注册和进行识别NetBIOS名字。对于IP协议上的Net BIOS，就需要基于UDP进行广播，在小网络上这种方式工作得很好，但当网络增大时，就会被使用路由器将大网络分割为几个小网。在一般情况下路由器不转发广播数据，广播包仅发送到本地网络。虽然可以配置路由器进行b-node广播转发，但是这将使UDP广播产生大量的无用网络数据，且名字注册和解析的难度也增加了。因此对于较大的网络，这种方式不可取。

        P-node（peer-to-peer）：对等方式能为识别名字提供非常有效的方法，它使用 NetBIOS名字服务器进行名字的注册登记和名字识别。因此对于每个NetBIOS计算机，必须指定同样的NBNS 服务器的IP地址。这样在NBNS服务器停机或更改了设置（如IP地址等情况）的情况下，名字解析不能完成，就不能进行NetBIOS通信。当然NetBIOS计算机可以配置为使用多个NBNS服务器，以便在其中一个出现问题时使用备份的服务器。

        M-node（Mixed）：为了正确解析NetBIOS名字，最好综合使用广播和名字服务器的方式，这样的名字识别是一个复合的过程。M-node首先通过B-node广播方式进行名字识别过程，当广播方式失败之后，再使用P-node方式进行查询。

        H-Node（Hybrid）：H-node模式也是一种复合模式，它与M-node不同的地方是查找的顺序不同。H-node先查找NBNS名字服务器，然后再使用广播方式进行查询。

        Windows中实际使用的名字识别方式是对标准H-node方式的扩展，Windows系列的计算机将首先检查缓存中的内容，然后再查看WINS服务器，之后进行广播，然后将查找lmhosts文件，以及通过hosts和DNS 进行查找。实际进行NetBIOS识别是一个复杂的过程，主要就是由于NetBIOS是一个动态的名字解析方式，每一台计算机都必须注册自身。

    • NetBIOS名字识别的过程

        与DNS不同，NetBIOS名字使用动态方式进行管理。DNS数据是静态的，增加和删除DNS名字需要管理员手工更改配置文件。但NetBIOS要求计算机在网络上自动注册其名字，计算机停机之后占用的名字会被释放，这个过程不需要管理员干预。因为它需要额外的网络数据以完成名字登记等过程，使得它不适合象Internet这样的大型网络。NetBIOS名字识别需要三个步骤：

        名字注册：在NetBIOS启动时，计算机向整个网络声明占用了一个NetBIOS名字，如果已经有其他计算机占用了这个名字，这个计算机就会收到错误信息。注册是通过向网络广播声明信息或向NetBIOS名字服务器登记的方式来实现的。

        名字解析：通过广播或查询NetBIOS名字服务器来解析一个NetBIOS名字。此外还可以通过lmhosts 文件和DNS辅助解析名字。

        名字删除：在系统关机或提供的工作站服务结束时，会删除其占用的NetBIOS名。

        通过NetBIOS名字和共享的目录名，就能够定位Windows计算机上的资源。Microsoft使用U NC的形式来确定一个网络资源的位置，一个UNC以双反斜线开始，接下来是提供资源计算机的NetBIOS名字，然后是该台计算机上提供资源的共享名，接下来就是下面的目录和文件名。如：\\ntserver\share\files ，因此使用一个资源的命令为：

    C:\> net use f: \\ntserver\share
C:\> f:
F:\>

        上面的net use命令将ntserver上的share资源映射为F:盘。

    • 名字服务器的工作原理

      •

        由于b-node广播会在网络上产生大量的信息流，尤其是在网络是由多个子网构成的时候，而使用路由器本来就是要隔离广播信息，可是为了进行名字解析，就不得不转发b-node广播信息包，这就达不到缩减无用网络流量的目的。

        使用名字服务器进行解析就能避免这个问题，客户通过对名字服务器进行查询而非广播，信息流就不必传播到各个子网上，就能减少广播数据，减轻网络的负担节省带宽，并且能有效的提高名字解析的速度及准确性。

        实际存在的Windows网络甚至很少利用名字服务器进行名字解析，这就使得这些网络名字解析存在很大问题，常常会出现不同计算机的网络邻居列表不同，根本原因就是广播方式是没有保证的，必须转向名字服务器方式才能解决名字解析问题。

        普通NetBIOS计算机和NBNS服务器进行通信有四个不同的通信过程：

        名字注册：每台NetBIOS计算机启动时，都在名字服务器上注册。这样就保持了数据库的自动更新，并具备动态更新的特性。名字服务器将返回确认信息，以及这个名字的生存期TTL。如果客户要求的名字已经被占用了，服务器就查询占用这个名字的客户是否还在网络上，以判断这个名字是否可以再次被使用。这种情况主要发生在Windows计算机死机后重新登记的过程中，因为此时在计算机死机之前，它在名字服务器中登记的名字还存在，如果名字服务器简单的拒绝提供名字，那么这个计算机就无法再次获得自己的名字。只有在真正发生冲突的情况下，客户的名字注册才会失败。

        名字更新：由于每个名字都存在一个生存期TTL，那么当经历了这个TTL一半的时间，客户会向服务器进行更新请求，刷新服务器上的TTL设置。

        名字释放：客户停机时会与服务器通信释放其占用的NetBIOS名字，其名字TTL超时也会使得服务器释放这个名字。

        名字识别：客户可以向NBNS服务器发送查询名字的请求，进行名字解析。

        有些情况下，客户没有设置支持名字服务器，或者使用的客户软件还不支持名字服务器进行解析，可以通过设置一个
                  WINS代理，由它来在广播数据和查询名字服务器之间进行转换，它可以帮助客户注册并回应客户的广播查询。

    •


FreeBSD连载(65)：SMB/CIFS协议
王波

SMB/CIFS协议

    在NetBIOS出现之后，Microsoft就使用NetBIOS实现了一个网络文件/打印服务系统，这个系统基于NetBIOS设定了一套文件共享协议，Microsoft称之为SMB（Server Message Block）协议。这个协议被Microsoft用于它们Lan Manager和Windows NT服务器系统中，而Windows系统均包括这个协议的客户软件，因而这个协议在局域网系统中影响很大。

    随着Internet的流行，Microsoft希望将这个协议扩展到Internet上去，成为Inter net上计算机之间相互共享数据的一种标准。因此它将原有的几乎没有多少技术文档的SMB协议进行整理，重新命名为 CIFS（Common Internet File System），并打算将它与NetBIOS相脱离，试图使它成为Internet上的一个标准协议。

    因此，为了让Windows和Unix计算机相集成，最好的办法即是在Unix中安装支持SMB/CIFS协议的软件，这样Windows客户就不需要更改设置，就能如同使用Windows NT服务器一样，使用Unix计算机上的资源了。

    与其他标准的TCP/IP协议不同，SMB协议是一种复杂的协议，因为随着Windows计算机的开发，越来越多的功能被加入到协议中去了，很难区分哪些概念和功能应该属于Windows操作系统本身，哪些概念应该属于SMB 协议。其他网络协议由于是先有协议，实现相关的软件，因此结构上就清晰简洁一些，而SMB协议一直是与Microsoft 的操作系统混在一起进行开发的，因此协议中就包含了大量的Windows系统中的概念。

  • 浏览

    在SMB协议中，计算机为了访问网络资源，就需要了解网络上存在的资源列表（例如在Windows下使用网络邻居查看可以访问的计算机），这个机制就被称为浏览（Browsing）。虽然SMB协议中经常使用广播的方式，但如果每次都使用广播的方式了解当前的网络资源（包括提供服务的计算机和各个计算机上的服务资源），就需要消耗大量的网络资源和浪费较长的查找时间，因此最好在网络中维护一个网络资源的列表，以方便查找网络资源。只有必要的时候，才重新查找资源，例如使用Windows下的查找计算机功能。

    但没有必要每个计算机都维护整个资源列表，维护网络中当前资源列表的任务由网络上的几个特殊计算机完成的，这些计算机被称为Browser，这些Browser通过记录广播数据或查询名字服务器来记录网络上的各种资源。

    Browser并不是事先指定的计算机，而是在普通计算机之间通过自动进行的推举产生的。不同的计算机可以按照其提供服务的能力，设置在推举时具备的不同权重。为了保证一个Browser停机时网络浏览仍然正常，网络中常常存在多个Browser，一个为主Browser（Master Browser），其他的为备份Browser。

  • 工作组和域

    工作组和域这两个概念在进行浏览时具备同样的用处，都是用于区分并维护同一组浏览数据的多个计算机。事实上他们的不同在于认证方式上，工作组中每台计算机都基本上是独立的，独立对客户访问进行认证，而域中将存在一个（或几个）域控制器，保存对整个域中都有效的认证信息，包括用户的认证信息以及域内成员计算机的认证信息。浏览数据的时候，并不需要认证信息，Microsoft将工作组扩展为域，只是为了形成一种分级的目录结构，将原有的浏览和目录服务相结合，以扩大Mircrosoft网络服务范围的一种策略。

    工作组和域都可以跨越多个子网，因此网络中就存在两种Browser，一种为Domain Master Browser ，用于维护整个工作组或域内的浏览数据，另一种为Local Master Browser，用于维护本子网内的浏览数据，它和Domain Master Browser通信以获得所有的可浏览数据。划分这两种Browser 主要是由于浏览数据依赖于本地网广播来获得资源列表，不同子网之间只能通过浏览器之间的交流能力，才能互相交换资源列表。

    但是，为了浏览多个子网的资源，必须使用NBNS名字服务器的解析方式，没有NBNS的帮助，计算机将不能获得子网外计算机的NetBIOS名字。Local Master Browser也需要查询NetBIOS名字服务器以获得Domain Master Browser的名字，以相互交换网络资源信息。

    由于域控制器在域内的特殊性，因此域控制器倾向于被用做Browser，主域控制器应该被用作Domain Master Browser，他们在推举时设置的权重较大。

  • 认证方式

    在Windows 9x系统中，习惯上使用共享级认证的方式互相共享资源，主要原因是在这些Windows系统上不能提供真正的多用户能力。一个共享级认证的资源只有一个口令与其相联系，而没有用户数据。这个想法是适合于一小组人员相互共享很少的文件资源的情况下，一旦需要共享的资源变多，需要进行的限制复杂化，那么针对每个共享资源都设置一个口令的做法就不再合适了。

    因此对于大型网络来讲，更适合的方式是用户级的认证方式，区分并认证每个访问的用户，并通过对不同用户分配权限的方式共享资源。对于工作组方式的计算机，认证用户是通过本机完成的，而域中的计算机能通过域控制器进行认证。当 Windows计算机通过域控制器的认证时，它可以根据设置执行域控制器上的相应用户的登录脚本并桌面环境描述文件。

  • 共享资源

    每个SMB服务器能对外提供文件或打印服务，每个共享资源需要被给予一个共享名，这个名字将显示在这个服务器的资源列表中。然而，如果一个资源的名字的最后一个字母为$，则这个名字就为隐藏名字，不能直接表现在浏览列表中，而只能通过直接访问这个名字来进行访问。

    在SMB协议中，为了获得服务器提供的资源列表，必须使用一个隐藏的资源名字IPC$来访问服务器，否则客户无法获得系统资源的列表。


FreeBSD连载(66)：安装samba
王波

配置和使用Samba

    FreeBSD下实现SMB/CIFS协议的软件为samba ── 一个可以运行在很多种Unix系统中的著名自由软件，它使得Unix对外如同一个Lan Manager服务器，向Windows客户提供文件和打印服务。 Samba的当前版本为2.0，在FreeBSD下可以通过Packages Collection或Ports Collection进行安装。

    samba的主页为http://samba.org，包括有大量samba的资源。

    虽然SMB协议主要用于Microsoft网络，但samba的出现与其无关。它是作者Andrew Tridgell 试图在一台Sun工作站上完成DEC Pathworks功能的尝试，以完成他的其他研究工作。Pathworks 是另一个基于SMB的服务器。那时Andrew Tridgell对SMB和NetBIOS一无所知，但通过分析DOS客户端和Pathworks的行为，他完成了Samba的最初版本。此后随着越来越多的人加入Samba的开发，Microsft也公开了SMB的文档，Samba也越来越完善。使用Samba的使用者一般都会使用过Windows NT等其他SMB服务器，根据他们的经验，Samba服务器的性能要超过其他的各种SMB服务器，包括Windows NT。

    samba软件的主要组成部分有：

    smbd：这就是samba的SMB服务器，它使用SMB协议与客户连接，完成事实上的用户认证、权限管理和文件共享任务；

    nmbd：提供NetBIOS名字服务的守护进程，可以帮助客户定位服务器和域，如同Windows NT上的WINS服务器；

    smb.conf：是samba的配置文件，在FreeBSD中它被放在/usr/local/etc目录中。

    swat：是一个Samba专用的WWW服务器，用于通过客户浏览器配置samba，提供了对Samba的图形配置界面；

    smbclient：是一个简单的SMB客户程序，用于访问其他SMB计算机共享的文件或打印资源，例如Windows95 或NT计算机，它的操作和ftp类似。

    smbprint：一个shell脚本，它使用smbclient向Windows计算机上共享出的打印机上发送要打印的文档。

    nmblookup：用于查询NetBIOS名字的命令行工具。

  • 安装samba

当使用Packages Collection安装了Samba之后，将自动安装一个启动脚本samba.sh.sample到/usr/local/etc/rc.d目录中，可以将其更名为samba.sh，用于计算机启动时自动启动samba服务器smbd和nmbd。但要启动samba，还需要更改/usr/local/etc/目录下的配置文件smb.conf，安装程序将自动安装一个样例文件smb.conf.default，可以将其复制为smb.conf文件，然后再进行修改。

# pkg_add samab-2.0.2.tgz
# cd /usr/local/etc
# cp smb.conf.default smb.conf
# cd rc.d
# cp samba.sh.sample samba.sh
# sh samba.sh
Samba

    为了正常使用samba，必须对smb.conf进行配置，可以直接编辑配置文件，或者使用图形设置界面进行设置。由于samba是一个非常流行的SMB服务器，因此存在多种图形界面的配置程序，samba2.0本身提供的
              swat就是其中的一种，它作为一个Web服务器，可以通过WWW浏览器来配置smb.conf。但是即使能通过图形界面进行设置，但手工编辑smb.conf仍然是最基本的设置方式。

    如同上面的执行命令中所显示的，缺省的smb.conf就正常启动samba服务器，只是缺省配置并不一定适合用户的具体设置情况。例如域（或工作组）名字缺省为MYGROUP，而实际网络中则不一定使用这个名字。下面的命令使用Samba提供的smbclient客户程序，查看缺省smb.conf启动的samba服务器的设置。

# smbclient -L localhost -U%
Added interface ip=202.102.245.60 bcast=202.102.245.255 nmask=255.255.255.0
Domain=[MYGROUP] OS=[Unix] Server=[Samba 2.0.2]

        Sharename      Type      Comment
        ---------      ----      -------
        IPC$           IPC       IPC Service (Samba Server)
        ascii          Printer   lj5gray-a4-ascii-mono
        lp2            Printer   lj5gray-a4-auto-mono
        lj5gray-a4-ra  Printer   lj5gray auto raw
        wb             Disk      Home Directories

        Server               Comment
        ---------            -------
        fbsdsrv              Samba Server

        Workgroup            Master
        ---------            -------
        MYGROUP

    从这个输出结果可以看出，缺省使用的工作组为MYGROUP，提供共享的资源有IPC$，用户个人目录wb，以及系统中存在的多个打印机资源。samba使用计算机的hostname生成它NetBIOS名字fbsdsrv。

    最一般的情况下，只需要将工作组名字改动为与具体网络使用的名字相一致，就能使得使用Windows计算机的客户正常访问samba服务器了，用户在登录Windows的时候，使用自己在samba所在的Unix服务器上的用户名和口令登录，那么就可以访问samba服务器上自己的个人目录及打印机资源了。

    FreeBSD将Samba的文档安装到/usr/local/share/doc/samba目录下，一些设置文件的例子被安装到/usr/local/share/examples/samba目录下，这些文档和例子对于理解SMB协议，正确设置Samba都是非常重要的参考资料。

  • 启动samba方式

    •

启动samba的基本方法是使用Package中提供的shell程序 ── 安装在/usr/local/etc/rc.d目录下的samba.sh。这个程序将会以守护进程的方式启动smbd和nmbd两个守护进程（启动时使用-D参数）。这样在计算机启动时就能自动启动samba服务器。

除了直接启动之外，还可以使用超级服务器inetd来启动samba，这时inetd.conf中应该包括以下行：

netbios-ssn    stream    tcp  nowait  	root /usr/local/sbin/smbd     smbd

netbios-ns     dgram     udp  wait 		root /usr/local/sbin/nmbd     nmbd

    其中netbios-ssn和netbios-ns是在/etc/services中定义的两个用于NetBIOS
              的端口，一个用于NetBIOS会话管理，一个用于NetBIOS名字解析。当这两个端口就被inetd占据之后，使用上面启动脚本或直接启动smbd和nmbd就无法成功。但由于inetd效率较低，启动服务器较慢，这种配置只适合偶尔共享自己的文件的计算机，不适合会被频繁访问的文件/打印服务器。

    当使用samba.sh启动samba之后（或者使用inetd来启动samba），就可以从Windows
              客户机的网络邻居中发现这个FreeBSD服务器。或者使用net use命令直接访问服务器。

    由于一般在Windows中没有配置WINS服务器，那么就可能会出现名字解析的问题。为了帮助进行名字解析，可以在Windows的lmhosts文件中增加samba服务器的NetBIOS名字和IP配置，帮助Windows
              解析名字。或者使用samba作为NBNS服务器。

    samba在/var/log下留下了大量的访问日志文件，日志文件的名字在smb.conf中定义。通常日志文件以log开头，以用户名或计算机的NetBIOS为后缀，例如一台计算机NetBIOS名字为cca，那么它访问这台服务器的日志文件就为log.cca。


FreeBSD连载(67)：配置samba

王波

配置samba

    虽然缺省情况已经适合大部分用户访问自己在服务器上的个人目录的要求，但是为了充分发挥samba提供的功能，与这些复杂多样的Windows网络相适应，就必须更改smb.conf的设置。以提供更多的共享设置、服务器设置，以及用于支持包括比较简单的共享方式和复杂的域认证方式在内的认证方式。

    smb.conf中的语法非常简单，整个配置文件分为多个不同的部分，每个部分具有一个标题。使用方括号将标题引起来，标题下包括一些相关设置，每一行都用于一个相关设置。设置文件中的每个部分或者定义了一个共享资源的名字，或者设置了一组参数。以下以缺省smb.conf为例，介绍smb.conf中的相关设置。

  • [global]设置

# This is the main Samba configuration file. You should read the
# smb.conf(5) manual page in order to understand the options listed
# here. Samba has a huge number of configurable options (perhaps too
# many!) most of which are not shown in this example
#
# Any line which starts with a ; (semi-colon) or a # (hash)
# is a comment and is ignored. In this example we will use a #
# for commentry and a ; for parts of the config file that you
# may wish to enable
#
# NOTE: Whenever you modify this file you should run the command "testparm"
# to check that you have not many any basic syntactic errors.
#
#======================= Global Settings =====================================
[global]

    [global]部分定义了服务器本身使用的配置参数，以及其他共享资源部分使用的缺省配置参数，因此相当重要。

# workgroup = NT-Domain-Name or Workgroup-Name, eg: REDHAT4
   workgroup = MYGROUP

    工作组设置本地网络使用工作组名字（或者是NT域名字），这对于将正确进行浏览数据中非常重要。否则，Windows客户就不能从其网络邻居中发现这个Samba服务器。

# server string is the equivalent of the NT Description field
   server string = Samba Server

    server string是对于本地服务器的简单描述，这些信息将作为这台服务器的属性，返回给Browser，显示在Windows客户中作为对这个服务器的描述。

# This option is important for security. It allows you to restrict
# connections to machines which are on your local network. The
# following example restricts access to two C class networks and
# the "loopback" interface. For more examples of the syntax see
# the smb.conf man page
;   hosts allow = 192.168.1. 192.168.2. 127.

    hosts allow参数用于限制可以访问这台samba服务器的客户机的IP地址范围，通过指定一系列网络地址，使得只有这些网络中的计算机才能访问这台服务器提供的资源，以提供安全限制。缺省情况下，这行配置被注释了，使得所有的客户都可以访问这台计算机，这样就存在一定的安全问题。

# If you want to automatically load your printer list rather
# than setting them up individually then you'll need this
   load printers = yes

# you may wish to override the location of the printcap file
;   printcap name = /etc/printcap

# on SystemV system setting printcap name to lpstat should allow
# you to automatically obtain a printer list from the SystemV spool
# system
;   printcap name = lpstat

# It should not be necessary to specify the print system type unless
# it is non-standard. Currently supported print systems include:
# bsd, sysv, plp, lprng, aix, hpux, qnx
;   printing = bsd

    这些设置是用于设置samba服务器的打印机资源，load printer=yes就允许samba服务器对外共享服务器的打印机。由于不同的Unix系统中会使用不同的打印系统和不同的打印设置文件，因此需要设置正确的
              printcap和printing类型，对于使用BSD打印系统的FreeBSD来讲，打印系统为BSD，使用的设置文件为 printcap，这些是缺省设置，不需要改动。对于使用Unix
              System V打印系统的Samba，则需要重新进行设置。

# Uncomment this if you want a guest account, you must add this to /etc/passwd
# otherwise the user "nobody" is used
;  guest account = pcguest

    由于Mircrosoft客户没有用户的概念，因此有时会用没有用户和口令的请求访问服务器，就需要将这个没有用户的请求映射为系统中的某个用户，Samba服务器才能安全的访问系统。guest
              account 就定义这样的请求在Unix下对应的用户权限。为了安全的原因，不能让这个帐户在系统中有可写的权限，通常可以增加一个专用帐户，如pcguest。如果这个设置被注释的情况下，系统缺省使用nobody执行
              Windows客户的请求。一些使用者建议不要使用nobody用户，因为系统中的很多程序缺省都使用它，因此就会有安全问题。

# this tells Samba to use a separate log file for each machine
# that connects
   log file = /var/log/log.%m

# Put a capping on the size of the log files (in Kb).
   max log size = 50

    这里定义samba的日志文件为/var/log目录下的以log为前缀的文件，%m用于代表从访问的NetBIOS 计算机名，如果使用的用户级认证，还可以使用%U表示不同的登录用户。例如从一台名字为win95c的计算机访问samba服务器的日志，将记录在/var/log/log.win95c文件中。max
              log size定义每个日志文件的存储限制。

# Security mode. Most people will want user level security. See
# security_level.txt for details.
   security = user
# Use password server option only with security = server
;   password server = <NT-Server-Name>

# You may wish to use password encryption. Please read
# ENCRYPTION.txt, Win95.txt and WinNT.txt in the Samba documentation.
# Do not enable this option unless you have read those documents
;  encrypt passwords = yes

    在SMB协议中，有多个不同的认证方式，包括简单的共享级认证和用户级认证。Unix为多用户操作系统，缺省就使用用户级认证方式。当使用用户级认证的时候，Samba服务器使用Unix操作系统的用户和口令（来自/etc/passwd
              ）对用户进行认证，这是一种独立的认证方式。而有时候希望所有的服务器使用同一个认证数据库进行统一认证，因此就导致出现了基于域的统一认证模式。在一个域中，用户只需要通过域控制器进行认证即可，域中其他SMB服务器就将认可域控制器的认证。

    为了使Samba服务器支持域认证方式，可以有两种不同的设置方式，一种为真正的域认证，另一种为服务器认证方式，将Samba服务器配置为通过服务器验证用户，这需要指定security=server，以及指定password
              server的名字为NT的域控制器。认证服务器的方式不能事先域认证方式提供的一些特征，但它的适用范围并不仅限于域，使用工作组的网络也能通过统一的认证服务器来使用统一认证模式。设置域认证方式在后面进行详细解释。

    在Windows NT 4及Windows 98之后，客户和服务器之间进行认证时，口令不再以明文的方式在网络中传输了。为了支持加密口令传输，需要设置encrypt
              passwords选项。同样，这也需要其他复杂的设置。

# Using the following line enables you to customise your configuration
# on a per machine basis. The %m gets replaced with the netbios name
# of the machine that is connecting
;   include = /usr/local/etc/smb.conf.%m

    系统管理员可以为每个特定的计算机定制一个特定的配置文件，那里的设置将覆盖smb.conf中的缺省设置。这样就可以针对不同的计算机提供不同的配置。

# Most people will find that this option gives better performance.
# See speed.txt and the manual pages for details
   socket options = TCP_NODELAY

    socket参数用于配置对TCP的处理方式，以适合Microsoft客户的特征。Microsoft习惯为每个很短的会话都建立单独的连接，而不是使用一个连接进行多次传输，这样在传输中就需要进行多次连接会话设定过程，对性能有一定影响。为了改善性能，需要设置TCP_NODELAY或IPTOS_LOWDELAY选项。

# Configure Samba to use multiple interfaces
# If you have multiple network interfaces then you must list them
# here. See the man page for details.
;   interfaces = 192.168.12.2/24 192.168.13.2/24

    如果计算机上有多个网络界面，那么就需要让samba向多个界面广播b-node广播包，以及为这些界面提供资源服务，否则samba就会只向某一个界面提供网络服务。当然也可以设置这个参数，使得samba
              只服务于某个指定的网络，而不是服务器连接所有的网络。

# Browser Control Options:
# set local master to no if you don't want Samba to become a master
# browser on your network. Otherwise the normal election rules apply
;   local master = no

# OS Level determines the precedence of this server in master browser
# elections. The default value should be reasonable
;   os level = 33

# Domain Master specifies Samba to be the Domain Master Browser. This
# allows Samba to collate browse lists between subnets. Don't use this
# if you already have a Windows NT domain controller doing this job
;   domain master = yes

# Preferred Master causes Samba to force a local browser election on startup
# and gives it a slightly higher chance of winning the election
;   preferred master = yes

# Use only if you have an NT server on your network that has been
# configured at install time to be a primary domain controller.
;   domain controller = <NT-Domain-Controller-SMBName>

    这些设置选项主要用于SMB网络中进行浏览时，设置samba服务器的行为。缺省情况不让samba服务器参加broswser的推举过程，为了使得samba服务器能成为browser，就需要设定local
              master =yes。然后samba服务就可以根据os level设置的权重进行推举，缺省的os level为0，这个权重不会赢得推举。但可以取消注释，将os
              level设置为33，这将在与所有Windows计算机（包括Windows NT）的推举竞赛中获得胜利，因为NT server的权重为32。设置比33更高的权重，只是在不同的samba
              服务器之间进行选择时才有意义。

    由于Unix及Samba服务器在同样硬件配置下具有更高的网络性能，因此一般情况下，使用Samba服务器作Browser更佳。当然可能在Samba服务器启动之前，网络中都已经存在了Browser了，一般情况下不必重新进行推举过程，让网络中的现有Browser继续发挥作用。如果希望Samba服务器总是成为Browser，可以设置当Samba服务器启动时，迫使网络中重新进行推举过程，这需要设定perfered
              master参数。

    通常Samba能够胜任master Browser的角色，然而在多个子网的情况时，网络上就会存在Local master
              Browser和Domain master Browser。以上的设置只能使Samba成为 Local master Browser，缺省Samba并不参加Domain
              master Brower的推举。设置Samba服务器成为Domain master Browser就必须使用domain master参数进行设置，这对于使用工作组方式进行跨子网浏览意义重大。

    但是如果网络使用的是NT的域方式，就要使用NT的域控制器作为Domain master Browser ，不要设置与NT域控制器同一个子网中的Samba服务器的domain
              brower与browser功能，以免它和域控制器竞争。不让Samba服务器和NT域控制器竞争的原因是由于Windows NT中域控制器还涉及域认证（不是认证域用户，而是认证域上的合法成员计算机），SMB协议中各种复杂功能交错混合，浏览和认证两种不同的功能竟也混合在一起。由于域控制器完成的域认证任务，Samba服务器不能够完成，因此为了避免与NT域控制器相互冲突，最好使用域控制器作Domain
              master Browser。

    让Samba服务器了解当前域中存在的域控制器的方法是指定在设置文件中指定域基本控制器PDC（primary Domain
              Controller）的NetBIOS名字，这需要使用domain controller参数进行设置。

# Enable this if you want Samba to be a domain logon server for
# Windows95 workstations.
;   domain logons = yes

# if you enable domain logons then you may want a per-machine or
# per user logon script
# run a specific logon batch file per workstation (machine)
;   logon script = %m.bat
# run a specific logon batch file per username
;   logon script = %U.bat

# Where to store roving profiles (only for Win95 and WinNT)
#        %L substitutes for this servers netbios name, %U is username
#        You must uncomment the [Profiles] share below
;   logon path = \\%L\Profiles\%U

    当用户通过一台Windows 9x客户机使用用户级认证访问网络时，他可以选择登录进网络中的域。这意味着他不但要在SMB服务器中进行验证，而且会执行服务器中相应目录中的登录脚本，以自动执行一些相关设置。通常这种登录功能是由Windows
              NT服务器来执行的，然而Samba服务器也能完成这个任务，但必须设定domain logons 参数。此后就可以对不同的客户计算机或不同用户指定相应的登录脚本。这个功能还必须要求在本配置文件后面设置
              netlogon共享选项，以便客户机能访问相应的登录脚本。

    除了登录脚本之外，Windows NT中为了支持移动用户在不同地点进行漫游，也提供了针对每个用户的描述其使用环境的Profile文件，Samba服务器也可以通过logon
              path来支持对windows客户机这种漫游能力的支持。这样当Windows客户机使用漫游功能的时候，客户机会自动将用户的配置文件保存到服务器上，此后每次登录进域的时候都重新下载这个配置文件，设置Windows桌面环境。

# Windows Internet Name Serving Support Section:
# WINS Support - Tells the NMBD component of Samba to enable it's WINS Server
;   wins support = yes

# WINS Server - Tells the NMBD components of Samba to be a WINS Client
#       Note: Samba can be either a WINS Server, or a WINS Client, but NOT both
;   wins server = w.x.y.z

# WINS Proxy - Tells Samba to answer name resolution queries on
# behalf of a non WINS capable client, for this to work there must be
# at least one  WINS Server on the network. The default is NO.
;   wins proxy = yes

# DNS Proxy - tells Samba whether or not to try to resolve NetBIOS names
# via DNS nslookups. The built-in default for versions 1.9.17 is yes,
# this has been changed in version 1.9.18 to no.
   dns proxy = no

    上面的这些选项是用于设置NetBIOS名字解析方式，wins support选项使得nmdb能对外表现为一个NBNS服务器。wins
              server用于指定一个外部名字服务器的地址（可以为NT上的wins服务器或另一个Samba服务器），使得nmbd能用做NBNS客户端，通过访问该wins名字服务器解析NetBIOS名字。

    此外，还有一些不使用名字服务器进行解析的NetBIOS客户，如果名字服务器位于另一个子网上，那么它们就无法正确解析名字，而Samba可以使用wins
              proxy帮助它们使用名字服务器解析地址。例如一个WINS服务器在另一个子网上，本地子网内的Samba服务器配置了wins server的地址，其他Windows客户没有设置wins服务器地址，它们使用b-node广播方式查询名字，在这台Samba服务器设置了wins
              proxy能力之后，它就能代替wins服务器回应客户请求。因此要用作wins代理，就必须本身能使用名字服务器进行解析，就要求先设置wins
              server参数。

    此外，NetBIOS名字解析也可以扩展到通过DNS查询进行帮助，使用dns proxy设置就能让Samba 服务器通过dns进行查询，回应NetBIOS名字查询请求。

  • [homes]个人目录共享

#============================ Share Definitions ==============================
[homes]
   comment = Home Directories
   browseable = no
   writable = yes

    [homes]部分使得每个Unix用户通过SMB客户登录上来的时候，可以共享使用他自己的个人目录。这个共享资源具备特别属性，当用户登录上之后，共享名就不是homes，而是被服务器映射为用户自己的标识符。

    设置这个特别的共享选项，就允许每个用户访问自己的个人目录，而不必为每个用户都配置一个共享资源部分。正由于系统会自动映射，因此就不需要定义要共享的文件目录路径，而在其它文件资源共享选项中，都需要使用path参数进行定义。

    由于Samba系统会自动将homes共享名改变为用户的个人标识符，因此要设定browseable=no ，设置homes本身这个名字不出现在资源列表中。writable为用户写权限设置，由于是在用户的个人目录下，用户可以具备写权限。

  • [netlogon]与[Profiles]

# Un-comment the following and create the netlogon directory for Domain Logons
; [netlogon]
;   comment = Network Logon Service
;   path = /usr/local/samba/lib/netlogon
;   guest ok = yes
;   writable = no
;   share modes = no

    当允许Samba服务器支持客户的网络登录功能之后（设置domain logon），就需要设置[netlogon] 部分（删除注释符号），为guest用户打开登录路径的访问权限，以保证每个用户都能访问其自己的登录脚本。由于需要使用guest对应的Unix帐户访问登录脚本，这个登录路径及其下面的脚本文件都要允许该Unix帐号可以读取。

    建立这个目录之后，要设定正确的权限，并且创建这个目录下对应各个计算机或用户的登录脚本，以提供给客户正确的登录脚本。

# Un-comment the following to provide a specific roving profile share
# the default is to use the user's home directory
;[Profiles]
;    path = /usr/local/samba/profiles
;    browseable = no
;    guest ok = yes

    当支持Windows计算机漫游能力时，可以设定[Profiles]部分，并为相应的路径建立目录，及分配权限。来为Window计算机用户设置桌面环境。

  • [Printers]打印机设置

# NOTE: If you have a BSD-style print system there is no need to
# specifically define each individual printer
[printers]
   comment = All Printers
   path = /var/spool/samba
   browseable = no
# Set public = yes to allow user 'guest account' to print
   guest ok = no
   writable = no
   printable = yes

    这个部分就用于设置将printcap中定义的所有打印机使用的相关设置，缺省情况下允许所有的合法客户使用所有的打印机。BSD风格的打印系统，不需要任何设置就能正确共享所有的打印机，当然也可以使用printer参数指定具体的打印机以提供共享。而path参数定义的是打印机缓冲区的位置。guest
              ok、writeable用于设置正确的权限，而printable用于设置打印属性。

    由于Windows的打印驱动已经将要打印的文件转化为打印机支持的那种描述语言，因此这些打印文件不再需要任何过滤器进行转换。因此需要在printcap中定义一个不使用任何过滤器、直接将打印文档输出到打印机端口的打印机选项。

  •

    其他专有共享目录

# This one is useful for people to share files
;[tmp]
;   comment = Temporary file space
;   path = /tmp
;   read only = no
;   public = yes

# A publicly accessible directory, but read only, except for people in
# the "staff" group
;[public]
;   comment = Public Stuff
;   path = /home/samba
;   public = yes
;   writable = yes
;   printable = no
;   write list = @staff

# Other examples.
#
# A private printer, usable only by fred. Spool data will be placed in fred's
# home directory. Note that fred must have write access to the spool directory,
# wherever it is.
;[fredsprn]
;   comment = Fred's Printer
;   valid users = fred
;   path = /homes/fred
;   printer = freds_printer
;   public = no
;   writable = no
;   printable = yes

# A private directory, usable only by fred. Note that fred requires write
# access to the directory.
;[fredsdir]
;   comment = Fred's Service
;   path = /usr/somewhere/private
;   valid users = fred
;   public = no
;   writable = yes
;   printable = no

# a service which has a different directory for each machine that connects
# this allows you to tailor configurations to incoming machines. You could
# also use the %U option to tailor it by user name.
# The %m gets replaced with the machine name that is connecting.
;[pchome]
;  comment = PC Directories
;  path = /usr/pc/%m
;  public = no
;  writable = yes

# A publicly accessible directory, read/write to all users. Note that all files
# created in the directory by users will be owned by the default user, so
# any user with access can delete any other user's files. Obviously this
# directory must be writable by the default user. Another user could of course
# be specified, in which case all files would be owned by that user instead.
;[public]
;   path = /usr/somewhere/else/public
;   public = yes
;   only guest = yes
;   writable = yes
;   printable = no

# The following two entries demonstrate how to share a directory so that two
# users can place files there that will be owned by the specific users. In this
# setup, the directory should be writable by both users and should have the
# sticky bit set on it to prevent abuse. Obviously this could be extended to
# as many users as required.
;[myshare]
;   comment = Mary's and Fred's stuff
;   path = /usr/somewhere/shared
;   valid users = mary fred
;   public = no
;   writable = yes
;   printable = no
;   create mask = 0765

    此后，缺省smb.conf中给出了一些设定各种共享文件资源、打印机资源的例子，例如设置特定打印机的 [fredprn]，设置私人文件共享资源的[freddir]和[myshare]，使用宏为多个用户设置共享的[pchome]，提供公共访问的[public]和[tmp]，FreeBSD的管理员可以根据具体情况，根据这些设置例子设置相应的共享资源，并设置相应的访问权限，以保护文件系统不被非法访问。

    需要注意的是，当使用valid user用来设置合法访问用户时，或者使用wirte list定义具备写权限的用户时，都可以使用@staff的形式使用Unix的组名，这样凡是属于该staff组成员的用户，都会具备相应权限。

    从这些例子中可以看到[global]用于设定全局参数，不会出现在资源列表中，[homes]用于设定个人目录共享，其共享的名字映射为个人标识符而非homes，[printers]设定打印机共享，将共享所有的打印机名字，除了这些标题的共享名字与标题不同之外，其他每个标题都将代表一个共享资源的名字。

    当更改设置之后，可以重新启动Samba服务器，提供新的共享服务了。但在重新启动服务器之前，最好使用 Samba软件包中提供的测试软件，检查一下设置是否正确。这些小工具程序包括检查smb.conf设置的testparm
              ，检查打印机名字的正确性的程序testprn，用于进行NetBIOS名字解析的nmblookup等。

  • 使用swat配置samba

    samba 2.0提供了一个能够通过浏览器来配置samba的工具──swat。它是一个专用www服务器，使用inetd 来启动，然后经过认证，可以允许用户通过浏览器来配置smb.conf。为了达到这个目的，首先要为swat分配一个固定的端口，这个工作可以通过在/etc/services中增加一行来完成：

swat    901/tcp

    出于安全的考虑，应该使用1024以下的端口，这是因为非root用户也能占用1024以上的端口，如果使用 1024之上的端口，可能在某些情况下，普通用户就可能通过欺骗的方法获得管理员的口令。

    为了启动swat，需要在inetd.conf中增加一个入口，并重起inetd：

swat  stream    tcp  nowait  	root /usr/local/sbin/swat     swat

    然后就能使用Netscape等浏览器来配置samba了，为了避免认证口令通过网络传输，应该在本地启动浏览器（并进一步可以使用tcp_wrapper提供保护）。输入URL为：http://localhost:901
              /，浏览器将提示用户名和口令对用户进行认证，可以输入任意一个Unix用户进入swat页面，但普通用户只能读取 samba设置，而不能更改，为了设置samba，必须使用root用户进行认证。一些功能简单的浏览器不支持浏览器方式的用户认证，就无法使用swat设置Samba。

    由于改变smb.conf对于系统安全有严重的影响，因此使用swat一定要小心。为了防止进行swat认证时root密码被窃听，不应该在远程启动浏览器进行设置，应该在控制台或本地安全网络内进行设置。而且一旦设置完毕，应该立即退出浏览器，因为浏览器在内存中保存用户的认证信息，直到浏览器退出。

    注意，swat将删除原有smb.conf中的全部注释，并重新安排各个设置项的位置，因此应该在使用swat 设置之前备份原有的smb.conf。而且swat只是提供了一个容易使用的设置界面，并不能保证设置一定就是正确的，因此还是要在理解smb.conf的基础上才能正确设置。

    swat提供7个不同功能的页面，提供管理员访问。主页面HOME，提供了对Samba文档的连接，用于管理员实时查看相关手册；GLOBALS页面提供对smb.conf中[globals]部分中的各个参数进行设置；SHARES
              用于选择、增加、删除各个共享资源，查看并更改其设置选项；PRINTERS用于设置打印机选项；STATUS 用于检查当前Samba服务器的状态，包括客户计算机的连接状态和用户的连接信息，管理员可以使用它来重新启动
              Samba，这样就能在更改设置之后使新设置生效；VIEW用于查看当前设置的smb.conf的内容；PASSWORD 用于管理加密口令，提供加密认证情况下增加和管理用户，并可以保持Unix和Windows
              NT的口令一致，这个功能只在使用了加密口令功能之后才有用，更改的口令将直接保存在/usr/local/private目录下的smbpasswd
              文件中。PASSWORD功能将不但更改smb.conf，还将更改Samba使用的口令选项，因此对于使用加密口令认证方式的系统，最为有用。

    使用SWAT，设置Samba就非常容易，不再需要手工编辑设置文件，而可以直接使用浏览器更改设置，并重新启动Samba服务器。


FreeBSD连载(68)：根据Windows网络设置Samba

王波

根据Windows网络设置Samba

    使用SMB协议实现的网络的情况非常不同，有的网络仅仅由几台Windows计算机组成，只需要提供计算机之间最简单的资源共享，并不需要一个中心控制点 ── 文件服务器提供服务，而有的网络由多个物理网络通过路由器连接而成，网络中拥有多种文件/打印服务器，网络中的操作系统也各不相同，包括Windows和Unix。

    Samba服务器能适应这些不同要求的网络的不同要求，然而由于网络的需要各不相同，因此对Samba的设置也不相同。如何根据需要来规划网络、设置Samba是一个灵活但复杂的问题，同时存在各种各样的设置方式都能满足用户的需要，这里给出的只是一种可行性建议。

  • 小型网络，无NT服务器

    这种网络的特征是网络资源的使用程度不大，通常所有的计算机都位于一个局域网内，几乎没有专用文件/打印服务器。所有的计算机均使用工作组方式相互访问。此时使用Samba服务器的目的是为了更好的利用网络资源，提供方便的文件/打印服务。

    在这样的网络中，仅仅需要最简单的文件/打印共享服务。虽然共享级认证方式能够满足此时的需要，但是最好使用用户级认证方式，因为只有这样才能充分发挥服务器提供服务的优势。需要为每个使用者在FreeBSD服务器上分别建立帐户，这样缺省设置就自动为用户共享其个人目录，用做私人数据的保存。为了网络用户之间的相互交换数据，可以设定一个公用共享目录，例如上面例子中的[public]共享目录。

    由于Samba服务器具有优秀性能，最好将Samba服务器设置为本地的Browser，仅需要设置local master参数，并给os leverl一个较大的值就能达到目的。可以不使用nmbd的名字解析能力用做名字服务器，因为此时都在一个物理网络内，b-node广播方式能够提供正确的解析。

    当为Windows 98或者Windows NT SP3提供认证的时候，它们将使用加密过的口令进行认证，这能提供更大的网络安全性。Samba服务器也能提供这种认证，然而对于这样的小型网络，使用原有的非加密口令认证方式就足够了，因为口令不会跨越网络传输，安全问题限制于本地网络内部。在Samba的文档中，提供了将Windows 98或Windows NT SP3设置为原有认证方式的注册表信息，分别为/usr/local/share/examples/samba 目录下的Win95_PlainPassword.reg和NT4_PlainPasswor.reg文件。

  • 小型网络，与NT服务器相互协作

    这种网络中存在一个或几个Windows NT服务器，因此网络中的关键问题是认证的策略问题。有的网络中使用分散式的认证策略，即各个服务器各自认证使用自己资源的客户，适合网络上服务器属于不同管理者的情况，另一种情况是希望在访问多个服务器时使用一致的认证，无论是在NT服务器还是在Samba服务器，对于同一个用户只需要使用一个口令就能使用网络资源。

    当使用分散认证策略的时候，Samba服务器可以使用缺省设置security=user，当要求Samba 服务器和NT服务器认证同样的用户的时候，可以使用security=server，让NT服务器来认证用户，此时还需要设置password server的名字，以设置提供认证的NT服务器的名字。

    由于是使用NT服务器对用户进行认证，然而NT上的用户与FreeBSD用户的名字可能不同，为了将NT用户重新映射到FreeBSD上的Samba用户，就需要进行用户名的映射。这需要使用username map参数，这个参数设置一个用于用户名映射的文件名，在这个指定的文件中，可以设置FreeBSD用户（或用户组）等价于哪个NT 用户（或用户组）。

  • 具备多个物理网段的网络

    如果用户的网络跨越了多个物理网络，为了实现浏览，最重要的问题就是设置使用名字服务器进行名字解析。此时可以选择使用Samba的nmbd作为名字服务器，也可以使用Windows NT的WINS服务器作为名字服务器。

    但如果计划在网络上使用多个NetBIOS服务器，以提供相互备份的能力，就只能使用多个Windows NT 来运行WINS，WINS的一项功能是具备相互复制的能力，而nmbd不能和其他WINS服务器相互复制数据。WINS 使用这个功能主要是用于克服系统操作本身的故障，以提高可靠性。对于一般的网络，使用一个名字服务器，尤其是运行在高稳定性的FreeBSD系统之上的Samba，可靠性就能满足网络的需要。当然偶然发生的物理故障是无法避免的，这样将使用分布在不同地点的多个服务器会有一定的帮助。

    当选择好了名字服务器的设置策略，就可以决定Samba是用作名字服务器，还是普通的使用名字服务器的客户机。Samba可以同时设置为名字服务器和客户，这并不冲突。还可以设置Samba为wins proxy和dns proxy ，为不能使用wins和dns进行名字解析的NetBIOS客户提供b-node方式的代理解析。

    当网络使用的是分散式的工作组方式的时候，要实现跨越子网的浏览，Samba服务器就担任了重要的角色。因为不存在域控制器，此时Samba要设置成为Domain master Browser，以提供不同子网间的Local master Browser相互交换浏览信息。

    如果远程网络中的计算机不使用本地的Samba作名字服务器，该网络中的Domain master Browser 也不与本地网络的Local Master Browser交换信息，那么那个网络上的Brower就无法了解本地上的资源列表。作为本地Browser的Samba服务器能使用一种折衷的方法来通知远程网络上的Browser ，告诉它本地网络提供的资源服务，这就称为remote announce，并能用于远程网络中的浏览信息与本地网络同步。为了使用remote announce，需要设置remote announce和remote brow se sync参数，使用的设置值为远程网络的广播地址，如192.168.1.255，可以同时设置多个地址，以同步多个远程Browser。

    如果网络中使用NT域认证方式，就不要让Samba和域控制器争夺Domain master Browser 的权利，Samba还不能设置为PDC为整个域服务。因此需要设置domain master=no，但可以让Samba 服务器在没有PDC的子网中担当Local master Browser的任务，即设置local master=yes。

    当前NT服务器使用SAM数据库用于保存认证信息，但是下一代NT服务器将转向kerberos认证方式，这种认证方式本来就是在Unix上开发的，更有利于与Samba软件集成在一起。

    此时也可以使用NT的域控制器提供认证（设置security=server，并将password server 设置为PDC或BDC），以使得Samba服务器能承认域控制器认证过的用户。这样客户技术就可以使用加密认证方式，因为Samba服务器不进行认证，仅仅是把认证信息转发给相应的NT服务器进行认证。

  • 支持加密口令认证

    前面提到过为了适应Windows 98和Windows NT 4.0 SP3之后的客户使用加密过的口令认证方式，可以将客户计算机再次设回使用普通口令认证方式来解决认证问题，然而当客户可能跨越子网进行认证的时候，就应该使用加密认证，以防止口令明文跨越子网传输，提供更高的安全性。

    为了支持加密口令认证，就需要使用独立于FreeBSD系统口令文件之外的认证系统，需要在smb.conf 中的[globals]中增加设置为：

      encrypt passwords = yes
      null passwords = yes
      smbpasswd file = /usr/local/private/smbpasswd

    然后使用命令smbpasswd -a user，将用户user及其口令加入指定的口令文件smbpasswd 文件中，这样在进行认证时，就能通过这个smbpasswd文件中的设置，通过口令的加密认证方式进行认证了。然而此时将绕过系统标准认证过程，原有的用户数据必须重新一个一个加入smbpasswd文件中才能完成认证，没有添加到这个文件中的用户就无法完成认证以使用系统资源。其中null
              passwords的设置不是必须的，只是Windows NT中一般许可用户使用空口令，这项设置用来与Windows NT的设置保持一致。加密口令文件smbpasswd
              在FreeBSD系统下缺省位于/usr/local/private目录中。

    Samba手册中使用的目录可能会与FreeBSD中的具体目录不一致，这是因为使用Packages Collection 或Ports
              Collection安装的Samba，其软件的安装目录均按照FreeBSD的习惯做了调整，因此会与Samba手册提到的位置不太相同。

    此时，使用SWAT的PASSWORD设置选项可以直接将一个用户加入口令数据库，并打开访问这个用户的许可，对于加密口令的管理更为简便。因此应该使用SWAT来管理加密口令数据文件，而不必直接使用smbpasswd命令。

  • 将Samba服务器加入域

    使用域代替工作组的好处是，所有的客户能使用同一个认证来访问所有的资源。虽然域的概念还是一种非常初级的目录服务的概念，但由于Microsoft网络的流行，它的重要性也非常之大。

    在一个以域为认证方式的网络中，可以将Samba加入域中去，以采用与域一致的认证和管理方式。在一个域中的 SMB计算机有各种形式，一种为提供认证服务的域控制器，分为PDC（Primary
              Domain Controller）和BDC（Backup Domain Controller），另一种为不提供认证服务的成员服务器，还有就是普通客户机。Samba当前能作为普通成员服务器加入域。

    为了将Samba加入域，首先要为Samba服务器在PDC服务器中创建一个帐户，这个操作就如同为普通NT 成员服务器创建用户一样，通过NT服务器的Server
              Manager for Domain来完成。

    加入NT域的时候首先需要停止Samba服务器的正常工作，使用smbpasswd将这个Samba服务器登记进域，这需要使用：

# smbpasswd -j DOMAINNAME -r SAMBASRV

其中DOMAINNAME为域的名字，SAMBASRV为前面PDC上为Samba服务器创建的帐户名，这样Samba服务器就加入了域。然后需要更改smb.conf的设置：

       security = domain
       workgroup = DOMAINNAME
       password server = PDC_name BDC1 BDC2

    password server设置为这个域内的PDC和BDC的名字。此后，再次启动Samba服务器，则服务器就为这个域的一个成员服务器了。

    虽然使用域认证方式和服务器认证方式都能让同样的用户访问Samba服务器上的资源，然而对于认证细节是不同的，使用域认证方式能利用域提供的更安全的认证通道。

  • 设置lmhosts

    在Miscrosfot扩展的NetBIOS协议中，可以使用查询设置文件的方法来进行名字解析，这个静态文件为 lmhosts。在Windows下的这个文件位于系统目录中，Samba将其放在与smb.conf相同的目录下，FreeBSD系统中为/usr/local/etc中。

# Sample Samba lmhosts file.
192.168.1.24  WIN95
192.168.1.21  NTSRV#20
192.168.1.121 FBSDSRV		   #PRE

    lmhosts的文件格式与/etc/hosts文件非常类似，也是IP地址/主机名字对，除了这个文件中使用的名字是NetBIOS名字。此外NetBIOS名字有一个定义属性类别的字节（NetBIOS中的第16个字节），这个属性字节可以在lmhosts中直接设置，以回应特定类别的请求，不设置这个属性，就对应所有类别。例如上例中的第二项定义的NTSRV，就明确指定了其属性为16进制的0x20。

    此外，lmhosts也支持一些特殊的语法，例如用在一个设置项之后的#PRE选项将使得这项设置在启动Samba 时自动载入系统缓冲区中，使得能最先识别。标准情况下的lmhosts文件在名字解析查询顺序的后部，在经过wins
              和b-node广播之后才会检查lmhosts设置，而#PRE选项设置的名字就会在此之前进行解析。

    一般情况下不必设置这个文件，因为使用其他方法进行名字查询就足够了，这种方法用于辅助解析的，例如在跨越子网进行浏览，但wins服务器不能提供访问时的一个备份措施。其中的#PRE方式也能在系统启动时的进行一些初始名字解析设置。


FreeBSD连载(69)：使用smbclient访问Windows资源
王波

访问Windows系统资源

    通过配置Samba服务器，可以提供Windows客户机来访问FreeBSD系统上共享的资源。也能够在 FreeBSD上通过SMB协议访问Windows系统上的共享资源。只是习惯上Unix计算机用做服务器，Windows 计算机用做客户机，很少有让Unix访问Windows计算机的需要。但是越来越多的计算机使用者不但使用 Unix作服务器，也使用Unix来处理很多其他任务，那么就可能会需要访问其他Windows计算机上的资源。

  • 使用smbclient访问Windows资源

        samba软件中用于访问网络上其他SMB资源的软件为smbclient，它是一个类似于ftp操作方式，通过远程操作的方式进行文件传递的软件。为了获得网络上可以访问的计算机列表，首先需要使用 smbclient来获得一个Windows计算机共享出来的资源，这需要使用-L参数访问IPC$资源，对于使用用户级认证的Windows NT或Samba服务器，可以使用-N参数指定使用空口令登录，或者使用-U%参数，使用空用户名和空口令访问服务器：

    $ smbclient -L windows_host -N

        如果没有使用-N或-U%，smbclient将提示口令，一般可以直接回车，也可以给予正确的口令。因为一般计算机均允许匿名浏览IPC$资源，即能给所有的计算机提供自己所了解的浏览数据。smbclient将显示一个浏览数据列表和该机的共享资源列表。

        如果不清楚一个Windows计算机的NetBIOS名字，可以使用-I加要访问计算机的IP地址来代替-L 参数及使用的NetBIOS名字。或者可以使用nmblookup先来解析NetBIOS名字。

    $ nmblookup fbsdsrv
Sending queries to 192.168.3.255
192.168.3.1 fbsdsrv<00>

        要想使用smbclient来访问windows时，也需要使用UNC来标识Windows资源的位置。此时就需要了解
                  Windows UNC在Unix下进行表示的不同之处。不同之处在于Unix的shell下反斜线为特殊字符，它被定义为转义恢复字符，表示将一些转义字符恢复为其本身字符的意义。因此必须使用两个反斜线才能等同于一个反斜线。因此一个UNC实际使用时应使用双倍的反斜线。

    $ smbclient \\\\localhost\\wb -U wb
Added interface ip=192.168.3.1 bcast=192.168.3.255 nmask=255.255.255.0
Password:
Domain=[MYGROUP] OS=[Unix] Server=[Samba 2.0.2]
smb: \> help
ls             dir            du             lcd            cd
pwd            get            mget           put            mput
rename         more           mask           del            rm
mkdir          md             rmdir          rd             prompt
recurse        translate      lowercase      print          printmode
queue          cancel         quit           q              exit
newer          archive        tar            blocksize      tarmode
setmode        help           ?              !
smb: \> quit

        然后就可以使用与ftp相似的命令，如dir，cd，get，put等命令来传输文件。

        Samba可以用于帮助备份Windows系统，除了使用smbclient之外，Samba还提供了一个 shell脚本smbtar，它使用smbclient以及tar，直接将Windows系统中的文件备份到FreeBSD
                  系统中的磁带设备中。

        要使用Windows下的打印机资源，要首先使用smbclient以将打印文档发送给Windows计算机，并执行print命令。samba软件包中提供了一个shell脚本smbprint用来使用合适的命令帮助FreeBSD
                  将打印文件发送给Windows打印机。FreeBSD下这个脚本被安装到/usr/local/share/examples/samba/printing
                  目录下，可以根据需要将这个脚本复制到/usr/local/bin或其他目录下，提供给用户使用。

        对于经常使用的Windows打印机，还可以在printcap文件中为它增加一个入口，使用smbprint 作过滤器，这样就将打印输出直接交给smbprint，用户不必手工进行控制，而是直接使用FreeBSD系统的打印系统lpr等命令进行打印和管理。这样还可以将这台FreeBSD计算机用做一个打印网关，所有的支持LPD方式打印的Unix均可通过这台服务器的smbprint打印机入口，将打印文档发送给Windows打印机。

    •


FreeBSD连载(70)：用SharityLight装SMB文件系统

王波

使用SharityLight安装SMB文件系统

    使用smbclient进行使用Windows计算机上的文件资源的方式还是一种命令行的控制方式，必须将文件下载到本地才能进行处理。更方便的方法是将远程文件服务器上的资源装载到本地的目录树上，这样就能如同处理本地文件一样对远程文件进行处理了。Unix上的NFS就是这样的处理方式，Windows系统的映射网络驱动器也是使用的这种处理方式。

    在Unix中，提供这种远程网络文件系统的标准做法是重新完成一个文件系统驱动程序，这样由驱动程序来完成装载远程SMB文件系统的目的，运行在Linux上的smbfs就是这么做的。然而也存在另一种思路，即是将一个网络文件系统协议翻译为现有的网络文件系统协议，如NFS，然后由系统中的NFS驱动程序进行装载。这种想法完全也能实现装载SMB网络文件系统的目的，由于不必更改内核程序而使用十分成熟的原有驱动程序，而会带来更具稳定性的特征。

    Sharity就是将SMB协议翻译为NFS协议，然后在Unix上装载上共享资源的软件，因为这个软件没有运行在内核中，因此其速度会受到一点影响，但正因为如此，即使已经安装到本地文件系统的远程Windows系统的崩溃也不会对Unix造成影响，由于Windows系统并不稳定，因此这种特性是非常有益的。

    需要使用Packages Collection来安装这个软件，当前的免费Sharity为Sharity Light，而最新版本的Sharity为商业软件，Sharity Light使用了GNU软件的部分代码，因此也遵从GNU许可，是对外提供源代码的软件。

    Sharity的网址位于http://www.obdev.at/Products/Sharity.html

    安装Sharity Light将安装两个应用程序shlight和unshlight到/usr/local/sbin 目录中，一个用于安装文件系统，另一个用于卸载已安装的文件系统。Sharity的使用方法非常简单，不需要任何设置。

# /usr/local/sbin/shlight //fbsdsrv/wb /dist -U wb
Password:
Using port 1908 for NFS.
bash-2.02# mount
/dev/da0s2a on / (local, writes: sync 1192 async 12795)
/dev/da0s2f on /usr (local, writes: sync 18054 async 80408)
/dev/da0s2e on /var (local, writes: sync 15954 async 33980)
procfs on /proc (local)
shlight-39011 on /dist
bash-2.02# /usr/local/sbin/unshlight /dist

    注意，sharity使用斜线代替UNC中的反斜线，标识UNC，这与Samba的做法不同。


FreeBSD连载(71)：DHCP的工作过程

王波

设置DHCP

    动态主机配置协议（Dynamic Host Configuration Protocol，DHCP）是用于对多个客户计算机集中分配IP地址以及IP地址相关的信息的协议，这样就能将IP地址和TCP/IP的设置统一管理起来，而避免不必要的地址冲突的问题，因此常常用在网络中对众多DOS/Windows计算机的管理方面，节省了网络管理员手工设置和分配地址的麻烦。

    除了能够方便管理之外，DHCP还能略微达到节省IP地址的目的。假设网络中有50个计算机，但只有40个 IP地址，但是这50台计算机不会同时启动，IP地址应该满足要求。如果使用静态IP地址的设置方式，还是会遇到分配地址的困难，因为计算机的使用是随机的，无论怎样分配地址都无法避免出现冲突现象，而使用DHCP就能避免这个问题。 DHCP也能用于统一设置其他的一些IP设置，如缺省路由、DNS服务器等等，使用它能减少一个大型网络的管理任务。

    DHCP是从原有的BootP协议发展起来的，原来的目的是为无盘工作站分配IP地址的协议，当前更多的用于集中管理IP地址。然而DHCP协议也有其缺点，例如一台DHCP客户计算机没有一个固定的IP地址，而对于提供网络服务的服务器来讲，经常变化的IP地址并不适合。并且当前的DNS协议并不能和DHCP协作，为DHCP客户直接提供主机名解析任务。

  • DHCP的工作过程

    DHCP工作时要求客户机和服务器进行交互，由客户机通过广播向服务器发起申请IP地址的请求，然后由服务器分配一个IP地址以及其他的TCP/IP设置信息。整个过程可以分为以下步骤：

    IP地址租用申请：DHCP客户机的TCP/IP首次启动时，就要执行DHCP客户程序，以进行TCP/IP 的设置。由于此时客户机的TCP/IP还没有设置完毕，就只能使用广播的方式发送DHCP请求信息包，广播包使用 UDP端口67和68进行发送，广播信息中包括了客户机的网络界面的硬件地址和计算机名字，以提供DHCP服务器进行分配。

    IP地址租用提供：当接收到DHCP客户机的广播信息之后，所有的DHCP服务器均为这个客户机分配一个合适的IP地址，将这些IP地址、网络掩码、租用时间等信息，按照DHCP客户提供的硬件地址发送回DHCP客户机。这个过程中对DHCP服务器没有对客户计算机进行限制，因此客户机能收到多个IP地址提供信息。

    IP地址租用选择：由于客户机接收到多个服务器发送的多个IP地址提供信息，客户机将选择一个IP地址，拒绝其他提供的IP地址，以便这些地址能分配给其他客户。客户机将向它选择的服务器发送选择租用信息。

    IP地址租用确认：服务器将收到客户的选择信息，如果也没有例外发生，将回应一个确认信息，将这个IP地址真正分配给这个客户机。客户机就能使用这个IP地址及相关的TCP/IP数据，来设置自己的TCP/IP堆栈。

    更新租用：DHCP中，每个IP地址是有一定租期的，若租期已到，DHCP服务器就能够将这个IP地址重新分配给其他计算机。因此每个客户计算机应该提前不断续租它已经租用的IP地址，服务器将回应客户机的请求并更新该客户机的租期设置。一旦服务器返回不能续租的信息，那么DHCP客户机只能在租期到达时放弃原有的IP地址，重新申请一个新 IP地址。为了避免发生问题，续租在租期达到50%时就将启动，如果没有成功将不断启动续租请求过程。

    释放IP地址租用：客户机可以主动释放自己的IP地址请求，也可以不释放，但也不续租，等待租期过期而释放占用的IP地址资源。

    由于DHCP依赖于广播信息，因此一般的情况下，客户机和服务器应该位于同一个网络之内。然而可以设置网络中的路由器为可以转发BootP广播包，使得服务器和客户机可以位于两个不同的网络中。然而配置转发广播信息，不是一个很好的解决办法，更好的办法为使用DHCP中转计算机，DHCP中转计算机和DHCP客户机位于同一个网络中，来回应客户机的租用请求，然而它不维护DHCP数据和拥有IP地址资源，它只是将请求通过TCP/IP转发给位于另一个网络上的DHCP服务器，进行实际的IP地址分配和确认。


FreeBSD连载(72)：设置和使用DHCP

王波

设置和使用DHCP

    在FreeBSD的Packages Collection中，有两个不同的DHCP客户机和服务器软件，一个为ISC-DHCP，另一个为WIDE-DHCP，两个软件都包括了DHCP客户软件和服务器软件，其中ISC-DHCP 更为常用一些，这里就以ISC-DHCP为例介绍在FreeBSD上安装和设置DHCP。

    为了支持DHCP，首先要确认系统内核支持伪设备bpfilter，如果没有，就需要重新编译内核。伪设备bpfilter 是一个允许应用程序接收网络的原始数据包的界面，这样应用程序就能接收目的地址非本机IP地址的数据包了。DHCP使用bpfilter的原因是在DHCP设置好计算机的TCP/IP之前，由于计算机本身没有定义IP地址，而TCP/IP堆栈本身不会接收不具备本机IP地址的数据包。要接收DHCP服务器发送回客户的数据包，就需要绕过TCP/IP堆栈，而必须使用伪设备bpfilter。

pseudo-device    bpfilter    4

    定制内核之后，还要保证/dev/目录下具有对应bpfilter的设备文件。

# cd /dev
# sh MAKEDEV bpf0 bpf1 bpf2 bpf3

    从Packages Collecion中安装DHCP软件，这将DHCP软件中的dhcpd，dhclient和dhcprelay
              安装到/usr/local/sbin目录下。

$ ls /usr/local/sbin/dhc*
/usr/local/sbin/dhclient   /usr/local/sbin/dhcpd
/usr/local/sbin/dhcrelay

  • 设置服务器

  •

    •

    为了设置DHCP服务器dhcpd，首先就要设置其配置文件/etc/dhcpd.conf。这个配置文件语法简单，比较容易理解。

server-identifier 192.168.3.1;

subnet 192.168.3.0 netmask 255.255.255.0 {
        range 192.168.3.10 192.168.3.20;
        default-lease-time 600;
        max-lease-time 7200;
        option subnet-mask 255.255.255.0;
        option broadcast-address 192.168.3.255;
        option routers 192.168.3.1;
        option domain-name-servers 192.168.3.1;
        option domain-name "exampleorg.org.cn";
}
host a1 {
        hardware ethernet 00:90:27:4e:92:09;
        fixed-address 192.168.3.32;
        option subnet-mask 255.255.255.0;
        option broadcast-address 192.168.3.255;
        option routers 192.168.3.1;
        option domain-name-servers 192.168.3.1;
        option domain-name "exampleorg.org.cn";
}

    基本的dhcpd.conf首先使用server-identifier定义了本服务器的IP地址，这对于有多个IP地址的服务器系统十分重要，一般不必设置这个参数，dhcpd能自动侦测。然后定义要分配IP地址的客户机组，每组拥有一个可用的IP地址范围。有两种客户机组的划分方式，一种为指定子网段来区分，一种为指定主机来区分。

    这个例子中的第一组定义了一个子网192.168.3.0/24，这个子网段内，可供DHCP服务器分配的I P地址范围为192.168.3.10到192.168.3.20，这个地址范围也可以不是连续的，不连续的地址可以使用多个range设置参数来设置。此外，还设置了这一组内分配的IP地址的租期限制default-lease-time
              和max-lease-time，可以使用缺省值，而不必改动。后面的option参数设置DHCP的附加功能，例如设置DHCP客户的网络掩码、广播地址、DNS服务器、域名等等。事实上这些option设置选项也可以被用作全局选项设置，即放置在server-identifier之后，对所有的客户机组起作用。

    例子的第二组是针对某个特定主机a1进行的设置，这个主机被限定为以太网地址为hardware ethernet 参数值的计算机，将给这个计算机分配一个固定地址。这种分配方式实际等价于固定地址分配方式，唯一的好处就是能够对IP地址进行集中管理，不必每个计算机分别设置了。这里同样也可以使用option参数，设置TCP/IP的参数。

    dhcpd.conf中还能有更多的组，包括对非本网段的子网上的客户机指定的组。

    当设置了dhcpd.conf之后，就能启动dhcpd守护进程了，由于计算机会有多个网络界面，需要指定dhcpd 服务器的网络界面，以便回应相应界面上的DHCP请求。

# /usr/local/sbin/dhcpd fxp0

    在调试阶段，可以使用-d参数，这样dhcpd就不会进入后台运行，而一直保留在前台，并显示各个与客户计算机通信的过程。当一切都调试完毕之后，就能去除-d参数，并将执行命令放入rc.local启动脚本中，以便系统能够自动执行。

    此后，dhcpd正常运行的时候，会将每一次客户请求及其回应的IP地址分配的记录，都记录在/var/run/dhcpd.leases
              文件中。为了使dhcpd能正常进行日志记录，应该在启动dhcpd之前使用touch 命令，生成一个新的日志文件。以后就可以查看这个日志文件的内容，以得到当前DHCP服务器的状态和客户机IP地址分配的情况。以下是一个日志文件的部分内容。

       lease 192.168.3.11 {
          starts 3 1998/11/26 05:46:28;
          ends 4 1998/11/27 05:46:28;
          hardware ethernet 0:80:c2:12:fd:d;
          uid 1:0:80:c2:12:fd:d;
       }

    touch命令的优点是在存在相关的文件时，不删除或更改文件内容，只更新其访问时间设置，只有在文件不存在时才生成新文件。

    然后就能设置网络中的客户计算机使用DHCP协议，获取合法的IP地址了。通常Windows计算机的TCP/IP设置中能直接设置支持DHCP协议，如果为Unix（包括FreeBSD）设置DHCP客户软件，就需要dhclient的支持。

  • 设置客户软件

    ISC-DHCP中同样也提供了一个客户程序dhclient，用于FreeBSD系统从DHCP服务器上动态获取一个IP地址。这个程序同样也要求内核支持bpfilter伪设备。

    dhclient使用的配置文件为/etc/dhclient.conf，然而最一般的情况下可以不使用它，软件本身的缺省配置就满足一般情况下请求IP地址的需要了。缺省设置下dhclient在获得了IP地址之后，会自动执行/etc/dhclient-script
              这个脚本程序，以针对刚获取的动态IP地址进行必要的设置。很多依赖于IP地址的网络服务，就可以在这个脚本中启动，或者针对重新分配的动态IP地址对已有的网络服务进行修正。虽然使用者也许不希望使用这个脚本设置网络，但如果不存在这个脚本程序，或者这个程序不可执行，那么dhclient就不能正常执行。

    因此对于最一般的客户机，一般只连接到一个网络上，仅具备一个网络界面，可以使用一个空的dhclient.conf 和空的declient-script文件，就能完成设置IP地址和其他TCP/IP参数的任务了。

# touch /etc/dhclient.conf
# touch /etc/dhclient-script
# chmod +x /etc/dhclient-script
# /usr/local/sbin/dhclient fxp0
Listening on BPF/fxp0/00:90:27:4e:92:09/unattached
Sending on   BPF/fxp0/00:90:27:4e:92:09/unattached
Sending on   Socket/fallback/fallback-net
DHCPDISCOVER on fxp0 to 255.255.255.255 port 67 interval 22
DHCPOFFER from 192.168.3.1
DHCPREQUEST on fxp0 to 255.255.255.255 port 67
DHCPACK from 192.168.3.1
bound to 192.168.3.32 -- renewal in 3600 seconds.

    在更复杂的情况下，就要指定更多的内容，例如当系统有多个网卡时，要指定dhclient应该从哪个子网中获得IP地址设置，就需要使用设置文件dhclient.conf。一般除非有多个局域网网络界面，都应该使用空设置文件，避免产生配置错误。以下为一个简单的dhclient.conf的例子，可以用于多网络界面的情况：

# Defaults
timeout 60;
reboot 10;

retry 60;
select-timeout 5;
initial-interval 2;

script "/etc/dhclient-script";

interface "fxp0" {
 request subnet-mask, broadcast-address, routers, domain-name-servers,
         domain-name, host-name;
 require domain-name-servers;
}

    这个设置文件主要用于重新定义一些参数，比较容易理解，更改也比较容易。

    成功的手工执行dhclient之后，就可以考虑将其和系统启动文件相结合了。因为很多网络服务是依赖于网络配置的，应该在启动这些网络服务之前使用DHCP配置好TCP/IP。使用dhclient-script启动服务的想法虽然也能解决问题，然而这就不能使用系统的启动rc文件中的相关设置启动网络服务，而在这个dhclient-script
              中重新启动，因此比较麻烦。更简便的做法是仅仅在dhclient-script中设置hostname，而让系统启动文件完成其他网络服务的启动。这样就要求将dhclient与系统rc文件结合起来。

#hostname="my.domain.name"
network_interfaces="fxp0 lo0"    # List of network interfaces (lo0 is
loopback).
ifconfig_lo0="inet 127.0.0.1"   # default loopback device configuration.
#ifconfig_fxp0="inet 192.168.3.12  netmask 255.255.255.0"
defaultrouter="NO"              # Set to default gateway (or NO).

这样就需要更改rc.conf文件，更改一些设置语句。首先要注释hostname设置，而在dhclient.script中进行设置，也不必设置defaultrouter，它通过DHCP协议自动设置。同时要保证network_interfaces参数中，设置了要通过dhclient来获取IP地址的网络界面fxp0，以允许rc系统文件能启动该与该界面相关的设置文件，然而却必须注释设置该界面的参数ifconfig_fxp0，因为这个设置参数是用于设置静态IP地址的选项，因此要屏蔽它，而使用start_if.fxp0配置脚本来设置网络界面。

缺省情况下，不存在start_if.fxp0等start_if设置网络脚本，但是这些脚本在rc.network已经做好了设置，针对每个网络界面启动，而不需要在rc.conf中做特别设定。对于dhclient，可以创建一个简单的启动脚本start_if.fxp0为：

#! /bin/sh
/usr/local/sbin/dhclient fxp0

    这样，dhclient就和系统启动文件结合起来了，在系统启动的时候会自动设置好TCP/IP，此后再启动相关的网络服务。此时需要注意的是删除原来可能在rc.local或者在/usr/local/etc/rc.d目录中的dhclient启动命令，以避免冲突。

    在FreeBSD系统上不推荐使用动态IP地址，因为FreeBSD能提供大量有用的网络服务，都会与IP地址或域名有关，不适合使用动态IP地址。如果必须要作为DHCP客户以保持IP地址的统一管理，建议使用dhcpd针对硬件地址的设置方式，在DHCP服务器上为FreeBSD系统设定一个固定IP地址。

  • 设置DHCP中转

    当网络中存在多个子网的时候，由于客户计算机只能通过广播发送DHCP请求，这些请求一般不能跨越路由器。为了在DHCP服务器存在的子网之外的DHCP客户分配IP地址，可以设置路由器转发DHCP请求，即转发相应的UDP
              端口67和68的广播数据包。但这样设置就增加了网络广播，不利于减少网络流量。

    此外，还有另外一种方法来使得DHCP客户计算机能使用子网之外的DHCP服务器来分配IP地址。这就是使用 DHCP中转计算机来转发DHCP的请求。DHCP中转计算机能听取DHCP广播，由于它了解DHCP服务器的IP地址，因此能通过正常的IP数据包将原广播包转发到服务器中，然后再将服务器的回应信息回复客户机。这样DHCP客户机就以为本子网中也存在一个DHCP服务器。

    在ISC-DHCP软件中，提供的中转程序为dhcrelay，这是一个简单的程序，不需要额外的设置。启动 dhcrelay的标准方式为使用命令行指定将DHCP服务请求中转到的目的DHCP服务器，由于DHCP中允许多个
              DHCP服务器同时为客户提供地址，而不会产生冲突，就可以使用多个DHCP服务器进行中转。

# dhcrelay dhcpsrv1 dhcpsrv2

    如果这台中转服务器为多网络界面计算机，那么dhcrelay将侦听所有网络界面的DHCP请求，有时不希望 dhcrelay中转某些界面上的请求，就可以设置dhcrelay侦听的网络界面，这需要指定-i参数。

# dhcrelay -i xl0 dhcpsrv1

  • 提供备份的DHCP设置

    在一个具备多个子网的大型网络中，提供冗余是一个非常重要的问题。由于DHCP协议中DHCP服务器负责分配 IP地址，一旦DHCP服务器出现故障，那么所有的客户就无法正确获得IP地址，从而不能访问网络。

    但可以同时设置多个DHCP服务器来提供一个冗余能力。然而DHCP服务器本身是不提供备份能力的，不能互为备份。他们占用的IP地址资源也不能重叠，以免发生客户机IP地址冲突的现象。提供容错能力是通过分割可用的IP地址到不同的DHCP服务器上，通过多个DHCP服务器同时为一个网络服务，从而使得一个服务器发生故障还能正常执行操作。通常为了进一步增强可靠性，还可以将不同的DHCP服务器放置在不同子网中，互相使用中转提供服务。

    例如在两个子网上各自有一个DHCP服务器，标准的做法可以不使用DHCP中转，各个子网上的服务器为各个子网服务就行了。然而为了达到容错的目的，可以互相为另一个子网提供服务，通过设置中转或路由器转发广播以达到互为服务的目的。

    例如位于192.168.3.0网络上的srv1的配置可能为：

subnet 192.168.3.0 netmask 255.255.255.0 {
        range 192.168.3.10 192.168.3.199;
}
subnet 192.168.4.0 netmask 255.255.255.0 {
        range 192.168.4.200 192.168.4.220;
}

    位于192.168.4.0网络上的srv2的配置可能为：

subnet 192.168.4.0 netmask 255.255.255.0 {
        range 192.168.4.10 192.168.4.199;
}
subnet 192.168.3.0 netmask 255.255.255.0 {
        range 192.168.3.200 192.168.3.220;
}

    注意，上述设置都是设置样例，标准情况下还需分别指定各个option，用于设置IP地址及其相关设置。

    可以看出两个服务器都能对两个网络上的客户机分配IP地址，而各自又有一个主要服务的网络。每个网络上的IP 地址主要放在本地的服务器上，但也有少部分地址放在另一个子网中的服务器上（地址资源不能冲突），这样提供了一定的容错能力。

    实际的多子网网络中，并不必要每个子网都设置一个服务器，并使用另外的服务器备份，一般网络中有2-3个DH CP服务器就够用了。其他子网可以通过DHCP中转的方式，给该子网提供DHCP服务。


FreeBSD连载(73)：认证与加密

王波

第8章 系统与网络安全

    当将计算机连接到Internet上的时候，那么计算机就对整个网络开放连接许可。这在通过网络为用户提供网络服务的同时，也带来了计算机系统会遭受非法使用或破坏的危险。然而既然要对外提供服务，就只能通过维护和管理来增加安全性，而不能因为害怕风险就不提供网络服务。因此安全问题是连接到Internet的网络系统需要特别注意的问题之一。

    毫无疑问，FreeBSD是一种具备相当高的安全性的操作系统，提供了各种不同的访问控制、加密和认证等安全特性。然而，出于使用方便的考虑，FreeBSD并没有将安全问题看作唯一的需求，有些传统Unix提供的服务，虽然会带来一定的安全问题，但也不能简单的屏蔽。假如需要，可以根据具体情况堵上这些具备轻微危险的漏洞，进一步增强安全性。

    FreeBSD不但能对自己系统提供安全保障，也能用作提供网络安全的工具。它的网络能力非常强大，能用于设置功能全面的防火墙系统，保障网络内其他计算机系统的安全性。

  • 网络安全概念

    网络安全的问题随着Internet的发展，也越来越受到人们的关注。这主要原因是由于Internet和Unix 是一个开放的系统，所有的使用者都能对系统进行研究并提出问题，这样就针对安全性提出了很多问题。在Internet 上也发生过相当多的安全问题，使得安全问题进一步为大家所关注。如果基于此就对Internet缺乏信心，也是不必要的，Internet虽然不是一个安全性很高的网络系统，然而也不是象想象的那样不可信赖的，主要是因为Internet 的开放性，使得很多安装问题比较公开。而只要正确使用它，同样也能保证安全性。

    对待安全问题有两种不同的态度，一种为封闭的态度，认为将问题隐藏起来是最好的解决安全问题的办法。隐藏起来不被发现当然就避免了安全问题，然而人们也没有办法去证明不会有人发现这个问题，或者说保证掌握安全漏洞的人不会出于各种考虑而利用这个安全问题。很多商业软件都采用这种态度，事实上很多软件本身安全性很低，到了安全专家和攻击者那里，其漏洞就很容易被发现。另一种更为积极的态度，认为安全问题不应该隐藏起来，只有通过从不了解到了解并解决安全问题的不断的、动态过程，才能真正保证系统的安全性。由于这种态度，一方面系统的使用者至少可以了解哪些是安全的，哪些存在问题，从而避开问题而不必担心被欺骗，同样采用这种方法开发的软件，其安全漏洞能被很快发行并被纠正，如果一个软件经过了众多Internet使用者的考验，其中不乏专家，使用者就不必担心其中还有十分严重的安全漏洞了。

    Unix用户大部分都是持后一种态度的Internet使用者，不断学习是网络安全的一个独立的、而又非常重要的方面。尽管网络上的攻击者能够从Internet上获得关于网络安全漏洞的技术方法，同样管理员也能获得这些技术，并能及时弥补漏洞。事实上很多导致系统漏洞的问题其实是Internet上早以解决的问题，通过参加相关的安全组织或通过网络定期查阅其报告，就能不受这些系统安全漏洞的影响。

    Internet上最著名的一个安全组织是CERT，它提供安全方面的建议，并通过Internet发布报告，这些报告内容包括各种操作系统的问题和漏洞，以及相应的解决办法。其主页为http://www.cert.org ，建议所有关心网络安全的使用者都经常查阅他们提供的资源，从中选择与自己使用的系统相关的内容。

    很多网络安全问题发生的原因不在于入侵者攻击手段的高明，而是由于系统管理员的不称职造成的，而合格的系统管理员能跟踪自己操作系统暴露出来的问题，并根据Internet上的建议堵上这些漏洞，国外的很多公司还聘用专业的网络安全顾问，这些顾问的任务之一就是及时发现系统问题，提示管理员进行系统修正。

  • 认证与加密

    为了区分合法用户和非法使用者，就需要对用户进行认证。标准的Unix认证用户的过程是，用户输入口令，口令传输到系统程序中，由系统程序对口令进行加密，并与系统中的口令密文进行比较来判断口令是否正确。在这种方法中，如果要通过网络认证，就要将口令以明文形式在网络中传输，因此就存在被窃听的危险。

    此外，流行的认证方式还有S/key，Kerberos，Radius等方式，其中S/key是使用一次性的口令，这样即使口令被窃听也无关紧要，其然而使用起来却比较烦琐，使用S/key的用户可能需要打印出长长的口令来帮助输入正确的口令。Kerberos和Radius认证方式能保证口令不被窃听，但他们是在服务器和客户机都支持相应的认证方式的条件下才能使用，因而需要更复杂的设置。

    当前Kerberos V认证方式比较流行，Windows 2000中也将采用这种认证方式。但在FreeBSD 中提供的是Kerberos IV认证方式。需要注意的是，Kerberos V和Kerberos IV差异较大，是两个互不兼容的独立版本。

    通常使用的加密算法为DES算法，经实践证明它是一种很有效加密算法，虽然Unix上使用的密钥长度为56位，还不足够安全。因为在Internet上，已经有人通过多台计算机合作计算，通过几个月时间破解了使用它加密的内容。但对于一般的安全性，加上选择得当的口令，56位的DES算法也足够用了。如果要提供更高的安全性，可以使用更长的密钥，或者使用另外的算法，如IDEA算法、三重DES算法等。

    与安全有关的算法还包括一类单向散列算法，如MD2、MD4、MD5等，这些算法的目的是用于从已有数据中生成与其他数据不同的少量标识数据，从而区分不同的数据，这样就能通过这些标识数据分辨不同数据。由于不同的数据使用上面的算法生成的标识数据只有极少的可能相同，这些算法一般被用于数字签名，用于保证网络中的文件传输没有发生错误。这些算法也能用于口令认证，其中MD4用于认证时存在安全性不高的问题，因而用于认证时一般使用MD5算法。

    FreeBSD缺省使用MD5算法用作口令认证，这并不影响系统的正常执行。

    对于DES等算法来讲，加密和解密是使用同一个密钥，这个密钥必须秘密保存，一旦泄露就不能保证数据的安全，但要让其他使用者获得加密的信息，就必须告诉他这个密钥，这样就很容易泄露密钥。因此在加密传输中，密钥的传输是一个与数据安全非常相关的问题。另一种不同的思路是使用多个密钥，例如两个密钥，一个加密过的数据只能由另一个来解密，其中一个密钥由用户保存，为私有密钥，另一个向所有要进行加密传输信息的使用者公开，称为公开密钥。当他们要向这个用户发送信息时，能使用该用户的公开密钥加密信息，那么只有这个用户能使用自己的私有密钥能解开信息。同样这个用户用自己的私有密钥加密信息，那么其他用户只能使用他的公开密钥才能解开，这样就保证了信息是由这个用户发出的，而不是其他人的伪造信息。最著名的公开密钥加密算法为RSA算法。

    使用公开密钥算法进行传输，就能避免数据被窃听的问题，常用的使用公开密钥算法的软件有ssh，pgp，以及其他使用SSL的应用程序。

    加密算法的选择是一个非常关键的问题，由于加密算法涉及非常高深的数学问题，因此不是任何人都能发明一个加密算法。有的人以为使用一个不公开算法本身的专有加密算法会增加安全性，其实不然，未经验证的加密算法很可能存在漏洞，在专业密码学家那里有很多种方法可以进行破解，在密码学领域内有很多失败的例子，即使是非常专业的密码学专家，发明一种加密方法也不是一个简单的事情，未经验证的算法在其他专业密码学家的破解下，很容易面临失败的危险。因此，应该尽量选择已被证明是成熟的加密方法。


FreeBSD连载(74)：安全问题
王波

安全问题

    当要维护网络安全的时候，需要加以了解的关键问题就是网络漏洞可能存在于位于何处。只有了解攻击者会从何处入手，才能采取相应的措施加强系统的安全。下面部分针对可能存在的安全漏洞进行了简单的概括，这些地方都是网络安全需要注意的方面。

  • 物理安全性：网络窃听与地址欺骗

    物理安全性的安全性非常重要，但这个问题中的大部分内容与网络安全无关，例如如果服务器被盗窃了，其上面的硬盘就能被窃贼使用物理读取的方式进行分析读取。这只是一个极端的例子，更一般的情况可能是非法使用者接触了系统的控制台，重新启动计算机并获得控制权，或者通过物理连接的方式窃听网络信息。

    最近国内报告了几例 “黑客” 事件，攻击者通过将物理线路连接到目的线路上，并利用对这些专有的计算机系统的了解来窃取信息。事实上这种攻击方式不能算一个真正的网络攻击，并不用说网络黑客了。

    在物理安全方面，与网络相关的问题主要在于传输数据的安全性。由于TCP/IP协议是一种包交换网络，各个数据包在网络上都是透明传输的，将经过各个不同的网络，由那些网络上的路由器转发，才能到达目的计算机。由于数据包都是直接经过这些网络，那么这些网络上的计算机都有可能将其捕获，从而窃听到正在传输的数据。这个物理上的传输安全问题对网络安全非常重要，因为当前的TCP/IP协议本身并没有对安全传输进行考虑，很多应用程序，如telnet、ftp 等，甚至使用明文来传递非常敏感的口令数据。获取网络上流过全部数据的方法通常被称为网络分析（sniffing）。

    由于物理网络的传输限制，并不是在网络上的任意位置都能捕获数据包信息的。对于最常用的以太网，较老的共享式以太网能在任意一个位置窃听所有流经网络的信息包，而新式的交换式以太网能够在交换机上隔离流向不同计算机的数据，因此安全性更高。然而无论怎样的网络，路由器总是一个非常关键的位置，所有流入流出网络的数据都经过这个特殊的计算机，如果攻击者在路由器上进行窃听就会造成非常严重的安全问题。

    交换式以太网并不能保证不能百分之百不被窃听，高明的窃听者能通过欺骗以太网交换机来完成窃听的任务，然而这需要针对具体交换机的弱点进行攻击，事实上很难进行。

    防范窃听的方法是对传输的数据进行加密，最简单的情况下就不要使用明文来传输重要的认证信息。在FreeBSD 下可以使用Kerberos认证保证口令传输不被窃听。更进一步，可以使用支持加密传输的应用程序传输重要的数据，如ssh。在数据要通过的不安全网络上设定虚拟专用网也能解决这个问题。当前，从IP层支持数据安全的协议为IPSec ，FreeBSD下也有一个开发组KAME是支持IPSec的（KAME的网址位于http://www.kame.net/ ）。以后会有越来越多的应用程序支持IPSec，不再有传输安全的问题。

    涉及物理安全性的另一个问题是网络地址欺骗，很多网络服务将安全性依赖于区分不同计算机的方式，可信任的计算机能够访问网络资源，不可信任的计算机被拒绝访问。然而非法入侵者可以通过欺骗的方式，使得目的计算机认为它是可信任的计算机，从而达到入侵的目的。

    网络地址欺骗可以分为两种，一种为假冒其他计算机网卡的硬件MAC地址，这样就能使得这台计算机能完全冒充另外那台计算机，突破依赖于MAC地址的访问限制。很多网卡可以通过驱动程序更改MAC地址，操作系统也能通过软件的方法更改其驱动程序中保存的MAC地址。因此MAC地址是不可靠的，不能依赖于它来保护具备敏感性的数据信息。显然，假冒MAC地址方法只能存在于同一个局域网之中，不能跨越网络。

    然而对TCP/IP来讲，通信还是主要依赖于IP地址，因此更普遍的地址欺骗还是要通过假冒IP地址的方法进行的。对于任何操作系统来讲，更改IP地址非常简便。在同一个子网当中，更改IP地址之后，它就能假冒那台被信任计算机。然而在同一个子网之外，假冒IP地址就需要更复杂的技术，首先它需要了解假冒的IP数据包是否能发送到目的计算机上，这需要依赖于它和目的计算机的路由器的设置，很多的路由器不能分辨IP数据包是否是从正确的子网发送出来的（或者没有屏蔽这些非法的IP数据包），这样假冒的IP数据包就能到达目的计算机。由于假冒的IP数据包中的IP地址与发送的计算机不相符，因此回应的数据包不会返回假冒IP地址的计算机，这样就需要假冒的计算机只能依靠猜测来攻击目的计算机。

    在地址欺骗中，如果要被假冒的计算机正在运行，势必要发生冲突。入侵者为了避免出现这些问题，可能会首先攻击要被假冒的计算机，使其当机或超负荷运行，而不能响应服务请求。然后才能无妨碍的进行攻击过程。

  • 操作系统安全性：软件BUG和后门

    任何软件系统都可能存在种种系统漏洞，提供相应服务的同时也就可能暴露某个问题。由于FreeBSD继承了非常成熟的BSD代码，以及采用了开放源代码的策略，FreeBSD是非常安全的系统，然而这也不能绝对保证系统中没有问题存在。而那些不公开代码的商业软件，由于测试远远少于开放代码的软件，就可能存在更多的问题。因而，入侵者就能利用这些漏洞来侵入计算机，或者利用这些漏洞破坏计算机。

    但还没有登录入这台计算机的攻击者，他们会扫描这台计算机的端口，以寻找这台计算机提供的网络服务，然后从这些网络服务出发，寻找提供这些网络服务的系统守护进程的漏洞，进而入侵系统。

    事实上Internet网络中充斥着这些端口扫描程序，在国内，大部分端口扫描程序是用来寻找代理服务器的，由于国内网络的现状（CERNET中出国访问按流量收费），这些行为虽然也是为非法使用代理服务器做准备，然而也是值得原谅的。

    对于已经进入这台计算机的入侵者，由于一般情况下入侵者进入系统只能获得普通用户的权限，并不能控制系统。入侵者需要获取更大的权利，来控制整个系统。Unix下root用户具备最大的权限，能完成所有可以执行的操作，因此就是入侵者攻击的目标。能获得root用户的权限的基本方法是通过执行root用户拥有的、并且具备SetUID属性的执行程序，一般这些程序只完成特定操作，或者也要预先验证用户的身份，因此入侵者并不能直接得逞。然而如果这些SetUID 的程序存在漏洞，那么入侵者可以通过缓冲区溢出等手段，使这些程序执行入侵者设定的非正常操作，来达到获得root 身份的目的。此外，得到root身份还能通过系统驱动程序的漏洞、以root用户权限执行的守护进程漏洞等方法达到目的。

    SetGID的程序不能使入侵者得到root权限，但可以使入侵者得到其他非法权限，使得入侵者能完成更多的操作，为获得root权限起到辅助作用。

    除了这些利用软件漏洞的方法之外，入侵者还可以通过欺骗用户，使其执行入侵者的程序，来达到获得非法权限的目的。这些入侵者的程序是一些特洛伊木马程序，它模仿正常程序的行为，但暗中窃取了口令等重要的数据。入侵者常常设定特洛伊木马来获得更大的权限。

    为了预防这些安全问题，需要尽量减少计算机提供的服务数量，不必要的服务就不要提供。同时尽量减少系统中存在的SetUID、SetGID程序的数量，不要执行未经验证的程序，尤其不能以root身份执行。

    一些软件能比系统提供的软件提供更详细的访问记录和更细致的访问限制，以增加网络安全性。例如tcp wrapper ，sudo等。另一些软件能自动分析计算机提供的服务中存在的漏洞，因而能帮助系统管理员及时弥补被发现的漏洞。如Satan、Cops等。

  • 服务阻塞

    服务阻塞技术并不一定要利用系统的漏洞，它可能只利用了系统提供的正常功能。很多情况下，提供服务并没有对使用服务的使用者占用的资源进行限制，允许用户使用尽可能多的资源。这因为服务器信任使用它的用户，然而恶意的攻击者能通过自己不停的申请并占用系统资源，使得服务器不能正常向外提供正常服务，或者当机。

    在操作系统中也存在这种攻击方式，例如一个用户不断占用磁盘空间，直至系统空间被填满，其他需要空间的用户就不能正常工作。或者一个用户不断生成子进程，直至系统进程表被填满，其他用户无法启动进程为止。

    优秀的系统和服务程序，应该考虑到这些问题，因此也可以认为这种问题属于软件设计考虑不周，然而这毕竟与软件漏洞还是有所不同。如果一个服务程序过多的考虑了各种资源的限制，其效率和可用性都会大大减低的。

    在服务阻塞方面的网络攻击方法被外部入侵者常用的是IP-SYN攻击，它能使计算机的TCP/IP堆栈处于拥塞状态，而无法正常相应其他请求。


FreeBSD连载(75)：防火墙技术
王波

防火墙技术

    将本地网络连接到Internet之后，Internet上的计算机就能自由访问本地网络中的计算机了。显然，由于本地网络属于同一个组织，本地网络中的计算机相互之间都可以信任，而外部Internet上的计算机可能来自任意地方，因此不可信任。如何给可信任的本地网络中的计算机提供资源，而不给其他Internet上的计算机提供访问或入侵的机会，同时又不妨碍本地网络中的计算机正常访问Internet，就成为了建立内部网络的一个要求。

    当然，针对每个计算机进行设置，也可以达到屏蔽外部网络访问的目的。然而这样做一方面不太方便，对每个计算机都要进行设置，另一方面不太安全，内部网络中不是每台计算机使用的操作系统都具备良好的保护措施，而外部网络中的计算机可以通过这些不安全的操作系统进入内部网络，提供了攻击的途径。因此更好的办法是御入侵者于网络之外，在内部网络和外部网络中架设一个防火墙，所有的访问都需要经过它进行验证，对内部网络提供了保护作用。

  • 包过滤技术

    为了对内部网络提供保护，就有必要对通过防火墙的数据包进行检查，例如检查其源地址和目的地址、端口地址、数据包的类型等，根据这些数据来判断这个数据包是否为合法数据包，如果不符合预定义的规则，就不将这个数据包发送到其目的计算机中去。由于包过滤技术要求内外通信的数据包必须通过使用这个技术的计算机，才能进行过滤，因而包过滤技术必须用在路由器上。因为只有路由器才是连接多个网络的桥梁，所有网络之间交换的数据包都得经过它，所以路由器就有能力对每个数据包进行检查。

    通常的路由器都支持基本的包过滤能力，路由器在转发IP数据包的时候，缺省状态并不涉及数据包中的内容，只是按照IP包的目的地址和本身的路由表进行转发。为了使得它进行包过滤，就必须定义一系列过滤规则，使得路由器能进行过滤。通常情况下，过滤能针对IP地址、端口地址、连接类型等进行设定，还能够针对数据包进行转发，将数据包转发到合适的计算机中。

    在包过滤的条件下，内部网络的计算机还是直接和外部计算机相通信的。由于这是直接在IP层工作，可以适合所有的应用服务，灵活性和效率都较高。但也存在缺点，比如不能了解应用协议的具体形式，也不能提供清晰的日志记录等。

  • 代理服务

    代理服务是另一种防火墙技术，与包过滤不同，它直接和应用服务程序打交道。它不会让数据包直接通过，而是自己接收了数据包，并对其进行分析。当代理程序理解了连接请求之后，它将自己启动另一个连接，向外部网络发送同样的请求，然后将返回的数据发送回那个提出请求的内部网计算机。

    虽然代理服务器不必连接到两个网络上就能提供代理服务，然而要想通过代理服务器限制网络之间的通信，提供代理服务的计算机必须连接到两个网络上，所有的网络之间通信都需要通过它的代理才行，而不能直接连接到Internet上。因此代理服务器也不能打开包转发能力，如果代理服务器同时也是路由器，那么内部计算机就可以通过它的路由能力而非代理能力在不同的网络之间通信，代理服务器就起不到防火墙的作用。除非特定情况下，才能设置路由能力，此时也应该配置了更严格的包过滤规则，以保护网络安全。

    在有代理服务的情况下，内部网络的计算机必须配置具体的代理服务使用的代理服务器，它只同代理服务器打交道，而由代理服务器发送请求并返回结果。代理服务器必须要了解它要代理的服务，并为每一种服务都提供详细的访问日志记录，并能针对不同的使用者进行认证。

    一般来讲，由于代理服务器要针对一个请求启动一个代理服务连接，因此代理服务器效率不高，但是如果针对具体的服务应用，可以在代理服务器上配置大量的缓冲区，通过缓冲区可以提高其工作效率，提供更高的性能。例如对于使用HTTP 代理服务器时，代理服务器就能在缓冲区中查找到同样的数据，因而不必再次访问Internet，减少了对宝贵的Internet 带宽的占用。代理服务器不仅是一个防火墙技术，它还能用来提高访问Internet的效率。

    常用的代理服务器有http代理，ftp代理等，所有的代理服务能力都需要客户软件的支持，这也意味着当用户要使用代理功能的时候，需要设置客户软件，如浏览器，如果客户软件不支持代理功能，就无法使用代理服务器。然而，为了减轻配置负担、利用代理服务器的缓冲能力，可以设置一种透明代理服务器，这种方式不需要设置客户软件，通过设置路由器，将本来发送到其他计算机的IP数据包，依据IP地址和端口转发到代理服务器中。

  • 网络地址翻译

    在TCP/IP开始开发的时候，没有人会想象到它发展的如此之快。当前使用的IPv4地址空间为32位大小，因而地址资源已经十分紧张了。而下一代的IPv6还没有得到大家的认可。FreeBSD虽然有支持IPv6的开发计划，正由于整个Internet上IPv6还没有实施，因此FreeBSD还没有将以开发的IPv6合并入正式发布的系统中去。

    为了解决地址紧张的问题，提出了网络地址翻译（Network Address Translation, NAT）的方法。NAT能处理每个IP数据包，将其中的地址部分进行转换，将对内部和外部IP进行直接映射，从一批可使用的IP地址池中动态选择一个地址分配给内部地址，或者不但转换IP地址，也转换端口地址，从而使得多个内部地址能共享一个外部IP地址。

    动态分配外部IP地址的方法只能有限的解决IP地址紧张的问题，而让多个内部地址共享一个外部IP地址的方式能更有效的解决IP地址紧张的问题。让多个内部IP地址共享一个外部IP地址，就必须转换端口地址，这样内部不同IP 地址但具有同样端口地址的数据包就能转换为同一个IP地址而端口地址不同，这种方法又被称为端口地址转换（Port Address Translation, PAT），或者称为IP伪装（IP masquerading）

    网络地址翻译也是一个重要的防火墙技术，因为它对外隐藏了内部的网络结构，外部攻击者无法确定内部计算机的连接状态。并且不同的时候，内部计算机向外连接使用的地址都是不同的，给外部攻击造成了困难。同样NAT也能通过定义各种映射规则，屏蔽外部的连接请求，并可以将连接请求映射到不同的计算机中。

    网络地址翻译都和IP数据包过滤一起使用，就构成一种更复杂的包过滤型的防火墙。仅仅具备包过滤能力的路由器，其防火墙能力还是比较弱，抵抗外部入侵的能力也较差，而和网络地址翻译技术相结合，就能起到更好的安全保证。

  • 主动监测技术

    无论是包过滤，还是代理服务，都是根据管理员预定义好的规则提供服务或者限制某些访问。然而在提供网络访问能力和防止网络安全方面，显然存在矛盾，只要允许访问某些网络服务，就有可能造成某种系统漏洞，然而如果限制太严厉，合法的网络访问就受到不必要的限制。代理型的防火墙的限制就在这个方面，必须为一种网络服务分别提供一个代理程序，当网络上的新型服务出现的时候，就不可能立即提供这个服务的代理程序。事实上代理服务器一般只能代理最常用的几种网络服务，可提供的网络访问十分有限。

    为了在开放网络服务的同时也提供安全保证，必须有一种方法能监测网络情况，当出现网络攻击时就立即告警或切断相关连接。主动监测技术就是基于这种思路发展起来的，它维护一个记录各种攻击模式的数据库，并使用一个监测程序时刻运行在网络中进行监控，当一旦发现网络中存在与数据库中的某个模式相匹配时，就能推断可能出现网络攻击。由于主动监测程序要监控整个网络的数据，因此需要运行在路由器上，或路由器旁能获得所有网络流量的位置。由于监测程序会消耗大量内存，并会影响路由器的性能，因此最好不在路由器上运行。

    主动检测方式作为网络安全的一种新兴技术，由于需要维护各种网络攻击的数据库，因此需要一个专业性的公司维护。理论上这种技术能在不妨碍正常网络使用的基础上保护网络安全，然而这依赖于网络攻击的数据库和监测程序对网络数据的智能分析，而且在网络流量较大时，使用sniffing技术的监测程序可能会遗漏数据包信息，因此这种技术主要用于要求较高，只用于对网络安全要求非常高的网络系统中，常用的网络并不需要使用这种方式。


FreeBSD连载(76)：设置基本系统

王波

    FreeBSD系统是一种安全性非常好的通用操作系统，在Internet上很少发生FreeBSD系统被攻击的报告，事实上最近一端时间内CERT的安全报告中几乎没有发生在FreeBSD系统上的安全报告。一方面是因为 FreeBSD安全性很好，另一方面也是由于FreeBSD用户对于系统安全比较了解的缘故。

    与其他Unix系统相比，FreeBSD系统的传统味道更足一些，设计者以追求完美的态度去完成每一种设计，稳定性和安全性就是其中的重要因素。因此，初始安装好的FreeBSD系统已经具备比较高的安全性，一般用户不需要特别设置，便具备了相当高的安全性。而且经过一些简单的设置之后，安全性可以更高。一些商业操作系统软件声称经过了某个安全认证，其实这些认证也只是保证最基本的安全性。当前的各种Unix版本（不包括较老的版本）经过一些设置工作，同样也能达到通过测试目的，只是包括FreeBSD在内的自由软件系统，没有资金、也没有必要去参加这类测试。

    对系统安全要求更高，而又不打算自己调整系统设置的使用者，可以选择另一种BSD Unix──OpenBSD ，它使用最大安全性的策略，其缺省设置中应用了大量的系统安全措施，也因为如此，它稍微难用一些。

  • 设置基本系统

    增强FreeBSD的安全性可以从两个方面出发，一个为使用FreeBSD提供的安全措施，这些安全措施可能在缺省情况下可能并没有打开，但能够提供额外的安全性。另一种为安装其他辅助的安全软件，这些额外的软件可以在特定方面增加系统安全，或帮助检查系统安全的工具。

  • 用户登录控制

    为了提高系统的安全性，一个重要的方面就是区分不同的用户，对于要使用不同服务的用户区别对待。有些用户只使用远程登录服务的就不必具备控制台访问的权限，有些用户只在某些子网上使用系统的就不必允许在任何位置进行登录，有些帐户只是用于系统维护目的，没有任何使用者需要使用相应帐户登录，就不必允许登录请求。

    当区分不同用户的情况，最大限度的提供了登录限制之后，就能对入侵者利用窃取的帐户从其他位置进行攻击设置了障碍，提供更大的安全性。

  • 控制台安全控制

    系统的控制台是一个非常重要的安全弱点所在的位置，因为一个使用者能接触控制台，那么就表示他得到管理人员的特殊信任。系统缺省赋予了控制台终端以较大的安全信任。此外，接触控制台还能从物理上访问系统硬件，包括重新启动系统、将硬盘窃取分析其中的数据等等。然而，物理安全等措施不是在这里要讨论的内容。

    为了避免偶然的非法访问控制台造成的安全问题，所需要设置的第一件任务就是取消控制台的信任设置，这个设置位于/etc/ttys中。

console none     unknown off secure

    初始设置为secure表示root用户可以在控制台登录，另外，它还表示系统重新启动之后，如果管理员要求进入单用户状态，将不询问root的口令进行验证，这是一个重要的安全漏洞。将secure更改为insecure可以使得进入单用户状态时首先验证root口令，它带来的后果是，一旦系统损坏了passwd文件（主要是master.passwd
              文件），root口令无法认证，就没有办法进入单用户状态进行修复工作，此时使用安装盘启动fixit 系统进行才能进行修正。

    使用另外一个运行在软盘上的小FreeBSD系统也能完成修复系统的任务，后面将介绍定制单软盘FreeBSD 系统的方法，这种小系统被称为PICOBSD，可以用于设置网关或防火墙，以及可以用作专有系统的嵌入式操作系统。

    此外，为了防止用户无意中重新启动系统，还需要取消Ctrl-Alt-Del热键的重新启动能力，这需要重新定制内核时使用以下选项。

options		SC_DISABLE_REBOOT

    注意，这是针对使用标准控制台syscon的系统才有效果。

    当屏蔽了系统的热启动能力，那么重新启动或关闭系统便需要使用系统命令来完成，此时能启动系统的使用者便需要 root权限。而root口令知道的人越多，系统越不安全。此时可以使用软件包sudo来帮助解决这个问题，sudo
              能限制某些特定用户使用root权限完成指定的操作，它使用用户本身的口令，而非root口令验证用户。

    即使屏蔽了热启动能力，并且重新启动进入单用户状态也需要询问口令，系统仍然存在安全性问题。非法使用者可以首先切断电源，然后使用安装盘或其他不使用现有文件系统的FreeBSD系统盘启动系统，获得相关数据，或更改pas
              swd文件，以便在重新启动之后获得root权限。保护这些攻击，需要其他手段，例如设置计算机的启动口令，拆除系统上的软盘驱动器、光盘驱动器等。然而，对于能进行物理攻击的入侵者，他的行为就如同一个正常系统管理员修复系统的行为一样，没有绝对的办法能杜绝这样大胆妄为的举动。

    如果管理员不能信任计算机系统的物理安全，为了防止信息外泻，唯一的方法是进行加密，可以通过Unix命令crypt 对具备敏感信息的文件加密。然而更简便的方法是使用一种加密文件系统，这类加密文件系统对于正常操作就如同标准文件系统一样，对任何应用程序的文件操作完全透明，然而数据是以加密方式保存到物理设备中。而且在网络中传送的也都是加密后的密钥，不必担心泄露密钥。FreeBSD下可以使用的加密文件系统为TCFS，但它这不是FreeBSD的标准配置，需要从http:// tcfs.dia.unisa.it/中单独获得。

  • 登录控制

    •

    为了加强控制台的安全，还应该阻止一般用户在控制台上登录入系统。为了达到这个目的，需要设置登录访问限制文件/etc/login.access。该文件由login程序读取，限制用户的登录位置，该文件中具备下面语句将屏蔽除了wheel组、admin之外的用户在console登录的权力。

-:ALL EXCEPT wheel admin:console

    第一个字符“-“号，用于指明该句是用于屏蔽，相反，“+“用于打开登录许可，由于这个文件主要用于控制登录位置的目的，所以打开登录许可的方式很少用得到。此后用冒号分隔的第二部分为帐号域，可以使用用户名和组名，以及使用
              login.access的关键字All、ALL EXCEPT等定义用户。第三部分为登录位置，这里仅仅用于限制console。

    这个文件不但能用来限制在控制台登录，也能用来限制从其他位置登录入系统，还可以限制一些帐户在所有的位置都不能登录，这样就能更好的保证安全性。

-:wheel:ALL EXCEPT LOCAL .local.net

    这句设置了对管理员组wheel的登录位置限制，只能在本地或者本地的local.net域内计算机上建立登录连接。设置对能执行特定操作管理员的登录限制也能增强系统安全性。

-:daemon bin lpd nobody nogroup:ALL

    这个设置限制一些特殊的系统用户在所有节点上都不能登录，系统中的很多帐户事实上是用于系统维护的目的，并没有任何用户需要使用他们登录，显然这也能增加安全性。

    然而，使用login.access并不能表示该帐户就无法被非法使用了，很多网络服务不使用这个文件进行用户限制，而是使用自己的用户限制方式，因此入侵者可以通过这些网络服务攻击相关帐户。入侵者也可以通过先以其他用户身份登录，再使用su命令绕过这个限制。所以使用这个限制文件并不是一劳永逸的做法，事实上在保证网络安全方面，不存在百分之百的解决方案，只能通过各个方面配置，尽量提高安全性。

    即使提供了有效的登录控制，对于某些不必要的缺省帐户或长期不再使用的帐户，最好还是将其删除，以最大可能的避免安全问题。例如用于UUCP的帐户uucp，只有很少的系统需要这个帐户。可以放心的是，FreeBSD系统中不存在没有口令保护的缺省帐户，这将满足一般用户的安全需要。

  • 安全认证方式

    •

    由于FreeBSD是一个多用户系统，不但能由控制台用户使用，还可以通过网络，提供其他用户使用。而允许其他用户通过网络使用系统的时候，必须要对用户进行验证。此时的一个重要的安全问题就是口令以明文形式在网络中传输的问题。

  • S/key和Kerberos

    •

    为了避免口令被窃听，有很多解决方法可以避免这个问题。一个很有意思的解决方法是使用一次性的口令系统，如 S/key，即使口令被窃听也不会对安全造成影响。FreeBSD缺省就支持S/key系统，每个用户都可以选择是否使用这个系统保证自己的口令安全性。为了使用S/key系统，首先需要使用keyinit初始化针对这个用户的口令串。

bash-2.02$ keyinit
Updating wb:
Old key: de415501
Reminder - Only use this method if you are directly connected.
If you are using telnet or rlogin exit with no password and use keyinit -s.
Enter secret password:
Again secret password:
ID wb s/key is 99 de415502
GAS SAM RUSK BASH NEWS WAIT

    由于这个命令是用于初始化S/key系统，要输入一个S/key口令短语（这个口令可以设置的非常长，通常建议使用一个句子以保证安全性），这个口令将影响以后产生的一次性口令，因此这个命令应该在一个安全连接的终端上（如控制台）执行，而不应该在通过普通telnet等网络连接的登录会话上执行。在两次输入S/key的口令之后，keyinit
              将产生第一个一次性口令，keyinit输出的最后一行就是这个一次性口令，上面的ID行中的99指一次性口令的序列号，de415502是这个一次性口令对应的
              “种子” 。口令的 “种子” ，和S/key口令短语相结合就用于产生不同的一次性口令序列。

    当使用了keyinit初始化S/key之后，就可以立即使用S/key一次性口令登录了。也可以使用key 命令产生其他一次性口令，这需要指定一次性口令的序列号和种子。

bash-2.02$ key 99 de415502
Reminder - Do not use this program while logged in via telnet or rlogin.
Enter secret password:
GAS SAM RUSK BASH NEWS WAIT

    key将提示用户输入口令短语，因此这个命令也不应该通过网络来使用，只能用于直接连接的时候。然而不必为此担心，因为无论在那台计算机上，使用同样的序列号、种子和口令短语产生的口令序列都是同样的，因此可以在本地计算机上，产生用于远程FreeBSD计算机登录的一次性口令。

    注意，S/key系统用于产生一次性口令使用的单向Hash函数可能不同，最常用的有MD4、MD5和DES 算法，使用不同算法产生的一次性口令序列不会相同。FreeBSD的S/key系统使用MD4算法，因此如果要在客户计算机为FreeBSD服务器产生S/key一次性口令，需要使用采用MD4算法的key程序。

    这样当系统进行认证时，将提示skey序列号和种子。这样用户就能使用正确的一次性口令登录了。一旦一个口令用过，这个口令就不再被使用，而使用下一个序列号的口令。

Login: wb
s/key 99 de415502
Password:

    由于每次使用过的口令将不再使用，而通过S/key认证的连接本身是不安全的连接，不应该用于再次产生新口令。那么如果仅通过本地计算机产生S/key口令，就限制了客户机上必须安装有S/key系统。事实上可以在建立安全连接的时候，一次可以产生多个S/key一次性口令，将这些口令记录或打印在密码本上，随用随查，只要密码本不丢失，就没有口令泄露的问题。产生多个S/key一次性口令需要使用-n参数执行key：

bash-2.02$ key -n 5 80 de415503
Reminder - Do not use this program while logged in via telnet or rlogin.
Enter secret password:
76: FIR SIGH BABE SUNG FUSS BAY
77: SOCK HOME WAGE CAN BALL WORE
78: DORA JUNO JAY YET HEAD SLUR
79: COWL TROY HURT SLAB SCAR GAGE
80: TOE BAKE FRAU PEG DOE I

    这将产生5个一次性口令的序列，80为口令序列的结束序号。此后需要经常更新所使用的口令序列，即更改 S/key的种子，以产生新的口令序列。

    更改S/key种子仍然还需要使用keyinit命令，然而此时有了一次性口令，就不需要在安全的终端上进行了，需要使用-s参数，使得keyinit使用一次性口令来获得S/key口令短语，而不必直接输入S/key口令短语。只要保证S/key口令短语的安全，就能保证整个S/key一次性口令序列不会被再现。

bash-2.02$ keyinit -s
Updating wb:
Old key: de415502
Reminder you need the 6 english words from the key command.
Enter sequence count from 1 to 9999: 100
Enter new key [default de415503]:
s/key 100 de415503
s/key access password: GAS SAM RUSK BASH NEWS WAIT

ID wb s/key is 100 de415503
GAS SAM RUSK BASH NEWS WAIT

    keyinit -s命令中，需要输入一次性口令序列中口令的数量，以及新种子的值。而用于认证的S/key 一次性口令为提示的一次性口令，这里为de415503，序列号为100。

    需要注意的是，缺省情况下即使使用S/key认证，原有的Unix口令认证方式仍然有效，如果S/key认证不成功，系统就接下来使用原有的老Unix口令认证方式。对于一些图形界面的应用程序，不能提示S/key口令的序列号，那么用户也无法输入正确的一次性口令，此时使用老口令就有必要了。

    然而，也能限制用户必须使用S/key口令，不能使用普通Unix明文口令，以更大程度上增强安全性。为了强制用户使用S/key口令，需要创建一个/etc/skey.access文件。

# touch /etc/skey.access

    当存在这个文件时，S/key认证系统就不再调用标准Unix认证系统。然而这个文件中可以设置一些例外的情况，允许使用Unix认证系统，例如在内部网络中允许使用Unix明文认证系统，等等。针对IP地址、用户和终端来设置可以使用Unix明文认证系统的权力。针对用户打开这个设置的情况一般是因为该用户不需要特别安全的情况，针对终端打开这个设置的情况通常发生在拨号访问FreeBSD系统的情况，由于认证口令不通过网络，因此也不需要
              S/key加密。

permit internet 198.162.0.0 255.255.0.0
permit user aaa
permit port ttyd0

    对于一些需要自动进行认证的应用程序，需要将口令暂时保存起来，定时自动进行认证工作，但由于S/key的口令是一次性方式的，而客户软件不能根据S/key的提示，输入正确的口令，此时使用老口令也是必要的。如有些使用POP3
              协议的客户端能定时从邮件服务器中下载邮件，这样就必须使用标准Unix口令。显然这明显是一个非常严重的安全漏洞，特别是明文口令不但是在网络上传输，而且是定时、多次传输的时候，问题更为明显。对于这样的情况，最好立即转换为支持加密口令的协议，对POP3来讲可以使用APOP协议。

    FreeBSD下使用的另一种安全认证方式为Kerberos方式，这是一种安全的认证模式，然而它需要客户和服务器都支持这个认证方式才行。当前流行的Kerberos为Kerberos
              V，而FreeBSD下使用的为Kerberos IV ，因此与其他Kerberos客户存在兼容的问题，使得这个认证系统大部分情况下用于多台FreeBSD
              系统之间进行认证。这里就不再介绍其使用方法了，需要使用这个能力的用户可以查看FreeBSD Handbook ，以获得相关的内容。

    FreeBSD下也可以安装Kerberos V认证系统，它位于Posts Collecion中的sec urity部分中。

  • 可加载认证模块PAM

    •

    3.1-release之后的FreeBSD版本支持可加载的认证方式模块PAM，这种机制能使得系统能非常灵活的支持多种认证方式，具备非常大的可扩展性。PAM的设置文件为/etc/pam.conf，这里定义了各种条件下使用的认证方式。

# Configuration file for Pluggable Authentication Modules (PAM).
#
# This file controls the authentication methods that login and other
# utilities use.  See pam(8) for a description of its format.
#
# Note: the final entry must say "required" -- otherwise, things don't
# work quite right.  If you delete the final entry, be sure to change
# "sufficient" to "required" in the entry before it.
#
# $FreeBSD: src/etc/pam.conf,v 1.1 1998/11/20 23:20:01 jdp Exp $

# If the user can authenticate with S/Key, that's sufficient.
login	auth	sufficient	pam_skey.so

# Check skey.access to make sure it is OK to let the user type in
# a cleartext password.  If not, then fail right here.
login	auth	requisite	pam_cleartext_pass_ok.so

# If you want KerberosIV authentication, uncomment the next line:
#login	auth	sufficient	pam_kerberosIV.so		try_first_pass

# Traditional getpwnam() authentication.
login	auth	required	pam_unix.so			try_first_pass

    这是系统缺省的pam.conf文件，这里定义了三个认证过程，按照顺序系统将首先使用pam_skey.so ，然后pam_cleartext_pass_ok.so，最后是标准unix认证pam_unix.so。第一个是用于使用S/key系统认证，第二个不是一个认证，而是用于限制用户访问的，它检查/etc/skey.access
              ，以禁止非许可的节点、用户登录，因此其第三个参数为requisite，而非pam_skey.so对应的sufficient ，如果第二个设置许可，才能进入第三项定义的标准Unix认证方式。

    注意，如果存在/etc/pam.d目录，PAM将在这个目录中寻找设置信息，而忽略pam.conf。

    这些认证系统的动态连接库均位于系统中的/usr/lib/目录下，如果需要，可以增加其他认证方式。

# ls -l /usr/lib/*pam*
-r--r--r--  1 root  wheel  59938 Feb 15 18:41 /usr/lib/libpam.a
lrwxrwxrwx  1 root  wheel     11 Apr 14 16:24 /usr/lib/libpam.so -> libpam.so.1
-r--r--r--  1 root  wheel  33451 Feb 15 18:41 /usr/lib/libpam.so.1
-r--r--r--  1 root  wheel   2895 Feb 15 18:41 /usr/lib/pam_cleartext_pass_ok.so
-r--r--r--  1 root  wheel   6587 Feb 15 18:41 /usr/lib/pam_radius.so
-r--r--r--  1 root  wheel   3798 Feb 15 18:41 /usr/lib/pam_skey.so
-r--r--r--  1 root  wheel   6497 Feb 15 18:41 /usr/lib/pam_tacplus.so
-r--r--r--  1 root  wheel   3333 Feb 15 18:41 /usr/lib/pam_unix.so

    其中每个以pam_开头的库均对应一种认证方式，可以看出系统中还能提供其他几种认证方式，如RADUIS、 TACPLUS等方式。使用libpam能帮助用户开发其他PAM认证程序。

    PAM是一种新的、更为灵活的认证机制，以前的FreeBSD版本并不支持这种方式。PAM虽然更为灵活，但对于一般目的，缺省的支持s/key和标准认证方式的设置就能满足需要了，一般不必改动配置文件。然而有些时候，譬如
              ISP，通常使用RADUIS服务器来保存用户的认证数据，此时使用RADUIS进行认证就能带来非常大的益处。因为 PAM涉及系统认证，因而对安全性非常重要，不能轻易加入一个非信任的认证模块，因为除了模块本身的问题之外，认证模块中很容易加入后门。建议经常检查/etc/pam.conf，/etc/pam.d/目录，以及/usr/lib/*pam*
              文件是否被非法改动，以保证系统安全。

  • 网络服务与应用程序安全

    •

    由于提供服务与保障系统安全性是有冲突的，提供的服务越多，就会存在越多的潜在的危险性。因此为了增加系统安全，就要尽量减少系统提供的服务。

    提供网络服务的守护进程主要有两种启动方式，一种为从系统启动文件中启动，另一种为通过inetd超级守护进程启动应用程序。

  • 系统rc文件

    •

    通常的系统启动文件启动的守护进程有sendmail、syslogd、lpd等，要改变系统启动的服务进程，需要更改的文件包括/etc/rc.conf、/etc/rc.local，以及/usr/local/etc/rc.d
              与/usr/X11R6/etc/rc.d目录下的以.sh结尾的启动文件（这两个启动脚本目录是由rc.conf 中的local_startup定义，因此也有可能被设置为了其他的值）。除非特殊情况，其他的rc文件不应该被改动，如果其他的rc文件被非法更改，很可能是入侵行为。

    特别需要注意/etc/default/rc.conf，/etc/rc.conf.local文件，因为这些文件也能用于设置启动服务，而不被管理员所注意，因此可能是入侵者用于放置后门程序的位置。

    为了减少守护进程，就需要将rc.conf中相关选项设置为NO，例如要屏蔽sendmail，就可以设置 sendmail_enable=”NO”。此外，缺省的rc.local文件中没有内容，因此在这里也不应该有降低系统安全的设置，/usr/local/etc/rc.d/和/usr/X11R6/etc/rc.d/目录下的执行脚本为安装其他软件包时所安装的，对于不希望提供的网络服务，应该将执行脚本更改为以其他后缀结尾的文件，只有以
              .sh结尾的执行脚本才会在启动时自动执行。

    一个安全的FreeBSD系统，应该具有干净的rc.local文件，/usr/local/etc/rc.d 与/usr/X11R6/etc/rc.d目录，以及尽量减少基本启动进程的rc.conf文件。

    守护进程直接放在rc文件中启动，将具备root的权限，危险性较大。如果能使用用户的身份可以执行守护进程的相应操作，就应该使用用户的身份执行它。这可以通过使用su命令启动服务进程的方式，代替直接启动服务进程的命令。

su user services_process

  • inetd服务器

    •

    然而，Unix系统中绝大多数服务进程还是通过超级服务器进程inetd来启动的。它的设置文件为/etc/inetd.conf
              ，以下为这个文件的一部分。

#
#	$Id: inetd.conf,v 1.30 1998/09/30 16:12:40 wosch Exp $
#
# Internet server configuration database
#
#	@(#)inetd.conf	5.4 (Berkeley) 6/30/90
#
ftp	stream	tcp	nowait	root	/usr/libexec/ftpd	ftpd -l
telnet	stream	tcp	nowait	root	/usr/libexec/telnetd	telnetd
shell	stream	tcp	nowait	root	/usr/libexec/rshd	rshd
login	stream	tcp	nowait	root	/usr/libexec/rlogind	rlogind
finger	stream	tcp	nowait/3/10 nobody /usr/libexec/fingerd	fingerd -s
#exec	stream	tcp	nowait	root	/usr/libexec/rexecd	rexecd
#uucpd	stream	tcp	nowait	root	/usr/libexec/uucpd	uucpd
#nntp	stream	tcp	nowait	usenet	/usr/libexec/nntpd	nntpd
comsat	dgram	udp	wait	root	/usr/libexec/comsat	comsat
ntalk	dgram	udp	wait	root	/usr/libexec/ntalkd	ntalkd

    这个文件中的每一行对应一个服务程序。为了增强系统安全，建议除了必要的服务，如telnetd、ftpd之外，其他比如rshd、rlogind等r命令服务程序，fingerd等守护进程都应该加以注释。telnet和ftp
              也应该与S/key等认证方式相结合，来保证口令的安全性。除非需要，不要提供匿名ftp服务。

    当使用rlogin,rsh等r命令的时候，/etc/hosts.equiv文件和用户个人目录下的.rhosts 文件中的设置将对系统安全有严重的影响。

    如果要求更安全的系统，甚至可以屏蔽inetd，不使用inetd来提供任何服务,通过其他安全途径来完成远程访问FreeBSD。要屏蔽inetd，需要在rc.conf中改变inetd_enable变量的值为NO。即使使用inetd的时候，最好让inetd记录相关日志，这需要使用参数-l启动inetd，在rc.conf中可以设置inetd_flags为”-l”。

    当需要启动某个守护进程的时候，inetd.conf中的第五列参数对安全性有重要影响，这个参数设置启动这个进程的用户标识，应该尽量不要使用root用户，以减少具备root身份的进程。

    为了避免服务程序出现问题，还要经常更新软件的版本，或应用补丁程序，以堵上可能出现的漏洞，因此有些服务程序的老版本存在已经发现的安全问题，如果不及时弥补，入侵者就能利用这些漏洞达到入侵系统的目的。虽然每个FreeBSD
              版本使用的都是最新版本的服务软件，但服务器软件是不断升级的，因此就需要及时升级服务器软件。

    在inetd启动的服务中，telnetd和ftpd是最重要的两个，它们提供最基本的网络服务。telnetd 本身的安全问题较少，与它相关的安全问题有访问认证问题，可以通过S/key，login.access等方式加以保护，而ftpd则的安全问题就更为敏感一些。

    如果需要启动ftp服务，虽然在inetd.conf中启动ftpd已经使用了-l参数，使ftpd将日志记录发送给syslogd，但是还需要配置syslogd才能接收ftpd发送的记录。如果/etc/syslog.conf
              文件中没有下面的设置行用于记录ftp的日志，请修改syslog.conf加入。

ftp.*           /var/log/ftpd

    然后还需要执行下列命令，使得syslogd重新启动，使其能开始记录下ftpd发送的记录信息。

# touch /var/log/ftpd
# killall -HUP syslogd

    ftp对访问进行了种种限制，这些限制对于网络安全都是非常重要的，当用户的shell不在/etc/shells 中的时候，ftp拒绝提供服务，当用户的用户名位于/etc/ftpusers文件中时，或者是/etc/ftpusers
              中记录的组的成员，ftp同样也拒绝提供服务，这样就对使用ftp的用户进行了限制，尤其对于安全敏感的用户。如果/var/run/nologin文件存在时，ftp将拒绝一切用户访问。

    ftp认证是通过标准认证过程进行的，因此也可以使用S/key等安全认证的方式。同样，/etc/ftphosts 可以设置对来自不同位置的主机访问ftp服务的限制。

    很多情况下需要FreeBSD服务器提供匿名ftp服务功能，如果此时普通用户能通过更安全的方法访问系统，就应该屏蔽普通用户使用ftp服务的权力，而只允许匿名ftp，可以使用-A选项启动ftp服务器，此时ftp将拒绝正常用户登录，避免ftp服务器出现安全问题的可能性及减少安全问题的影响。当使用-S选项时，ftp将所有匿名访问的传输日志也记录在/var/log/ftpd文件中。这两个选项对于提供匿名ftp服务非常有用。对于提供匿名ftp
              的服务器，还可以不再使用FreeBSD提供的ftpd服务器，而使用wuftpd或ncftpd等其他种类的ftp 服务器，同样也需要针对这些服务器设置其安全性。

  • 改变程序的根文件系统

    •

    当不得不提供一些服务的时候，为了增加安全性，可以考虑提供chroot的服务。chroot意味着改变运行程序的根文件系统，当一个程序运行在chroot的环境下时，它所了解的文件系统只是chroot设置给它的某级目录开始，它就不能访问这个目录之外文件系统中的内容，使得即使这个程序出现安全问题，也不会影响文件系统中的其他重要数据的安全性。显然不是每种服务都适合这种形式，有的服务提供访问的文件资源不固定在某个目录下，就不能使用这个形式。

    由于设置一个服务程序使用chroot的时候，它就以为给它指定的目录就是它的根目录，因此它无论访问哪个文件，都将在相对的目录中查找，包括它要访问的重要系统文件。这样就必须为这个chroot程序建立一个小的，但完全满足其要求的系统目录结构，这个目录将和系统目录结构类似，也具有/etc/、/usr/、/var/、/dev/、/tmp/、/usr/lib/
              等等，并具备应用程序要访问的相应文件。

    如果程序是动态连接的，就需要/usr/lib目录中存在动态连接库，应用程序还可能会访问/etc目录下的配置文件，/dev目录下的设备文件，以及其他可能的文件。必须在应用程序的新的根目录下设置所有必须的目录结构和复制需要访问的文件。当然文件内容可以是系统原来文件的一个子集，而非原有的整个文件，以尽可能的保障安全。例如服务程序要访问的passwd文件只是系统passwd文件的一部分，等等。

    当chroot的程序需要访问某个用户的口令数据时，就需要将/etc/passwd文件中有关这个用户的内容复制到用户chroot目录下etc子目录下，然而口令文件并不止passwd一个文件，将包括master.passwd，pwd.db
              及spwd.db。由于pwd.db和spwd.db使用了数据库形式，就使得复制部分用户数据变得比较困难。

    改变根文件系统的服务程序有两种类型，一种为本身不具备改变根文件系统的能力，但由于不访问过多的文件，能使用系统的chroot命令来启动程序，使其运行在某个目录下。另一种类型为程序本身就支持这个能力，这样就不需要使用手工使用chroot命令，系统在特定条件下或使用一定参数启动时就自动进行chroot操作。然而这些类型进行目录设置时需要进行的操作是相同的。而要设置网络服务所使用的文件环境，就要对该服务程序有详细的了解，这才是最为困难的问题。

    这里以配置改变根文件系统的namd为例，简介设置改变根文件系统的网络服务的步骤，这个设置步骤的原始文档为http://www.psionic.com/papers/dns.html（这个适用于OpenBSD和Fr
              eeBSD，没有使用Ports Collection，但给了较详细的解释），和http://www.antisocial.net/~modred/papers/named.html
              （使用了FreeBSD的Ports Collection，给出了详细的步骤）。以下只着重介绍操作过程，并没有详细给出操作步骤，需要设置chroot
              named的使用者可以参阅这些相关网页的内容。

  • 编译静态连接的named和namd-xfer，这需要增加编译连接标志-static，重新编译bind8 软件。这个过程也可以使用Ports
                Collecion来完成，然而要注意的是使用Ports Collection 编译的named和直接编译的named对目录结构的处理有所不同，这将影响后面建立目录结构的处理过程。使用静态连接的执行程序的好处是不必考虑为chroot环境复制对应的动态连接库，简化了chroot文件系统设置。

  • 建立chroot目录结构，首先在根目录下建立/chroot/named目录，作为这个服务的根目录，然后在这个目录中建立dev,etc,etc/namedb,usr,usr/libexec,
                var, var/run等目录，注意这些目录结构是与应用软件中的设置相关的，如果使用Ports Collection 定制的named和named-xfer，它使用目录结构是与Bind8的缺省设置不同的，需要建立/usr/local/libexec
                而非/usr/libexec目录。

  • 然后向新的文件系统中复制相应的文件、建立相关的设备。如果是动态连接的程序，还需要考虑复制/usr/lib下的动态连接库和相关的ld程序。可以通过ldd命令查询程序需要的动态连接库。然而增加文件就降低了系统安全性，因此一般应该使用静态连接的程序，新的环境中应具备尽可能少的文件。

  • 设置环境，包括增加程序执行的用户和组，目录结构的属主和权限设置等等。可以为named 添加用户named和组named。

  • 手工执行chroot的named，执行命令为”/chroot/named -unamed -g named
                -t /chroot/named” ，-t参数指出named应该使用/chroot/named作根目录执行chroot操作，一切正确之后，再更改启动脚本。

  • 更改启动脚本，屏蔽原有的named的执行权限，使得新named成为系统的网络服务程序，并设置正确的启动参数。

    • 用户相关的安全问题

      •

        系统管理员有时也不希望用户占用太多的系统资源，在有些Unix系统中入侵者能通过普通帐户，启动大量的进程或产生大量的文件，从而使系统死掉或不能提供正常操作，而FreeBSD下则不必有此担忧，因为可以通过login.conf
                  和用户的口令数据来设置用户类别，限制用户对系统资源的占用，同样占用的硬盘资源可以通过quota来限制。

        at和cron机制能帮助用户自动启动应用程序和服务进程，如果必要，可以屏蔽用户使用at和cron的权限。也要注意检查root用户的at和cron设置，这里也是入侵者可能用于设置后门程序的一个位置。

        系统中，除了服务进程可能具备root身份之外，再就是具备SetUID身份的程序能进入root身份。由于 SetUID和SetGID与系统安全息息相关，因此系统中也应该具备尽量少的SetUID和SetGID程序。要不定期使用find命令查找，或者检查/var/log下的日志文件，了解系统中这些程序文件的更改情况。

        实际上很多SetUID程序不会被使用的，例如很少有人使用uucp，如果使用的是局域网也很少使用ppp和 pppd，因此对于这些不常用到的SetUID程序，应该取消其SetUID位，甚至取消执行属性，以避免用户来执行它。

        为了避免不必要的SetUID程序，一个办法是可以在安装一个文件系统时就设定不承认这个文件系统中的SetUID 程序。安装文件系统时可以使用nosuid选项，就能让文件属性中的SetUID和SetGID位失效。因此为了利用这个优点，可以创建使用使用nosuid位的/home文件系统，让所有的用户使用，而其他可以存在SetUID
                  程序的文件系统，如/usr，则不允许用户写入。同样也要创建一个/var/tmp文件系统，将系统的/tmp目录指向这个目录，/var/tmp也应该是nosuid的，以避免用户在/tmp目录中保存SetUID程序。其他的文件系统，如使用NFS装载的文件系统，也要使用nosuid安装选项。

        划分多个磁盘分区、安装到不同目录上也能防止入侵者企图填满磁盘空间的阻塞攻击。同样，对于用户使用的磁盘文件系统，应该使用qutoa来限制用户个人占用的磁盘空间。

        这个nosuid安全选项应该加入到/etc/fstab文件中，一使得每次都能生效。需要注意的是nosuid 安装选项不能影响一些解释性语言程序的这个属性，如perl程序，当解释性语言程序具备SetUID属性，语言解释器为其设置身份，由于真正的setuid()调用是由语言解释器执行的，因此如果语言解释器具备root权限（具备
                  SetUID属性），那么就能使解释器将具备SetUID位的程序设置入root权限。这不是系统的问题，而是语言解释器的问题，屏蔽语言解释器本身的SetUID属性可以避免这个问题。

        当系统作为NFS服务器，设置共享出去的NFS文件系统时，应该使用maproot或mapall参数，以便隔离危险，使得即使在远程系统被侵入的情况下，防止从这个允许安装文件系统的客户上对本机的入侵。还可以考虑使用安全的NFS协议，使用DES算法进行服务器和客户机的认证。如果系统不使用NFS及其他RPC服务时，最好屏蔽相关的选项，如portmap_enable选项。

    • 安全日志记录

      •

        Unix系统使用Syslog记录应用软件发送的日志记录，日志记录对于安全管理非常重要，因为管理员可以从这些日志中发现系统遭受攻击的痕迹及证据。然而syslogd本身也是一个服务程序，能接收网络上的消息，因此其本身也存在安全问题。

        这样，syslog就存在两个矛盾的问题，为了安全起见syslogd不应该接收网络上的其他计算机发送的日志记录。由于接收消息是通过UDP传送并且没有加密保护，因此syslog消息可能是伪造的，即便攻击者不使用伪造信息进行欺骗，仅仅使用服务阻塞的方法，就能导致正常的日志记录系统不能正常使用，此后攻击者就能放心进行入侵操作而无需担心留下踪迹。那么即使syslogd没有因为这种阻塞攻击而崩溃，大量无意义的syslog记录，也使得其他有用的日志记录被迅速淹没或清除（为了防止日志文件占用过多的磁盘空间，系统中缺省情况下会自动进行日志的清理工作）。

        为了使得syslogd不理会其他计算机的记录，可以使用-s参数重新启动syslogd。在rc.conf 中更改syslogd_flags的值为"-s"。

        FreeBSD系统中用于管理syslog日志文件的程序为newsyslog，它由crontab来启动，它检查由newsyslog.conf中指定的日志文件，当这些文件达到一定大小时，就截断原文件，重新启动syslogd
                  ，并压缩保存原有记录。为了避免占用太多的磁盘空间，newsyslog保存的日志备份文件有数量的限制，因此就使得阻塞攻击清除日志的攻击方式成为了可能。可以增加newsyslog保存的日志备份文件的数量，和进行备份时文件的大小，增大系统日志文件的容量。

        然而，当一台计算机仅仅使用自己硬盘来记录日志的话，那么一旦入侵者成功入侵这台计算机，他就能按照syslogd 的配置文件syslog.conf的设置，清除相关的日志记录，以便为以后继续潜伏在系统中做打算。甚至可以直接删除/var/log目录下文件以及其他syslog.conf中指明的文件，消灭入侵踪迹及证据。这样，将syslog
                  日志记录保留在其他计算机系统中也是一个有效增强安全审计的重要因素。

        因此，可以设定一台用于记录日志的计算机，其syslogd屏蔽外部计算机的日志请求，只记录本地可信任的计算机系统的日志。这样，就需要在使用"-s"参数屏蔽任意计算机请求的同时，使用"-a"加上信任的计算机主机名，或者子网号，域名等，这样就只会记录这些计算机的日志记录。为了安全起见，这台计算机最好是专用于这一项服务，不执行任何服务程序，以避免遭受入侵。然而由于syslogd对系统要求不高，因此这台计算机可以不必使用很高的硬件配置，除了需要足够的硬盘空间以容纳大量日志记录。

        此外，还可以通过将特别重要的syslog的记录直接发送到行式打印机的方式，避免入侵者清除日志记录。

        由于日志记录会迅速增加，特别是在遭受攻击的时候更为显著，因此需要使用一些日志分析工具来帮助分析这些日志文件，以快速定位发生的安全问题，否则面临庞大的日志文件，很难找到有用的日志记录。logcheck或其他具备相似功能的程序就用来完成这个任务。http://www.psionic.com/abacus/abacus_logcheck.html为logcheck的主页。

    • 其他服务程序问题

      •

        有些软件本身很可能存在安全问题，应该尽量使用该软件的最新稳定版本并及时进行打补丁，或者使用具备同样功能，但更安全的软件来代替这种软件，例如使用qmail或postfix来代替sendmail。

        有时候软件的新版本由于增加了新功能，会变得更不稳定或具备其他的安全漏洞，对于这种情况就不能盲目升级软件。

        X Window也对网络安全有一定影响，特别是X服务器的认证问题，不要为了方便起见而直接使用xhost+ 命令，这样就会其他使用者能窥视用户正在进行的操作。除了上面提到的措施之外，还可以将FreeBSD系统放置到防火墙之内，或者直接利用FreeBSD系统的包过滤能力，屏蔽一些不友好节点的访问，或者屏蔽所有的外部连接请求，而不影响本机对外部的访问。将FreeBSD设置为防火墙是一个重要的安全措施，因为这不但能对本机提供保护，也能对网络内其他客户计算机提供保护。毫无疑问，FreeBSD系统的包过滤能力非常优秀，结合FreeBSD具备的网络地址翻译的能力，就使得它能构建仅次于硬件防火墙的防火墙系统。本章的后续部分中将详细讨论将FreeBSD设置为防火墙系统的各种方法。

    • 内核安全级别

      •

        FreeBSD内核有一个安全级别（securelevel）的概念，这是指系统内核运行使用的安全等级，不同的等级具备不同的保护和检查机制。因为这是内核的检查机制，因此相当严格，没有办法能绕过这个机制提供的保护，因此就对保护FreeBSD的安全性十分有用。

        内核的安全级别按照提供安全保护的程度分为-1、0、1、2共分为四个级别，安全级别能提供的保护有：

        系统文件：系统文件可以设置保护标志 “ 不可更改 “ 和 “ 只能附加 “ ，具有这些保护标志的文件在系统的文件属性之外，还受这些保护标志的保护。安全级别可以规定这些标志能否取消。

        磁盘设备文件：磁盘设备文件具备两种访问方式，随机访问的方式对应的块设备文件和顺序访问方式对应的字符设备文件，其中字符设备文件可以直接读取硬件设备，因此对于安全至关重要。内核安全级别可以决定是否允许以直接读取硬件的方式操作硬盘设备文件。

        直接内存访问：/dev/mem和/dev/kmem是系统内存的映射文件，访问它们就能直接访问系统内存，一些需要获取系统信息和需要进程间共享内存机制的程序需要访问这两个设备文件以直接访问内存，然而访问内存空间显然也影响系统的安全运行。内核安全级别可以决定是否允许访问系统内存。

        安全级别-1为一种永久性的不安全级别，系统内核不提供任何额外的保护。系统缺省就处于这个级别，此时系统文件的保护标志能被root用户取消，所有的设备，包括磁盘设备和内存映射设备，均能按照其属性来访问。

        安全级别0为不安全的级别，它和等级-1一样没有对系统提供额外的安全保护，但它影响到内核进程init的行为。当内核处于级别-1时，内核init程序不会自动更改运行级别，因此一直到进入能够登录的状态，系统安全级别仍然为-1。这是系统的缺省行为，没有打开安全级别保护机制。但如果安全级别不为-1，init在进入单用户状态时将改变为0级别，在进入多用户模式时改变为安全级别1。因此安全级别0为设置了安全级别保护之后，单用户状态下的安全级别。

        安全级别1为安全的级别，提供了对系统的保护能力。此时系统文件的那两个保护标志不能被取消，已安装文件系统对应的磁盘设备，以及/dev/mem，/dev/kmem不可以用写入模式打开。

        安全级别2与级别1类似，只是进一步增加了对磁盘设备低级操作的限制，不管该磁盘设备是否安装，都不允许直接以写入方式访问，这样就无法进行fdisk、disklabel以及newfs等操作。

        可以使用sysctl来查看当前系统的安全级别，但如果没有经过特别设置，FreeBSD的缺省安全级别应该为-1：

    # sysctl kern.securelevel
kern.securelevel: -1

        安全级别中最重要的一点是，除了内核的init进程之外，即使是root用户，也只能不断提高安全级别，没有办法将安全级别降低。这样就基本上保证远程入侵者在没有重新启动计算机的情况下，无法降低系统运行级别。如果root
                  想提高系统运行的安全级别，也需要使用sysctl命令。

    # sysctl -w kern.securelevel=0
kern.securelevel: -1 -> 0

        安全级别的意义就在于对文件和设备的保护，如果要对文件提供保护，就需要对文件设置保护标志schg。设置这个标志需要使用chflags命令，系统文件如/kernel，系统安全的时候就具备这个保护标志。即使在非安全级别下要更改这些文件的时候，也要首先取消保护标志才能进行正常操作。

    # mv /kernel /kernel.bak
mv: rename /kernel to /kernel.bak: Operation not permitted
# chflags noschg /kernel
# mv /kernel /kernel.bak
# mv /kernel.bak /kernel
# chflags schg /kernel

        上面操作先取消了kernel文件的不可更改标志schg，显然这是在非安全级别下的操作。当安全级别处于 1或2时，就不能使用chflags改变文件的保护标志了。

    # chflags noschg /kernel

    chflags: /kernel: Operation not permitted

        可以使用带-o参数的ls来查看文件具备的标志。

    # ls -lo /kernel

    -r-xr-xr-x  1 root  wheel  schg 1061679 Jun 30 01:27 /kernel

        因此可以将系统安全相关的很多程序都设置保护标志，这样入侵者就不能轻易更改这些文件了。建议将/bin，/sbin下的文件都设置这个标志。

    # chflags schg /bin
# chflags schg /bin/*
# chflags schg /sbin
# chflags schg /sbin/*

        这里首先将相关目录本身设置保护标志，这样入侵者就不能通过将目录更改名字的方法创造一个新的/sbin或 /bin目录。

        当文件具备了保护标志，并且安全级别高于1时，保护标志就无法取消，这些文件就不能更改，因此就带来一些必要的操作无法进行，例如重新生成内核的操作等。此时就必须再重新启动系统进入单用户状态执行这些操作。

        通常情况下，如果FreeBSD系统只提供网络服务，那么使用安全级别1或2毫无问题。然而如果要运行X Server
                  ，由于X Server使用了共享内存机制，需要访问/dev/mem和/dev/kmem，这样就会带来问题。这时的一种解决办法是在启动X
                  Server之后（例如使用Xdm），再升高安全级别，以避开这个问题，但此时 X Server已经打开了/dev/mem和/dev/kmem，安全级别的保护就不再是完美无缺的了。

        如果不使用X Server之类的程序，那么就可以将设置安全级别的命令直接放入系统的启动rc文件中，以便自动提高安全级别。这需要在rc.conf文件中设置两个变量：kern_securelevel_enable和kern_securelevel。

    kern_securelevel_enable=”YES”
kern_securelevel=0

        上面将安全级别设置为0，那么在启动之后将自动更改为1，这是一种标准的做法。

    •


FreeBSD连载(77)：安全工具
王波

安全工具

    虽然只使用FreeBSD基本系统提供的功能，就能将计算机系统设置为具有非常高的安全性的系统。然而网络上也存在各种用于增强或检查系统安全性的软件工具，有些工具是标准程序的更安全替代品，增强了系统安全性，有些是对系统或网络进行监视和检查的工具。使用这些工具，毫无疑问会进一步增强系统的安全性。FreeBSD的Packages Collection或Ports Collection通常将这些工具放在security子类中。

  • 系统工具软件

    虽然FreeBSD系统本身提供了对访问的认证、控制和记录，然而由于在Unix系统中，服务程序基本上是独立的，使用标准的安全控制方式的服务程序能从FreeBSD的认证控制机制中获益，但是有些服务程序并没有使用这些安全认证方式。对于独立进行认证控制的软件，除了使用其本身的控制能力之外，还有一些独立的软件具备为其他程序服务的控制访问功能。

    还有一些系统工具，能用于自动检查系统，帮助管理员发现系统中存在的问题，这些软件也是非常有用的工具。此外，还有一些工具软件属于系统工具，但对于增进系统安全也有很大意义，例如sudo，能在一定程度上增加root口令的安全性。

  • TcpWrapper

    tcp_wrapper对于多种服务器软件是非常有用的访问控制工具，它能以统一的方式保护各种不同服务器。对于没有受防火墙保护的独立主机系统，tcpwrapper的保护更为重要。因为配置了tcp_wrapper之后，任何向inetd发起的连接首先是连接到tcp_wrapper提供的tcpd上之后，再连接到具体的服务进程上，这样tcpd就有机会查看远程系统是否被允许访问，并能将连接的情况通过syslog记录下来，包括请求的种类，时间和连接的来源地址。

    这个程序事实上代替了系统提供的守护进程，来轻松和高效的监控外部网络与服务器的连接。由于它提供了详细的日志记录，也是用于抓住入侵者，并提供可靠的证据的一种方法。tcpwrapper的思想与代理型防火墙的思路是相同的，都是通过替换正常服务器的做法来完成控制任务。

    当使用Packages Collection安装了tcpwrapper之后，它的守护进程tcpd就被安装到了/usr/local/libexec目录下，然后就能使用tcpd来代替原有的守护进程提供网络服务了。

    FreeeBSD 3.2-RELEASE之后，tcp_wrapper进入了FreeBSD的基本系统中，而不再需要额外安装。

    有几种不同的使用tcpd的办法，最基本的办法是通过更改inetd.conf来启动tcpd。例如要想让tcpd来保护 fingerd，那么就需要将inetd.conf中对应fingerd的设置更改为tcpd：

    finger stream tcp nowait/3/10 nobody /usr/local/libexec/tcpd fingerd -s

    tcpd能在标准的系统文件目录中查找正确的守护进程以提供服务，如果进程不在标准的目录路径下，就需要在最后一列中指定所要执行文件的全路径，如/usr/libexec/fingerd。此后，对finger端口的访问，将被记录进系统的日志文件，具体为syslog.conf中对auth指定的记录文件，例如下面的syslog设置将tcpd的信息发送到/var/log/auth.log 文件中（需要保证auth.log文件已存在）。

    auth.* /var/log/auth.log

    tcpd使用/usr/local/etc/目录下的hosts.allow和hosts.deny文件来控制对服务器的访问，访问控制是基于IP 地址和域名的。以下为一个hosts.allow控制文件的例子。可以看出设置文件比较简单易懂，tcpwrapper也提供了一个程序tcpdchk，来检查用户更改过的设置文件是否正确。

    ALL: domain.com

    telnet: 192.168.3.0/255.255.255.0 EXCEPT 192.168.3.10

    此外有着相似功能，但用于替换inetd的软件为xinetd，它能用于代替原有的inetd来启动各种服务程序，但提供了更详细的日志记录。

  • 系统安全检查工具

    Internet上针对每个系统均报告了大量的安全相关的问题，如果将这些已知的安全问题有效的组织起来，使用程序对系统自动进行检查，就能极大的帮助网络管理员查找现有的问题，使得系统更为安全。网络上存在多种这类的工具，如Satan、cops，就用于这个目的。然而由于它们的强大功能，这些工具也能被企图入侵他人系统的使用者利用，因此为了避免入侵者，系统管理员应该尽早使用这些软件，以起到预防作用。

    cops是一个由系统管理员运行，检查系统内部设置的程序。它针对已知的Unix存在问题进行检查，如检查系统中是否存在没有口令的帐户，是否有非法SetUID程序，以及是否存在Internet上已经报告过的系统漏洞，是否存在有问题的软件等等。系统管理员能使用cops来检查系统的配置有无问题。

    Satan则与cops不同，Satan是从系统外部进行检查系统是否存在安全问题的程序，它能对网络存在的脆弱性自动进行搜索、分析并提供安全报告。这种从外部分析系统的软件一般称为扫描器，由于Satan功能强大并提供了可扩展的框架，因此在Internet上十分流行。它的另一个特点就是它通过Web浏览器工作，使用者只需指明要搜索的主机以及搜索深度和相近规则的级别，Satan就能自动收集尽可能多的目标信息。

    由于Santa是一个安全工具，因此它对扫描目标计算机并没有刻意隐藏，这样就在目标计算机的系统日志中留下了大量的扫描连接记录，尤其是当目标计算机使用了tcpwrapper的时候。这些日志能用于标识是否遭到扫描攻击。一些更隐蔽的软件工具能通过不进行完全连接等方式隐藏扫描记录，要发现它们就更为困难，因而对系统安全更为危险。

  • 加密数据传输

    一般情况下，用户需要从客户机上访问服务器，数据是以透明的方式通过网络传输的，这样数据包经过的网络中的计算机都有可能截取传送的信息。由于这个问题来源于低层网络的结构，只能通过协议的加密来防止信息泄露。然而当前大部分网络协议并不支持加密传送，因此使用窥探的方式获取网络上的信息，虽然是一种被动的方式，却是对网络安全的重要威胁。

  • Tcpdump

    任何事情都具有两面性，事实上能够获得网络上传输的数据的工具对于维护网络运行也非常重要，网络需要这些工具软件来帮助分析网络状态、解决各种网络故障，它们是网络工程师的好帮手。在市场上销售的有好几种专用的网络分析设备，来实现截获数据并进行分析的目的。虽然这些硬件实现的设备虽然功能强大，但价格昂贵，而使用软件通过标准计算机的网络接口来实现这种功能，相对来讲对于一般使用者还是可以承受的。

    tcpdump就是一种免费的网络分析工具，尤其其提供了源代码，公开了接口，因此具备很强的可扩展性，对于网络维护和入侵者都是非常有用的工具。tcpdump存在于基本的FreeBSD系统中，由于它需要将网络界面设置为混杂模式，普通用户不能正常执行，但具备root权限的用户可以直接执行它来获取网络上的信息。因此系统中存在网络分析工具主要不是对本机安全的威胁，而是对网络上的其他计算机的安全存在威胁。

    普通情况下，直接启动tcpdump将监视第一个网络界面上所有流过的数据包。

bash-2.02# tcpdump
tcpdump: listening on fxp0
11:58:47.873028 202.102.245.40.netbios-ns > 202.102.245.127.netbios-ns: udp 50
11:58:47.974331 0:10:7b:8:3a:56 > 1:80:c2:0:0:0 802.1d ui/C len=43
                         0000 0000 0080 0000 1007 cf08 0900 0000
                         0e80 0000 902b 4695 0980 8701 0014 0002
                         000f 0000 902b 4695 0008 00
11:58:48.373134 0:0:e8:5b:6d:85 > Broadcast sap e0 ui/C len=97
                         ffff 0060 0004 ffff ffff ffff ffff ffff
                         0452 ffff ffff 0000 e85b 6d85 4008 0002
                         0640 4d41 5354 4552 5f57 4542 0000 0000
                         0000 00
^C

    tcpdump支持相当多的不同参数，如使用-i参数指定tcpdump监听的网络界面，这在计算机具有多个网络界面时非常有用，使用-c参数指定要监听的数据包数量，使用-w参数指定将监听到的数据包写入文件中保存，等等。

    然而更复杂的tcpdump参数是用于过滤目的，这是因为网络中流量很大，如果不加分辨将所有的数据包都截留下来，数据量太大，反而不容易发现需要的数据包。使用这些参数定义的过滤规则可以截留特定的数据包，以缩小目标，才能更好的分析网络中存在的问题。tcpdump使用参数指定要监视数据包的类型、地址、端口等，根据具体的网络问题，充分利用这些过滤规则就能达到迅速定位故障的目的。请使用man
              tcpdump查看这些过滤规则的具体用法。

    显然为了安全起见，不用作网络管理用途的计算机上不应该运行这一类的网络分析软件，为了屏蔽它们，可以屏蔽内核中的bpfilter伪设备。一般情况下网络硬件和TCP/IP堆栈不支持接收或发送与本计算机无关的数据包，为了接收这些数据包，就必须使用网卡的混杂模式，并绕过标准的TCP/IP堆栈才行。在FreeBSD下，这就需要内核支持伪设备bpfilter。因此，在内核中取消bpfilter支持，就能屏蔽tcpdump之类的网络分析工具。

    并且当网卡被设置为混杂模式时，系统会在控制台和日志文件中留下记录，提醒管理员留意这台系统是否被用作攻击同网络的其他计算机的跳板。

    May 15 16:27:20 host1 /kernel: fxp0: promiscuous mode enabled

    虽然网络分析工具能将网络中传送的数据记录下来，但是网络中的数据流量相当大，如何对这些数据进行分析、分类统计、发现并报告错误却是更关键的问题。网络中的数据包属于不同的协议，而不同协议数据包的格式也不同。因此对捕获的数据进行解码，将包中的信息尽可能的展示出来，对于协议分析工具来讲更为重要。昂贵的商业分析工具的优势就在于它们能支持很多种类的应用层协议，而不仅仅只支持tcp、udp等低层协议。

    从上面tcpdump的输出可以看出，tcpdump对截获的数据并没有进行彻底解码，数据包内的大部分内容是使用十六进制的形式直接打印输出的。显然这不利于分析网络故障，通常的解决办法是先使用带-w参数的tcpdump
              截获数据并保存到文件中，然后再使用其他程序进行解码分析。当然也应该定义过滤规则，以避免捕获的数据包填满整个硬盘。FreeBSD提供的一个有效的解码程序为tcpshow，它可以通过Packages
              Collection来安装。

# pkg_add /cdrom/packages/security/tcpshow*
# tcpdump -c 3 -w tcpdump.out
tcpdump: listening on fxp0
# tcpshow < tcpdump.out
---------------------------------------------------------------------------
Packet 1
TIME:	12:00:59.984829
LINK:	00:10:7B:08:3A:56 -> 01:80:C2:00:00:00 type=0026
    <*** No decode support for encapsulated protocol ***>
---------------------------------------------------------------------------
Packet 2
TIME:	12:01:01.074513 (1.089684)
LINK:	00:A0:C9:AB:3C:DF -> FF:FF:FF:FF:FF:FF type=ARP
ARP:	htype=Ethernet ptype=IP hlen=6 plen=4 op=request
    sender-MAC-addr=00:A0:C9:AB:3C:DF sender-IP-address=202.102.245.3
    target-MAC-addr=00:00:00:00:00:00 target-IP-address=202.102.245.3
---------------------------------------------------------------------------
Packet 3
TIME:	12:01:01.985023 (0.910510)
LINK:	00:10:7B:08:3A:56 -> 01:80:C2:00:00:00 type=0026
    <*** No decode support for encapsulated protocol ***>

    tcpshow能以不同方式对数据包进行解码，并以不同的方式显示解码数据，使用者可以根据其手册来选择最合适的参数对截获的数据包进行分析。从上面的例子中可以看出，tcpshow支持的协议也并不丰富，对于它不支持的协议就无法进行解码。

    除了tcpdump之外，FreeBSD的Packages Collecion中还提供了Ethereal 和Sniffit两个网络分析工具，以及其他一些基于网络分析方式的安全工具。其中Ethereal运行在X
              Window 下，具有不错的图形界面，Sniffit使用字符窗口形式，同样也易于操作。然而由于tcpdump对过滤规则的支持能力更强大，因此系统管理员仍然更喜欢使用它。

    对于有经验的网络管理员，使用这些网络分析工具不但能用来了解网络到底是如何运行的，故障出现在何处，还能进行有效的统计工作，如那种协议产生的通信量占主要地位，那个主机最繁忙，网络瓶颈位于何处等等问题。因此网络分析工具是用于网络管理的宝贵系统工具。

    为了防止数据被滥用的网络分析工具截获，关键还是要在网络的物理结构上解决。常用的方法是使用交换机或网桥将信任网络和不信任网络分隔开，可以防止外部网段窃听内部数据传输，但仍然不能解决内部网络与外部网络相互通信时的数据安全问题。

    如果没有足够的经费将网络上的共享集线器升级为以太网交换机，可以使用FreeBSD系统执行网桥任务。这需要使用option
              BRIDGE编译选项重新定制内核，此后使用bridge命令启动网桥功能。

  • ssh

    由于网络上的数据传输是不安全，因此出现了S/key等方式来保护口令的安全。然而这些认证系统只是保证了口令等特别敏感信息的安全，而不能保证连接之后的传输数据安全性。为了保证数据传输的安全性，就必须先将数据加密之后再进行传输。

    对传输加密可以从两个方面入手，一个是在网络低层进行加密，应用程序不需了解加密的细节，因此可以兼容现有的应用程序，这种考虑方式包括建立虚拟专用网（VPN）的各种协议，如PPTP、L2TP，以及以后将采用的IPSec
              协议。另一种考虑方式是从网络应用程序入手，应用程序首先加密信息然后在进行传输，通过特定的服务程序和客户程序来建立安全连接，这种方式的代表就是ssh，此外还包括支持SSL（加密Socket层）的各个应用程序，如Telnet
              SSL，ApachSSL等。

    SSL在FreeBSD下的实现为openssl，它是在FreeBSD之类的免费操作系统下安装其他基于SSL应用程序的基础。

    PGP也是一个具备重要影响的加密程序，其本身虽然是为网络环境而设计的，但其程序本身不涉及网络。通常它和电子邮件的客户程序合作，构成安全的电子邮件系统。

    这些加密程序一般要使用Ports Collection下载安装，而没有现成的二进制软件包，主要原因是这些软件使用的公开密钥算法在美国有专利限制，其专利属于RSA研究所，因此FreeBSD就不将它们作成二进制软件包，以避免法律纠纷。即使使用Ports
              Collection下载这些软件的时候，也需要设定一个环境变量USA_RESIDENT ，以区分是不是美国居民，make程序好决定从何处下载这些程序，当然，手工下载就不必顾及这些。RSA
              算法在其他国家没有专利限制，因此可以随意使用。

    如果需要反复安装这些加密工具，可以更改/etc/make.conf中的设置，使其自动设置这个变量，以方便安装过程。

    在这些工具中，最重要的还是ssh，因为它提供了Unix系统最基本访问功能的安全实现，如终端访问、文件传输功能。当使用ssh访问服务器时，服务器首先发送自己的公用密钥，客户可以使用这个密钥加密自己产生的随机密码，此后客户和服务器使用这个密码，用传统的算法，如IDEA、DES等方法来加密通信数据。对于任何希望增强安全性的系统来讲，使用ssh来代替telnet,ftp以及rlogin,rsh,rcp等命令，都是最优先要考虑的措施。网络安全敏感的系统一般都要屏蔽telnet,rlogin等方式，而使用ssh提供远程访问。

    ssh有两个不同的版本，ssh1和ssh2，这两个版本互不兼容。由于ssh1更为流行，在非Unix系统之外也拥有不同的客户程序，一般需要使用ssh1，否则就会遇到与其他ssh的服务器系统和客户软件不兼容的问题。ssh2
              功能更为强大，然而其提供的额外功能一般不需要，ssh1提供的能力已经是绰绰有余的了。Ports Collection中这两个版本使用同样的安装位置，不能同时安装。

    安装了ssh之后，ssh将自动产生它所使用的公用密钥，这个密钥和ssh的设置文件保存在/usr/local/etc/ 目录中，不需要改动这些设置，直接启动ssh守护进程sshd就可以正常提供ssh登录服务了。通过Ports
              Collection安装的ssh的sshd位置为/usr/local/sbin/sshd。启动sshd之后，ssh客户程序就能登录和使用这台系统，可以
              立即使用命令ssh来连接本地系统。

bash-2.02$ ssh localhost
wb@localhost's password:
Last login: Wed May 19 08:14:13 1999 from 202.102.245.72
Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994
        The Regents of the University of California.   All rights reserved.

FreeBSD 3.1-RELEASE (wb) #6: Thu Apr 22 18:29:12 CST 1999
Welcome to FreeBSD!

    Ports Collection会在/usr/local/etc/rc.d目录下放置ssh的启动文件sshd.sh ，用以在系统启动时自动启动sshd。

    sshd使用端口22来监听用户的连接请求，需要调整网络中防火墙系统的设置，打开对ssh服务器端口22的连接请求，以便让网络之外的客户能够发送请求并建立连接。由于ssh系统相当安全，不必担心这样作会带来安全问题。

    当在低速网络上使用ssh的时候，就会希望网络连接的效率更高，可以在客户端启动ssh时使用压缩选项-C，这将使用与gzip相同的压缩算法对数据先进行压缩再传输，能用来提高传输非压缩数据的效率。

    同样文件传输也能通过加密的方式进行，ssh提供了scp用于复制远程文件，它的参数与rcp使用的参数相同，用与email地址相似的方式标识远程主机及确定的用户，然后再是文件位置。

bash-2.02$ scp vpn.txt wb@remotehost:vpn.txt
wb@mx's password:
vpn.txt                   |          1 KB |   1.5 kB/s | ETA: 00:00:00 | 100%

    对于使用Windows系统的客户，可以从Internet中下载运行在Windows下的ssh客户程序。支持ssh的仿真终端软件有：

              TTSSH http://www.zip.com.au/~roca/ttssh.html

              SecureCRT http://www.vandyke.com/

              F-Secure http://www.DataFellows.com）

    ssh的另一项强大能力是可以在客户机和服务器之间建立加密传输通道，从而能将本地的数据转发到远端的服务器上。这种功能最常用于将X
              Window的数据包进行转发，以便能在本地X服务器上通过ssh连接到远程，然后在ssh的连接终端上启动远程计算机上的X应用程序，但显示到本地X服务器上。此时X系统的通信数据是通过ssh建立的加密通道进行传输的，而不是普通情况下直接通过网络进行的传输，因此就保证了安全性。这种X11转发功能不需要任何设置，包括设置DISPLAY
              环境变量或-dislay参数，因此同时兼具安全性和方便性。

bash-2.02$ ssh remotehost /usr/X11R6/bin/xterm
wb@remotehost's password:
Waiting for forwarded connections to terminate...
The following connections are open:
  X11 connection from remotehost port 3979

    此外，还可以使用ssh转发其他不同的TCP连接，这样就不必担心数据在通过不安全的网络部分时的安全问题了。这首先需要使用ssh的-L参数定义本地端口和要转发的远程服务器端口的对应关系。

bash-2.02$ ssh remotehost -L 1234:192.168.3.1:23
wb@remote's password:

    如果使用上例建立ssh连接之后，任何对本地端口1234的连接请求，将首先转发给ssh，然后再由ssh服务器连接远端计算机的相应端口上。

  • 使用ssh和ppp建立安全连接

    由于ssh能在客户和服务器之间建立加密连接，因此它能和其他程序合作，如ppp，建立安全的网络通道。这种建立VPN的方式虽然不符合任何标准，然而却十分有效。对于FreeBSD系统之间，以及FreeBSD与其他Unix
              系统之间，都可以使用这种方式建立虚拟专有网络连接。

    无论使用ppp或者是pppd，都能用于和ssh协作建立VPN。然而ppp更易于使用和设置，FreeBSD 下，通常使用ppp程序建立ppp连接，因此这里就介绍使用ppp程序建立虚拟安全连接的方法。

    在/etc/ppp/目录下的ppp缺省配置文件ppp.conf中，已经提供了一个和外部程序协作，建立安全ppp连接的基本例子。就是由ppp启动外部程序建立连接，通过认证之后自动在远端执行ppp服务器，从而建立ppp
              连接。这种方法中ppp通过set device命令设置使用管道启动外部命令，但是这种管道方法不能和ssh很好的合作。因为进行认证的口令是ssh直接从终端设备上读取的，而在通道方式中ppp供应口令是通过标准输入/输出进行的，因此这些认证信息到达不了ssh中，就造成不能通过ssh认证建立连接。

    为了修正这个问题，让ppp程序能够建立ssh加密连接，一个解决办法是使用外部拨号程序，首先使用外部程序首先进行ssh认证，认证之后再将标准输入输出交回ppp，而外部程序可以生成伪设备文件直接控制ssh进行验证，然而需要使用者进行一些编程工作，并使用这个伪设备文件作为通信设备。另一种方式是通过设置ssh系统信任，使其不需要进行标准方式的口令认证（可以使用事先分发的公开密钥进行认证），显然这不是一个简单且安全的解决办法。更好、更简单的办法是使用ssh的TCP/IP转发能力，结合ppp建立IP通道的能力，从而建立安全的专有连接。

    为了建立ssh转发条件下的安全专有连接，首先回顾使用ppp建立IP通道的方法，这个方法在前面设置ppp 时介绍过。可以根据这些设置来设置客户端ppp配置文件ppp.conf，建立与本机的IP通道。

vpnclient:
 set timeout 0
 set log phase chat connect lcp ipcp
 set dial
 set ifaddr 192.168.4.10 192.168.4.1 255.255.255.0
 set device localhost:3333

    上面vnpclient的拨号设备设置为本地端口3333，与建立标准IP通道时的设置是不同，这里设置的是本地计算机的端口。而服务器端的设置为：

vpnserver:

 set timeout 0

 set log phase lcp ipcp command

 set ifaddr 192.168.4.1 192.168.4.10 255.255.255.0

 allow mode direct

 enable proxy

    为了建立安全连接，与设置IP通道类似，服务器端也需要设置使用inetd之类的超级服务器程序来启动ppp 服务器，回应客户端的请求以在IP通道上建立PPP连接。需要修改/etc/services，增加启动ppp服务器的端口号。

ppploop 6671/tcp # loopback ppp daemon

    然后修改/etc/inetd.conf文件，增加对ppp服务器启动的支持，并重新启动inetd。

ppploop stream tcp nowait root /usr/sbin/ppp ppp -direct vpnserver

    但是，由于ppp客户是向本地计算机发送连接请求，而非直接将请求发送给PPP服务器，因此就需要启动ssh，并建立相应的数据包转发功能，将转发的目标端口设置为服务器上ppp监听的端口。

bash-2.02$ ssh remotehost -L 3333:remotehost:6671
wb@remotehost's password:

    此后，可以在本地使用ppp连接本地的转发端口，直接建立安全连接。

bash-2.02# ppp -b vpnclient
Working in background mode
Using interface: tun0
PPP enabled.
bash-2.02# ifconfig tun0
tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500
        inet 192.168.4.10 --> 192.168.4.1 netmask 0xffffff00


FreeBSD连载(78)：设置和使用ipfw/natd

王波

设置防火墙功能

    通过设置，FreeBSD系统能够具备更高的安全性，防止外界入侵者进入系统，即使入侵者利用人为的问题进入系统，FreeBSD严密的保护也将使他们无所作为，不能对系统造成严重的破坏。然而，除了用于保护系统本身的能力之外，FreeBSD还能用于保护同一个网络内的其他计算机。此时这个FreeBSD系统就必须作为内部网络的缺省网关，担负将内部网络连接到外部网络的任务。

    FreeBSD系统实现了包过滤能力与网络地址转换能力，如果仅将这些能力用作保护系统本身，显然不是这些功能的设计目的，保护本地系统只是保护本地网络的一部分功能。包过滤能力是针对路由器等网络设备来设计的，而网络地址转换也是重要的防火墙功能，这些设计就使得FreeBSD能被十分方便的设置为防火墙系统。此外，FreeBSD上也能运行其他类型的防火墙软件，如代理型防火墙软件fwtk等，作为代理服务器来保护本地网络内的系统。

    即使FreeBSD系统不是用作防火墙，它所支持防火墙能力也同样能用来保护本地系统的安全。

  • 设置和使用ipfw/natd

        在专用路由器系统开始流行之前，Internet上的路由器大部分是基于Unix的软件路由器，其中多数是BSD Unix。显然这是由于BSD Unix在Internet上占据的重要地位决定的，即便是在专用硬件路由器流行的今天，当由于价格等因素不能考虑硬件路由器时，BSD系统仍然是用作软件路由器的首选系统。

        由于路由器处于网络之间，所有网络间需要交换的数据包都要通过它转发，因此就可以进行一定的限制，即按照预定义的一定规则处理每个数据包，符合要求的允许通过，不符合要求的就进行丢弃。这样路由器就能用作一个简单的防火墙系统，保护内部计算机。BSD系统中最早使用ipfw过滤器来定义不同的过滤规则，随后ipfw也被移植到其他平台上，并根据开发者的理解不同而独立发展。当前不同系统上的ipfw已经大不相同了，并出现了具备相同功能的其他过滤器， FreeBSD下的ipfw也经过了不断发展，具备了更强的过滤能力，尤其是它能和natd守护进程相结合，提供网络地址转换能力，具备更完善的防火墙能力。
  • 使用ipfw设置过滤

        由于包过滤要对每个数据包都进行判断，因此在网络流量较大时需要较高的处理器处理能力，FreeBSD的包过滤能力是在内核中实现的，这样才能具备最高的效率和性能。因此为了在FreeBSD上使用这个防火墙功能，需要在编译内核时打开下面选项重新定制内核。

    options IPFIREWALL
options IPFIREWALL_VERBOSE
options “IPFIREWALL_VERBOSE_LIMIT=100”
options IPFIREWALL_DEFAULT_TO_ACCEPT

options IPDIVERT

        其中第一项设置IPFIREWALL是用于打开基本的包过滤支持的，只有使用它才能在内核中支持包过滤。IPFIREWALL_VERBOSE
                  和IPFIREWALL_VERBOSE_LIMIT设置记录过滤日志，及日志记录的限制。IPFIREWALL_DEFAULT_TO_ACCEPT是设置IPFIREWALL的缺省行为，在数据包不符合所有的过滤规则的情况下进行转发，显然这是一种宽松的限制，此时系统主要用于屏蔽特定地址和特定服务，而提供其他的缺省网络能力。如果没有定义这个选项，系统就只能允许符合已定义规则的数据包通过，而屏蔽其他任何数据包，这样在没有定义过滤规则的情况下，系统不能和其他计算机相互通信。最后一个选项IPDIVERT是用于定义IPFIREWALL与natd的接口。

        当编译安装了内核之后，还需要设置内核具备数据包的转发能力。需要在rc.conf中设置gateway_enable
                  的值为YES，这样就能在系统启动时自动打开包转发能力。也可以直接执行下面命令来打开内核包转发能力。

    # sysctl -w net.inet.ip.forwarding=1

      net.inet.ip.forwarding: 0 -> 1

  • ipfw过滤规则

        IPFIREWALL的过滤规则是由ipfw命令来设置的，例如下面的规则允许所有127.0.0.1的数据传输。

                    # /sbin/ipfw add 1000 pass all from 127.0.0.1 to 127.0.0.1

        ipfw命令中，首先指定对这个规则的处理方式，ipfw add为向内核中的过滤规则中添加，此外，ipfw
                  delete用于删除一条规则，ipfw list用于显示当前定义的所有过滤规则，ipfw flush将清除所有的过滤规则，而ipfw
                  file用于从文件file中读取定义的过滤规则。

        此外，ipfw定义的规则都有自己的序号，其序号可以在处理方式之后指定，如ipfw
                  delete 1000 就是删除第1000条过滤规则，内核中可以同时支持65535条过滤规则。有时可以不使用规则的序号，那么ipfw
                  就处理当前规则，而处理过一次规则之后，就立即将当前规则序号增加100，这样就对于添加过滤规则时十分方便，不必指定序号，ipfw
                  add将每隔100添加一条过滤规则。

        每个过滤规则中，要首先给出这条规则的处理指令，allow指令（或者使用同义词pass,
                  permit,accept）为许可某类数据包通过；deny指令（或同义词drop）为不允许某类数据包通过，将该类数据包丢弃；
                  reject指令与deny指令有所不同，但它不是简单的将数据包丢弃，而是在丢弃原有数据包的同时，回应ICMP host
                  unreachable，通知发送计算机不能通过它与目的计算机进行通信，这样就免得发起连接请求的计算机一直发送连接请求，造成不必要的数据流量。使用count指令能对该类数据包进行简单记数，这个功能主要用于对网络使用进行记帐。log指令用于将连接发送到系统的日志记录中。

        其中count和log指令与其他指令不同，其他指令都是对数据包进行处理的指令，因此每个数据包只要匹配这个指令，就立即将数据包或转发，或丢弃，不再进行其他处理，而count和log只是记录指令，只是将记录下这个数据包，而数据包本身还将继续受到其他过滤规则的处理。

        过滤规则的第二部分是规定数据包的协议类型，指定规则是用于处理哪种数据包的，FreeBSD可以处理TCP,UCP,ICMP
                  类型的数据，以及在/etc/protocols文件中定义的其他数据包的类型，上例中使用all ，匹配所有类型的数据包。对于TCP或UDP，还可以在后面定义地址时指定应用的端口号（可以使用数字或/etc/services
                  中定义端口名字），进一步增加过滤能力。

        过滤规则的第三部分是规定过滤规则适用的地址范围，这可以通过指定源和目的计算机的IP地址范围或数据包通过的网络界面来进行指定。

  • 用from规定数据包的来源地址，可以是主机地址或网络；

  • 用to规定数据包的目的地址，可以是主机地址或网络；

  • 用in或out规定数据包是流向本机，还是向外发送的；

  • 用via、recv、xmit规定数据包经过、接收、发送的网络介面，rece可以是接收本地发送的数据包，而xmit一定是向外发送，因此应该和out选项合用；

        例如：屏蔽任何来自192.168.1.5的数据的指令为：

    # ipfw add deny all from 192.168.1.5

        而许可来自192.168.1.0网络上的远程登录的指令为：

    # ipfw add allow tcp from 192.168.1.0/24 telnet

        应用过滤规则的顺序是按照过滤规则的序号，从小到大进行匹配，一旦一个数据包匹配一个过滤规则，就立即按照该规则转发或丢弃，不再需要继续考虑以下的规则（count和log规则除外）。因此在前面的例子中，192.168.1.5
                  就不能使用telnet连接，因为首先碰到的是不允许的规则，如果两个命令次序相反，则它就能够进行telnet连接。

        最后一条过滤规则，第65535条规则，缺省被设为”deny all from
                  any to any”时，为不允许对任何连接，此时在没有定义其他规则之前，不允许所有的网络连接。但是编译内核时使用IPFIREWALL_DEFAULT_TO_ACCEPT
                  选项，就能将这条规则改为”allow all from any to any”，允许转发不符合其他规则的所有数据。这两种不同的设置属于两种不同的考虑方式，一种适用于安全性要求较高的系统中，缺省情况不允许外界连接，另一种主要限制部分节点的访问，缺省情况允许任意网络连接，普通系统使用这样的设置更多些。

    • rc.firewall

      •

        当启动了系统的包过滤能力之后，就需要在系统启动时将这些过滤规则自动载入内核，可以将这些添加过滤规则的指令写入启动文件rc.local或者其他启动文件中。但系统的启动文件中本来就具备载入这些过滤规则的相关启动文件
                  rc.firewall，这个文件中根据防火墙的基本要求，设置了常用的过滤规则，可以减轻防火墙管理员的设置工作。

        为了让系统执行rc.firewall中的设置，需要在rc.conf中设置参数firewall为YES，以及设置firewall_type的值，这个参数值将传递给rc.firewall，使rc.firewall执行不同的设置。一般情况下可以将firewall_type设置为open，对网络访问不进行限制，而client主要用于计算机不对外提供网络服务，保护本计算机只用于访问外部系统而拒绝所有的访问请求，设置为simple则定义了简单的防火墙规则，可以使用这台计算机保护防火墙内部的计算机，这三个选项比较常用。下面为缺省rc.firewall
                  中的有关过滤规则的设置。

    ############
# Define the firewall type in /etc/rc.conf.  Valid values are:
#   open     - will allow anyone in
#   client   - will try to protect just this machine
#   simple   - will try to protect a whole network
#   closed   - totally disables IP services except via lo0 interface
#   UNKNOWN  - disables the loading of firewall rules.
#   filename - will load the rules in the given filename
    #(full path required)
# For ``client'' and ``simple'' the entries below should be customized
# appropriately.

        这里解释了rc.conf中对firewall参数的可能设置值，可以设置为不同的设置值，或者可以使用一个文件名作为firewall_type的值，指定一个包括了ipfw规则的文件，而设置使用者自己定制的过滤规则。

    ############
# Only in rare cases do you want to change these rules
$fwcmd add 100 pass all from any to any via lo0
$fwcmd add 200 deny all from any to 127.0.0.0/8

        这两个规则用于设置本地网络lo0的数据包能进行传输，但屏蔽所有从其他网络界面通向本地网络lo0的通信。这是最基本的设置，防止在路由或IP地址设置不正确的情况下，外部计算机访问127.0本地网络。

    # Prototype setups.
if [ "${firewall_type}" = "open" -o "${firewall_type}" = "OPEN" ]; then

        $fwcmd add 65000 pass all from any to any

        设置open为防火墙的类型时，即使没有设置IPFIREWALL_DEFAULT_TO_ACCEPT内核选项，也允许对数据包进行转发，因为这里设置的规则序号为65000，小于缺省的65535规则。

    elif [ "${firewall_type}" = "client" ]; then

    ############
    # This is a prototype setup that will protect
        # your system somewhat against
    # people from outside your own network.
    ############

    # set these to your network and netmask and ip
    net="192.168.4.0"
    mask="255.255.255.0"
    ip="192.168.4.17"

        当设置了client为防火墙的类型，那么就需要更改这里的IP地址和子网掩码的设置，使其符合自己计算机的实际情况。client类型主要用于单机系统，保护本机不受外部计算机侵袭的设置。它的保护与tcpwrapper类似，但比tcpwrapper更为基本和高效，但是它不能提供详细的连接记录日志。

    # Allow any traffic to or from my own net.
$fwcmd add pass all from ${ip} to ${net}:${mask}
$fwcmd add pass all from ${net}:${mask} to ${ip}

        这两个规则用于许可计算机与本地网络的通信。

    # Allow TCP through if setup succeeded
$fwcmd add pass tcp from any to any established

        上面这两个规则允许连接已经设定成功的TCP连接的数据包能够保持连接，数据传输能够继续进行。
                  established参数就用于说明数据包为已经设置成功的TCP连接数据包。

    # Allow setup of incoming email
$fwcmd add pass tcp from any to ${ip} 25 setup

        允许外部计算机能向内地smtp端口发起连接请求，setup用于说明定义的数据包为请求连接的数据包。

    # Allow setup of outgoing TCP connections only
$fwcmd add pass tcp from ${ip} to any setup

        允许本地计算机能向外部网络发起连接请求。

    # Disallow setup of all other TCP connections
$fwcmd add deny tcp from any to any setup

        此后屏蔽所有其他种类的TCP连接请求数据包，因此如果要打开其他TCP连接请求，就需要在这个规则之前进行定义。

    # Allow DNS queries out in the world
    $fwcmd add pass udp from any 53 to ${ip}
    $fwcmd add pass udp from ${ip} to any 53

    # Allow NTP queries out in the world
    $fwcmd add pass udp from any 123 to ${ip}
    $fwcmd add pass udp from ${ip} to any 123

    # Everything else is denied as default.

        此后定义对UDP数据包的过滤规则，只许可DNS和NTP协议通过，而屏蔽其他UDP数据包。

        上面这些指令都是client类型的过滤规则，综合上面的指令，这就表示为屏蔽外部计算机向本地除smtp之外的TCP连接请求，而允许本地计算机向外发起连接请求，屏蔽除DNS和NTP之外的其他UDP数据包。这些过滤规则可以有效的保护一个不对外提供服务的客户系统。但是，如果要对外提供网络服务，就需要更改这里的设置，打开需要提供服务的端口，例如打开TCP端口22，以使得ssh客户能连接到系统中。

    elif [ "${firewall_type}" = "simple" ]; then

    ############
    # This is a prototype setup for a simple firewall.
        #  Configure this machine
    # as a named server and ntp server, and point all
        #   the machines on the inside
    # at this machine for those services.
    ############

    # set these to your outside interface network and netmask and ip
    oif="ed0"
    onet="192.168.4.0"
    omask="255.255.255.0"
    oip="192.168.4.17"

    # set these to your inside interface network and netmask and ip
    iif="ed1"
    inet="192.168.3.0"
    imask="255.255.255.0"
    iip="192.168.3.17"

        防火墙类型simple用于设置一个简单的防火墙系统，用于保护内部网络中的计算机。由于防火墙系统需要连接多个网络界面，一个用于连接外部网络，而其他用于连接内部网络。这个简单的防火墙只针对两个网络界面进行了过滤规则的设置，内部网络的界面iif，外部网络的界面oif，因此它只适合只有两个网络界面的防火墙系统。

        当真正要使用这个防火墙设置的时候，首先就要修改iif与oif的IP地址，网络掩码等相关设置，与本地系统实际使用的设置相同。

    # Stop spoofing
$fwcmd add deny all from ${inet}:${imask} to any in via ${oif}
$fwcmd add deny all from ${onet}:${omask} to any in via ${iif}

        这两个过滤规则用于丢弃涉及IP地址欺骗的数据包，这包括来自于外部网络界面，但源地址为内部网络地址，或者来自于内部网络界面，但源地址为外部网络地址的数据包。由于这些数据包涉及IP地址欺骗，每个路由器都应该丢弃这样的数据包。

    # Stop RFC1918 nets on the outside interface
    $fwcmd add deny all from 192.168.0.0:255.255.0.0 to any via ${oif}
    #$fwcmd add deny all from any to 192.168.0.0:255.255.0.0 via ${oif}
    $fwcmd add deny all from 172.16.0.0:255.240.0.0 to any via ${oif}
    $fwcmd add deny all from any to 172.16.0.0:255.240.0.0 via ${oif}
    $fwcmd add deny all from 10.0.0.0:255.0.0.0 to any via ${oif}
    $fwcmd add deny all from any to 10.0.0.0:255.0.0.0 via ${oif}

        RFC1918中定义了一些只用于内部网络的IP地址，这些地址不能用于Internet上的计算机，而只能用于内部网络中。这里禁止从外部网络界面上向内部地址进行数据传输，以防止外部网络向内部网络的地址进行连接，也是防火墙的重要功能之一。

        注意，上例中与系统提供的缺省设置是不同的，将其中对应于实际使用的内部地址的一行加上了注释。这是因为该设置与natd相互冲突，使得natd发送的数据（具备内部网络地址）也被过滤。可以简单的注释对应本地网络地址的设置项，以使得它们能够相互协议，而将保护功能留给natd来完成。如果不使用natd，就不必使用上面的注释。

    # Allow TCP through if setup succeeded
    $fwcmd add pass tcp from any to any established

    # Allow setup of incoming email
    $fwcmd add pass tcp from any to ${oip} 25 setup

    # Allow access to our DNS
    $fwcmd add pass tcp from any to ${oip} 53 setup

    # Allow access to our WWW
    $fwcmd add pass tcp from any to ${oip} 80 setup

    # Reject&Log all setup of incoming connections from the outside
    $fwcmd add deny log tcp from any to any in via ${oif} setup

    # Allow setup of any other TCP connection
    $fwcmd add pass tcp from any to any setup

        此后屏蔽除了email，www，dns之外的其他向内部网络的TCP连接请求，而只允许向外进行连接。当实际内部网络要向外提供服务时，再添加连接许可。

    # Allow DNS queries out in the world
    $fwcmd add pass udp from any 53 to ${oip}
    $fwcmd add pass udp from ${oip} to any 53

    # Allow NTP queries out in the world
    $fwcmd add pass udp from any 123 to ${oip}
    $fwcmd add pass udp from ${oip} to any 123

    # Everything else is denied as default.

        然后定义UDP连接的限制，同样也只允许DNS和NTP数据包通过，这可以用于屏蔽类似BO之类的远程操纵程序。

    elif [ "${firewall_type}" != "UNKNOWN" -a -r "${firewall_type}" ]; then
        $fwcmd ${firewall_type}

fi

        如果使用者喜欢自己定制过滤规则，而不是在系统提供的规则基础上更改，那么可以将规则放入一个文件中，在rc.conf文件中设置firewall_enable=”YES”的基础上，将firewall_type的值改为放置ipfw规则的文件名。这样系统启动时就能够使用ipfw自动执行这些配置。但如果只是对过滤规则的少量更改，就可以直接修改rc.firewall文件。

    • 使用natd设置地址转换

      •

        natd与ipfw相互配合，能够实现网络地址翻译的能力。内核通过一个特定的divert类型的端口，将需要转换的数据包交给natd，而natd转换之后，再发送回内核，由内核再进行转发。它的好处不但是能提供防火墙能力，还能使得内部计算机能共享外部网络地址，这在IP地址空间比较紧张的当前是一个非常有用的技术。

        当应用网络地址翻译时，可供选择的内部IP有：10.0.0.0到10.255.255.255，172.16.0.0到
                  172.31.255.255，192.168.0.0到192.168.255.255。这些地址由RFC1918中定义为内部地址，不会出现在Internet上。

        FreeBSD下有几种软件能实现部分或全部NAT功能，功能最简单的是用户级ppp提供的alias功能，使用alias参数启动ppp将使ppp将所有来自其他网络介面的数据包中的源IP地址改变为tun0网络界面的IP
                  ，转发到ppp连接上去。这种IP伪装的方式虽然功能简单，但对于拨号将内部网络和Internet连接的用户非常适合。

        设置natd需要以下的步骤，首先设置好包过滤支持，包括内核中的IPFIREWALL和rc.conf中的
                  gateway_enable参数设置。它需要内核支持IPDIVERT选项，如果没有设置这个选项，就需要重新编译支持这些选项的内核；然后需要为natd指定一个divert端口，用于接收和发送从内核转发过来的包。这需要在/etc/services
                  中增加一个divert端口的设置：

    natd      8668/divert

        然后需要将所有的数据包都发送给相应的divert端口natd，然后由监听这个端口的守护进程natd
                  接收并转换。

    # /sbin/ipfw -f flush
# /sbin/ipfw add divert natd all from any to any via fxp0
# /sbin/ipfw add pass all from any to any

        上面的命令中使用了一个新的ipfw指令divert，这个指令就对符合这个规则的数据包通过divert规定的端口natd进行地址转换。但是divert指令和log和count指令相似，它并没有终止过滤规则，而是继续进行数据包过滤，只是此后的过滤将是针对转换后的数据包进行的了。

        执行了这些ipfw指令之后，而由于还没有启动natd守护进程，那么网络的正常连接都不再能进行了，发送到
                  divert的端口natd的数据包就被丢掉。直到启动natd进程，通过它进行处理之后，数据包才会正常发送。

        最简单的启动natd的指令为：

    # natd -interface fxp1

        此时，natd将内部的向外连接中的内部地址转换为fxp1上的IP地址，而内部网络的计算机必须设置这个防火墙为它们的路由器，以便将数据包交给它进行转发。但由于整个网络对外只表现为一个地址，外部网络并不需要了解这台防火墙的路由能力。

        如果要在系统启动时自动设置地址转换，就需要将这些ipfw/natd的过滤规则与系统启动文件结合在一起。缺省的启动文件已经支持了ipfw/natd，因而仅仅需要打开启动文件中相关设置就可以了。这不但需要在rc.conf
                  中设置gateway_enable，firewall_enable，还需要设置natd_enable为YE S，以使得自动启动natd守护进程，还需要指定natd使用的网络界面natd_interface的值，帮助将正确的数据包发送给natd，并使系统执行natd时使用正确的参数。而设置项natd_flags用来指定其他natd
                  需要的参数，例如用于指定natd设置文件等，简单情况下不需要使用这个设置项。

        当打开natd_enable时，将在其他过滤规则之前添加这个过滤规则，但是其他规则同样也会生效，因为当数据包从natd发送回系统之后，系统再对其应用过滤规则。

        不过，由于在natd转换IP地址之后还应用过滤规则，因此这些数据包还有可能被过滤。尤其在同时设置了
                  firewall_type为simple以执行rc.firewall中的防火墙过滤设置的时候，就需要注意其中与na td相冲突的设置。simple过滤规则中存在屏蔽外部计算机对RFC1918规定的IP地址进行访问的设置，然而n
                  atd将正常通信的数据包中的地址转换为了内部IP地址，因而缺省设置将阻止这些数据包发送到内部计算机中。

        为了和natd协作，必须修改其中过滤设置，以保证经natd转换过的数据包能发到内部计算机上。一般情况下，可以简单的rc.firewall将针对发送到本地网络的过滤规则设置注释掉就可以了，而从本地网络发送到外部网络的数据包在应用过滤规则之前，就已经进行完地址转换了，因此就不受规则影响。前一部分中介绍rc.firewall时，给出了进行注释的例子。另一种方法是调整过滤规则和顺序，将屏蔽这些内部地址的规则放置到divert指令之前。

    • natd的高级设置

      •

        使用-interface参数（或者使用其简写形式-n）启动的natd，可将所有内部网络向外的请求转换为该interface界面使用的IP地址，与外界进行通信。这种方式中，所有的连接中的内部地址不但转换的IP地址，同时也要转换端口地址，以避免地址冲突，并且外部网络只能连接到防火墙，而不能访问内部计算机上的服务。natd还有种种高级设置，使得系统能使用更复杂的地址转换功能。更复杂的情况是防火墙拥有一个合法子网，具有多个可利用的IP地址，此时防火墙对外表现为一个路由器，负责一个内部子网。

        使用natd时，计算机至少必须拥有一个合法的外部地址，用于将内部地址转换为外部地址时使用，当使用
                  -interface时，这个值被设置为该网络界面绑订的IP地址，如果该网络界面上的IP地址可能改变（例如它被设置为d hcp客户端，或者是PPP连接），-dynamic参数能使natd跟踪该界面上的地址更改。如果不使用-interface
                  参数指定网络界面，就必须直接使用-alias_address指定natd使用的外部IP地址。alias_address
                  定义的地址可以是防火墙本身外部网络界面上拥有的合法IP地址之一，也可以是作为路由器的防火墙的内部网络所拥有的合法IP地址之一。

        natd可以使用-redirect_address参数，设置静态IP地址转换，例如使用参数”-redirect_address
                  iip oip”，将内部地址iip与外部地址oip进行映射，则所有发送给oip的连接将被转给内部的iip。

    # natd -alias_address 202.102.245.60 -redirect_address
    192.168.3.2 202.102.245.17

        上面的命令将使得防火墙使用202.102.245.60作为内部计算机向外连接的缺省地址，而192.168.3.2
                  被映射为202.102.245.17，可以允许外部网络上的计算机对其进行访问。

        此时外部网络应该将发送往这两个ip地址的数据都发送到这个防火墙上，一般情况下这个防火墙应对外表现为一个路由器，负责将包括这两个IP地址在内的网络连接到外部网络上，而外界网络上的路由器也具有达到它的正确路由。但也可以通过Proxy
                  ARP或在防火墙外部网络界面上绑订多个ip地址的方法来实现。

        为了让外部路由器了解这个防火墙负责的网络，除了在外部路由器上设置静态路由之外，还可以使用动态交换路由协议，将防火墙的路由数据与外部路由器动态交换。这就需要使用与外部路由器相同的路由交换协议，常用的内部路由交换协议有rip,
                  rip 2，以及ospf，其中routed用于支持rip协议，而gated可以支持其他种类的协议。由于路由交换协议是整个网络统一规定的，因此必须根据统一使用。

        另一个非常有用的参数是-redirect-port，它是用于将对某个IP地址固定端口的连接请求，转发至指定内部计算机中。这个参数非常灵活，针对tcp或udp进行设置。例如将对-alias_address定义地址的
                  http请求转发到内部地址192.168.3.3的另一个端口8080上。

    # natd -alias_address 202.102.245.60 -redirect_port tcp
    192.168.3.3:8080 80

        当然也可以为其他地址，如202.102.245.17，设置映射。

    # natd -alias_address 202.102.245.60    \
-redirect_port tcp 192.168.3.3:8080 202.102.245.17:80

        进一步可以使用-redirect_port为特定的外部计算机的特定连接进行映射。

        还可以使用-f或-config参数指定natd的配置文件，从文件中而非从命令行读取natd的设置，使得设置更为清晰明了。下面的设置文件例子中使用了另外几个很有用的参数。

    alias_address 		202.102.245.60
deny_incoming 		yes
unregistered_only	yes
same_ports			yes
use_sockets			yes

        deny_incoming用于拒绝向alias_address发起的所有连接请求，用来保护网络内部安全，这个参数可以和-redirect_port参数结合，控制提供的网络服务。

        unregistered_only用于只对RFC1918定义的内部网址进行地址转换，防止出现错误设置影响正常的路由设置。

        same_ports在网络转换时尽量选择与原有数据包相同的端口，这样来保证一些与端口相关的服务能够被尽可能满足，但这并不表示普通的地址转换会百分之百使用同样的端口，在将多个内部转换为一个外部地址时，总会有端口冲突发生的可能，真正要避免冲突，还必须使用-redirect_port直接指定。

        use_sockets允许natd查看ftp、irc等连接的数据内部，以根据内容设置正确的端口，这将占用较多的系统资源，因此一般不要使用这个选项。然而和same_port协作使用，可以支持更复杂的客户程序。

        其他还有一些设置选项，如log参数指定natd将日志记录到/var/log/alias.log文件中，
                  dynamic参数用于和interface参数协作，跟踪网络界面的IP地址改变的信息，等等。

        在设置文件中指定的参数，其形式与在命令行中使用的方式相似，不同之处在于有的参数在配置文件中需指定yes
                  或no，而在命令行中不需特别指定就意味着使用了yes属性。如直接使用-log而非-log yes。设置好这个设置文件之后，就可以启动natd了。

    # natd -f filename

    •


FreeBSD连载(79)：设置和使用ipfilter

王波

设置和使用ipfilter

    虽然ipfw/natd已经是相当强大的网络地址转换及防火墙系统，然而它还是有一定的缺点存在。其中最重要的一个缺点是natd是使用守护进程的方法来进行地址转换，因为它没有运行在内核中，而是通过divert socket 来和内核通信，这种方式虽然比较灵活，但效率显然要低一些。

    另外，natd的功能还不能满足有些要求，natd能做静态地址转换和使用一个伪装地址为多个内部地址服务，但其不能从一个给定的地址池中，为内部地址自动分配IP地址。毕竟natd是一个较早的网络地址转换工具，当前的发展已经比较迟缓。但是由于ipfw是FreeBSD系统的一部分，并且过滤和地址转换是由不同的部分来完成的，结构清晰，因此对于大部分情况都很适合，因此一般仍应使用ipfw/natd。

    如果ipfw/natd不能满足使用者的需要，能避免ipfw/natd缺点的另一个网络地址转换和数据包过滤的工具是ipfilter。虽然FreeBSD是其支持的主要系统，但它其实是一个支持多平台的独立软件，不仅能运行在FreeBSD上，也能运行在其他多种Unix系统中。由于它被包括进FreeBSD基本系统中，因此在FreeBSD 下配置ipfilter同样也非常轻松。

    ipfilter的网址为http://cheops.anu.edu.au/~avalon/， FreeBSD 3.0之前它不包括在FreeBSD的基本系统中，需要手工设置。

    由于ipfilter与ipfw同为在内核级对IP数据包进行处理的系统，因此他们相互冲突，不能同时并存在一个内核内，否则内核的TCP/IP功能就不能正常执行。为了使用ipfilter，就需要重新定制内核，删除所有 IPFIREWALL的设置，而添加IPFILTER的设置。

#options		IPFIREWALL
#options		IPDIVERT

options		IPFILTER
options		IPFILTER_LOG

    选项IPFILTER为支持IPFILTER的基本代码，IPFILTER_LOG为支持IPFILTER的统计记录能力。需要增加这些选项，并注释IPFIREWALL、IPDIVERT及其相关选项。此后，就可以重新定制、安装新内核。然而在重新启动之前，还需要在rc.conf中设置firewall_enable的值为NO，当系统内核不存在IPFIREALL功能又设置了firewall_enable的时候，启动文件就会自动载入支持这个功能的可加载模块ipfw.ko，载入ipfw.ko之后的系统内核就等同于使用IPFIREWALL内核选项的系统，与
              ipfilter发生冲突。然而ipfilter仍然需要设置gateway_enable，以打开系统内核的数据包转发功能。

    使用新内核启动系统之后，如果本地计算机的网络功能正常，此时再使用ipfw就会报告错误。这就能使用ipfilter
              来设置包过滤和网络地址转换了。

  • 设置地址转换

    •

    为了在ipfilter下设置网络地址转换，首先要创建一个地址转换设置文件，例如/etc/ipflter
              .nat。与ipfw/natd的相似，最基本的用法为使用一个外部地址来转换所有内部地址，此时必须进行端口转换，因此ipfilter.nat中应该包含的NAT规则为：

    map fxp1 192.168.3.0/24 -> 202.102.245.60/32
              portmap tcp/udp 10000:65000

    这个设置中，首先使用map关键字指明是进行地址转换的设置，此后的fxp1为连接外部网络的网络界面，在这个网络界面上执行数据包的IP地址和端口地址转换，第三个参数为进行转换的内部地址的范围，此后跟随的一个->
              符号表示进行地址转换，第五个参数为要转换为的外部地址，当指定子网掩码长度为32时就表示这只是一个主机而非子网范围，后面portmap关键字对tcp/udp协议进行端口转换，其使用的映射端口范围为在10000到65000之间，也可以对tcp或udp协议分别指定转换端口的范围。

    如果使用者拥有的不仅是一个主机，而是一个具备多个合法IP地址的子网，这样就能设置使用地址池，为内部向外连接的计算机动态分配合法的外部IP地址，这样的设置更为简单，因为不需要指定portmap进行地址转换。

    map fxp1 192.168.3.0/24 -> 202.102.245.0/26

    显然内部计算机的数量显然要多于系统拥有的合法地址的数量，上例中内部地址最多254个，而合法的外部地址仅仅有62个，这样如果向外连接的计算机一多，必然出现地址资源用光的问题。因此动态分配IP一般和端口转换结合起来，以避免出现地址消耗完毕的问题。

    map规则是用于转换外出数据包的源地址，使得被转换后的地址好象是从外部地址中发起的。而另一个规则rdr
              用于转换数据包中的目的地址，这样就能使得一个数据包被转发到某个特定计算机上进行处理，这可用于构建端口映射关系。

    rdr fxp1 202.102.245.60 port ftp -> 192.168.3.2
              port ftp

    上面的规则将指定ipfilter在fxp1网络界面上将发送给202.102.245.60，端口为ftp
              的数据包，转换为发送给内部地址192.168.3.2。

    rdr的另一个重要用途是可以用以构建透明的代理服务器，普通代理服务器都需要在客户机上进行设置，如果不进行设置，客户机将直接访问Internet上的计算机而不通过代理服务器，然而防火墙可以将这些应用请求转发给代理服务器，完成代理工作。此时对外界发送请求是在内部网络界面fxp0上发起的，因此也要在这里进行地址转换，而使用0.0.0.0/0
              代表对所有目的地址，并且是80端口的浏览请求都转发到127.0.0.1上去，而127.0.0.1 必须运行代理服务器软件，以提供代理服务。

    rdr fxp0 0.0.0.0/0 port 80 -> 127.0.0.1
              port 80

    虽然不是所有的应用代理服务都能使用透明代理的方法来减轻客户设置的负担，但绝大多数代理完全可以使用这种方法，使得客户不需要修改软件设置，就能利用代理服务器，而代理服务器具备大量的缓冲区，能够节约内部网络的Internet
              访问流量并加速Internet访问速度。

    因此，一个简单的不支持透明代理服务器的设置文件ipnat.conf例子为：

map fxp1 192.168.3.0/24 -> 202.102.245.0/26 portmap tcp/udp 10000:65000
map fxp1 192.168.3.0/24 -> 202.102.245.0/26
rdr fxp1 202.102.245.60 port ftp -> 192.168.3.2 port ftp

    在这样的设置下，tcp和udp在地址资源消耗完毕之后将进行端口转换，而其他协议，如icmp，将直接进行地址转换而不必进行端口转换。此后就可以将这个转换规则加入系统中，需要执行ipnat命令：

# ipnat -C
# ipnat -f /etc/ipnat.conf

    当前使用-C参数用于清除现有的转换规则，-f用于从配置文件中读取转换规则。设置了转换规则之后，就可以使用-l参数查看当前设置的转换规则和已经激活的转换关系。

# ipnat -l
List of active MAP/Redirect filters:
map fxp1 192.168.3.0/24  -> 202.102.245.0/26  portmap tcp/udp 10000:65000
map fxp1 192.168.3.0/24  -> 202.102.245.0/26
rdr fxp1 202.102.245.60/32 port 21 -> 192.168.3.2 port 21 tcp

List of active sessions:
RDR 192.168.3.2     21    <- -> 202.102.245.60  21    [202.102.245.25 35635] 863
992 0 407
MAP 192.168.3.2     1024  <- -> 202.102.245.60  10000 [202.102.245.25 9999] 8639
93 0 1f09

  • 设置包过滤

    •

    ipfilter也能很好的完成包过滤任务，它的过滤规则相当复杂。下面为一些简单的过滤设置例子，一般这些过滤规则可以保存在/etc/ipf.conf文件中。

block in log quick all with short
block in log quick all with ipopts

    block参数用于屏蔽符合过滤条件的数据包，in代表数据包的方向，标识从网络上或其他网络界面上发送到某个网络界面上的数据包，log用于指出该规则过滤的数据包应被记录下来，quick指示ipfilter进行快速过滤处理，符合这个规则的数据包将立即丢弃，all
              with short标识不完整的IP数据包，数据包的长度太小就没有包含合法的源地址或目标地址，从而无法被ipfilter识别，all
              with ipopts标志本身带有路由数据的IP数据包，这些IP数据包由于包含自己的路由信息，因此可能会带来网络安全问题。

    这两句设置用于过滤可能会带来安全问题的短数据包或具备路由信息的数据包。

pass in on fxp0 all
pass out on fxp0 all
pass in on lo0 all
pass out on lo0 all

    pass用于指定数据包可以通过，out与in相反，标识从网络界面向网络上或其他网络界面发送的数据包，而on
              fxp0或on lo0标识进行处理的网络界面。这里的设置允许内部网络界面、loopback网络界面可以自由发送和接收数据包。

block in log on fxp1 all
block out log on fxp1 all

    为了安全起见，除了明确指定可以发送和接收的数据包之外，屏蔽其余的外部网络界面进行数据发送和接收。

block in log quick on fxp1 from 10.0.0.0/8 to any
block in log quick on fxp1 from 192.168.0.0/16 to any
block in log quick on fxp1 from 172.16.0.0/12 to any
block in log quick on fxp1 from 127.0.0.0/8 to any

    上面的设置明确屏蔽具备内部网络地址的数据包被转发到外部网络去，由于ipfilter中地址转换和包过滤是在同一个系统中完成的，因此不必担心它们会发生冲突问题。

pass out log on fxp1 proto icmp all keep state
pass out log on fxp1 proto tcp/udp from any to any keep state

    proto用于指定不同的协议，通常可以设置为tcp, udp和icmp。这两行设置允许TCP,
              UDP, ICMP协议的数据包可以向外发送出去，keep state用于标识建立TCP连接之后的数据包，或者ICMP、UDP的回应数据包，以允许回应数据包能发送回内部网络。

pass in quick on fxp1 proto tcp from any to any port = ftp-data keep state
pass in quick on fxp1 proto tcp from any port = ftp-data to any port >
1023 keep state

    ftp中将打开额外的端口以进行数据传输，这两个设置允许对ftp数据端口的数据包能够进行转发。

block return-rst in log on fxp1 proto tcp from any to any flags S/SA
block return-icmp(net-unr) in log on fxp1 proto udp from any to any

    对于其他tcp连接请求，防火墙回应一个RST数据包关闭连接，S/SA标识TCP数据包的标志，S为Syn，
              A为Ack，而S/SA表示对Syn和Ack中的Syn标志进行检查，这类数据包是用于设定连接的数据包。对UDP请求，防火墙回应网络不可达到的ICMP包。

    上面的例子将屏蔽外部计算机发向网络内部的数据包，但允许内部向外的发起网络访问。如果要允许外部网络对内的访问，就必须增加其他pass
              in规则，以使得过滤规则能适应更复杂的情况。为了使上面的设置生效，必须将过滤规则加入到内核中去，这需要使用ipf命令。

# ipf -Fa
# ipf -f  /etc/ipf.conf

    首先使用-Fa标志清除所有的过滤规则，然后将ipf.conf中的设置加入系统中。此后，可以使用ipfstat来检查ipfilter进行过滤的各种统计信息。

# ipfstat
 input packets:		blocked 227 passed 116210 nomatch 68219 counted 0
output packets:		blocked 0 passed 74586 nomatch 20316 counted 0
 input packets logged:	blocked 227 passed 24883
output packets logged:	blocked 0 passed 17153
 packets logged:	input 0 output 0
 log failures:		input 25028 output 17139
fragment state(in):	kept 0	lost 0
fragment state(out):	kept 0	lost 0
packet state(in):	kept 1	lost 0
packet state(out):	kept 14	lost 8
ICMP replies:	160	TCP RSTs sent:	9
Result cache hits(in):	47523	(out):	53694
IN Pullups succeeded:	0	failed:	0
OUT Pullups succeeded:	0	failed:	0
Fastroute successes:	0	failures:	0
TCP cksum fails(in):	0	(out):	0
Packet log flags set: (0x10000000)
    packets passed through filter

    虽然在规则中指定了log选项，但是缺省时候syslogd并不会记录ipfilter发送的信息。符合规则的数据记录并没有真正被发送到系统日志记录中，必须使用ipmon打开记录功能。

# ipmon -s -n -x

    由于ipmon使用的是syslog的local0通道，缺省情况下local0通道并没有打开，因此只有很少的错误信息被发送到/var/log/messages文件中。为了打开local0通道，还需要改动syslogd.conf，增加下面的设置，以记录ipfilter的全部记录。

local0.*		/var/log/ipfilter.log

    为了不让ipfilter的记录发送到/var/log/messages等其他日志文件中，可以在/var/log/messags设置行中添加一个记录local.none。

    此后，使用touch创建ipfilter.log文件，并重新启动syslogd，就能在/var/log/ipfilter.log中正确记录过滤记录了。当一切都设置完毕之后，就能将ipf和ipnat这两个设置命令放入系统启动文件rc.local，以便每次系统自动启动都能执行防火墙设置。


FreeBSD连载(80)：构建防火墙

王波

构建防火墙

    防火墙的主要目标是控制内部网络和外部Internet之间的连接，有限制的允许内部网络中的计算机访问Internet 上的服务，但限制外部网络访问内部计算机。为了实现这个目的，至少需要一个具有两个（或更多）网络界面的计算机，它的一个网络界面连接外部网络，另一个网络界面连接内部网络。然而如何实现限制网络访问的方法却有所不同，主要就可以分为基于IP数据包过滤的防火墙和基于代理的防火墙。ipfw/natd和ipfilter都是基于包过滤和网络地址转换的软件工具，而代理服务器通常通过代理服务器软件来实现。

  FreeBSD下用于防火墙的最重要的代理软件是fwtk，它提供了多种代理服务器和统一的认证方式。FreeBSD 上也能运行其他的代理服务器，然而那些代理服务器主要用于代理单个协议，不能单独用于构建全面功能的防火墙系统，而fwtk则提供了多种代理服务器，为构建一个完整的防火墙系统提供了基础。然而fwtk不是一个设置完好的防火墙系统，而只是一组构建防火墙的组件。因此要使用fwtk来设定防火墙，仍然是一个复杂的任务。虽然在FreeBSD 下可以使用Ports Collection很方便的编译安装fwtk，但问题的关键是针对具体的服务进行设置。

    fwtk能在多种Unix系统上运行，很多资料和书籍都已经介绍了其使用和设置方法，这里就不再介绍fwtk 的使用和设置。这里主要介绍基于包过滤和NAT的防火墙系统。

  • 选择防火墙的类型

    早期的包过滤防火墙只是建立在路由器的基础上，只支持有限的过滤规则，并且不能保持网络连接状态。更关键的问题是，基于路由器的防火墙不能隐藏内部网络的拓扑结构，这样入侵者就比较容易利用包括IP欺骗在内的方式对内部计算机进行攻击。然而，网络地址转换技术可以改变这种情况，使用ipfw/natd或ipfilter可以建立更安全、更高性能的防火墙系统。

    由于NAT改变了内部计算机的IP地址，因此这种方式也可以称作网络层代理。而其他直接支持应用程序的代理服务器，如squid，fwtk等，被称为应用层代理，应用层代理的好处是可以定义更复杂的访问控制形式，例如针对用户进行认证等，并能提供较详细的日志记录。然而应用层代理的缺点是不方便用户使用，需要对客户端软件进行其他设置，并且不一定会具有所有种类的应用程序的代理程序。

    代理型防火墙的另一个问题是，无法向外部提供网络服务。这也可以算一个优点，因为向外提供网络服务就必然降低网络安全性，然而实际上网络使用者也希望通过自己的网络向外发布信息，而不只是简单的浏览Internet。当然在提供服务的同时也要保证发布信息服务器的安全，因此希望将其放入防火墙内部。对于需要发布信息的要求，NAT通过映射端口（或地址）就能满足要求，但代理服务器不能。

    然而，也能设计这样一种代理服务器，它接收Internet上任意（或受限）主机的访问，而将代理这些访问请求访问内部的服务器，这种代理服务器称为反向代理服务器。

    在不同类型的防火墙之间进行选择主要依赖于不同的需要，一般的情况下，内部网络的使用希望防御外部网络上的入侵者，但又希望能够最大可能的使用各种网络应用程序来访问Internet，而同时也希望系统配置比较简单，这样直接利用FreeBSD提供的ipfw/natd或ipfilter均能满足这种要求，网络地址转换类型的防火墙配置简洁、性能更高，并且对应用程序的支持相当强。

    有些网络内部计算机的使用比较混乱，因此希望针对用户进行认证控制，此后才允许用户能访问Internet，并还希望能限制用户使用访问Internet的应用种类，进行更复杂的日志记录，这些情况下就应该选用应用层代理服务器fwtk。极端的情况下，只打算对内部用户提供有限种类的Internet服务，那么设置一个专用的应用代理服务器也就满足要求了，例如设置squid代理WWW访问。

    然而，在FreeBSD上构建防火墙系统是通过系统提供的各种组件进行组合得到的，采取多种组件进行组合，就能构建更复杂的系统。可以根据不同需要，同时利用包过滤、网络地址转换及各种不同应用层代理等多种形式，设置不同复杂程度的防火墙系统，这就是FreeBSD系统的优势。但在这些情况下，由于FreeBSD提供的这些组件并不是单一软件，而是相互独立的多个软件，因此要设置一个完整的防火墙系统，还需要使用者进行复杂的设置。或者还需要管理员使用一些简单的脚本程序以辅助分析系统日志，发送警报，甚至对网络状态进行实时监控，通过迅速改变防火墙设置来保护内部网络系统。

    通过分析防火墙的日志记录，甚至监控通过防火墙的数据流模式，就可以寻找发生过或正在进行的系统入侵行为（通常可能是服务阻塞、暴力攻击甚至更复杂的特定攻击模式），进而反馈回防火墙系统，以重新调整设置，增强系统安全性。

  • 防火墙的拓扑结构

    当构建防火墙系统时，首先就要考虑网络的拓扑结构，这将对防火墙的设置产生影响。简单的网络可能只需要一台防火墙设备，而复杂的网络会需要更多的网络设备，包括多个防火墙系统。以下给出了最常使用的几种使用防火墙的网络拓扑，基本上这些拓扑将适合大多数的情况，可以使用这些拓扑来作为建立自己内部网络的参考。

    最简单的情况为使用具备两个网络界面的一个防火墙来分隔内部与外部网络。这种形式简单易行，适合大部分只需要访问Internet，而不需要对外发布信息的网络。一旦要向外发布信息，那么所提供的服务就会降低网络的安全性，造成相应的安全问题。

    为了避免在向外提供服务的服务器被侵入之后，影响内部网络的安全性，就需要将对外提供服务的服务器和只访问外部网络的客户计算机分隔到不同的网络上。可以采用上面的方式，防火墙使用三个网络界面，分别用于外部网络、内部网络和提供服务的服务器。

    使用单个防火墙的网络，网络安全被一台防火墙的安全所限制，更复杂的情况是同时使用多个防火墙系统。例如使用两个防火墙，第一层防火墙与第二层防火墙之间可以放置允许外部访问的服务器，这个区域被称为停火区，即使入侵者进入这个区域，还需要近一步攻击内部防火墙才能接触内部网络。

    如果这两个防火墙使用不同的技术，如外部防火墙为网络地址转换方式，而内部防火墙为代理服务器方式，这样即使入侵者侵入一个防火墙，但另一个防火墙使用的是完全不同的技术，就给入侵者带来更大的阻碍，提高整个网络的安全性。

    利用这些工具，网络可以设置的非常安全。事实上当前大部分安全问题仍然来源于人的因素，如管理不善造成的口令泄露等。这就使得正常的安全措施无法正常应用，而带来不可避免的安全问题。

  • PicoBSD

    软件方式的防火墙系统的一大问题就是由于系统本身能够安装丰富的软件，因此常常同时被用作其他用途，当用作其他用途时就有可能对本身的安全性造成影响。而硬件防火墙使用专有操作系统，只用作网络服务，这保证了它不会受到其他方面的影响。对于用作防火墙的计算机，通常应该专用而不要兼作其他用途。因为防火墙的安全性非常重要，内部网络安全要依赖防火墙的安全来保障，一旦防火墙被入侵，网络安全也就无法保证了。

    通常安装的FreeBSD系统都具备硬盘，当具备硬盘的FreeBSD用做防火墙系统时，一方面免不了想提供多种复杂的服务，这样系统可能会具备潜在的安全漏洞，另一方面入侵者入侵这个系统之后，可以在系统硬盘上隐藏入侵程序以进一步入侵网络内部。因此对于用作防火墙的FreeBSD系统，最好直接修改系统的rc文件，屏蔽所有的网络服务。另一种方法是可以尝试使用软盘上的FreeBSD系统，这样计算机本身不具备硬盘，可以从管理上杜绝它用作其他使用的机会，同时也节约了资源。此时FreeBSD系统可以不使用硬盘、显示器、键盘，通过串口进行设置，这样的系统可以安装在网络设备的机架上，专门用作防火墙提供安全服务。

    PicoBSD就是这样的一个小型FreeBSD系统，能够安装在一张软盘上。PicoBSD提供了四个不同的版本：dial、isp、net和router，dial为拨号访问Internet的版本，isp为接受拨号访问的版本，net和router是用于网关和路由器的版本，它们都能够在386处理器和10M内存下运行（dial版本仅仅需要8MB内存）。虽然从FreeBSD的主页上，可以得到预定制好的多种PicoBSD的磁盘镜像，然而由于计算机使用的硬件差异很大，定制好的磁盘镜像不一定适合使用者的计算机硬件，由于软盘容量很小，不能容纳尽可能多的硬件驱动，每个磁盘镜像也不能支持太多的硬件设备，因此就需要根据自己计算机的具体硬件环境定制PicoBSD。

    要定制PicoBSD，就需要一个安装了全部源代码的FreeBSD系统，并且这个FreeBSD系统的内核要支持伪设备vn及具备对应的设备文件，以便PicoBSD的设置程序能完成磁盘镜像文件的创建工作。PicoBSD 的源代码位于系统的/usr/src/release/picobsd目录下，这个目录中包含编译、配置PicoBSD 的说明，以及不同PicoBSD版本的配置。

    定制PicoBSD系统要使用的该目录的子目录build中的build脚本，为了制作一个PicoBSD的磁盘镜像，就需要在这个目录下启动build命令。

# cd /usr/src/release/picobsd
# cd build
# ./build

    build命令使用菜单将让使用者选择不同的PicoBSD的基本版本，如dial、isp、net和router
              ，根据不同的目的进行选择，此后选择n（no change）就能继续进行制作镜像文件的处理。当这个执行过程结束之后，build子目录下就产生了一个1.44MB的磁盘镜像文件picobsd.bin。此后可以在FreeBSD
              下，或者在DOS下将镜像文件写入软盘，则一个单软盘的PicoBSD系统就制作完毕了。

    build进程将使用/mnt来装载vn0设备，因此必须保证/mnt没有装载其他文件系统，而且vn0设备没有被占用。否则就会遇到错误。

    然而这样制作的PicoBSD使用的还是缺省的设置，如果要定制PicoBSD系统，就需要更改缺省设置。首先应该根据具体的需要，选择功能相近版本的PicoBSD，再进一步更改硬件设置。每一个PicoBSD版本的设置都位于具有相同名字的子目录下，例如net版本PicoBSD的目录为/usr/src/release/picobsd/net/
              ，在这个目录之下的conf子目录为PicoBSD内核的定制目录，而crunch1目录中为最后复制到 PicoBSD系统中的应用程序的名字列表。

    当需要针对运行防火墙的计算机更改硬件设置时，需要更改conf子目录中的内核设置文件PICOBSD，这个文件就是PicoBSD的内核设置文件，可以删除或增加设置选项，改变对不同硬件设置的支持。如果要更改复制到软盘镜象中的执行程序的数量，就需要更改同样位于该版本目录下的crunch1子目录中的文件。只是注意软盘空间有限，因此只能装载有限的程序。

    更改完这些设置之后，就可以转回build子目录重新定制PicoBSD，这样产生的镜象文件就为与硬件设置相符合的设置。将镜象文件写入软盘之后，就可以使用这个软盘启动防火墙系统，然后再使用命令行进行手工设置。需要注意的是，此时更改的只是写在内存文件系统MFS中的文件，而不是在软盘中文件，因此一旦系统重新启动，配置就不会保留下来。必须使用update命令将更改后的文件写回磁盘中之后，设置才能保留回磁盘中。


FreeBSD连载(81)：超文本传输协议HTTP

王波

第9章 设置WWW服务

由于能够提供图形、声音等多媒体数据，WWW已经成为Internet使用者最喜爱的访问方式，当前的大部分Internet流量均是由WWW浏览产生的。由于这种多媒体浏览方式的帮助，Internet不再仅仅是由专业人员使用，对计算机了解不多的普通使用者也能进入Internet的世界，享受Internet带来的新鲜内容。

    虽然WWW服务非常之流行，然而要建立一个WWW服务器以提供WWW服务却仍然属于专业领域的任务。当前能够提供WWW服务的软件有很多种，分别运行在不同的操作系统之上，其中有一些软件能够运行在个人使用的Windows桌面系统上，具备图形界面且易于配置，因此很多希望尝试提供WWW服务的使用者常常会安装并试运行过这些系统。然而这些系统基本上是只能提供极其有限的服务能力的系统，如果要想提供一个能够允许正常的Internet访问的服务器系统，至少应该使用Windows NT系统。当要求更高的性能和稳定性系统时，就应该选择Unix。FreeBSD显然是使用Intel平台系统时，可供选择的极其优秀的WWW服务器操作系统。

  • 基本概念

    虽然普通使用者只需要了解一些常识性的概念，如URL、HTML等，就能通过浏览器很轻松的访问Internet 上的Web资源。然而要建立一个Web服务器，却需要更多的相关概念，如HTTP、MIME、CGI等，这样才能了解Web服务器的设置参数，以正确设置这些参数建立一个真正可用的服务器系统。

  • 超文本传输协议HTTP

    用于支持WWW浏览的网络协议为HTTP，这是一种最基本的客户机/服务器的访问协议。浏览器向服务器发送请求，而服务器回应相应的网页。HTTP协议从1990年开始出现，发展到当前的HTTP 1.1标准，已经有了相当多的扩展，然而其最基本的实现是非常简单的，服务器需要进行的额外处理相当少，这也是为什么Web服务器软件如此众多的原因之一。

  • 请求方法

  • 通常，HTTP协议使用端口80来提供客户访问，因此也可以使用其他的网络软件，如telnet，模拟客户向服务器发送请求，来查看HTTP的传输方式。

    $ telnet webserver 80
Trying 192.168.0.1...
Connected to webserver.
Escape character is '^]'.
GET /index.html

        当telnet显示了Connect等信息建立了连接之后，服务器就等待使用者输入请求，而不进行任何提示。上例中，使用者输入GET
                    /index.html指令，则服务器立即将相应的网页返回，然后关闭连接。

        客户程序向服务器发送的请求可以有不同的类型，这样服务器可以根据不同的请求类型进行不同的处理。在HTTP
                    1.0中，定义了三种最基本的请求类型，GET、POST和HEAD，这些请求方法的实现方式均与上例相同，客户程序用大写指令将请求发送给服务器，后面跟随具体的数据。

        GET请求最为常见，它后面跟随一个网页的位置，服务器接受请求并返回其请求的页面。除了页面位置作参数之外，请求还可以跟随协议的版本如HTTP/1.0等作为参数，以发送给服务器更多的信息。

        POST请求要求服务器接收大量的信息，除了POST后面跟随的参数之外，浏览器还会在后面持续发送数据，让服务器进行处理。通常，POST方法是和CGI程序分不开的，服务器应该启动一个CGI程序来处理POST发送来的数据。

        HEAD请求在客户程序和服务器之间进行交流，而不会返回具体的文档。当使用GET和POST方法时，服务器最后都将结果文档返回给客户程序，浏览器将刷新显示。而HEAD请求则不同，它仅仅交流一些内部数据，这些数据不会影响浏览的过程。因此HEAD方法通常不单独使用，而是和其他的请求方法一起起到辅助作用。一些搜寻引擎使用的自动搜索机器人使用这个方法来获得网页的标志信息，或者进行安全认证时，使用这个方法来传递认证信息。

        除了这三种最常见的访问方法之外，在HTTP
                    1.1中还定义了更多的访问方法类型，如PUT，用于将网页放置到正确位置，DELETE用于删除相关文档等。这些方法并不常用，因而大部分Web服务器软件并没有实现他们。然而对于特定场合他们还是非常有用的，例如使用软件编辑网页时，网页编辑器可以使用这些方法，管理不同的网页。

        如果服务器不支持客户发送的请求方法，服务器将返回错误并立即关闭连接。

  •

    服务器对HTTP的处理方式

        HTTP协议的这种请求/回应的模式，使得服务器只能根据客户程序的请求发送回信息，这样的好处是客户具备很大的自由度，可以任意访问服务器上的信息。因此就存在多个客户同时访问一个服务器的问题。

        在Unix下，由一个守护进程来监视来自客户程序的请求，当守护进程接受到一个请求时，就建立一个新的进程对请求进行处理。通常服务器能创建足够多的新进程来回应客户的请求，然而如果同时发送请求的客户太多，那么服务器就有可能出现超载的情况，创建进程的速度跟不上众多客户发送请求的速度，这样就造成了服务器对外表现反应迟缓。此外，为了提高用户使用浏览器时的性能，现代浏览器还支持并发的访问方式，浏览一个网页时同时建立多个连接，以迅速获得一个网页上的多个图标，这样能更快速完成整个网页的传输。但是对服务器来讲，更增加了瞬间负载。

        显然，造成这个问题的关键是服务器对HTTP协议的处理方式，一次请求就要建立一个连接，在网页上充满了多个较小的图象文件的时候，那么服务器和客户程序之间的大部分工作是用于建立连接，而真正用于传递数据的工作却很轻松。因此，更好的利用现有连接，减少建立连接的消耗，就需要能在一次连接中回应多个请求。在HTTP
                    1.1中提供了这种持续连接的方式，而下一代HTTP协议：HTTP-NG更增加了有关会话控制、丰富的内容协商等方式的支持，来提供更高效率的连接。

        除了针对每次请求都建立一个新进程的处理方式之外，HTTP守护进程也能使用其他的方式处理多个请求，例如使用多线程，或者使用异步方式在不同请求之间进行切换，就能在一个进程内处理多个请求。虽然比起建立新进程来讲，这样消耗的处理器资源略微减少，但是并不能从根本上消除并发访问带来的处理器资源不足的问题。一般使用线程和异步方式的程序较为复杂，不能很容易扩充对新特性的支持，并有可能因为程序内部要自己进行同步等原因也会造成资源消耗。使用这些方式，虽然对处理静态的网页有好处，但对于执行CGI程序，仍然要创建子进程进行处理。因此，大部分运行在Unix上的守护程序仍然使用多进程的方式，这种方式简单却有效。

        即使对于使用多进程方式进行处理的Web服务器，也有不同的处理方式。Unix系统中提供了超级服务器进程inetd
                    ，因此简单的Web服务器可以使用inetd来启动真正的Web服务器。然而，inetd效率不高，使用in etd的服务器不能用作高负载的服务器系统，因此高负载的Web服务器，本身来监听客户连接请求，并负责启动子进程真正处理客户的请求。

       如果选择的服务器程序的确需要使用inetd来启动，可以选择与inetd功能相同，但效率更高的超级服务器进程tcpserver，它可以比inetd更高效的启动服务进程。

    •

              [上一页]
              [下一页]


FreeBSD连载(82)：数据处理方式

王波

数据处理方式

    当浏览器通过各种请求方法，试图从服务器获得数据的时候，服务器就必须将正确的数据返回给浏览器。浏览器并不关心服务器是如何进行处理的，服务器可以返回一个预先编辑好的HTML文档，也能根据请求动态生成返回的数据。而WW W的一大特点就是能用来传送多媒体数据，并且这些数据的传送是完全透明的，通过同样的HTTP连接，可以传送不同格式的声音、图象等数据。当服务器仅仅用于返回静态的HTML文档的时候，浏览器能够很容易的识别其数据类型，但当服务器不但用于返回静态的HTML文档，还可以动态返回各种类型的多媒体信息时，浏览器就不能仅仅从URL请求本身上判断服务器将会返回何种数据了。

    服务器和浏览器之间是采用了另外的方式来标识数据的类型，这种方式下通过在传输真正的数据之前，预先传输一个数据的MIME类型的方法，来标识数据类型。

  • 多媒体文件格式MIME

    最早的HTTP协议中，并没有附加的数据类型信息，所有传送的数据都被客户程序解释为超文本标记语言HTML 文档，而为了支持多媒体数据类型，HTTP协议中就使用了附加在文档之前的MIME数据类型信息来标识数据类型。

    MIME意为多目Internet邮件扩展，它设计的最初目的是为了在发送电子邮件时附加多媒体数据，让邮件客户程序能根据其类型进行处理。然而当它被HTTP协议支持之后，它的意义就更为显著了。它使得HTTP传输的不仅是普通的文本，而变得丰富多彩。

    每个MIME类型由两部分组成，前面是数据的大类别，例如声音audio、图象image等，后面定义具体的种类。

常见的MIME类型

超文本标记语言文本 | .html,.html | text/html
普通文本 | .txt | text/plain
RTF文本 | .rtf | application/rtf
GIF图形 | .gif | image/gif
JPEG图形 | .ipeg,.jpg | image/jpeg
au声音文件 | .au | audio/basic
MIDI音乐文件 | mid,.midi | audio/midi,audio/x-midi
RealAudio音乐文件 | .ra, .ram | audio/x-pn-realaudio
MPEG文件 | .mpg,.mpeg | video/mpeg
AVI文件 | .avi | video/x-msvideo
GZIP文件 | .gz | application/x-gzip
TAR文件 | .tar | application/x-tar

    Internet中有一个专门组织IANA来确认标准的MIME类型，但Internet发展的太快，很多应用程序等不及IANA来确认他们使用的MIME类型为标准类型。因此他们使用在类别中以x-开头的方法标识这个类别还没有成为标准，例如：x-gzip，x-tar等。事实上这些类型运用的很广泛，已经成为了事实标准。只要客户机和服务器共同承认这个MIME类型，即使它是不标准的类型也没有关系，客户程序就能根据MIME类型，采用具体的处理手段来处理数据。而Web服务器和浏览器（包括操作系统）中，缺省都设置了标准的和常见的MIME类型，只有对于不常见的 MIME类型，才需要同时设置服务器和客户浏览器，以进行识别。

    由于MIME类型与文档的后缀相关，因此服务器使用文档的后缀来区分不同文件的MIME类型，服务器中必须定义文档后缀和MIME类型之间的对应关系。而客户程序从服务器上接收数据的时候，它只是从服务器接受数据流，并不了解文档的名字，因此服务器必须使用附加信息来告诉客户程序数据的MIME类型。服务器在发送真正的数据之前，就要先发送标志数据的MIME类型的信息，这个信息使用Content-type关键字进行定义，例如对于HTML文档，服务器将首先发送以下两行MIME标识信息,这个标识并不是真正的数据文件的一部分。

    Content-type: text/html

    注意，第二行为一个空行，这是必须的，使用这个空行的目的是将MIME信息与真正的数据内容分隔开。

  • CGI与SSI

    普通服务器返回的文档为静态的HTML文档，文档中的内容为静态的。而很多情况下，需要根据浏览器发送请求时的条件改变浏览器返回的文档的内容。有些情况下，服务器能提供更复杂的功能，如通过浏览器登记用户的信息等，这些情况就要求Web服务器能根据请求运行一些特的应用程序，来完成更复杂的服务功能。

    返回动态文档的基本方法是使用通用网关接口CGI，它定义了Web服务器和由它执行的程序共享信息的方法。这样Web服务器可以根据浏览器的请求，在服务器端运行CGI程序，这个程序可以根据HTTP服务器设置的各种环境变量、服务器磁盘文件中保存的相关信息、以及服务器输入的客户端的请求信息，创建动态网页，并通过服务器返回给浏览器。CGI 标准十分简单，一个CGI程序就是一个标准Unix程序，它从命令行参数和标准输入中获得用户在浏览器上输入的信息，使用环境变量获得当前浏览客户的设置情况，最后使用标准输出输出它创建的动态网页。因此可以使用各种编程语言编写 CGI程序，如sh、C或Perl。

    可以使用C这样的编译型语言来编写CGI程序，也可以使用解释型的语言来编写CGI程序，这两种方法各有优劣。使用C编程效率较高，但由于要处理的内容大部分为文本，因此需要大量的编写、调试工作，效率不高。而解释型语言编写、调试程序比较容易，并且由于大部分解释语言都有强大的内建文本处理功能，本身就比较适合处理文档，因此解释语言在CGI 编写方面有一定的优势。例如Perl语言本身功能就十分强大，是用于CGI编程一种主要编程语言工具。但是解释型的语言本身存在效率问题，服务器执行解释型的CGI程序时首先要将解释语言器载入内存，这增加了服务器的额外开销。

    CGI需要启动一个额外的CGI程序以创建动态文档，由于每处理一个CGI请求都要启动一个进程，这样就加重了服务器端的负担。另一种产生动态文档的方式是使用服务器端分析文档，HTTP服务器不启动外部CGI程序来产生动态文档，而是由服务器本身分析要返回的html文档，对其中的一些特殊标记进行解释，并根据情况生成为符合HTML语法的具体数据，从而产生动态HTML文档。显然服务器端分析文档需要特殊功能的服务器，因此与CGI不同，并不存在服务器分析文档的标准。常见的服务器端分析方式有SSI、PHP、ASP等，然而由于这并不是标准，Web服务器可以有选择的支持这些特殊功能。

    最基本的服务器分析文档标准为SSI（Server Side Include），它能快速的处理一些简单的标志，使得创建动态HTML文档更为容易。SSI主要是采用宏替换的方式处理网页，当一个使用SSI处理过的HTML 文件被返回给浏览器时，有些与文档本身相关的信息，如文档最后一次修改时间等原本在HTML文档中使用特殊的标记来表示的信息，都会被替换为正确的数据。


FreeBSD连载(83)：Apache基本安装

王波

安装和设置Apache

    由于HTTP协议比较简单，因此Web服务器软件相当多，但是性能、可靠性、功能等都非常优秀的却并不是很多。当前最流行的Web服务器软件是Apache，它基于几年前相当流行的一种Web服务器NCSA-httpd，并增加了很多新的特点，以增加功能和提高效率，因此它的使用非常流行。

    Apache的网址为http://www.apache.org，这里可以找到关于Apache的最新源文件和二进制文件、文档和相关的开发计划。这里提到的Apache本身及其相关的模块的源文件，均可以在这个站点中获得。

    Apache可以运行在各种操作系统──从Unix到Windows系统上，易于安装和配置，提供了很多较新的特性，例如它支持模块功能，很容易就能通过增加新的模块以增加新的服务器功能。Apache和FreeBSD结合起来，提供了出色的稳定性和性能，非常适合建立重负载的专业Web站点。

    在FreeBSD上安装Apache服务器非常容易，可以使用Packages Collection安装A pache服务器的二进制版。然而，如果是基于特殊目的而需要调整Apache支持的模块，就需要重新编译Apache 。重新编译可以使用Ports Collection进行编译和安装。

    在Ports Collection中，提供了好几个版本的Apache服务器，其中一些属于Apache 1.2.x版本，而另一些为Apache 1.3版本，即使是同一个Apache版本，也提供了使用了不同模块支持的 Apache。当前应该选择Apache 1.3版本，第一次安装可以选择基本版本apache13，这个版本中没有提供额外的模块支持，此后当正式使用Apache的时候，会需要加入SSL支持和PHP3支持，因此应该选择 apach13-modssl或apache13-php3版本。其中基本版本apache13和apache13-php3 有预编译的二进制软件包。

  • 基本安装

    使用Packages Collection或Ports Collection可以轻松安装Apache服务器。安装时将缺省设置文件复制到了/usr/local/etc/apache目录下，除了这些标准的设置文件之外，这些设置文件还有对应的以.default为后缀的备份，如果万一设置文件被破坏，可以使用这些备份来恢复缺省配置文件。而缺省配置文件中的文档目录为/usr/local/www/data，指向随同软件一起安装的apache文档，CGI程序的目录为/usr/local/www/cgi-bin。

    在稍早的版本中，缺省配置文件和文档路径并没有直接安装好，而仅仅安装了以.default结尾的备份文件，以及cgi-bin.default,data.default目录。以提醒使用者修改缺省配置文件。将这些.def ault结尾的文件和目录复制为不包括.default后缀的文件和目录就能得到正确的设置。

    缺省设置并不一定百分之百保证能启动Apache服务器，缺省设置适合绝大多数情况，但不能保证没有特殊情况发生，例如服务器没有正确的配置名字等。一般情况下，不需要更改缺省设置就可以直接启动Apache服务器了，但即使如此，使用者也需要根据自己的实际情况更改设置文件，例如修改管理员的电子邮件地址等。如果Apache服务器不能正常启动，也没有关系，这仅仅说明缺省设置不适合该计算机的实际情况，可以通过调整设置参数来进行修正。

    Ports Collection安装的缺省设置文件并不是Apache软件包中直接附带的模板文件，而是P ort的维护者根据FreeBSD环境加以更改之后的设置，因此适合大部分FreeBSD环境，基本上不进行改动就能启动Apache。

    安装完毕之后，就可以尝试启动Apache服务器了，通常可以使用apachectl程序来完成这个操作。

# /usr/local/sbin/apachectl start

    如果安装的apache为较早的1.2.x系列版本，那么可能不存在apachectl这个管理命令，可以通过安装到/usr/local/etc/rc.d目录中的启动脚本apache.sh来启动Apache。或者直接执行Apache服务器的守护进程程序──httpd。

# /usr/local/etc/rc.d/apache.sh start

    在提供了apachectl命令的Apache 1.3版本，apache.sh实际是调用这个命令启动和停止服务器。

    当服务器启动之后，就可以使用浏览器来查看服务器是否回应http请求，可以使用X Window下的Net
              scpe Navigtor，然而更方便的工具为字符界面的浏览器lynx。对于进行管理和维护来讲，还可以使用te lnet向Web服务器直接发送控制命令，为了验证服务器是否正常运行，不需要请求某个文档，只需要发送HEAD请求就可以了。

$ telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
HEAD /http/1.0
HTTP/1.0 200 OK
Date:

    如果服务器能象这个例子一样回应对80端口的连接请求，并对用户输入的请求命令返回一定的结果，那么就说明A
              pache服务器安装和运行一切正常。此时如果使用浏览器访问这个使用缺省设置的服务器，那么就将看到Apache的文档。这是因为缺省页面被设置为了Apache文档，此后Web管理员可以将/usr/local/www/data
              目录更改为真正要对外发布的网页文档目录，使得系统真正能对外提供Web服务。


FreeBSD连载(84)：配置Apache服务器(1)

王波

配置Apache服务器(1)

Apache服务器的设置文件位于/usr/local/etc/apache目录下，传统上使用三个配置文件httpd.conf,access.conf和srm.conf，来配置Apache服务器的行为。httpd. conf提供了最基本的服务器配置，是对守护程序httpd如何运行的技术描述；srm.conf是服务器的资源映射文件，告诉服务器各种文件的MIME类型，以及如何支持这些文件；access.conf用于配置服务器的访问权限，控制不同用户和计算机的访问限制；这三个配置文件控制着服务器的各个方面的特性，因此为了正常运行服务器便需要设置好这三个文件。

    除了这三个设置文件之外，Apache还使用mime.types文件用于标识不同文件对应的MIME类型， magic文件设置不同MIME类型文件的一些特殊标识，使得Apache服务器从文档后缀不能判断出文件的MIME 类型时，能通过文件内容中的这些特殊标记来判断文档的MIME类型。

bash-2.02$ ls -l /usr/local/etc/apache
total 100
-rw-r--r--   1 root  wheel    348 Apr 16 16:01 access.conf
-rw-r--r--   1 root  wheel    348 Feb 13 13:33 access.conf.default
-rw-r--r--   1 root  wheel  30331 May 26 08:55 httpd.conf
-rw-r--r--   1 root  wheel  29953 Feb 13 13:33 httpd.conf.default
-rw-r--r--   1 root  wheel  12441 Apr 19 15:42 magic
-rw-r--r--   1 root  wheel  12441 Feb 13 13:33 magic.default
-rw-r--r--   1 root  wheel   7334 Feb 13 13:33 mime.types
-rw-r--r--   1 root  wheel    383 May 13 17:01 srm.conf
-rw-r--r--   1 root  wheel    357 Feb 13 13:33 srm.conf.default

    事实上当前版本的Apache将原来httpd.conf、srm.conf与access.conf中的所有配置参数均放在了一个配置文件httpd.conf中，只是为了与以前的版本兼容的原因（使用这三个设置文件的方式来源于NCSA-httpd），才使用三个配置文件。而提供的access.conf和srm.conf文件中没有具体的设置。

    新版本Apache使用的配置文件为apache.conf，它就等价于httpd.conf。

    由于在新版本的Apache中，所有的设置都被放在了httpd.conf中，因此只需要调整这个文件中的设置。以下使用缺省提供的httpd.conf为例，解释Apache服务器的各个设置选项。然而不必因为它提供设置的参数太多而烦恼，基本上这些参数都很明确，也可以不加改动运行Apache服务器。但如果需要调整Apache服务器的性能，以及增加对某种特性的支持，就需要了解这些设置参数的含义。

    关于Apache服务器的性能，在Internet上存在很大的争议，基本上使用过Apache的使用者几乎都不怀疑它的优秀性能，Apache也支撑了很多著名的高负载的网站，但是在商业机构的评测中，Apache往往得分不高。很多人指出，在这些评测中，商业Web服务器及其操作系统往往由其专业公司的工程师进行过性能调整，而Free
              的操作系统和Web服务器往往就使用其缺省配置或仅仅作很小的更改。需要指出的是，除了操作系统的性能调整之外，Apache 服务器本身的缺省配置绝不是最优化和最高效的，而是要适应几乎所有种类操作系统、所有种类硬件下的设置，多平台的软件不可能为特定平台和特定硬件提供最优化的缺省配置。因此要使用Apache的时候，性能调整是必不可少的。

    在商业评测中忽略了的另一个事实是，评测时往往对不同种类的功能进行比较，例如使用Apache的标准CGI
              的性能与ISAPI，NSAPI等服务器端API比较，事实上Apache服务器与此可以比较的功能为modperl ，FastCGI，与ASP类似的功能为PHP3等等，只不过由于Apache的开放模式，这些功能是由独立的开发组，作为独立的模块来实现的。但是在评测中，测试人员没有加入相应的模块评测其性能。

  • HTTP守护进程的运行参数

    •

    httpd.conf中首先定义了一些httpd守护进程运行时需要的参数，来决定其运行方式和运行环境。

    ServerType standalone

    ServerType定义服务器的启动方式，缺省值为独立方式standalone，http
              d服务器将由其本身启动，并驻留在主机中监视连接请求。在FreeBSD下将在启动文件/usr/local/etc /rc.d/apache.sh中自动启动Web服务器，这种方式是推荐设置。

    启动Apache服务器的另一种方式是inet方式，使用超级服务器inetd监视连接请求并启动服务器。当需要使用inetd启动方式时，便需要更改为这个设置，并屏蔽/usr/local/etc/rc.d/apache
              .sh文件，以及更改/etc/inetd.conf并重起inetd，那么Apache就能从inetd中启动了。

    两种方式的区别是独立方式是由服务器自身管理自己的启动进程，这样在启动时能立即启动服务器的多个副本，每个副本都驻留在内存中，一有连接请求不需要生成子进程就可以立即进行处理，对于客户浏览器的请求反应更快，性能较高。而
              inetd方式要由inetd发现有连接请求后才去启动http服务器，由于inetd要监听太多的端口，因此反应较慢、效率较低，但节约了没有连接请求时Web服务器占用的资源。因此inetd方式只用于偶尔被访问并且不要求访问速度的服务器上。事实上inetd方式不适合http的突发和多连接的特性，因为一个页面可能包含多个图象，而每个图象都会引起一个连接请求，即使虽然访问人数造成教少，但瞬间的连接请求并不少，这就受到inetd性能的限制，甚至会影响由inetd启动的其他服务器程序。

    ServerRoot "/usr/local"

    ServerRoot用于指定守护进程httpd的运行目录，httpd在启动之后将自动将进程的当前目录改变为这个目录，因此如果设置文件中指定的文件或目录是相对路径，那么真实路径就位于这个ServerR
              oot定义的路径之下。

    由于httpd会经常进行并发的文件操作，就需要使用加锁的方式来保证文件操作不冲突，由于NFS文件系统在文件加锁方面能力有限，因此这个目录应该是本地磁盘文件系统，而不应该使用NFS文件系统。

    #LockFile /var/run/httpd.lock

    LockFile参数指定了httpd守护进程的加锁文件，一般不需要设置这个参数，Apac
              he服务器将自动在ServerRoot下面的路径中进行操作。但如果ServerRoot为NFS文件系统，便需要使用这个参数指定本地文件系统中的路径。

    PidFile /var/run/httpd.pid

    PidFile指定的文件将记录httpd守护进程的进程号，由于httpd能自动复制其自身，因此系统中有多个httpd进程，但只有一个进程为最初启动的进程，它为其他进程的父进程，对这个进程发送信号将影响所有的httpd进程。PidFILE定义的文件中就记录httpd父进程的进程号。

    ScoreBoardFile /var/run/httpd.scoreboard

    httpd使用ScoreBoardFile来维护进程的内部数据，因此通常不需要改变这个参数，除非管理员想在一台计算机上运行几个Apache服务器，这时每个Apache服务器都需要独立的设置文件htt
              pd.conf，并使用不同的ScoreBoardFile。

    #ResourceConfig conf/srm.conf

                  #AccessConfig conf/access.conf

    这两个参数ResourceConfig和AccessConfig，就用于和使用srm.conf和access.conf设置文件的老版本Apache兼容。如果没有兼容的需要，可以将对应的设置文件指定为/dev/null，这将表示不存在其他设置文件，而仅使用httpd.conf一个文件来保存所有的设置选项。

    Timeout 300

    Timeout定义客户程序和服务器连接的超时间隔，超过这个时间间隔（秒）后服务器将断开与客户机的连接。

    KeepAlive On

    在HTTP 1.0中，一次连接只能作传输一次HTTP请求，而KeepAlive参数用于支持HTTP
              1.1版本的一次连接、多次传输功能，这样就可以在一次连接中传递多个HTTP请求。虽然只有较新的浏览器才支持这个功能，但还是打开使用这个选项。

    MaxKeepAliveRequests
              100

    MaxKeepAliveRequests为一次连接可以进行的HTTP请求的最大请求次数。将其值设为0将支持在一次连接内进行无限次的传输请求。事实上没有客户程序在一次连接中请求太多的页面，通常达不到这个上限就完成连接了。

    KeepAliveTimeout 15

    KeepAliveTimeout测试一次连接中的多次请求传输之间的时间，如果服务器已经完成了一次请求，但一直没有接收到客户程序的下一次请求，在间隔超过了这个参数设置的值之后，服务器就断开连接。

    MinSpareServers 5MaxSpareServers
              10

    在使用子进程处理HTTP请求的Web服务器上，由于要首先生成子进程才能处理客户的请求，因此反应时间就有一点延迟。但是，Apache服务器使用了一个特殊技术来摆脱这个问题，这就是预先生成多个空余的子进程驻留在系统中，一旦有请求出现，就立即使用这些空余的子进程进行处理，这样就不存在生成子进程造成的延迟了。在运行中随着客户请求的增多，启动的子进程会随之增多，但这些服务器副本在处理完一次HTTP请求之后并不立即退出，而是停留在计算机中等待下次请求。但是空余的子进程副本不能光增加不减少，太多的空余子进程没有处理任务，也占用服务器的处理能力，因此也要限制空余副本的数量，使其保持一个合适的数量，使得既能及时回应客户请求，又能减少不必要的进程数量。

    因此就可以使用参数MinSpareServers来设置最少的空余子进程数量，
              以及使用参数MaxSpareServers 来限制最多的空闲子进程数量，多余的服务器进程副本就会退出。根据服务器的实际情况来进行设置，如果服务器性能较高，并且也被频繁访问，就应该增大这两个参数的设置。对于高负载的专业网站，这两个值应该大致相同，并且等同于系统支持的最多服务器副本数量，也减少不必要的副本退出。

    StartServers 5

    StartServers参数就是用来设置httpd启动时启动的子进程副本数量，这个参数与上面定义的MinSpareServers和MaxSpareServers参数相关，都是用于启动空闲子进程以提高服务器的反应速度的。这个参数应该设置为前两个值之间的一个数值，小于MinSpareServers和大于MaxS
              pareServers都没有意义。

    MaxClients 150

    在另一方面，服务器的能力毕竟是有限的，不可能同时处理无限多的连接请求，因此参数Maxclient
              s就用于规定服务器支持的最多并发访问的客户数，如果这个值设置得过大，系统在繁忙时不得不在过多的进程之间进行切换来为太多的客户进行服务，这样对每个客户的反应就会减慢，并降低了整体的效率。如果这个值设置的较小，那么系统繁忙时就会拒绝一些客户的连接请求。当服务器性能较高时，就可以适当增加这个值的设置。对于专业网站，应该使用提高服务器效率的策略，因此这个参数不能超过硬件本身的限制，如果频繁出现拒绝访问现象，就说明需要升级服务器硬件了。对于非专业网站，不太在意对客户浏览器的反应速度，或者认为反应速度较慢也比拒绝连接好，就也可以略微超过硬件条件来设置这个参数。

    这个参数限制了MinSpareServers和MaxSpareServers的设置，它们不应该大于这个参数的设置。

    MaxRequestsPerChild 30

    使用子进程的方式提供服务的Web服务，常用的方式是一个子进程为一次连接服务，这样造成的问题就是每次连接都需要生成、退出子进程的系统操作，使得这些额外的处理过程占据了计算机的大量处理能力。因此最好的方式是一个子进程可以为多次连接请求服务，这样就不需要这些生成、退出进程的系统消耗，Apache就采用了这样的方式，一次连接结束后，子进程并不退出，而是停留在系统中等待下一次服务请求，这样就极大的提高了性能。

    但由于在处理过程中子进程要不断的申请和释放内存，次数多了就会造成一些内存垃圾，就会影响系统的稳定性，并且影响系统资源的有效利用。因此在一个副本处理过一定次数的请求之后，就可以让这个子进程副本退出，再从原始的htt
              pd进程中重新复制一个干净的副本，这样就能提高系统的稳定性。这样，每个子进程处理服务请求次数由MaxRe questPerChild定义。
              缺省的设置值为30，这个值对于具备高稳定性特点的FreeBSD系统来讲是过于保守的设置，可以设置为1000甚至更高，设置为0支持每个副本进行无限次的服务处理。

    #Listen 3000

                  #Listen 12.34.56.78:80

                  #BindAddress *

    Listen参数可以指定服务器除了监视标准的80端口之外，还监视其他端口的HTTP请求。由于FreeBSD系统可以同时拥有多个IP地址，因此也可以指定服务器只听取对某个BindAddress的IP地址的HTTP请求。如果没有配置这一项，则服务器会回应对所有IP的请求。

    即使使用了BindAddress参数，使得服务器只回应对一个IP地址的请求，但是通过使用扩展的Listen参数，仍然可以让HTTP守护进程回应对其他IP地址的请求。此时Listen参数的用法与上面的第二个例子相同。这种比较复杂的用法主要用于设置虚拟主机。此后可以用VirtualHost参数定义对不同IP的虚拟主机，然而这种用法是较早的HTTP
              1.0标准中设置虚拟主机的方法，每针对一个虚拟主机就需要一个IP地址，实际上用处并不大。在HTTP 1.1中，增加了对单IP地址多域名的虚拟主机的支持，使得虚拟主机的设置具备更大的意义。

LoadModule mime_magic_module  libexec/apache/mod_mime_magic.so
LoadModule info_module        libexec/apache/mod_info.so
LoadModule speling_module     libexec/apache/mod_speling.so
LoadModule proxy_module       libexec/apache/libproxy.so
LoadModule rewrite_module     libexec/apache/mod_rewrite.so
LoadModule anon_auth_module   libexec/apache/mod_auth_anon.so
LoadModule db_auth_module     libexec/apache/mod_auth_db.so
LoadModule digest_module      libexec/apache/mod_digest.so
LoadModule cern_meta_module   libexec/apache/mod_cern_meta.so
LoadModule expires_module     libexec/apache/mod_expires.so
LoadModule headers_module     libexec/apache/mod_headers.so
LoadModule usertrack_module   libexec/apache/mod_usertrack.so
LoadModule unique_id_module   libexec/apache/mod_unique_id.so

ClearModuleList
AddModule mod_env.c
AddModule mod_log_config.c
AddModule mod_mime_magic.c
AddModule mod_mime.c
AddModule mod_negotiation.c
AddModule mod_status.c
AddModule mod_info.c
AddModule mod_include.c
AddModule mod_autoindex.c
AddModule mod_dir.c
AddModule mod_cgi.c
AddModule mod_asis.c
AddModule mod_imap.c
AddModule mod_actions.c
AddModule mod_speling.c
AddModule mod_userdir.c
AddModule mod_proxy.c
AddModule mod_alias.c
AddModule mod_rewrite.c
AddModule mod_access.c
AddModule mod_auth.c
AddModule mod_auth_anon.c
AddModule mod_auth_db.c
AddModule mod_digest.c
AddModule mod_cern_meta.c
AddModule mod_expires.c
AddModule mod_headers.c
AddModule mod_usertrack.c
AddModule mod_unique_id.c
AddModule mod_so.c
AddModule mod_setenvif.c

    Apache服务器的一个重要特性就是其模块化的结构，这不但表现为其能在编译时能通过新的模块加入新的功能，还表现为其模块可以动态加载入http服务程序中，而不必载入不需要的模块。使用Apache的动态加载模块只需要设置好LoadModule和AddModule参数就可以了，这种特性就是Apache的
              DSO（Dynamic Shared Object）特性，然而要想充分使用DSO特性仍然不是一个简单的事情，不适当的改动这里的设置就可能造成服务器不能正常启动。因此如果不是要增加或减少服务器提供的功能，就不要改动这里的设置。

    上面这些列表就显示了FreeBSD下的缺省Apache服务器支持的模块，事实上很多模块是没有必要的，不必要模块不会被载入内存。模块可以静态连接到Apache服务器内部，也可以这样动态加载，将Apache的特性都编译成动态可加载模块是该Port的做法，而不是Apache的缺省做法，这样就以牺牲很小的性能的同时，带来极大的灵活性。

    因而动态可加载的能力还是对性能有轻微的影响，因此可以重新编译Apache，将自己所需要的功能编译进Apache
              服务器内部，可以让系统显得更为干净，效率也有轻微的提高。通常仅仅为了这一个目的就重新编译Apache是没有必要的，如果需要增加其他特性而重新编译Apache，不妨在增加其他模块的同时将所有的模块都静态连接入Apache
              服务器。有的使用者更喜欢动态加载模块，那么也不妨全部都使用动态加载模块。

    这些模块都被Ports Collection放置到/usr/local/libexec/apache目录下，每个模块对应Apache服务器的一个特性。详细解释每个模块的功能需要相当多的篇幅，其中比较重要的特性将在后面相应的地方中进行解释，而具体每个模块的功能及用法就需要查看Apache的文档。

    #ExtendedStatus On

    Apache服务器可以通过特殊的HTTP请求，来报告自身的运行状态，打开这个ExtendedStatus
              参数可以让服务器报告更全面的运行状态信息。


FreeBSD连载(85)：配置Apache服务器(2)

王波

配置Apache服务器(2)

  • 主服务器设置

    Apache服务器需要各种设置，以定义自己使用各种参数以提供Web服务。对于使用虚拟主机的情况，除了在虚拟主机的定义项中覆盖的设置之外（有的设置必须重新定义），这里的设置也是虚拟主机的缺省设置。

    Port 80

    Port定义了Standalone模式下httpd守护进程使用的端口，标准端口是80。这个选项只对于以独立方式启动的服务器才有效，对于以inetd方式启动的服务器则在inetd.conf中定义使用哪个端口。

    在Unix下使用80端口需要root权限，一些管理员为了安全的原因，认为httpd服务器不可能没有安全漏洞，因而更愿意使用普通用户的权限来启动服务器，这样就不能使用80端口及其他小于1024的端口，而必须使用大于 1024的端口来启动httpd，一般情况下8000或8080也是常用的端口。而Apache httpd服务器本身可以在以root权限打开80端口后再改变为普通用户身份进行运行，这样就减少了危险性，因而就不需要考虑这个安全问题。但是如果普通用户也想安装配置自己的WWW服务器，那么就不得不使用大于1024的端口，当然普通用户不能使用 Ports Collection进行编译安装，而必须手工编译安装。

    User nobody

    Group nogroup

    User和Group配置是Apache的安全保证，Apache在打开端口之后，就将其本身设置为这两个选项设置的用户和组权限进行运行，这样就降低了服务器的危险性。这个选项也只用于 Standalone模式，inetd模式在inetd.conf中指定运行Apache的用户。由于服务器必须执行改变身份的setuid()操作，因此初始进程应该具备root权限，如果是使用非root用户来启动Aapche，这个配置就不会发挥作用。

    缺省设置为nobody和nogroup，这个用户和组在系统中不拥有文件，保证了服务器本身和由它启动的CGI 进程没有权限更改文件系统。在某些情况下，例如为了运行CGI与Unix交互，也需要让服务器来访问服务器上的文件，如果仍然使用nobody和nogroup，那么系统中将会出现属于nobody的文件，这对于系统安全是不利的，因为其他程序也会以nobody和nogroup的权限执行某些操作，就有可能访问这些nobody拥有的文件，造成安全问题。一般情况下要为Web服务设定一个特定的用户和组，同时在这里更改用户和组设置。

    ServerAdmin you@your.address

    配置文件中应该改变的也许只有ServerAdmin， 这一项用于配置WWW服务器的管理员的email地址，这将在HTTP服务出现错误的条件下返回给浏览器，以便让Web使用者和管理员联系，报告错误。习惯上使用服务器上的webmaster作为WWW服务器的管理员，通过邮件服务器的别名机制，将发送到webmaster 的电子邮件发送给真正的Web管理员。

    #ServerName new.host.name

    缺省情况下，并不需要指定这个ServerName参数，服务器将自动通过名字解析过程来获得自己的名字，但如果服务器的名字解析有问题（通常为反向解析不正确），或者没有正式的DNS名字，也可以在这里指定I P地址。当ServerName设置不正确的时候，服务器不能正常启动。

    通常一个Web服务器可以具有多个名字，客户浏览器可以使用所有这些名字或IP地址来访问这台服务器，但在没有定义虚拟主机的情况下，服务器总是以自己的正式名字回应浏览器。ServerName就定义了Web服务器自己承认的正式名字，例如一台服务器名字（在DNS中定义了A类型）为freebsd.exmaple.org.cn，同时为了方便记忆还定义了一个别名（CNAME记录）为www.exmaple.org.cn，那么Apache自动解析得到的名字就为freebsd.example.org.cn，这样不管客户浏览器使用哪个名字发送请求，服务器总是告诉客户程序自己为freebsd.example.org.cn。虽然这一般并不会造成什么问题，但是考虑到某一天服务器可能迁移到其他计算机上，而只想通过更改DNS中的www别名配置就完成迁移任务，所以不想让客户在其书签中使用 freebsd记录下这个服务器的地址，就必须使用ServerName来重新指定服务器的正式名字。

    DocumentRoot "/usr/local/www/data"

    DocumentRoot定义这个服务器对外发布的超文本文档存放的路径，客户程序请求的UR L就被映射为这个目录下的网页文件。这个目录下的子目录，以及使用符号连接指出的文件和目录都能被浏览器访问，只是要在URL上使用同样的相对目录名。

    注意，符号连接虽然逻辑上位于根文档目录之下，但实际上可以位于计算机上的任意目录中，因此可以使客户程序能访问那些根文档目录之外的目录，这在增加了灵活性的同时但减少了安全性。Apache在目录的访问控制中提供了Fol lowSymLinks选项来打开或关闭支持符号连接的特性。

    Options FollowSymLinks
    AllowOverride None

    Apache服务器可以针对目录进行文档的访问控制，然而访问控制可以通过两种方式来实现，一个是在设置文件
              httpd.conf（或access.conf）中针对每个目录进行设置，另一个方法是在每个目录下设置访问控制文件，通常访问控制文件名字为.htaccess。虽然使用这两个方式都能用于控制浏览器的访问，然而使用配置文件的方法要求每次改动后重新启动httpd守护进程，比较不灵活，因此主要用于配置服务器系统的整体安全控制策略，而使用每个目录下的.htaccess文件设置具体目录的访问控制更为灵活方便。

    Directory语句就是用来定义目录的访问限制的，这里可以看出它的标准语法，为一个目录定义访问限制。上例的这个设置是针对系统的根目录进行的，设置了允许符号连接的选项FollowSymLinks
              ，以及使用AllowOverride None表示不允许这个目录下的访问控制文件来改变这里进行的配置，这也意味着不用查看这个目录下的相应访问控制文件。

    由于Apache对一个目录的访问控制设置是能够被下一级目录继承的，因此对根目录的设置将影响到它的下级目录。注意由于AllowOverride
              None的设置，使得Apache服务器不需要查看根目录下的访问控制文件，也不需要查看以下各级目录下的访问控制文件，直至httpd.conf（或access.conf
              ）中为某个目录指定了允许Alloworride，即允许查看访问控制文件。由于Apache对目录访问控制是采用的继承方式，如果从根目录就允许查看访问控制文件，那么Apache就必须一级一级的查看访问控制文件，对系统性能会造成影响。而缺省关闭了根目录的这个特性，就使得Apache从httpd.conf中具体指定的目录向下搜寻，减少了搜寻的级数，增加了系统性能。因此对于系统根目录设置AllowOverride
              None不但对于系统安全有帮助，也有益于系统性能。

    Options Indexes FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all

    这里定义的是系统对外发布文档的目录的访问设置，设置不同的AllowOverride选项，以定义配置文件中的目录设置和用户目录下的安全控制文件的关系，而Options选项用于定义该目录的特性。

    配置文件和每个目录下的访问控制文件都可以设置访问限制，设置文件是由管理员设置的，而每个目录下的访问控制文件是由目录的属主设置的，因此管理员可以规定目录的属主是否能覆盖系统在设置文件中的设置，这就需要使用
              AllowOverride参数进行设置，通常可以设置的值为：

AllowOverride的设置 | 对每个目录访问控制文件作用的影响
All | 缺省值，使访问控制文件可以覆盖系统配置
None | 服务器忽略访问控制文件的设置
Options | 允许访问控制文件中可以使用Options参数定义目录的选项
FileInfo | 允许访问控制文件中可以使用AddType等参数设置
AuthConfig | 允许访问控制文件使用AuthName，AuthType等针对每个用户的认证机制，这使目录属主能用口令和用户名来保护目录
Limit | 允许对访问目录的客户机的IP地址和名字进行限制

    每个目录具备一定属性，可以使用Options来控制这个目录下的一些访问特性设置，以下为常用的特性选项：

Options设置 | 服务器特性设置
All | 所有的目录特性都有效，这是缺省状态
None | 所有的目录特性都无效
FollowSymLinks | 允许使用符号连接，这将使浏览器有可能访问文档根目录（DocumentRoot）之外的文档
SymLinksIfOwnerMatch | 只有符号连接的目的与符号连接本身为同一用户所拥有时，才允许访问，这个设置将增加一些安全性
ExecCGI | 允许这个目录下可以执行CGI程序
Indexes | 允许浏览器可以生成这个目录下所有文件的索引，使得在这个目录下没有index.html（或其他索引文件）时，能向浏览器发送这个目录下的文件列表

    此外，上例中还使用了Order、Allow、Deny等参数，这是Limit语句中用来根据浏览器的域名和
              IP地址来控制访问的一种方式。其中Order定义处理Allow和Deny的顺序，而Allow、Deny则针对名字或IP进行访问控制设置，上例使用allow
              from all，表示允许所有的客户机访问这个目录，而不进行任何限制。

    UserDir public_html

    当在一台FreeBSD上运行Apache服务器时，这台计算机上的所有用户都可以有自己的网页路径，形如
              http://freebsd.example.org.cn/~user，使用波浪符号加上用户名就可以映射到用户自己的网页目录上。映射目录为用户个人主目录下的一个子目录，其名字就用UseDir这个参数进行定义，缺省为public_html。如果不想为正式的用户提供网页服务，使用DISABLED作UserDir的参数即可。

#
#    AllowOverride FileInfo AuthConfig Limit
#    Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
#
#        Order allow,deny
#        Allow from all
#
#
#        Order deny,allow
#        Deny from all
#
#

    这里可以看到Directory的另一个用法，即可以通过简单的模式匹配方法，针对分布在不同目录下的子目录定义访问控制权限。这样设置就需要Apache服务器对每个路径进行额外的处理，因此就会降低服务器的性能，所以缺省情况并没有打开这种访问限制。

    这里可以看到另外一个语句Limit，Limit语句就是用来针对具体的请求方法来设定访问控制的，其中可以使用GET、POST等各种服务器支持的请求方法做Limit的参数，来设定对不同请求方法的访问限制。一般可以打开对GET、POST、HEAD三种请求方法，而屏蔽其他的请求方法，以增加安全性。Limit语句中，可以使用Order
              、Allow、Deny，Allow和Deny中可以使用匹配的方法针对域名和IP进行限制，只是对于域名是从后向前匹配，对于IP地址则从前向后匹配。

    DirectoryIndex index.html

    很多情况下，URL中并没有指定文档的名字，而只是给出了一个目录名。那么Apache服务器就自动返回这个目录下由DirectoryIndex定义的文件，当然可以指定多个文件名字，系统会这个目录下顺序搜索。当所有由DirectoryIndex指定的文件都不存在时，Apache服务器可以根据系统设置，生成这个目录下的所有文件列表，提供用户选择。此时该目录的访问控制选项中的Indexes选项（Options
              Indexes ）必须打开，以使得服务器能够生成目录列表，否则Apache将拒绝访问。

    AccessFileName .htaccess

    AccessFileName定义每个目录下的访问控制文件的文件名，缺省为.htaccess
              ，可以通过更改这个文件，来改变不同目录的访问控制限制。

    Order allow,deny
    Deny from all

    除了可以针对目录进行访问控制之外，还可以根据文件来设置访问控制，这就是File语句的任务。使用File
              语句，不管文件处于哪个目录，只要名字匹配，就必须接受相应的访问控制。这个语句对于系统安全比较重要，例如上例将屏蔽所有的使用者不能访问.htaccess文件，这样就避免.htaccess中的关键安全信息不至于被客户获取。

    #CacheNegotiatedDocs

    缺省情况下如果代理服务器和Apache服务器协商是否缓存其网页，Apache给予否定的回答，不希望自己的网页被代理服务器缓存。然而这样就不能有效的利用代理服务器的优势，因此可以设置CacheNegotiatieDocs
              选项， 使得代理服务器可以对网页进行缓存。然而即使不设置这个选项，有的代理服务器（或通过调整设置）也能对网页进行缓存。

    UseCanonicalName On

    打开这个UseCanonicalName是Web服务器的标准做法，因为客户发送的大部分请求都是对本服务器的引用，这样服务器就能使用ServerName和Port选项的设置内容构建完整的URL，并回应客户，使浏览器能得到规范的URL。如果将这个参数设置为Off，那么Apache将使用从客户请求中获得服务器的名字和端口值（支持HTTP
              1.1的客户的请求中将会有这些信息），重新构建URL。

    TypesConfig /usr/local/etc/apache/mime.types

    TypeConfig用于设置保存有不同的MIME类型数据的文件名，在FreeBSD下缺省设置为/usr/local/etc/apache/mime.types。

    DefaultType text/plain

    如果Web服务器不能决定一个文档的缺省类型，这通常表示文档使用了非标准的后缀，那么服务器就使用
              DefaultType定义的MIME类型将文档发送给客户浏览器。这里的设置为text/plain，这样设置的问题是，如果服务器不能判断出文档的MIME，那么大部分情况下这个文档为一个二进制文档，但使用
              text/plain格式发送回去，浏览器将在内部打开它而不会提示保存。因此建议将这个设置更改为 application/octet-stream，这样浏览器将提示用户进行保存。

    MIMEMagicFile /usr/local/etc/apache/magic

    除了从文件的后缀出发来判断文件的MIME类型之外，Apache还可以进一步分析文件的一些特征，来判断文件的真实MIME类型。这个功能是由mod_mime_magic模块实现的，它需要一个记录各种MIME类型特征的文件，以进行分析判断。上面的设置是一个条件语句，如果载入了这个模块，就必须指定相应的标志文件magic的位置。

    HostnameLookups Off

    通常连接时，服务器仅仅可以得到客户机的IP地址，如果要想获得客户机的主机名，以进行日志记录和提供给
              CGI程序使用，就需要使用这个HostnameLookups选项，将其设置为On打开DNS反查功能。但是这将使服务器对每次客户请求都进行DNS查询，增加了系统开销，使得反应变慢，因此缺省设置为使用Off关闭此选项。关闭选项之后，服务器就不会获得客户机的主机名，而只能使用IP地址来记录客户。

ErrorLog /var/log/httpd-error.log
LogLevel warn
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent
#CustomLog /var/log/httpd-access.log common
#CustomLog /var/log/httpd-referer.log referer
#CustomLog /var/log/httpd-agent.log agent
CustomLog /var/log/httpd-access.log combined

    这里定义了系统日志的形式，对于服务器错误记录，
              由ErrorLog、LogLevel 来定义不同的错误日志文件及其记录内容。

    对于系统的访问日志，缺省使用CustomLog参数定义日志的位置，缺省使用combined
              参数指定将所有的访问日志放在一个文件中，然而也可以将不同种类的访问日志放在不同的日志记录文件中，这是通过在 CustomLog中指定不同的记录类型来完成的。common表示普通的对单页面请求访问记录，referer表示每个页面的引用记录，可以看出一个页面中包含的请求数，agent表示对客户机的类型记录，显然可以将现有的combined
              定义的设置行注释掉，并使用common、referer和agent作为CustomLog的参数，来为不同种类的日志分别指定日志记录文件。

    显然，LogFormat是用于定义不同类型的日志进行记录时使用的格式，
              这里使用了以%开头的宏定义，以记录不同的内容。

    如果这些参数指定的文件使用的是相对路径，那么就是相对于ServerRoot的路径。

    ServerSignature On

    一些情况下，例如当客户请求的网页并不存在时，服务器将产生错误文档，缺省情况下由于打开了
              ServerSignature选项，错误文档的最后一行将包含服务器的名字、Apache的版本等信息。有的管理员更倾向于不对外显示这些信息，就可以将这个参数设置为Off，或者设置为Email，最后一行将替换为对ServerAdmin
              的Email提示。

Alias /icons/ "/usr/local/www/icons/"

    Options Indexes MultiViews
    AllowOverride None
    Order allow,deny
    Allow from all

    Alias参数用于将URL与服务器文件系统中的真实位置进行直接映射，一般的文档将在DocumentRoot
              中进行查询，然而使用Alias定义的路径将直接映射到相应目录下，而不再到DocumentRoot 下面进行查询。因此Alias可以用来映射一些公用文件的路径，例如保存了各种常用图标的icons路径。这样使得除了使用符号连接之外，文档根目录（DocumentRoot）外的目录也可以通过使用了Alias映射，提供给浏览器访问。

    定义好映射的路径之后，应该需要使用Directory语句设置访问限制。

ScriptAlias /cgi-bin/ "/usr/local/www/cgi-bin/"

    AllowOverride None
    Options None
    Order allow,deny
    Allow from all

    ScriptAlias也是用于URL路径的映射，但与Alias的不同在于，ScriptAlias是用于映射CGI程序的路径，这个路径下的文件都被定义为CGI程序，通过执行它们来获得结果，而非由服务器直接返回其内容。缺省情况下CGI程序使用cgi-bin目录作为虚拟路径。

    # Redirect old-URI new-URL

    Redirect参数是用来重写URL的，当浏览器访问服务器上的一个已经不存在的资源的时候，服务器返回给浏览器新的URL，告诉浏览器从该URL中获取资源。这主要用于原来存在于服务器上的文档，改变了位置之后，而又希望能使用老URL能访问到，以保持与以前的URL兼容。

IndexOptions FancyIndexing
AddIconByEncoding (CMP,/icons/compressed.gif) x-compress x-gzip
AddIconByType (TXT,/icons/text.gif) text/*
AddIconByType (IMG,/icons/image2.gif) image/*
AddIconByType (SND,/icons/sound2.gif) audio/*
AddIconByType (VID,/icons/movie.gif) video/*
AddIcon /icons/binary.gif .bin .exe
AddIcon /icons/binhex.gif .hqx
AddIcon /icons/tar.gif .tar
AddIcon /icons/world2.gif .wrl .wrl.gz .vrml .vrm .iv
AddIcon /icons/compressed.gif .Z .z .tgz .gz .zip
AddIcon /icons/a.gif .ps .ai .eps
AddIcon /icons/layout.gif .html .shtml .htm .pdf
AddIcon /icons/text.gif .txt
AddIcon /icons/c.gif .c
AddIcon /icons/p.gif .pl .py
AddIcon /icons/f.gif .for
AddIcon /icons/dvi.gif .dvi
AddIcon /icons/uuencoded.gif .uu
AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl
AddIcon /icons/tex.gif .tex
AddIcon /icons/bomb.gif core
AddIcon /icons/back.gif ..
AddIcon /icons/hand.right.gif README
AddIcon /icons/folder.gif ^^DIRECTORY^^
AddIcon /icons/blank.gif ^^BLANKICON^^
DefaultIcon /icons/unknown.gif
#AddDescription "GZIP compressed document" .gz
#AddDescription "tar archive" .tar
#AddDescription "GZIP compressed tar archive" .tgz
ReadmeName README
HeaderName HEADER
IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t

    当一个HTTP请求的URL为一个目录的时候，服务器返回这个目录中的索引文件。但如果一个目录中不存在缺省的索引文件，并且该服务器又许可显示目录文件列表的时候，就会显示出这个目录中的文件列表，为了使得这个文件列表能具有可理解性，而不仅仅是一个简单的列表，就需要前面的这些设置参数。

    如果使用了IndexOptions
              FancyIndexing选项，可以让服务器产生的目录列表中针对各种不同类型的文档引用各种图标。而哪种文件使用哪种图标，则使用下面的
              AddIconByEncoding、AddIconByType以及AddIcon来定义，分别依据MIME的编码、类型以及文件的后缀来判断使用何种图标。如果不能确定文档使用的图标，就使用
              DefaultIcon定义的缺省图标。

    同样，使用AddDescription可以为不同类型的文档加入不同的描述。并且，服务器还在目录下，查询使用ReadmeName和HeaderName定义的文件（自动加上.
              html后缀，如果没有发现，再使用.txt后缀进行搜索），如果发现了这些文件，就在文件列表之前首先显示这些文件的内容，以使得普通目录列表具备更大的可理解性。

    IndexIgnore让服务器在列出文件列表时忽略相应的文件，
              这里使用模式配置的方式定义文件名。

AddEncoding x-compress Z
AddEncoding x-gzip gz

    AddEncoding用于告诉一些使用压缩的MIME类型，这样可以让浏览器进行解压缩操作。

AddLanguage en .en
AddLanguage fr .fr
AddLanguage de .de
AddLanguage da .da
AddLanguage el .el
AddLanguage it .it
LanguagePriority en fr de

    一个HTML文档可以同时具备多个语言的版本，如对于file1.html文档可以具备file1.html.en、file1.html.fr
              等不同的版本，每个语言后缀必须使用AddLanguage进行定义。这样服务器可以针对不同国家的客户，通过与浏览器进行协商，发送不同的语言版本。而LanguagePriority
              定义不同语言的优先级，以便在浏览器没有特殊要求时，按照顺序使用不同的语言版本回应对file1.html 的请求。这个国际化的能力实际的应用并不多。

#AddType application/x-httpd-php3 .phtml
#AddType application/x-httpd-php3-source .phps

    AddType参数可以为特定后缀的文件指定MIME类型，这里的设置将覆盖mime.types中的设置。

    #AddHandler cgi-script
              .cgi

    AddHandler是用于指定非静态的处理类型，用于定义文档为一个非静态的文档类型，需要进行处理，再向浏览器返回处理结果。例如上面注释中的设置是将以.cgi结尾的文件设置为cgi-script类型，那么服务器将启动这个CGI程序以进行处理。如果需要在前面AliasScript定义的路径之外执行CGI程序，就需要使用这个参数进行设置，此后以.cgi结尾的文件将被当作CGI程序执行。

    在配置文件、这个目录中的.htaccess以及其上级目录的.htaccess中必须允许执行CGI程序，这需要通过Options
              ExecCGI参数设定。

#AddType text/html .shtml
#AddHandler server-parsed .shtml

    另外一种动态进行处理的类型为server-parsed，由服务器自身预先分析网页内的标记，将标记更改为正确的HTML标识。由于server-parsed需要对text/html类型的文档进行处理，因此首先定义了对应的.shtml为text/html类型。

    然而要支持SSI，还要首先要在配置文件（或.htaccess）中使用Options
              Includes允许该目录下的文档可以为SSI类型，或使用Options IncludesNOExec让执行普通的SSI标志，但不执行其中引用的外部程序。

    另一种指定server-parsed类型的方式为使用XBitBack设置选项，如果将XBitHack设置为On，服务器将检查所有text/html类型的文档（包括.html后缀的文档），如果发现文件属性具备执行位
              “x"，则服务器就认为它是服务器分析文档，需要服务器进行处理。推荐使用AddHandler进行设置，而将XBitBack 设置为Off，因为使用XBitBack将对所有的HTML文档都执行额外的检查，降低了效率。

#AddHandler send-as-is asis
#AddHandler imap-file map
#AddHandler type-map var

    上面被注释的AddHandler用于支持Apache服务器的asis、map和var处理能力。

# Action media/type /cgi-script/location
# Action handler-name /cgi-script/location

    因为Apache内部提供的处理功能有限，因此可以使用Action为服务器定义外部程序作为可处理的动态文档类型，这些外部程序与标准CGI程序相同，都是对输入的数据处理之后，再输出不同MIME类型的结果。例如要定义一个对特殊后缀wri都先执行wri2txt进行处理操作，再返回结果的操作，可以使用：

         Action windows-writer /bin/wri2txt
         AddHandler windows-writer wri

    更进一步，可以直接使用Action定义对某个MIME类型预先进行处理操作，这需要例子中第一种格式的Action
              参数设置方式。这样设置方式就不再需要额外的AddHandler用来将处理操作与文件后缀联系起来，而是使用Action直接处理MIME类型的文件。但如果文档后缀没有正式的MIME类型，还需要先定义一个MIME类型。

#MetaDir .web

#MetaSuffix .meta

    Meta信息是在文档发送给客户之前，预先发送给客户浏览器一些数据，因此浏览器可以通过HEAD请求来访问这些Meta信息而不必真正通过GET来返回全部文档数据。服务器通常发送给浏览器的是一些标准的HTTP头信息，如果要想增加额外的信息，就需要使用MetaDir来定义Meta数据存放的目录，
              而MetaS uffix用于指定包含Meta数据的文件后缀。

#ErrorDocument 500 "The server made a boo boo.
#ErrorDocument 404 /missing.html
#ErrorDocument 404 /cgi-bin/missing_handler.pl
#ErrorDocument 402 http://some.other_server.com/subscription_info.html

    如果客户请求的网页不存在，或者没有访问权限等情况发生时，服务器将产生一个错误代码，同时也将回应客户浏览器一个标识错误的网页。ErrorDocument就用于设置当出现哪个错误时应该回应客户浏览器那些内容，ErrorDocument的第一个参数为错误的序号，第二个参数为回应的数据，可以为简单的文本，本地网页，本地CGI程序，以及远程主机上的网页。

BrowserMatch "Mozilla/2" nokeepalive
BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0
BrowserMatch "RealPlayer 4\.0" force-response-1.0
BrowserMatch "Java/1\.0" force-response-1.0
BrowserMatch "JDK/1\.0" force-response-1.0

    BrowserMatch命令为特定的客户程序，设置特殊的参数，以保证对老版本浏览器的兼容性，并支持新浏览器的新特性。

#
#    SetHandler server-status
#    Order deny,allow
#    Deny from all
#    Allow from .your_domain.com
#
#
#    SetHandler server-info
#    Order deny,allow
#    Deny from all
#    Allow from .your_domain.com
#
#
#    Deny from all
#    ErrorDocument 403 http://phf.apache.org/phf_abuse_log.cgi
#

    用于设置访问控制的设置主要是针对目录和文件进行设置的，然而也可以针对不同的URL进行访问控制的设置，这样就不必担心ScriptAlias、Alias是否将路径设置到了受控制的目录之外了。针对URL进行控制的语句为
              Location语句，这样不但能对服务器上的文件、CGI提供保护，此外，它还能保护不能找到对应文件，而是由服务器本身提供的特殊功能URL。http://servername/server-status用于报告当前Apache服务器的状态，http://servername/server-info用于报告Apache
              服务器的统计信息。与此相关的设置还有ExtendedStatus参数，可以让服务器输出更详细的的报告。

#
#ProxyRequests On
#
#
#    Order deny,allow
#    Deny from all
#    Allow from .your_domain.com
#
#ProxyVia On
#CacheRoot "/usr/local/www/proxy"
#CacheSize 5
#CacheGcInterval 4
#CacheMaxExpire 24
#CacheLastModifiedFactor 0.1
#CacheDefaultExpire 1
#NoCache a_domain.com another_domain.edu joes.garage_sale.com

#

    Apache服务器本身就具备代理的功能，然而这要求加载入mod_proxy模块。这能使用IfModule语句进行判断，如果存在mod_proxy模块，就使用ProxyRequests打开代理支持。此后的Directory用于设置对Proxy功能的访问权限设置，以及用于设置缓冲的各个参数设置。

  • 虚拟主机

    •

#NameVirtualHost 12.34.56.78:80
#NameVirtualHost 12.34.56.78
#
#    ServerAdmin webmaster@host.some_domain.com
#    DocumentRoot /www/docs/host.some_domain.com
#    ServerName host.some_domain.com
#    ErrorLog logs/host.some_domain.com-error_log
#    CustomLog logs/host.some_domain.com-access_log common
#

#
#

    缺省设置文件中的这些内容是用于设置命名基础的虚拟主机服务器时使用。其中NameVirtualHost
              来指定虚拟主机使用的IP地址，这个IP地址将对应多个DNS名字，如果Apache使用了Listen 参数控制了多个端口，那么就可以在这里加上端口号以进一步进行区分对不同端口的不同连接请求。此后，使用
              VirtualHost语句，使用NameVirtualHost指定的IP地址作参数，对每个名字都定义对应的虚拟主机设置。

    虚拟主机是在一台Web服务器上，可以为多个单独域名提供Web服务，并且每个域名都完全独立，包括具有完全独立的文档目录结构及设置，这样域名之间完全独立，不但使用每个域名访问到的内容完全独立，并且使用另一个域名无法访问其他域名提供的网页内容。

    虚拟主机的概念对于ISP来讲非常有用，因为虽然一个组织可以将自己的网页挂在具备其他域名的服务器上的下级往址上，但使用独立的域名和根网址更为正式，易为众人接受。传统上，必须自己设立一台服务器才能达到单独域名的目的，然而这需要维护一个单独的服务器，很多小单位缺乏足够的维护能力，更为合适的方式是租用别人维护的服务器。ISP也没有必要为一个机构提供一个单独的服务器，完全可以使用虚拟主机能力，使服务器为多个域名提供Web服务，而且不同的服务互不干扰，对外就表现为多个不同的服务器。

    有两种设定虚拟主机的方式，一种是基于HTTP
              1.0标准，需要一个具备多IP地址的服务器，再配置DNS 服务器，给每个IP地址以不同的域名，最后才能配置Apache的配置文件，使服务器对不同域名返回不同的Web文档。由于这需要使用额外的IP地址，对每个要提供服务的域名都要使用单独的IP地址，因此这种方式实现起来问题较多。

    可以在一个网络界面上绑定多个IP地址，FreeBSD下需要使用ifconfig的alias参数来进行这个配置，但此时会影响网络性能。

    HTTP 1.1标准在协议中规定了对浏览器和服务器通信时，服务器能够跟踪浏览器请求的是哪个主机名字。因此可以利用这个新特性，使用更轻松的方式设定虚拟主机。这种方式不需要额外的IP地址，但需要新版本的浏览器支持。这种方式已经成为建立虚拟主机的标准方式。

    要建立非IP基础的虚拟主机，多个域名是不可少的配置，因为每个域名就对应一个要服务的虚拟主机。因此需要更改DNS服务器的配置，为服务器增加多个CNAME选项，如：

freebsd			IN 	A     		192.168.1.64
vhost1 			IN 	CNAME 		freebsd
vhost2 			IN 	CNAME 		freebsd

    基本的设置选项都是为了freebsd主机设定的，如果要为vhost1和vhost2设定虚拟主机，就要使用VirtualHost语句定义不同的选项，在语句中可以使用配置文件前面中的大部分选项，而可以重新定义几乎所有的针对服务器的设置。

NameVirtualHost 192.168.1.64

DocumentRoot /usr/local/www/data
ServerName  freebsd.example.org.cn

DocumentRoot /vhost1
ServerName  vhost1.example.org.cn

DocumentRoot /vhost2
ServerName  vhost2.example.org.cn

    这里需要注意的是，VirtualHost的参数地址一定要和NameVirtualHost定义的地址相一致，必须保证所有的值严格一致，Apache服务器才承认这些定义是为这个IP地址定义的虚拟主机。

    此外，定义过NameVirtualHost之后，那么对这个IP地址的访问都被区分不同的虚拟主机进行处理，而对其他IP地址的访问，例如127.0.0.1，才应用前面定义的缺省选项。


FreeBSD连载(86)：对IP地址和域名的控制

王波

服务器的安全控制

Apache提供的各种特性非常丰富，主要是由于其采用的是模块化的结构，这样就很容易进行分布式开发。 Internet上的众多开发者为Apache提供了各种各样的能力，使其能具备其他的Web服务器不能与之相比的能力。在服务器所具备的众多特性中，安全控制的特性最为有用。

  • 对IP地址和域名的控制

    Apache服务器可以基于IP地址和基于用户对访问服务器进行控制。在设置文件httpd.conf（或 access.conf）中，这些访问控制的设置是放置在Directory、File和Location语句中的，分别针对主机上的目录、文件以及URI进行存取控制。然而，由于不是每个使用者都可以随便更改系统Web服务器的设置文件，并能重新启动服务器的，因此在设置文件中的控制语句只是提供了基本的访问控制策略，而更灵活的方式是通过各个文档目录中的访问控制文件来实现的。

    为了在需要访问控制的每个目录下都设置访问控制文件，首先要在系统配置文件中设置这个访问控制文件及其访问作用。需要使用AccessFileName定义访问控制文件的名字，缺省它被设置为.htaccess。缺省设置文件将在针对根目录及/usr/local/www/data这个文档根目录的访问控制语句中设置AllowOverride None ，这就意味着不允许这个目录及其子目录中的访问控制文件起作用，为了使得访问控制文件发挥作用，必须针对需要设置访问控制的目录设置AllowOverride All或其他有部分访问控制功能的选项，此时该目录及其子目录下的访问控制文件也会发挥作用。

    AllowOverride All将允许.htaccess文件能改变所有的访问控制功能，如果仅仅希望目录的所有者只控制部分访问控制功能，可以使用AllowOverride的其他设置选项，那样.htaccess只能使用允许的设置选项。

    要在.htaccess文件中针对IP地址和域名进行控制，就需要使用访问控制语句的Limit语句。因此就要求httpd.conf中必须允许控制文件使用Limit功能，对应的设置为AllowOverride Limit选项（或All选项）。

    Limit语句可以使用不同的参数，这些参数为HTTP协议的请求方法，如使用<limit GET> 限制HTTP协议中的GET方法，<limit POST>限制http协议中的POST方法，使用</limit>标识这个控制段的结束。对于一般的情况，可以对大部分客户打开GET、POST和HEAD 请求，而关闭PUT、DELETE等其他更复杂且不常用的请求。

    如果在.htaccess中没有使用Limit语句指定具体的访问方法，那么就表示访问控制命令将对所有的请求方法都进行控制。

    Order定义服务器查询访问控制的顺序，当设置为Order Allow, Deny的时候将先处理Allow 语句，再处理Deny语句。Order Deny, Allow的处理顺序相反。由于这两种不同的方式代表不同的访问控制策略，Order deny, allow和deny from all合作，是用于只允许设置过的客户机访问服务器，而Order allow, deny和allow from all合作，是允许所有的客户机访问，而仅仅屏蔽部分具有恶意的网络地址。

    在每个Allow或Deny命令中，可以使用域名（从后向前匹配）、IP（从前向后匹配），all（代表所有主机）来标识Internet上的计算机。这里是一个例子：

order deny, allow
deny from all
allow from 192.168.1.
allow from example.org.cn
allow from 127.

    这个例子是一个专有网络的例子，它采用的封闭式策略，以保证服务器的安全性。对于对整个 Internet开放的公共Web服务器，那么采取的策略应该与之相反。


FreeBSD连载(87)：基于用户的访问控制

王波

基于用户的访问控制

更严格、有效的控制方法还是基于用户和对应的口令对浏览客户进行控制。这使得对这个目录进行强制性的保护，浏览器用户必须输入合法的用户名和正确的口令才能浏览网页。如果要针对用户对访问服务器的客户进行控制，首先就要设置访问控制文件为对用户进行认证，因此要允许目录访问控制文件中具备AuthConfig的设置。

    设置用户认证需要为这个目录指定AuthName、AuthType和AuthUserFile 指令，AuthUserFile定义一个口令文件，那么此后就可以使用require valid-user命令让客户输入名字和正确的口令，根据这个口令文件对用户的身份进行验证。AuthName定义这个认证的标识，用于返回给浏览器用户，起到提示作用。AuthType定义使用的认证加密类型，通常使用 Basic，即使用Unix的标准加密算法进行加密。

AuthUserFile /usr/local/etc/htpasswd
AuthName SecurityAuth
AuthType Basic
require vaild-user

    这个例子里，使用/usr/local/etc/htpasswd作口令文件，使用Basic的加密认证方法，并定义AuthName为SecurityAuth。

    虽然浏览器访问每个使用这种认证方式保护的网页都需要先进行认证，然而不会每访问一次网页都让用户输入用户名和口令，因为浏览器会将用户输入的用户和口令数据保存起来，每次需要认证的时候就自动进行认证操作。由于认证是通过H
              EAD请求来完成的，因此它不会影响浏览器显示的网页。然而，用户有可能使用浏览器访问了多个不同的对用户进行认证的网页，那么浏览器就会保存了多个不同的用户和口令对，当自动进行认证的时候，浏览器必须区分出应该使用哪个用户名和口令进行认证，而区分就是通过AuthName的值进行的，服务器将首先将AuthName的值传递给客户浏览器，此后浏览器就能发送正确的用户和口令进行认证了。

    要使用口令文件来认证合法用户，首先就必须生成这个口令文件。当认证类型为Basic时，口令文件与Unix
              的passwd文件非常类似，甚至可以直接使用系统passwd文件来作认证文件，当然由于现代Unix使用了sha dow技术，/etc/passwd中并没有保存真实的加密口令，因此直接使用系统passwd文件进行认证只能适合那些没有使用shadow技术的Unix系统。而使用shadow技术的Unix系统的真实口令文件（FreeBSD
              下为master.passwd）被保护起来，读取它需要root权限，而Web服务器通常以普通用户的权限运行，不能直接使用系统口令对用户进行认证。如果强制使用root权限启动httpd守护进程来访问shadow之后的口令，那么必然会带来严重的安全漏洞。

    因此一般使用与系统口令相分离的口令文件来认证Web服务器用户，这样即使口令被泄露，并被破译，造成的安全影响也很小，不至于影响系统的正常运行。可以使用Apache附带的htpasswd命令来创建口令文件，并设置用户及其口令。

$ htpasswd -c .htpasswd user1
Adding Password for user1
New password:
Re-type new password:

    htpasswd的-c选项告诉htpasswd创建一个新口令文件为.htpasswd，如果没有这个选项，htpasswd就将用户及其口令加入已经存在的口令文件中。此后的参数就是口令文件名和需要增加或改变口令的用户名。

    为了便于管理，可以进一步将这些用户分组，组文件的每一行定义了一个组及其成员的名字，然后在.htaccess
              中使用AuthGroupFile指定这个目录使用的组文件的名字，例如：

group1: user1 user2 user3 user4

    这条内容创建了一个口令组group1，包括user1,user2,user3,user4成员。

    除了可以使用require valid-user要求输入的用户必须为口令文件中的合法用户之外，也可以设置要求只有特定的合法用户才能访问的目录，这就需要使用require
              user或require group指令。例如使用require user user1要求只有user1用户才能访问，使用require
              group g roup1就要求必须是group1组的合法成员才能访问。针对具体用户和组的访问控制就进一步增加了访问控制的灵活性。

    当基于用户的认证和基于地址的认证综合使用时，可以通过使用satify参数指定不同的限制条件，如果设置
              satify all，那么必须同时通过用户和地址认证才能访问网页，而设置satify any，只需要通过一个认证客户就能访问这个目录了。缺省情况下Satify参数的值为all。下面为一个综合了地址认证和用户认证的.htaccess
              的例子，这个例子允许private.site的计算机可以不需认证访问这台服务器，而其他位置的用户必须是 group1组中的合法用户，或者是user1、user2、user3用户，才能访问这台服务器。

AuthUserFile /usr/local/etc/.htpasswd
AuthGroupFile /usr/local/etc/.htgroup
AuthName SecurityAuth
AuthType Basic

<Limit HEAD GET POST>
order deny,allow
deny from all
allow from private.site
require group group1
require user user1 user2 user3
</Limit>

satify any

  • 其他认证方式

    •

    Apache使用AuthType指定加密的方式，AuthType设为Basic时为使用命令htpasswd
              创建口令文件并进行口令加密。然而这种方式有两个缺点，一个为浏览器将在Internet上使用明文发送用户名和口令信息，另一个是htpasswd的口令文件为普通文本文件，这样当用户数目较多时，查找用户的效率就很低。

    为了弥补安全性的缺点，可以将AuthType设置为Digest，这样就会使用Digest鉴别方式进行认证，此时认证口令文件要使用AuthDigestFile来规定，而口令文件必须使用另一个加密程序htdigest
              产生和维护，而hdigest的使用方法和htpasswd相同。在Digest认证方式下，浏览器不会直接发送口令的明文信息，而是在传输口令之前先使用MD5算法进行编码处理。注意，不是所有类型的浏览器都支持Digest类型的鉴别方式的，只有在浏览器和服务器同时都支持Digest方式时，这种认证才可行。

    AuthType为Basic时，是使用系统加密方法，一般是使用DES算法，但在FreeBSD下有可能是使用的MD5算法，但除非管理员希望在不同系统间共享口令文件，否则不必考虑他们使用的到底是何种算法。需要与其他系统兼容时，可以重新安装DES算法。但在系统使用时重新安装加密算法，就无法重建整个口令文件，因此不推荐在系统使用过程中更换认证算法，而应该在系统安装时就确定使用的认证算法。

    为了减少用户数量较多时服务器的处理开销，就必须使用数据库技术，这是因为数据库使用了索引技术，对数据的查找就比较快速。Unix下最简单的数据库为使用系统提供的DB（或DBM）库进行创建数据库文件的技术，Apache
              服务器中使用模块mod_auth_db.so对这种数据库口令文件提供支持。htpasswd产生的文本文件在有几百个用户时就会花费相当大的服务器开销，而DBM格式的认证方式可以高效的支持上万个用户。

    BSD风格的Unix系统通常使用DB库，而其他Unix通常使用DBM库。因此其他Unix使用的命令和设置中应该为dbm而非db。

    为了支持这种认证方式，应载入mod_auth_db.so模块，使用Ports Collection安装的Apache服务器缺省情况就支持这个模块而不需要改动。可以让Apache同时支持多种认证方式，而不会发生冲突。

    此外，配置文件中的认证方式也需要改变，首先要创建数据库文件，这会在通过使用dbmmanage命令第一次增加用户时创建。

# dbmmanage /usr/local/etc/users adduser user1 pass123

    这个命令将创建/usr/local/etc/usersdbm数据库文件，并使用pass123为口令在数据库中增加用户user1。然后就可以针对现有的数据库文件，增加、删除和查看用户信息了：

# dbmmanage /usr/local/etc/httpd/usersdbm delete user2
# dbmmanage /usr/local/etc/httpd/usersdbm view

    在拥有了数据库文件和用户数据之后，就可以使用这种认证方式了：

AuthName DBMTest
AuthType Basic
AuthDBUserFile /usr/local/etc/usersdbm
require  valid-user

    可以使用dbmmanage命令也可以用来管理组，例如将user1加入group1组，但必须添加用户的同时进行设置，需要使用dhmmanage的另一个参数：

    # dbmmanage /usr/local/etc/users adduser
              user1 pass123 group1

    这样就能使用AuthDBGroupFile和require group1进行认证管理。

    除了使用DBM之外，Apache还可以配置成与匿名ftp认证方式类似的方式，或者使用mSql、Oracle
              等SQL数据库进行认证，或者使用Kerboros、LDAP服务器进行认证，这些认证方式更为强大，能使Web 认证与其他网络服务的认证方式相统一。但是这些额外的认证方式必须使用相应的认证模块进行支持。


FreeBSD连载(88)：安全连接方式SSL

王波

安全连接方式SSL

通常的连接方式中，通信是以非加密的形式在网络上传播的，这就有可能被非法窃听到，尤其是用于认证的口令信息。为了避免这个安全漏洞，就必须对传输过程进行加密。对HTTP传输进行加密的协议为HTTPS，它是通过SSL（安全Socket层）进行HTTP传输的协议，不但通过公用密钥的算法进行加密保证传输的安全性，而且还可以通过获得认证证书CA，保证客户连接的服务器没有被假冒。

    使用公用密钥的方式可以保证数据传输没有问题，但如果浏览器客户访问的站点被假冒，这也是一个严重的安全问题。这个问题不属于加密本身，而是要保证密钥本身的正确性问题。要保证所获得的其他站点公用密钥为其正确的密钥，而非假冒站点的密钥，就必须通过一个认证机制，能对站点的密钥进行认证。当然即使没有经过认证，仍然可以保证信息传输安全，只是客户不能确信访问的服务器没有被假冒。如果不是为了提供电子商务等方面对安全性要求很高的服务，一般不需要如此严格的考虑。

    虽然Apache服务器不支持SSL，但Apache服务器有两个可以自由使用的支持SSL的相关计划，一个为Apache-SSL，它集成了Apache服务器和SSL，另一个为Apache+mod_ssl，它是通过可动态加载的模块mod_ssl来支持SSL，其中后一个是由前一个分化出的，并由于使用模块，易用性很好，因此使用范围更为广泛。还有一些基于Apache并集成了SSL能力的商业Web服务器，然而使用这些商业Web服务器主要是北美，这是因为在那里SSL使用的公开密钥的算法具备专利权，不能用于商业目的，其他的国家不必考虑这个专利问题，而可以自由使用SSL。

    虽然通常mod_ssl以及其他复杂的Apache模块都提供了详细的编译安装说明，并提供了非常有用的脚本程序和Makefile来帮助使用者进行安装。然而为Web服务器增加一个模块并不是一个简单而易于描述的任务，幸运的是，FreeBSD提供了Ports Collection，让使用者不必关系每一步安装细节就能安装好这个模块。

    如果不打算使用Ports Collection来安装mod_ssl，那么事情就略微麻烦一些，必须自己手工下载Apache的源代码，以及mod_ssl的代码，按照说明一步步的编译安装。

    Apache+mod_ssl依赖于另外一个软件：openssl，它是一个可以自由使用的SSL实现，首先需要安装这个Port（由于专利的影响，这些软件无法制作为可以直接安装的二进制软件包，必须使用Ports Collection 安装）。openssl位于/usr/ports下面的security子目录下，当下载其源程序之前，需要设置环境变量USA_RESIDENT为NO，以避开专利纷争。

# USA_RESIDENT=NO; export USA_RESIDENT
# cd /usr/ports/security/openssl
# make; make install

    安装好openssl之后，就可以安装Apache+mod_ssl了。然而为了安装完全正确，需要清除原先安装的Apache服务器的其他版本，并且还要清除所有的设置文件及其缺省设置文件，以避免出现安装问题。最好也删除
              /usr/local/www目录（或更名），以便安装程序能建立正确的初始文档目录。如果是一台没有安装过Apache 服务器的新系统，就可以忽略这个步骤，而直接安装Apache+mod_ssl了。

    删除旧有文件之后，便可进入相应目录，启动安装和编译进程。

# cd /usr/ports/www/apache13+mod_ssl
# make ; make install
# make certifaction=custom

    最后一个make用于生成认证证书，由于这个Port直接生成了httpd.conf等缺省文件（如果安装的时候没有httpd.conf等文件存在），因此可以直接启动新的服务器而不需要设置，如果启动过程因为设置文件的不合适而导致一些小问题，请参照前面对标准Apache服务器的设置说明作出相应修改。

# /usr/local/sbin/apachectl startssl

    此时使用start参数为仅仅启动普通Apache的httpd守护进程，而不启动其SSL能力，而startssl
              才能启动Apache的SSL能力。如果之前Apache的守护进程正在运行，便需要使用stop参数先停止服务器运行。

    然后，就可以启动netscape或其他支持SSL的浏览器，输入URL为：https://ssl_server/
              来查看服务器是否有相应，https使用的缺省端口为443，如果一切正常，服务器将返回mod_ssl的使用手册，讲解SSL以及mod_ssl的技术及其使用方法。


FreeBSD连载(89)：CGI和SSI的安全性

王波

CGI和SSI的安全性

允许根据用户的请求而在服务器上运行程序，本身就是一种安全漏洞，因此只有在必要时，才允许用户使用这些功能。

    对于SSI，安全问题比较简单，可以将其设置为只分析普通标志，不执行外部程序，这必须在配置文件中使用 Options IncludesNOEXEC选项，而非Options Includes选项。就能满足对安全性的一般要求。

    CGI程序的情况更为复杂。由于CGI可以用两种方式设置，一种为由ScriptAlias设置CGI程序的路径，另一种为通过设置CGI的后缀而设置的。通常只有在信任用户有能力创建没有（或很少）漏洞的CGI程序时，才使用后缀确认CGI程序。否则将会产生一些很糟糕的CGI程序，使得系统很容易被攻击。因此将CGI程序限制在一些固定目录下的做法更为常见，这至少让一个CGI程序经过服务器管理员的一些检查，避免明显的漏洞。

    CGI程序的另一个问题是，如果CGI程序要保存浏览器客户发布的数据，那么它就要访问系统的文件系统。通常 Apache服务器使用User和Group配置服务器运行的用户和组属性，Apache服务器启动的CGI程序缺省也使用这个用户和组属性运行，也就拥有了这个用户和组的权限，可以存取文件系统中的数据，这就对系统安全造成另一个影响。然而又必须让CGI程序存取数据文件，因此就要适当调整User和Group的设置，使得它能够存取合适的数据文件。

    即使如此，由于所有的CGI程序都以同样的用户执行，那么不同用户的CGI就能相互操作别的用户的数据文件，从而造成安全问题。为了使得不同的用户以不同的用户身份执行CGI，就需要使用程序的SetUID功能。因为SetUID 会带来极大的系统漏洞问题。因此如非必要，不要使用SetUID程序，尤其是root身份的SetUID程序。设置用户身份的问题可以使用Apache的suEXEC能力来帮助完成，它首先将身份改变为合适的用户，再执行相应的CGI程序。


FreeBSD连载(90)：单服务器性能调整

王波

调整服务器性能

前面介绍了Apache服务器的基本设置选项，通过调整这些设置，就能使Web服务器达到非常优秀的性能。此外，还可以调整操作系统的设置，包括重新定制整个系统，使之适合高负载的Web服务器。进一步，还可以利用Apache 提供的各种服务器技术，如FastCGI、PHP等，充分发挥Web服务器的作用。

    调整Web服务器的性能，首先就要调整系统内核的性能，需要定制一个适合服务器要求的内核。此外，不要忘记使用egcc及更大的优化选项来编译Web服务器。

  • 单服务器性能调整

    由于Apache服务器具备高度的可配置性，因此通过调整其设置，可以极大的提升服务器的性能。对于Web 服务器，所面对的性能问题主要可以分为两个方面，一个为Web服务器提供静态网页的性能，另一个为产生动态网页时的性能。其中在产生动态网页时的性能下降是影响服务器性能的主要因素。

  • 使用新特性提升性能

    为了改善产生动态网页时的性能，可以尝试使用Apache能提供的新特性来帮助解决性能问题。虽然CGI和SSI 都能用于产生动态网页，但都各具缺点。CGI需要每次都要启动一个进程，因此增加了运行服务器的负担，而SSI功能简单，不适合大部分需要。因此为了增加服务器的性能，Web服务器的开发者考虑了各种不同的技术，以提高服务器提供动态网页时的运行速度。

    增加产生动态网页的性能，可以从两个角度出发，一个基于原有的CGI程序，设法使得一个CGI进程能提供多次 CGI服务，而不必每次都重新产生进程，增加服务器负担，基于这种考虑的解决方式的代表为FastCGI，这是由OpenMarket 公司开发了一个基于CGI的新标准，一个FastCGI程序能驻留在系统中，和Web服务器通信，并多次回应CGI请求，而不必重新生成进程。FastCGI程序与标准CGI程序非常类似，仅仅需要简单的修改原有的CGI 程序，就能支持FastCGI。FreeBSD下没有支持FastCGI的Port，因此要支持FastCGI就需要重新手工编译安装。

    另一个角度是从服务器端分析功能入手，既然SSI功能较弱，可以进一步在服务器内部提供更复杂的功能，PHP 就是一个代表，PHP具备丰富的数据库支持能力，因此非常流行。然而PHP却有相应的Port支持，因此可以使用 Ports Collection轻松安装PHP，同时这个Port还支持和mod_ssl相集成，可以通过选择同时集成 php3和mod_ssl。需要注意的是在安装之前仍然需要清除原有设置文件，以免带来不必要的麻烦。

    Apache-PHP3具备一个预编译好的二进制软件包，如果不想重新编译Apache，可以直接使用这个软件包。要建立一个复杂的网站，至少要使用这个预编译好的软件包，以提供高效率的动态网页支持。

    此外，由于CGI程序使用Perl编程的非常之多，因而一个非常有意义的作法为将perl解释器和Apache 集成在一起，这样在执行perl程序时就不需要重新载入Perl解释器了，这样同样也能数倍提高服务器的效率。支持集成perl到Apache中的模块为mod_perl，它充分发挥了perl的强大功能。在这种方式下，不但可以直接执行perl编写的CGI程序，还可以在嵌入perl语句，甚至使用perl控制Apache服务器的行为，包括使用perl来编写Apache的内部功能处理模块。mod_perl同样也没有Port Collection支持，需要自己下载软件重新编译Apache。

    FastCGI、PHP3和嵌入的perl只是在Apache服务器上最流行的几种新特性，使用它们可以非常高效的完成动态网页的生成。这些新特性对于建立一个高负载的站点是必需的。但是，也没有必要同时都提供支持，不同的使用者会喜欢使用不同的动态网页生成方式。其中PHP3的安装和设置非常简单，它又是服务器端分析方式，因此是在做新站点时的首选方式。而如果有大量原有的CGI程序需要继承，就可以选择FastCGI，perl的忠实拥护者则会选择modperl。

  • 调整系统设置

    由于Apache服务器是采用传统的生成子进程的方式来提供服务的形式，这种形式比较适合服务比较复杂的情况，但性能却没有单进程的服务器高，尤其在高负载的情况下更是如此。一些使用单进程的Web服务器，都其声称提供静态网页的速度为Apache服务器的几倍，例如能通过Ports Collection安装的boa，或者另一个非常简单的服务器thttpd，它们提供静态网页的速度的确是Apache服务器无法与之相比的。当然，这些服务器除了因为其是单进程的服务，效率较高之外，还因为这些服务器没有提供复杂的特性，包括安全认证等，例如安全认证就需要Web服务器读取其上面各级目录的访问许可，这些额外的文件操作会明显降低服务器的效率。然而，由于执行CGI处理时，服务器都必须启动外部进程，这些简易的服务器就不再具备什么优势了。

    因此，如果使用者仅仅是想提供简易的静态网页服务，完全可以不必使用Apache服务器，单进程服务器性能更好，但使用者也无法利用Apache服务器提供的各种优秀特性了。然而，即使是使用Apache服务器，对提高效率也提供了很多设置参数，如果能将这些参数调整的合适，就能进一步提高服务器的性能，缩小与单进程服务器性能的差别。

    有些性能损失，如提供安全控制的特性造成的损失，只能尽量减少，而无法消除。为了减少这些特性造成的损失，对于安全控制，可以在设置文件中针对根目录指定AllowOverrider None禁止查找.htaccess文件，只对于特定需要访问控制的目录才打开访问控制功能。此外，还要设置XbitBack为Off来关闭缺省文档的SSI 功能，只使用AddHandler指令执行SSI文档。

    除了高级特性找成的性能损失之外，还有的性能损失是由于子进程服务的方式造成的，Apache服务器在这个方面做了很大的努力，由于使用服务器的用户需求多种多样，因此缺省需求并不一定最适合服务器，便需要调整参数设置。

    为了提升服务器性能，Apache服务器所做的一个有效的改动为使一个子进程能服务多次HTTP请求，这样就不再需要不断生成进程造成的性能损耗。但同时为了避免一个进程服务提供过多的次数的服务造成内存垃圾，Apache定义了一个MaxRequestPerChild来规定一个进程提供服务的次数，缺省设置为30。如果服务器提供的为静态网页，产生内存垃圾的机会就很少，可以将其设置为2000或者更高。即使服务器载入了各种不同的功能模块，产生内存垃圾的机会就多一些，可以相应将这个值的设置降低一些。

    此外，还可以定义另一个参数MaxClients，用于设置Apache服务器可以同时拥有的最多进程数。进程数目越多，那么占用的内存数量就越大，一旦占用的内存超过系统的物理内存，那么就必须有多余的进程被交换到交换空间中，这样的事情一旦发生，服务器的效率就急剧降低了。因此，即使希望服务器能同时提供较多的服务，也不能超过服务器的物理内存限制进行设置。通常这可以通过计算进行估计，根据每个httpd守护进程占用空间的大小计算出这个数值的上限。或者可以根据系统维护命令，如top等，观察每个子进程占用的空间及系统内存分配情况。一般来讲，Apache服务器占用的空间并不会特别厉害，但一旦载入特别的模块，特别是modperl，它就会使用较多的内存。

    原则上虽然可以使用物理内存来估算MaxClients的值，但是一方面还要考虑CPU的处理能力，当系统进程过多的时候，系统在进程之间切换造成的资源损失太大，就得不偿失了（top命令中的CPU利用率选项中，有一项sys 就用于标识内核占用的处理器处理时间的比率，这一个比率不应该过大）。另一方面，由于FreeBSD是合并内存和磁盘缓冲区的机制，因此应该给磁盘缓冲区留下一定的大小，毕竟Web服务器中磁盘I/O的性能也非常重要。

    FreeBSD中，编译时设定了最大的客户进程数为512，这是一个硬性设置，不能通过配置文件来更改的。如果想想将MaxCliets设置为大于512，就必须使用新的HARD_SERVER_LIMIT定义重新编译Apa che服务器。在非Ports Collection编译的Apache版本中，它的缺省设置为256。

    因此就需要综合考虑这些因素来设置MaxClients，首先要为磁盘缓冲区留下足够的空间，并以不交换到交换设备上为原则，定出一个上限值，然后根据处理器的情况进行分析。如果这个站点主要提供的是静态网页，那么对处理器的要求不大，就可以设置MaxClients为接近内存许可的上限值。如果这个站点有很多CGI程序，尤其是当这些CGI 程序需要执行繁重的处理任务时，那么系统启动过多的CGI程序，都不会迅速结束，反而不如让系统启动较少的CGI程序效率高，因此就要考虑适当降低MaxClients的设置。

    考虑Maxclients设置的前提是同时有超出现有Maxclients设置的并发请求发生，如果系统本来就没有那么多的并发请求，就不必考虑增加这个设置的值，而应该使用最大并发访问请求数来设置这个参数。

    为了确定服务器的最优设置，可以通过使用Apache提供的一个性能测试软件ab来进行模拟访问，这个程序缺省被安装到/usr/local/sbin中。例如使用ab向本地服务器的一个网页同时发起50个连接，共进行1000次连接，就执行：

bash-2.02$ /usr/local/sbin/ab -n 1000 -c 50 localhost/
This is ApacheBench, Version 1.2
Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright (c) 1998-1999 The Apache Group, http://www.apache.org/

Server Software:        Apache/1.3.4
Server Hostname:        localhost
Server Port:            80

Document Path:          /
Document Length:        360 bytes

Concurrency Level:      50
Time taken for tests:   3.881 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      607212 bytes
HTML transferred:       360720 bytes
Requests per second:    257.67
Transfer rate:          156.46 kb/s received

Connnection Times (ms)
              min   avg   max
Connect:        0     0     1
Processing:    26   190  1034
Total:         26   190  1035

    先调整相应的设置，然后使用ab模拟真实情况下的连接，来测试服务器的性能，并进一步调整参数以获得最佳的设置。

    为了避免服务器进程在系统空闲时被无意义的杀死，可以简单的将MinSpareServers、MaxSpa
              reServers和StartServers的值设置为与MaxClients的值相同。这种设置方式对于总是处于重负载的专业Web站点的设置方式，对于业余站点，就没有必要如此设置，这些值都可以设置得较小，以便来没有客户访问时，系统负载可以降低，留出处理能力完成其他任务。


FreeBSD连载(91)：提升静态网页服务能力的综合方式

王波

提升静态网页服务能力的综合方式

由于真正的HTTP请求常常是混合了静态请求和动态页面请求，那么很难调整Apache的设置使其既能适合静态网页请求，又能适合动态网页请求。为了提升Web服务的性能，还可以使用多个服务器，来帮助提升服务器性能。

  • 代理服务器的加速模式

    由于Apache服务器不能够特别高效的提供静态网页服务，那么就可以使用一些辅助手段来帮助Apache服务器来高效的实现静态网页服务。一个有效的方法为使用代理服务器Squid，Squid具备一种加速模式，这个模式下 Squid能将所有的HTTP请求转发给内部的真正Web服务器。然而由于Squid是单进程的服务器，这样就不会因为并发访问而产生大负载，并且它具备对静态网页的缓存功能，使得Squid不必每次都需要访问后端Web服务器。因此使用Squid能明显减轻对静态网页频繁访问造成的负载问题。

    由于Squid不会带来很大的CPU负载，因此不必要让Squid单独运行在一台服务器上，可以让Squid 和Apache服务器同时运行在一台服务器上，这样通过对磁盘I/O产生一些额外的负载，但能有效的增加静态网页的服务能力。

    请查看Squid的手册以得到如何设置加速模式的方法，Squid软件包含在FreeBSD的Packages Collection中。

  • 分离静态网页服务器和动态网页服务器

    由于Apache提供静态网页的服务能力不佳，那么可以将静态请求交给效率较高的服务器软件，如thttpd ，而动态请求较给Apache服务器来执行处理。这样的缺点就是其他的简易Web服务器不能提供Apache服务器一样的丰富功能，因此虽然这样做会提升效率，但一般并不建议这样设置服务器。

    考虑到Apache服务器的设置因素，如果设置合适，Apache服务器本身就能提供高效的静态页面服务，只是当静态页面和动态页面混合的时候，就无法决定最优设置。尤其是当Apache支持了一些特定模块的时候，这些模块将使用大量的内存（例如一个mod_perl可能占据10M以上的内存空间），使得即使这个服务器是提供静态网页服务时，也要占用那么多内存，这样就使得为动态网页定制的设置完全不适合静态网页。

    因此为了解决服务器的不同情况下的优化设置不同的问题，就可以在一台计算机同时运行两个Apache服务器，一个比较纯粹，没有支持额外的模块，只是为了和第二个服务器协作，需要支持proxy模块，用于支持静态网页，同时提供对第二个Apache服务器的代理请求，第二个Apache服务器可以载入复杂的模块，以支持动态网页。

    两个Apache服务器可以根据不同的需要，进行不同的参数调整。第一个Apache服务器只进行静态网页服务和代理服务，因此可以将MaxClients设置的较大，而第二个Apache服务器要提供消耗处理器能力的动态网页服务，因此就要将MaxClients设置的较小。此时在第一个Apache服务器上设置其代理功能，虽然Apache 的代理能力比不上Squid优秀，然而这简化了服务器的种类，并能使用同一的访问控制手段。

    此时代理服务器是用于代理动态网页请求，和前面使用Squid代理静态网页请求的目的不同。但是也可以适用 Squid，在外部访问静态网页的时候，它代理访问第一个Web服务器，访问动态网页的时候，代理访问第二个Web服务器。

    当使用这种设置方式的时候，为了使得外部客户访问第一个服务器时能自动代理到第二个服务器上，就需要在第一个 Apache上使用ProxyPass参数进行设置，将用于动态网页的CGI请求转发给第二个服务器。此时就有不同的选择，可以使用两个计算机各自运行一个Web服务器，也可以在一台计算机上安装两个Apache服务器，第一个服务器监听普通的80端口，而第二个服务器监听其他端口，例如3456，在第一个服务器的httpd.conf中设置ProxyPass：

ProxyPass /cgi-/bin/ http://localhost:3456/cgi-bin/

    当在一个计算机上安装两个Apache服务器的时候，必须注意安装路径的问题。至少有一个服务器不能使用
              Ports Collection直接安装，应该更改过路径设置编译安装。


FreeBSD连载(92)：基于DNS的负载均衡

王波

负载均衡技术

可以使用上面提到的各种技术来提升Apache服务器的性能，同时也可以使用增加硬件性能的方法来提高Web 服务器的性能。但是单台服务器的性能总是有限的，尤其是服务器上需要运行大量的CGI程序时，不可能仅靠上面的调整服务器设置的方法来建立一个面向整个Internet，如同Yahoo等站点一样的高负载Web站点。

    为了建立一个高负载的Web站点，必须使用多服务器的分布式结构。上面提到的使用代理服务器和Web服务器相结合，或者两个Web服务器相互协作的方式也属于多服务器的结构，但在这些多服务器的结构中，每个服务器所起到的作用是不同的，属于非对称的体系结构。非对称的服务器结构中每个服务器起到的作用是不同的，例如一个服务器用于提供静态网页，而另一个用于提供动态网页等等，这样就使得网页设计时就需要考虑不同服务器之间的关系，一旦要改变服务器之间的关系，就会使得某些网页出现连接错误，不利于维护，可扩展性也差。

    另外一种多服务器的设计结构为对称结构，在对称结构中每台服务器都具备等价的地位，都可以单独对外提供服务而无须其他服务器的辅助。然后，可以通过某种技术，将外部发送来的请求均匀分配到对称结构中的每台服务器上，接收到连接请求的服务器都独立回应客户的请求。在这种结构中，将外部请求均匀分配到服务器上的技术称为负载均衡技术，由于建立内容完全一致的Web服务器并不困难，因此负载均衡技术就成为建立一个高负载Web站点的关键性技术。

  • 基于DNS的负载均衡

    最早的负载均衡技术是通过DNS服务中的随机名字解析来实现的。在DNS服务器中，可以为多个不同的地址配置同一个名字，这个数据被发送给其他名字服务器，而最终查询这个名字的客户机将在解析这个名字时随机使用其中一个地址。因此，对于同一个名字，不同的客户机会得到不同的地址，因此不同的客户访问的也就是不同地址的Web服务器，从而达到负载均衡的目的。

    例如如果希望使用三个Web服务器来回应对www.exampleorg.org.cn的HTTP请求，就可以设置该域的DNS服务器中关于该域的数据包括与下面例子类似的结果：

www1		IN		A 		192.168.1.1
www2		IN		A 		192.168.1.2
www3		IN		A 		192.168.1.3
www		IN		CNAME		www1
www		IN		CNAME		www2
www		IN		CNAME		www3

    这里先为每个计算机定义一个真实名字，然后再为它们定义同一个别名。直接针对不同地址设置同一个真实名字（A记录）也是可行的，但使用别名的方法易于管理一些。

    由于此时反向解析只能针对一台计算机，那么每个Web服务器都需要使用ServerName重新定义同一个名字，或者设置名字解析的顺序为hosts文件优先，并在hosts文件中定义本身为www，以保证每个服务器的名字设置保持一致。

    此后外部的客户机就可能随机的得到对应www的不同地址，那么随后的HTTP请求也就会发送给不同地址了。

    当使用DNS负载均衡的时候，必须尽量保证不同的客户计算机能均匀获得不同的地址。由于DNS数据是具备一个刷新时间的标志的，一旦超过这个时间限制过期，其他DNS服务器就需要和这个服务器交谈以重新获得地址数据，就有可能获得不同IP地址。因此为了使得地址能随机分配，就应该使得刷新时间尽量短，不同地方的DNS服务器能更新对应的地址，使得地址获得能随机一些。然而将过期时间设置的过低将使得DNS流量大增，而造成额外的网络问题。出于折衷的考虑，一般将刷新时间设置为1个小时。

    DNS负载均衡的一个问题是一旦某个服务器出现故障，即使及时修改了DNS设置，还是要等待足够的时间（刷新时间）才能发挥作用，在此期间保存了故障服务器地址的客户计算机将不能正常访问服务器。

    尽管存在多种问题，然而它还是一种非常有效的做法，当前使用在包括Yahoo在内的很多Web站点上。


FreeBSD连载(93)：反向代理负载均衡

王波

反向代理负载均衡

   前面提到了使用代理服务器可以将请求转发给内部的Web服务器，使用这种加速模式显然可以提升静态网页的访问速度。然而，也可以考虑这样一种技术，使用代理服务器将请求均匀转发给多台Web服务器上，从而达到负载均衡的目的。

    Apache开发组的一位成员Ralf S.Engelschall基于Apache的代理模块mod_proxy开发了反向代理模块mod_rproxy，用于实现负载均衡，请参考他的文章Load Balancing Your Web Site： http://www.WebTechniques.com/features/1998/05/engelschall/engelschall.shtml

    这种代理方式与普通的代理方式有所不同，标准代理方式是客户使用代理访问多个外部Web服务器，而这种代理方式是代理多个客户访问内部Web服务器，因此也被称为反向代理模式。Squid的加速模式与此相似，但没有实现对多内部服务器的均衡设置。虽然实现这个任务并不能算是特别复杂，然而由于要求特别高的效率，则实现起来并不是十分简单。

    使用反向代理的好处是，可以将负载均衡和代理服务器的高速缓存技术结合在一起，提供有益的性能。然而它本身也存在不小的问题，首先就是必须为每一种服务都专门开发一个反向代理服务器，这就不是一个轻松的任务了。并且，虽然代理服务器本身虽然可以设计的效率非常高，但是每针对每一次代理，代理服务器就必须维护两个连接，一个对外的连接，一个对内的连接，因此对于特别高的连接请求的时候，代理服务器的负载也就非常之大了。很可能在最后反向代理服务器成为了服务的瓶颈。


FreeBSD连载(94)：基于NAT的负载均衡技术

王波

基于NAT的负载均衡技术

    网络地址转换为Internet网关的一个重要功能，它能将内部地址和外部地址进行转换，以使具备内部地址的计算机能访问外部网络。同样外部网络访问网关拥有的某一外部地址时，地址转换网关能将其转发到该地址映射的内部地址的计算机上。

    因此，可以通过重新修改地址转换程序，使得地址转换网关能将请求均匀转换为内部的多个服务器的内部地址，此后外部网络中的计算机就各自与自己转换得到的内部服务器进行通信了。

    要实现这个负载均衡软件，仍然需要更改原有的地址转换程序。然而，由于FreeBSD下提供了地址转换工具 natd及其源代码，因此这个任务并不复杂。通过更改natd，可以使得在FreeBSD上实现负载均衡能力。

  • 第四层交换

    由于地址转换相对来讲比较接近网络的低层，因此就有可能将它集成在硬件设备中，通常这样的硬件设备为局域网交换机。

    当前先进的局域网交换机开始支持所谓的第四层交换技术，就是按照IP地址和TCP端口进行虚拟连接的交换，直接将数据包发送到目的计算机的相应端口中。通过可以进一步增强它的功能，通过交换机就能将来自外部的初始连接请求，分别与内部的多个地址相联系，此后就能对这些已经建立的虚拟连接进行交换。因此一些具备第四层交换能力的局域网交换机，就能作为一个硬件负载均衡器，完成Web服务器的负载均衡。

    由于第四层交换基于硬件芯片，因此其性能非常优秀，尤其是对于网络传输的速度，交换的速度远远超过普通的数据包转发。然而正因为它是使用硬件实现的，因此也比较不灵活，仅仅能够处理几种最标准的应用协议的负载均衡，如HTTP 。当前负载均衡主要用于解决Web服务器的处理能力不足的问题，因此并不能充分发挥交换机带来的高网络带宽的优点。