LoginSignup
5
3

More than 5 years have passed since last update.

Apache Portable Runtime(APR) を導入してtomcatでOpenSSLエンジンを試す。

Last updated at Posted at 2018-10-07

背景

  • 今までtomcatでSSLといえば、JavaネイティブのJSSEで実装されたコネクタ(Http11NioProtocol)を使い、キーはJKS(Java Key Store)で管理するのが一般的だったと思う。
  • OpenSSLでキー、証明書を管理するのが一般的なケースが多く、PEM形式のキー、証明書をどうのように組み込みか?毎回悩んでしまう。
  • tomcatも進化し、pem形式への対応は行われている。
  • さらにAPRは、openSSLをエンジンとしてそのまま利用でき、スケーラビリティ、パフォーマンス、管理面で優位であると言われる。
  • HTTP2を利用するには、Java8のTLS実装ではALPNをサポートしておらず、OpenSSLのTLS実装を使うしか方法はない。 server.xml内のコメントに以下の記述あり
    
    Because Java 8's TLS implementation does not support ALPN (which is required for 
    HTTP/2 oves TLS), 
    you must be using an OpenSSL based TLS implementation to enable HTTP/2 support. 
    See the sslImplementationName attribute of the Connector. 
    
  • JavaはPSK未実装のためPSKを利用する場合は、APRコネクタ + OpenSSLエンジン一択。opensslはPSK対応。
    
    $ openssl ciphers -v PSK 
    PSK-AES256-CBC-SHA      SSLv3 Kx=PSK      Au=PSK  Enc=AES(256)  Mac=SHA1 
    PSK-AES128-CBC-SHA      SSLv3 Kx=PSK      Au=PSK  Enc=AES(128)  Mac=SHA1 
    PSK-RC4-SHA             SSLv3 Kx=PSK      Au=PSK  Enc=RC4(128)  Mac=SHA1 
    PSK-3DES-EDE-CBC-SHA    SSLv3 Kx=PSK      Au=PSK  Enc=3DES(168) Mac=SHA1 
    

tomcatでのPEM形式証明書でのSSL構成として以下の3つが考えられる。APRを利用した構成(2.3.)について導入、設定を確認する。

  1. JSSE + PEM
  2. APR + OpenSSL + PEM
  3. APR + OpenSSL + ALPN(HTTP2) + PEM

APRを導入する

  1. libapr1-devパッケージのインストール

    
    root@v_ubuntu_64:/# apt list libapr1-dev 
    Listing... Done 
    libapr1-dev/bionic 1.6.3-2 amd64 
    root@v_ubuntu_64:/# apt install libapr1-dev 
    
  2. libssl-devパッケージのインストール

    
    root@v_ubuntu_64:/# apt list libssl-dev 
    Listing... Done 
    libssl-dev/bionic-updates,bionic-security 1.1.0g-2ubuntu4.1 amd64 
    N: There is 1 additional version. Please use the '-a' switch to see it 
    root@v_ubuntu_64:/# apt install libssl-dev 
    
  3. gcc/makeのインストール(確認) ※私のubuntu初期環境ではinstall済みでした

    
    root@v_ubuntu_64:/# apt list gcc 
    Listing... Done 
    gcc/bionic,now 4:7.3.0-3ubuntu2 amd64 [installed] 
    root@v_ubuntu_64:/# apt list make 
    Listing... Done 
    make/bionic,now 4.1-9.1ubuntu1 amd64 [installed] 
    
  4. APRコンポーネントのビルド、インストール
    4.1. APRコンポーネントはtomcat-native.tar.gzにパッケージされていますが、"apt install tomcat8"では、インストールされていないので、別途、ここからダウンロード
    4.2. ビルド作業ディレクトリで展開

    
     # cd /home/tetsuohino/tomcat-apr-build/apache-tomcat-8.5.34/bin 
     # tar zxvf tomcat-native.tar.gz
    

4.3. 環境変数JAVA_HOMEの設定
      * JRE_HOMEではなくJDK_HOMEを指定する
      * 私のubuntu環境ではJREしかインストールされていなかったため、JDKをインストールし直しています。
 


 # export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 

4.4. configure

 # cd tomcat-native-1.2.17-src/native 
 # .configure
checking build system type... x86_64-pc-linux-gnu 
checking host system type... x86_64-pc-linux-gnu 
checking target system type... x86_64-pc-linux-gnu 
checking for a BSD-compatible install... /usr/bin/install -c 
checking for working mkdir -p... yes 
Tomcat Native Version: 1.2.17 
checking for chosen layout... tcnative 
checking for APR... yes 
configure: APR 1.6.3 detected. 
  setting CC to "x86_64-linux-gnu-gcc" 
  setting CPP to "x86_64-linux-gnu-gcc -E" 
  setting LIBTOOL to "/usr/share/apr-1.0/build/libtool" 
  adding "-I/usr/lib/jvm/java-8-openjdk-amd64/include" to TCNATIVE_PRIV_INCLUDES 
checking for JDK os include directory...  linux 
  adding "-I/usr/lib/jvm/java-8-openjdk-amd64/include/linux" to TCNATIVE_PRIV_INCLUDES 
checking for gcc... x86_64-linux-gnu-gcc 
checking whether the C compiler works... yes 
checking for C compiler default output file name... a.out 
checking for suffix of executables...
checking whether we are cross compiling... no 
checking for suffix of object files... o 
checking whether we are using the GNU C compiler... yes 
checking whether x86_64-linux-gnu-gcc accepts -g... yes 
checking for x86_64-linux-gnu-gcc option to accept ISO C89... none needed 
checking for OpenSSL library... using openssl from /usr/${exec_prefix}/lib and /usr/include 
checking OpenSSL library version >= 1.0.2... ok 
checking for OpenSSL DSA support... yes 
  setting TCNATIVE_LDFLAGS to "-lssl -lcrypto" 
  adding "-DHAVE_OPENSSL" to CFLAGS 
  setting TCNATIVE_LIBS to "" 
  setting TCNATIVE_LIBS to " /usr/lib/x86_64-linux-gnu/libapr-1.la " 
checking for apr_pollset_wakeup in -lapr-1... yes 
  adding "-DHAVE_POLLSET_WAKEUP" to CFLAGS 
configure: creating ./config.status 
config.status: creating tcnative.pc 
config.status: creating Makefile 
config.status: executing default commands 

4.5. make


  # make 
make[1]: Entering directory '/home/tetsuohino/tomcat-apr-build/apache-tomcat-8.5.34/bin/tomcat-native-1.2.17-src/native' 
/usr/share/apr-1.0/build/libtool --no-silent --mode=compile x86_64-linux-gnu-gcc -pthread  -g -O2 -DHAVE_OPENSSL -DHAVE_POLLSET_WAKEUP -DHAVE_CONFIG_H  -DLINUX -D_REENTRANT -D_GNU_SOURCE   -g -O2 -DHAVE_OPENSSL -DHAVE_POLLSET_WAKEUP   -I./include -I/usr/lib/jvm/java-8-openjdk-amd64/include -I/usr/lib/jvm/java-8-openjdk-amd64/include/linux  -I/usr/include/apr-1.0   -o src/address.lo -c src/address.c && touch src/address.lo 

libtool: compile:  x86_64-linux-gnu-gcc -pthread -g -O2 -DHAVE_OPENSSL -DHAVE_POLLSET_WAKEUP -DHAVE_CONFIG_H -DLINUX -D_REENTRANT -D_GNU_SOURCE -g -O2 -DHAVE_OPENSSL -DHAVE_POLLSET_WAKEUP -I./include -I/usr/lib/jvm/java-8-openjdk-amd64/include -I/usr/lib/jvm/java-8-openjdk-amd64/include/linux -I/usr/include/apr-1.0 -c src/address.c  -fPIC -DPIC -o src/.libs/address.o 

....snip....

libtool: link: (cd ".libs" && rm -f "libtcnative-1.so.0" && ln -s "libtcnative-1.so.0.2.17" "libtcnative-1.so.0") 

libtool: link: (cd ".libs" && rm -f "libtcnative-1.so" && ln -s "libtcnative-1.so.0.2.17" "libtcnative-1.so") 

libtool: link: x86_64-linux-gnu-ar cru .libs/libtcnative-1.a  src/address.o src/bb.o src/dir.o src/error.o src/file.o src/info.o src/jnilib.o src/lock.o src/misc.o src/mmap.o src/multicast.o src/network.o src/os.o src/poll.o src/pool.o src/proc.o src/shm.o src/ssl.o src/sslconf.o src/sslcontext.o src/sslinfo.o src/sslnetwork.o src/sslutils.o src/stdlib.o src/thread.o src/user.o os/unix/system.o os/unix/uxpipe.o 

x86_64-linux-gnu-ar: u' modifier ignored sinceD' is the default (see `U') 

libtool: link: x86_64-linux-gnu-ranlib .libs/libtcnative-1.a 

libtool: link: ( cd ".libs" && rm -f "libtcnative-1.la" && ln -s "../libtcnative-1.la" "libtcnative-1.la" ) 

make[1]: Leaving directory '/home/tetsuohino/tomcat-apr-build/apache-tomcat-8.5.34/bin/tomcat-native-1.2.17-src/native' 

4.6. make install


  # make install 
make[1]: Entering directory '/home/tetsuohino/tomcat-apr-build/apache-tomcat-8.5.34/bin/tomcat-native-1.2.17-src/native' 

make[1]: Nothing to be done for 'local-all'. 

make[1]: Leaving directory '/home/tetsuohino/tomcat-apr-build/apache-tomcat-8.5.34/bin/tomcat-native-1.2.17-src/native' 

.... snip....

libtool: install: /usr/bin/install -c -m 755 .libs/libtcnative-1.so.0.2.17 /usr/local/apr/lib/libtcnative-1.so.0.2.17 

libtool: install: (cd /usr/local/apr/lib && { ln -s -f libtcnative-1.so.0.2.17 libtcnative-1.so.0 || { rm -f libtcnative-1.so.0 && ln -s libtcnative-1.so.0.2.17 libtcn

libtool: finish: PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/sbin" ldconfig -n /usr/local/apr/lib 



Libraries have been installed in: 

/usr/local/apr/lib 

If you ever happen to want to link against installed libraries 
in a given directory, LIBDIR, you must either use libtool, and 
specify the full pathname of the library, or use the '-LLIBDIR' 

flag during linking and do at least one of the following: 
   - add LIBDIR to the 'LD_LIBRARY_PATH' environment variable 
     during execution 
   - add LIBDIR to the 'LD_RUN_PATH' environment variable 
     during linking 
   - use the '-Wl,-rpath -Wl,LIBDIR' linker flag 
   - have your system administrator add LIBDIR to '/etc/ld.so.conf' 
See any operating system documentation about shared libraries for 

more information, such as the ld(1) and ld.so(8) manual pages. 

  1. APRのインストール先を確認
    
    # ls -l /usr/local/apr/lib 
    total 3044 
    -rw-r--r-- 1 root root 1971456  9月 25 20:06 libtcnative-1.a 
    -rwxr-xr-x 1 root root    1041  9月 25 20:06 libtcnative-1.la 
    lrwxrwxrwx 1 root root      23  9月 25 20:06 libtcnative-1.so -> libtcnative-1.so.0.2.17 
    lrwxrwxrwx 1 root root      23  9月 25 20:06 libtcnative-1.so.0 -> libtcnative-1.so.0.2.17 
    -rwxr-xr-x 1 root root 1131920  9月 25 20:06 libtcnative-1.so.0.2.17 
    drwxr-xr-x 2 root root    4096  9月 25 20:06 pkgconfig 
    

APR + OpenSSL

server.conf設定例

 <!-- Define a SSL Coyote HTTP/1.1 Connector on port 8443 --> 
    <Connector 
           protocol="org.apache.coyote.http11.Http11AprProtocol" 
           port="8443" maxThreads="200"  
           scheme="https" secure="true" SSLEnabled="true">
        <SSLHostConfig>
             <Certificate certificateFile="/home/hoge/pem/server.crt" 
                        certificateKeyFile="/home/hoge/pem/private.key" 
                     certificateChainFile="/home/hoge/pem/bundle.crt"/> 
        </SSLHostConfig> 
    </Connector>

起動確認(catalina.log)

02-Oct-2018 10:48:37.106 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["https-openssl-apr-8443"] 
...
02-Oct-2018 10:48:39.880 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["https-openssl-apr-8443"] 

APR + OpenSSL + HTTP2

server.conf設定例

   <!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2 
         This connector uses the APR/native implementation which always uses 
         OpenSSL for TLS. 
         Either JSSE or OpenSSL style configuration may be used. OpenSSL style 
         configuration is used below. 
    --> 
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol" 
               maxThreads="150" SSLEnabled="true" > 
        <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" /> 
        <SSLHostConfig> 
            <Certificate certificateKeyFile="/home/hoge/pem/private.key" 
                         certificateFile="/home/hoge/pem/server.crt" 
                     certificateChainFile="/home/hoge/pem/bundle.crt" 
                         type="RSA" /> 
        </SSLHostConfig> 
    </Connector> 

起動確認(catalina.log)

["https-openssl-apr-8443"] connector has been configured to support negotiation to [h2] via ALPN 

02-Oct-2018 10:52:06.257 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["https-openssl-apr-8443"]
...
02-Oct-2018 10:52:08.358 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["https-openssl-apr-8443"]  

トラブルシュート

  • 起動時に「Unable to load certificate key」というエラーが発生する。
    • PEM形式の各証明書、キーファイルをtomcatの実行グループであること。
  • 起動時に「java.io.FileNotFoundException: Configured file xxx does not exist」 というエラーが発生する。
    • "."で区切られたディレクトリに格納されたキーファイル、証明書は見つけてくれない。
5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3