本文讲述在Tomcat中配置SSL的支持。
1. 在Tomcat中配置对SSL的支持还是比较容易的。大概分为这么几步:
(1) 如果JVM的版本低于1.3,那么需要下载JSSE,这是JAVA对SSL的支持库。从JDK 1.4开始,JSSE已经被内置进JDK。所以象现在的话,这个步骤就可以省略了。
(2) 执行命令(Linux系统下):
$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA
windows下也是一样,就是路径要用正的斜杠。
通过这个命令,会在当前用户的主目录下生成一个名为.keystore的文件,这就是Tomcat做SSL的时候用的CA证书文件。在执行上面命令的时候,要输入一些信息,比如公司名称,单位名称等,照实输入即可。关键是要输入两个密码,第一个密码在一开始就要求输入,Tomcat会利用这个密码来对传输的信息进行加密,Tomcat默认会认为这个密码是"changeit',我们可以不设成这个密码,不设置成这个密码的话,等会在server.xml中配置SSL的时候就要求配置我们设置的密码;第二个会询问的密码叫做private keystore password,这个密码是用来加密证书本身的,也就是该证书和其他证书区分的一个密码。这里千万注意,Tomcat告知说这个密码必需要和第一个密码完全相同,否则Tomcat会报错误。所以在输入第二个密码的时候直接按回车即可,就设成和第一个密码一样了。
(3) 配置server.xml中有关SSL的那段connector,默认情况下,这个connector的配置是被注释掉的,将注释打开,然后我这边的配置如下:
1. 在Tomcat中配置对SSL的支持还是比较容易的。大概分为这么几步:
(1) 如果JVM的版本低于1.3,那么需要下载JSSE,这是JAVA对SSL的支持库。从JDK 1.4开始,JSSE已经被内置进JDK。所以象现在的话,这个步骤就可以省略了。
(2) 执行命令(Linux系统下):
$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA
windows下也是一样,就是路径要用正的斜杠。
通过这个命令,会在当前用户的主目录下生成一个名为.keystore的文件,这就是Tomcat做SSL的时候用的CA证书文件。在执行上面命令的时候,要输入一些信息,比如公司名称,单位名称等,照实输入即可。关键是要输入两个密码,第一个密码在一开始就要求输入,Tomcat会利用这个密码来对传输的信息进行加密,Tomcat默认会认为这个密码是"changeit',我们可以不设成这个密码,不设置成这个密码的话,等会在server.xml中配置SSL的时候就要求配置我们设置的密码;第二个会询问的密码叫做private keystore password,这个密码是用来加密证书本身的,也就是该证书和其他证书区分的一个密码。这里千万注意,Tomcat告知说这个密码必需要和第一个密码完全相同,否则Tomcat会报错误。所以在输入第二个密码的时候直接按回车即可,就设成和第一个密码一样了。
(3) 配置server.xml中有关SSL的那段connector,默认情况下,这个connector的配置是被注释掉的,将注释打开,然后我这边的配置如下:
<!--
Define a SSL HTTP/1.1 Connector on port 443
-->
< Connector port ="443" maxHttpHeaderSize ="8192"
maxThreads ="150" minSpareThreads ="25" maxSpareThreads ="75"
enableLookups ="false" disableUploadTimeout ="true"
acceptCount ="100" scheme ="https" secure ="true"
clientAuth ="false" keystorePass ="jofoeasycluster" sslProtocol ="TLS" />
< Connector port ="443" maxHttpHeaderSize ="8192"
maxThreads ="150" minSpareThreads ="25" maxSpareThreads ="75"
enableLookups ="false" disableUploadTimeout ="true"
acceptCount ="100" scheme ="https" secure ="true"
clientAuth ="false" keystorePass ="jofoeasycluster" sslProtocol ="TLS" />
从上面这段配置可以看出,首先我把SSL的端口改成了标准的443,tomcat默认的是8443(因为1024以前的端口非root用户不能用,而我们的EC下,tomcat肯定是root用户启动的),这样用户就直接输入https://xxx.xxx.xxx.xxx/easycluster就可以访问到EC了,不需要再加入端口了;其次,我加入了keystorePass="jofoeasycluster",这就是我在生成.keystore文件的时候输入的密码。这里还有一些其他的常用配置,都列在了本文档中,参考 附件1 的表格。比如如果我们没有把.keystore文件放到启动tomcat的那个用户的用户主目录下,需要设置keystoreFile attribute。包括还有象clientAuth的取值,这里设成了false,就是说不需要client提供证书,只需要client接受我们的证书就OK了,等等。
这样就设置完成了,而且在我的tomcat配置中,我将非SSL的原来工作于8080端口的connector注释掉了,这样用户就无法访问非SSL的EC了。在tomcat中,可以定义多个connector,tomcat本身就有好多个connector,有做SSL的,有普通的,还有工作于8009端口的connector,用来做AJP,等等。
通过上面的配置,我们的EasyCluster无需改动任何代码,就可以run在SSL上了。这样做的缺点是:由于基于SSL方式的http,在传输数据的时候,都需要server端加密,然后传送给客户端,客户端再解密,这样对server来说,负载较重,因为SSL的加密算法计算量还是比较密集的。所以常见的做法是,整个web应用中,不是每个页面都使用SSL,只在一些涉及到敏感数据的页面设置SSL的访问方式。
但是对于EC来说,这种方式有点问题,因为EC是基于struts的,所以,所有的链接和form表单的提交,采用的都是struts的机制,也就是我们不需要写全完整的URL,只要给出相对地址就可以了,这样就没有机会让我们在代码中手动设置这个link是http的还是https的。
关于这个问题,专门有一个Struts的extension来做这个事情,在google中search "struts ssl"就可以找到,这也是Struts官方推荐的做法。这个extension会增加和修改一些tld,增加一些class,安装了这个extension之后,我们就可以在标签库和Action的config的时候,加入一个secure=true/false的配置,从而来指定该action/link走https还是http。
但是对于EC来说,这种方式有点问题,因为EC是基于struts的,所以,所有的链接和form表单的提交,采用的都是struts的机制,也就是我们不需要写全完整的URL,只要给出相对地址就可以了,这样就没有机会让我们在代码中手动设置这个link是http的还是https的。
关于这个问题,专门有一个Struts的extension来做这个事情,在google中search "struts ssl"就可以找到,这也是Struts官方推荐的做法。这个extension会增加和修改一些tld,增加一些class,安装了这个extension之后,我们就可以在标签库和Action的config的时候,加入一个secure=true/false的配置,从而来指定该action/link走https还是http。
目前我们暂不考虑上面的extension,因为对于EC来说,本身的访问量就不会很大,而且基本上高性能计算的服务器计算能力都很强,所以暂不考虑了。但要记住,是有解决方案的。
OK,通过上面的描述,我们已经可以让tomcat跑在SSL上,但是本文档还非常好的介绍了一些SSL的背景知识,我认为非常有价值,所以这里也做了笔记,理解这些背景知识对于理解上面的一些配置项也是非常有好处的。
1. SSL introduction. 我们都知道SSL最常见的用途就是对传输数据的加密。不管是server端还是client端,跑在SSL上的时候,任何数据的收发都有着解密/加密的过程,这样保证了数据传输的安全。不过更重要的是,SSL还有一个认证(Authentication)的功能。具体来说,当我们请求一个secure connection的时候,server会首先给我们的浏览器发送一个Certificate(证书),通过这个证书,我们可以很明确的知道这个网站的owner和一些相关信息,从而让客户端可以知道自己正在访问的网站是不是我们所期望的;其次,在某些时候,server也可能要求client端提供一个证书,来证明client的身份,这样的功能对于那些B2B的网站来说,很重要,因为无论是client还是server,都需要清楚的知道对方的身份,这就叫做"Client Authentication"。也就是在上面的配置中,clientAuth=true/false/want这些值的原因。当然了,一般情况下,大部分的server都不会要求客户端提供证书,因为我们需要的只是一个加密的数据传输通道,不需要对client也做验证。
2. 一个server要能具备SSL的能力,必须具备一个证书,也就是上面提到的给客户端看的一个证书。本文中将这个证书解释为"digital driver's license"。而且整个证书必须安全,权威,很难让人破解(否则不法分子就可以伪造该证书了)。于是,从正规的角度来说,一个商业的SSL server要从一些第三方的机构(Certificate Authority, CA)来购买一个证书,CA保证该证书的安全性和可靠性,那么,只要client信任CA,就可以信任该证书。有名的CA有VeriSign, Thawte等。但是,对于我们来说,这显然是没有必要的,因为我们对安全的要求没那么高,所以,就有了象keytool这样的工具,这样的工具能让我们自己生成一个证书(self-signed Certificate),虽然这种证书没有CA颁布的那些证书来的安全和可靠,但也够用了。OK,当我们使用了这样的证书之后,就能解释为什么我们在访问一些SSL的网站的时候,IE会弹出一个窗口说该证书未经验证,可能有风险这样的对话框了,因为这个证书不是来自CA的,是我们自己self-signed的。如果我们信任该证书的话,那么,只要该IE窗口不关闭,以后的操作就不会再弹出这样的框,但是一旦关闭了IE,再重开IE访问这个网站,这个框就又会弹出来。为此,IE也提供了保存证书的功能,如果我们将这个证书保存到了本地,那么,以后访问该网站就再也不会弹出这样的框了。当然,有些浏览器不提供保存证书的功能,那么就每次都会有这种框弹出来了。
3. 我们使用jdk提供的keytool生成的keystore叫做JKS型证书,这是JAVA自己做的。除此以外,还有PKCS11,PKCS12格式的keystores。这些格式的证书要使用象openssl,Microsoft key manager这样的软件来生成。
4. 本文的后半部分解说了如何安装一个来自CA的证书,并配置tomcat来使用这样的证书。有需要的话可以来参考,不错的。
5. 在上面的配置中,我们在使用keytool生成证书的时候,有一个选项叫-alias tomcat,这是给证书加一个别名,用来区分多个证书。这个名为tomcat的alias也是tomcat的默认值,也就是说,tomcat会默认认为他找到的证书的alias是tomcat,如果我们修改了这个别名,那么,别忘记在tomcat的server.xml中做配置。
6. 如果我们在tomcat中配置SSL的时候,修改了默认端口号(8443),那么别忘记同时修改非SSL的connector中的redirectPort attribute的值,这个redirectPort表示的就是当从Non-SSL的连接转向SSL连接的时候,使用的端口号。当然了,在上面的配置中,我们将Non-SSL的Connector注释掉了,呵呵。
7. 本文的最后有一个Troubleshooting,在配置tomcat over ssl的时候碰到问题,不妨到这里找找看有没有答案。
8. 本文的最后给出了一个有用的东西,就是在SSL的时候,如何获取session id,方法和非SSL的时候有点不一样,代码应该这样写:
String sslID = (String)request.getAttribute("javax.servlet.request.ssl_session");
1. SSL introduction. 我们都知道SSL最常见的用途就是对传输数据的加密。不管是server端还是client端,跑在SSL上的时候,任何数据的收发都有着解密/加密的过程,这样保证了数据传输的安全。不过更重要的是,SSL还有一个认证(Authentication)的功能。具体来说,当我们请求一个secure connection的时候,server会首先给我们的浏览器发送一个Certificate(证书),通过这个证书,我们可以很明确的知道这个网站的owner和一些相关信息,从而让客户端可以知道自己正在访问的网站是不是我们所期望的;其次,在某些时候,server也可能要求client端提供一个证书,来证明client的身份,这样的功能对于那些B2B的网站来说,很重要,因为无论是client还是server,都需要清楚的知道对方的身份,这就叫做"Client Authentication"。也就是在上面的配置中,clientAuth=true/false/want这些值的原因。当然了,一般情况下,大部分的server都不会要求客户端提供证书,因为我们需要的只是一个加密的数据传输通道,不需要对client也做验证。
2. 一个server要能具备SSL的能力,必须具备一个证书,也就是上面提到的给客户端看的一个证书。本文中将这个证书解释为"digital driver's license"。而且整个证书必须安全,权威,很难让人破解(否则不法分子就可以伪造该证书了)。于是,从正规的角度来说,一个商业的SSL server要从一些第三方的机构(Certificate Authority, CA)来购买一个证书,CA保证该证书的安全性和可靠性,那么,只要client信任CA,就可以信任该证书。有名的CA有VeriSign, Thawte等。但是,对于我们来说,这显然是没有必要的,因为我们对安全的要求没那么高,所以,就有了象keytool这样的工具,这样的工具能让我们自己生成一个证书(self-signed Certificate),虽然这种证书没有CA颁布的那些证书来的安全和可靠,但也够用了。OK,当我们使用了这样的证书之后,就能解释为什么我们在访问一些SSL的网站的时候,IE会弹出一个窗口说该证书未经验证,可能有风险这样的对话框了,因为这个证书不是来自CA的,是我们自己self-signed的。如果我们信任该证书的话,那么,只要该IE窗口不关闭,以后的操作就不会再弹出这样的框,但是一旦关闭了IE,再重开IE访问这个网站,这个框就又会弹出来。为此,IE也提供了保存证书的功能,如果我们将这个证书保存到了本地,那么,以后访问该网站就再也不会弹出这样的框了。当然,有些浏览器不提供保存证书的功能,那么就每次都会有这种框弹出来了。
3. 我们使用jdk提供的keytool生成的keystore叫做JKS型证书,这是JAVA自己做的。除此以外,还有PKCS11,PKCS12格式的keystores。这些格式的证书要使用象openssl,Microsoft key manager这样的软件来生成。
4. 本文的后半部分解说了如何安装一个来自CA的证书,并配置tomcat来使用这样的证书。有需要的话可以来参考,不错的。
5. 在上面的配置中,我们在使用keytool生成证书的时候,有一个选项叫-alias tomcat,这是给证书加一个别名,用来区分多个证书。这个名为tomcat的alias也是tomcat的默认值,也就是说,tomcat会默认认为他找到的证书的alias是tomcat,如果我们修改了这个别名,那么,别忘记在tomcat的server.xml中做配置。
6. 如果我们在tomcat中配置SSL的时候,修改了默认端口号(8443),那么别忘记同时修改非SSL的connector中的redirectPort attribute的值,这个redirectPort表示的就是当从Non-SSL的连接转向SSL连接的时候,使用的端口号。当然了,在上面的配置中,我们将Non-SSL的Connector注释掉了,呵呵。
7. 本文的最后有一个Troubleshooting,在配置tomcat over ssl的时候碰到问题,不妨到这里找找看有没有答案。
8. 本文的最后给出了一个有用的东西,就是在SSL的时候,如何获取session id,方法和非SSL的时候有点不一样,代码应该这样写:
String sslID = (String)request.getAttribute("javax.servlet.request.ssl_session");
有问题再回来读这篇文档吧,写的不错。