aAPT
dDebian
fFFmpeg
jJava
mMercurial: Usage
oOCaml
pPostgreSQL

Home Applications

Apache Tomcat

Running Tomcat on port lower than 1024 with authbind

  1. Find out the tomcat user:
# grep tomcat /etc/passwd
  1. Bind the port:
# touch /etc/authbind/byport/443
# chmod 500 /etc/authbind/byport/443
# chown tomcat /etc/authbind/byport/443
  1. For Tomcat version < 9 uncomment and adjust AUTHBIND setting in /etc/default/tomcatX config.

SSL encryption with LE

1. Get domain certificate

letsencrypt-rs sign -D example.org -P /var/lib/tomcat8/webapps/ROOT -k domain.key -o domain.crt

2. Create java keystore file

Download LE CA certificate:

wget --quiet -O ca.pem https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem

and then

openssl pkcs12 -export -in domain.crt -inkey domain.key -out /etc/tomcat8/tomcat.jks -name tomcat -CAfile ca.pem -caname root -chain

However, if LE root certificate is not present in the OpenSSL root certificate bundle, openssl may produce the following error:

Error unable to get issuer certificate getting chain.

In this case, it is necessary to join chain, root CA and the cross-signinig certificates into single bundle and repeat:

wget --quiet -O x1.pem https://letsencrypt.org/certs/isrgrootx1.pem
wget --quiet -O x3.pem https://ssl-tools.net/certificates/dac9024f54d8f6df94935fb1732638ca6ad77c13.pem
cat x1.pem x3.pem ca.pem > bundle.pem

openssl pkcs12 -export -in domain.crt -inkey domain.key -out /etc/tomcat8/tomcat.jks -name tomcat -CAfile bundle.pem -caname root -chain

Another possible problem is that export ends with the error

Error certificate has expired getting chain.

To resolve this error open the chain.pem (or fullchain.pem) in the text editor and remove the last certificate.

Note for dehydrated acme client: since the dehydrated uses the different file layout and nomenclature, the openssl argument values would be as follows:

openssl pkcs12 -export \
-in /etc/dehydrated/ssl/certs/domain/cert.pem \
-inkey /etc/dehydrated/ssl/certs/domain/privkey.pem \
-out keystore.jks \
-name yourname \
-CAfile /etc/dehydrated/ssl/certs/domain/chain.pem \
-caname root \
-chain

3. Configure Tomcat

server.xml example:

<Connector port="443" protocol="HTTP/1.1"
           connectionTimeout="20000"
           URIEncoding="UTF-8"
           SSLEnabled="true"
           scheme="https" secure="true"
           clientAuth="false" sslProtocol="TLS"
           keystoreFile="/etc/tomcat8/tomcat.jks"
           keystorePass="secret"
           ciphers="TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA" />

SSL + Apache Tomcat with APR

APR works with certificates stored in PEM, not in keystores. Sample server.xml (with HTTP redirect) is as follows:

<Connector port="80" protocol="HTTP/1.1" 
           connectionTimeout="20000" 
           URIEncoding="UTF-8"
           redirectPort="443" />
<Connector port="443" maxHttpHeaderSize="8192"
           maxThreads="150"
           enableLookups="false" disableUploadTimeout="true"
           acceptCount="100" scheme="https" secure="true"
           SSLEnabled="true"
           SSLCertificateFile="/etc/tomcat7/domain.crt"
           SSLCertificateKeyFile="/etc/tomcat7/domain.key"
           SSLCertificateChainFile="/etc/tomcat7/ca.pem"
           SSLDisableCompression="true"
           SSLCipherSuite="HIGH:!DH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!kRSA" />

To force APR specify protocol="org.apache.coyote.http11.Http11AprProtocol".

For HTTP redirect to fully work the following constraint in web application's web.xml may be needed:

<web-app>
    ...
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>HTTPSOnly</web-resource-name>
            <url-pattern>/*</url-pattern>
        </web-resource-collection>
        <user-data-constraint>
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint>
</web-app>