Heroku SSL
Last updated 08 July 2020
Table of Contents
Heroku provides free Automated Certificate Management (ACM) for all applications running on paid dynos in the Common Runtime. With ACM, Heroku automatically provisions and renews SSL certificates for your application.
If you need to upload your own certificate manually, follow the steps in this article.
SSL is a cryptographic protocol that provides end-to-end encryption and integrity for all web requests. Apps that transmit sensitive data should enable SSL to ensure all information is transmitted securely.
The Heroku SSL feature is included for free on any app that uses paid dynos: Hobby, Standard-1X, Standard-2X, Performance-M and Performance-L. Apps using free dynos can use the *.herokuapp.com
certificate if they need SSL.
Behind the scenes Heroku SSL uses Server Name Indication (SNI), an extension of the TLS protocol, which is widely supported in modern browsers. If your application needs to support older browsers and clients, you may need to use an SSL Endpoint instead of Heroku SSL. Please check the Minimum supported browser versions section below for more details.
Manually uploading certificates and intermediaries
Add your certificate, any intermediate certificates bundles, and private key with the certs:add
command.
$ heroku certs:add server.crt server.key
Adding SSL to example... done
exampleapp now served by exemplary-sushi-4gr7rb6h8djkvo9j5zf16mfp.herokudns.com.
Certificate details:
Expires At: 2012-10-31 21:53:18 GMT
Issuer: C=US; ST=CA; L=SF; O=Heroku; CN=www.example.com
Starts At: 2011-11-01 21:53:18 GMT
...
If you want to add intermediate certificate bundles you can pass this as the first argument to the certs:add
command:
$ heroku certs:add intermediary.crt server.crt server.key
At this point, you can verify that your application is serving your certificate by running:
$ openssl s_client -connect <dns target>:443 -servername <your domain>
# e.g. openssl s_client -connect exemplary-sushi-4gr7rb6h8djkvo9j5zf16mfp.herokudns.com:443 -servername www.example.com
Once you have verified that your app is serving your certificate, you must update your DNS settings for each domain on your app. The DNS entry assigned to your app’s domains will be listed after you add your certificate, using the pattern <adjective>-<noun>-<random>.herokudns.com
. In the above example, it would be exemplary-sushi-4gr7rb6h8djkvo9j5zf16mfp.herokudns.com
If you need to review the DNS targets again, simply run heroku domains
to see where you should set it up.
If the “Common Name(s)” (CN) or “Subject Alternative Names” (SAN) fields on your certificate do not match any domains on your application then it will show errors when accessing the site. You will need to check and add a matching custom domain to avoid these errors.
Heroku does not allow private keys to be extracted out of its systems. Make sure to keep a copy safely for yourself in case it needs to be reused anywhere.
Please check View existing domains for the DNS Target format.
SSL certificate details
To get the detailed information about a certificate, use certs:info
.
$ heroku certs:info
Fetching SSL tyrannosaurus-87601 info for exampleapp... done
Certificate details:
Expires At: 2012-10-31 21:53:18 GMT
Issuer: C=US; ST=CA; L=SF; O=Heroku; CN=www.example.com
Starts At: 2011-11-01 21:53:18 GMT
Subject: C=US; ST=CA; L=SF; O=Heroku; CN=www.example.com
...
Verify SSL is setup correctly
Use a command line utility like curl
to test that everything is configured correctly for your secure domain.
$ curl -vI https://www.example.com
* About to connect() to www.example.com port 443 (#0)
* Trying 50.16.234.21... connected
* Connected to www.example.com (50.16.234.21) port 443 (#0)
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using AES256-SHA
* Server certificate:
* subject: C=US; ST=CA; L=SF; O=SFDC; OU=Heroku; CN=www.example.com
* start date: 2011-11-01 17:18:11 GMT
* expire date: 2012-10-31 17:18:11 GMT
* common name: www.example.com (matched)
* issuer: C=US; ST=CA; L=SF; O=SFDC; OU=Heroku; CN=www.heroku.com
* SSL certificate verify ok.
> GET / HTTP/1.1
> User-Agent: curl/7.19.7 (universal-apple-darwin10.0) libcurl/7.19.7 OpenSSL/0.9.8r zlib/1.2.3
> Host: www.example.com
> Accept: */*
...
Pay attention to the output. It should print SSL certificate verify ok
. If it prints something like common name: www.example.com (does not match 'www.somedomain.com')
then something is not configured correctly.
If you use the -k
flag with the curl command, it will result in a connection error if are running curl on many versions of Mac OS X as SNI information is not passed with -k
.
Update certificate
You can update a certificate using the certs:update
command with the new certificate and the new or an existing private key:
$ heroku certs:update server.crt server.key
Updated certificate details:
Common Name(s): www.example.com
Expires At: 2017-03-21 21:35 UTC
Issuer: /C=US/ST=California/L=San Francisco/O=Heroku/OU=Engineering/CN=www.example.com
Starts At: 2016-03-21 21:35 UTC
Subject: /C=US/ST=California/L=San Francisco/O=Heroku/OU=Engineering/CN=www.example.com
Remove certificate
You can remove a certificate using the certs:remove
command
$ heroku certs:remove
Removing SSL certificate tyrannosaurus-87601 (exemplary-sushi-4gr7rb6h8djkvo9j5zf16mfp.herokudns.com) from example... done
Removing a certificate will cease any HTTPS traffic to the certificate’s domain.
Migrate from SSL:Endpoint to Heroku SSL
You can migrate from the SSL:Endpoint add-on to Heroku SSL with zero downtime.
Add the SSL Certificate to your app
$ heroku certs:add example.crt example.key --type sni
You need to use the flag --type sni
if your app already has the SSL Endpoint add-on.
Change your DNS for all domains on your app
Verify your DNS settings by running dig www.yourdomainname.com cname +short
. If it returns something like <adjective>-<noun>-<random>.herokudns.com
then it is likely you have set it up correctly. If you are using an ALIAS or ANAME record, you can verify that based on the DNS provider. For instance, DNSimple will return a TXT record showing how your domain’s ALIAS is set-up.
Please note that it may take up to 24 hours before your DNS is fully propagated globally.
Remove SSL:Endpoint Add-on after 24 hours
If it has been 24 hours since you updated your DNS settings, then you can remove the SSL:Endpoint add-on.
$ heroku addons:destroy ssl
If you ever need to switch back to SSL Endpoint, after you, you can follow the steps in the SSL Endpoint article.
SSL details
Client IP address
When an end-client (often the browser) initiates an SSL request, the request must be decrypted before being sent to your app. This extra SSL termination step obfuscates the originating IP address of the request.
As a workaround, the IP address of the external client is added to the X-Forwarded-For
HTTP request header.
Supported SSL protocols
- TLS 1.0
- TLS 1.1
- TLS 1.2
We do not support SSLv3 for security reasons. The cipher suite in use is curated to strike a balance between security best practices and backwards compatibility.
Heroku SSL does not allow customization of TLS versions or ciphers. If you need more specific TLS versions then these can be customized when using the SSL Endpoint instead - please open a support ticket if you need these to be changed.
Minimum supported browser versions
SNI SSL termination has minimum browser versions that it needs to support. If you have a browser that is less than one of these versions, it will result in a connection error. It is worth noting that the amount of traffic from incompatible browsers is considerably small, less than 0.1% of overall platform traffic. If you need to support legacy versions, then consider using the SSL Endpoint add-on.
Desktop Browsers
- Firefox 2 and above
- Internet Explorer 7 on Windows Vista and above
- Windows Vista or OS X 10.6 with:
- Chrome 5.0.342.0
- Opera 14
- Safari 4
Mobile Browsers
- Mobile Safari on iOS 4.0 and above
- Android 4.0 (“Ice Cream Sandwich”) and above
- Windows Phone 7 and above
Troubleshooting
Internal server error
If you get an Internal server error
when adding your certificate, it may be that you have an outdated version of the Heroku CLI.
Verify your CLI installation and update it to the latest version with heroku update
, or reinstall it.
SSL file types
Many different file types are produced and consumed when creating an SSL certificate.
- A
.csr
file is a certificate signing request, which initiates your certificate request with a certificate provider and contains administrative information about your organization. - A
.key
file is the private key used for your site’s SSL-enabled requests. .pem
and.crt
extensions are often used interchangeably and are both base64 ASCII encoded files. The technical difference is that.pem
files contain both the certificate and key whereas a.crt
file only contains the certificate. In reality this distinction is often ignored.