分类: BSD
2008-04-03 17:09:14
console none unknown off secure |
初始设置为secure表示root用户可以在控制台登录,另外,它还表示系统重新启动之后,如果管理员要求进入单用户状态,将不询问root的口令进行验证,这是一个重要的安全漏洞。将secure更改为insecure可以使得进入单用户状态时首先验证root口令,它带来的后果是,一旦系统损坏了passwd文件(主要是master.passwd 文件),root口令无法认证,就没有办法进入单用户状态进行修复工作,此时使用安装盘启动fixit 系统进行才能进行修正。
使用另外一个运行在软盘上的小FreeBSD系统也能完成修复系统的任务,后面将介绍定制单软盘FreeBSD 系统的方法,这种小系统被称为PICOBSD,可以用于设置网关或防火墙,以及可以用作专有系统的嵌入式操作系统。
此外,为了防止用户无意中重新启动系统,还需要取消Ctrl-Alt-Del热键的重新启动能力,这需要重新定制内核时使用以下选项。
options SC_DISABLE_REBOOT |
注意,这是针对使用标准控制台syscon的系统才有效果。
当屏蔽了系统的热启动能力,那么重新启动或关闭系统便需要使用系统命令来完成,此时能启动系统的使用者便需要 root权限。而root口令知道的人越多,系统越不安全。此时可以使用软件包sudo来帮助解决这个问题,sudo 能限制某些特定用户使用root权限完成指定的操作,它使用用户本身的口令,而非root口令验证用户。
即使屏蔽了热启动能力,并且重新启动进入单用户状态也需要询问口令,系统仍然存在安全性问题。非法使用者可以首先切断电源,然后使用安装盘或其他不使用现有文件系统的FreeBSD系统盘启动系统,获得相关数据,或更改pas swd文件,以便在重新启动之后获得root权限。保护这些攻击,需要其他手段,例如设置计算机的启动口令,拆除系统上的软盘驱动器、光盘驱动器等。然而,对于能进行物理攻击的入侵者,他的行为就如同一个正常系统管理员修复系统的行为一样,没有绝对的办法能杜绝这样大胆妄为的举动。
如果管理员不能信任计算机系统的物理安全,为了防止信息外泻,唯一的方法是进行加密,可以通过Unix命令crypt 对具备敏感信息的文件加密。然而更简便的方法是使用一种加密文件系统,这类加密文件系统对于正常操作就如同标准文件系统一样,对任何应用程序的文件操作完全透明,然而数据是以加密方式保存到物理设备中。而且在网络中传送的也都是加密后的密钥,不必担心泄露密钥。FreeBSD下可以使用的加密文件系统为TCFS,但它这不是FreeBSD的标准配置,需要从 tcfs.dia.unisa.it/中单独获得。
为了加强控制台的安全,还应该阻止一般用户在控制台上登录入系统。为了达到这个目的,需要设置登录访问限制文件/etc/login.access。该文件由login程序读取,限制用户的登录位置,该文件中具备下面语句将屏蔽除了wheel组、admin之外的用户在console登录的权力。
-:ALL EXCEPT wheel admin:console |
第一个字符“-“号,用于指明该句是用于屏蔽,相反,“+“用于打开登录许可,由于这个文件主要用于控制登录位置的目的,所以打开登录许可的方式很少用得到。此后用冒号分隔的第二部分为帐号域,可以使用用户名和组名,以及使用 login.access的关键字All、ALL EXCEPT等定义用户。第三部分为登录位置,这里仅仅用于限制console。
这个文件不但能用来限制在控制台登录,也能用来限制从其他位置登录入系统,还可以限制一些帐户在所有的位置都不能登录,这样就能更好的保证安全性。
-:wheel:ALL EXCEPT LOCAL .local.net |
这句设置了对管理员组wheel的登录位置限制,只能在本地或者本地的local.net域内计算机上建立登录连接。设置对能执行特定操作管理员的登录限制也能增强系统安全性。
-:daemon bin lpd nobody nogroup:ALL |
这个设置限制一些特殊的系统用户在所有节点上都不能登录,系统中的很多帐户事实上是用于系统维护的目的,并没有任何用户需要使用他们登录,显然这也能增加安全性。
然而,使用login.access并不能表示该帐户就无法被非法使用了,很多网络服务不使用这个文件进行用户限制,而是使用自己的用户限制方式,因此入侵者可以通过这些网络服务攻击相关帐户。入侵者也可以通过先以其他用户身份登录,再使用su命令绕过这个限制。所以使用这个限制文件并不是一劳永逸的做法,事实上在保证网络安全方面,不存在百分之百的解决方案,只能通过各个方面配置,尽量提高安全性。
即使提供了有效的登录控制,对于某些不必要的缺省帐户或长期不再使用的帐户,最好还是将其删除,以最大可能的避免安全问题。例如用于UUCP的帐户uucp,只有很少的系统需要这个帐户。可以放心的是,FreeBSD系统中不存在没有口令保护的缺省帐户,这将满足一般用户的安全需要。
由于FreeBSD是一个多用户系统,不但能由控制台用户使用,还可以通过网络,提供其他用户使用。而允许其他用户通过网络使用系统的时候,必须要对用户进行验证。此时的一个重要的安全问题就是口令以明文形式在网络中传输的问题。
为了避免口令被窃听,有很多解决方法可以避免这个问题。一个很有意思的解决方法是使用一次性的口令系统,如 S/key,即使口令被窃听也不会对安全造成影响。FreeBSD缺省就支持S/key系统,每个用户都可以选择是否使用这个系统保证自己的口令安全性。为了使用S/key系统,首先需要使用keyinit初始化针对这个用户的口令串。
bash-2.02$ keyinit Updating wb: Old key: de415501 Reminder - Only use this method if you are directly connected. If you are using telnet or rlogin exit with no password and use keyinit -s. Enter secret password: Again secret password: ID wb s/key is 99 de415502 GAS SAM RUSK BASH NEWS WAIT |
由于这个命令是用于初始化S/key系统,要输入一个S/key口令短语(这个口令可以设置的非常长,通常建议使用一个句子以保证安全性),这个口令将影响以后产生的一次性口令,因此这个命令应该在一个安全连接的终端上(如控制台)执行,而不应该在通过普通telnet等网络连接的登录会话上执行。在两次输入S/key的口令之后,keyinit 将产生第一个一次性口令,keyinit输出的最后一行就是这个一次性口令,上面的ID行中的99指一次性口令的序列号,de415502是这个一次性口令对应的 “种子” 。口令的 “种子” ,和S/key口令短语相结合就用于产生不同的一次性口令序列。
当使用了keyinit初始化S/key之后,就可以立即使用S/key一次性口令登录了。也可以使用key 命令产生其他一次性口令,这需要指定一次性口令的序列号和种子。
bash-2.02$ key 99 de415502 Reminder - Do not use this program while logged in via telnet or rlogin. Enter secret password: GAS SAM RUSK BASH NEWS WAIT |
key将提示用户输入口令短语,因此这个命令也不应该通过网络来使用,只能用于直接连接的时候。然而不必为此担心,因为无论在那台计算机上,使用同样的序列号、种子和口令短语产生的口令序列都是同样的,因此可以在本地计算机上,产生用于远程FreeBSD计算机登录的一次性口令。
注意,S/key系统用于产生一次性口令使用的单向Hash函数可能不同,最常用的有MD4、MD5和DES 算法,使用不同算法产生的一次性口令序列不会相同。FreeBSD的S/key系统使用MD4算法,因此如果要在客户计算机为FreeBSD服务器产生S/key一次性口令,需要使用采用MD4算法的key程序。
这样当系统进行认证时,将提示skey序列号和种子。这样用户就能使用正确的一次性口令登录了。一旦一个口令用过,这个口令就不再被使用,而使用下一个序列号的口令。
Login: wb s/key 99 de415502 Password: |
由于每次使用过的口令将不再使用,而通过S/key认证的连接本身是不安全的连接,不应该用于再次产生新口令。那么如果仅通过本地计算机产生S/key口令,就限制了客户机上必须安装有S/key系统。事实上可以在建立安全连接的时候,一次可以产生多个S/key一次性口令,将这些口令记录或打印在密码本上,随用随查,只要密码本不丢失,就没有口令泄露的问题。产生多个S/key一次性口令需要使用-n参数执行key:
bash-2.02$ key -n 5 80 de415503 Reminder - Do not use this program while logged in via telnet or rlogin. Enter secret password: 76: FIR SIGH BABE SUNG FUSS BAY 77: SOCK HOME WAGE CAN BALL WORE 78: DORA JUNO JAY YET HEAD SLUR 79: COWL TROY HURT SLAB SCAR GAGE 80: TOE BAKE FRAU PEG DOE I |
这将产生5个一次性口令的序列,80为口令序列的结束序号。此后需要经常更新所使用的口令序列,即更改 S/key的种子,以产生新的口令序列。
更改S/key种子仍然还需要使用keyinit命令,然而此时有了一次性口令,就不需要在安全的终端上进行了,需要使用-s参数,使得keyinit使用一次性口令来获得S/key口令短语,而不必直接输入S/key口令短语。只要保证S/key口令短语的安全,就能保证整个S/key一次性口令序列不会被再现。
bash-2.02$ keyinit -s Updating wb: Old key: de415502 Reminder you need the 6 english words from the key command. Enter sequence count from 1 to 9999: 100 Enter new key [default de415503]: s/key 100 de415503 s/key access password: GAS SAM RUSK BASH NEWS WAIT ID wb s/key is 100 de415503 GAS SAM RUSK BASH NEWS WAIT |
keyinit -s命令中,需要输入一次性口令序列中口令的数量,以及新种子的值。而用于认证的S/key 一次性口令为提示的一次性口令,这里为de415503,序列号为100。
需要注意的是,缺省情况下即使使用S/key认证,原有的Unix口令认证方式仍然有效,如果S/key认证不成功,系统就接下来使用原有的老Unix口令认证方式。对于一些图形界面的应用程序,不能提示S/key口令的序列号,那么用户也无法输入正确的一次性口令,此时使用老口令就有必要了。
然而,也能限制用户必须使用S/key口令,不能使用普通Unix明文口令,以更大程度上增强安全性。为了强制用户使用S/key口令,需要创建一个/etc/skey.access文件。
# touch /etc/skey.access |
当存在这个文件时,S/key认证系统就不再调用标准Unix认证系统。然而这个文件中可以设置一些例外的情况,允许使用Unix认证系统,例如在内部网络中允许使用Unix明文认证系统,等等。针对IP地址、用户和终端来设置可以使用Unix明文认证系统的权力。针对用户打开这个设置的情况一般是因为该用户不需要特别安全的情况,针对终端打开这个设置的情况通常发生在拨号访问FreeBSD系统的情况,由于认证口令不通过网络,因此也不需要 S/key加密。
permit internet 198.162.0.0 255.255.0.0 permit user aaa permit port ttyd0 |
对于一些需要自动进行认证的应用程序,需要将口令暂时保存起来,定时自动进行认证工作,但由于S/key的口令是一次性方式的,而客户软件不能根据S/key的提示,输入正确的口令,此时使用老口令也是必要的。如有些使用POP3 协议的客户端能定时从邮件服务器中下载邮件,这样就必须使用标准Unix口令。显然这明显是一个非常严重的安全漏洞,特别是明文口令不但是在网络上传输,而且是定时、多次传输的时候,问题更为明显。对于这样的情况,最好立即转换为支持加密口令的协议,对POP3来讲可以使用APOP协议。
FreeBSD下使用的另一种安全认证方式为Kerberos方式,这是一种安全的认证模式,然而它需要客户和服务器都支持这个认证方式才行。当前流行的Kerberos为Kerberos V,而FreeBSD下使用的为Kerberos IV ,因此与其他Kerberos客户存在兼容的问题,使得这个认证系统大部分情况下用于多台FreeBSD 系统之间进行认证。这里就不再介绍其使用方法了,需要使用这个能力的用户可以查看FreeBSD Handbook ,以获得相关的内容。
FreeBSD下也可以安装Kerberos V认证系统,它位于Posts Collecion中的sec urity部分中。
3.1-release之后的FreeBSD版本支持可加载的认证方式模块PAM,这种机制能使得系统能非常灵活的支持多种认证方式,具备非常大的可扩展性。PAM的设置文件为/etc/pam.conf,这里定义了各种条件下使用的认证方式。
# Configuration file for Pluggable Authentication Modules (PAM). # # This file controls the authentication methods that login and other # utilities use. See pam(8) for a description of its format. # # Note: the final entry must say "required" -- otherwise, things don't # work quite right. If you delete the final entry, be sure to change # "sufficient" to "required" in the entry before it. # # $FreeBSD: src/etc/pam.conf,v 1.1 1998/11/20 23:20:01 jdp Exp $ # If the user can authenticate with S/Key, that's sufficient. login auth sufficient pam_skey.so # Check skey.access to make sure it is OK to let the user type in # a cleartext password. If not, then fail right here. login auth requisite pam_cleartext_pass_ok.so # If you want KerberosIV authentication, uncomment the next line: #login auth sufficient pam_kerberosIV.so try_first_pass # Traditional getpwnam() authentication. login auth required pam_unix.so try_first_pass |
这是系统缺省的pam.conf文件,这里定义了三个认证过程,按照顺序系统将首先使用pam_skey.so ,然后pam_cleartext_pass_ok.so,最后是标准unix认证pam_unix.so。第一个是用于使用S/key系统认证,第二个不是一个认证,而是用于限制用户访问的,它检查/etc/skey.access ,以禁止非许可的节点、用户登录,因此其第三个参数为requisite,而非pam_skey.so对应的sufficient ,如果第二个设置许可,才能进入第三项定义的标准Unix认证方式。
注意,如果存在/etc/pam.d目录,PAM将在这个目录中寻找设置信息,而忽略pam.conf。
这些认证系统的动态连接库均位于系统中的/usr/lib/目录下,如果需要,可以增加其他认证方式。
# ls -l /usr/lib/*pam* -r--r--r-- 1 root wheel 59938 Feb 15 18:41 /usr/lib/libpam.a lrwxrwxrwx 1 root wheel 11 Apr 14 16:24 /usr/lib/libpam.so -> libpam.so.1 -r--r--r-- 1 root wheel 33451 Feb 15 18:41 /usr/lib/libpam.so.1 -r--r--r-- 1 root wheel 2895 Feb 15 18:41 /usr/lib/pam_cleartext_pass_ok.so -r--r--r-- 1 root wheel 6587 Feb 15 18:41 /usr/lib/pam_radius.so -r--r--r-- 1 root wheel 3798 Feb 15 18:41 /usr/lib/pam_skey.so -r--r--r-- 1 root wheel 6497 Feb 15 18:41 /usr/lib/pam_tacplus.so -r--r--r-- 1 root wheel 3333 Feb 15 18:41 /usr/lib/pam_unix.so |
其中每个以pam_开头的库均对应一种认证方式,可以看出系统中还能提供其他几种认证方式,如RADUIS、 TACPLUS等方式。使用libpam能帮助用户开发其他PAM认证程序。
PAM是一种新的、更为灵活的认证机制,以前的FreeBSD版本并不支持这种方式。PAM虽然更为灵活,但对于一般目的,缺省的支持s/key和标准认证方式的设置就能满足需要了,一般不必改动配置文件。然而有些时候,譬如 ISP,通常使用RADUIS服务器来保存用户的认证数据,此时使用RADUIS进行认证就能带来非常大的益处。因为 PAM涉及系统认证,因而对安全性非常重要,不能轻易加入一个非信任的认证模块,因为除了模块本身的问题之外,认证模块中很容易加入后门。建议经常检查/etc/pam.conf,/etc/pam.d/目录,以及/usr/lib/*pam* 文件是否被非法改动,以保证系统安全。
由于提供服务与保障系统安全性是有冲突的,提供的服务越多,就会存在越多的潜在的危险性。因此为了增加系统安全,就要尽量减少系统提供的服务。
提供网络服务的守护进程主要有两种启动方式,一种为从系统启动文件中启动,另一种为通过inetd超级守护进程启动应用程序。
通常的系统启动文件启动的守护进程有sendmail、syslogd、lpd等,要改变系统启动的服务进程,需要更改的文件包括/etc/rc.conf、/etc/rc.local,以及/usr/local/etc/rc.d 与/usr/X11R6/etc/rc.d目录下的以.sh结尾的启动文件(这两个启动脚本目录是由rc.conf 中的local_startup定义,因此也有可能被设置为了其他的值)。除非特殊情况,其他的rc文件不应该被改动,如果其他的rc文件被非法更改,很可能是入侵行为。
特别需要注意/etc/default/rc.conf,/etc/rc.conf.local文件,因为这些文件也能用于设置启动服务,而不被管理员所注意,因此可能是入侵者用于放置后门程序的位置。
为了减少守护进程,就需要将rc.conf中相关选项设置为NO,例如要屏蔽sendmail,就可以设置 sendmail_enable=”NO”。此外,缺省的rc.local文件中没有内容,因此在这里也不应该有降低系统安全的设置,/usr/local/etc/rc.d/和/usr/X11R6/etc/rc.d/目录下的执行脚本为安装其他软件包时所安装的,对于不希望提供的网络服务,应该将执行脚本更改为以其他后缀结尾的文件,只有以 .sh结尾的执行脚本才会在启动时自动执行。
一个安全的FreeBSD系统,应该具有干净的rc.local文件,/usr/local/etc/rc.d 与/usr/X11R6/etc/rc.d目录,以及尽量减少基本启动进程的rc.conf文件。
守护进程直接放在rc文件中启动,将具备root的权限,危险性较大。如果能使用用户的身份可以执行守护进程的相应操作,就应该使用用户的身份执行它。这可以通过使用su命令启动服务进程的方式,代替直接启动服务进程的命令。
su user services_process |
然而,Unix系统中绝大多数服务进程还是通过超级服务器进程inetd来启动的。它的设置文件为/etc/inetd.conf ,以下为这个文件的一部分。
# # $Id: inetd.conf,v 1.30 1998/09/30 16:12:40 wosch Exp $ # # Internet server configuration database # # @(#)inetd.conf 5.4 (Berkeley) 6/30/90 # ftp stream tcp nowait root /usr/libexec/ftpd ftpd -l telnet stream tcp nowait root /usr/libexec/telnetd telnetd shell stream tcp nowait root /usr/libexec/rshd rshd login stream tcp nowait root /usr/libexec/rlogind rlogind finger stream tcp nowait/3/10 nobody /usr/libexec/fingerd fingerd -s #exec stream tcp nowait root /usr/libexec/rexecd rexecd #uucpd stream tcp nowait root /usr/libexec/uucpd uucpd #nntp stream tcp nowait usenet /usr/libexec/nntpd nntpd comsat dgram udp wait root /usr/libexec/comsat comsat ntalk dgram udp wait root /usr/libexec/ntalkd ntalkd |
这个文件中的每一行对应一个服务程序。为了增强系统安全,建议除了必要的服务,如telnetd、ftpd之外,其他比如rshd、rlogind等r命令服务程序,fingerd等守护进程都应该加以注释。telnet和ftp 也应该与S/key等认证方式相结合,来保证口令的安全性。除非需要,不要提供匿名ftp服务。
当使用rlogin,rsh等r命令的时候,/etc/hosts.equiv文件和用户个人目录下的.rhosts 文件中的设置将对系统安全有严重的影响。
如果要求更安全的系统,甚至可以屏蔽inetd,不使用inetd来提供任何服务,通过其他安全途径来完成远程访问FreeBSD。要屏蔽inetd,需要在rc.conf中改变inetd_enable变量的值为NO。即使使用inetd的时候,最好让inetd记录相关日志,这需要使用参数-l启动inetd,在rc.conf中可以设置inetd_flags为”-l”。
当需要启动某个守护进程的时候,inetd.conf中的第五列参数对安全性有重要影响,这个参数设置启动这个进程的用户标识,应该尽量不要使用root用户,以减少具备root身份的进程。
为了避免服务程序出现问题,还要经常更新软件的版本,或应用补丁程序,以堵上可能出现的漏洞,因此有些服务程序的老版本存在已经发现的安全问题,如果不及时弥补,入侵者就能利用这些漏洞达到入侵系统的目的。虽然每个FreeBSD 版本使用的都是最新版本的服务软件,但服务器软件是不断升级的,因此就需要及时升级服务器软件。
在inetd启动的服务中,telnetd和ftpd是最重要的两个,它们提供最基本的网络服务。telnetd 本身的安全问题较少,与它相关的安全问题有访问认证问题,可以通过S/key,login.access等方式加以保护,而ftpd则的安全问题就更为敏感一些。
如果需要启动ftp服务,虽然在inetd.conf中启动ftpd已经使用了-l参数,使ftpd将日志记录发送给syslogd,但是还需要配置syslogd才能接收ftpd发送的记录。如果/etc/syslog.conf 文件中没有下面的设置行用于记录ftp的日志,请修改syslog.conf加入。
ftp.* /var/log/ftpd |
然后还需要执行下列命令,使得syslogd重新启动,使其能开始记录下ftpd发送的记录信息。
# touch /var/log/ftpd # killall -HUP syslogd |
ftp对访问进行了种种限制,这些限制对于网络安全都是非常重要的,当用户的shell不在/etc/shells 中的时候,ftp拒绝提供服务,当用户的用户名位于/etc/ftpusers文件中时,或者是/etc/ftpusers 中记录的组的成员,ftp同样也拒绝提供服务,这样就对使用ftp的用户进行了限制,尤其对于安全敏感的用户。如果/var/run/nologin文件存在时,ftp将拒绝一切用户访问。
ftp认证是通过标准认证过程进行的,因此也可以使用S/key等安全认证的方式。同样,/etc/ftphosts 可以设置对来自不同位置的主机访问ftp服务的限制。
很多情况下需要FreeBSD服务器提供匿名ftp服务功能,如果此时普通用户能通过更安全的方法访问系统,就应该屏蔽普通用户使用ftp服务的权力,而只允许匿名ftp,可以使用-A选项启动ftp服务器,此时ftp将拒绝正常用户登录,避免ftp服务器出现安全问题的可能性及减少安全问题的影响。当使用-S选项时,ftp将所有匿名访问的传输日志也记录在/var/log/ftpd文件中。这两个选项对于提供匿名ftp服务非常有用。对于提供匿名ftp 的服务器,还可以不再使用FreeBSD提供的ftpd服务器,而使用wuftpd或ncftpd等其他种类的ftp 服务器,同样也需要针对这些服务器设置其安全性。
当不得不提供一些服务的时候,为了增加安全性,可以考虑提供chroot的服务。chroot意味着改变运行程序的根文件系统,当一个程序运行在chroot的环境下时,它所了解的文件系统只是chroot设置给它的某级目录开始,它就不能访问这个目录之外文件系统中的内容,使得即使这个程序出现安全问题,也不会影响文件系统中的其他重要数据的安全性。显然不是每种服务都适合这种形式,有的服务提供访问的文件资源不固定在某个目录下,就不能使用这个形式。
由于设置一个服务程序使用chroot的时候,它就以为给它指定的目录就是它的根目录,因此它无论访问哪个文件,都将在相对的目录中查找,包括它要访问的重要系统文件。这样就必须为这个chroot程序建立一个小的,但完全满足其要求的系统目录结构,这个目录将和系统目录结构类似,也具有/etc/、/usr/、/var/、/dev/、/tmp/、/usr/lib/ 等等,并具备应用程序要访问的相应文件。
如果程序是动态连接的,就需要/usr/lib目录中存在动态连接库,应用程序还可能会访问/etc目录下的配置文件,/dev目录下的设备文件,以及其他可能的文件。必须在应用程序的新的根目录下设置所有必须的目录结构和复制需要访问的文件。当然文件内容可以是系统原来文件的一个子集,而非原有的整个文件,以尽可能的保障安全。例如服务程序要访问的passwd文件只是系统passwd文件的一部分,等等。
当chroot的程序需要访问某个用户的口令数据时,就需要将/etc/passwd文件中有关这个用户的内容复制到用户chroot目录下etc子目录下,然而口令文件并不止passwd一个文件,将包括master.passwd,pwd.db 及spwd.db。由于pwd.db和spwd.db使用了数据库形式,就使得复制部分用户数据变得比较困难。
改变根文件系统的服务程序有两种类型,一种为本身不具备改变根文件系统的能力,但由于不访问过多的文件,能使用系统的chroot命令来启动程序,使其运行在某个目录下。另一种类型为程序本身就支持这个能力,这样就不需要使用手工使用chroot命令,系统在特定条件下或使用一定参数启动时就自动进行chroot操作。然而这些类型进行目录设置时需要进行的操作是相同的。而要设置网络服务所使用的文件环境,就要对该服务程序有详细的了解,这才是最为困难的问题。
这里以配置改变根文件系统的namd为例,简介设置改变根文件系统的网络服务的步骤,这个设置步骤的原始文档为(这个适用于OpenBSD和Fr eeBSD,没有使用Ports Collection,但给了较详细的解释),和~modred/papers/named.html (使用了FreeBSD的Ports Collection,给出了详细的步骤)。以下只着重介绍操作过程,并没有详细给出操作步骤,需要设置chroot named的使用者可以参阅这些相关网页的内容。
系统管理员有时也不希望用户占用太多的系统资源,在有些Unix系统中入侵者能通过普通帐户,启动大量的进程或产生大量的文件,从而使系统死掉或不能提供正常操作,而FreeBSD下则不必有此担忧,因为可以通过login.conf 和用户的口令数据来设置用户类别,限制用户对系统资源的占用,同样占用的硬盘资源可以通过quota来限制。
at和cron机制能帮助用户自动启动应用程序和服务进程,如果必要,可以屏蔽用户使用at和cron的权限。也要注意检查root用户的at和cron设置,这里也是入侵者可能用于设置后门程序的一个位置。
系统中,除了服务进程可能具备root身份之外,再就是具备SetUID身份的程序能进入root身份。由于 SetUID和SetGID与系统安全息息相关,因此系统中也应该具备尽量少的SetUID和SetGID程序。要不定期使用find命令查找,或者检查/var/log下的日志文件,了解系统中这些程序文件的更改情况。
实际上很多SetUID程序不会被使用的,例如很少有人使用uucp,如果使用的是局域网也很少使用ppp和 pppd,因此对于这些不常用到的SetUID程序,应该取消其SetUID位,甚至取消执行属性,以避免用户来执行它。
为了避免不必要的SetUID程序,一个办法是可以在安装一个文件系统时就设定不承认这个文件系统中的SetUID 程序。安装文件系统时可以使用nosuid选项,就能让文件属性中的SetUID和SetGID位失效。因此为了利用这个优点,可以创建使用使用nosuid位的/home文件系统,让所有的用户使用,而其他可以存在SetUID 程序的文件系统,如/usr,则不允许用户写入。同样也要创建一个/var/tmp文件系统,将系统的/tmp目录指向这个目录,/var/tmp也应该是nosuid的,以避免用户在/tmp目录中保存SetUID程序。其他的文件系统,如使用NFS装载的文件系统,也要使用nosuid安装选项。
划分多个磁盘分区、安装到不同目录上也能防止入侵者企图填满磁盘空间的阻塞攻击。同样,对于用户使用的磁盘文件系统,应该使用qutoa来限制用户个人占用的磁盘空间。
这个nosuid安全选项应该加入到/etc/fstab文件中,一使得每次都能生效。需要注意的是nosuid 安装选项不能影响一些解释性语言程序的这个属性,如perl程序,当解释性语言程序具备SetUID属性,语言解释器为其设置身份,由于真正的setuid()调用是由语言解释器执行的,因此如果语言解释器具备root权限(具备 SetUID属性),那么就能使解释器将具备SetUID位的程序设置入root权限。这不是系统的问题,而是语言解释器的问题,屏蔽语言解释器本身的SetUID属性可以避免这个问题。
当系统作为NFS服务器,设置共享出去的NFS文件系统时,应该使用maproot或mapall参数,以便隔离危险,使得即使在远程系统被侵入的情况下,防止从这个允许安装文件系统的客户上对本机的入侵。还可以考虑使用安全的NFS协议,使用DES算法进行服务器和客户机的认证。如果系统不使用NFS及其他RPC服务时,最好屏蔽相关的选项,如portmap_enable选项。
Unix系统使用Syslog记录应用软件发送的日志记录,日志记录对于安全管理非常重要,因为管理员可以从这些日志中发现系统遭受攻击的痕迹及证据。然而syslogd本身也是一个服务程序,能接收网络上的消息,因此其本身也存在安全问题。
这样,syslog就存在两个矛盾的问题,为了安全起见syslogd不应该接收网络上的其他计算机发送的日志记录。由于接收消息是通过UDP传送并且没有加密保护,因此syslog消息可能是伪造的,即便攻击者不使用伪造信息进行欺骗,仅仅使用服务阻塞的方法,就能导致正常的日志记录系统不能正常使用,此后攻击者就能放心进行入侵操作而无需担心留下踪迹。那么即使syslogd没有因为这种阻塞攻击而崩溃,大量无意义的syslog记录,也使得其他有用的日志记录被迅速淹没或清除(为了防止日志文件占用过多的磁盘空间,系统中缺省情况下会自动进行日志的清理工作)。
为了使得syslogd不理会其他计算机的记录,可以使用-s参数重新启动syslogd。在rc.conf 中更改syslogd_flags的值为"-s"。
FreeBSD系统中用于管理syslog日志文件的程序为newsyslog,它由crontab来启动,它检查由newsyslog.conf中指定的日志文件,当这些文件达到一定大小时,就截断原文件,重新启动syslogd ,并压缩保存原有记录。为了避免占用太多的磁盘空间,newsyslog保存的日志备份文件有数量的限制,因此就使得阻塞攻击清除日志的攻击方式成为了可能。可以增加newsyslog保存的日志备份文件的数量,和进行备份时文件的大小,增大系统日志文件的容量。
然而,当一台计算机仅仅使用自己硬盘来记录日志的话,那么一旦入侵者成功入侵这台计算机,他就能按照syslogd 的配置文件syslog.conf的设置,清除相关的日志记录,以便为以后继续潜伏在系统中做打算。甚至可以直接删除/var/log目录下文件以及其他syslog.conf中指明的文件,消灭入侵踪迹及证据。这样,将syslog 日志记录保留在其他计算机系统中也是一个有效增强安全审计的重要因素。
因此,可以设定一台用于记录日志的计算机,其syslogd屏蔽外部计算机的日志请求,只记录本地可信任的计算机系统的日志。这样,就需要在使用"-s"参数屏蔽任意计算机请求的同时,使用"-a"加上信任的计算机主机名,或者子网号,域名等,这样就只会记录这些计算机的日志记录。为了安全起见,这台计算机最好是专用于这一项服务,不执行任何服务程序,以避免遭受入侵。然而由于syslogd对系统要求不高,因此这台计算机可以不必使用很高的硬件配置,除了需要足够的硬盘空间以容纳大量日志记录。
此外,还可以通过将特别重要的syslog的记录直接发送到行式打印机的方式,避免入侵者清除日志记录。
由于日志记录会迅速增加,特别是在遭受攻击的时候更为显著,因此需要使用一些日志分析工具来帮助分析这些日志文件,以快速定位发生的安全问题,否则面临庞大的日志文件,很难找到有用的日志记录。logcheck或其他具备相似功能的程序就用来完成这个任务。http://www.psionic.com/abacus/abacus_logcheck.html为logcheck的主页。
有些软件本身很可能存在安全问题,应该尽量使用该软件的最新稳定版本并及时进行打补丁,或者使用具备同样功能,但更安全的软件来代替这种软件,例如使用qmail或postfix来代替sendmail。
有时候软件的新版本由于增加了新功能,会变得更不稳定或具备其他的安全漏洞,对于这种情况就不能盲目升级软件。
X Window也对网络安全有一定影响,特别是X服务器的认证问题,不要为了方便起见而直接使用xhost+ 命令,这样就会其他使用者能窥视用户正在进行的操作。除了上面提到的措施之外,还可以将FreeBSD系统放置到防火墙之内,或者直接利用FreeBSD系统的包过滤能力,屏蔽一些不友好节点的访问,或者屏蔽所有的外部连接请求,而不影响本机对外部的访问。将FreeBSD设置为防火墙是一个重要的安全措施,因为这不但能对本机提供保护,也能对网络内其他客户计算机提供保护。毫无疑问,FreeBSD系统的包过滤能力非常优秀,结合FreeBSD具备的网络地址翻译的能力,就使得它能构建仅次于硬件防火墙的防火墙系统。本章的后续部分中将详细讨论将FreeBSD设置为防火墙系统的各种方法。
FreeBSD内核有一个安全级别(securelevel)的概念,这是指系统内核运行使用的安全等级,不同的等级具备不同的保护和检查机制。因为这是内核的检查机制,因此相当严格,没有办法能绕过这个机制提供的保护,因此就对保护FreeBSD的安全性十分有用。
内核的安全级别按照提供安全保护的程度分为-1、0、1、2共分为四个级别,安全级别能提供的保护有:
系统文件:系统文件可以设置保护标志 “ 不可更改 “ 和 “ 只能附加 “ ,具有这些保护标志的文件在系统的文件属性之外,还受这些保护标志的保护。安全级别可以规定这些标志能否取消。
磁盘设备文件:磁盘设备文件具备两种访问方式,随机访问的方式对应的块设备文件和顺序访问方式对应的字符设备文件,其中字符设备文件可以直接读取硬件设备,因此对于安全至关重要。内核安全级别可以决定是否允许以直接读取硬件的方式操作硬盘设备文件。
直接内存访问:/dev/mem和/dev/kmem是系统内存的映射文件,访问它们就能直接访问系统内存,一些需要获取系统信息和需要进程间共享内存机制的程序需要访问这两个设备文件以直接访问内存,然而访问内存空间显然也影响系统的安全运行。内核安全级别可以决定是否允许访问系统内存。
安全级别-1为一种永久性的不安全级别,系统内核不提供任何额外的保护。系统缺省就处于这个级别,此时系统文件的保护标志能被root用户取消,所有的设备,包括磁盘设备和内存映射设备,均能按照其属性来访问。
安全级别0为不安全的级别,它和等级-1一样没有对系统提供额外的安全保护,但它影响到内核进程init的行为。当内核处于级别-1时,内核init程序不会自动更改运行级别,因此一直到进入能够登录的状态,系统安全级别仍然为-1。这是系统的缺省行为,没有打开安全级别保护机制。但如果安全级别不为-1,init在进入单用户状态时将改变为0级别,在进入多用户模式时改变为安全级别1。因此安全级别0为设置了安全级别保护之后,单用户状态下的安全级别。
安全级别1为安全的级别,提供了对系统的保护能力。此时系统文件的那两个保护标志不能被取消,已安装文件系统对应的磁盘设备,以及/dev/mem,/dev/kmem不可以用写入模式打开。
安全级别2与级别1类似,只是进一步增加了对磁盘设备低级操作的限制,不管该磁盘设备是否安装,都不允许直接以写入方式访问,这样就无法进行fdisk、disklabel以及newfs等操作。
可以使用sysctl来查看当前系统的安全级别,但如果没有经过特别设置,FreeBSD的缺省安全级别应该为-1:
# sysctl kern.securelevel kern.securelevel: -1 |
安全级别中最重要的一点是,除了内核的init进程之外,即使是root用户,也只能不断提高安全级别,没有办法将安全级别降低。这样就基本上保证远程入侵者在没有重新启动计算机的情况下,无法降低系统运行级别。如果root 想提高系统运行的安全级别,也需要使用sysctl命令。
# sysctl -w kern.securelevel=0 kern.securelevel: -1 -> 0 |
安全级别的意义就在于对文件和设备的保护,如果要对文件提供保护,就需要对文件设置保护标志schg。设置这个标志需要使用chflags命令,系统文件如/kernel,系统安全的时候就具备这个保护标志。即使在非安全级别下要更改这些文件的时候,也要首先取消保护标志才能进行正常操作。
# mv /kernel /kernel.bak mv: rename /kernel to /kernel.bak: Operation not permitted # chflags noschg /kernel # mv /kernel /kernel.bak # mv /kernel.bak /kernel # chflags schg /kernel |
上面操作先取消了kernel文件的不可更改标志schg,显然这是在非安全级别下的操作。当安全级别处于 1或2时,就不能使用chflags改变文件的保护标志了。
# chflags noschg /kernel |
可以使用带-o参数的ls来查看文件具备的标志。
# ls -lo /kernel |
因此可以将系统安全相关的很多程序都设置保护标志,这样入侵者就不能轻易更改这些文件了。建议将/bin,/sbin下的文件都设置这个标志。
# chflags schg /bin # chflags schg /bin/* # chflags schg /sbin # chflags schg /sbin/* |
这里首先将相关目录本身设置保护标志,这样入侵者就不能通过将目录更改名字的方法创造一个新的/sbin或 /bin目录。
当文件具备了保护标志,并且安全级别高于1时,保护标志就无法取消,这些文件就不能更改,因此就带来一些必要的操作无法进行,例如重新生成内核的操作等。此时就必须再重新启动系统进入单用户状态执行这些操作。
通常情况下,如果FreeBSD系统只提供网络服务,那么使用安全级别1或2毫无问题。然而如果要运行X Server ,由于X Server使用了共享内存机制,需要访问/dev/mem和/dev/kmem,这样就会带来问题。这时的一种解决办法是在启动X Server之后(例如使用Xdm),再升高安全级别,以避开这个问题,但此时 X Server已经打开了/dev/mem和/dev/kmem,安全级别的保护就不再是完美无缺的了。
如果不使用X Server之类的程序,那么就可以将设置安全级别的命令直接放入系统的启动rc文件中,以便自动提高安全级别。这需要在rc.conf文件中设置两个变量:kern_securelevel_enable和kern_securelevel。
kern_securelevel_enable=”YES” kern_securelevel=0 |
上面将安全级别设置为0,那么在启动之后将自动更改为1,这是一种标准的做法。