10

10.1概要

这章将对系统安全概念作一个基本介绍,还有一些通用的好的规则和一些FreeBSD下的高级主题。这儿提到的许多主题已经很好地应用于系统和Internet的安全。确保你的系统安全将保护你的数据,智力财产,时间和其他很多东西不至于被入侵者或类似人员所窃取。FreeBSD提供了许多工具和机制来确保你的系统和网络的安全。

读完这章,你将了解到这些:

             FreeBSD的基本系统安全概念。

             FreeBSD中可用的如DESMD5这样的加密(crypt)机制。

             如何设置S/Key,一种一次性的口令验证机制。

             如何设置Kerberos,另一种口令验证机制。

             如何使用IPFW来创建防火墙。

             如何配置IPSec

             如何配置和使用OpenSSHFreeBSDSSH执行方式。

在阅读这章之前,你必须了解:

             了解基本的FreeBSDInternet概念。

10.2介绍

安全是系统管理至始至终最基本的要求。所有的BSD UNIX多用户系统都有它自身内在的安全性,建立和维护额外的安全机制,确保用户的诚实大概是系统管理最艰巨的工作之一。机器仅保持着建立时最原始的安全性,而安全性必须要考虑到用户使用的便利性。通常,UNIX系统能够支持巨大的并发用户处理,而这些处理中绝大部分是以服务器形式处理的——这意味着外部的实体能够互相连接和交谈。昨天的小型计算机和主机变成了今天的桌面机,计算机已连到局域网和互联网,安全就成了一个非常严峻的问题。

通过一个分层的方法,安全能够很好地实现。你所要做的就是创建很多的安全层,然后仔细地监视系统以防入侵。你不要过多地创建安全层,否则将会影响检测面。检测是许多安全机制中最重要的方法之一。例如,在每一个二进制程序中,去设置schg标记没有多大意义,因为这样会临时地保护二进制,它会阻止一个入侵者作一个很容易发现的修改,最终导致你的安全机制根本检测不到入侵者。

系统安全也涉及到许多攻击方式,包括试图摧毁或使一个系统无法使用,但不会试图破坏root。安全问题主要分成以下几类:

1.         拒绝服务的攻击。

2.         窃取用户的帐户。

3.         通过可访问服务器窃取root帐户。

4.         通过用户帐户窃取root帐户。

5.         创建后门。

拒绝式服务攻击是侵占机器所需资源的一种方法。有代表性的,D.O.S攻击,是一种非常残忍的攻击机制,它通过压倒性的流量来破坏服务器和网络堆栈,试图摧毁机器或使机器无法使用。一些D.O.S攻击利用在网络堆栈中的错误,仅用一个简单的信息包就可以摧毁一台机器。这可以向内核添加一个错误补丁来修复。在一些不利的条件下,对服务器的攻击能够被修复,只要适当地修改一下系统的选项来限制系统对服务器的负荷。顽强的网络攻击是很难对付的。例如,一个欺骗性信息包的攻击,无法阻止入侵者切断你的系统与Internet的连接。它不会使你的机器死掉,但它会把Internet连接占满。

窃取用户帐户要比D.O.S攻击更加普遍。许多系统管理员仍然在他们的服务器上运行着基本的telnetdrlogindrshdftpd服务。这些服务器默认情况下,不会通过加密连接来操作。结果是如果你的系统有中等规模大小的用户,在通过远程登陆的方式登陆到你系统的用户中,一些人的口令会被人窃取。仔细的系统管理员会从那些成功登陆系统的远程访问日志中寻找可疑的资源地址。

假定,一个入侵者已经访问到了一个用户的帐户,入侵者就会使超级用户失效。然而,事实是在一个很安全和可维护的系统中,访问用户的帐户不会让入侵者访问root。这个差别是很重要的,因为没有访问root的权限,入侵者是无法隐藏它的轨迹的,至少,除了把用户的文件弄乱或破坏机器外什么也做不了。窃取用户帐户是很普遍的事情,因为用户往往不会对系统管理员的警告采取措施。

系统管理员应该牢牢记住,可能有许多潜在的方法会使root失效。入侵者可能知道root的口令,可以在一个以root权限运行的服务器上找到一个错误(bug),就可以通过网络连接到那台服务器上使root失效,或者一旦入侵者已经侵入了一个用户的帐户,可以在自己的机器上运行一个suid-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终端在/etc/ttys文件中是以不安全的因素被指定的,以至直接通过telnetrlogin登陆root会不被接受。如果使用如sshd这样的其他登陆服务,确认直接登陆root也被关闭了。你可以通过编辑/etc/ssh/sshd_config文件来做到这一点,确信PermitRootLogin被设置成NO。考虑到每一种访问方法(如FTP这样的服务)经常会失败。直接登陆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机制仍然可能会让入侵者使root失效。虽然wheel机制比什么都没有要好得多,但它也不是最安全的选择。

确保用户帐户和最终使用root访问安全的间接方法是使用一个有选择性的登陆访问方法,为用户帐户使用加密口令。使用vipw命令,每一个加密的口令用一个简单的“*” 字符来代替。这个命令将升级/etc/master.passwd文件和用户名/口令数据库来关闭口令验证登陆。

一个用户帐户记录如:

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

由于加密的口令无法匹配“*”,这个修改将阻止普通的登陆发生。由于这一点,用户成员必须使用另一个如使用一个公共/私有密匙对的kerberosssh这样的机制来验证他们自己。当使用像kerberos这样的验证机制时,通常必须确保运行kerberos的服务器和你的桌面工作站的安全。当使用ssh的一个公共/私有密匙对时,通常必须确保用来登陆的机器的安全(典型的如你的工作站)。当用ssh-keygen命令创建密匙对时,需要通过保护密匙对的口令将一个另外的保护层添加到密匙对中。用“*”号隐藏用户帐户的口令也可以保证用户成员只可以通过你设定的安全访问方法来登陆。这迫使所有的用户成员为他们的所有会话使用安全的,加密的连接,这样就关闭了可以被很多入侵者使用的一个重要的漏洞:将一个毫无关系,很不安全的机器与网络隔离。

更多间接的安全机制也能够被实现。你可以从一个带有限制性的服务器到一个毫无限制性的服务器进行登陆。例如,如果你的主机运行在所有种类的服务器上,那你的工作站就无法运行任何东西。为了确保你工作站的安全,应当尽可能少运行些服务器,直到根本就没有包含服务器,然后运行一个受口令保护的屏保。当然,一个入侵者物理访问你的工作站,它就会把你所设置的所有安全特性都破坏掉。有一个问题必须明确,你必须考虑到这样一个事实,绝大多数入侵是从那些没有物理访问工作站或服务器权限的人那里,通过一个网络来侵入的。

使用像kerberos这样的技术,也会让你无法使用系统,或者改变用户帐户的口令,从而影响到拥有一个帐户的所有用户成员。如果一个用户成员的帐户已经失去安全,应当改变它在所有机器上的口令。对于不连续的口令,在N台机器上改变一个口令可能是很乱的。你可能要用kerberos重建口令的限制:一张kerberos的许可证可能一段时间后会过期,但kerberos系统可能要求用户在一段时间以后选择一个新口令(一般是一个月)。

10.3.2 确保以root权限运行的服务器和suid/sgid二进制程序的安全

谨慎的系统管理员只运行他需要的服务器,不多也不少。要清醒地认识到第三方的服务器经常有很多的错误。例如,运行一个老版本的imapdpopper,就像是给出了一个通用的root帐号来访问外部世界。运行每一个服务器,你都要仔细地检查。许多服务器不一定需要用root来运行。例如,ntalkcomsatfinger守护程序可能运行在一个特殊的用户发件箱(sandbox)上。一个sandbox是不完美的,除非你遇到了许多问题,但安全的层级模式仍然支持:如果能够通过运行在一个sandbox上的一个服务器侵入,他们仍然必须要攻破sandbox。入侵者必须通过很多的安全层,这样他侵入的可能性就很小了。过去已经找到了很多root的安全漏洞,包括基本的系统服务器。如果你运行着用户通过sshd来登陆而从不用telnetd rshdrlogind来登陆的服务器,你最好把这些服务关掉。

现在,FreeBSD默认在sandbox中运行ntalkdcomsatfinger。还有一个叫做named的程序。/etc/defaults/rc.conf中包含了运行named的选项,但被注释掉了。无论你是在安装一个新的系统,还是升级一个已存在的系统,被这些sandbox使用的特定用户帐号可能没有被安装。谨慎的系统管理员无论何时都要认真研究和执行sandbox

有许多其他的服务器通常不能运行在sandbox中:sendmailpopperimapdftpd和其他一些。你可以选一些,但安装它们可能需要你做很多工作。你可能必须用root来运行这些服务器,然后依靠其他的机制来检测可能通过他们进行的侵入活动。

其他比较大的潜在的root漏洞是安装在系统中的suid-rootsgid程序。这些程序,像rlogin,都放在/bin/sbin/usr/bin/usr/sbin中。当然,世上没有100%的安全,系统默认的suidsgid程序可能认为是比较安全的。另外,root漏洞有时候也能在这些程序中找到。1998年在xtermXlib中就发现了一个root漏洞。谨慎的系统管理员需要限制suid的程序,只有指定的用户可以运行,指定用户所在的特殊组可以访问,其他人都不能使用。一台没有显示器的服务器通常不需要一个xterm程序。sgid程序可能也会有危险。如果一个入侵者能够攻破sgid-kmem程序,入侵者就可以读到/dev/kmem,因而可以读到crypted口令文件,从而危及到受口令保护的帐户的安全。另外,一个侵入组kmem的入侵者可以通过pty终端来监测到击键的情况,包括通过安全方法登陆的用户使用的终端情况。一个侵入tty组的入侵者可以写入几乎任何用户的tty。如果用户正在运行一个终端程序或带有键盘模拟特性的模拟器,入侵者可以偷偷地发送一个数据流来使用户的终端显示一个命令,然后就以那个用户的身份来运行。

10.3.3确保用户帐户的安全

用户的帐户通常是很难确保安全的。当你用严格的访问限制来约束你的用户和用“*”号来隐藏他们输入的密码时,你不可以使用你有的普通用户帐户来这样做。如果你有足够的控制,那你可以确保用户帐户的安全。如果没有,你必须时刻警惕地监视那些帐户。为用户的帐户使用sshkerberos可能会有问题,需要额外的管理和技术支持,但与加密(crypted)的口令文件相比仍是一个比较好解决方案。

 

10.3.4确保口令文件的安全

唯一的确保安全的方法是用*号来代替输入的口令,使用ssh kerberos来访问那些帐户。即使加密的口令文件(/etc/spwd.db)只能被root读取,入侵者可能无法获得root写的权限,但也可能会获得读的权限。

你的安全脚本必须经常检查和报告口令文件的修改情况(看看下面检查文件的完整性章节)。

10.3.5确保内核核心,Raw设备和文件系统的安全

如果一个入侵者攻破root,他就可以很方便地做任何事情。例如,绝大多数现代内核都内建有一个数据包检测设备驱动程序。在FreeBSD下,它被叫做bpf设备。一个入侵者通常会试图在一台不安全的机器上运行一个数据包检测器。所以,绝大多数系统都不需要编译进bpf设备。

但即使你关闭了bpf设备,你仍然可能会对/dev/mem/dev/kmem担心。因为,入侵者仍可以写到raw磁盘设备。另外,还有另一个叫做模块化加载的内核特性,kldload。一个入侵者可以在运行内核时使用一个KLD 模块来安装它自己的bpf设备,或其他检测设备。要避免这些问题,你必须在更高安全级别上运行内核,至少在安全级别(securelevel1上。Securelevel可以在kern.securelevel变量上用sysctl来设置。一旦你把securelevel设置成1,对raw设备的写入操作将被拒绝,特定的chflags标记如schg将被强迫执行。你必须保证schg标记被设置在特定的启动程序、目录和脚本文件上。这样做可能有点夸大了。当你在一个安全性比较高的水平上操作时,升级系统可能会比较困难。你可以折中一下,将系统运行在一个安全性更高的水平上,但不对每个系统文件和目录设置schg标记。另外一个方法是简单地将//usr设为只读。这样就可以阻止所有重要的入侵检测了。

10.3.6检查文件的完整性:二进制程序,配置文件等

你需要保护你的核心系统配置和控制文件。例如,在//usr中的绝大多数文件上使用chflags来设置schg位可能达不到预期的目标,因为当它保护文件的时候,它也会关闭一个检测窗口。你安全层的最后一层也许是最重要的检测层。如果你不能检测到潜在的入侵,你安全层的其余部分可能就没有用了。你的工作是要让入侵者慢下来,而不是阻止他,以便寻找时机抓住他。

检测入侵的最好方法是寻找已修改过的,丢失或不需要的文件。寻找修改过的文件的最好方法是来自另一个访问受限制的系统。在一个特别的访问受到限制的系统上写上你的安全脚本使得潜在的入侵者无法看见,这一点很重要。为了集中优势,你通常必须使用有限访问的机器来访问其他机器,通常是执行一个其他机器的只读NFS输出到有限访问的机器,或通过设置ssh钥匙对来允许有限访问的机器ssh到其他机器。除了它的网络传输,NFS是很少用的方法——允许你在每个实际上无法检测客户机上监视文件系统。如果你的有限访问服务器通过一个交换机(switch)连接到客户机,NFS方法是比较好的选择。如果你的有限访问服务器是通过一个集线器(hub)或通过几层的路由连接到客户机,NFS方法可能很不安全,使用ssh可能是更好的选择。

一旦你使用一个访问受限制的机器,至少需要能读取客户系统,你必须写一些脚本来执行实时的检测。挂上NFS之后,你可以用findmd5这样的工具。至少每天一次物理地md5客户机文件。当发现匹配错误时,会发出尖叫声提示系统管理员去检查。一个好的安全脚本也会检查不适当的suid程序和系统分区上新增或删除的文件。

当使用ssh而不是NFS时,写入安全脚本是很困难的。为了运行它们,你必须scp脚本到客户机上,使它们看得见,为了安全,你也必须scp那些脚本使用的程序。在客户机上的ssh程序已经有安全问题了。总的来讲,当通过不安全的连接运行时,使用ssh可能是必须的,但它也比较难处理。

一个好的安全脚本将通过访问配置文件来检查用户成员的变化:

.rhosts.shosts.ssh/authorized_keys等等,这些文件已经超出了MD5检查的范围。

如果你有一个巨大的磁盘空间,它可能需要花很长时间来检查每个文件。在这种情况下,在那些分区上,设置加载标记来不接受suid程序和设备是一个好主意。nodevnosuid选项正是你所看到的。你可以把它们扫描一下,至少一个星期一次。

处理帐户是操作系统的一个相关特性,它可以作为一个post-break-in的评价机制。它在跟踪入侵者是如何侵入系统的时候特别有用。

最后,安全脚本应当处理日志文件,日志文件将用一个尽可能安全的方法来产生。一个入侵者设法掩盖自己的踪迹,日志文件可以指示系统管理员设法追踪到最初侵入的时间和方法。确保日志文件持久记录日志文件的一个方法是运行系统控制台到一个串行口,通过持续不断地检测控制台来收集信息。

10.3.7 偏执狂

带点偏执可能不会有伤害。作为一个惯例,一个系统管理员需要添加许多安全特性,并且尽可能地不影响到使用的便利性。更重要的是一个安全系统管理员应当经常修复漏洞。

10.3.8拒绝式服务攻击(DoS

这节将介绍拒绝式服务攻击。一个DoS攻击通常是一个包攻击,它可以使你的网络瘫痪。你应当做一些限制,让攻击不会瘫痪你的服务器。

1.    限制服务器的forks.

2.    限制跳板(springboard)攻击(ICMP response attacksping broadcast)

3.    内核发送的缓存。

一个普通的DoS攻击通常试图让服务器吃掉所有进程,文件描述符和内存,直到机器死掉。inetd有好几个选项可以来限制这种攻击。需要注意的是当无法阻止一个服务被攻击中断时,可以阻止一台机器当机。阅读一下inetd的联机手册,特别需要注意-c-C-R选项。注意,哄骗式的IP攻击可以绕过inetd-C选项。所以,最好一起使用这些选项。

Sendmail有一个-OMaxDaemonChildren选项,它往往要比sendmail的负载限制选项工作得好。你必须指定一个MaxDaemonChildren参数,当你启动sendmail时,可能你期望有很高的负载,但计算机无法处理这么高的负载。在队列模式运行sendmail时要非常谨慎(-ODeliveryMode=queued)。如果你在一个很短的时间间隔内实时分发你运行的队列,如-q1m,一定要为sendmail指定一个合适的MaxDaemonChildren选项以免发生错误。

Syslogd可能会被直接攻击,强烈建议你使用-s选项,或-a选项。你也应当注意像tcpwrapperreverse-identd这样的后台连接服务,它可以被直接攻击。因为这个原因,你通常不要使用tcpwrapperreverse-ident特性。

在你的边界路由器上设置一道防火墙来隔离内部网络与外部网络之间的连接是非常好的安全方法。这样可以阻止你的内部网络受到来自外部网络的攻击。这个方法可以阻断除了你指定的如namedntalkdsendmail这样的服务以外的低级端口。如果你设法使用其他方法来配置防火墙,你可能会忘记关闭一对服务,或你添加了一个新的内部服务而忘记了升级防火墙。你也可以在防火墙上打开比较高的端口范围,允许有许可性质的操作,而不会危及你的低级端口的安全。FreeBSD允许你控制用来动态绑定的端口号码的范围,通过不同的net.inet.ip.portrange sysctl’s(sysctl -a | fgrep portrange),这将会减轻你的防火墙配置的复杂性。例如,你可以使用普通的4000 5000端口范围,以及更高的49152 65535端口范围,然后隔断4000以下的端口(当然,除了某些特定的Internet访问端口)。

另一个普通的DoS攻击叫做跳板(springboard)攻击——它会让服务器不断产生回应,最终导致服务器、本地网络或其他机器超载。最普通的攻击是ICMP ping broadcast attack

入侵者欺骗性地用源IP地址向你的LAN广播地址发送ping数据包到他们希望攻击的实际机器。如果你的路由器无法阻止他们ping广播地址,你的LAN就会对每个欺骗性的请求产生回应,从而侵占大量的网络资源,特别是当入侵者使用同样的欺骗手段用几十个广播地址从几十个不同的网络进攻时。超过120MB的广播攻击是常用的。另外一个普通的攻击是针对ICMP错误报告系统的。通过产生数据包来形成ICMP错误请求,一个入侵者可以侵占一个服务器的输入网络,使得服务器用ICMP请求占满它的输出网络。如果服务器不能很快地处理ICMP请求的话,这种类型的攻击也可以使服务器瘫痪。FreeBSD内核有一个叫做ICMP_BANDLIM的新的内核选项,它可以限制这些端口攻击的效率。这种跳板类的攻击是与像udp echo这样的服务的某个内部inetd服务有关的。

一个入侵者只要简单地用成为服务器Aecho端口的源地址和成为服务器Becho端口的目标地址来哄骗一个UDP数据包。两个服务器就来回地转发数据包。入侵者只要发送几个这种类型的数据包就可以使服务器和内部网瘫痪。类似的问题也存在于内部chargen端口。一个熟练的系统管理员会关闭所有这些内部的inetd测试服务。

哄骗式数据包攻击也可以用来使内核发送缓存超载。可以参考一下net.inet.ip.rtexpire rtminexpirertmaxcache sysctl参数。随意使用一个源IP进行的哄骗式的数据包攻击将使内核在路由表中产生一个临时的高速缓冲路由,可以用netstat -rna | fgrep W3检查一下。这些路由大约会超时1600秒。如果内核检测到缓冲路由表太大,它将动态地减少rtexpire,但不会小于rtminexpire。有两个问题:

1.    当一个负载量很小的服务器突然受到攻击时,内核没有很快地响应。

2.    由于rtminexpire太小而无法抵抗住一个持续不断的攻击。

如果你的服务器通过T3或更高速度的线路连接到Internet,可能需要通过使用sysctl来手动地调整rtexpirertminexpire。千万不要把参数设为0(除非你想要摧毁机器)。把参数设为2秒对于保护路由表免受攻击是非常好的。

10.3.9KerberosSSH的访问问题

如果你打算使用它们的话,在kerberosssh之间有好几个问题需要记住。Kerberos V是一个非常卓越的验证协议,但在加密telnetrlogin应用程序时会有一些错误,可能会使它们不太适合处理二进制数据流。另外,默认的