环境:编译 Windows 7 Enterprise,Visual Studio 2008,CPU i5-4310 测试:Windows Server 2012 R2,CPU Xeon L5640
Tomcat-7.0.57 tomecat-native-1.1.33 apr-1.5.2 openssl-fips-2.0.10 openssl-1.0.2
除Tomcat以外,所有组件都需要下载源文件,自己编译。过程非常痛苦,Apache官方没有具体的文档,说明也并不清晰,需要一点一点摸索,所以做一下记录。
- 搭建好JAVA环境,perl编译环境,C的编译用的是Visual Studio 2008,需要在装的时候手动选择X64组件。
- 编译openssl-fips。结合https://wiki.openssl.org/index.php/Compilation_and_Installation和https://www.openssl.org/docs/fips/UserGuide-2.0.pdf第50页,使用VS组件Visual Studio 2008 x64 Win64 Command Prompt。
cd c:\myPath\openssl-fips
ms\do_fips [no-asm]
cd c:\myPath\openssl
perl Configure VCWIN64A fips withfipsdir=C:\myPath\openssl-fips
ms\do_nasm
nmake -f ms\ntdll.mak
全部运行完成,如果不报错,到openssl的out32dll的目录下运行openssl version
,出现类似OpenSSL 1.0.2e-fips-dev
输出,文件夹中存在libeay32.dll和ssleay32.dll两个文件,说明编译成功了。
3. 编译apr。下载源码解压,去掉版本号把所有内容复制到tomcat-native\jni\apr。用VS打开,发现里面一共有六个子项目,右键Solution,Property页里有Configuration Properties,初始状态每个子项目的Configuration都是Debug,Platform都是Win32,如果在安装VS的时候选择了X64组件,那么Platform里可以选择x64,Configuration选择Release,确定。需要注意的是,不知道是我的VS有bug还是什么问题,每次打开项目,有很大比例这里的配置会丢掉,需要重新手动配置。
对于dll项目(这里只有libapr),右键项目名-Property-Configuration Properties-Linker-Debugging-Generate Debug Info设置成No。然后点击整个solution来build就可以,顺序已经定义好了。
编译不报错,查看include文件夹下apr.h文件的修改时间是现在,基本编译就没有问题了。
4. 编译tomcat-native。首先,和第3步一样,修改编译环境和Debug配置。如果直接编译的话,会发现缺少很多源文件。右键tcnative项目-Property-Configuration Properties-C/C++-Additional Include Directories里有依赖项的配置。
为了结构不会太乱,我们使用./srclib文件夹,把第3步apr项目下include文件夹的所有文件拷到srclib/apr/include文件夹下,把openssl的inc32下openssl文件夹拷到和include平行的位置,即srclib/apr/openssl。这里有点confusing的是最后一行有一个openssl的文件夹,但事实证明把文件拷到那里依然找不到。
然后检查Configuration Properties-Linker-Input-Additional Dependencies里配置了第2步生成的两个dll文件libeay32.dll和ssleay32.dll,可以把地址改成绝对地址,也可以把这两个文件拷贝到项目根目录中,只要VS可以找到他们就可以。
到这里,就可以点build了,等到所有项目编译完成,检查LibR文件夹下有tcnative-1.dll,编译阶段就算完成了。
5. 到运行环境中,配置好tomcat,确保在没有做任何改动的情况下tomcat可以正常启动,包括http和https,以免之后做了改动分不清到底哪个阶段出了错。配置TLS的过程可以参考http://www.chesterproductions.net.nz/blogs/it/code/configuring-client-certificate-authentication-with-tomcat-and-java/537/,说的非常详细清晰。把第4步编译好的tcnative-1.dll和第2步编译的libeay32.dll和ssleay32.dll放到同一个文件夹,把这个文件夹地址加入PATH环境变量,或者在tomcat\bin下建一个setenv.bat文件,加入以下内容
set PATH=%PATH%;your\path
tomcat\conf\server.xml里加入
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on"/>
<Listener className="org.apache.catalina.core.AprLifecycleListener" FIPSMode="on"/>
运行tomcat,如果没有报错,且打印出INFO: Successfully entered FIPS mode
说明配置成功。
Apache对于tomcat native-apr的说明语焉不详https://tomcat.apache.org/tomcat-7.0-doc/apr.html,对于tomcat和openssl的编译说明甚至有误http://tomcat.apache.org/native-doc/,至今没懂把libeay32.dll和ssleay32.dll重命名成libeayMT32.dll和ssleay32MT.dll到底是什么用意,不论是源码还是其它地方都没有找到libeay32MT的引用。编译tcnative的时候要求引入这两个dll,但在编译生成的tcnative-1.dll中,并没有包含这两个dll的内容,导致直接复制tcnative-1.dll到生产环境后,tomcat永远会报The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path:
但没有任何说明,甚至从源代码里都找不到是缺了什么。使用Dependency Walker解包自己编译的tcnative-1.dll和官方提供的不支持FIPS的二进制tcnative-1.dll后发现,前者实际上缺少了openssl的两个dll包。
折腾了半个多月,终于把这个东西配出来了,看到那句Successfully entered FIPS mode的时候真的蛮激动的,网上想找这方面的资料实在是太少,一方面很少有人在Windows上配置这些,另一方面可能需要支持FIPS的需求也确实不多,谁让用户需求呢,摊手┑( ̄Д  ̄)┍。