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应用程序时会有一些错误,可能会使它们不太适合处理二进制数据流。另外,默认的kerberos也无法加密一个会话,除非你使用-x选项。ssh默认能加密任何东西。

我们建议无论用户什么时候登陆系统,你都可以结合kerberos来使用sshssh可以在编译时加入对kerberos的支持。我们也建议你在ssh配置中关闭key-forwarding,或者在它的authorized_keys文件中使用from=IP/DOMAIN选项,使得只有用作实体的密匙可以从特殊机器登陆进系统。

10.4 DESMD5Crypt

UNIX系统上的每个用户有一个与他们的帐号相关联的口令。看起来这些口令只有用户和操作系统知道。为了确保这些口令的秘密,它们通过一种叫做“one-way hash“的方式来加密,它们能被很容易地加密,但不能解密。换句话说,以前我们告诉你的通常不是真的:操作系统通常并不真正知道口令,它只知道口令的加密形式。获得口令的唯一方法是在可能的口令空间内实施强力匹配搜索。

加密口令的唯一安全方式是以DES为基础的数据加密标准。这对于US用户来说没有什么问题,但DES的源代码不允许被输出到US以外的国家,FreeBSD必须找到一个既遵守US法律,又要与其他使用DESUNIX兼容的方法。

解决方法是分解加密库以至于US用户可以安装DES库和使用DES,而国际用户也有一个加密方法。FreeBSD使用MD5作为默认的加密方法。MD5被认为要比DES更安全,所以使用DES主要是为了兼容性的原因。

10.4.1 重新配置你的加密机制

可以很容易地设置FreeBSD使用哪种加密方法。检查/etc/master.passwd文件中的加密口令是一种方法。用MD5 hash加密的口令通常要比用DES hash加密的口令长,通常以$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

    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用的cryptlibdescrypt,哪个口令格式将被用作新的口令可以通过在/etc/login.conf中设置passwd_format来控制,要么使用DES,要么使用MD5。看看login.conf的联机手册了解更多信息。

10.5 S/Key

S/key是基于单向hash功能的一次性口令管理方式。FreeBSD为了考虑兼容性,就使用MD4 hash函数,但其他系统则使用MD5DES-MAC。从1.1.5版开始,S/key已经成为FreeBSD的基本系统,同时也广泛应用于其他操作系统。S/keyBell Communications ResearchInc的注册商标。

下面将讨论三种不同的口令形式。第一种是你通常使用的UNIX风格或Kerberos口令,我们把它叫做“UNIX password”。第二种是由S/key程序或OPIE opiekey程序产生,然后被keyinitopiepasswd程序和登陆命令接受的一次性口令,我们把它叫做“one-time password”。最后一种口令是由专门的口令生成程序key/opiekey(有时是keyinit/opiepasswd程序)生成的一次性口令,我们把它叫做“secret password”或只是“password”

秘密口令并不是与UNIX password一点没有关系;它们也可能是一样的,但并不推荐使用。S/keyOPIE秘密口令不像UNIX口令需要限制在8位以内,它们可能会更长。一般都使用67位的长度。另外,S/keyOPIE系统操作完全独立于UNIX password系统。

除了口令,对于S/keyOPIE有两个数据很重要。一个是以“seed”“key”出名,包含两个字母和五个数字。其他的被叫做一次性口令的序列号“iteration count”,在1100之间。S/key通过连接种子(seed)和秘密口令来生成一次性口令,然后通过反复计算多次应用MD4 hash,再把结果变成六个英文字。这六个英文字就是你的一次性口令。如果用户提供的口令的hash值与先前的口令相一致,用户就通过了认证;每个成功的登陆确保用户和登陆程序保持同步之后,计算的次数就不断减少。当序列号的降到1时,S/keyOPIE必须被重新初始化。

   有四个程序被包含在S/key系统中,我们下面会谈到。口令程序接受一个序列号,一个种子和一个秘密口令,然后产生一个一次性口令。keyinitopiepasswd程序被用来初始化S/keyOPIE,然后改变口令,序列号或种子;它不是接受一个秘密口令,就是一个序列号,种子和一次性口令。keyinfoopieinfo程序会检查文件,然后打印出被调用的当前序列号和种子。最后,loginsu程序包含了用于认证S/key一次性口令的必须的逻辑性。login程序也可以不使用UNIX口令。

我们将讲述四种不同的操作。第一种是首先通过一个安全连接使用keyinitopiepasswd程序来设置一次性口令,或改变你的口令或种子。第二种操作是通过一个不安全的连接使用keyinit来与key相关联,或通过一个安全的连接使用opiepasswdopiekey相关联。第三种是通过一个不安全的连接使用key/opiekey来登陆。第四种是使用keyopiekey产生许多可以被记录或打印出来的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登陆系统时,系统将记住这些参数,然后把它们返回给你,所以你不必记住它们。最后一行给出了与那些参数和你的秘密口令相一致的特定的一次性口令;如果你需要立刻重新登陆,这个一次性口令就是你使用的。

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:

对于OPIE,你必须使用opiepasswd:

% 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。然后键入一个访问口令,转移到你的安全连接或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

或对于OPIE

% 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

现在,切换到不安全的连接,拷贝产生的一次性口令到相关的程序。

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:

或对于OPIE

% 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:

另外,S/keyOPIE有一个很有用的特性:如果你在口令提示行键入return键,登陆程序将会把键入的口令显示出来,所以你可以看到你键入的口令。如果你试图手工键入一个S/key,这个非常有用。如果这台机器被配置成通过一个来自源机器的连接不接受UNIX口令,命令行也将包括注意(S/key必须),指出只有s/key一次性口令将被接受。

基于这点,你必须产生你自己的一次性口令来回答这个登陆命令。这必须在一个可以运行口令命令的可信任的系统上做。口令程序既需要序列号和种子,也需要命令行选项。你可以从你登陆的机器的命令行剪切和粘贴这些选项。

在可信任的系统上:

    % key 97 fw13894

    Reminder - Do not use this program while logged in via telnet or rlogin.

    Enter secret password:

    WELD LIP ACTS ENDS ME HAAG

对于OPIE

% 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

现在,你已经有了可以继续登陆的一次性口令:

    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 ...

10.5.4产生多个一次性口令

有时,你会来到你不能访问一个可信任的机器或安全连接的地方。在这个例子中,可以使用key命令来产生许多一次性口令,例如:

    % 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 

    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。你也可以参考相关的联机手册了解更详细的说明。

10.6.1安装Kerberos

KerberosFreeBSD系统中的可选组件。安装这个软件的最容易的方法是在安装FreeBSD时选中krb4krb5组件。在FreeBSD中,Kerberos不是来自最初的4.4BSD-Lite,而是eBones,来自于USA/Canada以外的地区,那些受到美国加密代码出口限制的国家就可以使用它。

另外,来自MITKerberos组件可以在ports collection/security/krb5中找到。

10.6.2创建最初的数据库

这只可以在Kerberos服务器上来做。首先确定你没有旧的Kerberos数据库。你必须改变/etc/kerberosIV的目录,然后只检查下面出现的文件:

    # cd /etc/kerberosIV

    # ls

    README      krb.conf        krb.realms

如果任何其他文件(principal.* master_key)存在,那使用kdb_destroy命令就可以破坏旧的Kerberos数据库,或者如果Kerberos不在运行,只要删除其他的文件。

你现在必须编辑krb.confkrb.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

    TELECOM.MIT.EDU bitsy.mit.edu

    ARC.NASA.GOV trident.arc.nasa.gov

在这个例子中,其他规则没有出现。它们在这儿作为一个机器如何应用多种规则的例子。你可能希望不要简单地包括它们。

第一行命名了这个系统工作的规则。其他行包含了规则/主机的记录。每行的第一项就是一个规则,第二个是充当一个“key distribution center”的规则中的一台主机。接在一个主机名后面的管理服务器的命令意味着主机也要提供一个管理数据库服务器。更多信息,可以参考Kerberos的联机手册。

现在,我们必须添加grunt.grondar.zaGRONDAR.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.

    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.3使它完全运行

有两个主要的东西需要被添加到要用Kerberos确保安全的每个系统的数据库中。它们的名称是kpasswdrcmd。这些程序允许其他系统改变Kerberos的口令,然后像rcp rlogin rsh一样运行命令。

现在,让我们添加这些记录:

    # 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

   

    Principals 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] ?

   

    Principals 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.4创建新的服务器文件

我们现在必须分析在每台机器上定义的服务的所有情况。我们使用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.5定位数据库

我们现在添加一些用户记录到数据库。首先,让我们为用户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

   

    New Password:                <——- re-enter the password here

    Principals 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.6测试所有的

首先我们必须启动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 &

    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得到一个idjane入场券

    % kinit jane

    MIT Project Athena (grunt.grondar.za)

    Kerberos Initialization for “jane”

    Password:

如果我们正的有它们,使用klist设法列出记号:

    % klist

    Ticket file:    /tmp/tkt245

    Principal:      [email protected]

   

      Issued           Expires          Principal

    Apr 30 11:23:22  Apr 30 19:23:22  [email protected]

现在,如果kpasswd程序可以得到数据库的验证,可以使用passwd来检查正在修改的口令:

    % passwd

    realm GRONDAR.ZA

    Old password for jane:

    New Password for jane:

    Verifying password

    New Password for jane:

    Password changed.

10.6.7添加su特权

Kerberos允许我们给每个需要root权限的用户他们自己独立的su口令。我们现在可以添加一个被用来验证surootid。使用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

    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

   

    Principals 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:

现在,我们必须添加用户到root.klogin文件:

    # cat /root/.klogin

    [email protected]

现在设法执行su

    % su

    Password:

看看我们有些什么符号:

    # klist

    Ticket file:    /tmp/tkt_root_245

    Principal:      [email protected]

   

      Issued           Expires          Principal

    May  2 20:43:12  May  3 04:43:12  [email protected]

10.6.8 使用其他命令

在一个先前的例子中,我们创建了一个叫做jane的用户作为一个root。这里就以这个用户为例,这是Kerberos默认的;如果必须的记录在.klogin文件中,那形式<username>.root<principal>.<instance>将允许<username> su root

    # cat /root/.klogin

    [email protected]

同样的,如果一个用户已在它们自己的home目录行中:

    % cat ~/.klogin

    [email protected]

    [email protected]

这允许在GRONDAR.ZA中的已通过janejack验证的任何人通过rloginrshrcp访问并登陆到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

10.7 防火墙

防火墙是提高人们访问互联网的兴趣的一个工具,它能够提高私有网络的安全性。这节将介绍防火墙是什么,如何使用它们和如何使用内核中提供的工具来实现它们。

注意:人们经常认为在你的内部网络与外部网络之间建立一个防火墙能够解决所有的安全问题。但是一个糟糕的防火墙设置要比没有防火墙可能更加危险。一个防火墙可以为你的系统增加另一个安全层,但它不可能完全阻止一些入侵高手侵入你的系统。如果你觉得你的防火墙能够完全阻止入侵者入侵而放松了安全设置,那你可能会让入侵者侵入你的系统变得更加容易。

10.7.1什么是防火墙?

今天,经常使用的防火墙主要有两种类型。第一种类型是叫做数据包过滤路由(packet filtering router),它主要是通过设置一定的规则来转发或阻止数据包的传输。第二种是代理服务器(proxy server),依靠守护程序来提供验证,然后转发数据包。

有时,有些站点同时使用两种类型的防火墙,以至只有某台机器(bastion host)才能被允许发送数据包到内部网络。代理服务运行在bastion host上,通常它要比普通的验证机制安全。

FreeBSD有一个内核数据包过滤程序(IPFW),在这节的余下部分将详细讲到,但由于有很多的代理服务器可以使用,所以在这篇文档中无法一一讲到。

数据包过滤路由

路由器是负责在网络之间转发数据的机器。一个数据包过滤路由器在它的内核中有额外一部分代码,它们在决定数据包是被转发还是被阻止之前,会根据给出的规则比较每个数据包。绝大多数现代的IP路由软件都有数据包过滤代码。要启用这些过滤器,你必须定义一些过滤代码的规则,以便它能决定数据包是否被允许转发或阻止。

过滤代码会检查所设定的匹配一个数据包头部内容的规则来决定这个数据包是否被通过。一旦一个匹配找到了,这个规则动作就启用了。这个规则可能会减慢数据包以便传输数据,或是发送一个ICMP信息给这个数据包的发送者。只有第一个匹配会计数,以便按顺序来查找到这些规则。因此,这些规则的列表可以被看作是规则链。

数据包匹配标准的变化依赖于使用的软件,但典型的你可以指定依赖于数据包的源IP地址,目标IP地址,源端口号,目标端口号,或是数据包类型(UDPTCPICMP)的规则。

代理型服务器

代理型服务器是把普通系统守护程序(telnetdftpd)用作特殊服务器的机器。这些服务器被叫做proxy servers。这个可以在你的防火墙主机上运行一个代理telnet服务器,人们可以从外部telnet进入你的防火墙,通过一些验证机制,然后获得访问内部网络的权利。

代理型服务器通常要比普通的服务器更安全,可以提供更广泛的验证机制,包括“one-shot”口令系统,所以即使有人设法寻找了你使用的口令,他们也不能使用它获得访问你的系统的权利,因为口令会立即失效。由于他们不能给用户访问主机的权利,所以它使得想要在的系统上安装后门变得困难得多。

代理型服务器有很多种限制访问的方法,所以只有某个主机获得了访问服务器的权利,他们才可以被设置,以至你可以限制哪个用户可以跟哪个机器交谈。另外,要使用哪个完全取决于你选择的代理软件哪个更强大。

10.7.2 IPFW允许你做些什么?

IPFW,由FreeBSD提供的软件,是一个位于内核中的数据包过滤和结算系统,有一个用户级的控制工具,ipfw。他们允许你定义和查询内核正在使用的规则。

IPFW有两个相关的部分。防火墙那节允许你执行数据包过滤。也有一个IP结算章节允许你追踪你的路由器的使用情况。这将允许你看到你的路由器从某个机器得到了多少的传输量,或有多少的WWW数据被转发。

IPIW的这样设计,你可以在没有路由的机器上,在输入与输出的连接之间,使用IPFW执行数据包过滤。这是IPFW一个比较特殊的用法,同样的命令和技术也可以在这样的情形下使用。

10.7.3FreeBSD上启用IPFW

由于IPFW的主要部分被捆绑在内核中,你必须要在你的内核配置文件中添加一个或多个选项,这取决于你要使用哪个工具,然后重新编译内核。

IPFW相关的有三种内核配置选项:

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/deletionlistingflushingclearingAddition/deletion被用来建立控制数据包如何被接受,拒绝和日志的控制规则。Listing被用来检查你规则设置的内容和数据包记数器。Flushing被用来删除所有记录链的记录。Clearing被用来对一个或多个记数记录进行清零。

改变IPFW的规则

这种形式的命令语法是:

ipfw [-N] command [index] action [log] protocol addresses [options]

 

当使用这种形式的命令时,会有一个正确的标记:

-N

在输出中解决地址和服务的名称。

给出的命令可以被缩短到最短的形式。正确的命令是这样的:

add

添加一个记录到firewall/accounting规则列表

delete

firewall/accounting规则列表中删除一个记录

先前使用的IPFW可以分离firewallaccounting记录。现在的版本以每个防火墙记录来提供数据包accounting

如果提供一个索引值,它会被放置在数据链中的一个指定点的记录。否则,记录会被放置在超过上次数据链记录的索引值100的数据链的结尾(这不包括默认的策略,rule 65535deny)。

如果内核编译进IPFIREWALL_VERBOSE,日志选项会把匹配规则输出到系统控制台。

正确的指令是:

reject

阻止数据包,然后发送一个ICMP主机或无法到达数据包端口给数据源。

allow

通过数据包。(别名:pass accept

deny

阻止数据包。数据源没有得到ICMP消息的通报。

count

升级数据包记数器,但不允许/阻止以这个规则为基础的数据包。会继续对下一个数据链记录进行搜索。

每个动作会通过加上一个简短明确的前缀来验证。

可能被指定的协议是:

all

匹配所有的IP数据包

icmp

匹配ICMP数据包

tcp

匹配TCP数据包

udp

匹配UDP数据包

地址的规则:

address/mask [port] to address/mask [port] [via interface]

你可以只指定与支持端口的协议相关联的端口(UDPTCP)

via是可选择的,可以指定一个本地IP接口的IP地址或域名,或是一个只与来自这个接口的数据包匹配的接口名(如:ed0)。接口单位数目可以用一个可选择的通配符来表示。例如,ppp*将匹配所有内核PPP接口。

指定一个address/mask的语法:

    address

    address/mask-bits

    address:mask-pattern

一个正确的主机名可以被指定用来代替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连接的数据包。

tcpflags flags

匹配包含flags标记的用逗号分割的TCP头。支持的标记是finsynrstpshackurg

icmptypes types

匹配在types列表中出现的ICMP类型。列表可以用一个以逗号隔开的联合或分离的排列形式。通常使用的ICMP类型是:0 echo reply (ping reply)3 destination unreachable 5 redirect8 echo request (ping request)11 time exceeded

列出IPFW规则

这种形式的命令的语法是:

ipfw [-a] [-t] [-N] l

当使用这种命令时,有三种正确的标记:

-a

当列条目时,显示计数器的值。这个选项是唯一可以看到计数器值的方法。

-t

显示每个数据链记录的最后匹配次数。定时的列表与用ipfw工具输入的语法是不兼容的。

-N

试图分解给定的地址和服务名称。

提升IPFW 规则

语法是:

ipfw flush

这将把防火墙链中的所有记录都删除,除了内核中指定的可修复的默认策略(索引65535)。当提升规则时可以使用警告,默认的阻止策略将迫使你的系统断开网络,直到允许记录被添加到链中。

刷新IPFW数据包记数器

刷新一个或多个数据包记数器的方法:

ipfw zero [index]

当使用不带索引值选项时,所有的数据包计数器将被刷新。如果一个索引被启用,那刷新操作将只影响一个指定的数据链记录。

10.7.5 使用ipfw命令的例子

这个命令会阻止所有从主机evil.crackers.org到主机nice.people.orgtelnet端口的数据包:

    # ipfw add deny tcp from evil.crackers.org to nice.people.org 23

下一个例子会阻止和日志任何从crackers.org网络(c类地址)记录到机器nice.people.orgTCP传输(任何端口)。

    # 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

10.7.6建立一个数据包过滤防火墙

注意:下面的建议仅仅是建议。每个防火墙的要求是不同的,我们不能告诉你如何建立一个符合你特殊要求的防火墙。

当开始设置你的防火墙时,除非你有一个可测试的设置,可以在一个可控的环境中配置你的防火墙,否则强烈建议你使用命令的日志版本和在内核中启用日志。这将允许你快速地确定问题所在,以便不需要太久就可以修复。即使初始安装已经完成,还是建议你使用日志来阻止有可能的攻击,或根据你的要求修改防火墙的规则。

注意:如果你使用accept命令的日志版本,它可以产生巨大的日志数据,所以巨大的FTP/http传输将使系统的性能大大下降。在数据包通过之前它会要求内核做更多的工作。syslogd将开始使用更多的处理时钟,以至有许多额外的日志被记录到磁盘上,不久就会填满/var/log分区。

你可以从/etc/rc.conf.local/etc/rc.conf启用你的防火墙。相关的联机手册会解释如何列出当前的防火墙配置。如果你不使用当前的配置,ipfw列表将输出当前的规则设置到一个文件rc.conf。如果你不使用/etc/rc.conf.local/etc/rc.conf来启用防火墙,在任何接口被配置之前,确认你的防火墙被启用是很重要的。

下一个问题是你的防火墙实际上做了些什么!这主要依赖于你允许什么从外部访问你的网络和允许多少访问外部网络。一些通常的规则是:

             阻止所有TCP端口小于1024的访问。这是安全服务最敏感的地方,像fingerSMTP (mail) telnet

             阻止所有进入的UDP传输。通过UDP传输的没有多少有用的服务,有什么有用的传输服务,就会有什么安全问题。(如Suns RPCNFS 协议)。这也是它的缺点,既然UDP是一个无连接协议,阻止进入的UDP传输也会阻止对输出UDP传输的回应。这可能会对使用外部archie服务的人们带来麻烦。如果你要允许访问archie,你将必须允许来自端口1911525的数据包能够通过防火墙进入内部UDP端口。ntp是另一个你可以允许通过的服务,它使用端口123

             阻止端口6000与外部的传输服务。端口6000被用来访问X11服务器,可能会带来一个潜在的安全问题。X11实际上可以使用以6000开始的端口范围,上面的限制取决于你可以在机器上运行多少个X显示程序。上面的限制通过RFC 1700定义的是6063

             检查内部服务器使用什么服务器(SQL server)。阻止这些服务可能是一个好主意,因为它们分布于上面指定的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源代码安装

OpenSSLsrc-crypto src-secure cvsup collections的一部分。可以看看获得FreeBSD(附录A)那节了解更多有关获得和升级FreeBSD源代码的信息。

10.9 IPsec

特殊字符:在这节和其他章节中,你会注意到在一些例子后面有一个字符“^D”。这代表先按下control键,然后按下D键。另一个经常用到的是“^C”,这代表先按下control键,然后按下C键。

提示:有关在FreeBSD中的IPSec执行的其他HOWTO细节,请参考。

www.daemonnews.org/200101/ipsec-howto.htmlhttp://www.freebsddiary.org/ipsec.php

IPsec机制提供了IP层与socket层之间安全的通信方式。这节将介绍如何使用它们。有关执行细节,请参考开发人员手册。

当前的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的联机手册了解算法的命名。我们的选择是对AHMD5,对新AHnew-HMAC-SHA1,对新ESP用带有8位的new-DES-expIV

关键字的长度依赖于每个算法。例如,关键字的长度对于MD5需要用16位,对于new-HMAC-SHA1需要用20位,对于new-DES-expIV需要用8位。现在我们分别选择“MYSECRETMYSECRET”“KAMEKAMEKAMEKAMEKAME”“PASSWORD”

好的,让我们为每个协议分派一个SPI(Security Parameter Index)。请注意我们需要为这个安全通道设计3SPI,因为产生了三个安全header

(一个是从主机A到主机B,两个是从主机B到主机A)。另外,你也要注意SPI必须要超过或等于256。我们依次选择100020003000

(1)

          (1)PROTO=AH

            ALG=MD5(RFC1826)

            KEY=MYSECRETMYSECRET

            SPI=1000

         

(2.1)

        PROTO=AH

            ALG=new-HMAC-SHA1(new AH)

            KEY=KAMEKAMEKAMEKAMEKAME

            SPI=2000

       (2.2)

        PROTO=ESP

            ALG=new-DES-expIV(new ESP)

                IV length = 8

            KEY=PASSWORD

            SPI=3000

现在,让我们设置安全连接。在主机AB上执行setkey:

  # setkey -c

add 10.2.3.4 10.6.7.8 ah-old  1000 -m transport -A keyed-md5 “MYSECRETMYSECRET” ;

add 10.6.7.8 10.2.3.4 ah  2000 -m transport -A hmac-sha1 KAMEKAMEKAMEKAMEKAME” ;

add 10.6.7.8 10.2.3.4 esp 3000 -m transport -E des-cbc “PASSWORD” ;

^D

事实上,除非定义了安全策略记录,否则IPsec通信是不起作用的。在这个例子中,你必须设置每个主机。

    At A:

   

    # setkey -c

    spdadd 10.2.3.4 10.6.7.8 any -P out ipsec

        ah/transport/10.2.3.4-10.6.7.8/require ;

    ^D

   

    At B:

   

    # setkey -c

    spdadd 10.6.7.8 10.2.3.4 any -P out ipsec

        esp/transport/10.6.7.8-10.2.3.4/require ;

    spdadd 10.6.7.8 10.2.3.4 any -P out ipsec

        ah/transport/10.6.7.8-10.2.3.4/require ;

    ^D

10.9.2IPv6传输模式的例子

另一个使用IPv6的例子:

ESP传输模式建议使用主机AB之间的TCP端口110

加密算法是blowfish-cbc,它的关键字是“kamekame”,验证算法是hmac-sha1,它的关键字是“this is the test key”。在主机A上配置:

            # setkey -c <<EOF

            spdadd fec0::10[any] fec0::11[110] tcp -P out ipsec

                    esp/transport/fec0::10-fec0::11/use ;

            spdadd fec0::11[110] fec0::10[any] tcp -P in ipsec

                    esp/transport/fec0::11-fec0::10/use ;

            add fec0::10 fec0::11 esp 0x10001

                    -m transport

                    -E blowfish-cbc “kamekame”

                    -A hmac-sha1 “this is the test key” ;

            add fec0::11 fec0::10 esp 0x10002

                    -m transport

                    -E blowfish-cbc “kamekame”

                    -A hmac-sha1 “this is the test key” ;

            EOF

在主机B:

    # setkey -c <<EOF

            spdadd fec0::11[110] fec0::10[any] tcp -P out ipsec

                    esp/transport/fec0::11-fec0::10/use ;

            spdadd fec0::10[any] fec0::11[110] tcp -P in ipsec

                    esp/transport/fec0::10-fec0::11/use ;

            add fec0::10 fec0::11 esp 0x10001 -m transport

                    -E blowfish-cbc “kamekame”

                    -A hmac-sha1 “this is the test key” ;

            add fec0::11 fec0::10 esp 0x10002 -m transport

                    -E blowfish-cbc “kamekame”

                    -A hmac-sha1 “this is the test key” ;

            EOF

注意SP的方向。

10.9.3IPv4通道模式的例子

两个安全网关之间的通道模式

安全协议是老的AH通道模式,由RFC1826制定,用keyed-md5作为验证算法,它的关键字是“this is the test”

              

在网关A上配置:

            # setkey -c <<EOF

            spdadd 10.0.1.0/24 10.0.2.0/24 any -P out ipsec

                    ah/tunnel/172.16.0.1-172.16.0.2/require ;

            spdadd 10.0.2.0/24 10.0.1.0/24 any -P in ipsec

                    ah/tunnel/172.16.0.2-172.16.0.1/require ;

            add 172.16.0.1 172.16.0.2 ah-old 0x10003 -m any

                    -A keyed-md5 “this is the test” ;

            add 172.16.0.2 172.16.0.1 ah-old 0x10004 -m any

                    -A keyed-md5 “this is the test” ;

            EOF

如果端口号码范围被忽略,就像上面一样使用“[any]”`-m,指定了使用SA的模式。“-m any”意味着安全协议的模式。你可以为通道和传输模式都使用这个SA

在网关B:

            # setkey -c <<EOF

            spdadd 10.0.2.0/24 10.0.1.0/24 any -P out ipsec

                    ah/tunnel/172.16.0.2-172.16.0.1/require ;

            spdadd 10.0.1.0/24 10.0.2.0/24 any -P in ipsec

                    ah/tunnel/172.16.0.1-172.16.0.2/require ;

            add 172.16.0.1 172.16.0.2 ah-old 0x10003 -m any

                    -A keyed-md5 “this is the test” ;

            add 172.16.0.2 172.16.0.1 ah-old 0x10004 -m any

                    -A keyed-md5 “this is the test” ;

   

            EOF

在两个安全网关之间建立SA

在网关AB之间必须使用AH传输模式和ESP通道模式。在这个例子中,先应用ESP通道模式,然后是AH传输模式。

                      

10.9.4使用IPv6的通道模式的例子

加密算法是3des-cbc,针对ESP的验证算法是hmac-sha1。针对AH的验证算法是hmac-md5。在网关A上配置:

            # setkey -c <<EOF

            spdadd fec0:0:0:1::/64 fec0:0:0:2::/64 any -P out ipsec

                    esp/tunnel/fec0:0:0:1::1-fec0:0:0:2::1/require

                    ah/transport/fec0:0:0:1::1-fec0:0:0:2::1/require ;

            spdadd fec0:0:0:2::/64 fec0:0:0:1::/64 any -P in ipsec

                    esp/tunnel/fec0:0:0:2::1-fec0:0:0:1::1/require

                    ah/transport/fec0:0:0:2::1-fec0:0:0:1::1/require ;

            add fec0:0:0:1::1 fec0:0:0:2::1 esp 0x10001 -m tunnel

                    -E 3des-cbc “kamekame12341234kame1234”

                    -A hmac-sha1 “this is the test key” ;

            add fec0:0:0:1::1 fec0:0:0:2::1 ah 0x10001 -m transport

                    -A hmac-md5 “this is the test” ;

            add fec0:0:0:2::1 fec0:0:0:1::1 esp 0x10001 -m tunnel

                    -E 3des-cbc “kamekame12341234kame1234”

                    -A hmac-sha1 “this is the test key” ;

            add fec0:0:0:2::1 fec0:0:0:1::1 ah 0x10001 -m transport

                    -A hmac-md5 “this is the test” ;

            EOF

用不同的结尾来使用SA

在主机A和网关A之间需要使用ESP通道模式。加密算法是cast128-cbc,针对ESP的验证算法是hmac-sha1。建议在主机AB之间使用ESP传输模式。加密算法是rc5-cbc,针对ESP的验证算法是hmac-md5

在主机A上配置:

            # setkey -c <<EOF

            spdadd fec0:0:0:1::1[any] fec0:0:0:2::2[80] tcp -P out ipsec

                    esp/transport/fec0:0:0:1::1-fec0:0:0:2::2/use

                    esp/tunnel/fec0:0:0:1::1-fec0:0:0:2::1/require ;

            spdadd fec0:0:0:2::1[80] fec0:0:0:1::1[any] tcp -P in ipsec

                    esp/transport/fec0:0:0:2::2-fec0:0:0:l::1/use

                    esp/tunnel/fec0:0:0:2::1-fec0:0:0:1::1/require ;

            add fec0:0:0:1::1 fec0:0:0:2::2 esp 0x10001

                    -m transport

                    -E cast128-cbc “12341234”

                    -A hmac-sha1 “this is the test key” ;

            add fec0:0:0:1::1 fec0:0:0:2::1 esp 0x10002

                    -E rc5-cbc “kamekame”

                    -A hmac-md5 “this is the test” ;

            add fec0:0:0:2::2 fec0:0:0:1::1 esp 0x10003

                    -m transport

                    -E cast128-cbc “12341234”

                    -A hmac-sha1 “this is the test key” ;

            add fec0:0:0:2::1 fec0:0:0:1::1 esp 0x10004

                    -E rc5-cbc “kamekame”

                    -A hmac-md5 “this is the test” ;

                           EOF

10.10 OpenSSH

安全shell是一套用于安全地访问远程机器的网络连接工具。它可以被用来代替rlogin rshrcptelnet。另外,其他的TCP/IP连接也可以通过ssh来建立隧道和转发数据。ssh可以对所有传输的数据包进行加密以便防止被人窃听,网络入侵和攻击。

OpenSSH是由OpenBSD计划来维护的,建立在SSH v1.2.12基础之上,并作了最新的错误修补。它也兼容SSH协议12。自从FreeBSD4.0开始,OpenSSH已作为基本系统的一部分了。

10.10.1 使用OpenSSH的优势

通常,当使用telnetrlogin时,数据是以明码的形式发送的,并没有加密。在客户机和服务器上的网络检测器可以在你的会话中偷窃到你传输的用户名/口令。OpenSSH提供了多种验证和加密的方法来阻止这种事情的发生。

10.10.2 启用sshd

确信已将下面这行加入了你的rc.conf文件:

    sshd_enable=“YES”

这将在下次系统初始化时加载ssh程序。或者,你可以简单地运行sshd程序。

10.10.3 SSH 客户机

Ssh的工具与rlogin工作起来很像:

    # ssh [email protected]

    Host key not found from the list of known hosts.

    Are you sure you want to continue connecting (yes/no)? yes

    Host foobardomain.comadded to the list of known hosts.

    [email protected],s password: *******

如果使用rlogintelnet创建了一个会话,那登陆会继续。当客户端连接时,SSH会利用关键字指纹系统来指定这个服务器的验证。当第一次连接的时候,会提示用户只要键入‘yes’。以后的登陆会自动检验已保存的指纹关键字。如果保存的指纹与登陆时接受的指纹不同,SSH客户端将发出警告。指纹被保存在~/.ssh/known_hosts中。

10.10.4 安全拷贝

Scp命令与rcp工作起来很像;它会拷贝一个文件到或从一个远程机器上。

    # scp [email protected]:/COPYRIGHT COPYRIGHT

    [email protected]s password:

    COPYRIGHT            100% |*****************************|  4735      

    00:00   

    #

既然指纹已被保存在这台主机上,那当使用scp时,它将被修改。

10.10.5 配置

针对OpenSSH程序和客户端系统的配置文件放在/etc/ssh目录中。ssh_config配置客户机系统,sshd_config配置守护程序。

10.10.6 ssh-keygen

Ssh-keygen可以用来产生RSA密匙来验证一个用户以代替使用口令。

    % ssh-keygen

    Initializing random number generator...

    Generating p:  .++ (distance 66)

    Generating q:  ..............................++ (distance 498)

    Computing the keys...

    Key generation complete.

    Enter file in which to save the key (/home/user/.ssh/identity):

    Enter passphrase:

    Enter the same passphrase again:

    Your identification has been saved in /home/user/.ssh/identity.

    ...

Ssh-keygen将产生一个公共的和私有的密匙对来用于验证。私有密匙保存在~/.ssh/identity中,而公共密匙保存在~/.ssh/identity.pub中。为了安装工作,公共密匙必须放在远程机器的~/.ssh/authorized_keys中。

这将允许连接到基于RSA验证的远程机器以代替使用口令。

如果一条公共短语使用ssh-keygen,那用户为了使用私有密匙需要每次都键入一个口令。

一个SSH v2 DSA密匙可以使用ssh-keygen -d命令(或ssh-keygen -t dsa ,在FreeBSD-CURRENT中)来创建。这将只在SSH v2会话的中创建一个公共/私有DSA密匙来使用。公共密匙被存储在~/.ssh/id_dsa.pub中,而私有密匙被存储在~/.ssh/id_dsa中。DSA公共密匙被放在远程机器的~/.ssh/authorized_keys2中。ssh-agentssh-add是用来管理多口令私有密匙的工具。

10.10.7 SSH 通道

OpenSSH可以在一个加密的会话中创建一个通道来压缩另一个协议。下面的命令告诉sshtelnet创建一个通道。

    % ssh -2 -N -f -L 5023:localhost:23 [email protected]

    %

-2

迫使ssh使用2.0版的协议。

-N

不指出命令,而只有通道。如果忽略了,ssh将初始化一个普通的会话。

-f

迫使ssh在后台运行ssh

-L

localport:localhost:remoteport的风格初始化一个本地通道。

foo.bar.com是远程/目标SSH服务器。

一个SSH通道通过在本地的主机和端口上指定一个侦听套接字来工作。它通过SSH连接到远程机器把所有的连接指向本地主机/端口。

在这个例子中,在本机上的端口5023被指向远程机器的端口23。由于23是用于telnet的,所以这将通过SSH通道创建一个安全的telnet会话。

这可以用来隐藏许多不安全的TCP协议如smtppop3ftp等。

一个典型的SSH通道

    % ssh -2 -N -f -L 5025:localhost:25 [email protected]

    [email protected]s password: *****

    % telnet localhost 5025

    Trying 127.0.0.1...

    Connected to localhost.

    Escape character is ^].

    220 mailserver.foobar.com ESMTP

这可以用来连接ssh-keygen和额外用户帐户来创建一个无缝的SSH通道环境。密匙可以被用来代替键入口令,通道可以被运行在一个相互分离的用户上。

实用的SSH通道例子

确保一个POP3服务器访问的安全

在工作中,有一个接受来自外面连接的SSH服务器。在同一个办公网络中有一个运行POP3的邮件服务器。这个网络或在你家里和办公室之间的网络路径可能或不可能是完全可信任的。由于这个原因,你必须用一个安全的方法检查你的email。解决办法是创建一个到你的办公室的SSH服务器的SSH连接,通过通道连接到邮件服务器。

% ssh -2 -N -f -L 2110:mail.office-foobar.com [email protected]

[email protected]’s password: ******

当通道建立和运行时,你可以指示你的邮件客户端发送POP3请求到本地主机端口2110这儿的一个连接将安全地通过通道转发mail.office-foobar.com

越过一个严格的防火墙

一些网络管理员会使用非常严格的防火墙规则,不仅过滤输入的连接,而且过滤输出的连接。你可能被限定只能用22端口和80端口来使用SSH和进行Web冲浪。

你希望访问另一种(也许是与工作不相关的)服务,如Ogg Vorbis的流媒体服务器。如果这个Ogg Vorbis服务器正运行在2280以外的端口,你就无法访问了。

解决办法是创建一个到你网络防火墙以外的一台机器的SSH连接,然后使用它与Ogg Vorbis服务器建立一个通道。

% ssh -2 -N -f -L 8888:music.foobar.com:8000 [email protected]

[email protected]’s password: *******

你的流媒体客户端现在就可以被指向本地主机的8888端口,这将被转发到的主机music.foobar.com8000端口,这样就成功地越过了防火墙。

10.10.8 更深入的信息

OpenSSH http://www.openssh.com

ssh  scp  ssh-keygen  ssh-agent  ssh-add

sshd  sftp-server

有关这些程序的更深入的信息,请参考它们各自的联机手册。