Configure Jira server to connect to MySQL via SSL

Still need help?

The Atlassian Community is here for you.

Ask the community

This document gives a how-to for securing your database connection using MySQL and the JIRA Standalone installer, as well as some troubleshooting tips. Hat tip to Steven Jackson for his contributions to this document.

These instructions are tested on Ubuntu 20.04, and the general procedure is uniform across platforms.
However, depending on your distribution and the method you have used to install the software, the file locations may differ.

Please note that Atlassian Support will refer SSL support to the institution that issued the Certificate. We provide this documentation for reference.


Before we Begin

To complete this task, you will need the following:

  • JIRA 8.5+
  • MySQL 5.7+ with SSL support (most precompiled packages include this)
  • openSSL 1.0+


These instructions are based upon the MySQL Documentation available here: link
These commands should be run as root or by using the sudo command.
Perform steps 1-3 on your MySQL server.

Whatever method you use to generate the certificate and key files, the Common Name value used for the server and client certificates/keys must each differ from the Common Name value used for the CA certificate. Otherwise, the certificate and key files will not work for servers compiled using OpenSSL


1. Generating your SSL keys


  1. Ensure you have a clean workspace.

    Terminal Input
    rm -rf /etc/mysql/newcerts
    mkdir /etc/mysql/newcerts && cd /etc/mysql/newcerts
  2. Create CA Certificate

    Terminal Input
    openssl genrsa 2048 > ca-key.pem
    openssl req -new -x509 -nodes -days +365 -key ca-key.pem -out ca-cert.pem
  3. Create Server Certificate, remove passphrase, and sign it

    Terminal Input
    openssl req -newkey rsa:2048 -nodes -keyout server-key.pem -out server-req.pem
    openssl rsa -in server-key.pem -out server-key.pem
    openssl x509 -req -in server-req.pem -days +365 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem
  4. Create Client Certificate, remove passphrase, and sign it

    Terminal Input
    openssl req -newkey rsa:2048 -nodes -keyout client-key.pem -out client-req.pem
    openssl rsa -in client-key.pem -out client-key.pem
    openssl x509 -req -in client-req.pem -days +365 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem
  5. Verify your certificates to prevent surprises later

    Terminal Input
    openssl verify -CAfile ca-cert.pem server-cert.pem client-cert.pem

2. Configure MySQL to accept SSL connections

These instructions are based upon the MySQL Documentation available here: link

  1. Verify that your MySQL server includes SSL support

    Terminal Input
    mysql --ssl --help

    The server will then list the SSL options available. If you receive this, instead:

    mysqld --ssl --help
    060525 14:18:52 [ERROR] mysqld: unknown option '--ssl'

    then your MySQL package does not have SSL included. Selecting and installing the correct MySQL server is outside of the scope of this guide.

  2. Open the /etc/mysql/my.cnf file in the editor of your choice and find the following section:

    #ssl
    #ssl-ca=/etc/mysql/cacert.pem
    #ssl-cert=/etc/mysql/servercert.pem
    #ssl-key=/etc/mysql/serverkey.pem

    Edit the file so it looks like this, using the file paths from Step 1:

    ssl
    ssl-ca=/etc/mysql/newcerts/ca-cert.pem
    ssl-cert=/etc/mysql/newcerts/server-cert.pem
    ssl-key=/etc/mysql/newcerts/server-key.pem

3. Secure your JIRA user

This section is based on a server root username of 'root', a schema name of 'public', and a JIRA username of 'jira'. If this does not reflect your system, please adjust the statements.


  1. Begin by entering the MySQL client CLI:

    Terminal Input
    mysql -uroot -p
  2. Create (or change permissions for) JIRA user

    If you have already created your JIRA user, you must first revoke privileges to prevent the server from accepting an unencrypted connection:

    MySQL CLI Input
    REVOKE ALL on public from '<jira-user>'@'<jira-server-ip-address>';
    MySQL CLI Input
    GRANT ALL on public.* to 'jira'@'<jira-server-ip-address>' identified by 'password' REQUIRE SSL;
  3. Check permissions by attempting to connect to your database from the specified machine with the specified user with the MySQL Client, MySQL Administrator, or other tool. You should not be able to connect without using the SSL certificate.

Perform steps 4 and 5 on your JIRA server

4. Import your keys to your .keystore

The Tomcat server uses the default password 'changeit'. If you would like to use a different password, declare that during the following step, and add the parameter "keystorePassword='password'" to your Tomcat connector.


  1. Copy the resulting *.pem files from your MySQL server to your home folder on your JIRA server.
  2. Run the following command as root or using sudo:

    keytool -import -alias mysqlclientcertificate -file client-cert.pem
  3. Your .keystore will be created in your home folder as ~/.keystore 

5. Configure your JIRA server

  1. Stop JIRA if it is running.
  2. Find the file dbconfig.xml file in your <jira_home> folder.
  3. Edit the section below:

    <url>jdbc:mysql://<mysql-server-address>:3306/public?useUnicode=true&amp;characterEncoding=UTF8&amp;sessionVariables=storage_engine=InnoDB</url>

    so that it looks like this:

    <url>jdbc:mysql://<mysql-server-address>:3306/public?useUnicode=true&amp;characterEncoding=UTF8&amp;sessionVariables=storage_engine=InnoDB&amp;useSSL=true&amp;verifyServerCertificate=false</url>
  4. Find the server.xml file in your JIRA conf folder, typically /opt/atlassian/jira/conf
  5. Uncomment the Connector section as seen below:

             <Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol"
                  maxHttpHeaderSize="8192" SSLEnabled="true"
                  maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
                  enableLookups="false" disableUploadTimeout="true"
                  acceptCount="100" scheme="https" secure="true"
                  clientAuth="false" sslProtocol="TLS" useBodyEncodingForURI="true"
    	      keystoreFile="/some/keystore/path/.keystore"/>
  6. Start JIRA.

Troubleshooting

Here are some troubleshooting tips if you are using a self-signed key created by keytool, as described above.

When you enter "https://localhost:8443" in your browser, if you get a message such as "Cannot establish a connection to the server at localhost:8443", look for error messages in your logs/catalina.out log file. Here are some possible errors with explanations:

Can't find the keystore
java.io.FileNotFoundException: /home/user/.keystore (No such file or directory)

This indicates that Tomcat cannot find the keystore. The keytool utility creates the keystore as a file called .keystore in the current user's home directory. For Unix/Linux the home directory is likely to be /home/<username>. For Windows it is likely to be C:\Documents And Settings\<UserName>.

Make sure you are running JIRA as the same user who created the keystore. If this is not the case, or if you are running JIRA on Windows as a service, you will need to specify where the keystore file is in conf/server.xml. Add the following attribute to the connector tag you uncommented:

keystoreFile="<location of keystore file>"

If you still see the error, your JIRA instance may be configured to run with the permissions of the user 'jira'. In that case, the keystore is in a folder that cannot be accessed by the user jira. Issue the following commands in your shell:

(warning) This step must be performed as the root user, or with the use of sudo

mkdir /home/jira
cp ~/.keystore home/jira/


Certificate reply and certificate in keystore are identical


keytool error: java.lang.Exception: Certificate reply and certificate in keystore are identical

This error will happen if you have identical names or fingerprints, which is the result of attempting to recreate the cert in your existing keystore. If you need to recreate or update the Cert, you may remove the existing keystore and creating a fresh, new keystore. In this case, creating a new keystore and adding the related certs will fix the issue. The default path for it in this documentation is $JAVA_HOME/jre/lib/security/cacerts

Incorrect password
java.io.IOException: Keystore was tampered with, or password was incorrect

You used a different password than "changeit". You must either use "changeit" for both the keystore password and for the key password for Tomcat, or if you want to use a different password, you must specify it using the keystorePass attribute of the Connector tag, as described above.

Passwords don't match
java.io.IOException: Cannot recover key

You specified a different value for the keystore password and the key password for Tomcat. Both passwords must be the same.

Wrong certificate
javax.net.ssl.SSLException: No available certificate corresponds to the SSL cipher suites which are enabled.

If the Keystore has more than one certificate, Tomcat will use the first returned unless otherwise specified in the SSL Connector in conf/server.xml.

Add the keyAlias attribute to the Connector tag you uncommented, with the relevant alias, for example:

 <Connector port="8443" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true" useBodyEncodingForURI="true"
acceptCount="100" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="/opt/local/.keystore"
keystorePass="removed"
keyAlias="tomcat"/>
Using Apache Portable Runtime

APR uses a different SSL engine, and you will see an exception like this in your logs

 SEVERE: Failed to initialize connector [Connector[HTTP/1.1-8443]]
LifecycleException:  Protocol handler initialization failed: java.lang.Exception: No Certificate file specified or invalid file format

The reason for this is that the APR Connector uses OpenSSL and cannot use the keystore in the same way. You can rectify this in one of two ways:

Use the Http11Protocol to handle SSL connections

Edit the server.xml so that the SSL Connector tag you just uncommented specifies the Http11Protocol instead of the APR protocol

<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol"
  maxHttpHeaderSize="8192" SSLEnabled="true" keystoreFile="${user.home}/.keystore"
  maxThreads="150" enableLookups="false" disableUploadTimeout="true"
  acceptCount="100" scheme="https" secure="true"
  clientAuth="false" sslProtocol="TLS" useBodyEncodingForURI="true"/>
Configure the Connector to use the APR protocol

This is only possible if you have PEM encoded certificates and private keys. If you have used OpenSSL to generate your key, then you will have these PEM encoded files - in all other cases contact your certificate provider for assistance.

<Connector
  port="8443" maxThreads="200"
  scheme="https" secure="true" SSLEnabled="true"
  SSLCertificateFile="${user.home}/certificate.pem"
  SSLCertificateKeyFile="${user.home}/key.pem"
  clientAuth="optional" SSLProtocol="TLSv1"/>


Last modified on Jan 13, 2022

Was this helpful?

Yes
No
Provide feedback about this article
Powered by Confluence and Scroll Viewport.