Switch SSL termination from tomcat to Apache
Asked by Mike Ellis:

Hello,

I have a configuration question I hope someone can help fix. I have inherited Confluence and JIRA sites running on the same machine, the original and existing setup has Tomcat doing all the SSL termination, but this leaves users having to have port numbers in their URLs. This is no longer desired and in Test I have Apache doing the SSL termination and passing the requests back to Confluence and JIRA, this all works very well, looks great with no port numbers in the URLs, so the managers are pleased, but I worry there are users out there that have bookmarks set to lots of pages using the old URLs. In production, how can I setup Apache to forward/rewrite requests for something like https://jira.mysite.com:8443/\<some-URI\> to https://jira.mysite.com/\<some-URI\> ? I have Confluence and JIRA running on the same machines, but I have name-based Apache virtual hosts setup which appears to be working well, but I know there will be someone with bookmarked pages that will cause me no end of grief if I move this new setup into Production use without some consideration. Below are the old Apache and tomcat configs as well as the new.

I have tried copying the below 443 NameVirtualHost but the URL is not rewritten so the redirect fails and I get an SSL error. I get this is most likely an Apache issue, but was hoping someone here has run into this issue and gotten it sorted.

**Old Setup:**

`server.xml` defines the Listen address and the Connector port, the keys are all stored in the Java keystore and Apache is simply sitting in front of tomcat, listening on port 80, but just doing a simple redirect to the application, so the application port is included in the URL.

Tomcat:

```
&lt;Service name="Catalina"&gt;        &lt;Connector port="8080"                   maxThreads="150"                   minSpareThreads="25"                   connectionTimeout="20000"                   enableLookups="false"                   maxHttpHeaderSize="8192"                   protocol="HTTP/1.1"                   useBodyEncodingForURI="true"                   redirectPort="8443"                   acceptCount="100"                   disableUploadTimeout="true"                   address="10.1.2.3" /&gt;            &lt;Connector port="8443"                   protocol="org.apache.coyote.http11.Http11Protocol"              maxHttpHeaderSize="8192" SSLEnabled="true"              maxThreads="150" minSpareThreads="25"              enableLookups="false" disableUploadTimeout="true"              acceptCount="100" scheme="https" secure="true"              clientAuth="false" sslProtocol="TLS" useBodyEncodingForURI="true"              keyAlias="jira-test" keystoreFile="/opt/atlassian/data/keystore" /&gt;
```

Apache:

```
NameVirtualHost 10.1.2.3:80&lt;VirtualHost 10.1.2.3:80&gt;    ServerAdmin sysadmin@xxxxxxxxxxxxxxxx.com    ServerName jira-test.mysite.com    Redirect permanent / https://jira-test.mysite.com:8443&lt;/VirtualHost&gt;
```

Example URL:

```
https://jira-test.mysite.com:8443/browse/INFRA-747
```

**New Setup:**

Tomcat (localhost is named 'linux7030.mysite.com):

```
&lt;Service name="Catalina"&gt;        &lt;Connector port="8080"                   proxyPort="443"                   scheme="https"                   proxyName="linux7030.mysite.com"                   address="127.0.0.1"                   maxThreads="150"                   minSpareThreads="25"                   connectionTimeout="20000"                   enableLookups="false"                   maxHttpHeaderSize="8192"                   protocol="HTTP/1.1"                   useBodyEncodingForURI="true"                   redirectPort="8443"                   acceptCount="100"                   disableUploadTimeout="true"/&gt;SSL Connector is left commented out.
```

Apache:

```
## JIRA Proxy VirtualHost ConfigurationListen 443NameVirtualHost *:443&lt;VirtualHost *:443&gt;   ServerAdmin sysadmin@mysite.com   ServerName linux7030.mysite.com:443    &lt;Proxy *&gt;            Order deny,allow            Allow from all    &lt;/Proxy&gt;   SSLProxyEngine          On   ProxyRequests           Off   ProxyPreserveHost       On   ProxyPass               /       http://127.0.0.1:8080/   ProxyPassReverse        /       http://127.0.0.1:8080/   SSLCertificateFile      /etc/httpd/ssl/linux7030.cer   SSLCertificateKeyFile   /etc/httpd/ssl/linux7030.key   SSLCertificateChainFile /etc/httpd/ssl/WestCAchain.cer   RewriteEngine On   RewriteCond %{HTTPS} off   RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}&lt;/VirtualHost&gt;NameVirtualHost *:80&lt;VirtualHost *:80&gt;   ServerAdmin sysadmnin@mysite.com   ServerName linux7030.mysite.com:80   Redirect permanent  /       https://linux7030.mysite.com/   RewriteEngine On   RewriteCond %{HTTPS} off   RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}    &lt;Proxy *&gt;            Order deny,allow            Allow from all    &lt;/Proxy&gt;   SSLProxyEngine          On   ProxyRequests           Off   ProxyPreserveHost       On   ProxyPass               /       http://127.0.0.1:8080/   ProxyPassReverse        /       http://127.0.0.1:8080/&lt;/VirtualHost&gt;
```

Example URL:

```
https://linux7030.mysite.com/browse/SM-15
```

So what I think I need is possibly a new Virtual Host in Apache to correctly send or re-write requests to the old URLs to the new, which will not be using the 8443 port (or 9443 for Confluence...).

```
https://jira-test.mysite.com:8443/browse/INFRA-747  -&gt; -&gt; -&gt;  (fancy redirect/re-write icons)https://jira-test.mysite.com/browse/INFRA-747
```

Please let me know if you have any questions and thanks in advance!

-Mike


Answers:
author: Alexander_Grau
body: Hi Mike,

Sorry for missunderstanding your question. I did some more investigation on that.

if you run JIRA not on port 8080 but on a different one (let's say port 7777 - change that in server.xml, you have to restart JIRA), you can have an Apache vHost which listens on Port 8080 (simulates the old URL) and does just the redirect to <https://jira.mysite.com>. I've got that in my environment to work.

Give it a try

Alex

comments: author: Mike Ellis
body: Hello Alex,I am not being clear it seems. In TEST, I am running JIRA only on the loopback address of 127.0.0.1:8080, so when uses browse to my JIRA site on port 80 or 443 they are redirected correctly, and over SSL, to my JIRA site. All the SSL work is done by Apache in this case. This is my preferred way of configuring JIRA access.My issue is I have an older site that is still using Tomcat to do the SSL work, so at this time we have Apache just redirecting requests to JIRA listening on port 8443, as configured. But the management does not want to have the port number in any URL. I can configure my site as I have done in test, as described above and I know it will work. But my fear is there are folks out there that have bookmarks or other references to the old URL with the port. So I need Apache to redirect any JIRA request with port 8443 to the correct site. I have tried Apache rewrite rules, and tried virtual host configurations to point 8443 requests to the 127.0.0.1:8080 site but these are failing stating an SSL error. Nothing more is logged by Apache so I am a bit lost.Something like this:User has a bookmark to "[https://jira.mysite.con:8443/DBA-1234"](https://jira.mysite.con:8443/DBA-1234&quot);.I need to setup Apache to forward/rewrite the URL to our preferred of "[https://jira.mysite.com/DBA-1234"](https://jira.mysite.com/DBA-1234&quot);. So far in my testing I am not able to get this to work.Thanks,-Mike


author: Alexander_Grau
body: Hi Mike,

I'm running JIra and Confluence on the same Linux box, too.

For JIRA I'm using following vhost in Apache

```
&lt;VirtualHost *:80&gt;    ServerAdmin webmaster@mysite.de    ServerName jira.mysite.eu    Redirect / https://jira.mysiteeu/&lt;/VirtualHost&gt;&lt;IfModule mod_ssl.c&gt;&lt;VirtualHost *:443&gt;    ServerAdmin webmaster@mysite.de    ServerName jira.mysite.eu    # Logging    ErrorLog ${APACHE_LOG_DIR}/jira-error.log    LogLevel info    CustomLog ${APACHE_LOG_DIR}/jira-access.log combined####  SSL Configuration    SSLEngine on    SSLProxyEngine on    SSLCertificateKeyFile /etc/ssl/mysite.eu/apache.key    SSLCertificateFile /etc/ssl/mysite.eu/certificate_mysite.eu.crt    SSLCertificateChainFile /etc/ssl/mysite.eu/linux_intermediate.pem    BrowserMatch "MSIE [2-6]" \        nokeepalive ssl-unclean-shutdown \        downgrade-1.0 force-response-1.0    # MSIE 7 and newer should be able to use keepalive    BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown#### End SSL Configuration    # Proxy Settings    ProxyRequests Off    ProxyPreserveHost On    ProxyPass / http://localhost:8080/    ProxyPassReverse / http://localhost:8080/    &lt;Proxy *&gt;        Order Deny,Allow        Allow from all    &lt;/Proxy&gt;    &lt;Location /&gt;         Order allow,deny         Allow from all    &lt;/Location&gt;&lt;/VirtualHost&gt;&lt;/IfModule&gt;
```

The server.xml looks like the following

```
&lt;?xml version="1.0" encoding="utf-8"?&gt;&lt;!--   ====================================================================================   Atlassian JIRA Standalone Edition Tomcat Configuration.   See the following for more information   http://confluence.atlassian.com/display/JIRA/Configuring+JIRA+Standalone   ==================================================================================== --&gt;&lt;!--  Licensed to the Apache Software Foundation (ASF) under one or more  contributor license agreements.  See the NOTICE file distributed with  this work for additional information regarding copyright ownership.  The ASF licenses this file to You under the Apache License, Version 2.0  (the "License"); you may not use this file except in compliance with  the License.  You may obtain a copy of the License at      http://www.apache.org/licenses/LICENSE-2.0  Unless required by applicable law or agreed to in writing, software  distributed under the License is distributed on an "AS IS" BASIS,  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the specific language governing permissions and  limitations under the License.--&gt;&lt;Server port="8005" shutdown="SHUTDOWN"&gt;    &lt;!--APR library loader. Documentation at /docs/apr.html --&gt;    &lt;Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on"/&gt;    &lt;!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html --&gt;    &lt;Listener className="org.apache.catalina.core.JasperListener"/&gt;    &lt;Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/&gt;    &lt;!-- Global JNDI resources         Documentation at /docs/jndi-resources-howto.html    --&gt;    &lt;!-- A "Service" is a collection of one or more "Connectors" that share        a single "Container" Note:  A "Service" is not itself a "Container",        so you may not define subcomponents such as "Valves" at this level.        Documentation at /docs/config/service.html    --&gt;    &lt;Service name="Catalina"&gt;        &lt;Connector port="8081"                   maxThreads="150"                   minSpareThreads="25"                   connectionTimeout="20000"                   enableLookups="false"                   maxHttpHeaderSize="8192"                   protocol="HTTP/1.1"                   useBodyEncodingForURI="true"                   redirectPort="8443"                   acceptCount="100"                   disableUploadTimeout="true"/&gt;        &lt;!--        ====================================================================================        To run JIRA via HTTPS:             * Uncomment the Connector below             * Execute:                 %JAVA_HOME%\bin\keytool -genkey -alias tomcat -keyalg RSA (Windows)                 $JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA  (Unix)               with a password value of "changeit" for both the certificate and the keystore itself.             * If you are on JDK1.3 or earlier, download and install JSSE 1.0.2 or later, and put the JAR files into               "$JAVA_HOME/jre/lib/ext"             * Restart and visit https://localhost:8443/             For more info, see :              http://confluence.atlassian.com/display/JIRA/Running+JIRA+over+SSL+or+HTTPS              and              http://tomcat.apache.org/tomcat-6.0-doc/ssl-howto.html        ====================================================================================        --&gt;        &lt;Connector acceptCount="100"                   connectionTimeout="20000"                   disableUploadTimeout="true"                   enableLookups="false"                   maxHttpHeaderSize="8192"                   maxThreads="150"                   minSpareThreads="25"                    port="8080"                   protocol="HTTP/1.1"                   redirectPort="8443"                   useBodyEncodingForURI="true"                    scheme="https"                   proxyName="jira.mysite.eu"                   proxyPort="443"                   secure="true"/&gt;         &lt;!--            &lt;Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol"              maxHttpHeaderSize="8192" SSLEnabled="true"              maxThreads="150" minSpareThreads="25"              enableLookups="false" disableUploadTimeout="true"              acceptCount="100" scheme="https" secure="true"              clientAuth="false" sslProtocol="TLS" useBodyEncodingForURI="true"/&gt;        --&gt;        &lt;!--         ====================================================================================         If you have Apache AJP Connector (mod_ajp) as a proxy in front of JIRA you should uncomment the following connector configuration line         See the following for more information :            http://confluence.atlassian.com/display/JIRA/Configuring+Apache+Reverse+Proxy+Using+the+AJP+Protocol         ====================================================================================        --&gt;        &lt;!--              &lt;Connector port="8009" redirectPort="8443" enableLookups="false" protocol="AJP/1.3" URIEncoding="UTF-8"/&gt;        --&gt;        &lt;Engine name="Catalina" defaultHost="localhost"&gt;            &lt;Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"&gt;                &lt;Context path="" docBase="${catalina.home}/atlassian-jira" reloadable="false" useHttpOnly="true"&gt;                    &lt;!--                     ====================================================================================                     Note, you no longer configure your database driver or connection parameters here.                     These are configured through the UI during application setup.                     ====================================================================================                    --&gt;                    &lt;Resource name="UserTransaction" auth="Container" type="javax.transaction.UserTransaction"                              factory="org.objectweb.jotm.UserTransactionFactory" jotm.timeout="60"/&gt;                    &lt;Manager pathname=""/&gt;                &lt;/Context&gt;            &lt;/Host&gt;            &lt;!--                ====================================================================================                 Access Logging.                 This should produce access_log.&lt;date&gt; files in the 'logs' directory.                 The output access log lies has the following fields :                 IP Request_Id User Timestamp  "HTTP_Method URL Protocol_Version" HTTP_Status_Code ResponseSize_in_Bytes RequestTime_In_Millis Referer User_Agent ASESSIONID                 eg :                 192.168.3.238 1243466536012x12x1 admin [28/May/2009:09:22:17 +1000] "GET /jira/secure/admin/jira/IndexProgress.jspa?taskId=1 HTTP/1.1" 200 24267 1070 "http://carltondraught.sydney.atlassian.com:8090/jira/secure/admin/jira/IndexAdmin.jspa" "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.10) Gecko/2009042523 Ubuntu/9.04 (jaunty) Firefox/3.0.10" "C2C99B632EE0F41E90F8EF7A201F6A78"                 NOTES:                 The RequestId is a millis_since_epoch plus request number plus number of concurrent users                 The Request time is in milliseconds                 The ASESSIONID is an hash of the JSESSIONID and hence is safe to publish within logs.  A session cannot be reconstructed from it.                 See http://tomcat.apache.org/tomcat-6.0-doc/config/valve.html for more information on Tomcat Access Log Valves                ====================================================================================            --&gt;            &lt;Valve className="org.apache.catalina.valves.AccessLogValve" resolveHosts="false"                   pattern="%a %{jira.request.id}r %{jira.request.username}r %t &amp;quot;%m %U%q %H&amp;quot; %s %b %D &amp;quot;%{Referer}i&amp;quot; &amp;quot;%{User-Agent}i&amp;quot; &amp;quot;%{jira.request.assession.id}r&amp;quot;"/&gt;        &lt;/Engine&gt;    &lt;/Service&gt;&lt;/Server&gt;
```

This setup works pretty fine for. The setup for Confluence is almost the same!

Hopefully this helps

BR  
Alex

comments: author: Mike Ellis
body: Hello Alex,Thanks, I have this working and working well. What I am having trouble with is the old way moving to the new setup. In the old way we had Tomcat doing all the SSL work, so we would get the port numbers in our URLs, but now management wants to see the URLs with no port numbers. And I am certain people have bookmarks to the old URLs with ports, so I need to find a way to get Apache to forward the requests correctly to the standard 443 and 80 ports to avoid the ports appearing in the URLs, while still allowing the old bookmarks to function correctly. I have tried to get Apache to listen on the old port, then forward the requests to the 'new' URL, but I get an {{ssl_error_rx_record_too_long}} SSL error and the URL is not re-written. I am going to keep working on this some more...Thanks again,-Mike


author: TRW-Admin
body: Hi Mike, I know this thread is from a while back but was wondering if you ever found a solution to the Apache rewrite issue? I have EXACTLY the same problem - I need to account for users who have foo.com:8443 bookmarks directly to the Tomcat web server, so when I change to my Apache reverse proxy, exactly as you have above, they get redirected to foo.com.

It seems like such a simple thing to achieve, yet as much as I have researched it I cannot find a way for Apache to redirect in this way. If a user goes to foo.com:8443, it bypasses Apache and goes straight to the Tomcat web server. This is not good!

Yes, I can stop users getting to tomcat directly by specifying the connector address as 127.0.0.1 and I can change the SSL port of the tomcat connector to something else, and then 'simulate' the old tomcat :8443 connector by creating an Apache vhost listening on :8443, but neither of these solutions are desirable. They seem like hack workarounds. I want Apache to redirect for me!

Glenn


Tags: confluence-administration

jira

jira-administration