Securing Bitbucket Server with Tomcat using SSL

This page describes how to enable HTTPS (HTTP over SSL) access for Apache Tomcat, the application server shipped with Bitbucket Data Center and Server.

Why should I secure Bitbucket using SSL?

You should consider doing this, and making secure access mandatory, if Bitbucket will be internet-facing, which could potentially put usernames, passwords and other proprietary data at risk.

There are other network topology options for running Bitbucket, including running Bitbucket behind a reverse proxy. For an overview of some common options, see Proxying and securing Bitbucket Server.

When Bitbucket is set up using these instructions, access to Bitbucket is direct, and all communication between a user's browser and Bitbucket will be secured using SSL.

Before you begin

The configuration described here results in a scenario where:

  • Bitbucket would listen for requests on port 8443; the port can be changed, if required.
  • Bitbucket would be available at https://<computer name>:8443; the base URL can be changed, if required.
  • As a result, any existing links with other applications would need to be reconfigured using this new URL for Bitbucket.
  • You can set the context path for Bitbucket if you are running another Atlassian application, or Java web application, at the same hostname and context path as Bitbucket.
  • Securing Git operations between the user's computer and Bitbucket is a separate consideration - see Enabling SSH access to Git.


These instructions are for reference use only

Atlassian applications allow the use of SSL within our products, however Atlassian Support does not provide assistance for configuring it. Consequently, Atlassian cannot guarantee providing any support for it.

If you require assistance with conversions of certificates is required, consult the vendor who provided the certificate. Atlassian Support will refer SSL-related support to the issuing authority for the certificate.

Also, these instructions are intended for administrators setting up Bitbucket for a small team. 

Generate a self-signed certificate

Self-signed certificates are useful if you require encryption but do not need to verify the identity of the requesting website. In general, you might use a self-signed certificate on a test environment and on internal corporate networks (intranets).

Because the certificate is not signed by a certificate authority (CA), users may receive a message that the site is not trusted and may have to perform several steps to accept the certificate before they can access the site. This usually occurs the first time they access the site.

This approach to creating a certificate uses Java's keytool, there are other tools for generating certificates are available.

If you are setting up a production instance of Bitbucket, we strongly recommend using a CA certificate (described below), rather than using a self-signed certificate.

To generate a self-signed certificate using Java's keytool utility

  1. Create a new .keystore file in the Bitbucket home directory.

    1. Log in with the user account that has access to Bitbucket home directory (or use sudo alternatively).

    2. Run the following command:

      Windows
      "%JAVA_HOME%\bin\keytool" -genkey -alias tomcat -keyalg RSA -sigalg SHA256withRSA -keystore <Bitbucket home>\shared\config\ssl-keystore
      Linux, macOS
      $JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA -sigalg SHA256withRSA -keystore <Bitbucket home>/shared/config/ssl-keystore

      The default keystore Bitbucket uses is <Bitbucket home directory>/shared/config/ssl-keystore. You can specify different keystore location using the keystore parameter. But, in this case, you will have to include it in the bitbucket.properties file as described in the configuration section.

  2. When asked for a password (the first of two passwords you will set, which must be identical):

    • Specify the password you want to use for the certificate (private key). 
    • The default password Tomcat expects is 'changeit'. If you use any other value you must specify it in the <Bitbucket home directory>/shared/bitbucket.properties file.
    • Make a note of the password as you will need it again in the next step.

  3. Follow the prompts to specify your name, organization and location. This information is used to construct the X.500 Distinguished Name (DN) of the entity.

    The CN ("What is your first and last name?") must match the fully-qualified hostname of the server running Bitbucket, otherwise Tomcat will not be able to use the certificate for SSL. This is the name you would type in your web browser after 'http://' (no port number) to access your Bitbucket installation.

  4. When asked for the password for 'tomcat' (the alias you entered in the keytool command above), press the 'Enter' key. This specifies that your keystore entry will have the same password as your private key. If needed, you can specify different key password.



Configure HTTPS in bitbucket.properties

The default connection for Bitbucket uses an unsecured HTTP connection. Depending on the type of access you require, you can change Bitbucket's default connector (or add additional connectors) to require HTTPS-only access to your instance.

  • To configure HTTPS-only access, you would replace the default connector to require HTTPS-only access.
  • To redirect HTTP requests to a secure HTTPS connection, you would configure the default connector to redirect to an additional, secured connector.

There are a number of ways to configure secure connections depending on your requirements. These instructions describe how to replace Bitbucket's default connector with a secure, HTTPS-only connection by adding configuration properties to the bitbucket.properties file.


To configure HTTPS-only access to Bitbucket

  1. Navigate to your home directory.

    1. Open the shared/bitbucket.properties file and add these properties:

      server.port=8443
      server.ssl.enabled=true
      server.ssl.key-store=/path/to/keystore/bitbucket.jks
      server.ssl.key-store-password=<password value>
      server.ssl.key-password=<password value>
      What these properties do...

      By adding these properties to your bitbucket.properties file you override the default connector values.

      PropertyWhat it does
      server.port=8443Enables SSL access on port 8443 (the default for HTTPS is 443, but 8443 is used here instead of 443 to avoid conflicts)
      server.scheme=https
      Specifies a required URL scheme.
      server.ssl.enabled=true
      Specifies whether SSL enabled (true) or not (false). Setting this to true automatically defaults server.scheme=https and server.secure=true; they do not need to be set explicitly.
      server.ssl.client-auth=need
      Specifies whether client authentication is wanted ("want") or needed ("need"). Requires a trust store.
      server.ssl.protocol=TLSv1.2
      We recommend requiring TLS 1.2. If you have clients that don't support TLS 1.2, don't include this property. The default is"TLS".
      server.ssl.key-alias=<alias>Specifies SSH key values. Only required if non-default alias is used (default value is "tomcat").
      server.ssl.key-store=/path/to/keystore/bitbucket.jks

      Specifies where the keystore is on your filesystem. Only required if you created the keystore in non-default location (other than <Bitbucket home directory>/shared/config/ssl-keystore).

      On Windows...

      On Windows you should use forward-slashes in the path, for example:

      server.ssl.key-store=c:/Atlassian/ApplicationData/Bitbucket/bitbucket.jks

      To use backslashes, they must be doubled (e.g. "C:\\Atlassian\\...")

      server.ssl.key-store-password=<password value>
      Specifies your keystore password. Only required if your keystore password is anything other than the default ("changeit").
      server.ssl.key-password=<password value>
      Specifies your key password. Only required if your key password is anything other than the default ("changeit").
      server.ssl.key-store-type=jks
      Specifies keystore type. Only required if your keystore is anything other than the default ("jks"). Could be "pkcs12" for certificates provided by CA.

      If you created the keystore somewhere else on the filesystem, add the keystoreFile attribute to the connector tag as well. If your keystore password is anything other than "changeit", add keystorePass="<password value>" to the bitbucket.properties file.

  2. Then save the file.

  3. Start (or re-start) Bitbucket.

  4. Access Bitbucket at https://localhost:8443/ in your browser.

Export the self-signed certificate

If you need to export a certificate from the keystore (for example, to be able to import it into another keystore), you should use the following commands.

To export the self-signed certificate, run this command

Windows
"%JAVA_HOME%\bin\keytool" -export -alias tomcat -file file.cer -keystore <Bitbucket home directory>\shared\config\ssl-keystore
Linux, macOS
$JAVA_HOME/bin/keytool -export -alias tomcat -file file.cer -keystore <Bitbucket home directory>/shared/config/ssl-keystore


Request a CA certificate

Digital certificates are issued by a Certification Authority (CA) to verify your website represents your company. When running Bitbucket in a production environment, you need a certificate issued by a CA, such as VeriSignDigiCert or Thawte. The instructions below are adapted from the Tomcat documentation.

First, you will generate a local certificate and create a certificate signing request (CSR) based on that certificate. You then submit the CSR to your chosen certificate authority. The CA will use that CSR to generate a certificate for you.

  1. Use Java's keytool utility to generate a local self-signed certificate, as described in the section above.

  2. Use the keytool utility to generate a CSR. If needed, replace the keystore file name with the path to and filename of the .keystore file you generated for your local certificate:

    Windows
    "%JAVA_HOME%\bin\keytool" -certreq -keyalg RSA -alias tomcat -file certreq.csr -keystore <Bitbucket home>\shared\config\ssl-keystore
    Linux, macOS
    $JAVA_HOME/bin/keytool -certreq -keyalg RSA -alias tomcat -file certreq.csr -keystore <Bitbucket home>/shared/config/ssl-keystore
  3. Submit the generated file called certreq.csr to your chosen certificate authority. Refer to the documentation on the CA's website to find out how to do this.

  4. The CA will send you a certificate.

  5. Import the new certificate into your local keystore. Assuming your certificate is called file.cer, run this command to add the certificate to the keystore:

    Windows
    "%JAVA_HOME%\bin\keytool" -import -alias tomcat -file file.cer -keystore <Bitbucket home>\shared\config\ssl-keystore
    Linux, macOS
    $JAVA_HOME/bin/keytool -import -alias tomcat -file file.cer -keystore <Bitbucket home>/shared/config/ssl-keystore

Troubleshooting

Here are some troubleshooting tips if you are using a self-signed key created by keytool, or a CA certificate, 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 <Bitbucket home>/shared/logs/atlassian-bitbucket.log file. Here are some possible errors with explanations.

SSL + Apache + IE problems

Some people have reported errors when uploading attachments over SSL using Internet Explorer. This is due to an IE bug, and can be fixed in Apache by setting:

BrowserMatch ".MSIE." \
	nokeepalive ssl-unclean-shutdown \
	downgrade-1.0 force-response-1.0

Google has plenty more on this.

Can't find the keystore

 java.io.FileNotFoundException: /var/atlassian/application-data/bitbucket/shared/config/ssl-keystore (No such file or directory)

This indicates that Tomcat cannot find the keystore. By default Bitbucket expects keystore to be available in the file <Bitbucket home directory>/shared/config/ssl-keystore. If you use non-default location, you will need to specify where the keystore file is in <Bitbucket home directory>/shared/bitbucket.properties. Add the following attribute to the connector tag you uncommented:

server.ssl.key-store=${bitbucket.shared.home}/config/ssl-keystore

Additionally, please, make sure you are running Bitbucket as the user who has permission to read the keystore file. 

Incorrect password, or passwords don't match

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

You likely used a different password for your keystore file than the default, which is "changeit", or specified incorrect key password in the bitbucket.properties file.

 java.io.IOException: Cannot recover key
You likely used a different password for your key than the default, which is "changeit", or specified incorrect key password in the bitbucket.properties file.

To check if either of these problems is the case, locate the <Bitbucket home directory>/shared/bitbucket.properties file, and verify these two properties have matching values.

server.ssl.key-store-password=<password value>
server.ssl.key-password=<password value>


Wrong certificate

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

By default, keytool creates certificates that use DSA public key. Make sure you are using -keyalg RSA option when generating certificates.   

If the Keystore has more than one certificate, Tomcat will use the "tomcat" certificate unless otherwise specified in the <Bitbucket home directory>/shared/bitbucket.properties file.

Verify this attribute is set in the bitbucket.properties file.

server.ssl.key-alias=tomcat

Bitbucket does not support APR at the moment.

Enabling client authentication

To enable client authentication in Tomcat, ensure that the value of the server.ssl.client-auth attribute in your bitbucket.properties file is set to "need".

server.ssl.client-auth=need


Wrong certificate type

If the certificate from the CA is in PKSC12 format, add the server.ssl.key-store-type attribute in your bitbucket.properties file with the "PKCS12" value.

server.ssl.key-store=${bitbucket.shared.home}/config/ssl-keystore
server.ssl.key-store-password=changeit
server.ssl.key-store-type=pkcs12

Alternatively, you can import pkcs12 certificate into default JCS keystore using the following command:

keytool -importkeystore -srckeystore <Bitbucket home>/shared/config/certificate.pfx -srcstoretype pkcs12 -srcstorepass exportpass -srcalias <Source keystore alias> -destkeystore <Bitbucket home>/shared/config/ssl-keystore  -deststoretype jks -deststorepass changeit -destalias tomcat


Certificate chain is incomplete

If the root certificate and intermediary certificate(s) aren't imported into the keystore before the entity/domain certificate, you will see the following error:

[root@dev atlas]# $JAVA_HOME/bin/keytool -import -alias tomcat -file my_entity_cert.crt
Enter keystore password:
keytool error: java.lang.Exception: Failed to establish chain from reply

Most likely, the CA sent a compressed file containing several certificates. The import order matters so you must import the root certificate first, followed by one or many intermediate certificates, followed lastly by the entity/domain certificate. There are many resources online that provide guidance for certificate installation for Tomcat (Java-based) web servers using keytool.

Last modified on Feb 25, 2021

Was this helpful?

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