SSL Endpoint
Last updated June 14, 2023
This article is a work in progress, or documents a feature that is not yet released to all users. This article is unlisted. Only those with the link can access it.
Table of Contents
The SSL Endpoint add-on is deprecated and can no longer be provisioned by customers. Existing SSL Endpoints will continue to work. SSL Endpoints will be migrated starting July 31, 2021 to Heroku SSL. The ultimate shutdown date and end of life of the SSL Endpoint Add-on is October 18, 2021. SSL Endpoint customers will receive additional details via email. All existing and new Heroku applications should use Heroku SSL, which includes Automated Certificate Management (ACM).
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.
To enable SSL on a custom domain, for example, www.example.com
, use the SSL Endpoint add-on.
SSL Endpoint is a paid add-on service. Please keep this in mind when provisioning the service.
SSL Endpoint is only useful for custom domains. All default <appname>-<random-identifier>.herokuapp.com
domains are already SSL-enabled and can be accessed by using https
, for example, https://example-app-1234567890ab.herokuapp.com
.
Overview
Because of the unique nature of SSL validation, provisioning SSL for your application is a multi-step process that involves several third parties. You will need to:
- Purchase an SSL certificate from your SSL provider
- Provision an SSL endpoint from Heroku
- Upload the certificate to Heroku
- Update your DNS settings to reference the new SSL endpoint URL
Acquire SSL certificate
Staging, and other non-production, apps can use a free self-signed SSL certificate instead of purchasing one.
Purchasing an SSL certificate varies in cost and process depending on the vendor. DNSimple and ExpeditedSSL offer simple ways to purchase a certificate and are recommended solutions.
Otherwise, using other SSL providers requires some or all of the following steps.
Generate private key
Before requesting an SSL cert, you need to generate a private key in your local environment using the openssl
tool. If you cannot execute the openssl
command from the terminal you may need to install it.
If you have… | Install with… |
---|---|
Mac OS X | Homebrew: brew install openssl |
Windows | Windows complete package .exe installer |
Ubuntu Linux | apt-get install openssl |
Use openssl
to generate a new private key.
When prompted, enter an easy password value as it will only be used when generating the CSR and not by your app at runtime.
Heroku only supports RSA keys for certs. Elliptic curve (ECC) keys are not supported.
$ openssl genrsa -aes256 -out server.pass.key 4096
...
Enter pass phrase for server.pass.key:
Verifying - Enter pass phrase for server.pass.key:
The private key needs to be stripped of its password so it can be loaded without manually entering the password.
$ openssl rsa -in server.pass.key -out server.key
You now have a server.key
private key file in your current working directory.
Generate CSR
A CSR is a certificate signing request and is also required when purchasing an SSL cert. Using the private key from the previous step, generate the CSR. This will require you to enter identifying information about your organization and domain.
Though most fields are self-explanatory, pay close attention to the following:
Field | Description |
---|---|
Country Name | The two letter code, in ISO 3166-1 format, of the country in which your organization is based. |
Common Name | This is the fully qualified domain name that you wish to secure.
|
The Common Name
field must match the secure domain. You cannot purchase a certificate for the root domain, (for example, example.com
), and expect to secure www.example.com
. The inverse is also true.
Additionally, SSL Endpoint only supports one certificate per app. Please keep this in mind for multi-domain applications and specify a Common Domain
that matches all required domains.
Generate the CSR:
$ openssl req -nodes -new -key server.key -out server.csr
...
Country Name (2 letter code) [AU]:US
Common Name (eg, YOUR name) []:www.example.com
...
The result of this operation will be a server.csr
file in your local directory (alongside the server.key
private key file from the previous step).
Submit CSR to SSL provider
Next, begin the process of creating a new SSL certificate with your chosen certificate provider. This will vary depending on your provider, but at some point you will need to upload the CSR generated in the previous step.
You may also be asked for what web server to create the certificate. If so, select Nginx as the web server for use on Heroku. If Nginx is not an option, Apache 2.x will also suffice.
If you’re given an option of what certificate format to use, such as PKCS or X.509, choose X.509.
If you want to secure more than one subdomain you will need to purchase a wildcard certificate from your provider. While these certificates are typically more expensive, they allow you to serve requests for all subdomains of *.example.com
over SSL.
On completion of the SSL certificate purchase process you should have several files including:
- The SSL certificate for the domain specified in your CSR, downloaded from your certificate provider. This file will have either a
.pem
or.crt
extension. - The private key you generated in the first step,
server.key
.
Setting up SSL on Heroku
Once you have the SSL certificate file and private key you are ready to configure SSL Endpoint for your app. SSL configuration on Heroku depends slightly on where you are deploying your application.
Create the add-on
This step is only necessary for apps in the Common Runtime. Skip this step for apps in Private Spaces.
The SSL Endpoint is deprecated and can no longer be added by customers. See Heroku Support if you believe you need SSL Endpoint features.
Create the add-on with:
$ heroku addons:create ssl:endpoint
Adding ssl:endpoint on example... done, v1 ($20/mo)
Add certificate and intermediaries
Add your certificate, any intermediate certificates, and private key to the endpoint with the certs:add
command. Note that you will need to include the --type endpoint
argument to this command, as seen below.
Heroku automatically strips out unnecessary parts of the certificate chain as part of the certs:add
command. In some scenarios, this may not be desired.
$ heroku certs:add server.crt server.key --type endpoint
Adding SSL Endpoint to example... done
example now served by example-12345.ssl.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
...
The endpoint URL assigned to your app will be listed in the output, example-12345.ssl.herokudns.com
in this example. Visiting this URL will result in a “no such app” message – this is expected. Read further for proper verification steps.
Apps in Private Spaces will have a name in the form of some-name.some-other-name.herokuspace.com
In all cases, the output of the certs:add
command will accurately reflect this.
Endpoint details
You can verify the details of the SSL configuration with heroku certs
.
$ heroku certs
Name Endpoint Common Name(s) Expires Trusted Type
─────────── ───────────────────────── ────────────────── ──────────────────── ─────── ────────
example-2121 example-12345.ssl.herokudns.com www.example.com 2018-06-30 23:59 UTC False Endpoint
To get the detailed information about a certificate, use certs:info
.
$ heroku certs:info
Fetching SSL Endpoint example-12345.ssl.herokudns.com info for example... 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
...
In very rare circumstances, it can take an SSL endpoint an extended period (30 minutes to 2 hours) before it’s provisioned. If you are unable to hit the endpoint URL, please wait that amount of time before proceeding.
DNS and domain configuration
Once the SSL endpoint is provisioned and your certificate is confirmed, you must route requests for your secure domain through the endpoint URL. Unless you’ve already done so, add the domain specified when generating the CSR to your app with:
$ heroku domains:add www.example.com
Added www.example.com to example... done
Please note when using the SSL Endpoint add-on, the DNS target will be shown under Endpoint
when running heroku certs
.
The DNS targets shown under heroku domains
are for use with Heroku SSL or Automated Certificate Management (ACM)
Subdomain
If you’re securing a subdomain, for example, www.example.com
, modify your DNS settings and create a CNAME record to the endpoint or modify the CNAME target if you already have a CNAME record.
Record | Name | Target |
---|---|---|
CNAME |
www |
example-12345.ssl.herokudns.com. |
If you’re using a wildcard certificate your DNS setup will look similar.
Record | Name | Target |
---|---|---|
CNAME |
* |
example-12345.ssl.herokudns.com. |
Root domain
If you’re securing a root domain, for example, example.com
, you must be using a DNS provider that provides CNAME-like functionality at the zone apex.
Modify your DNS settings and create an ALIAS or ANAME record to the endpoint.
Record | Name | Target |
---|---|---|
ALIAS or ANAME |
<empty> or @ |
example-12345.ssl.herokudns.com. |
Testing SSL
Use a command line utility like curl
to test that everything is configured correctly for your secure domain.
The -k
option tells curl to ignore untrusted certificates.
$ curl -kvI 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.
Update certificate
Heroku automatically strips out unnecessary parts of the certificate chain as part of the certs:update
command. In some scenarios, this may not be desired. To avoid this automatic manipulation of the chain, include the --bypass
flag.
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 --endpoint example-12345.ssl.herokudns.com
Updating SSL Endpoint endpoint example-12345.ssl.herokudns.com for example... done
Remove certificate
You can remove a certificate using the certs:remove
command:
$ heroku certs:remove --endpoint example-12345.ssl.herokudns.com
Removing SSL Endpoint endpoint example-12345.ssl.herokudns.com on example... done
Removing a certificate will remove the SSL endpoint so any domain names pointing to it will stop working.
You cannot roll back after removing a certificate. Once the certificate is removed the SSL endpoint is also removed and rolling back will not work.
Removing a certificate does not stop billing. To stop billing, you must remove the SSL endpoint add-on. Remove the add-on with heroku addons:destroy ssl:endpoint
.
If you try to remove the SSL endpoint add-on before the certificate is removed, you will receive an error.
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.
Performance
SSL Endpoint infrastructure is elastic and scales automatically based on historical traffic levels. However, if you plan to switch a lot of traffic to a newly created SSL endpoint or if you expect large spikes, contact Heroku support so we can help with preemptive scaling.
An initial request rate of greater than 150 requests/sec or a doubling of the existing requests/second within a 5 minute period are the thresholds at which you should consider contacting support to pre-warm your endpoint. Please give us at least 2 business days advance notice for these types of requests.
Troubleshooting
Untrusted certificate
In some cases, when running heroku certs
it may list your certificate as untrusted.
$ heroku certs
Endpoint Common Name Expires Trusted
------------------------ ---------------- ----------------------- -------
example-12345.ssl.herokudns.com www.example.com 2012-10-31 21:53:18 GMT False
If this occurs it may be because it is not trusted by Mozilla’s list of root CA’s. If this is the case your certificate should work as you expect for many browsers.
If you have uploaded a certificate that was signed by a root authority but you get the message that it is not trusted, then something is wrong with the certificate. For example, it may be missing intermediary certificates. If so, download the intermediary certificates from your SSL provider and re-run the certs:add
command.
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.
$ heroku certs:add server.crt server.key --type endpoint
Adding SSL endpoint to example... failed
! Internal server error.
! Run 'heroku status' to check for known platform issues.
Verify your CLI installation and update it to the latest version with heroku update
.
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.