FreeBSD で Apache Tomcat を動かす

前提条件

Tomcat 8.0版はこちら


Apache httpd

Apache httpd をportsでインストールする

いくつかのコンパイルオプションを有効にするために ports からインストー ルします。

# cd /usr/ports/www/apache24
# make install clean 

/boot/loader.conf

HTTP/SSLバッファリング用のカーネルモジュールを有効にします。

accf_http_load="YES"
accf_data_load="YES"

/etc/rc.conf

apache24_enable="YES"
apache24_http_accept_enable="YES"

/usr/local/etc/apache24/extra/httpd-ssl.conf

Let's Encryptの証明書を使用します。

SSLCertificateFile "/usr/local/etc/letsencrypt/live/www.next-hop.net/fullchain.pem"
SSLCertificateKeyFile "/usr/local/etc/letsencrypt/live/www.next-hop.net/privkey.pem"

/usr/local/etc/apache24/httpd.conf

プロキシでAJPとWebSocketが使えるようにコメントを外します。

LoadModule proxy_module libexec/apache24/mod_proxy.so
LoadModule proxy_wstunnel_module libexec/apache24/mod_proxy_wstunnel.so
LoadModule proxy_ajp_module libexec/apache24/mod_proxy_ajp.so

/usr/local/etc/apache24/Includes/proxy.conf

サンプルプログラムをApacheから起動できるようにプロキシでリダイレクトします。

ProxyPass /examples/websocket/ ws://localhost:8080/examples/websocket/
ProxyPassReverse /examples/websocket/ ws://localhost:8080/examples/websocket/
ProxyPass /examples/ ajp://localhost:8009/examples/

Apache httpd を起動する

# service apache24 start

Apache Tomcat

Tomcat をパッケージでインストールする

# pkg install tomcat9

/etc/rc.conf

tomcat9_enable="YES"

/usr/local/apache-tomcat-9.0/conf/tomcat-users.xml

<user username="tomcat" password="secret" roles="manager-gui,admin-gui"/>

/usr/local/apache-tomcat-9.0/webapps/manager/META-INF/context.xml

/usr/local/apache-tomcat-9.0/webapps/host-manager/META-INF/context.xml

リモートから管理する場合はアクセス元の IP アドレスを追加します。

         allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1|10.1.1.1" />

/usr/local/apache-tomcat-9.0/conf/server.xml

TLS のコメントを外します。

--- server.xml.sample   2020-04-07 22:38:16.000000000 +0900
+++ server.xml  2020-05-05 23:26:13.424435000 +0900
@@ -84,7 +84,6 @@
          Either JSSE or OpenSSL style configuration may be used regardless of
          the SSLImplementation selected. JSSE style configuration is used below.
     -->
-    <!--
     <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
                maxThreads="150" SSLEnabled="true">
         <SSLHostConfig>
@@ -92,7 +91,6 @@
                          type="RSA" />
         </SSLHostConfig>
     </Connector>
-    -->
     <!-- Define an 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.
@@ -113,12 +111,10 @@
     -->

     <!-- Define an AJP 1.3 Connector on port 8009 -->
-    <!--
     <Connector protocol="AJP/1.3"
                address="::1"
                port="8009"
                redirectPort="8443" />
-    -->

     <!-- An Engine represents the entry point (within Catalina) that processes
          every request.  The Engine implementation for Tomcat stand alone

/usr/local/apache-tomcat-9.0/webapps/manager/WEB-INF/web.xml

マネージャのアップロード制限を大きくします。

--- web.xml.old 2016-05-01 15:57:43.000000000 +0900
+++ web.xml     2016-05-01 19:57:27.000000000 +0900
@@ -51,9 +51,9 @@
  </init-param>
  -->
    <multipart-config>
      -      <-- 50MB max -->
      -      <max-file-size>52428800</max-file-size>
      -      <max-request-size>52428800</max-request-size>
      +      <;-- 500MB max -->
      +      <max-file-size>524288000</max-file-size>
      +      <max-request-size>524288000</max-request-size>
      <file-size-threshold>0</file-size-threshold>
    </multipart-config>
  </servlet>

Let's Encrypt の証明書を Tomcat で使う

Let's Encrypt の証明書はそのままでは Tomcat で使えないので、 OpenSSL を用いて一旦 PKCS#12 形式に変換してから JDK の keytool を 用いてキーストアに変換します。
これらを一括で行うために以下のスクリプトを実行します。

#!/bin/sh

export LANG=C
LEDIR="/usr/local/etc/letsencrypt/live"
TOMCATDIR="/usr/local/apache-tomcat-9.0"
JAVABIN="/usr/local/openjdk8/bin"
KEYTOOL="$JAVABIN/keytool"
OPENSSL="/usr/bin/openssl"
HOSTNAME="`uname -n`"
SHORTNAME="tomcat"
#KEYSTORE="$TOMCATDIR/.keystore"
KEYSTORE="$TOMCATDIR/conf/localhost-rsa.jks"
PASSWD="changeit"

$OPENSSL pkcs12 -export -in $LEDIR/$HOSTNAME/cert.pem -inkey $LEDIR/$HOSTNAME/privkey.pem -out $TOMCATDIR/conf/$HOSTNAME.p12 -name $SHORTNAME -CAfile $LEDIR/$HOSTNAME/chain.pem -caname LetsEncrypt -passout pass:

if [ -f $KEYSTORE ]; then
    $KEYTOOL -list -keystore $KEYSTORE -storepass $PASSWD
    cp -p $KEYSTORE ${KEYSTORE}.old
    rm -f $KEYSTORE
fi

$KEYTOOL -importkeystore -deststorepass $PASSWD -destkeypass $PASSWD -destkeystore $KEYSTORE -deststoretype pkcs12 -srckeystore $TOMCATDIR/conf/$HOSTNAME.p12 -srcstoretype PKCS12 -srcstorepass "" -alias $SHORTNAME
$KEYTOOL -import -trustcacerts -alias root -file $LEDIR/$HOSTNAME/chain.pem -keystore $KEYSTORE -storepass $PASSWD
$KEYTOOL -list -keystore $KEYSTORE -storepass $PASSWD

rm -f $TOMCATDIR/conf/$HOSTNAME.p12

exit

# for JSEE with OpenSSL
cp $LEDIR/$HOSTNAME/privkey.pem conf/localhost-rsa-key.pem
cp $LEDIR/$HOSTNAME/cert.pem conf/localhost-rsa-cert.pem
cp $LEDIR/$HOSTNAME/chain.pem conf/localhost-rsa-chain.pem

chmod 600 $TOMCATDIR/conf/localhost-rsa-key.pem
chown www $TOMCATDIR/conf/*.pem

以下のようにキーストアが作成されます。

Keystore type: PKCS12
Keystore provider: SUN

Your keystore contains 2 entries

root, Dec 3, 2016, trustedCertEntry,
Certificate fingerprint (SHA1):
XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
tomcat, Dec 3, 2016, PrivateKeyEntry,
Certificate fingerprint (SHA1): XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX

Tomcat を起動する

# service tomcat9 start

Tomcat の動作を確認する

Tomcatに直接アクセスしてみます。

http://tomcat.next-hop.net:8080/
https://tomcat.next-hop.net:8443/

Tomcat

サンプルプログラムがすべてのパターンで動作することを確認します。

http://tomcat.next-hop.net:8080/examples/
https://tomcat.next-hop.net:8443/examples/
http://tomcat.next-hop.net/examples/
https://tomcat.next-hop.net/examples/

Tomcat

と言いつつ、WebSocketがhttpd経由だと動かない...


参考