While setting up a JIRA Enterprise installation in AWS we wanted a solution for redirecting users from HTTP to HTTPs. We were using an ELB so that we could point a DNS record at a longer lived resource than the application instance and to also make use of the ELB’s ability to encrypt traffic with TLS, but the ELB can not redirect traffic from HTTP to HTTPS.
What alternatives came to mind? Using NGINX or Apache to proxy the request. This adds additional overhead though, NGINX or Apache have to be installed somewhere, should they be installed on the JIRA application server? We would also need to install and configure NGINX or Apache, so more configuration code, another Ansible role… This seems like a lot extra just to redirect users from HTTP to HTTPS.
The JIRA application WAR includes a Tomcat installation and the redirect can be accomplished using only Tomcat by configuring multiple HTTP connectors in conf/server.xml.
…
<Service name="Catalina">
<Connector
acceptCount="100"
connectionTimeout="20000"
disableUploadTimeout="true"
enableLookups="false"
maxHttpHeaderSize="8192"
maxThreads="150"
minSpareThreads="25"
port="8080"
protocol="HTTP/1.1"
redirectPort="443"
useBodyEncodingForURI="true"
/>
<Connector
acceptCount="100"
clientAuth="false"
disableUploadTimeout="true"
enableLookups="false"
maxHttpHeaderSize="8192"
maxThreads="150"
minSpareThreads="25"
port="8443"
protocol="HTTP/1.1"
proxyName="jira.mycompany.com"
proxyPort="443"
scheme="https"
secure="true"
useBodyEncodingForURI="true"
/>
…
A security constraint also needs to be added to the file atlassian-jira/WEB-INF/web.xml. This can be added at the end of the file. As a result, if a request is made to any of these URL patterns on the unsecure connector then a redirect will be returned sending the request to the redirectPort specified above which in this case is 443.
…
<security-constraint>
<web-resource-collection>
<web-resource-name>all-except-attachments</web-resource-name>
<url-pattern>*.jsp</url-pattern>
<url-pattern>*.jspa</url-pattern>
<url-pattern>/browse/*</url-pattern>
<url-pattern>/issues/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
</web-app>
So, when a request is made using HTTP hitting port 80 on the ELB, the ELB will then send the request to the backend Tomcat server port 8080. The Tomcat server will then redirect the request to port 443 which hits the ELB again and sends encrypted traffic to port 8443 on the backend.