diff --git a/zh_CN.GB2312/books/handbook/audit/chapter.sgml b/zh_CN.GB2312/books/handbook/audit/chapter.sgml index 7eb4468291..bf5002cc26 100644 --- a/zh_CN.GB2312/books/handbook/audit/chapter.sgml +++ b/zh_CN.GB2312/books/handbook/audit/chapter.sgml @@ -1,612 +1,613 @@ Tom Rhodes 原作 Robert Watson 安全事件审计 概述 AUDIT 安全事件审计 MAC &os; 6.2 和更高版本中包含了对于细粒度安全事件审计的支持。 事件审计能够支持可靠的、 细粒度且可配置的, 对于各类与安全有关的系统事件, 包括登录、 配置变更, 以及文件和网络访问等的日志记录。 这些日志记录对于在正在运行的系统上实施监控、 入侵检测和事后分析都十分重要。 &os; 实现了 Sun 所发布的 BSM API 和文件格式, 并且与 &sun; 的 &solaris; 和 &apple; 的 &macos; X 审计实现兼容。 这一章的重点是安装和配置事件审计。 它介绍了事件策略, 并提供了一个审计的配置例子。 读完这章, 您将了解: 事件审计是什么, 以及它如何工作。 如何在 &os; 上为用户和进程配置事件审计。 如何使用审计记录摘要和复审工具来对审计记录进行复审。 阅读这章之前, 您应该: 理解 &unix; 和 &os; 的基础知识 ()。 熟悉关于内核配置和编译的基本方法 ()。 熟悉安全知识以及如何在 &os; 运用它们 ()。 - 在 &os; 6.2 上的审计机制是试验性的, + 在 &os; 6.X 上的审计机制是试验性的, 在生产环境中部署之前, 应仔细评估部署试验性软件可能带来的风险。 已知的限制是, 并不是所有与安全有关的系统事件都是可审计的, 某些登录机制, 例如基于 X11 显示管理器, 以及第三方服务的登录机制, 都不会在用户的登录会话中正确配置审计。 安全审计机制能够对系统活动生成非常详细的记录信息: 在繁忙的系统中, 记帐数据如果配置不当会非常的大, 并在一周内迅速超过几个 GB 的尺寸。 管理员应考虑审计配置中的导致磁盘空间需求的这些问题。 例如, 可能需要为 /var/audit 目录单独分配一个文件系统, 以防止在审计日志所用的文件系统被填满时影响其它文件系统。 本章中的一些关键术语 在开始阅读这章之前, 我们需要解释一下与审计有关的一些关键的术语: 事件 (event): 可审计事件是指能够被审计子系统记录的任何事件。 举例说来, 与安全有关的事件包括创建文件、 建立网络连接, 以及以某一用户身份登录, 等等。 任何事件必要么是 有主 (attributable) 的, 即可以最终归于某一已通过验证的用户的身份, 反之, 则称该事件是 无主 (non-attributable) 的。 无主事件可以是发生在登录过程成功之前的任何事件, 例如尝试一次无效密码等。 类 (class): 事件类是指相关事件的一个命名集合, 通常在筛选表达式中使用。 常用的事件类包括 创建文件 (fc)、 执行 (ex) 和 登入和注销 (lo)。 记录 (record): 记录是指描述一个安全事件的日志项。 记录包括记录事件类型、 执行操作的主体 (用户) 信息、 日期和事件信息, 以及与之相关的对象或参数信息, 最后是操作成功或失败。 账目 (trail): 审计账目, 或日志文件, 包含了一系列描述安全事件的审计记录。 典型情况下, 审计账目基本上是以事件发生的时间顺序记录的。 只有获得授权的进程, 才能够向审计账目中提交记录。 筛选表达式 (selection expression): 筛选表达式是包含一系列前缀和审计事件类名字, 用以匹配事件的字符串。 预选 (preselection): 系统通过这一过程来识别事件是否是管理员所感兴趣的, 从而避免为他们不感兴趣的事件生成记录。 预选配置使用一系列选择表达式, 用以识别事件类别、 要审计的用户, 以及适用于验证过用户身份, 以及未验证用户身份的进程的全局配置。 浓缩 (reduction): 从现有的审计记帐中筛选出用于保留、 打印或分析的过程。 除此之外, 它也表示从审计记帐中删去不需要的审计记录的过程。 通过使用浓缩操作, 管理员可以实现预留审计数据的策略。 例如, 详细的审计记帐信息, 可能会保留一个月之久, 但在这之后, 则对这些记帐信息执行浓缩操作, 只保留登录信息用于存档。 安装审计支持 对于事件审计的支持, 已经随标准的 installworld 过程完成。 管理员可以通过查看 /etc/security 的内容来确认这一点。 您应能看到一些名字以 audit 开头的文件, 例如 audit_event 用户空间对事件审计的支持已经作为 &os; 基本系统的一部分被安装。 - 在 &os; 6.3 和以后的版本中,内核对于事件审计的支持已被默认编译进内核。 - 对于 &os; 6.2 必须加入明确地把以下这行加入内核配置文件并编译。 + 在 &os; 7.0 和以后的版本中,内核对于事件审计的支持已被默认编译进内核。 + 对于 &os; 6.X + 必须加入明确地把以下这行加入内核配置文件并编译。 options AUDIT 接下来, 您应按照 中所介绍的步骤来完成一次内核的编译和安装。 在编译好并安装了内核, 并重新启动了系统之后, 就可以在 &man.rc.conf.5; 中增加下列配置来启用审计服务了: 在编译、安装了开启审计功能的内核,并重新启动计算机之后, 就可以在 &man.rc.conf.5; 中增加下列配置来启用审计服务了: auditd_enable="YES" 此后, 必须重新启动系统, 或通过下面的命令手工启动审计服务来启动审计支持: /etc/rc.d/auditd start 对审计进行配置 所有用于安全审计的配置文件, 都可以在 /etc/security 找到。 要启动审计服务, 下面这些文件必须存在: audit_class - 包含对于审计类的定义。 audit_control - 控制审计子系统的特性, 例如默认审计类、 在审计日志所在的卷上保留的最小空间、 审计日志的最大尺寸, 等等。 audit_event - 文字化的系统审计事件名称和描述, 以及每个事件属于哪个类别。 audit_user - 针对特定用户的审计需求, 这些配置在登录时会与全局的默认值合并。 audit_warn - 由 auditd 调用的一个可定制的 shell 脚本, 用于在意外情况, 如用于审计日志的空间过少, 或审计日志文件被翻转时, 生成警告信息。 在编辑和维护审计配置文件时一定要小心, 因为配置文件中的错误会导致记录事件不正确。 事件筛选表达式 在审计配置文件中的许多地方会用到筛选表达式来确定哪些事件是需要审计的。 表达式中需要指定要匹配的事件类型, 并使用前缀指定是否应接受或忽略匹配的事件, 此外, 还可以指定一个可选项指明匹配成功或失败的操作。 选择表达式是按从左到右的顺序计算的, 而对于两个表达式的情形, 则是通过将后一个追加到前一个之后来实现的。 下面列出了在 audit_class 中的默认事件类型: all - all (全部) - 表示匹配全部事件类。 ad - administrative (管理) - 所有在系统上所进行的管理性操作。 ap - application (应用) - 应用程序定义的动作。 cl - file close (文件关闭) - 审计对 close 系统调用的操作。 ex - exec (执行) - 审计程序的执行。 对于命令行参数和环境变量的审计是通过在 &man.audit.control.5; 中 policyargvenvv 参数来控制的。 fa - file attribute access (造访文件属性) - 审计访问对象属性, 例如 &man.stat.1;、 &man.pathconf.2; 以及类似事件。 fc - file create (创建文件) - 审计创建了文件的事件。 fd - file delete (删除文件) - 审计所发生的文件删除事件。 fm - file attribute modify (修改文件属性) - 审计文件属性发生变化的事件, 例如 &man.chown.8;、 &man.chflags.1;、 &man.flock.2;, 等等。 fr - file read (读文件数据) - 审计读取数据、 文件以读方式打开等事件。 fw - file write (写文件数据) - 审计写入数据、 文件以写方式打开等事件。 io - ioctl - 审计对 &man.ioctl.2; 系统调用的使用。 ip - ipc - 审计各种形式的进程间通信 (IPC), 包括 POSIX 管道和 System V IPC 操作。 lo - login_logout - 审计系统中发生的 &man.login.1; 和 &man.logout.1; 事件。 na - non attributable (无主) - 审计无法归类的事件。 no - invalid class (无效类) - 表示不匹配任何事件。 nt - network (网络) - 与网络操作有关的事件, 例如 &man.connect.2; 和 &man.accept.2;。 ot - other (其它) - 审计各类杂项事件。 pc - process (进程) - 审计进程操作, 例如 &man.exec.3; 和 &man.exit.3;。 这些审计事件, 可以通过修改 audit_classaudit_event 这两个配置文件来进行定制。 这个列表中, 每个审计类均包含一个表示匹配成功/失败操作的前缀, 以及这一项是否是增加或删去对事件类或类型的匹配。 (none) 审计事件的成功和失败实例。 + 审计这一类的成功事件。 - 审计这一类的失败事件。 ^ 不审计本类中的成功或失败事件。 ^+ 不审计本类中的成功事件。 ^- 不审计本类中的失败事件。 下面例子中的筛选字符串表示筛选成功和失败的登录/注销事件, 而对执行事件, 则只审计成功的: lo,+ex 配置文件 多数情况下, 在配置审计系统时, 管理员只需修改两个文件: audit_controlaudit_user。 前者控制系统级的审计属性和策略, 而后者则用于针对具体的用户来微调。 <filename>audit_control</filename> 文件 audit_control 文件指定了一系列用于审计子系统的默认设置。 通过查看这个文件, 我们可以看到下面的内容: dir:/var/audit flags:lo minfree:20 naflags:lo policy:cnt filesz:0 这里的 选项可以用来设置用于保存审计日志的一个或多个目录。 如果指定了多个目录, 则将在填满一个之后换用下一个。 一般而言, 审计通常都会配置为保存在一个专用的文件系统之下, 以避免审计系统与其它子系统在文件系统满的时候所产生的冲突。 字段用于为有主事件配置系统级的预选条件。 在前面的例子中, 所有用户成功和失败的登录和注销都会被审计。 参数用于定义保存审计日志的文件系统上剩余空间的最小百分比。 当超过这一阈值时, 将产生一个警告。 前面的例子中, 最小剩余空间比例设置成了两成。 选项表示审计类审计无主事件, 例如作为登录进程和系统服务的那些进程的事件。 选项用于指定一个以逗号分隔的策略标志表, 以控制一系列审计行为。 默认的 cnt 标志表示系统应在审计失败时继续运行 (强烈建议使用这个标志)。 另一个常用的标志是 argv, 它表示在审计命令执行操作时, 同时审计传给 &man.execve.2; 系统调用的命令行参数。 选项指明了审计日志在自动停止记录和翻转之前允许的最大尺寸。 默认值 0 表示禁用自动日志翻转。 如果配置的值不是零, 但小于最小值 512k, 则这个配置会被忽略, 并在日志中记录这一消息。 <filename>audit_user</filename> 文件 audit_user 文件允许管理员为特定用户指定进一步的审计需求。 每一行使用两个字段来配置用户的审计: 第一个是 alwaysaudit 字段, 它指明了一组对该用户总会进行审计的事件; 而第二个则是 neveraudit 字段, 它指明了一系列对该用户不审计的事件。 在下述 audit_user 示例文件中, 审计了 root 用户的 登录/注销 事件, 以及成功的命令执行事件, 此外, 还审计了 www 用户的文件创建和成功的命令执行事件。 如果与前面的示范 audit_control 文件配合使用, 则 rootlo 项就是多余的, 而对 www 用户而言, 其登录/注销事件也会被审计: root:lo,+ex:no www:fc,+ex:no 管理审计子系统 查看审计日志 审计记帐是以 BSM 二进制格式保存的, 因此必须使用工具来对其进行修改, 或将其转换为文本。 &man.praudit.1; 命令能够将记帐文件转换为简单的文本格式; 而 &man.auditreduce.1 命令则可以为分析、 存档或打印目的来浓缩审计日志文件。 auditreduce 支持一系列筛选参数, 包括事件类型、 事件类、 用户、 事件的日期和时间, 以及文件路径或操作对象。 例如, praudit 工具会将指定的审计记帐转存为简单文本格式的审计日志: &prompt.root; praudit /var/audit/AUDITFILE 此处 AUDITFILE 是要转存的审计日志文件。 审计记帐中包括一系列审计记录, 这些记录由一系列短语 (token) 组成, 而 praudit 能把它们顺序显示为一行。 每个短语都属于某个特定的类型, 例如 header 表示审计记录头, 而 path 则表示在一次名字查找中的文件路径。 下面是一个 execve 事件的例子: header,133,10,execve(2),0,Mon Sep 25 15:58:03 2006, + 384 msec exec arg,finger,doug path,/usr/bin/finger attribute,555,root,wheel,90,24918,104944 subject,robert,root,wheel,root,wheel,38439,38032,42086,128.232.9.100 return,success,0 trailer,133 这个审计记录表示一次成功的 execve 调用, 执行了 finger doug。 在参数短语中是由 shell 提交给内核的命令行。 path 短语包含了由内核查找得到的可执行文件路径。 attribute 短语中包含了对可执行文件的描述, 特别地, 它包括了文件的权限模式, 用以确定应用程序是否是 setuid 的。 subject(主体) 短语描述了主体进程, 并顺序记录了审计用户 ID、 生效用户 ID 和组 ID、 实际用户 ID 和组 ID、 进程 ID、 会话 ID、 端口 ID, 以及登录地址。 注意审计用户 ID 和实际用户 ID 是不同的: 用户 robert 在执行这个命令之前已经切换为 root 帐户, 但它会以最初进行身份验证的用户身份进行审计。 最后, return 短语表示执行成功, 而 trailer 表示终结这一记录。 在 &os; 6.3 以及以后的版本中, praudit 可以选择使用 参数来支持 XML 格式的输出。 浓缩审计记帐 由于审计日志可能会很大, 管理员可能会希望选择记录的一个子集来使用, 例如与特定用户相关的记录: &prompt.root; auditreduce -u trhodes /var/audit/AUDITFILE | praudit 这将选择保存在 AUDITFILE 中的所有由 trhodes 产生的审计日志。 委派审计复审权限 audit 组中的用户, 拥有读取 /var/audit 下的审计记帐的权限; 默认情况下, 这个组是空的, 因此只有 root 用户可以读取审计记帐。 如果希望给某个用户指定审计复审权, 则可以将其加入 audit。 由于查看审计日志的内容可以提供关于用户和进程行为的大量深度信息, 在您委派这些权力时, 请务必谨慎行事。 通过审计管道来实时监控 审计管道是位于设备文件系统中的自动复制 (cloning) 的虚拟设备, 用于让应用程序控制正在运行的审计记录流, 这主要是为了满足入侵检测和系统监控软件作者的需要。 不过, 对管理员而言, 审计管道设备也提供了一种无需冒审计记帐文件属主出现问题的麻烦, 或由于日志翻转而打断事件流的麻烦, 而实现实时监控的方便途径。 要跟踪实时事件流, 使用下面的命令行: &prompt.root; praudit /dev/auditpipe 默认情况下, 审计管道设备节点只有 root 用户才能访问。 如果希望 audit 组的成员能够访问它, 应在 devfs.rules 中加入下述 devfs 规则: add path 'auditpipe*' mode 0440 group audit 请参见 &man.devfs.rules.5; 以了解关于配置 devfs 文件系统的进一步信息。 很容易配置出审计事件反馈循环, 也就是查看事件的操作本身会产生更多的事件。 例如, 如果所有的网络 I/O 均被审计, 又在 SSH 会话中执行 &man.praudit.1;, 就会以很高的速率产生持续的审计事件流, 因为每显示一个事件都会产生新的事件。 建议您在需要在审计管道设备上执行 praudit 时, 选择一个没有进行细粒度 I/O 审计的会话来运行。 审计记帐文件的轮转 审计计账只由内核写入, 且只能由 auditd 管理。 管理员不应尝试使用 &man.newsyslog.conf.5; 或其它工具来完成审计日志的轮转工作。 您可以使用 audit 管理工具来关闭审计、 重新配置审计系统, 并完成日志轮转。 下面的命令将让审计服务创建新的审计日志, 并发信号给内核要求其使用新的日志。 旧日志将终止并被改名, 此时, 管理员就可以操作它了。 &prompt.root; audit -n 如果 auditd 服务程序没有在运行, 则这个命令将失败并给出错误提示。 /etc/crontab 加入如下设置, 将使 &man.cron.8; 每十二小时将日志轮转一次。 0 */12 * * * root /usr/sbin/audit -n 这些修改会在您保存 /etc/crontab 后生效。 对于审计记帐文件基于尺寸的自动翻转, 可以通过 &man.audit.control.5; 中的 选项来配置, 这个选项在这一章的配置文件一节中已经介绍过。 压缩审计记帐 由于审计记帐文件会变得很大, 通常会希望在审计服务关闭它时, 对其进行压缩或归档。 audit_warn 脚本可以用来在一系列与审计有关的事件发生时, 执行一些用户定义的操作, 这也包括在审计记帐翻转时进行清理操作。 举例而言, 可以在 audit_warn 脚本中加入下列内容来在审计记帐关闭时压缩它: # # Compress audit trail files on close. # if [ "$1" = closefile ]; then gzip -9 $2 fi 其它存档操作也包括将审计记帐复制到一个中央的服务器, 删除旧的记帐文件, 或浓缩审计记帐并删除不需要的记录等。 这个脚本会在审计记帐文件正常关闭时执行一次, 因此在非正常关闭系统时, 就不会执行它了。 diff --git a/zh_CN.GB2312/books/handbook/disks/chapter.sgml b/zh_CN.GB2312/books/handbook/disks/chapter.sgml index c3d61266b5..17cea85648 100644 --- a/zh_CN.GB2312/books/handbook/disks/chapter.sgml +++ b/zh_CN.GB2312/books/handbook/disks/chapter.sgml @@ -1,3665 +1,3669 @@ 存储 概述 这章介绍了 FreeBSD 中磁盘的使用方法。包括内存盘, 网络附属磁盘和标准的 SCSI/IDE 存储设备,以及使用 USB 的设备。 读完这章,您将了解到: FreeBSD 中用来描述硬盘上数据组织的术语 (partitions and slices)。 如何在您的系统上增加硬盘。 如何配置 &os; 来使用 USB 存储设备。 如何设置虚拟文件系统,例如内存磁盘。 如何使用配额来限制磁盘空间的使用。 如何增加磁盘安全来预防功击。 如何刻录 CD 和 DVD 。 用于备份的多种存储媒介。 如何在 FreeBSD 上使用备份程序。 如何备份到软磁盘。 文件系统快照是什么, 以及如何有效地使用它们。 在读这章之前,您应该: 知道怎样去配置和安装新的 FreeBSD 内核 (). 设备命名 下面是在 FreeBSD 上被支持的物理存储设备和它们被分配的设备名。 物理磁盘命名规则 驱动器类型 驱动设备命名 IDE 硬盘驱动器 ad IDE CDROM 驱动器 acd SCSI 硬盘以及 USB 大容量存储设备 da SCSI CDROM 驱动器 cd 各类非标准 CDROM 驱动器 用于 Mitsumi CD-ROM 的 mcd 以及用于 Sony CD-ROM 驱动器的 scd Floppy drives fd SCSI tape drives sa IDE tape drives ast Flash drives fla for &diskonchip; Flash device RAID drives aacd for &adaptec; AdvancedRAID, mlxd and mlyd for &mylex;, amrd for AMI &megaraid;, idad for Compaq Smart RAID, twed for &tm.3ware; RAID.
David O'Brien Originally contributed by 添加磁盘 磁盘 添加 假设我们要给一台只有一个磁盘的机器增加一个新的 SCSI 磁盘。首先 需要关掉计算机,然后按操作规程来安装驱动器,控制器和驱动程序。由于 各厂家生产的产品各不相同,具体的安装细节不在此文档介绍之内。 root 用户登录。安装完驱动后,检查一下 /var/run/dmesg.boot 有没有找到新的磁盘。在我们 的例子中新增加的磁盘就是 da1,我们从 /1 挂上它。 (如果您正添加 IDE 驱动器, 则设备名应该是 ad1)。 partitions slices fdisk 因为 FreeBSD 运行在 IBM-PC 兼容机上,它必须遵循 PC BIOS 分区规范。 这与传统的 BSD 分区是不同的。一个 PC 的磁盘最高只能有四个 BIOS 主分区。如果磁盘只安装 FreeBSD 您可以使用 dedicated 模式。另外, FreeBSD 必须安装在 PC BIOS 支持的分区内。FreeBSD 把分区叫作 slices 这可能会把人搞糊涂。您也可以在只安装 FreeBSD 的磁盘上使用 slices,也可以在安装有其它操作系统的磁盘上使用 slices。这不会影响其它操作系统的 fdisk 分区工具。 在 slice 方式表示下,驱动器被添加到 /dev/da1s1e。 可以读作:SCSI 磁盘,编号为 1 (第二个SCSI 磁盘), slice 1 (PC BIOS 分区 1), 的 BSD 分区 e 。在有些例子中,也可以简化为 /dev/da1e 由于 &man.bsdlabel.8; 使用 32-位 的整数来表示扇区号, 因此在多数情况下它的表现力限于每个磁盘 2^32-1 个扇区或 2TB。 &man.fdisk.8; 格式允许的起始扇区号不能高于 2^32-1 而分区长度也不能大于 2^32-1, 通常情况下这限制了分区大小最大为 2TB 而磁盘大小则是 4TB。 &man.sunlabel.8; 格式的限制是每个分区 2^32-1 个扇区, 但允许 8 个分区因此最大支持 16TB 的磁盘。 要使用更大的分区, 则应使用 &man.gpt.8;。 使用 &man.sysinstall.8; sysinstall adding disks su 使用 <application>Sysinstall</application> 您可以使用 sysinstall 命令的菜单来分区和标记一个新的磁盘。 这一操作需要有 root 权限, 您可以直接使用 root 账户登录或者使用 su 命令来切换到 root 用户。运行 sysinstall ,然后选择 Configure 菜单。在 FreeBSD Configuration Menu 下,上下滚动, 选择 Fdisk 条目。 <application>fdisk</application> 分区编辑器 进入 fdisk 分区编辑器后,选择 A ,FreeBSD 将使用全部的磁盘。当被告知 remain cooperative with any future possible operating systems时,回答 YES。使用 W 保存刚才的修改。现在使用 q 退出 FDISK 编辑器。下面会看到有关 主引导区 的信息。 现在您已经在运行的系统上添加了一个磁盘, 因此应该选择 None Disk Label 编辑器 BSD partitions 接下来,您应该退出 sysinstall 并且再次启动它,并按照上面的步骤直接进入 Label 选项。进入 磁盘标签编辑器。 这就是您要创建的 BSD 分区。一个磁盘最多可以有 8 个分区,标记为 a-h。有几个分区标签有特殊的用途。 a 分区被用来作为根分区(/)。 系统磁盘(例如:从那儿启动的分区)必须有一个 a 分区。b 分区被用作交换分区,可以用很多磁盘用作交 换分区。 c 分区代表整个硬盘,或在 FreeBSD slice 模式下代表整个 slice。其它分区作为一般分区来使用。 sysinstall 的标签编辑器用 e 表示非 root 和非 swap 分区。在标签编辑器中,可以使用键入C 创建一个文件系统。当提示这是否是一个 FS(文件系统)或 swap 时,选择 FS,然后给出一个加载点(如: /mnt)。 当在 post-install 模式时添加一个磁盘, sysinstall 不会在 /etc/fstab 中创建记录,所以是否指定加载点并不重要。 现在已经准备把新标签写到磁盘上,然后创建一个文件系统,可以按下 W。出现任何错误都会不能创建新的分区。可以退出标签编辑 器然后重新执行 sysinstall 完成 下面一步就是编辑 /etc/fstab,为您的磁盘添加一个新 记录。 使用命令行工具 使用 Slices 这步安装将允许磁盘与可能安装在您计算机上的其它操作系统一起 正确工作,而不会搞乱其它操作系统的分区。推荐使用这种方法来安装 新磁盘,除非您有更好的理由再使用 dedicated 模式! &prompt.root; dd if=/dev/zero of=/dev/da1 bs=1k count=1 &prompt.root; fdisk -BI da1 #初始化新磁盘 &prompt.root; bsdlabel -B -w da1s1 auto #加上标签 &prompt.root; bsdlabel -e da1s1 # 现在编辑您刚才创建的磁盘分区 &prompt.root; mkdir -p /1 &prompt.root; newfs /dev/da1s1e # 为您创建的每个分区重复这个操作 &prompt.root; mount /dev/da1s1e /1 # 挂上分区 &prompt.root; vi /etc/fstab # 完成之后,添加合适的记录到您的 /etc/fstab文件。 如果有一个 IDE 磁盘,记得要用 ad 替换前面的 da 专用模式 OS/2 如果您并没有安装其它的操作系统,可以使用 dedicated 模式。记住这种模式可能会弄乱 Microsoft 的操作系统,但不会对它进行破坏。 它不识别找到的 IBM &os2 的 appropriate 分区。 &prompt.root; dd if=/dev/zero of=/dev/da1 bs=1k count=1 &prompt.root; bsdlabel -Bw da1 auto &prompt.root; bsdlabel -e da1 # 创建 `e' 分区 &prompt.root; newfs -d0 /dev/da1e &prompt.root; mkdir -p /1 &prompt.root; vi /etc/fstab # 为 /dev/da1e添加一个记录 &prompt.root; mount /1 另一种方法: &prompt.root; dd if=/dev/zero of=/dev/da1 count=2 &prompt.root; bsdlabel /dev/da1 | bsdlabel -BR da1 /dev/stdin &prompt.root; newfs /dev/da1e &prompt.root; mkdir -p /1 &prompt.root; vi /etc/fstab # 为 /dev/da1e添加一个记录 &prompt.root; mount /1 RAID 软件 RAID Christopher Shumway Original work by Jim Brown Revised by RAIDsoftware RAIDCCD 连接磁盘驱动器配置 (CCD) 选择一个大容量存储比较好的解决方案,最重要的因素是产品的速度、 性能和成本。 通常这三者不可能都满足;要获得比较快和可靠的大容量存储设备, 就比较昂贵。但如果将成本降下来,那它的速度或可靠性就会打折扣。 在设计下面描述的系统时, 价格被选为最重要的因素, 接下来是速度和性能。 这个系统的数据传输速度基本上受限于网络。 性能也非常重要, CCD 驱动器上的所有数据都被备份到了 CD-R 盘, 可以很容易地对数据进行恢复。 在选择一个大容量的存储解决方案时,第一步是要设计您自己的需求。 如果您的需求更偏重于速度和性能,那么您的解决方案将就不同于上面的设计。 安装硬件 除了 IDE 系统磁盘外,还有三个 Western Digital 30GB、5400 RPM 的 IDE 磁盘构成了大约 90G 的连接磁盘驱动存储空间。 理想情况是每个 IDE 硬盘都独占 IDE 控制器和数据线, 但为了尽可能降低成本, 通常并不会安装更多的控制器, 而是通过配置跳线,使每个 IDE 控制器都管理一个主盘和一个从盘。 重启动后,系统 BIOS 被配置成自动检测硬盘。FreeBSD 检测到它们: ad0: 19574MB <WDC WD205BA> [39770/16/63] at ata0-master UDMA33 ad1: 29333MB <WDC WD307AA> [59598/16/63] at ata0-slave UDMA33 ad2: 29333MB <WDC WD307AA> [59598/16/63] at ata1-master UDMA33 ad3: 29333MB <WDC WD307AA> [59598/16/63] at ata1-slave UDMA33 如果 FreeBSD 没有检测到它们,请确定它们的跳线是否设置 正确。大多数 IDE 磁盘有一个 Cable Select 跳线。这个 不是 设置 master/slave 硬盘的跳线。查阅文档 信息来确定正确的跳线设置。 接下来考虑的是,如何创建文件系统。应该好好研究一下 &man.vinum.8; ()和 &man.ccd.4; 两种方式,在这里我们选择 &man.ccd.4; 安装 CCD &man.ccd.4; 允许用户将几个相同的的磁盘通过一个逻辑文件系统 连接起来。要使用 &man.ccd.4;,您需要在内核中配置 &man.ccd.4; 支持选项。把这行加入到内核配置文件中,然后重建内核: device ccd 对 &man.ccd.4; 的支持也可以内核模块的形式载入。 要安装 &man.ccd.4;, 首先需要使用 &man.bsdlabel.8; 来编辑硬盘: bsdlabel -w ad1 auto bsdlabel -w ad2 auto bsdlabel -w ad3 auto 此处将整个硬盘创建为 ad1c, ad2cad3c 下一步是改变 disklable 的类型。也可以使用 &man.bsdlabel.8; 来编辑: bsdlabel -e ad1 bsdlabel -e ad2 bsdlabel -e ad3 这儿在每个已经设置了 EDITOR 环境变量的磁盘上打开了 disklable,在我我例子中使用的是 &man.vi.1;。 可以看到: 8 partitions: # size offset fstype [fsize bsize bps/cpg] c: 60074784 0 unused 0 0 0 # (Cyl. 0 - 59597) 添加一个新的 e 分区给 &man.ccd.4; 用。这可以是 c 分区的一个副本, 但 必须4.2BSD。做完之后,您会看到一面这些: 8 partitions: # size offset fstype [fsize bsize bps/cpg] c: 60074784 0 unused 0 0 0 # (Cyl. 0 - 59597) e: 60074784 0 4.2BSD 0 0 0 # (Cyl. 0 - 59597) 建立文件系统 现在已给每个磁盘都加上了标签,下面需要建立 &man.ccd.4;。要这样做, 需要使用 &man.ccdconfig.8; 工具,同时要提供类似下面的选项: ccdconfig ccd0 32 0 /dev/ad1e /dev/ad2e /dev/ad3e 每个选项的意义和用法如下所示: 配置设备的第一个参数,在这是 /dev/ccd0c/dev/ 部分是任选项。 下一个参数是文件系统的插入页(interleave)。插入页定义了一个 磁盘块中一个分段或条带(stripe)的大小,通常是 512 个字节。所以一个为 32 的插入页将是 16,384 字节。 插入页为 &man.ccdconfig.8; 附带了标记。如果您要启用驱动器镜像, 需要在这儿指定它。在这个配置中没有做 &man.ccd.4; 的镜像,所以把它 设为 0 (zero)。 &man.ccdconfig.8; 的最后配置是设备的排列问题。使用完整的设备 路径名。 运行 &man.ccdconfig.8; 后 &man.ccd.4; 就配置好了。现在要创建文件 系统了,参考 &man.newfs.8; 选项,执行下同的命令: newfs /dev/ccd0c 自动创建 最后,要挂上 &man.ccd.4; ,需要先配置它。把当前的配置文件写入 /etc/ccd.conf 中,使用下面的命令: ccdconfig -g > /etc/ccd.conf 当重新启动系统时,如果 /etc/ccd.conf 存在, 脚本 /etc/rc 就运行 ccdconfig -C。 这样就能自动配置 &man.ccd.4; 以到它能被挂上。 如果启动进入了单用户模式,在 &man.mount.8; 上 &man.ccd.4; 之前,需要执行下面的命令来配置队列: ccdconfig -C 要自动挂接 &man.ccd.4;,需要为 &man.ccd.4; 在 /etc/fstab 中配置一个记录,以便在启动时它能被挂上。 如下所示: /dev/ccd0c /media ufs rw 2 2 Vinum 卷管理 RAIDsoftware RAID Vinum Vinum 卷管理是一个实现虚拟磁盘的块驱动设备工具。它使磁盘从 块设备的接口和数据映射中独立出来。与传统的存储设备相比,增加了 灵活性、性能和可靠性。 &man.vinum.8; 实现了 RAID-0、RAID-1 和 RAID-5 三种模式,它们既可以独立使用,也可组合使用。 参考 得到更多 &man.vinum.8; 的信息。 硬件 RAID RAID hardware FreeBSD 支持很多硬件 RAID 控制器。 这些硬件不需要 FreeBSD 指定软件来管理 RAID 系统。 使用 BIOS 支持的硬件,一般情况下这些硬件可以自行操作。 下面是一个简明的描述设置一个 Promise IDE RAID 控制器。 当硬件设备装好且系统重启后,屏幕上显示一个询问信息。接着进入硬件设置屏幕。在这里, 您可以把所有的磁盘联合在一起使用。这样 FreeBSD 将磁盘看作一个驱动器。其它 级别的 RAID 也可以相应的进行设置。 重建 ATA RAID1 阵列 FreeBSD 允许您热插拔阵列中损坏的磁盘。 在您重新启动系统之前请注意这一点。 您可能会在 /var/log/messages 或者在 &man.dmesg.8; 的输出中看到类似下面这些的内容: ad6 on monster1 suffered a hard error. ad6: READ command timeout tag=0 serv=0 - resetting ad6: trying fallback to PIO mode ata3: resetting devices .. done ad6: hard error reading fsbn 1116119 of 0-7 (ad6 bn 1116119; cn 1107 tn 4 sn 11)\\ status=59 error=40 ar0: WARNING - mirror lost 使用 &man.atacontrol.8;,查看更多的信息: &prompt.root; atacontrol list ATA channel 0: Master: no device present Slave: acd0 <HL-DT-ST CD-ROM GCR-8520B/1.00> ATA/ATAPI rev 0 ATA channel 1: Master: no device present Slave: no device present ATA channel 2: Master: ad4 <MAXTOR 6L080J4/A93.0500> ATA/ATAPI rev 5 Slave: no device present ATA channel 3: Master: ad6 <MAXTOR 6L080J4/A93.0500> ATA/ATAPI rev 5 Slave: no device present &prompt.root; atacontrol status ar0 ar0: ATA RAID1 subdisks: ad4 ad6 status: DEGRADED 首先您应将包含故障盘的 ata 通道卸下, 以便安全地将其拆除: &prompt.root; atacontrol detach ata3 换上磁盘 重新挂接 ata 通道: &prompt.root; atacontrol attach ata3 Master: ad6 <MAXTOR 6L080J4/A93.0500> ATA/ATAPI rev 5 Slave: no device present 将新盘作为热备盘加入阵列: &prompt.root; atacontrol addspare ar0 ad6 重建阵列: &prompt.root; atacontrol rebuild ar0 可以通过下面的命令来查看进度: &prompt.root; dmesg | tail -10 [output removed] ad6: removed from configuration ad6: deleted from ar0 disk1 ad6: inserted into ar0 disk1 as spare &prompt.root; atacontrol status ar0 ar0: ATA RAID1 subdisks: ad4 ad6 status: REBUILDING 0% completed 等待操作完成。 Marc Fonvieille Contributed by USB 存储设备 USB disks 到目前为止,有许多外部外部存储解决方案, 例如:通用串行总线 (USB):硬盘、USB thumbdrives、CD-R burners 等等。 &os; 为这些设备提供了支持。 配置 USB 大容量存储设备驱动,在 &man.umass.4;, 中提供了对 USB 存储设备的支持。如果您使用 GENERIC 内核,您不必要改变配置文件里的任何内容。 如果您使用了定制的内核,就要确定下面的行出现在您的内核配置文件里: device scbus device da device pass device uhci device ohci device usb device umass &man.umass.4; 驱动程序使用 SCSI 子系统来访问 USB 存储设备, 您的 USB 设备将被系统看成为一个 SCSI 设备。依靠您主板上的 USB 芯片, 您只须选择 device uhcidevice ohci 二者之一即可, 但是两者都加入内核配置文件当中也没有坏外。 不要忘了如果您加入了上面的几行要重新编译和安装内核。 如果您的 USB 设备是一个 CD-R 或 DVD 刻录机, SCSI CD-ROM 驱动程序, &man.cd.4;, 就必须加入内核中通过下面这行: device cd 由于刻录机被视为 SCSI 设备, 因此, 不应该在内核配置文件中使用 &man.atapicam.4; 驱动程序。 在 &os; 中已经提供了对 USB 2.0 控制器的内建支持; 然而, 您必须在编译内核时在配置中加入: device ehci 注意, 如果需要 USB 1.X 的支持, 您仍需要使用 &man.uhci.4; 和 &man.ohci.4; 驱动程序。 测试配置 配置好后准备进行测试:插入您的 USB 设备, 在系统信息中 (&man.dmesg.8;), 应该会出现像下面的设备: umass0: USB Solid state disk, rev 1.10/1.00, addr 2 GEOM: create disk da0 dp=0xc2d74850 da0 at umass-sim0 bus 0 target 0 lun 0 da0: <Generic Traveling Disk 1.11> Removable Direct Access SCSI-2 device da0: 1.000MB/s transfers da0: 126MB (258048 512 byte sectors: 64H 32S/T 126C) 当然啦,商标,设备标识 (da0) 和其它的细节信息会根据您的配置不同 而有所不同。 因为 USB 设备被看作 SCSI 设备中的一个, camcontrol 命令也能够用来列出 USB 存储设备和系统的关联: &prompt.root; camcontrol devlist <Generic Traveling Disk 1.11> at scbus0 target 0 lun 0 (da0,pass0) 如果设备上已经包含了文件系统, 现在应该就可以挂接它了。 如果需要, 请参阅 来了解如何在 USB驱动器上格式化和创建分区。 如果希望设备能够被普通用户挂接, 还需要做一些其它操作。 首先, 在 USB 存储设备连接到计算机上时, 系统自动生成的设备文件, 必须是该用户能够读写的。 一种做法是让所有属于 operator 组的用户都可以访问该设备。 要完成这项工作, 首先需要用 &man.pw.8; 来给用户指定组。 其次, 在生成设备文件时, operator 组应能读写它们。 这可以通过在 /etc/devfs.rules 中增加一些相应的设置来实现: [localrules=1] add path 'da*' mode 0660 group operator 如果系统中已经有其它 SCSI 磁盘, 则上述操作必须做一些变化。 例如, 如果系统中已经存在了设备名为 da0da2 的磁盘, 则第二行应改为: add path 'da[3-9]*' mode 0660 group operator 这会将系统中已经存在的磁盘, 排除在属于 operator 组的设备之外。 另外, 您还需要在 /etc/rc.conf 文件中, 启用 &man.devfs.rules.5; 规则集: devfs_system_ruleset="localrules" 接下来, 需要配置内核, 令普通用户能够挂接文件系统。 最简单的方法是将下面的配置加入到 /etc/sysctl.conf vfs.usermount=1 注意, 这个设置只有在下次重启系统时才会生效。 另外, 您也可以使用 &man.sysctl.8; 来设置这个变量。 最后一步是创建将要挂接文件系统的目录。 这个目录必须是属于将要挂接文件系统的用户的。 以 root 身份为用户建立属于该用户的 /mnt/$USER (此处 $USER 应替换成用户的登录名): &prompt.root; mkdir /mnt/$USER &prompt.root; chown $USER:$USER /mnt/$USER 假设已经插入了一个 USB 读卡设备, 并且系统将其识别为 /dev/da0s1, 由于这些设备通常是 FAT 文件系统, 用户可以这样挂接它们: &prompt.user; mount -t msdosfs -m 644 -M 755 /dev/da0s1 /mnt/$USER 如果拔出设备 (必须首先将其对应的磁盘卷卸下), 则您会在系统消息缓冲区中看到类似下面的信息: umass0: at uhub0 port 1 (addr 2) disconnected (da0:umass-sim0:0:0:0): lost device (da0:umass-sim0:0:0:0): removing device entry GEOM: destroy disk da0 dp=0xc2d74850 umass0: detached 深入阅读 除了 Adding Disks 和 Mounting and Unmounting File Systems 章之外,阅读 &man.umass.4;, &man.camcontrol.8;, 和 &man.usbdevs.8; 也是很有益的。 Mike Meyer Contributed by 创建和使用光学介质(CD) CDROMs creating 介绍 CD 与普通的磁盘相比有很多不同的特性。最初它们是不能被用户写入的。 由于没有磁头和磁道移动时的延迟,所以它们可以连续的进行读取。 方便的在两个系统之间进行数据的传输,比起相同大小的存储介质来说。 CD 有磁道,这关系到数据读取时的连续性而不是物理磁盘的性能。 要在 FreeBSD 中制作一个 CD,您要准备好要写到 CD 上的数据文件, 然后根据每个 tracks 写入到 CD。 ISO 9660 文件系统 ISO 9660 ISO 9660 文件系统被设计用来处理这些差异。 但令人遗憾的是, 它也有一些其他文件系统所没有的限制, 不过幸运的是, 它提供了一项扩展机制, 使得正确写入的 CD 能够超越这些限制, 而又能在不支持这些扩展的系统上正常使用。 sysutils/cdrtools sysutils/ port 包括了 &man.mkisofs.8;, 这是一个可以用来生成包含 ISO 9660 文件系统的数据文件的程序。 他也提供了对于一些扩展的支持选项,下面将详细介绍。 CD burner (刻录机) ATAPI 使用哪个工具来刻录 CD 取决于您的 CD 刻录机是 ATAPI 的, 还是其他类型的。 对于 ATAPI CD 刻录机, 可以使用基本系统附带的 burncd 程序。 SCSI 和 USB CD 刻录机, 则需要配合 cdrecord 程序使用, 它可以通过 sysutils/cdrtools port 安装。 除此之外, 在 ATAPI 接口的刻录机上, 也可以配合 ATAPI/CAM 模块 来使用 cdrecord 以及其它为 SCSI 刻录机撰写的工具。 如果您想使用带图形界面的 CD 刻录软件, 可以考虑一下 X-CD-RoastK3b。 这些工具可以通过使用预编译安装包, 或通过 sysutils/xcdroastsysutils/k3b ports 来安装。 X-CD-RoastK3b 需要 ATAPI/CAM 模块 配合 ATAPI 硬件。 mkisofs &man.mkisofs.8; 程序作为 sysutils/cdrtools port 的一部分, 将生成 ISO 9660 文件系统,其中包含 &unix; 命名空间中的文件名。 最简单的用法是: &prompt.root; mkisofs -o imagefile.iso /path/to/tree 文件系统 ISO 9660 这个命令将创建一个包含 ISO9660 文件系统的 imagefile.iso 文件,它是目录树 /path/to/tree 的一个副本。 在处理过程中, 它将文件名称映射为标准的 ISO9660 文件系统的文件名,将排除那些不典型的 ISO 文件系统的文件。 文件系统 HFS 文件系统 Joliet 有很多选项能够用来克服那些限制。特别的, 选项能够启用 Rock Ridge 扩展一般的 &unix; 系统, 选项能启用用于 Microsoft 系统的 Joliet 扩展, 选项能用来创建用于 &macos; 系统的 HFS 文件系统。 对于那些即将要在 FreeBSD 系统中使用 CD 的人来说, 选项能用来消除所有文件名的限制。当使用 选项时,它会产生一个 文件系统映像,它与您从那儿启动 FreeBSD 树是一样的,虽然它在许多方面也违反了 ISO 9660 的标准。 CDROMs 创建启动光盘 最后一个常用的选项是 。 它用来指定启动映像的位置, 用以生成 El Torito 启动 CD。 这个选项使用一个参数, 用以指定将写入 CD 的目录的根。 默认情况下, &man.mkisofs.8; 会以常说的 软盘模拟 方式来创建 ISO, 因此它希望引导映像文件的尺寸恰好是 1200, 1440 或 2880 KB。 某些引导加载器, 例如 FreeBSD 发行版磁盘, 并不使用模拟模式; 这种情况下, 需要使用 选项。 因此, 如果 /tmp/myboot 是一个包含了启动映像文件 /tmp/myboot/boot/cdboot 的可引导的 FreeBSD 系统, 您就可以使用下面的命令生成 ISO 9660 文件系统映像 /tmp/bootable.iso &prompt.root; mkisofs -R -no-emul-boot -b boot/cdboot -o /tmp/bootable.iso /tmp/myboot 完成这些工作之后, 如果您的内核中配置了 md, 就可以用下列命令来挂接文件系统了: &prompt.root; mdconfig -a -t vnode -f /tmp/bootable.iso -u 0 &prompt.root; mount -t cd9660 /dev/md0 /mnt 可以发现 /mnt/tmp/myboot 是一样的。 还可以使用 &man.mkisofs.8; 的其它选项来调整它的行为。特别是修改 ISO 9660 的划分格式,创建 Joliet 和 HFS 格式的磁盘。查看 &man.mkisofs.8; 联机手册得到更多的帮助。 burncd CDROMs burning 如果用的是 ATAPI 的 CD 刻录机,可以使用 burncd  命令来刻录您的 CD ISO 映像文件。 burncd 命令是基本  系统的一部分,中以使用 /usr/sbin/burncd 来安装。  用法如下: &prompt.root; burncd -f cddevice data imagefile.iso fixate cddevice 上刻录一份 imagefile.iso 的副本。 默认的设备是 /dev/acd0。 请参考 &man.burncd.8; 以了解设置写入速度的参数,如何在刻录完成之后自动弹出CD,以及刻录音频数据。 cdrecord 如果没有一个 ATAPI CD 刻录机,必须使用 cdrecord 来刻录您的 CD 。 cdrecord 不是基本系统的一部分;必须 从 sysutils/cdrtools 或适当的 package 安装它。基本系统的变化可能会引起这个程序的错误。可能是由 coaster 引起的。当升级系统时,同时需要升级 port, 或者如果您 使用 -STABLE, 那么在升级到新版本时也要升级 port。 cdrecord 有许多选项,基本用法与 burncd 相似。刻录一个 ISO 9660 映像文件只需这样做: &prompt.root; cdrecord dev=device imagefile.iso 使用 cdrecord 的比较巧妙的方法是找到使用的 。要找到正确的设置,可以使用 cdrecord 标记,这会产生这样的结果: CDROMs burning &prompt.root; cdrecord -scanbus Cdrecord-Clone 2.01 (i386-unknown-freebsd7.0) Copyright (C) 1995-2004 Jörg Schilling Using libscg version 'schily-0.1' scsibus0: 0,0,0 0) 'SEAGATE ' 'ST39236LW ' '0004' Disk 0,1,0 1) 'SEAGATE ' 'ST39173W ' '5958' Disk 0,2,0 2) * 0,3,0 3) 'iomega ' 'jaz 1GB ' 'J.86' Removable Disk 0,4,0 4) 'NEC ' 'CD-ROM DRIVE:466' '1.26' Removable CD-ROM 0,5,0 5) * 0,6,0 6) * 0,7,0 7) * scsibus1: 1,0,0 100) * 1,1,0 101) * 1,2,0 102) * 1,3,0 103) * 1,4,0 104) * 1,5,0 105) 'YAMAHA ' 'CRW4260 ' '1.0q' Removable CD-ROM 1,6,0 106) 'ARTEC ' 'AM12S ' '1.06' Scanner 1,7,0 107) * 这个列表列出了设备的的适当的 值。找到您的 CD burner ,使用三个用逗号分隔的数值来表示 .在 这个例子中,CRW 是 ,所以正确的输入应是 dev=1,5,0 。有一个很容易的方法可以指定这个值;看看 &man.cdrecord.1; 的介绍了解有关音轨,控制速度和其他的东西。 复制音频 CD 您可以这样复制 CD,把 CD 上面的音频数据解压缩出一系列的文件, 再把这些文件写到一张空白 CD 上。 这个过程对于 ATAPI 和 SCSI 驱动器来说有些微的不同。 SCSI 驱动器 使用 cdda2wav 来解压缩音频。 &prompt.user; cdda2wav -v255 -D2,0 -B -Owav 使用 cdrecord 来写 .wav 文件。 &prompt.user; cdrecord -v dev=2,0 -dao -useinfo *.wav 确保 2,0 被适当地设置了, 具体方法在 中有所描述。 ATAPI 驱动器 ATAPI CD 驱动用 /dev/acddtnn表示每个轨道, 这里 d 是驱动器号, nn 是轨道号,由两位小数位组成,省略前缀零。 所以第一个盘片上的第一个轨道就是 /dev/acd0t01,第二个就是 /dev/acd0t02,第三个就是 /dev/acd0t03,等等。 请务必确认在 /dev 中出现了对应的文件。 如果您发现有某些项目缺失, 则应强制系统重新识别介质: &prompt.root; dd if=/dev/acd0 of=/dev/null count=1 使用 &man.dd.1; 解压缩每个轨道。当解压缩文件的时候您也必须使用 一个特殊的块大小。 &prompt.root; dd if=/dev/acd0t01 of=track1.cdr bs=2352 &prompt.root; dd if=/dev/acd0t02 of=track2.cdr bs=2352 ... 使用 burncd 把解压缩的文件刻录到光盘上。您必须指定 这些文件是音频文件,这样 burncd 会在刻录完成时 结束光盘。 &prompt.root; burncd -f /dev/acd0 audio track1.cdr track2.cdr ... fixate 复制数据 CD 您可以把数据 CD 复制成一个与之等价的映像文件, 可以使用 &man.mkisofs.8; 创建这种文件, 或使用它来复制任何数据 CD。 这里给出的例子假定您的 CDROM 设备是 acd0, 您应将其替换为您实际使用的 CDROM 设备。 &prompt.root; dd if=/dev/acd0 of=file.iso bs=2048 现在您有一个映像文件了,您可以像上面描述的那样把它刻录成 CD。 使用数据 CD 现在您已经创建了一张标准的数据 CDROM,您或许想要 挂载来读取上面的设备。 默认情况下,&man.mount.8; 假定文件系统是 ufs 类型的。如果您尝试下面的命令: &prompt.root; mount /dev/cd0 /mnt 您会得到一条 Incorrect super block 的错误信息,没有挂载成功。CDROM 不是 UFS 文件系统,所以试图这样挂载它是 是不行的。您需要告诉 &man.mount.8; 文件系统是 ISO9660 类型的,这样 就可以了。只需要指定 &man.mount.8; 的 选项。例如, 如果您想要挂载 CDROM 设备, /dev/cd0/mnt 目录,您需要执行: &prompt.root; mount -t cd9660 /dev/cd0 /mnt 注意您的设备名 (在这个例子中是 /dev/cd0)可能 有所不同,取决于您的 CDROM 使用的接口。另外, 选项等同于执行 &man.mount.cd9660.8;。上面的例子可以缩短 为: &prompt.root; mount_cd9660 /dev/cd0 /mnt 用这种方法您基本可以使用任何买到的数据 CDROM。 然而某些有 ISO 9660 扩展的光盘可能会行为古怪。 例如,joliet 光盘用两个字节的 unicode 字符存储所有的文件名。 FreeBSD 内核并不使用 Unicode, 但 &os; CD9660 驱动可以将 Unicode 字符自动转换为内核可以识别的形式。 如果您发现有些非英文字符显示为问号, 就绪要使用 选项来指定字符集了。 欲了解进一步的详情, 请参见联机手册 &man.mount.cd9660.8;。 如果希望通过 选项来进行字符集转换, 则内核会需要加载 cd9660_iconv.ko 模块。 这项工作可以通过在 loader.conf 中加入下列配置: cd9660_iconv_load="YES" 并重新启动计算机来完成, 除此之外, 也可以通过 &man.kldload.8; 来手动加载。 有时候,当您试图挂载 CDROM 的时候,会得到一条 Device not configured 的错误信息。这通常 表明 CDROM 驱动认为托盘里没有光盘, 或者驱动器在总线上不可见。 需要几秒钟时间等待 CDROM 驱动器辨别已经接到反馈的信息, 请耐心等待。 有时候,SCSI CDROM 可能会找不到,因为没有足够的 时间来应答总线的 reset 信号。如果您有一个 SCSI CDROM 请将下面的选项添加到您的内核 配置文件并重建您的内核。 options SCSI_DELAY=15000 这个告诉您的 SCSI 总线启动时暂停 15 秒钟, 给您的 CDROM 驱动器足够的机会来应答 总线 reset 信号。 刻录原始数据 CD 您可以选择把一个文件目录刻录到 CD 上而不用 创建 ISO 9660 文件系统。有些人这么做是为了备份的 目的。这个运行的比刻录一个标准 CD 速度要快得多: &prompt.root; burncd -f /dev/acd1 -s 12 data archive.tar.gz fixate 要重新找回这样刻录到 CD 上的数据, 您必须从原始设备节点读取数据: &prompt.root; tar xzvf /dev/acd1 您不能像挂载一个通常的 CDROM 一样挂载这张光盘。 这样的 CDROM 也不能在除了 FreeBSD 之外的任何操作系统上读出。 如果您想要可以挂载 CD,或者 和另一种操作系统共享数据,您必须像上面描述的那样使用 &man.mkisofs.8;。 Marc Fonvieille Contributed by CD burner ATAPI/CAM driver 使用 ATAPI/CAM 驱动 这个驱动允许 ATAPI 设备(CD-ROM, CD-RW, DVD 驱动器等...)通过 SCSI 子系统访问, 这样允许使用像 sysutils/cdrdao 或者 &man.cdrecord.1; 这样的程序。 要使用这个驱动, 您需要把下面这行添加到 /boot/loader.conf 文件中: atapicam_load="YES" 接下来, 重新启动计算机。 如果您希望将 &man.atapicam.4; 以静态联编的形式加入内核, 则需要在内核配置文件中加入这行: device atapicam 此外还需要在内核配置文件中加入: device ata device scbus device cd device pass 这些应该已经有了。 然后, 重新联编并安装新内核, 并重新启动计算机。 在引导过程中, 您的刻录机将会出现在内核的提示信息中, 就像这样: acd0: CD-RW <MATSHITA CD-RW/DVD-ROM UJDA740> at ata1-master PIO4 cd0 at ata1 bus 0 target 0 lun 0 cd0: <MATSHITA CDRW/DVD UJDA740 1.00> Removable CD-ROM SCSI-0 device cd0: 16.000MB/s transfers cd0: Attempt to query device size failed: NOT READY, Medium not present - tray closed 驱动器现在可以通过 /dev/cd0 设备名访问了,例如要 挂载 CD-ROM 到 /mnt,只需要键入下面的 命令: &prompt.root; mount -t cd9660 /dev/cd0 /mnt 作为 root,您可以运行下面的 命令来得到刻录机的 SCSI 地址: &prompt.root; camcontrol devlist <MATSHITA CDRW/DVD UJDA740 1.00> at scbus1 target 0 lun 0 (pass0,cd0) 这样 1,0,0 就是 SCSI 地址了,可以被 &man.cdrecord.1; 和其他的 SCSI 程序使用。 有关 ATAPI/CAM 和 SCSI 系统的更多信息, 可以参阅 &man.atapicam.4; 和 &man.cam.4; 手册 页。 Marc Fonvieille Contributed by Andy Polyakov With inputs from 创建和使用光学介质(DVD) DVD burning 介绍 和 CD 相比,DVD 是下一代光学存储介质技术。 DVD 可以容纳比任何 CD 更多的数据,已经成为现今视频出版业的标准。 我们称作可记录 DVD 的有五种物理记录格式: DVD-R:这是第一种可用的 DVD 可记录格式。 DVD-R 标准由 DVD Forum 定义。 这种格式是一次可写的。 DVD-RW:这是 DVD-R 标准的可覆写版本。 一张 DVD-RW 可以被覆写大约 1000 次。 DVD-RAM:这也是一种被 DVD Forum 所支持的可覆写格式。 DVD-RAM 可以被看作一种可移动硬盘。 然而,这种介质和大部分 DVD-ROM 驱动器以及 DVD-Video 播放器不兼容; 只有少数 DVD 刻录机支持 DVD-RAM。 请参阅 以了解关于如何使用 DVD-RAM 的进一步详情。 DVD+RW:这是一种由 DVD+RW Alliance 定义的可覆写格式。一张 DVD+RW 可以被覆写大约 1000 次。 DVD+R:这种格式是 DVD+RW 格式的一次可写变种。 一张单层的可记录 DVD 可以存储 4,700,000,000  字节,相当于 4.38 GB 或者说 4485 MB (1 千字节等于 1024 字节)。 必须说明一下物理介质与应用程序的分歧。 例如 DVD-Video 是一种特殊的文件系统, 可以被覆写到任何可记录的 DVD 物理介质上: DVD-R、DVD+R、DVD-RW 等等。在选择介质类型之前, 您一定要确认刻录机和 DVD-Video 播放器 (一种单独的播放器或者计算机上的 DVD-ROM 驱动器) 是和这种介质兼容的。 配置 &man.growisofs.1; 将被用来实施 DVD 刻录。 这个命令是 dvd+rw-tools 工具集 (sysutils/dvd+rw-tools) 的一部分。 dvd+rw-tools 支持所有的 DVD 介质类型。 这些工具将使用 SCSI 子系统来访问设备,因此 ATAPI/CAM 支持 必须加入内核。 如果您的刻录机采用 USB 接口则不需要这么做,请参考 来了解 USB 设备配置的进一步详情。 此外,还需要启用 ATAPI 设备的 DMA 支持。 这一工作可以通过在 /boot/loader.conf 文件中加入下面的行来完成: hw.ata.atapi_dma="1" 试图使用 dvd+rw-tools 之前您应该参考 dvd+rw-tools 硬件兼容性列表 是否有与您的 DVD 刻录机有关的信息。 如果您想要一个图形化的用户界面,您应该看一看 K3b (sysutils/k3b),它提供了 &man.growisofs.1; 的一个友好界面和许多其他刻录工具。 刻录数据 DVD &man.growisofs.1; 命令是 mkisofs 的前端,它会调用 &man.mkisofs.8; 来创建文件系统布局,完成到 DVD 上的刻录。 这意味着您不需要在刻录之前创建数据映像。 要把 /path/to/data 目录的数据刻录到 DVD+R 或者 DVD-R 上面,使用下面的命令: &prompt.root; growisofs -dvd-compat -Z /dev/cd0 -J -R /path/to/data 选项传递给 &man.mkisofs.8; 用于文件系统创建 (这表示创建带有带有 joliet 和 Rock Ridge 扩展的 ISO 9660 文件系统), 参考 &man.mkisofs.8; 联机手册了解更多细节。 选项 用来在任何情况下初始刻录会话: 不管多会话与否。 DVD 设备,/dev/cd0, 必须依照您的配置做出改变。 参数会结束光盘, 光盘成为不可附加的。这会提供更多的和 DVD-ROM 驱动器的介质兼容性。 也可以刻录成一个 pre-mastered 映像, 例如记录一个映像文件 imagefile.iso, 我们可以运行: &prompt.root; growisofs -dvd-compat -Z /dev/cd0=imagefile.iso 刻录的速度可以被检测到并自动进行调整, 根据介质和驱动器的使用情况。如果您想强制改变速度, 可以使用 参数。更多的信息,请看 &man.growisofs.1; 联机手册。 DVD DVD-Video 刻录 DVD-Video DVD-Video 是一种特殊的基于 ISO 9660 和 micro-UDF (M-UDF) 规范的文件系统。 DVD-Video 也呈现了一个特殊的数据格式, 这就是为什么您需要一个特殊的程序像 multimedia/dvdauthor 来制作 DVD 的原因。 如果您已经有了 DVD-Video 文件系统的映像, 就可以以同样的方式制作另一个映像,可以参看前面章节的例子。 如果您想制作 DVD 并想放在特定的目录中,如在目录 /path/to/video 中, 可以使用下面的命令来刻录 DVD-Video: &prompt.root; growisofs -Z /dev/cd0 -dvd-video /path/to/video 选项将传递给 &man.mkisofs.8; 并指示它创建一个 DVD-Video 文件系统布局。 除此之外。 选项也包含了 &man.growisofs.1; 选项。 DVD DVD+RW 使用 DVD+RW 不像 CD-RW, 一个空白的 DVD+RW 在每一次使用前必须先格式化。 &man.growisofs.1; 程序将会适时的自动对其进行适当的处理, 这是 recommended 的方式。您也可以使用 dvd+rw-format 来对 DVD+RW 进行格式化: &prompt.root; dvd+rw-format /dev/cd0 您只需要执行这样的操作一次,牢记只有空白的 DVD+RW 介质才需要格式化。您可以以前面章节同样的方式来刻录 DVD+RW。 如果您想刻录新的数据 (刻录一个新的完整的文件系统 而不仅仅是追加一些数据) 到 DVD+RW,您不必再将其格式化成空白盘, 您只须要直接覆盖掉以前的记录即可。 (执行一个新的初始化对话), 像这样: &prompt.root; growisofs -Z /dev/cd0 -J -R /path/to/newdata DVD+RW 格式化程序为简单的向以前的记录追加数据提供了可能性。 这个操作有一个新的会话和一个已经存在的会话合并而成。 它不需要多个写会话过程, &man.growisofs.1; 将在介质上 增加 ISO 9660 文件系统。 例如,我们想追加一些数据到到我们以前的 DVD+RW 上,我们可以使用下面的命令: &prompt.root; growisofs -M /dev/cd0 -J -R /path/to/nextdata 在以后的写操作时, 应使用与最初的刻录会话时相同的 &man.mkisofs.8; 选项。 如果您想获得与 DVD-ROM 驱动更好的兼容性,可以使用 选项。 在 DVD+RW 这种情况下, 这样做并不妨碍您添加数据。 如果出于某种原因您真的想要空白介质盘, 可以执行下面的命令: &prompt.root; growisofs -Z /dev/cd0=/dev/zero DVD DVD-RW 使用 DVD-RW DVD-RW 接受两种光盘格式:增补顺序写入和受限式覆写。默认的 DVD-RW 盘是顺序写入格式。 空白的 DVD-RW 能够直接进行刻录而不需要格式化操作, 然而非空的顺序写入格式的 DVD-RW 需要格式化才能写入新的初始区段。 要格式化一张 DVD-RW 为顺序写入模式,运行: &prompt.root; dvd+rw-format -blank=full /dev/cd0 一次完全的格式化 () 在 1x 倍速的介质上将会花费大约 1 个小时。快速格式化可以使用 选项来进行,如果 DVD-RW 要以 Disk-At-Once (DAO) 模式刻录的话。要以 DAO 模式刻录 DVD-RW,使用命令: &prompt.root; growisofs -use-the-force-luke=dao -Z /dev/cd0=imagefile.iso 选项不是必需的, 因为 &man.growisofs.1; 试图最低限度的检测 (快速格式化) 介质并进行 DAO 写入。 事实上对于任何 DVD-RW 都应该使用受限式覆写模式, 这种格式比默认的增补顺序写入更加灵活。 在一张顺序 DVD-RW 上写入数据,使用和其他 DVD 格式相同的指令: &prompt.root; growisofs -Z /dev/cd0 -J -R /path/to/data 如果您想在您以前的刻录上附加数据,您必须使用 &man.growisofs.1; 的 选项。然而, 如果您在一张增补顺序写入模式的 DVD-RW 上附加数据, 将会在盘上创建一个新的区段,结果就是一张多区段光盘。 受限式覆写格式的 DVD-RW 在新的初始化区段前不需要格式化, 您只是要用 选项覆写光盘,这和 DVD+RW 的情形是相似的。也可以用和 DVD+RW 同样方式的 选项把现存的 ISO 9660 文件系统写入光盘。 结果会是一张单区段 DVD。 要把 DVD-RW 置于受限式覆写格式, 必须使用下面的命令: &prompt.root; dvd+rw-format /dev/cd0 更改回顺序写入模式使用: &prompt.root; dvd+rw-format -blank=full /dev/cd0 多区段 几乎没有哪个 DVD-ROM 驱动器支持多区段 DVD,它们大多数时候都只读取第一个区段。 顺序写入格式的 DVD+R、DVD-R 和 DVD-RW 可以支持多区段, DVD+RW 和 DVD-RW 受限式覆写格式不存在多区段的概念。 在 DVD+R、DVD-R 或者 DVD-RW 的顺序写入格式下, 一次初始化 (未关闭) 区段之后使用下面的命令, 将会在光盘上添加一个新的区段: &prompt.root; growisofs -M /dev/cd0 -J -R /path/to/nextdata 对 DVD+RW 或者 DVD-RW 在受限式覆写模式下使用这条命令, 会合并新区段到存在的区段中来附加数据。 结果就是一张单区段光盘。 这是在这些介质上用于在最初的写操作之后添加数据的方式。 介质上的一些空间用于区段之间区段的开始与结束。 因此,应该用大量的数据添加区段来优化介质空间。 对于 DVD+R 来说区段的数量限制为 154, 对于 DVD-R 来说大约是 2000,对于双层 DVD+R 来说是 127。 更多的信息 要获得更多的关于 DVD 的信息 dvd+rw-mediainfo /dev/cd0 命令可以运行来获得 更多的信息。 更多的关于 dvd+rw-tools 的信息可以在 &man.growisofs.1; 联机手册找到,在 dvd+rw-tools web sitecdwrite mailing list 联接中也可找到。 dvd+rw-mediainfo 命令的输出结果记录, 以及介质的问题会被用来做问题报告。 如果没有这些输出, 就很难帮您解决问题。 使用 DVD-RAM DVD DVD-RAM 配置 DVD-RAM 刻录机通常使用 SCSI 或 ATAPI 两种接口之一。 对于 ATAPI 设备, DMA 传输模式必须手工启用。 这一工作可以通过在 /boot/loader.conf 文件中增加下述配置来完成: hw.ata.atapi_dma="1" 初始化介质 如本章前面的介绍所言, DVD-RAM 可以视为一移动硬盘。 与任何其它型号的移动硬盘类似, 首次使用它之前, 应首先 初始化 DVD-RAM。 在下面的例子中, 我们将在全部空间上使用标准的 UFS2 文件系统: &prompt.root; dd if=/dev/zero of=/dev/acd0 count=2 &prompt.root; bsdlabel -Bw acd0 &prompt.root; newfs /dev/acd0 您应根据实际情况将 acd0 改为您所使用的设备名。 使用介质 一旦您在 DVD-RAM 上完成了前面的操作, 就可以像普通的硬盘一样挂接它了: &prompt.root; mount /dev/acd0 /mnt 然后就可以正常地对 DVD-RAM 进行读写了。 Julio Merino 原作 Martin Karlsson 重写 创建和使用软盘 把数据存储在软盘上有时也是十分有用的。 例如, 在没有其它可靠的存储介质, 或只需将少量数据传到其他计算机时。 这一章将介绍怎样在 FreeBSD 上使用软盘。 在使用 DOS 3.5 英寸软盘时首要要涉及的就是格式化, 但其概念与其它的软盘格式化极为类似。 格式化软盘 设备 软盘的访问像其它设备一样是通过在 /dev 中的条目来实现的。 直接访问软盘时, 只需简单地使用 /dev/fdN 来表示。 格式化 一张软盘在使用这前必须先被低级格式化。 通常卖主已经做过了,但格式化是检测介质完整性的一种好方法。 尽管这有可能会强取大量(或少量)的硬盘大小,但 大部分磁盘都能被格式化设计为 1440kB 。 低级格式化软盘你需要使用 &man.fdformat.1; 命令。这个程序需要设备名作为参数。 要留意一切错误信息,这些信息能够帮助你确定 磁盘的好与坏。 软盘的格式化 使用 /dev/fdN 设备来格式化软盘。插入一张新的 3.5 英寸的软盘在你的设备中: &prompt.root; /usr/sbin/fdformat -f 1440 /dev/fd0 磁盘标签 经过低级格式化后, 你需要给它分配一个标签。 这个磁盘标签以后会被删去, 但系统需要使用它来确定磁盘的尺寸。 新的磁盘标签将会接管整个磁盘,会包括所有合适的关于软盘的 geometry 信息。 磁盘标签的 geometry 值列在 /etc/disktab中。 现在可以用下面的方法来使用 &man.bsdlabel.8; 了: &prompt.root; /sbin/bsdlabel -B -w /dev/fd0 fd1440 文件系统 现在对软盘进行高级格式化。 这会在它上面安置一个新的文件系统,可使 FreeBSD 来对它进行读写。 在创建完新的文件系统后,磁盘标签将被消毁,所以如果你想重新格式化磁盘, 你必须重新创建磁盘标签。 软盘的文件系统可以选择 UFS 或 FAT 。 FAT 是通常情况下软盘比较好的选择。 要制作新的文件系统在软盘上,可以使用下面的命令: &prompt.root; /sbin/newfs_msdos /dev/fd0 现在磁盘已经可以进行读取和使用。 使用软盘 要使用软盘,需要先使用 &man.mount.msdosfs.8; 挂接它。 除此之外, 也可以使用在 ports 套件中的 emulators/mtools 程序。 用磁带机备份 tape media 主流的磁带机有 4mm, 8mm, QIC, mini-cartridge 和 DLT。 4mm (DDS: Digital Data Storage) tape media DDS (4mm) tapes tape media QIC tapes 4mm 磁带机正在逐步取代 QIC 成为工作站备份数据的首选设备。 在 Conner 收购了 QIC 磁带机领域领先的制造商 Archive 之后不久, 即不再生产这种磁带机, 这使得这一趋势变得愈加明显。 4mm 的驱动器更加小和安静,但对于数据保存的可靠性仍不及 8mm 驱动器。它要比 8mm 的便宜和小得多 (3 x 2 x 0.5 inches, 76 x 51 x 12 mm) 。和 8mm 的一样,读写关的寿命都不长,因为它们同样使用螺旋式 的方式来读写。 这些设备的数据传输的速度约在 ~150 kB/s 到 ~500 kB/s 之间, 存储空间从 1.3 GB 到 2.0 GB 之间,硬件压缩可使空间加倍。磁带库 单元可以有 6 台磁带机,120 个磁带匣,以自动切换的方式使用同一个磁带柜, 磁带库的容量可达 240 GB 。 DDS-3 标准现在支持的磁带机容量最高可达到 12 GB (或压缩的 24 GB )。 4mm 和 8mm 同样都使用螺旋式读写的方式,所有螺旋式读写的优点及缺点, 都可以在 4mm 和 8mm 磁带机上看到。 磁带在经过 2,000 次的使用或 100 次的全部备份后,就该退休了。 8mm (Exabyte) tape media Exabyte (8mm) tapes 8mm 磁带机是最常见的 SCSI 磁带机,也是磁带交换的最佳选择。几乎每个 工作站都有一台 2 GB 8mm 磁带机。8mm 磁带机可信度高、方便、安静。 卡匣小 (4.8 x 3.3 x 0.6 inches; 122 x 84 x 15 mm)而且不贵。8mm 磁带机 的下边是一个短短的读写头,而读写头的寿命取决于磁带经过读写头时,相对高 速运动情况。 数据传输速度约在 250 kB/s 到 500 kB/s 之间,可存储的空间从 300 MB 到 7 GB,硬件压缩可使空间加倍。磁带库单元可以有 6 台磁 带机,120 个磁带匣,以自动切换的方式使用同一个磁带柜,磁带库的容量可达 840+ GB。 Exabyte Mammoth 模型支持 12 GB 的容量在一个磁带 上(压缩后可达 24 GB )相当于普通磁带的二倍。 数据是使用螺旋式读写的方式记录在磁带上的,读写头和磁带约相差 6 度, 磁带以 270 度缠绕着轴,并抵住读写头,轴适时地旋转,使得磁带具有高密度, 从一端到另一端并可使磁道紧密地分布。 QIC tape media QIC-150 QIC-150 磁带和磁带机可能是最常见的磁带机和介质了。 QIC 磁带机是最便宜的 正规 备份设备。 它的缺点在于介质的价格较高。 QIC 磁带要比 8mm 或 4mm 磁带贵, 每 GB 的数据存储价格可能最高高出 5 倍。 但是, 如果您的需求能够为半打磁带所满足的话, 那么 QIC 可能是明智之选。 QIC 是 常见的磁带机。 每个站点都会有某种密度的 QIC。 这有时是一种麻烦, QIC 有很多在外观上相似(有时一样),但是密度不同的磁带。 QIC 磁带机噪音很大。 它们在寻址以及读写时都会发出声音。 QIC 磁带的规格是 6 x 4 x 0.7 英寸 (152 x 102 x 17 毫米)。 数据传输的速度介于 150 kB/s 到 500 kB/s 之间,可存储的空间 从 40 MB 到 15 GB。较新的 QIC 磁带机具有硬件压缩的功能。 QIC 的使用率愈来愈低,渐渐被 DAT 所取代。 数据以磁道的方式记录在磁带上,磁道数及磁道的宽度会根据容量而有所不同。 通常新的磁带机具有的向后兼容的读取功能(通常也具备写入的功能)。对于数据 的安全性,QIC 具有不错的评价。 磁带机在经过 5,000 次的使用后,就该退休了。 DLT tape media DLT 在这一章列出的磁带机中 DLT 具有最快的数据传输率。 1/2" (12.5mm) 的 磁带包含在单轴的磁带匣 (4 x 4 x 1 inches; 100 x 100 x 25 mm)中。磁带匣 的一边是一个旋转匣道,通过匣道的开合,可以让磁带卷动。磁带匣内只有一个 轴,而本章中所提到的其他磁带匣都是有两个轴的(9磁道磁带机例外)。 数据传输的速度约 1.5 MB/s,是 4mm, 8mm, 或 QIC 磁带机的三倍。 可存储的空间从 10 GB 到 20 GB,具有磁带机数据库。磁带机数据库 单元可以有 1 to 20 台磁带机,5 到 900 个磁带匣,磁带机数据库的容量可达 50 GB 到 9 TB 。 如果要压缩的话,DLT 型 IV 格式的磁带机最高可支持 70 GB 的存储 容量。 数据存储在平行于磁带运行方向的磁道上(就像 QIC 磁带),一次写入两个 磁道。读写头的寿命相当长,每当磁带停止前进,磁带与读写头之间没有相对运动。 AIT tape media AIT AIT 是 Sony 开发的一种新格式,每个磁带最高可以存储 50 GB。磁带 机使用内存芯片来保存磁带上的索引内容。这个索引能够被磁带机驱动器快速阅读 来搜索磁带机上文件所处的位置,而不像其他的磁带机需要花几分钟的时间才能找 到文件。像 SAMS:Alexandria 这样的软件:能够操 作四十或者更多的 AIT 磁带库,直接使用内存芯片来进行通信把内容显示在屏幕上, 以决定把什么文件备份到哪个磁带上,加载和恢复数据。 像这样的库成本大概在 $20,000 美元左右,零售市场可能还要贵一点。 第一次使用新的磁带机 当在一块完全空白的磁带上尝试定入数据时,会得到类似下面这样的错误信息: sa0(ncr1:4:0): NOT READY asc:4,1 sa0(ncr1:4:0): Logical unit is in process of becoming ready 信息指出这块磁带没有块编号 (block 编号为 0)。在 QIC-525 之后的所有 QIC 磁带,都采用 QIC-525 标准,必须写入一个 Identifier Block 。对于这种问题, 有以下两种解决的办法: mt fsf 1 可以让磁带机对磁带写入 Identifier Block 。 使用面板上的按钮磁带。 再插入一次,并存储 dump 数据到磁带上。 这时dump 将传回 DUMP: End of tape detected ,然后您会得到这样的错误信息: HARDWARE FAILURE info:280 asc:80,96 这时用 mt rewind 来倒转磁带。 磁带操作的后续操作就完成了。 用软盘备份 能够使用软盘来备份数据吗 backup floppies floppy disks 软磁盘通常是用来备份的设备中不太合适的设备: 这种设备不太可靠,特别是长期使用。 备份和恢复都很慢 它们只有非常有限的存储容量。 然而,如果没有其它的备份数据的方法,那软盘备份总比没有备份要好。 如果必须使用软盘的话,必须确保盘片的质量。软盘在办公室中使用已经有许多 年了。最好使用一些名牌厂商的产品以确保质量。 如何备份数据到软盘 最好的备份数据到软盘的方法是使用 &man.tar.1; 程序加上 选项, 它可以允许数据备份到多张软盘上。 要备份当前目录中所有的文件可以使用这个命令 (需要有 root权限): &prompt.root; tar Mcvf /dev/fd0 * 当第一张盘满的时候, &man.tar.1; 会指示您插入下一张盘,插入第二张盘之后就按回车。 Prepare volume #2 for /dev/fd0 and hit return: 这个步骤可能需要重复很多次,直到这些文件备份完成为止。 可以压缩备份吗 tar gzip compression 不幸的是,&man.tar.1; 在为多卷文件作备份时是不允许使用 选项的。当然,可以用 &man.gzip.1; 压缩所有的文件,把它们打包到磁盘,以后在用 &man.gunzip.1; 解开。 如何恢复备份 要恢复所有文件: &prompt.root; tar Mxvf /dev/fd0 有两种方法来恢复软盘中的个别文件。首先,就要用第一张软盘启动: &prompt.root; tar Mxvf /dev/fd0 filename &man.tar.1; 程序会提示您插入后面的软盘,直到它找到所需要的文件。 如果您知道哪个文件在哪个盘上,您就可以插入那张盘,然后使用上同同样的命令。 如果软盘上的第一个文件与前面的文件是连续的,那 &man.tar.1; 命令会警告您它无法 恢复,即使您不要求它这样做。 Lowell Gilbert 原作 备份策略 设计备份计划的第一要务是确认以下问题皆已考虑到: 磁盘故障 文件的意外删除 随机的文件损毁 机器完全损毁 (例如火灾), 包括破坏全部在线备份。 针对上述的每个问题采用完全不同的技术来解决是完全可行的。 除了只包含少量几乎没有价值数据的个人系统之外, 一般来说很少有一种技术能够同时兼顾前面所有的需要。 可以采用的技术包括: 对整个系统的数据进行存档, 备份到永久性的离线介质上。 这种方法实际上能够提供针对前面所有问题的保护, 但这样做通常很慢, 而且恢复时会比较麻烦。 您可以将备份置于近线或在线的状态, 然而恢复文件仍然是一个难题, 特别是对没有特权的那些用户而言。 文件系统快照。 这种技术实际上只对无意中删除文件这一种情况有用, 但在这种情况下它会提供 非常大 的帮助, 而且访问迅速, 操作容易。 直接复制整个文件系统和/或磁盘 (例如周期性地对整个机器做 &man.rsync.1;)。 通常这对于在网络上的单一需求最为适用。 要为磁盘故障提供更为通用的保护, 通常这种方法要逊于 RAID。 对于恢复无意中删除的文件来说, 这种方法基本上与 UFS 快照属于同一层次, 使用哪一个取决于您的喜好。 RAID。 它能够最大限度地减少磁盘故障导致的停机时间。 其代价是需要处理更为频繁的磁盘故障 (因为磁盘的数量增加了), 尽管这类故障不再需要作为非常紧急的事项来处理。 检查文件的指纹。 &man.mtree.8; 工具对于这种操作非常有用。 尽管这并不是一种备份的技术, 但它能够确保您有机会注意到那些您需要求助于离线备份的事情。 这对于离线备份非常重要, 而且应有计划地加以检查。 很容易列举更多的技术, 它们中有许多实际上是前面所列出的方法的变种。 特别的需求通常会需要采用特别的技术 (例如, 备份在线运行的数据库, 往往需要数据库软件提供某种方法来完成中间步骤) 来满足。 最重要的事情是, 一定要了解需要将数据保护起来免受何种风险, 以及发生问题时应该如何处理。 备份程序 有三个主要的备份程序 &man.dump.8;、&man.tar.1; 和 &man.cpio.1;。 Dump 和 Restore 备份软件 dump / restore dump restore dumprestore 是 &unix; 传统的备份程序。它以 block 而不是以文件为单位来备份数据、链接或目录。 dump 备份的是设备上的整个文件系统,不能只备份一 一个文件系统的部分或是用到两个以上文件系统的目录树。 dump 不会写文件和目录到磁带机,而是写入包含文件 和目录的原始数据块。 如果在您的 root 目录使用 dump ,将不需要 备份 /home/usr 或其他目录, 因为这些是典型的其他文件系统或符号连接到那些文件系统的加载点。 dump 是最早出现于 AT&T UNIX 的 Version 6 (约 1975)。 默认的参数适用于 9-track 磁带(6250 bpi),所以如果要用高密度的磁带(最高可达 62,182 ftpi),就不能用默认的参数,而要另外指定参数。这些默认值必须在命令行被 修改以更好地利用当前磁带机的功能。 .rhosts rdumprrestore 可以通过网络在另一 台计算机的磁带机上备份数据。这两个程序都是依靠 &man.rcmd.3; 和 &man.ruserok.3; 来访问远程的磁带机。因此,运行备份的用户必须要有远程 主机的 .rhosts 访问权。rdumprrestore 的参数必须适用于远程主机(例如,当您从 FreeBSD 连到 一台 SUN 工作站 knomodo 去使用磁带机时,使用: &prompt.root; /sbin/rdump 0dsbfu 54000 13000 126 komodo:/dev/nsa8 /dev/da0a 2>&1 要注意的是:必须检查您在使用 .rhosts 时的安全情况。 也可以通过使用 ssh 用一个更安全的方式来使用 dumprestore 通过 <application>ssh</application> 使用 <command>dump</command> &prompt.root; /sbin/dump -0uan -f - /usr | gzip -2 | ssh -c blowfish \ targetuser@targetmachine.example.com dd of=/mybigfiles/dump-usr-l0.gz 或使用 dump 的 built-in 方法, 设置环境变量 RSH 通过设置 <application>ssh</application> 环境变量 <envar>RSH</envar> 使用 <command>dump</command> &prompt.root; RSH=/usr/bin/ssh /sbin/dump -0uan -f targetuser@targetmachine.example.com:/dev/sa0 /usr <command>tar</command> 备份软件 tar &man.tar.1; 也同样是在第 6 版 AT&T UNIX (大约是 1975 前后) 出现的。 tar 对文件系统直接操作; 其作用是把文件和目录写入磁带。 tar 并不支持 &man.cpio.1; 所提供的全部功能, 但也不需要 cpio 所需要使用的诡异的命令行管道。 tar 在 FreeBSD 5.3 和更高版本中, 同时提供了 GNU tar 和默认的 bsdtar。 GNU 的版本可以通过 gtar 来使用。 它通过与 rdump 一样的语法来支持远程设备。 要 tar 到连接在名为 komodo 的 Sun 机器上的 Exabyte 磁带机, 可以使用: &prompt.root; /usr/bin/gtar cf komodo:/dev/nsa8 . 2>&1 您也可以让 bsdtar 通过管道和 rsh 将数据发送到远程的磁带机上。 &prompt.root; tar cf - . | rsh hostname dd of=tape-device obs=20b 如果您担心通过网络备份会有安全问题,应当使用 ssh , 而不是 rsh <command>cpio</command> backup software cpio &man.cpio.1; 是 &unix; 最早用来作文件交换的磁带机程序。它有执行字节 交换的选项,可以用几种不同的格式写入,并且可以将数据用管道传给其他程序。 cpio 没办法自动查找目录树内的文件列表,必须通过标准 输入 stdin 来指定。 cpio cpio 不支持通过网络的备份方式。可以使用 pipeline 和 rsh 来传送数据给远程的磁带机。 &prompt.root; for f in directory_list; do find $f >> backup.list done &prompt.root; cpio -v -o --format=newc < backup.list | ssh user@host "cat > backup_device" 这里的 directory_list 是要备份的目录列表, user@host 结合了将 要执行备份的用户名和主机名,backup_device 是写 入备份的设备(如 /dev/nsa0)。 <command>pax</command> backup software pax pax POSIX IEEE &man.pax.1; 是符合 IEEE/&posix; 标准的程序。多年来各种不同版本 的 tarcpio 间有些不兼容。 为了防止这种情况,并使其标准化,&posix; 出了这套新的工具程序。 pax 尝试可以读写各种 cpiotar 的格式,并可以自己增加新的格式。它的命令 集比 tar 更接近 cpio <application>Amanda</application> backup software Amanda Amanda Amanda (Advanced Maryland Network Disk Archiver) 并非单一的程序,而是一个客户机/服务器模式的备份系统 。一台 Amanda 服务器可以备份任意数量执行 Amanda 的客户机或是将连上 Amanda 服务器的计算机上的数据备份到一台磁带机上。一个常见的问题是,数据写入磁带机的时间将超 过取行数据的时间,而 Amanda 解决了这个问题。它使用一个 holding disk 来同时备份几个文件系统。 Amanda 建立 archive sets 的一组磁带,用来备份在 Amanda 的配置文件中所列出的完整的文件系统。 Amanda 配置文件提供完整的备份控制及 Amanda 产生的网络传输。 Amanda 可以使用上述任何一个设备程序来向磁带写入数据。Amanda 可以从 port 或 package 取得,它并非系统默认安装的。 Do Nothing 备份策略 Do nothing 不是一个程序,而是被广泛使用的备份策略。 不需要预算,不需要备份的计划表,全部都不用。如果您的数据发生了什么问题, 忽略它! 如果您的时间和数据不值得您做这些事,那么 Do nothing 将是最好的备份程序。要注意的是,&unix; 是相当好用的工具,您可能在几个月 内,就发现您已经收集了不少对您来说相当具有价值的文件和程序。 Do nothing 对于像 /usr/obj 和其他 可由您的计算机产生的文件来说,是最好的方法。例如这本手册包含有 HTML 或 &postscript; 格式的文件。这些文档格式是从 SGML 输入文件创建的。创建 HTML 或 &postscript; 格式的文件的备份就没有必要了。只要经常备份 SGML 文件就够了。 哪个备份程序最好? LISA 在&man.dump.8; 时期 Elizabeth D. Zwicky 测试了所有以上列出的备份程序。在各种各样怪异的文件系统中, dump 是您明智的选择。Elizabeth 建立起各种各样、 奇怪或常见的文件系统,并用各种备份程序,测试在各种文件系统上备份 及恢复数据。这些怪异之处包括:具有 holes 和一个 nulls block 的文件, 文件名具有有趣字符,无法读写的文件及设备,在备份时改变文件大小,在 备份时建立或删除的文件。她将结果刑在: LISA V in Oct. 1991. See torture-testing Backup and Archive Programs. 应急恢复程序 在出现灾难前 在遇到灾难前,只需要执行以下四个步骤: bsdlabel 第一,打出您的每个磁盘驱动器的磁盘标签 (例如: bsdlabel da0 | lpr),文件系统表, (/etc/fstab) ,以及所有启动信息, 并将其复制两份。 fix-it floppies 第二,确定遇到的情况时,用来启动及修复的软盘 (boot.flpfixit.flp) 具有您所有的设备代号。最简单的方法是用软盘启动,然后检查启动信息, 如果设备都被列出,并且可以正常使用,就可以跳到第三步。 否则,必须建立两张传统的可启动软盘,并包含: fdisk, bsdlabel, newfs, mount, 以及所有使用的 备份程序。这些程序必须被静态的连接。如果使用的是 dump, 那么这张软盘就必须包含 restore 第三,定期将数据备份到磁带。任何在上次备份后的改变都无法恢复。记得将 磁盘写保护。 第四,测试在第二步所建立的软盘及备份的磁带,将过程记录下来,并和这张 可启动的软盘和磁带放在一起。也许您在恢复时会想要,而这份记录将防止您破坏 您的磁带 (怎么说呢?因为您可能将 tar xvf /dev/sa0 打成 tar cvf /dev/sa0 而重写了备份磁带)。 为了安全,您可以每次都做两份备份磁带及一张启动磁盘,并将其中 一份备份磁带存放在其它地方。其它地方不是指同一栋办公大楼的地下室 (世贸中心的一些公司应该学到了一些教训),而是真的要让人的磁带离您 的的计算机远远的。 一个建立启动磁盘的 shell 脚本例子: /mnt/sbin/init gzip -c -best /sbin/fsck > /mnt/sbin/fsck gzip -c -best /sbin/mount > /mnt/sbin/mount gzip -c -best /sbin/halt > /mnt/sbin/halt gzip -c -best /sbin/restore > /mnt/sbin/restore gzip -c -best /bin/sh > /mnt/bin/sh gzip -c -best /bin/sync > /mnt/bin/sync cp /root/.profile /mnt/root chmod 500 /mnt/sbin/init chmod 555 /mnt/sbin/fsck /mnt/sbin/mount /mnt/sbin/halt chmod 555 /mnt/bin/sh /mnt/bin/sync chmod 6555 /mnt/sbin/restore # # create minimum file system table # cat > /mnt/etc/fstab < /mnt/etc/passwd < /mnt/etc/master.passwd < 出现灾难后 关键问题是: 您的硬件是否幸免于难? 由于已经做好了定期的备份工作, 因此并不需要担心软件的问题。 如果硬件已经损毁, 这些部分应该在尝试使用计算机之前换掉。 如果硬件还能用, 检查一下您的软盘。 如果使用定制的引导软盘, 启动单用户模式 (在 boot: 提示后输入 -s)。 跳过下面一段。 如果您使用 boot.flpfixit.flp 软盘, 请继续阅读。 将 boot.flp 软盘插到计算机的第一个软驱并启动机器。 此时, 最初的安装菜单将显示在屏幕上。 选择 Fixit--Repair mode with CDROM or floppy. 选项。 在得到提示后插入 fixit.flprestore 以及其他需要的程序, 可以在 /mnt2/rescue (对于 &os; 5.2 之前的版本, 则是 /mnt2/stand)。 分别恢复每一个文件系统 mount root partition bsdlabel newfs 试着 mount 上您的第一个磁盘的 root 分区(例如: mount /dev/da0a /mnt)。假如这个磁盘标签已经损坏,使用 bsdlabel 来重新分割并分配磁盘标签(利用您以前保留下来的数据)。使用 newfs 来建立文件系统,并重新挂上软盘读写的 root 分区 (mount -u -o rw /mnt)。然后使用备份程序及备份磁带来修复文件系统 (例如: restore vrf /dev/sa0)。最后 Unmount 这个文件系统 (例如: umount /mnt)。对于每个损坏的文件系统都重复一次。 当您的系统正常启动后,将您的数据备份到新的磁带。任何造成数据丢失的 的灾难都可能再次发生。现在花一些时间,也许可以使您免于下次的灾难。 * I Did Not Prepare for the Disaster, What Now? ]]> Marc Fonvieille Reorganized and enhanced by 网络、内存和 和以及映像文件为介质的虚拟文件系统 virtual disks 磁盘 虚拟 除了插在您计算机上的物理磁盘: 软盘、 CD、 硬盘驱动器, 等等之外, FreeBSD 还能识别一些其他的磁盘形式 - 虚拟磁盘 NFS Coda disks memory 这还包括, 如 网络文件系统 (Network File System) 和 Coda一类的网络文件系统、 内存以及映像文件为介质的虚拟文件系统。 随运行的 FreeBSD 版本不同, 用来创建和使用以映像文件介质文件系统和内存文件系统的工具也不尽相同。 系统会使用 &man.devfs.5; 来创建设备节点, 这对用户来说是透明的。 以映像文件为介质的文件系统 disks (磁盘) file-backed (采用文件作为介质) 在 FreeBSD 系统中, 可以用 &man.mdconfig.8; 程序来配置和启用内存磁盘, &man.md.4;。 要使用 &man.mdconfig.8;, 就需要在内核配置文件中添加 &man.md.4; 模块来支持它: device md &man.mdconfig.8; 命令支持三种类型的虚拟文件系统: 使用 &man.malloc.9;,来分配内存文件系统,内存文件系统作为文件或作为 备用的交换分区。一种使用方式是在文件中来挂载一个软盘和 CD 镜像。 将一个暨存的映像文件作为文件系统挂载: 使用 <command>mdconfig</command> 挂载已经存在的映像文件 &prompt.root; mdconfig -a -t vnode -f diskimage -u 0 &prompt.root; mount /dev/md0 /mnt 使用 &man.mdconfig.8; 来创建新的映像文件: 使用 <command>mdconfig</command> 将映像文件作为文件系统挂载 &prompt.root; dd if=/dev/zero of=newimage bs=1k count=5k 5120+0 records in 5120+0 records out &prompt.root; mdconfig -a -t vnode -f newimage -u 0 &prompt.root; bsdlabel -w md0 auto &prompt.root; newfs md0a /dev/md0a: 5.0MB (10224 sectors) block size 16384, fragment size 2048 using 4 cylinder groups of 1.25MB, 80 blks, 192 inodes. super-block backups (for fsck -b #) at: 160, 2720, 5280, 7840 &prompt.root; mount /dev/md0a /mnt &prompt.root; df /mnt Filesystem 1K-blocks Used Avail Capacity Mounted on /dev/md0a 4710 4 4330 0% /mnt 如果没有通过 选项指定一个标识号 &man.mdconfig.8; 将使用 &man.md.4; 为它自动选择一个未用的设备标识号。 分配给它的标识名将被输出到标准输出设备, 其形式是与 md4 类似。 如果希望了解更多相关信息, 请参见联机手册 &man.mdconfig.8;。 &man.mdconfig.8; 功能很强大, 但在将映像文件作为文件系统挂载时, 仍需使用许多行的命令。 为此 FreeBSD 也提供了一个名为 &man.mdmfs.8; 的工具, 该程序使用 &man.mdconfig.8; 来配置 &man.md.4; 设备, 并用 &man.newfs.8; 在其上创建 UFS 文件系统, 然后用 &man.mount.8; 来完成挂载操作。 例如, 如果想创建和挂接像上面那样的文件系统映像, 只需简单地执行下面的步骤: 使用 <command>mdmfs</command> 命令配置和挂载一个映像文件为文件系统 &prompt.root; dd if=/dev/zero of=newimage bs=1k count=5k 5120+0 records in 5120+0 records out &prompt.root; mdmfs -F newimage -s 5m md0 /mnt &prompt.root; df /mnt Filesystem 1K-blocks Used Avail Capacity Mounted on /dev/md0 4718 4 4338 0% /mnt 如果你使用没有加标识号的 选项, &man.mdmfs.8; 将使用 &man.md.4; 的自动标示号特性来自动为其 选择一个未使用的设备。更详细的 &man.mdmfs.8;,请参考联机手册。 以内存为介质的文件系统 disks (磁盘) 内存文件系统 一般来说, 在建立以内存为介质的文件系统时, 应使用 交换区作为介质 (swap backing)。 使用交换区作为介质, 并不意味着内存盘将被无条件地换出到交换区, 它只是表示将根据需要从可换出的内存池中分配内存。 此外, 也可以使用 &man.malloc.9; 创建以内存作为介质的文件系统。 不过在内存不足时, 这种方式可能引致系统崩溃。 用 <command>mdconfig</command> 创建新的内存盘设备 &prompt.root; mdconfig -a -t swap -s 5m -u 1 &prompt.root; newfs -U md1 /dev/md1: 5.0MB (10240 sectors) block size 16384, fragment size 2048 using 4 cylinder groups of 1.27MB, 81 blks, 192 inodes. with soft updates super-block backups (for fsck -b #) at: 160, 2752, 5344, 7936 &prompt.root; mount /dev/md1 /mnt &prompt.root; df /mnt Filesystem 1K-blocks Used Avail Capacity Mounted on /dev/md1 4718 4 4338 0% /mnt 使用 <command>mdmfs</command> 来新建内存介质文件系统 &prompt.root; mdmfs -s 5m md2 /mnt &prompt.root; df /mnt Filesystem 1K-blocks Used Avail Capacity Mounted on /dev/md2 4846 2 4458 0% /mnt 从系统中移除内存盘设备 磁盘 移除内存盘设备 当不再使用内存盘设备时, 应将其资源释放回系统。 第一步操作是卸下文件系统, 然后使用 &man.mdconfig.8; 把虚拟磁盘从系统中分离, 以释放资源。 例如, 要分离并释放所有 /dev/md4 使用的资源, 应使用命令: &prompt.root; mdconfig -d -u 4 mdconfig -l 命令可以列出关于配置 &man.md.4; 设备的信息。 Tom Rhodes Contributed by 文件系统快照 文件系统 快照 FreeBSD 提供了一个和 Soft Updates 关联的新功能: 文件系统快照 快照允许用户创建指定文件系统的映像,并把它们当做一个文件来对待。 快照文件必须在文件系统正在使用时创建,一个用户对每个文件系统创建的 快照不能大于20个。活动的快照文件被记录在超级块中,所以它们可以在系统 启动的时候一块进行挂接后摘掉。当一个快照不再需要时,可以使用标准的 &man.rm.1; 使用来使其删除。快照可以以任何顺序进行移除,但所有使用 的快照不可能同时进行移除,因为其它的快照将有可能互相引用一些块。 不可改的 文件标志, 是由 &man.mksnap.ffs.8; 在完成创建快照文件时设置的。 &man.unlink.1; 命令是一个特例, 以允许删除快照文件。 快照可以通过 &man.mount.8; 命令创建。 将文件系统 /var 的快照放到 /var/snapshot/snap 可以使用下面的命令: &prompt.root; mount -u -o snapshot /var/snapshot/snap /var 作为选择,你也可以使用 &man.mksnap.ffs.8; 来创建一个快照: &prompt.root; mksnap_ffs /var /var/snapshot/snap 可以查找文件系统中的快照文件 (例如 /var), 方法是使用 &man.find.1; 命令: &prompt.root; find /var -flags snapshot 当快照文件被创建好后,可以用于下面一些目的: 有些管理员用文件快照来进行备份, 因为快照可以被转移到 CD 或磁带上。 文件系统一致性检查程序 &man.fsck.8; 可以用来检查快照文件。 如果文件系统在挂接前是一致的, 则检查结果也一定是一致的 (也就是不会做任何修改)。 实际上这也正是后台 &man.fsck.8; 的操作过程。 在快照上运行 &man.dump.8; 程序。 dump 将返回包含文件系统和快照的时间戳。&man.dump.8; 也能够抓取快照,使用 标志可以首先创建快照, 完成 dump 映像之后再自动删除它。 用 &man.mount.8; 来挂接快照作为文件系统的一个冻结的镜像。 要 &man.mount.8; 快照 /var/snapshot/snap 运行: &prompt.root; mdconfig -a -t vnode -f /var/snapshot/snap -u 4 &prompt.root; mount -r /dev/md4 /mnt 现在你就可以看到挂接在 /mnt 目录下的 /var 文件系统的快照。 每一样东西都保存的像它创建时的状态一样。 唯一例外的是更早的快照文件将表现为长度为 0 的文件。 用完快照文件之后可以把它卸下,使用: &prompt.root; umount /mnt &prompt.root; mdconfig -d -u 4 想了解更多关于 和 文件系统快照的信息, 包括技术说明, 可以访问 Marshall Kirk McKusick 的 WWW 站点 文件系统配额 accounting disk space disk quotas 配额是操作系统的一个可选的功能, 它允许管理员以文件系统为单元, 限制分派给用户或组成员所使用的磁盘空间大小或是使用的总文件数量。 这经常被用于那些分时操作的系统上, 对于这些系统而言, 通常希望限制分派到每一个用户或组的资源总量, 从而可以防止某个用户占用所有可用的磁盘空间。 配置系统来启用磁盘配额 在决定使用磁盘配额前,确信磁盘配额已经在内核中配置好了。只要在在内核 中配置文件中添加下面一行就行了: options QUOTA 在默认情况下 GENERIC 内核是不会启用这个功能的, 所以必须配置、重建和安装一个定制的内核。请参考 FreeBSD 内核配置 这章了解更多有关内核配置的信息。 接下来,需要在 /etc/rc.conf 中启用磁盘配额。可以 通过添加下面这行来完成: enable_quotas="YES" disk quotas checking 为了更好的控制配额时的启动,还有另外一个可配置的变量。通常 启动时,集成在每个文件系统上的配额会被配额检查程序 &man.quotacheck.8; 自动检查。配额检查功能能够确保在配额数据库中 的数据正确地反映了文件系统的数 据情况。这是一个很耗时间的处理进程,它会影响系统的启动时间。如果 想跳过这一步,可以在文件 /etc/rc.conf 加入 下面这一行来达到目的: check_quotas="NO" 最后,要编辑 /etc/fstab 文件,以在每一个 文件系统基础上雇用磁盘配额。这是启用用户和组配额,或同时启用用户 和组配额的地方。 要在一个文件系统上启用每个用户的配额,可以在 /etc/fstab 里添加 选项在要雇用配额文件的系统上。例如: /dev/da1s2g /home ufs rw,userquota 1 2 同样的,要启用组配额,使用 选项来代替 选项。要同时启用用户和组配额,可以这样做: /dev/da1s2g /home ufs rw,userquota,groupquota 1 2 默认情况下,配额文件是存放在文件系统的以 quota.userquota.group 命名的根目录下。可以查看 &man.fstab.5; 联机手册了解更多信息。 尽管联机手册 &man.fstab.5; 提到, 可以为配额文件指定其他的位置, 但并不推荐这样做, 因为不同的配额工具并不一定遵循此规则。 到这儿,可以用新内核重新启动系统。 /etc/rc 将自动 运行适当的命令来创建最初的配额文件,所以并不需要手动来创建任何零长度的配额 文件。 在通常的操作过程中,并不要求手动运行 &man.quotacheck.8;、 &man.quotaon.8;, 或 &man.quotaoff.8; 命令,然而可能需要阅读与他们的操作 相似的联机手册。 设置配额限制 disk quotas limits 一旦您配置好了启用配额的系统,可以检查一下它们是真的有用。 可以这样做: &prompt.root; quota -v 您应该能够看到一行当前正在使用的每个文件系统启用的磁盘配额 使用情况的摘要信息。 现在可以使用 &man.edquota.8; 命令准备启用配额限制。 有几个有关如何强制限制用户或组可以分配到的磁盘空间大小的选项。 您可以限制磁盘存储块的配额, 或文件的数量, 甚至同时限制两者。 这些限制最终可分为两类: 硬限制和软限制。 硬性限制 硬性限制是一种不能越过的限制。 一旦用户达到了系统指定的硬性限制, 他就无法在对应的文件系统分配到更多的资源。 例如, 如果文件系统上分给用户的硬性限制是 500 KB, 而现在已经用掉了 490 KB, 那么这个用户最多还能再分配 10 KB 的空间。 换言之, 如果这时试图再分配 11 KB, 则会失败。 软性限制 而与此相反, 软性限制在一段时间内是允许越过的。 这段时间也称为宽限期, 其默认值是一周。 如果一个用户延缓时间太长的话,软限制将会变成硬限制, 而继续分配磁盘空间的操作将被拒绝。 当用户占用的空间回到软性限制值以下时, 宽限期将重新开始计算。 下面是一个运行 &man.edquota.8; 时看到的例子。当 &man.edquota.8; 命令被调用时,会被转移进 EDITOR 环境变量指派的编辑 器中,允许编辑配额限制。如果环境变量没有设置,默认在 vi 编辑器上进行。 &prompt.root; edquota -u test Quotas for user test: /usr: kbytes in use: 65, limits (soft = 50, hard = 75) inodes in use: 7, limits (soft = 50, hard = 60) /usr/var: kbytes in use: 0, limits (soft = 50, hard = 75) inodes in use: 0, limits (soft = 50, hard = 60) 在每一个启用了磁盘配额的文件系统上,通常会看到两行。一行是 block 限制,另一行是 inode 限制。简单地改变要修改的配额限制的值。 例如,提高这个用户软限制的数值到 500 ,硬限制到 600 : /usr: kbytes in use: 65, limits (soft = 50, hard = 75) to: /usr: kbytes in use: 65, limits (soft = 500, hard = 600) 当离开编辑器的时候,新的配额限制设置将会被保存。 有时,在 UIDs 的范围上设置配额限制是非常必要的。这可以通过在 &man.edquota.8; 命令后面加上 选项来完成。首先, 给用户分配所需要的配额限制,然后运行命令 edquota -p protouser startuid-enduid。例如,如果 用户 test 已经有了所需要的配额限制,下面的命令 可以被用来复制那些 UIDs 为10,000 到 19,999 的配额限制: &prompt.root; edquota -p test 10000-19999 更多细节请参考 &man.edquota.8; 联机手册。 检查配额限制和磁盘使用 disk quotas checking 既可以使用 &man.quota.1; 也可以使用 &man.repquota.8; 命令来检查 配额限制和磁盘使用情况。 &man.quota.1; 命令能够检查单个用户和组的配置 使用情况。只有超级用户才可以检查其它用户的配额和磁盘使用情况。 &man.repquota.8; 命令可以用来了解所有配额和磁盘的使用情况。 下面是一个使用 quota -v 命令后的输出情况: Disk quotas for user test (uid 1002): Filesystem usage quota limit grace files quota limit grace /usr 65* 50 75 5days 7 50 60 /usr/var 0 50 75 0 50 60 宽限期 前面以 /usr 作为例子。 此用户目前已经比软限制 50 KB 超出了 15 KB, 还剩下 5 天的宽限期。 请注意, 星号 * 说明用户已经超出了其配额限制。 通常, 如果用户没有使用文件系统上的磁盘空间, 就不会在 &man.quota.1; 命令的输出中显示, 即使已经为那个用户指定了配额。 而使用 选项则会显示它们, 例如前面例子中的 /usr/var 通过 NFS 使用磁盘配额 NFS 配额能够在 NFS 服务器上被配额子系统强迫使用。在 NFS 客户端, &man.rpc.rquotad.8; 命令可以使用 quota 信息用于 &man.quota.1; 命令, 可以允许用户查看它们的 quota 统计信息。 可以这样在 /etc/inetd.conf 中启用 rpc.rquotad rquotad/1 dgram rpc/udp wait root /usr/libexec/rpc.rquotad rpc.rquotad 现在重启 inetd &prompt.root; kill -HUP `cat /var/run/inetd.pid` Lucky Green Contributed by
shamrock@cypherpunks.to
加密磁盘分区 disks encrypting FreeBSD 提供了极好的数据保护措施,防止未受权的数据访问。 文件权限和强制访问控制(MAC)(看 ) 可以帮助预防在操作系统处于运行状态和计算机加电时未受权的第三方访问数据。 但是,和操作系统强制受权不相关的是,如果黑客有物理上访问计算机的可能, 那他就可以简单的把计算机的硬件安装到另一个系统上复制出敏感的数据。 无论攻击者如何取得停机后的硬件或硬盘驱动器本身, &os; GEOM Based Disk Encryption (基于 GEOM 的磁盘加密, gbde)geli 加密子系统都能够保护计算机上的文件系统数据, 使它们免受哪怕是训练有素的攻击者获得有用的资源。 与那些只能加密单个文件的笨重的加密方法不同, gbdegeli 能够透明地加密整个文件系统。 明文数据不会出现在硬盘的任何地方。 使用 <application>gbde</application> 对磁盘进行加密 成为 <username>root</username> 配置 gbde 需要超级用户的权力。 &prompt.user; su - Password: 在内核配置文件中添加对 &man.gbde.4; 的支持 在您的内核配置中加入下面一行: options GEOM_BDE 按照 所进行的介绍重新编译并安装内核。 重新引导进入新的内核。 另一种无需重新编译内核的方法, 是使用 kldload 来加载 &man.gbde.4;: &prompt.root; kldload geom_bde 准备加密盘 下面这个例子假设您添加了一个新的硬盘在您的系统并将拥有一个单独的加密分区。 这个分区将挂接在 /private目录下。 gbde 也可以用来加密 /home/var/mail, 但是这需要更多的复杂命令来执行。 添加新的硬盘 添加新的硬盘到系统中可以查看在 中的说明。 这个例子的目的是说明一个新的硬盘分区已经添加到系统中如: /dev/ad4s1c。在例子中 /dev/ad0s1* 设备代表系统中存在的标准 FreeBSD 分区。 &prompt.root; ls /dev/ad* /dev/ad0 /dev/ad0s1b /dev/ad0s1e /dev/ad4s1 /dev/ad0s1 /dev/ad0s1c /dev/ad0s1f /dev/ad4s1c /dev/ad0s1a /dev/ad0s1d /dev/ad4 创建一个目录来保存 gbde Lock 文件 &prompt.root; mkdir /etc/gbde gbde lock 文件包含了 gbde 需要访问的加密分区的信息。 没有 lock 文件, gbde 将不能解密包含在加密分区上的数据。 每个加密分区使用一个独立的 lock 文件。 初始化 gbde 分区 一个 gbde 分区在使用前必须被初始化, 这个初始化过程只需要执行一次: - &prompt.root; gbde init /dev/ad4s1c -i -L /etc/gbde/ad4s1c + &prompt.root; gbde init /dev/ad4s1c -i -L /etc/gbde/ad4s1c.lock &man.gbde.8; 将打开您的编辑器, 提示您去设置在一个模板文件中的配置变量。 使用 UFS1 或 UFS2,设置扇区大小为 2048: $FreeBSD: src/sbin/gbde/template.txt,v 1.1 2002/10/20 11:16:13 phk Exp $ # # Sector size is the smallest unit of data which can be read or written. # Making it too small decreases performance and decreases available space. # Making it too large may prevent filesystems from working. 512 is the # minimum and always safe. For UFS, use the fragment size # sector_size = 2048 [...] &man.gbde.8; 将让您输入两次用来加密数据的密钥短语。 两次输入的密钥必须相同。 gbde 保护您数据的能力依靠您选择输入的密钥的质量。 这个提示教您怎样选择一个安全易记的密钥短语, 请看 Diceware Passphrase 网站。 gbde init 命令为您的 gbde 分区创建了一个 lock 文件, 在这个例子中存储在 - /etc/gbde/ad4s1c中。 + /etc/gbde/ad4s1c.lock中。 + gbde lock 文件必须使用 + .lock 扩展名才能够被 + /etc/rc.d/gbde 启动脚本正确识别。 gbde lock 文件 必须 和加密分区上的内容同时备份。 如果发生只有 lock 文件遭到删除的情况时, 就没有办法确定 gbde 分区上的数据是否是解密过的。 另外, 如果没有 lock 文件, 即使磁盘的合法主人, 不经过大量细致的工作也无法访问加密分区上的数据, 而这是在设计 &man.gbde.8; 时完全没有考虑过的。 把加密分区和内核进行关联 - &prompt.root; gbde attach /dev/ad4s1c -l /etc/gbde/ad4s1c + &prompt.root; gbde attach /dev/ad4s1c -l /etc/gbde/ad4s1c.lock 在加密分区的初始化过程中您将被要求提供一个密码短语。 新的加密设备将在 /dev 中显示为 /dev/device_name.bde &prompt.root; ls /dev/ad* /dev/ad0 /dev/ad0s1b /dev/ad0s1e /dev/ad4s1 /dev/ad0s1 /dev/ad0s1c /dev/ad0s1f /dev/ad4s1c /dev/ad0s1a /dev/ad0s1d /dev/ad4 /dev/ad4s1c.bde 在加密设备上创建文件系统 当加密设备和内核进行关联后, 您就可以使用 &man.newfs.8; 在此设备上创建文件系统, 使用 &man.newfs.8; 来初始化一个 UFS2 文件系统比初始化一个 UFS1 文件系统还要快,摧荐使用 选项。 &prompt.root; newfs -U -O2 /dev/ad4s1c.bde &man.newfs.8; 命令必须在一个 gbde 分区上执行, 这个分区通过一个存在的 *.bde 设备名进行标识。 挂接加密分区 为加密文件系统创建一个挂接点。 &prompt.root; mkdir /private 挂接加密文件系统。 &prompt.root; mount /dev/ad4s1c.bde /private 校验加密文件系统是否有效 加密的文件系统现在对于 &man.df.1; 应该可见并可以使用。 &prompt.user; df -H Filesystem Size Used Avail Capacity Mounted on /dev/ad0s1a 1037M 72M 883M 8% / /devfs 1.0K 1.0K 0B 100% /dev /dev/ad0s1f 8.1G 55K 7.5G 0% /home /dev/ad0s1e 1037M 1.1M 953M 0% /tmp /dev/ad0s1d 6.1G 1.9G 3.7G 35% /usr /dev/ad4s1c.bde 150G 4.1K 138G 0% /private 挂接已有的加密文件系统 每次系统启动后, 在使用加密文件系统前必须和内核重新进行关联, 校验错误和再次挂接。使用的命令必须由 root用户来执行。 关联 gbde 分区到内核 - &prompt.root; gbde attach /dev/ad4s1c -l /etc/gbde/ad4s1c + &prompt.root; gbde attach /dev/ad4s1c -l /etc/gbde/ad4s1c.lock 接下来系统将提示您输入在初始化加密的 gbde 分区时所用的密码短语。 校验文件系统错误 加密文件系统不能列在 /etc/fstab 文件中进行自动加载, 在加载前必须手动运行 &man.fsck.8; 命令对文件系统进行错误检测。 &prompt.root; fsck -p -t ffs /dev/ad4s1c.bde 挂接加密文件系统 &prompt.root; mount /dev/ad4s1c.bde /private 加密后的文件系统现在可以有效使用。 自动挂接加密分区 可以创建脚本来自动地附加、 检测, 并挂接加密分区, 然而, 处于安全考虑, 这个脚本不应包含 &man.gbde.8; 密码。 因而, 我们建议这类脚本在控制台或通过 &man.ssh.1; 执行并要求用户输入口令。 除此之外, 系统还提供了一个 rc.d 脚本。 这个脚本的参数可以通过 &man.rc.conf.5; 来指定, 例如: gbde_autoattach_all="YES" -gbde_devices="ad4s1c" +gbde_devices="ad4s1c" +gbde_lockdir="/etc/gbde" 在启动时将要求输入 gbde 的口令。 在输入正确的口令之后, gbde 加密分区将被自动挂接。 对于将 gbde 用在笔记本电脑上时, 这就很有用了。 gbde 提供的密码学保护 &man.gbde.8; 采用 CBC 模式的 128-位 AES 来加密扇区数据。 磁盘上的每个扇区都采用不同的 AES 密钥来加密。 要了解关于 gbde 的密码学设计, 包括扇区密钥如何从用户提供的口令字中生成等细节, 请参考 &man.gbde.4;。 兼容性问题 &man.sysinstall.8; 是和 gbde 加密设备不兼容的。 在启动 &man.sysinstall.8; 时必须将 *.bde 设备和内核进行分离,否则在初始化探测设备时将引起冲突。 与加密设备进行分离在我们的例子中使用如下的命令: &prompt.root; gbde detach /dev/ad4s1c 还需要注意的是, 由于 &man.vinum.4; 没有使用 &man.geom.4; 子系统, 因此不能同时使用 gbdevinum 卷。 Daniel Gerzo 撰写者 使用 <command>geli</command> 对磁盘进行加密 从 &os; 6.0 开始提供了一个新的密码学 GEOM class — geli。 它目前由 &a.pjd; 开发。 Geli 工具与 gbde 不同; 它提供了一些不同的功能, 并采用了不同的方式来进行密码学运算。 &man.geli.8; 最重要的功能包括: 使用了 &man.crypto.9; 框架 — 如果系统中有加解密硬件加速设备, 则 geli 会自动加以利用。 支持多种加密算法 (目前支持 AES、 Blowfish, 以及 3DES)。 允许对根分区进行加密。 在系统启动时, 将要求输入用于加密根分区的口令。 允许使用两个不同的密钥 (例如, 一个 个人密钥 和一个 公司密钥)。 geli 速度很快 — 它只进行简单的扇区到扇区的加密。 允许备份和恢复主密钥。 当用户必须销毁其密钥时, 仍然可以通过从备份中恢复密钥来存取数据。 允许使用随机的一次性密钥来挂接磁盘 — 这对于交换区和临时文件系统非常有用。 更多 geli 功能介绍可以在 &man.geli.8; 联机手册中找到。 下面的步骤介绍了如何启用 &os; 内核中的 geli 支持, 并解释了如何创建新和使用 geli 加密 provider。 要使用 geli, 您必须运行 &os; 6.0-RELEASE 或更新版本。 由于需要修改内核, 因此您还需要拥有超级用户权限。 在内核中加入 <command>geli</command> 支持 在内核配置文件中加入下面两行: options GEOM_ELI device crypto 按照 介绍的步骤重新编译并安装内核。 另外, geli 也可以在系统引导时加载。 这是通过在 /boot/loader.conf 中增加下面的配置来实现的: geom_eli_load="YES" &man.geli.8; 现在应该已经为内核所支持了。 生成主密钥 下面的例子讲描述如何生成密钥文件, 它将作为主密钥 (Master Key) 的一部分, 用于挂接到 /private 的加密 provider。 这个密钥文件将提供一些随机数据来加密主密钥。 同时, 主密钥也会使用一个口令字来保护。 Provider 的扇区尺寸为 4kB。 此外, 这里的讨论将介绍如何挂载 geli provider, 在其上创建文件系统, 如何挂接并在其上工作, 最后将其卸下。 建议您使用较大的扇区尺寸 (例如 4kB), 以获得更好的性能。 主密钥将由口令字保护, 而密钥文件的数据来源则将是 /dev/random。 我们称之为 provider 的 /dev/da2.eli 的扇区尺寸将是 4kB。 &prompt.root; dd if=/dev/random of=/root/da2.key bs=64 count=1 &prompt.root; geli init -s 4096 -K /root/da2.key /dev/da2 Enter new passphrase: Reenter new passphrase: 同时使用口令字和密钥文件并不是必须的; 您也可以只使用其中的一种来加密主密钥。 如果密钥文件写作 -, 则表示使用标准输入。 下面是关于如何使用多个密钥文件的例子: &prompt.root; cat keyfile1 keyfile2 keyfile3 | geli init -K - /dev/da2 将 provider 与所生成的密钥关联 &prompt.root; geli attach -k /root/da2.key /dev/da2 Enter passphrase: 新的明文设备将被命名为 /dev/da2.eli &prompt.root; ls /dev/da2* /dev/da2 /dev/da2.eli 创建新的文件系统 &prompt.root; dd if=/dev/random of=/dev/da2.eli bs=1m &prompt.root; newfs /dev/da2.eli &prompt.root; mount /dev/da2.eli /private 现在加密的文件系统应该已经可以被 &man.df.1; 看到, 并处于可用状态了: &prompt.root; df -H Filesystem Size Used Avail Capacity Mounted on /dev/ad0s1a 248M 89M 139M 38% / /devfs 1.0K 1.0K 0B 100% /dev /dev/ad0s1f 7.7G 2.3G 4.9G 32% /usr /dev/ad0s1d 989M 1.5M 909M 0% /tmp /dev/ad0s1e 3.9G 1.3G 2.3G 35% /var /dev/da2.eli 150G 4.1K 138G 0% /private 卸下卷并断开 provider 一旦在加密分区上的工作完成, 并且不再需要 /private 分区, 就应考虑将其卸下并将 geli 加密分区从内核上断开。 &prompt.root; umount /private &prompt.root; geli detach da2.eli 关于如何使用 &man.geli.8; 的更多信息, 可以在其联机手册中找到。 使用 <filename>geli</filename> <filename>rc.d</filename> 脚本 geli 提供了一个 rc.d 脚本, 它可以用于简化 geli 的使用。 通过 &man.rc.conf.5; 配置 geli 的方法如下: geli_devices="da2" geli_da2_flags="-p -k /root/da2.key" 这将把 /dev/da2 配置为一个 geli provider, 其主密钥文件位于 /root/da2.key, 而 geli 在连接 provider 时将不使用口令字 (注意只有在 geli init 阶段使用了 才可以这样做)。 系统将在关闭之前将 geli provider 断开。 关于如何配置 rc.d 的详细信息可以在使用手册的 rc.d 一节中找到。
Christian Brüffer 原作 对交换区进行加密 swap (交换区) encrypting (加密) 从 &os; 5.3-RELEASE 开始, &os; 提供了易于配置的交换区加密机制。 随所用的 &os; 版本, 可用的配置选项会有所不同, 而配置方法也会有一些差异。 从 &os; 6.0-RELEASE 开始, 已经可以使用 &man.gbde.8; 和 &man.geli.8; 两种加密系统来进行交换区的加密操作了。 在更早的版本中, 则只提供了 &man.gbde.8;。 前面所说的这两种加密系统, 都用到了 encswap 这个 rc.d 脚本。 在前面的小节 如何加密磁盘分区 中, 已经就不同的加密系统之间的区别进行了简单的讨论。 为什么需要对交换区进行加密? 与加密磁盘分区类似, 加密交换区有助于保护敏感信息。 为此, 我们不妨考虑一个需要处理敏感信息的程序, 例如, 它需要处理口令。 如果这些口令一直保持在物理内存中, 则一切相安无事。 然而, 如果操作系统开始将内存页换出到交换区, 以便为其他应用程序腾出内存时, 这些口令就可能以未加密的形式写到磁盘上, 并为攻击者所轻易获得。 加密交换区能够有效地解决这类问题。 准备 在本节余下的部分中, 我们约定使用 ad0s1b 作为交换区。 到目前为止, 交换区仍是未加密的。 很可能其中已经存有明文形式的口令或其他敏感数据。 要纠正这一问题, 首先应使用随机数来覆盖交换分区的数据: &prompt.root; dd if=/dev/random of=/dev/ad0s1b bs=1m 使用 &man.gbde.8; 来加密交换区 如果使用 &os; 6.0-RELEASE 或更新的版本, 则 /etc/fstab 中与交换区对应的行中, 设备名应追加 .bde 后缀: # Device Mountpoint FStype Options Dump Pass# /dev/ad0s1b.bde none swap sw 0 0 对于 &os; 6.0-RELEASE 之前的版本, 还需要在 /etc/rc.conf 中加入: gbde_swap_enable="YES" 使用 &man.geli.8; 来加密分区 另一种方法是使用 &man.geli.8; 来达到加密交换区的目的, 其过程与使用 &man.gbde.8; 大体相似。 此时, 在 /etc/fstab 中交换区对应的行中, 设备名应追加 .eli 后缀: # Device Mountpoint FStype Options Dump Pass# /dev/ad0s1b.eli none swap sw 0 0 &man.geli.8; 默认情况下使用密钥长度为 256-位的 AES 加密算法。 当然, 这些默认值是可以通过 /etc/rc.conf 中的 geli_swap_flags 选项来修改的。 下面的配置表示让 rc.d 脚本 encswap 创建一个 &man.geli.8; 交换区, 在其上使用密钥长度为 128-位 的 Blowfish 加密算法, 4 kilobytes 的扇区尺寸, 并采用 最后一次关闭时卸下 的策略: geli_swap_flags="-e blowfish -l 128 -s 4096 -d" For systems prior to &os; 6.2-RELEASE, use the following line: geli_swap_flags="-a blowfish -l 128 -s 4096 -d" 请参见 &man.geli.8; 联机手册中关于 onetime 命令的说明, 以了解其他可用的选项。 验证所作的配置能够发挥作用 在重启系统之后, 就可以使用 swapinfo 命令来验证加密交换区是否已经在正常运转了。 如果使用了 &man.gbde.8;, 则: &prompt.user; swapinfo Device 1K-blocks Used Avail Capacity /dev/ad0s1b.bde 542720 0 542720 0% 如果使用了 &man.geli.8;, 则: &prompt.user; swapinfo Device 1K-blocks Used Avail Capacity /dev/ad0s1b.eli 542720 0 542720 0%
diff --git a/zh_CN.GB2312/books/handbook/firewalls/chapter.sgml b/zh_CN.GB2312/books/handbook/firewalls/chapter.sgml index 831ad01872..57db8b190d 100644 --- a/zh_CN.GB2312/books/handbook/firewalls/chapter.sgml +++ b/zh_CN.GB2312/books/handbook/firewalls/chapter.sgml @@ -1,2986 +1,2990 @@ Joseph J. Barbish Contributed by Brad Davis Converted to SGML and updated by 防火墙 防火墙 安全 防火墙 入门 防火墙的存在, 使得过滤出入系统的数据流成为可能。 防火墙可以使用一组或多组 规则 (rules), 来检查出入您的网络连接的数据包, 并决定允许或阻止它们通过。 这些规则通常可以检查数据包的某个或某些特征, 这些特征包括, 但不必限于协议类型、 来源或目的主机地址, 以及来源或目的端口。 防火墙可以大幅度地改善主机或网络的安全。 它可以用来完成下面的任务: 保护和隔离应用程序、 服务程序, 以及您内部网络上的机器, 不受那些来自公共的 Internet 网络上您所不希望的数据流量的干扰。 限制或禁止从内部网访问公共的 Internet 上的服务。 支持网络地址转换 (NAT), 它使得您的内部网络能够使用私有的 IP 地址, 并分享一条通往公共的 Internet 的连接 (使用一个 IP 地址, 或者一组公网地址)。 读完这章, 您将了解: 如何正确地定义包过滤规则。 &os; 中内建的集中防火墙之间的差异。 如何使用和配置 OpenBSD 的 PF 防火墙。 如何使用和配置 IPFILTER 如何使用和配置 IPFW 阅读这章之前, 您需要: 理解基本的 &os; 和 Internet 概念。 防火墙的概念 防火墙/primary> 规则集 建立防火墙规则集的基本方法有两种: 包容式的排斥式的。 排斥式的防火墙, 允许除了禁止的那些数据之外的所有网络流量通过。 包容式的防火墙正好相反。 后者只允许符合规则的流量通过, 而其他所有的流量都被阻止。 包容式防火墙一般说来要比排斥式防火墙安全, 因为他们显著地降低了由于允许不希望的网络流量通过所带来的风险。 如果使用了 带状态功能的防火墙 (stateful firewall), 则安全机制可以进一步地细化。 带状态功能的防火墙能够记录通过防火墙的连接, 进而只允许与现有连接匹配的连接, 或创建新的连接。 带状态功能的防火墙的缺点, 则是在很短时间内有大量的连接请求时, 它们可能会受到拒绝服务 (DoS) 攻击。 绝大多数防火墙都提供了同时启用两种防火墙的能力, 以便为站点提供更好的保护。 防火墙软件包 &os; 的基本系统内建了三种不同的防火墙软件包。 它们是 IPFILTER (也被称作 IPF)、 IPFIREWALL (也被称作 IPFW), 以及 OpenBSD 的 PacketFilter (也被称为 PF)。 &os; 也提供了两个内建的、 用于流量整形 (基本上是控制带宽占用) 的软件包: &man.altq.4; 和 &man.dummynet.4;。 Dummynet 在过去一直和 IPFW 紧密集成, 而 ALTQ 则需要配合 - IPF/PF 使用。 IPF、 + PF 使用。 IPFILTER + 对于流量整形可以使用 IPFILTER 的 NAT + 和过滤功能以及 IPFW 的 &man.dummynet.4; 配合, + 或者 使用 PF 跟 + ALTQ 的组合。 IPFW, 以及 PF 都是用规则来控制是否允许数据包出入您的系统, 虽然它们采取了不同的实现方法和规则语法。 &os; 包含多个内建的防火墙软件包的原因在于, 不同的人会有不同的需求和偏好。 任何一个防火墙软件包都很难说是最好的。 作者倾向于使用 IPFILTER, 因为它提供的状态式规则, 在 NAT 的环境中要简单许多, 而且它内建了 ftp 代理, 这简化了使用外部 FTP 服务时所需的配置。 由于所有的防火墙都基于检查所选定的包控制字段来实现功能, 撰写防火墙规则集时, 就必须了解 TCP/IP 是如何工作的, 以及包的控制字段在正常会话交互中的作用。 您可以在这个网站找到一份很好的解释文档: . OpenBSD Packet Filter (PF) 和 <acronym>ALTQ</acronym> 防火墙 PF 2003 年 7 月, OpenBSD 的防火墙, 也就是常说的 PF 被成功地移植到了 &os; 上, 并可以通过 &os; Ports Collection 来安装了; 第一个将 PF 集成到基本系统中的版本是 2004 年 11 月发行的 &os; 5.3。 PF 是一个完整的提供了大量功能的防火墙软件, 并提供了可选的 ALTQ (交错队列, Alternate Queuing) 功能。 ALTQ 提供了服务品质 (QoS) 带宽整形功能, 这个功能能够以基于过滤规则的方式来保障不同服务的带宽。 OpenBSD Project 在维护 PF 用户指南方面已经做了非常卓越的工作, 因此我们不打算在这本使用手册中进行更进一步的阐述, 以避免不必要的重复劳动。 更多的详细信息, 可以在 &os; 版本的 PF 网站上找到: 启用 PF PF 作为 &os; 5.3 和更高版本基本系统安装的一部分, 作为一个可以动态加载的模块出现。 如果在 rc.conf 中配置了 pf_enable="YES" 则系统会自动加载对应的内核模块。 可加载内核模块在构建时启用了 &man.pflog.4;。 这个模块假定 options INETdevice bpf 是存在的。 除非编译时指定了 NOINET6 (对 &os; 6.0-RELEASE 之前的版本) 或 NO_INET6 (对更新一些的版本) (例如在 &man.make.conf.5; 中定义) 它还需要 options INET6 一旦加载了这个内核模块, 或者将 PF 支持静态联编进内核, 就可以随时通过 pfctl 来启用或禁用 pf 了。 下面的例子展示了如何启用 pf &prompt.root; pfctl -e pfctl 命令提供了一种与 pf 防火墙交互的方法。 要了解进一步的信息, 参考 &man.pfctl.8; 联机手册是一个不错的办法。 内核选项 内核选项 device pf 内核选项 device pflog 内核选项 device pfsync 将下面这些选项加入到 &os; 内核的编译配置文件中并不是启用 PF 的强制性要求。 这里列出它们主要是为了介绍一些背景信息。 将 PF 编译到内核中之后, 就不再需要使用可加载内核模块了。 如何在内核编译配置中加入对于 PF 选项的例子可以在内核源代码中的 /usr/src/sys/conf/NOTES 这个文件中找到。 这里列举如下: device pf device pflog device pfsync device pf 用于启用 Packet Filter 防火墙的支持。 device pflog 启用可选的 &man.pflog.4; 伪网络设备, 用以通过 &man.bpf.4; 描述符来记录流量。 &man.pflogd.8; 服务可以用来存储信息, 并把它们以日志形式记录到磁盘上。 device pfsync 启用可选的 &man.pfsync.4; 伪网络设备, 用以监视 状态变更。 由于这不是那个可加载内核模块的一部分, 因此如果需要使用它, 就必须自行编译定制的内核了。 这些设置只有在您使用它们构建和安装新内核之后才会生效。 可用的 rc.conf 选项 您需要在 /etc/rc.conf 中添加如下配置, 以便在启动时激活 PF: pf_enable="YES" # 启用 PF (如果需要的话, 自动加载内核模块) pf_rules="/etc/pf.conf" # pf 使用的规则定义文件 pf_flags="" # 启动时传递给 pfctl 的其他选项 pflog_enable="YES" # 启动 pflogd(8) pflog_logfile="/var/log/pflog" # pflogd 用于记录日志的文件名 pflog_flags="" # 启动时传递给 pflogd 的其他选项 如果您的防火墙后面有一个 LAN, 而且需要通过它来转发 LAN 上的包, 或进行 NAT, 还必须同时启用下述选项: gateway_enable="YES" # 启用为 LAN 网关 启用 <acronym>ALTQ</acronym> ALTQ 只有在作为编译选项加入到 &os; 内核时, 才能使用。 ALTQ 目前还不是所有的可用网卡驱动都能够支持的。 请参见 &man.altq.4; 联机手册了解您正使用的 &os; 版本中的驱动支持情况。 下面这些选项将启用 ALTQ 以及一些附加的功能。 options ALTQ options ALTQ_CBQ # 基于分类的排列 (CBQ) options ALTQ_RED # 随机先期检测 (RED) options ALTQ_RIO # 对进入和发出的包进行 RED options ALTQ_HFSC # 带等级的包调度器 (HFSC) options ALTQ_PRIQ # 按优先级的排列 (PRIQ) options ALTQ_NOPCC # 在联编 SMP 内核时必须使用,禁止读时钟 options ALTQ 将启用 ALTQ 框架的支持。 options ALTQ_CBQ 用于启用基于分类的队列 (CBQ) 支持。 CBQ 允许您将连接分成不同的类别, 或者说, 队列, 以便在规则中为它们指定不同的优先级。 options ALTQ_RED 将启用随机预检测 (RED)。 RED 是一种用于防止网络拥塞的技术。 RED 度量队列的长度, 并将其与队列的最大和最小长度阈值进行比较。 如果队列过长, 则新的包将被丢弃。 如名所示, RED 从不同的连接中随机地丢弃数据包。 options ALTQ_RIO 将启用出入的随机预检测。 options ALTQ_HFSC 启用层次式公平服务平滑包调度器。 要了解关于 HFSC 进一步的信息, 请参见 options ALTQ_PRIQ 启用优先队列 (PRIQ)。 PRIQ 首先允许高优先级队列中的包通过。 options ALTQ_NOPCC 启用 ALTQSMP 支持。 如果是 SMP 系统, 则必须使用它。 建立过滤规则 Packet Filter 会从 &man.pf.conf.5; 文件中读取配置规则, 并根据那里的规则修改、 丢弃或让数据包通过。 默认安装的 &os; 已经提供了一个默认的、 包含一些有用例子和注释的 /etc/pf.conf 尽管 &os; 提供了自己的 /etc/pf.conf, 但这个文件和 OpenBSD 中的语法是一样的。 OpenBSD 开发团队提供了一个非常好的配置 pf 资源, 它可以在 找到。 在浏览 pf 用户手册时, 请时刻注意, 在 &os; 中所包含的 pf 的版本和 OpenBSD 中是不一样的。 在 &os; 5.X 中 pf 相当于 OpenBSD 3.5 中的版本, 而 &os; 6.X 中则相当于 OpenBSD 3.7。 关于 pf 的配置和使用问题, 可以在 &a.pf; 提出。 当然, 在提出问题之前, 别忘了查阅邮件列表的存档。 IPFILTER (IPF) 防火墙 防火墙 IPFILTER 这一节的内容正在撰写中。 其内容可能不总是十分准确。 IPFILTER 的作者是 Darren Reed。 IPFILTER 是独立于操作系统的: 它是一个开放源代码的应用, 并且已经被移植到了 &os;、 NetBSD、 OpenBSD、 SunOS、 HP/UX, 以及 Solaris 操作系统上。 IPFILTER 的支持和维护都相当活跃, 并且有规律地发布更新版本。 IPFILTER 提供了内核模式的防火墙和 NAT 机制, 这些机制可以通过用户模式运行的接口程序进行监视和控制。 防火墙规则可以使用 &man.ipf.8; 工具来动态地设置和删除。 NAT 规则可以通过 &man.ipnat.1; 工具来维护。 &man.ipfstat.8; 工具则可以用来显示 IPFILTER 内核部分的统计数据。 最后, 使用 &man.ipmon.8; 程序可以把 IPFILTER 的动作记录到系统日志文件中。 IPF 最初是使用一组 以最后匹配的规则为准 的策略来实现的, 这种方式只能支持无状态的规则。 随着时代的进步, IPF 被逐渐增强, 并加入了 quick 选项, 以及支持状态的 keep state 选项, 这使得规则处理逻辑变得更富有现代气息。 IPF 的官方文档介绍了传统的规则编写方法和文件处理逻辑。 新增的功能只是作为一些附加的选项出现, 如果能完全理解这些功能, 则对于建立更安全的防火墙就很有好处。 这一节中主要是针对 quick 选项, 以及支持状态的 keep state 选项的介绍。 这是包容式防火墙规则集最基本的编写要素。 包容式防火墙只允许与规则匹配的包通过。 这样, 您就既能够控制来自防火墙后面的机器请求 Internet 公网上的那些服务, 同时也可以控制来自 Internet 的请求能够访问内部网上的哪些服务。 所有其它的访问请求都会被阻止, 并记录下来。 包容式防火墙一般而言要远比排斥式的要安全, 而且也只需要定义允许哪些访问通过。 要获得关于传统规则处理方式的详细信息, 请参考: 以及 IPF FAQ 可以在 找到。 除此之外, 您还可以在 找到开放源代码的 IPFilter 的邮件列表存档, 并进行搜索。 启用 IPF IPFILTER 启用 IPF 作为 &os; 基本安装的一部分, 以一个独立的内核模块的形式提供。 如果在 rc.conf 中配置了 ipfilter_enable="YES", 系统就会自动地动态加载 IPF 内核模块。 这个内核模块在创建时启用了日志支持, 并加入了 default pass all 选项。 如果只是需要把默认的规则设置为 block all 的话, 并不需要把 IPF 编译到内核中。 可以简单地通过把这条规则加入自己的规则集来达到同样的目的。 内核选项 内核选项 IPFILTER 内核选项 IPFILTER_LOG 内核选项 IPFILTER_DEFAULT_BLOCK IPFILTER 内核选项 下面这些 &os; 内核编译选项并不是启用 IPF 所必需的。 这里只是作为背景知识来加以阐述。 如果将 IPF 编入了内核, 则对应的内核模块将不被使用。 关于 IPF 选项语句的内核编译配置的例子, 可以在内核源代码中的 /usr/src/sys/conf/NOTES 找到。 此处列举如下: options IPFILTER options IPFILTER_LOG options IPFILTER_DEFAULT_BLOCK options IPFILTER 用于启用 IPFILTER 防火墙的支持。 options IPFILTER_LOG 用于启用 IPF 的日志支持, 所有匹配了包含 log 的规则的包, 都会被记录到 ipl 这个包记录伪—设备中。 options IPFILTER_DEFAULT_BLOCK 将改变防火墙的默认动作, 进而, 所有不匹配防火墙的 pass 规则的包都会被阻止。 这些选项只有在您重新编译并安装内核之后才会生效。 可用的 rc.conf 选项 要在启动时激活 IPF, 您需要在 /etc/rc.conf 中增加下面的设置: ipfilter_enable="YES" # 启动 ipf 防火墙 ipfilter_rules="/etc/ipf.rules" # 将被加载的规则定义, 这是一个文本文件 ipmon_enable="YES" # 启动 IP 监视日志 ipmon_flags="-Ds" # D = 作为服务程序启动 # s = 使用 syslog 记录 # v = 记录 tcp 窗口大小、 ack 和顺序号(seq) # n = 将 IP 和端口映射为名字 如果您的 LAN 在防火墙后面, 并且使用了保留的私有 IP 地址范围, 那就需要增加下面的一些选项来启用 NAT 功能: gateway_enable="YES" # 启用作为 LAN 网关的功能 ipnat_enable="YES" # 启动 ipnat 功能 ipnat_rules="/etc/ipnat.rules" # 用于 ipnat 的规则定义文件 IPF ipf ipf 命令可以用来加载您自己的规则文件。 一般情况下, 您可以建立一个包括您自定义的规则的文件, 并使用这个命令来替换掉正在运行的防火墙中的内部规则: &prompt.root; ipf -Fa -f /etc/ipf.rules 表示清除所有的内部规则表。 用于指定将要被读取的规则定义文件。 这个功能使得您能够修改自定义的规则文件, 通过运行上面的 IPF 命令, 可以将正在运行的防火墙刷新为使用全新的规则集, 而不需要重新启动系统。 这对于测试新的规则来说就很方便, 因为您可以任意执行上面的命令。 请参考 &man.ipf.8; 联机手册以了解这个命令提供的其它选项。 &man.ipf.8; 命令假定规则文件是一个标准的文本文件。 它不能处理使用符号代换的脚本。 也确实有办法利用脚本的非常强大的符号替换能力来构建 IPF 规则。 要了解进一步的细节, 请参考 IPFSTAT ipfstat IPFILTER 统计 默认情况下, &man.ipfstat.8; 会获取并显示所有的累积统计, 这些统计是防火墙启动以来用户定义的规则匹配的出入流量, 您可以通过使用 ipf -Z 命令来将这些计数器清零。 请参见 &man.ipfstat.8; 联机手册以了解进一步的细节。 默认的 &man.ipfstat.8; 命令输出类似于下面的样子: input packets: blocked 99286 passed 1255609 nomatch 14686 counted 0 output packets: blocked 4200 passed 1284345 nomatch 14687 counted 0 input packets logged: blocked 99286 passed 0 output packets logged: blocked 0 passed 0 packets logged: input 0 output 0 log failures: input 3898 output 0 fragment state(in): kept 0 lost 0 fragment state(out): kept 0 lost 0 packet state(in): kept 169364 lost 0 packet state(out): kept 431395 lost 0 ICMP replies: 0 TCP RSTs sent: 0 Result cache hits(in): 1215208 (out): 1098963 IN Pullups succeeded: 2 failed: 0 OUT Pullups succeeded: 0 failed: 0 Fastroute successes: 0 failures: 0 TCP cksum fails(in): 0 (out): 0 Packet log flags set: (0) 如果使用了 (进入流量) 或者 (输出流量), 它就只获取并显示内核中所安装的对应过滤器规则的统计数据。 ipfstat -in 以规则号的形式显示进入的内部规则表。 ipfstat -on 以规则号的形式显示流出的内部规则表。 输出和下面的类似: @1 pass out on xl0 from any to any @2 block out on dc0 from any to any @3 pass out quick on dc0 proto tcp/udp from any to any keep state ipfstat -ih 显示内部规则表中的进入流量, 每一个匹配规则前面会同时显示匹配的次数。 ipfstat -oh 显示内部规则表中的流出流量, 每一个匹配规则前面会同时显示匹配的次数。 输出和下面的类似: 2451423 pass out on xl0 from any to any 354727 block out on dc0 from any to any 430918 pass out quick on dc0 proto tcp/udp from any to any keep state ipfstat 命令的一个重要的功能可以通过指定 参数来使用, 它会以类似 &man.top.1; 的显示 &os; 正运行的进程表的方式来显示统计数据。 当您的防火墙正在受到攻击的时候, 这个功能让您得以识别、 试验, 并查看攻击的数据包。 这个选项提还提供了实时选择希望监视的目的或源 IP、 端口或协议的能力。 请参见 &man.ipfstat.8; 联机手册以了解详细信息。 IPMON ipmon IPFILTER 记录日志 为了使 ipmon 能够正确工作, 必须打开 IPFILTER_LOG 这个内核选项。 这个命令提供了两种不同的使用模式。 内建模式是默认的模式, 如果您不指定 参数, 就会采用这种模式。 服务模式是持续地通过系统日志来记录的工作模式, 这样, 您就可以通过查看日志来了解过去曾经发生过的事情。 这种模式是 &os; 和 IPFILTER 配合工作的模式。 由于在 &os; 中提供了一个内建的系统日志自动轮转功能, 因此, 使用 syslogd 比默认的将日志信息记录到一个普通文件要好。 在默认的 rc.conf 文件中, 您会看到一个 ipmon_flags 语句, 指定了 标志: ipmon_flags="-Ds" # D = 作为服务程序启动 # s = 使用 syslog 记录 # v = 记录 tcp 窗口大小、 ack 和顺序号(seq) # n = 将 IP 和端口映射为名字 记录日志的好处是很明显的。 它提供了在事后重新审查相关信息, 例如哪些包被丢弃, 以及这些包的来源地址等等。 这将为查找攻击者提供非常有用的第一手资料。 即使启用了日志机制, IPF 仍然不会对其规则进行任何日志记录工作。 防火墙管理员可以决定规则集中的哪些应记录日志, 并在这些规则上加入 log 关键字。 一般来说, 只应记录拒绝性的规则。 作为惯例, 通常会有一条默认的、拒绝所有网络流量的规则, 并指定 log 关键字, 作为您的规则集的最后一条。 这样, 您就能够看到所有没有匹配任何规则的数据包。 IPMON 的日志 Syslogd 使用特殊的方法对日志数据进行分类。 它使用称为 facilitylevel 的组。 以 模式运行的 IPMON 采用 security 作为 facility 名。 所有由 IPMON 记录的数据都会进入 security。 如果需要, 可以用下列 levels 来进一步区分数据: LOG_INFO - 使用 "log" 关键字指定的通过或阻止动作 LOG_NOTICE - 同时记录通过的那些数据包 LOG_WARNING - 同时记录阻止的数据包 LOG_ERR - 进一步记录含不完整的包头的数据包 要设置 IPFILTER 来将所有的数据记录到 /var/log/ipfilter.log, 需要首先建立这个文件。 下面的命令可以完成这个工作: &prompt.root; touch /var/log/ipfilter.log syslog 功能可以通过在 /etc/syslog.conf 文件中的语句来定义。 syslog.conf 提供了相当多的用以控制 syslog 如何处理类似 IPF 这样的用用程序所产生的系统消息的方法。 您需要将下列语句加到 /etc/syslog.conf security.* /var/log/ipfilter.log 这里的 security.* 表示把所有的相关日志信息写到指定的文件中。 要让 /etc/syslog.conf 中的修改立即生效, 您可以重新启动计算机, 或者通过执行 /etc/rc.d/syslogd reload 来让它重新读取 /etc/syslog.conf 不要忘了修改 /etc/newsyslog.conf 来让您刚创建的日志进行轮转。 记录消息的格式 ipmon 生成的消息由空格分隔的数据字段组成。 所有的消息都包含的字段是: 接到数据包的日期。 接到数据包的时间。 其格式为 HH:MM:SS.F, 分别是小时、 分钟、 秒, 以及分秒 (这个数字可能有许多位)。 处理数据包的网络接口名字, 例如 dc0 组和规则的编号, 例如 @0:17 可以通过 ipfstat -in 来查看这些信息。 动作: p 表示通过, b 表示阻止, S 表示包头不全, n 表示没有匹配任何规则, L 表示 log 规则。 显示这些标志的顺序是: S, p, b, n, L。 大写的 P 或 B 表示记录包的原因是某个全局的日志配置, 而不是某个特定的规则。 地址。 这实际上包括三部分: 源地址和端口 (以逗号分开), 一个 -> 符号, 以及目的地址和端口。 209.53.17.22,80 -> 198.73.220.17,1722. PR, 后跟协议名称或编号, 例如, PR tcp。 len, 后跟包头的长度, 以及包的总长度, 例如 len 20 40。 对于 TCP 包, 则还会包括一个附加的字段, 由一个连字号开始, 之后是表示所设置的标志的一个字母。 请参见 &man.ipmon.8; 联机手册, 以了解这些字母所对应的标志。 对于 ICMP 包, 则在最后会有两个字段。 前一个总是 ICMP, 而后一个则是 ICMP 消息和子消息的类型, 中间以斜线分靠, 例如 ICMP 3/3 表示端口不可达消息。 构建采用符号替换的规则脚本 一些有经验的 IPF 会创建包含规则的文件, 并把它编写成能够与符号替换脚本兼容的方式。 这样做最大的好处是, 它能够让您只修改符号名字所代表的值, 而在脚本执行时直接替换掉所有的名符。 作为脚本, 您可以使用符号替换来把那些经常使用的值直接用于多个规则。 下面我们将给出一个例子。 这个脚本所使用的语法与 sh、 csh, 以及 tcsh 脚本。 符号替换的前缀字段是美元符号: $ 符号字段不使用 $ 前缀。 希望替换符号字段的值, 必须使用双引号 (") 括起来。 您的规则文件的开头类似这样: ############# IPF 规则脚本的开头 ######################## oif="dc0" # 外网接口的名字 odns="192.0.2.11" # ISP 的 DNS 服务器 IP 地址 myip="192.0.2.7" # 来自 ISP 的静态 IP 地址 ks="keep state" fks="flags S keep state" # 可以使用这个脚本来建立 /etc/ipf.rules 文件, # 也可以 "直接地" 运行它。 # # 请删除两个注释号之一。 # # 1) 保留下面一行, 则创建 /etc/ipf.rules: #cat > /etc/ipf.rules << EOF # # 2) 保留下面一行, 则 "直接地" 运行脚本: /sbin/ipf -Fa -f - << EOF # 允许发出到我的 ISP 的域名服务器的访问 pass out quick on $oif proto tcp from any to $odns port = 53 $fks pass out quick on $oif proto udp from any to $odns port = 53 $ks # 允许发出未加密的 www 访问请求 pass out quick on $oif proto tcp from $myip to any port = 80 $fks # 允许发出使用 TLS SSL 加密的 https www 访问请求 pass out quick on $oif proto tcp from $myip to any port = 443 $fks EOF ################## IPF 规则脚本的结束 ######################## 这就是所需的全部内容。 这个规则本身并不重要, 它们主要是用于体现如何使用符号代换字段, 以及如何完成值的替换。 如果上面的例子的名字是 /etc/ipf.rules.script, 就可以通过输入下面的命令来重新加载规则: &prompt.root; sh /etc/ipf.rules.script 在规则文件中嵌入符号有一个问题: IPF 无法识别符号替换, 因此它不能直接地读取这样的脚本。 这个脚本可以使用下面两种方法之一来使用: 去掉 cat 之前的注释, 并注释掉 /sbin/ipf 开头的那一行。 像其他配置一样, 将 ipfilter_enable="YES" 放到 /etc/rc.conf 文件中, 并在此后立刻执行脚本, 以创建或更新 /etc/ipf.rules 通过把 ipfilter_enable="NO" (这是默认值) 加到 /etc/rc.conf 中, 来禁止系统启动脚本开启 IPFILTER。 /usr/local/etc/rc.d/ 启动目录中增加一个类似下面的脚本。 应该给它起一个显而易见的名字, 例如 ipf.loadrules.sh。 请注意, .sh 扩展名是必需的。 #!/bin/sh sh /etc/ipf.rules.script 脚本文件必须设置为属于 root, 并且属主可读、 可写、 可执行。 &prompt.root; chmod 700 /usr/local/etc/rc.d/ipf.loadrules.sh 这样, 在系统启动时, 就会自动加载您的 IPF 规则了。 IPF 规则集 规则集是指一组编写好的依据包的值决策允许通过或阻止 ipf 规则。 包的双向交换组成了一个会话交互。 防火墙规则集对同一个包会进行两次处理, 第一次是它从公网的 Internet 主机到达的时候, 第二次是它离开并返回初始的 Internet 公网主机的时候。 每一个 TCP/IP 服务 (例如 telnet, www, 邮件等等) 是由协议预先定义的源或目的 IP 地址, 以及源或目的端口。 这是最基本的一些可以为防火墙规则所利用的, 判别是否允许服务通过的标准。 IPFILTER 规则处理顺序 IPF 最初被写成使用一组称作 以最后匹配的规则为准 的处理逻辑, 且只能处理无状态的规则。 随着时代的发展, IPF 进行了改进, 并提供了 quick 选项, 以及一个有状态的 keep state 选项。 后者使处理逻辑迅速地跟上了时代的步伐。 这一节中提供的一些指导, 是基于使用包含 quick 选项和有状态的 keep state 选项来进行阐述的。 这些是编写包容式防火墙规则集的基本要素。 包容式防火墙只允许与规则匹配的服务通过。 这样, 您就既能够控制来自防火墙后面的机器请求 Internet 公网上的那些服务, 同时也可以控制来自 Internet 的请求能够访问内部网上的哪些服务。 所有其它的访问请求都会被阻止, 并记录下来。 包容式防火墙一般而言要远比排斥式的要安全, 而且也只需要定义允许哪些访问通过。 当对防火墙规则进行操作时, 应该 谨慎行事。 某些配置可能会 将您反锁在 服务器外面。 安全起见, 您可以考虑在第一次进行防火墙配置时在本地控制台上, 而不是远程, 例如通过 ssh 来进行。 规则语法 IPFILTER 规则语法 这里给出的规则语法已经简化到只处理那些新式的带状态规则, 并且都是 第一个匹配的规则获胜 逻辑的。 要了解完整的传统规则语法描述, 请参见 &man.ipf.8; 联机手册。 # 字符开头的内容会被认为是注释。 这些注释可以出现在一行规则的末尾, 或者独占一行。 空行会被忽略。 规则由关键字组成。 这些关键字必须以一定的顺序, 从左到右出现在一行上。 接下来的文字中关键字将使用粗体表示。 某些关键字可能提供了子选项, 这些子选项本身可能也是关键字, 而且可能会提供更多的子选项。 下面的文字中, 每种语法都使用粗体的小节标题呈现, 并介绍了其上下文。 ACTION IN-OUT OPTIONS SELECTION STATEFUL PROTO SRC_ADDR,DST_ADDR OBJECT PORT_NUM TCP_FLAG STATEFUL ACTION = block | pass IN-OUT = in | out OPTIONS = log | quick | on 网络接口的名字 SELECTION = proto 协议名称 | 源/目的 IP | port = 端口号 | flags 标志值 PROTO = tcp/udp | udp | tcp | icmp SRC_ADD,DST_ADDR = all | from 对象 to 对象 OBJECT = IP地址 | any PORT_NUM = port 端口号 TCP_FLAG = S STATEFUL = keep state ACTION (动作) 动作对表示匹配规则的包应采取什么动作。 每一个规则 必须 包含一个动作。 可以使用下面两种动作之一: block 表示如果规则与包匹配, 则丢弃包。 pass 表示如果规则与包匹配, 则允许包通过防火墙。 IN-OUT 每个过滤器规则都必须明确地指定是流入还是流出的规则。 下一个关键字必须要么是 in, 要么是 out, 否则将无法通过语法检查。 in 表示规则应被应用于刚刚从 Internet 公网上收到的数据包。 out 表示规则应被应用于即将发出到 Internet 的数据包。 OPTIONS 这些选项必须按下面指定的顺序出现。 log 表示包头应被写入到 ipl 日志 (如前面 LOGGING 小节所介绍的那样), 如果它与规则匹配的话。 quick 表示如果给出的参数与包匹配, 则以这个规则为准, 这使得能够 "短路" 掉后面的规则。 这个选项对于使用新式的处理逻辑是必需的。 on 表示将网络接口的名称作为筛选参数的一部分。 接口的名字会在 &man.ifconfig.8; 的输出中显示。 使用这个选项, 则规则只会应用到某一个网络接口上的出入数据包上。 要配置新式的处理逻辑, 必须使用这个选项。 当记录包时, 包的头会被写入到 IPL 包日志伪设备中。 紧跟 log 关键字, 可以使用下面几个修饰符 (按照下列顺序): body 表示应同时记录包的前 128 字节的内容。 first 如果 log 关键字和 keep state 选项同时使用, 则这个选项只在第一个包上触发, 这样就不用记录每一个 keep state 包信息了。 SELECTION 这一节所介绍的关键字可以用于所检察的包的属性。 有一个关键字主题, 以及一组子选项关键字, 您必须从他们中选择一个。 以下是一些通用的属性, 它们必须按下面的顺序使用: PROTO proto 是一个主题关键字, 它必须与某个相关的子选项关键字配合使用。 这个值的作用是匹配某个特定的协议。 要使用新式的规则处理逻辑, 就必须使用这个选项。 tcp/udp | udp | tcp | icmp 或其他在 /etc/protocols 中定义的协议。 特殊的协议关键字 tcp/udp 可以用于匹配 TCPUDP 包, 引入这个关键字的作用是是避免大量的重复规则的麻烦。 SRC_ADDR/DST_ADDR 使用 all 关键词, 基本上相当于 from any to any 在没有配合其他关键字的情形。 from src to dst: from 和 to 关键字主要是用来匹配 IP 地址。 所有的规则都必须同时给出源和目的两个参数。 any 是一个可以用于匹配任意 IP 地址的特殊关键字。 例如, 您可以使用 from any to anyfrom 0.0.0.0/0 to anyfrom any to 0.0.0.0/0from 0.0.0.0 to any 以及 from any to 0.0.0.0 IP 地址可以按句点分隔的 IP 地址/掩码长度 的方式来指定, 也可以只指定一个句点分隔的 IP 地址。 如果无法使用子网掩码来表示 IP 的话, 表达地址就会很麻烦。 请参见下面的网页了解如何撰写掩码长度: PORT 如果为源或目的指定了匹配端口, 规则就只能应用于 TCPUDP 包了。 当编写端口比较规则时, 可以指定 /etc/services 中所定义的名字, 也可以直接用端口号来指定。 如果端口号出现在源对象一侧, 则被认为是源端口号; 反之, 则被认为是目的端口号。 要使用新式的规则处理逻辑, 就必须与 to 对象配合使用这个选项。 使用的例子: from any to any port = 80 端口的比较是以数字的形式进行的, 可以使用比较算符来指定, 也可以指定一个范围。 port "=" | "!=" | "<" | ">" | "<=" | ">=" | "eq" | "ne" | "lt" | "gt" | "le" | "ge". 要指定端口范围, 可以使用 "<>" | "><"。 在源和目的匹配参数之后, 需要使用下面两个参数, 才能够使用新式的规则处理逻辑。 <acronym>TCP</acronym>_FLAG 标志只对 TCP 过滤使用。 这些字母用来表达 TCP 包头的标志。 新式的规则处理逻辑使用 flags S 参数来识别 tcp 会话开始的请求。 STATEFUL keep state 表示如果有一个包与规则匹配, 则其筛选参数应激活有状态的过滤机制。 如果使用新式的处理逻辑, 则这个选项是必需的。 有状态过滤 IPFILTER 有状态过滤 有状态过滤将网络流量当作一种双向的包交换来处理。 如果激活它, keep-state 会动态地为每一个相关的包在双向会话交互过程中产生内部规则。 它能够确认发起者和包的目的地之间的会话是有效的双向包交换过程的一部分。 如果包与这些规则不符, 则将自动地拒绝。 状态保持也使得 ICMP 包能够与 TCP 或 UDP 会话相关。 因此, 如果您在浏览网站时收到允许的状态保持规则匹配的 ICMP 类型 3 代码 4 响应, 则这些响应会被自动地允许进入。 所有 IPF 能够处理的包, 都可以作为某种活跃会话的一部分, 即使它是另一种协议的, 也会被允许进入。 所发生的事情是: 将要通过联入公网的网络接口发出的包, 首先会经过动态状态表的检查。 如果包与会话中预期的下一个包匹配, 则防火墙就会允许包通过, 而会话的交互流信息也会在动态状态表中进行更新, 而其他的包, 则将使用发出规则集来检查。 发到联入 Internet 公网的包, 也会首先经过动态规则表的检查。 如果与会话中预期的下一个包匹配, 则防火墙就允许它通过, 并更新动态状态表。 其他包仍会使用进入规则集进行检查。 当会话结束时, 对应的项会在动态状态表中删除。 有状态过滤使得您能够集中于阻止/允许新的会话。 一旦新会话被允许通过, 则所有后续的包就都被自动地允许通过, 而伪造的包则被自动地拒绝。 如果新的会话被阻止, 则后续的包也都不会被允许通过。 有状态过滤从技术角度而言, 在阻止目前攻击者常用的洪水式攻击来说, 具有更好的抗御能力。 包容式规则集的例子 下面的规则集是如何编写非常安全的包容式防火墙规则集的一个范例。 包容式防火墙只让允许的服务通过, 而所有其他的访问都会被默认地拒绝。 所有的防火墙都有至少两个接口对应的默认规则, 从而使防火墙能够正常工作。 所有的类 &unix; 系统, 包括 &os; 都使用 lo0 和 IP 地址 127.0.0.1 用于操作系统中内部的通讯。 防火墙规则必须允许这些包无阻碍地通过。 接入 Internet 公网的网络接口, 是放置规则并允许将访问请求发到 Internet 以及接收响应的地方。 这有可能是用户模式的 PPP tun0 接口, 如果您的网卡同 DSL 或电缆调制解调器相联的话。 如果有至少一个网卡与防火墙后的内网 LAN 相联, 这些网络接口就应该有一个规则来允许来自这些 LAN 接口的包无阻碍地通过。 一般说来, 规则应被组织为三个主要的小节: 所有允许自由通过的接口规则, 发到公网接口的规则, 以及进入公网接口的规则。 每一个公网接口规则中, 经常会匹配到的规则应该放置在尽可能靠前的位置。 而最后一个规则应该是阻止包通过, 并记录它们。 下面防火墙规则集中, Outbound 部分是一些使用 'pass' 的规则, 这些规则指定了允许访问的公网 Internet 服务, 并且指定了 'quick'、 'on'、 'proto'、 'port', 以及 'keep state' 这些选项。 'proto tcp' 规则还指定了 'flag' 这个选项, 这样会话的第一个包将出发状态机制。 接下来的 Inbound 一节, 则首先阻止所有不希望的数据包。 这样做有两个原因, 其一是被阻止的包可能会被后面的规则允许, 从而并不妨碍获得授权的服务正常工作; 其二是这避免了那些不常见的包由于匹配到最后一条规则而触发日志, 规则集中的最后一条规则是阻止并记录所有的包, 通过这样的记录, 就比较容易找到攻击系统的人, 并为采取法律措施收集证据。 需要注意的另一件事情是, 如果收到了不希望的数据包, 则这些包会被丢弃, 而不是给出什么响应。 这样做的好处是, 攻击者无法了解包是否已经被您的系统收到。 攻击者所能了解到的信息越少, 攻陷您的系统所需要花费的时间也就越长。 我们在这里记录的连入的 'nmap OS 指纹' 探测企图, 一般来说正是攻击者所做的第一件事。 如果您看到了 'log first' 规则的日志, 就应该用 ipfstat -hio 命令来看看那个规则被匹配的次数, 以便了解系统是否正在或曾被攻击。 如果记录的包的端口号并不是您所知道的, 可以在 /etc/services 了解端口号通常的用途。 参考下面的网页, 了解木马使用的端口: 下面是我在自己的系统中使用的完整的, 非常安全的 '包容式' 防火墙规则集。 直接使用这个规则集不会给您造成问题, 您所要做的只是注释掉那些您不需要的服务。 如果在日志中发现了希望阻止的记录, 只需在 inbound 小节中增加一条阻止规则集可。 您必须将每一个规则中的 dc0 替换为您系统上接入 Internet 的网络接口名称, 例如, 用户环境下的 PPP 应该是 tun0 /etc/ipf.rules 中加入下面的内容: ################################################################# # No restrictions on Inside LAN Interface for private network # Not needed unless you have LAN ################################################################# #pass out quick on xl0 all #pass in quick on xl0 all ################################################################# # No restrictions on Loopback Interface ################################################################# pass in quick on lo0 all pass out quick on lo0 all ################################################################# # Interface facing Public Internet (Outbound Section) # Interrogate session start requests originating from behind the # firewall on the private network # or from this gateway server destine for the public Internet. ################################################################# # Allow out access to my ISP's Domain name server. # xxx must be the IP address of your ISP's DNS. # Dup these lines if your ISP has more than one DNS server # Get the IP addresses from /etc/resolv.conf file pass out quick on dc0 proto tcp from any to xxx port = 53 flags S keep state pass out quick on dc0 proto udp from any to xxx port = 53 keep state # Allow out access to my ISP's DHCP server for cable or DSL networks. # This rule is not needed for 'user ppp' type connection to the # public Internet, so you can delete this whole group. # Use the following rule and check log for IP address. # Then put IP address in commented out rule & delete first rule pass out log quick on dc0 proto udp from any to any port = 67 keep state #pass out quick on dc0 proto udp from any to z.z.z.z port = 67 keep state # Allow out non-secure standard www function pass out quick on dc0 proto tcp from any to any port = 80 flags S keep state # Allow out secure www function https over TLS SSL pass out quick on dc0 proto tcp from any to any port = 443 flags S keep state # Allow out send & get email function pass out quick on dc0 proto tcp from any to any port = 110 flags S keep state pass out quick on dc0 proto tcp from any to any port = 25 flags S keep state # Allow out Time pass out quick on dc0 proto tcp from any to any port = 37 flags S keep state # Allow out nntp news pass out quick on dc0 proto tcp from any to any port = 119 flags S keep state # Allow out gateway & LAN users non-secure FTP ( both passive & active modes) # This function uses the IPNAT built in FTP proxy function coded in # the nat rules file to make this single rule function correctly. # If you want to use the pkg_add command to install application packages # on your gateway system you need this rule. pass out quick on dc0 proto tcp from any to any port = 21 flags S keep state # Allow out secure FTP, Telnet, and SCP # This function is using SSH (secure shell) pass out quick on dc0 proto tcp from any to any port = 22 flags S keep state # Allow out non-secure Telnet pass out quick on dc0 proto tcp from any to any port = 23 flags S keep state # Allow out FBSD CVSUP function pass out quick on dc0 proto tcp from any to any port = 5999 flags S keep state # Allow out ping to public Internet pass out quick on dc0 proto icmp from any to any icmp-type 8 keep state # Allow out whois for LAN PC to public Internet pass out quick on dc0 proto tcp from any to any port = 43 flags S keep state # Block and log only the first occurrence of everything # else that's trying to get out. # This rule enforces the block all by default logic. block out log first quick on dc0 all ################################################################# # Interface facing Public Internet (Inbound Section) # Interrogate packets originating from the public Internet # destine for this gateway server or the private network. ################################################################# # Block all inbound traffic from non-routable or reserved address spaces block in quick on dc0 from 192.168.0.0/16 to any #RFC 1918 private IP block in quick on dc0 from 172.16.0.0/12 to any #RFC 1918 private IP block in quick on dc0 from 10.0.0.0/8 to any #RFC 1918 private IP block in quick on dc0 from 127.0.0.0/8 to any #loopback block in quick on dc0 from 0.0.0.0/8 to any #loopback block in quick on dc0 from 169.254.0.0/16 to any #DHCP auto-config block in quick on dc0 from 192.0.2.0/24 to any #reserved for docs block in quick on dc0 from 204.152.64.0/23 to any #Sun cluster interconnect block in quick on dc0 from 224.0.0.0/3 to any #Class D & E multicast ##### Block a bunch of different nasty things. ############ # That I do not want to see in the log # Block frags block in quick on dc0 all with frags # Block short tcp packets block in quick on dc0 proto tcp all with short # block source routed packets block in quick on dc0 all with opt lsrr block in quick on dc0 all with opt ssrr # Block nmap OS fingerprint attempts # Log first occurrence of these so I can get their IP address block in log first quick on dc0 proto tcp from any to any flags FUP # Block anything with special options block in quick on dc0 all with ipopts # Block public pings block in quick on dc0 proto icmp all icmp-type 8 # Block ident block in quick on dc0 proto tcp from any to any port = 113 # Block all Netbios service. 137=name, 138=datagram, 139=session # Netbios is MS/Windows sharing services. # Block MS/Windows hosts2 name server requests 81 block in log first quick on dc0 proto tcp/udp from any to any port = 137 block in log first quick on dc0 proto tcp/udp from any to any port = 138 block in log first quick on dc0 proto tcp/udp from any to any port = 139 block in log first quick on dc0 proto tcp/udp from any to any port = 81 # Allow traffic in from ISP's DHCP server. This rule must contain # the IP address of your ISP's DHCP server as it's the only # authorized source to send this packet type. Only necessary for # cable or DSL configurations. This rule is not needed for # 'user ppp' type connection to the public Internet. # This is the same IP address you captured and # used in the outbound section. pass in quick on dc0 proto udp from z.z.z.z to any port = 68 keep state # Allow in standard www function because I have apache server pass in quick on dc0 proto tcp from any to any port = 80 flags S keep state # Allow in non-secure Telnet session from public Internet # labeled non-secure because ID/PW passed over public Internet as clear text. # Delete this sample group if you do not have telnet server enabled. #pass in quick on dc0 proto tcp from any to any port = 23 flags S keep state # Allow in secure FTP, Telnet, and SCP from public Internet # This function is using SSH (secure shell) pass in quick on dc0 proto tcp from any to any port = 22 flags S keep state # Block and log only first occurrence of all remaining traffic # coming into the firewall. The logging of only the first # occurrence stops a .denial of service. attack targeted # at filling up your log file space. # This rule enforces the block all by default logic. block in log first quick on dc0 all ################### End of rules file ##################################### <acronym>NAT</acronym> NAT IP 伪装 NAT 网络地址转换 NAT NAT 是 网络地址转换(Network Address Translation) 的缩写。 对于那些熟悉 &linux; 的人来说, 这个概念叫做 IP 伪装 (Masquerading); NAT 和 IP 伪装是完全一样的概念。 由 IPF 的 NAT 提供的一项功能是, 将防火墙后的本地局域网 (LAN) 共享一个 ISP 提供的 IP 地址来接入 Internet 公网。 有些人可能会问, 为什么需要这么做。 一般而言, ISP 会为非商业用户提供动态的 IP 地址。 动态地址意味着每次登录到 ISP 都有可能得到不同的 IP 地址, 无论是采用电话拨号登录, 或使用 cable 以及 DSL 调制解调器的方式。 这个 IP 是您与 Internet 公网交互时使用的身份。 现在考虑家中有五台 PC 需要访问 Internet 的情形。 您可能需要向 ISP 为每一台 PC 所使用的独立的 Internet 账号付费, 并且拥有五根电话线。 有了 NAT, 您就只需要一个 ISP 账号, 然后将另外四台 PC 的网卡通过交换机连接起来, 并通过运行 &os; 系统的那台机器作为网关连接出去。 NAT 会自动地将每一台 PC 在内网的 LAN IP 地址, 在离开防火墙时转换为公网的 IP 地址。 此外, 当数据包返回时, 也将进行逆向的转换。 NAT 通常是在没有向 ISP 请求许可, 或事先知会的情况下进行的, 因而如果被发现, 有时可能会成为 ISP 撤销您的账号的一个借口。 商业用户一般来说会购买昂贵得多的 Internet 线路, 通常会获得一组长期有效的静态 IP 地址块。 ISP 一般会希望并同意商业用户在他们的内网中使用 NAT 在 IP 地址空间中, 有一些特殊的范围是保留供经过 NAT 的内网 LAN IP 地址使用的。 根据 RFC 1918, 您可以使用下面这些 IP 范围用于内网, 它们不会在 Internet 公网上路由: 起始 IP 10.0.0.0 - 结束 IP 10.255.255.255 起始 IP 172.16.0.0 - 结束 IP 172.31.255.255 起始 IP 192.168.0.0 - 结束 IP 192.168.255.255 IP<acronym>NAT</acronym> NAT 以及 IPFILTER ipnat NAT 规则是通过 ipnat 命令加载的。 默认情况下, NAT 规则会保存在 /etc/ipnat.rules 文件中。 请参见 &man.ipnat.1; 了解更多的详情。 如果在 NAT 已经启动之后想要修改 NAT 规则, 可以修改保存 NAT 规则的那个文件, 然后在执行 ipnat 命令时加上 参数, 以删除在用的 NAT 内部规则表, 以及所有地址翻译表中已有的项。 要重新加载 NAT 规则, 可以使用类似下面的命令: &prompt.root; ipnat -CF -f /etc/ipnat.rules 如果想要看看您系统上 NAT 的统计信息, 可以用下面的命令: &prompt.root; ipnat -s 要列出当前的 NAT 表的映射关系, 使用下面的命令: &prompt.root; ipnat -l 要显示详细的信息并显示与规则处理和当前的规则/表项: &prompt.root; ipnat -v IP<acronym>NAT</acronym> 规则 NAT 规则非常的灵活, 能够适应商业用户和家庭用户的各种不同的需求。 这里所介绍的规则语法已经被简化, 以适应非商用环境中的一般情况。 完整的规则语法描述, 请参考 &man.ipnat.5; 联机手册中的介绍。 NAT 规则的写法与下面的例子类似: map IF LAN_IP_RANGE -> PUBLIC_ADDRESS 关键词 map 出现在规则的最前面。 IF 替换为对外的网络接口名。 LAN_IP_RANGE 是内网中的客户机使用的地址范围。 通常情况下, 这应该是类似 192.168.1.0/24 的地址。 PUBLIC_ADDRESS 既可以是外网的 IP 地址, 也可以是 0/32 这个特殊的关键字, 它表示分配到 IF 上的所有地址。 <acronym>NAT</acronym> 的工作原理 当包从 LAN 到达防火墙, 而目的地址是公网地址时, 它首先会通过 outbound 过滤规则。 接下来, NAT 会得到包, 并按自顶向下的顺序处理规则, 而第一个匹配的规则将生效。 NAT 接下来会根据包对应的接口名字和源 IP 地址检查所有的规则。 如果包和某个 NAT 规则匹配, 则会检查包的 [源 IP 地址, 例如, 内网的 IP 地址] 是否在 NAT 规则中箭头左侧指定的 IP 地址范围匹配。 如果匹配, 则包的原地址将被根据用 0/32 关键字指定的 IP 地址重写。 NAT 将向它的内部 NAT 表发送此地址, 这样, 当包从 Internet 公网中返回时, 就能够把地址映射回原先的内网 IP 地址, 并在随后使用过滤器规则来处理。 启用 IP<acronym>NAT</acronym> 要启用 IPNAT, 只需在 /etc/rc.conf 中加入下面一些语句。 使机器能够在不同的网络接口之间进行包的转发, 需要: gateway_enable="YES" 每次开机时自动启动 IPNAT ipnat_enable="YES" 指定 IPNAT 规则集文件: ipnat_rules="/etc/ipnat.rules" 大型 LAN 中的 <acronym>NAT</acronym> 对于在一个 LAN 中有大量 PC, 以及包含多个 LAN 的情形, 把所有的内网 IP 地址都映射到同一个公网 IP 上会导致资源不够的问题, 因为同一个端口可能在许多做了 NAT 的 LAN PC 上被多次使用, 并导致碰撞。 有两种方法来缓解这个难题。 指定使用哪些端口 普通的 NAT 规则类似于: map dc0 192.168.1.0/24 -> 0/32 上面的规则中, 包的源端口在包通过 IPNAT 时时不会发生变化的。 通过使用 portmap 关键字, 您可以要求 IPNAT 只使用一定范围内的端口地址。 比如说, 下面的规则将让 IPNAT 把源端口改为指定范围内的端口: map dc0 192.168.1.0/24 -> 0/32 portmap tcp/udp 20000:60000 使用 auto 关键字可以让配置变得更简单一些, 它会要求 IPNAT 自动地检测可用的端口并使用: map dc0 192.168.1.0/24 -> 0/32 portmap tcp/udp auto 使用公网地址池 对很大的 LAN 而言, 总有一天会达到这样一个临界值, 此时的 LAN 地址已经多到了无法只用一个公网地址表现的程度。 如果有可用的一块公网 IP 地址, 则可以将这些地址作为一个 地址池 来使用, 让 IPNAT 来从这些公网 IP 地址中挑选用于发包的地址, 并将其为这些包创建映射关系。 例如, 如果将下面这个把所有包都映射到同一公网 IP 地址的规则: map dc0 192.168.1.0/24 -> 204.134.75.1 稍作修改, 就可以用子网掩码来表达 IP 地址范围: map dc0 192.168.1.0/24 -> 204.134.75.0/255.255.255.0 或者用 CIDR 记法来指定的一组地址了: map dc0 192.168.1.0/24 -> 204.134.75.0/24 端口重定向 非常流行的一种做法是, 将 web 服务器、 邮件服务器、 数据库服务器以及 DNS 分别放到 LAN 上的不同的 PC 上。 这种情况下, 来自这些服务器的网络流量仍然应该被 NAT, 但必须有办法把进入的流量发到对应的局域网的 PC 上。 IPNAT 提供了 NAT 重定向机制来解决这个问题。 考虑下面的情况, 您的 web 服务器的 LAN 地址是 10.0.10.25, 而您的唯一的公网 IP 地址是 20.20.20.5, 则可以编写这样的规则: rdr dc0 20.20.20.5/32 port 80 -> 10.0.10.25 port 80 或者: rdr dc0 0.0.0.0/0 port 80 -> 10.0.10.25 port 80 另外, 也可以让 LAN 地址 10.0.10.33 上运行的 LAN DNS 服务器来处理公网上的 DNS 请求: rdr dc0 20.20.20.5/32 port 53 -> 10.0.10.33 port 53 udp FTP 和 <acronym>NAT</acronym> FTP 是一个在 Internet 如今天这样为人所熟知之前就已经出现的恐龙, 那时, 研究机构和大学是通过租用的线路连到一起的, 而 FTP 则被用于在科研人员之间共享大文件。 那时, 数据的安全性并不是需要考虑的事情。 若干年之后, FTP 协议则被埋进了正在形成中的 Internet 骨干, 而它使用明文来交换用户名和口令的缺点, 并没有随着新出现的一些安全需求而得到改变。 FTP 提供了两种不同的风格, 即主动模式和被动模式。 两者的区别在于数据通道的建立方式。 被动模式相对而言要更加安全, 因为数据通道是由发起 ftp 会话的一方建立的。 关于 FTP 以及它所提供的不同模式, 在 进行了很好的阐述。 IP<acronym>NAT</acronym> 规则 IPNAT 提供了一个内建的 FTP 代理选项, 它可以在 NAT map 规则中指定。 它能够监视所有外发的 FTP 主动或被动模式的会话开始请求, 并动态地创建临时性的过滤器规则, 只打开用于数据通道的端口号。 这样, 就消除了 FTP 一般会给防火墙带来的, 需要大范围地打开高端口所可能带来的安全隐患。 下面的规则可以处理来自内网的 FTP 访问: map dc0 10.0.10.0/29 -> 0/32 proxy port 21 ftp/tcp 这个规则能够处理来自网关的 FTP 访问: map dc0 0.0.0.0/0 -> 0/32 proxy port 21 ftp/tcp 这个则处理所有来自内网的非 FTP 网络流量: map dc0 10.0.10.0/29 -> 0/32 FTP map 规则应该在普通的 map 规则之前出现。 所有的包会从最上面的第一个规则开始进行检查。 匹配的顺序是网卡名称, 内网源 IP 地址, 以及它是否是 FTP 包。 如果所有这些规则都匹配成功, 则 FTP 代理将建立一个临时的过滤规则, 以便让 FTP 会话的数据包能够正常出入, 同时对这些包进行 NAT。 所有的 LAN 数据包, 如果没有匹配第一条规则, 则会继续尝试匹配下面的规则, 并最终被 NAT IP<acronym>NAT</acronym> FTP 过滤规则 如果使用了 NAT FTP 代理, 则只需要为 FTP 创建一个规则。 如果没有使用 FTP 代理, 则需要下面三个规则: # Allow out LAN PC client FTP to public Internet # Active and passive modes pass out quick on rl0 proto tcp from any to any port = 21 flags S keep state # Allow out passive mode data channel high order port numbers pass out quick on rl0 proto tcp from any to any port > 1024 flags S keep state # Active mode let data channel in from FTP server pass in quick on rl0 proto tcp from any to any port = 20 flags S keep state IPFW 防火墙 IPFW 这一节的内容正在撰写中。 其内容可能不总是十分准确。 IPFIREWALL (IPFW) 是一个由 &os; 发起的防火墙应用软件, 它由 &os; 的志愿者成员编写和维护。 它使用了传统的无状态规则和规则编写方式, 以期达到简单状态逻辑所期望的目标。 标准的 &os; 安装中, IPFW 所给出的规则集样例 (可以在 /etc/rc.firewall 中找到) 非常简单, 建议不要不加修改地直接使用。 该样例中没有使用状态过滤, 而该功能在大部分的配置中都是非常有用的, 因此这一节并不以系统自带的样例作为基础。 IPFW 的无状态规则语法, 是由一种提供复杂的选择能力的技术支持的, 这种技术远远超出了一般的防火墙安装人员的知识水平。 IPFW 是为满足专业用户, 以及掌握先进技术的电脑爱好者们对于高级的包选择需求而设计的。 要完全释放 IPFW 的规则所拥有的强大能力, 需要对不同的协议的细节有深入的了解, 并根据它们独特的包头信息来编写规则。 这一级别的详细阐述超出了这本手册的范围。 IPFW 由七个部分组成, 其主要组件是内核的防火墙过滤规则处理器, 及其集成的数据包记帐工具、 日志工具、 用以触发 NAT 工具的 'divert' (转发) 规则、 高级特殊用途工具、 dummynet 流量整形机制, 'fwd rule' 转发工具, 桥接工具, 以及 ipstealth 工具。 启用 IPFW IPFW 启用 IPFW 是基本的 &os; 安装的一部分, 以单独的可加载内核模块的形式提供。 如果在 rc.conf 中加入 firewall_enable="YES" 语句, 就会自动地加载对应的内核模块。 除非您打算使用由它提供的 NAT 功能, 一般情况下并不需要把 IPFW 编进 &os; 的内核。 如果将 firewall_enable="YES" 加入到 rc.conf 中并重新启动系统, 则下列信息将在启动过程中, 以高亮的白色显示出来: ipfw2 initialized, divert disabled, rule-based forwarding disabled, default to deny, logging disabled 可加载内核模块在编译时加入了记录日志的能力。 要启用日志功能, 并配置详细日志记录的限制, 需要在 /etc/sysctl.conf 中加入一些配置。 这些设置将在重新启动之后生效: net.inet.ip.fw.verbose=1 net.inet.ip.fw.verbose_limit=5 内核选项 内核选项 IPFIREWALL 内核选项 IPFIREWALL_VERBOSE 内核选项 IPFIREWALL_VERBOSE_LIMIT IPFW 内核选项 把下列选项在编译 &os; 内核时就加入, 并不是启用 IPFW 所必需的, 除非您需要使用 NAT 功能。 这里只是将这些选项作为背景知识来介绍。 options IPFIREWALL 这个选项将 IPFW 作为内核的一部分来启用。 options IPFIREWALL_VERBOSE 这个选项将启用记录通过 IPFW 的匹配了包含 'log' 关键字规则的每一个包的功能。 options IPFIREWALL_VERBOSE_LIMIT=5 以每项的方式, 限制通过 &man.syslogd.8; 记录的包的个数。 如果在比较恶劣的环境下记录防火墙的活动可能会需要这个选项。 它能够避免潜在的针对 syslog 的洪水式拒绝服务攻击。 内核选项 IPFIREWALL_DEFAULT_TO_ACCEPT options IPFIREWALL_DEFAULT_TO_ACCEPT 这个选项默认地允许所有的包通过防火墙, 如果您是第一次配置防火墙, 使用这个选项将是一个不错的主意。 options IPV6FIREWALL options IPV6FIREWALL_VERBOSE options IPV6FIREWALL_VERBOSE_LIMIT options IPV6FIREWALL_DEFAULT_TO_ACCEPT 这些选项与 IPv4 的对应选项功能一样, 它们是针对 IPv6 的。 如果不使用 IPv6, 则不带任何规则的 IPV6FIREWALL 将阻止所有的 IPv6 包。 内核选项 IPDIVERT options IPDIVERT 这一选项启用 NAT 功能。 如果内核选项中没有加入 IPFIREWALL_DEFAULT_TO_ACCEPT, 或将您的防火墙设置配置为允许所有的进入包, 则所有发到本机或发出的包都会被阻止。 <filename>/etc/rc.conf</filename> Options 启用防火墙: firewall_enable="YES" 要选择由 &os; 提供的几种防火墙类型中的一种来作为默认配置, 您需要阅读 /etc/rc.firewall 文件并选出合适的类型, 然后在 /etc/rc.conf 中加入类似下面的配置: firewall_type="open" 您还可以指定下列配置规则之一: open — 允许所有流量通过。 client — 只保护本机。 simple — 保护整个网络。 closed — 完全禁止除回环设备之外的全部 IP 流量。 UNKNOWN — 禁止加载防火墙规则。 filename — 到防火墙规则文件的绝对路径。 有两种加载自定义 ipfw 防火墙规则的方法。 其一是将变量 firewall_type 设为包含不带 &man.ipfw.8; 命令行选项的 防火墙规则 文件的完整路径。 下面是一个简单的规则集例子: add block in all add block out all 除此之外, 也可以将 firewall_script 变量设为包含 ipfw 命令的可执行脚本, 这样这个脚本会在启动时自动执行。 与前面规则集文件等价的规则脚本如下: #!/bin/sh ipfw -q flush ipfw add block in all ipfw add block out all 如果 firewall_type 设为 clientsimple, 则还应查看在 /etc/rc.firewall 中的默认规则, 以确认它们与所在机器的配置相一致。 此外, 请注意这一章中的例子均假定 firewall_script/etc/ipfw.rules 启用日志: firewall_logging="YES" 设置 firewall_logging 的唯一作用是, 系统将把 net.inet.ip.fw.verbose sysctl 变量置为 1 (参见 )。 并没有能够设置日志限制的 rc.conf 变量, 不过这种限制可以通过设置某些 sysctl 变量来完成, 可以手工进行操作, 也可以写到 /etc/sysctl.conf 文件中: net.inet.ip.fw.verbose_limit=5 如果您的计算机是作为网关使用的, 也就是它通过 &man.natd.8; 提供网络地址翻译 (NAT), 请参见 以了解需要在 /etc/rc.conf 中配置的选项。 IPFW 命令 ipfw ipfw 命令是在防火墙运行时, 用于在其内部规则表中手工逐条添加或删除防火墙规则的标准工具。 这一方法的问题在于, 一旦您的关闭计算机或停机, 则所有增加或删除或修改的规则也就丢掉了。 把所有的规则都写到一个文件中, 并在启动时使用这个文件来加载规则, 或一次大批量地替换防火墙规则, 那么推荐使用这里介绍的方法。 ipfw 的另一个非常实用的功能是将所有正在运行的防火墙规则显示出来。 IPFW 的记账机制会为每一个规则动态地创建计数器, 用以记录与它们匹配的包的数量。 在测试规则的过程中, 列出规则及其计数器是了解它们是否工作正常的重要手段。 按顺序列出所有的规则: &prompt.root; ipfw list 列出所有的规则, 同时给出最后一次匹配的时间戳: &prompt.root; ipfw -t list 列出所有的记账信息、 匹配规则的包的数量, 以及规则本身。 第一列是规则的编号, 随后是发出包匹配的数量, 进入包的匹配数量, 最后是规则本身。 &prompt.root; ipfw -a list 列出所有的动态规则和静态规则: &prompt.root; ipfw -d list 同时显示已过期的动态规则: &prompt.root; ipfw -d -e list 将计数器清零: &prompt.root; ipfw zero 只把规则号为 NUM 的计数器清零: &prompt.root; ipfw zero NUM IPFW 规则集 规则集是一组根据包中选择的数值使用 allow 或 deny 写出的 ipfw 规则。 在两个主机之前的双向包交换组成了一次会话交互。 防火墙规则集, 会对同一个包处理两次: 第一次是包从公网上到达防火墙时, 而第二次则是包返回 Internet 公网上的主机时。 每一个 TCP/IP 服务 (例如 telnet, www, mail, 等等), 都有事先定义好的协议, 以及一个端口号。 这可以作为建立允许或阻止规则时的基本选择依据。 IPFW 规则处理顺序 当有数据包进入防火墙时, 会从规则集里的第一个规则开始进行比较, 并自顶向下地进行匹配。 当包与某个选择规则参数相匹配时, 将会执行规则所定义的动作, 并停止规则集搜索。 这种策略, 通常也被称作 最先匹配者获胜 的搜索方法。 如果没有任何与包相匹配的规则, 那么它就会根据强制的 ipfw 默认规则, 也就是 65535 号规则截获。 一般情况下这个规则是阻止包, 而且不给出任何回应。 如果规则定义的动作是 countskiptotee 规则的话, 搜索会继续。 这里所介绍的规则, 都是使用了那些包含状态功能的, 也就是 'keep state'、 'limit'、 'in'/'out'、 或者 'via' 选项的规则。 这是编写包容式防火墙规则集所需的基本框架。 包容式防火墙只允许与规则匹配的包通过。 这样, 您就既能够控制来自防火墙后面的机器请求 Internet 公网上的那些服务, 同时也可以控制来自 Internet 的请求能够访问内部网上的哪些服务。 所有其它的访问请求都会被阻止, 并记录下来。 包容式防火墙一般而言要远比排斥式的要安全, 而且也只需要定义允许哪些访问通过。 在操作防火墙规则时应谨慎行事, 如果操作不当, 有可能将自己反锁在外面。 规则语法 IPFW 规则语法 这里所介绍的规则语法已经经过了简化, 只包括了建立标准的包容式防火墙规则集所必需的那些。 要了解完整的规则语法说明, 请参见 &man.ipfw.8; 联机手册。 规则是由关键字组成的: 这些关键字必须以特定的顺序从左到右书写。 下面的介绍中, 关键字使用粗体表示。 某些关键字还包括了子选项, 这些子选项本身可能也是关键字, 有些还可以包含更多的子选项。 # 用于表示开始一段注释。 它可以出现在一个规则的后面, 也可以独占一行。 空行会被忽略。 CMD RULE_NUMBER ACTION LOGGING SELECTION STATEFUL CMD 每一个新的规则都应以 add 作为前缀, 它表示将规则加入内部表。 RULE_NUMBER 每一个规则都必须包含一个规则编号。 ACTION 每一个规则可以与下列的动作之一相关联, 所指定的动作将在进入的数据包与规则所指定的选择标准相匹配时执行。 allow | accept | pass | permit 这些关键字都表示允许匹配规则的包通过防火墙, 并停止继续搜索规则。 check-state 根据动态规则表检查数据包。 如果匹配, 则执行规则所指定的动作, 亦即生成动态规则; 否则, 转移到下一个规则。 check-state 规则没有选择标准。 如果规则集中没有 check-state 规则, 则会在第一个 keep-state 或 limit 规则处, 对动态规则表实施检查。 deny | drop 这两个关键字都表示丢弃匹配规则的包。 同时, 停止继续搜索规则。 LOGGING log or logamount 当数据包与带 log 关键字的规则匹配时, 将通过名为 SECURITY 的 facility 来把消息记录到 syslogd。 只有在记录的次数没有超过 logamount 参数所指定的次数时, 才会记录日志。 如果没有指定 logamount, 则会以 sysctl 变量 net.inet.ip.fw.verbose_limit 所指定的限制为准。 如果将这两种限制值之一指定为零, 则表示不作限制。 万一达到了限制数, 可以通过将规则的日志计数或包计数清零来重新启用日志, 请参见 ipfw reset log 命令来了解细节。 日志是在所有其他匹配条件都验证成功之后, 在针对包实施最终动作 (accept, deny) 之前进行的。 您可以自行决定哪些规则应启用日志。 SELECTION 这一节所介绍的关键字主要用来描述检查包的哪些属性, 用以判断包是否与规则相匹配。 下面是一些通用的用于匹配包特征的属性, 它们必须按顺序使用: udp | tcp | icmp 也可以指定在 /etc/protocols 中所定义的协议。 这个值定义的是匹配的协议, 在规则中必须指定它。 from src to dst from 和 to 关键字用于匹配 IP 地址。 规则中必须同时指定源和目的两个参数。 如果需要匹配任意 IP 地址, 可以使用特殊关键字 any。 还有一个特殊关键字, 即 me, 用于匹配您的 &os; 系统上所有网络接口上所配置的 IP 地址, 它可以用于表达网络上的其他计算机到防火墙 (也就是本机), 例如 'from me to any' 或 'from any to me' 或 'from 0.0.0.0/0 to any' 或 'from any to 0.0.0.0/0' 或 'from 0.0.0.0 to any' 或 'from any to 0.0.0.0' 以及 'from me to 0.0.0.0'。 IP 地址可以通过 带点的 IP 地址/掩码长度, 或者一个带点的 IP 地址的形式来指定。 这是编写规则时所必需的。 如果不清楚如何写掩码长度, 请参见 port number 这个参数主要用于那些支持端口号的协议 (例如 TCP 和 UDP)。 如果要通过端口号匹配某个协议, 就必须指定这个参数。 此外, 也可以通过服务的名字 (根据 /etc/services) 来指定服务, 这样会比使用数字指定端口号直观一些。 in | out 相应地, 匹配进入和发出的包。 这里的 in 和 out 都是关键字, 在编写匹配规则时, 必需作为其他条件的一部分来使用。 via IF 根据指定的网络接口的名称精确地匹配进出的包。 这里的 via 关键字将使得接口名称成为匹配过程的一部分。 setup 要匹配 TCP 会话的发起请求, 就必须使用它。 keep-state 这是一个必须使用的关键字。 在发生匹配时, 防火墙将创建一个动态规则, 其默认行为是, 匹配使用同一协议的、从源到目的 IP/端口 的双向网络流量。 limit {src-addr | src-port | dst-addr | dst-port} 防火墙只允许匹配规则时, 与指定的参数相同的 N 个连接。 可以指定至少一个源或目的地址及端口。 'limit' 和 'keep-state' 不能在同一规则中同时使用。 'limit' 提供了与 'keep-state' 相同的功能, 并增加了一些独有的能力。 状态规则选项 IPFW 带状态过滤 有状态过滤将网络流量当作一种双向的包交换来处理。 它提供了一种额外的检查能力, 用以检测会话中的包是否来自最初的发送者, 并在遵循双向包交换的规则进行会话。 如果包与这些规则不符, 则将自动地拒绝它们。 'check-state' 用来识别在 IPFW 规则集中的包是否符合动态规则机制的规则。 如果匹配, 则允许包通过, 此时防火墙将创建一个新的动态规则来匹配双向交换中的下一个包。 如果不匹配, 则将继续尝试规则集中的下一个规则。 动态规则机制在 SYN-flood 攻击下是脆弱的, 因为这种情况会产生大量的动态规则, 从而耗尽资源。 为了抵抗这种攻击, 从 &os; 中加入了一个叫做 limit 的新选项。 这个选项可以用来限制符合规则的会话允许的并发连接数。 如果动态规则表中的规则数超过限制, 则包将被丢弃。 记录防火墙消息 IPFW 记录日志 记录日志的好处是显而易见的: 它提供了在事后检查所发生的状况的方法, 例如哪些包被丢弃了, 这些包的来源和目的地, 从而为您提供找到攻击者所需的证据。 即使启用了日志机制, IPFW 也不会自行生成任何规则的日志。 防火墙管理员需要指定规则集中的哪些规则应该记录日志, 并在这些规则上增加 log 动作。 一般来说, 只有 deny 规则应记录日志, 例如对于进入的 ICMP ping 的 deny 规则。 另外, 复制默认的 ipfw 终极 deny 规则, 并加入 log 动作来作为您的规则集的最后一条规则也是很常见的用法。 这样, 您就能看到没有匹配任何一条规则的那些数据包。 日志是一把双刃剑, 如果不谨慎地加以利用, 则可能会陷入过多的日志数据中, 并导致磁盘被日志塞满。 将磁盘填满是 DoS 攻击最为老套的手法之一。 由于日志除了会写入磁盘之外, 还会输出到 root 的控制台屏幕上, 因此有过多的日志信息是很让人恼火的事情。 IPFIREWALL_VERBOSE_LIMIT=5 内核选项将限制同一个规则发到系统日志程序 syslogd 的连续消息的数量。 当内核启用了这个选项时, 某一特定规则所产生的连续消息的数量将封顶为这个数字。 一般来说, 没有办法从连续 200 条一模一样的日志信息中获取更多有用的信息。 举例来说, 如果同一个规则产生了 5 次消息并被记录到 syslogd, 余下的相同的消息将被计数, 并像下面这样发给 syslogd: last message repeated 45 times 所有记录的数据包包消息, 默认情况下会最终写到 /var/log/security 文件中, 后者在 /etc/syslog.conf 文件里进行了定义。 编写规则脚本 绝大多数有经验的 IPFW 用户会创建一个包含规则的文件, 并且, 按能够以脚本形式运行的方式来书写。 这样做最大的一个好处是, 可以大批量地刷新防火墙规则, 而无须重新启动系统就能够激活它们。 这种方法在测试新规则时会非常方便, 因为同一过程在需要时可以多次执行。 作为脚本, 您可以使用符号替换来撰写那些经常需要使用的值, 并用同一个符号在多个规则中反复地表达它。 下面将给出一个例子。 这个脚本使用的语法同 'sh'、 'csh' 以及 'tcsh' 脚本兼容。 符号替换字段使用美元符号 $ 作为前缀。 符号字段本身并不使用 $ 前缀。 符号替换字段的值必须使用 "双引号" 括起来。 可以使用类似下面的规则文件: ############### start of example ipfw rules script ############# # ipfw -q -f flush # Delete all rules # Set defaults oif="tun0" # out interface odns="192.0.2.11" # ISP's DNS server IP address cmd="ipfw -q add " # build rule prefix ks="keep-state" # just too lazy to key this each time $cmd 00500 check-state $cmd 00502 deny all from any to any frag $cmd 00501 deny tcp from any to any established $cmd 00600 allow tcp from any to any 80 out via $oif setup $ks $cmd 00610 allow tcp from any to $odns 53 out via $oif setup $ks $cmd 00611 allow udp from any to $odns 53 out via $oif $ks ################### End of example ipfw rules script ############ 这就是所要做的全部事情了。 例子中的规则并不重要, 它们主要是用来表示如何使用符号替换。 如果把上面的例子保存到 /etc/ipfw.rules 文件中, 您就可以通过输入下面的命令来加载它。 &prompt.root; sh /etc/ipfw.rules /etc/ipfw.rules 这个文件可以放到任何位置, 也可以命名为随便什么别的名字。 也可以手工执行下面的命令来达到类似的目的: &prompt.root; ipfw -q -f flush &prompt.root; ipfw -q add check-state &prompt.root; ipfw -q add deny all from any to any frag &prompt.root; ipfw -q add deny tcp from any to any established &prompt.root; ipfw -q add allow tcp from any to any 80 out via tun0 setup keep-state &prompt.root; ipfw -q add allow tcp from any to 192.0.2.11 53 out via tun0 setup keep-state &prompt.root; ipfw -q add 00611 allow udp from any to 192.0.2.11 53 out via tun0 keep-state 带状态规则集 以下的这组非-NAT 规则集, 是如何编写非常安全的 '包容式' 防火墙的一个例子。 包容式防火墙只允许匹配了 pass 规则的包通过, 而默认阻止所有的其他数据包。 必须有至少两个网络接口, 并且在其上配置了规则才能使防火墙正常工作。 所有类 &unix; 操作系统, 也包括 &os;, 都设计为允许使用网络接口 lo0 和 IP 地址 127.0.0.1 来完成操作系统内部的通讯。 防火墙必须包含一组规则, 使这些数据包能够无障碍地收发。 接入 Internet 公网的那个网络接口上, 应该配置授权和访问控制, 来限制对外的访问, 以及来自 Internet 公网的访问。 这个接口很可能是您的 ppp 接口, 例如 tun0, 或者您接在 DSL 或电缆 modem 上的网卡。 如果有至少一个网卡接入了防火墙后的内网 LAN, 则必须为这些接口配置规则, 以便让这些接口之间的包能够顺畅地通过。 所有的规则应被组织为三个部分, 所有应无阻碍地通过的规则, 公网的发出规则, 以及公网的接收规则。 公网接口相关的规则的顺序, 应该是最经常用到的放在尽可能靠前的位置, 而最后一个规则, 则应该是阻止那个接口在那一方向上的包。 发出部分的规则只包含一些 'allow' 规则, 允许选定的那些唯一区分协议的端口号所指定的协议通过, 以允许访问 Internet 公网上的这些服务。 所有的规则中都指定了 proto, port, in/out, via 以及 keep state 这些选项。 'proto tcp' 规则同时指定 'setup' 选项, 来区分开始协议会话的包, 以触发将包放入 keep state 规则表中的动作。 接收部分则首先阻止所有不希望的包, 在这里有两个目的。 首先是, 这些包被禁止掉之后, 就不会由于匹配了后面的某个规则而被允许。 其次, 明确地禁止这些包, 就不会再在日志中记录它们而形成干扰。 防火墙的最后一条规则是阻止并记录所有包, 这样, 您就可以留下用于起诉攻击您的系统的人的有用记录。 另一件需要注意的事情是, 不希望的数据包一般来说不会有任何响应, 这些数据包会被丢弃并消失。 这样, 攻击者也就无法了解他的数据包是否到达了您的系统。 而攻击者了解的信息越少, 它们攻陷系统所需的时间也就越长。 当记录的包使用的端口号不是您所熟悉的那些时, 可以看一看 /etc/services/ 或到 并查找一下端口号, 以了解其用途。 另外, 您也可以在这个网页上了解常见木马所使用的端口: 包容式规则集的例子 下面是一个非-NAT 的规则集, 它是一个完整的包容式规则集。 使用它作为您的规则集不会有什么问题。 只需把那些不需要的服务对应的 pass 规则注释掉就可以了。 如果您在日志中看到消息, 而且不想再看到它们, 只需在接收部分增加一个一个 deny 规则。 您可能需要把 'dc0' 改为接入公网的接口的名字。 对于使用用户态 ppp 的用户而言, 应该是 'tun0'。 您可以看出这些规则中的模式。 所有请求 Internet 公网上服务的会话开始包, 都使用了 keep-state。 所有来自 Internet 的授权服务请求, 都采用了 limit 选项来防止洪水式攻击。 所有的规则都使用了 in 或者 out 来说明方向。 所有的规则都使用了 via 接口名来指定应该匹配通过哪一个接口的包。 这些规则都应放到 /etc/ipfw.rules ################ Start of IPFW rules file ############################### # Flush out the list before we begin. ipfw -q -f flush # Set rules command prefix cmd="ipfw -q add" pif="dc0" # public interface name of NIC # facing the public Internet ################################################################# # No restrictions on Inside LAN Interface for private network # Not needed unless you have LAN. # Change xl0 to your LAN NIC interface name ################################################################# #$cmd 00005 allow all from any to any via xl0 ################################################################# # No restrictions on Loopback Interface ################################################################# $cmd 00010 allow all from any to any via lo0 ################################################################# # Allow the packet through if it has previous been added to the # the "dynamic" rules table by a allow keep-state statement. ################################################################# $cmd 00015 check-state ################################################################# # Interface facing Public Internet (Outbound Section) # Interrogate session start requests originating from behind the # firewall on the private network or from this gateway server # destine for the public Internet. ################################################################# # Allow out access to my ISP's Domain name server. # x.x.x.x must be the IP address of your ISP.s DNS # Dup these lines if your ISP has more than one DNS server # Get the IP addresses from /etc/resolv.conf file $cmd 00110 allow tcp from any to x.x.x.x 53 out via $pif setup keep-state $cmd 00111 allow udp from any to x.x.x.x 53 out via $pif keep-state # Allow out access to my ISP's DHCP server for cable/DSL configurations. # This rule is not needed for .user ppp. connection to the public Internet. # so you can delete this whole group. # Use the following rule and check log for IP address. # Then put IP address in commented out rule & delete first rule $cmd 00120 allow log udp from any to any 67 out via $pif keep-state #$cmd 00120 allow udp from any to x.x.x.x 67 out via $pif keep-state # Allow out non-secure standard www function $cmd 00200 allow tcp from any to any 80 out via $pif setup keep-state # Allow out secure www function https over TLS SSL $cmd 00220 allow tcp from any to any 443 out via $pif setup keep-state # Allow out send & get email function $cmd 00230 allow tcp from any to any 25 out via $pif setup keep-state $cmd 00231 allow tcp from any to any 110 out via $pif setup keep-state # Allow out FBSD (make install & CVSUP) functions # Basically give user root "GOD" privileges. $cmd 00240 allow tcp from me to any out via $pif setup keep-state uid root # Allow out ping $cmd 00250 allow icmp from any to any out via $pif keep-state # Allow out Time $cmd 00260 allow tcp from any to any 37 out via $pif setup keep-state # Allow out nntp news (i.e. news groups) $cmd 00270 allow tcp from any to any 119 out via $pif setup keep-state # Allow out secure FTP, Telnet, and SCP # This function is using SSH (secure shell) $cmd 00280 allow tcp from any to any 22 out via $pif setup keep-state # Allow out whois $cmd 00290 allow tcp from any to any 43 out via $pif setup keep-state # deny and log everything else that.s trying to get out. # This rule enforces the block all by default logic. $cmd 00299 deny log all from any to any out via $pif ################################################################# # Interface facing Public Internet (Inbound Section) # Interrogate packets originating from the public Internet # destine for this gateway server or the private network. ################################################################# # Deny all inbound traffic from non-routable reserved address spaces $cmd 00300 deny all from 192.168.0.0/16 to any in via $pif #RFC 1918 private IP $cmd 00301 deny all from 172.16.0.0/12 to any in via $pif #RFC 1918 private IP $cmd 00302 deny all from 10.0.0.0/8 to any in via $pif #RFC 1918 private IP $cmd 00303 deny all from 127.0.0.0/8 to any in via $pif #loopback $cmd 00304 deny all from 0.0.0.0/8 to any in via $pif #loopback $cmd 00305 deny all from 169.254.0.0/16 to any in via $pif #DHCP auto-config $cmd 00306 deny all from 192.0.2.0/24 to any in via $pif #reserved for docs $cmd 00307 deny all from 204.152.64.0/23 to any in via $pif #Sun cluster interconnect $cmd 00308 deny all from 224.0.0.0/3 to any in via $pif #Class D & E multicast # Deny public pings $cmd 00310 deny icmp from any to any in via $pif # Deny ident $cmd 00315 deny tcp from any to any 113 in via $pif # Deny all Netbios service. 137=name, 138=datagram, 139=session # Netbios is MS/Windows sharing services. # Block MS/Windows hosts2 name server requests 81 $cmd 00320 deny tcp from any to any 137 in via $pif $cmd 00321 deny tcp from any to any 138 in via $pif $cmd 00322 deny tcp from any to any 139 in via $pif $cmd 00323 deny tcp from any to any 81 in via $pif # Deny any late arriving packets $cmd 00330 deny all from any to any frag in via $pif # Deny ACK packets that did not match the dynamic rule table $cmd 00332 deny tcp from any to any established in via $pif # Allow traffic in from ISP's DHCP server. This rule must contain # the IP address of your ISP.s DHCP server as it.s the only # authorized source to send this packet type. # Only necessary for cable or DSL configurations. # This rule is not needed for .user ppp. type connection to # the public Internet. This is the same IP address you captured # and used in the outbound section. #$cmd 00360 allow udp from any to x.x.x.x 67 in via $pif keep-state # Allow in standard www function because I have apache server $cmd 00400 allow tcp from any to me 80 in via $pif setup limit src-addr 2 # Allow in secure FTP, Telnet, and SCP from public Internet $cmd 00410 allow tcp from any to me 22 in via $pif setup limit src-addr 2 # Allow in non-secure Telnet session from public Internet # labeled non-secure because ID & PW are passed over public # Internet as clear text. # Delete this sample group if you do not have telnet server enabled. $cmd 00420 allow tcp from any to me 23 in via $pif setup limit src-addr 2 # Reject & Log all incoming connections from the outside $cmd 00499 deny log all from any to any in via $pif # Everything else is denied by default # deny and log all packets that fell through to see what they are $cmd 00999 deny log all from any to any ################ End of IPFW rules file ############################### 一个 <acronym>NAT</acronym> 和带状态规则集的例子 NAT 以及 IPFW 要使用 IPFW 的 NAT 功能, 还需要进行一些额外的配置。 除了其他 IPFIREWALL 语句之外, 还需要在内核编译配置中加上 'option divert' 语句。 /etc/rc.conf 中, 除了普通的 IPFW 配置之外, 还需要加入: natd_enable="YES" # Enable NATD function natd_interface="rl0" # interface name of public Internet NIC natd_flags="-dynamic -m" # -m = preserve port numbers if possible 将带状态规则与转发 natd 规则 (网络地址转换) 会使规则集的编写变得非常复杂。 check-state 的位置, 以及 'divert natd' 规则将变得非常关键。 这样一来, 就不再有简单的顺序处理逻辑流程了。 提供了一种新的动作类型, 称为 'skipto'。 要使用 skipto 命令, 就必须给每一个规则进行编号, 以确定 skipto 规则号是您希望跳转到的位置。 下面给出了一些未加注释的例子来说明如何编写这样的规则, 用以帮助您理解包处理规则集的处理顺序。 处理流程从规则文件最上边的第一个规则开始处理, 并自顶向下地尝试每一个规则, 直到找到匹配的规则, 且数据包从防火墙中放出为止。 请注意规则号 100 101, 450, 500, 以及 510 的位置非常重要。 这些规则控制发出和接收的包的地址转换过程, 这样它们在 keep-state 动态表中的对应项中就能够与内网的 LAN IP 地址关联。 另一个需要注意的是, 所有的 allow 和 deny 规则都指定了包的方向 (也就是 outbound 或 inbound) 以及网络接口。 最后, 请注意所有发出的会话请求都会请求 skipto rule 500 以完成网络地址转换。 下面以 LAN 用户使用 web 浏览器访问一个 web 页面为例。 Web 页面使用 80 来完成通讯。 当包进入防火墙时, 规则 100 并不匹配, 因为它是发出而不是收到的包。 它能够通过规则 101, 因为这是第一个包, 因而它还没有进入动态状态保持表。 包最终到达规则 125, 并匹配该规则。 最终, 它会通过接入 Internet 公网的网卡发出。 这之前, 包的源地址仍然是内网 IP 地址。 一旦匹配这个规则, 就会触发两个动作。 keep-state 选项会把这个规则发到 keep-state 动态规则表中, 并执行所指定的动作。 动作是发到规则表中的信息的一部分。 在这个例子中, 这个动作是 "skipto rule 500"。 规则 500 NAT 包的 IP 地址, 并将其发出。 请务必牢记, 这一步非常重要。 接下来, 数据包将到达目的地, 之后返回并从规则集的第一条规则开始处理。 这一次, 它将与规则 100 匹配, 其目的 IP 地址将被映射回对应的内网 LAN IP 地址。 其后, 它会被 check-state 规则处理, 进而在暨存会话表中找到对应项, 并发到 LAN。 数据包接下来发到了内网 LAN PC 上, 而后者则会发送从远程服务器请求下一段数据的新数据包。 这个包会再次由 check-state 规则检查, 并找到发出的表项, 并执行其关联的动作, 即 'skipto 500'。 包跳转到规则 500 并被 NAT 后发出。 在接收一侧, 已经存在的会话的数据包, 会被 check-state 规则自动地处理, 并放到转发 natd 规则。 我们需要解决的问题是, 阻止所有的坏数据包, 而只允许授权的服务。 例如在防火墙上运行了 Apache 服务, 而我们希望人们在访问 Internet 公网的同时, 也能够访问本地的 web 站点。 新的接入开始请求包将匹配规则 100, 而 IP 地址则为防火墙所在的服务器而映射到了 LAN IP。 此后, 包会匹配所有我们希望检查的那些令人生厌的东西, 并最终匹配规则 425。 一旦发生匹配, 会发生两件事。 数据包会被发到 keep-state 动态表, 但此时, 所有来自那个源 IP 的会话请求的数量会被限制为 2。 这一做法能够挫败针对指定端口上服务的 DoS 攻击。 动作同时指定了包应被发到 LAN 上。 包返回时, check-state 规则会识别出包属于某一已经存在的会话交互, 并直接把它发到规则 500 做 NAT, 并发到发出接口。 示范规则集 #1: #!/bin/sh cmd="ipfw -q add" skip="skipto 500" pif=rl0 ks="keep-state" good_tcpo="22,25,37,43,53,80,443,110,119" ipfw -q -f flush $cmd 002 allow all from any to any via xl0 # exclude LAN traffic $cmd 003 allow all from any to any via lo0 # exclude loopback traffic $cmd 100 divert natd ip from any to any in via $pif $cmd 101 check-state # Authorized outbound packets $cmd 120 $skip udp from any to xx.168.240.2 53 out via $pif $ks $cmd 121 $skip udp from any to xx.168.240.5 53 out via $pif $ks $cmd 125 $skip tcp from any to any $good_tcpo out via $pif setup $ks $cmd 130 $skip icmp from any to any out via $pif $ks $cmd 135 $skip udp from any to any 123 out via $pif $ks # Deny all inbound traffic from non-routable reserved address spaces $cmd 300 deny all from 192.168.0.0/16 to any in via $pif #RFC 1918 private IP $cmd 301 deny all from 172.16.0.0/12 to any in via $pif #RFC 1918 private IP $cmd 302 deny all from 10.0.0.0/8 to any in via $pif #RFC 1918 private IP $cmd 303 deny all from 127.0.0.0/8 to any in via $pif #loopback $cmd 304 deny all from 0.0.0.0/8 to any in via $pif #loopback $cmd 305 deny all from 169.254.0.0/16 to any in via $pif #DHCP auto-config $cmd 306 deny all from 192.0.2.0/24 to any in via $pif #reserved for docs $cmd 307 deny all from 204.152.64.0/23 to any in via $pif #Sun cluster $cmd 308 deny all from 224.0.0.0/3 to any in via $pif #Class D & E multicast # Authorized inbound packets $cmd 400 allow udp from xx.70.207.54 to any 68 in $ks $cmd 420 allow tcp from any to me 80 in via $pif setup limit src-addr 1 $cmd 450 deny log ip from any to any # This is skipto location for outbound stateful rules $cmd 500 divert natd ip from any to any out via $pif $cmd 510 allow ip from any to any ######################## end of rules ################## 下面的这个规则集基本上和上面一样, 但使用了易于读懂的编写方式, 并给出了相当多的注解, 以帮助经验较少的 IPFW 规则编写者更好地理解这些规则到底在做什么。 示范规则集 #2: #!/bin/sh ################ Start of IPFW rules file ############################### # Flush out the list before we begin. ipfw -q -f flush # Set rules command prefix cmd="ipfw -q add" skip="skipto 800" pif="rl0" # public interface name of NIC # facing the public Internet ################################################################# # No restrictions on Inside LAN Interface for private network # Change xl0 to your LAN NIC interface name ################################################################# $cmd 005 allow all from any to any via xl0 ################################################################# # No restrictions on Loopback Interface ################################################################# $cmd 010 allow all from any to any via lo0 ################################################################# # check if packet is inbound and nat address if it is ################################################################# $cmd 014 divert natd ip from any to any in via $pif ################################################################# # Allow the packet through if it has previous been added to the # the "dynamic" rules table by a allow keep-state statement. ################################################################# $cmd 015 check-state ################################################################# # Interface facing Public Internet (Outbound Section) # Interrogate session start requests originating from behind the # firewall on the private network or from this gateway server # destine for the public Internet. ################################################################# # Allow out access to my ISP's Domain name server. # x.x.x.x must be the IP address of your ISP's DNS # Dup these lines if your ISP has more than one DNS server # Get the IP addresses from /etc/resolv.conf file $cmd 020 $skip tcp from any to x.x.x.x 53 out via $pif setup keep-state # Allow out access to my ISP's DHCP server for cable/DSL configurations. $cmd 030 $skip udp from any to x.x.x.x 67 out via $pif keep-state # Allow out non-secure standard www function $cmd 040 $skip tcp from any to any 80 out via $pif setup keep-state # Allow out secure www function https over TLS SSL $cmd 050 $skip tcp from any to any 443 out via $pif setup keep-state # Allow out send & get email function $cmd 060 $skip tcp from any to any 25 out via $pif setup keep-state $cmd 061 $skip tcp from any to any 110 out via $pif setup keep-state # Allow out FreeBSD (make install & CVSUP) functions # Basically give user root "GOD" privileges. $cmd 070 $skip tcp from me to any out via $pif setup keep-state uid root # Allow out ping $cmd 080 $skip icmp from any to any out via $pif keep-state # Allow out Time $cmd 090 $skip tcp from any to any 37 out via $pif setup keep-state # Allow out nntp news (i.e. news groups) $cmd 100 $skip tcp from any to any 119 out via $pif setup keep-state # Allow out secure FTP, Telnet, and SCP # This function is using SSH (secure shell) $cmd 110 $skip tcp from any to any 22 out via $pif setup keep-state # Allow out whois $cmd 120 $skip tcp from any to any 43 out via $pif setup keep-state # Allow ntp time server $cmd 130 $skip udp from any to any 123 out via $pif keep-state ################################################################# # Interface facing Public Internet (Inbound Section) # Interrogate packets originating from the public Internet # destine for this gateway server or the private network. ################################################################# # Deny all inbound traffic from non-routable reserved address spaces $cmd 300 deny all from 192.168.0.0/16 to any in via $pif #RFC 1918 private IP $cmd 301 deny all from 172.16.0.0/12 to any in via $pif #RFC 1918 private IP $cmd 302 deny all from 10.0.0.0/8 to any in via $pif #RFC 1918 private IP $cmd 303 deny all from 127.0.0.0/8 to any in via $pif #loopback $cmd 304 deny all from 0.0.0.0/8 to any in via $pif #loopback $cmd 305 deny all from 169.254.0.0/16 to any in via $pif #DHCP auto-config $cmd 306 deny all from 192.0.2.0/24 to any in via $pif #reserved for docs $cmd 307 deny all from 204.152.64.0/23 to any in via $pif #Sun cluster $cmd 308 deny all from 224.0.0.0/3 to any in via $pif #Class D & E multicast # Deny ident $cmd 315 deny tcp from any to any 113 in via $pif # Deny all Netbios service. 137=name, 138=datagram, 139=session # Netbios is MS/Windows sharing services. # Block MS/Windows hosts2 name server requests 81 $cmd 320 deny tcp from any to any 137 in via $pif $cmd 321 deny tcp from any to any 138 in via $pif $cmd 322 deny tcp from any to any 139 in via $pif $cmd 323 deny tcp from any to any 81 in via $pif # Deny any late arriving packets $cmd 330 deny all from any to any frag in via $pif # Deny ACK packets that did not match the dynamic rule table $cmd 332 deny tcp from any to any established in via $pif # Allow traffic in from ISP's DHCP server. This rule must contain # the IP address of your ISP's DHCP server as it's the only # authorized source to send this packet type. # Only necessary for cable or DSL configurations. # This rule is not needed for 'user ppp' type connection to # the public Internet. This is the same IP address you captured # and used in the outbound section. $cmd 360 allow udp from x.x.x.x to any 68 in via $pif keep-state # Allow in standard www function because I have Apache server $cmd 370 allow tcp from any to me 80 in via $pif setup limit src-addr 2 # Allow in secure FTP, Telnet, and SCP from public Internet $cmd 380 allow tcp from any to me 22 in via $pif setup limit src-addr 2 # Allow in non-secure Telnet session from public Internet # labeled non-secure because ID & PW are passed over public # Internet as clear text. # Delete this sample group if you do not have telnet server enabled. $cmd 390 allow tcp from any to me 23 in via $pif setup limit src-addr 2 # Reject & Log all unauthorized incoming connections from the public Internet $cmd 400 deny log all from any to any in via $pif # Reject & Log all unauthorized out going connections to the public Internet $cmd 450 deny log all from any to any out via $pif # This is skipto location for outbound stateful rules $cmd 800 divert natd ip from any to any out via $pif $cmd 801 allow ip from any to any # Everything else is denied by default # deny and log all packets that fell through to see what they are $cmd 999 deny log all from any to any ################ End of IPFW rules file ############################### diff --git a/zh_CN.GB2312/books/handbook/geom/chapter.sgml b/zh_CN.GB2312/books/handbook/geom/chapter.sgml index 7726b9a0f3..052b8d5ab6 100644 --- a/zh_CN.GB2312/books/handbook/geom/chapter.sgml +++ b/zh_CN.GB2312/books/handbook/geom/chapter.sgml @@ -1,612 +1,605 @@ Tom Rhodes 原作 GEOM: 模块化磁盘变换框架 概述 GEOM GEOM 磁盘框架 GEOM 本章将介绍以 &os; GEOM 框架来使用磁盘。 这包括了使用这一框架来配置的主要的 RAID 控制工具。 这一章不会深入讨论 GEOM 如何处理或控制 I/O、 其下层的子系统或代码。 您可以从 &man.geom.4; 联机手册及其众多 SEE ALSO 参考文献中得到这些信息。 这一章也不是对 RAID 配置的权威介绍, 它只介绍由 支持GEOM 的 RAID 级别。 读完这章, 您将了解: 通过 GEOM 支持的 RAID 类型。 如何使用基本工具来配置和管理不同的 RAID 级别。 如何通过 GEOM 使用镜像、 条带、 加密和挂接在远程的磁盘设备。 如何排除挂接在 GEOM 框架上的磁盘设备的问题。 阅读这章之前, 您应: 理解 &os; 如何处理磁盘设备 ()。 了解如何配置和安装新的 &os; 内核 ()。 GEOM 介绍 GEOM 允许访问和控制类 (classes) — 主引导记录、 BSD 标签 (label), 等等 — 通过使用 provider, 或在 /dev 中的特殊文件。 它支持许多软件 RAID 配置, GEOM 能够向操作系统, 以及在其上运行的工具提供透明的访问方式。 Tom Rhodes 原作 Murray Stokely RAID0 - 条带 GEOM 条带 条带是一种将多个磁盘驱动器合并为一个卷的方法。 许多情况下, 这是通过硬件控制器来完成的。 GEOM 磁盘子系统提供了 RAID0 的软件支持, 它也成为磁盘条带。 RAID0 系统中, 数据被分为多个块, 这些块将分别写入阵列的所有磁盘。 与先前需要等待系统将 256k 数据写到一块磁盘上不同, RAID0 系统, 能够同时分别将打碎的 64k 写到四块磁盘上, 从而提供更好的 I/O 性能。 这一性能提升还能够通过使用多个磁盘控制器来进一步改进。 RAID0 条带中的每一个盘的尺寸必须一样, 因为 I/O 请求是分散到多个盘上的, 以便让这些盘上的读写并行完成。 磁盘条带图 在未格式化的 ATA 磁盘上建立条带 加载 geom_stripe 模块: &prompt.root; kldload geom_stripe 确信存在合适的挂接点 (mount point)。 如果这个卷将成为根分区, 那么暂时把它挂接到其他位置i, 如 /mnt &prompt.root; mkdir /mnt 确定将被做成条带卷的磁盘的设备名, 并创建新的条带设备。 举例而言, 要将两个未用的、 尚未分区的 ATA 磁盘 /dev/ad2/dev/ad3 做成一个条带设备: &prompt.root; gstripe label -v st0 /dev/ad2 /dev/ad3 接着需要写标准的 label, 也就是通常所说的分区表到新卷上, 并安装标准的引导代码: &prompt.root; bsdlabel -wB /dev/stripe/st0 上述过程将在 /dev/stripe 目录中的 st0 设备基础上建立两个新设备。 这包括 st0ast0c。 这时, 就可以在 st0a 设备上用下述 newfs 命令来建立文件系统了: &prompt.root; newfs -U /dev/stripe/st0a 在屏幕上将滚过一些数字, 整个操作应该能在数秒内完成。 现在可以挂接刚刚做好的卷了。 要挂接刚创建的条带盘: &prompt.root; mount /dev/stripe/st0a /mnt 要在启动过程中自动挂接这个条带上的文件系统, 需要把关于卷的信息放到 /etc/fstab 文件中: &prompt.root; echo "/dev/stripe/st0a /mnt ufs rw 2 2" \ >> /etc/fstab 此外, geom_stripe 模块也必须通过在 /boot/loader.conf 中增加下述设置, 以便在系统初始化过程中自动加载。 &prompt.root; echo 'geom_stripe_load="YES"' >> /boot/loader.conf RAID1 - 镜像 GEOM 磁盘镜像 镜像是一种许多公司和家庭用户使用的不需中断的备份技术。 当存在镜像时, 它的意思是说 磁盘B 简单地复制 磁盘A。 或者, 也可能是 磁盘C+D 复制 磁盘A+B。 无论磁盘如何配置, 共同的特征, 都是磁盘或卷的信息会被复制。 随后,在无需中断服务或访问的情况下, 可以很容易地复原和备份这些信息, 甚至把它们存储到其他更安全的地方。 要开始做这件事, 首先要确保系统中有两个同样大的磁盘驱动器, 下面的例子假定使用直接访问方式 (Direct Access, &man.da.4;) SCSI 的磁盘。 首先需要把 &os; 安装到第一块磁盘上, 并建立两个分区。 第一个分区将成为交换区, 其尺寸应该是两倍的 RAM 尺寸, 而余下的空间, 则作为根 (/) 文件系统来使用。 当然, 也可以为其他挂接点划分不同的分区; 但是, 这将使难度提高一个量级, 因为您将不得不手工修改 &man.bsdlabel.8; 和 &man.fdisk.8; 的设置。 重新启动系统, 并等待其完全初始化完。 当这个过程完成之后, 以 root 用户的身份登录。 创建 /dev/mirror/gm 设备, 并将其连接到 /dev/da1 &prompt.root; gmirror label -vnb round-robin gm0 /dev/da1 系统应会给出下列回应: Metadata value stored on /dev/da1. Done. 初始化 GEOM, 这将加载 /boot/kernel/geom_mirror.ko 内核模块: &prompt.root; gmirror load 这个命令应该会在 /dev/mirror 目录中创建 gm0 设备节点。 在刚创建的 gm0 设备上安装通用的 fdisk 标签以及引导区代码: &prompt.root; fdisk -vBI /dev/mirror/gm0 接下来安装通用的 bsdlabel 信息: &prompt.root; bsdlabel -wB /dev/mirror/gm0s1 如果存在多个区段 (slice) 或分区 (partition), 则需要修改一部分上面命令的参数。 它们必须与另一个盘上对应的区段和分区匹配。 使用 &man.newfs.8; 工具来在 gm0s1a 设备上建立默认的 UFS 文件系统: &prompt.root; newfs -U /dev/mirror/gm0s1a 这将让系统输出很多信息和一系列数字。 不必为此担心, 只需看看是否有错误提示就可以了, 如果没问题, 接下来把它挂到 /mnt 挂接点上面: &prompt.root; mount /dev/mirror/gm0s1a /mnt 现在需要把所有引导盘上的数据迁移到新的文件系统上了。 下面的例子使用了 &man.dump.8; 和 &man.restore.8; 这两个命令; 不过, 用 &man.dd.1; 在这里也可以达到完全一样的目的。 &prompt.root; dump -L -0 -f- / |(cd /mnt && restore -r -v -f-) 这个操作必须在所有文件系统上都作一遍。 您可以将前述命令中的文件系统, 改为所希望的文件系统的位置。 接下来应该编辑复制出来的 /mnt/etc/fstab 文件, 并删去或注释掉交换文件 需要注意的是, 在 fstab 注释掉交换文件, 通常会需要您以其他方式重建交换空间。 请参见 以了解进一步的细节。 。 修改其他文件系统对应的信息, 以便让它们使用新盘。 参考下面的例子: # Device Mountpoint FStype Options Dump Pass# #/dev/da0s2b none swap sw 0 0 /dev/mirror/gm0s1a / ufs rw 1 1 - 接下来应在当前和新 root 分区中分别建立一个 boot.config 文件。 它会 - 帮助 系统的 BIOS - 从正确的驱动器上引导: - - &prompt.root; echo "1:da(1,a)/boot/loader" > /boot.config - - &prompt.root; echo "1:da(1,a)/boot/loader" > /mnt/boot.config - - - 在所有的分区上都放这些是为了保证系统能够正确引导。 - 如果由于某种原因系统无法从新的根分区读数据, - 则还有一根救命稻草。 - - 用下面的命令来确保系统引导时会加载 geom_mirror.ko &prompt.root; echo 'geom_mirror_load="YES"' >> /mnt/boot/loader.conf + &prompt.root; echo 'geom_mirror_load="YES"' >> /boot/loader.conf 最后重新启动系统: &prompt.root; shutdown -r now - 如果一切顺利, 系统将从 - gm0s1a 设备启动, 并给出 login - 提示等待用户登录。 如果发生错误, 请查阅接下来的故障排除环节。 我们接着将 - da0 磁盘也加入 gm0 - 设备: + 在启动时选择第 4 个选项进入单用户模式。 在控制台, + 可以通过 &man.df.1; 的输出来确认系统是从 + gm0s1a 启动的。 + + 如果一切顺利,系统将从 gm0s1a + 设备启动。 现在可以使用以下命令清除主磁盘并插入镜像中: + + &prompt.root; dd if=/dev/zero of=/dev/da0 bs=512 count=79 &prompt.root; gmirror configure -a gm0 &prompt.root; gmirror insert gm0 /dev/da0 此处 告诉 &man.gmirror.8; 采用自动同步, 或换言之: 自动地将磁盘的写操作做镜像处理。 联机手册中详细解释了如何重建, 以及替换磁盘, 只不过它用 data 表示这里的 gm0 + 在镜像建立后,可以用如下命令检查镜像的状态: + + &prompt.root; gmirror status + 故障排除 - 系统拒绝引导 如果系统引导时出现类似下面的提示: ffs_mountroot: can't find rootvp Root mount failed: 6 mountroot> 这种情况应使用电源或复位按钮重启机器。 在引导菜单中, 选择第六 (6) 个选项。 这将让系统进入 &man.loader.8; 提示符。 在此处手工加载内核模块: OK? load geom_mirror OK? boot 如果这样做能解决问题, 则说明由于某种原因模块没有被正确加载。 可以通过在内核配置文件中加入: options GEOM_MIRROR 然后重新编译和安装内核来解决这个问题。 GEOM Gate 网络设备 通过 gate 工具, GEOM 支持以远程方式使用设备, 例如磁盘、 CD-ROM、 文件等等。 这和 NFS 类似。 在开始工作之前, 首先要创建一个导出文件。 这个文件的作用是指定谁可以访问导出的资源, 以及提供何种级别的访问授权。 例如, 要把第一块 SCSI 盘的第四个 slice 导出, 对应的 /etc/gg.exports 会是类似下面的样子: 192.168.1.0/24 RW /dev/da0s4d 这表示允许同属私有子网的所有机器访问 da0s4d 分区上的文件系统。 要导出这个设备, 首先请确认它没有被挂接, 然后是启动 &man.ggated.8; 服务: &prompt.root; ggated 现在我们将在客户机上 mount 该设备, 使用下面的命令: &prompt.root; ggatec create -o rw 192.168.1.1 /dev/da0s4d ggate0 &prompt.root; mount /dev/ggate0 /mnt 到此为止, 设备应该已经可以通过挂接点 /mnt 访问了。 请注意, 如果设备已经被服务器或网络上的任何其他机器挂接, 则前述操作将会失败。 如果不再需要使用这个设备, 就可以使用 &man.umount.8; 命令来安全地将其卸下了, 这一点和其他磁盘设备类似。 为磁盘设备添加卷标 GEOM 磁盘卷标 在系统初始化的过程中, &os; 内核会为检测到的设备创建设备节点。 这种检测方式存在一些问题, 例如, 在通过 USB 添加设备时应如何处理? 很可能有闪存盘设备最初被识别为 da0 而在这之后, 则由 da0 变成了 da1。 而这则会在挂接 /etc/fstab 中的文件系统时造成问题, 这些问题, 还可能在系统引导时导致无法正常启动。 解决这个问题的一个方法是以连接拓扑方式链式地进行 SCSI 设备命名, 这样, 当在 SCSI 卡上增加新设备时, 这些设备将使用一个未用的编号。 但如果 USB 设备取代了主 SCSI 磁盘的位置呢? 由于 USB 通常会在 SCSI 卡之前检测到, 因此很可能出现这种现象。 当然, 可以通过在系统引导之后再插入这些设备来绕过这个问题。 另一种绕过这个问题的方法, 则是只使用 ATA 驱动器, 并避免在 /etc/fstab 中列出 SCSI 设备。 还有一种更好的解决方法。 通过使用 glabel 工具, 管理员或用户可以为磁盘设备打上标签, 并在 /etc/fstab 中使用这些标签。 由于 glabel 会将标签保存在对应 provider 的最后一个扇区, 在系统重启之后, 它仍会持续存在。 因此, 通过将具体的设备替换为使用标签表示, 无论设备节点变成什么, 文件系统都能够顺利地完成挂接。 这并不是说标签一定是永久性的。 glabel 工具既可以创建永久性标签, 也可以创建临时性标签。 在重启时, 只有永久性标签会保持。 请参见联机手册 &man.glabel.8; 以了解两者之间的差异。 标签类型和使用示范 有两种类型的标签, 一种是普通标签, 另一种是文件系统标签。 两者的差异体现在是否能够自动检测, 以及是否在重启后保持。 这些标签会放到 /dev 中的特殊目录中, 这些目录的名字取决于文件系统类型。 例如, UFS2 文件系统的标签会创建到 /dev/ufs2 目录中。 普通标签在系统下次重启时会消失, 这些标签会创建到 /dev/label 目录中, 很适合测试之用。 永久性标签可以使用 tunefsnewfs 工具来创建。 要为 UFS2 文件系统创建标签, 而不破坏其上的数据, 可以使用下面的命令: &prompt.root; tunefs -L home /dev/da3 如果文件系统满了, 这可能会导致数据损坏; 不过, 如果文件系统快满了, 此时应首先删除一些无用的文件, 而不是增加标签。 现在, 您应可以在 /dev/ufs2 目录中看到标签, 并将其加入 /etc/fstab /dev/ufs2/home /home ufs rw 2 2 当运行 tunefs 时, 应首先卸下文件系统。 现在可以像平时一样挂接文件系统了: &prompt.root; mount /home 现在, 只要在系统引导时通过 /boot/loader.conf 配置加载了内核模块 geom_label.ko, 或在联编内核时指定了 GEOM_LABEL 选项, 设备节点由于增删设备而顺序发生变化时, 就不会影响文件系统的挂接了。 通过使用 newfs 命令的 参数, 可以在创建文件系统时为其添加默认的标签。 请参见联机手册 &man.newfs.8; 以了解进一步的详情。 下列命令可以清除标签: &prompt.root; glabel destroy home 通过 GEOM 实现 UFS 日志 GEOM 日志 随着 &os; 7.0 的发布, 实现了长期为人们所期待的 UFS 日志。 这个实现采用了 GEOM 子系统, 可以很容易地使用 &man.gjournal.8; 工具来进行配置。 日志是什么? 日志的作用是保存文件系统事务的记录, 换言之, 完成一次完整的磁盘写入操作所需的变动, 这些记录会在元数据以及文件数据写盘之前, 写入到磁盘中。 这种事务日志可以在随后用于重放并完成文件系统事务, 以避免文件系统出现不一致的问题。 这种方法是另一种阻止文件系统丢失数据并发生不一致的方法。 与 Soft Updates 追踪并确保元数据更新顺序这种方法不同, 它会实际地将日志保存到磁盘最后的扇区, 或另外一块磁盘上。 与其他文件系统的日志实现不同, gjournal 采用的是基于块, 而不是作为文件系统的一部分的方式 - 它只是作为一种 GEOM 扩展实现。 如果希望启用 gjournal, &os; 内核需要下列选项 - 这是 7.X 系统上的默认配置: options UFS_GJOURNAL 现在, 可以为空闲的文件系统创建日志了。 对于新增的 SCSI 磁盘 da4, 具体的操作步骤为: &prompt.root; gjournal label /dev/da4 &prompt.root; gjournal load 这样, 就会出现一个与 /dev/da4 设备节点对应的 /dev/da4.journal 设备节点。 接下来, 可以在这个设备上简历文件系统: &prompt.root; newfs -O 2 -J /dev/da4.journal 这个命令将建立一个包含日志的 UFS2 文件系统。 然后就可以用 mount 命令来挂接设备了: &prompt.root; mount /dev/da4.journal /mnt 当磁盘包含多个 slice 时, 每个 slice 上都会建立日志。 例如, 如果有 ad4s1ad4s2 这两个 slice, 则 gjournal 会建立 ad4s1.journalad4s2.journal。 如果连续运行两次这个命令, 则会建立 多层日志 在某些情况下, 可能会希望在其他磁盘上保存日志。 对于这些情形, 日志提供者或存储设备, 应在启用日志的设备后给出。 在暨存的文件系统上, 可以用 tunefs 来启用日志; 不过, 在尝试修改文件系统之前, 您应对其进行备份。 多数情况下, gjournal 会因为无法建立日志而失败, 在误用 tunefs 时, 这可能导致失败。 diff --git a/zh_CN.GB2312/books/handbook/introduction/chapter.sgml b/zh_CN.GB2312/books/handbook/introduction/chapter.sgml index 2911e5ca4d..0ef9e3bf1d 100644 --- a/zh_CN.GB2312/books/handbook/introduction/chapter.sgml +++ b/zh_CN.GB2312/books/handbook/introduction/chapter.sgml @@ -1,864 +1,864 @@ Jim Mock Restructured, reorganized, and parts rewritten by 介绍 概述 非常感谢您对 FreeBSD 感兴趣! 下面的章节涵盖了 FreeBSD 项目的各个方面, 比如它的历史、目标、开发模式,等等。 阅读完这章,您将了解: FreeBSD 与其它计算机操作系统的关系。 FreeBSD 项目的历史。 FreeBSD 项目的目标。 FreeBSD 开放源代码开发模式的基础。 当然还有:FreeBSD 这个名称的由来。 欢迎来到 FreeBSD 的世界! 4.4BSD-Lite FreeBSD 是一个支持 Intel (x86 和 &itanium;),AMD64,Alpha,Sun &ultrasparc; 计算机的基于 4.4BSD-Lite 的操作系统。 到其他体系结构的移植也在进行中。 您也可以阅读 FreeBSD 的历史, 或者最新的发行版本。 如果您有意捐助(代码, 硬件,基金),请看为 FreeBSD 提供帮助这篇文章。 FreeBSD 能做些什么? FreeBSD有许多非凡的特性。其中一些是: 抢占式多任务 抢占式多任务与动态优先级调整确保在应用程序和用户之间平滑公正的分享计算机资源, 即使工作在最大的负载之下。 多用户设备 多用户设备 使得许多用户能够同时使用同一 FreeBSD 系统做各种事情。 比如, 像打印机和磁带驱动器这样的系统外设, 可以完全地在系统或者网络上的所有用户之间共享, 可以对用户或者用户组进行个别的资源限制, 以保护临界系统资源不被滥用。 TCP/IP 网络 符合业界标准的强大 TCP/IP 网络 支持, 例如 SCTP、 DHCP、 NFS、 NIS、 PPP, SLIP, IPsec 以及 IPv6。 这意味着您的 FreeBSD 主机可以很容易地和其他系统互联, 也可以作为企业的服务器,提供重要的功能, 比如 NFS(远程文件访问)以及 email 服务, 或将您的组织接入 Internet 并提供 WWW,FTP,路由和防火墙(安全)服务。 内存保护 内存保护确保应用程序(或者用户)不会相互干扰。 一个应用程序崩溃不会以任何方式影响其他程序。 FreeBSD 是一个 32 位操作系统 (在 Alpha,&itanium;,AMD64,和 &ultrasparc; 上是64 位), 并且从开始就是如此设计的。 X Window 系统 XFree86 业界标准的 X Window 系统 (X11R7)为便宜的常见 VGA 显示卡和监视器提供了一个图形化的用户界面(GUI), 并且完全开放代码。 二进制代码兼容性 Linux 二进制代码兼容性 SCO 二进制代码兼容性 SVR4 二进制代码兼容性 BSD/OS 二进制代码兼容性 NetBSD 和许多 Linux,SCO,SVR4,BSDI 和 NetBSD 程序的二进制代码兼容性 数以千计的 ready-to-run 应用程序可以从 FreeBSD portspackages 套件中找到。 您可以顺利地从这里找到, 何须搜索网络? 可以在 Internet 上找到成千上万其它 easy-to-port 的应用程序。 FreeBSD 和大多数流行的商业 &unix; 代码级兼容, 因此大多数应用程序不需要或者只要很少的改动就可以编译。 虚拟内存 页式请求虚拟内存集成的 VM/buffer 缓存设计有效地满足了应用程序巨大的内存需求并依然保持其他用户的交互式响应。 对称多处理器(SMP) SMP 提供对多处理器的支持。 编译器 C 编译器 C++ 编译器 FORTRAN 内建了完整的 CC++Fortran 开发工具。 许多附加的用于高级研究和开发的程序语言, 也可以在通过 ports 和 packages 套件获得。 源代码 完整的系统源代码意味着您对您环境的最大程度的控制。 当您拥有了一个真正的开放系统时, 为什么还要受困于私有的解决方案, 任商业公司摆布呢? 丰富的在线文档 不仅如此! 4.4BSD-Lite 计算机系统研究组(CSRG) U.C. Berkeley FreeBSD 基于加州大学伯克利分校计算机系统研究组(CSRG)发布的 4.4BSD-Lite, 继承了 BSD 系统开发的优良传统。 除了 CSRG 优秀的工作之外, FreeBSD 项目花费了非常多的时间来优化调整系统, 使其在真实负载情况下拥有最好的性能和可靠性。 在现今, 许多商业巨人正为给 PC 操作系统增加新功能、 提升和改善其可靠性, 以便在其上展开激烈竞争的同时, FreeBSD 现在 已经能够提供所有这一切了! FreeBSD 可以提供的应用事实上仅局限于您的想象力。 从软件开发到工厂自动化,从存货控制到遥远的人造卫星天线方位控制, 如果商业的 &unix; 产品可以做到,那么就非常有可能您也可以用 FreeBSD 来做! FreeBSD 也极大地受益于全世界的研究中心和大学开发的数以千计的高质量的应用程序, 这些程序通常只需要很少的花费甚至免费。 可用的商业应用程序, 每天也都在大量地增加。 因为 FreeBSD 自身的源代码是完全公开的, 所以对于特定的应用程序或项目,可以对系统进行最大限度的定制。 这对于大多数主流的商业生产商的操作系统来说几乎是不可能的。 以下是当前人们应用 FreeBSD 的某些程序的例子: Internet 服务:FreeBSD 内建的强大的 TCP/IP 网络使它得以成为各种 Internet 服务的理想平台,比如: FTP 服务器 FTP 服务器 web 服务器 World Wide Web 服务器(标准的或者安全的 [SSL]) IPv4 and IPv6 路由 防火墙 NAT 防火墙和 NAT(IP 伪装) 网关 电子邮件 email email 电子邮件服务器 USENET USENET 新闻组和电子布告栏系统 还有许多... 使用 FreeBSD, 您可以容易地从便宜的 386 类 PC 起步,并随着您的企业成长,一路升级到带有 RAID 存储的四路 Xeon 服务器。 教育:您是一名计算机科学或者相关工程领域的学生吗? 学习操作系统,计算机体系结构和网络没有比在 FreeBSD 可提供的体验下动手实践更好的办法了。许多可自由使用的 CAD、数学和图形设计包也使它对于那些主要兴趣是在计算机上完成其他工作的人非常有帮助。 研究:有完整的系统源代码, FreeBSD 对于操作系统研究以及其他计算机科学分支都是一个极好的平台。 FreeBSD 可自由获得的本性, 同样可以使处在不同地方的开发团队在开放的论坛上讨论问题、 交流想法与合作开发成为可能, 且不必担心特别的版权协定或者限制。 路由 DNS 服务器 网络:需要一个新的路由器? 一台域名服务器 (DNS)? 一个隔离您的内部网络的防火墙? FreeBSD 可以容易的把丢弃在角落不用的 386 或者 486 PC 变成一台完善的带包过滤能力的高级路由器。 X Window 系统 XFree86 X Window 系统 Accelerated-X X Window 工作站: FreeBSD 是廉价 X 终端的一种绝佳解决方案, 您可以选择使用免费的 X11 服务器。 与 X 终端不同,如果需要的话 FreeBSD 能够在本地直接运行程序, 因而减少了中央服务器的负担。 FreeBSD 甚至能够在 无盘 环境下启动, 这使得终端更为便宜和易于管理。 GNU Compiler Collection 软件开发: 基本的 FreeBSD 系统带有包括著名的 GNU C/C++ 编译器和调试工具在内的一整套开发工具。 FreeBSD 可以通过 CDROM、DVD, 以及匿名 FTP 以源代码和二进制方式获得。请查看 了解获取 FreeBSD 的更多细节。 谁在使用 FreeBSD? 用户 运行 FreeBSD 的大型站点 FreeBSD 已被用来支持 Internet 上一些最大的站点, 包括: Yahoo! Yahoo! Apache Apache Blue Mountain Arts Blue Mountain Arts Pair Networks Pair Networks Sony Japan Sony Japan Netcraft Netcraft Weathernews Weathernews Supervalu Supervalu TELEHOUSE America TELEHOUSE America Sophos Anti-Virus Sophos Anti-Virus JMA Wired JMA Wired 等等许多。 关于 FreeBSD 项目 下面的章节提供了项目的一些背景信息, 包括简要的历史、项目目标、以及项目开发模式。 Jordan Hubbard Contributed by FreeBSD 的简要历史 386BSD Patchkit Hubbard, Jordan Williams, Nate Grimes, Rod FreeBSD 项目 历史 FreeBSD 项目起源于 1993 年早期, 部分作为 Unofficial 386BSD Patchkit 的副产物,patchkit 的最后 3 个协调维护人是:Nate Williams,Rod Grimes 和我。 386BSD 我们最初的目标是做出一份 386BSD 的测试版以修正一些 Patchkit 机制无法解决的错误(bug)。 很多人可能还记得早期的项目名称叫做 386BSD 0.5 或者 386BSD Interim 就是这个原因。 Jolitz, Bill 386BSD 是 Bill Jolitz 的操作系统, 到那时已被严重地忽视了一年之久。 由于 Patchkit 在过去的每一天里都在急剧膨胀, 使得对其进行消化吸收变得越来越困难, 因此我们一致同意应该做些事情并决定通过提供这个临时的 cleanup 版本来帮助 Bill。 然而,Bill 却在事先没有指出这个项目应该如何开展下去的情况下, 突然决定退出这个项目,最终这个计划只好被迫停止。 Greenman, David Walnut Creek CDROM 没过多久, 我们认为即便没有 Bill 的支持, 项目仍有保留的价值, 因此,我们采用了 David Greenman 的意见,给其命名为 FreeBSD。在和当时的几个用户商量后, 我们提出了最初的目标, 而这件事明朗化后, 这个项目就走上了正轨,甚至可能成为现实。 为了拓展 FreeBSD 的发行渠道,我抱着试试看的心态, 联系了光盘商 Walnut Creek CDROM, 以便那些上网不方便的用户得到 FreeBSD。 Walnut Creek CDROM 不仅支持发行 FreeBSD 光盘版的想法, 还为这个计划提供了所需的计算机和高速网络接入。 在那时, 若没有 Walnut Creek CDROM 对一个完全未知的项目的空前信任, FreeBSD 不太可能像它今天这样,影响如此深远,发展如此快速。 4.3BSD-Lite Net/2 U.C. Berkeley 386BSD Free Software Foundation 第一个 CDROM (以及在整个互联网范围内发行的) 发行版本是 FreeBSD 1.0,于 1993 年 10 月发布。这个版本基于 U.C. Berkeley 的 4.3BSD-Lite(Net/2)磁带, 也有许多组件是 386BSD 和自由软件基金会提供的。 对于第一次发行,这算是相当成功了。 在 1994 年 5 月,我们发布了更加成功的 FreeBSD 1.1 版。 Novell U.C. Berkeley Net/2 AT&T 然而此后不久,发生了一些意外的情况。 Novell 和 U.C. Berkeley 决定就 Berkeley Net/2 磁带的归属权问题打的那场马拉松式的官司达成和解。 判决的结果是, U.C. Berkeley 承认 Net/2 很大一部分代码是侵占来的 且这些代码归 Novell 公司所拥有。这些代码是 Novell 不久前从 AT&T 买来的。 Berkeley 得到了来自 Novell 的 祝福: 4.4BSD-Lite 发行后,将不认为是侵权, 且要求现存的 Net/2 的用户更换新版。 这也包括 FreeBSD,我们的项目被要求在 1994 年 6 月底停止发行基于 Net/2 的产品。在此协议允许的时间内, 本项目被允许发行最后一版,也就是 FreeBSD 1.1.5.1。 于是 FreeBSD 开始艰苦的从全新的而且不完整的 4.4BSD-Lite 中重新整合自己。Lite 版本是不完整的, 因为 Berkeley 的 CSRG 已经删除了大量的构建可启动运行的系统所需要的代码 (因为各种各样的版权问题),事实上 4.4 的 Intel port 是非常不完整的。 直到 1994 年 11 月项目才完成这个转换,这个时候才把 FreeBSD 2.0 通过网络和 CDROM(在 12 月)发布出来。 尽管系统很多地方还很粗糙,这个版本还是取得了重大的成功, 接下来在 1995 年 6 月发布了更强大和容易安装的 FreeBSD 2.0.5 版本。 我们于 1996 年 8 月发布了 FreeBSD 2.1.5 版本, 它在 ISP 和商业团体中非常流行。 随后, 2.1-STABLE 分支的另一个版本应运而生,它就是 FreeBSD 2.1.7.1,在 1997 年 2 月发布并停止了 2.1-STABLE 的主流开发。现在,它处于维护状态, 仅仅提供安全性的增强和其他严重的错误修补的维护(RELENG_2_1_0)。 FreeBSD 2.2 版作为 RELENG_2_2 分支,于 1996 年 11 月从开发主线 (-CURRENT)分出来。 它的第一个完整版(2.2.1)于 1997 年 4 月发布出来。 97 年夏秋之间,顺着 2.2 分支的更进一步的版本在开发。 其最后一版(2.2.8)于 1998 年 11 月发布出来。 第一个官方的 3.0 版本出现在 1998 年 10 月, 意味着 2.2 分支结束的开始。 1999 年 1 月 20 日又出现了新的分支,就是 4.0-CURRENT 和 3.X-STABLE 分支。从 3.X-STABLE 起,3.1 在 1999 年 2 月 15 日发行,3.2 在1999 年 5 月 15 日,3.3 在 1999 年 9 月 16 日,3.4 在 1999 年 12 月 20 日,3.5 在 2000 年 6 月 24 日,接下来几天后发布了很少的修补升级至 3.5.1,加入了对 Kerberos 安全性方面的修补。 这是 3.X 分支最后一个发行版本。 随后在 2000 年 3 月 13 日出现了一个新的分支, 也就是 4.X-STABLE。 这之后发布了许多的发行版本: 4.0-RELEASE 于 2000 年 3月发布, 而最后的 4.11-RELEASE 则是在 2005 年 1 月发布的。 期待已久的 5.0-RELEASE 于 2003 年 1 月 19 日正式发布。 这是将近三年的开发的巅峰之作, 同时也标志了 FreeBSD 在先进的多处理器和应用程序线程支持的巨大成就, 并引入了对于 &ultrasparc; 和 ia64 平台的支持。 之后于 2003 年 6 月发布了 5.1。 最后一个从 -CURRENT 分支的 5.X 版本是 5.2.1-RELEASE, 它在 2004 年 2 月正式发布。 RELENG_5 于 2004 年 8 月正式创建, 紧随其后的是 5.3-RELEASE, 它是 5-STABLE 分支的标志性发行版。 最新的 &rel2.current;-RELEASE 是在 &rel2.current.date; 发布的。 RELENG_5 分支不会有后续的发行版了。 其后在 2005 年 7 月又建立了 RELENG_6 分支。 而 6.X 分支上的第一个版本, 即 6.0-RELEASE, 则是在 2005 年 11 月发布的。 最新的 &rel.current;-RELEASE 发布于 &rel.current.date;。 我们还将继续从 RELENG_6 发布新的版本。 目前, 中长期的开发项目继续在 7.X-CURRENT (主干, trunk) 分支中进行, 而 6.X 的 CDROM (当然, 也包括网络) 快照版本可以在 快照服务器 找到。 Jordan Hubbard Contributed by FreeBSD 项目目标 FreeBSD Project goals FreeBSD 项目的目标是无附加条件地提供能够用于任何目的的软件。 我们中的许多人对代码 (以及项目本身) 都有非常大的投入, 因此当然不介意偶尔有一些资金上的补偿, 但我们并没打算坚决地要求得到这类资助。 我们认为我们的首要 使命 是为任何人提供代码, 不管他们打算用这些代码做什么, 因为这样代码将能够被更广泛地使用, 从而最大限度地发挥其价值。 我认为这是自由软件最基本的, 同时也是为我们所倡导的一个目标。 GNU General Public License (GPL) GNU Lesser General Public License (LGPL) BSD Copyright 我们源代码树中, 以 GNU 公共许可证 (GPL) 或者 GNU 函数库公共许可证 (LGPL) 发布的那些代码带有少许的附加限制, 还好只是强制性的要求开放代码而不是别的。 由于使用 GPL 的软件在商业用途上会增加若干复杂性, 因此,如果可以选择的话, 我们更偏好使用限制相对更宽松的 BSD 版权来发布软件。 Satoshi Asami 撰写者 FreeBSD 开发模式 FreeBSD Project 开发模式 FreeBSD 的开发是一个非常开放且有有伸缩性的过程, 就像从我们的 贡献者列表里看到的,它是完全由来自全世界的数以百计的贡献者发展起来的。 FreeBSD 的开发基础结构允许数以百计的开发者通过互联网协同工作。 我们也经常关注着那些对我们的计划感兴趣的新开发者和新的创意, 那些有兴趣更进一步参与项目的人只需要在 &a.hackers; 联系我们。 &a.announce; 对那些希望了解我们工作所涉及到哪些领域的人也是有用的。 无论是独立地工作或者封闭式的团队工作, 了解FreeBSD计划和它的开发过程都是有益的: CVS 代码库 CVS 代码库 并行版本系统 CVS FreeBSD 的中央源代码树是由 CVS (并行版本控制系统)来维护的。CVS 是一个与 FreeBSD 捆绑的可自由获得的源代码控制工具。 主 CVS 代码库放置在美国加利福尼亚州圣克拉拉的一台机器上, 它被复制到全世界的大量镜像站上。CVS 中包括了 -CURRENT 和 -STABLE 树, 它同样可以很容易地复制到您的机器上。 请查阅 同步您的源代码树这一章节来了解更多信息。 committer 列表 committers committer 是那些对 CVS 树有权限的人, 他们被授权修改 FreeBSD 的源代码 (术语 committer 来自于 &man.cvs.1; 的 commit 命令,这个命令用来把新的修改提交给 CVS 代码库)。提交修正的最好方法是使用 &man.send-pr.1; 命令。如果您发现在系统中出现了一些问题的话, 您也可以通过邮件将它们发送至 &a.committers;。 FreeBSD 核心团队 core team 如果把 FreeBSD 项目看作一家公司,那么 FreeBSD 核心团队就相当于董事会。 核心团队的主要任务是提出总体上的发展计划,然后确定一个正确的方向。 邀请那些富有献身精神和可靠的开发者加入到 committer 队伍中来也是核心团队的工作之一, 这些新的成员将作为新核心团队成员和其他人一起继续前进。 当前的核心团队是 2006 年 7 月从 committer 中选举产生的。选举每两年一次。 一些核心团队的成员还负责特定的责任范围, 也就是说他们必须尽力确保某个子系统能工作正常。 FreeBSD 开发者的完整列表和他们的责任范围,请参见 贡献者列表 核心团队的大部分成员加入 FreeBSD 开发的时候都是志愿的, 并没有从项目中获得任何财政上的资助, 所以承诺不应该被理解为支持保证。 前面所述董事会的类推并不十分准确, 或许更好的说法是,他们是一群愿意放弃他们的生活, 投身于 FreeBSD 项目而非选择其个人更好的生活的人! 外围贡献者 contributors 事实上,最大的开发团队正是为我们提供反馈和错误修补的用户自己。 FreeBSD 的非集中式的开发者保持联系的主要方式就是预订 &a.hackers;,很多事情在那里讨论。查看了解众多 FreeBSD 邮件列表的更多信息。 FreeBSD 贡献者列表 很长并在不断增长, 为什么不加入它来为 FreeBSD 做贡献呢? 提供代码不是为这个计划做贡献的唯一方式; 有一个更完整的需要做的事情的列表,可以参见 FreeBSD 项目网站 总的来说,我们的开发模式好像是一组没有拘束的同心圆。 这种集中式的开发模式,主要是考虑到用户的方便, 同时让他们能很容易地维护同一份软件, 而不会把潜在的贡献者排除在外! 我们的目标是提供一个包含有大量具有一致性 应用程序的稳定的操作系统, 以利于用户的安装和使用,— 这种模式在完成目标的过程中工作得非常有效。 我们对于那些想要加入,成为FreeBSD开发者的期待是: 具有如同当前其他人一样的投入,来确保持续的成功! 最新的 FreeBSD 发行版本 NetBSD OpenBSD 386BSD Free Software Foundation U.C. Berkeley Computer Systems Research Group (CSRG) FreeBSD 是一个免费使用且带有完整源代码的基于 4.4BSD-Lite 的系统, 它广泛运行于 Intel &i386;、&i486;、&pentium;、 &pentium; Pro、 &celeron;、 &pentium; II、 &pentium; III、 &pentium; 4(或者兼容系统)、 &xeon;、DEC Alpha 和 Sun &ultrasparc; 的计算机系统上。 它主要以 加州大学伯克利分校 的 CSRG 研究小组的软件为基础,并加入了 NetBSD、OpenBSD、386BSD 以及来自 自由软件基金会 的一些东西。 自从 1994 年末我们的 FreeBSD 2.0 发行以来, FreeBSD 的性能,可定制性,稳定性都有了令人注目的提高。 最大的变化是通过 整合虚拟内存/文件系统 中的高速缓存改进的虚拟内存系统, 它不仅提升了性能,而且减少了 FreeBSD 对内存的需要, 使得 5 MB 内存成为可接受的最小配置。 其他的改进包括完整的 NIS 客户端和服务器端的支持, 事务式 TCP 协议支持,按需拨号的 PPP,集成的 DHCP 支持,改进的 SCSI 子系统, ISDN 的支持,ATM,FDDI,快速 Gigabit 以太网(1000 Mbit)支持, 提升了最新的 Adaptec 控制器的支持和修补了很多的错误。 除了最基本的系统软件,FreeBSD 还提供了一个拥有成千上万广受欢迎的程序组成的软件的 Ports Collection。 到本书付印时,已有超过 &os.numports; 个 ports (ports 包括从 http(WWW) 服务器到游戏、程序设计语言、编辑器以及您能想到的几乎所有的东西)。 完整的 Ports Collection 大约需要 &ports.size; 的存储空间。所有的只提供对原始代码的 修正。这使得我们能够容易地更新软件, 而且减少了老旧的 1.0 Ports Collection 对硬盘空间的浪费。 要编译一个 port,您只要切换到您想要安装的程序的目录, 输入 make install,然后让系统去做剩下的事情。 您要编译的每一个程序完整的原始代码可以从 CDROM 或本地 FTP 获得,所以您只需要编译您想要软件的足够的磁盘空间。 几乎大多数的软件都提供了事先编译好的 package 以方便安装,对于那些不希望从源代码编译他们自己的 ports 的人只要使用一个简单的命令 (pkg_add)就可以安装。 有关 package 和 ports 的更多信息可以在中找到。 您可以在最近的 FreeBSD 主机的 /usr/share/doc 目录下找到许多有用的文件来帮助您安装及使用 FreeBSD。 您也可以用一个 HTML 浏览器来查阅本地安装的手册, 使用下面的 URL: FreeBSD 使用手册 /usr/share/doc/handbook/index.html FreeBSD FAQ /usr/share/doc/faq/index.html 您也可以查看在 的主站上的副本。 diff --git a/zh_CN.GB2312/books/handbook/kernelconfig/chapter.sgml b/zh_CN.GB2312/books/handbook/kernelconfig/chapter.sgml index 245626fe7e..027087371b 100644 --- a/zh_CN.GB2312/books/handbook/kernelconfig/chapter.sgml +++ b/zh_CN.GB2312/books/handbook/kernelconfig/chapter.sgml @@ -1,1239 +1,1316 @@ Jim Mock Updated and restructured by Jake Hamby Originally contributed by 配置FreeBSD的内核 概述 内核 建立一个定制的内核 内核是 &os; 操作系统的核心。 它负责管理内存、 执行安全控制、 网络、 磁盘访问等等。 尽管 &os; 可以动态修改的现在已经越来越多, 但有时您还是需要重新配置和编译您的内核。 读完这章,您将了解: 为什么需要建立定制的内核。 如何编写内核配置文件,或修改已存在的配置文件。 如何使用内核配置文件创建和联编新的内核。 如何安装新内核。 如何处理出现的问题。 这一章给出的命令应该以 root 身份执行, 否则可能会不成功。 为什么需要建立定制的内核? 过去, &os; 采用称作 单片式 的内核。 这句话的意思是说内核是一个大的程序, 支持固定的设备, 如果您希望改变内核的行为则必须编译一个新的, 并重新启动计算机来引导它。 今天, &os; 已经迅速地转移到了一个新的模型, 其重要特征是内核功能可以由能够根据需要动态加载和卸载的模块来提供。 这使得内核能够迅速地适应硬件的调整 (例如笔记本电脑的 PCMCIA), 或为内核增加在最初编译它时所不具备的新的功能。 这一模式成为模块化内核。 尽管如此, 一些功能仍然需要静态地连编进内核。 一些情况是因为这些功能于内核的结合十分紧密, 而不可能将它们做成可以动态加载的。 另一种情况是因为没有人有时间来编写实现那个功能的可以动态加载的内核模块。 建造定制的内核是几乎每一个 BSD 用户所必须经历的一关。 尽管这项工作可能比较耗时, 但它能够为使用 &os; 系统带来很多好处。 与必须支持大量各式硬件的 GENERIC 内核不同, 定制的内核可以只包含对于 您的 PC 硬件的支持。 这有很多好处, 例如: 更快地启动。 因为内核只需要检测您系统上的硬件, 启动时所花费的时间将大大缩短。 使用更少的内存。 定制的内核通常会比 GENERIC 内核使用更少的内存, 由于内核必须时刻处于物理内存中, 因此这就显得更加重要。 基于这样的原因, 对于内存较小的系统来说, 定制内核将发挥更大的作用。 支持更多的硬件。 定制的内核允许您增加类似声卡这样的 GENERIC 内核没有提供内建支持的硬件。 + + + + + Tom + Rhodes + 作者 + + + + 发现系统硬件 + + 在尝试配置内核以前,比较明智的做法是先获得一份机器硬件的清单。 + 当 &os; 并不是主操作系统时,通过查看当前操作系统的配置可以很容易的 + 创建一份机器硬件的配置清单。举例来说, µsoft; 的 + 设备管理器 里通常含有关于已安装硬件的重要信息。 + 设备管理器 位于控制面板。 + + + 某些版本的 µsoft.windows; 有一个 系统 + 图标会指明 设备管理器 的位置。 + + + 如果机器上并不存在其他的操作系统, + 系统管理员只能手动寻找这些信息了。其中的一个方法是使用 + &man.dmesg.8; 工具以及 &man.man.1; 命令。&os; + 上大多数的驱动程序都有一份手册页(manual page)列出了所支持的硬件, + 在系统启动的时候,被发现的硬件也会被列出。举例来说, + 下面的这几行表示 psm 驱动找到了一个鼠标: + + psm0: <PS/2 Mouse> irq 12 on atkbdc0 +psm0: [GIANT-LOCKED] +psm0: [ITHREAD] +psm0: model Generic PS/2 mouse, device ID 0 + + 这个驱动需要被包含在客户制定的内核配置文件里, + 或着使用 &man.loader.conf.5; 加载。 + + 有时,dmesg 里只会显示来自系统消息的数据, + 而不是系统启动时的检测信息。在这样的情况下,你可以查看文件 + /var/run/dmesg.boot + + 另一个查找硬件信息的方法是使用 &man.pciconf.8; 工具, + 它能提供更详细的输出,比如: + + ath0@pci0:3:0:0: class=0x020000 card=0x058a1014 chip=0x1014168c rev=0x01 hdr=0x00 + vendor = 'Atheros Communications Inc.' + device = 'AR5212 Atheros AR5212 802.11abg wireless' + class = network + subclass = ethernet + + 这个片断取自于 pciconf + 命令的输出,显示 ath + 驱动找到了一个无线以太网设备。输入命令 + man ath + 就能查阅有关 &man.ath.4; 的手册页(manual page)了。 + + 还可以传给 &man.man.1; 命令 选项, + 同样能获得有用的信息。例如: + + &prompt.root; man -k Atheros + + 能得到一份包含特定词语的手册页(manual page): + + ath(4) - Atheros IEEE 802.11 wireless network driver +ath_hal(4) - Atheros Hardware Access Layer (HAL) + + 手头备有一份硬件的配置清单, + 那么编译制定内核的过程就显得不那么困难了。 + + 建立并安装一个定制的内核 内核 建立/安装 首先对内核构建目录做一个快速的浏览。 这里所提到的所有目录都在 /usr/src/sys 目录中; 也可以通过 /sys 来访问它。 这里的众多子目录包含了内核的不同部分, 但对我们所要完成的任务最重要的目录是 arch/conf, 您将在这里编辑定制的内核配置; 以及 compile, 编译过程中的文件将放置在这里。 arch 表示 i386alphaamd64ia64powerpcsparc64, 或 pc98 (在日本比较流行的另一种 PC 硬件开发分支)。 在特定硬件架构目录中的文件只和特定的硬件有关; 而其余代码则是与机器无关的, 则所有已经或将要移植并运行 &os; 的平台上都共享这些代码。 文件目录是按照逻辑组织的, 所支持的硬件设备、 文件系统, 以及可选的组件通常都在它们自己的目录中。 这一章提供的例子假定您使用 i386 架构的计算机。 如果您的情况不是这样, 只需对目录名作相应的调整即可。 如果您的系统中 没有 /usr/src/sys 这样一个目录, 则说明没有安装内核源代码。 安装它最简单的方法是通过以 root 身份运行 sysinstall, 选择 Configure, 然后是 Distributionssrc, 选中其中的 basesys。 如果您不喜欢 sysinstall 并且有一张 官方的 &os; CDROM, 也可以使用下列命令, 从命令行来安装源代码: &prompt.root; mount /cdrom &prompt.root; mkdir -p /usr/src/sys &prompt.root; ln -s /usr/src/sys /sys &prompt.root; cat /cdrom/src/ssys.[a-d]* | tar -xzvf - &prompt.root; cat /cdrom/src/sbase.[a-d]* | tar -xzvf - 接下来, 进入 arch/conf 目录下面, 复制 GENERIC 配置文件, 并给这个文件起一个容易辨认的名称, 它就是您的内核名称。例如: &prompt.root; cd /usr/src/sys/i386/conf &prompt.root; cp GENERIC MYKERNEL 通常,这个名称是大写的,如果您正维护着多台不同硬件的&os;机器, 以您机器的域名来命名是非常好的主意。我们把它命名为MYKERNEL就是这个原因。 将您的内核配置文件直接保存在 /usr/src 可能不是一个好主意。 如果您遇到问题, 删掉 /usr/src 并重新开始很可能是一个诱人的选择。 一旦开始做这件事, 您可能几秒钟之后才会意识到您同时会删除定制的内核配置文件。 另外, 也不要直接编辑 GENERIC, 因为下次您 更新代码 时它会被覆盖, 而您的修改也就随之丢失了。 您也可以考虑把内核配置文件放到别的地方, 然后再到 i386 目录中创建一个指向它的符号链接。 例如: &prompt.root; cd /usr/src/sys/i386/conf &prompt.root; mkdir /root/kernels &prompt.root; cp GENERIC /root/kernels/MYKERNEL &prompt.root; ln -s /root/kernels/MYKERNEL 必须以 root 身份执行这些和接下来命令, 否则就会得到 permission denied 的错误提示。 现在就可以用您喜欢的文本编辑器来编辑 MYKERNEL 了。 如果您刚刚开始使用 FreeBSD, 唯一可用的编辑器很可能是 vi, 它的使用比较复杂, 限于篇幅, 这里不予介绍, 您可以在 参考书目 一章中找到很多相关书籍。 不过, &os; 也提供了一个更好用的编辑器, 它叫做 ee, 对于新手来说, 这很可能是一个不错的选择。 您可以修改配置文件中的注释以反映您的配置, 或其他与 GENERIC 不同的地方。 SunOS 如果您在&sunos;或者其他BSD系统下定制过内核,那这个文件中的绝大部分将对您非常熟悉。 如果您使用的是诸如DOS这样的系统,那GENERIC配置文件看起来就非常困难, 所以在下面的 配置文件章节将慢慢地、仔细地进行介绍。 如果您和 &os; project 进行了 代码同步, 则一定要在进行任何更新之前查看 /usr/src/UPDATING。 这个文件中描述了更新过的代码中出现的重大问题或需要注意的地方。 /usr/src/UPDATING 总是和您的 &os; 源代码对应, 因此能够提供比手册更具时效性的新内容。 现在应该编译内核的源代码了。 联编内核 进入 /usr/src 目录: &prompt.root; cd /usr/src 编译内核: &prompt.root; make buildkernel KERNCONF=MYKERNEL 安装新内核: &prompt.root; make installkernel KERNCONF=MYKERNEL 使用这种方法联编内核时, 需要安装完整的 &os; 源代码。 默认情况下, 在联编您所定制的内核时, 全部 内核模块也会同时参与构建。 如果您希望更快地升级内核, 或者只希望联编您所需要的模块, 则应在联编之前编辑 /etc/make.conf MODULES_OVERRIDE = linux acpi sound/sound sound/driver/ds1 ntfs 这个变量的内容是所希望构建的模块列表。 WITHOUT_MODULES = linux acpi sound/sound sound/driver/ds1 ntfs 这个变量的内容是在联编过程中将不被编译的模块列表。 如果希望了解更多与构建内核有关的变量, 请参见 &man.make.conf.5; 联机手册。 /boot/kernel.old 新内核将会被复制到 /boot/kernel 目录中成为 /boot/kernel/kernel 而旧的则被移到 /boot/kernel.old/kernel。 现在关闭系统, 然后用新的内核启动计算机。 如果出现问题, 后面的一些 故障排除方法 将帮您摆脱困境。 如果您的内核 无法启动, 请参考那一节。 其他与启动过程相关的文件, 如 &man.loader.8; 及其配置, 则放在 /boot。 第三方或定制的模块也可以放在 /boot/kernel, 不过应该注意保持模块和内核的同步时很重要的, 否则会导致不稳定和错误。 Joel Dahl Updated for &os; 6.X by 配置文件 内核 NOTES NOTES 内核 配置文件 配置文件的格式是非常简单的。 每一行都包括一个关键词, 以及一个或多个参数。 实际上, 绝大多数行都只包括一个参数。 在 # 之后的内容会被认为是注释而忽略掉。 接下来几节, 将以 GENERIC 中的顺序介绍所有关键字。 如果需要与平台有关的选项和设备的详细列表, 请参考与 GENERIC 文件在同一个目录中的那个 NOTES, 而平台无关的选项, 则可以在 /usr/src/sys/conf/NOTES 找到。 如果您需要一份包含所有选项的文件, 例如用于测试目的, 则应以 root 身份执行下列命令: &prompt.root; cd /usr/src/sys/i386/conf && make LINT 内核 配置文件 下面是一个 GENERIC 内核配置文件的例子, 它包括了一些需要解释的注释。 这个例子应该和您复制的 /usr/src/sys/i386/conf/GENERIC 非常接近。 内核选项 机器 machine i386 这是机器的架构, 他只能是 alpha, amd64, i386, ia64, pc98, powerpc, 或 sparc64 中的一种。 内核选项 cpu cpu I486_CPU cpu I586_CPU cpu I686_CPU 上面的选项指定了您系统中所使用的 CPU 类型。 您可以使用多个 CPU 类型 (例如, 您不确定是应该指定 I586_CPUI686_CPU)。 然而对于定制的内核, 最好能够只指定您使用的那种 CPU。 如果您对于自己使用的 CPU 类型没有把握, 可以通过查看 /var/run/dmesg.boot 中的启动信息来了解。 内核选项 ident ident GENERIC 这是内核的名字。 您应该取一个自己的名字, 例如取名叫 MYKERNEL, 如果您一直在按照前面的说明做的话。 您放在 ident 后面的字符串在启动内核时会显示出来, 因此如果希望能够容易区分常用的内核和刚刚定制的内核, 就应该采取不同的名字 (例如, 您想定制一个试验性的内核)。 #To statically compile in device wiring instead of /boot/device.hints #hints "GENERIC.hints" # Default places to look for devices. &man.device.hints.5; 可以用来配置设备驱动选项。 在启动的时候 &man.loader.8; 将会检查缺省位置 /boot/devicehints。 使用 hints 选项您就可以把这些 hints 静态编译进内核。 这样就没有必要在 /boot下创建devicehints makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols 一般的 &os; 联编过程, 在所联编的内核指定了 选项时, 由于此选项将传递给 &man.gcc.1; 表示加入调试信息, 因此会将调试符号也包含进来。 options SCHED_4BSD # 4BSD scheduler 这是 &os; 传统上使用的默认系统调度器。 请保留此选项。 options PREEMPTION # Enable kernel thread preemption 允许内核线程根据优先级的抢占调度。 这有助于改善交互性, 并可以让中断线程更早地执行, 而无须等待。 options INET # InterNETworking 网络支持,即使您不打算连网,也请保留它,大部分的程序至少需要回环网络(就是和本机进行网络连接),所以强烈要求保留它。 options INET6 # IPv6 communications protocols 这将打开IPv6连接协议。 options FFS # Berkeley Fast Filesystem 这是最基本的硬盘文件系统,如果打算从本地硬盘启动,请保留它。 options SOFTUPDATES # Enable FFS Soft Updates support 这个选项会启用内核中的 Soft Updates 支持, 它会显著地提高磁盘的写入速度。 尽管这项功能是由内核直接提供的, 但仍然需要在每个磁盘上启用它。 请检查 &man.mount.8; 的输出, 以了解您系统中的磁盘上是否已经启用了 Soft Updates。 如果没有看到 soft-updates 选项, 则需要使用 &man.tunefs.8; (对于暨存系统) 或 &man.newfs.8; (对于新系统) 命令来激活它。 options UFS_ACL # Support for access control lists 这个选项将启用内核中的访问控制表的支持。 这依赖于扩展属性以及 UFS2, 以及在 中所介绍的那些特性。 ACL 默认是启用的, 并且如果已经在文件系统上使用了这一特性, 就不应再关掉它, 因为这会去掉文件的访问控制表, 并以不可预期的方式改变受保护的文件的访问方式。 options UFS_DIRHASH # Improve performance on big directories 通过使用额外的内存,这个选项可以加速在大目录上的磁盘操作。 您应该在大型服务器和频繁使用的工作站上打开这个选项,而在磁盘操作不是很重要的 小型系统上关闭它,比如防火墙。 options MD_ROOT # MD is a potential root device 这个选项将打开以基于内存的虚拟磁盘作为根设备的支持。 内核选项 NFS 内核选项 NFS_ROOT options NFSCLIENT # Network Filesystem Client options NFSSERVER # Network Filesystem Server options NFS_ROOT # NFS usable as /, requires NFSCLIENT 网络文件系统。 如果您不打算通过 TCP/IP 挂接 &unix; 文件服务器的分区, 就可以注释掉它。 内核选项 MSDOSFS options MSDOSFS # MSDOS Filesystem &ms-dos; 文件系统。 只要您不打算在启动时挂接由 DOS 格式化的硬盘分区, 就可以把它注释掉。 如前面所介绍的那样, 在您第一次挂接 DOS 分区时, 内核会自动加载需要的模块。 此外, emulators/mtools 软件提供了一个很方便的功能, 通过它您可以直接访问 DOS 软盘而无需挂接或卸下它们 (而且也完全不需要 MSDOSFS)。 options CD9660 # ISO 9660 Filesystem 用于 CDROM 的 ISO 9660 文件系统。 如果没有 CDROM 驱动器或很少挂接光盘数据 (因为在首次使用数据 CD 时会自动加载), 就可以把它注释掉。 音乐 CD 并不需要这个选项。 options PROCFS # Process filesystem (requires PSEUDOFS) 进程文件系统。 这是一个挂接在 /proc 的一个 假扮的 文件系统, 其作用是允许类似 &man.ps.1; 这样的程序给出正在运行的进程的进一步信息。 多数情况下, 并不需要使用 PROCFS, 因为绝大多数调试和监控工具, 已经进行了一系列修改, 使之不再依赖 PROCFS: 默认安装的系统中并不会挂接这一文件系统。 options PSEUDOFS # Pseudo-filesystem framework 在 6.X 内核中, 如果希望使用 PROCFS, 就必须加入 PSEUDOFS 的支持。 options GEOM_GPT # GUID Partition Tables. 这个选项提供了在磁盘上使用大量的分区的能力。 options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!] 使系统兼容4.3BSD。不要去掉这一行,不然有些程序将无法正常运行。 options COMPAT_FREEBSD4 # Compatible with &os;4 为了支持在旧版本的&os;下编译的程序,该选项在&os; 5.X &i386;和Alpha systems下需要打开。 最好在所有的&i386;和Alpha systems下打开这个选项,因为可能要运行老应用程序。 在5.X才开始支持的平台,比如ia64和&sparc64;,就不需要这个选项。 options COMPAT_FREEBSD5 # Compatible with &os;5 对于 &os; 6.X 和更高版本而言, 如果希望在其上运行为 &os; 5.X 版本联编的、 用到 &os; 5.X 系统调用接口的程序, 则需要使用这个选项。 options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI 这将让内核在探测每个 SCSI 设备之前等待 5 秒。 如果您只有 IDE 硬盘驱动器, 就可以不管它, 反之您可能会希望尝试降低这个数值以加速启动过程。 当然, 如果您这么做之后 &os; 在识别您的 SCSI 设备时遇到问题, 则您还需要再把它改回去。 options KTRACE # ktrace(1) support 这个选项打开内核进程跟踪,在调试时很有用。 options SYSVSHM # SYSV-style shared memory 提供System V共享内存(SHM)的支持,最常用到SHM的应该是X Window的XSHM延伸, 不少绘图相关程序会自动使用SHM来提供额外的速度。如果您要使用X Window,您最好加入这个选项。 options SYSVMSG # SYSV-style message queues 支持 System V 消息。 这只会在内核中增加数百字节的空间占用。 options SYSVSEM # SYSV-style semaphores 支持System V 信号量, 不常用到, 但只在kernel中占用几百个字节的空间。 &man.ipcs.1; 命令的 选项可以显示出任何用到这些 System V 机制的进程。 options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions 在 1993 年 &posix; 添加的实时扩展。 在 Ports Collection 中某些应用程序会用到这些 (比如&staroffice;)。 options KBD_INSTALL_CDEV # install a CDEV entry in /dev - 这个选项与键盘有关。 它在 /dev - 中安装一个 CDEV 项。 + 这个选项是在 /dev下建立键盘设备节点必需的。 options ADAPTIVE_GIANT # Giant mutex is adaptive. 内核全局锁 (Giant) 是一种互斥机制 (休眠互斥体) 的名字, 它用于保护许多内核资源。 现在, 这已经成为了一种无法接受的性能瓶颈, 它已经被越来越多地使用保护单个资源的锁代替。 ADAPTIVE_GIANT 选项将使得内核全局锁作为一种自适应自旋锁。 这意味着, 当有线程希望锁住内核全局锁互斥体, 但互斥体已经被另一个 CPU 上的线程锁住的时候, 它将继续运行, 直到那个线程释放锁为止。 一般情况下, 另一个线程将进入休眠状态并等待下一次调度。 如果您不确定是否应该这样做的话, 一般应该打开它。 + + 请注意在 &os; 8.0-CURRENT 及以后的版本,所有的互斥体默认都是自适应的, + 除非在编译时使用 NO_ADAPTIVE_MUTEXES 选项, + 明确的指定为非自适应。因此,内核全局锁(Giant)目前默认也是自适应的, + 而且 ADAPTIVE_GIANT 选项已经从内核配置文件中移出。 + + 内核选项 SMP device apic # I/O APIC apic 设备将启用使用 I/O APIC 作为中断发送设备的能力。 apic 设备可以被 UP 和 SMP 内核使用, 但 SMP 内核必须使用它。 要支持多处理器, 还需要加上 options SMP The apic device exists only on the i386 architecture, this configuration line should not be used on other architectures. device eisa 如果您的主机板上有EISA总线,加入这个设置。使用这个选项可以自动扫描并设置所有连接在EISA总线上的设备。 device pci 如果您的主板有PCI总线,就加入这个选项。使用这个选项可以自动扫描PCI卡,并在PCI到ISA之间建立通路。 # Floppy drives device fdc 这是软驱控制器。 # ATA and ATAPI devices device ata 这个驱动器支持所有ATA和ATAPI设备。您只要在内核中加入device ata选项, 就可以让内核支持现代计算机上的所有PCI ATA/ATAPI设备。 device atadisk # ATA disk drives 这个是使用 ATAPI 硬盘驱动器时必须加入的选项。 device ataraid # ATA RAID drives 这个选项需要 device ata, 它用于 ATA RAID 驱动。 device atapicd # ATAPI CDROM drives 这个是ATAPI CDROM驱动器所必须的。 device atapifd # ATAPI floppy drives 这个是ATAPI 软盘驱动器所必须的。 device atapist # ATAPI tape drives 这个是ATAPI 磁带机驱动器所必须的. options ATA_STATIC_ID # Static device numbering 这指定对控制器使用其静态的编号; 如果没有这个选项, 则会动态地分配设备的编号。 # SCSI Controllers device ahb # EISA AHA1742 family device ahc # AHA2940 and onboard AIC7xxx devices options AHC_REG_PRETTY_PRINT # Print register bitfields in debug # output. Adds ~128k to driver. device ahd # AHA39320/29320 and onboard AIC79xx devices options AHD_REG_PRETTY_PRINT # Print register bitfields in debug # output. Adds ~215k to driver. device amd # AMD 53C974 (Teckram DC-390(T)) device isp # Qlogic family #device ispfw # Firmware for QLogic HBAs- normally a module device mpt # LSI-Logic MPT-Fusion #device ncr # NCR/Symbios Logic device sym # NCR/Symbios Logic (newer chipsets + those of `ncr') device trm # Tekram DC395U/UW/F DC315U adapters device adv # Advansys SCSI adapters device adw # Advansys wide SCSI adapters device aha # Adaptec 154x SCSI adapters device aic # Adaptec 15[012]x SCSI adapters, AIC-6[23]60. device bt # Buslogic/Mylex MultiMaster SCSI adapters device ncv # NCR 53C500 device nsp # Workbit Ninja SCSI-3 device stg # TMC 18C30/18C50 SCSI控制器。可以注释掉您系统中没有的设备。 如果您只有IDE设备,您可以把这些一起删掉。 *_REG_PRETTY_PRINT 这样的配置, 则是对应驱动程序的调试选项。 # SCSI peripherals device scbus # SCSI bus (required for SCSI) device ch # SCSI media changers device da # Direct Access (disks) device sa # Sequential Access (tape etc) device cd # CD device pass # Passthrough device (direct SCSI access) device ses # SCSI Environmental Services (and SAF-TE) SSCSI外围设备。也可以像上面一样操作。 目前系统提供的 USB &man.umass.4; 以及少量其它驱动使用了 SCSI 子系统, 尽管它们并不是真的 SCSI 设备。 因此, 如果在内核配置使用了这类驱动程序, 请务必不要删除 SCSI 支持。 # RAID controllers interfaced to the SCSI subsystem device amr # AMI MegaRAID device arcmsr # Areca SATA II RAID device asr # DPT SmartRAID V, VI and Adaptec SCSI RAID device ciss # Compaq Smart RAID 5* device dpt # DPT Smartcache III, IV - See NOTES for options device hptmv # Highpoint RocketRAID 182x device rr232x # Highpoint RocketRAID 232x device iir # Intel Integrated RAID device ips # IBM (Adaptec) ServeRAID device mly # Mylex AcceleRAID/eXtremeRAID device twa # 3ware 9000 series PATA/SATA RAID # RAID controllers device aac # Adaptec FSA RAID device aacp # SCSI passthrough for aac (requires CAM) device ida # Compaq Smart RAID device mfi # LSI MegaRAID SAS device mlx # Mylex DAC960 family device pst # Promise Supertrak SX6000 device twe # 3ware ATA RAID 支持RAID控制器。如果您没有这些,可以把它们注释掉或是删掉。 # atkbdc0 controls both the keyboard and the PS/2 mouse device atkbdc # AT keyboard controller 键盘控制器(atkbdc)提供AT键盘输入以及PS/2指针设备的I/O服务。 键盘驱动程序(atkbd)与PS/2鼠标驱动程序(psm)需要这个控制器,所以不要删除它。 device atkbd # AT keyboard atkbd驱动程序,与atkbdc控制器一起使用, 提供连接到AT键盘控制器的AT 84键盘与AT加强型键盘的访问服务。 device psm # PS/2 mouse 如果您的鼠标连接到PS/2鼠标端口,就使用这个设备驱动程序。 device kbdmux # keyboard multiplexer 针对键盘多路选择器的基本支持。 如果您不打算使用多个键盘, 则可以放心地删除这一行。 device vga # VGA video card driver 显卡驱动。 device splash # Splash screen and screen saver support 启动时的 splash 画面! 屏幕保护程序也需要这一选项。 # syscons is the default console driver, resembling an SCO console device sc sc 是默认的控制台驱动程序, 类似 SCO 控制台。 由于绝大部分全屏幕程序都通过类似 termcap 这样的终端数据库函数库赖访问控制台, 因此无论您使用这个或与 VT220 兼容的 vt 都没有什么关系。 如果您在运行这种控制台时使用全屏幕程序时发生问题, 请在登录之后将 TERM 变量设置为 scoansi # Enable this for the pcvt (VT220 compatible) console driver #device vt #options XSERVER # support for X server on a vt console #options FAT_CURSOR # start with block cursor 这是一个兼容 VT220 的控制台驱动, 它同时能够向下兼容 VT100/102。 在同 sc 硬件不兼容的一些笔记本上它能够运行的很好。 当然, 登录系统时请把 TERM 变量设置为 vt100vt220。 此驱动在连接网络上大量不同的机器时也被证明非常有用, 因为此时 termcapterminfo 通常没有可用的 sc 设备 — 而 vt100 则几乎每种平台都支持。 device agp 如果您的机器使用 AGP 卡, 请把上面一行加入配置。 这将启用 AGP, 以及某些卡上的 AGP GART 支持。 APM # 电源管理支持 (参见 NOTES 了解更多选项) #device apm 高级电源管理支持。 对笔记本有用, 不过在 &os; 5.X 和更高版本中的 GENERIC 里默认禁用。 # 增加 i8254 的 挂起/恢复 支持。 device pmtimer 用于电源管理事件, 例如 APM 和 ACPI 的时钟设备驱动。 # PCCARD (PCMCIA) support # PCMCIA and cardbus bridge support device cbb # cardbus (yenta) bridge device pccard # PC Card (16-bit) bus device cardbus # CardBus (32-bit) bus PCMCIA支持。如果您使用膝上型计算机,您需要这个。 # Serial (COM) ports device sio # 8250, 16[45]50 based serial ports 这些串口在 &ms-dos;/&windows; 的世界中称为 COM 口。 如果使用内置式的调制解调器, 并占用 COM4 而您另有一个串口在 COM2, 则必须把调制解调器的 IRQ 改为 2 (由于晦涩的技术原因, IRQ2 = IRQ 9) 才能够在 &os; 中访问它。 如果有多口的串口卡, 请参考 &man.sio.4; 以了解需要在 /boot/device.hints 中进行的设置。 某些显卡 (特别是基于 S3 芯片的卡) 使用形如 0x*2e8 的 IO 地址, 而许多廉价的串口卡不能够正确地对 16-位 IO 地址空间进行解码, 因此它们会产生冲突, 并造成 COM4 实际上无法使用。 每一个串口都需要有一个唯一的 IRQ (除非您使用支持中断分享的串口卡), 因此默认的 COM3COM4 IRQ 是不能使用的。 # Parallel port device ppc ISA-bus并行接口。 device ppbus # Parallel port bus (required) 提供并行总线的支持。 device lpt # Printer 提供并口打印机的支持。 要使用并口打印机,就必须同时加入上面三行设置。 device plip # TCP/IP over parallel 这是针对并行网络接口的驱动器。 device ppi # Parallel port interface device 普通用途的I/O (geek port) + IEEE1284 I/O. #device vpo # Requires scbus and da zip drive 这是针对Iomega Zip驱动器的。它要求scbusda的支持。 最好的执行效果是工作在EPP 1.9模式。 #device puc 如果您有由 &man.puc.4; 支持的 串行或并行 PCI 卡, 则应去掉这一行的注释。 # PCI Ethernet NICs. device de # DEC/Intel DC21x4x (Tulip) device em # Intel PRO/1000 adapter Gigabit Ethernet Card device ixgb # Intel PRO/10GbE Ethernet Card device txp # 3Com 3cR990 (Typhoon) device vx # 3Com 3c590, 3c595 (Vortex) 多种PCI网卡驱动器。注释或删除您系统中没有的设备. # PCI Ethernet NICs that use the common MII bus controller code. # NOTE: Be sure to keep the 'device miibus' line in order to use these NICs! device miibus # MII bus support MII总线支持对于一些PCI 10/100 Ethernet NIC来说是必需的。 device bce # Broadcom BCM5706/BCM5708 Gigabit Ethernet device bfe # Broadcom BCM440x 10/100 Ethernet device bge # Broadcom BCM570xx Gigabit Ethernet device dc # DEC/Intel 21143 and various workalikes device fxp # Intel EtherExpress PRO/100B (82557, 82558) device lge # Level 1 LXT1001 gigabit ethernet device msk # Marvell/SysKonnect Yukon II Gigabit Ethernet device nge # NatSemi DP83820 gigabit ethernet device nve # nVidia nForce MCP on-board Ethernet Networking device pcn # AMD Am79C97x PCI 10/100 (precedence over 'lnc') device re # RealTek 8139C+/8169/8169S/8110S device rl # RealTek 8129/8139 device sf # Adaptec AIC-6915 (Starfire) device sis # Silicon Integrated Systems SiS 900/SiS 7016 device sk # SysKonnect SK-984x & SK-982x gigabit Ethernet device ste # Sundance ST201 (D-Link DFE-550TX) device stge # Sundance/Tamarack TC9021 gigabit Ethernet device ti # Alteon Networks Tigon I/II gigabit Ethernet device tl # Texas Instruments ThunderLAN device tx # SMC EtherPower II (83c170 EPIC) device vge # VIA VT612x gigabit ethernet device vr # VIA Rhine, Rhine II device wb # Winbond W89C840F device xl # 3Com 3c90x (Boomerang, Cyclone) 使用MII总线控制器代码的驱动器。 # ISA Ethernet NICs. pccard NICs included. device cs # Crystal Semiconductor CS89x0 NIC # 'device ed' requires 'device miibus' device ed # NE[12]000, SMC Ultra, 3c503, DS8390 cards device ex # Intel EtherExpress Pro/10 and Pro/10+ device ep # Etherlink III based cards device fe # Fujitsu MB8696x based cards device ie # EtherExpress 8/16, 3C507, StarLAN 10 etc. device lnc # NE2100, NE32-VL Lance Ethernet cards device sn # SMC's 9000 series of Ethernet chips device xe # Xircom pccard Ethernet # ISA devices that use the old ISA shims #device le ISA 以太网卡驱动。 参见 /usr/src/sys/i386/conf/NOTES 以了解关于哪个驱动程序能够驱动您的网卡的细节。 # Wireless NIC cards device wlan # 802.11 support 通用 802.11 支持。 这行配置是无线网络所必需的。 device wlan_wep # 802.11 WEP support device wlan_ccmp # 802.11 CCMP support device wlan_tkip # 802.11 TKIP support 针对 802.11 设备的加密支持。 如果希望使用加密和 802.11i 安全协议, 就需要这些配置行。 device an # Aironet 4500/4800 802.11 wireless NICs. device ath # Atheros pci/cardbus NIC's device ath_hal # Atheros HAL (Hardware Access Layer) device ath_rate_sample # SampleRate tx rate control for ath device awi # BayStack 660 and others device ral # Ralink Technology RT2500 wireless NICs. device wi # WaveLAN/Intersil/Symbol 802.11 wireless NICs. #device wl # Older non 802.11 Wavelan wireless NIC. 用以支持多种无线网卡。 # Pseudo devices device loop # Network loopback 这是 TCP/IP 的通用回环设备。 如果您 telnet 或 FTP 到 localhost (也就是 127.0.0.1) 则将通过这个设备回到本机。 这个设备是 必需的 device random # Entropy device Cryptographically secure random number generator. device ether # Ethernet support ether 只有在使用以太网卡时才需要。 它包含了通用的以太网协议代码。 device sl # Kernel SLIP sl 用以提供 SLIP 支持。 目前它几乎已经完全被 PPP 取代了, 因为后者更容易配置, 而且更适合调制解调器之间的连接, 并提供了更强大的功能。 device ppp # Kernel PPP 这一选项用以提供内核级的 PPP 支持, 用于拨号连接。 也有以用户模式运行的 PPP 实现, 使用 tun 并提供包括按需拨号在内的更为灵活的功能。 device tun # Packet tunnel. 它会被用户模式的 PPP 软件用到。 参考本书的 PPP 以了解更多的细节。 device pty # Pseudo-ttys (telnet etc) 这是一个 pseudo-terminal 或模拟登入端口。 它用来接收连入的 telnet 以及 rlogin 会话、 xterm, 以及一些其它程序如 Emacs 等。 device md # Memory disks 内存盘伪设备。 device gif # IPv6 and IPv4 tunneling 它实现了在 IPv4 上的 IPv6 隧道、 IPv6 上的 IPv4 隧道、 IPv4 上的 IPv4 隧道、 以及IPv6 上的 IPv6隧道。 gif 设备是 自动克隆 的, 它会根据需要自动创建设备节点。 device faith # IPv6-to-IPv4 relaying (translation) 这个伪设备能捕捉发给它的数据包,并把它们转发给 IPv4/IPv6 翻译服务程序。 # The `bpf' device enables the Berkeley Packet Filter. # Be aware of the administrative consequences of enabling this! # Note that 'bpf' is required for DHCP. device bpf # Berkeley packet filter 这是 Berkeley 包过滤器。这个伪设备允许网络接口被置于混杂模式, 从而,截获广播网 (例如,以太网) 上的每一个数据包。 截获的数据报可以保存到磁盘上,也可以使用 &man.tcpdump.1; 程序来分析。 &man.bpf.4; 设备也被用于 &man.dhclient.8; 来获取默认路由器(网关)的 IP 地址。如果使用DHCP,就不要注释掉这行。 # USB support device uhci # UHCI PCI->USB interface device ohci # OHCI PCI->USB interface device ehci # EHCI PCI->USB interface (USB 2.0) device usb # USB Bus (required) #device udbp # USB Double Bulk Pipe devices device ugen # Generic device uhid # Human Interface Devices device ukbd # Keyboard device ulpt # Printer device umass # Disks/Mass storage - Requires scbus and da device ums # Mouse device ural # Ralink Technology RT2500USB wireless NICs device urio # Diamond Rio 500 MP3 player device uscanner # Scanners # USB Ethernet, requires mii device aue # ADMtek USB Ethernet device axe # ASIX Electronics USB Ethernet device cdce # Generic USB over Ethernet device cue # CATC USB Ethernet device kue # Kawasaki LSI USB Ethernet device rue # RealTek RTL8150 USB Ethernet 支持各类 USB 设备。 # FireWire support device firewire # FireWire bus code device sbp # SCSI over FireWire (Requires scbus and da) device fwe # Ethernet over FireWire (non-standard!) 支持各类火线设备。 要了解 &os; 所支持的设备的其他情况, 请参考 /usr/src/sys/i386/conf/NOTES 大内存支持(<acronym>PAE</acronym>) 物理地址扩展 (PAE) 大内存 大内存配置的机器需要超过4GB的虚拟地址。 因为4GB的限制,Intel在&pentium;及后续的CPUs上增加了36位物理地址的支持。 物理地址扩展 (PAE) 是 &intel; &pentium; Pro和后续的 CPU 提供的一种允许将内存地址扩展到 64GB 的功能, &os; 的所有最新版本均支持此功能, 并通过 选项来启用这个能力。 因为Intel架构的限制, 高于或低于 4GB 都没有什么区别, 超过 4GB 的内存分配只是简单地添加到可用内存池中。 为了让内核支持PAE,只要增加下面这一行到配置文件: options PAE PAE在&os;里面现在只能支持 &intel; IA-32处理器。 同时,还应该注意,&os;的PAE支持没有经过广泛的测试, 和其他稳定的特性相比只能当作是beta版。 PAE在&os;下有如下的一些限制: 进程不能接触大于4GB的VM空间。 KLD 模块不能加载到一个打开了PAE支持的内核里面, 这是因为内核模块和内核的建立框架不一样。 没有使用 &man.bus.dma.9; 接口的设备驱动程序在打开了 PAE 支持的内核中会导致数据损坏。 因为这个原因, PAE 内核配置文件 会把所有在打开了 PAE 的内核上不能工作的驱动程序排除在外。 一些系统打开了探测系统内存资源使用能力的功能,因为打开了 PAE支持,这些功能可能会被覆盖掉。 其中一个例子就是内核参数,它是控制 内核能使用的最大vnodes数目的,建议重新调整它及其他类似参数到合适的值。 为了避免KVA的消耗,很有必要增加系统的内核虚拟地址, 或者减少很耗系统资源的内核选项的总量(看上面)。选项 可以用来增加KVA空间。 为了稳定和高性能,建议查看&man.tuning.7;手册页。&man.pae.4;手册页包含 &os;'sPAE支持的最新信息。 如果出现问题怎么办 在定制一个内核时,可能会出现五种问题。它们是: config失败: 如果 &man.config.8; 在给出您的内核描述时失败, 则可能在某些地方引入了一处小的错误。 幸运的是, &man.config.8; 会显示出它遇到问题的行号, 这样您就能够迅速地定位错误。 例如, 如果您看到: config: line 17: syntax error 可以通过与 GENERIC 或其他参考资料对比, 来确定这里的关键词是否拼写正确。 make失败: 如果 make 命令失败, 它通常表示内核描述中发生了 &man.config.8; 无法找出的的错误。 同样地, 仔细检查您的配置, 如果仍然不能解决问题, 发一封邮件到 &a.questions; 并附上您的内核配置, 则问题应该很快就能解决。 内核无法启动: 如果您的内核无法启动, 或不识别您的设备, 千万别慌! 非常幸运的是, &os; 有一个很好的机制帮助您从不兼容的内核恢复。 在 &os; 启动加载器那里简单地选择一下要启动的内核就可以了。 当系统在引导菜单的 10 秒倒计时时进入它, 方法是选择 Escape to a loader prompt 选项, 其编号为 6。 输入 unload kernel, 然后输入 boot /boot/kernel.old/kernel, 或者其他任何一个可以正确引导的内核即可。 当重新配置内核时, 保持一个已经证明能够正常启动的内核永远是一个好习惯。 当使用好的内核启动之后您可以检查配置文件并重新尝试编译它。 比较有用的资源是 /var/log/messages 文件, 它会记录每次成功启动所产生的所有内核消息。 此外, &man.dmesg.8; 命令也会显示这次启动时产生的内核消息。 如果在编译内核时遇到麻烦, 请务必保留一个 GENERIC 或已知可用的其他内核, 并命名为别的名字以免在下次启动时被覆盖。 不要依赖 kernel.old 因为在安装新内核时, kernel.old 会被上次安装的那个可能不正常的内核覆盖掉。 另外, 尽快把可用的内核挪到 /boot/kernel 否则类似 &man.ps.1; 这样的命令可能无法正常工作。 为了完成这一点, 需要修改目录的名字: &prompt.root; mv /boot/kernel /boot/kernel.bad &prompt.root; mv /boot/kernel.good /boot/kernel 内核工作,但是&man.ps.1;根本不工作: 如果您安装了一个与系统中内建工具版本不同的内核, 例如在 -STABLE 系统上安装了 -CURRENT 的内核, 许多用于检查系统状态的工具如 &man.ps.1; 和 &man.vmstat.8; 都将无法正常使用。 您应该 重新编译一个和内核版本一致的系统。 这也是为什么一般不鼓励使用与系统其他部分版本不同的内核的一个主要原因。 diff --git a/zh_CN.GB2312/books/handbook/linuxemu/chapter.sgml b/zh_CN.GB2312/books/handbook/linuxemu/chapter.sgml index 0308f9776f..f6c5058c0c 100644 --- a/zh_CN.GB2312/books/handbook/linuxemu/chapter.sgml +++ b/zh_CN.GB2312/books/handbook/linuxemu/chapter.sgml @@ -1,3027 +1,3029 @@ Jim Mock Restructured and parts updated by Brian N. Handy Originally contributed by Rich Murphey Linux二进制兼容模式 概述 Linux二进制兼容模式 二进制兼容模式 Linux FreeBSD 提供了与其他几种类 &unix; 操作系统, 包括 Linux, 的兼容性。 现在您可能会问, 为什么 FreeBSD 需要能够运行 Linux 的可执行文件? 答案很简单。 许多公司和开发人员只为 Linux 开发程序, 因为这是目前计算机世界 最热门 的技术。 这使得我们 FreeBSD 用户不得不去劝说这些公司和开发人员提供他们应用程序可以直接在 FreeBSD 上运行的版本。 问题是, 许多这样的公司并不真的知道到底提供了 FreeBSD 版本之后能带来多少用户, 因此许多仍然只开发 Linux 的版本。 这时 FreeBSD 用户能做什么呢? 答案就是使用 FreeBSD 所提供的 Linux 二进制兼容性。 简而言之, 这种兼容性能够让 FreeBSD 用户不加修改地直接运行大约 90% 的 Linux 应用程序。 这包括类似 &staroffice;, Linux 版本的 &netscape;&adobe; &acrobat;&realplayer;VMware&oracle;&wordperfect;DoomQuake, 等等。 此外, 也有人说, 某些情况下, 在 FreeBSD 上面运行的 Linux 程序的性能, 甚至好于直接在 Linux 上面运行。 然而, 仍然有一些只有 Linux 才有的操作系统特性在 FreeBSD 上并不被支持。 如果 Linux 程序过分地使用只能在 &i386; 上使用的特性, 例如启用虚拟 8086 模式, 则也有可能无法在 FreeBSD 上运行。 读完这章,您将了解到: 如何在您的系统中启用Linux兼容模式。 如何安装额外的Linux共享库。 如何在FreeBSD上安装Linux应用程序。 在FreeBSD上,Linux兼容模式的执行细节。 阅读这章之前,您应该知道: 如何安装第三方软件()。 安装 KLD (kernel loadable object) 默认情况下, 并不开启 Linux 二进制兼容支持。 启用这一功能最简单的方法是载入 linux KLD 模块 (Kernel LoaDable object)。 以 root 的身份, 键入下列命令即可: &prompt.root; kldload linux 如果希望 Linux 兼容支持在系统初始化过程中自动启用, 则应在 /etc/rc.conf 中增加: linux_enable="YES" &man.kldstat.8;可以用来检查KLD模块是否加载: &prompt.user; kldstat Id Refs Address Size Name 1 2 0xc0100000 16bdb8 kernel 7 1 0xc24db000 d000 linux.ko kernel options (内核选项) COMPAT_LINUX 如果您不想或者无法将Linux KLD加载,您就需要在内核中静态链接进Linux二进制兼容模式。您必须在 您的内核配置文件里面加入options COMPAT_LINUX,然后按照重新编译内核。 安装Linux运行时库 Linux 安装Linux运行时库 有两种方法来安装Linux运行时库,要么使用linux_base port, 要么手动安装。 通过使用 linux_base Port 来安装 Ports Collection 这是最容易的安装方法,只需要像安装其他port一样从 Ports Collection来安装: &prompt.root; cd /usr/ports/emulators/linux_base-fc4 &prompt.root; make install distclean 您现在应当是工作在Linux兼容模式下了。一些程序可能会提示系统库的版本不正确。通常,这不是问题。 有多个版本的emulators/linux_base port,针对不同的版本的Linux。 您应该选择最接近Linux应用程序需要的那个版本来安装。 手动安装 如果您没有安装 Ports Collection,您也可以通过手动来安装Linux运行时库。 您将需要这些程序依赖的Linux共享库,而且您需要创建一个shadow root 目录/compat/linux,任何要被Linux程序打开的共享库都首先在这个目录里面查找。 所以,如果一个Linux程序加载了,例如,/lib/libc.so,FreeBSD 会首先尝试打开 /compat/linux/lib/libc.so,如果不存在,它将尝试打开/lib/libc.so。 共享库应该安装在/compat/linux/lib而不是Linux ld.so报告的其他路径。 通常,您需要寻找Linux程序依赖的共享库。 此后, 你的系统上就会有一组 Linux 共享库, 这组共享库足以用来运行新安装的 Linux 二进制程序。 如何安装额外的共享库 共享库 如果您安装了linux_base port,但是您的 您的应用程序仍会报告丢失共享库的信息?您如何知道Linux程序需要哪个共享库? 基本上,有两种可能性(接下来的指令需要root权限): 如果您有可以访问的Linux系统, 看看应用程序需要什么共享库, 把它们复制到您的FreeBSD系统。看下面的例子: 我们假设您通过FTP得到Linux程序Doom, 并把它放在您能访问的Linux系统上。然后您可以通过ldd linuxdoom来检查需要哪些共享库, 就像这样: &prompt.user; ldd linuxdoom libXt.so.3 (DLL Jump 3.1) => /usr/X11/lib/libXt.so.3.1.0 libX11.so.3 (DLL Jump 3.1) => /usr/X11/lib/libX11.so.3.1.0 libc.so.4 (DLL Jump 4.5pl26) => /lib/libc.so.4.6.29 符号链接 您需要得到上面输出的右列的所有文件,并把它们复制到 /compat/linux, 第一列的名字用符号连接指向它们。这样您的FreeBSD系统上就有了这些文件: /compat/linux/usr/X11/lib/libXt.so.3.1.0 /compat/linux/usr/X11/lib/libXt.so.3 -> libXt.so.3.1.0 /compat/linux/usr/X11/lib/libX11.so.3.1.0 /compat/linux/usr/X11/lib/libX11.so.3 -> libX11.so.3.1.0 /compat/linux/lib/libc.so.4.6.29 /compat/linux/lib/libc.so.4 -> libc.so.4.6.29
如果您已经有了一个与ldd 输出的第一列的主修订号相匹配的Linux共享库, 您就已经完成了工作, 而不需要把右列命名的文件复制到您的系统上了。 如果有一个新的版本, 那无论如何都要复制一个共享库。 您可以删掉旧的, 您只要做一个符号连接到新的版本。 所以,如果有这些库在您的系统上: /compat/linux/lib/libc.so.4.6.27 /compat/linux/lib/libc.so.4 -> libc.so.4.6.27 如果您根据ldd输出的发现需要一个更新版本的库: libc.so.4 (DLL Jump 4.5pl26) -> libc.so.4.6.29 如果结尾的数字只有一到两个版本过期,那也不要担心复制 /lib/libc.so.4.6.29, 因为程序在稍微旧一些的版本上也能很好地工作。 然而,如果喜欢的话,您可以替换libc.so,变成这样: /compat/linux/lib/libc.so.4.6.29 /compat/linux/lib/libc.so.4 -> libc.so.4.6.29
符号链接机制 仅仅是 Linux 程序需要的。 FreeBSD 的运行时连接器会自己寻找匹配的主修订号,您不需要为此担心。
安装Linux ELF程序 Linux ELF程序 ELF格式的程序需要一步额外的步骤标记。如果您尝试运行没有标记的ELF程序, 您会得到像下面这样的错误信息: &prompt.user; ./my-linux-elf-binary ELF binary type not known Abort 为了帮助FreeBSD内核分辨FreeBSD ELF程序和Linux程序,要使用&man.brandelf.1;工具: &prompt.user; brandelf -t Linux my-linux-elf-binary GNU工具 GNU工具现在会自动把适当的标记信息放到ELF程序中,您以后遇到这个问题的机会越来越少。 配置主机名解析器 如果DNS不能正常工作或是您得到下列信息: resolv+: "bind" is an invalid keyword resolv+: "hosts" is an invalid keyword 您就需要配置/compat/linux/etc/host.conf文件,此文件包含: order hosts, bind multi on order这一行指出/etc/hosts先被搜索再接着搜索DNS。 如果/compat/linux/etc/host.conf没有被安装,Linux程序会读取FreeBSD的 /etc/host.conf然后提示不兼容的FreeBSD语法。 如果您没有使用/etc/resolv.conf 文件设置DNS,应该删除bind
Boris Hollas Updated for Mathematica 5.X by 安装&mathematica; applications Mathematica 这份文档介绍了如何在 FreeBSD 系统中安装 Linux 版本的 &mathematica; 5.X Linux 版本的 &mathematica;&mathematica; for Students 可以直接从 Wolfram 的 订购。 运行 &mathematica; 安装程序 首先您应告诉 &os; &mathematica; 的 Linux 可执行文件需要使用 Linux ABI。 达到这一目的最简单的办法, 是将未加标志的可执行文件的默认 ELF 标记为 Linux, 输入下面的命令: &prompt.root; sysctl kern.fallback_elf_brand=3 这回让 &os; 假定所有未加标志的 ELF 可执行文件, 都应使用 Linux ABI, 这样就可以直接从 CDROM 执行安装程序了。 接下来, 需要将 MathInstaller 复制到硬盘上: &prompt.root; mount /cdrom &prompt.root; cp /cdrom/Unix/Installers/Linux/MathInstaller /localdir/ 在这个文件的第一行中, 将 /bin/sh 改为 /compat/linux/bin/sh。 这样就能确保安装程序是使用 Linux 版本的 &man.sh.1; 来运行的。 接下来, 使用文本编辑器或下面的脚本, 把所有的 Linux) 替换为 FreeBSD)。 由于 &mathematica; 安装程序会调用 uname -s 来检测操作系统, 这样做能够让它视 &os; 为一种 类-Linux 操作系统。 现在执行 MathInstaller 就能安装 &mathematica; 了。 修改 &mathematica; 执行文件 在安装 &mathematica; 的过程中所创建的脚本, 必须首先进行适当的修改才能使用。 如果您选择将 /usr/local/bin 作为 &mathematica; 可执行文件的安装路径, 则可以在这个目录中找到一些到名为 mathmathematicaMathematica, 以及 MathKernel 的文件的符号连接。 您可以使用文本编辑器, 或者下面的 shell 脚本来将这些文件中的 Linux) 改为 FreeBSD) #!/bin/sh cd /usr/local/bin for i in math mathematica Mathematica MathKernel do sed 's/Linux)/FreeBSD)/g' $i > $i.tmp sed 's/\/bin\/sh/\/compat\/linux\/bin\/sh/g' $i.tmp > $i rm $i.tmp chmod a+x $i done 获得您的&mathematica; 密码 以太网 MAC地址 在首次启动 &mathematica; 时, 您将被问及一个密码。 如果您还未从 Wolfram 获得密码, 则安装目录中的 mathinfo 可以帮助您获得 machine ID (计算机 ID)。 这个计算机 ID 取决于您第一块以太网卡的 MAC 地址, 以确保您不在多台机器上运行 &mathematica; 在通过电子邮件、 电话或传真向 Wolfram 注册时, 您需要向他们提供 machine ID, 探后它们会给您一个与之对应的由一组数字组成的密码。 通过网络来运行&mathematica; &mathematica; 使用一些特殊的字体来显示字符, 与现在使用的标准字体不一样(integrals, sums, Greek letters,等等)。 X协议要求将这些字体安装在 本地。 这意味着您需要从&mathematica;的CDROM里面复制这些字体并安装到本地。 这些字体一般在CDROM的/cdrom/Unix/Files/SystemFiles/Fonts里面, 或本地硬盘的/usr/local/mathematica/SystemFiles/Fonts。 实际的字体在Type1X子目录。有很多种方法来使用它们。 第一种方法是把字体复制到一个已存在的目录/usr/X11R6/lib/X11/fonts。 这需要编辑fonts.dir文件。添加字体名字进去,并改变第一行的字体数目。 另外,您也需要在复制字体的目录下执行&man.mkfontdir.1;。 第二种方法是复制到 /usr/X11R6/lib/X11/fonts 目录: &prompt.root; cd /usr/X11R6/lib/X11/fonts &prompt.root; mkdir X &prompt.root; mkdir MathType1 &prompt.root; cd /cdrom/Unix/Files/SystemFiles/Fonts &prompt.root; cp X/* /usr/X11R6/lib/X11/fonts/X &prompt.root; cp Type1/* /usr/X11R6/lib/X11/fonts/MathType1 &prompt.root; cd /usr/X11R6/lib/X11/fonts/X &prompt.root; mkfontdir &prompt.root; cd ../MathType1 &prompt.root; mkfontdir 现在,添加新的字体目录到您的字体目录: &prompt.root; xset fp+ /usr/X11R6/lib/X11/fonts/X &prompt.root; xset fp+ /usr/X11R6/lib/X11/fonts/MathType1 &prompt.root; xset fp rehash 如果您正使用 &xorg; 服务器, 则可以通过修改 xorg.conf 文件来自动加载它们。 对于 &xfree86; 服务器, 配置文件的名字是 XF86Config fonts 如果您没有一个叫/usr/X11R6/lib/X11/fonts/Type1的目录, 您可以把MathType1改成Type1 Aaron Kaplan Contributed by Robert Getschmann Thanks to 安装&maple; 应用程序 Maple &maple;是一个类似于&mathematica;的商业数学软件。 您可以从买到这个软件并注册得到一个使用许可。 要在FreeBSD上安装这个软件,请按照下面的步骤: 从软件的发行包执行INSTALL shell脚本。当进入安装程序的提示符时, 选择RedHat 选项。典型的安装目录是/usr/local/maple 如果您不这样做,可以从Maple Waterloo Software () 为 &maple; 订购一个授权许可。 然后把它复制到 /usr/local/maple/license/license.dat 通过运行&maple;中的INSTALL_LIC安装shell脚本来 安装FLEXlm许可管理器。 指定许可服务器为您的机器名。 像下面这样Patch您的/usr/local/maple/bin/maple.system.type 文件: ----- snip ------------------ *** maple.system.type.orig Sun Jul 8 16:35:33 2001 --- maple.system.type Sun Jul 8 16:35:51 2001 *************** *** 72,77 **** --- 72,78 ---- # the IBM RS/6000 AIX case MAPLE_BIN="bin.IBM_RISC_UNIX" ;; + "FreeBSD"|\ "Linux") # the Linux/x86 case # We have two Linux implementations, one for Red Hat and ----- snip end of patch ----- 请注意"FreeBSD"|\后面没有空格。 这个补丁指示&maple;FreeBSD识别为一种Linux系统。 bin/maple shell脚本调用bin/maple.system.type 脚本执行uname -a来查找操作系统名,根据操作系统名,就知道该使用哪个程序。 启动许可服务器。 下面的脚本,安装成/usr/local/etc/rc.d/lmgrd.sh, 是很方便的启动lmgrd的方法: ----- snip ------------ #! /bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin PATH=${PATH}:/usr/local/maple/bin:/usr/local/maple/FLEXlm/UNIX/LINUX export PATH LICENSE_FILE=/usr/local/maple/license/license.dat LOG=/var/log/lmgrd.log case "$1" in start) lmgrd -c ${LICENSE_FILE} 2>> ${LOG} 1>&2 echo -n " lmgrd" ;; stop) lmgrd -c ${LICENSE_FILE} -x lmdown 2>> ${LOG} 1>&2 ;; *) echo "Usage: `basename $0` {start|stop}" 1>&2 exit 64 ;; esac exit 0 ----- snip ------------ 开始测试&maple; &prompt.user; cd /usr/local/maple/bin &prompt.user; ./xmaple 您应该成功启动起来了。记得写信告诉Maplesoft您想要一个本地FreeBSD版本! 一些缺陷 FLEXlm许可管理器可能是一个使用比较困难的工具。 关于它的额外的文档可以在找到。 lmgrd对许可文件非常挑剔,有一点问题就会core dump。 正确的许可文件看起来像下面这样: # ======================================================= # License File for UNIX Installations ("Pointer File") # ======================================================= SERVER chillig ANY #USE_SERVER VENDOR maplelmg FEATURE Maple maplelmg 2000.0831 permanent 1 XXXXXXXXXXXX \ PLATFORMS=i86_r ISSUER="Waterloo Maple Inc." \ ISSUED=11-may-2000 NOTICE=" Technische Universitat Wien" \ SN=XXXXXXXXX 序列号被'X'代替了。 chillig是主机名。 只要不修改FEATURE行,编辑后一般都能工作。 Dan Pelleg Contributed by 安装&matlab; 应用程序 MATLAB 这一节描述在一个 &os; 上安装Linux版本的&matlab; version 6.5。 它工作的很好,除了&java.virtual.machine;例外(参考 )。 Linux版本的&matlab;可以从MathWorks订购。请确定您也得到了许可文件或安装说明。 等您成功后,让他们知道您想要一个本地&os;版本。 安装&matlab; 请按照下面的步骤安装&matlab; root身份插入安装CD并挂载上。 推荐使用安装脚本,为了启动安装脚本,键入: &prompt.root; /compat/linux/bin/sh /cdrom/install 安装程序是图形的。如果您得到不能打开显示的错误,可以键入 setenv HOME ~USERUSER是您&man.su.1;成的用户。 当问&matlab;的根目录时,键入: /compat/linux/usr/local/matlab 为了下面的安装过程更方便,在shell提示符下键入 set MATLAB=/compat/linux/usr/local/matlab 根据获得&matlab;许可时的指示来编辑许可文件。 您可以用您喜欢的编辑器提前准备这个文件, 并在安装程序要您编辑它之前复制到 $MATLAB/license.dat 完成安装过程 到这里,您的&matlab;安装已经完成了。 接下来的步骤是让它和您的&os; 系统胶合在一起。 许可管理器的启动 为许可管理器建立符号链接的脚本: &prompt.root; ln -s $MATLAB/etc/lmboot /usr/local/etc/lmboot_TMW &prompt.root; ln -s $MATLAB/etc/lmdown /usr/local/etc/lmdown_TMW 建立启动文件/usr/local/etc/rc.d/flexlm.sh。 下面的例子是一个$MATLAB/etc/rc.lm.glnx86的修改版本。 变化的是文件的位置,和模拟Linux下许可管理器的启动。 #!/bin/sh case "$1" in start) if [ -f /usr/local/etc/lmboot_TMW ]; then /compat/linux/bin/sh /usr/local/etc/lmboot_TMW -u username && echo 'MATLAB_lmgrd' fi ;; stop) if [ -f /usr/local/etc/lmdown_TMW ]; then /compat/linux/bin/sh /usr/local/etc/lmdown_TMW > /dev/null 2>&1 fi ;; *) echo "Usage: $0 {start|stop}" exit 1 ;; esac exit 0 必须使脚本文件可执行: &prompt.root; chmod +x /usr/local/etc/rc.d/flexlm.sh 您也必须替换username为机器上的一个用户(不要是root)。 用命令启动许可管理器: &prompt.root; /usr/local/etc/rc.d/flexlm.sh start 链接&java;运行时环境 改变&java;运行时环境(JRE),链接到一个可以工作的版本: &prompt.root; cd $MATLAB/sys/java/jre/glnx86/ &prompt.root; unlink jre; ln -s ./jre1.1.8 ./jre 创建&matlab;启动脚本 把下面的启动脚本放到/usr/local/bin/matlab #!/bin/sh /compat/linux/bin/sh /compat/linux/usr/local/matlab/bin/matlab "$@" 然后输入命令chmod +x /usr/local/bin/matlab 依赖于您的emulators/linux_base版本, 您在运行这个脚本时可能会出错,为了避免错误,编辑/compat/linux/usr/local/matlab/bin/matlab, 把这行: if [ `expr "$lscmd" : '.*->.*'` -ne 0 ]; then (在13.0.1版本是在第410行)改成: if test -L $newbase; then Creating a &matlab; Shutdown Script The following is needed to solve a problem with &matlab; not exiting correctly. Create a file $MATLAB/toolbox/local/finish.m, and in it put the single line: ! $MATLAB/bin/finish.sh The $MATLAB is literal. In the same directory, you will find the files finishsav.m and finishdlg.m, which let you save your workspace before quitting. If you use either of them, insert the line above immediately after the save command. Create a file $MATLAB/bin/finish.sh, which will contain the following: #!/usr/compat/linux/bin/sh (sleep 5; killall -1 matlab_helper) & exit 0 Make the file executable: &prompt.root; chmod +x $MATLAB/bin/finish.sh 使用&matlab; 现在您已经可以键入 matlab 并开始使用它了。 Marcel Moolenaar Contributed by 安装&oracle; 应用程序 Oracle 前言 这节描述在FreeBSD上安装Linux版的&oracle; 8.0.5&oracle; 8.0.5.1 Enterprise Edition 安装Linux环境 确信您已经从 Ports Collection 安装了 emulators/linux_basedevel/linux_devtools。 如果在使用这些 port 时遇到困难, 您可能就不得不从 package, 或使用较早版本的 Ports Collection 来安装。 如果要运行智能代理, 您还需要安装 Red Hat Tcl 软件包: tcl-8.0.3-20.i386.rpm。 用于安装官方的 RPM (archivers/rpm) 软件包的命令是: &prompt.root; rpm -i --ignoreos --root /compat/linux --dbpath /var/lib/rpm package 的安装通常不会出错。 创建&oracle;环境 安装&oracle;之前,您需要设置正确的环境。 这节只描述了在FreeBSD下安装Linux版本&oracle;需要特别注意的地方。 不像在&oracle;安装指南中所描述的那样。 调整内核 调整内核 正如&oracle;安装指南描述的那样,您需要设置共享内存的最大值。 不要在FreeBSD下使用SHMMAXSHMMAX 只是用来计算SHMMAXPGSPGSIZE的。 因此要使用SHMMAXPGS。所有其他要使用的选项可以参考指南,例如: options SHMMAXPGS=10000 options SHMMNI=100 options SHMSEG=10 options SEMMNS=200 options SEMMNI=70 options SEMMSL=61 设置这些选项来适应 &oracle;的使用。 当然,确信您的内核配置文件中有下面这些选项: options SYSVSHM #SysV shared memory options SYSVSEM #SysV semaphores options SYSVMSG #SysV interprocess communication &oracle;帐号 创建一个oracle帐号,正如您创建其他帐号一样。 oracle 帐号特殊的地方是您需要给它一个Linux shell。 添加/compat/linux/bin/bash/etc/shells, 然后设置oracle帐号的shell为/compat/linux/bin/bash 环境 除了普通的&oracle;变量外, 比如ORACLE_HOMEORACLE_SID,您还必须设置下面的环境变量: 变量 LD_LIBRARY_PATH $ORACLE_HOME/lib CLASSPATH $ORACLE_HOME/jdbc/lib/classes111.zip PATH /compat/linux/bin /compat/linux/sbin /compat/linux/usr/bin /compat/linux/usr/sbin /bin /sbin /usr/bin /usr/sbin /usr/local/bin $ORACLE_HOME/bin 建议在.profile里面设置所有的环境变量。一个完整的例子是: ORACLE_BASE=/oracle; export ORACLE_BASE ORACLE_HOME=/oracle; export ORACLE_HOME LD_LIBRARY_PATH=$ORACLE_HOME/lib export LD_LIBRARY_PATH ORACLE_SID=ORCL; export ORACLE_SID ORACLE_TERM=386x; export ORACLE_TERM CLASSPATH=$ORACLE_HOME/jdbc/lib/classes111.zip export CLASSPATH PATH=/compat/linux/bin:/compat/linux/sbin:/compat/linux/usr/bin PATH=$PATH:/compat/linux/usr/sbin:/bin:/sbin:/usr/bin:/usr/sbin PATH=$PATH:/usr/local/bin:$ORACLE_HOME/bin export PATH 安装&oracle; 由于 Linux 模拟器的一处小小的差异, 您必须在 /var/tmp 中创建一个名为 .oracle 的目录才能够启动安装程序。 需要把它设置为属于 oracle 用户。 接下来, 您就可以毫无问题地安装 &oracle; 了。 如果您遇到问题, 请首先检查 &oracle; 软件包和/或配置文件!安装完 &oracle; 之后, 使用下面两节中所说的补丁。 一个比较常见的问题是 TCP 协议适配器安装不正确。 其结果是将无法进行任何的 TCP 侦听。 下面的操作将帮助解决此问题: &prompt.root; cd $ORACLE_HOME/network/lib &prompt.root; make -f ins_network.mk ntcontab.o &prompt.root; cd $ORACLE_HOME/lib &prompt.root; ar r libnetwork.a ntcontab.o &prompt.root; cd $ORACLE_HOME/network/lib &prompt.root; make -f ins_network.mk install 不要忘记了再运行一下root.sh 修补root.sh 从CD安装&oracle;时,一些工作需要在root下执行, 这些工作都被记录在一个叫root.sh的脚本里面。这个脚本被写在orainst目录。 为了使用root.sh来正确定位chown或在Linux本地shell下执行脚本, 应该对它进行修补。 *** orainst/root.sh.orig Tue Oct 6 21:57:33 1998 --- orainst/root.sh Mon Dec 28 15:58:53 1998 *************** *** 31,37 **** # This is the default value for CHOWN # It will redefined later in this script for those ports # which have it conditionally defined in ss_install.h ! CHOWN=/bin/chown # # Define variables to be used in this script --- 31,37 ---- # This is the default value for CHOWN # It will redefined later in this script for those ports # which have it conditionally defined in ss_install.h ! CHOWN=/usr/sbin/chown # # Define variables to be used in this script 当您不从CD安装&oracle;时, 您可以从源代码来修补root.sh。 它叫做rthd.sh,定位在源代码树的orainst目录。 修补genclntsh genclntsh脚本用来创建一个简单的共享客户端库。在建立demos时被使用。 完成补丁后就注释掉了下面的PATH变量: *** bin/genclntsh.orig Wed Sep 30 07:37:19 1998 --- bin/genclntsh Tue Dec 22 15:36:49 1998 *************** *** 32,38 **** # # Explicit path to ensure that we're using the correct commands #PATH=/usr/bin:/usr/ccs/bin export PATH ! PATH=/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin export PATH # # each product MUST provide a $PRODUCT/admin/shrept.lst --- 32,38 ---- # # Explicit path to ensure that we're using the correct commands #PATH=/usr/bin:/usr/ccs/bin export PATH ! #PATH=/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin export PATH # # each product MUST provide a $PRODUCT/admin/shrept.lst 运行&oracle; 如果您已经按上面的指示去操作,您应该可以像在Linux下运行&oracle;了。 Holger Kipp Contributed by Valentino Vaschetto Original version converted to SGML by 安装&sap.r3; 应用程序 SAP R/3 在FreeBSD上安装的&sap;系统不会被&sap; 支持团队— 所支持——他们只支持某些特定的平台。 前言 这篇文章描述了在FreeBSD系统上安装一个带有&oracle; Database for Linux的&sap.r3; System,包括 FreeBSD的安装和&oracle;的安装。 下面将描述两个不同的配置: 在FreeBSD 4.3-STABLE上安装带有&oracle; 8.0.5&sap.r3; 4.6B (IDES) 在FreeBSD 4.5-STABLE上安装带有&oracle; 8.1.7&sap.r3; 4.6C 虽然这篇文章深入地描述了许多重要的安装步骤,但它不能取代&oracle;&sap.r3;的安装指南。 请参考&sap.r3; Linux edition自带的文档和 &oracle;的特殊问题。 软件 下面的CD-ROMs被用作&sap;的安装: &sap.r3; 4.6B, &oracle; 8.0.5 名称 号码 描述 KERNEL 51009113 SAP Kernel Oracle / Installation / AIX, Linux, Solaris RDBMS 51007558 Oracle / RDBMS 8.0.5.X / Linux EXPORT1 51010208 IDES / DB-Export / Disc 1 of 6 EXPORT2 51010209 IDES / DB-Export / Disc 2 of 6 EXPORT3 51010210 IDES / DB-Export / Disc 3 of 6 EXPORT4 51010211 IDES / DB-Export / Disc 4 of 6 EXPORT5 51010212 IDES / DB-Export / Disc 5 of 6 EXPORT6 51010213 IDES / DB-Export / Disc 6 of 6 此外,我们使用&oracle; 8 Server (Linux版本的8.0.5预览版,Linux内核是2.0.33)和 FreeBSD 4.3-STABLE。 &sap.r3; 4.6C SR2, &oracle; 8.1.7 名称 号码 描述 KERNEL 51014004 SAP Kernel Oracle / SAP Kernel Version 4.6D / DEC, Linux RDBMS 51012930 Oracle 8.1.7/ RDBMS / Linux EXPORT1 51013953 Release 4.6C SR2 / Export / Disc 1 of 4 EXPORT1 51013953 Release 4.6C SR2 / Export / Disc 2 of 4 EXPORT1 51013953 Release 4.6C SR2 / Export / Disc 3 of 4 EXPORT1 51013953 Release 4.6C SR2 / Export / Disc 4 of 4 LANG1 51013954 Release 4.6C SR2 / Language / DE, EN, FR / Disc 1 of 3 依赖于您要安装的语言,可能需要额外的语言CDs。 这儿我们只使用DE和EN,所以只需要第一张语言CD。 还要注意的是所有EXPORT CDs的号码是一样的。 其他3张语言CDs的号码也一样(这和4.6B IDES release CD的号码不同)。 &sap; Notes 安装使用&sap.r3;之前,请先看看下面的注释: &sap.r3; 4.6B, &oracle; 8.0.5 号码 标题 0171356 SAP Software on Linux: Essential Comments 0201147 INST: 4.6C R/3 Inst. on UNIX - Oracle 0373203 Update / Migration Oracle 8.0.5 --> 8.0.6/8.1.6 LINUX 0072984 Release of Digital UNIX 4.0B for Oracle 0130581 R3SETUP step DIPGNTAB terminates 0144978 Your system has not been installed correctly 0162266 Questions and tips for R3SETUP on Windows NT / W2K &sap.r3; 4.6C, &oracle; 8.1.7 号码 标题 0015023 Initializing table TCPDB (RSXP0004) (EBCDIC) 0045619 R/3 with several languages or typefaces 0171356 SAP Software on Linux: Essential Comments 0195603 RedHat 6.1 Enterprise version: Known problems 0212876 The new archiving tool SAPCAR 0300900 Linux: Released DELL Hardware 0377187 RedHat 6.2: important remarks 0387074 INST: R/3 4.6C SR2 Installation on UNIX 0387077 INST: R/3 4.6C SR2 Inst. on UNIX - Oracle 0387078 SAP Software on UNIX: OS Dependencies 4.6C SR2 硬件要求 下面的设备配置对&sap.r3; System来说已经足够了。如果 用于生产用途,就需要更强的配置: 组件 4.6B 4.6C 处理器 2 x 800MHz &pentium; III 2 x 800MHz &pentium; III 内存 1GB ECC 2GB ECC Hard Disk Space 50-60GB (IDES) 50-60GB (IDES) 用于生产使用,就需要使用带大缓存的&xeon;处理器,和高速大容量磁盘(SCSI, RAID hardware controller),以及USV 和ECC-RAM内存。 配置IDES System前需要大量的硬盘空间,因为安装时将创建27 GB的数据库文件。 这些空间用于系统和数据的初始化也是足够的。 &sap.r3; 4.6B, &oracle; 8.0.5 对于这个安装,我的硬件配置如下:带2个800 MHz &pentium; III处理器的主板, &adaptec; 29160 Ultra160 SCSI适配器(能够访问40/80 GB DLT磁带机和CDROM), &mylex; &acceleraid; (2个通道, firmware 6.00-1-00 with 32 MB RAM)。 &mylex; RAID controller被挂上2个17 GB(mirrored)硬盘和4个36 GB硬盘(RAID level 5)。 &sap.r3; 4.6C, &oracle; 8.1.7 对于这个安装,配置是&dell; &poweredge; 2500,带2个1000 MHz &pentium; III处理器的 主板(256 kB Cache), 2 GB PC133 ECC SDRAM, PERC/3 DC PCI RAID Controller with 128 MB,和一个EIDE DVD-ROM驱动器。RAID controller被挂上2个18 GB硬盘(mirrored) 和4个36 GB硬盘(RAID level 5)。 安装FreeBSD 首先需要安装 FreeBSD。 有很多方法来完成这个工作。 要了解进一步的情况请参考 磁盘划分 为了简单,对&sap.r3; 46B&sap.r3; 46C SR2的安装使用相同的磁盘划分。只是设备名换了,因为是安装在不同的硬件上 (/dev/da/dev/amr, 所以如果是使用AMI &megaraid;,我们能看到 /dev/amr0s1a 代替了 /dev/da0s1a): 文件系统 尺寸(1k-blocks) 尺寸(GB) 挂载点 /dev/da0s1a 1.016.303 1 / /dev/da0s1b 6 swap /dev/da0s1e 2.032.623 2 /var /dev/da0s1f 8.205.339 8 /usr /dev/da1s1e 45.734.361 45 /compat/linux/oracle /dev/da1s1f 2.032.623 2 /compat/linux/sapmnt /dev/da1s1g 2.032.623 2 /compat/linux/usr/sap 预先用&mylex; 或PERC/3 RAID 软件配置和初始化这两个逻辑驱动器。 改变BIOS的引导顺序来启动软件。 请注意这里的磁盘划分和&sap;推荐的是不一样的,&sap;建议把 &oracle;子目录(及其他子目录)分离开来, 我决定只简单的创建几个子目录。 <command>make world</command>和建立新内核 下载最新的-STABLE源代码,配置完内核配置文件后重建系统和新内核。 这儿当然要包括 &sap.r3;&oracle;需要的内核参数。 安装Linux环境 安装Linux基本系统 首先linux_base port需要安装(以root身份): &prompt.root; cd /usr/ports/emulators/linux_base &prompt.root; make install distclean 安装Linux开发环境 如果您想根据在FreeBSD上安装 &oracle; &prompt.root; cd /usr/ports/devel/linux_devtools &prompt.root; make install distclean Linux开发环境只是安装给&sap.r3; 46B IDES的,如果&oracle; DB不是在这个 FreeBSD系统上重新链接,它就不需要了。 安装必需的RPMs RPMs 为了启动R3SETUP程序, PAM支持是必需的。 第一次安装&sap;到FreeBSD 4.3-STABLE时我们先安装了 PAM的所有依赖包再安装PAM包,它可以工作。对于&sap.r3; 4.6C SR2我们 直接安装PAM RPM也可以工作,所以依赖包不是必需的: &prompt.root; rpm -i --ignoreos --nodeps --root /compat/linux --dbpath /var/lib/rpm \ pam-0.68-7.i386.rpm 要让&oracle; 8.0.5运行智能代理, 我们需要安装RedHat Tcl包tcl-8.0.5-30.i386.rpm (否则重新链接&oracle;不能工作)。 重新链接&oracle;时还有其他要注意的地方, 但那是&oracle; Linux的问题,不是FreeBSD的问题。 其它一些注意的地方 添加 linprocfs/etc/fstab 是个好主意。 要了解进一步的细节, 请参考 &man.linprocfs.5; 联机手册。 另一个是设置 kern.fallback_elf_brand=3, 这可以通过 /etc/sysctl.conf 文件来完成。 创建&sap.r3;环境 创建必需的文件系统和挂载点 对简单的安装,创建下面的文件系统就够了: mount point size in GB /compat/linux/oracle 45 GB /compat/linux/sapmnt 2 GB /compat/linux/usr/sap 2 GB 创建一些链接也是必要的,否则&sap;安装程序在检查创建的链接时 会报错: &prompt.root; ln -s /compat/linux/oracle /oracle &prompt.root; ln -s /compat/linux/sapmnt /sapmnt &prompt.root; ln -s /compat/linux/usr/sap /usr/sap 安装时可能出现的错误(对于PRD系统和&sap.r3; 4.6C SR2 的安装): INFO 2002-03-19 16:45:36 R3LINKS_IND_IND SyLinkCreate:200 Checking existence of symbolic link /usr/sap/PRD/SYS/exe/dbg to /sapmnt/PRD/exe. Creating if it does not exist... WARNING 2002-03-19 16:45:36 R3LINKS_IND_IND SyLinkCreate:400 Link /usr/sap/PRD/SYS/exe/dbg exists but it points to file /compat/linux/sapmnt/PRD/exe instead of /sapmnt/PRD/exe. The program cannot go on as long as this link exists at this location. Move the link to another location. ERROR 2002-03-19 16:45:36 R3LINKS_IND_IND Ins_SetupLinks:0 can not setup link '/usr/sap/PRD/SYS/exe/dbg' with content '/sapmnt/PRD/exe' 创建用户和目录 &sap.r3;需要两个用户和3个组。 用户名依赖于包含3个字母的&sap;系统ID(SID)。一些SIDs 被&sap;保留(例如SAPNIX)。 完成的列表参考&sap;文档。对于IDES的安装,我们使用IDS, 对于4.6C SR2安装,使用PRD。 这样我们定义了下面的几个组: 组ID 组名 描述 100 dba Data Base Administrator 101 sapsys &sap; System 102 oper Data Base Operator 对于默认的&oracle;安装,只有dba组被使用。 和oper组一样,我们也可以使用dba组 (更详细的信息参考&oracle;&sap;文档)。 我们也需要下面的用户 用户ID 用户名 普通名称 附加组 描述 1000 idsadm/prdadm sidadm sapsys oper &sap; Administrator 1002 oraids/oraprd orasid dba oper &oracle; Administrator 使用&man.adduser.8;添加用户要求&sap; Administrator有下面的记录 (请注意shell和home目录): Name: sidadm Password: ****** Fullname: SAP Administrator SID Uid: 1000 Gid: 101 (sapsys) Class: Groups: sapsys dba HOME: /home/sidadm Shell: bash (/compat/linux/bin/bash) 对于&oracle; Administrator: Name: orasid Password: ****** Fullname: Oracle Administrator SID Uid: 1002 Gid: 100 (dba) Class: Groups: dba HOME: /oracle/sid Shell: bash (/compat/linux/bin/bash) 在您使用组dbaoper的情况下您也应该包括 oper 创建目录 这些目录通常建立在不同的文件系统上。这完全依赖于您的需求。 我们选择把它们建立在同一个目录: 首先我们将设置一些目录的所有者和权限(以root身份设置): &prompt.root; chmod 775 /oracle &prompt.root; chmod 777 /sapmnt &prompt.root; chown root:dba /oracle &prompt.root; chown sidadm:sapsys /compat/linux/usr/sap &prompt.root; chmod 775 /compat/linux/usr/sap 然后我们以orasid身份创建目录, 这些目录将成为/oracle/SID的子目录: &prompt.root; su - orasid &prompt.root; cd /oracle/SID &prompt.root; mkdir mirrlogA mirrlogB origlogA origlogB &prompt.root; mkdir sapdata1 sapdata2 sapdata3 sapdata4 sapdata5 sapdata6 &prompt.root; mkdir saparch sapreorg &prompt.root; exit 对于&oracle; 8.1.7的安装,需要一些额外的目录: &prompt.root; su - orasid &prompt.root; cd /oracle &prompt.root; mkdir 805_32 &prompt.root; mkdir client stage &prompt.root; mkdir client/80x_32 &prompt.root; mkdir stage/817_32 &prompt.root; cd /oracle/SID &prompt.root; mkdir 817_32 目录client/80x_32必须是这个名字,不要用其他数字或字母来替换x 第三步我们要以sidadm身份创建目录: &prompt.root; su - sidadm &prompt.root; cd /usr/sap &prompt.root; mkdir SID &prompt.root; mkdir trans &prompt.root; exit <filename>/etc/services</filename>中的条目 &sap.r3;/etc/services里面需要一些条目, 这些不会在安装过程中被正确设置,请添加下面的条目: sapdp00 3200/tcp # SAP Dispatcher. 3200 + Instance-Number sapgw00 3300/tcp # SAP Gateway. 3300 + Instance-Number sapsp00 3400/tcp # 3400 + Instance-Number sapms00 3500/tcp # 3500 + Instance-Number sapmsSID 3600/tcp # SAP Message Server. 3600 + Instance-Number sapgw00s 4800/tcp # SAP Secure Gateway 4800 + Instance-Number 必要的本地化 本地化 &sap;至少要求两个本地化设置,它不是RedHat的默认安装。 &sap;提供从他们的FTP服务器下载必需的RPMs(只有您是OSS的客户才能访问)。 看注解0171356查找您需要的RPMs列表。 也可以只创建适当的链接(例如从de_DEen_US), 但是我们不推荐在生产系统上这样做(尽管它让IDES system工作的没有一点问题)。 下面的本地化设置是必需的: de_DE.ISO-8859-1 en_US.ISO-8859-1 像这样创建链接 &prompt.root; cd /compat/linux/usr/share/locale &prompt.root; ln -s de_DE de_DE.ISO-8859-1 &prompt.root; ln -s en_US en_US.ISO-8859-1 如果他们不出现,在安装时可能会有问题。如果忽略这些问题(通过设置CENTRDB.R3S文件 里面的STATUSOK),不费一番周折, 您就别想登录进&sap;系统。 内核调整 内核调整 &sap.r3; 需要许多资源。我因此添加了下面的参数在我的内核配置文件中: # Set these for memory pigs (SAP and Oracle): options MAXDSIZ="(1024*1024*1024)" options DFLDSIZ="(1024*1024*1024)" # System V options needed. options SYSVSHM #SYSV-style shared memory options SHMMAXPGS=262144 #max amount of shared mem. pages #options SHMMAXPGS=393216 #use this for the 46C inst.parameters options SHMMNI=256 #max number of shared memory ident if. options SHMSEG=100 #max shared mem.segs per process options SYSVMSG #SYSV-style message queues options MSGSEG=32767 #max num. of mes.segments in system options MSGSSZ=32 #size of msg-seg. MUST be power of 2 options MSGMNB=65535 #max char. per message queue options MSGTQL=2046 #max amount of msgs in system options SYSVSEM #SYSV-style semaphores options SEMMNU=256 #number of semaphore UNDO structures options SEMMNS=1024 #number of semaphores in system options SEMMNI=520 #number of semaphore identifiers options SEMUME=100 #number of UNDO keys 这篇文档中指定的最小值是来自&sap;。 没有针对Linux的描述, 看看HP-UX的相关介绍了解更多信息。 安装4.6C SR2需要更多的内存, 共享内存比 &sap;&oracle; 需要的还多, 所以尽量为共享内存选一个大值。 在 &i386; 上 的 FreeBSD 默认配置中, 应将 MAXDSIZDFLDSIZ 设置为 1 GB。否则, 会出现类似 ORA-27102: out of memoryLinux Error: 12: Cannot allocate memory 这样的奇怪的错误。 安装&sap.r3; 准备&sap; CDROMs 在安装过程中,有许多 CDROM 要被挂上和卸下。建议您有多个CDROM驱动器, 您可以把它们都挂上。我决定复制 CDROM 的内容到相应的目录: /oracle/SID/sapreorg/cd-name 对于4.6B/IDES的安装,cd-nameKERNELRDBMSEXPORT1EXPORT2EXPORT3, EXPORT4, EXPORT5EXPORT6中的一个,对于4.6C SR2的安装,是 KERNELRDBMSDISK1DISK2DISK3DISK4LANG中的一个。 所有挂载上的CDs里面的文件名都应该是大写, 否则要用选项来挂载。所以使用下面的命令: &prompt.root; mount_cd9660 -g /dev/cd0a /mnt &prompt.root; cp -R /mnt/* /oracle/SID/sapreorg/cd-name &prompt.root; umount /mnt 运行安装脚本 首先您需要准备一个install目录: &prompt.root; cd /oracle/SID/sapreorg &prompt.root; mkdir install &prompt.root; cd install 然后运行安装脚本,他会复制所有相关的文件到install目录: &prompt.root; /oracle/SID/sapreorg/KERNEL/UNIX/INSTTOOL.SH 由于这是一个完全定制化的&sap.r3;演示系统的IDES安装(4.6B), 我们有6个而不仅仅是3个EXPORT CDs。 基于这点,安装模板CENTRDB.R3S是用来安装一个标准的中央环境 (&r3;和数据库),而不是IDES中央环境, 所以从EXPORT1目录复制相应的CENTRDB.R3S, 否则R3SETUP只要求3个EXPORT CDs。 新的&sap; 4.6C SR2发行版带有4张EXPORT CDs。 控制安装步骤的参数文件是CENTRAL.R3S。 和早期发行版不同,它没有分开的中央环境的安装模板。 安装完后,使用hostname命令得到&sap;需要的主机名, 不需要完整的域名。 所以为orasidsidadm 直接设置主机名,或设置别名alias hostname='hostname -s'。 可以在.profile.login里面为这两个用户设置。 启动<command>R3SETUP</command> 4.6B 确定LD_LIBRARY_PATH设置正确: &prompt.root; export LD_LIBRARY_PATH=/oracle/IDS/lib:/sapmnt/IDS/exe:/oracle/805_32/lib 从安装目录以root身份启动R3SETUP &prompt.root; cd /oracle/IDS/sapreorg/install &prompt.root; ./R3SETUP -f CENTRDB.R3S 这个脚本会问一些问题(括号里面是缺省值,后面是实际输入): 问题 缺省值 输入 Enter SAP System ID [C11] IDSEnter Enter SAP Instance Number [00] Enter Enter SAPMOUNT Directory [/sapmnt] Enter Enter name of SAP central host [troubadix.domain.de] Enter Enter name of SAP db host [troubadix] Enter Select character set [1] (WE8DEC) Enter Enter Oracle server version (1) Oracle 8.0.5, (2) Oracle 8.0.6, (3) Oracle 8.1.5, (4) Oracle 8.1.6 1Enter Extract Oracle Client archive [1] (Yes, extract) Enter Enter path to KERNEL CD [/sapcd] /oracle/IDS/sapreorg/KERNEL Enter path to RDBMS CD [/sapcd] /oracle/IDS/sapreorg/RDBMS Enter path to EXPORT1 CD [/sapcd] /oracle/IDS/sapreorg/EXPORT1 Directory to copy EXPORT1 CD [/oracle/IDS/sapreorg/CD4_DIR] Enter Enter path to EXPORT2 CD [/sapcd] /oracle/IDS/sapreorg/EXPORT2 Directory to copy EXPORT2 CD [/oracle/IDS/sapreorg/CD5_DIR] Enter Enter path to EXPORT3 CD [/sapcd] /oracle/IDS/sapreorg/EXPORT3 Directory to copy EXPORT3 CD [/oracle/IDS/sapreorg/CD6_DIR] Enter Enter path to EXPORT4 CD [/sapcd] /oracle/IDS/sapreorg/EXPORT4 Directory to copy EXPORT4 CD [/oracle/IDS/sapreorg/CD7_DIR] Enter Enter path to EXPORT5 CD [/sapcd] /oracle/IDS/sapreorg/EXPORT5 Directory to copy EXPORT5 CD [/oracle/IDS/sapreorg/CD8_DIR] Enter Enter path to EXPORT6 CD [/sapcd] /oracle/IDS/sapreorg/EXPORT6 Directory to copy EXPORT6 CD [/oracle/IDS/sapreorg/CD9_DIR] Enter Enter amount of RAM for SAP + DB 850Enter (in Megabytes) Service Entry Message Server [3600] Enter Enter Group-ID of sapsys [101] Enter Enter Group-ID of oper [102] Enter Enter Group-ID of dba [100] Enter Enter User-ID of sidadm [1000] Enter Enter User-ID of orasid [1002] Enter Number of parallel procs [2] Enter 如果没有把CD复制到不同的位置,那么&sap;安装程序就不能 找到需要的CD(通过CD上的LABEL.ASC来辨别), 它会要求您挂上CD,或键入加载路径。 CENTRDB.R3S不可能是自由出错的, 它再次请求EXPORT4 CD,但是正确的值是6_LOCATI ON,然后7_LOCATION 等,所以您可以键入正确的值。 处理下面提到的问题,一样东西都要直接通过&oracle;数据库软件安装的地方。 Start <command>R3SETUP</command> 4.6C SR2 确定LD_LIBRARY_PATH设置正确。 这和带&oracle; 8.0.5的4.6B的安装是不同的: &prompt.root; export LD_LIBRARY_PATH=/sapmnt/PRD/exe:/oracle/PRD/817_32/lib root身份从安装目录启动R3SETUP &prompt.root; cd /oracle/PRD/sapreorg/install &prompt.root; ./R3SETUP -f CENTRAL.R3S 这个脚本会问一些问题(括号里面是缺省值,后面是实际输入): 问题 缺省值 输入 Enter SAP System ID [C11] PRDEnter Enter SAP Instance Number [00] Enter Enter SAPMOUNT Directory [/sapmnt] Enter Enter name of SAP central host [majestix] Enter Enter Database System ID [PRD] PRDEnter Enter name of SAP db host [majestix] Enter Select character set [1] (WE8DEC) Enter Enter Oracle server version (2) Oracle 8.1.7 2Enter Extract Oracle Client archive [1] (Yes, extract) Enter Enter path to KERNEL CD [/sapcd] /oracle/PRD/sapreorg/KERNEL Enter amount of RAM for SAP + DB 2044 1800Enter (in Megabytes) Service Entry Message Server [3600] Enter Enter Group-ID of sapsys [100] Enter Enter Group-ID of oper [101] Enter Enter Group-ID of dba [102] Enter Enter User-ID of oraprd [1002] Enter Enter User-ID of prdadm [1000] Enter LDAP support 3Enter (no support) Installation step completed [1] (continue) Enter Choose installation service [1] (DB inst,file) Enter 到目前为止, 安装阶段只在创建用户时给出了一个错误OSUSERDBSID_IND_ORA(创建 用户orasid)和 OSUSERSIDADM_IND_ORA(创建用户sidadm)。 处理下面提到的问题,一样东西都要直接通过&oracle;数据库软件安装的地方。 安装&oracle; 8.0.5 请看相应的&sap;注释和 &oracle;的关于Linux的Readme 以及&oracle; DB可能出现的问题。不是所有的问题都和不兼容库有关。 关于&oracle;更多的安装信息,请参考安装&oracle;。 用<command>orainst</command>安装&oracle; 8.0.5 如果&oracle; 8.0.5要被使用,一些其他的库需要被成功地重新链接, 因为&oracle; 8.0.5是与一个老的glibc连接的(Redhat 6.0), 但RedHat 6.1已经使用了一个新的glibc。所以您必须安装下面额外的软件包来保证链接正常: - compat-libs-5.2-2.i386.rpm - compat-glibc-5.2-2.0.7.2.i386.rpm - compat-egcs-5.2-1.0.3a.1.i386.rpm - compat-egcs-c++-5.2-1.0.3a.1.i386.rpm - compat-binutils-5.2-2.9.1.0.23.1.i386.rpm + + compat-libs-5.2-2.i386.rpm + compat-glibc-5.2-2.0.7.2.i386.rpm + compat-egcs-5.2-1.0.3a.1.i386.rpm + compat-egcs-c++-5.2-1.0.3a.1.i386.rpm + compat-binutils-5.2-2.9.1.0.23.1.i386.rpm + 更多的信息,看相应的&sap;注释和&oracle;的Readme。 如果这不是选项,您可以使用最初的程序,或使用与最初的Redhat系统重链接的程序。 要编译智能代理,必须安装RedHat Tcl包。如果您不能得到 tcl-8.0.3-20.i386.rpm,一个更新的 tcl-8.0.5-30.i386.rpm也可以用。 除了重新链接,安装是直截了当的: &prompt.root; su - oraids &prompt.root; export TERM=xterm &prompt.root; export ORACLE_TERM=xterm &prompt.root; export ORACLE_HOME=/oracle/IDS &prompt.root; cd $ORACLE_HOME/orainst_sap &prompt.root; ./orainst Enter来确认所有的屏幕直到安装完成,除了您必须取消 &oracle; On-Line Text Viewer选项,因为当前Linux下不可用。 &oracle;会要求用i386-glibc20-linux-gcc重新链接来 代替gccegcs或者i386-redhat-linux-gcc 由于时间紧迫,我决定使用&oracle; 8.0.5 PreProduction版本。 安装&oracle; 8.0.5 Pre-production Release for Linux (Kernel 2.0.33) 个安装很容易。挂上CD,启动安装程序。它就会要求&oracle;home目录的定位, 然后复制那里所有的程序。我不删除先前安装的RDBMS。 然后,&oracle;数据库就可以毫无问题地运行了。 安装&oracle; 8.1.7 Linux压缩包 oracle81732.tgz 复制到您要安装的目录, 然后解压到/oracle/SID/817_32/ 继续&sap.r3;安装 首先检查用户idsamd (sidadm)和 oraids(orasid)的环境变量。 他们现在都有使用主机名的.profile.login.cshrc文件。在这个例子中,系统的主机名是没有限制的名称, 您必须在所有三个文件中改变hostname为hostname -s。 加载数据库 然后,可以重新启动或继续R3SETUPR3SETUP就使用R3load 创建表空间加载数据(对46B IDES,从EXPORT1到EXPORT6,对46C从DISK1到DISK4)。 数据加载完后(可能需要一些时间),需要创建一些口令。对于测试安装,可以使用缺省口令: 问题 输入 Enter Password for sapr3 sapEnter Confirum Password for sapr3 sapEnter Enter Password for sys change_on_installEnter Confirm Password for sys change_on_installEnter Enter Password for system managerEnter Confirm Password for system managerEnter 到目前为止,我们只在安装4.6B的过程中dipgntab出现了几个问题。 监听 像下面这样用orasid用户启动 &oracle; &prompt.user; umask 0; lsnrctl start 另外您可能得到ORA-12546错误,因为sockets没有正确的权限。 看&sap;注释072984。 更新MNLS表 如果您打算倒入non-Latin-1 languages到&sap;系统, 您必须更新表的多语言支持。这在&sap; OSS注释15023和45619有描述。否则, 您可以在安装&sap;的时候忽略这个问题。 如果您不需要MNLS,还是需要检查表TCPDB和初始化工作是否做了。 更多信息参考&sap;注释0015023和0045619。 快速安装步骤 需要&sap.r3;许可密钥 您不得不要&sap.r3;许可密钥。这是必需的, 因为临时许可只能用4个星期。 首先得到硬件的密匙。以用idsadm登入, 然后调用saplicense &prompt.root; /sapmnt/IDS/exe/saplicense -get 不带参数调用saplicense会给出一系列选项。 要安装上面的许可密钥,可以这样: &prompt.root; /sapmnt/IDS/exe/saplicense -install 您要输入下面的值: SAP SYSTEM ID = SID, 3 chars CUSTOMER KEY = hardware key, 11 chars INSTALLATION NO = installation, 10 digits EXPIRATION DATE = yyyymmdd, usually "99991231" LICENSE KEY = license key, 24 chars 创建用户 在客户机000中创建一个用户(有些工作需用客户机000来完成,但与用户sap*ddic有些不同)。 作为一个用户名,我通常选择wartung (或英语中的service)。 配置文件需要sap_newsap_all。对于额外的安全的默认用户口令应当被改变(这包括用户sap*ddic)。 配置传送系统,配置,操作模式等 在客户端000,用户不同于ddicsap*,做下面的工作: 任务 处理 Configure Transport System, e.g. as Stand-Alone Transport Domain Entity STMS Create / Edit Profile for System RZ10 Maintain Operation Modes and Instances RZ04 些和所有其他的快速安装步骤在&sap;安装指南里面有描述。 编辑<filename>init<replaceable>sid</replaceable>.sap</filename>(<filename>initIDS.sap</filename>) 文件/oracle/IDS/dbs/initIDS.sap 包含了&sap;备份配置。 这儿是使用的磁带机的大小,压缩的类型。要使用sapdba / brbackup来得到这些。 我们可以改变下面的值: compress = hardware archive_function = copy_delete_save cpio_flags = "-ov --format=newc --block-size=128 --quiet" cpio_in_flags = "-iuv --block-size=128 --quiet" tape_size = 38000M tape_address = /dev/nsa0 tape_address_rew = /dev/sa0 解释 compress:我使用的磁带机是HP DLT1,它支持硬件压缩。 archive_function: 这个定义了保存&oracle;文件日志的默认行为:新的日志文件被保存到磁带机上, 保存的日志文件会被再次保存然后再删除。如果您需要恢复数据库, 而其中一个磁带机已经损坏了,这可以防止出现麻烦。 cpio_flags:缺省使用来设置块大小为 5120 Bytes。对于DLT-Tapes,HP建议至少32 K,所以我们使用 设置64 K。 是必需的,因为我的inode数目超过了65535。 最后一个选项是必需的,否则brbackup会在用 cpio来输出的时候报错。 cpio_in_flags: 这个标志从磁带机加载回数据。格式是自动验证的。 tape_size: 通常给出了磁带机的存储容量。出于安全原因,这个值要比实际的值要小一些。 tape_address:被cpio使用的非rewindable的设备。 tape_address_rew:被cpio使用的非rewindable的设备。 安装后的配置 下面的&sap;参数应该在安装以后调整(例子是IDES 46B, 1 GB内存): 名称 ztta/roll_extension 250000000 abap/heap_area_dia 300000000 abap/heap_area_nondia 400000000 em/initial_size_MB 256 em/blocksize_kB 1024 ipc/shm_psize_40 70000000 &sap;注释0013026: 名称 ztta/dynpro_area 2500000 &sap;注释0157246: Name Value rdisp/ROLL_MAXFS 16000 rdisp/PG_MAXFS 30000 根据上面的参数,在使用1 GB内存的系统上,可以像下面这样找到内存消耗: Mem: 547M Active, 305M Inact, 109M Wired, 40M Cache, 112M Buf, 3492K Free 安装过程出现的问题 修复一个问题后重起<command>R3SETUP</command> 如果出现问题R3SETUP会停止。如果您找到相关的日志文件并修复了问题。 您需要再次重起R3SETUP,对于R3SETUP报的最后一个错误可以使用 REPEAT选项。 要重起R3SETUP,只要使用相应的R3S文件重起: &prompt.root; ./R3SETUP -f CENTRDB.R3S for 4.6B, or with &prompt.root; ./R3SETUP -f CENTRAL.R3S 对4.6C,不管有没有错误都使用CENTRAL.R3SDATABASE.R3S 在某些阶段,R3SETUP假设database和&sap; 进程都启动了。但是如果发生错误使得database没有启动,您就必须手动启动database和&sap;。 修复错误后,还需要再次重起R3SETUP 也不要忘记再次重起&oracle;监听。 OSUSERSIDADM_IND_ORA during <command>R3SETUP</command> 如果在这阶段R3SETUP报错,编辑R3SETUP使用的模板文件 (CENTRDB.R3S (4.6B)或者CENTRAL.R3S或者DATABASER3S (4.6C))。定位到[OSUSERSIDADM_IND_ORA]或者搜索STATUS=ERROR条目 然后像下面这样编辑它: HOME=/home/sidadm (was empty) STATUS=OK (had status ERROR) 然后重起R3SETUP OSUSERDBSID_IND_ORA during <command>R3SETUP</command> R3SETUP也可能在这个阶段报错。修正方法和上面的OSUSERSIDADM_IND_ORA一样。 编辑下面的值: STATUS=OK 重起R3SETUP &oracle;安装找不到<errorname>oraview.vrf文件</errorname> 开始安装之前没有取消&oracle; On-Line Text Viewer 既然这个选项当前没有用于Linux,这在安装时是需要标记的,在&oracle; 安装中取消它,然后重新安装。 <errorname>TEXTENV_INVALID</errorname> during <command>R3SETUP</command>, RFC or SAPgui Start 如果这个错误还出现,正确的本地化可能已经丢了。 &sap;注释0171356列出了必须的RPMs (比如saplocales-1.0-3, saposcheck-1.0-1 for RedHat 6.1)。 在这个例子中,您忽略了所有相关的错误, STATUSERROROK然后重起 R3SETUP&sap;系统不会被正确地配置, 您就不能用一个SAPgui连接到系统。 设法使用一个旧的Linux sapgui连接会得到下面的信息: Sat May 5 14:23:14 2001 *** ERROR => no valid userarea given [trgmsgo. 0401] Sat May 5 14:23:22 2001 *** ERROR => ERROR NR 24 occured [trgmsgi. 0410] *** ERROR => Error when generating text environment. [trgmsgi. 0435] *** ERROR => function failed [trgmsgi. 0447] *** ERROR => no socket operation allowed [trxio.c 3363] Speicherzugriffsfehler 这个问题归咎于&sap.r3;不能正确地本地化,也不能自己正确地配置。 要能够连接到&sap;, 需要在 DEFAULT.PFL(看注释0043288) 文件中添加下面的记录: abap/set_etct_env_at_new_mode = 0 install/collate/active = 0 rscp/TCP0B = TCP0B 重起&sap;系统。现在,您可以连接到系统, 即使您指定的国家语言不能正常工作。设置完国家后,这些记录会从DEFAULT.PFL文件 删除。然后重新启动&sap;系统。 <errorcode>ORA-00001</errorcode> 这个错误只会在FreeBSD 4.5上安装&oracle; 8.1.7 的时候出现。因为&oracle;database不能自己正确初始化。 在系统上保留semaphores和shared memory。 然后再次启动数据库会出现ORA-00001错误。 ipcs -a找到再用ipcrm去掉。 <errorcode>ORA-00445</errorcode> (后台进程PMON没有启动) 这个错误发生在&oracle; 8.1.7上。 如果没有用prdadm用户启动startsap脚本 (例如startsap_majestix_00)会报这个错误。 一种可能的解决方法是用oraprd用户使用svrmgrl &prompt.user; svrmgrl SVRMGR> connect internal; SVRMGR> startup; SVRMGR> exit <errorcode>ORA-12546</errorcode>(用正确的权限启动监听) oraids用户启动&oracle;监听: &prompt.root; umask 0; lsnrctl start 如果您得到ORA-12546错误,没有权限连接到sockets。 请看&sap;注释0072984。 <errorcode>ORA-27102</errorcode> (Out of Memory) 这个错误发生在使用MAXDSIZDFLDSIZ大于 1 GB(1024x1024x1024)。 我们一般得到错误Linux Error 12: Cannot allocate memory [DIPGNTAB_IND_IND] during <command>R3SETUP</command> 基本上, 参见 &sap; 注释 0130581 (R3SETUP 步骤中的 DIPGNTAB 终止)。 在 IDES-专用安装的时候, 因为某些原因安装过程没有使用正确的 &sap; 系统名 IDS, 而是用空串 ""代替。 这会导致一些访问目录的小问题, 因为路径是动态使用 SID来创建的 (这里是IDS)。 所以用下面的方法代替: /usr/sap/IDS/SYS/... /usr/sap/IDS/DVMGS00 下面的路径被使用 /usr/sap//SYS/... /usr/sap/D00 为了继续安装,我们创建了一个附加的目录: &prompt.root; pwd /compat/linux/usr/sap &prompt.root; ls -l total 4 drwxr-xr-x 3 idsadm sapsys 512 May 5 11:20 D00 drwxr-x--x 5 idsadm sapsys 512 May 5 11:35 IDS lrwxr-xr-x 1 root sapsys 7 May 5 11:35 SYS -> IDS/SYS drwxrwxr-x 2 idsadm sapsys 512 May 5 13:00 tmp drwxrwxr-x 11 idsadm sapsys 512 May 4 14:20 trans 我们也发现在&sap;注释(0029227和0008401)里面描述了这个行为。 我们没有在&sap; 4.6C安装里面遭遇这些问题。 [RFCRSWBOINI_IND_IND] during <command>R3SETUP</command> 安装&sap; 4.6C时,这个错误是前面发生过的一个错误的 结果。所以,您不得不查看相应的日志文件并修复错误。 如果查看完日志文件后这个错误确实存在(看&sap;注释),您可以设置STATUSERROROKCENTRDB.R3S文件里面) 然后重起R3SETUP。安装完后,您必须从事务SE38执行 RSWBOINS。关于RFCRSWBOINIRFCRADDBDIF的更多信息 查看&sap;注释0162266。 [RFCRADDBDIF_IND_IND] during <command>R3SETUP</command> 通过查看日志文件确定这个错误,它不是由于前面的问题导致的。 如果您确定已经应用了&sap;注释0162266,就只要设置 STATUSERROROKCENTRDB.R3S文件里面)。然后重起R3SETUP。 安装完后,您必须从事务SE38执行RADDBDIF <errorcode>sigaction sig31: File size limit exceeded</errorcode> 这个错误在启动&sap;进程disp+work时出现。 如果用startsap脚本启动&sap;, 就会启动子进程,并由它启动后面所有的其他&sap;进程。 所以脚本本身不会注意到有错误发生。 为了检查&sap;进程是否正确启动,可以用 ps ax | grep SID查看进程的状态。 您会得到所有&oracle;&sap;进程列表。 如果看起来有些进程没有启动,或者您不能正确连接到&sap;系统。 查看相应的日志文件,可以在 /usr/sap/SID/DVEBMGSnr/work/ 下找到, 一般查看 dev_msdev_disp 文件。 如果&oracle;&sap;的共享内存总量超过了 内核配置文件定义的大小就会出现signal 31错误,并且不能解析大的内存地址: # larger value for 46C production systems: options SHMMAXPGS=393216 # smaller value sufficient for 46B: #options SHMMAXPGS=262144 启动<command>saposcol</command>失败 使用saposcol (version 4.6D)会出现一些问题。 &sap;系统使用saposcol收集系统性能数据。 这个程序不是必需的。所以这些问题可以看作是小问题。 老版本(4.6B)可以工作,但是不能收集所有的性能数据(很多调用只返回0,像CPU使用率)。 高级主题 如果您对Linux兼容模式是如何工作的感到好奇,这节正是您所需要的。 下面的绝大部分内容是由 Terry Lamberttlambert@primenet.com (Message ID: <199906020108.SAA07001@usr09.primenet.com>)发表在邮件列表&a.chat;上的内容组成的。 它是如何工作的? 可执行类加载器 FreeBSD有一个可执行类加载器。它主要是嵌入了&man.execve.2;系统调用。 碰巧的是FreeBSD有一个引导器(loader)的列表,而不是一个简单的返回一个 符号 #!的引导器! 从历史上来讲,只有&unix;平台的引导器会检查魔术(magic)数 (通常是文件的前4个或8个字节)是否是二进制的, 如果是,就调用二进制引导程序。 如果它不是二进制类型的&man.execve.2;调用就会返回一个错误,shell就试图用shell命令执行它。 缺省是使用当前设定的shell 随后,进行了一些hack, &man.sh.1;开始检查前两个字符,如果它们是:\n, 那它就调用&man.csh.1;(我们相信是SCO最先做这个hack的)。 FreeBSD现在所做的是用一个普通的#!引导器仔细检查引导器的列表, 然后由解释程序一个接一个地解释,返回给/bin/sh ELF 为了支持Linux ABI,FreeBSD就把魔术数看作为一个二进制ELF程序。( 这样一来,它就使得在FreeBSD, &solaris;,Linux和其他任何操作系统之间只要使用ELF格式就都可以顺利运行)。 Solaris ELF引导器会寻找一个专门的标记, 它是在ELF映像中的一个注释部分,但在SVR4/&solaris;的ELF中没有。 为了执行Linux程序,它们必须被打上Linux类型的标记; 使用&man.brandelf.1;: &prompt.root; brandelf -t Linux file 做完之后,ELF引导器就会看到文件上的Linux的标记。 ELF 标记 当ELF引导器看到Linux的标记, 引导器就会在proc结构中替换一个指示器。 所有的系统调用就会通过这个指示器来索引(在一个传统的 &unix;系统中, 这就是sysent[]结构队列,包含系统调用)。 此外,为了解决由于信号杂乱所造成的陷阱向量的问题,会造成线程的剧增, 需要切断其他(或较小的)由Linux内核模块产生的修正。 Linux系统调用向量包含一个sysent[]记录的列表, 它的地址位于内核模块之中。 当一个系统调用被Linux程序调用时,有缺陷的代码会把系统调用功能的指示器从proc结构中解除, 然后获得Linux,而不是FreeBSD,系统调用入口点。 另外,Linux模式动态地reroots查找;这和启动文件系统的 选项是等效的(即时不是unionfs文件系统)。 首先会试图在/compat/linux/original-path 目录查找文件,如果失败了,就会在/original-path 目录下查找。这使得需要其它程序的程序可以运行(例如,Linux工具链都可以在Linux ABI的支持下工作)。 也就是说Linux程序可以加载和执行FreeBSD程序,如果当前没有相应的Linux程序, 那您可以在/compat/linux目录树中放置一个&man.uname.1;,来确保Linux程序不提示它们不能运行在Linux上。 在FreeBSD内核中有一个Linux内核;由内核提供的能够提供所有服务的各种潜在功能 在FreeBSD系统调用表记录和Linux系统调用表记录之间是一样的: 文件系统操作,虚拟内存操作,信号发送,System V IPC,…等等。 唯一的不同是FreeBSD会得到FreeBSD的胶合功能, 而Linux程序会得到Linux的胶合功能 (大部分老的操作系统只有它们自己的胶合函数, 函数地址在静态全局变量sysent[]结构数据里面, 而不是动态的初始化到进程的proc结构)。 哪一个是FreeBSD自己的ABI呢?这无关紧要。基本上, 唯一的不同是FreeBSD的胶合功能是被静态连接到内核, 而Linux的胶合功能可能是被静态连接到内核, 也可能它们通过一个内核模块来访问。 有一个真正的模拟器吗?没有,它只不过是一个ABI执行机制,不是一个模拟器。 为什么有时它被叫做Linux模拟器? 只是为了更容易地卖出FreeBSD罢了! 实际上,历史上从来没有描述这样一种执行机制的名字,FreeBSD并不是真正地运行Linux程序,如果您不编译进代码, 或加载一个模块。 就需要有一个名字来描述这样一种加载功能--因此就想出了Linux模拟器这样一个名字。
diff --git a/zh_CN.GB2312/books/handbook/ports/chapter.sgml b/zh_CN.GB2312/books/handbook/ports/chapter.sgml index 300d1e82b5..3d212b898d 100644 --- a/zh_CN.GB2312/books/handbook/ports/chapter.sgml +++ b/zh_CN.GB2312/books/handbook/ports/chapter.sgml @@ -1,1281 +1,1297 @@ 安装应用程序: Packages 和 Ports 概述 ports packages FreeBSD 将许多系统工具捆绑作为基本系统的一部分。 然而, 要完成实际的工作, 可能还需要安装更多的第三方应用。 FreeBSD 提供了两种补充的技术, 用以在您的系统中安装第三方软件: FreeBSD Ports 套件 (用于从源代码安装), 以及 packages (用以从预编译的二进制版本安装)。 这两种方法都可以用于从本地介质, 或从网上直接安装您喜欢的应用程序的最新版本。 读完这章,您将了解到: 如何安装第三方的二进制软件包。 如何使用 ports 套件从源代码构建第三方软件。 如何删除先前安装的软件包。 如何改动Ports Collection里面的一些参数,定制软件使用。 如何找到您需要的软件包。 如何升级您的应用软件。 软件安装预览 如果您以前使用过 &unix; 系统,那典型的第三方软件安装的步骤是像下面描述的: 下载这个软件,软件的发行版可能是源代码格式,或是一个二进制包。 解开软件(其中代表性的是用 &man.compress.1;, &man.gzip.1;, 或 &man.bzip2.1; 压缩过的tar包)。 阅读相关文档,了解如何安装。 (多半一个文件名是INSTALLREADME, 或在doc/ 目录下的一些文档) 如果软件是以源代码形式发布的,那就需要编译它。可能需要编辑一个 Makefile文件, 或运行 configure脚本,和其他的一些工作。 测试和安装软件。 如果一切顺利的话,就这么简单。如果您在安装一个软件包时发生一些错误, 您可能需要编辑一下它的代码,以使它能正常工作。 您可以继续使用 传统的方式安装软件。 然而, FreeBSD 提供了两种技术: packages 和 ports。 就在写这篇文章的时候, 已经有超过 &os.numports; 个第三方的应用程序可以使用了。 对于任意一个应用程序包,是一个可以下载的FreeBSD package文件。这个 FreeBSD package包含了编译好的的副本, 还有一些配置文件或文档。 一个下载的包文件可以用 FreeBSD 的包管理命令来操作, 例如 &man.pkg.add.1;,&man.pkg.delete.1;, &man.pkg.info.1; 等等。 可以使用一个简单的命令安装一个新的应用程序。 一个FreeBSD的port是一个可以自动从源代码编译成应用程序的文件集合。 记住,如果您自己来编译的话,需要执行很多步的操作 (解压, 补丁, 编译, 安装)。 这些整理 port 的文件集合包含了系统需要完成这个工作的必需信息。 您可以运行一些简单的命令, 那些源代码就可以自动地下载, 解开, 打补丁, 编译, 直至安装完成。 实际上,ports 系统也能做出被 pkg_add 的程序包和不久就要讲到的其他包管理命令来安装的软件包。 Packages 和 ports 是互相 依赖 的。 假设您想安装一个依赖于已经安装的特定库的应用程序。 应用程序和那个库都已经应用于 FreeBSD ports 和 packages。 如果您使用 命令或 ports 系统来添加应用程序, 两个都必须注意库是否被安装, 如果没有, 它会自动先安装库。 这里给出的两种技术是很相似的,您可能会奇怪为什么 FreeBSD 会弄出这两种技术。 其实, packages 和 ports 都有它们自己的长处, 使用哪一种完全取决于您自己的喜好。 Package的优点 一个压缩的 package 通常要比一个压缩的包含源代码的应用程序小得多。 package 不需要进行额外的编译。 对于大型应用程序如 MozillaKDEGNOME 来说这显得尤为重要, 特别是在您的系统资源比较差的情况下。 package不需要您知道如何在FreeBSD上编译软件的详细过程。 Ports 的优点 package 在编译时通常使用比较保守的选项, 这是为了保证它们能够运行在大多数的系统上。 通过从 port 安装, 您可以细微调整编译选项来产生适合于处理器的代码 (针对于 Pentium 4 或 AMD 的 Athlon CPU)。 一些软件包已经把与它们相关的能做和不能做的事情的选项都编译进去了。 例如, Apache 可能就配置了很多的选项。 从 port 中安装时, 您不一定要接受默认的选项, 可以自己来设置。 在一些例子中,一个软件有不同的配置存在多个package。 例如, Ghostscript存在 ghostscript package 和 ghostscript-nox11 package两个配置package, 这取决于您是否安装了X11服务器。 这样的调整对package是可能的, 但如果一个应用程序有超过一个或两个不同的编译时间选项时, 就不行了。 一些软件的许可条件禁止采用二进制形式发行。 它们必须带上源代码。 一些人不信任二进制发行形式。 至少有了源代码, (理论上) 可以亲自阅读它,寻找潜在的问题。 如果您要自己对软件打补丁,您就需要有源代码。 一些人喜欢整天围着源代码转, 所以他们喜欢亲自阅读源代码, 修改源代码等等。 保持更新 ports, 订阅邮件列表 &a.ports; 和递交错误报告 &a.ports-bugs;。 安装任何应用程序之前, 应首先检查 上是否有关于您所安装的应用程序的安全问题报告。 您也可以安装 ports-mgmt/portaudit, 它能够自动地检查已经安装的应用程序的漏洞; 此外, 在您安装程序之前它也会首先检查是否存在已知的漏洞。 另外, 您也可以使用 portaudit -F -a 这个命令在安装了某个软件包之后作出检查。 这章的其余部分将介绍在 FreeBSD 上如何使用 packages 和 ports 来安装和管理第三方软件。 寻找您要的应用程序 在您安装任何应用程序之前,需要知道您需要什么,那个应用程序叫什么。 FreeBSD中可用的应用程序正在不断地增长着。幸运的是, 有许多方法可以找到您所需要的程序: FreeBSD站点上有一个可以搜索到的当前所有可用的应用程序列表,在 http://www.FreeBSD.org/ports/。 它分很多种类,您既可以通过程序的名称来搜索, 也可以在分类中列出所有可用的应用程序 (如果您知道名字), 也可以在分类中列出所有可用的应用程序。 FreshPorts Dan Langille 维护着网站 FreshPorts,在 。 FreshPort时刻 追踪 着在 ports 中应用程序的变化。当有任何程序被升级时,他们就会发 email 提醒您。 FreshMeat 如果您不知道您想要的应用程序的名字,可以通过 () 网站来查找, 如果找到了应用程序, 您可以回 FreeBSD 的主站去看一下这个应用程序是否已经被 port 进去了。 如果您知道一个port的准确名字, 但需要知道在哪个类别里面能找到它,您可以使用 &man.whereis.1; 这个命令。简单地输入 whereis filefile 就是您想安装的程序名字。 如果系统找到了它, 您将被告知在它在哪里, 例如: &prompt.root; whereis lsof lsof: /usr/ports/sysutils/lsof 结果告诉我们这个命令lsof (一个系统配置程序)可以在 /usr/ports/sysutils/lsof目录中找到。 + + 你可以使用简单的 &man.echo.1; + 语句来查找某个 port 是否存在于 ports 树中。 + 例如: + + &prompt.root; echo /usr/ports/*/*lsof* +/usr/ports/sysutils/lsof + + Note that this will return any matched files downloaded into the + /usr/ports/distfiles + directory. + 请注意这条命令将会返回下载到 + /usr/ports/distfiles + 目录中所有符合条件的文件。 + + 还有另外的一个寻找您需要的port的方法--是用ports collecton 内嵌的搜索机制。要使用这个搜索, 您需要先到 /usr/ports目录下面。 在那个目录里面, 运行make search name=program-nameprogram-name 就是您想寻找的程序名字。 举个例子, 如果您想找 lsof &prompt.root; cd /usr/ports &prompt.root; make search name=lsof Port: lsof-4.56.4 Path: /usr/ports/sysutils/lsof Info: Lists information about open files (similar to fstat(1)) Maint: obrien@FreeBSD.org Index: sysutils B-deps: R-deps: 在输出的内容里面您要特别注意包含 Path: 的这行将告诉您在哪里可以找到这个 port。 如果要安装此 port, 那其他输出的信息不是必须的, 但是还是显示输出了。 为了更深入的搜索,您还可以用 make search key=stringstring就是您想搜索的部分内容。 它将搜索port的名字、 注释, 描述和从属关系, 如果您不知道您想搜索的程序名字, 可以利用它搜索一些关键主题来找到您需要的。 上面说的这些方法, 搜索的关键字没有大小写区分的。 搜索 LSOF的结果将和搜索lsof的结果一样。 Chern Lee Contributed by 使用Packages系统 一个package的安装 packages installing pkg_add 您可以用 &man.pkg.add.1; 这个命令从本地文件或网络上的服务器来安装一个 FreeBSD 软件包。 在本地手动下载一个package,并安装它 &prompt.root; ftp -a ftp2.FreeBSD.org Connected to ftp2.FreeBSD.org. 220 ftp2.FreeBSD.org FTP server (Version 6.00LS) ready. 331 Guest login ok, send your email address as password. 230- 230- This machine is in Vienna, VA, USA, hosted by Verio. 230- Questions? E-mail freebsd@vienna.verio.net. 230- 230- 230 Guest login ok, access restrictions apply. Remote system type is UNIX. Using binary mode to transfer files. ftp> cd /pub/FreeBSD/ports/packages/sysutils/ 250 CWD command successful. ftp> get lsof-4.56.4.tgz local: lsof-4.56.4.tgz remote: lsof-4.56.4.tgz 200 PORT command successful. 150 Opening BINARY mode data connection for 'lsof-4.56.4.tgz' (92375 bytes). 100% |**************************************************| 92375 00:00 ETA 226 Transfer complete. 92375 bytes received in 5.60 seconds (16.11 KB/s) ftp> exit &prompt.root; pkg_add lsof-4.56.4.tgz 如果您没有本地package的安装盘 (如 FreeBSD CD-ROM), 可以执行 &man.pkg.add.1; 命令并加上 选项。 这将迫使程序自动决定目标文件的正确格式和版本, 然后自动从一个 FTP 站点寻找和安装 package。 pkg_add &prompt.root; pkg_add -r lsof 上面的例子将下载正确的package, 而不需要用户的干预就可以安装。 如果您想指定 FreeBSD package 的镜像站点, 替换主站点, 就必须相应地设置 PACKAGESITE 这个环境变量, 覆盖原来的设置。 &man.pkg.add.1; 使用 &man.fetch.3; 下载文件, 可以使用多种环境变量, 包含 FTP_PASSIVE_MODEFTP_PROXY, 和 FTP_PASSWORD。 如果您使用 FTP/HTTP 代理或在防火墙后面, 您可能需要设置这些环境变量。 详细的列表请参考 &man.fetch.3;。上述例子中用 lsof 替代了 lsof-4.56.4。 当使用远程安装 Package 的时候软件名字不需要包含版本号。 &man.pkg.add.1; 将自动的找到这个软件最新的版本。 如果您使用 &os.current; 或 &os.stable;版本的FreeBSD, &man.pkg.add.1; 将下载您的应用软件的最新版本。 如果您使用 -RELEASE 版本的 FreeBSD, 它将会获得与您的版本相应的软件包版本。 您可以通过修改环境变量 PACKAGESITE 来改变这一行为。 例如, 如果您运行 &os; 5.4-RELEASE 系统, 默认情况下 &man.pkg.add.1; 将尝试从 ftp://ftp.freebsd.org/pub/FreeBSD/ports/i386/packages-5.4-release/Latest/ 下载预编译的软件包。 如果您希望强制 &man.pkg.add.1; 下载 &os; 5-STABLE 的软件包, 则可以将 PACKAGESITE 设置为 ftp://ftp.freebsd.org/pub/FreeBSD/ports/i386/packages-5-stable/Latest/ 软件包采用 .tgz.tbz 两种格式。您可以在 下面或从 FreeBSD 的发行光盘找到, 它在每一个 4CD 的 FreeBSD 发行版的 /packages目录中。 软件包的设计规划与 /usr/ports 树一致。 每个分类都有自己的目录, 所有的软件包可以在目录 All中找到。 软件包系统的目录结构与ports的设计规划一致; 它们共同构成了整个 package/port。 软件包的管理 packages managing &man.pkg.info.1; 是用于列出已安装的所有软件包列表和描述的程序。 pkg_info &prompt.root; pkg_info cvsup-16.1 A general network file distribution system optimized for CV docbook-1.2 Meta-port for the different versions of the DocBook DTD ... &man.pkg.version.1;是一个用来统计所有安装的软件包版本的工具。 它可以用来比较本地 package 的版本与 ports 目录中的当前版本是否一致。 pkg_version &prompt.root; pkg_version cvsup = docbook = ... 在第二列的符号指出了安装版本的相关时间和本地ports目录树中可用的版本。 符号 含义 = 在本地ports树中与已安装的软件包版本相匹配。 < 已安装的版本要比在ports树中的版本旧。 >已安装的版本要比在ports树中的版本新 (本地的port树可能没有更新)。 ? 已安装的软件包无法在ports索引中找到。 (可能发生这种事情,举个例子, 您早先安装的一个 port 从 port 树中移出或改名了) *软件包有很多版本。 删除一个软件包 pkg_delete packages deleting 要删除先前安装的软件package,只要使用&man.pkg.delete.1; 工具。 &prompt.root; pkg_delete xchat-1.7.1 需要注意的是, &man.pkg.delete.1; 需要提供完整的包名; 如果您只是指定了类似 xchat 而不是 xchat-1.7.1 这样的名字, 则它将拒绝执行操作。 不过, 您可以使用 &man.pkg.version.1; 来了解安装的 package 的版本。 除此之外, 也可以使用通配符: &prompt.root; pkg_delete xchat\* 这时, 所有名字以 xchat 开头的 package 都会被删掉。 其它 所有已安装的 package 信息都保存在 /var/db/pkg 目录下。 安装文件的列表和每个 package 的内容和描述都能在这个目录的相关文件中找到。 使用Ports Collection 下面的几个小节中, 给出了关于如何使用 Ports 套件来在您的系统中安装或卸载程序的介绍。 关于可用的 make targets 以及环境变量的介绍, 可以在 &man.ports.7; 中找到。 获得Ports Collection 在您能使用 ports 之前, 您必须先获得 Ports Collection — 本质上是 /usr/ports 目录下的一堆 Makefile、 补丁和描述文件。 在您安装 FreeBSD 系统的时候, sysinstall 会询问您是否需要安装 Ports Collection。 如果您选择 no, 那您可以用下面的指令来安装 Ports Collection: CVSup 方法 保持您本地 Ports 套件最新的一种快捷的方法, 是使用 CVSup 来进行更新。 如果您希望了解更多关于 CVSup 的细节, 请参见 使用 CVSup。 csup 是用 C 语言对 CVSup 软件的重写, 在 &os; 6.2 和更高版本中, 作为系统的一部分提供。 您可以直接使用系统附带的 csup 而跳过 #1 这一步, 并将这份文档余下部分中的 cvsup 命令改为 csup。 对于较早版本而言, 可以使用 net/csup port 或预编译包来安装 csup 在首次运行 CVSup 之前, 务必确认 /usr/ports 是空的! 如果您之前已经用其他地方安装了一份 Ports 套件, 则 CVSup 可能不会自动删除已经在上游服务器上删除掉的补丁文件。 安装 net/cvsup-without-gui 软件包: &prompt.root; pkg_add -r cvsup-without-gui 请参见 如何安装 CVSup () 以了解更多细节。 运行 cvsup &prompt.root; cvsup -L 2 -h cvsup.FreeBSD.org /usr/share/examples/cvsup/ports-supfile cvsup.FreeBSD.org 改为离您较近的 CVSup 服务器。 请参见 CVSup 镜像 () 中的镜像站点完整列表。 有时可能希望使用自己的 ports-supfile, 比如说, 不想每次都通过命令行来指定所使用的 CVSup 服务器。 这种情况下, 需要以 root 身份将 /usr/share/examples/cvsup/ports-supfile 复制到新的位置, 例如 /root 或您的主目录。 编辑 ports-supfile CHANGE_THIS.FreeBSD.org 修改成离您较近的 CVSup 服务器。 可以参考 CVSup 镜像 () 中的镜像站点完整列表。 接下来按如下的方式运行 cvsup &prompt.root; cvsup -L 2 /root/ports-supfile 此后运行 &man.cvsup.1; 命令将下载最近所进行的改动, 并将它们应用到您的 Ports Collection 上, 不过这一过程并不重新联编您系统上的 ports。 Portsnap 方式 Portsnap 是另一种用于发布 Ports 套件的方法。 它最早从 &os; 6.0 开始引入。 在较早的系统中, 您可以通过 ports-mgmt/portsnap package 来安装它: &prompt.root; pkg_add -r portsnap 请参见 使用 Portsnap 以了解关于全部 Portsnap 功能的详细描述。 如果您使用 &os; 6.1-RELEASE, 或通过 port 或 package 安装了较新版本的 Portsnap 的话, 可以直接跳过这一步。 /usr/ports 将在首次使用 &man.portsnap.8; 命令时自动创建。 而如果您使用的是较早期版本的 Portsnap, 就只能手工创建空的 /usr/ports 目录了。 &prompt.root; mkdir /usr/ports 下载压缩的 Ports 套件快照到 /var/db/portsnap。 您可以根据需要在这之后关闭 Internet 连接。 &prompt.root; portsnap fetch 假如您是首次运行 Portsnap, 则需要将快照释放到 /usr/ports &prompt.root; portsnap extract 如果您已经有装好的 /usr/ports 而您只想更新, 则应执行下面的命令: &prompt.root; portsnap update Sysinstall 方式 这种方法需要使用 sysinstall 从安装介质上安装 Ports 套件。 注意, 安装的将是发布发行版时的旧版 Ports 套件。 如果您能访问 Internet, 应使用前面介绍的方法之一。 root 身份运行 sysinstall (对 &os; 5.2 之前的版本, 应执行 /stand/sysinstall): &prompt.root; sysinstall 用光标向下选择 Configure, 并按 Enter 向下并选择 Distributions, 按 Enter 选择 ports, 并按 Space 选择 Exit, 并按 Enter 选择所希望的安装介质, 例如 CDROM、 FTP, 等等。 选择 Exit 并按 Enter X 退出 sysinstall 安装 Ports ports 安装 当提到 Ports Collection 时, 第一个要说明的就是何谓 skeleton。 简单地说, port skeleton 是让一个程序在 FreeBSD 上简洁地编译并安装的所需文件的最小组合。 每个 port skeleton 包含: 一个 MakefileMakefile 包括好几个部分, 指出应用程序是如何编译以及将被安装在系统的哪些地方。 一个 distinfo 文件。这个文件包括这些信息: 这些文件用来对下载后的文件校验和进行检查 (使用 &man.md5.1; 和 &man.sha256.1;), 来确保在下载过程中文件没有被破坏。 一个 files 目录。 这个目录包括在 FreeBSD 系统上编译和安装程序需要用到的补丁。 这些补丁基本上都是些小文件, 指出特定文件作了哪些修正。 它们都是纯文本的的格式,基本上是这样的 删除第 10 行将第 26 行改为这样 ..., 补丁文件也被称作 diffs, 他们由 &man.diff.1; 程序生成。 这个目录也包含了在编译 port 时要用到的其它文件。 一个 pkg-descr 文件。 这是一个提供更多细节,有软件的多行描述。 一个 pkg-plist 文件。 这是即将被安装的所有文件的列表。它告诉 ports 系统在卸载时需要删除哪些文件。 一些ports还有些其它的文件, 例如 pkg-message。 ports 系统在一些特殊情况下会用到这些文件。 如果您想知道这些文件更多的细节以及 ports 的概要, 请参阅 FreeBSD Porter's Handbook port里面包含着如何编译源代码的指令, 但不包含真正的源代码。 您可以在网上或 CD-ROM 上获得源代码。 源代码可能被开发者发布成任何格式。 一般来说应该是一个被 tar 和 gzip 过的文件, 或者是被一些其他的工具压缩或未压缩的文件。 ports中这个程序源代码标示文件叫 distfile, 安装 &os; port的方法还不止这两种。 您必须使用 root 用户登录后安装 ports。 在安装任何 port 之前, 应该首先确保已经更新到了最新的 Ports Collection, 并检查 中是否有与那个 port 有关的安全问题。 在安装应用程序之前, 可以使用 portaudit 来自动地检查是否存在已知的安全问题。 这个工具同样可以在 Ports Collection (ports-mgmt/portaudit) 中找到。 在安装新的 port 之前, 可以考虑先运行一下 portaudit -F 来抓取最新的漏洞数据库。 在每天的周期性系统安全检察时, 数据库会被自动更新, 并且会在这之后实施安全审计。 欲了解进一步的情况,请参阅 &man.portaudit.1; 和 &man.periodic.8;。 Ports 套件假定您有可用的 Internet 连接。 如果您没有, 则需要将 distfile 手工放到 /usr/ports/distfiles 中。 要开始操作, 首先进入要安装 port 的目录: &prompt.root; cd /usr/ports/sysutils/lsof 一旦进入了 lsof 的目录,您将会看到这个port的结构。 下一步就是 make,或说 联编 这个 port。 只需在命令行简单地输入 make 命令就可轻松完成这一工作。 做好之后,您可以看到下面的信息: &prompt.root; make >> lsof_4.57D.freebsd.tar.gz doesn't seem to exist in /usr/ports/distfiles/. >> Attempting to fetch from ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/. ===> Extracting for lsof-4.57 ... [extraction output snipped] ... >> Checksum OK for lsof_4.57D.freebsd.tar.gz. ===> Patching for lsof-4.57 ===> Applying FreeBSD patches for lsof-4.57 ===> Configuring for lsof-4.57 ... [configure output snipped] ... ===> Building for lsof-4.57 ... [compilation output snipped] ... &prompt.root; 注意,一旦编译完成,您就会回到命令行。 下一步安装 port, 要安装它只需要在 make 命令后跟上一个单词 install 即可: &prompt.root; make install ===> Installing for lsof-4.57 ... [installation output snipped] ... ===> Generating temporary packing list ===> Compressing manual pages for lsof-4.57 ===> Registering installation for lsof-4.57 ===> SECURITY NOTE: This port has installed the following binaries which execute with increased privileges. &prompt.root; 一旦您返回到提示符,您就可以运行您刚刚安装的程序了。因为 lsof 是一个赋予特殊权限的程序, 因此显示了一个安全警告。 在编译和安装 ports 的时候, 您应该留意任何出现的警告。 删除工作目录是个好主意, 这个目录中包含了全部在编译过程中用到的临时文件。 这些文件不仅会占用宝贵的磁盘空间, 而且可能会给升级新版本的 port 时带来麻烦。 &prompt.root; make clean ===> Cleaning for lsof-4.57 &prompt.root; 使用 make install clean 可以一步完成 makemake installmake clean 这三个分开的步骤的工作。 一些 shell 会缓存环境变量 PATH 中指定的目录里的可执行文件, 以加速查找它们的速度。 如果您使用的是这类 shell, 在安装 port 之后可能需要执行 rehash 命令, 然后才能运行新安装的那些命令。 这个命令可以在类似 tcsh 的 shell 中使用。 对于类似 sh 的 shell, 对应的命令是 hash -r。 请参见您的 shell 的文档以了解进一步的情况。 某些第三方 DVD-ROM 产品, 如 FreeBSD Mall 的 FreeBSD Toolkit 中包含了 distfiles。 这些文件可以与 Ports 套件配合使用。 将 DVD-ROM 挂接到 /cdrom。 如果您使用不同的挂接点, 则应设置 make 变量 CD_MOUNTPTS。 如果盘上有需要的 distfiles, 则会自动使用。 请注意, 少数 ports 并不允许通过 CD-ROM 发行。 这可能是由于下载之前需要填写注册表格, 或者不允许再次发布, 或者有一些其它原因。 如果您希望安装在 CD-ROM 上没有的 port, 就需要在线操作了。 ports 系统使用 &man.fetch.1; 去下载文件, 它有很多可以设置的环境变量, 其中包括 FTP_PASSIVE_MODEFTP_PROXY, 和 FTP_PASSWORD。 如果您在防火墙之后,或使用 FTP/HTTP代理, 您就可能需要设置它们。 完整的说明请看 &man.fetch.3;。 当使用者不是所有时间都能连接上网络, 则可以利用 make fetch。 您只要在顶层目录 (/usr/ports) 下运行这个命令, 所有需要的文件都将被下载。 这个命令也同样可以在下级类别目录中使用, 例如: /usr/ports/net。 注意, 如果一个port有一些依赖的库或其他 port, 它将 下载这些依赖的 port 的 distfile 文件, 如果您想获取所有依赖的 port 的所有 distfile, 请用 fetch-recursive 命令代替 fetch命令。 您可以在一个类别或在顶级目录编译所有的 port, 或者使用上述提到的 make fetch命令。 这样是非常危险的, 因为有一些port不能并存。 或者有另一种可能, 一些port会安装两个不同的文件, 但是却是相同的文件名。 在一些罕见的例子中, 用户可能需要在除了 MASTER_SITES 以外的一个站点(本地已经下载下来的文件)去获得一个文件包。 您可以用以下命令不使用 MASTER_SITES: &prompt.root; cd /usr/ports/directory &prompt.root; make MASTER_SITE_OVERRIDE= \ ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/distfiles/ fetch 在这个例子中,我们把 MASTER_SITES这个选项改为了 ftp.FreeBSD.org/pub/FreeBSD/ports/distfiles/ 一些 port 允许 (或甚至要求) 您指定编译选项来 启用/禁用 应用程序中非必需的功能, 一些安全选项, 以及其他可以订制的内容。 具有代表性的包括 www/mozillasecurity/gpgme、 以及 mail/sylpheed-claws。 如果存在这样的选项, 通常会在编译时给出提示。 改变默认的 Ports 目录 有时, 使用不同的工作临时目录和目标目录可能很有用 (甚至是必要的)。 可以用 WRKDIRPREFIXPREFIX 这两个变量来改变默认的目录。 例如: &prompt.root; make WRKDIRPREFIX=/usr/home/example/ports install 将在 /usr/home/example/ports 中编译 port 并把所有的文件安装到 /usr/local &prompt.root; make PREFIX=/usr/home/example/local install 将在 /usr/ports 编译它并安装到 /usr/home/example/local 当然, &prompt.root; make WRKDIRPREFIX=../ports PREFIX=../local install 将包含两种设置 (没有办法在这一页把它写完, 但您应该已经知道怎么回事了)。 另外, 这些变量也可以作为环境变量来设置。 请参考您的 shell 的联机手册上关于如何设置环境变量的说明。 处理 <command>imake</command> 一些 port 使用 imake (这是 X Window 系统的一部分) 不能正常地配合 PREFIX, 它们会坚持把文件安装到 /usr/X11R6 下面。 类似地, 一些 Perl port 会忽略 PREFIX 并把文件安装到 Perl 的目录中。 让这些 port 尊重 PREFIX 是困难甚至是不可能的事情。 重新配置 Ports 当你在编译某些 ports 的时候,可能会弹出一个基于 ncurses 的菜单来让你来选择一些编译选项。 通常用户都希望能够在一个 port 被编译安装了以后还能再次访问这份菜单以添加删除或修改这些选项。 实际上有很多方法来做这件事情。 一个方法进入那个 port 的目录后键入 make config, 之后便会再次显示出菜单和已选择的项目。 另一个方法是用 make showconfig, 这会给你显示出所有的配置选项。还有一个方法是执行 make rmconfig, 这将删除所有已选择的项目。 有关这些选项更详细的内容请参阅 &man.ports.7;。 卸载已经安装的 Ports ports 卸载 现在您已经了解了如何安装 ports, 并希望进一步了解如何卸载, 特别是在错误地安装了某个 port 之后。我们将卸载前面例子 (假如您没有注意的话, 是 lsof) 中安装的 port。 Ports 可以同 packages 以完全相同的方式 (在 Packages 一节 中进行了介绍) 卸载, 方法是使用 &man.pkg.delete.1; 命令: &prompt.root; pkg_delete lsof-4.57 升级 Ports ports 升级 首先, 使用 &man.pkg.version.1; 命令来列出 Ports Collection 中提供了更新版本的那些 port: &prompt.root; pkg_version -v <filename>/usr/ports/UPDATING</filename> 在您更新了 Ports 套件之后, 在升级 port 之前, 应查看 /usr/ports/UPDATING。 这个文件中介绍了在升级时用户应注意的问题, 以及一些可能需要进行的操作。 这可能包括更改文件格式、 配置文件位置的变动, 以及与先前版本的兼容性等等。 如果 UPDATING 与本书中介绍的内容不同, 请以 UPDATING 为准。 使用 Portupgrade 来更新 Ports portupgrade portupgrade 工具是设计来简化升级已安装的 port 的操作的。 它通过 ports-mgmt/portupgrade port 来提供。 您可以像其它 port 那样, 使用 make install clean 命令来安装它: &prompt.root; cd /usr/ports/ports-mgmt/portupgrade &prompt.root; make install clean 使用 pkgdb -F 命令来扫描已安装的 port 的列表, 并修正其所报告的不一致。 在每次升级之前, 有规律地执行它是个好主意。 运行 portupgrade -a 时, portupgrade 将开始并升级系统中所安装的所有过时的 ports。 如果您希望在每个升级操作时得到确认, 应指定 参数。 &prompt.root; portupgrade -ai 如果您只希望升级某个特定的应用程序, 而非全部可用的 port, 应使用 portupgrade pkgname。 如果 portupgrade 应首先升级指定应用程序的话, 则应指定 参数。 &prompt.root; portupgrade -R firefox 要使用预编译的 package 而不是 ports 来进行安装, 需要指定 。 如果指定了这个选项, portupgrade 会搜索 PKG_PATH 中指定的本地目录, 如果没有找到, 则从远程站点下载。 如果本地没有找到, 而且远程站点也没有成功地下载预编译包, 则 portupgrade 将使用 ports。 要禁止使用 port, 可以指定 &prompt.root; portupgrade -PP gnome2 如果只想下载 distfiles (或者, 如果指定了 的话, 是 packages) 而不想构建或安装任何东西, 可以使用 。 要了解更多细节, 请参考 &man.portupgrade.1;。 使用 Portmanager 来升级 Ports portmanager Portmanager 是另一个用以简化已安装 port 升级操作的工具。 它可以通过 ports-mgmt/portmanager port 安装: &prompt.root; cd /usr/ports/ports-mgmt/portmanager &prompt.root; make install clean 可以通过这个简单的命令来升级所有已安装的 port: &prompt.root; portmanager -u 如果希望 Portmanager 在进行每步操作之前都给出提示, 应使用 参数。 Portmanager 也可以用来在系统中安装新的 ports。 与通常的 make install clean 命令不同, 它会在联编和安装您所选择的 port 之前升级所有依赖包。 &prompt.root; portmanager x11/gnome2 如果关于所选 port 的依赖有任何问题, 可以用 Portmanager 来以正确的顺序重新构建它们。 完成之后, 有问题的 port 也将被重新构建。 &prompt.root; portmanager graphics/gimp -f 要了解更多信息, 请参见 &man.portmanager.1;。 Ports 和磁盘空间 ports disk-space 使用 Ports 套件会最终用完磁盘空间。 在通过 ports 联编和安装软件之后, 您应记得清理临时的 work 目录, 其方法是使用 make clean 命令。 您可以使用下面的命令来清理整个 Ports 套件: &prompt.root; portsclean -C 随着时间的推移, 您可能会在 distfiles 目录中积累下大量源代码文件。 您可以手工删除这些文件, 也可以使用下面的命令来删除所有 port 都不引用的文件: &prompt.root; portsclean -D 除此之外, 也可以用下列命令删去目前安装的 port 没有使用的源码包文件: &prompt.root; portsclean -DD 这个 portsclean 工具是 portupgrade 套件的一部分。 不要忘记删除那些已经安装, 但已不再使用的 ports。 用于自动完成这种工作的一个好工具是 ports-mgmt/pkg_cutleaves port。 安装之后还要做点什么? 通常,您通过port安装完一个软件后,可以阅读它带的一些文档(如果它包含文档的话), 或需要编辑它的配置文件,来确保这个软件的运行, 或在机器启动的时候启动(如果它是一个服务的话),等等。 对于不同的软件有着不同的配置步骤。不管怎样, 如果您装好了一个软件,但是不知道下一步怎么办的时候, 这些小技巧可能可以帮助您: 使用 &man.pkg.info.1; 命令,它能找到安装了哪些文件,以及装在哪里。 举个例子,如果您安装了 FooPackage version 1.0.0, 那么这个命令 &prompt.root; pkg_info -L foopackage-1.0.0 | less 将显示这个软件包安装的所有文件,您要特别注意在man/目录里面的文件, 它们可能是手册,etc/目录里面的配置文件,以及 doc/目录下面更多的文档。 如果您不确定已经安装好的软件版本,您可以使用这样的命令 &prompt.root; pkg_info | grep -i foopackage 它将会找到所有已安装的软件包名字中包含foopackage 的软件包。 对于其他的查找, 您只需要在命令行中替换 foopackage 一旦一些软件手册已被您确认安装,您可以使用 &man.man.1; 查看它。 同样的,如果有的话,您还可以完整的查看一遍配置文件的示例,以及任何额外的文档。 如果应用软件有网站, 您还可以从网站上找到文档,常见问题的解答,或其他更多。 如果您不知道它们的网站地址,请使用下面的命令 &prompt.root; pkg_info foopackage-1.0.0 一个 WWW: 行, 如果它存在, 它将提供一个这个应用程序的网站URL. Ports 如果需要在服务器启动时运行(就像互联网服务器), 它通常会把一个脚本的样例放入 /usr/local/etc/rc.d 目录。为了保证正确性, 您可以查看这个脚本, 并编辑或更改这个脚本的名字。 详情请看启动服务。 如何处理坏掉的 Ports 如果您发现某个 port 无法正常工作, 有几件事值得尝试, 包括: 问题报告数据库 中查找是否有尚未提交的修正。 如果有, 可以使用所提议的修正。 要求 port 的监护人 (maintainer) 提供帮助。 输入 make maintainer 或阅读 Makefile 查找监护人的电子邮件地址。 请记得把 port 的名字和版本写在邮件里 (Makefile 中的 $FreeBSD:这一行) 并把错误输出的头几行发给 maintainer。 某些 ports 并非一个人维护, 而是写了一个 邮件列表。 许多, 但并非所有 port, 使用类似 freebsd-listname@FreeBSD.org 这样的地址。 请在提出问题时考虑这一点。 特别地, 由 freebsd-ports@FreeBSD.org 监护的 port, 实际上并没有人维护。 订阅这个邮件列表的人们会感谢您提供的修正和支持。 我们一直都需要更多志愿者! 如果您没有得到回应, 则可以使用 &man.send-pr.1; 来提交问题报告 (请参见 如何撰写 FreeBSD 问题报告)。 修正它! Porter 手册 中提供了关于 Ports 基础设施的详细信息, 通过了解这些内容, 您就能修正偶然坏掉的 port, 或甚至提交自己的 port 了! 从较近的 FTP 站点下载一个编译好的安装包。 中央的 package collection 在 ftp.FreeBSD.orgpackages 目录中, 但 在此之前 一定记得先看看 本地镜像 上是否已经有了! 通常情况下这些安装包都可以直接使用, 而且应该比自行编译快一些。 安装过程本身可以通过 &man.pkg.add.1; 来完成。 diff --git a/zh_CN.GB2312/books/handbook/ppp-and-slip/chapter.sgml b/zh_CN.GB2312/books/handbook/ppp-and-slip/chapter.sgml index 5759a0c4fa..dbcb7bb8da 100644 --- a/zh_CN.GB2312/books/handbook/ppp-and-slip/chapter.sgml +++ b/zh_CN.GB2312/books/handbook/ppp-and-slip/chapter.sgml @@ -1,2792 +1,2792 @@ Jim Mock Restructured, reorganized, and updated by PPP 和 SLIP 概述 PPP SLIP FreeBSD 有很多方法可以将计算机与计算机连接起来。 通过使用拨号 modem 来建立网络或 Internet 连接, 或允许其他人通过您的机器来连上网络, 这些都要求使用 PPP 或 SLIP。 这章将详细介绍设置这些基于 modem 的通信服务的方法。 读完这一章, 您将了解: 如何设置用户级 PPP。 如何设置内核级 PPP。 如何设置 PPPoE (PPP over Ethernet)。 如何设置 PPPoA (PPP over ATM)。 如何配置和安装 SLIP 客户端和服务器。 PPP 用户级 PPP PPP 内核级 PPP PPP PPPoE 在阅读这章之前, 您应: 熟悉基本的网络术语。 理解拨号连接和 PPP、 SLIP 的基础知识。 您可能想知道用户级 PPP 与内核级 PPP 之间的不同之处。 回答很简单: 用户级 PPP 处理用户级的输入和输出数据, 而不是内核级。 在内核与用户区之间复制数据的花费要大一些, 但它能提供具有更多特性的PPP实现。 用户级PPP使用 tun 设备与外界通信而内核级 PPP 使用 ppp 设备。 除非需要与其它 PPP 软件 (比如 pppd) 相区别, 在这一章中, 用户级 PPP 就简称为 ppp。 另外, 若没有额外的注明, 本章所介绍的所有命令都需要 root 权限。 Tom Rhodes Updated and enhanced by Brian Somers Originally contributed by Nik Clayton With input from Dirk Frömberg Peter Childs 使用用户级 PPP 用户级 PPP 前提条件 本章假定您具备如下条件: ISP PPP 您有一个 ISP 提供的用于连接使用 PPP 的帐号。 您需要一个连接到您的系统, 并做了正确配置的 modem 或其它设备, 使您能连接到 ISP。 ISP 的拨号号码。 PAP CHAP UNIX login name password?/primary> 您的登录名称和密码 (可能是一般的 UNIX 风格的登录名和密码对, 也可能是 PAP 或 CHAP 登录名和密码对。) nameserver 一个或多个域名服务器 IP 地址。 通常, 您会从ISP处得到两个这样的IP地址。 如果您至少得到了一个, 就可以在文件 ppp.conf 中加入 enable dns 命令使 ppp 设置域名服务。 这个功能取决于 ISP 对支持 DNS 协商的具体实现。 下面的信息由您的 ISP 提供, 但不是必需的: ISP的网关IP地址。 网关是您准备连接, 并设为 默认路由 的主机。 如果您没有这个信息, 您可以虚构一个, 在连接时 ISP 的 PPP 服务器会自动告诉您正确的值。 这个虚构的 IP 地址在 ppp 中记做 HISADDR 准备使用的子网掩码。 如果ISP没有提供, 一般使用 255.255.255.255 是没有问题的。 static IP address (静态 IP 地址) 如果 ISP 提供了静态的IP地址和主机名, 可以输入它们。 反之, 则应让对方主机指定它认为合适的 IP 地址。 如果您不知道这些信息, 请与您的 ISP 联系。 在这节中, 所有作为例子展示的配置文件中都有行号。 这些行号只是为了使解释和讨论变得方便, 在真实的文件中并不存在。 此外, 在必要时应使用 Tab 和空格来进行缩进。 <application>PPP</application>自动化配置 PPPconfiguration ppppppd(PPP的内核级实现) 都使用/etc/ppp目录中的配置文件。 用户级 PPP 的例子可以在 /usr/share/examples/ppp/ 中找到。 配置ppp要求根据您的需要编辑几个文件。 编辑哪几个文件取决于您的 IP 是静态分配还是动态分配的。 PPP和静态IP地址 PPPwith static IP addresses 您需要编辑配置文件/etc/ppp/ppp.conf, 如下所示。 以冒号:结尾的行从第一列 (行首)开始, 其它所有的行都要使用空格或制表符 (Tab) 来缩进。 1 default: 2 set log Phase Chat LCP IPCP CCP tun command 3 ident user-ppp VERSION (built COMPILATIONDATE) 4 set device /dev/cuaa0 5 set speed 115200 6 set dial "ABORT BUSY ABORT NO\\sCARRIER TIMEOUT 5 \ 7 \"\" AT OK-AT-OK ATE1Q0 OK \\dATDT\\T TIMEOUT 40 CONNECT" 8 set timeout 180 9 enable dns 10 11 provider: 12 set phone "(123) 456 7890" 13 set authname foo 14 set authkey bar 15 set login "TIMEOUT 10 \"\" \"\" gin:--gin: \\U word: \\P col: ppp" 16 set timeout 300 17 set ifaddr x.x.x.x y.y.y.y 255.255.255.255 0.0.0.0 18 add default HISADDR 行1: 指定默认的项。 当PPP运行时这个项中的命令将自动执行。 行2: 启用登录参数。 工作正常后, 为避免产生过多的日志文件, 这行应该简化为: set log phase tun 行 3: 告诉 PPP 怎样向对方标识自己。 如果在建立或使用连接时遇到任何麻烦, PPP就会向对方主机自我标识。 对方主机管理员在处理这个问题时, 这些信息会有用。 行 4: 标明modem要连接的端口号。 COM1 对应的设备是 /dev/cuaa0, 而 COM2 对应的则是 /dev/cuaa1 行 5: 设置连接的速度。 如果 115200 有问题, 试试 38400。 行 6 & 7: PPPuser PPP 拨号字符串。 用户级 PPP 使用一种与 &man.chat.8;程序相似的语法。 请参考联机手册了解这种语言的相关信息。 注意, 为了便于阅读此命令进行了换行。 任何 ppp.conf 里的命令都可以这样做, 前提是行的最后一个字符必须是 \ 行 8: 设置连接的时间间隔。 默认是 180 秒, 所以这一行是多余的。 行 9: 告诉PPP向对方主机确认本地域名解析设置。 如果您运行了本地的域名服务器, 要注释或删除掉这一行。 行 10: 为了可读性的需要设置一个空行。 空行会被PPP忽略。 行 11: provider指定一个项。 可以改成 ISP的名字, 这样您以后就可以使用 来开启连接。 行 12: 设置提供商的电话号码。 多个电话号码可以使用冒号 (:) 或管道符号 (|) 隔开。 这两个字符的区别在&man.ppp.8;的联机手册中有介绍。 总的来讲, 如果您要循环使用这些号码, 可以使用冒号。 如果您想使用第一个号码, 当第一个号码失败了再用第二个号码, 就使用管道符号。 如所示的那样, 要给整个电话号码加上引号(")。 如果电话号码里有空格, 必须用引号(")将其括起来。 否则会造成简单却难以察觉的错误。 行 13 & 14: 指定用户名和密码。 当使用 &unix; 风格的命令提示符登录时, 这些值可以用带有 \U \P 参数的 set login 命令进行修改。 当使用PAP或CHAP进行连接时, 这些值在验证使用。 行 15: PAP CHAP 如果您使用的是PAP或者CHAP, 在这里就不会有登录。 要注释或删除掉这一行。 请参考 PAP 和 CHAP认证 以了解更多细节。 登录命令是的语法是chat类型的。 在这个例子中是这样的: J. Random Provider login: foo password: bar protocol: ppp 您需要改变这个脚本以适合您自己的需要。 当您第一次写这个脚本时, 应当确保已经启用 chat 并处于登录状态, 这样您才能确认通信是否正在按计划进行。 行16: timeout 设置默认的超时时间。 这里, 连接若在 300 秒内无响应将被断开。如果您不想设置成超时, 将这个值设置成0, 或在命令行使用 选项。 行 17: ISP 设置接口地址。 您需要用 ISP 提供给您的 IP 地址替换字符串 x.x.x.x, 用 ISP 的网关 IP 地址 (即您要连接的主机) 替换字符串 y.y.y.y。 如果ISP没有给您提供网关地址, 可以使用 10.0.0.2/0。 如果您需要使用一个 猜到的地址, 请确保在 /etc/ppp/ppp.linkup 中为每个 PPP和动态IP地址 指令创建了这一项。 如果没有这一行, ppp 将无法以 模式运行。 第18行: 添加一个到ISP网关的默认路由。 HISADDR这个关键字会被第17行所指定的网关地址替换。 这行必须出现在第17行之后,以免在 HISADDR 初始化之前使用它的值。 如果您不想使用 的 PPP,则这行应挪到 ppp.linkup 文件中。 若您有一个静态IP地址, 且使用 模式运行ppp(因为在连接之前已经正确设置了路由表项), 那就不需要再向ppp.linkup 添加项。 您可能希望在连接以后创建一个项来调用程序。 这在以后的sendmail的例子中会解释。 示例配置文件可以在目录/usr/share/examples/ppp/中找到。 PPP和动态IP地址 PPPwith dynamic IP addresses IPCP 如果ISP没给您指定静态的IP地址, ppp要被配置成能够与对方协商确定本地和远程地址。 要完成这项工作, 先要一个IP地址, 然后允许 ppp在连接后使用IP配置协议(IPCP)进行正确配置。 ppp.conf的配置是与 PPP和静态IP地址一样的, 除了以下的改变: 17 set ifaddr 10.0.0.1/0 10.0.0.2/0 255.255.255.255 再次强调, 不要包括行号, 它只是一个引用标记。 缩排一个空格是必需的。 行17: / 字符后面是 PPP 所要求的地址掩码。 您可以根据需要使用不同 IP 地址, 但以上的例子永远是可行的。 最后的参数(0.0.0.0)告诉 PPP从0.0.0.0 而不是 10.0.0.1 开始协商地址, 对于有些ISP, 这是必需的。 不要将 0.0.0.0 作为 set ifaddr 的第一个参数, 因为这使得 PPP 在 模式时不能设置初始路由。 如果您不运行模式, 就需要在/etc/ppp/ppp.linkup中创建一个项。 连接建立之后, ppp.linkup被启用。 这时候, ppp将指派接口地址, 接着再添加路由表项: 1 provider: 2 add default HISADDR 行 1: 为了建立连接, ppp 会按按照如下规则在 ppp.linkup寻找项:首先, 试图寻找相同的标签 (如同在ppp.conf一样)。 如果失败了, 寻找作为网关 IP 地址的项, 此项是四个八位字节的风格。 如果依旧没有找到, 就寻找 MYADDR 行 2: 这行告诉 ppp添加指向 HISADDR的默认路由。 HISADDR由通过IPCP协商得到的IP号替换。 参考/usr/share/examples/ppp/ppp.conf.sample/usr/share/examples/ppp/ppp.linkup.sample 中的pmdemand项以获取细节化的例子。 接收拨入 PPPreceiving incoming calls 当要配置 ppp接受来自LAN上的 拨入时, 您需要决定是否将包转给LAN。 如果是的话, 您就必须从 LAN 子网中给对方分配一个IP, 需要在文件 /etc/ppp/ppp.conf 中使用命令 enable proxy。 您还应该确定文件 /etc/rc.conf 中包含以下内容: gateway_enable="YES" 使用哪个getty? 配置 FreeBSD 的拨号服务 描述了如何用 &man.getty.8; 来启动拨号服务。 除了 getty 之外还有 mgetty, 它是 getty 的智能版本, 是按照拨号线的思想设计的。 使用 mgetty 的好处是它能积极地与 modem 进行 会话, 这就意味着如果在/etc/ttys中的端口被关闭, 您的moderm就不会回应拨入。 较新版本的 mgetty (从 0.99beta 起) 也支持自动检测 PPP 数据流, 这样即便客户端不使用脚本也能访问服务器了。 参考Mgetty 和 AutoPPP的联机手册了解更多信息。 <application>PPP</application> 权限 ppp 命令通常必须以 root 用户的身份运行。 如果希望以普通用户的身份启动 ppp 服务 (就像下面描述的那样), 就必须把此用户加入 network 组, 使其获得运行 ppp 的权限。 您还需要使用allow命令使用户能访问配置文 件的一个或多个部分: allow users fred mary 如果这个命令被用在 default 部分中, 您可以让指定的用户访问任何东西。 动态IP用户的PPP Shell PPP shells 创建一个名为/etc/ppp/ppp-shell文件, 加入以下内容: #!/bin/sh IDENT=`echo $0 | sed -e 's/^.*-\(.*\)$/\1/'` CALLEDAS="$IDENT" TTY=`tty` if [ x$IDENT = xdialup ]; then IDENT=`basename $TTY` fi echo "PPP for $CALLEDAS on $TTY" echo "Starting PPP for $IDENT" exec /usr/sbin/ppp -direct $IDENT 这个脚本要有可执行属性。 然后通过如下命令创建一个指向此脚本且名为 ppp-dialup的符号链接: &prompt.root; ln -s ppp-shell /etc/ppp/ppp-dialup 您应该将这个脚本作为所有拨入用户的 shell。 以下是在文件 /etc/passwd 中关于 PPP 用户 pchilds 的例子 (切记, 不要直接修改这个密码文件, 用 &man.vipw.8; 来修改它)。 pchilds:*:1011:300:Peter Childs PPP:/home/ppp:/etc/ppp/ppp-dialup 创建一个名为 /home/ppp的目录作为拨入用户的主目录, 包含以下这些空文件: -r--r--r-- 1 root wheel 0 May 27 02:23 .hushlogin -r--r--r-- 1 root wheel 0 May 27 02:22 .rhosts 这样就可以防止/etc/motd被显示出来。 静态IP用户的Shell PPP shells 像上面那样创建ppp-shell文件, 为每个静态分配IP用户创建一个到 ppp-shell的 符号链接。 例如, 如果您希望为三个拨号用户, fredsam, 和 mary 路由 /24 CIDR 的网络, 则需要键入以下内容: &prompt.root; ln -s /etc/ppp/ppp-shell /etc/ppp/ppp-fred &prompt.root; ln -s /etc/ppp/ppp-shell /etc/ppp/ppp-sam &prompt.root; ln -s /etc/ppp/ppp-shell /etc/ppp/ppp-mary 每个用户的Shell必须被设成一个符号链接(例如用户 mary的Shell应该是/etc/ppp/ppp-mary)。 为动态IP用户设置<filename>ppp.conf</filename> /etc/ppp/ppp.conf文件应该包含下面 这些行: default: set debug phase lcp chat set timeout 0 ttyd0: set ifaddr 203.14.100.1 203.14.100.20 255.255.255.255 enable proxy ttyd1: set ifaddr 203.14.100.1 203.14.100.21 255.255.255.255 enable proxy 缩进得必须的。 default:项在每次会话时都会加载。 每个在 /etc/ttys 中启用的行都必须为其创建一个相似于 ttyd0: 的项。 每一行应该从动态 IP 地址池中取得唯一的IP地址。 为静态 IP 用户配置 <filename>ppp.conf</filename> 根据上面 /usr/share/examples/ppp/ppp.conf 文件的内容, 您必须为每个静态拨号用户添加一个项。 我们继续以 fredsam 以及 mary为例。 fred: set ifaddr 203.14.100.1 203.14.101.1 255.255.255.255 sam: set ifaddr 203.14.100.1 203.14.102.1 255.255.255.255 mary: set ifaddr 203.14.100.1 203.14.103.1 255.255.255.255 如果需要, /etc/ppp/ppp.linkup 也应该包括每个静态IP用户的的路由信息。 下面这一行为客户连接添加了到 203.14.101.0/24 网络的路由。 fred: add 203.14.101.0 netmask 255.255.255.0 HISADDR sam: add 203.14.102.0 netmask 255.255.255.0 HISADDR mary: add 203.14.103.0 netmask 255.255.255.0 HISADDR <command>mgetty</command>和AutoPPP mgetty AutoPPP LCP 在配置和编译mgetty 时启用 AUTO_PPP选项 使mgetty能够探测PPP连接的的LCP状态 并自动产生PPP Shell。 但如果默认的login/password队列没有出现, 那就必须使用PAP或CHAP来验证用户。 这节假定您已经为用户成功地配置, 编译了带有AUTO_PPP选项的 mgetty 确认文件 /usr/local/etc/mgetty+sendfax/login.config 包含以下内容: /AutoPPP/ - - /etc/ppp/ppp-pap-dialup 这行告诉mgetty运行 ppp-pap-dialup脚本来侦听PPP连接。 创建/etc/ppp/ppp-pap-dialup文件写入以下内容 (此文件应该是可执行的): #!/bin/sh exec /usr/sbin/ppp -direct pap$IDENT 对应于每个在/etc/ttys的启用行, 都要在/etc/ppp/ppp.conf 中创建相应的项。 这和上面的定义是相同的。 pap: enable pap set ifaddr 203.14.100.1 203.14.100.20-203.14.100.40 enable proxy 每个以这种方式登录的用户, 都必须在 /etc/ppp/ppp.secret 文件中给出用户名/口令, 或者使用以下选项, 来通过 PAP 方式以 /etc/passwd 文件提供的信息来完成身份验证。 enable passwdauth 如果您想为某些用户分配静态IP, 可以在 /etc/ppp/ppp.secret 中将IP号作为第三个参数指定。 请参见 /usr/share/examples/ppp/ppp.secret.sample 中的例子。 MS Extensions DNS NetBIOS PPPMicrosoft extensions 可以配置PPP以提供DNS和NetBIOS域名服务器地址。 要在 PPP 1.x 版本中启用这些扩展, 需要在 /etc/ppp/ppp.conf 的对应项中加入下列配置: enable msext set ns 203.14.100.1 203.14.100.2 set nbns 203.14.100.5 PPP版本2及以上: accept dns set dns 203.14.100.1 203.14.100.2 set nbns 203.14.100.5 这将告诉客户端首选域名服务器和备用域名服务器。 在版本2及以上版本中, 如果省略了 set dns, PPP会使用 /etc/resolv.conf中的值。 PAP 和 CHAP 验证 PAP CHAP 一些 ISP 将系统配置为使用 PAP 或 CHAP 机制来完成连接验证。 如果遇到这种情况, 在您连接时 ISP 就不会看到 login: 提示符, 而是立即开始 PPP 对话。 PAP 安全性要比 CHAP 差一些, 但在这里安全性并不是问题, 因为密码 (即使用明文传送) 只是通过串行线传送, 攻击者并没有太多机会去 窃听 它。 参考 PPP 与静态 IP 地址 或 PPP 与动态 IP 地址 小节, 并完成下列改动: 13 set authname MyUserName 14 set authkey MyPassword 15 set login 第 13 行: 这一行指明您的PAP/CHAP用户名。 您需要为MyUserName输入正确的值。 第 14 行: password 这一行指明您的 PAP/CHAP password密码。 您需要为 MyPassword 输入正确的值。 另外,您可能希望加入一些额外的选项,例如: 16 accept PAP 16 accept CHAP 以明确您的意图, 不过, 默认情况下 PAP 和 CHAP 都会被接受。 行 15: 如果您使用的是 PAP 或 CHAP, 一般来说 ISP 就不会要求您登录服务器了。 这时, 就必须禁用 set login 设置。 即时改变您的<command>ppp</command> 配置 与后台运行的ppp程序进行对话是可能的, 前提是设置了一个合适的诊断端口。 做到这一点, 需要把下面的行加入到您的配置中: set server /var/run/ppp-tun%d DiagnosticPassword 0177 这行告诉 PPP在指定的&unix;域socket中侦听, 当用户连接时需要给出指定的密码。 %dtun设备号替换。 一旦启用了socket, 就可以在脚本中调用程序&man.pppctl.8;来处理正在运行的 的PPP。 使用PPP网络地址翻译 PPPNAT PPP 可以使用内建的 NAT, 而无需内核支持。 您可以在 /etc/ppp/ppp.conf 中加入如下配置来启用它: nat enable yes PPP NAT也可以使用命令行选项 -nat启动。 在 /etc/rc.conf 文件中也有 ppp_nat 项, 并默认启用。 如果您使用了这个特性, 您还会发现在 /etc/ppp/ppp.conf中以下 选项对于启用incoming connections forwarding是有用的: nat port tcp 10.0.0.2:ftp ftp nat port tcp 10.0.0.2:http http 或者完全不信任外来的请求 nat deny_incoming yes 最后的系统配置 PPPconfiguration 现在您已配置了ppp, 但在真正工作之前还有一些事情要做。 即修改 /etc/rc.conf 从上依次往下看, 确认已经正确地配置了 hostname=, 例如: hostname="foo.example.com" 如果您的ISP提供给您一个静态的IP和名字, 将这个名字设为hostname是最合适的。 寻找 network_interfaces 变量。 如果要配置系统通过拨号连入ISP, 一定要将tun0设备加入这个列表, 否则就删除它。 network_interfaces="lo0 tun0" ifconfig_tun0= ifconfig_tun0变量应该是空的, 且要创建一个名为 /etc/start_if.tun0的文件。 这个文件应该包含这一行: ppp -auto mysystem 此脚本在网络配置时被执行, 开启PPP守护进程进入自动模式。 如果这台机子充当一个LAN的网关, 您可能希望使用 。 参考相关联机手册了解更多细节。 务必在 /etc/rc.conf 中, 把路由程序设置为 NO router_enable="NO" routed 不启动 routed 服务程序非常重要, 因为 routed 总会删掉由 ppp 所建立的默认路由。 此外, 我们建议您确认一下 sendmail_flags 这一行中没有指定 参数, 否则 sendmail 将会不断地尝试查找网络, 而这样做将会导致机器不断地进行拨号。 可以考虑: sendmail_flags="-bd" sendmail 替代的做法是当每次 PPP 连接建立时您必须通过键入以下命令强制 sendmail 重新检查邮件队列: &prompt.root; /usr/sbin/sendmail -q 您也可以在ppp.linkup使用!bg命令自动完成这些工作: 1 provider: 2 delete ALL 3 add 0 0 HISADDR 4 !bg sendmail -bd -q30m SMTP 如果您不喜欢这样做, 可以设立一个 dfilter 以阻止 SMTP 传输。 参考相关文件了解更多细节。 现在您唯一要做的事是重新启动计算机。 重启之后,可以输入: &prompt.root; ppp 然后是dial provider以开启 PPP会话。 或者如果您想让ppp自动建立会话, 因为您有一条广域网连接 (且没有创建 start_if.tun0 脚本), 键入: &prompt.root; ppp -auto provider 总结 当第一次设置PPP时, 下面几步是必须的: 客户端: 确保 tun编译进了进核。 确保tunN 设备文件在 /dev 目录中是可用的。 /etc/ppp/ppp.conf中创建一个项。 pmdemand示例应该适合于绝大多数ISP。 如果您使用动态IP地址, 在/etc/ppp/ppp.linkup创建一个项。 更新/etc/rc.conf 文件。 如果您要求按需拨号, 创建一个start_if.tun0脚本。 服务器端: 确保tun设备已编译入内核。 确保tunN设备文件在 /dev目录中是可用的。 /etc/passwd中创建一个项 (使用&man.vipw.8;程序)。 在用户的home目录创建一个运行 ppp -direct direct-server或相似命令的profile。 /etc/ppp/ppp.conf中创建一个项。 direct-server示例应该能满足要求。 /etc/ppp/ppp.linkup中创建一个项。 更新 /etc/rc.conf 文件。 Gennady B. Sorokopud Parts originally contributed by Robert Huff 使用内核级PPP 设立内核级PPP PPPkernel PPP 在开始设置内核级PPP时, 需要确信pppd已经被定位在/usr/sbin 中 且存在/etc/ppp目录。 pppd能在两种模式下工作: 作为一个 客户 — 您要通过PPP串行线或modem线把您的机器连接到互联网上。 PPPserver 作为服务器 —计算机已经位于网络上, 且被用于通过PPP与其它计算机连接。 两种情况您都需要设立一个选项文件, (/etc/ppp/options 或者是 ~/.ppprc 如果您的计算机有多个用户使用PPP)。 您还需要一些modem/serial软件(comms/kermit就很适合), 使您能够拨号并与远程主机建立连接。 Trev Roydhouse Based on information provided by 使用<command>pppd</command>作为客户端 PPPclient Cisco 下面这个 /etc/ppp/options选项文件能够被用来与CISCO终端服务器的 PPP线连接。 crtscts # enable hardware flow control modem # modem control line noipdefault # remote PPP server must supply your IP address # if the remote host does not send your IP during IPCP # negotiation, remove this option passive # wait for LCP packets domain ppp.foo.com # put your domain name here :<remote_ip> # put the IP of remote PPP host here # it will be used to route packets via PPP link # if you didn't specified the noipdefault option # change this line to <local_ip>:<remote_ip> defaultroute # put this if you want that PPP server will be your # default router 连接: Kermit modem 使用 Kermit (或其他 modem 程序来拨号), 然后输入您的用户名和口令 (或在远程主机上启用 PPP 所需的其他信息)。 退出 Kermit (并不挂断连接)。 键入下面这行: &prompt.root; /usr/src/usr.sbin/pppd.new/pppd /dev/tty01 19200 一定要使用正确的速度和设备名。 现在您的计算机已经用PPP连接。 如果连接失败, 您可在文件 /etc/ppp/options 中添加 选项, 并查看控制台信息以跟踪问题。 下面这个/etc/ppp/pppup脚本能自动完成这三个步骤: #!/bin/sh -ps ax |grep pppd |grep -v grep -pid=`ps ax |grep pppd |grep -v grep|awk '{print $1;}'` +pgrep -l pppd +pid=`pgrep pppd` if [ "X${pid}" != "X" ] ; then echo 'killing pppd, PID=' ${pid} kill ${pid} fi -ps ax |grep kermit |grep -v grep -pid=`ps ax |grep kermit |grep -v grep|awk '{print $1;}'` +pgrep -l kermit +pid=`pgrep kermit` if [ "X${pid}" != "X" ] ; then echo 'killing kermit, PID=' ${pid} kill -9 ${pid} fi ifconfig ppp0 down ifconfig ppp0 delete kermit -y /etc/ppp/kermit.dial pppd /dev/tty01 19200 Kermit /etc/ppp/kermit.dial 是一个 Kermit 脚本, 它会完成拨号, 并在远程主机上完成所有需要的身份验证过程 (这份文档的最后有一个脚本实例)。 使用下面这个脚本/etc/ppp/pppdown断开PPP连线: #!/bin/sh -pid=`ps ax |grep pppd |grep -v grep|awk '{print $1;}'` +pid=`pgrep pppd` if [ X${pid} != "X" ] ; then echo 'killing pppd, PID=' ${pid} kill -TERM ${pid} fi -ps ax |grep kermit |grep -v grep -pid=`ps ax |grep kermit |grep -v grep|awk '{print $1;}'` +pgrep -l kermit +pid=`pgrep kermit` if [ "X${pid}" != "X" ] ; then echo 'killing kermit, PID=' ${pid} kill -9 ${pid} fi /sbin/ifconfig ppp0 down /sbin/ifconfig ppp0 delete kermit -y /etc/ppp/kermit.hup /etc/ppp/ppptest 通过执行/usr/etc/ppp/ppptest, 看看pppd 是否仍在运行: #!/bin/sh -pid=`ps ax| grep pppd |grep -v grep|awk '{print $1;}'` +pid=`pgrep pppd` if [ X${pid} != "X" ] ; then echo 'pppd running: PID=' ${pid-NONE} else echo 'No pppd running.' fi set -x netstat -n -I ppp0 ifconfig ppp0 执行脚本 /etc/ppp/kermit.hup以挂起moderm, 这个文件包含: set line /dev/tty01 ; put your modem device here set speed 19200 set file type binary set file names literal set win 8 set rec pack 1024 set send pack 1024 set block 3 set term bytesize 8 set command bytesize 8 set flow none pau 1 out +++ inp 5 OK out ATH0\13 echo \13 exit 也可以用chat 代替kermit 以下两个文件用以建立pppd连接。 /etc/ppp/options /dev/cuaa1 115200 crtscts # enable hardware flow control modem # modem control line connect "/usr/bin/chat -f /etc/ppp/login.chat.script" noipdefault # remote PPP serve must supply your IP address # if the remote host doesn't send your IP during # IPCP negotiation, remove this option passive # wait for LCP packets domain <your.domain> # put your domain name here : # put the IP of remote PPP host here # it will be used to route packets via PPP link # if you didn't specified the noipdefault option # change this line to <local_ip>:<remote_ip> defaultroute # put this if you want that PPP server will be # your default router /etc/ppp/login.chat.script 以下的内容应该放在一行内。 ABORT BUSY ABORT 'NO CARRIER' "" AT OK ATDT<phone.number> CONNECT "" TIMEOUT 10 ogin:-\\r-ogin: <login-id> TIMEOUT 5 sword: <password> 一旦这些被安装且修改正确, 您所要做的就是运行pppd, 就像这样: &prompt.root; pppd 使用<command>pppd</command>作为服务器 /etc/ppp/options要包括下面这些内容: crtscts # Hardware flow control netmask 255.255.255.0 # netmask (not required) 192.114.208.20:192.114.208.165 # IP's of local and remote hosts # local ip must be different from one # you assigned to the Ethernet (or other) # interface on your machine. # remote IP is IP address that will be # assigned to the remote machine domain ppp.foo.com # your domain passive # wait for LCP modem # modem line 下面这个脚本/etc/ppp/pppserv 使pppd以服务器方式启动: - #!/bin/sh -ps ax |grep pppd |grep -v grep -pid=`ps ax |grep pppd |grep -v grep|awk '{print $1;}'` + #!/bin/sh +pgrep -l pppd +pid=`pgrep pppd` if [ "X${pid}" != "X" ] ; then echo 'killing pppd, PID=' ${pid} kill ${pid} fi -ps ax |grep kermit |grep -v grep -pid=`ps ax |grep kermit |grep -v grep|awk '{print $1;}'` +pgrep -l kermit +pid=`pgrep kermit` if [ "X${pid}" != "X" ] ; then echo 'killing kermit, PID=' ${pid} kill -9 ${pid} fi # reset ppp interface ifconfig ppp0 down ifconfig ppp0 delete # enable autoanswer mode kermit -y /etc/ppp/kermit.ans # run ppp pppd /dev/tty01 19200 使用脚本/etc/ppp/pppservdown停止服务器: #!/bin/sh -ps ax |grep pppd |grep -v grep -pid=`ps ax |grep pppd |grep -v grep|awk '{print $1;}'` +pgrep -l pppd +pid=`pgrep pppd` if [ "X${pid}" != "X" ] ; then echo 'killing pppd, PID=' ${pid} kill ${pid} fi -ps ax |grep kermit |grep -v grep -pid=`ps ax |grep kermit |grep -v grep|awk '{print $1;}'` +pgrep -l kermit +pid=`pgrep kermit` if [ "X${pid}" != "X" ] ; then echo 'killing kermit, PID=' ${pid} kill -9 ${pid} fi ifconfig ppp0 down ifconfig ppp0 delete kermit -y /etc/ppp/kermit.noans 下面的 Kermit 脚本 (/etc/ppp/kermit.ans) 能够启用/禁用您 modem 的自动应答模式。 其内容类似下面这样: set line /dev/tty01 set speed 19200 set file type binary set file names literal set win 8 set rec pack 1024 set send pack 1024 set block 3 set term bytesize 8 set command bytesize 8 set flow none pau 1 out +++ inp 5 OK out ATH0\13 inp 5 OK echo \13 out ATS0=1\13 ; change this to out ATS0=0\13 if you want to disable ; autoanswer mode inp 5 OK echo \13 exit 一个名为/etc/ppp/kermit.dial的脚本用于向远程主机 进行拨号和验证。 您要根据需要定制它。 要加入您的登寻名和密码, 您还要根据 modem 和远程主机的反应修改输入语句。 ; ; put the com line attached to the modem here: ; set line /dev/tty01 ; ; put the modem speed here: ; set speed 19200 set file type binary ; full 8 bit file xfer set file names literal set win 8 set rec pack 1024 set send pack 1024 set block 3 set term bytesize 8 set command bytesize 8 set flow none set modem hayes set dial hangup off set carrier auto ; Then SET CARRIER if necessary, set dial display on ; Then SET DIAL if necessary, set input echo on set input timeout proceed set input case ignore def \%x 0 ; login prompt counter goto slhup :slcmd ; put the modem in command mode echo Put the modem in command mode. clear ; Clear unread characters from input buffer pause 1 output +++ ; hayes escape sequence input 1 OK\13\10 ; wait for OK if success goto slhup output \13 pause 1 output at\13 input 1 OK\13\10 if fail goto slcmd ; if modem doesn't answer OK, try again :slhup ; hang up the phone clear ; Clear unread characters from input buffer pause 1 echo Hanging up the phone. output ath0\13 ; hayes command for on hook input 2 OK\13\10 if fail goto slcmd ; if no OK answer, put modem in command mode :sldial ; dial the number pause 1 echo Dialing. output atdt9,550311\13\10 ; put phone number here assign \%x 0 ; zero the time counter :look clear ; Clear unread characters from input buffer increment \%x ; Count the seconds input 1 {CONNECT } if success goto sllogin reinput 1 {NO CARRIER\13\10} if success goto sldial reinput 1 {NO DIALTONE\13\10} if success goto slnodial reinput 1 {\255} if success goto slhup reinput 1 {\127} if success goto slhup if < \%x 60 goto look else goto slhup :sllogin ; login assign \%x 0 ; zero the time counter pause 1 echo Looking for login prompt. :slloop increment \%x ; Count the seconds clear ; Clear unread characters from input buffer output \13 ; ; put your expected login prompt here: ; input 1 {Username: } if success goto sluid reinput 1 {\255} if success goto slhup reinput 1 {\127} if success goto slhup if < \%x 10 goto slloop ; try 10 times to get a login prompt else goto slhup ; hang up and start again if 10 failures :sluid ; ; put your userid here: ; output ppp-login\13 input 1 {Password: } ; ; put your password here: ; output ppp-password\13 input 1 {Entering SLIP mode.} echo quit :slnodial echo \7No dialtone. Check the telephone line!\7 exit 1 ; local variables: ; mode: csh ; comment-start: "; " ; comment-start-skip: "; " ; end: Tom Rhodes Contributed by <acronym>PPP</acronym> 连接故障排除 PPPtroubleshooting 本节将讲述通过modem连接使用PPP时可能出现的问题。 例如, 您可能需要确切地知道您拨入的系统会出现一个怎样的命令行提示符。 有些 ISP 会提供 ssword提示符, 而其它的可能会出现 password; 如果没有根据情况的不同相应地编写 ppp 脚本, 登录就会失败。 诊断 ppp 最常用的方法是手动进行连接。 以下的信息会一步一步地带您完成手动连接。 检查设备节点 如果您的内核是经过重新配置的, 那么就需要检查sio设备。 如果没有配置过内核, 就没什么可担心的了。 只要查看 dmesg的输出以找到modem设备: &prompt.root; dmesg | grep sio 您应该找到与 sio 设备有关的输出。 这些就是我们需要的 COM 端口。 如果您的 modem 按照标准串行端口工作, 您就会在 sio1COM2 上找到它。 如果 modem 设备连接在 sio1 接口 (在 DOS 中称为COM2), 那么您的 modem 将会是 /dev/cuaa1 手动连接 通过手动控制ppp来连接Internet 是诊断连接及获知ISP处理PPP客户端方式的一个快速, 简单的方法。 让我们从PPP 命令行开始, 在所有的例子中我们使用 example 表示运行 PPP 服务的主机名。 键入ppp 命令打开 ppp &prompt.root; ppp 现在我们已经打开了ppp ppp ON example> set device /dev/cuaa1 设置modem设备, 在本例子中是 cuaa1 ppp ON example> set speed 115200 设置连接速度, 在本例中我们使用15,200 kbps ppp ON example> enable dns 使ppp配置域名服务, 在文件/etc/resolv.conf中添加域名服务器行。 如果 ppp不能确定我们的主机名, 可以在稍后设置。 ppp ON example> term 切换到 终端样我们就能手动地控制这台 modem 的模式。 deflink: Entering terminal mode on /dev/cuaa1 type '~h' for help at OK atdt123456789 使用命令at初始化modem, 然后使用atdtISP给您的号码进行拨号。 CONNECT 连接配置, 如果我们遇到了与硬件无关的连接问题, 可以在这里尝试解决。 ISP Login:myusername 这里提示您输入用户名, 输入ISP提供的用户名然后按回车。 ISP Pass:mypassword 这时提示我们输入密码, 输入 ISP提供的密码。 如同登录入&os;, 密码不会显示。 Shell or PPP:ppp 由于ISP的不同, 这个提示符可能不会出现。 这里我们需要考虑: 是使用运行于提供商端的 Shell, 还是启动 ppp? 这本例中, 我们选择使用 ppp, 因为我们希望得到 Internet 连接。 Ppp ON example> 注意在这个例子中, 第一个 已经大写。 这表示我们已经成功地连接上了 ISP PPp ON example> 我们已经成功通过了 ISP的验证, 正在等待分配IP地址。 PPP ON example> 我们得到了一个 IP 地址, 成功地完成了连接。 PPP ON example>add default HISADDR 这样就完成了添加默认路由所需的配置。 这是与外界通信所必需的。 因为之前我们只是与服务器端建立了连接。 如果由于已存在的路由而导致操作失败, 您可以在 前加 !号。 除此之外, 您也可以在真正连接之前设置这些 (指 add default HISADDR), ppp 会根据这项设定协商取得新的路由。 如果一切顺利, 现在我们应该能得到一个活动的 Internet 连接, 可以使用 CTRL z 使其转入后台。 如果您发现 PPP重新变为 ppp, 则表示连接被断开。 大写的 P 表明建立了到 ISP 的连接, 而小写的 p 则表示连接由于某种原因被断开, 这有助于帮助我们了解连接的状态。 ppp 只有这两个状态。 诊断排错 如果您有一根直连线且似乎不能建立连接, 要使用以关闭字节流的CTS/RTS。 这种情况一般发生在连接兼容 PPP 的终端服务器时。 当它向通信连接写入数据时, PPP就会挂起, 一直等待一个CTS, 或者一个不可能出现的 Clear to Send 信号。 如果使用了这个选项, 您还应使用 选项, 某些存在缺陷的硬件在完成端对端发送特定字符, 特别是 XON/XOFF 时可能会遇到困难。 请参见 &man.ppp.8; 联机手册以了解关于可用选项的更多细节, 以及如何使用它们。 如果您的 modem 比较旧, 就需要使用 了。 奇偶校验的默认设置是 none, 但在旧式的 (当流量大量增加时) 调制解调器和某些 ISP 被用来纠错。 您需要使用这个选项才能使用 Compuserve ISP PPP 可能并不返回命令模式, 这通常是 ISP 等待您这一端发起协商时发生了错误。 此时, 使用 ~p 命令将强制 ppp 开始发送配置信息。 如果您没有看到登录提示, 则很可能需要使用 PAPCHAP 验证来代替前面例子中的 &unix; 风格验证。 要使用 PAPCHAP 只需在进入终端模式之前把下面的选项加入 PPP ppp ON example> set authname myusername 此处 myusername 应改为您的 ISP 分配给您的用户名。 ppp ON example> set authkey mypassword 此处 mypassword 应该为您的 ISP 分配给您的口令。 如果连接正常, 但无法查找域名, 请尝试 &man.ping.8; 某个 IP 地址来看看是否返回了信息。 如果您发现百分之百 (100%) 丢包, 那么您很可能没有分配默认路由。 请仔细检查选项 是否在连接时被设置了。 如果您能连接到远程的 IP 地址则有可能域名解析服务器的地址没有被加入到 /etc/resolv.conf。 这个文件应该是下面的样子: domain example.com nameserver x.x.x.x nameserver y.y.y.y 此处 x.x.x.xy.y.y.y 应该改为您的 ISP 的 DNS 服务器的 IP 地址。 这一信息在您注册时可能会提供给您, 不过通常只需给 ISP 打个电话就能知道了。 您还可以让 &man.syslog.3; 为您的 PPP 连接提供日志。 只需增加: !ppp *.* /var/log/ppp.log /etc/syslog.conf 中。 绝大多数情况下, 这个功能默认已经打开了。 Jim Mock Contributed (from http://node.to/freebsd/how-tos/how-to-freebsd-pppoe.html) by 使用基于以太网的PPP(PPPoE) PPPover Ethernet PPPoE PPP, over Ethernet (以太网上的 PPP) 本节将介绍如何建立基于以太网的PPP (PPPoE)。 配置内核 对于PPPOE, 并没有必须的内核配置。 如果必需的 netgraph 支持没有编译入内核, 它可以由 ppp 动态加载。 设置<filename>ppp.conf</filename> 以下是一个ppp.conf的例子: default: set log Phase tun command # you can add more detailed logging if you wish set ifaddr 10.0.0.1/0 10.0.0.2/0 name_of_service_provider: set device PPPoE:xl1 # replace xl1 with your Ethernet device set authname YOURLOGINNAME set authkey YOURPASSWORD set dial set login add default HISADDR 运行<application>ppp</application> root 身份执行: &prompt.root; ppp -ddial name_of_service_provider 启动时运行<application>ppp</application> /etc/rc.conf 中加入以下内容: ppp_enable="YES" ppp_mode="ddial" ppp_nat="YES" # if you want to enable nat for your local network, otherwise NO ppp_profile="name_of_service_provider" 使用 PPPoE 服务标签 在某些时候, 有必要使用一个服务标签来建立您的连接。 服务标签用于区分同一网络中的不同服务器。 您可以在ISP提供的文档中找到必要的服务标签信息。 若不能找到, 则应向您的 ISP 寻求技术支持。 作为最后的方法, 您可以试试 Roaring Penguin PPPoE, 它可以在 Ports Collection 中找到。 然而需要注意的是, 它可能会清楚 modem 的固件, 并使其无法正常工作, 因此一定要仔细考虑之后再做这个操作。 简单地安装由服务提供商随 modem 提供的程序。 随后, 选择 System 菜单。 您的配置文件应该会在这里列出。 一般来说它的名字应该是 ISP 配置文件名 (service tag, 服务标签) 将被用于 PPPoE 在 ppp.conf 中的配置项, 作为服务商 set device 命令的一部分 (参见 &man.ppp.8; 联机手册以了解更多细节)。 它应该类似下面的样子: set device PPPoE:xl1:ISP 记住将xl1换成实际的以太网设备。 记住将 ISP 换成您刚刚找到的profile名。 获得更多的信息, 请参考: Cheaper Broadband with FreeBSD on DSL by Renaud Waldura. Nutzung von T-DSL und T-Online mit FreeBSD by Udo Erdelhoff (in German). 带有一个&tm.3com; <trademark class="registered">HomeConnect</trademark>ADSL Modem的PPPOE双重连接 这个 modem 不遵循 RFC 2516 (A Method for transmitting PPP over Ethernet (PPPoE), 其作者为 L. Mamakos、 K. Lidl、 J. Evarts、 D. Carrel、 D. Simone 以及 R. Wheeler)。 而是使用不同的数据包格式作为以太网的框架。 请向 3Com 抱怨, 如果您认为它应该遵守 PPPoE 的规范。 为了让FreeBSD能够与这个设备通信, 必须设置sysctl。 通过更改/etc/sysctl.conf, 这一步可以在启动时自动完成: net.graph.nonstandard_pppoe=1 或者, 也可以直接执行下面的命令: &prompt.root; sysctl net.graph.nonstandard_pppoe=1 很不幸,由于这是系统全局设置, 无法同时与正常的PPP客户端(或服务器) 和&tm.3com;HomeConnect ADSL Modem通信。 使用 ATM 上的 <application>PPP</application> (PPPoA) PPPover ATM PPPoA 基于ATM的PPP 以下将介绍如何设置基于ATM的PPP(PPPoA)。 PPPoA是欧洲DSL提供商的普遍选择。 使用 Alcatel &speedtouch;USB 的 PPPoA 针对这一设备的 PPPoA 支持, 在 FreeBSD 中是作为 port 提供的, 因为其固件使用了 阿尔卡特许可协议, 因而不能与 FreeBSD 的基本系统一起免费地再发布。 使用 Ports 套件 可以非常方便地安装 net/pppoa port, 之后按照它提供的指示操作就可以了。 和许多 USB 设备类似, 阿尔卡特的 &speedtouch; USB 需要从主机上下载固件才能够正常工作。 在 &os; 中您可以将此操作自动化, 在有设备插到某个 USB 口的时候自动下载固件。 可以在 /etc/usbd.conf 文件中加入下面的信息来让它自动完成固件的传送。 注意, 必须以 root 用户的身份编辑它。 device "Alcatel SpeedTouch USB" devname "ugen[0-9]+" vendor 0x06b9 product 0x4061 attach "/usr/local/sbin/modem_run -f /usr/local/libdata/mgmt.o" 要启动USB守护进程usbd, 在/etc/rc.conf加入以下行: usbd_enable="YES" 也可以将ppp设置成启动时拨号。 向 /etc/rc.conf加入以下这几行。 同样地您需要以root用户登录。 ppp_enable="YES" ppp_mode="ddial" ppp_profile="adsl" 为了使其正常工作, 您需要使用net/pppoa port提供的ppp.conf样例。 使用mpd 可以使用 mpd 来连接多种类型的服务, 特别是 PPTP 服务。 您可以在 Ports Collection 中找到 mpd, 它的位置是 net/mpd。 许多 ADSL modem 需要在 modem 和计算机之间建立一条 PPTP 隧道, 而阿尔卡特 &speedtouch; Home 正是其中的一种。 首先需要从 port 完成安装, 然后才能配置 mpd 来满足您的需要, 并完成服务商的配置。 port 会把一系列包括了详细注解的配置文件实例放到 PREFIX/etc/mpd/。 注意, 这里的 PREFIX 表示 ports 安装的目录, 默认情况下, 应该是 /usr/local/。 关于配置 mpd 的完整说明, 会以 HTML 格式随 port 一起安装。 这些文件将放在 PREFIX/share/doc/mpd/。 下面是通过 mpd 连接 ADSL 服务的一个简单例子。 配置被分别放到了两个文件中, 第一个是 mpd.conf default: load adsl adsl: new -i ng0 adsl adsl set bundle authname username set bundle password password set bundle disable multilink set link no pap acfcomp protocomp set link disable chap set link accept chap set link keep-alive 30 10 set ipcp no vjcomp set ipcp ranges 0.0.0.0/0 0.0.0.0/0 set iface route default set iface disable on-demand set iface enable proxy-arp set iface idle 0 open username用来向您的ISP进行验证。 password用来向您的ISP进行验证。 mpd.links包含连接的信息: adsl: set link type pptp set pptp mode active set pptp enable originate outcall set pptp self 10.0.0.1 set pptp peer 10.0.0.138 运行mpd的主机的IP地址。 ADSL modem的IP地址。 Alcatel &speedtouch; Home 默认的是 10.0.0.138 初始化连接: &prompt.root; mpd -b adsl 您可以通过以下命令查看连接状态: &prompt.user; ifconfig ng0 ng0: flags=88d1<UP,POINTOPOINT,RUNNING,NOARP,SIMPLEX,MULTICAST> mtu 1500 inet 216.136.204.117 --> 204.152.186.171 netmask 0xffffffff 使用mpd连接ADSL服务是推荐的方式。 使用pptpclient 也可以使用net/pptpclient连接其它的 PPPoA。 要使用 net/pptpclient 连接 DSL 服务, 需要安装 port 或 package 并编辑 /etc/ppp/ppp.conf。 您需要有 root 权限才能完成这两项操作。 以下是 ppp.conf 中的一个示例项。 参考 ppp 的联机手册 &man.ppp.8;, 以了解更多有关 ppp.conf 选项的信息。 adsl: set log phase chat lcp ipcp ccp tun command set timeout 0 enable dns set authname username set authkey password set ifaddr 0 0 add default HISADDR 您在 DSL 服务提供商那里的用户名 您帐户的口令。 由于您必须将帐号密码以明文的方式放入ppp.conf 您应该确保没有任何人能看到此文件的内容。 以下一系列命令将会确保此文件只对 root用户可读。 请参见 &man.chmod.1; 和 &man.chown.8; 的联机手册以了解有关如何操作的进一步信息。 &prompt.root; chown root:wheel /etc/ppp/ppp.conf &prompt.root; chmod 600 /etc/ppp/ppp.conf 以下将为到 DSL 路由器的会话打开一个 tunnel。 以太网DSL modem有一个设置的局域网IP地址。 以 Alcatel &speedtouch; Home 为例, 这个地址是 10.0.0.138。 路由器的文档应该会告诉您它使用的地址。 执行以下命令以打开 tunnel 并开始会话: &prompt.root; pptp address adsl 您应该在命令的最后加上(&)号, 否则 pptp 无法返回到命令行提示符。 要创建一个 tun虚拟设备用于进程pptpppp 之间的交互。 一旦您回到了命令行, 或者 pptp 进程确认了一个连接, 您可以这样检查tunnel设备: &prompt.user; ifconfig tun0 tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500 inet 216.136.204.21 --> 204.152.186.171 netmask 0xffffff00 Opened by PID 918 如果您无法连接, 一般可以通过telnet或者web浏览器检查路由器(modem)的配置。 如果依旧无法连接, 您应该检查pptp的输出及ppp的日志文件 /var/log/ppp.log 以获得线索。 Satoshi Asami Originally contributed by Guy Helmer With input from Piero Serini 使用SLIP SLIP 设置SLIP客户端 SLIPclient 下面是在静态主机网络上配置 FreeBSD 机器使用 SLIP 的方法。 对于动态主机名分配 (您的地址会随每次拨号而不同), 您可能需要稍复杂一些的设置。 首先, 您需要确认调制解调器所连接的串口。 许多人会设置一个符号连接, 例如 /dev/modem, 用以指向实际的设备名, /dev/cuaaN (或在 &os; 6.X 下是 /dev/cuadN)。 这样您就可以对实际的设备名进行抽象, 以备调制解调器换到其他串口时方便调整之用。 不然, 在系统中修改一大堆 /etc 下的文件以及 .kermrc 将是非常麻烦的事情! /dev/cuaa0 (或 &os; 6.X 中的 /dev/cuad0) 对应 COM1, 而 cuaa1 (或 /dev/cuad1) 则对应 COM2, 等等。 确保您的内核文件包含以下内容: device sl 这包含在GENERIC内核, 所以这应该不会是个问题, 除非您 已经删除了它。 只需做一次的事情 把您本地网络上的机器、 网关以及域名服务器, 都加入到 /etc/hosts 文件中。 我们的是下面这个样子: 127.0.0.1 localhost loghost 136.152.64.181 water.CS.Example.EDU water.CS water 136.152.64.1 inr-3.CS.Example.EDU inr-3 slip-gateway 128.32.136.9 ns1.Example.EDU ns1 128.32.136.12 ns2.Example.EDU ns2 在 FreeBSD 5.0 之前的版本中, 请务必确保 /etc/host.conf 中的 hostsbind 之前出现。 从 FreeBSD 5.0 开始, 系统转而使用 /etc/nsswitch.conf 文件, 请确认在这个文件中 一行里, files 出现在 dns 之前。 如果没有这些参数, 可能会发生很奇怪的事情。 编辑/etc/rc.conf 编辑以下这行设置主机名(hostname): hostname="myname.my.domain" 应该用您主机的Internet全名代替。 default route 改变这一行以指明默认的路由: defaultrouter="NO" 改为: defaultrouter="slip-gateway" 创建文件/etc/resolv.conf, 写入以下内容: domain CS.Example.EDU nameserver 128.32.136.9 nameserver 128.32.136.12 nameserver domain name 正如您看到的, 这些行设置了域名服务器。 当然, 实际的域名和IP地址取决于您的环境。 设置roottoor的密码(其它任何没有密码的帐号)。 重启计算机, 然后确认使用了正确的主机名。 创建一个SLIP连接 SLIPconnecting with 在命令提示符之后输入 slip 进行拨号, 输入您的机器名和口令。 具体需要输入什么, 与您的环境密切相关。 如果使用 Kermit, 则可以使用类似下面的脚本: # kermit setup set modem hayes set line /dev/modem set speed 115200 set parity none set flow rts/cts set terminal bytesize 8 set file type binary # The next macro will dial up and login define slip dial 643-9600, input 10 =>, if failure stop, - output slip\x0d, input 10 Username:, if failure stop, - output silvia\x0d, input 10 Password:, if failure stop, - output ***\x0d, echo \x0aCONNECTED\x0a 当然, 您还需要修改用户名和口令来满足实际需要。 完成这些操作之后, 只需在 Kermit 提示符之后输入 slip 就可以连接了。 将密码以纯文本的形式存放在文件系统无论如何都是个 主意。 请考虑这样做的风险。 在这里退出 Kermit (也可以用 Ctrl z 将其挂起), 以 root 用户键入: &prompt.root; slattach -h -c -s 115200 /dev/modem 如果您能ping通路由器另一端的主机, 就是连接好了! 如果不行, 您可以使用选项代替 作为slattach的参数。 关闭连接 按下面的步骤做: &prompt.root; kill -INT `cat /var/run/slattach.modem.pid` 来杀掉 slattach。 切记上述操作只有以 root 身份才能完成。 接下来回到 kermit (如果之前是将它挂起了, 则使用 fg) 并退出 (q)。 在 &man.slattach.8; 联机手册中提到, 必须使用 ifconfig sl0 down 才能将接口标记为关闭, 但和这样做似乎没有什么区别。 (ifconfig sl0 仍然报告同样的东西。) 有时, 您的 modem 可能会拒绝挂断。 这种情况下, 只需重新启动 kermit 并再次退出它就可以了。 一般来说试二次就可以了。 问题解答 如果还不行, 尽管发邮件到 &a.net.name; 邮件列表来提问。 常见的问题包括: 执行 slattach 时不使用 选项 (这应该不是关键的, 但有些用户报告这样做解决了问题)。 使用替换 (在一些字体下很难看出不同)。 试试ifconfig sl0来查看您的接口状态。 例如, 您可以这样做: &prompt.root; ifconfig sl0 sl0: flags=10<POINTOPOINT> inet 136.152.64.181 --> 136.152.64.1 netmask ffffff00 如果在使用 &man.ping.8; 时得到了 no route to host 这样的提示, 则说明您的路由表可能有问题。 可以用 netstat -r 命令来显示当前的路由: &prompt.root; netstat -r Routing tables Destination Gateway Flags Refs Use IfaceMTU Rtt Netmasks: (root node) (root node) Route Tree for Protocol Family inet: (root node) => default inr-3.Example.EDU UG 8 224515 sl0 - - localhost.Exampl localhost.Example. UH 5 42127 lo0 - 0.438 inr-3.Example.ED water.CS.Example.E UH 1 0 sl0 - - water.CS.Example localhost.Example. UGH 34 47641234 lo0 - 0.438 (root node) 前述的例子来自于一个非常繁忙的系统。 您系统上的这些数字会因网络活动的不同而改变。 设置SLIP服务器 SLIPserver 本文提供了在 FreeBSD 上设置 SLIP 服务, 也就是如何配置您的系统, 使其能在远程 SLIP 客户端登录时自动地开启连接的建议。 前提条件 TCP/IP networking 这一节技术性很强, 所以要求您有一定的背景知识。 本节假定您熟悉 TCP/IP 网络协议, 特别是网络和节点寻址、 子网掩码、 子网划分、 路由、 路由协议 (如RIP) 等知识。 在拨号服务器上配置 SLIP 需要这些概念性的知识。 如果您不熟悉它们, 请先阅读 Craig Hunt 的 TCP/IP 网络管理 由O'Reilly & Associates, Inc. 出版 (ISBN 0-937175-82-X), 或 Douglas Comer 有关 TCP/IP 协议的书籍。 modem 此外还假定您已经配置好了您的调制解调器以及相应的系统文件, 以允许通过调制解调器进行登录。 如果您还没有为此配置好系统, 请参见 以了解关于如何进行拨号服务的配置。 您可能也会想看一看 &man.sio.4; 的联机手册, 以了解关于串口设备驱动的进一步信息, 以及 &man.ttys.5;、 &man.gettytab.5;、 &man.getty.8; & &man.init.8; 上关于怎样配置系统来接受来自调制解调器的登录请求的具体情况, 还有 &man.stty.1; 以了解关于设置串口参数 (例如 clocal 表示串口直联) 等。 快速浏览 使用FreeBSD作为SLIP服务器, 在典型配置时, 它是这样工作的: 一个SLIP客户拨号并以专用的login ID登录到FreeBSD SLIP服务器系统。 这个用户使用 /usr/sbin/sliplogin 作为 shell。 sliplogin 程序会在文件 /etc/sliphome/slip.hosts 中查找这个用户的项, 如果找到了匹配项, 就将串行线连接到一个可用的 SLIP 接口, 然后运行 shell 脚本 /etc/sliphome/slip.login 以配置 SLIP 接口。 一个SLIP服务器登录的例子 例如, 如果一个SLIP用户的ID是Shelmerg, 在/etc/master.passwdShelmerg的项如下的所示: Shelmerg:password:1964:89::0:0:Guy Helmer - SLIP:/usr/users/Shelmerg:/usr/sbin/sliplogin Shelmerg登录时, sliplogin在文件 /etc/sliphome/slip.hosts中搜索与用户ID匹配的行;如下所示: Shelmerg dc-slip sl-helmer 0xfffffc00 autocomp sliplogin找到这条区配行, 并将串行线与另一个可用的SLIP接口连起来, 然后执行/etc/sliphome/slip.login脚本: /etc/sliphome/slip.login 0 19200 Shelmerg dc-slip sl-helmer 0xfffffc00 autocomp 如果一切顺利 /etc/sliphome/slip.login 将在 sliplogin 绑定的 SLIP 接口上发出 ifconfig (前述的例子中是 SLIP 接口 0, 这是 slip.login 的第一个参数), 以设置本地 IP 地址 (dc-slip)、 远程 IP 地址 (sl-helmer)、 这一 SLIP 接口的子网掩码 (0xfffffc00), 以及任何其他标志 (autocomp)。 如果发生错误, sliplogin 通常会通过 syslogd 的 daemon facility 记下有用的信息, 前者会把这些信息保存到 /var/log/messages (参见 &man.syslogd.8; 和 &man.syslog.conf.5; 以及 /etc/syslog.conf 的联机手册, 以了解 syslogd 在记录什么, 以及这些内容将被记在哪里)。 内核配置 kernelconfiguration SLIP &os; 的默认内核 (GENERIC) 提供了 SLIP (&man.sl.4;) 支持; 使用定制的内核时, 您必须把下面的设置加入到配置文件: device sl 默认情况下, 您的 &os; 计算机不会转发包。 如果您希望将 FreeBSD SLIP 服务器作为路由器使用, 就需要修改 /etc/rc.conf 文件, 并加入一项将 gateway_enable 变量设为 的设制。 接下来需要重新启动以便使新设置生效。 请参见 以了解如何配置 FreeBSD 内核, 并获得在重新配置内核方面的指导。 Sliplogin配置 正如先前所提到的, /etc/sliphome目录有三个文件构成/usr/sbin/sliplogin的配置 (参考sliplogin的联机手册&man.sliplogin.8;):slip.hosts, 定义SLIP用户及有关IP地址; slip.login, 一般只配置SLIP接口; 文件 slip.logout(可选的), 串行连接终止时, 撤消slip.login所做的修改。 配置 <filename>slip.hosts</filename> /etc/sliphome/slip.hosts里的每行包含至少四个元素, 元素之间由空格隔开: SLIP用户的登录ID SLIP连接的本地地址(指SLIP服务器) SLIP连接的远程地址 网络掩网 本地和远程地址可以是主机名 (通过文件/etc/hosts或者域名服务解析为IP地址, 这取决于文件/etc/nsswitch.conf 中的设置), 网络掩网可以是一个 能通过文件/etc/networks解析的名字。 在一个样例系统中, /etc/sliphome/slip.hosts是这样的: # # login local-addr remote-addr mask opt1 opt2 # (normal,compress,noicmp) # Shelmerg dc-slip sl-helmerg 0xfffffc00 autocomp 在这行末尾是一或多个选项: —不压缩报头 — 压缩报头 —如果远程端允许, 压缩报头 —禁用ICMP数据包 (这样就会丢弃所有的ping数据包, 不占用您的带宽) SLIP TCP/IP networking 对SLIP连接的本地及远程地址的选择取决是您是准备在SLIP服务器上使用 TCP/IP 子网还是使用ARP代理 (它并不是真正的ARP代理, 而是我们在本节用于介绍的术语)。 如果您不能确定选择何种方式或者如何分配地址, 请参考"前提条件"()里列出的TCP/IP书籍 或者向您的IP网络管理员请教。 如果打算为您的 SLIP 客户使用一个独立的子网, 就需要先从分配得到的网络号中取出一个子网号, 然后再在这个子网里给每个 SLIP 客户分配 IP 地址。 接下来, 您还需要通过 SLIP 服务器在最近的 IP 路由器上配置一个指向 SLIP 子网的静态路由。 Ethernet 如果您要使用 代理 ARP的方式, 您需要从SLIP服务器的以太子网中为每个SLIP客户分配IP地址, 还必须修改/etc/sliphome/slip.login/etc/sliphome/slip.logout脚本以使用 &man.arp.8;来管理proxy-ARP在服务器ARP表中的项。 <filename>slip.login</filename> Configuration 典型的/etc/sliphome/slip.login 如下所示: #!/bin/sh - # # @(#)slip.login 5.1 (Berkeley) 7/1/90 # # generic login file for a slip line. sliplogin invokes this with # the parameters: # 1 2 3 4 5 6 7-n # slipunit ttyspeed loginname local-addr remote-addr mask opt-args # /sbin/ifconfig sl$1 inet $4 $5 netmask $6 这个slip.login脚本仅仅为带有相应本地及远程地址和掩码的SLIP接口执行 ifconfig 如果您决定使用ARP代理 方式(而非为您的SLIP客户使用独立的子网), 您的/etc/sliphome/slip.login 应该是这样: #!/bin/sh - # # @(#)slip.login 5.1 (Berkeley) 7/1/90 # # generic login file for a slip line. sliplogin invokes this with # the parameters: # 1 2 3 4 5 6 7-n # slipunit ttyspeed loginname local-addr remote-addr mask opt-args # /sbin/ifconfig sl$1 inet $4 $5 netmask $6 # Answer ARP requests for the SLIP client with our Ethernet addr /usr/sbin/arp -s $5 00:11:22:33:44:55 pub slip.login新加的行arp -s $5 00:11:22:33:44:55 pub 在 SLIP 服务器的 ARP 表中加入了一个表项。 这个ARP项使得每当这个以太网上的其它 IP 节点对 SLIP 客户端 IP 地址进行 ARP 请求时, SLIP 服务器会以自已的以太网MAC地址作为回应。 Ethernet (以太网)MAC address (MAC 地址) 当使用以上的例子时, 一定要将 以太网MAC地址(00:11:22:33:44:55)替换成您系统网卡的MAC地址, 否则ARP代理将 完全无法工作!您可以查看netstat -i输出结果以取得以太网MAC地址; 输出的第二行应该是这样: ed0 1500 <Link>0.2.c1.28.5f.4a 191923 0 129457 0 116 这行表明这个系统的以太网MAC地址是00:02:c1:28:5f:4anetstat -i输出的以太网MAC地址必须改成用冒号隔开, 并且要单个十六进数前加上。 这是&man.arp.8;要求的格式; 参考&man.arp.8; 的联机手册以获取完整的使用方法。 在编写 /etc/sliphome/slip.login/etc/sliphome/slip.logout 时, 一定要设置 可执行 (execute) 位 (换言之, chmod 755 /etc/sliphome/slip.login /etc/sliphome/slip.logout), 否则 sliplogin将无法执行它。 <filename>slip.logout</filename>配置 /etc/sliphome/slip.logout并不是必需的 (除非您使用了ARP代理), 如果您准备创建它, 这里有一个基本的 slip.logout 脚本的例子: #!/bin/sh - # # slip.logout # # logout file for a slip line. sliplogin invokes this with # the parameters: # 1 2 3 4 5 6 7-n # slipunit ttyspeed loginname local-addr remote-addr mask opt-args # /sbin/ifconfig sl$1 down 如果使用了 代理 ARP, 则可能希望 /etc/sliphome/slip.logout 在用户注销时自动为 SLIP 客户端删除 ARP 项: #!/bin/sh - # # @(#)slip.logout # # logout file for a slip line. sliplogin invokes this with # the parameters: # 1 2 3 4 5 6 7-n # slipunit ttyspeed loginname local-addr remote-addr mask opt-args # /sbin/ifconfig sl$1 down # Quit answering ARP requests for the SLIP client /usr/sbin/arp -d $5 arp -d $5 将删除由 代理 ARP slip.login 在 SLIP 客户程序登录时所生成的 ARP 项。 再次强调: 建立 /etc/sliphome/slip.logout 之后, 一定要设置可执行位 (也就是说, chmod 755 /etc/sliphome/slip.logout)。 路由考虑 SLIP routing 如果没有使用 代理 ARP 的方法来在您的 SLIP 客户机和网络的其余部分 (也可能是 Internet) 之间路由数据包, 您可能需要增加离您最近的默认路由器的静态路由, 以便通过 SLIP 服务器来在 SLIP 客户机子网上进行路由。 静态路由 static routes 向您最近的默认路由添加一个静态路由可以说是很麻烦 (或者说是不可能, 如果您没有权限这么做)。 如果在您的组织中使用多路由器网络, 有些路由器 (比如 Cisco 和 Proteon 生产的) 不但要配置指向 SLIP 子网的路由, 而且还需要配置将哪些静态路由传给其它的路由器。 所以一些专家意见和问题解答对于使基于静态路由表的路由正常工作很有必要。 运行<application>&gated;</application> &gated; &gated;现在是一个私有软件, 因而您无法得到其源代码 (在 &gated; 上提供了进一步的详情)。 这一节内容主要是为了确保与仍在使用旧版软件的用户兼容而保留。 另一种避免静态路由所造成的头疼的方法, 是在您的 FreeBSD SLIP 服务器上安装 &gated;, 并配置它使用合适的路由协议 (RIP/OSPF/BGP/EGP) 来告诉其他路由器您的 SLIP 子网的存在。 您需要编写一个 /etc/gated.conf 文件来配置 &gated;; 这里是 FreeBSD SLIP 服务器作者编写的一个例子: # # gated configuration file for dc.dsu.edu; for gated version 3.5alpha5 # Only broadcast RIP information for xxx.xxx.yy out the ed Ethernet interface # # # tracing options # traceoptions "/var/tmp/gated.output" replace size 100k files 2 general ; rip yes { interface sl noripout noripin ; interface ed ripin ripout version 1 ; traceoptions route ; } ; # # Turn on a bunch of tracing info for the interface to the kernel: kernel { traceoptions remnants request routes info interface ; } ; # # Propagate the route to xxx.xxx.yy out the Ethernet interface via RIP # export proto rip interface ed { proto direct { xxx.xxx.yy mask 255.255.252.0 metric 1; # SLIP connections } ; } ; # # Accept routes from RIP via ed Ethernet interfaces import proto rip interface ed { all ; } ; RIP 上面这个 gated.conf 示例文件, 将把关于 SLIP 子网 xxx.xxx.yy 的信息, 通过 RIP 广播到 Ethernet 上; 如果您使用了的 Ethernet 驱动不是 ed, 则需要把 ed 改为相应的网络接口。 这个例子也配置了将跟踪信息写到 /var/tmp/gated.output 以提供调试 &gated; 活动的信息; 当然, 如果 &gated; 工作正常, 就可以关闭这些跟踪信息了。 您需要把 xxx.xxx.yy 改成您自己的 SLIP 子网 (一定要同时修改 proto direct 小节)。 一旦在系统中安装并配置了 &gated;, 就可以告诉 FreeBSD 启动脚本来运行 &gated; 而不是 routed 了。 最简单的办法,是配置 routerrouter_flags 两个 /etc/rc.conf 变量。 请参见 &gated; 的联机手册, 以了解更多关于命令行参数的信息。 diff --git a/zh_CN.GB2312/books/handbook/security/chapter.sgml b/zh_CN.GB2312/books/handbook/security/chapter.sgml index d52063a444..2d294a0040 100644 --- a/zh_CN.GB2312/books/handbook/security/chapter.sgml +++ b/zh_CN.GB2312/books/handbook/security/chapter.sgml @@ -1,4440 +1,4423 @@ Matthew Dillon 这一章的许多内容来自 security(7) 联机手册,其作者是 安全 security 概述 这一章将对系统安全的基本概念进行介绍, 除此之外, 还将介绍一些好的习惯, 以及 &os; 下的一些更深入的话题。 这章的许多内容对于一般的系统和 Internet 安全也适用。 如今, Internet 已经不再像以前那样是一个人人都愿意与您作好邻居的 友善 的地方。 让系统更加安全, 将保护您的数据、 智力财产、 时间, 以及其他很多东西不至于被入侵者或心存恶意的人所窃取。 &os; 提供了一系列工具和机制来保证您的系统和网络的完整及安全。 读完这章,您将了解: 基本的 &os; 系统安全概念。 &os; 中众多可用的密码学设施,例如 DESMD5 如何设置一次性口令验证机制。 如何配置 TCP Wrappers 以便与 - inetd 配合使用。 + inetd 配合使用。 如何在 &os; 5.0 以前的版本上设置 KerberosIV 如何在 &os; 上设置 Kerberos5 如何配置 IPsec 并在 &os;/&windows; 机器之间建构 VPN 如何配置并使用 OpenSSH,以及 &os; 的 SSH 执行方式。 系统 ACL 的概念,以及如何使用它们。 如何使用 Portaudit 工具来审核从 Ports Collection 安装的第三方软件包的安全性。 如何从 &os; 的安全公告中获得有用信息并采取相应措施。 对于进程记帐功能的感性认识, 并了解如何在 &os; 中启用它。 在开始阅读这章之前,您需要: 理解基本的 &os; 和 Internet 概念。 其他安全方面的话题, 则贯穿本书的始终。 例如, 强制性访问控制 (MAC) 在 中进行了介绍, 而 Internet 防火墙则在 中进行了讨论。 介绍 安全是系统管理员自始至终的基本要求。 由于所有的 BSD &unix; 多用户系统都提供了与生俱来的安全性, 因此建立和维护额外的安全机制, 确保用户的 诚实 可能也就是最需要系统管理员考虑的艰巨的工作了。 机器的安全性取决于您设置的安全设施, 而许多安全方面的考虑, 则会与人们使用计算机时的便利性相矛盾。 一般来说, &unix; 系统能够胜任数目众多进程并发地处理各类任务, 这其中的许多进程是以服务身份运行的 — 这意味着, 外部实体能够与它们互联并产生会话交互。 如今的桌面系统, 已经能够达到许多昔日的小型机甚至主机的性能, 而随着这些计算机的联网和在更大范围内完成互联, 安全也成为了一个日益严峻的课题。 系统的安全也应能够应付各种形式的攻击, 这也包括那些使系统崩溃, 或阻止其正常运转, 但并不试图窃取 root 帐号 (破译 root) 的攻击形式。 安全问题大体可分为以下几类: 拒绝服务攻击。 窃取其他用户的帐户。 通过可访问服务窃取root帐户。 通过用户帐户窃取root帐户。 建立后门。 DoS 攻击 拒绝服务攻击 (DoS) 安全 DoS 攻击 拒绝服务攻击 (DoS) 拒绝服务攻击 (DoS) 拒绝式服务攻击是侵占机器所需资源的一种行为。 通常, DoS 攻击采用暴力(brute-force)手段通过压倒性的流量来破坏服务器和网络栈, 以使机器崩溃或无法使用。 某些 DoS 攻击则利用在网络栈中的错误, 仅用一个简单的信息包就可以让机器崩溃, 这类情况通常只能通过给内核打补丁来修复。 在一些不利的条件下, 对服务器的攻击能够被修复, 只要适当地修改一下系统的选项来限制系统对服务器的负荷。 顽强的网络攻击是很难对付的。 例如,一个欺骗性信息包的攻击, 无法阻止入侵者切断您的系统与Internet的连接。 它不会使您的机器死掉,但它会把Internet连接占满。 security 窃取用户帐户 窃取用户帐户要比D.o.S.攻击更加普遍。 许多系统管理员仍然在他们的服务器上运行着基本的 telnetdrlogindrshdftpd 服务。 这些服务在默认情况下不会以加密连接来操作。 结果是如果您的系统有中等规模大小的用户群, 在通过远程登录的方式登录到您系统的用户中, 一些人的口令会被人窃取。 仔细的系统管理员会从那些成功登录系统的远程访问日志中寻找可疑的源地址。 通常必须假定,如果一个入侵者已经访问到了一个用户的帐户, 那么它就可能使自己成为 root。 然而, 事实是在一个安全和维护做得很好的系统中, 访问用户的帐户不一定会让入侵者成为 root。 这个差别是很重要的,因为没有成为 root 则入侵者通常是无法隐藏它的轨迹的, 而且, 如果走运的话, 除了让用户的文件乱掉和系统崩溃之外, 它不能做什么别的事情。 窃取用户帐户是很普遍的事情, 因为用户往往不会对系统管理员的警告采取措施。 security 后门 系统管理员必须牢牢记住,可能有许多潜在的方法会使他们机器上的 root 用户受到威胁。入侵者可能知道 root 的口令,而如果在以 root 权限运行的服务器上找到一个缺陷 (bug), 就可以通过网络连接到那台服务器上达到目的;另外, 一旦入侵者已经侵入了一个用户的帐户, 可以在自己的机器上运行一个 suid-root 程序来发现服务器的漏洞, 从而让他侵入到服务器并获取 root。 攻击者找到了入侵一台机器上 root 的途径之后, 他们就不再需要安装后门了。许多 root 漏洞被发现并修正之后, 入侵者会想尽办法去删除日志来消除自己的访问痕迹, 所以他们会安装后门。 后门能给入侵者提供一个简单的方法来重新获取访问系统的 root 权限, 但它也会给聪明的系统管理员一个检测入侵的简便方法。 让入侵者无法安装后门事实上对您的系统安全是有害的, 因为这样并不会修复那些侵入系统的入侵者所发现的新漏洞。 安全的管理方法应当使用像 洋葱皮 一样多层次的方法来实现, 这些措施可以按下面的方式进行分类: 确保 root 和维护人员帐户的安全。 确保 root – 以root用户权限运行的服务器和suid/sgid可执行程序的安全。 确保用户帐户的安全。 确保口令文件的安全。 确保内核中核心组件、直接访问设备和文件系统的安全。 快速检测系统中发生的不适当的变化。 做个偏执狂。 这一章的下一节将比较深入地讲述上面提到的每一个条目。 确保 &os; 的安全 security 确保 &os; 的安全 命令与协议 在这份文档中,我们使用 粗体 来表示应用程序, 并使用 单倍距 字体来表示命令。 这样的排版区分能够有效地区分类似 ssh 这样的概念, 因为它既可以表示命令,又可以表示协议。 接下来的几节中, 将介绍在这一章中 前一节 中所介绍的那些加强 &os; 系统安全性的手段。 确保 <username>root</username> 和维护人员帐户的安全 su 首先,如果您没有确保 root 帐户的安全, 就没必要先劳神确保用户帐户的安全了。绝大多数系统都会指派一个口令给 root 帐户。 我们的第一个假定是,口令 总是 不安全的。 这并不意味着您要把口令删掉。 口令通常对访问机器的控制台来说是必须的。 也就是说, 您应该避免允许在控制台以外的地方使用口令, 甚至包括使用 &man.su.1; 命令的情形。 例如,确信您的 pty 终端在 /etc/ttys 文件中被指定为 insecure (不安全),这将使直接通过 telnetrlogin 登录 root 会不被接受。 如果使用如 sshd 这样的其他登录服务, 也要确认直接登录 root 是关闭的。您可以通过编辑 /etc/ssh/sshd_config 文件来做到这一点,确信 PermitRootLogin 被设置成 NO。 考虑到每一种访问方法 — 如FTP这样的服务, 以免因为它们而导致安全性的损失。 直接登录 root 只有通过系统控制台才被允许。 wheel 当然, 作为一个系统管理员, 您应当获得 root身份, 因此, 我们开了一些后门来允许自己进入。 但这些后门只有在经过了额外的口令确认之后才能使用。 一种让 root 可访问的方法是增加适当的用户帐户到 wheel 组 (在 /etc/group 中)。wheel 组中的用户成员可以使用 su 命令来成为 root。 绝对不应该通过在口令项中进行设置来赋予维护人员天然的 wheel 组成员身份。 维护人员应被放置在 staff 组中,然后通过 /etc/group 文件加入到 wheel 组。事实上,只有那些需要以 root 身份进行操作的用户才需要放进 wheel 组中。 当然,也可以通过 某种其它的验证手段,例如 Kerberos,可以通过 root 帐户中的 .k5login 文件来允许执行 &man.ksu.1; 成为 root ,而不必把它们放进 wheel 组。 这可能是一种更好的解决方案, 因为 wheel 机制仍然可能导致入侵者获得 root ,如果他拿到了口令文件,并能够进入职员的帐户。 尽管有 wheel 比什么都没有要强一些, 但它并不是一种绝对安全的办法。 - + 可以使用 &man.pw.8; 命令来完全禁止某一个帐号: - 一种间接地提高员工帐号, 乃至 root - 权限安全性的方法, 便是采用其他的登录访问方式, - 并使用 星号 - 替代员工加密的口令。使用 &man.vipw.8; 命令, - 可以把每一个加密的口令替换成一个 * 符。 - 这将更新 /etc/master.passwd 文件,以及 - 用户名/口令数据库,以禁用口令登录。 + &prompt.root;pw lock staff - 如下面的员工帐号 + 这将阻止用户使用任何方法登录,包括 &man.ssh.1;。 + + 另一个阻止某个帐户访问的方法是使用一个 + * 字符替换掉加密后的口令。 + 这将不会与任何加密后的口令匹配,从而阻止了用户的访问。 + 举例说明: foobar:R9DT/Fa1/LV9U:1000:1000::0:0:Foo Bar:/home/foobar:/usr/local/bin/tcsh 应被改为: foobar:*:1000:1000::0:0:Foo Bar:/home/foobar:/usr/local/bin/tcsh - 这一更改将阻止一般的登录,因为加密的口令永远不会与 - * 匹配。一旦这么做之后, - 任何员工都必须使用其他的方式来完成登录,例如,使用 - &man.kerberos.1; 或者通过 &man.ssh.1; 利用 公钥/密钥对 - 的方式来完成登录。当使用 Kerberos 这样的工具时,通常必须加强运行 - Kerberos 的服务器,以及桌面工作站的安全性。当使用 公钥/密钥对以 - ssh 登录时,通常必须加固用户 开始 - 登录的那台机器的安全 (通常这是他们的工作站)。 - 在这之上还可以增加一层安全性,即在使用 &man.ssh-keygen.1; - 生成它的时候,使用口令来保护它们。 如果能够用 - 星号 替换掉所有员工的口令, - 那么,这也就保证了他们只能通过您设置的安全的方法来登录。 - 这将迫使所有的员工使用安全的、经过加密的连接来完成他们的会话, - 而这将使得入侵者通过监听网络通讯, 从某些不相关的、 - 不太安全的机器上窃取口令成为不可能。 - - 另一种间接的安全机制则是, + 这会阻止用户 foobar 使用传统的方式登录。 + 但是对于使用了 Kerberos + 或者配置了 &man.ssh.1; 公钥/密钥对的情况下,用户依然可以访问。 + + 这些安全机制同样假定, 从严格受限的机器向限制更宽松的机器上登录。 例如, 如果您的服务器运行了所有的服务,那么,工作站应该什么都不运行。 为了让工作站尽可能地安全,应该避免运行任何没有必要的服务, 甚至不运行任何服务。 另外, 也应该考虑使用带口令保护功能的屏幕保护程序。 毋庸置疑, 如果攻击者能够物理地接触您的工作站, 那么他就有能力破坏任何安全设施,这确实是我们需要考虑的一个问题,但同样地, 真正能够物理接触您的工作站或服务器并实施攻击的人在现实生活中并不常见, 绝大多数攻击来自于网络, 而攻击者往往无法物理地接触服务器或工作站。 KerberosIV 使用类似 Kerberos 这样的工具,也为我们提供了使用一个工具来禁用某个用户, 或修改他们的口令, 并在所有机器上立即生效的方法。 如果员工的帐号被窃取, 能够在所有的其他机器上生效的口令变更将很有意义。如果口令分散地保存在多个机器上, 一次修改 N 台机器上的口令很可能是一件痛苦的事情。 此外, Kerberos 还能够提供更多的限制,除了 Kerberos 令牌有很好的过期机制之外, 它还能够强制用户在某个特定的期限内修改口令(比如说,每月一次). 确保以root用户权限运行的服务器和suid/sgid可执行程序的安全 ntalk comsat finger sandboxes sshd telnetd rshd rlogind 谨慎的管理员只运行他们需要的服务, 不多, 不少。 要当心第三方的服务程序很可能有更多的问题。 例如, 运行旧版的 imapdpopper 无异于将 root 令牌拱手送给全世界的攻击者。 永远不要运行那些您没有仔细检查过的服务程序, 另外也要知道, 许多服务程序并不需要以 root 的身份运行。 例如, ntalkcomsat, 以及 finger 这些服务, 都能够以一种被称作 沙盒 的特殊用户的身份运行。 除非您已经解决掉了许多麻烦的问题, 否则沙盒就不是完美的, 但洋葱式安全规则仍然成立: 如果有人设法攻破了在沙盒中运行的程序, 那么在做更多坏事之前, 他们还必须想办法攻破沙盒本身的限制。 攻击者需要攻破的层次越多, 他们成功的可能性就越小。 过去, 破解 root 的漏洞几乎在所有以 root 身份运行的服务上都发现过, 包括那些基本的系统服务。 如果您的机器只打算向外界提供 sshd 登录, 而用户不会使用 telnetdrshd 甚至 rlogind 登录, 就应该毫不犹豫地关闭它们! &os; 现在默认在沙盒中运行 ntalkd, comsat, 以及 finger。此外, &man.named.8; 也可以这样运行。 /etc/defaults/rc.conf 中包括了如何如此运行 named 的方法,只是这些内容被注释掉了。 如何升级或安装系统将决定这些沙盒所使用的特殊用户是否被自动安装。 谨慎的系统管理员将根据需要研究并实现沙盒。 sendmail 此外,还有一些服务通常并不在沙盒中运行: sendmail, popper, imapd, ftpd, 以及一些其他的服务。当然,它们有一些替代品,但安装那些服务可能需要做更多额外的工作。 可能必须以 root 身份运行这些程序, 并通过其他机制来检测入侵。 系统中另一个比较大的 root 漏洞 是安装在其中的 suid-root 和 sgid 的可执行文件。绝大多数这类程序, 例如 rlogin, 被存放于 /bin, /sbin, /usr/bin, 或 /usr/sbin 中。 尽管并没有 100% 的安全保证,但系统默认的 suid 和 sgid 可执行文件通常是相对安全的。 当然,偶尔也会发现一些存在于这些可执行文件中的 root 漏洞。1998年,Xlib 中发现了一处 root 漏洞,这使得 xterm (通常是做了suid的) 变得可以入侵。 做得安全些, 总比出现问题再后悔要强。 因此,谨慎的管理员通常会限制 suid 可执行文件, 并保证只有员工帐号能够执行它们,或只开放给特定的用户组,甚至彻底干掉 (chmod 000) 任何 suid 可执行文件, 以至于没有人能够执行它们。没有显示设备的服务器通常不会需要 xterm 可执行文件。 sgid 可执行文件通常同样地危险。 一旦入侵者攻克了sgid-kmem,那么他就能够读取 /dev/kmem 并进而读取经过加密的口令文件, 从而窃取任何包含口令的帐号。另外,攻破了 kmem 的入侵者能够监视通过 pty 传送的按键序列,即使用户使用的是安全的登录方式。 攻破了 tty 组的用户则能够向几乎所有用户的 tty 写入数据。如果用户正在运行一个终端程序,或包含了键盘模拟功能的终端仿真程序, 那么,入侵者能够以那个用户的身份执行任何命令。 确保用户帐户的安全 用户帐号的安全通常是最难保证的。虽然您可以为您的员工设置严苛的登录限制, 并用 星号 替换掉他们的口令, 但您可能无法对普通的用户这么做。 如果有足够的决策权, 那么在保证用户帐号安全的斗争中或许会处于优势, 但如果不是这样, 您能做的只是警惕地监控这些帐号的异动。 让用户使用 ssh 或 Kerberos 可能会有更多的问题, 因为需要更多的管理和技术支持, 尽管如此, 与使用加密的口令文件相比, 这仍不失为一个好办法。 确保口令文件的安全 能够确保起作用的唯一一种方法, 是将口令文件中尽可能多的口令用星号代替, 并通过 ssh 或 Kerberos 来使用这些账号。 即使只有 root 用户能够读取加密过的口令文件 (/etc/spwd.db), 入侵者仍然可能设法读到它的内容, 即使他暂时还无法写入这个文件。 您的安全脚本应该经常检查并报告口令文件的异动 (参见后面的 检查文件完整性 一节)。 确保内核中内核设备、直接访问设备和文件系统的安全 如果攻击者已经拿到了 root 那么他就有能力作任何事情, 当然, 有一些事情是他们比较喜欢干的。 例如, 绝大多数现代的内核都包括一个内建的听包设备。 在 &os; 中,这个设备被称作 bpf 。攻击者通常会尝试在攻克的系统上运行它。 如果您不需要 bpf 设备提供的功能,那么,就不要把它编入内核。 sysctl 但即使已经关掉了 bpf 设备,您仍然需要担心 /dev/mem/dev/kmem 。 就事论事地说,攻击者仍然能够通过直接访问的方式写入磁盘设备。同样地, 还有一个被称作模块加载器, &man.kldload.8; 的机制,也会包含潜在的危险。 尝试入侵企业网络的入侵者会尝试在正在运行的内核上安装他自己的 bpf 设备,或其他听包设备。为了防止这些问题, 需要抬高内核安全级, 至少调整到 1。 可以通过对 kern.securelevel 执行 sysctl 来完成这个任务。 一旦把安全级调整到1, 对于直接访问设备的写入操作将被拒绝, 而特殊的 chflags 标记, 如 schg, 也将强制执行。 一定要在重要的启动执行文件、 目录和脚本文件上设置 schg 标记 — 不要漏过在安全级生效之前将被运行的任何文件。 这可能做得有些过火, 并将导致在较高安全级上运行时升级系统变得困难。 您也可以略微做些妥协, 即以较高的安全级运行, 但并不将系统文件和目录配置为 schg。 另一种可行的方法是把 //usr 以只读方式挂接。 请注意, 如果保护措施做的过分的严苛, 则可能导致入侵检测无法进行, 而这种检测是安全中十分重要的一环。 检查文件完整性: 可执行文件,配置文件和其他文件 当实施严格的限制时,往往会在使用的方便性上付出代价。例如,使用 chflags 来把 schg 标记 应用到 //usr 中的绝大多数文件上可能会起到反作用, 因为尽管它能够保护那些文件, 但同时也使入侵检测无法进行。 层次化安全的最后一层可能也是最重要的 — 检测。 如果无法检测出潜在的入侵行为, 那么安全的其他部分可能相对来讲意义可能就不那么大了 (或者,更糟糕的事情是, 那些措施会给您安全的假象)。 层次化安全最重要的功能是减缓入侵者, 而不是彻底不让他们入侵, 这样才可能当场抓住入侵者。 检测入侵的一种好办法是查找那些被修改、 删除或添加的文件。 检测文件修改的最佳方法是与某个 (通常是中央的) 受限访问的系统上的文件进行比对。 在一台严格限制访问的系统上撰写您的安全脚本通常不能够被入侵者察觉, 因此,这非常重要。为了最大限度地发挥这一策略的优势,通常会使用只读的 NFS, 或者设置 ssh 钥匙对以便为其他机器提供访问。除了网络交互之外, NFS可能是一种很难被察觉的方法 — 它允许您监控每一台客户机上的文件系统, 而这种监控几乎是无法察觉的。如果一台严格受限的服务器和客户机是通过交换机连接的, 那么 NFS 将是一种非常好的方式。 不过,如果那台监控服务器和客户机之间通过集线器 (Hub),或经过许多层的路由来连接,则这种方式就很不安全了, 此时,应考虑使用 ssh ,即使这可以在审计记录中查到。 一旦为这个受限的机器赋予了至少读取它应监控的客户系统的权限, 就应该为实际的监控撰写脚本。以 NFS 挂接为例,可以用类似 &man.find.1; 和 &man.md5.1; 这样的命令为基础来完成我们所需的工作。 最好能够每天对被控机的所有执行文件计算一遍 md5,同时,还应以更高的频率测试那些 /etc/usr/local/etc 中的控制文件。一旦发现了不匹配的情形,监控机应立即通知系统管理员。 好的安全脚本也应该检查在系统分区,如 //usr 中是否有新增或删除的可执行文件,以及不适宜的 suid 。 如果打算使用 ssh 来代替 NFS,那么撰写安全脚本将变得困难许多。 本质上,需要在脚本中使用 scp 在客户端复制文件, 另一方面,用于检查的执行文件 (例如 find) 也需要使用 scp 传到客户端,因为 ssh 客户程序很可能已经被攻陷。 总之,在一条不够安全的链路上 ssh 可能是必须的, 但也必须应付它所带来的难题。 安全脚本还应该检查用户以及职员成员的权限设置文件: .rhosts.shosts.ssh/authorized_keys 等等。 这些文件可能并非通过 MD5 来进行检查。 如果您的用户磁盘空间很大, 检查这种分区上面的文件可能非常耗时。 这种情况下, 采用标志来禁止使用 suid 可执行文件将是一个好主意。 您可能会想看看 nosuid 选项 (参见 &man.mount.8;)。 尽管如此, 这些扫描仍然应该至少每周进行一次, 这样做的意义并不是检测有效的攻击, 而是检查攻击企图。 进程记帐 (参见 &man.accton.8;) 是一种相对成本较低的, 可以帮助您在被入侵后评估损失的机制。 对于找出入侵者是如何进入系统的这件事情来说, 它会非常的有所助益,特别是当入侵者什么文件都没有修改的情况下。 最后, 安全脚本应该处理日志文件, 而日志文件本身应该通过尽可能安全的方法生成 — 远程 syslog 可能非常有用。 入侵者会试图掩盖他们的踪迹, 而日志文件对于希望了解入侵发生时间的系统管理员来说则显得尤为重要。 保持日志文件的永久性记录的一种方法是在串口上运行系统控制台, 并在一台安全的机器上收集这些信息。 偏执 带点偏执不会带来伤害。作为一种惯例, 系统管理员在不影响使用的便利的前提下可以启用任何安全特性,此外, 在经过深思熟虑之后,也可以增加一些 确实会 让使用变得不那么方便的安全特性。 更重要的是,有安全意识的管理员应该学会混合不同的安全策略 — 如果您逐字逐句地按照这份文档来配置您的机器, 那无异于向那些同样能得到这份文档的攻击者透露了更多的信息。 拒绝服务攻击 拒绝服务 (DoS) 这一节将介绍拒绝服务攻击。 DoS 攻击通常是基于数据包的攻击, 尽管几乎没有任何办法来阻止大量的伪造数据包耗尽网络资源, 但通常可以通过一些手段来限制这类攻击的损害,使它们无法击垮服务器: 限制服务进程 fork。 限制 springboard 攻击 (ICMP 响应攻击, ping 广播,等等)。 使内核路由缓存过载。 一种比较常见的 DoS 攻击情形, 是通过攻击复制进程 (fork) 的服务, 使其产生大量子进程, 从而是其运行的机器耗尽内存、 文件描述符等资源, 直到服务器彻底死掉。 inetd (参见 &man.inetd.8;) 提供了许多选项来限制这类攻击。 需要注意的是, 尽管能够阻止一台机器彻底垮掉, 但通常无法防止服务本身被击垮。 请仔细阅读 inetd 的联机手册, 特别是它的 以及 这三个选项。 伪造 IP 攻击能够绕过 inetd 选项, 因此, 这些选项需要配合使用。 某些独立的服务器也有类似的限制参数。 例如, Sendmail 就提供了自己的 选项, 它通常比 Sendmail 的负载限制选项更为有效, 因为服务器负载的计算有滞后性。 您可以在启动 sendmail 时指定一个 MaxDaemonChildren 参数; 把它设的足够高以便承载您所需要的负荷, 当然, 不要高到足以让运行 Sendmail 的机器死掉。 此外, 以队列模式 () 运行 Sendmail 并把服务程序 (sendmail -bd) 和队列执行程序分别执行 (sendmail -q15m) 也是一个好主意。 如果您希望保证队列的实时性, 可以考虑使用更短的间隔, 例如 , 但同时也需要指定一个合理的子进程数, 也就是通过 MaxDaemonChildren 选项以免 那个 Sendmail 造成重叠的故障。 Syslogd 可以被直接地攻击,因此, 强烈建议只要可行,就在启动它的时候加上 参数, 其他情况下,则至少应该加上 对于基于连接的服务,例如 TCP Wrapper 的 reverse-identd, 都应该格外的小心, 因为它们都可能直接遭受攻击。 一般情况下, 基于安全考虑, 不应使用 TCP Wrapper 所提供的 reverse-ident 这样的功能。 此外, 将内部服务保护起来, 阻止来自其他主机的访问也十分重要, 这些工作可以通过设置边界路由器来完成。 主要的想法, 是阻止来自您的 LAN 以外的访问, 这有助于避免 root 受到攻击。 尽可能配置排他式的防火墙, 例如, 用防火墙阻止所有的网络流量 除了 端口 A、B、 C、D,以及 M-Z。 通过采用这种方法, 您可以很容易地将低端口的访问阻止在外, 而又不难配置使防火墙放过那些明确需要开放的服务, 例如 named (如果您的机器准备作为域的主要解析服务器), ntalkdsendmail,以及其他可以从 Internet 访问的服务。 如果您尝试以其他方式配置防火墙 — 采用比较宽松的策略, 那么您将很有可能忘记 关掉 一两个服务, 或者在增加了一些服务之后忘记更新防火墙策略。 尽管如此, 仍然可以考虑允许让数据进入编号较高的那一部分端口, 这将保证那些需要这样特性的服务能够正常工作, 而又不影响低端口服务的安全性。 此外, 还应注意到 &os; 允许您来控制动态绑定的端口的范围, 即一系列 net.inet.ip.portrange 变量,通过 sysctl 来完成设置。 (sysctl -a | fgrep portrange)。 这使得您完成较复杂的防火墙策略变得易如反掌。 例如, 您可能希望普通的高段端口的起止范围是 4000 到 5000, 而更高范围则是 49152 到 65535, 随后在防火墙中阻止低于 4000 的所有端口 (当然, 除了那些特地为 Internet 访问而开设的端口)。 另一种常被称作 springboard 的攻击也是非常常见的 DoS 攻击 — 它通过使服务器产生其无法处理的响应来达到目的。 最常见的攻击就是 ICMP ping 广播攻击。 攻击者通过伪造 ping 包, 将其源 IP 设置为希望攻击的机器的 IP。 如果您的边界路由器没有进行禁止 ping 广播地址的设置, 则您的网络将最终陷于响应伪造的 ping 包之中, 特别是当攻击者同时使用了多个不同的网络时。 广播攻击能够产生超过 120 兆位的瞬时流量。 另一种常见的针对 ICMP 错误报告系统的 springboard 攻击, 通过建立可以生成 ICMP 出错响应的包, 攻击者能够攻击服务器的网络下行资源, 并导致其上行资源耗尽。 这种类型的攻击也可以通过耗尽内存来使得使得被攻击的服务器崩溃, 特别是当这些服务器无法足够快地完成 ICMP 响应的时候。 较新的内核可以通过调整 sysctl 变量 net.inet.icmp.icmplim 来限制这种攻击。 最后一类主要的 springboard 是针对某些 inetd 的内部服务, 例如 udp echo 服务进行的。 攻击者简单地伪造一个来自服务器 A 的 echo 口的 UDP 包, 然后将这个包发到 B 的 echo 口。 于是, 两台服务器将不停地将包弹给对方。 攻击者能够将两台服务器的这种服务都耗竭, 并且通过这种方式, 只需要很少的包就可以让 LAN 超载。 类似的问题对 chargen 口也是存在的。 好的系统管理员应该关闭这些 inetd 的测试服务。 伪造的包攻击也可以用来使内核的路由缓存过载。 请参考 net.inet.ip.rtexpirertminexpire, 以及 rtmaxcache sysctl 参数。 伪造的包可以用随机的源 IP 攻击, 使得内核在路由表中产生一个临时的缓存项, 它可以通过 netstat -rna | fgrep W3 看到。 这些路由通常需要 1600 秒才会过期。 如果内核发现路由表变得太大, 它会动态地降低 rtexpire 但以 rtminexpire 为限。 这引发了两个问题: 在访问量不大的服务器上, 内核对于突然袭击的反应不够快。 rtminexpire 的值没有低到让内核在此类攻击时活下去的程度。 如果您的服务器通过 T3 或更快的线路接入 Internet, 那么通过 &man.sysctl.8; 来手动地降低 rtexpirertminexpire 就非常必要。 当然,绝不要把它们设置为零 (除非您想让机器崩溃) 将这两个参数设置为 2 通常已经足以抵御这类攻击了。 Kerberos 和 SSH 的访问问题 ssh KerberosIV 如果您打算使用, 那么 Kerberos 和 ssh 都有一些需要解决的问题。 Kerberos 5 是一个很棒的验证协议, 但使用了它的 telnetrlogin 应用程序有一些 bug, 使得它们不适合处理二进制流。 而且, 除非使用了 选项, 否则默认情况下 Kerberos 并不加密会话。 ssh 在默认时加密所有的会话内容。 除了默认转发加密密钥之外, ssh 在所有的其他方面都做得很好。 这意味着如果您持有供您访问系统其他部分密钥的工作站作了很好的安全防护, 而您连到了一台不安全的机器上, 则您的密钥可能被别人获得。 尽管实际的密钥并没有被泄漏, 但由于 ssh 会在您登录的过程中启用一个转发端口, 如果攻击者拿到那台不安全的机器上的 root 那么他将能够利用那个端口来使用您的密钥, 从而访问您能够访问的那些机器。 我们建议您在使用 ssh 时配合 Kerberos 来完成工作人员的登录过程。 Ssh 在编译时可以加入 Kerberos 支持。 在减少了潜在地暴露 ssh 密钥的机会的同时, 它还能够通过 Kerberos 来保护口令。 Ssh 密钥只有在做过安全防护的机器上执行自动操作时才应使用 (这是 Kerberos 不适合的情形)。 此外,我们还建议您要么在 ssh 配置中关闭密钥转发, 要么在 authorized_keys 中增加 from=IP/DOMAIN 选项, 来限制这些密钥能够登录的来源机器。 Bill Swingle 部分重写、更新来自 DES、 Blowfish、 MD5, 以及 Crypt 安全 密码 crypt Blowfish DES MD5 &unix; 系统上的每个用户都有一个与其帐户关联的口令。 很显然, 密码只需要被这个用户和操作系统知道。 为了保证口令的私密性, 采用了一种称为 单向散列 的方法来处理口令, 简单地说, 很容易从口令推算出散列值, 反之却很难。 其实, 刚才那句话可能并不十分确切: 因为操作系统本身并不 真的 知道您的口令。 它只知道口令 经过加密的形式。 获取口令对应 明文 的唯一办法是采用暴力在口令可能的区间内穷举。 不幸的是,当 &unix; 刚刚出现时,安全地加密口令的唯一方法基于DES, 数据加密标准 ( the Data Encryption Standard )。 于是这给那些非美国居民带来了问题, 因为 DES 的源代码在当时不能被出口到美国以外的地方, &os; 必须找到符合美国法律,但又要与其他那些使用 DES 的 &unix; 版本兼容的办法。 解决方案是把加密函数库分割为两个, 于是美国的用户可以安装并使用 DES 函数库, 而国际用户则使用另外一套库提供的一种可以出口的加密算法。 这就是 &os; 为什么使用 MD5 作为它的默认加密算法的原因。 MD5 据信要比 DES 更安全,因此,安装 DES 更多地是出于兼容目的。 识别您采用的加密算法 现在这个库支持 DES、 MD5 和 Blowfish 散列函数。默认情况下, &os; 使用 MD5 来加密口令。 可以很容易地识别 &os; 使用哪种加密方法。 检查 /etc/master.passwd 文件中的加密密码是一种方法。 用 MD5 散列加密的密码通常要比用 DES 散列得到的长一些, 并且以 $1$ 字符开始。 以 $2a$ 开始的口令是通过 Blowfish 散列函数加密的。 DES 密码字符没有任何可以用于鉴别的特征, 但他们要比 MD5 短, 并且以不包括 $ 在内的 64 个可显示字符来表示, 因此相对比较短的、没有以美元符号开头的字符串很可能是一个 DES 口令。 新口令所使用的密码格式是由 /etc/login.conf 中的 passwd_format 来控制的, 可供选择的算法包括 des, md5blf。 请参考 &man.login.conf.5; 联机帮助以获得更进一步的详情。 一次性口令 一次性口令 安全 一次性口令 默认情况下, &os; 提供了 OPIE (One-time Passwords In Everything) 支持, 它默认使用 MD5 散列。 下面将介绍三种不同的口令。 第一种是您常用的 &unix; 风格或 Kerberos 口令; 我们在后面的章节中将称其为 &unix; 口令。 第二种是使用 OPIE 的 &man.opiekey.1; 程序生成, 并为 &man.opiepasswd.1; 以及登录提示所接受的一次性口令,我们称其为 一次性口令。 最后一类口令是您输入给 opiekey 程序 (有些时候是 opiepasswd 程序) 用以产生一次性口令的秘密口令,我们称其为 秘密口令 或通俗地简称为 口令 秘密口令和您的 &unix; 口令毫无关系, 尽管可以设置为相同的, 但不推荐这么做。 OPIE 秘密口令并不像旧式的 &unix; 口令那样只能限于8位以内在 &os; 中标准的登录口令最长不能超过 128 个字符。。 您想要用多长的口令都可以。 有六、七个词的短句是很常见的选择。 在绝大多数时候, OPIE 系统和 &unix; 口令系统完全相互独立地工作。 除了口令之外, 对于 OPIE 还有两组至关重要的数据。 其一被称作 种子key, 它包括两个字符和五个数字。 另一个被称作 迭代轮数, 这是一个 1 到 100 之间的数字。 OPIE 通过将种子加到秘密口令后面, 并执行迭代轮数那么多次的 MD4/MD5 散列运算来得到结果, 并将结果表示为 6 个短的英文单词。 这 6 个英文单词就是您的一次性口令。 验证系统 (主要是 PAM) 会记录上次使用的一次性口令, 如果用户提供的口令的散列值与上次一致, 则可以通过身份验证。 由于使用了单向的散列函数, 因此即使截获了上次使用的口令, 也没有办法恢复出下次将要使用的口令; 每次成功登录都将导致迭代轮数递减, 这样用户和登录程序将保持同步。 每当迭代轮数减少到 1 时, 都必须重新初始化 OPIE。 接下来将讨论和每个系统有关的三个程序。 opiekey 程序能够接收带迭代计数, 种子和秘密口令, 并生成一个一次性口令, 或一张包含连续的一组一次性口令的表格。 opiepasswd 程序用于初始化 OPIE, 并修改口令、 迭代次数、种子和一次性口令。 和 opieinfo 程序可以用于检查相应的验证数据文件 (/etc/opiekeys) 并显示执行命令的用户当前的迭代轮数和种子。 我们将介绍四种不同的操作。 在安全的连接上通过 opiepasswd 来第一次设置一次性口令, 或修改口令及种子。 第二类操作是在不安全的连接上使用 opiepasswd 辅以在安全连接上执行的 opiekey 来完成同样的工作。 第三类操作是在不安全的连接上使用 opiekey 来登录。 最后一类操作是采用 opiekey 来生成大批的密码, 以便抄下来或打印出来,在没有安全连接的地方使用。 安全连接的初始化 第一次初始化 OPIE 时, 可以使用 opiepasswd 命令: &prompt.user; opiepasswd -c [grimreaper] ~ $ opiepasswd -f -c Adding unfurl: Only use this method from the console; NEVER from remote. If you are using telnet, xterm, or a dial-in, type ^C now or exit with no password. Then run opiepasswd without the -c parameter. Using MD5 to compute responses. Enter new secret pass phrase: Again new secret pass phrase: ID unfurl OTP key is 499 to4268 MOS MALL GOAT ARM AVID COED Enter new secret pass phrase:Enter secret password: 提示之后, 应输入一个密码或口令字。 请留意, 这并不是您用于登录的口令, 它用于生成一次性的登录密钥。 ID 这一行给出了所需的参数: 您的登录名, 迭代轮数, 以及种子。 登录系统时, 它能够记住这些参数并呈现给您, 因此无需记忆它们。 最后一行给出了与您的秘密口令对应的、用于登录的一个一次性口令; 如果您立即重新登录, 则它将是您需要使用的那个口令。 不安全连接初始化 如果您需要通过一个不安全的连接来初始化, 则应首先在安全连接上执行过一次 opiekey; 您可能希望在可信的机器的 shell 提示符下完成。 此外还需要指定一个迭代轮数 (100 也许是一个较好的选择) 也可以选择一个自己的种子, 或让计算机随机生成一个。 在不安全的连接上 (当然是连到您希望初始化的机器上),使用 opiepasswd 命令: &prompt.user; opiepasswd Updating unfurl: You need the response from an OTP generator. Old secret pass phrase: otp-md5 498 to4268 ext Response: GAME GAG WELT OUT DOWN CHAT New secret pass phrase: otp-md5 499 to4269 Response: LINE PAP MILK NELL BUOY TROY ID mark OTP key is 499 gr4269 LINE PAP MILK NELL BUOY TROY 为了接受默认的种子, 按下 Return (回车)。 在输入访问口令之前, 到一个有安全连接的机器上, 并给它同样的参数: &prompt.user; opiekey 498 to4268 Using the MD5 algorithm to compute response. Reminder: Don't use opiekey from telnet or dial-in sessions. Enter secret pass phrase: GAME GAG WELT OUT DOWN CHAT 现在回到不安全的连接, 并将生成的一次性口令粘贴到相应的应用程序中。 生成一个一次性密码 一旦初始化过 OPIE, 当您登录时将看到类似这样的提示: &prompt.user; telnet example.com Trying 10.0.0.1... Connected to example.com Escape character is '^]'. FreeBSD/i386 (example.com) (ttypa) login: <username> otp-md5 498 gr4269 ext Password: 另外, OPIE 提示有一个很有用的特性 (这里没有表现出来): 如果您在口令提示处按下 Return (回车) 系统将回显刚键入的口令, 您可以藉此看到自己所键入的内容。 如果试图手工键入一个一次性密码, 这会非常有用。 MS-DOS Windows MacOS 此时您需要生成一个一次性密码来回答这一提示。 这项工作必须在一个可信的系统上执行 opiekey 来完成。 (也可以找到 DOS、 &windows; 以及 &macos; 等操作系统上运行的版本)。 这个程序需要将迭代轮数和种子提供给它。 您可以从登录提示那里复制和粘贴它们。 在可信的系统上: &prompt.user; opiekey 498 to4268 Using the MD5 algorithm to compute response. Reminder: Don't use opiekey from telnet or dial-in sessions. Enter secret pass phrase: GAME GAG WELT OUT DOWN CHAT 现在就可以用刚刚获得的一次性口令登录了。 产生多个一次性口令 有时,会需要到不能访问可信的机器或安全连接的地方。 这种情形下, 可以使用 opiekey 命令来一次生成许多一次性口令。 例如: &prompt.user; opiekey -n 5 30 zz99999 Using the MD5 algorithm to compute response. Reminder: Don't use opiekey from telnet or dial-in sessions. Enter secret pass phrase: <secret password> 26: JOAN BORE FOSS DES NAY QUIT 27: LATE BIAS SLAY FOLK MUCH TRIG 28: SALT TIN ANTI LOON NEAL USE 29: RIO ODIN GO BYE FURY TIC 30: GREW JIVE SAN GIRD BOIL PHI 按顺序请求 5 个口令, 则指定了最后一个迭代轮数应该是多少。 注意这些口令将按与使用顺序相反的顺序来显示。 如果您比较偏执, 可以手工写下这些结果; 一般来说把它粘贴到 lpr 就可以了。 注意,每一行都显示迭代轮数及其对应的一次性的密码; 一些人建议用完一个就划掉一个。 限制使用 &unix; 口令 OPIE 可以对 &unix; 口令的使用进行基于 IP 的登录限制。 对应的文件是 /etc/opieaccess, 这个文件默认情况下就是存在的。 请参阅 &man.opieaccess.5; 以了解关于这个文件进一步的情况, 以及安全方面需要进行的一些考虑。 下面是一个示范的 opieaccess 文件: permit 192.168.0.0 255.255.0.0 这行允许指定 IP 地址的用户 (再次强调这种地址容易被伪造) 在任何时候使用 &unix; 口令登录。 如果 opieaccess 中没有匹配的规则, 则将默认拒绝任何非 OPIE 登录。 Tom Rhodes - 作者: + 作者 TCP Wrappers TCP Wrappers 每一个熟悉 &man.inetd.8; 都应该听说过 TCP Wrappers, 但几乎没有人对它在网络环境中的作用有全面的理解。 几乎每个人都会安装防火墙来处理网络连接, 然而虽然防火墙有非常广泛的用途, 它却不是万能的, 例如它无法处理类似向连接发起者发送一些文本这样的任务。 而 TCP 软件能够完成它以及更多的其他事情。 接下来的几段中将讨论许多 TCP Wrappers 提供的功能, 并且, 还给出了一些配置实例。 TCP Wrappers 软件扩展了 inetd 为受其控制的服务程序实施控制的能力。 通过使用这种方法, 它能够提供日志支持、 返回消息给联入的连接、 使得服务程序只接受内部连接, 等等。 尽管防火墙也能够完成其中的某些功能, 但这不仅增加了一层额外的保护, 也提供了防火墙无法提供的功能。 然而, 由 TCP Wrappers 提供的一些额外的安全功能, 不应被视为好的防火墙的替代品。 TCP Wrappers 应结合防火墙或其他安全加强设施一并使用, 为系统多提供一层安全防护。 由于这些配置是对于 inetd 的扩展, 因此, 读者应首先阅读 配置 inetd 这节。 尽管由 &man.inetd.8; 运行的程序并不是真正的 服务程序, 但传统上也把它们称为服务程序。 下面仍将使用这一术语。 初始配置 在 &os; 中使用 TCP Wrappers 的唯一要求是确保 inetd 在从 rc.conf 中启动时包含了 选项; 这是默认的设置。 当然, 还需要对 /etc/hosts.allow 进行适当的配置, 但 &man.syslogd.8; 在配置不当时会在系统日志中记录相关消息。 与其它的 TCP Wrappers 实现不同, 使用 hosts.deny 在这里被认为是不推荐和过时的做法。 所有的配置选项应放到 /etc/hosts.allow 中。 在最简单的配置中, 服务程序的连接策略是根据 /etc/hosts.allow 允许或阻止。 &os; 中的默认配置是允许一切发到由 inetd 所启动的服务的连接请求。 在基本配置之后将讨论更复杂的情况。 基本配置的形式通常是 服务 : 地址 : 动作。 这里 服务 是从 inetd 启动的服务程序的名字。 而 地址 可以是任何有效的主机名、 一个 IP 或由方括号 ([ ]) 括起来的 IPv6 地址。 动作字段可以使 allow 或 deny, 分别用于允许和禁止相应的访问。 在配置时您需要注意所有的配置都是按照第一个匹配的规则运转的, 这表示配置文件将按照顺序查找匹配规则, 而一旦找到匹配, 则搜索也就停止了。 另外也有许多其他选项, 这些将在后面介绍。 简单的配置行从上面这些描述之中可以很容易得出。 例如, 允许 POP3 连接通过 mail/qpopper 服务, 应把下面的行添加到 hosts.allow # This line is required for POP3 connections: qpopper : ALL : allow 增加这样之后, 需要重新启动 inetd。 可以通过使用 &man.kill.1; 命令来完成这项工作, 或使用 /etc/rc.d/inetdrestart parameter 参数。 高级配置 TCP Wrappers 也有一些高级的配置选项; 它们能够用来对如何处理连接实施更多的控制。 一些时候, 返回一个说明到特定的主机或请求服务的连接可能是更好的办法。 其他情况下, 记录日志或者发送邮件给管理员可能更为适合。 另外, 一些服务可能只希望为本机提供。 这些需求都可以通过使用 通配符, 扩展字符以及外部命令来实现。 接下来的两节将介绍这些。 外部命令 假设由于发生了某种状况, 而导致连接应该被拒绝掉, 而将其原因发送给发起连接的人。 如何完成这样的任务呢? 这样的动作可以通过使用 选项来实现。 当发起了连接请求时, 将调用一个命令或脚本。 在 hosts.allow 文件中已经给出了一个例子: # The rest of the daemons are protected. ALL : ALL \ : severity auth.info \ : twist /bin/echo "You are not welcome to use %d from %h." 这个例子将把消息 You are not allowed to use daemon from hostname. 返回给访问先前没有配置过允许访问的服务客户。 对于希望把消息反馈给连接发起者, 然后立即切断这样的需求来说, 这样的配置非常有用。 请注意所有反馈信息 必须 被引号 " 包围; 这一规则是没有例外的。 如果攻击者向服务程序发送大量的连接请求, 则可能发动一次成功的拒绝服务攻击。 另一种可能是针对这种情况使用 。 类似 也暗含拒绝连接, 并可以用来执行外部命令或服务。 与 不同的是, 不会向连接发起者发送回应。 考虑下面的配置: # We do not allow connections from example.com: ALL : .example.com \ : spawn (/bin/echo %a from %h attempted to access %d >> \ /var/log/connections.log) \ : deny 这将拒绝来自 *.example.com 域的所有连接; 同时还将记录主机名, IP 地址, 以及对方所尝试连接的服务名字到 /var/log/connections.log 文件中。 除了前面已经介绍过的转义字符, 例如 %a 之外, 还有一些其它的转义符。 参考 &man.hosts.access.5; 联机手册可以获得完整的列表。 通配符选项 前面的例子都使用了 ALL。 其它选项能够将功能扩展到更远。 例如, ALL 可以被用来匹配每一个服务、 域,或 IP 地址。 另一些可用的通配符包括 PARANOID, 它可以用来匹配任何来自可能被伪造的 IP 地址的主机。 换言之, paranoid 可以被用来定义来自 IP 与其主机名不符的客户。 下面的例子将给您更多的感性认识: # Block possibly spoofed requests to sendmail: sendmail : PARANOID : deny 在这个例子中, 所有连接 sendmailIP 地址与其主机名不符的主机都将被拒绝。 如果服务器和客户机有一方的 DNS 配置不正确, 使用 PARANOID 可能会严重地削弱服务。 在设置之前, 管理员应该谨慎地考虑。 要了解关于通配符和他们的功能, 请参考 &man.hosts.access.5; 联机手册。 为了使设置能够生效, 应该首先把 hosts.allow 的第一行配置注释掉。 这节的开始部分已经说明了这一点。 Mark Murray 撰写者 Mark Dapoz 初稿 <application>KerberosIV</application> Kerberos 是一个网络附加系统/协议, 它使得用户能够通过一个安全服务器的服务来验证身份。 象远程登录, 远程复制, 系统间的相互文件复制和其他完成高风险任务的服务将被变得相当安全和可控制。 下面将具体介绍如何配置随 &os; 发行的 Kerberos。 不过, 您还是应该阅读相应的联机手册以获得完整的说明。 安装 <application>KerberosIV</application> MIT KerberosIV 安装 Kerberos 是 &os; 的一项可选组件。 安装该软件最简单的办法就是 在使用 sysinstall 安装 &os; 时选择 krb4krb5。 这样将会安装 eBones (KerberosIV) 或 Heimdal (Kerberos5) 的 Kerberos 实现。 采用实现的原因是它们在美国/加拿大 以外的地区开发, 因此这些国家之外的人使用, 而不必受美国的加密代码出口管制的限制。 此外, 您可以从 security/krb5 得到 Kerberos 的 MIT 实现。 创建最初的数据库 这项工作只需要在 Kerberos 服务器上完成。 首先确认没有旧的 Kerberos 数据库存在。 您应该进入到 /etc/kerberosIV 目录中并检查下述文件是否已经存在: &prompt.root; cd /etc/kerberosIV &prompt.root; ls README krb.conf krb.realms 如果您发现了除此之外的其它文件 (例如 principal.*master_key) 已经存在, 请使用 kdb_destroy 命令来销毁旧的数据库, 或者, 如果 Kerberos 没有在运行,简单地删除掉那些多余的文件。 现在必须编辑 krb.confkrb.realms 文件来定义您的 Kerberos 领域。 在本例中, 这个领域将是 EXAMPLE.COM 而其服务器是 grunt.example.com。 我们编辑或创建如下的 krb.conf 文件: &prompt.root; cat krb.conf EXAMPLE.COM EXAMPLE.COM grunt.example.com admin server CS.BERKELEY.EDU okeeffe.berkeley.edu ATHENA.MIT.EDU kerberos.mit.edu ATHENA.MIT.EDU kerberos-1.mit.edu ATHENA.MIT.EDU kerberos-2.mit.edu ATHENA.MIT.EDU kerberos-3.mit.edu LCS.MIT.EDU kerberos.lcs.mit.edu TELECOM.MIT.EDU bitsy.mit.edu ARC.NASA.GOV trident.arc.nasa.gov 在这个例子中, 除此之外的其它领域并不是必需的。 把他们在这里一并展示是为了演示如何让机器了解多个领域的存在。 简单起见, 在实际的配置中可以省略它们。 第一行命名了这个系统工作的领域。 其它行包含了领域/主机的记录。 每行的第一项是一个领域, 其后是在这个领域中充当 密钥分发中心 的主机名。 其后的 admin server 表示该主机同时还提供管理数据库服务。进一步的详细说明请参考 Kerberos 联机手册。 现在应该添加 grunt.example.comEXAMPLE.COM 领域, 同时追加一项以便将出现在 EXAMPLE.COM 领域中 .example.com 域的所有主机也加入进来。 krb.realms 这个文件需要按照下面的方法修改: &prompt.root; cat krb.realms grunt.example.com EXAMPLE.COM .example.com EXAMPLE.COM .berkeley.edu CS.BERKELEY.EDU .MIT.EDU ATHENA.MIT.EDU .mit.edu ATHENA.MIT.EDU 再次强调, 其它领域并不是必需的。 在这里只是要展示如何使用多个领域。 可以删掉它们以简化配置。 第一行将 指定的 系统置于所指名字的领域内。 这一行的其它部分则指明了特定子域内的主机应该默认属于哪个领域。 接下来我们就可以创建数据库了。 只有在 Kerberos 服务器上 (或密钥分发中心上) 才需要它。 可以通过 kdb_init 命令来完成这一步: &prompt.root; kdb_init Realm name [default ATHENA.MIT.EDU ]: EXAMPLE.COM You will be prompted for the database Master Password. It is important that you NOT FORGET this password. Enter Kerberos master key: 现在我们应该保存密钥, 这样本机上运行的其他服务就能够了解这一变化。 用 kstash 命令来完成这一步: &prompt.root; kstash Enter Kerberos master key: Current Kerberos master key version is 1. Master key entered. BEWARE! 这一操作将把主口令保存到 /etc/kerberosIV/master_key 让一切运转起来 KerberosIV 初始配置 有两个主要的东西需要被添加到要用 Kerberos 来确保安全的 每一个 系统上。 它们的名字是 kpasswdrcmd。 这些程序允许另外系统改变 Kerberos 的密码, 在不同的系统上可能有不同的名字。 服务程序 kpasswdrcmd 使得其他系统能够修改 Kerberos 口令, 以及执行类似 &man.rcp.1;, &man.rlogin.1; 和 &man.rsh.1; 这样的命令。 我们添加下面这些记录: &prompt.root; kdb_edit Opening database... Enter Kerberos master key: Current Kerberos master key version is 1. Master key entered. BEWARE! Previous or default values are in [brackets] , enter return to leave the same, or new value. Principal name: passwd Instance: grunt <Not found>, Create [y] ? y Principal: passwd, Instance: grunt, kdc_key_ver: 1 New Password: <---- enter RANDOM here Verifying password New Password: <---- enter RANDOM here Random password [y] ? y Principal's new key version = 1 Expiration date (enter yyyy-mm-dd) [ 2000-01-01 ] ? Max ticket lifetime (*5 minutes) [ 255 ] ? Attributes [ 0 ] ? Edit O.K. Principal name: rcmd Instance: grunt <Not found>, Create [y] ? Principal: rcmd, Instance: grunt, kdc_key_ver: 1 New Password: <---- enter RANDOM here Verifying password New Password: <---- enter RANDOM here Random password [y] ? Principal's new key version = 1 Expiration date (enter yyyy-mm-dd) [ 2000-01-01 ] ? Max ticket lifetime (*5 minutes) [ 255 ] ? Attributes [ 0 ] ? Edit O.K. Principal name: <---- null entry here will cause an exit 创建服务器文件 现在需要分析在每台机器上定义的服务的所有情况。 为了做到这一点, 可以使用 ext_srvtab 命令。 这将创建一个文件, 它需要被 通过安全的途径 复制或移动到每一个 Kerberos 客户端的 /etc 目录中。 在每一台服务器上都必须存在这个文件, 它对 Kerberos 的运行至关重要。 &prompt.root; ext_srvtab grunt Enter Kerberos master key: Current Kerberos master key version is 1. Master key entered. BEWARE! Generating 'grunt-new-srvtab'.... 现在,这个命令只产生一个临时文件,必须被重命名为 srvtab 以便所有的服务可以识别它。 用 &man.mv.1; 命令把它挪到原系统的这个位置: &prompt.root; mv grunt-new-srvtab srvtab 如果文件是针对客户系统的, 而且网络可能会不安全, 则应把 client-new-srvtab 复制到可移动的介质上, 并通过物理上安全的方式拿走。 将其改名为 srvtab 并放到客户机的 /etc/kerberosIV 目录中, 并赋予 mode 600: &prompt.root; mv grumble-new-srvtab srvtab &prompt.root; chmod 600 srvtab 复制数据库 现在添加一些用户记录到数据库。 首先为用户 jane 创建其对应的项。 使用 kdb_edit 命令来完成此项工作: &prompt.root; kdb_edit Opening database... Enter Kerberos master key: Current Kerberos master key version is 1. Master key entered. BEWARE! Previous or default values are in [brackets] , enter return to leave the same, or new value. Principal name: jane Instance: <Not found>, Create [y] ? y Principal: jane, Instance: , kdc_key_ver: 1 New Password: <---- enter a secure password here Verifying password New Password: <---- re-enter the password here Principal's new key version = 1 Expiration date (enter yyyy-mm-dd) [ 2000-01-01 ] ? Max ticket lifetime (*5 minutes) [ 255 ] ? Attributes [ 0 ] ? Edit O.K. Principal name: <---- null entry here will cause an exit 测试全部相关信息 首先必须启动 Kerberos 的服务程序。 这里需要指出, 如果您正确地修改了 /etc/rc.conf 则系统在启动时会自动完成这个工作。 只有在 Kerberos 服务器上才需要这么做。 Kerberos 客户程序将自动地从 /etc/kerberosIV 目录中的文件获取所需要的信息。 &prompt.root; kerberos & Kerberos server starting Sleep forever on error Log file is /var/log/kerberos.log Current Kerberos master key version is 1. Master key entered. BEWARE! Current Kerberos master key version is 1 Local realm: EXAMPLE.COM &prompt.root; kadmind -n & KADM Server KADM0.0A initializing Please do not use 'kill -9' to kill this job, use a regular kill instead Current Kerberos master key version is 1. Master key entered. BEWARE! 接下来应使用 kinit 命令来获取与我们刚刚创建的 ID jane 对应的 ticket: &prompt.user; kinit jane MIT Project Athena (grunt.example.com) Kerberos Initialization for "jane" Password: 尝试使用 klist 列出句柄以了解是否真的拥有它们: &prompt.user; klist Ticket file: /tmp/tkt245 Principal: jane@EXAMPLE.COM Issued Expires Principal Apr 30 11:23:22 Apr 30 19:23:22 krbtgt.EXAMPLE.COM@EXAMPLE.COM 现在可以试试看用 &man.passwd.1; 来修改口令, 以验证 kpasswd 服务程序是否能够从 Kerberos 数据库中获得需要的授权: &prompt.user; passwd realm EXAMPLE.COM Old password for jane: New Password for jane: Verifying password New Password for jane: Password changed. 授予 <command>su</command> 特权 Kerberos 使我们能够给予 每一个 需要使用 root 特权的用户使用他们自己 单独的 &man.su.1; 口令。 现在我们追加一个被授予 &man.su.1; 到 root 权限的 ID。 这件事是由与 root 相关联的一个 principal 实例来控制的。使用 kdb_edit 可以在 Kerberos 数据库中建立一个 jane.root 条目: &prompt.root; kdb_edit Opening database... Enter Kerberos master key: Current Kerberos master key version is 1. Master key entered. BEWARE! Previous or default values are in [brackets] , enter return to leave the same, or new value. Principal name: jane Instance: root <Not found>, Create [y] ? y Principal: jane, Instance: root, kdc_key_ver: 1 New Password: <---- enter a SECURE password here Verifying password New Password: <---- re-enter the password here Principal's new key version = 1 Expiration date (enter yyyy-mm-dd) [ 2000-01-01 ] ? Max ticket lifetime (*5 minutes) [ 255 ] ? 12 <--- Keep this short! Attributes [ 0 ] ? Edit O.K. Principal name: <---- null entry here will cause an exit 现在试试看获得相应的句柄, 以确认它已经正常工作了: &prompt.root; kinit jane.root MIT Project Athena (grunt.example.com) Kerberos Initialization for "jane.root" Password: 接下来我们需要把用户添加到 root.klogin 文件里: &prompt.root; cat /root/.klogin jane.root@EXAMPLE.COM 试试看 &man.su.1;: &prompt.user; su Password: 然后看看我们拥有哪些句柄: &prompt.root; klist Ticket file: /tmp/tkt_root_245 Principal: jane.root@EXAMPLE.COM Issued Expires Principal May 2 20:43:12 May 3 04:43:12 krbtgt.EXAMPLE.COM@EXAMPLE.COM 使用其它命令 在前文给出的例子中, 我们创建了一个称为 jane 的用户, 以及一个 root 实例。 此处的用户名和它的 principal 相同, 这是 Kerberos 默认的; 一个形如 <username>.root<principal>.<instance> 将允许 <username> 使用 &man.su.1; 成为 root, 只要所需的那些条目在 root home 目录中的 .klogin 中存在的话: &prompt.root; cat /root/.klogin jane.root@EXAMPLE.COM 类似地, 如果用户的 home 目录中有这样的设置: &prompt.user; cat ~/.klogin jane@EXAMPLE.COM jack@EXAMPLE.COM 则表明在 EXAMPLE.COM 领域的经过身份验证的 jane 或者 jack (通过 kinit, 详情见前文) 能够使用 jane 的身份或系统 (grunt) 中的文件, 无论通过 &man.rlogin.1;, &man.rsh.1; 或是 &man.rcp.1;。 举例来说, jane 现在通过 Kerberos 登入了其它系统: &prompt.user; kinit MIT Project Athena (grunt.example.com) Password: &prompt.user; rlogin grunt Last login: Mon May 1 21:14:47 from grumble Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994 The Regents of the University of California. All rights reserved. FreeBSD BUILT-19950429 (GR386) #0: Sat Apr 29 17:50:09 SAT 1995 或者, 当 jack 登录到 jane 在同一台机器上的账号 (jane 按照前面所介绍的那样配置了 .klogin 文件, 而负责 Kerberos 的管理员, 则为 jack 的 principal 配置了一个空的 instance): &prompt.user; kinit &prompt.user; rlogin grunt -l jane MIT Project Athena (grunt.example.com) Password: Last login: Mon May 1 21:16:55 from grumble Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994 The Regents of the University of California. All rights reserved. FreeBSD BUILT-19950429 (GR386) #0: Sat Apr 29 17:50:09 SAT 1995 Tillman Hodgson 撰写者 Mark Murray 原文来自 <application>Kerberos5</application> 在 &os;-5.1 之后的每一个 &os; 版本都只包含 Kerberos5 支持了, 因而, Kerberos5 是它们所包含的唯一的 Kerberos 版本, 其配置在绝大多数方面和 KerberosIV 非常类似。 下述信息只适用于 &os;-5.0 之后版本中的 Kerberos5。 希望使用 KerberosIV 的用户可以安装 security/krb4 port。 Kerberos 是一组附加的网络系统/协议, 用以让用户通过一台安全服务器提供的服务来验证身份。 包括远程登录、远程复制、在系统间安全地复制文件, 以及其它高危险性的操作, 由于其存在而显著地提高了安全型并且更加可控。 Kerberos 可以理解为一种身份验证代理系统。 它也被描述为一种以受信第三方为主导的身份验证系统。 Kerberos 只提供一种功能 — 在网络上安全地完成用户的身份验证。 它并不提供授权功能 (也就是说用户能够做什么操作) 或审计功能 (记录用户作了什么操作)。 一旦客户和服务器都使用了 Kerberos 来证明各自的身份之后, 他们还可以加密全部的通讯以保证业务数据的私密性和完整性。 因此, 强烈建议将 Kerberos 同其它提供授权和审计服务的安全手段联用。 接下来的说明可以用来指导如何安装 &os; 所附带的 Kerberos。 不过, 您仍然需要参考相应的联机手册以获得完整的描述。 为了展示 Kerberos 的安装过程, 我们约定: DNS 域 (zone) 为 example.org。 Kerberos 领域是 EXAMPLE.ORG。 在安装 Kerberos 时请使用实际的域名即使您只是想在内部网上用一用。 这可以避免 DNS 问题并保证了同其它 Kerberos 之间的互操作性。 历史 Kerberos5 历史 Kerberos 最早由 MIT 作为解决网络安全问题的一个方案提出。 Kerberos 协议采用了强加密, 因此客户能够在不安全的网络上向服务器 (以及相反地) 验证自己的身份。 Kerberos 是网络验证协议名字, 同时也是用以表达实现了它的程序的形容词。 (例如 Kerberos telnet)。 目前最新的协议版本是 5,在 RFC 1510 中有所描述。 该协议有许多免费的实现, 这些实现涵盖了许多种不同的操作系统。 最初研制 Kerberos 的麻省理工学院 (MIT) 也仍然在继续开发他们的 Kerberos 软件包。 在 US 它被作为一种加密产品使用, 因而历史上曾经受到 US 出口管制。 MIT Kerberos 可以通过 port (security/krb5) 来安装和使用。 Heimdal Kerberos 是另一种第 5 版实现, 并且明确地在 US 之外的地区开发, 以避免出口管制 (因此在许多非商业的类 &unix; 系统中非常常用。 Heimdal Kerberos 软件包可以通过 port (security/heimdal) 安装, 最新的 &os; 的最小安装也会包含它。 为使尽可能多的读者从中受益, 这份说明以 &os; 附带的 Heimdal 软件包为准。 配置 Heimdal <acronym>KDC</acronym> Kerberos5 密钥分发中心 密钥分发中心 (KDC) 是 Kerberos 提供的集中式验证服务 — 它是签发 Kerberos tickets 的那台计算机。 KDCKerberos 领域中的其它机器看来是 受信的, 因此必须格外注意其安全性。 需要说明 Kerberos 服务器只需要非常少的计算资源, 尽管如此, 基于安全理由仍然推荐使用独占的机器来扮演 KDC 的角色。 要开始配置 KDC, 首先请确认您的 /etc/rc.conf 文件包含了作为一个 KDC 所需的设置 (您可能需要适当地调整路径以适应自己系统的情况): kerberos5_server_enable="YES" kadmind5_server_enable="YES" 接下来需要修改 Kerberos 的配置文件, /etc/krb5.conf [libdefaults] default_realm = EXAMPLE.ORG [realms] EXAMPLE.ORG = { kdc = kerberos.example.org admin_server = kerberos.example.org } [domain_realm] .example.org = EXAMPLE.ORG 请注意这个 /etc/krb5.conf 文件假定您的 KDC 有一个完整的主机名, 即 kerberos.example.org。 如果您的 KDC 主机名与它不同, 则应添加一条 CNAME (别名) 项到 zone 中去。 对于有正确地配置过的 BIND DNS 服务器的大型网络, 上述例子可以精简为: [libdefaults] default_realm = EXAMPLE.ORG 将下面的内容加入到 example.org zone 数据文件中: _kerberos._udp IN SRV 01 00 88 kerberos.example.org. _kerberos._tcp IN SRV 01 00 88 kerberos.example.org. _kpasswd._udp IN SRV 01 00 464 kerberos.example.org. _kerberos-adm._tcp IN SRV 01 00 749 kerberos.example.org. _kerberos IN TXT EXAMPLE.ORG 要让客户机能够找到 Kerberos 服务, 就 必须 首先配置完整或最小配置的 /etc/krb5.conf 并且 正确地配置 DNS 服务器。 接下来需要创建 Kerberos 数据库。 这个数据库包括了使用主密码加密的所有实体的密钥。 您并不需要记住这个密码, 它会保存在一个文件 (/var/heimdal/m-key) 中。 要创建主密钥, 需要执行 kstash 并输入一个口令。 主密钥一旦建立, 您就可以用 kadmin 程序的 -l 参数 (表示 local) 来初始化数据库了。 这个选项让 kadmin 直接地修改数据库文件而不是通过 kadmind 的网络服务。 这解决了在数据库创建之前连接它的鸡生蛋的问题。 进入 kadmin 提示符之后, 用 init 命令来创建领域的初始数据库。 最后, 仍然在 kadmin 中, 使用 add 命令来创建第一个 principal。 暂时使用全部的默认设置, 随后可以在任何时候使用 modify 命令来修改这些设置。 另外, 也可以用 ? 命令来了解可用的选项。 典型的数据库创建过程如下: &prompt.root; kstash Master key: xxxxxxxx Verifying password - Master key: xxxxxxxx &prompt.root; kadmin -l kadmin> init EXAMPLE.ORG Realm max ticket life [unlimited]: kadmin> add tillman Max ticket life [unlimited]: Max renewable life [unlimited]: Attributes []: Password: xxxxxxxx Verifying password - Password: xxxxxxxx 现在是启动 KDC 服务的时候了。 运行 /etc/rc.d/kerberos start 以及 /etc/rc.d/kadmind start 来启动这些服务。 尽管此时还没有任何正在运行的 Kerberos 服务, 但您仍然可以通过获取并列出您刚刚创建的那个 principal (用户) 的 ticket 来验证 KDC 确实在正常工作, 使用 KDC 本身的功能: &prompt.user; kinit tillman tillman@EXAMPLE.ORG's Password: &prompt.user; klist Credentials cache: FILE:/tmp/krb5cc_500 Principal: tillman@EXAMPLE.ORG Issued Expires Principal Aug 27 15:37:58 Aug 28 01:37:58 krbtgt/EXAMPLE.ORG@EXAMPLE.ORG 完成所需的操作之后, 可以撤消这一 ticket: &prompt.user; k5destroy 为 <application>Kerberos</application> 启用 Heimdal 服务 Kerberos5 启用服务 首先我们需要一份 Kerberos 配置文件 /etc/krb5.conf 的副本。 只需简单地用安全的方式 (使用类似 &man.scp.1; 的网络工具, 或通过软盘) 复制 KDC 上的版本, 并覆盖掉客户机上的对应文件就可以了。 接下来需要一个 /etc/krb5.keytab 文件。 这是提供 Kerberos 服务的服务器和工作站的一个主要区别 — 服务器必须有 keytab 文件。 这个文件包括了服务器的主机密钥, 这使得 KDC 得以验证它们的身份。 此文件必须以安全的方式传到服务器上, 因为如果密钥被公之于众, 则安全也就毁于一旦。 也就是说, 通过明文的通道, 例如 FTP 是非常糟糕的想法。 一般来说, 您会希望使用 kadmin 程序来把 keytab 传到服务器上。 由于也需要使用 kadmin 来为主机建立 principal (KDC 一端的 krb5.keytab), 因此这并不复杂。 注意您必须已经获得了一个 ticket 而且这个 ticket 必须许可使用 kadmind.acl 中的 kadmin 接口。 请参考 Heimdal info 中的 Remote administration(远程管理) 一节 (info heimdal) 以了解如何设计访问控制表。 如果不希望启用远程的 kadmin 操作, 则可以简单地采用安全的方式连接 KDC (通过本机控制台, &man.ssh.1; 或 Kerberos &man.telnet.1;) 并使用 kadmin -l 在本地执行管理操作。 安装了 /etc/krb5.conf 文件之后, 您就可以使用 Kerberos 上的 kadmin 了。 add --random-key 命令可以用于添加主机 principal, 而 ext 命令则允许导出服务器的主机 principal 到它的 keytab 中。 例如: &prompt.root; kadmin kadmin> add --random-key host/myserver.example.org Max ticket life [unlimited]: Max renewable life [unlimited]: Attributes []: kadmin> ext host/myserver.example.org kadmin> exit 注意 ext 命令 (这是 extract 的简写) 默认会把导出的密钥放到 /etc/krb5.keytab 中。 如果您由于没有在 KDC 上运行 kadmind (例如基于安全理由) 因而无法远程地使用 kadmin 您可以直接在 KDC 上添加主机 principal (host/myserver.EXAMPLE.ORG) 随后将其导出到一个临时文件中 (以免覆盖 KDC 上的 /etc/krb5.keytab), 方法是使用下面的命令: &prompt.root; kadmin kadmin> ext --keytab=/tmp/example.keytab host/myserver.example.org kadmin> exit 随后需要把 keytab 复制到服务器上 (例如使用 scp 或软盘)。 一定要指定一个不同于默认的 keytab 名字以免覆盖 KDC 上的 keytab。 到现在您的服务器已经可以同 KDC 通讯了 (因为已经配置了 krb5.conf 文件), 而且它还能够证明自己的身份 (由于配置了 krb5.keytab 文件)。 现在可以启用一些 Kerberos 服务。 在这个例子中, 我们将在 /etc/inetd.conf 中添加下面的行来启用 telnet 服务, 随后用 /etc/rc.d/inetd restart 重启 &man.inetd.8; 服务来使设置生效: telnet stream tcp nowait root /usr/libexec/telnetd telnetd -a user 关键的部分是 -a (表示验证) 类型设置为用户 (user)。 请参考 &man.telnetd.8; 联机手册以了解细节。 使用 Heimdal 来启用客户端 <application>Kerberos</application> Kerberos5 客户端配置 设置客户机是非常简单的。 在正确配置了 Kerberos 的网络中, 只需要将位于 /etc/krb5.conf 的配置文件进行一下设置就可以了。 这一步骤可以简单地通过安全的方式将文件从 KDC 复制到客户机上来完成。 尝试在客户机上执行 kinitklist, 以及 kdestroy 来测试获取、 显示并删除 刚刚为 principal 建立的 ticket 是否能够正常进行, 如果能, 则用其它的 Kerberos 应用程序来连接启用了 Kerberos 的服务。 如果应用程序不能正常工作而获取 ticket 正常, 则通常是服务本身, 而非客户机或 KDC 有问题。 在测试类似 telnet 的应用程序时, 应考虑使用抓包程序 (例如 &man.tcpdump.1;) 来确认您的口令没有以明文方式传输。 尝试使用 telnet-x 参数, 它将加密整个数据流 (类似 ssh)。 许多非核心的 Kerberos 客户应用程序也是默认安装的。 在 Hemidal 的 最小 安装理念下, telnet 是唯一一个采用了 Kerberos 的服务。 Heimdal port 则提供了一些默认不安装的客户应用程序, 例如启用了 Kerberos 版本的 ftprshrcprlogin 以及一些更不常用的程序。 MIT port 也包括了一整套 Kerberos 客户应用程序。 用户配置文件: <filename>.k5login</filename> 和 <filename>.k5users</filename> .k5login .k5users 在某个领域中的用户往往都有自己的 Kerberos principal (例如 tillman@EXAMPLE.ORG) 并映射到本机用户帐户 (例如本机上名为 tillman 的帐户)。 客户端应用程序, 如 telnet 通常并不需要用户名或 principal。 不过, 有时您可能会需要赋予某些没有匹配 Kerberos principal 的人使用本地用户帐户的权限。 例如 tillman@EXAMPLE.ORG 可能需要访问本地的 webdevelopers 用户帐号。 其它 principal 可能也会需要访问这个本地帐号。 用户 home 目录中的 .k5login.k5users 这两个文件可以配合 .hosts.rhosts 来有效地解决这个问题。 例如, 如果 .k5login 中有如下内容: tillman@example.org jdoe@example.org 并放到了本地用户 webdevelopers 的 home 目录中, 则列出的两个 principals 都可以使用那个帐号, 而无须共享口令。 建议您在开始实施之前首先阅读这些命令的联机帮助。 特别地, ksu 的联机手册包括了 .k5users 的相关内容。 <application>Kerberos</application> 提示、技巧和故障排除 Kerberos5 故障排除 当使用 Heimdal 或 MIT Kerberos ports 时, 需要确认 PATH 环境变量把 Kerberos 客户应用列在系统自带的版本之前。 同一领域内的所有计算机的时间设置是否同步? 如果不是的话, 则身份验证可能会失败。 描述了如何使用 NTP 来同步时钟。 MIT 和 Heimdal 能够很好地互操作。 一个例外是 kadmin, 因为这个协议没有被标准化。 如果您改变了主机名, 您还需要修改您的 host/ principal 并更新 keytab。 这一规律也适用于类似 Apache 的 www/mod_auth_kerb 所使用的 www/ principal 这样的特殊 keytab 项。 您的领域中的每一台主机必须在 DNS (或至少在 /etc/hosts 中) 可以解析 (同时包括正向和反向)。 CNAME 能够正常使用, 但必须有正确的对应 A 和 PTR 记录。 此时给出的错误信息可能很让人困惑: Kerberos5 refuses authentication because Read req failed: Key table entry not found 某些作为客户使用您的 KDC 的操作系统可能没有将 ksu 设置为 setuid root 的权限。 这意味着 ksu 将不能够正常工作, 从安全角度说这是一个不错的主意, 但可能令人烦恼。 这类问题并不是 KDC 的错误。 使用 MIT Kerberos 时, 如果希望允许一个 principal 拥有超过默认的十小时有效期的 ticket 则必须使用 kadmin 中的 modify_principal 来修改 principal 本身以及 krbtgt 的 maxlife(最大有效期)。 此后, principal 可以使用 kinit-l 参数来请求一个有更长有效期的 ticket。 如果在 KDC 上运行了听包程序, 并在工作站上执行 kinit, 您可能会注意到 TGT 是在 kinit 一开始执行的时候就发出了的 — 甚至在您输入口令之前! 关于这个现象的解释是 Kerberos 服务器可以无限制地收发 TGT (Ticket Granting Ticket) 给任何未经授权的请求; 但是, 每一个 TGT 都是使用用户的口令派生出来的密钥进行加密的。 因此, 当用户输入口令时它并不会发送给 KDC, 而是直接用于解密 kinit 所拿到的 TGT。 如果解密过程得到了一个包含合法的时间戳的有效 ticket, 则说明用户的 Kerberos 凭据有效。 这些凭据包含了一个会话密钥用以在随后建立 Kerberos 服务器的加密通讯, 传递由服务器自己的私钥加密的实际的 ticket-granting ticket。 这个第二层加密对于用户来说是看不到的, 但它使得 Kerberos 服务器能够验证每一个 TGT 的真实性。 如果需要有效期更长的 ticket (例如一周) 而且您使用 OpenSSH 连接保存您的 ticket 的机器, 请确认 sshd_config 中的 Kerberos 被设置为 no 否则在注销时会自动删除所有的 ticket。 切记主机的 principals 的 ticket 有效期一定要比用户的长。 如果您的用户 principal 的有效期是一周, 而所连接的主机的有效期是九个小时, 则缓存的主机 principal 将先行过期, 结果是 ticket 缓存无法正常工作。 当配置 krb5.dict 文件来防止使用特定的简单口令 (kadmind 的联机手册中简要介绍了它), 请切记只有指定了口令策略的 principals 才会使用它们。 krb5.dict 文件的格式很简单: 每个串占一行。 创建一个到 /usr/share/dict/words 的符号连接会很有用。 与 <acronym>MIT</acronym> port 的区别 MIT 和 Heimdal 主要的区别在于 kadmin 程序使用不同 (尽管等价) 的命令和协议。 如果您的 KDCMIT 的, 则其影响是不能使用 Heimdal 的 kadmin 程序来远程管理 KDC (或相反)。 完成同样工作的命令可能会有些许的不同。 推荐按照 MIT Kerberos 的网站 () 上的说明来操作。 请小心关于路径的问题, MIT port 会默认安装到 /usr/local/, 您因此可能会执行 普通的 系统应用程序而非 MIT, 如果您的 PATH 环境变量把 把系统目录放在前面的话。 如果使用 &os; 提供的 MIT security/krb5 port, 一定要仔细阅读 port 所安装的 /usr/local/share/doc/krb5/README.FreeBSD, 如果您想知道为什么通过 telnetdklogind 登录时会出现一些诡异的现象的话。 最重要地, incorrect permissions on cache file(缓存文件权限不正确) 行为需要使用 login.krb5 来进行验证, 才能够正确地修改转发凭据的属主。 除此之外, 还应修改 rc.conf 并加入下列配置: kerberos5_server="/usr/local/sbin/krb5kdc" kadmind5_server="/usr/local/sbin/kadmind" kerberos5_server_enable="YES" kadmind5_server_enable="YES" 这样做的原因是, MIT kerberos 会将可执行文件装到 /usr/local 之下。 缓解 <application>Kerberos</application> 的限制 Kerberos5 限制和不足 <application>Kerberos</application> 是一种 all-or-nothing 方式 在网络上启用的每个服务都必须进行修改以便让其能够配合 Kerberos 工作 (否则就只能使用其它方法来保护它们不受网络攻击的侵害), 如果不是这样, 则用户的凭据就有可能被窃取并再次使用。 一个例子是对所有的远程 shell (例如通过 rshtelnet) 启用了 Kerberos 但没有将使用明文验证的 POP3 邮件服务器 Kerberos化。 <application>Kerberos</application> 是为单用户工作站设计的 在多用户环境中 Kerberos 的安全性会被削弱。 这是因为它把 ticket 保存到 /tmp 目录中, 而这个目录可以被任何用户读取。 如果有用户与其它人同时共享一台计算机 (也就是 multi-user), 则这个用户的 ticket 就可能被其它用户窃取 (复制)。 可以通过使用 -c 文件名 这样的命令行选项, 或者(推荐的)改变 KRB5CCNAME 环境变量来避免这个问题, 但很少有人这么做。原则上, 将 ticket 保存到用户的 home 目录并简单地设置权限就能够缓解这个问题。 KDC 会成为单点崩溃故障点 根据设计, KDC 必须是安全的, 因为主密码数据库保存在它上面。 决不应该在 KDC上面运行其它服务, 而且还应确保它的物理安全。 由于 Kerberos 使用同一个密钥 (传说中的那个 密钥) 来加密所有的密码, 而将这个文件保存在 KDC, 因此其安全尤为重要 不过, 主密钥的泄露并没有想象中的那么可怕。 主密钥只用来加密 Kerberos 数据库以及产生随机数发生器的种子。 只要 KDC 是安全的, 即使攻击者拿到了主密钥也做不了什么。 另外, 如果 KDC 不可用 (例如由于拒绝服务攻击或网络故障) 则网络服务将由于验证服务无法进行而不能使用, 从而导致更大范围的拒绝服务攻击。 通过部署多个 KDC (一个主服务器, 配合一个或多个从服务器) 并采用经过仔细设计和实现的备用验证方式可以避免这种问题 (PAM 是一个不错的选择)。 <application>Kerberos</application> 的不足 Kerberos 允许用户、主机和服务之间进行相互认证。 但它并没有提供机制来向用户、主机或服务验证 KDC。 这意味着种过木马的程序,例如 kinit 有可能记录用户所有的用户名和密码。 尽管如此, 可以用类似 security/tripwire 这样的文件系统完整性检查工具来避免此类情况的发生。 相关资源和其它资料 Kerberos5 外部资源 The Kerberos FAQ Designing an Authentication System: a Dialog in Four Scenes RFC 1510, The Kerberos Network Authentication Service (V5) MIT Kerberos home page Heimdal Kerberos home page Tom Rhodes 作者 OpenSSL 安全 OpenSSL 许多用户可能并没有注意到 &os; 所附带的 OpenSSL 工具包的功能。 OpenSSL 提供了建立在普通的通讯层基础上的加密传输层; 这些功能为许多网络应用和服务程序所广泛使用。 OpenSSL 的一些常见用法包括加密邮件客户的身份验证过程, 基于 Web 的交易如信用卡等等。 许多 ports 如 www/apache13-ssl, 以及 mail/sylpheed-claws 等等都提供了编译进 OpenSSL 支持的方法。 绝大多数情况下 Ports Collection 会试图使用 security/openssl 除非明确地将 WITH_OPENSSL_BASE make 变量设置为 yes &os; 中附带的 OpenSSL 版本能够支持 安全套接字层 v2/v3 (SSLv2/SSLv3) 和 安全传输层 v1 (TLSv1) 三种网络协议, 并可作为通用的密码学函数库使用。 尽管 OpenSSL 支持 IDEA 算法, 但由于美国专利, 它在默认情况下是不编译的。 如果想使用它, 请查阅相应的授权, 如果认为授权可以接受, 则可以在 make.conf 中设置 MAKE_IDEA 为应用软件提供证书是 OpenSSL 最为常用的功能之一。 证书是一种能够确保公司或个人有效身份不被伪造的凭据。 如果证书没有被众多 权威发证机构, 或 CA 中的某一个确认, 则会产生一个警告。 权威发证机构通常是一家公司, 例如 VeriSign, 它能够通过签署来证明个人或公司证书的有效性。 这个过程是需要付费的, 当然, 这不是使用证书的必要条件; 然而, 这样做会让那些比较偏执的用户感到轻松。 生成证书 OpenSSL 生成证书 为了生成证书, 需要使用下面的命令: &prompt.root; openssl req -new -nodes -out req.pem -keyout cert.pem Generating a 1024 bit RSA private key ................++++++ .......................................++++++ writing new private key to 'cert.pem' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:US State or Province Name (full name) [Some-State]:PA Locality Name (eg, city) []:Pittsburgh Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Company Organizational Unit Name (eg, section) []:Systems Administrator Common Name (eg, YOUR name) []:localhost.example.org Email Address []:trhodes@FreeBSD.org Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:SOME PASSWORD An optional company name []:Another Name 请注意, 在 Common Name 提示后面我们输入的是一个域名。 这个提示要求输入服务器的名字, 这个名字今后将用于完成验证过程; 如果在这里输入域名以外的内容, 那么证书也就失去其意义了。 您还可以指定一些其他的选项, 比如证书的有效期, 以及使用的加密算法等等。 这些选项的完整列表, 可以在 &man.openssl.1; 联机手册中找到。 在您执行前述命令的目录中将生成两个文件。 证书申请, 即 req.pem, 可以发给一家发证机构, 它将验证您输入的凭据的真实性, 并对申请进行签名, 再把证书返还给您。 第二个文件的名字将是 cert.pem, 它包含了证书的私钥, 应被全力保护; 如果它落入别人手中, 则可以被用来伪造您 (或您的服务器)。 如果不需要来自 CA 的签名, 也可以创建自行签名的证书。 首先, 需要生成 RSA 密钥: &prompt.root; openssl dsaparam -rand -genkey -out myRSA.key 1024 接下来, 生成 CA 密钥: &prompt.root; openssl gendsa -des3 -out myca.key myRSA.key 然后用这个密钥来创建证书: &prompt.root; openssl req -new -x509 -days 365 -key myca.key -out new.crt 上述步骤将在当前目录中生成两个新文件: 一个是权威发证机构的签名文件, myca.key; 另一个是证书本身, new.crt。 这些文件应该放到同一个目录中, 一般而言, 推荐放到 /etc, 并且只允许 root 读取。 建议把权限设置为 0700, 这可以通过 chmod 工具来完成。 使用证书的一个例子 那么有了这些文件可以做些什么呢? 一个比较典型的用法是用来加密 Sendmail MTA 的通讯连接。 这可以解决用户通过本地 MTA 发送邮件时使用明文进行身份验证的问题。 这个用法可能并不完美, 因为某些 MUA 会由于没有在本地安装证书而向用户发出警告。 请参考那些软件的说明了解关于安装证书的信息。 下面的设置应添加到本地的 .mc 文件 dnl SSL Options define(`confCACERT_PATH',`/etc/certs')dnl define(`confCACERT',`/etc/certs/new.crt')dnl define(`confSERVER_CERT',`/etc/certs/new.crt')dnl define(`confSERVER_KEY',`/etc/certs/myca.key')dnl define(`confTLS_SRV_OPTIONS', `V')dnl 这里, /etc/certs/ 是准备用来在本地保存证书和密钥的位置。 最后, 需要重新生成本地的 .cf 文件。 这一工作可以简单地通过在 /etc/mail 目录中执行 make install 来完成。 接下来, 可以使用 make restart 来重新启动 Sendmail 服务程序。 如果一切正常的话, 在 /var/log/maillog 中就不会出现错误提示, Sendmail 也应该出现在进程列表中。 做一个简单的测试, 使用 &man.telnet.1; 来连接邮件服务器: &prompt.root; telnet example.com 25 Trying 192.0.34.166... Connected to example.com. Escape character is '^]'. 220 example.com ESMTP Sendmail 8.12.10/8.12.10; Tue, 31 Aug 2004 03:41:22 -0400 (EDT) ehlo example.com 250-example.com Hello example.com [192.0.34.166], pleased to meet you 250-ENHANCEDSTATUSCODES 250-PIPELINING 250-8BITMIME 250-SIZE 250-DSN 250-ETRN 250-AUTH LOGIN PLAIN 250-STARTTLS 250-DELIVERBY 250 HELP quit 221 2.0.0 example.com closing connection Connection closed by foreign host. 如果输出中出现了 STARTTLS 则说明一切正常。 Nik Clayton
nik@FreeBSD.org
撰写者
IPsec IPsec 上的 VPN 使用 FreeBSD 网关在两个被 Internet 分开的网络之间架设 VPN。 Hiten M. Pandya
hmp@FreeBSD.org
撰写者
理解 IPsec 这一节将指导您完成架设 IPsec, 并在一个包含了 FreeBSD 和 µsoft.windows; 2000/XP 机器的网络中使用它来进行安全的通讯的全过程。 为了配置 IPsec, 您应当熟悉如何编译一个定制的内核的一些概念 (参见 )。 IPsec 是一种建立在 Internet 协议 (IP) 层之上的协议。 它能够让两个或更多主机以安全的方式来通讯 (并因此而得名)。 FreeBSD IPsec 网络协议栈 基于 KAME 的实现, 它支持两种协议族, IPv4 和 IPv6。 FreeBSD 包括了采用 硬件加速的 IPsec 协议栈, 也称作 Fast IPsec, 它来自 OpenBSD。 它能够通过 &man.crypto.4; 子系统来利用加密硬件 (只要可能) 优化 IPSec 的性能。 这个子系统是新的, 暂时还不支持 KAME 版本的 IPsec 的全部功能。 此外, 为了启用硬件加速的 IPsec, 必须把下面的选项加入到内核配置中: 内核选项 FAST_IPSEC options FAST_IPSEC # new IPsec (cannot define w/ IPSEC) 需要注意的是, 目前还不能用 Fast IPsec 子系统完全替代 KAME 的 IPsec 实现。 请参见联机手册 &man.fast.ipsec.4; 以了解进一步的详情。 如果希望防火墙能够正确地跟踪到 &man.gif.4; 信道的状态, 您还需要在内核配置中启用 options IPSEC_FILTERGIF #filter ipsec packets from a tunnel IPsec ESP IPsec AH IPsec 包括了两个子协议: Encapsulated Security Payload (ESP), 保护 IP 包数据不被第三方介入, 通过使用对称加密算法 (例如 Blowfish、 3DES)。 Authentication Header (AH), 保护 IP 包头不被第三方介入和伪造, 通过计算校验和以及对 IP 包头的字段进行安全散列来实现。 随后是一个包含了散列值的附加头, 以便能够验证包。 ESPAH 可以根据环境的不同, 分别或者一同使用。 VPN 虚拟专用网 VPN IPsec 既可以用来直接加密主机之间的网络通讯 (也就是 传输模式); 也可以用来在两个子网之间建造 虚拟隧道 用于两个网络之间的安全通讯 (也就是 隧道模式)。 后一种更多的被称为是 虚拟专用网 (VPN)。 &man.ipsec.4; 联机手册提供了关于 FreeBSD 中 IPsec 子系统的详细信息。 要把 IPsec 支持放进内核, 应该在配置文件中加入下面的选项: 内核选项 IPSEC 内核选项 IPSEC_ESP options IPSEC #IP security options IPSEC_ESP #IP security (crypto; define w/ IPSEC) 内核选项 IPSEC_DEBUG 如果需要 IPsec 的调试支持, 还应增加: options IPSEC_DEBUG #debug for IP security
问题 由于对如何建立 VPN 并不存在标准, 因此 VPN 可以采用许多种不同的技术来实现, 每种技术都有其长处和弱点。 这篇文章讲展现一个具体的应用情景, 并为它设计了适合的 VPN。 情景: 两个网络都接入了 Internet, 希望像一个网络那样工作 VPN 创建 现有条件如下: 至少有两个不同的站点 每个站点都使用内部的 IP 两个站点都通过运行 FreeBSD 的网关接入 Internet。 每个网络上的网关至少有一个公网的 IP 地址。 网络的内部地址可以是公网或私有的 IP 地址, 这并不是问题。 如果需要, 还可以在网关上运行 NAT。 两个网络上的 IP 地址 不冲突。 虽然理论上可以通过 VPN 和 NAT 连用来使这种情况能够正常工作, 但那毫无疑问将是管理的噩梦。 如果您发现您正打算连接两个内网使用同一私有 IP 地址范围的网络 (例如它们都使用 192.168.1.x), 则其中的一个必须修改网络地址。 网络的拓扑结构如下: 网络 #1 [ 内部主机 ] 私有网络,192.168.1.2-254 [ Win9x/NT/2K ] [ UNIX ] | | .---[fxp1]---. 私有 IP, 192.168.1.1 | FreeBSD | `---[fxp0]---' 公网 IP, A.B.C.D | | -=-=- Internet -=-=- | | .---[fxp0]---. 公网 IP, W.X.Y.Z | FreeBSD | `---[fxp1]---' 私有 IP, 192.168.2.1 | | 网络 #2 [ Internal Hosts ] [ Win9x/NT/2K ] 私有网络, 192.168.2.2-254 [ UNIX ] 请注意两个公网 IP 地址。 在这篇文章的其余部分我将用这些字母来表示它们。 在文章中看到这些字母的时候, 请把它们换成自己的公网 IP 地址。 另外, 在内部, 两个网关都是使用的 .1 的 IP地址, 而两个网络使用了不同的私有 IP 地址 (相应地, 192.168.1.x192.168.2.x)。 所有私有网络上的机器都被配置为使用 .1 这台机器作为它们的网关。 我们希望, 从网络的观点看, 每一个网络上的机器都应该能够像在直接连接到同一路由器上一样看到对方网络上的机器 -- 尽管可能比路由器略慢一些, 并且有时会有丢包的现象。 这意味着 (举例来说), 主机 192.168.1.20 应该能够运行 ping 192.168.2.34 并且这能够透明地工作。 &windows; 机器应该能够看到其他网络上的机器, 浏览文件共享, 等等, 就像在本地网络上一样。 而且这些事情必须是安全的, 也就是说两个网络之间的通讯必须加密。 在两个网络之间建立 VPN 可以分为几步。 这些步骤包括: 在两个网络之间, 通过 Internet 建立一个 虚拟的 网络连接。 使用类似 &man.ping.8; 这样的工作来验证它是否正常工作。 在两个网络之间应用安全策略以保证它们之间的通讯被透明地加密和解密。 可以使用 &man.tcpdump.1; 或类似的工具来验证这一点。 在 FreeBSD 网关上配置其他软件, 让 &windows; 机器能够通过 VPN 看到另一个网络中的机器。 步骤 1: 建立并测试 <quote>虚拟的</quote> 网络连接 假设您目前已经登录到了网络 #1 的网关机上 (其公网 IP 地址是 A.B.C.D, 私网 IP 地址是 192.168.1.1), 则您可以执行 ping 192.168.2.1, 这是公网 IP 为 W.X.Y.Z 的私网地址。 需要做什么实现上述功能呢? 作为网关的机器需要知道如何能够到达 192.168.2.1。 换言之, 它需要一条通往 192.168.2.1 的路由。 私网 IP 地址, 例如 192.168.x 这样的地址是不应在 Internet 上面大量出现的。 因此, 发送到 192.168.2.1 的数据包将会封装到另外的包中。 这样的包对外展现的应该是来自 A.B.C.D, 并被发到 W.X.Y.Z 去。 这个过程称为 封装 一旦包到达了 W.X.Y.Z 就需要对其 拆封, 并传递给 192.168.2.1 可以把上述过程理解为在两个网络间建立了一个 隧道。 两个 隧道口 是 IP 地址 A.B.C.DW.X.Y.Z, 而隧道必须被告知哪些私有地址可以自由地在其中通过。 隧道被用来在公共的 Internet 上传递私有的 IP 数据。 在 FreeBSD 上, 隧道可以通过一般的网络接口, 或 gif 来建立。 您也许已经猜到了, 每一台网关机的 gif 接口需要配置四个 IP 地址; 两个是公网 IP 地址, 另两个则是私网 IP 地址。 对于 gif 设备的支持必须在两台网关机上编译进 &os; 内核。 可以通过添加下面的设置来达到目的: device gif 到两边的内核配置文件中, 并重新编译、 安装和启动它们。 配置隧道可以分为两步来完成。 首先隧道必须被告知外部的 (或公网的) IP 地址, 可以通过 &man.ifconfig.8; 来完成这步。 私网 IP 地址则必须使用 &man.ifconfig.8; 来配置。 在网络 #1 的网关机上可以通过下面的这些命令来配置隧道。 &prompt.root; ifconfig gif0 create &prompt.root; ifconfig gif0 tunnel A.B.C.D W.X.Y.Z &prompt.root; ifconfig gif0 inet 192.168.1.1 192.168.2.1 netmask 0xffffffff 在另一台网关上也需要执行同样的命令, 但 IP 地址的顺序相反。 &prompt.root; ifconfig gif0 create &prompt.root; ifconfig gif0 tunnel W.X.Y.Z A.B.C.D &prompt.root; ifconfig gif0 inet 192.168.2.1 192.168.1.1 netmask 0xffffffff 随后执行: ifconfig gif0 可以查看当前的配置情况。 例如, 在网络 #1 的网关上您应该能够看到: &prompt.root; ifconfig gif0 gif0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1280 tunnel inet A.B.C.D --> W.X.Y.Z inet 192.168.1.1 --> 192.168.2.1 netmask 0xffffffff 如您所见, 虽然到已经在物理地址 A.B.C.DW.X.Y.Z 之间建立起来, 而允许通过隧道的地址则是 192.168.1.1192.168.2.1 这个范围。 这同时会在两边机器的路由表中加入一项, 可以通过 netstat -rn 来观察。 来自网络 #1的网关机的输出如下。 &prompt.root; netstat -rn Routing tables Internet: Destination Gateway Flags Refs Use Netif Expire ... 192.168.2.1 192.168.1.1 UH 0 0 gif0 ... 正如 Flags 的值所显示的那样, 这是一个主机路由, 这意味着每一个网关都知道如何到达另一端的网关, 但它们现在还不知道如何到达对方的网络。 我们接下来立刻解决这个问题。 您很可能在两台机器上都在运行防火墙。 这需要作一些变动, 以便适应 VPN 的需要。 一般来说会希望两个网络相互传递数据包, 或者通过防火墙来隔离两边的危险。 如果您将防火墙配置为允许两边的网络传输通过, 则测试工作会简单不少。 随后您可以随时将限制变得更严格一些。 假如您在网关上使用 &man.ipfw.8; 则下面的命令 ipfw add 1 allow ip from any to any via gif0 将允许两端点的 VPN 数据通过, 而不影响其他防火墙策略。 很显然, 您需要在两个网关上都执行上述命令。 现在已经可以让两台机器相互 ping 了。 在 192.168.1.1 您应该能够正常执行 ping 192.168.2.1 并得到回应。 对于另一台网关来说也是一样。 然而, 到目前为止仍然还无法连上另一网络上的内部主机。 原因是路由 -- 尽管网关机知道如何到达对方那里, 但它们都不知道如何到达对方后面的网络。 要解决这个问题, 就必须在两边都添加一条静态路由。 可以在第一台网关上执行: route add 192.168.2.0 192.168.2.1 netmask 0xffffff00 这相当于是说 为了到达 192.168.2.0 子网的机器, 需要把包发给 192.168.2.1。 您需要在另一个网关上也执行类似的命令, 但使用 192.168.1.x 的地址。 来自一个网络上的 IP 访问现在能够抵达对面的网络了。 在两个网络之间建立 VPN 的过程已经完成了三分之二, 它现在已经是 虚拟的 网络, 然而它还不够专用。 您可以使用 &man.ping.8; 和 &man.tcpdump.1; 来进行测试, 并记录两边收发的数据包 tcpdump dst host 192.168.2.1 接下来登录到本机的另一个会话 ping 192.168.2.1 您将在输出中发现 16:10:24.018080 192.168.1.1 > 192.168.2.1: icmp: echo request 16:10:24.018109 192.168.1.1 > 192.168.2.1: icmp: echo reply 16:10:25.018814 192.168.1.1 > 192.168.2.1: icmp: echo request 16:10:25.018847 192.168.1.1 > 192.168.2.1: icmp: echo reply 16:10:26.028896 192.168.1.1 > 192.168.2.1: icmp: echo request 16:10:26.029112 192.168.1.1 > 192.168.2.1: icmp: echo reply 如您所见, ICMP 消息在收发的过程中都没有加密。 如果使用了 参数来运行 &man.tcpdump.1;, 甚至可以得到包中的更多信息以及其中的数据。 很明显这是不能接受的。 下一节将讨论如何让两个网络之间的连接更安全, 这件事是通过对通讯实施加密来完成的。 小结: 在两边的内核中配置 device gif 编辑网关 #1 上的 /etc/rc.conf 并将下面的行添加进去 (根据需要改 IP )。 gif_interfaces="gif0" gifconfig_gif0="A.B.C.D W.X.Y.Z" ifconfig_gif0="inet 192.168.1.1 192.168.2.1 netmask 0xffffffff" static_routes="vpn" route_vpn="192.168.2.0 192.168.2.1 netmask 0xffffff00" 在两台机器上编辑防火墙脚本 (/etc/rc.firewall, 或类似的名字) 在其中加入 ipfw add 1 allow ip from any to any via gif0 在网络 #2 的网关机上也对 /etc/rc.conf 做同样的修改, 注意把 IP 地址倒过来。 步骤 2: 对连接实施安全加固 为了加密连接通讯将用到 IPsec。 IPsec 提供了一种机制, 使得两台主机协商一个加密密钥, 并使用它加密之间的通讯。 在配置时有两个地方需要考虑。 必须有能够让两台主机协商所采用的加密方式的机制。 一旦双方确认了这机制, 则称他们之间建立了 安全关联 必须采用某种机制来指定哪些通讯需要加密。 很明显地, 通常并不需要所有的发出数据都被加密 -- 一般只需要加密在 VPN 上传输的那些数据。 这类决定哪些数据被加密的规则被称为 安全策略 安全关联和安全策略都是由内核来维护的, 并可以通过用户态的程序来修改。 在能够这样做之前, 首先需要配置内核来让它支持 IPsec 和安全载荷封装 (ESP) 协议。 配置下面的内核选项 内核选项 IPSEC options IPSEC options IPSEC_ESP 然后重新编译、 安装最后重新启动新的内核。 在继续进行设置之前, 您需要在两台网关上都进行同样的设置。 IKE 在建立安全关联时有两种选择。 一种方法是完全手工地在两台主机之间选择加密算法、 密钥等等, 另一种方法是使用实现了 Internet 密钥交换协议 (IKE) 的服务程序来帮您完成这些任务。 我们推荐后者。 不说别的, 它配置起来要容易得多。 IPsec security policies setkey 用 &man.setkey.8; 可以编辑和显示安全策略。 打个比方, setkey 之于内核的安全策略表, 就相当于 &man.route.8; 之于内核中的路由表。 setkey 还可以显示当前的安全关联, 这一点和 netstat -r 类似。 在 FreeBSD 上可供选择的用于管理安全关联的服务程序有很多。 这篇文章将介绍其中的一种, racoon —。 它可以从 &os; 的 Ports collection 中的 security/ipsec-tools 安装。 racoon racoon 软件, 必须在两台网关机上都运行。 需要配置 VPN 另一端的 IP, 以及一个密钥 (这个密钥可以任意选择, 但两个网关上的密钥必须一致)。 两端的服务程序将相互通讯, 并确认它们各自的身份 (使用刚刚配置的密钥) 然后服务程序将生成一个新的密钥, 并用它来加密 VPN 上的数据通讯。 它们定期地改变密钥, 因此即使供给者破解了一个密钥 (虽然这在理论上并不十分可行) 他也得不到什么 -- 破解密钥的时候, 已经产生一组新的密钥了。 racoon 的配置文件是存放在 ${PREFIX}/etc/racoon 目录中的。 在那里应该能够找到一个配置文件, 不需要修改太多的设置。 raccon 配置的另一部分, 也就是需要修改的内容, 是 预先配置的共享密钥 默认的 racoon 配置应该可以在 ${PREFIX}/etc/racoon/psk.txt 这个文件中找到。 需要强调的是, 这个密钥 并非 用于加密 VPN 连接的密钥, 他们只是密钥管理服务程序用以信任对方的一种凭据。 psk.txt 包含了需要打交道的每一个远程站点。 在本例中一共有两个站点, 每一个 psk.txt 都只有一行 (因为每个 VPN 接入点都只和一个端点连接)。 在网关机 #1 上应该是: W.X.Y.Z secret 这包括了远程站点的 公网 IP 地址, 空格, 以及提供秘密的字符串。 很明显不应使用 secret 作为实际的密钥 -- 通常的口令选择策略在这里也适用。 在网关 #2 上对应的配置是 A.B.C.D secret 也就是说, 对面端的公网 IP 地址, 以及同样的密钥。 psk.txt 的权限必须是 0600 (也就是说, 只有 root 能够读写) 否则 racoon 将不能运行。 两边的机器上都必须执行 racoon。 另外, 还需要增加一些防火墙规则来允许 IKE 通讯通过, 它是通过 UDP 在 ISAKMP (Internet 安全关联密钥管理协议) 端口上运行的协议。 再次强调, 这个规则应该在规则集尽可能早的位置出现。 ipfw add 1 allow udp from A.B.C.D to W.X.Y.Z isakmp ipfw add 1 allow udp from W.X.Y.Z to A.B.C.D isakmp 一旦 racoon 开始运行, 就可以开始测试让网关进行相互的 ping 了。 此时连接还没有进行加密, 但 racoon 将在两个主机之间建立安全关联 -- 这可能需要一段时间, 对您来说, 具体的现象则是在 ping 命令开始响应之前会有短暂的延迟。 一旦安全关联建立之后, 就可以使用 &man.setkey.8; 来查看它了。 在两边的网关上执行 setkey -D 就可以看到安全关联的相关信息了。 现在只完成了一半的工作。 另一半是设置安全策略。 想要完成一个有判断力的安全策略, 首先要看我们已经完成的步骤。 接下来的讨论针对连接的两端。 您所发出的每一个 IP 包都包括一个包头, 其内容是和这个包有关的描述性数据。 包头包括了包的来源和目的的 IP 地址。 正如我们所了解的那样, 私有 IP 地址, 例如 192.168.x.y 这样的地址范围, 不应该出现在 Internet 的公网上。 因此, 他们必须首先封装到别的包中。 包的来源或目的如果是私有 IP 地址, 则必须替换成公网 IP 地址。 因此如果发出的包类似下面这样: .-------------------. | Src: 192.168.1.1 | | Dst: 192.168.2.1 | | <其他头信息 > | +-------------------+ | <包数据 > | `-------------------' 随后它将被封装进另一个包中, 像下面这样: .--------------------------. | Src: A.B.C.D | | Dst: W.X.Y.Z | | <附加头信息 > | +--------------------------+ | .----------------------. | | | Src: 192.168.1.1 | | | | Dst: 192.168.2.1 | | | | <附加头信息 > | | | +----------------------+ | | | <包数据 > | | | `----------------------' | `--------------------------' 封装过程是在 gif 设备上完成的。 如上图所示, 包现在有了外部的实际 IP 地址, 而原始的包则被封装到里面作为数据。 这个包将通过 Internet 传递。 很明显地, 我们希望 VPN 之间的通讯是加密的。 用于言来描述大致是: 如果包从 A.B.C.D 发出且其目的地是 W.X.Y.Z, 则通过必要的安全关联进行加密。 如果包来自 W.X.Y.Z 且其目的地是 A.B.C.D, 则通过必要的安全关联进行解密。 这已经很接近了, 但还不够正确。 如果这么做的话, 所有来自和发到 W.X.Y.Z 的包, 无论是否属于 VPN 通讯都会被加密。 这可能并不是您所希望的, 因此正确的安全策略应该是 如果包从 A.B.C.D 发出, 且封装了其他的包, 其目的地是 W.X.Y.Z, 则通过必要的安全关联进行加密。 如果包来自 W.X.Y.Z, 且封装了其他的包, 其目的地是 A.B.C.D, 则通过必要的安全关联进行解密。 一个很小, 但却必要的改动。 安全策略也是通过 &man.setkey.8; 设置的。 &man.setkey.8; 提供了一种用于配置策略的语言。 可以直接在 stdin 上输入策略, 或通过 选项来指定一个包含配置命令的文件。 网关 #1 上的配置 (其 IP 地址是 A.B.C.D) 强制将所有到 W.X.Y.Z 的通讯进行加密的配置是: spdadd A.B.C.D/32 W.X.Y.Z/32 ipencap -P out ipsec esp/tunnel/A.B.C.D-W.X.Y.Z/require; 把这些命令放到一个文件 (例如 /etc/ipsec.conf) 然后执行 &prompt.root; setkey -f /etc/ipsec.conf 会告诉 &man.setkey.8; 我们希望把规则加入到安全策略数据库中。 命令的其它部分指定了什么样的包能够匹配这规则。 A.B.C.D/32W.X.Y.Z/32 是用于指定规则能够匹配的网络或主机的 IP 地址和掩码。 本例中, 希望应用到两个主机之间的通讯上。 则告诉内核这规则只应被用于封装其他包的那些数据包。 表示策略是针对发出的包的, 而 则表示需要对数据包进行加密。 第二行指定了如何加密。 是将要使用的协议, 而 则表示包应该进一步封装进一个 IPsec 包里面。 反复使用 A.B.C.DW.X.Y.Z 用来选择所用的安全关联 而最后的 则强制所有匹配这规则的包都被加密。 上面的规则只匹配了发出的包。 接下来需要配置类似的匹配进入包的规则。 spdadd W.X.Y.Z/32 A.B.C.D/32 ipencap -P in ipsec esp/tunnel/W.X.Y.Z-A.B.C.D/require; 请注意本例中 代替了 并且 IP 地址的顺序也相反。 在另一个网关上 (其公网 IP 地址是 W.X.Y.Z) 也需要类似的规则。 spdadd W.X.Y.Z/32 A.B.C.D/32 ipencap -P out ipsec esp/tunnel/W.X.Y.Z-A.B.C.D/require; spdadd A.B.C.D/32 W.X.Y.Z/32 ipencap -P in ipsec esp/tunnel/A.B.C.D-W.X.Y.Z/require; 最后是添加允许 ESP 和 IPENCAP 包进出的防火墙规则。 这些规则需要在两边分别设置。 ipfw add 1 allow esp from A.B.C.D to W.X.Y.Z ipfw add 1 allow esp from W.X.Y.Z to A.B.C.D ipfw add 1 allow ipencap from A.B.C.D to W.X.Y.Z ipfw add 1 allow ipencap from W.X.Y.Z to A.B.C.D 由于规则的对称性, 因此可以在两台网关上使用同样的规则。 发出的包如下图所示: .------------------------------. --------------------------. | Src: A.B.C.D | | | Dst: W.X.Y.Z | | | <other header info> | | Encrypted +------------------------------+ | packet. | .--------------------------. | -------------. | contents | | Src: A.B.C.D | | | | are | | Dst: W.X.Y.Z | | | | completely | | <other header info> | | | |- secure | +--------------------------+ | | Encap'd | from third | | .----------------------. | | -. | packet | party | | | Src: 192.168.1.1 | | | | Original |- with real | snooping | | | Dst: 192.168.2.1 | | | | packet, | IP addr | | | | <other header info> | | | |- private | | | | +----------------------+ | | | IP addr | | | | | <packet data> | | | | | | | | `----------------------' | | -' | | | `--------------------------' | -------------' | `------------------------------' --------------------------' 当 VPN 数据被远端接到时, 它将首先被解密 (使用 racoon 协商得到的安全关联)。 然后它们将进入 gif 接口, 并在那里展开第二层, 直到只剩下最里层的包, 并将其转发到内网上。 可以通过与之前同样的 &man.ping.8; 命令来测试安全性。 首先登录到 A.B.C.D 网关上并执行: tcpdump dst host 192.168.2.1 在同一主机上登录另一会话, 执行 ping 192.168.2.1 此时的输出应该是: XXX tcpdump output 如您看到的, &man.tcpdump.1; 给出的将是 ESP 包。 假如您想查看它们的内容可以使用 option 选项, 您将 (显然地) 看到一些乱码, 因为传输过程实施了加密。 祝贺您。 您已经完成了两个远程站点之间的 VPN 的架设工作。 小结 将两边的内核配置加入: options IPSEC options IPSEC_ESP 安装 security/ipsec-tools。 编辑两台网关上的 ${PREFIX}/etc/racoon/psk.txt 并添加远程主机的 IP 和共享的密钥。 文件的权限应该是 0600。 将下面的设置加入两台主机的 /etc/rc.conf 中: ipsec_enable="YES" ipsec_file="/etc/ipsec.conf" 在两个网关上都建立 /etc/ipsec.conf 并添加必要的 spdadd。 在网关 #1 上是: spdadd A.B.C.D/32 W.X.Y.Z/32 ipencap -P out ipsec esp/tunnel/A.B.C.D-W.X.Y.Z/require; spdadd W.X.Y.Z/32 A.B.C.D/32 ipencap -P in ipsec esp/tunnel/W.X.Y.Z-A.B.C.D/require; 在网关 #2 上则是: spdadd W.X.Y.Z/32 A.B.C.D/32 ipencap -P out ipsec esp/tunnel/W.X.Y.Z-A.B.C.D/require; spdadd A.B.C.D/32 W.X.Y.Z/32 ipencap -P in ipsec esp/tunnel/A.B.C.D-W.X.Y.Z/require; 添加防火墙规则以允许 IKE, ESP, 和 IPENCAP 通讯能够到达各自的主机: ipfw add 1 allow udp from A.B.C.D to W.X.Y.Z isakmp ipfw add 1 allow udp from W.X.Y.Z to A.B.C.D isakmp ipfw add 1 allow esp from A.B.C.D to W.X.Y.Z ipfw add 1 allow esp from W.X.Y.Z to A.B.C.D ipfw add 1 allow ipencap from A.B.C.D to W.X.Y.Z ipfw add 1 allow ipencap from W.X.Y.Z to A.B.C.D 前面的两步应该足以让 VPN 运转起来了。 两个网络上的机器都应该能通过 IP 来访问对方, 而所有的通讯都被自动地进行加密。
Chern Lee 原著 OpenSSH OpenSSH 安全 OpenSSH OpenSSH 是一组用于安全地访问远程计算机的连接工具。 它可以作为 rloginrsh rcp 以及 telnet 的直接替代品使用。 更进一步, 其他任何 TCP/IP 连接都可以通过 SSH 安全地进行隧道/转发。 OpenSSH 对所有的传输进行加密, 从而有效地阻止了窃听、 连接劫持, 以及其他网络级的攻击。 OpenSSH 由 OpenBSD project 维护, 它基于 SSH v1.2.12 并包含了最新的错误修复和更新。 它同时兼容 SSH 协议的 1 和 2 两个版本。 使用 OpenSSH 的好处 一般说来, 在使用 &man.telnet.1; 或 &man.rlogin.1; 时, 数据是以未经加密的明文的形式发送的。 这样一来, 在客户机和服务器之间的网络上运行的听包程序, 便可以在会话中窃取到传输的用户名/密码和数据。 OpenSSH 提供了多种的身份验证和加密方法来防止这种情况的发生。 启用 sshd OpenSSH 启用 sshd 的启用是作为 &os; 安装中 Standard 安装过程中的一步来进行的。 要查看 sshd 是否已被启用, 请检查 rc.conf 文件中的: sshd_enable="YES" 这表示在下次系统启动时加载 OpenSSH 的服务程序 &man.sshd.8;。 此外, 也可以手动使用 &man.rc.8; 脚本 /etc/rc.d/sshd 来启动 OpenSSH /etc/rc.d/sshd start SSH 客户 OpenSSH 客户 &man.ssh.1; 的工作方式和 &man.rlogin.1; 非常类似。 &prompt.root; ssh user@example.com Host key not found from the list of known hosts. Are you sure you want to continue connecting (yes/no)? yes Host 'example.com' added to the list of known hosts. user@example.com's password: ******* 登录过程和使用 rlogintelnet 建立的会话非常类似。 在连接时, SSH 会利用一个密钥指纹系统来验证服务器的真实性。 只有在第一次连接时, 用户会被要求输入 yes。 之后的连接将会验证预先保存下来的密钥指纹。 如果保存的指纹与登录时接收到的不符, 则将会给出警告。 指纹保存在 ~/.ssh/known_hosts 中, 对于 SSH v2 指纹, 则是 ~/.ssh/known_hosts2 默认情况下, 较新版本的 OpenSSH 只接受 SSH v2 连接。 如果能用版本 2 则客户程序会自动使用, 否则它会返回使用版本 1 的模式。 此外, 也可以通过命令行参数 来相应地强制使用版本 1 或 2。 保持客户端的版本 1 能力是为了考虑较早版本的兼容性。 安全复制 OpenSSH 安全复制 scp &man.scp.1; 命令和 &man.rcp.1;; 的用法类似, 它用于将文件复制到远程的机器上, 或复制过来, 区别是它是安全的。 &prompt.root; scp user@example.com:/COPYRIGHT COPYRIGHT user@example.com's password: ******* COPYRIGHT 100% |*****************************| 4735 00:00 &prompt.root; 由于先前的例子中已经保存了指纹, 使用 &man.scp.1; 时会自动地加以验证。 &man.scp.1; 使用的参数同 &man.cp.1; 类似。 第一个参数是一个或一组文件, 然后是复制的目标。 由于文件是通过 SSH 在网上传递的, 因此某些文件的名字需要写成 配置 OpenSSH 配置 针对 OpenSSH 服务程序和客户端的系统级配置文件在 /etc/ssh 目录中。 ssh_config 用于配置客户端的设定, 而 sshd_config 则用于配置服务器端。 另外 (默认是 /usr/sbin/sshd), 以及 这两个 rc.conf 选项提供了更多的配置选择。 ssh-keygen 用于取代口令的一种方法是使用 &man.ssh-keygen.1; 来生成 DSA 或 RSA 密钥对用于验证用户的身份: &prompt.user; ssh-keygen -t dsa Generating public/private dsa key pair. Enter file in which to save the key (/home/user/.ssh/id_dsa): Created directory '/home/user/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/user/.ssh/id_dsa. Your public key has been saved in /home/user/.ssh/id_dsa.pub. The key fingerprint is: bb:48:db:f2:93:57:80:b6:aa:bc:f5:d5:ba:8f:79:17 user@host.example.com &man.ssh-keygen.1; 会生成一个包含公私钥对用于验证身份。 私钥将保存到 ~/.ssh/id_dsa~/.ssh/id_rsa, 而公钥则被存放到 ~/.ssh/id_dsa.pub~/.ssh/id_rsa.pub, 文件名取决于您选择的 DSARSA 密钥类型。 RSA 或者 DSA 公钥必须被存放到远程机器上的 ~/.ssh/authorized_keys 才能够使系统正确运转。 这将允许从远程连接时以基于 SSH 密钥的验证来代替口令验证。 如果在 &man.ssh-keygen.1; 中使用了通行字, 则每次使用私钥时都需要输入它。 &man.ssh-agent.1; 能够缓解多次输入长通行字的压力, 并将在接下来的 予以详述。 选项和配置文件可能随 OpenSSH 的版本不同而不同; 为了避免出现问题, 您应参考 &man.ssh-keygen.1; 联机手册。 这将使到远程机器的连接基于 SSH 密钥而不是口令。 如果在运行 &man.ssh-keygen.1; 时使用了通行字, 每次使用私钥的时候用户都将被要求输入通行字。 &man.ssh-agent.1; 能够减缓重复输入较长通行字的负担, 有关更详细的探究在 下一节 . 随着你系统上的 OpenSSH 版本的不同,各种选项和配置文件也会不同; 为了避免此类问题, 你需要参阅 &man.ssh-keygen.1; 联机手册。 ssh-agent 和 ssh-add &man.ssh-agent.1; 和 &man.ssh-add.1; 这两个工具, 提供了一种将 SSH 秘钥加载到内存中以便使用, 而不必每次都输入通行字的方法。 &man.ssh-agent.1; 工具能够使用加载到其中的私钥来处理验证过程。 &man.ssh-agent.1; 应被用于启动另一个应用程序。 最基本的用法是, 使用它来启动 shell, 而高级一些的用法则是用它来启动窗口管理器。 要在 shell 中使用 &man.ssh-agent.1;, 首先应把 shell 作为参数来启动它。 随后, 应通过 &man.ssh-add.1; 并输入通行字, 来向它提供身份验证信息。 一旦这些步骤都做完了, 用户就应该能够 &man.ssh.1; 到任何一个安装了对应公钥的机器了。 例如: &prompt.user; ssh-agent csh &prompt.user; ssh-add Enter passphrase for /home/user/.ssh/id_dsa: Identity added: /home/user/.ssh/id_dsa (/home/user/.ssh/id_dsa) &prompt.user; 要在 X11 中使用 &man.ssh-agent.1;, 调用 &man.ssh-agent.1; 的过程应置于 ~/.xinitrc 之中。 这将把 &man.ssh-agent.1; 服务提供给所有在 X11 中运行的程序。 下面是一个 ~/.xinitrc 文件的实例: exec ssh-agent startxfce4 这将启动 &man.ssh-agent.1;, 而后者将在每次 X11 启动时运行 XFCE。 作完这些之后就可以重启 X11 以便使修改生效。 随后您就可以运行 &man.ssh-add.1; 来加载全部 SSH 密钥了。 SSH 隧道 OpenSSH 隧道 OpenSSH 能够创建隧道以便用加密的会话来封装其他协议。 下面的命令告诉 &man.ssh.1; 为 telnet 创建一个隧道: &prompt.user; ssh -2 -N -f -L 5023:localhost:23 user@foo.example.com &prompt.user; 上述 ssh 命令使用了下面这些选项: 强制 ssh 使用第2版的协议 (如果需要和较老的 SSH 一同工作请不要使用这个选项)。 表示不使用命令行, 或者说只使用隧道。 如果省略, ssh 将同时初始化会话。 强制 ssh 在后台执行。 表示产生一条 本地端口:远程主机:远程端口 形式的隧道。 远程 SSH 服务器。 SSH 隧道通过监听 localhost 上面指定端口来完成工作。 它将把本机主机/端口上接收到的连接通过 SSH 连接转发到远程主机/端口。 本例中, 位于 localhost5023 端口 被用于转发 localhost 的连接到远程主机的 23 端口。 由于 23telnet 使用的, 因此它将通过 SSH 隧道完成 telnet 会话。 这可以用来封装任意不安全的 TCP 协议, 例如 SMTP、 POP3、 FTP等等。 使用 SSH 为 SMTP 创建安全隧道 &prompt.user; ssh -2 -N -f -L 5025:localhost:25 user@mailserver.example.com user@mailserver.example.com's password: ***** &prompt.user; telnet localhost 5025 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. 220 mailserver.example.com ESMTP 这可以与 &man.ssh-keygen.1; 以及额外的用户帐号配合来建立一个更透明的 SSH 隧道环境。 密钥可以被用在需要输入口令的地方, 而且可以为不同的用户配置不同的隧道。 实用的 SSH 通道例子 加强 POP3 服务的安全 工作时, 有一个允许外来连接的 SSH 服务器。 同一个办公网络中有一个邮件服务器提供 POP3 服务。 这个网络, 或从您家到办公室的网络可能不, 或不完全可信。 基于这样的原因, 您需要以安全的方式来查看邮件。 解决方法是创建一个到办公室 SSH 服务器的连接, 并通过这个连接来访问 POP3 服务: &prompt.user; ssh -2 -N -f -L 2110:mail.example.com:110 user@ssh-server.example.com user@ssh-server.example.com's password: ****** 当这个通道连上时, 您可以把 POP3 请求发到 localhost 端口 2110。 这个连接将通过通道安全地转发到 mail.example.com 绕过严厉的防火墙 一些大脑长包的网络管理员会使用一些极端的防火墙策略, 不仅过滤进入的连接, 而且也过滤连出的连接。 一些时候您可能只能连接远程机器 22 端口,以及 80 端口用来进行 SSH 和网页浏览。 您可能希望访问一些其它的 (也许与工作无关的) 服务, 例如提供音乐的 Ogg Vorbis 流媒体服务器。 如果 Ogg Vorbis server 在 22 或 80 端口以外的端口播放音乐, 则您将无法访问它。 解决方法是建立一个到您的网络的防火墙之外的网络上的 SSH 服务器, 并通过它提供的通道连接到 Ogg Vorbis 服务器上。 &prompt.user; ssh -2 -N -f -L 8888:music.example.com:8000 user@unfirewalled-system.example.org user@unfirewalled-system.example.org's password: ******* 现在您可以把客户程序指定到 localhost 的 8888 端口, 它将把请求转发给 music.example.com 的 8000 端口, 从而绕过防火墙。 允许用户登录 <varname>AllowUsers</varname> 选项 通常限制哪些用户能够登录, 以及从何处登录会是好主意。 采用 AllowUsers 选项能够方便地达到这一目的。 例如, 想要只允许 root 用户从 192.168.1.32 登录, 就可以在 /etc/ssh/sshd_config 文件中加入下述设置: AllowUsers root@192.168.1.32 要允许用户 admin 从任何地方登录, 则只需列出用户名: AllowUsers admin 可以在同一行指定多个用户, 例如: AllowUsers root@192.168.1.32 admin 列出需要登录机器的用户很重要; 否则他们将被锁在外面。 在完成对 /etc/ssh/sshd_config 的修改之后您必须告诉 &man.sshd.8; 重新加载其配置文件, 方法是执行: &prompt.root; /etc/rc.d/sshd reload 进一步的资料 OpenSSH &man.ssh.1; &man.scp.1; &man.ssh-keygen.1; &man.ssh-agent.1; &man.ssh-add.1; &man.ssh.config.5; &man.sshd.8; &man.sftp-server.8; &man.sshd.config.5; Tom Rhodes 作者 ACL 文件系统访问控制表 与文件系统在其他方面的加强, 如快照等一道, &os; 5.0 及更高版本提供了通过文件系统访问控制表 (ACL) 实现的安全机制。 访问控制表以高度兼容 (&posix;.1e) 的方式扩展了标准的 &unix; 权限模型。 这一特性使得管理员能够利用其优势设计更为复杂的安全模型。 如果想为 UFS 文件系统启用 ACL 支持, 则需要添加下列选项: options UFS_ACL 并重新编译内核。 如果没有将这个选项编译进内核, 则在挂接支持 ACL 的文件系统时将会收到警告。 这个选项在 GENERIC 内核中已经包含了。 ACL 依赖于在文件系统上启用扩展属性。 在新一代的 &unix; 文件系统, UFS2 中内建了这种支持。 UFS1 上配置扩展属性需要比 UFS2 更多的管理开销。 而且, 在 UFS2 上的扩展属性的性能也有极大的提高。 因此, 如果想要使用访问控制表, 推荐使用 UFS2 而不是 UFS1 ACL 可以在挂接时通过选项 来启动, 它可以加入 /etc/fstab。 另外, 也可以通过使用 &man.tunefs.8; 修改超级块中的 ACL 标记来持久性地设置自动的挂接属性。 一般而言, 后一种方法是推荐的做法, 其原因是: 挂接时的 ACL 标记无法被重挂接 (&man.mount.8; ) 改变, 只有完整地 &man.umount.8; 并做一次新的 &man.mount.8; 才能改变它。 这意味着 ACL 状态在系统启动之后就不可能在 root 文件系统上发生变化了。 另外也没有办法改变正在使用的文件系统的这个状态。 在超级块中的设置将使得文件系统总被以启用 ACL 的方式挂接, 即使在 fstab 中的对应项目没有作设置, 或设备顺序发生变化时也是如此。 这避免了不慎将文件系统以没有启用 ACL 的状态挂接, 从而避免没有强制 ACL 这样的安全问题。 可以修改 ACL 行为, 以允许在没有执行一次全新的 &man.mount.8; 的情况下启用它, 但我们认为, 不鼓励在未启用 ACL 时这么做是有必要的, 因为如果启用了 ACL, 然后关掉它, 然后在没有刷新扩展属性的情况下重新启用它是很容易造成问题的。 一般而言, 一旦启用了文件系统的 ACL 就不应该再关掉它, 因为此时的文件系统的保护措施可能和用户所期待的样子不再兼容, 而重新启用 ACL 将重新把先前的 ACL 附着到文件上, 而由于它们的权限发生了变化, 就很可能造成无法预期的行为。 在查看目录时, 启用了 ACL 的文件将在通常的属性后面显示 + (加号)。 例如: drwx------ 2 robert robert 512 Dec 27 11:54 private drwxrwx---+ 2 robert robert 512 Dec 23 10:57 directory1 drwxrwx---+ 2 robert robert 512 Dec 22 10:20 directory2 drwxrwx---+ 2 robert robert 512 Dec 27 11:57 directory3 drwxr-xr-x 2 robert robert 512 Nov 10 11:54 public_html 这里我们看到了 directory1directory2, 以及 directory3 目录使用了 ACL。 而 public_html 则没有。 使用 <acronym>ACL</acronym> 文件系统 ACL 可以使用 &man.getfacl.1; 工具来查看。 例如, 如果想查看 testACL 设置, 所用的命令是: &prompt.user; getfacl test #file: #owner:1001 #group:1001 user::rw- group::r-- other::r-- 要修改这个文件上的 ACL 设置, 则需要使用 &man.setfacl.1; 工具。 例如: &prompt.user; setfacl -k test 参数将把所有当前定义的 ACL 从文件或文件系统中删除。 一般来说应该使用 因为它会保持让 ACL 正常工作的那些项不变。 &prompt.user; setfacl -m u:trhodes:rwx,group:web:r--,o::--- test 在前面的命令中, -m 选项被用来修改默认的 ACL 项。由于已经被先前的命令 删除,因此没有预先定义的项,于是默认的选项被恢复,并附加上指定的选项。 请小心地检查,如果您加入了一个不存在的用户或组,那么将会在 stdout 得到一条 Invalid argument 的错误提示。 Tom Rhodes Contributed by Portaudit 监视第三方安全问题 过去几年中, 安全领域在如何处理漏洞的评估方面取得了长足的进步。 几乎每一个操作系统都越来越多地安装和配置了第三方工具, 而系统被入侵的威胁也随之增加。 漏洞的评估是安全的一个关键因素, 尽管 &os; 会发布基本系统的安全公告, 然而为每一个第三方工具都发布安全公告则超出了 &os; Project 的能力。 在这一前提下, 一种减轻第三方漏洞的威胁, 并警告管理员存在已知的安全问题的方法也就应运而生。 名为 Portaudit 的 &os; 附加工具能够帮助您达成这一目的。 ports-mgmt/portaudit port 会下载一个数据库, 这一数据库是由 &os; Security Team 和 ports 开发人员维护的, 其中包含了已知的安全问题。 要开始使用 Portaudit, 需要首先从 Ports Collection 安装它: &prompt.root; cd /usr/ports/ports-mgmt/portaudit && make install clean 在安装过程中, &man.periodic.8; 的配置文件将被修改, 以便让 Portaudit 能够在每天的安全审计过程中运行。 一定要保证发到 root 帐号的每日安全审计邮件确实有人在读。 除此之外不需要进行更多的配置了。 安装完成之后, 管理员可以通过下面的命令来更新数据库, 并查看目前安装的软件包中所存在的已知安全漏洞: &prompt.root; portaudit -Fda 由于每天执行 &man.periodic.8; 时都会自动更新数据库, 因此, 运行这条命令是可选的。 在这里只是作为例子给出。 在任何时候, 如果希望对通过 Ports Collection 安装的第三方软件工具进行审计, 管理员都可以使用下面的命令: &prompt.root; portaudit -a 针对存在漏洞的软件包, Portaudit 将生成类似下面的输出: Affected package: cups-base-1.1.22.0_1 Type of problem: cups-base -- HPGL buffer overflow vulnerability. Reference: <http://www.FreeBSD.org/ports/portaudit/40a3bca2-6809-11d9-a9e7-0001020eed82.html> 1 problem(s) in your installed packages found. You are advised to update or deinstall the affected package(s) immediately. 通过访问上面给出的 URL, 管理员能够了解关于那个漏洞的进一步信息。 这些信息通常包括受到影响的 &os; Port 版本, 以及其他可能包含安全公告的网站。 简而言之, Portaudit 是一个强大的工具, 并能够配合 Portupgrade port 来非常有效地工作。 Tom Rhodes 作者 FreeBSD 安全公告 &os; 安全公告 像其它具有产品级品质的操作系统一样, &os; 会发布 安全公告。 通常这类公告会只有在相应的发行版本已经正确地打过补丁之后发到安全邮件列表并在勘误中说明。 本节将介绍什么是安全公告, 如何理解它, 以及为系统打补丁的具体步骤。 安全公告看上去是什么样子? &os; 安全公告的样式类似下面的范例, 这一例子来自 &a.security-notifications.name; 邮件列表。 ============================================================================= &os;-SA-XX:XX.UTIL Security Advisory The &os; Project Topic: denial of service due to some problem Category: core Module: sys Announced: 2003-09-23 Credits: Person@EMAIL-ADDRESS Affects: All releases of &os; &os; 4-STABLE prior to the correction date Corrected: 2003-09-23 16:42:59 UTC (RELENG_4, 4.9-PRERELEASE) 2003-09-23 20:08:42 UTC (RELENG_5_1, 5.1-RELEASE-p6) 2003-09-23 20:07:06 UTC (RELENG_5_0, 5.0-RELEASE-p15) 2003-09-23 16:44:58 UTC (RELENG_4_8, 4.8-RELEASE-p8) 2003-09-23 16:47:34 UTC (RELENG_4_7, 4.7-RELEASE-p18) 2003-09-23 16:49:46 UTC (RELENG_4_6, 4.6-RELEASE-p21) 2003-09-23 16:51:24 UTC (RELENG_4_5, 4.5-RELEASE-p33) 2003-09-23 16:52:45 UTC (RELENG_4_4, 4.4-RELEASE-p43) 2003-09-23 16:54:39 UTC (RELENG_4_3, 4.3-RELEASE-p39) CVE Name: CVE-XXXX-XXXX For general information regarding FreeBSD Security Advisories, including descriptions of the fields above, security branches, and the following sections, please visit http://www.FreeBSD.org/security/. I. Background II. Problem Description III. Impact IV. Workaround V. Solution VI. Correction details VII. References Topic(标题) 一栏说明了问题到底是什么。 它基本上是对所发现的安全问题及其所涉及的工具的描述。 Category (分类) 是指系统中受到影响的组件, 这一栏可能是 corecontrib, 或者 ports 之一。 core 分类表示安全弱点影响到了 &os; 操作系统的某个核心组件。 contrib 分类表示弱点存在于某个捐赠给 &os; Project 的软件, 例如 sendmail。 最后是 ports, 它表示该弱点影响了 Ports Collection 中的某个第三方软件。 Module(模块) 一栏给出了组件的具体位置, 例如 sys。 在这个例子中, 可以看到 sys 模块是存在问题的; 因此, 这个漏洞会影响某个在内核中的组件。 Announced(发布时间) 一栏反映了与安全公告有关的数据是什么时候公之于众的。 这说明安全团队已经证实问题确实存在, 而补丁已经写入了 &os; 的代码库。 Credits(作者) 一栏给出了注意到问题存在并报告它的个人或团体。 The Affects(影响范围) 一栏给出了 &os; 的哪些版本存在这个漏洞。 对于内核来说, 检视受影响的文件上执行的 ident 输出可以帮助确认文件版本。 对于 ports, 版本号在 /var/db/pkg 里面的 port 的名字后面列出。 如果系统没有与 &os; CVS 代码库同步并每日构建, 它很可能是有问题的。 Corrected(修正时间) 一栏给出了发行版本中修正问题的具体日期、时间和时差。 在公共漏洞数据库 (Common Vulnerabilities Database) 系统中预留的, 用于查看漏洞的标识信息。 Background(技术背景) 一栏提供了受影响的组件的作用。 多数时候这一部分会说明为什么 &os; 中包含了它, 它的作用, 以及它的一些原理。 Problem Description(问题描述) 一栏深入阐述安全漏洞的技术细节。 这部分有时会包括有问题的代码相关的详细情况, 甚至是这个部件如何能够被恶意利用并打开漏洞的细节。 Impact(影响) 一栏描述了问题能够造成的影响类型。 例如, 可能导致拒绝服务攻击, 权限提升, 甚至导致得到超级用户的权限。 Workaround(应急方案) 一栏给出了系统管理员在暂时无法升级系统时可以采取的临时性对策。 这些原因可能包括时间限制, 网络资源的限制, 或其它因素。 不过无论如何, 安全不能够被轻视, 有问题的系统要么应该打补丁, 要么应该实施这种应急方案。 Solution(解决方案) 一栏提供了如何给有问题的系统打补丁的方法。 这是经过逐步测试和验证过的给系统打补丁并让其安全地工作的方法。 =Correction Details(修正细节) 一栏展示了针对 CVS 分支或某个发行版的修正特征。 同时也提供了每个分支上相关文件的版本号。 References(文献) 一栏通常会给出其它信息的来源。 这可能包括 URL, 书籍、 邮件列表以及新闻组。 Tom Rhodes Contributed by 进程记帐 进程记帐 进程记帐是一种管理员可以使用的跟踪系统资源使用情况的手段, 包括它们分配给了哪些用户、 提供系统监视手段, 并且可以精细到用户执行的每一个命令。 当然, 这种做法是兼有利弊的。 它的好处是, 查找入侵时可以迅速把范围缩小到攻击者进入的时刻; 而这样做的缺点, 则是记帐会产生大量的日志, 因而需要很多磁盘空间来存储它们。 这一节将带领管理员一步一步地配置基本的进程记帐。 启用并利用进程记帐 在使用进程记帐之前, 必须先启用它。 要完成这项工作, 需要运行下面的命令: &prompt.root; touch /var/account/acct &prompt.root; accton /var/account/acct &prompt.root; echo 'accounting_enable="YES"' >> /etc/rc.conf 一旦启用之后, 记帐就会开始跟踪 CPU 统计数据、 命令, 等等。 所有的记帐日志不是以可读的方式记录的, 要查看它们, 需要使用 &man.sa.8; 这个工具。 如果没有给出其他参数, 则 sa 将按用户, 以分钟为单位显示他们所使用的时间、 总共的 CPU 和用户时间, 以及平均的 I/O 操作数目, 等等。 要显示关于刚刚发出的命令的相关信息, 则应使用 &man.lastcomm.1; 工具。 - lastcomm 可以用来显示在某一 &man.ttys.5; + lastcomm 命令可以用来显示在某一 &man.ttys.5; 上的用户信息, 例如: &prompt.root; lastcomm ls trhodes ttyp1 将会显示出所有已知的 trhodes - 在 ttyp1 终端上执行 ls 的情况。 + 在 ttyp1 终端上执行 ls 的情况。 更多的可用选项在联机手册 &man.lastcomm.1;、 &man.acct.5; 和 &man.sa.8; 中有所介绍。
diff --git a/zh_CN.GB2312/books/handbook/x11/chapter.sgml b/zh_CN.GB2312/books/handbook/x11/chapter.sgml index a375ce4b12..e2d4dd9531 100644 --- a/zh_CN.GB2312/books/handbook/x11/chapter.sgml +++ b/zh_CN.GB2312/books/handbook/x11/chapter.sgml @@ -1,1485 +1,1487 @@ Ken Tom 根据 X.Org 的 X11 服务修改此文档 Marc Fonvieille X Window 系统 概述 FreeBSD 使用 X11 来为用户提供功能强大的图形用户界面。 X11 是一种可以免费使用的 X 视窗系统, 其实现包括 &xorg;&xfree86; (以及一些其他这里没有讨论的软件包)。 &os; 在包括 &os; 5.2.1-RELEASE 在内的版本之前, 都默认安装 &xfree86;, 一种由 &xfree86; Project, Inc. 发布的 X11 服务。 从 &os; 5.3-RELEASE 开始, 默认并且为官方支持的 X11 变成了 &xorg;, 它是由 X.Org 基金会开发的 X11 服务, 采用与 &os; 类似的授权。 此外, 也有一些用于 &os; 的商业 X 服务器。 这章将介绍 X11 的安装和配置, 并着重强调 &xorg; 的 &xorg.version; 版。 如欲了解关于 &xfree86; 的详细信息 (在较早的 &os; 版本中, &xfree86; 是默认的 X11 软件包) 或较早版本的 &xorg;, 则可以访问存档的旧版 &os; 使用手册, 其网址为 欲了解 X11 所支持的显示卡等硬件, 请访问 &xorg; 网站。 在阅读完这一章后,您将会了解: X 视窗系统的不同组件,它们是如何协同工作的。 如何安装和配置 X11。 如何安装和使用不同的窗口管理器。 如何在 X11 中使用 &truetype; 字体。 如何为您的系统设置图形登录 (XDM)。 在阅读这一章之前,您应该: 知道如何安装额外的第三方应用程序()。 理解 X 对于那些熟悉其他图形环境,比如 µsoft.windows; 或者 &macos; 的用户来说,第一次使用 X 可能会感觉很惊讶。 通常您并不需要深入了解各种 X 组件的作用以及它们之间的相互影响, 不过, 了解一些关于它们的基础知识, 有助于更好地利用 X 的强大功能。 为什么要使用 X? X 不是第一个为 &unix; 而开发的视窗系统, 但它是最流行的。 X 的原始开发团队在开发 X 之前就已经在另外一个视窗系统上工作了。 那个系统的名字叫做 W (就是 Window)。X 只是罗马字母中 W 后面 的一个。 X 可以被叫做 X, X Window 系统, X11, 等等。把 X11 称做 X Windows 可能会冒犯某些人; 查看 &man.X.7; 可以了解更多的信息。 X 客户机/服务器模型 X 一开始就是针对网络而设计的,所以 采用了 client-server 模型。在 X 模型中, X server 运行在有键盘,显示器,鼠标的计算机上。 - 服务器用来管理显示信息,处理来自键盘和鼠标的输入等。 + 服务器用来管理显示信息,处理来自键盘和鼠标的输入信息, + 并与其他输入输出设备交互 (比如作为输入设备的 tablet, + 或者作为输出设备的投影仪)。 每一个 X 应用程序 (比如 XTerm, 或者 &netscape;) 就是一个 客户程序 (client)。 客户程序给服务器发送信息,如 请在这些坐标上画一个窗口, 而服务器则返回处理信息, 如 用户刚刚点击了 OK 按钮 如果您家或办公环境中只有一台使用 FreeBSD 的计算机, 就只能在同一台计算机上运行 X server 和 X client 了。 然而, 如果您有很多运行 FreeBSD 的机器, 您可以在您的桌面计算机上运行 X server, 而在比较高档的服务器上运行 X 应用程序。 在这样的环境中, X server 和 X client 之间的通信就可以通过网络来进行。 这可能会让一些人感到困惑, 因为 X 的术语和他们料想的有些不同。 他们以为 X server 是运行在功能强大的大型机上的,而 X client 是运行在他们桌面上的计算机上的。 记住,X server 是有键盘和显示器的那台计算机,而 X client 是那些显示窗口的程序。 Client 和 server 不一定都要运行在同一种操作系统上, 它们甚至无需在同一种类型的计算机上运行。 在 µsoft.windows; 或 Apple 公司的 &macos; 上运行 X server 也是可以的, 在它们上面也有很多免费的和商业化的应用程序。 窗口管理器 X 的设计哲学很像 &unix; 的设计哲学, tools, not policy。这就意味着 X 不会试图去规定任务应该如何 去完成,而是,只给用户提供一些工具,至于决定如何使用这些工具是用户自己的 事情。 这套哲学扩展了 X,它不会规定窗口在屏幕上应该是什么样子,要如何移动鼠标, 应该用什么键来切换窗体 (比如, Alt Tab 按键,在 µsoft.windows; 环境中的作用), 每个窗口的工具条应该 看起来像什么,他们是否应该有关闭按钮等等。 实际上,X 行使了一种叫做 窗口管理器的应用程序的职责。有很多这样的程序可用: AfterStep, Blackbox, ctwm, Enlightenment, fvwm, Sawfish, twm, Window Maker,等等。每一个窗口管理器 都提供了不同的界面和观感;其中一些还支持 虚拟桌面;有一些允许您可以定制一些键来管理您的桌面; 一些有开始 按钮,或者其他类似的设计;一些是 可定制主题的(themeable), 通过安装新的主题, 可以完全改变外观。 这些以及很多其他的窗口管理器, 都可以在 Ports Collection 的 x11-wm 分类目录里找到。 另外,KDEGNOME 桌面环境都有他们自己的窗口管理器 与桌面集成。 每个窗口管理器也有不同的配置机制;有些需要手工来写配置文件, 而另外一些则可以使用 GUI 工具来完成大部分的配置任务, 举例而言, (Sawfish) 就使用 Lisp 语言书写配置文件。 焦点策略 窗口管理器的另一个特性是鼠标的 focus policy。 每个窗口系统都需要有一个选择窗口的方法来接受键盘的输入信息,以及当前 哪个窗口处于可用状态。 您通常比较熟悉的是一个叫做 click-to-focus 的焦点策略。 这是 µsoft.windows; 使用的典型焦点策略,也就是您在一个窗口上点击 一下鼠标,这个窗口就处于当前可用的状态。 X 不支持一些特殊的焦点策略。确切地说,窗口管理器控制着在什么时候哪个窗口 拥有焦点。不同的窗口管理器支持不同的焦点方案。它们都支持点击即获得焦点, 而且它们中的大多数都支持好几种方案。 最流行的焦点策略: focus-follows-mouse 鼠标指示器下面的窗口就是获得焦点的窗口。 这个窗口不一定位于其他所有窗口之上。 通过将鼠标移到另一个窗口就可以改变焦点, 而不需要在它上面点击。 sloppy-focus 这种方式是对 focus-follows-mouse 策略的一个小小扩展。对于 focus-follows-mouse, 如果您把鼠标移到了根窗口(或桌面背景)上, 则所有的其它窗口都会失去焦点, 而相关的全部键盘输入也会丢失。 如果选择了 sloppy-focus, 则只有当指针进入新窗口时, 窗口焦点才会发生变化, 而当退出当前窗口时是不会变化的。 click-to-focus 当前窗口由鼠标点击来选择。窗口被突出显示 , 出现在所有其他窗口的前面。即使指针被移向了另一个窗口,所有的键盘输入 仍会被这个窗口接收。 许多窗口管理器支持其他的策略,与这些相比又有些变化。您可以看具体 窗口管理器的文档。 窗口部件 提供工具而非策略的 X 方法使得在每个应用程序屏幕上看到的窗口部件得到了 大大的扩展。 Widget 只是针对用户接口中所有列举项目的一个术语,它 可以用某种方法来点击或操作;如按钮,复选框,单选按钮,图标,列表框等等。 µsoft.windows; 把这些叫做控件 µsoft.windows; 和苹果公司的 &macos; 都有一个严格的窗口部件策略。 应用程序开发者被建议确保他们的应用程序共享一个普通的所见即所得的用户界面。 对于 X,它并不要求一个特殊的图形风格或一套相结合的窗口部件集。 这样的结果是您不能期望 X 应用程序只拥有一个普通的所见即所得的界面。 有很多的流行的窗口部件集设置,包括来自于 MIT 的 Athena, &motif; (模仿 µsoft.windows; 的窗口风格, 所有部件都具有斜边和3种灰色度), OpenLook, 等等。 如今, 绝大多数比较新的 X 应用程序采用一组新式的窗口设计, 这包括 KDE 所使用的 Qt, 以及 GNOME 所使用的 GTK+。 在这样一种窗口系统下,&unix; 桌面的一些所见即所得特性作了一些收敛, 以使初学者感到更容易一些。 安装 X11 &xorg; 是 &os; 上的默认 X11 实现。 &xorg; 是由 X.Org 基金会发行的开放源代码 X Window 系统实现中的 X 服务。 &xorg; 基于 &xfree86 4.4RC2 和 X11R6.6 的代码。 从 &os; Ports 套件可以安装 &xorg; 的 &xorg.version; 版本。 如果需要从 Ports Collection 编译和安装 &xorg; &prompt.root; cd /usr/ports/x11/xorg &prompt.root; make install clean 要完整地编译 &xorg; 则需要至少 4 GB 的剩余磁盘空间。 另外 X11 也可以直接从 package 来安装。 我们提供了可以与 &man.pkg.add.1; 工具配合使用的 X11 安装包。 如果从远程下载和安装, 在使用 &man.pkg.add.1; 时请不要指定版本号。 &man.pkg.add.1; 会自动地下载最新版本的安装包。 想要从 package 安装 &xorg;, 简单地输入下面的命令: &prompt.root; pkg_add -r xorg 上面的例子介绍了如何安装完整的 X11 软件包, 包括服务器端,客户端,字体等等。 此外, 也有一些单独的 X11 的 ports 和 packages. 这一章余下的部分将会讲解如何配置 X11, 以及如何设置一个高效的桌面环境。 Christopher Shumway Contributed by 配置 X11 &xorg; X11 开始之前 在配置 X11 之前, 您需要了解所安装的系统的下列信息: 显示器规格 显示卡的芯片类型 显示卡的显存容量 水平刷新率 垂直刷新率 显示器的规格被 X11 用来决定显示的分辨率和刷新率。 这些规格通常可以从显示器所带的文档中, 以及制造商的网站找到。 需要知道两个数字范围: 垂直刷新率和水平刷新率。 显示卡的芯片类型将决定 X11 使用什么模块来驱动图形硬件。 尽管系统能自动检测出绝大多数的硬件, 但事先了解在自动检测出错的时候还是很有用处的。 显示卡的显存大小决定了系统支持的分辨率和颜色深度。 了解这些限制非常重要。 配置 X11 对于 &xorg; 7.3 这个版本, 可以不需要任何的配置文件就能运行,在提示符下键如下命令: &prompt.user; startx 如果这个命令并不能启动 X11, 也许是默认的配置文件不适合你机器的配置, 这时候就需要手工配置 X11 了。 配置 X11 需要几步, 第一步是以超级用户的身份建立初始的配置文件: &prompt.root; Xorg -configure 这会在 /root 中生成一个叫做 xorg.conf.new 的配置文件 (无论您使用 &man.su.1; 或直接登录, 都会改变默认的 $HOME 目录变量)。 X11 程序将尝试探测系统中的图形硬件,并将探测到的硬件信息写入配置文件, 以便加载正确的驱动程序。 下一步是测试现存的配置文件, 以确认 &xorg; 能够同系统上的图形设备正常工作。 要完成这个任务,只需: &prompt.root; Xorg -config xorg.conf.new 如果用户看到一个黑灰的格子和一个 X 形的鼠标指针,那么配置就是成功的。 要退出测试, 只要同时按下 Ctrl Alt Backspace 如果鼠标工作不正常, 则需要先配置它。 参见 &os; 安装一章中的 X11 调优 接下来是调整 xorg.conf.new 配置文件并作测试。 用文本编辑器如 &man.emacs.1; 或 &man.ee.1; 打开这个文件。 要做的第一件事是为当前系统的显示器设置刷新率。 这些值包括垂直和水平的同步频率。 把它们加到 xorg.conf.new"Monitor" 小节中: Section "Monitor" Identifier "Monitor0" VendorName "Monitor Vendor" ModelName "Monitor Model" HorizSync 30-107 VertRefresh 48-120 EndSection 在配置文件中也有可能没有 HorizSyncVertRefresh。 如果是这样的话, 就只能手动添加, 并在 HorizSyncVertRefresh 后面设置合适的数值了。 在上面的例子中, 给出了相应的显示器的参数。 X 能够使用显示器所支持的 DPMS (能源之星) 功能。 &man.xset.1; 程序可以控制超时时间, 并强制待机、挂起或关机。 如果希望启用显示器的 DPMS 功能, 则需要把下面的设置添加到 monitor 节中: Option "DPMS" xorg.conf 关闭 xorg.conf.new 之前还应该选择默认的分辨率和色深。 这是在 "Screen" 小节中定义的: Section "Screen" Identifier "Screen0" Device "Card0" Monitor "Monitor0" DefaultDepth 24 SubSection "Display" Viewport 0 0 Depth 24 Modes "1024x768" EndSubSection EndSection DefaultDepth 关键字描述了要运行的默认色深。 这可以通过 &man.Xorg.1; 的 命令行开关来替代配置文件中的设置。 Modes 关键字描述了给定颜色深度下屏幕的分辨率。 需要说明的是, 目标系统的图形硬件只支持由 VESA 定义的标准模式。 前面的例子中, 默认色深是使用 24位色。 在采用这个色深时, 允许的分辨率是 1024x768。 最后就是将配置文件存盘, 并使用前面介绍的测试模式测试一下。 在发现并解决问题的过程中, 包含了与 X11 服务器相关的各个设备的信息的 X11 日志文件会为您发现和排除问题有所帮助。 &xorg; 日志的文件名是 /var/log/Xorg.0.log 这样的格式。 实际的日志文件名可能是 Xorg.0.logXorg.8.log 等等。 如果一切准备妥当, 就可以把配置文件放到公共的目录中了。 您可以在 &man.Xorg.1; 里面找到具体位置。 这个位置通常是 /etc/X11/xorg.conf/usr/local/etc/X11/xorg.conf &prompt.root; cp xorg.conf.new /etc/X11/xorg.conf 现在已经完成了 X11 的配置全过程。 &xorg; 可以通过 &man.startx.1; 工具来启动。 除此之外, X11 服务器也可以用 &man.xdm.1; 来启动。 有一个图形配置工具 &man.xorgcfg.1;, 会随 X11 软件包一同安装。 它可以通过选择合适的驱动和设置交互式地定义配置。 这个程序可以从控制台通过命令 xorgcfg -textmode 来直接启动。 欲了解详情, 请参考 &man.xorgcfg.1; 的联机手册。 另外还有一个叫做 &man.xorgconfig.1; 的文本界面配置工具 这是一个控制台工具, 对用户而言不太友好, 但也正因它使用的是纯文本界面, 因此当其他工具无法工作时, 您仍可使用这个工具。 高级配置主题 配置 &intel; i810 显示芯片组 Intel i810 显示芯片 配置Intel i810芯片组的显示卡需要有针对 X11 的能够用来驱动显示卡的 agpgart AGP程序接口。 请参见 &man.agp.4; 驱动程序的联机手册了解更多细节。 这也适用于其他的图形卡硬件配置。 注意如果系统没有将 &man.agp.4; 驱动程序编译进内核,尝试用 &man.kldload.8; 加载模块是无效的。 这个驱动程序必须编译进内核或者使用 /boot/loader.conf 在启动时加载进入内核。 添加宽屏平板显示器 widescreen flatpanel configuration 这一节假定您了解一些关于高级配置的知识。 如果使用前面的标准配置工具不能产生可用的配置, 则在日志文件中提供的信息应该足以修正配置使其正确工作。 如果需要的话, 您应使用一个文本编辑器来完成这项工作。 目前的宽屏 (WSXGA、 WSXGA+、 WUXGA、 WXGA、 WXGA+, 等等) 支持 16:10 和 10:9 或一些支持不大好的显示比例。 常见的一些 16:10 比例的分辨率包括: 2560x1600 1920x1200 1680x1050 1440x900 1280x800 有时, 也可以简单地把这些分辨率作为 Section "Screen" 中的 Mode 来进行配置, 类似下面这样: Section "Screen" Identifier "Screen0" Device "Card0" Monitor "Monitor0" DefaultDepth 24 SubSection "Display" Viewport 0 0 Depth 24 Modes "1680x1050" EndSubSection EndSection &xorg; 能够自动地通过 I2C/DDC 信息来自动获取宽屏显示器的分辨率信息, 并处理显示器支持的频率和分辨率。 如果驱动程序没有对应的 ModeLines, 就需要给 &xorg; 一些提示了。 使用 /var/log/Xorg.0.log 能够提取足够的信息, 就可以写一个可用的 ModeLine 了。 这类信息如下所示: (II) MGA(0): Supported additional Video Mode: (II) MGA(0): clock: 146.2 MHz Image Size: 433 x 271 mm (II) MGA(0): h_active: 1680 h_sync: 1784 h_sync_end 1960 h_blank_end 2240 h_border: 0 (II) MGA(0): v_active: 1050 v_sync: 1053 v_sync_end 1059 v_blanking: 1089 v_border: 0 (II) MGA(0): Ranges: V min: 48 V max: 85 Hz, H min: 30 H max: 94 kHz, PixClock max 170 MHz 这些信息称做 EDID 信息。 从中建立 ModeLine 只是把这些数据重新排列顺序而已: ModeLine <name> <clock> <4 horiz. timings> <4 vert. timings> 如此, 本例中的 Section "Monitor" 中的 ModeLine 应类似下面的形式: Section "Monitor" Identifier "Monitor1" VendorName "Bigname" ModelName "BestModel" ModeLine "1680x1050" 146.2 1680 1784 1960 2240 1050 1053 1059 1089 Option "DPMS" EndSection 经过简单的编辑步骤之后, X 就可以在您的宽屏显示器上启动了。 Murray Stokely 供稿 在 X11 中使用字体 Type1 字体 X11 使用的默认字体不是很理想。 大型的字体显得参差不齐,看起来很不专业, 并且, 在 &netscape; 中, 小字体简直无法看清。 有好几种免费、 高质量的字体可以很方便地用在 X11 中。 例如,URW字体集合 (x11-fonts/urwfonts) 就包括了高质量的 标准 type1 字体 (Times Roman, HelveticaPalatino 和其他一些)。 在 Freefont 集合中 (x11-fonts/freefonts) 也包括更多的字体, 但它们中的绝大部分使用在图形软件中,如 Gimp,在屏幕字体中使用并不完美。另外, 只要花很少的功夫,可以将 &xfree86; 配置成能使用 &truetype; 字体:请参见后面的 &truetype; 字体一节。 要安装上面的Type1字体,您只需要运行下面的命令: &prompt.root; cd /usr/ports/x11-fonts/urwfonts &prompt.root; make install clean freefont 或其他的字库和上面所说的大体类似。 为了让 X 服务器能够检测到这些字体, 需要在 X 服务器的配置文件 (/etc/X11/xorg.conf) 中增加下面的配置: FontPath "/usr/local/lib/X11/fonts/URW/" 或者,也可以在命令行运行: &prompt.user; xset fp+ /usr/local/lib/X11/fonts/URW &prompt.user; xset fp rehash 这样会起作用,但是当 X 会话结束后就会丢失, 除非它被添加到启动文件 (~/.xinitrc 中, 针对一个寻常的 startx 会话,或者当您通过一个类似 XDM 的图形登录管理器登录时添加到 ~/.xsession 中)。 第三种方法是使用新的 /usr/local/etc/fonts/local.conf 文件: 查看 anti-aliasing 章节。 &truetype; 字体 TrueType 字体 fonts (字体) TrueType &xorg; 已经内建了对 &truetype; 字体的支持。有两个不同的模块能够启用这个功能。 在这个例子中使用 freetype 这个模块,因为它与其他的字体描绘后端 是兼容的。要启用 freetype 模块,只需要将下面这行添加到 /etc/X11/xorg.conf 文件的 "Module" 部分。 Load "freetype" 现在,为 &truetype; 字体创建一个目录 (比如, /usr/local/lib/X11/fonts/TrueType) 然后把所有的 &truetype; 字体复制到这个目录。记住您不能直接从 &macintosh; 计算机中提取 &truetype; 字体; 能被 X11 使用的必须是 &unix;/&ms-dos;/&windows; 格式的。 一旦您已经将这些文件复制到了这个目录, 就可以用 ttmkfdir 来创建 fonts.dir 文件, 以便让X字体引擎知道您已经安装了这些新文件。 ttmkfdir 可以在 FreeBSD Ports 套件中的 x11-fonts/ttmkfdir 中找到。 &prompt.root; cd /usr/local/lib/X11/fonts/TrueType &prompt.root; ttmkfdir -o fonts.dir 现在把 &truetype; 字体目录添加到字体路径中。 这和上面 Type1 字体的步骤是一样的, 那就是,使用 &prompt.user; xset fp+ /usr/local/lib/X11/fonts/TrueType &prompt.user; xset fp rehash 或者把 FontPath 这行加到 xorg.conf 文件中。 就是这样。现在 &netscape;, Gimp, &staroffice; 和其他所有的 X 应用程序 应该可以认出安装的 &truetype; 字体。一些很小的字体(如在 Web 页面上高分辨率显示的文本) 和一些很大的字体(在 &staroffice; 下) 现在看起来已经很好了。 Joe Marcus Clarke Updated by Anti-Aliased 字体 anti-aliased fonts fonts anti-aliased X11 从 &xfree86; 4.0.2 开始支持字体的反走样。 但是, 字体配置在 &xfree86; 4.3.0 之前是非常繁琐的。 从 &xfree86; 4.3.0 开始, 对于所有支持 Xft 的应用程序, 所有放到 X11 /usr/local/lib/X11/fonts/~/.fonts/ 中的字体都自动地被加入反走样支持。 并不是所有的应用程序都支持 Xft, 但已经有相当多的程序提供 Xft 支持了。 支持 Xft 的应用程序包括 Qt 2.3 以及更高版本 (用以开发 KDE 桌面的工具包)、 GTK+ 2.0 和更高版本 (用于开发 GNOME 桌面的工具包), 以及 Mozilla 1.2 和更高版本。 要控制哪些字体是 anti-aliased,或者配置 anti-aliased 特性, 创建(或者编辑,如果文件已经存在的话)文件 /usr/local/etc/fonts/local.conf。Xft 字体系统的几个 高级特性都可以使用这个文件来调节; 这一部分只描述几种最简单的情况。要了解更多的细节,请查看 &man.fonts-conf.5;. XML 这个文件一定是 XML 格式的。注意确保所有的标签都完全的关闭掉。 这个文件以一个很普通的 XML 头开始, 后跟一个 DOCTYPE 定义, 接下来是 <fontconfig> 标签: <?xml version="1.0"?> <!DOCTYPE fontconfig SYSTEM "fonts.dtd"> <fontconfig> 像前面所做的那样,在 /usr/local/lib/X11/fonts/~/.fonts/ 目录下的所有字体已经可以被支持 Xft 的 应用程序使用了。如果您想添加这两个目录以外的其他路径, 简单的添加下面这行到 /usr/local/etc/fonts/local.conf文件中: <dir>/path/to/my/fonts</dir> 添加了新的字体,尤其是添加了新的字体目录后, 您应该运行下面的命令重建字体缓存: &prompt.root; fc-cache -f Anti-aliasing 会让字体边缘有些模糊,这样增加了非常小的文本的可读性, 并从大文本字体中删除 锯齿。 但如果使用普通的文本, 则可能引起眼疲劳。 要禁止 14磅 以下字体的反走样, 需要增加如下配置: <match target="font"> <test name="size" compare="less"> <double>14</double> </test> <edit name="antialias" mode="assign"> <bool>false</bool> </edit> </match> <match target="font"> <test name="pixelsize" compare="less" qual="any"> <double>14</double> </test> <edit mode="assign" name="antialias"> <bool>false</bool> </edit> </match> fonts spacing 用 anti-aliasing 来间隔一些等宽字体也是不适当的。 这似乎是 KDE 的一个问题。 要修复这个问题需要确保每个字体之间的间距保持在100。 加入下面这些行: <match target="pattern" name="family"> <test qual="any" name="family"> <string>fixed</string> </test> <edit name="family" mode="assign"> <string>mono</string> </edit> </match> <match target="pattern" name="family"> <test qual="any" name="family"> <string>console</string> </test> <edit name="family" mode="assign"> <string>mono</string> </edit> </match> (这里把其他普通的修复的字体作为 "mono"),然后加入: <match target="pattern" name="family"> <test qual="any" name="family"> <string>mono</string> </test> <edit name="spacing" mode="assign"> <int>100</int> </edit> </match> 某些字体,比如 Helvetica,当 anti-aliased 的时候可能存在问题。 通常的表现为字体本身似乎被垂直的切成两半。 糟糕的时候,还可能导致应用程序比如 Mozilla 崩溃。 为了避免这样的现象,考虑添加下面几行到 local.conf文件里面: <match target="pattern" name="family"> <test qual="any" name="family"> <string>Helvetica</string> </test> <edit name="family" mode="assign"> <string>sans-serif</string> </edit> </match> 一旦您完成对 local.conf 文件的编辑,确保您使用了 </fontconfig> 标签来结束文件。 不这样做将会导致您的更改被忽略。 X11 默认的字库当使用反走样时会比较难看。 更好的字库可以在 x11-fonts/bitstream-vera port 中找到。 这个 port 会创建一个 /usr/local/etc/fonts/local.conf 文件, 如果这个文件不存在的话。 反之, port 将创建 /usr/local/etc/fonts/local.conf-vera 文件。 将其内容合并到 /usr/local/etc/fonts/local.conf 中, 则 Bitstream 字体将自动地代替默认的 X11 Serif, Sans Serif, 以及单倍距字体。 最后,用户可以通过他们个人的 .fonts.conf 文件来添加自己的设定。 要完成此项工作, 用户只需简单地创建 ~/.fonts.conf 并添加相关配置。 此文件也必须是 XML 格式的。 LCD screen Fonts LCD screen 最后:对于LCD屏幕, 可能希望使用子像素的取样。 简单而言, 这是通过分别控制 (水平方向分开的) 红、绿、蓝 像素, 来改善水平分辨率; 这样做的效果一般会非常明显。 要启用它, 只需在 local.conf 文件的某个地方加入: <match target="font"> <test qual="all" name="rgba"> <const>unknown</const> </test> <edit name="rgba" mode="assign"> <const>rgb</const> </edit> </match> 随您显示器的种类不同, 可能需要把 rgb 改为 bgrvrgbvbgr: 试验一下看看那个更好。 Mozilla disabling anti-aliased fonts (禁用反锯齿字体) 在下次启动 X server 时, 反锯齿 (anti-aliasing) 功能就启用了。 不过, 应用程序必须了解如何使用它, 才能因此而受益。 目前 Qt 工具包已经对其提供了全面支持, 因此整个 KDE 环境都能使用反锯齿字体。 GTK+ 和 GNOME 也可以通过 Font capplet 来使用反锯齿功能 (进一步细节请参见 )。 默认情况下, Mozilla 1.2 及更高版本有能力自动使用反锯齿。 要禁用这一特性, 则需要使用指定 -DWITHOUT_XFT 并重新联编 Mozilla Seth Kingsley Contributed by X 显示管理器 概要 X Display Manager X 显示管理器(XDM) 是一个X视窗系统用于进行登录会话管理的可选项。 这个可以应用于多种情况下,包括小 X Terminals, 桌面,大网络显示服务器。既然 X 视窗系统不受网络和协议的限制, 那对于通过网络连接起来的运行 X 客户端和服务器端的不同机器, 就会有很多的可配置项。 XDM 提供了一个选择要连接到哪个显示服务器的图形接口, 只要键入如登录用户名和密码这样的验证信息。 您也可以把 XDM 想象成与 &man.getty.8 工具一样(see for details)。为用户提供了同样功能。它可以完成系统的登录任务, 然后为用户运行一个会话管理器 (通常是一个 X 视窗管理器)。接下来 XDM 就等待这个程序退出,发出信号用户已经登录完成,应当退出屏幕。 这时, XDM 就可以为下一个登录用户显示登录和可选择屏幕。 使用 XDM XDM 精灵程序在 /usr/local/bin/xdm 中。您可以在任何时候 用 root 来运行这个程序, 在本地机器上,它将启动管理X的画面。如果要 XDM 每次机器一启动就开始运行, 一个简单的办法是在 /etc/ttys 中加入一个记录。 有关这个文件的更多的格式和使用方法,可以看看 。在默认的 /etc/ttys 文件中用于运行 XDM 守护程序的一行是这样的: ttyv8 "/usr/local/bin/xdm -nodaemon" xterm off secure 默认情况下,这个记录是关闭的,要启用它, 您需要把第5部分的 off 改为 on 然后按照 的指导 重新启动 &man.init.8;。第一部分,这个程序将管理的终端名称是 ttyv8。这意味着 XDM 将运行在第9个虚拟终端上。 配置 XDM XDM 的配置目录是在 /usr/local/lib/X11/xdm中。在这个目录中, 您会看到几个用来改变 XDM 行为和外观的文件。您会找到这些文件: 文件 描述 Xaccess 客户端授权规则。 Xresources 默认的X资源值。 Xservers 远程和本地显示管理列表。 Xsession 用于登录的默认的会话脚本。 Xsetup_* 登录之前用于加载应用程序的脚本。 xdm-config 运行在这台机器上的所有显示的全局配置。 xdm-errors 服务器程序产生的错误。 xdm-pid 当前运行的 XDM 的进程 ID。 XDM 运行时, 在这个目录中有几个脚本和程序可以用来设置桌面。 这些文件中的每一个的用法都将被简要地描述。 这些文件的更详细的语法和用法在 &man.xdm.1; 中将有详细描述。 默认的配置是一个矩形的登录窗口,上面有机器的名称, Login:Password:。如果您想设计您自己个性化的 XDM 屏幕,这是一个很好的起点。 Xaccess 用以连接由 XDM 所控制的显示设备的协议, 叫做 X 显示管理器连接协议 (XDMCP)。 这个文件是一组用以控制来自远程计算机的 XDMCP 连接的规则。 除非您修改 xdm-config 使其接受远程连接, 否则其内容将被忽略。 默认情况下, 它不允许来自任何客户端的连接。 Xresources 这是一个默认的用来显示选项和登录屏幕的应用程序文件。 您可以在这个文件中对登录程序的外观进行定制。 其格式与 X11 文档中描述的默认应用程序文件是一样的。 Xservers 这是一个选择者应当提供的作为可选的远程显示列表。 Xsession 这是一个用户登录后针对 XDM 的默认会话脚本。通常,在 ~/.xsession 中每个用户将有一个可定制的会话脚本。 Xsetup_* 在显示选择者或登录接口之前,这些将被自动运行。 这是一个每个显示都要用到的脚本,叫做 Xsetup_, 后面会跟一个本地显示的数字(比如 Xsetup_0)。典型的,这些脚本将在后台 (如 xconsole)运行一个或两个程序。 xdm-config 此文件以应用程序默认值的形式, 提供了在安装时所使用的普适的显示设置。 xdm-errors 这个文件包含了 XDM 正设法运行的的 X 服务器 的输出。 如果 XDM 正设法运行的显示由于某种原因被挂起, 那这是一个寻找错误信息的好地方。 这些信息会在每一个会话的基础上被写到用户的 ~/.xsession-errors 文件中。 运行一个网络显示服务器 对于其他客户端来说, 如果希望它们能连接到显示服务器,您就必须编辑访问控制规则, 并启用连接侦听。 默认情况下, 这些都预设为比较保守的值。 要让 XDM 能侦听连接, 首先要在 xdm-config 文件中注释掉一行: ! SECURITY: do not listen for XDMCP or Chooser requests ! Comment out this line if you want to manage X terminals with xdm DisplayManager.requestPort: 0 然后重新启动XDM。 记住默认应用程序文件的注释以! 字母开始,不是#。 您需要设置严格的访问控制 — 看看在 Xaccess 文件中的实例, 并参考 &man.xdm.1; 的联机手册, 以了解进一步的细节。 替换 XDM 有几个替换默认 XDM程序的方案。 其中之一是 上一节已经描述过的kdm (与 KDE捆绑在一起)。 kdm 提供了许多视觉上的改进和局部的修饰, 同样能让用户在启动时能选择他们喜欢的窗口管理器。 Valentino Vaschetto Contributed by 桌面环境 这节描述了 FreeBSD 上用于 X 的不同桌面环境。 桌面环境 可能仅仅是一个简单的窗口管理器, 也可能是一个像 KDE 或者 GNOME这样的完整桌面应用程序套件。 GNOME 有关 GNOME GNOME GNOME 是一个用户界面友好的桌面环境, 能够使用户很容易地使用和配置他们的计算机。 GNOME 包括一个面板(用来启动应用程序和显示状态), 一个桌面(存放数据和应用程序的地方), 一套标准的桌面工具和应用程序, 和一套与其他人相互协同工作的协议集。 其他操作系统的用户在使用 GNOME提供的强大的图形驱动环境时会觉得很好。 更多的关于 FreeBSD 上 GNOME 的信息 可以在 FreeBSD GNOME Project 的网站上找到。 此外, 这个网站也提供了相当详尽的关于安装、 配置和管理 GNOME 的常见问题解答 (FAQ)。 安装 GNOME 这个软件可以很容易地通过预编译包或 Ports 套件来安装: 要从网络安装GNOME, 只要键入: &prompt.root; pkg_add -r gnome2 从源代码编译GNOME,可以使用 ports树: &prompt.root; cd /usr/ports/x11/gnome2 &prompt.root; make install clean 一旦装好了 GNOME, 就必须告诉 X server 启动 GNOME 而不是默认的窗口管理器。 最简单的启动 GNOME 的方法是使用 GDM, GNOME 显示管理器。 随 GNOME 桌面一同安装的 GDM (但默认是禁用的), 可以通过在 /etc/rc.conf 中加入 gdm_enable="YES" 来启用。 这样在重新启动的时候, GNOME 就会在登录时自动启动 — 除此之外不需要进一步设置了。 GNOME 也可以通过适当地配置名为 .xinitrc 的文件来启动。 如果已经有了自定义的 .xinitrc, 将启动当前窗口管理器的那一行改为启动 /usr/local/bin/gnome-session 就可以了。 如果还没有, 那么只需简单地: &prompt.user; echo "/usr/local/bin/gnome-session" > ~/.xinitrc 接下来输入 startxGNOME 桌面环境就启动了。 如果之前使用了一些旧式的显示管理器, 例如 XDM, 则这样做是没用的。 此时应建立一个可执行的 .xsession 文件, 其中包含同样的命令。 要完成这项工作, 需要用 /usr/local/bin/gnome-session 取代现有的窗口管理器: &prompt.user; echo "#!/bin/sh" > ~/.xsession &prompt.user; echo "/usr/local/bin/gnome-session" >> ~/.xsession &prompt.user; chmod +x ~/.xsession 还有一种做法, 是配置显示管理器, 以便在登录时提示您选择窗口管理器; 在 KDE 细节 环节中介绍了关于如何为 kdmKDE 的显示管理器)进行这样的配置。 在GNOME上使用Anti-aliased字体 GNOME anti-aliased fonts X11 通过RENDER扩展来支持 anti-aliasing。 GTK+ 2.0 以及更高的版本(被 GNOME使用的工具包)可以使用这个功能。 配置 anti-aliasing 在 描述。所以,使用最近的软件, anti-aliasing 可以应用在 GNOME桌面环境中。只需要依次选择 应用程序 桌面首选项 字体,然后选上 最佳形状最佳对比度,或者 像素圆滑(LCD)。对于 GTK+ 应用程序,它们不是 GNOME 桌面的一部分,在启动程序前需要设置 环境变量GDK_USE_XFT的值为 1 KDE KDE 有关 KDE KDE 是一个容易使用的现代桌面环境。 KDE 有很多很好的特性: 一个美丽的现代的桌面。 一个集合了完美网络环境的桌面。 一个集成的帮助系统,能够方便、高效地帮助您使用 KDE 桌面和它的应用程序。 所有的KDE应用程序具有一致的所见即所得界面。 标准的菜单和工具栏,键盘布局,颜色配置等。 国际化:KDE 可以使用超过40种语言。 集中化、 统一的对话框驱动的桌面配置 许多有用的 KDE应用程序。 KDE 附带了一个名为 Konqueror 的 web 浏览器, 它是其他运行于 &unix; 系统上的 web 浏览器的一个强大的竞争对手。 要了解关于 KDE 的更多详情, 可以访问 KDE 网站。 与 FreeBSD 相关的 KDE 信息和资源, 可以在 FreeBSD 上的 KDE 团队 的网站找到。 安装 KDE GNOME 和其他桌面环境类似, 这个软件可以很容易地通过预编译包或 Ports 套件来安装: 要从网络安装 KDE 只需要: &prompt.root; pkg_add -r kde &man.pkg.add.1; 就会自动的下载最新版本的应用程序。 要从源代码编译 KDE, 可以使用 ports 树: &prompt.root; cd /usr/ports/x11/kde3 &prompt.root; make install clean KDE 安装完成后, X server必须被告知启动这个应用程序以代替默认的窗口管理器。 这可以通过编辑 .xinitrc 文件来完成: &prompt.user; echo "exec startkde" > ~/.xinitrc 现在,无论您什么时候用 startx进入 X 视窗系统, KDE 就将成为您的桌面环境。 如果使用一个像 XDM这样的显示管理器, 那配置文件可能有点不同。需要编辑一个 .xsession 文件,有关 kdm 的用法会在这章的后面介绍。 有关 KDE 的更多细节 现在 KDE 已经被安装在系统中了。 通过帮助页面或点击多个菜单可以发现很多东西。 &windows; 或 &mac; 用户会有回到家的感觉。 有关 KDE 的最好的参考资料是 它的在线文档。KDE 拥有它自己的 web 浏览器 Konqueror, 还有很多其他的应用程序和丰富文档。 这节的余下部分将讨论一些很难用走马观花的方法来学习的技术项目。 KDE 显示管理器 KDE display manager 如果在同一系统上有多个用户, 则管理员通常会希望使用图形化的登录界面。 前面已经提到, 使用 XDM 可以完成这项工作。 不过, KDE 本身也提供了另一个选择, 即 kdm, 它的外观更富吸引力, 而且提供了更多的登录选项。 值得一提的是, 用户还能通过菜单很容易地选择希望使用的桌面环境 (KDEGNOME 或其它)。 要启用 kdm, 需要修改 /etc/ttys 中的 ttyv8 项。 将其改为类似下面的样子: ttyv8 "/usr/local/bin/kdm -nodaemon" xterm on secure XFce 有关XFce XFce是以被GNOME 使用的 GTK+ 工具包为基础的桌面环境, 但是更加轻巧,适合于那些需要一个易于使用和配置并且简单而高效的桌面的人。 看起来,它非常像使用在商业&unix;系统上的 CDE环境。 XFce的主要特性有下面这些: 一个简单,易于使用的桌面。 完全通过鼠标的拖动和按键来控制等。 CDE 相似的主面板,菜单,applets和应用launchers。 集成的窗口管理器,文件管理器,声音管理器, GNOME 应用模块等等。 可配置界面的主题。(因为它使用GTK+) 快速,轻便,高效:对于比较老的/旧的机器或带有很少内存的机器仍然很理想。 更多有关XFce 的信息可以参考XFce 网站 安装XFce 有一个二进制的XFce 软件包存在(在写作的时候)。要安装的话,执行下面的命令: &prompt.root; pkg_add -r xfce4 另外,要从源代码建立,使用Ports Collection: &prompt.root; cd /usr/ports/x11-wm/xfce4 &prompt.root; make install clean 现在,要告诉X服务器在下次X启动时执行 XFce。 只要执行下面的命令: &prompt.user; echo "/usr/local/bin/startxfce4" > ~/.xinitrc 接下来就是启动 X, XFce将成为您的桌面。 与以前一样,如果使用像 XDM 这样的显示管理器,需要创建一个 .xsession文件,就像有关 GNOME 的那节描述的, 使用/usr/local/bin/startxfce4 命令,或者,配置显示管理器允许在启动时选择一个桌面, 就像有关kdm的那节描述的。