tomcat5文档(SSL配置)-
时间:2006-12-11 来源:饮鸩止渴
1.快速上手
下面描述使用的变量$CATALINA_HOME指的是Tomcat 5的安装目录,大部分目录都基于它来解析。不过,如果你通过使用CATALINA_BASE目录来运行Tomcat 5的多个实例,则应该使用$CATALINA_BASE替代这些引用。
要在Tomcat 5上安装、配置SSL,请按以下步骤做,如果需要更多信息,请看文档的剩下部分。
1.如果你运行的是JVM 1.3,请从http://java.sun.com/products/jsse/下载JSSE 1.0.3(或更新版),然后扩展安装,或设置一个环境变量JSSE_HOME指向安装的目录。
2.执行下面的命令创建一个证书keystore:
Windows:
%JAVA_HOME%\bin\keytool -genkey -alias tomcat -keyalg RSA |
Unix:
$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA |
并指定密码:"changeit"。
3.取消$CATALINA_HOME/conf/server.xml中"SSL HTTP/1.1 Connector"的注释并做必要的调整。
2.SSL简介
SSL(Secure Socket Layer)是一种能让web浏览器和服务器在建立一个安全连接的基础上进行通信的技术。这意味着一端将数据加密后发送、传输,在另一端处理前解密。这是一个双向过程,服务端和客户端对所有要发出的数据都进行加密。
另一个重要的方面是鉴权。这意味着你的最初和web服务器的通信是建立在安全连接基础上的。服务器将给你的web浏览器一套证书形式的信任状,来证明这个站点是它所声称的那一个站点。在某种情况下服务器也会向你的浏览器请求一个证书,要求证明你是你所声称的那个人。这就是"客户身份认证",尽管在实际应用中是business-to-business交易而不是个人用户。大部分使用了SSL的web服务器不要求客户认证。
3.SSL和Tomcat
注意,只有当Tomcat以独立模式运行时,才通常需要利用安全sockets来配置它。当Tomcat主要是作为运行在其它web服务器(如Apache或Microsoft IIS)后的Servlet/JSP容器时,通常需要配置主web服务器来处理从用户来的SSL连接。典型的,这个服务器将处理所有SSL有关的功能,然后在解密那些请求后再把以Tomcat为目的的请求转发给Tomcat。同样的,Tomcat将返回没经过加密的响应,由主服务器加密后发给用户浏览器。在这种情况下,Tomcat知道主服务器和客户端的通信是建立在安全连接上的(因为你的应用需要能够知道这个),但本身不参与加密或解密。
4.证书(Certificates)
为了实现SSL,web服务器必须有一个针对每个接口(IP地址)的接受安全连接的相关证书。在这个设计背后的理论是服务器应该提供某种‘你觉得它的所有者是谁'的担保,特别是在接受任何敏感信息前。然而对证书更深的解释超过了本文档的范围,可以把证书看作一个对Internet地址的"digital driver's license"。它声明了这个站点是什么公司的和一些关于站点所有者或管理员的基本联系信息。
"driver's license"是被所有者加密签名的,因此对任何其它人来说,伪造都是极端困难的。对和电子商务或其它任何商业交易有关的网站来说,身份验证是一个重要问题。证书通常从一个著名的认证授权机构(Certificate Authority)比如VeriSign或Thawte处购买。CA将为它承认的证书担保,这些证书都能有效的被电子验证。因此如果你信任CA承认的证书,那么你就可以相信证书的有效性。
然而在很多情况下,身份鉴定不是真正所关心的。管理员可能只不过想确保连接中的服务器传输和接收的数据是秘密的且不被网上其它任何想偷听的人所窃听。幸运的是,Java提供了一个叫keytool的相对简单的命令行工具,它能方便的创建一个"自签名"的证书。自签名证书只是用户生成的证书,它不会被任何著名的CA所官方注册,因此并不是真正可信的担保。这对你来说可能重要也可能不,取决于你的需要。
5.运行SSL的小技巧
当一个用户第一次访问你的网站的安全页面时,通常会给他一个包含证书详细信息(比如公司和联系名称)的对话框,并问他是否原意接受证书有效且继续交易。一些浏览器会提供一个永久接受该证书的选项,这样用户就不必为每次访问你的网站被提示而烦恼了。一旦被用户认可,证书将在整个浏览器的会话期间内被认为有效。
虽然SSL协议被设计为有足够有效的安全性,但加密/解密从性能上考虑是一个昂贵的计算处理。并不是整个web应用都必需严格的在SSL上运行,开发者能够挑选哪些页面需要安全连接,哪些不需要。对一个适度繁忙的站点,仅仅将某些可能交换敏感信息的页面运行在SSL下是一种惯例。这通常包括登录页面、个人信息页面和购物车检查页面(信用卡信息可能会被发送)。一个应用里的任何页面都可以通过一个安全socket请求,只要在地址前用前缀"https:"替代"http:"。任何完全要求安全连接的页面应该检查和请求的协议类型,并采取https没有指定的适当的动作。
在安全连接上使用基于名字的虚拟主机会有问题,这是SSL协议本身的设计局限。SSL的握手,就是客户浏览器接受服务器证书的过程,必须发生在HTTP请求达到之前。结果,包含性能主机名的请求信息不能在认证前确定,因此不可能分配多个证书给一个IP地址。如果在一个IP上的所有虚拟主机都需要依靠相同的证书鉴别,那么附加的虚拟主机不应干扰服务器上SSL的正常操作。然而,大部分客户浏览器会依靠证书的域名列表比较服务器的域名(即便是正式的、CA签名的证书)。如果域名不匹配,则浏览器会向用户显示一条警告。通常,只有基于地址的虚拟主机普遍在正式场合下使用SSL。
6.配置
6.1下载并安装JSSE
从http://java.sun.com/products/jsse/上下载版本1.0.3以上的Java Secure Socket Extensions (JSSE)包。如果你是从源代码安装的Tomcat,那么可能已经下载了这个包。如果你运行的是JDK 1.4.x,这些类已经直接集成到JDK中了,可以跳过这一步。
解压后,有两种方法让它对Tomcat可用(选择一种):
1.通过复制三个JAR文件(jcert.jar、jnet.jar和jsse.jar)到$JAVA_HOME/jre/lib/ext目录将JSSE作为扩展安装。
2.创建一个新的环境变量JSSE_HOME,将其指向你解压的JSSE目录的绝对路径。
6.2准备证书Keystore
Tomcat通常只在JKS或PKCS12格式的keystores上执行。JKS是Java的标准"Java KeyStore"格式,并且是命令行工具创建的格式,此工具在JDK中。PKCS12是一个internet标准,且能够通过OpenSSL和Microsoft's Key-Manager操纵。不过通常对PKCS12的支持有些限制。
要导入一个存在的证书到JKS keystore,请阅读关于keytool的文档(在JDK文档包中)。
要导入一个存在的被你自己的CA签名的证书到使用OpenSSL的PKCS12 keystore,要执行一条象下面这样的命令:
openssl pkcs12 -export -infile mycert.crt -inkey mykey.key \ -outfile mycert.p12 -name tomcat -CAfile myCA.crt \ -caname root -chain |
需要更多高级用法,请参考OpenSSL文档。
要创建一个临时的,包含单独的自签名的证书,在终端上执行下面的命令:
Windows:
%JAVA_HOME%\bin\keytool -genkey -alias tomcat -keyalg RSA |
Unix:
$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA |
(RSA算法是首选的安全算法,并且确保了和其它服务器、组件的兼容性。)
此命令将在你运行的目录下创建一个新文件,文件名为".keystore"。要指定文件的地址,在-keystore参数后跟文件的全路径。你需要在后面描述的server.xml配置文件中反映出这一变化。例:
Windows:
%JAVA_HOME%\bin\keytool -genkey -alias tomcat -keyalg RSA \ -keystore \path\to\my\keystore |
Unix:
$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA \ -keystore /path/to/my/keystore |
执行此命令后,会提示你输入keystore的密码。Tomcat使用的缺省密码是"changeit"(全小写),你也可以自己指定。同时也需要在后面描述的server.xml中指定自定义的密码。
接下来会提示你关于此证书的说明,比如公司、联系名等等。此信息会显示给要访问你的安全页面的用户,因此请确保此处提供的信息和用户期望的匹配。
最后,会提示你输入key password,这个password是这个证书特有的(区别于任何其它存储在同一个keystore文件中的证书)。你必须使用和keystore相同的密码。(通常keytool的提示会告诉你直接回车会自动完成此项。)
如果所有的都完成了,你现在就有一个能给服务器使用的包含证书的keystore文件了。
6.3编辑Tomcat配置文件
最后一步是在$CATALINA_HOME/conf/server.xml中配置你的secure socket。在安装好的Tomcat里缺省server.xml中已经包含了一个SSL connector的元素样本。看起来如下:
<-- Define a SSL Coyote HTTP/1.1 Connector on port 8443 --> |
你会注意到Connector元素缺省被注释了,因此你需要删除它周围的注释标签。接着你可以自定义一些属性。要更多各种选项的信息,请参考Server Configuration Reference。下面的讨论只覆盖建立SSL通信时最感兴趣的那些属性。
port属性(缺省为8443)是Tomcat监听安全连接的TCP/IP端口号。你可以将它改成任何你需要的端口号(如https通信的缺省端口443)。然而在许多操作系统上,Tomcat要使用一个1024以下的端口需要做一些特别的设置(这不在本文档范围内)。
如果改变了此处的端口号,应该同时改变在non-SSL connector上redirectPort属性的值。作为Servlet 2.4 Specification中所必需的,这允许Tomcat自动重定向用户访问有安全限制的页面的请求,指出需要SSL。
还有一些其它的选项配置SSL协议。你可能需要增加或改变下面的属性值,取决于你开始对keystore的配置:
clientAuth |
如果想要Tomcat为了使用这个socket而要求所有SSL客户出示一个客户证书,置该值为true。 |
keystoreFile |
如果创建的keystore文件不在Tomcat认为的缺省位置(一个在Tomcat运行的home目录下的叫.keystore的文件),则加上该属性。可以指定一个绝对路径或依赖$CATALINA_BASE环境变量的相对路径。 |
keystorePass |
如果使用了一个与Tomcat预期不同的keystore(和证书)密码(changeit),则加入该属性。 |
keystoreType |
如果使用了一个PKCS12 keystore,加入该属性。有效值是JKS和PKCS12。 |
sslProtocol |
socket使用的加密/解密协议。如果使用的是Sun的JVM,则不建议改变这个值。据说IBM的1.4.1版的TLS协议的实现和一些流行的浏览器不兼容。这种情况下,使用SSL。 |
ciphers |
此socket允许使用的被逗号分隔的密码列表。缺省情况下,可以使用任何可用的密码。 |
algorithm |
使用的X509算法。缺省为Sun的实现(SunX509)。对于IBM JVMS应该使用ibmX509。对于其它JVM,参考JVM文档取正确的值。 |
truststoreFile |
用来验证客户证书的TrustStore文件。 |
truststorePass |
访问TrustStore使用的密码。缺省值是keystorePass。 |
truststoreType |
如果使用一个不同于正在使用的KeyStore的TrustStore格式,加入该属性。有效值是JKS和PKCS12。 |
完成这些配置后,要重启Tomcat。你将能通过访问任何Tomcat支持的web应用。如:
如果创建的keystore文件不在Tomcat认为的缺省位置(一个在Tomcat运行的home目录下的叫.keystore的文件),则加上该属性。可以指定一个绝对路径或依赖$CATALINA_BASE环境变量的相对路径。 |
|
keystorePass |
如果使用了一个与Tomcat预期不同的keystore(和证书)密码(changeit),则加入该属性。 |
keystoreType |
如果使用了一个PKCS12 keystore,加入该属性。有效值是JKS和PKCS12。 |
sslProtocol |
socket使用的加密/解密协议。如果使用的是Sun的JVM,则不建议改变这个值。据说IBM的1.4.1版的TLS协议的实现和一些流行的浏览器不兼容。这种情况下,使用SSL。 |
ciphers |
此socket允许使用的被逗号分隔的密码列表。缺省情况下,可以使用任何可用的密码。 |
algorithm |
使用的X509算法。缺省为Sun的实现(SunX509)。对于IBM JVMS应该使用ibmX509。对于其它JVM,参考JVM文档取正确的值。 |
truststoreFile |
用来验证客户证书的TrustStore文件。 |
truststorePass |
访问TrustStore使用的密码。缺省值是keystorePass。 |
truststoreType |
如果使用一个不同于正在使用的KeyStore的TrustStore格式,加入该属性。有效值是JKS和PKCS12。 |
https://localhost:8443 |
现在你应该看到通常的Tomcat的splash页面(除非你修改了ROOT web应用)。如果没有看到,下面的节有一些解决问题的技巧。
7.从一个CA安装一个证书
为了从一个CA(如:verisign.com,thawte.com或trustcenter.de)获得并安装一个证书,应该已经阅读过前面的小节,现在跟随下面的指导:
7.1创建一个本地Certificate Signing Request (CSR)
为了从你选择的CA获得一个证书,应该先创建一个所谓的Certificate Signing Request (CSR)。CSR将被CA用来创建一个证明你的站点安全的证书。要创建CSR,遵循下面的步骤:
创建一个本地证书:
keytool -genkey -alias tomcat -keyalg RSA -keystore |
注意:在一些情况下,为了创建一个运转的证书,你必须在字段"first- and lastname"中输入你的网站的域名(如:www.myside.org)。
然后创建CSR:
keytool -certreq -keyalg RSA -alias tomcat -file certreq.csr -keystore |
现在,你有了一个叫certreq.csr的文件,你可以将它提交到CA(参考CA网站上的文档怎样做)。然后就得到了证书。
7.2导入证书
现在,你有了自己的证书,你可以将它导入到本地keystore。首先,必须导入一个所谓的Chain Certificate或Root Certificate到你的keystore。然后你可以继续导入你的证书。
7.2.1从你获得证书的CA下载Chain Certificate:
对于Verisign.com,去http://www.verisign.com/support/install/intermediate.html
对于Trustcenter.de,去http://www.trustcenter.de/certservices/cacerts/en/en.htm#server
对于Thawte.com,去http://www.thawte.com/certs/trustmap.html
7.2.2将Chain Certificate导入到keystore:
keytool -import -alias root -keystore \ -trustcacerts -file |
7.2.3最后,导入你的新证书:
keytool -import -alias tomcat -keystore \ -trustcacerts -file |
8.解决问题
这里有一个安装SSL时常见的问题列表,和它们的解决方法:
1.在日志文件中出现"java.security.NoSuchAlgorithmException"的错误。
JVM没找到JSSE JAR文件。请照"下载和安装JSSE"节的指导做。
2.Tomcat启动时,出现"java.io.FileNotFoundException: {some-directory}/{some-file} not found"的错误。
一个可能的解释是Tomcat没有找到keystore文件。缺省的,Tomcat认为该文件在Tomcat运行的home目录下,名为 .keystore。如果该文件在其它地方,则需要在Factory元素中加入keystoreFile属性。
3.Tomcat启动时出现"java.io.FileNotFoundException: Keystore was tampered with, or password was incorrect"的错误。
假设确实没人篡改过keystore文件,最大的可能是Tomcat使用了一个和创建keystore文件时不同的密码。要修正它,可以重新创建keystore文件或在Factory中加入keystorePass属性。记住:密码是区分大小写的。
如果仍然有问题,可求助TOMCAT-USER邮件列表。通过列表,可以在以前的消息中得到指示,在http://jakarta.apache.org/site/mail.html处订阅或取消订阅。