IBM WebSphere 开发者技术期刊: WebSphere Application Server V6 高级安全性加强——第 1 部分

安全性加强概述和方法

安全性不仅是在网络边缘保护您不受外部攻击的防火墙,还可能是一组旨在加强您系统安全的复杂的操作和过程。本文涉及安全性概念的多个方面,详细讨论了 IBM® WebSphere® Application Server 体系结构的安全性,并讨论了如何增强 WebSphere Application Server 环境的安全性。这是由两部分组成的文章中的第 1 部分。

Keys Botzum, 高级技术人员 , EMC

Keys Botzum IBM Software Services for WebSphere 的一名高级技术人员。Botzum 在大型分布式系统设计方面有着十多年经验,并且专攻安全性问题。他使用过各种分布式技术,包括 Sun RPC、DCE、CORBA、AFS 和 DFS。最近,他着重研究 J2EE 及其相关技术。他拥有斯坦福大学计算机硕士学位和卡内基梅隆大学应用数学/计算机科学学士学位。

Botzum 发表过许多 WebSphere 和 WebSphere 安全性方面的文章。Keys Botzum 的其他文章和演示文稿可以在 http://www.keysbotzum.comIBM developerWorks WebSphere 上找到。他还著有 IBM WebSphere:Deployment and Advanced Configuration 一书(与 Bill Hines 合作完成)。



2006 年 2 月 06 日

摘自 IBM WebSphere 开发者技术期刊

本文是以 IBM WebSphere: Deployment and Advanced Configuration 一书的安全性章节为基础编写的。本文内容已针对 WebSphere Application Server V6 进行了大幅度更新,并经过编辑,只讨论安全性加强方面的内容。该文本已进行过编辑和排版以作为独立的文章发表。虽然本文基于 WebSphere Application Server V6,但这里的大多数问题也同样适用于 V5 和 V5.1。其中有一个问题是 V6 特有的,我们会特别指出。除此之外,几乎所有其他内容都适合这三个主要版本,不过屏幕截图和示例均来自 V6。

引言

在本文中,我们将介绍安全性的几个方面。我们将首先简单讨论一下安全性为什么重要,然后详细介绍 WebSphere Application Server 安全性体系结构。本文将说明 WebSphere Application Server 安全性的一些要点,然后详细讨论如何加强 WebSphere Application Server 环境以使其更加安全。最后,我们会提供一些关于安全性问题故障诊断的技巧。由于篇幅有限,本资料的很多内容是概括性的,没有进行详细分析。我们将尽可能地为读者提供相关详细信息的适当参考资料。


为什么需要安全性?

令人欣慰的是,大多数读者都能够认识到安全性是企业系统的一个关键方面。尽管如此,为了引入一些理解安全性的常用方法,我们仍将简要介绍一下安全性。

安全性的基本目的是为了阻止不怀好意的人进入您的系统。更准确地说,安全性是一个流程,它应用多种技术来防止未经授权的用户(也就是通常所说的入侵者)对内容进行未经授权的访问。

有许多类型的外部入侵者:外国间谍机构、您的竞争对手、黑客,甚至您自己的雇员。每个入侵者都有不同的动机、不同的技能和知识、不同的访问入口以及不同的需求级别。例如:

  • 雇员可能对公司有攻击动机,虽然雇员有非常高的内部访问和系统知识级别,但他们的资源和黑客技能可能很有限。
  • 外部黑客也许是安全性攻击方面的专家,但是他们对您可能没有攻击动机。
  • 外国间谍机构,可能对攻击您很感兴趣(这取决于您的业务)并且拥有丰富的资源。

入侵者可能为了两个原因之一而入侵您的系统:为了获取他们本不应该拥有的信息,或者为了以某种方式改变系统的正常运行状况。在后一种情况中,通过改变系统的运行状况,他们可以寻求执行对其有利的事务,或者他们只是为了用某种有意义的方式导致您的系统崩溃,以造成对您的组织的损害。

如您所见,有很多不同类型的入侵者、很多不同的动机,以及(我们后面将要讨论的)许多不同的攻击类型。在您规划安全性时,必须注意这些。

我们还要强调的是,安全性不应该仅仅视为阻挡“外人”的大门。那是一个过于简单化的观点。当前许多组织将他们的安全性完全集中在针对组织以外的人群,他们错误地认为只有外部人群才是危险的。实际上并不是这样。组织内部的人也很有可能攻击您的系统。最近的一些研究表明,可能有将近一半的入侵是由(或涉及)组织内部的雇员或者合同工造成的。

即使您假设网络中的每个人都是值得信任的,那么也能够假设他们永远不犯错误吗?考虑到通过 e-mail 传播的病毒如此猖獗,假设整个内部网络都可以信任是鲁莽之举。不能这样做。

您的安全性应该努力保护系统不被所有的潜在入侵者攻击。这就是本文为什么如此之长,并且分成两个部分的原因。安全性不仅仅是在网络边缘保护您的系统不受“外部”攻击的防火墙,它还是一组困难且复杂的操作和过程,旨在尽可能地加强您的系统。

限制和现实状况

应该认识到没有完美的安全系统,这一点很重要。您的目标是在业务约束下尽可能地保护系统。在考虑安全性时,理论上应该:

  • 分析攻击的多个方面。
  • 考虑每种攻击的危害。
  • 确定攻击成功而导致安全性被破坏的可能性。
  • 评估为防止每种攻击而付出的代价。

在估计安全性被破坏而造成的危害时,不要忘记安全性被破坏会导致系统用户对您的系统失去信心。因此,“安全性被破坏的代价”可能包括非常高的间接代价(比如,失去投资者的信任)。

一旦完成以上列出的步骤,您就可以对风险对抗成本做出适当的权衡。从本质上说,这个目标就是要让入侵者为入侵您的系统而付出的代价超过他们可以获得的利益,同时确保业务能够承受运行安全系统所付出的代价。(当某些黑客入侵您的系统只是为了取乐时,这将是一个问题。您能够期望的是通过创建合理的安全环境,入侵者将转而攻击其他更容易攻击的目标。)归根结底,需要什么安全级别是一个业务决策,而不是技术上的问题。然而,作为技术人员,我们必须帮助所有各方理解安全性的价值和重要性。也就是说,除了保护内部应用程序免受攻击外,本文中建议的大多数安全性加强步骤成本都相当低,所以大多数组织都应该全部实现。这里没有介绍更加复杂和昂贵的安全性方法——强身份验证、审核和入侵检测等,它们超出了本机 WebSphere Application Server 产品功能的范围。

安全性是一个很大的话题,本文不可能完全包含安全性的所有方面。本文不打算作为安全性的介绍或者关于如何保护基于 WebSphere Application Server 的系统的教程。而是打算作为概要性概述或者涉及 WebSphere Application Server 时需要考虑的核心技术问题的检查表。本文中的信息应该与创建安全企业这些更大型的工作结合起来。

希望了解更多相关信息的读者请查阅参考资料部分。特别是我的网站,它提供一些应用程序安全性基本知识的概要性概述,不过,有些内容是过时的。

社会工程

由于这是一篇技术性的文章,因此我们重点讨论保护系统的技术解决方案。事实上,我们主要集中于 WebSphere Application Server 部分的安全性难题。尽管如此,您应该意识到使用社会工程 (Social Engineering) 技术而达到危害系统的目的往往更加简单。也就是说,通过欺骗在您的组织中工作的人员,攻击者可以获得权限以访问他们本不应该访问的系统和信息。(请参阅 What is social engineering? 以获得更多信息。)

也许对本文所讨论的关于社会工程攻击技术的一个结论就是:通过使用社会工程,攻击者可能来自您的网络内部。这再次强调了前面提到的仅仅防御来自网络外部的攻击者是远远不够的。这就是为什么这里的讨论要集中于多个级别的安全性的原因。每个级别防范不同的攻击类型,并且提供对攻击者更有效的屏障。


总的系统观点:细节问题

在详细研究具体建议之前,我们打算花一些时间来概述创建安全系统的基础技术。基本观点是着眼于每个系统边界或共享点,并检查哪些参与者访问了这些边界或共享的组件。也就是说,假设这些边界存在(我们假设子系统比较可靠),则入侵者如何入侵这些边界呢?或者,假定某些东西是共享的,则入侵者是否可以不正当地共享某些东西呢?大多数边界是很明显的:网络连接、进程与进程的通信、文件系统、操作系统接口等等,但是有些边界就不好辨别。例如,如果一个应用程序在 WebSphere Application Server 中使用 J2C 资源,则必须考虑其他某些应用程序试图访问那些相同资源的可能性。这是因为第一个应用程序和 WebSphere Application Server 之间以及第二个应用程序和 WebSphere Application Server 之间都存在系统边界。可能这两个应用程序都可以访问这个公共资源(实际上它们确实可以)。这是不合理共享的一种情况。

要防止这些各种形式的攻击,您可以应用许多众所周知的技术。对于较低级别的基于网络的攻击,可以应用加密和网络过滤。这样可以拒绝攻击者查看或访问他们不应该看到的内容。我们还依赖操作系统提供的机制来保护操作系统资源不被滥用。例如,我们不希望普通用户级别的代码能够访问系统总线以及直接读取内部通信。我们还利用了大多数主流操作系统对系统 API 保护得相当可靠这一事实。遗憾的是,在 WebSphere Application Server 环境中,这些操作系统保护的价值比较有限,因为它们是基于流程识别的,当考虑到应用服务器同时接受数千用户发出的请求时,这是一个非常粗粒度的概念。

在高级别上,我们严格应用身份验证和授权。每个 API、每个方法和每个资源都潜在需要某种形式的授权。也就是说,对这些的访问必须严格基于需求。当然,如果没有可靠的身份验证,授权也就失去了价值。身份验证所做的事情就是分辨调用者的身份。我们加了“可靠”这个词,这是因为容易被伪造的身份验证是没有价值的。

如果没有合适的身份验证和授权,那么只能采取巧妙的设计和过程来防止潜在的问题。我们就是用这种方式来保护 J2C 资源。由于 WebSphere Application Server 没有提供对 J2C 资源的访问授权,我们只好转为应用其他技术来限制(基于配置)应用程序不正当访问 J2C 资源的能力。

可以想像,检查所有的系统边界和共享组件这一任务很困难。并且在实际中保护一个系统就需要充分考虑它的复杂性。关于安全性最困难的事情可能就是创建一个依靠抽象工作的安全系统。也就是说,良好的抽象的原则之一就是通过更高级的组件将关注的问题隐藏起来。这是人们非常需要的,也是非常好的做法。遗憾的是,入侵者对我们没有那么友善。他们并不在乎我们的抽象或者我们的良好设计。他们的目标是想尽办法入侵我们的系统。为了达到目标,他们需要在我们的严密设计中寻找漏洞。因此,为了验证系统的安全性,您必须考虑抽象的每个级别:从最高级的体系结构到最低级的详细内容。需要对所有的内容进行严格的审核。

最小的错误都可能破坏整个系统的完整性。使用缓冲区溢出技术来控制基于 C/C++ 的系统的技术是对这最好的例证。其本质为,入侵者传入一个大于现有缓冲区的字符串。然后该额外信息覆盖正在运行的程序的一部分,并导致运行时执行本不应该执行的指令。注意,这会导致程序做几乎任何事情。(有关详细信息,请查阅Buffer Overflows -- What Are They and What Can I Do About Them?)作为安全架构师,要识别这种攻击,就必须深入理解 C/C++ 运行时如何管理内存和执行在运行的程序。假设您了解缓冲区溢出问题的存在,则您也不得不检查每一行代码以发现这个特殊的漏洞。

目前我们已经了解了这种攻击,但是它仍然能够攻击成功,这是因为个别编程人员做出了非常小的错误决策,它会危及整个系统的安全。幸运的是,这种特别的攻击在 Java™ 中不奏效。然而,不要马上就认为其他的小错误不会导致系统受到威胁。要对安全性进行认真的考虑;这是很难的。


加强安全性概述

J2EE™ 规范和 WebSphere Application Server 提供了一种用于实现安全系统的强大的基础设施。遗憾的是,许多人没有意识到创建基于 WebSphere Application Server 的安全系统的各种问题。这些信息有许多自由度和许多不同的来源。这往往使人们忽视安全性问题,部署的系统不够安全。这一部分试图对关键的问题进行总结。

安全性加强指的是配置 WebSphere Application Server、开发应用程序和配置其他各种相关组件以使得安全性最大化——其本质就是防止、阻碍或减轻各种形式的攻击。要使安全性得到有效加强,了解攻击形式是很重要的。攻击应用服务器有四种基本方法:

攻击基于 J2EE 的系统有四种基本方法:

  • 基于网络的攻击
    这些攻击依赖于对网络数据包的低级别访问,它们试图通过改变通信或者发现这些包中的信息来危害系统。

  • 基于计算机的攻击
    在这种情况中,入侵者已经可以访问运行 WebSphere Application Server 的计算机。我们的目标是限制入侵者损害配置或者看到不应该看到的内容的能力。

  • 基于应用程序的外部攻击
    在这种情况中,入侵者使用应用级的协议(HTTP、IIOP、JMX.Web 服务,等等)来访问应用程序,可能通过 Web 浏览器或者其他某种客户端类型。入侵者使用这种访问方式来试图超越应用程序的正常使用,做一些不正当的事情。关键的问题是入侵者是使用定义良好的 API 和协议来进行攻击的。入侵者并不一定是在公司外部,但他是从应用程序自身的外部执行代码的。这些攻击类型是最危险的,因为它们要求的技能很少,并且只要有可用的 IP 连接,就可以从很远的距离实施攻击。

  • 基于应用程序的内部攻击
    在这种情况中,我们关心的是恶意应用程序的危害性。这种情况中多个应用程序共享相同的 WebSphere Application Server 基础设施,我们不能完全信任每一个应用程序。虽然完美的安全性是不可能达到的,但是有一些技术可以限制每个应用程序的危害程度。内部攻击通常表明存在不受信任的代码,是它带来了“麻烦”。通常要注意的就是这一点。但始终要记住,黑客可能远程危害一个应用程序(通过前面的技术),然后利用内部攻击方法来进行更多的危害。

请注意,我们没有考虑一种其他形式的技术攻击:拒绝服务 (Denial of Service, DoS) 攻击。尽管这很重要,但是它超出了本文的范围。防范 DoS 攻击需要不同的技术,这超出了应用服务器所能提供的范围。您需要考虑网络流量监视器、速率限制器、入侵检测工具,等等。

加强方法

现在,我们将确定要保护 WebSphere Application Server 基础设施免受这四种形式的攻击应该采取的各种已知的步骤。理想的情况下,您可以将这些信息分成四个部分,每个部分对应于一种形式的攻击。遗憾的是,攻击并不完全按照那些界线来划分。有几种不同的保护技术可以防范多种形式的攻击,而有时一次攻击可能利用多种入侵形式才达到最终目标。例如,在最简单的情况中,网络嗅探能够用于获取密码,然后这些密码可以用于进行应用级攻击。因而,我们将根据活动发生时间或问题相关人员的角色来将加强技术组织到逻辑结构中:

  • 基础设施
    为将 WebSphere Application Server 基础设施配置为最大化安全性而采取的操作。当基础设施在外部构建并且只涉及系统管理员时,通常采取这些措施。

  • 应用程序配置
    应用程序开发人员和管理员所采用的操作,这些操作在部署流程中是可见的。本质上说,这是一些应用程序设计和实现决策,它们对 WebSphere Application Server 管理员可见并且可以作为部署流程的一部分进行检验(可能有一些难度)。这一部分将介绍大量技术,以进一步加强安全性的不足之处;安全性是每个参与应用程序设计、开发和部署的人员的责任。

  • 应用程序设计和实现
    开发人员和设计人员在部署期间所采取的对安全性至关紧要的操作,但是这些操作难以作为部署流程的一部分进行检验。

  • 应用程序隔离
    这将单独进行详细讨论,因为它涉及到的问题比较复杂。

在每个部分中,我们都按优先级顺序排列各种技术。当然,优先级是主观的。我们尝试大致使用这种方法来确定每个区域中的威胁的优先级:

  • 基于计算机的威胁比网络威胁的可能性小,因为生产中的计算机通常是限制访问的。如果您的环境中不是这种情况,则这些威胁很有可能会出现。您需要限制对这些计算机的访问。

  • 最严重的攻击是只使用 IP 连接进行远程攻击。这意味着所有通信都必须是经过身份验证的。

  • 要保护传输,应该对其进行加密,但对 WebSphere Application Server 内部传输进行加密不如对“超越 WebSphere Application Server”的传输进行加密来得重要。这是因为网络可能会穿越更多的节点,黑客可以在这些节点上窥探传输。

为了帮助您将这些技术与刚才提到的攻击类别联系起来,我们将使用以下图形解释各种技术:

这四个方块加了适当的底纹,以代表这种技术有助于防范的攻击类型:

  • N = 基于网络的攻击
  • M = 基于计算机的攻击
  • E = 基于外部应用程序的攻击
  • I = 基于内部应用程序的攻击

请记住,内部应用程序始终可以利用“外部的”攻击方法进行攻击。因此,当 E 已经表示时,我们就不再明确地列出 I。但是当漏洞只被内部应用程序利用时,我们就会列出“I”。

SSL 概述

安全套接字层 (SSL) 是 WebSphere Application Server 安全性体系结构的一个关键组件。SSL 被广泛用于安全通信。它用于保护 HTTP 传输、IIOP 传输、LDAP 传输和 SOAP 传输。SSL 需要使用公钥/私钥对,对于 WebSphere Application Server,这些密钥存储在密钥存储库中。因为 SSL 在保护基础设施上具有重要作用,所以我们将暂时离开话题来介绍 SSL 的一些与 WebSphere Application Server 相关的重要方面。这一讨论有意只做简要介绍,并且只讨论要正确配置 SSL 所需要的关键点。

公钥密码术 (Public Key Cryptography) 从根本上讲是基于公钥/私钥对的。这两个密钥是通过密码术进行关联的。关键的问题是这些密钥是非对称的——使用一个密钥加密的信息可以使用另一个密钥来解密。私钥自然是私有的。也就是说,您必须始终保护该私钥。其他任何人只要能够访问该私钥,他接下来就可以用它来“证明”身份,并以您的名义进行活动。它很像一个密码,只是更改比较困难。持有私钥就是身份的证明。公钥是密钥对的一部分,它可以与其他人共享。

如果有一种安全的方法可以将公钥分发给受信任的群体,这就足够了。然而,公钥密码术更进一步,它引入了签名公钥的概念。签名公钥有数字签名(非常类似于人工签名)来表明签署者对公钥的担保。签署者保证与签名公钥相对应的私钥持有者是通过密钥识别的群体。这些签名公钥被称为证书。众所周知的签署者被称为证书授权方 (CA)。也可以使用公钥签署其自身。这些被称为自签署 (self-signed) 证书。自签署证书的安全性不亚于通过证书授权方签署的证书。它们只是乍看起来不易于管理。

图 1 中显示了使用 CA 创建证书和分发的基本流程,对于本例,用于通过 SSL 执行服务器身份验证。也就是说,服务器持有一个证书,用于向客户端表明其身份。客户端不持有证书,因此对 SSL 是匿名的。

图 1. 服务器 SSL 身份验证 – 证书创建和分发
图 1. 服务器 SSL 身份验证 – 证书创建和分发

在查看此图时,请注意客户端必须持有证书,它签署了服务器产生的公钥。这是信任的关键部分。由于客户端信任它拥有的任何证书(在本例中包含 CA 证书),所以它信任 CA 签署的证书。如果您使用自签署的证书,这将没有什么价值,因为您将需要手动将这些自签署证书分发到每个客户端,而不是依靠可能已经构建到客户端的众所周知的 CA 证书。这并非不安全,但如果您有许多客户端,要将所有这些签署的证书(每个服务器对应一个)分发到所有客户端将会变得更加难以管理。只分发一个签署了许多证书的 CA 证书比较容易。对于使用 SSL 的服务器身份验证来说更是如此。在身份验证之后,SSL 将真正使用保密的密钥加密来保护通道,但其细节与本讨论无关。

当客户端向服务器验证其自身身份时,虽然角色相反,但流程与此相似。为了让服务器对客户端进行身份验证(这通常称为客户端证书身份验证),客户端必须持有一个私钥和相应的证书,而服务器必须持有相应的签署证书。这对它来说是举手之劳。请注意什么不是必需的。SSL 证书身份验证仅仅确定证书的有效性,而不关心该证书代表谁。这是后者——SSL 后处理的责任。这有着重要的意义,稍后我们将会看到。

总之,因为 SSL 使用证书身份验证,所以 SSL 连接的每一端都必须持有密钥存储文件中的适当密钥。只要您配置 SSL 密钥存储库,都需要考虑哪一群体需要哪些密钥的基本规则。通常,这将让您知道您需要什么。

强大的 SSL 欺骗

正如我们刚刚提到的,一旦 SSL 检验过证书,身份验证流程就不在 SSL 的有效范围内。接下来理想的情况应该是另一个组件查看证书中的身份,然后使用该身份做出授权决策。授权决策可以是客户端确认服务器是受信任的(Web 浏览器只要核实证书中的名称与 Web 服务器的主机名称相同就可以进行确认),也可以是服务器提取用户名称,然后使用它来为以后的授权决策创建证书(WebSphere Application Server 在对最终用户进行身份验证时采取的就是这种方式)。遗憾的是,并非所有的系统都有这样的功能。对于这样的系统,您可以利用流行的 SSL 欺骗:限制有效的证书。

请注意,在前面涉及客户端身份验证的场景中,客户端提供一个证书,然后服务器针对受信任的证书集对其进行检验。一旦检验通过,SSL 握手就完成了。如果我们限制服务器上受信任的签署者,我们就连谁能完成 SSL 握手都可以限制。在自签署证书的极端情况下,我们可以创建只有一个签署者的情形:只有一份的自签署证书。这意味着只有一个有效的客户端私钥可以用于连接此 SSL 端点——也就是我们在一开始创建自签署证书时生成的私钥。通过这种方式我们就可以轻松地限制谁能通过 SSL 连接到系统,即使服务器端组件不提供授权。您可以将这看作是在网络层创建安全的受信任隧道。假设一切都已正确配置完成,则只有特定的受信任客户端才可以通过这一传输连接。这在 WebSphere Application Server 中的几种情况下非常有用,这一点我们后面将会讨论。

管理 SSL

正如我们已经看到的,WebSphere Application Server 是在密钥存储文件中管理密钥的。有两种类型的密钥文件:密钥存储库和信任存储库。信任存储库只不过是(根据约定)仅仅包含受信任的签署者的密钥存储库。因此,您应该将 CA 证书和其他签名证书放入信任存储库,并将私有信息(含有私钥的个人证书)放入密钥存储库中。

遗憾的是,这个简单的系统存在一个问题。大多数 WebSphere Application Server 都使用新的 Java 定义的密钥存储库格式(称为 Java Key Stores (JKS))。(事实上,WebSphere Application Server SSL 配置支持三种现行的密钥数据库格式:JKS、JCEKS 和 PKCS12。)而 IBM HTTP Server 和 WebSphere Application Server Web 服务器插件则使用一种较老的密钥格式(称为 KDB 格式,或者更准确地说是 CMS 格式)。这两种格式功能上相似,但格式上不兼容。因此要注意不能将它们混用。

IBM 提供了一个名为 ikeyman 的工具来管理密钥存储库。这是一个非常简单的工具,用于创建密钥存储库、生成自签署证书、导入和导出密钥,以及为 CA 生成证书请求。在管理密钥存储库时应该使用这个工具。自 WebSphere Application Server V5.1 起,ikeyman 的一个单独版本支持所有需要的密钥存储库格式。如果您使用的是早期版本的 WebSphere Application Server,则包含在 WebSphere Application Server 的 bin 目录中的 ikeyman 不支持 KDB 格式。要创建 KDB 文件,您必须运行更老的 ikeyman,它应该位于在安装 WebSphere Application Server 时隐式安装的 GSK5 安装目录下。在 Windows™ 中,GSK 通常位于 c:\program files\ibm\gsk5。在 Solaris™ 中,通常位于 /opt/ibm/gsk5。其他平台与此类似。

WebSphere Application Server SSL 配置

为了帮助理解,我们简要介绍一下 SSL 配置如何在 WebSphere Application Server 中工作。只要使用基于 SSL 的传输,WebSphere Application Server 服务器代码就会使用 SSL 配置。这意味着 HTTPS、IIOP/SSL、SSL 通道和 LDAP/SSL 都共享管理 SSL 配置的公共代码。因此,在您后面配置 SSL 时,您需要理解这些公共信息。SSL 配置是通过 SSL 区域中的全局安全性面板管理的。当您单击那里时,您将看到为该计算单元定义的 SSL 配置列表。您可以为新的使用添加自己的 SSL 配置,也可以修改现有的配置。明显地,在修改现有的配置时应该很谨慎,因为它们是由多个组件共享的。

图 2 显示了一个 SSL 配置示例。

图 2. SSL 配置
图 2. SSL 配置

这里感兴趣的关键项是:

  • 客户端身份验证
    对此的设置将通知 WebSphere Application Server 应该使用客户端证书身份验证对内部请求进行身份验证。这意味着要求客户端提供一个证书,并且用已配置的信任存储库中指定的签署者对其进行检验。是否所有的一切都通过该身份完成取决于协议。在许多情况下,WebSphere Application Server 对证书中的身份不做任何事情,这就是为什么我们前面提到的 SSL 欺骗如此有用的原因。

  • 安全级别
    您应该将其设置为 HIGH(这是缺省值)以限制可接受的密码,除非您有很好的理由不这么做。如果您愿意,还可以使用选择列表来更准确地指定要使用的密码,但这通常是不需要的。

SSL 面板的下半部分允许您指定密钥存储文件和信任存储文件。请查看图 3。在本例中,您需要指定文件系统位置(每台服务器上都必须一样)、密钥文件密码(服务器用它来对文件进行加密),以及密钥文件格式。WebSphere Application Server 支持多种标准格式,但缺省格式是 JKS。正如我们前面所说的,密钥文件包含私钥,而信任文件包含签名密钥。

图 3. SSL 配置(续)
图 3. SSL 配置(续)

既然我们已经讨论了 WebSphere Application Server 中的 SSL 的基本知识,现在我们应该将注意力转移到安全性的真正目的——创建安全的环境。

基于基础设施的预防措施

在保护基础设施时,首先必须理解要保护的组件。与任何漏洞分析一样,我们从确定组件及其外部通信路径开始。这一分析并没有公开内部应用程序漏洞,但公开了其他大多数漏洞。这有助于审核标准的 WebSphere Application Server 拓扑并查看所有网络链接和协议。作为关注安全性的人员,您需要了解所有这些链接并专注于保护这些链接。我们前面提到过,这些链接代表粗粒度的系统边界。请参见图 4。

图 4. 网络链接图
图 4. 网络链接图

在图 4 中,链接上的字母表示跨那些通信链接使用的协议。对于每个协议,我们列出其用法,并提供一些关于防火墙友好性的信息:

  • H = HTTP 传输

    • 用法:浏览至 Web 服务器、从 Web 服务器到应用服务器的通信,以及管理 Web 客户端。
    • 防火墙友好。
  • W = WebSphere Application Server 内部通信

    • 用法:管理客户端和 WebSphere Application Server 内部服务器管理传输。请注意,WebSphere Application Server 内部通信使用以下几种协议之一:
      • RMI/IIOP 或 SOAP/HTTP:管理客户端协议是可配置的。
      • 文件传输服务(dmgr 到节点代理):使用 HTTP(S)。
      • DCS (Distributed Consistency Service) RMM (Reliable Multicast Messaging):使用私有协议。用于内存到内存复制、无状态会话 EJB、动态缓冲区和高可用性管理器。
    • SOAP/HTTP 防火墙友好。DCS 可以是防火墙友好的。
  • I = RMI/IIOP 通信

    • 用法:EJB 客户端(独立的和 Web 容器的)。
    • 由于使用动态端口和嵌入式 IP 地址(它会影响防火墙执行网络地址转换),所以通常防火墙对其不友好。
  • M = SIB 消息传递协议

    • 用法:从 JMS 客户端到消息传递引擎的传输。
    • 协议:私有协议
    • 对防火墙友好,因为可以修复使用的端口。很可能对 NAT 防火墙不友好。
  • MQ = MQ 协议

    • 用法:WebSphere MQ 客户端(真实客户端和应用服务器)。
    • 协议:私有协议
    • 防火墙可用(有大量端口需要考虑)。请参阅 WebSphere MQ support pac MA86。
  • L = LDAP 通信

    • 用法:WebSphere Application Server 对注册表中的用户信息进行验证。
    • 协议:按照 LDAP RFC 中的定义进行格式化的 TCP 流
    • 防火墙友好
  • J = 通过供应商 JDBC 驱动程序进行的 JDBC 数据库通信

    • 用法:应用程序 JDBC 访问和 WebSphere Application Server 会话数据库访问。
    • 协议:每个数据库私有的网络协议。
    • 防火墙方面取决于数据库(通常对防火墙友好)。
  • S = SOAP

    • 用法:SOAP 客户端
    • 协议:通常为 SOAP/HTTP
    • 当使用 SOAP/HTTP 时对防火墙友好。

如图 4 所示,典型的 WebSphere Application Server 配置有大量网络链接。尽可能地保护其中每个链接上的传输以防范入侵者,这是非常重要的。在本部分剩下的内容中,我们将讨论保护刚刚描述的基础设施所需要的步骤。

1. 在没有 WebSphere Application Server 的情况下,将 Web 服务器放在 DMZ 中
攻击代码

DMZ 有三个基本原则您需要考虑:

  • 来自外部的入站网络传输必须终止在 DMZ 中。网络传输负载平衡器(例如 Network Dispatcher)自身并不满足这种需求。

  • 从 DMZ 到 Intranet 的传输类型和开放端口数量必须进行限制。

  • 必须对运行在 DMZ 中的组件进行加强,并遵循最少功能和最低复杂度的原则。

在典型的 DMZ 配置中,有一个外部防火墙、一个内容尽可能少的 DMZ 网络,以及一个保护生产网络的内部防火墙。

因此,一般将 Web 服务器放在 DMZ 中,并将 WebSphere Application Server 应用服务器放在内部防火墙内。这是比较理想的,因为这样做可以使 Web 服务器拥有简单的配置,并且需要的软件很少。DMZ 还有一个作用就是终止入站请求。最后,内部防火墙唯一必须开放的端口就是用于目标应用服务器的 HTTP(S) 端口。这些步骤使得对攻击者的防范非常严格。如果您将 WebSphere Application Server 放在 DMZ 中的一台计算机上,则必须在那些计算机上安装更多的软件,并且必须在内部防火墙上开放更多的端口,以使 WebSphere Application Server 可以访问生产网络。这极大地破坏了 DMZ 的价值。

2. 将生产网络从 Intranet 独立出来
攻击代码

现在,大多数组织都理解将 Internet 外来者与 Intranet 独立开来的 DMZ 的价值。然而,非常多的组织没有意识到许多入侵者是来自内部网络的。正如我们前面提到的,您需要防范来自内部和外部的威胁。正如保护自己免受来自大量的不受信任的 Internet 的攻击一样,您也应该保护您的生产系统免受大规模的不受信任的 Intranet 的攻击。可以使用防火墙将您的生产网络与内部网络分开。这些防火墙看似比面向 Internet 的防火墙随意得多,但仍然能够防御许多形式的攻击。通过应用这一步骤和前一步骤,您应该可以完成如图 5 所示的防火墙拓扑。有关防火墙端口分配的更多信息,请参阅 WebSphere Application Server 中的防火墙端口分配

请注意,我们在防火墙的边缘放置了 wsadmin。这样做是为了试图说明,虽然我们倾向于只让 wsadmin 在生产网络内(受保护的区域内)运行,但您可以非常容易地通过防火墙运行 wsadmin。我们也在边缘地方显示了 EJB 客户端,因为它们可能位于防火墙的任一侧。

图 5. 推荐的防火墙配置
图 5. 推荐的防火墙配置

我们选择了只显示单个防火墙,而不是面向 Intranet 的整个 DMZ。这是最常见的拓扑。然而,我们也逐渐看到了完整的 DMZ(以及内部 DMZ 中的 Web 服务器),它保护生产网络免受来自非生产网络的 Intranet 的攻击。这的确是一种合理的方法。

3. 启用全局安全性
攻击代码

缺省情况下,WebSphere Application Server 不提供安全性。这意味着所有网络链接都是不加密和不经过身份验证的。因此,任何有权访问部署管理器(通过 HTTP 访问 Web 管理控制台,或者通过 SOAP/IIOP 访问 JMX 管理端口)的用户都可以使用 WebSphere Application Server 管理工具来执行任何管理操作,甚至包含删除现有的服务器。毫无疑问,这带来了极大的安全风险。

因此,您至少应该在生产环境中启用 WebSphere Application Server 全局安全性来预防这些常见形式的攻击。一旦在全局范围内启用 WebSphere Application Server 安全性,部署管理器和应用服务器之间的 WebSphere Application Server 内部链接,以及从管理客户端(Web 和命令行)到部署管理器的传输都将进行加密和身份验证(请参见图 5)。此外,这意味着在运行管理工具时,需要对管理员进行身份验证。

启用单点登录

当使用 LTPA 启用 WebSphere Application Server 全局安全性时,将始终启用单点登录(Single Sign-On)。这样可以通知 WebSphere Application Server 创建 LTPA cookie,并将它们发回到浏览器。这使得应用服务器可以跨请求记忆用户身份。如果您没有启用 SSO,则 WebSphere Application Server 将不会创建 cookie,每一次请求都必须重新对用户进行身份验证。在许多场合中,这是不可行的。对于没有 SSO 的基于表单登录,因为不能成功地重定向到该页面,所以每次登录都导致用户返回登录页面,这是因为 WebSphere Application Server 在登录之后会立即忘记用户身份。更重要的是,这样效率很低。因为每次请求都造成对用户重新进行身份验证,所以系统的性能会变得非常糟糕。

我们没有提到过 SWAM,因为我们尽量不使用它,这有以下几点原因:

  1. 它在以后将被弃用。
  2. 它在 WebSphere Application Server Network Deployment (ND) 中不受支持。
  3. 它依赖于 HTTP 会话实现安全性。因为 HTTP 会话并没有设计得很安全,所以这不是很好的主意。

请注意,启用全局安全性并没有保护所有网络链接,而只是大量关键的内部链接。在本文后面,我们将讨论保护其他网络链接。既然已经启用了 WebSphere Application Server 安全性,我们也将讨论利用它来保护应用程序。

4. 对浏览器访问使用 HTTPS
攻击代码

如果您的站点要执行任何身份验证或者有任何应该保护的活动,则需要对从浏览器到 Web 服务器的访问使用 HTTPS。如果没有使用 HTTPS,则像密码、用户活动、WebSphere Application Server 会话 ID 和 LTPA 安全令牌之类的信息将可能被入侵者看到,因为传输是通过外部网络进行的。

虽然您可以通过未加密的通道发送 LTPA 令牌,但是为了最大程度地加以保护,最好通过加密链接发送它们。如果 LTPA 令牌被成功截获,则窃取者可以模拟该用户的身份,直到它到期为止。

5. 配置安全文件传输
攻击代码

即使启用了安全性,部署管理器仍然使用未经过身份验证的协议向节点代理发送配置更新。更准确地说,节点代码使用未经过身份验证的文件传输服务从部署管理器获取管理配置更新。因此,任何外来的客户端都可以潜在地连接到部署管理器并上传任意文件。如果上传无数大文件,操作系统会耗尽磁盘空间,导致整体故障。理论上也可以下载从部署管理器复制到节点的文件。然而,考虑到这些文件的短暂特性,这种可能性不大。

要确保部署管理器只响应来自计算单元中受信任的服务器的文件传输请求,您必须安装 filetransferSecured 应用程序并替换现有的不安全的应用程序。因为此应用程序是一个系统应用程序,所以它通常不可见,但确实存在。您必须删除它,并使用 wsadmin 安装一个新的应用程序。IBM 提供了一个脚本来达到此目的,但请注意,在撰写本文时,V6 Information Center 中的指令并不十分正确(而且这在 V5 或 V5.1 Information Centers 中没有文档说明)。要安装 filetransferSecured 应用程序,请按照以下步骤(我们显示的是 Windows 示例,但 UNIX® 基本相同)。

cd <profilehome>\bin wsadmin.bat -user <wasadminuser> -password
<waspassword> wsadmin>source ../../../bin/redeployFileTransfer.jacl wsadmin>fileTransferAuthenticationOn <your cell
name> <dmgr node name> dmgr wsadmin>$AdminConfig save

我们采用的是 WebSphere Application Server ND 环境。如果您使用的是 WebSphere Application Server Base,则服务器名称明显不是 dmgr。而可能是 server1。

如果您没有记住计算单元名称和节点名称,您可以在概要的 config 目录中找到它们。请记住,节点是部署管理器的节点,因此名称结尾可能为“CellManager”。

6. 配置证书以确保基于 Web 的管理证书验证合理
攻击代码

当安全性启用并且您使用 Web 管理控制台时,您的 Web 浏览器可能警告您证书不受信任,并且主机名与证书中的主机名不匹配。您可以看到如图 6 和 7 所示的消息(我们使用的是 Mozilla Web 浏览器)。

图 6. Mozilla 通知用户证书不受信任
图 6. Mozilla 通知用户证书不受信任
图 7.Mozilla 通知用户证书中指定的主机名与浏览器期望的主机名不相符
图 7. Mozilla 通知用户证书指定的主机名与浏览器期望的不相符

这些消息警告可能存在与 WebSphere Application Server 所使用的证书相关的安全性问题。当您更新缺省的 keyring 时,您可以采取措施来阻止这些警告。首先,生成一个证书,该证书的 Subject 名称与运行管理 Web 应用程序(Base 中的一个服务器,或者其他版本中的部署管理器)的计算机的主机名相同。它将负责第二个浏览器错误消息。第一个消息可以通过从众所周知的 CA 为 WebSphere Application Server 管理控制台购买证书(这可能成本较高)或者通过永久接受该证书来避免。请记住,如果您再次看到这个消息,则很可能表明安全性已被破坏。因此,应该对您的系统管理员进行培训,使其认识到该警告只应该在证书更新时出现。如果它出现在其他时候,则就是系统受到危害的危险警报。

7. 保护 JNDI
攻击代码

J2EE 应用程序使用 JNDI 来发现其他应用程序和资源。因此 WebSphere Application Server 广泛使用 JNDI。遗憾的是,JNDI 命名空间在缺省情况下是不安全的。每个人都有读权限,而所有经过身份验证的用户都有读/写权限。因此,任何通过 IIOP 访问该计算单元的客户端(JNDI 命名空间可以通过 IIOP 远程访问),只要在 WebSphere Application Server 注册表中具有有效的用户 ID 和密码,就可以以任意方式修改该命名空间。毫无疑问,这存在极大风险。

为了解决这个问题,您应该以管理员身份使用管理控制台中的 Environment => Naming => CORBA Naming Service Groups 区域来指定更加严格的限制,从而限制对 JNDI 命令空间的访问。我们建议您将对命名空间的访问限制为“Everyone”都有读权限,但没有人具有读/写权限。这是相当安全的,因为 JNDI 中没有存储敏感数据(密码不存储在那里)。入侵者可以确定服务器端点,但也只能做到这一点。关键是防止恶意更新。请参见图 8 中的示例。请注意,我们已经删除了缺省的 ALL AUTHENTICATED 授权。

图 8. EVERYONE 只具有读权限的命名授权
图 8. EVERYONE 只具有读权限的命名授权

这一设置确保攻击者不能修改 JNDI 命名空间。这不会影响 WebSphere Application Server 自己的操作(包括注册 JNDI 中的资源),因为它始终会授予自己需要的权限。然而,写入 JNDI 的应用程序将会失败。因为这很少出现,所以这在大多数情况下应该不是问题。如果一些应用程序需要对 JNDI 具有写访问权限,则您必须授予它们需要的权限。请注意,JNDI 权限适用于整个命名空间,而不只是其中一部分。

8. 确保对缺省消息传递的授权有意义
攻击代码 只适用于 V6

缺省情况下,服务集成总线 (SIB) 并没有有意义的授权,即使在 WebSphere Application Server 安全性启用时。这意味着任何一方,只要在 WebSphere Application Server 注册表中拥有有效的用户 ID 和密码,就可以对任何队列执行任何操作。所有这些在管理控制台中都是不可见的,也是不可配置的,所以您必须使用 wsadmin。消息传递总线管理任务是由 wsadmin $AdminTask 命令控制的。如果您使用 listGroupsInBusConnectorRole,则在缺省情况下可以快速发现所有可以访问总线的已经过身份验证的用户。这并不非常安全!

我们建议您立即使用 removeGroupFromBusConnectorRole 和 addUserToBusConnectorRole/addGroupToBusConnectorRole 任务来修正这个问题。例如:

wsadmin>$AdminTask removeGroupFromBusConnectorRole {-bus mySIB -group AllAuthenticated}

wsadmin>$AdminTask addUserToBusConnectorRole {-bus mySIB -user bususeryoudetermine}

当然,一旦您配置授权来限制可以连接的各方,则需要使用合适的标识来确保对客户端组件(MDB、JMS 等)进行身份验证。

9. 限制对 WebSphere MQ 消息传递的访问
攻击代码

如果您使用 WebSphere MQ 作为您的消息传递提供程序,则需要通过其他技术来提供队列授权。当使用客户端/服务器模式时(绑定模式依赖于在计算机中进行进程到进程的身份验证),在缺省情况下,WebSphere MQ 并不执行任何用户身份验证。事实上,当您在连接工厂为 WebSphere MQ 指定用户 ID 和密码时,这些值会被 WebSphere MQ 忽略。

解决这个问题的一个选择是,在 WebSphere MQ 服务器端实现自己的自定义 WebSphere MQ 身份验证插件来对 WebSphere Application Server 发送的用户 ID 和密码进行验证。第二种,也可能是更简单的方法,将 WebSphere MQ 配置为使用 SSL 来进行客户端身份验证,然后确保只有 WebSphere Application Server 服务器持有连接到 WebSphere MQ 可接受的证书(利用前面提到的 SSL 客户端身份验证欺骗)。

10. 加密从 WebSphere Application Server 到 LDAP 的链接
攻击代码

当使用 LDAP 注册表时,WebSphere Application Server 会使用标准的 ldap_bind 来验证用户密码。这要求 WebSphere Application Server 将用户密码发送到 LDAP 服务器。如果该请求没有加密,则黑客可以使用网络嗅探器来窃取用于身份验证的用户密码(包括管理密码!)。大多数 LDAP 目录都支持 LDAP over SSL,并且可以对 WebSphere Application Server 进行配置以使用它。在 LDAP 用户注册表面板中(请参见图 9),选择使用 SSL 选项,然后配置适合您的 LDAP 目录的 SSL Configuration。您可能最需要将用于 LDAP 服务器证书的签名密码放在信任存储库中。最好是只为 LDAP 创建新的 SSL Configuration,以避免与现有的 SSL 使用发生问题。

图 9. 启用 LDAP SSL
图 9. 启用 LDAP SSL

如果您使用自定义注册表,则需要使用任何可用的机制来保护该传输。

11. 更改缺省密钥文件
攻击代码

更改缺省 keyring 的注意事项

当更改缺省证书时,需要谨记一件重要的事情。与任何基于 SSL 的系统一样,客户端必须验证服务器提供的证书。这需要客户端为签署服务器提供的证书的签署者保存签名证书。

当附带 WebSphere Application Server 时,所有这些证书都负责 Java 客户端,包括 IBM 提供的工具,例如 wsadmin 和 Tivoli™ Performance Viewer(用于 V6 以前的版本),以及自定义编写客户端。然而,当您更新服务器密钥文件以使用新的私钥和由签署者签署的证书时,您必须确保 Java 客户端能够验证这些证书。您将需要更新客户端信任文件以包含签署者证书,它用于颁发新服务器证书的一方。这意味着任何 Java 客户端(例如 WebSphere Application Server admin 客户端)都可能需要新的客户端密钥文件。如果您使用由众所周知的 CA(例如 Verisign)颁发的证书,则不需要进行更新,因为缺省的客户端 keyring 都已经包含来自最普通的公共 CA 的签名证书。对于 WebSphere Application Server 内部通信,不推荐从 CA 购买证书。如果您的 Java 客户端很少,则通常只需要生成自签署证书并手动更新这些少数的客户端 keyring,这样比较简单和廉价。

这个问题也影响 Web 服务器与应用服务器的通信。因为 Web 服务器插件缺省支持 HTTPS,所以 Web 服务器插件 keyring 包含了 WebSphere Application Server 签名证书示例的副本。如果您更改了缺省的 keyring,请不要忘记更新 Web 服务器插件以包含新的证书。

如前面所述,启用 WebSphere Application Server 安全性使得大多数内部传输都使用 SSL 来保护其不受各种形式的网络攻击。然而,为了建立 SSL 连接,服务器必须持有证书和相应的私钥。为了简化初始安装流程,在交付 WebSphere Application Server 时也提供了一个包含私钥示例的密钥文件示例。售出的每个 WebSphere Application Server 副本都包含这个“私”钥。因此它也不是非常私有。该密钥文件的名称 DummyServerKeyFile 表明了这一点。

要保护您的环境,您应该为通信创建自己的私钥和证书。所有这些都使用 ikeyman 工具来完成。使用 ikeyman 创建新的密钥存储库和信任存储库,然后更新现有的 SSL 配置来使用这些新的文件。有关更多详细信息,请参阅 WebSphere Application Information Center 和 WebSphere Application Security 6.0 安全性红皮书

在您创建新的密钥存储库和信任存储库时,请记住您放在信任存储库中的每个签署者都是对信任的声明。您信任签署者能够确定系统中的主体。如果您信任多个签署者,则根据证书与用户身份的映射关系,可能会出现多个签署者为相同的用户创建证书,这存在极大风险。如果您使用证书来对客户端进行身份验证,为了减低这种风险,您应该减少信任存储库中签署者的数量以尽可能减少证书数。

在我们讨论证书时,需要暂时转移到一个关键点——证书期满。当 WebSphere Application Server 证书期满时,WebSphere Application Server 应该停止工作。不再可能进行任何通信。因此当您按照我们的建议创建证书时,请确保您标记了终止日期。如果您不按照我们的建议,而是使用缺省的密钥,也要记住它们的期限。您必须为证书期满做好准备,并在证书期满之前获取或生成新的证书。

12. 加强 Web 服务器主机
攻击代码

如果您遵循前面推荐的标准拓扑,则 Web 服务器是在 DMZ 中运行。因为 DMZ 是防范潜在入侵者的第一道防线,所以必须特别注意加强此服务器。

本文不讨论 Web 服务器的加强细节,但您应该在操作系统加强、限制 Web 服务器模块被加载和其他 Web 服务器配置步骤上下足功夫。有关这些话题的详细信息,请参阅 Building Secure Servers with LINUX

Web 服务器管理(只适用于 V6)

在加强 Web 服务器时,有一个 WebSphere Application Server 特殊项需要考虑。由 WebSphere Application Server 管理基础设施来管理 Web 服务器是可能的。虽然它使用方便看似好事,但这带来了严重的安全问题。有两种方式可以管理 Web 服务器:使用托管节点和使用本机 IBM HTTP Server (IHS) Admin Server。

要使用托管节点,您需要在 Web 服务器(通常位于 DMZ 中)上放置一个节点代理,使该代理作为 WebSphere Application Server 计算单元的一部分。这从安全角度来看是完全不可接受的,因此不应该使用,除非在极少数不需要 DMZ 的情况下。这不可接受的原因有两点:

  • 节点代理是计算单元的一个全功能成员,它有完整的管理权限。如果它在 DMZ 中受到危害,则整个计算单元都将受到危害。

  • WebSphere Application Server 是一个大而强的产品,因此很难按照本文所示的方法进行加强。这样的产品不会位于 DMZ 中。

第二种方法需要使用 IBM HTTP Server 和配置 HTTP Admin Server。在这种情况下,部署管理器将管理请求发送到运行在 Web 服务器主机上的 HTTP Admin Server。这看似一种合理的方法,但这种传输类型也有一些问题需要关注。

13. 不要在生产中运行示例
攻击代码

WebSphere Application Server 附带了几个非常好的示例来演示产品的各个部分。这些示例不是为在生产环境中使用准备的。不要在那里运行它们,因为它们会带来重大的安全风险。特别是 showCfg 和 snoop Servlet 会向外部人员提供大量关于您的系统的信息。这恰好是您不希望潜在的入侵者获得的信息。只要不在生产中运行 server1(它包含这些示例),就很容易解决这个问题。如果您使用的是 WebSphere Application Server Base,则应该从 server1 中删除这些示例。

14. 审核 Web 服务器信任边界
攻击代码

在配置环境时,要始终注意考虑信任边界。遗憾的是,我们很容易在不经意间不适当地扩展信任边界而导致创建的环境不够安全。WebSphere Application Server 通常使用强机制来执行自己的身份验证。但 WebSphere Application Server 也可能信任您的基础设施中的其他组件,由其执行身份验证。如果处理适当,则不会出现问题。然而,如果处理不适当或者没有认真考虑,则可能创建一个不安全的系统,或者至少是对信任关系理解不足的系统。请记住古谚语——安全性只取决于其最薄弱环节!要谨慎地限制 WebSphere Application Server 信任域。

当编写 TAIs、逻辑模块或其他自定义代码时,通常会显式扩展 WebSphere Application Server 信任域,但它也可以隐式扩展,例如在使用证书时。

在对 Web 客户端使用客户端证书身份验证时,要意识到 Web 服务器现在是信任域的一部分。WebSphere Application Server 将用户证书的有关信息转发到应用服务器。应用服务器必须信任 Web 服务器已经正确地完成证书身份验证。WebSphere Application Server 不能重复 SSL 身份验证握手(只有 SSL 终止器才能这样做)。因此,危害 Web 服务器就彻底危害 WebSphere Application Server 的安全性。

另外,当您对 Web 服务器使用客户端证书身份验证时,由于现在 WebSphere Application Server 已经完全信任 Web 服务器,所以您应该在 Web 服务器和应用服务器之间配置已通过身份验证的 HTTPS 以避免欺骗证书信息的攻击。这就引出了下一个话题。

15. 考虑对 Web 服务器到 WebSphere Application Server HTTP 的链接进行身份验证
攻击代码

WebSphere Application Server Web 服务器插件将来自 Web 服务器的请求转发到目标应用服务器。在缺省情况下,如果与 Web 服务器的传输是通过 HTTPS 完成的,则该插件在将请求转发到应用服务器时会自动使用 HTTPS,从而保护其机密性。

另外,更谨慎的做法是可以将应用服务器(它包含一个小的嵌入式 HTTP 侦听器)配置为只接受来自已知 Web 服务器的请求。这可以在 Web 服务器前或 Web 服务器中防止各种绕过任何安全性检查的暗中攻击,并且创建一个受信任的网络路径。这种情况看似不太可能出现,但存在这种可能性。举些例子:

  • 您拥有一个身份验证代理服务器,它只是将用户 ID 作为 HTTP Header 发送出去,而没有任何身份验证信息。可以直接访问 Web 容器的入侵者只需要提供这一相同的 Header 就可以成为任何人。Tivoli Access Manager WebSEAL 不存在这种弱点。

  • 您正在对 Web 服务器使用客户端证书身份验证。当这种情况发生时,WebSphere Application Server 插件会将证书信息从 Web 服务器转发到应用服务器并信任它。因此,当使用客户端证书时,入侵者直接访问 Web 容器会彻底危害 WebSphere Application Server 的安全性,因为入侵者可以断言任何有效的证书并成为任何人。

要创建从 Web 服务器到应用服务器的受信任网络路径,您需要配置应用服务器 Web 容器 SSL 配置以使用客户端身份验证。一旦您确保客户端身份验证正在使用中,您就需要确保只有受信任的 Web 服务器才能联系 Web 容器。要实现这一点,您需要通过应用 SSL 欺骗来限制具有访问权限的群体。具体到本例,您需要执行以下操作:

  1. 使用 ikeyman 为 Web 容器创建一个密钥存储库和信任存储库,并为 Web Server 插件创建一个密钥存储库。

  2. 从所有密钥存储库(包括信任存储库)删除所有现有的签名证书。此时,您不能使用任何密钥存储库来检验证书,这是有意这样做的。

  3. 在这两个密钥存储库中创建自签署证书,并只导出该证书(而不是私钥)。

  4. 将从 Web 容器密钥存储库中导出的证书导入插件密钥存储库。将插件证书导入 Web 容器信任存储库。现在每一端都只包含一个签名证书。这意味着您可以准确地检验一个证书——为对方创建的自签署证书。

  5. 将新创建的密钥存储库安装到 Web 容器和 Web 服务器插件。

16. 保护私钥
攻击代码

WebSphere Application Server 维护几组私钥。其中两个最重要的例子是用于内部通信的主密钥存储库和用于 Web 服务器和应用服务器之间通信的密钥存储库。这些私钥应该保持私有,不能共享。由于它们存储在计算机文件系统中,所以这些文件系统必须妥善保护。考虑到密钥存储库中信息的敏感性,即使将它放在可通过网络访问的共享文件系统中,也是不妥当的。

也应该注意避免不经意地共享这些密钥。例如,不要在生产中使用与其他环境中相同的密钥。许多人可以访问开发和测试计算机及其私钥。要谨慎地保护生产密钥。

17. 谨慎地配置和使用信任关联拦截器 (Trust Association Interceptor)
攻击代码

TAI 经常用于使 WebSphere Application Server 能够从 Web SSO 代理服务器(例如 Tivoli Access Manager WebSEAL)识别现有的身份验证信息。这通常没什么问题。然而,在开发、选择和配置 TAI 时需要特别注意。TAI 会扩展信任域。目前 WebSphere Application Server 信任 TAI 及 TAI 所信任的所有内容。如果 TAI 开发或配置不适当,就有可能彻底危害 WebSphere Application Server 的安全性。如果您自定义开发 TAI,请确保 TAI 仔细检验请求中传递的参数,并确保检验以安全的方式进行。我们曾经见过 TAI 执行愚蠢的事情,比如简单地接受 HTTP Header 中的用户名。这是没有用处的,除非确保 WebSphere Application Server 收到的所有传输都必须通过身份验证代理发送。例如,使用前面描述的技术,这样身份验证代理将始终重写客户端设置的 HTTP Header,因为 HTTP Header 可以伪造。

WebSEAL TAI 配置

TAI 版本说明

较新的 WebSEAL TAI(WebSphere Application Server V5.1.1 和更高版本包含该 TAI)不再支持相互 SSL 身份验证,也不再通过类名称 TAMTrustAssociationInterceptorPlus 来获知它。您仍然可以在 WebSphere Application Server 中配置相互 SSL(通常这样做也是有用的),但 TAI 不会认同它。对于较新的 TAI,您必须使用来自 WebSEAL 的基于密码的身份验证。较旧的 TAI (WebSealTrustAssociationInterceptor) 也继续包含在其中,如果您需要,可以使用它。

为了阐明仔细配置的重要性,我们准备具体讨论 IBM 提供的 WebSEAL TAI,但任何 TAI 都需要认真设计和配置才能够安全。对 WebSphere Application Server 和 Tivoli Access Manager WebSEAL 之间的信任关系进行合理的配置是创建安全配置的关键所在。要创建安全配置,就必须对 WebSphere Application Server 和 WebSEAL 都采取一些步骤。在 WebSphere Application Server 中,必须对 Web 容器配置和 WebSEAL TAI 配置都进行合理的设置。

这两种产品之间的信任关系是很重要的,因为 WebSphere Application Server 中的 WebSEAL TAI 接受来自 WebSEAL 的身份断言。如果该链接受到威胁,则入侵者就可以断言任何身份并彻底破坏基础设施的安全性。WebSphere Application Server 和 WebSEAL 之间的信任关系是通过以下两种机制之一建立的:相互 SSL 身份验证和基于密码的身份验证。每一种机制在安全环境中都是适用的。然而,每一种都必须进行合理的配置,否则可能出现严重的安全问题。在每种机制中,WebSEAL 都将最终用户的用户 ID 作为 iv-user Header 在 HTTP 请求中发送。这两种配置的区别在于 WebSEAL 向应用服务器证明自身的方式。

WebSEAL 密码配置

当使用密码身份验证时,WebSEAL 会将其用户 ID 和密码作为基本的 auth Header 在 HTTP 请求中发送(该用户的用户 ID 位于 iv_user Header)。基于密码的身份验证要在两个地方中配置。首先,对于要配置的交叉点,必须配置 TAM WebSEAL 以将其用户 ID 和密码发送到应用服务器。当然,此密码是机密的,必须谨慎保护。WebSEAL TAI 在收到密码时会根据注册表对其进行检验。

然而,这一点很不起眼,容易被忽视。如果在 WebSEAL 属性上没有设置 LoginId 属性,则 TAI 就会检验从 WebSEAL 发送出来的用户 ID 和密码组合,如果它是任何有效的用户 ID 和密码组合,则会信任它。这种配置是不安全的,因为这意味着任何知道有效用户 ID 和密码组合的人都可以连接到 WebSphere Application Server,并断言任何用户身份。当您指定 LoginId 属性时,WebSEAL TAI 会忽略基本 auth Header 中的入站用户 ID,并检验 LoginId 和 WebSEAL 密码组合。在这种情况下,只会从 WebSEAL 发出一个(大概接近于受保护的机密)有效的密码。当然,您应该配置从 WebSEAL 到应用服务器的 SSL 以确保该机密密码不会以明文方式发送。

WebSEAL mutualSSL 配置

相互 SSL 是通过三个独立的非常重要的步骤配置的:

  1. 您必须配置 WebSEAL 以使用 SSL 来与 WebSphere Application Server 进行通信,而且该 SSL 配置必须包含只对应用服务器 Web 容器已知的客户端证书。

  2. 您必须配置该应用服务器 Web 容器以执行客户端证书身份验证。也必须更改其信任存储库,使之只包含 WebSEAL 正在使用的客户端证书。这个步骤至关重要,因为只有这样我们才能保证对应用服务器 Web 容器的请求仅来自 WebSEAL 而非某个入侵者(使用相互身份验证的 SSL 是不够的)。您也必须将非 HTTPS 传输从 Web 容器中删除,以确保在与服务器联系时只使用相互身份验证的 SSL。

  3. 您必须配置 WebSEAL TAI,使其属性中 mutualSSL=true。然而,您必须理解最后这个步骤只是向 TAI 表明它应该假设连接是安全的,而且它使用相互身份验证的 SSL。如果前面这两个步骤没有严格地正确配置,您的环境就不是十分安全的。因此,选择使用 mutualSSL 必须非常谨慎。任何配置失误都会导致环境可被任何用户模拟。

如果您在混合体中添加一个 Web 服务器,则会使事情变得更复杂。在这种情况下,您必须谨慎地配置 WebSEAL 和 Web 服务器之间的相互 SSL 配置,以及 Web 服务器插件和 WebSphere Application Server Web 容器之间的第二个配置。

18. 只使用新的 LTPA cookie 格式
攻击代码

WebSphere Application Server V5.1.1 给支持主题传播引入了新的 LTPA cookie 格式 (LTPAToken2) (请参阅 WebSphere Application Server 中的高级身份验证)。当引入了新的格式时,也解决了旧格式中的一些理论上的缺点。请记住,这些缺点只是理论上存在的。还没有出现已知的威胁。我们应该使用新的更强的格式,除非您不得不使用比较旧的格式。

新的 LTPA 令牌使用以下强加密技术:

  • Random Salt
  • 基于强 AES 的密码
  • 对数据签名
  • 对数据加密。

出于好奇,我们使用 1024 位 RSA 密钥对来进行签名,使用 128 位机密密钥 (AES) 来进行加密。用于加密的密码是 AES/CBC/PKCS5Padding。

缺省情况下同时支持新旧 cookie 格式,以确保在创建 LTPA cookie 时与其他系统相兼容,例如较老版本的 WebSphere Application Server、Lotus® Domino® 和 TAM WebSEAL。如果您不需要这种兼容性,则应该禁用它。要禁用它,请转到 Security => Authentication Mechanisms => LTPA => SSO 配置面板并取消选择 interoperability mode。请参见图 10。

图 10. SSO 互操作模式设置
图 10. SSO 互操作模式设置

19. 不要在命令行中指定密码
攻击代码

一旦启用安全性,WebSphere Application Server 管理工具就要求您只有通过身份验证才能使用它。实现身份验证的缺省或明显的方式就是在命令行中指定用户 ID 和密码,将其作为参数传递给该工具。请不要这样做。这会向任何窥探您左右的人暴露您的管理密码。而且在许多操作系统中,任何可以看到进程列表的人都可以看到命令行上的参数。相反,应该确保由管理工具提示输入用户 ID 和密码。从 WebSphere Application Server V6.0.2 起,所有管理工具在没有人向命令行提供用户 ID 和密码时,会自动提示输入。不需要其他的操作。

如果您使用的是较老版本的 WebSphere Application Server,则可以通过告诉这些工具使用 RMI(缺省的是 SOAP)通信来强制它们提示输入用户 ID 和密码。RMI 引擎在需要时会提示。要实现这一点,只需要指定 -conntype RMI -port <bootstrap port>。这里是以这种方式启动 wsadmin 来连接到侦听缺省端口的部署管理器的一个示例:

wsadmin.sh -connectype RMI -port 9809

您可能会发现命令行工具以图形方式提示输入用户 ID 和密码非常烦人。幸运的是,您可以重写该行为。您可以强制该工具使用简单的基本文本的提示方式。要实现这一点,请通过编辑合适的配置文件,将 loginSource 从 prompt 更改为 stdin。在缺省情况下,管理工具使用 SOAP,因此您需要编辑 soap.client.props 文件。如果您使用的是 RMI,则编辑 sas.client.props。请查找合适文件中的 loginSource 属性,并更改它以指定 stdin。

20. 谨慎地限制受信任签署者
攻击代码

在使用证书身份验证(客户端或服务器)时,您需要理解信任存储库中的每个签署者都代表一个身份信息(证书)的受信任提供者。您信任的签署者应该尽可能少。否则,有可能两个签署者颁发的证书映射到同一个用户身份。这会在您的体系结构中产生严重的安全漏洞。

您应该使用 ikeyman 检查客户端和服务器上的信任存储库,删除任何不需要的签署者。

21. 加密缺省的消息传递链接
攻击代码 只适用于 V6

在缺省情况下,消息是通过未加密的链接传递的。这明显是不可取的。要修正这个问题,您应该进行一些配置更改。对于每个应用服务器(非集群),请转到消息传递引擎入站传输面板并禁用 InboundBasicMessaging 传输。一旦您这样做,客户端将只能使用 InboundSecureMessaging 传输。请参见图 11。

版本说明

WebSphere Application Server V6.0.2 增加了为 MDB 指定传输链的功能。

要完成任务,您还必须配置每个客户端以使用 InboundSecureMessaging 传输。这需要您在几个位置之一指定此传输(取决于客户端类型)。普通的 JMS 客户端(甚至服务器端)需要在连接工厂面板指定 InboundSecureMessaging 传输。请参见图 12。MDB 需要在激活规范面板中指定 InboundSecureMessaging。最后,如果使用交叉总线通信,则需要在总线配置面板中指定 InboundSecureMessaging 作为引擎间传输链。

图 11. 禁用 InboundBasicMessaging
图 11. 禁用 InboundBasicMessaging
图 12. 配置连接工厂以使用安全传输
图 12. 配置连接工厂以使用安全传输

有关更多信息,请参阅 Administering messaging security

22. 加密 WebSphere MQ 消息传递链接
攻击代码

如果您使用的是 MQ 而非缺省的消息传递提供程序,则当然应该对 MQ 使用 SSL。这是通过指定 SSLCIPHERSUITE 属性来完成的。有关这一点的更多信息,请参阅 WebSphere Application Server Information Center 和 WebSphere MQ 文档。

23. 加密 Distribution 和 Consistency Services 传输链接
攻击代码 只适用于 V6

核心组依赖于 Distribution and Consistency Services (DCS),它使用可靠的多播消息 (RMM) 系统来进行传输。RMM 可以使用几种有线传输技术之一。为了使安全性最大化,应该使用加密链接。为了使每个核心组都具有最大安全性,需要选择一种通道框架传输类型,并将 DCS-Secure 作为通道链。请参见图 13。

图 13. 配置 DCS 以使用受保护的链接
图 13. 配置 DCS 以使用受保护的链接

请注意,当启用全局安全性时,DCS 始终对消息进行身份验证。一旦传输加密,您就需要有一个高度安全的通道。

一旦您做到这一点,所有依赖于 DCS 的服务都将使用加密的和经过身份验证的传输。这些服务是 DynaCache、内存到内存会话复制、核心组、Web 服务缓存和有状态会话 Bean 持久性。

24. 加密 Distributed Replication Service 网络链接
攻击代码

如果您使用的是 WebSphere Application Server V6 并且已经配置了 DCS 以使用加密链接,则不需要这个步骤,因为 Distributed Replication Service (DRS) 是在 DCS 链接上运行的。

DRS 传输在缺省情况下是不加密的,即使启用了全局安全性。DRS 加密的配置是通过在复制域配置面板 (environment => replication domains => yourdomain) 中指定加密类型为 DES 或 3DES 来实现的。

25. 保护从应用服务器到数据库的链接
攻击代码

与其他任何网络链接一样,机密信息可能是写入数据库或从数据库中读取的。虽然大多数数据库都支持某种形式的身份验证,但并没有全部支持对客户端(在本例中为 WebSphere Application Server 应用程序)和数据库之间的 JDBC 传输进行加密(请查阅您的数据库提供商的文档)。因此,您必须认识到这个弱点并采取合适的步骤。某种可能使用 IP 安全性协议 (IPSEC) 的网络级加密形式(例如虚拟专用网 (VPN))是最可取的解决方案,虽然也有其他合理的选择。如果您可以将数据库放在 WebSphere Application Server 附近(从网络角度讲),则各种形式的防火墙和简单路由欺骗都可以极大地限制访问数据库的网络传输。这里关键之处是识别这种风险,然后合理地解决它。

26. 创建独立的管理用户 ID
攻击代码

当 WebSphere Application Server 安全性配置完成时,在开始时会将一个安全性 ID 配置为 Security Server ID。这个 ID 实际上等同于 WebSphere Application Server 中的根,它能够执行任何管理操作。由于这个 ID 很重要,所以最好不要到处共享其密码。

控制台登录说明

对于 WebSphere Application Server V6,您将发现一旦配置了 JNDI 加强(如前面所述),您将无法以管理员身份(而非安全性服务器 ID)登录到管理控制台。您将需要特别授予管理员所有 CosNaming 权限,这样他们才能够登录。

与大多数系统一样,WebSphere Application Server 不允许多个主体担任管理员角色。可以简单地使用管理应用程序并进入系统管理/控制台用户(或用户组)部分,来指定应该授予管理权限的其他用户或用户组。当您进行这样的授权之后,在管理 WebSphere Application Server 时每个人都可以以自己的名义进行身份验证。请注意,计算单元中的所有管理员都具有相同的权限。WebSphere Application Server 不支持基于实例的管理授权。

对于 WebSphere Application Server 5.0.2,会导致更改 WebSphere Application Server 配置的所有管理操作都需要经过部署管理器的审核,包括进行更改的主体的身份。显然,如果每个管理员都有独立的身份,则这些审核记录会更加有用。审核记录被视为重要信息,并从部署管理器发送到 SystemOut.log(缺省情况下)。

在由中心管理员管理多个 WebSphere Application Server 计算单元的环境下,为每个管理员授予独立管理权限会非常方便。虽然每个计算单元都有自己的本地“根”ID 和密码,但是您可以配置所有这些计算单元以共享公共注册表,这样管理员就可以使用相同的 ID 和密码来管理每个计算单元。

27. 利用管理角色
攻击代码

WebSphere Application Server 允许四种管理角色:管理员、操作员、监视人员和配置人员。这些角色使得授予个人(和自治系统)适合他们(它们)需要的访问级别成为可能。我们强烈建议您尽可能地利用角色。通过使用角色较弱的监视人员和操作员,您可以限制管理员能够采取的操作。例如,您可以赋予较为低级的管理员启动和停止服务器的能力;赋予夜间操作员监视系统(监视人员)的能力。这些操作通过限制人们只具有他们需要的权限,从而极大地限制了损害风险。

一个有趣的角色是监视人员角色。通过授予用户或系统这种访问级别,您可以使他们(它们)只具有监视系统状态的能力。您不能够更改状态,也不能够修改配置。例如,如果您开发用于检查系统运行状况的监视脚本,并且必须用该脚本在本地保存用户 ID 和密码,则应该使用具有监视人员角色的 ID。即使该 ID 受到威胁,所造成的损害也不会很严重。

28. 删除 Web 服务器和插件安装程序遗留的 JDK
攻击代码

当您安装 IBM 的 HTTP Server 时,安装程序会在安装根目录的 _jvm 目录中遗留一个 JDK。由于这是一个完整的 JDK(包含开发工具),所以不应该放在 DMZ 中的计算机上。您应该删除此 JDK。请记住,这样将不能在此 Web 服务器上运行一些工具(例如 ikeyman)。我们不认为这个问题很重要,因为在 DMZ 中运行这样的工具是不合适的。

当您使用 IBM 安装程序安装 WebSphere Application Server HTTP Server 插件时,它也会遗留 JDK——在本例中有两个。第一个 JDK 供卸载程序使用,它位于插件安装根目录的 _uninstPlugin 目录中。第二个 JDK 位于 java 目录中,它由 ikeyman 和其他 Java 工具使用。正如前面提到的,您在安装后应该删除此 JDK。

如果您选择删除该 JDK,请做一下备份以防将来使用。一种方法是对该 JDK 进行 zip 或 tar,并在以后将它放回原处(例如在应用补丁时 WebSphere Application Server 更新安装程序需要它的时候),然后对其进行 zip/tar,并在过程结束时再次将其删除。

29. 选择合适的进程身份
攻击代码

WebSphere Application Server 进程是在操作系统上运行的,因此必须在某个操作系统身份下运行。有三种运行 WebSphere Application Server 的方式与操作系统身份有关:

  • 以 root 身份运行一切程序。
  • 以单用户身份(例如“was”)运行一切程序。
  • 以 root 身份运行节点代理,并以应用服务器自己的身份运行各个应用服务器。

IBM 测试过并完全支持前面两种方法。第三种方法看似很有诱惑力,因为那样您可以利用操作系统权限,但它在实际中不是非常有效,这有以下几点原因:

  • 它配置困难,而且过程没有文档说明。许多 WebSphere Application Server 进程都需要对无数文件具有读访问权限,并且对 log 和 transaction 目录具有写访问权限。

  • 通过以 root 身份运行节点代理,您可以有效地对 WebSphere Application Server 管理员和任何在 WebSphere Application Server 中运行的应用程序授予 root 权限。

  • 这种方法的主要价值在于控制应用程序访问的文件系统。您可以使用 Java 2 权限来实现这一点。

  • 这种方法会造成应用程序互相隔离的错觉。其实不是。WebSphere Application Server 内部安全模型是基于 J2EE 和 Java 2 安全性的,不受操作系统权限的影响。因此,如果您选择使用这种方法来保护自己免受“恶意”应用程序的侵害,则会被您的方法误导了。

第一种方法明显是不可取的,因为作为一般的最佳实践,如果可以避免以 root 身份运行任何进程,则最好避免。这样就只剩下第二种方法,它是完全受支持的,并且在与 Java 2 安全性联合使用时提供应用程序隔离(这正是我们想要的)。因此,我们建议采用这种方法。

明显地,一旦您选择使用 WebSphere Application Server 进程身份,您就应该利用操作系统文件权限来限制对 WebSphere Application Server 文件的文件系统访问。与任何复杂系统一样,WebSphere Application Server 使用和维护大量敏感信息。一般来讲,不应该有人对大多数 WebSphere Application Server 信息具有读或写权限。特别是 WebSphere Application Server configuration 文件 (<root>/config),它既包含配置信息,也包含密码。

对这一点也不要过于走极端。我们见过非常多这种情况:在开发期间,开发人员甚至不允许查看应用服务器日志文件。这种极端做法完全没有必要。在开发期间,最大化安全性无助于生产。在生产期间,您应该尽可能地锁定 WebSphere Application Server。在开发期间,则应该采取较宽松的尺度。

30. 强制 CSIv2 传输使用 SSL
攻击代码

当 WebSphere Application Server 服务器和客户端使用 CSIv2 IIOP 进行通信时,它们之间协商传输安全性。对双方来说可接受的所有一切都选上了。一般来说,这是可以的,但您应该注意一个潜在的弱点。WebSphere Application Server 支持 CSIv2 over SSL 或明文方式。在缺省情况下,双方通常会协商使用 SSL,从而建立加密的通信通道。然而,如果在协商中有任意一方请求使用明文,则将使用明文方式。您甚至可能没有意识到传输是以明文方式发送的!这种问题可能出现,例如,如果一个客户端配置错误。如果您想要保证传输是加密的(您也应该保证这样),则更保险的做法是确保 SSL 始终使用。

您可以通过在 CSlv2 传输面板 (Security => Authentication Protocol => CSIv2 Inbound Transport) 中指明 SSL 是必需而不是可选的来确保对 IIOP 使用 SSL。对 CSIv2 Outbound Transport 也应该这样做。请参见图 14。

图 14. CSIv2 传输面板
图 14. CSIv2 传输面板

31. 保持补丁和修复最新
攻击代码

与其他复杂产品一样,IBM 会不时地发现和修复 WebSphere Application Server、IBM HTTP Server 和其他产品中的安全性错误。保持这些修复最新是很关键的。建议您订阅您使用的产品的支持布告栏,对于 WebSphere Application Server,要监视推荐更新支持页面。这些布告栏通常包含最近发现的安全性错误和修复通知。可以肯定,潜在的入侵者会很快了解那些安全性漏洞。越早采取行动越好。

请注意,对于每个支持的版本,WebSphere Application Server 安全性修复通常会包含到下一个累积修复中,然后推荐更新页面中不再列出。因此,如果您想要修复所有已知的安全漏洞,则需要保持累积修复最新。

32. 禁用不使用的端口
攻击代码

安全性加强的基本原则是使潜在攻击的攻击面最小化。当给定的服务没有已知的安全问题时尤其应该这样。如果该服务对站点的正常运转是不必要的,则应该将其删除,以使得攻击者在将来的某个时候利用这个额外功能进行攻击的可能性最小化。查看图 15,您将发现一个典型的 WebSphere Application Server 应用服务器正在侦听大量端口。

图 15. WebSphere Application Server ND 应用服务器的缺省端口
图 15. WebSphere Application Server ND 应用服务器的缺省端口

如果给定的服务不是必需的,则可以禁用其侦听端口。请看此列表,要禁用的潜在候选端口是:

  • SAS_SSL_SERVERAUTH_LISTENER_ADDRESS – 用于与 WebSphere Application Server V4 和更早版本相兼容。这是旧的 IIOP 安全性协议。V5 中使用 CSIv2 来替代它。

  • SIB_ENDPOINT_* -- 供内置的消息传递引擎使用。如果您没有使用消息传递,则不需要使用它。

  • SIB_MQ_* -- 供消息传递引擎在与 WebSphere MQ 连接时使用。

  • WC_adminhost* -- 用于管理性 Web 浏览器访问。这些端口在作为计算单元的一部分的应用服务器中已经禁用。

  • WC_defaulthost* -- 缺省的 Web 容器侦听端口。如果您已经添加自定义侦听端口,则可能不需要这些。

不同端口需要使用不同的技术来禁用,这取决于它们的实现方式:

  • 可以通过在全局安全性面板中选择 CSI 作为活动协议来将 SAS_SSL_SERVERAUTH_LISTENER_ADDRESS 从服务中除去。

  • WC_* 端口都是用于 Web 容器的。从 Web 容器传输链配置面板 (application servers => servername => web container => transport chain) 删除、修改或禁用它们是最好的。您需要的侦听 Web 端口只有您的应用程序使用的那些端口。

  • 除非启用了消息传递引擎,否则不会启动 SIB_* 端口,所以不需要对它们采取措施。

基于应用程序的预防措施:配置

此时,我们已经着重介绍过 WebSphere Application Server 体系结构和管理团队要确保创建安全基础设施可以采取的基本步骤。这明显是个很重要的步骤,但只有这样是不够的。既然基础设施已经加强,我们必须检查要使应用程序安全需要做的事情。明显地,应用程序需要利用 WebSphere Application Server 提供的基础设施,但应用程序开发人员还需要进行其他许多操作。我们这里将详细讨论其中的许多问题。

33. 不要将 Web 服务器的文档根目录设置为 WAR
攻击代码

WAR 文件包含应用程序代码和许多敏感信息。其中只有一些信息是可服务于 Web 的内容。因此,将 Web 服务器文档根目录设置为 WAR 根目录是不合适的。如果您这样做,Web 服务器将不加解释地提供 WAR 的所有内容。这将导致将代码、未经处理的 JSP 和其他更多内容提供给最终用户。

请注意,此建议只适用于 Web 服务器和应用服务器共存时——这种配置我们不推荐。

34. 仔细检查每个 Servlet 别名是否安全
攻击代码

WebSphere Application Server 通过 URL 保护 Servlet。每个要保护的 URL 都必须在描述应用程序的 web.xml 文件中指定。如果 Servlet 有不止一个别名(也就是说,多个 URL 访问相同的 Servlet 类),或者有许多 Servlet,则比较容易遗漏对别名的保护。这需要小心。由于 WebSphere Application Server 保护的是 URL,而不是基础类,所以即使只有一个 Servlet URL 是不安全的,入侵者也能够绕过您的安全性。为了减少这种威胁,应该尽可能使用通配符来保护 Servlet。如果那样做不合适,则应该在部署前再次仔细检查您的 web.xml 文件。

通过类名提供 Servlet 这一功能进一步加剧了别名问题,这就引出了我们的下一个推荐。

35. 不要通过类名提供 Servlet
攻击代码

您可以通过类名或正常的 URL 别名来提供 Servlet。通常应用程序选择后者。也就是开发人员手动在 web.xml 文件中定义从每个 URL 到每个 Servlet 类的准确映射,或者通过使用几种 WebSphere Application Server 开发工具之一来定义。

然而,WebSphere Application Server 也允许您通过类名提供 Servlet。与为每个 Servlet 定义映射不同,它用一个泛型 URL(例如 /servlet)来提供所有 Servlet。假设基本路径后面的路径组件是 Servlet 的类名。例如,“/servlet/com.ibm.sample.MyServlet”引用 Servlet 类“com.ibm.sample.MyServlet”。

通过类名提供 Servlet 是通过在 ibm-web-ext.xmi 文件中将 serveServletsByClassnameEnabled 属性设置为 true 完成的,或者在 IBM Rational® Application Developer 的 WAR 编辑器中选中“serve servlets by classname”。请不要启用这个功能。这个功能使得任何人都知道任何 Servlet 的类名,从而可以直接调用它。即使您的 Servlet URL 是受保护的,攻击者也可能绕过正常的基于 URL 的安全性。更进一步地,根据类加载器的结构,攻击者可能在您的 Web 应用程序外部调用 Servlet。

35. 不要将敏感信息放在 WAR 根目录中
攻击代码

WAR 文件包含可提供的内容。Web 容器提供 WAR 文件根目录中的 HTML 和 JSP 文件。当您只在该根目录中放置可提供的内容时,这样做是可行的。因此,永远不要将不应该显示给最终用户的内容放在该 WAR 的根目录中。例如,不要将属性文件、类文件或其他重要信息放在那里。如果您必须将信息放在 WAR 中,则将其放在 WEB-INF 目录中,这在 Servlet 规范中是允许的。Web 容器永远不会提供那里的信息。

36. 定义缺省的错误处理程序
攻击代码

当 Web 应用程序中出现错误时,即使在该应用程序分派之前(例如 WebSphere Application Server 不能发现目标 Servlet),也会向用户显示错误消息。在缺省情况下,WebSphere Application Server 会显示该错误一个原始异常堆栈。这不仅对最终用户非常不友好,也暴露了应用程序的有关信息。类和方法的名称位于堆栈信息中。同时也显示异常消息;这个消息可能包含敏感信息。

最好是确保最终用户永远看不到原始错误消息。虽然您可以在每个单一的 Servlet 中确保始终捕获异常,但这并没有涵盖每种情况(正如我们前面所说的)。而是应该定义缺省的错误页面。一旦出现未处理的异常,就显示该缺省的错误页面。此页面可以是一个友好的错误消息,而不是堆栈跟踪。该缺省的错误页面是在 ibm-web-ext.xmi 中使用 defaultErrorPage 属性定义的。它也可以在 Rational Application Developer 中使用 Web Deployment Descriptor 编辑器(扩展选项卡)设置。

37. 考虑禁用文件服务和目录浏览
攻击代码

您可以通过禁用 Web 应用程序中的文件服务和目录浏览来进一步限制内容服务不适当的风险。明显地,如果 WAR 包含可服务的静态内容,则需要启用文件服务。

38. 启用会话安全性
攻击代码

WebSphere Application Server 通常不强制对 HTTP Session 访问进行任何授权。任何具有有效会话标识符的一方都可以访问任何会话。虽然会话标识符不可猜测,但也可能通过其他手段获得会话标识符。

要降低这种攻击形式的风险,您应该考虑启用会话安全性。这一设置是在 application server => <server name> => web container => session management 面板中配置的。选中标签为 security integration 的框。一旦选中它,WebSphere Application Server 将跟踪什么用户(通过它们提供的 LTPA 凭证来确定)拥有什么会话,并确保只有那个用户才能访问那个会话。

在极少数情况下,这种设置会中断 Web 应用程序。如果应用程序包含安全的(具有授权约束的)和不安全的 Servlet 的混合体,则不安全的 Servlet 将无法访问会话对象。一旦一个安全的 Servlet 访问该会话,则它会被标记为被该用户“拥有”。不安全的 Servlet(以匿名方式运行)如果试图访问这些页面,则会授权失败。

39. 注意自定义的 JMX 网络访问
攻击代码

JMX 和自定义 MBean 使得您的应用程序能够支持强大的远程自定义管理。请注意,JMX MBean 是可以通过网络访问的。如果您选择部署它们,要十分谨慎,以确保它们的操作具有合适的授权。WebSphere Application Server 会根据 MBean JAR 文件中的描述符中的信息,自动为 MBean 提供缺省的授权限制。这样是否合适取决于您的应用程序。有关更多信息,请参阅 IBM WebSphere:Advanced Deployment and Administration

基于应用程序的预防措施:设计和实现

现在我们将注意力转移到应用程序开发人员和设计人员要构建安全的应用程序必须采取的操作上。这些步骤是很关键的,但遗憾的是经常被忽视。

40. 使用 WebSphere Application Server 安全性来保护应用程序
攻击代码

应用程序开发组通常能认识到他们的应用程序需要某种程度的安全性。这通常是业务上的需求。遗憾的是,许多团队自己开发安全性基础设施。虽然也有可能做好,但是非常困难,而且大部分团队都不能成功。相反,他们的系统看似很安全,但实际上系统安全性非常脆弱。安全性是个很困难的问题。加密、重播攻击和其中各种形式的攻击中有各种细微问题容易被忽视。这里要说的是您应该使用 WebSphere Application Server 安全性,除非它真的不能满足您的要求。而这种情况非常少见。

也许关于 J2EE 定义的声明性安全模型的最常见的抱怨是它没有提供足够的粒度。例如,您可以只在 EJB 或 Servlet 的方法级上执行授权,而不必在实例级上执行授权。在此上下文中,Servlet 上的方法是一种 HTTP 方法:GET、POST、PUT 等等。再如,所有的银行账号都有相同的安全性限制,但是您更希望某些用户对其自己的账号拥有特殊权限。

这个问题可以通过 J2EE 安全性 API(isCallerInRole 和 getCallerPrincipal)来解决。通过使用这些 API,应用程序可以开发自己强大且灵活的授权规则,但是仍然要通过已知是准确的信息(来自 WebSphere Application Server 运行时的安全性属性)来驱动那些规则。

一个弱安全性的例子

这里是一个弱安全性系统的例子。不使用 WebSphere Application Server 安全性的应用程序倾向于创建自己的安全性令牌,并在应用程序内部传递。这些令牌通常包含用户名和一些安全性属性,比如它们的组成员关系。这些安全性令牌一般没有密码验证信息。这种方法假设您可以根据这些令牌中的信息做出安全性决策。这是错误的。该令牌仅仅断言用户的特权。

这里的问题是,任何 Java 程序都能够伪造这些安全性对象,并且可以通过后门侵入您的系统。最能说明问题的例子是,当应用程序在 Servlet 层创建这些令牌,然后将其传递到 EJB 层的时候。如果 EJB 层不安全(请参见下一部分),则入侵者可以使用伪造的凭证直接调用 EJB,使应用程序的安全性无效。因此,如果没有充实的工程计划,则唯一可靠的用户信息安全来源是 WebSphere Application Server 基础设施。(请注意,您可以将 WebSphere Application Server 安全性基础设施和其他身份验证或授权产品相集成。例如 Tivoli Access Manager 可以提供身份验证和授权支持。)

41. 保护应用程序的每个层(特别是 EJB 层)
攻击代码

我们常常将 Web 应用程序以一定程度的安全性(自制的或者基于 WebSphere Application Server)部署在 Servlet 层,但是对作为应用程序的一部分的其他层却不加保护。这样做是基于一个错误假设的:应用程序中只有 Servlet 需要保护,因为它们是应用程序的前门。但是,正如警察对您常说的那样,您也必须关上您家的后门和窗户。

有许多方法可以做到这一点,但是当 EJB 组件作为多层体系结构的一部分使用,而此时 Java 客户端不是应用程序的一部分时最容易出现这种疏忽。在这种情况下,开发人员常常认为 EJB 组件不需要保护,因为它们在应用程序设计中不是“用户可以访问的”,但这种想法是一个危险的错误。如果您不对 EJB 层实施保护,入侵者就可以绕过 Servlet 接口,直接进入 EJB 层并进行破坏。使用可用的 Java IDE 可以很容易做到这一点,它们能够检查运行中的 EJB、获取其元数据,以及动态创建测试客户端。Rational Application Developer 有这样的功能,并且如果开发人员使用集成的测试客户端,则会每天都看到这些。

通常,对此问题的第一反应就是通过一些平常的手段(或许通过将它们标记为可被所有已通过身份验证的用户访问)来保护 EJB。但是,根据注册表,“所有已通过身份验证的用户”可能是公司中的每个雇员。一些人更进一步地限制特定组中成员的访问权限,这个组大概指“可以访问此应用程序的任何人”。这样更好一些,但是通常还不够,因为不是能够访问应用程序的每个人都有必要执行应用程序中的所有操作。解决这个问题的正确方式是在 EJB 中实现授权检查。您也可以考虑将 EJB 实现为本地 EJB,使其不可能通过远程访问。

42. 不要依赖于 HTTP Session 跟踪用户身份
攻击代码

遗憾的是,一些使用自己的安全性的应用程序通过使用 HTTP Session 来跟踪用户的身份验证会话。这是非常危险的。该会话是通过一个会话 ID 跟踪的(在 URL 或者 cookie 中)。虽然该 ID 是随机生成的,但是它仍然受重播攻击的影响,因为它没有超时(除非处于空闲状态)。另一方面,LTPA 令牌(它是在应用程序使用 WebSphere Application Server 安全性时创建的)被设计为提供更强的身份验证令牌。特别是,LTPA 生存期有限,并且使用强加密。该安全性子系统对可能伪造的 LTPA 令牌的收据进行审核。

43. 检验所有用户输入
攻击代码

跨站点脚本是相当危险的攻击,它利用 Web 浏览器的灵活性和强大功能。大多数 Web 浏览器都可以解释各种脚本语言,例如 JavaScript。浏览器知道它正在根据一系列特殊的转义字符来执行一些可执行文件。这展现了 Web 浏览器安全性模型的强大和危险之处。

入侵者欺骗 Web 站点在浏览器中显示入侵者要该站点执行的脚本,通过这样来利用此漏洞。在允许任意用户输入的站点上这是很容易做到的。例如,如果一个站点包含一个表单来让用户输入地址,而用户可以在其中输入 JavaScript。当站点随后显示该地址时,Web 浏览器就会执行该脚本。那段脚本由于来自该站点,并在 Web 浏览器内部运行,所以可以访问安全信息,例如用户 cookie。

到此为止,这还看似没什么危险,但入侵者可以进一步执行此步骤。他们欺骗用户进入一个 Web 站点并输入“恶意脚本”,欺骗手段可以是通过 email 向用户发送无害的 URL。现在入侵者可以使用该用户的身份进行破坏了。有关更多信息,请参阅 Understanding Malicious Content Mitigation for Web Developers

这个问题实际上是与用户输入验证相关的一类更大问题的一个特例。只要您允许用户输入自由文本,您就必须确保该文本不会包含会造成破坏的特殊字符。例如,如果用户要输入一个字符串,用它来搜索某个索引,则必须过滤掉可能会造成越界搜索的不合适的通配符,这是很重要的。对于跨站点脚本预防情况,您需要过滤掉浏览器支持的脚本语言的转义字符。这里要说明的是对所有外部输入都应该采取怀疑态度并仔细进行验证。

44. 安全地存储信息
攻击代码

要创建安全的系统,您必须考虑在哪存储或显示信息。有时,一些相当严重的安全性漏洞是在无意中造成的。例如,对在 HTTP Session 对象中存储高度机密的信息要十分谨慎,因为此对象可能被序列化到数据库中。因此,该信息可以从那里读取。如果入侵者可以访问您的数据库,甚至是对数据库信息的原始计算机级访问,他或她都可能看到会话中的信息。毫无疑问,这样的攻击需要非常高的技能。

45. 审核和跟踪可以是敏感的
攻击代码

出于商业目的和调试目的,任何有价值的应用程序都将生成丰富的日志和跟踪信息。这是很好的。请注意,文件中的信息往往驻留在许多地方(可能位于您的公司外)。非常敏感的信息不应该进行跟踪,如果可以,也应该试图避免对其进行审核。例如,我们见过客户端将用户密码打印到跟踪文件中。如果该文件被错误的人阅读(可能是一个要帮助您的顾问),则就不适当地透漏了敏感信息。

我们强烈建议您对记录的内容加以限制,并检查记录哪些内容才是安全的。

46. 使空闲用户无效
攻击代码

在您使用完用户 HTTP Session 和身份验证会话的同时要使它们无效。这样做可以降低空闲会话被另一个用户窃取的可能性。它也可以为其他工作释放资源。

HTTP Session 是通过使用 HTTPSession.invalidate() 方法销毁的。WebSphere Application Server 身份验证会话信息是通过将用户定向到 ibm_security_logout URL 销毁的。详细信息请参阅 WebSphere Application Server Information Center。值得一提的是,消除浏览器中的 cookie 的大多数可靠方式只是退出 Web 浏览器。现在许多 Web 站点明确推荐这样做;也许您的 Web 站点也应该这样。请注意,关闭浏览器并没有删除任何服务器端状态——它将等待服务器端超时。如果您担心这一点,那么可以考虑通过 JavaScript 捕获浏览器关闭事件。


继续进入第 2 部分

这一文章系列接下来将介绍 WebSphere Application Server V6 高级安全性加强,第 2 部分:高级安全性注意事项

参考资料

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


这是您第一次登陆到 developerWorks,已经自动为您创建了您的概要文件。 选择您概要文件中可以公开的信息的信息(如姓名、国家/地区,以及公司),这些信息同时也会与您所发布的内容相关联。 您可以随时更新您的 IBM 账号。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=WebSphere
ArticleID=163396
ArticleTitle=IBM WebSphere 开发者技术期刊: WebSphere Application Server V6 高级安全性加强——第 1 部分
publish-date=02062006