Securing Bamboo with Tomcat using SSL
This page in intended for administrators setting up Bamboo for a small team. It describes how to enable HTTPS (HTTP over SSL) access for Tomcat, the webserver distributed with Bamboo, using a self-signed certificate. You should consider doing this, and making secure access mandatory, if Bamboo will be internet-facing and usernames, passwords and other proprietary data may be at risk.
If you are setting up a production instance you should consider using a CA certificate, briefly described below.
Note that you can set up Bamboo to run behind a web server, such as Apache HTTP Server. To secure Bamboo with HTTPS, when Apache HTTP Server acts as a reverse proxy for Bamboo, see Integrating Bamboo with Apache HTTP Server.
Please note that Atlassian Support will refer SSL-related support to the issuing authority for the certificate. The documentation on this page is for reference only.
On this page:
Related pages:
1. Generate a self-signed certificate
Self-signed certificates are useful where you require encryption but do not need to verify the website identity. They are commonly used for testing and on internal corporate networks (intranets).
Users may receive a warning that the site is untrusted and have to "accept" the certificate before they can access the site. This usually will only occur the first time they access the site.
The following approach to creating a certificate uses Java's keytool, for Java 1.6. Other tools for generating certificates are available.
To generate a self-signed certificate:
Log in with the user account that Bamboo will run under, and run the following command:
Windows"%JAVA_HOME%\bin\keytool" -genkey -alias tomcat -keyalg RSA
Linux, MacOS and Unix
$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA
This will create (if it doesn't already exist) a new.keystorefile located in the home directory of the user you used to run the keytool command.
Note the following:
- When running the keytool command you will be prompted with:
What is your first and last name?
You must enter the fully qualified hostname of the server running Bamboo. This is the name you would type in your web browser after 'http://' (no port number) to access your Bamboo installation. The qualified host name should match the base URL you have set in Bamboo (without the port number).
- The keytool utility will also prompt you for two passwords: the keystore password and the key password for Tomcat.
You must use the same value for both passwords, and the value must be either:
- "changeit", which is the default value Tomcat expects, or
- any other value, but you must also specify it in
conf/server.xmlfile by adding the following attribute to the<Connector/>→<SSLHostConfig/>-><Certificate/>tag:certificateKeystorePassword="<password value>"
2. Configure HTTPS in Tomcat
To configure HTTPS in Tomcat:
Edit
conf/server.xmland, at the bottom, before the</Service>tag, add this section (or uncomment it if it already exists). Place it inside a<Connector ...>element, using thecertificateKeystoreFileattribute within<SSLHostConfig>and the<Certificate>element:<Connector port="8443" maxHttpHeaderSize="8192" SSLEnabled="true" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" disableUploadTimeout="true" useBodyEncodingForURI="true" acceptCount="100" scheme="https" secure="true"> <SSLHostConfig sslProtocol="TLS" certificateVerification="none"> <Certificate certificateKeystoreFile="/path/to/.keystore"/> </SSLHostConfig> </Connector>This enables SSL access on port 8443 (the default for HTTPS is 443, but 8443 is used instead of 443 to avoid conflicts).
Exporting the self-signed certificate
If Bamboo will run as the user who ran the keytool --genkey command, you do not need to export the certificate.
You may need to export the self-signed certificate, so that you can import it into a different keystore, if Bamboo will not be run as the user executing keytool --genkey. You can do so with the following command:
Windows
"%JAVA_HOME%\bin\keytool" -export -alias tomcat -file file.cer
Linux, MacOS and Unix
$JAVA_HOME/bin/keytool -export -alias tomcat -file file.cer
If you generate the certificate as one user and run Bamboo as another, you'll need to do the certificate export as the generating user and the import as the target user.
Requesting a CA certificate
Digital certificates that are issued by trusted 3rd party CAs (Certification Authorities) provide verification that your website does indeed represent your company.
When running Bamboo in a production environment, you will need a certificate issued by a CA, such as VeriSign, DigiCert 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.
- Use Java's
keytoolutility to generate a local certificate, as described in the section above. Use the
keytoolutility to generate a CSR, replacing the text<MY_KEYSTORE_FILENAME>with the path to and file name of the.keystorefile generated for your local certificate:
Windows"%JAVA_HOME%\bin\keytool" -certreq -keyalg RSA -alias tomcat -file certreq.csr -keystore <MY_KEYSTORE_FILENAME>Linux, MacOS and Unix
$JAVA_HOME/bin/keytool -certreq -keyalg RSA -alias tomcat -file certreq.csr -keystore <MY_KEYSTORE_FILENAME>- Submit the generated file called
certreq.csrto your chosen certificate authority. Refer to the documentation on the CA's website to find out how to do this. - The CA will send you a certificate.
Import the new certificate into your local keystore. Assuming your certificate is called "file.cer" whether obtained from a CA or self-generated, the following command will add the certificate to the keystore:
Windows"%JAVA_HOME%\bin\keytool" -import -alias tomcat -file file.cerLinux, MacOS and Unix$JAVA_HOME/bin/keytool -import -alias tomcat -file file.cer
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 logs/catalina.out log file. Here are some possible errors with explanations:
SSL + Apache + IE problems
Some people have reported errors when uploading attachments over SSL using IE. 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: /home/user/.keystore (No such file or directory)
This indicates that Tomcat cannot find the keystore. In Tomcat 10, HTTPS should be configured using the SSLHostConfig/Certificate, and Tomcat no longer implicitly uses ${user.home}/.keystore. You must explicitly point Tomcat to your key material (keystore or PEM files) in conf/server.xml using absolute paths.
Make sure you are running Bamboo/Tomcat as a user that can read the keystore (or PEM) files. If Bamboo runs as a service, confirm the service account has file-system access.
Specify the keystore in server.xml like this:
<Connector>
<!-- ... -->
<SSLHostConfig>
<Certificate
certificateKeystoreFile="/absolute/path/to/your/keystore"
certificateKeystorePassword="changeit"/>
</SSLHostConfig>
</Connector>
If you use PEM files instead of a keystore, configure:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true">
<SSLHostConfig>
<Certificate
certificateFile="/absolute/path/to/cert.pem"
certificateKeyFile="/absolute/path/to/key.pem"
certificateChainFile="/absolute/path/to/chain.pem"/>
</SSLHostConfig>
</Connector>
On Linux, paths typically look like /etc/ssl/... or /home/<username>/...
On Windows, paths usually look like C:\path\to...
Ensure the running user can read these files.
Incorrect password
java.io.IOException: Keystore was tampered with, or password was incorrect
You used a different password than "changeit". You must do one of the following:
- Use "changeit" for both the keystore password and for the key password for Tomcat.
- If you want to use a different password, specify it using the
certificateKeystorePasswordattribute of the<Connector/>→<SSLHostConfig/>-><Certificate/>tag.
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 certificateKeyAlias attribute to the <Connector/> → <SSLHostConfig/> -> <Certificate/> tag you uncommented, with the relevant alias, for example:
<Connector port="8443"
SSLEnabled="true"
maxThreads="150"
minSpareThreads="25"
maxSpareThreads="75"
acceptCount="100"
scheme="https"
secure="true">
<SSLHostConfig sslProtocol="TLS" certificateVerification="none">
<Certificate
certificateKeystoreFile="/opt/local/keystore.p12"
certificateKeystorePassword="removed"
certificateKeyAlias="tomcat"/>
</SSLHostConfig>
</Connector>
Using Apache Portable Runtime
Using Apache Portable Runtime (Tomcat 10)
APR uses a different SSL engine, and you may 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
In Tomcat 10, rectify this in one of two ways:
Use the NIO protocol (JSSE) to handle SSL connections
Edit server.xml so the SSL Connector uses the NIO protocol and SSLHostConfig/Certificate:
<Connector port="8443"
protocol="org.apache.coyote.http11.Http11NioProtocol"
maxHttpHeaderSize="8192"
SSLEnabled="true"
maxThreads="150"
enableLookups="false"
disableUploadTimeout="true"
acceptCount="100"
scheme="https"
secure="true"
useBodyEncodingForURI="true">
<SSLHostConfig protocols="TLSv1.2,TLSv1.3" certificateVerification="none">
<Certificate
certificateKeystoreFile="${user.home}/.keystore"
certificateKeystorePassword="changeit"/>
</SSLHostConfig>
</Connector>
Configure the Connector to use PEM (OpenSSL via Tomcat Native)
This is only possible if you have PEM-encoded certificates and private keys.
<Connector port="8443"
protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="200"
scheme="https"
secure="true"
SSLEnabled="true">
<SSLHostConfig protocols="TLSv1.2,TLSv1.3" certificateVerification="optional">
<Certificate
certificateFile="${user.home}/certificate.pem"
certificateKeyFile="${user.home}/key.pem"/>
</SSLHostConfig>
</Connector>
Enabling client authentication
To enable client authentication in Tomcat, ensure that the value of the certificateVerification attribute in your Connector → SSLHostConfig element of your Tomcat's server.xml file is required.
<Connector>
<!-- ... -->
<SSLHostConfig certificateVerification="required">
<Certificate/>
</SSLHostConfig>
</Connector>
For more information about Connector element parameters, please refer to the 'SSL Support' section of the Tomcat 10.1 documentation.
Wrong certificate type
If the certificate from the CA is in PKSC12 format, add the certificateKeystoreType attribute to the SSL Connector → <SSLHostConfig/> -> <Certificate/> in conf/server.xml.
<Connector>
<!-- ... -->
<SSLHostConfig>
<Certificate
certificateKeystoreFile="/opt/local/wildcard_atlassian_com.p12"
certificateKeystorePassword="removed"
certificateKeystoreType="PKCS12"/>
</SSLHostConfig>
</Connector>
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]# /usr/java/jdk1.7.0_17/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.