FreeBSD handbook中文版 10 安全
发布时间:2006-10-14 8:46:30   收集提供:gaoqian
目录
10 安全
10.1 概要
10.2 介绍
10.3 确保FreeBSD 的安全特性
10.4 DES, MD5 和Crypt 
10.5 S/Key 
10.6 Kerberos 
10.7 防火墙
10.8 OpenSSL 
10.9 IPsec 
10.10 openSSH 
=============================================================
第10 章安全
=============================================================
(翻译中出现的任何问题或错误,请广大读者及时反馈给我:freebsdhandbook@163.com) 
10.1 概要
这章将对系统安全概念作一个的基本介绍,还有一些通用的好的规则,和一些在
FreeBSD 下的高级主题。这儿提到的许多主题已经很好地应用于系统和Internet 的安全。
确保你的系统安全将保护你的数据,不至于被黑客所窃取。
FreeBSD 提供了许多工具和机制来确保你的系统和网络的安全。
读完这章,你将了解到这些: 
. FreeBSD 的基本系统安全概念。
. FreeBSD 中可用的如DES 和MD5 这样的加密(crypt)机制。
. 如何设置S/Key,一种一次性的密码验证机制。
. 如何设置Kerberos,另一种密码验证机制。
. 如何使用IPFW 来创建防火墙。
. 如何配置IPSec。
. 如何配置和使用OpenSSH,FreeBSD 的SSH 执行方式。
在阅读这章之前,你必须了解: 
. 了解基本的FreeBSD 和internet 概念。
10.2 介绍
安全是系统管理至始至终最基本的要求。所有的BSD UNIX 系统都有它自身内在的安
全性,建构和维护额外的安全机制,确保用户的“诚实”大概是系统管理最艰巨的工作之一。
机器仅保持着建构时最原始的安全性,而安全性必须要考虑到用户使用的便利性。通常
UNIX 系统能够支持巨大的并发用户处理,而这些处理中绝大部分是以服务器形式处理的---- 
这意味着外部的实体能够连接和互相交谈。昨天的小型电脑和主机变成了今天的桌面机,电
脑已连到局域网和互联网,安全就成了一个非常严峻的问题。
第1 页FreeBSD 使用手册
通过一个分层的方法,安全能够很好地实现。你所要做的就是创建很多的安全层,然后
仔细地监视系统以防入侵。你不要过多地创建安全层,否则你将会影响检测面。检测是许多
安全机制中最重要的方法。例如,在每一个二进制程序中,很难判断schg 标记,因为这样
会临时地保护二进制,它会妨碍对一个已经侵入的攻击者作一个很容易的检测,以至最终你
的安全机制根本检测不到攻击者。
系统安全也涉及到攻击的许多方面,包括试图摧毁或使一个系统无法使用。安全问题主
要被分成几类: 
1, 拒绝服务的攻击; 
2, 窃取用户的帐户; 
3, 通过最近的服务器窃取root 帐户; 
4, 通过用户帐户窃取root 帐户; 
5, 创建后门; 
拒绝式服务攻击是侵占机器所需资源的一种方法。有代表性的,D.O.S 攻击,是非常残
忍的攻击机制,它通过压倒性的流量来破坏服务器和网络堆栈,试图摧毁机器或使机器无法
使用。一些D.O.S 攻击利用在网络堆栈中的错误,仅用一个简单的信息包就可以摧毁一台机
器。这可以向内核添加一个错误补丁来修复。在一些不利的条件下,对服务器的攻击能够被
修复,只要适当地修改一下系统的选项来限制系统对服务器的负荷。顽强的网络攻击是很难
对付的。例如,一个欺骗性信息包的攻击,无法阻止入侵者切断你的系统与internet 的连接。
它不会使你的机器死掉,但它会把internet 管道塞满。
窃取用户帐户要比D.O.S 攻击更加普遍。许多系统管理员仍然在它们的服务器上运行着
基本的telnetd,rlogind,rshd,ftpd 服务。这些服务器默认情况下,不会通过加密连接来操作。
结果是如果你的系统有中等规模大小的用户,在通过远程登陆的方式登陆到你系统的用户
中,一些人的密码会被人窃取。仔细的系统管理员会从那些成功登陆系统的远程访问日志中
寻找可疑的资源地址。
假定,一个入侵者已经访问到了一个用户的帐户,入侵者就会使超级用户失效。然而, 
事实是在一个安全的系统中,访问用户的帐户不应该给入侵者访问root 的权限。这个区别
是很重要的,因为没有访问root 的权限,入侵者是无法隐藏它的轨迹的,但可能不需要做
什么,就可以把用户的文件弄乱或使机器崩溃。窃取用户帐户是很普遍的事情,因为用户往
第2 页FreeBSD 使用手册
往不会对系统管理员的警告采取措施。
系统管理员应该牢牢记住,可能有许多潜在的方法会使root 失效。入侵者可能知道root 
的密码,可以在一个以root 权限运行的服务器上找到一个错误(bug),就可以通过网络连
接到那台服务器上使root 失效,或者一旦入侵者已经侵入了一个用户的帐户,可以在自己
的机器上运行一个程序来发现服务器的漏洞,从而让他侵入到服务器使root 失效。如果入
侵者已经找到了方法使root 失效,入侵者就不需要安装一个后门。许多root 漏洞被找到之
后,入侵者会想尽办法去删除日期来清除自己的访问痕迹,所以很多入侵者会安装后门。后
门能给入侵者提供一个简单的重新获取访问系统的root 权限,但它也会给聪明的系统管理
员一个探测入侵的简便方法。认为入侵者不可能安装了后门,这种思想事实上对你的系统安
全是有害的,因为这样他就不会隔离从一开始就侵入系统的黑客发现的漏洞。
安全的管理方法应当使用象剥洋葱皮一样多层次,层层逼近的方法来实现,可以按下面
的方式进行分类: 
1, 确保root 用户和其它用户帐户的安全; 
2, 确保root 用户---以root 用户权限运行的服务器和suid/sgid 二进制程序的安全; 
3, 确保用户帐户的安全; 
4, 确保密码文件的安全; 
5, 确保内核中内核设备和文件系统的安全; 
6, 快速检测系统中发生的不适当的变化; 
7, 偏执狂; 
这一章的下一节将比较深入地讲述上面提到的每一个条目。
10.3 确保FreeBSD 的安全
下面这节将讲述确保系统安全的方法。
10.3.1 确保root 用户和其它用户帐户的安全
首先,如果你没有确保root 帐户的安全,请不要为确保其它用户的安全而烦恼。绝大
多数系统都会指派一个密码给root 用户帐户。第一件事是假定密码总是不安全。这并不意
味着你要把密码删掉。密码通常对用控制台访问机器是必须的。也就是说,你不应当让它用
到控制台以外的密码,即使是使用su 命令。例如,确信你的pty’s 作为不安全的因素已经被
第3 页FreeBSD 使用手册
记录在/etc/ttys 文件中,以至直接通过telnet 或rlogin 登陆root 会不被接受。如果使用(如sshd) 
其它的登陆服务,确认直接登陆root 根本不行。考虑到每一种访问方法--(如FTP 服务)通
过cracks 经常失败。直接登陆root 应当只有通过系统控制台被允许。
当然,作为一个系统管理员,你应当获得root 权限,所以我们公开几个漏洞。但我们
确信这些漏洞需要额外的密码确认才能操作。一种成为root 访问的是增加适当用户的帐户
到wheel 组(在/etc/group 中)。Wheel 组中的用户可以使用su 命令来访问root。在它们的密
码登陆口,通过把它们放置在wheel 组中,你就永远不会给用户成员访问本地wheel 的权限。
用户帐户应当被放置在staff 组中,然后通过/etc/group 文件加入到wheel 组。事实上,那些
需要访问root 的用户成员将会被放置在wheel 组中。当然也会有可能,用一个如kerberos 
的认证方法。在root 帐户中使用kerberos 的.k5login 文件,可以不需要把任何人放置在wheel 
组中就允许ksu 访问root.如果入侵者已经获得了密码文件,或者已侵入了一个用户帐户,这
可能是一个比较好的解决方法,因为wheel 机制仍然可能会使入侵者break root。虽然wheel 
机制要什么都没有要好得多,但它也不是最安全的选择。
确保超级用户帐户安全的间接方法是通过使用一个有选择性的登陆访问方法确保你的
用户帐户的安全。这样做,入侵者可能会偷窃到密码文件,但不会侵入任何用户帐户。用户
成员通过使用一对私有或公共密匙(如kerberos 或ssh)的安全机制来进入它们的帐户。当
你使用kerberos 时,你必须确保使用kerberos 的服务器或工作站的安全。当你使用一对ssh 
的公共/私有密匙系统,你必须确保你所登陆的那台机器的安全,但当你用ssh-keygen 创建
它时,你可以添加一个额外的保护层到你的钥匙对中。你可以强制所有的用户成员使用加密
的方法连接它们的活动,这样就可以关闭可能会被入侵者使用的一个重要漏洞:将一个毫无
关系,很不安全的机器与网络隔离。
更多间接的安全机制能够被实现。你可以从一个带有限制性的服务器到一个毫无限制性
的服务器进行登陆。例如,如果你的主邮箱运行在所有种类的服务器上,那你的工作站就无
法运行任何东西。为了确保你工作站的安全,尽可能少运行服务器,直到根本就没有服务器
运行,然后运行一个受密码保护的屏保。当然,一个入侵者强行访问你的工作站,它就会把
你所设置的所有安全特性都破坏掉。有一个问题必须明确,你必须考虑到这样一个事实,绝
大多数入侵是从那些没有物理访问工作站或服务器权限的人那里,通过一个网络来侵入的。
使用象kerberos 这样的技术,也会让你无法使用系统,或者改变用户帐户的密码,从而影响
到拥有一个帐户的所有用户成员。如果一个用户成员的帐户已经失去安全,应当改变它在所
有机器上的密码。对于不连续的密码,在n 台机器上改变一个密码可能是很乱的。你可能要
第4 页FreeBSD 使用手册
用kerberos 重建密码的限制:一张kerberos 的许可证可能一段时间后会过期,但kerberos 系
统可能要求用户在一段时间以后选择一个新密码(一般是一个月)。
10.3.2 确保以root 权限运行的服务器和suid/sgid 二进制程序的安全
谨慎的系统管理员只运行他需要的服务器,不多也不少。要清醒地认识到第三方的服
务器经常有很多的错误。例如,运行一个老版本的imapd 或popper,就象是给出了一个通用
的root 帐号来访问外部世界。运行每一个服务器,你都要仔细地检查。许多服务器不一定
需要用root 来运行。例如,ntalk, comsat, 和finger 守护程序可能运行在一个特殊的用
户sandboxes 上。一个sandbox 是不完全的,除非你遇到了许多问题,但安全的层级模式
仍然支持:如果能够通过运行在一个sandbox 上的一个服务器侵入,他们仍然必须要攻破
sandbox。攻击者必须通过很多的安全层,这样他侵入的可能性就很小了。过去已经找到了
很多root 的安全漏洞,包括基本的系统服务器。如果你运行着用户通过sshd 来登陆而从
不用telnetd 或rshd 或rlogind 来登陆的服务器,你最好把这些服务器关掉。
现在,FreeBSD 默认在sandbox 中运行ntalkd, comsat,和finger。还有一个叫做named 
的程序。/etc/defaults/rc.conf中包含了运行named 的选项,但被注意掉了。无论你是在
安装一个新的系统,还是升级一个已存在的系统,被这些sandboxes 使用的特殊用户帐号
可能没有被安装。谨慎的系统管理员无论何时都要认真研究和执行sandboxes。
有许多其他的服务器通常不能运行在sandboxes 中:sendmail, popper, imapd, ftpd, 
和其他一些。你可以选一些,但安装它们可能需要你做很多工作。你可能必须以root 来运
行这些服务器,然后依靠其他的机制来检测可能通过他们进行的侵入活动。
其他比较大的潜在的root 漏洞是安装在系统中的suid-root 和sgid 程序。这些程序, 
象rlogin,都放在/bin, /sbin, /usr/bin,或/usr/sbin 中。当然,世上没有100%的安全, 
系统默认的suid 和sgid 程序可能认为是比较安全的。
另外,root 漏洞有时候能在这些程序中找到。在1998 年在xterm 的Xlib 中的一个root 
漏洞被发现。谨慎的系统管理员需要限制suid 的程序,只有指定的人可以运行,指定人所
在的特殊组可以访问,其他人都不能使用。一台没有显示器的服务器通常不需要一个xterm 
程序。
Sgid 程序可能也会有危险。如果一个入侵者能够攻破sgid-kmem 程序,入侵者就可以
第5 页FreeBSD 使用手册
读到/dev/kmem,因而可以读到crypted 密码文件,从而危及到受密码保护的帐户的安全。
另外,一个侵入组kmem 的入侵者可以通过pty’s 来监测到击键的情况,包括通过安全方
法登陆的用户的情况。一个侵入tty 组的入侵者可以写入几乎任何用户的tty。如果用户正
在运行一个终端程序或带有键盘模拟特性的模拟器,入侵者可以偷偷地发送一个数据流来
使用户的终端显示一个命令,然后就以那个用户的身份来运行。
10.3.3 确保用户帐户的安全
用户的帐户通常是很难确保安全的。当你用严格的访问限制来约束你的用户时,你不
可以使用你有的普通用户帐户来这样做。如果你有充分的控制,那你可以确保用户帐户的
安全。如果没有,你必须时刻警惕地监视那些帐户。为用户的帐户使用ssh 和kerberos 可
能会有问题,需要额外的管理和技术支持,但与crypted 密码文件相比仍是一个比较好解决
方案。
10.3.4 确保密码文件的安全
唯一的确保安全的方法是用*号来代替输入的密码,使用ssh 或kerberos 来访问那些帐
户。即使crypted 密码文件(/etc/spwd.db)只能被root 读取,入侵者可能无法获得root 写
的权限,但也可能会获得读的权限。
你的安全脚本必须经常检查和报告密码文件的修改情况。
10.3.5 确保内核核心,Raw 设备和文件系统的安全
如果一个入侵者攻破root,他就可以做任何事情。例如,绝大多数现代内核都有一个
包来探测内建的设备启动器。在FreeBSD 下,它被叫做bpf 设备。一个入侵者通常会试图
在一台不安全的机器上运行一个包探测器。所以,绝大多数系统都不把bpf 设备编译进内
核。
但即使你关闭了bpf 设备,你仍然可能会对/dev/mem 和/dev/kmem 担心。因为,入侵
者仍可以写到raw 磁盘设备。另外,还有另一个叫做module loader 的内核特性,kldload。
一个入侵者可以在运行内核时使用一个KLD module 来安装它自己的bpf 设备,或其他检测
设备。
第6 页FreeBSD 使用手册
要避免这些问题,你必须在更高安全级别上运行内核,至少在securelevel 1 上。
Securelevel 可以在kern.securelevel 变量上用sysctl 来设置。一旦你把securelevel 设
置成1,对raw 设备的写入操作将被拒绝,特殊的chflags 标记如schg 将被强迫执行。你
必须保证schg 标记被设置在特定的启动程序,目录和脚本文件上。这样做可能有点夸大了。
当你在一个安全性比较高的水平上操作时,升级系统可能比较困难。
你可以折中一下,将系统运行在一个安全性更高的水平上,但不对每个系统文件和目
录设置schg 标记。另外一个方法是简单地将/ 和/usr 设为只读。这样就可以阻止所有重要
的侵入检测了。
10.3.6 检查文件的完整性:程序,配置文件等
你需要保护你的核心系统配置和控制文件。例如,在/和/usr 中的绝大多数文件上使用
chflag 来设置schg 位可能达不到预期的目标,因为当它保护文件的时候,它也会关闭一个
检测窗口。你安全层的最后一层也许是最重要的检测层。如果你不能检测到潜在的入侵, 
你安全层的其余部分可能就没有用了。你的工作是要让入侵者慢下来,而不是阻止它,以
便寻找时机抓住它。
检测入侵的最好方法是寻找有没有修改,丢失或不需要的文件。寻找修改文件的最好
方法是来自另一个访问受限制的系统。在一个特别的访问受到限制的系统上写上你的安全
脚本使得入侵者不可见,这一点很重要。为了集中优势,你通常必须使用有限访问的机器
来访问其他机器,通常是执行一个其他机器的只读NFS 输出到有限访问的机器,或通过设
置ssh 钥匙对来允许有限访问的机器ssh 到其他机器。除了它的网络传输,NFS 是很少用的
方法---允许你监视每个客户机的文件系统。
如果你的有限访问服务器通过一个switch 来连接到客户机,NFS 方法是比较好的选择。
如果你的有限访问服务器是通过一个hub 或通过几层的路由连接到客户机,NFS 方法可能很
不安全,使用ssh 可能是更好的选择。
一旦你使用一个访问受限制的机器,至少需要能读取客户系统,你必须写一些脚本来
执行实时的检测。挂上NFS 之后,你可以用find 和md5 这样的工具。至少每天一次物理地
md5 客户机文件。当发现匹配错误时,会发出“尖叫声”提示系统管理员去检查。一个安全
脚本也会检查不适当的suid 程序和系统分区上新增或删除的文件。
第7 页FreeBSD 使用手册
当使用ssh 而不是NFS 时,写入安全脚本是很困难的。为了运行它们,你必须scp 脚
本到客户机上,使它们看得见,为了安全你也必须scp 那些脚本使用的程序。在客户机上
的ssh 程序已经有安全问题了。总的来讲,当通过不安全的连接运行时,使用ssh 可能是
必须的,但它也比较难处理。
一个好的安全脚本将通过访问配置文件来检查用户的变
化:.rhosts, .shosts, .ssh/authorized_keys。它已经超出了MD5 检查的范围。
如果你有一个巨大的磁盘空间,它可能需要花很长时间来检查每个文件。在这种情况
下,设置挂载标记来不接受suid 程序和设备在那些分区上是一个好主意。nodev 选项nosuid 
选项正是你所看到的。你可以把它们扫描一下,至少一个星期一次。
处理帐户是操作系统的一个相关特性,它可以作为一个post-break-in 的评价机制。
它在跟踪入侵者是如何侵入系统的时候特别有用. 
最后,安全脚本应当处理日志文件。一个入侵者设法掩盖自己的踪迹,日志文件可以
指示系统管理员设法追踪到最初侵入的时间和方法。确保日志文件持久记录的日志文件的
一个方法是运行系统控制台到一个串行口,通过持续不断地检测控制台来收集信息。
10.3.7 偏执狂
带点偏执可能不会有伤害。作为一个惯例,一个系统管理员需要添加许多安全特性, 
并且尽可能地不影响到使用的便利性。更重要的是一个安全系统管理员应当经常修复漏洞。
10.3.8 拒绝式服务攻击(DoS) 
这节将介绍拒绝式服务攻击。一个DoS 攻击通常是一个包攻击,它可以使你的网络瘫
痪。你应当做一些限制,让攻击不会瘫痪你的服务器。
1. 限制服务器的forks. 
2. 限制跳板springboard 攻击(ICMP response attacks, ping broadcast, etc.)。
3. 内核通道的缓存。
一个普通的DoS 攻击通常试图让服务器吃掉所有进程,文件描述和内存,直到机器死
机。inetd 有好几个选项可以来限制这种攻击。需要注意的是当无法阻止一个服务被攻击所
打断时,可以阻止一台机器当机。阅读一下inetd 的联机手册,特别需要注意-c, -C, 和
第8 页FreeBSD 使用手册
-R 选项。注意,哄骗式的IP 攻击可以饶过inetd 的-C 选项。所以,最好一起使用这些选
项。
Sendmail 有一个-OMaxDaemonChildren 选项,它往往要比sendmail 的负载限制选项工
作得好。你必须指定一个MaxDaemonChildren 参数,当你启动sendmail 时,可能你期望有
很高的负载,但电脑无法处理这么高的负载。在队列模式运行sendmail 时要非常谨慎
(-ODeliveryMode=queued)。如果你在一个很短的时间间隔内实时分发你运行的队列,如
-q1m,一定要为sendmail 指定一个合适的MaxDaemonChildren 选项以免发生错误。
Syslogd 可能会被直接攻击,强烈建议你使用-s 选项,或-a 选项。你也应当注意象
tcpwrapper 的reverse-identd 这样的后台连接服务,它可以被直接攻击。因为这个原因, 
你通常不要使用tcpwrappers 的reverse-ident 特性。
在你的路由器上设置一道防火墙来隔离内部网络与外部网络之间的连接是非常好的安
全方法。这样可以阻止你的内部网络受到来自外部网络的攻击。
这个方法可以阻断除了你指定的如named, ntalkd, sendmail 这样的服务以外的低级
端口。如果你设法使用其他方法来配置防火墙,你可能会忘记关闭一对服务,或你添加了
一个新的内部服务而忘记了升级防火墙。
你也可以在防火墙上打开比较高的端口范围,允许有许可性质的操作,而不会危及你
的低级端口的安全。FreeBSD 允许你控制用来动态绑定的端口号码的范围,通过不同的
net.inet.ip.portrange sysctl's(sysctl -a | fgrep portrange),将会减轻你的防火墙
配置的复杂性。例如,你可以使用普通的4000 到5000 端口范围,以及更高的49152 到
65535 端口范围,然后隔断4000 以下的端口。
另一个普通的DoS 攻击叫做springboard 攻击—它会让服务器不断产生回应,最终导
致服务器,本地网络或其他机器超载。最普通的攻击是ICMP ping broadcast attack。
攻击者欺骗性地用源IP 地址向你的LAN 广播地址发送ping 数据包到他们希望攻击的
实际机器。如果你的路由器无法阻止他们ping 广播地址,你的LAN 就会对每个欺骗性的请
求产生回应,从而侵占大量的网络资源,特别是当攻击者使用同样的欺骗手段用几十个广
播地址从几十个不同的网络进攻时。
第9 页FreeBSD 使用手册
超过120MB 的广播攻击是常用的。另外一个普通的攻击是针对ICMP 错误报告系统的。
通过产生数据包来形成ICMP 错误请求,一个攻击者可以侵占一个个服务器的输入网络,使
得服务器用ICMP 请求占满它的输出网络。如果服务器不能很快地处理ICMP 请求的话,这
种类型的攻击也可以使服务器瘫痪。FreeBSD 内核有一个叫做ICMP_BANDLIM 的新的内核选
项,它可以限制这些端口攻击的效率。这种跳板类的攻击是与象这样的udp echo 服务的某
个内部inetd 服务有关的。
一个攻击者只要简单地用成为服务器A 的echo 端口的源地址和成为服务器B 的echo 
端口的目的地址来哄骗一个UDP 数据包。两个服务器就来回地弹发数据包。攻击者只要发
送几个这种类型的数据包就可以使服务器和内部网瘫痪。类似的问题也存在于内部chargen 
端口。一个熟练的系统管理员会关闭所有这些内部的inetd 测试服务。
哄骗式数据包攻击也可以被用来是内核路由缓存超载。可以参考一下
net.inet.ip.rtexpire, rtminexpire, 和rtmaxcache sysctl 参数。随意使用一个源IP 
进行的哄骗式的数据包攻击将使内核在路由表中产生一个临时的高速缓冲路由,可以用
netstat -rna | fgrep W3 检查一下。这些路由大约会超时1600 秒。如果内核检测到缓冲
路由表太大,它将动态地减少rtexpire,但不会小于rtminexpire。有两个问题: 
1. 当一个负载量很小的服务器突然受到攻击时,内核没有很快地响应。
2. 由于rtminexpire 太小而无法抵抗住一个持续不断的攻击。
如果你的服务器通过T3 或更高速度的线路连接到internet,可能需要通过使用sysctl 
来手动地调整rtexpire 和rtminexpire。千万不要把参数设为0(除非你想要摧毁机器)。
把参数设为2 秒对于保护路由表免受攻击是非常好的。
10.3.9 用Kerberos 和SSH 的访问问题
如果你打算使用它们的话,在kerberos 和ssh 之间有好几个问题需要记住。Kerberos 
V 是一个非常卓越的验证协议,但在加密telnet 和rlogin 应用程序时会有一些错误,可能
会使它们不太适合处理二进制数据流。另外,默认的kerberos 也无法加密一个会话,除非
你使用-x 选项。ssh 默认能加密任何东西。
我们建议无论用户什么时候登陆系统,你都可以结合kerberos 来使用ssh。ssh 可以在
编译时加入对kerberos 的支持。我们也建议你在ssh 配置中关闭key-forwarding,或者在它
第10 页FreeBSD 使用手册
的authorized_keys 文件中使用from=IP/DOMAIN 选项使得只有用作实体的密匙可以从特殊
机器登陆进系统。
10.4 DES, MD5 和Crypt 
在unix 系统上的每个用户有一个与他们的帐号相关联的密码。看起来这些密码只有用
户和操作系统知道。为了确保这些密码的秘密,他们通过一种叫做one-way hash 的方式来
加密,它们能被很容易地加密,但不能解密。换句话说,以前我们告诉你的通常不是真的: 
操作系统通常并不真正知道密码。它只知道密码的加密形式。
加密密码的唯一安全方式是以DES 为基础的数据加密标准。这对于US 用户来说没有什
么问题,但DES 的源代码不允许被输出到US 以外的国家,FreeBSD 必须找到一个既遵守US 
法律,又要与其他使用DES 的unix 兼容的方法。
解决方法是分解加密库以至于US 用户可以安装DES 库和使用DES,而国际用户也有一
个加密方法。这就是FreeBSD 为什么使用MD5 来作为默认的加密方法。MD5 被认为要比DES 
更安全,所以使用DES 主要是为了兼容性的原因。
10.4.1 重新配置你的Crypt 机制
可以很容易地设置FreeBSD 使用哪种加密方法。检查/etc/master.passwd 文件中的加
密密码是一种方法。用MD5 加密的密码通常要比用DES 加密的密码长,通常以$1$字符作为
起始。DES 密码字符没有任何鉴别特征,但它们要比MD5 密码短,通常是以64 位字符的字
母表来编码的,它不包括$字符,所以通常一个不以$符号开始的很可能是DES 密码。
也可以通过区别库来鉴别密码。DES 库能够鉴别MD5 密码,使用MD5 来检查用哪种方法
加密的密码,然后用DES 加密剩下的。之所以可以这样做,是因为DES 库也包括MD5。但是, 
倒过来就不行了,所以MD5 库不能鉴别用DES 加密的密码。
鉴别你当前系统使用的是哪个库也是很容易的。任何使用crypt 的程序是与libcrypt 
连接在一起的,每一种类型的库是与适当的执行程序有一个符号连接的。例如,在使用DES 
的系统上: 
% ls -l /usr/lib/libcrypt* 
lrwxr-xr-x 1 root wheel 13 Mar 19 06:56 libcrypt.a -> libdescrypt.a 
第11 页FreeBSD 使用手册
lrwxr-xr-x 1 root wheel 18 Mar 19 06:56 libcrypt.so.2.0 -> 
libdescrypt.so.2.0 
lrwxr-xr-x 1 root wheel 15 Mar 19 06:56 libcrypt_p.a -> libdescrypt_p.a 
在使用MD5 库的系统上,同样的连接也会出现,但目标库是libscrypt 而不是
libdescrypt。如果你安装了DES 用的crypt 库libdescrypt,哪个密码格式将被用作新的密
码可以通过在/etc/login.conf 中设置passwd_format 来控制,要么使用DES,要么使用MD5。
看看login.conf 的联机手册了解更多信息。
10.5 S/Key 
S/key 是基于单向hash 功能的一次性密码管理方式。FreeBSD 为了考虑兼容性,就使
用MD4 hash 函数,但其它系统则使用MD5 和DES-MAC。从1.1.5 版开始,S/key 已经成为
FreeBSD 的基本系统,同时也广泛应用于其他操作系统。S/key 是Bell Communications 
Research, Inc 的注册商标。
下面将讨论三种不同的密码形式。第一种是你通常使用的Unix 风格或Kerberos 密码; 
我们把它叫做Unix password。第二种是由S/key 程序产生,然后被keyinit 程序和登陆命
令接受的一次性密码;我们把它叫做one-time password。最后一种密码是由专门的密码生
成程序生成的秘密密码;我们把它叫做secret password 或绝对password。
秘密密码与unix password 毫无关系;他们也可能是一样的,但并不推荐使用。S/key 
秘密密码不象unix 密码需要限制在8 位以内,它们可能会更长。一般都使用6 到7 位的长
度。另外,S/key 系统操作完全独立于unix password 系统。
除了密码,对于S/key 有两个数据很重要。一个是以seed 或key 出名,包含两个字母
和五个数字。其他的被叫做iteration count,在1 到100 之间。S/key 通过连接“种子” 
(seed)和秘密密码来生成一次性密码,然后通过反复计算多次应用MD4 hash,再把结果
变成六个英文字。这六个英文字就是你的一次性密码。如果用户提供的密码的hash 值与先
前的密码相一致,那用户就通过了认证;每个成功的登陆确保用户和登陆程序保持同步之
后,计算的次数就不断减少。当反复计算的降到1 时,S/key 必须被重新初始化。
有四个程序被包含在S/key 系统中,我们下面会谈到。密码程序接受一个反复计算数, 
一个种子,和一个秘密密码,然后产生一个一次性密码。Keyinit 程序被用来初始化S/key, 
第12 页FreeBSD 使用手册
然后改变密码,反复计算数或种子;它不是接受一个秘密密码,就是一个反复计算数,种
子和一次性密码。Keyinfo 程序会检查文件,然后打印出被调用的当前反复计算数和种子。
最后,login 和su 程序包含了用于认证S/key 一次性密码的必需的逻辑性。login 程序也
可以不使用unix 密码。
我们将讲述四种不同的操作。第一种是首先通过一个安全连接设置S/key 使用keyinit 
程序,或改变你的密码或种子。第二种操作是通过一个不安全的连接使用keyinit 程序, 
通过一个安全的连接与密码程序相关联,同样能达到目的。第三种是使用密码程序产生许
多key,它可以被记录或打印出来。
10.5.1 安全连接的初始化
首先是当通过一个安全连接登陆时,初始化S/key,改变你的密码,或改变你的种子, 
当你自己登陆时,使用不带任何参数的keyinit 程序: 
% keyinit 
Adding unfurl: 
Reminder - Only use this method if you are directly connected. 
If you are using telnet or rlogin exit with no password and use keyinit -s. 
Enter secret password: 
Again secret password: 
ID unfurl s/key is 99 to17757 
DEFY CLUB PRO NASH LACE SOFT 
在键入秘密密码时:你必须键入一个密码或短语。记住,这不是你用来登陆的密码, 
它只是用来产生一次性登陆密码。ID 行给出了你特定的S/key 实例的参数;你的登陆名, 
反复计算数,和种子。当用S/key 登陆系统时,系统将记住这些参数,然后把它们返回给
你,所以你不必记住它们。最后一行给出了与那些参数和你的秘密密码相一致的特定的一
次性密码;如果你需要立刻重新登陆,这个一次性密码就是你使用的。
第13 页FreeBSD 使用手册
10.5.2 不安全连接初始化
通过一个不安全的连接来初始化S/key 或改变你的秘密密码,你必须已经有连接到可
以运行密码程序的地方的安全连接。这可以是在Macintosh 上桌面访问的方式,或是在你
信任的机器上的一个shell 命令。你也必须指定一个反复计算数(通常是100),你可以使
用你自己的种子,或使用一个随机产生的值。在一个不安全的连接上,可以使用keyinit -s 
命令: 
% keyinit -s 
Updating unfurl: 
Old key: to17758 
Reminder you need the 6 English words from the key command. 
Enter sequence count from 1 to 9999: 100 
Enter new key [default to17759]: 
s/key 100 to 17759 
s/key access password: 
要接受默认的种子,键入return。然后键入一个访问密码,转移到你的安全连接或S/key 
桌面程序,给它指定一样的参数: 
% key 100 to17759 
Reminder - Do not use this program while logged in via telnet or rlogin. 
Enter secret password: <secret password> 
CURE MIKE BANE HIM RACY GORE 
现在,切换到不安全的连接,拷贝一次性通过密码程序产生的一次性密码给keyinit 
程序: 
s/key access password:CURE MIKE BANE HIM RACY GORE 
第14 页ID unfurl s/key is 100 to17759 
CURE MIKE BANE HIM RACY GORE 
10.5.3 产生一个简单的一次性密码
一旦你初始化你S/key,当你登陆时,你会看到下面的命令行: 
% telnet example.com 
Trying 10.0.0.1... 
Connected to example.com 
Escape character is '^]'. 
FreeBSD/i386 (example.com) (ttypa) 
login: <username> 
s/key 97 fw13894 
Password: 
另外,S/key 有一个很有用的特性:如果你在密码行键入return 键,登陆程序将会把
键入的密码显示出来,所以你可以看到你键入的密码。如果你试图手工键入一个S/key,这
个非常有用。如果这台机器被配置成通过一个来自源机器的连接不接受unix 密码,命令行
也将包括注意(S/key 必须),指出只有s/key 一次性密码将被接受。
基于这点,你必须产生你的一次性密码来回答这个登陆命令。这必须在一个可以运行密
码命令的可信任的系统上做。密码程序既需要反复计算数和种子,也需要命令行选项。你可
以从你登陆的机器的命令行剪切和粘贴这些选项。
在可信任的系统上: 
% key 97 fw13894 
FreeBSD 使用手册
第15 页FreeBSD 使用手册
Reminder - Do not use this program while logged in via telnet or rlogin. 
Enter secret password: 
WELD LIP ACTS ENDS ME HAAG 
现在,你已经有了可以继续登陆的一次性密码: 
login: <username> 
s/key 97 fw13894 
Password: <return to enable echo> 
s/key 97 fw13894 
Password [echo on]: WELD LIP ACTS ENDS ME HAAG 
Last login: Tue Mar 21 11:56:41 from 10.0.0.2 ... 
如果你有一个可信任的系统,这是最容易的机制。有一个java S/key 密码小程序,The 
Java OTP Calculator,你可以下载和在本地支持java 的浏览器中运行。
10.5.4 产生多个一次性密码
有时,你会来到你不能访问一个可信任的机器或安全连接的地方。在这个例子中,可以
使用密码命令来产生许多一次性密码,例如: 
% key -n 5 30 zz99999 
Reminder - Do not use this program while logged in via telnet or rlogin. 
Enter secret password: <secret password> 
26: SODA RUDE LEA LIND BUDD SILT 
27: JILT SPY DUTY GLOW COWL ROT 
28: THEM OW COLA RUNT BONG SCOT 
29: COT MASH BARR BRIM NAN FLAG 
第16 页FreeBSD 使用手册
30: CAN KNEE CAST NAME FOLK BILK 
-n 5 按顺序请求5 个密匙,30 指定了最后的反复计算的号码是什么。注意这些将按与
实际相反的顺序打印出来。如果你是一个偏执狂,你可以手工写下这些结果;否则你可以打
印出来。注意,每一行都显示了重复计算数和一次性的密码。
10.5.5 Unix 密码的限制使用
这种限制可能是基于主机名,用户名,终端口,或登陆时的IP 地址的unix 密码的使用。
这些限制可以在配置文件/etc/skey.access 中找到。skey.access 的联机手册中,有这个文
件的完整格式和细节。
如果没有/etc/skey.access 文件(这是FreeBSD 默认的),那所有的用户将被允许使
用unix 密码。如果文件存在,那所有的用户将被要求使用s/key,除非明确地允许这样做。
在所有的案例中,unix 密码是允许用在控制台的。
这儿是一个配置文件的例子,下面举三种普通使用的配置例子: 
permit internet 192.168.0.0 255.255.0.0 
permit user fnord 
permit port ttyd0 
第一行允许他的Ip 源地址与指定的值和掩码相配的用户使用unix 密码。这不应当被认
为是一种安全的机制,但应当提醒那些使用不安全连接的网络的用户必须使用s/key 验证。
第二行允许指定用户名在任何时候使用unix 密码,在这个例子中是fnord。一般来讲, 
这将被那些不能使用密码程序的人或不可教育的人来使用。
第三行允许所有的通过指定的终端行登陆的用户使用unix 密码;这将被用在拨号中。
10.6 Kerberos 
Kerberos 是一个网络附加系统/协议,可以允许用户通过一个安全服务器的服务来验证
他们自己。象远程登陆,远程拷贝,系统间的相互文件拷贝和其他高风险任务的服务将被变
得相当安全和可控制。
下面的文章将用来指导你如何为FreeBSD 设置Kerberos。你也可以参考相关的联机手册
第17 页FreeBSD 使用手册
了解更详细的说明。
在FreeBSD 中,Kerberos 不是来自最初的4.4BSD-Lite,而是eBones,来自于USA/Canada 
以外的地区,那些受到美国加密代码出口限制的国家就可以使用它。
10.6.1 创建最初的数据库
这只可以由Kerberos 服务器来做。首先确定你没有旧的Kerberos 数据库。你必须改变
/etc/kerberosIV 的目录,然后只检查下面出现的文件: 
# cd /etc/kerberosIV 
# ls 
README krb.conf krb.realms 
如果任何其他文件(如principal.* 或master_key)存在,那使用kdb_destroy 命令就
可以破坏旧的Kerberos 数据库,或者如果Kerberos 不在运行,只要删除其他的文件。
你现在必须编辑krb.conf 和krb.realms 文件来定义你的Kerberos 规则。在这个例子
中,规则将是GRONDAR.ZA,服务器是grunt.grondar.za。我们可以编辑或创建krb.conf 
文件: 
# cat krb.conf 
GRONDAR.ZA 
GRONDAR.ZA grunt.grondar.za 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 
第18 页FreeBSD 使用手册
TELECOM.MIT.EDU bitsy.mit.edu 
ARC.NASA.GOV trident.arc.nasa.gov 
在这个例子中,其他规则没有出现。他们在这儿作为一个机器如何应用多种规则的例子。
你可能希望不要简单地包括它们。
第一行命名了这个系统工作的规则。其它行包含了规则/主机的记录。每行的第一项就
是一个规则,第二个是充当一个key distribution center 的规则中的一台主机。接在一个
主机名后面的管理服务器的命令意味着主机也要提供一个管理数据库服务器。更多信息,可
以参考Kerberos 的联机手册。
现在,我们必须添加grunt.grondar.za 到GRONDAR.ZA,然后添加一个记录把所有主机
放在.grondar.za 域中。krb.realms 文件将被升级: 
# cat krb.realms 
grunt.grondar.za GRONDAR.ZA 
.grondar.za GRONDAR.ZA 
.berkeley.edu CS.BERKELEY.EDU 
.MIT.EDU ATHENA.MIT.EDU 
.mit.edu ATHENA.MIT.EDU 
它们在这儿作为一个例子来指出一台机器如何可以知道多个领域。你也可以简单地把它
们删除。
第一行把指定的系统放在已命名的域中。其他行显示了如何把一个特殊子域的系统默认
设为一个命名的域。
现在我们已经准备创建数据库。这将需要运行Kerberos 服务器。执行命令kdb_init: 
# kdb_init 
Realm name [default ATHENA.MIT.EDU ]: GRONDAR.ZA 
You will be prompted for the database Master Password. 
第19 页FreeBSD 使用手册
It is important that you NOT FORGET this password. 
Enter Kerberos master key: 
现在我们必须保存密匙,以便本地机器的服务器能够得到加速。使用kstash 命令: 
# kstash 
Enter Kerberos master key: 
Current Kerberos master key version is 1. 
Master key entered. BEWARE! 
这保存加密过的主密码在/etc/kerberosIV/master_key。
10.6.2 使它完全运行
有两个主要的东西需要被添加到要用Kerberos 确保安全的每个系统的数据库中。它们
的名称是kpasswd 和rcmd。这些程序允许其他系统改变Kerberos 的密码,然后象rcp, rlogin 
和rsh 一样运行命令。
现在,让我们添加这些记录: 
# kdb_edit 
Opening database... 
Enter Kerberos master key: 
第20 页FreeBSD 使用手册
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 ] ? 
第21 页FreeBSD 使用手册
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. 
第22 页FreeBSD 使用手册
Principal name: <---- null entry here will cause an exit 
10.6.3 创建新的服务器文件
我们现在必须分析在每台机器上定义的服务的所有情况。我们使用ext_srvtab 命令。
这将创建一个文件,它必须通过安全方式被拷贝或移动到每个Kerberos 客户端的
/etc/kerberosIV 目录。这个文件必须在每个服务器和客户机上出现,这对Kerberos 的操
作是很重要的。
# ext_srvtab grunt 
Enter Kerberos master key: 
Current Kerberos master key version is 1. 
Master key entered. BEWARE! 
Generating 'grunt-new-srvtab'.... 
现在,这个命令只产生一个临时文件,它必须被重命名为srvtab,以便所有的服务可
以得到加速。使用mv 命令把它移到最初的系统上: 
# mv grunt-new-srvtab srvtab 
如果文件是针对客户系统的,那网络可能就会不安全,拷贝client-new-srvtab 到可抽
取式设备上,然后通过安全的物理方式进行传输。确信在客户机的/etc/kerberosIV 目录中
把它重命名为srvtab,确定它是mode 600: 
# mv grumble-new-srvtab srvtab 
# chmod 600 srvtab 
10.6.4 定位数据库
第23 页FreeBSD 使用手册
我们现在添加一些用户记录到数据库。首先,让我们为用户jane 创建一个记录。使用
kdb_edit 命令来完成: 
# 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 
第24 页FreeBSD 使用手册
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 
10.6.5 测试所有的
首先我们必须启动Kerberos 守护程序。注意如果你没有正确地编辑你的/etc/rc.conf 
文件,那这将在你重启系统的时候自动发生。这只有在Kerberos 服务器上是必须的。
Kerberos 客户机将从/etc/kerberosIV 目录自动获得他们所需要的。
# 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: GRONDAR.ZA 
# kadmind -n & 
第25 页FreeBSD 使用手册
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 的“入场券”: 
% kinit jane 
MIT Project Athena (grunt.grondar.za) 
Kerberos Initialization for "jane" 
Password: 
如果我们正的有它们,使用klist 设法列出记号: 
% klist 
Ticket file: /tmp/tkt245 
Principal: jane@GRONDAR.ZA 
Issued Expires Principal 
Apr 30 11:23:22 Apr 30 19:23:22 krbtgt.GRONDAR.ZA@GRONDAR.ZA 
现在,如果kpasswd 程序可以得到数据库的验证,可以使用passwd 来检查正在修改的
密码: 
% passwd 
第26 页FreeBSD 使用手册
realm GRONDAR.ZA 
Old password for jane: 
New Password for jane: 
Verifying password 
New Password for jane: 
Password changed. 
10.6.6 添加su 特权
Kerberos 允许我们给每个需要root 权限的用户他们自己的分离supassword。我们现在
可以添加一个被用来验证su 到root 的id。使用kdb_edit,我们可以在Kerberos 数据库中
创建一个记录jane.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 
第27 页FreeBSD 使用手册
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 
现在设法获得一些记号来确定它在做什么: 
# kinit jane.root 
MIT Project Athena (grunt.grondar.za) 
Kerberos Initialization for "jane.root" 
Password: 
第28 页FreeBSD 使用手册
现在,我们必须添加用户到root 的.klogin 文件: 
# cat /root/.klogin 
jane.root@GRONDAR.ZA 
现在设法执行su: 
% su 
Password: 
看看我们有些什么符号: 
# klist 
Ticket file: /tmp/tkt_root_245 
Principal: jane.root@GRONDAR.ZA 
Issued Expires Principal 
May 2 20:43:12 May 3 04:43:12 krbtgt.GRONDAR.ZA@GRONDAR.ZA 
10.6.7 使用其他命令
在一个早期的例子中,我们创建了一个叫做jane 的用户作为一个root。这里就以这个
用户为例,这是Kerberos 默认的;如果必须的记录在.klogin 文件中,那形式
<username>.root 的<principal>.<instance>将允许<username> su 到root: 
# cat /root/.klogin 
jane.root@GRONDAR.ZA 
同样的,如果一个用户已在它们自己的home 目录行中: 
% cat ~/.klogin 
jane@GRONDAR.ZA 
第29 页FreeBSD 使用手册
jack@GRONDAR.ZA 
这允许在GRONDAR.ZA 中的已通过jane 或jack 验证的任何人通过rlogin, rsh 或rcp 
访问并登陆到jane 的在这个系统上的帐户或文件。
例如,jane 现在登陆进另一个系统,使用Kerberos: 
% kinit 
MIT Project Athena (grunt.grondar.za) 
Password: 
% 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 的帐户。
% kinit 
% rlogin grunt -l jane 
MIT Project Athena (grunt.grondar.za) 
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 
第30 页FreeBSD 使用手册
10.7 防火墙
防火墙是提高人们访问互联网的兴趣的一个工具,它能够提高私有网络的安全性。这节
将介绍防火墙是什么,如何使用它们,和如何使用内核中提供的工具来实现它们。
注意:人们经常认为在你的内部网络与外部网络之间建立一个防火墙能够解决所有的安
全问题。但是一个糟糕的防火墙设置要比没有防火墙可能更加危险。一个防火墙可以为你的
系统增加另一个安全层,但它不可能完全阻止一些黑客高手侵入你的系统。如果你觉得你的
防火墙能够完全阻止黑客入侵而放松了安全设置,那你可能会让黑客侵入你的系统变得更加
容易。
10.7.1 什么是防火墙? 
今天,经常使用的防火墙主要有两种类型。第一种类型是叫做packet filtering 
router,它主要是通过设置一定的规则来转发或阻止数据包的传输。第二种是proxy server, 
依靠守护程序来提供验证,然后转发数据包。
有时,有些站点同时使用两种类型的防火墙,以至只有某台机器(主要是bastion host) 
才能被允许发送数据包到内部网络。代理服务运行在bastion host上,通常它要比普通的
验证机制安全。
FreeBSD 有一个内核数据包过滤程序(IPFW),在这节的余下部分将详细讲到,但由于有
很多的代理服务器可以使用,所以在这篇文档中无法一一讲到。
10.7.1.1 数据包过滤路由
路由器是负责在网络之间转发数据的机器。一个数据包过滤路由器在它的内核中有额外
一部分代码,它们在决定数据包是被转发还是被阻止之前,会根据给出的规则比较每个数据
包。绝大多数现代的IP 路由软件都有数据包过滤代码。要启用这些过滤器,你必须定义一
些过滤代码的规则,以便它能决定数据包是否被允许转发或阻止。
过滤代码会检查所设定的匹配一个数据包头部内容的规则来决定这个数据包是否被通
过。一旦一个匹配找到了,这个规则动作就启用了。这个规则可能会减慢数据包以便传输数
据,或是发送一个ICMP 信息给这个数据包的发送者。只有第一个匹配会计数,以便按顺序
来查找到这些规则。因此,这些规则的列表可以被看作是规则链。
第31 页FreeBSD 使用手册
数据包匹配标准的变化依赖于使用的软件,但典型的你可以指定依赖于数据包的源IP 
地址,目的IP 地址,源端口号,目的端口号,或是数据包类型(UDP, TCP, ICMP 等)的规则, 
10.7.1.2 代理型服务器
代理型服务器是把普通系统守护程序(telnetd, ftpd 等)用作特殊服务器的机器。这些
服务器被叫做proxy servers。这个可以在你的防火墙主机上运行一个代理telnet 服务器, 
人们可以从外部telnet 进入你的防火墙, 通过一些验证机制,然后获得访问内部网络的权
利。
代理型服务器通常要比普通的服务器更安全,可以提供更广泛的验证机制,包括
one-shot 口令系统,所以即使有人设法寻找了你使用的密码,他们也不能使用它获得访问你
的系统的权利,因为密码会立即失效。由于他们不能给用户访问主机的权利,所以它使得想
要在的系统上安装后门变得困难得多。
代理型服务器有很多种限制访问的方法,所以只有某个主机获得了访问服务器的权利, 
他们才可以被设置,以至你可以限制哪个用户可以跟哪个机器交谈。另外,要使用哪个完全
取决于你选择的代理软件哪个更强大。
10.7.2 IPFW 允许你做些什么? 
IPFW,由FreeBSD 提供的软件,是一个位于内核中的数据包过滤和结算系统,有一个用
户水平的控制工具,ipfw。他们允许你定义和查询内核正在使用的规则。
IPFW 有两个相关的部分。防火墙那节允许你执行数据包过滤。也有一个IP 结算章节允
许你追踪你的路由器的情况。这将允许你看到你的路由器从某个机器得到了多少的传输量, 
或有多少的WWW 数据被转发。
你可以使用在没有路由的机器上在输入与输出的连接之间,使用IPFW 来执行数据包
过滤。这是IPFW 一个比较特殊的用法,同样的命令和技术也可以被用到。
10.7.3 在FreeBSD 上启用IPFW 
由于IPFW 的主要部分被捆绑在内核中,你必须要在你的内核配置文件中添加一个或多
个选项,这取决于你要使用哪个工具,然后重新编译内核。
与IPFW 相关的有三种内核配置选项: 
第32 页FreeBSD 使用手册
options IPFIREWALL 
将数据包过滤编译进内核。
options IPFIREWALL_VERBOSE 
通过syslogd 启用代码来允许记录数据包的日志。没有这个选项,即使你指定了,数据
包也不在过滤规则中被记录进日志。
options IPFIREWALL_VERBOSE_LIMIT=10 
通过syslogd 限制数据包日志的记录。你可以使用这个选项记录防火墙的活动,但不要
过多地使用syslogd,否则会给拒绝式服务攻击提供机会。当一个数据链记录到达指定的受
限制的数据包时,日志会在那个特殊的记录被关闭.要继续进行日志,你必须使用ipfw 工具
刷新相关的记数器: 
# ipfw zero 4500 
这儿的4500 是你希望继续日志的数据链记录。
先前的FreeBSD 版本已经包含了IPFIREWALL_ACCT 选项。现在,现在把它作为防火墙代
码已经变得很陈旧了。
10.7.4 配置IPFW 
IPFW 的配置可以通过使用ipfw 工具来完成。这个命令的语法看起来很复杂,但一旦
你理解个它的结构就会变得很简单。
当前,这个工具可以使用四种不同的命令:addition/deletion, listing, flushing 和clearing。
Addition/deletion 被用来建构控制数据包如何被接受,拒绝,和日志的控制规则。Listing 被
用来检查你规则设置的内容和数据包记数器。Flushing 被用来删除所有记录链的记录。
Clearing 被用来对一个或多个记数记录进行清零。
10.7.4.1 改变IPFW 的规则
这种形式的命令语法是: 
ipfw [-N] command [index] action [log] protocol addresses [options] 
第33 页FreeBSD 使用手册
当使用这种形式的命令时,会有一个正确的标记: 
-N 
在输出中解决地址和服务的名称。
给出的命令可以被缩短到最短的独特形式。正确的命令是这样的: 
add 
添加一个记录到firewall/accounting 规则列表
delete 
从firewall/accounting 规则列表中删除一个记录
先前使用的IPFW 可以分离firewall 和accounting 记录。现在的版本提供了与每个防
火墙记录数据包accounting。
如果提供一个索引值,它会被放置在数据链中的一个指定点的记录。否则,记录会被放
置在超过上次数据链记录的索引值100 的数据链的结尾(这不包括默认的策略,一般是
65535,deny)。
如果内核编译进IPFIREWALL_VERBOSE,日志选项会把匹配规则输出到系统控制台。
正确的指令是: 
reject 
阻止数据包,然后发送一个ICMP 主机或无法到达数据包端口给数据源。
allow 
通过数据包。(别名:pass and accept) 
deny 
阻止数据包。数据源没有得到ICMP 消息的通报。
count 
升级数据包记数器,但不允许/阻止以这个规则为基础的数据包。会继续对下一个数据
链记录进行搜索。
第34 页FreeBSD 使用手册
每个动作会通过加上一个简短明确的前缀来验证。
可能被指定的协议是: 
all 
匹配所有的IP 数据包
icmp 
匹配ICMP 数据包
tcp 
匹配TCP 数据包
udp 
匹配UDP 数据包
地址的规则: 
from address/mask [ port] to address/mask [ port] [via interface] 
你可以只指定与支持端口的协议相关联的端口(UDP 和TCP)。
所通过的路径是可选择的,可以指定一个本地IP 接口的IP 地址或域名,或是一个只与
来自这个接口的数据包匹配的接口名(如:ed0).接口单位数目可以用一个可选择的通配符
来表示。例如,ppp*将匹配所有内核PPP 接口。
指定一个address/mask的语法: 
address 

address/ mask-bits 

address: mask-pattern 
第35 页FreeBSD 使用手册
一个正确的主机名可以被指定用来代替IP 地址。mask-bits是一个十进制的数,可以
用来表示地址将被设置成多少位。例如,指定192.216.222.1/24 将创建一个允许与在C 类
子网中所有的地址相匹配的地址范围。(在这个例子中是,192.216.222)。mask-pattern 
是一个将与给定的地址想逻辑联系的IP 地址。任何关键字都可以被用来指定“任何IP 地址”。
指定将被阻止的端口号码: 
port [, port [, port [...]]] 
指定一个简单的端口或端口列表, 
port- port 
指定一个端口范围。你也可以结合一个简单的列表范围,但范围必须先被指定。
可用的选项是: 
frag 
匹配数据包中第一个片段。
in 
匹配进入的数据包
out 
匹配输出的数据包
ipoptions spec 
匹配IP 头包含用逗号分割的用spec指定的选项列表。IP 选项的支持列表是:ssrr (严
格源代码路由), lsrr (宽松源代码路由), rr (记录数据包路由),和ts (时间标记)。
established 
匹配已经建立TCP 连接的部分数据包。你可以通过在数据链中通过放置一个建立的规则
来调整防火墙的性能。
setup 
匹配试图建立一个TCP 连接的数据包。
第36 页FreeBSD 使用手册
tcpflags flags 
匹配包含flags标记的用逗号分割的TCP 头。支持的标记是fin, syn, rst, psh, ack, 
和urg。
icmptypes types 
匹配在types列表中出现的ICMP 类型。列表可以用一个以逗号隔开的联合或分离的排
列形式。通常使用的ICMP 类型是:0 echo reply (ping reply), 3 destination unreachable, 5 redirect, 
8 echo request (ping request), 和11 time exceeded 
10.7.4.2 列出IPFW 规则
这种形式的命令的语法是: 
ipfw [-a] [-t] [-N] l 
当使用这种命令时,有三种正确的标记: 
-a 
当列条目时,显示计数器的值。这个选项是唯一可以看到计数器值的方法。
-t 
显示每个数据链记录的最后匹配次数。定时的列表与用ipfw 工具输入的语法是不兼容
的。
-N 
试图分解给定的地址和服务名称。
10.7.4.3 提高IPFW 规则
语法是: 
ipfw flush 
这将把防火墙链中的所有记录都删除,除了内核中指定的可修复的默认策略(索引
65535)。当提高规则时可以使用警告,默认的阻止策略将迫使你的系统断开网络,知道允许
记录被添加到链中。
第37 页FreeBSD 使用手册
10.7.4.4 刷新IPFW 数据包记数器
刷新一个或多个数据包记数器的方法: 
ipfw zero [ index] 
当使用不带索引值选项时,所有的数据包计数器将被刷新。如果一个索引被启用,那刷
新操作将只影响一个指定的数据链记录。
10.7.5 使用ipfw 命令的例子
这个命令会阻止所有从主机evil.crackers.org 到主机nice.people.org 的telnet 端
口的数据包: 
# ipfw add deny tcp from evil.crackers.org to nice.people.org 23 
下一个例子会阻止和日志任何从crackers.org 网络(c 类地址)记录到机器
nice.people.org 的TCP 传输(任何端口)。
# ipfw add deny log tcp from evil.crackers.org/24 to nice.people.org 
如果你不要任何人发送X 会话给你的内部网络(C 类子网),下面的命令将会作必要的
过滤: 
# ipfw add deny tcp from any to my.org/28 6000 setup 
看看计算记录: 
# ipfw -a list 
或用一个简短的形式: 
# ipfw -a l 
你也可以看看上次相配的数据链记录: 
# ipfw -at l 
第38 页FreeBSD 使用手册
10.7.6 建构一个数据包过滤防火墙
注意:下面的建议仅仅是建议。每个防火墙的要求是不同的,我们不能告诉你如何建构
一个符合你特殊要求的防火墙。
当一开始设置你的防火墙时,除非你有一个可测试的设置,可以在一个可控的环境中配
置你的防火墙,否则强烈建议你使用命令的日志版本,和在内核中启用日志。这将允许你快
速地确定问题所在,以便不需要太久就可以修复。即使初始安装已经完成,还是建议你使用
日志来“阻止”有可能的攻击,或根据你的要求修改防火墙的规则。
注意:如果你使用接受命令的日志版本,它可以产生巨大的日志数据,所以巨大的
FTP/http 传输将使系统的性能大大下降。在数据包通过之前它会要求内核做更多的工作。
syslogd 将开始使用更多的处理时钟,以至有许多额外的日志被记录到磁盘上,不久就会填
满/var/log 分区。
你可以从/etc/rc.conf.local 或/etc/rc.conf 启用你的防火墙。相关的联机手册会解
释如何列出当前的防火墙配置。如果你不使用当前的配置,ipfw 列表将输出当前的规则设
置到一个文件rc.conf。如果你不使用/etc/rc.conf.local 或/etc/rc.conf 来启用防火墙, 
在任何接口被配置之前,确认你的防火墙被启用是很重要的。
下一个问题是你的防火墙实际上做了些什么!这主要依赖于你允许什么从外部访问你的
网络,和允许多少访问外部网络。一些通常的规则是: 
. 阻止所有TCP 端口小于1024 的访问。这是安全服务最敏感的地方,象finger, SMTP 
(mail) 和telnet。
. 阻止所有进入的UDP 传输。通过UDP 传输的有很多有用的服务,有什么有用的传输
服务,就会有什么安全问题。(如Suns RPC 和NFS 协议)。这也是它的缺点,既然UDP 
是一个无连接协议,阻止进入的UDP 传输也会阻止对输出UDP 传输的回应。这可能会对
使用外部archie 服务的人们带来麻烦。如果你要允许访问archie,你将必须允许来自端
口191 和1525 的数据包能够通过防火墙进入内部UDP 端口。ntp 是另一个你可以允许
访问通过的服务,它使用端口123。
第39 页FreeBSD 使用手册
. 阻止端口6000 与外部的传输服务。端口6000 被用来访问X11 服务器,可能会带来
一个潜在的安全问题。X11 实际上可以使用以6000 开始的端口范围,上面的限制取决于
你可以在机器上运行多少个X 显示程序。上面的限制通过RFC 1700 定义的是6063。
. 检查内部服务器使用什么服务器(如SQL servers 等)。阻止这些服务可能是一个好
主意,因为它们分布于上面指定的1-1024 的范围之内。
另外可以到下面这个网站去查看一下防火墙配置的列表
http://www.cert.org/tech_tips/packet_filtering.html 
就象上面提到的,这些只是guidelines (建议/ 指导原则)。你必须根据你的具体情况决
定使用什么过滤规则。如果有人侵入了你的网络,我们不承担任何责任,即使你按照了上面
提到的方法做了。
10.8 OpenSSL 
自从FreeBSD 4.0 以来,OpenSSL 工具包已经成为基本系统的一部分了。OpenSSL 提供
了一个普通的密码库,就象安全套接层v2/v3 (SSLv2/SSLv3),和传输层安全v1(TLSv1)网
络安全协议。
然而,包含在openssl 中的某些加密算法(特别是IDEA)被USA 加以限制了,它不能不
受限制地使用。在FreeBSD 中,IDEA 被包含在openssl 的源代码中,但它默认情况下没有
被构建。如果你想使用,你需要照着许可条款来操作,在/etc/make.conf 中启用MAKE_IDEA, 
然后重新建构整个系统。
今天,RSA 算法被自由使用在美国和其他国家。在过去它是受保护的。
10.8.1 源代码安装
OpenSSL 是src-crypto 和src-secure cvsup collections 的一部分。可以看看获得
FreeBSD 那节了解更多有关获得和升级FreeBSD 源代码的信息。
10.9 IPsec 
IPsec 机制提供了IP 层与socket 层之间安全的通讯方式。这节将介绍如何使用它们。
有关执行细节,请参考开发人员手册。
第40 页FreeBSD 使用手册
当前的IPsec 执行模式既支持传输模式也支持隧道模式。但隧道模式有一些限制。在
http://www.kame.net/newsletter/上有比较详细的例子: 
为了使用这个功能,请保持清醒,你必须将下面这些选项编译进内核: 
options IPSEC #IP security 
options IPSEC_ESP #IP security (crypto; define w/IPSEC) 
10.9.1 基于IPv4 的传输模式例子
让我们设置一个安全的连接以便在主机A (10.2.3.4)和主机B (10.6.7.8)之间配置一
个安全的通道。这儿列出了几个复杂的例子。从主机A 到主机B ,只有老的AH 可以被使用。
从主机B 到主机A,新的AH 和新的ESP 将被结合起来。
现在,我们必须选择一个算法以用来适应"AH"/"new AH"/"ESP"/"new ESP"。请参考
setkey 的联机手册了解算法的命名。我们的选择是对AH 用MD5,对新AH 用new-HMAC-SHA1, 
对新ESP 用带有8 位的new-DES-expIV。
关键字的长度依赖于每个算法。例如,关键字的长度对于MD5 需要用16 位,对于
new-HMAC-SHA1 需要用20 位,对于new-DES-expIV 需要用8 位。现在我们分别选择
"MYSECRETMYSECRET", "KAMEKAMEKAMEKAMEKAME", "PASSWORD"。
好的,让我们为每个协议分派一个SPI(Security Parameter Index)。请注意我们需要
为这个安全通道设计3 个SPIs,因为产生了三个安全headers。(one for from HOST A to HOST 
B, two for from HOST B to HOST A)。另外,你也要注意SPI 必须要超过或等于256。我
们依次选择1000, 2000 和3000。
(1) 
HOST A ------> HOST B 
(1)PROTO=AH 
ALG=MD5(RFC1826) 
KEY=MYSECRETMYSECRET 
第41 页SPI=1000 
(2.1) 
HOST A <------ HOST B 
<------ 
(2.2) 
(2.1) 
PROTO=AH 
ALG=new-HMAC-SHA1(new AH) 
KEY=KAMEKAMEKAMEKAMEKAME 
SPI=2000 
(2.2) 
PROTO=ESP 
ALG=new-DES-expIV(new ESP) 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50