Skip to content

Instantly share code, notes, and snippets.

@i-amolo
Forked from Teino1978-Corp/ tomcatssl.md
Created November 27, 2019 16:27
Show Gist options
  • Save i-amolo/46592b175d7a31b60ac12dae1ed41aa8 to your computer and use it in GitHub Desktop.
Save i-amolo/46592b175d7a31b60ac12dae1ed41aa8 to your computer and use it in GitHub Desktop.
Tomcat SSL

Tomcat 6 under secured Nginx?

In Big Blue Button Tomcat 6 is used under Nginx.

Tomcat documentation for "SSL - How to" in "SSL and Tomcat" section, clames that:
"It is important to note that configuring Tomcat to take advantage of secure sockets is usually only necessary when running it as a stand-alone web server. When running Tomcat primarily as a Servlet/JSP container behind another web server, such as Apache or Microsoft IIS, it is usually necessary to configure the primary web server to handle the SSL connections from users. Typically, this server will negotiate all SSL-related functionality, then pass on any requests destined for the Tomcat container only after decrypting those requests. Likewise, Tomcat will return cleartext responses, that will be encrypted before being returned to the user's browser. In this environment, Tomcat knows that communications between the primary web server and the client are taking place over a secure connection (because your application needs to be able to ask about this), but it does not participate in the encryption or decryption itself."

If Tomcat "knows" that communications are secure, how come "request.isSecure()" returns "false"?

Redirect HTTP to HTTPS on Tomcat

Source

You’ve bought your SSL secure certificate and successfully installed on Tomcat with the keytool but how do your redirect the entire site to go HTTPS and redirect any HTTP connection straight over to HTTPS.

You need to edit the 2 Tomcat configuration files; server.xml and web.xml and then when edited restart the tomcat service.

Open server.xml typically found in tomcat/conf and change:

<Connector port="80"
           enableLookups="false"
           redirectPort="8443" />

to

<Connector port="80"
           enableLookups="false"
           redirectPort="443"

Then open web.xml (same directory) and add this snippet before the closing tag of /web-app:

<security-constraint>
    <web-resource-collection>
        <web-resource-name>Protected Context</web-resource-name>
        <url-pattern>/*</url-pattern>
    </web-resource-collection>
    
    <!-- auth-constraint goes here if you requre authentication -->
    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
</security-constraint>

Restart Tomcat and all pages should redirect to https.

Set up Tomcat to redirect HTTP requests to HTTPS

Source

We had JIRA installed and using the built-in Tomcat app server, accepting both HTTP and HTTPS requests. We wanted to restrict it so that all JIRA access was only via SSL. The config changes were pretty simple.

First - Change Tomcat's server.xml. Edit the non-SSL entry listening on port 80 and add or edit the redirectPort atribute to point to the port on which the SSL is listening. By default, the redirectPort was pointing to port 443.

Was:

<Connector port="80"
           enableLookups="false" redirectPort="8443"
           maxThreads="100" minSpareThreads="100" maxSpareThreads="100"/>

Changed to:

<Connector port="80"
           enableLookups="false" redirectPort="443"
           maxThreads="100" minSpareThreads="100" maxSpareThreads="100"/>

Second - In the Tomcat web.xml file the following has to be added within the element. This new element must be added after the element:

<!-- SSL settings. only allow HTTPS access to JIRA -->
<security-constraint>
<web-resource-collection>
<web-resource-name>Entire Application</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>

How to configure Tomcat to always require HTTPS

Source

First, make sure that you have configured and enabled both the HTTP and HTTPS elements in your conf/server.xml file:

    <Connector port="8080" protocol="HTTP/1.1" 
               redirectPort="443"/>
    <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
               scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS"
               keystoreFile="conf/keystore" keystorePass="s00perSeeekrit"/>

For details on how to prepare your conf/keystore file, see http://tomcat.apache.org/tomcat-6.0-doc/ssl-howto.html

Then, Restart Tomcat and test both of these connectors, making sure that you can access your web application via either connector before you proceed. Next, edit your webapp's WEB-INF/web.xml file and add the following inside of your container element:

    <!-- Require HTTPS for everything except /img (favicon) and /css. -->
    <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>
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>HTTPSOrHTTP</web-resource-name>
            <url-pattern>*.ico</url-pattern>
            <url-pattern>/img/*</url-pattern>
            <url-pattern>/css/*</url-pattern>
        </web-resource-collection>
        <user-data-constraint>
            <transport-guarantee>NONE</transport-guarantee>
        </user-data-constraint>
    </security-constraint>

This configuration declares that the entire webapp is meant to be HTTPS only, and the container should intercept HTTP requests for it and redirect those to the equivalent "https://" URL. The exception is certain requests having URL patterns that match the "HTTPSOrHTTP" web resource collection, in which case the requests will be served through the protocol the request came in on, either HTTP or HTTPS.

Lastly, restart your webapp (or Tomcat). It should now redirect HTTP requests to HTTPS, and it should serve the webapp via HTTPS only.

How to secure Tomcat 7 with SSL / TLS

Source

Intro

The following article shows how to secure Tomcat 7 servlet container with SSL / TLS. Although there might me numerous different solutions (e.g. proxying from Apache server) the one that I present bases on Tomcat only and utilizes its default configuration files.

The following assumptions have been made for the rest of the article:

  • OS: Ubuntu 12.04 Server x64
  • Tomcat: tomcat7 installed from official Ubuntu repositories (apt-get install tomcat7)
  • Tomcat user: tomcat7
  • Tomcat home directory: /etc/tomcat7
  • SSL / TLS port: TCP port 8443
  • Keystore location: /etc/tomcat7/keystore.jks
  • Keystore password: keystore

The following section describes a detailed steps required for securing Tomcat 7 with SSL / TLS. All the commands have been run as a tomcat7 user.

Configuration

1) Generate the keystore file that will store the certificates trusted by the Tomcat server. Depending on your needs this step may require invoking different commands. A general HowTo regarding the keytool tool usage can be found here.

In my case the keystore file was already delivered to me by my CA when requesting the certificate. However having both the CA and the CA-signed certificate you can easily create the keystore file by running the following commands:

keytool -import -trustcacerts -alias root
-file [CA cert path] -keystore /etc/tomcat7/keystore.jks
keytool -import -trustcacerts -alias tomcat
-file [CA-signed cert path] -keystore /etc/tomcat7/keystore.jks

Or to generate the self-signed certificate:

keytool -genkey -keyalg RSA -alias tomcat
-keystore /etc/tomcat7/keystore.jks -storepass keystore
-validity 360 -keysize 2048

2) Update /etc/tomcat7/server.xml configuration file and change the following part of its configuration:

<!--
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
           maxThreads="150" scheme="https" secure="true"
           clientAuth="false" sslProtocol="TLS" />
 -->

to what's shown below:

<Connector protocol="org.apache.coyote.http11.Http11NioProtocol"
           port="8443" SSLEnabled="true" maxThreads="200"
           scheme="https" secure="true"
           keystoreFile="/etc/tomcat7/keystore.jks"
           keystorePass="keystore" clientAuth="false"
           sslProtocol="TLS" />

3) As a root user restart Tomcat by running the following command:

/etc/init.d/tomcat7 restart

You're done! The Tomcat is now secured with SSL / TLS on port 8443.

Related topics:

Razuna with Nginx as a front end server

Source

Fronting Razuna with the Nginx web server

Nginx is a small but powerful web server. Nginx is known for its high performance, stability, rich feature set, simple configuration, and low resource consumption.

All our websites our powered with Nginx and we have nothing but good experiences with it. Especially the low resource consumption and stability and a big plus. In our tests, Nginx performs around 20% better then Apache, given Nginx and Tomcat are configured correctly. Please follow the guidelines below.

Configure Tomcat

Nginx can not use the AJP protocol, so it is of no use together with Nginx. But it is of utmost importance that APR is configured. Thus the first step is to configure APR for Tomcat.

Enable APR (Tomcat Native Library)

Tomcat can use the Apache Portable Runtime to provide superior scalability, performance, and better integration with native server technologies. APR has many uses, including access to advanced IO functionality (such as sendfile, epoll and OpenSSL), OS level functionality (random number generation, system status, etc), and native process handling (shared memory, NT pipes and Unix sockets).

Note - You can also follow the installation directives from the official Tomcat Native Library page

Linux

The following steps are for Ubuntu, but they are about the same on any other Linux distro.

  1. Make sure that you have the libssl-dev and libapr1-dev packages installed
    $ apt-get install libssl-dev libapr1-dev
  2. Switch to your tomcat's bin directory
    $ cd $(TOMCAT_HOME)/bin
  3. Extract the tarball (tarred and gzipped archive) of the tomcat native lib
    $ tar -xvzf tomcat-native.tar.gz
  4. Jump into the source folder
    $ cd tomcat-native-xxx/jni/native
  5. Configure, make and install it:
    ./configure --with-apr=/usr/bin/apr-1-config && make && sudo make install
  6. Change to the system library folder
    $ cd /usr/lib
  7. Make a convenience link to you new library
    $ sudo ln -s /usr/local/apr/lib/libtcnative-1.so libtcnative-1.so
  8. Edit $(TOMCAT_HOME)/bin/catalina.sh adding the following lines:
    LD_LIBRARY_PATH=/usr/lib:$LD_LIBRARY_PATH
    export LD_LIBRARY_PATH
  9. Restart Tomcat.

Note: Some systems need to have IPv6 disabled in order to have APR working. Check your catalina.out log to see if APR is working.

MacOS X

Make sure to have installed the latest version of MacPorts.

  1. From the Terminal program, enter:sudo port install tomcat-native.
  2. From the Terminal program, make symbolic links from
    /opt/local/lib/libtcnative-1.*
    to
    /usr/lib/java:sudo ln -s /opt/local/lib/libtcnative-1.* /usr/lib/java
  3. Restart Tomcat

Windows

  1. Download the APR library directly from Tomcat Native Library page.
  2. Copy tcnative-xx.dll to %TOMCAT_HOME%/bin
  3. Restart Tomcat.

Configure Nginx

Now all there is to do is to tell Nginx to get the dynamic pages from Tomcat.

Note - The below configuration is meant for people who know what they are doing and have already installed Nginx.

Edit your "razuna" virtual host config file (create it) (Ubuntu: sites-available/razuna) and add the following lines:

server {
  listen          80 default;
  server_name     _;
  root            /opt/tomcat/webapps/razuna;
  location / {
    proxy_pass              http://localhost:8080;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header        Host $http_host;
    proxy_max_temp_file_size 0;
    expires     off;
    proxy_buffering off;
    proxy_store         off;
    proxy_connect_timeout 120;
    proxy_send_timeout    120;
    proxy_read_timeout    120;
 
  # All POST requests go directly
  if ($request_method = POST) {
    proxy_pass http://localhost:8080;
    break;
  }
}
 
  location ~ \.cfm$ {
    proxy_pass              http://localhost:8080;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header        Host $http_host;
    proxy_max_temp_file_size 0;
    #proxy_redirect     off;
    expires             off;
    proxy_buffering off;
    proxy_store         off;
    proxy_connect_timeout 120;
    proxy_send_timeout    120;
    proxy_read_timeout    120;
  # All POST requests go directly
  if ($request_method = POST) {
    proxy_pass http://localhost:8080;
    break;
  }
}
 
}

Of course, adjust the path settings and individual settings to your environment. But with this we actually tell Nginx to request any static file from the Razuna directory and any static content from Tomcat.

Tomcat 7 HTTP to HTTPS redirect

Source

Intro

The following article shows how to easily redirect HTTP to HTTP in Tomcat 7 servlet container that it always requires secure connection. It was assumed that the following TCP ports are used for that purpose:

  • 8080: for HTTP
  • 8443: for HTTPS

Please, follow the exact steps as described below to get it done.

Configuration

1) Update server.xml configuration file in Tomcat home directory and change the following part of its configuration:

<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           URIEncoding="UTF-8"
           redirectPort="8443" />

to what's shown below:

<Connector port="8080" enableLookups="false"
           redirectPort="8443" />

2) Update web.xml configuration file in Tomcat home directory and add the following content into the end before the closing </web-app> markup:

<security-constraint>
<web-resource-collection>
<web-resource-name>Protected Context</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<!-- auth-constraint goes here if you requre authentication -->
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>

3) Restart Tomcat servlet container.

You're done! The Tomcat always requires secure connection now.

Related topics:

WebFaction SSL

Nginx is used for SSL termination so the content served to GlassFish is not encrypted. While this is correct and transparent to applications it seems GlassFish expects to always be the first server in a stack.

However there may be a solution to this. According to this blog post
(http://stupidfredtricks.blogspot.co.uk/2012/10/glassfish-31x-behind-ssl-terminating.html)
GlassFish can take advantage of headers set by nginx to determine the "real" protocol.

We set the following headers in nginx when a request is sent over SSL:

HTTPS: on
X-Forwarded-Proto: https
X-Forwarded-SSL: on

If you can configure GlassFish to be aware of any of these you should be able to get it working.

Is there any way to skip Nginx front-end server altogether for a couple of ports managed by Glassfish?

This is possible, but isn't great. You'd need to switch your site to a different IP address and redirect your site to your application's port, like so:

https://admin.yourdomain.com:22715

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment