Apache Tomcat
Running Tomcat on port lower than 1024 with authbind
- Find out the tomcat user:
# grep tomcat /etc/passwd
- Bind the port:
# touch /etc/authbind/byport/443
# chmod 500 /etc/authbind/byport/443
# chown tomcat /etc/authbind/byport/443
- For Tomcat version < 9 uncomment and adjust
AUTHBINDsetting 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>