I’ve had a few requests to go over setting up a Wildcard SSL cert, especially as it relates to things like CDN’s, subdomains, etc. So I wanted to put a guide out there so people can get help for an issue that is surprisingly frustrating to find information about.

If you’ve read my other guide to setting up SSL, you’ll have a good basis for what we are about to do, and many steps I mention below will be the same. But I’ll go through the whole process anyway, so you won’t have to do the math as to where to stop, change things, and start again on.

Set up your wildcard certificate with Amazon Cloudfront as a CDN subdomain (https://cdn.example.com)

Set up your wildcard certificate with Ghost JS Blogging as a blog subdomain (https://blog.example.com)

Just the code:

BASIC STEPS

Install Open SSL: (almost all of this will be done from the command line)
Is OpenSSL already installed? openssl version If already installed, it should return: OpenSSL X.X.Xx D MON YEAR Where X.X.Xx is the version number (1.0.1a for example) and D MON YEAR is the day month and year – eg something like 31 Mar 2014 If it’s not installed, it will say something like -bash: openssl: command not found In which case you need to install it.

This should lead to the output:
Generating RSA private key, 2048 bit long modulus ......+++............................................................................................................+++ e is 65537 (0x10001) Enter pass phrase for server.pass.key:

Go ahead and enter a passphrase here if you want. I generated a random one with > 14 random digits/numbers/symbols. Be sure to remember this code as you might need it later. Now run:
openssl rsa -in server.pass.key -out server.key

This should lead to the output:
Enter pass phrase for server.pass.key:

Enter the passphrase we entered earlier. Now it should say:
writing RSA key

Once that is complete (instantaneous), run the next command:
openssl req -nodes -new -key server.key -out server.csr

Organizational Unit Name (eg, section) []:
I just used “Web Security” for mine. They are looking for a department (Marketing, etc).

Common Name (e.g. server FQDN or YOUR name) []: BE CAREFUL WITH THIS ONE!For those keeping score from my other article, this is where I start to differ. What we put here is the wildcard URL, eg *.example.com.

Please enter the following 'extra' attributes
Feel free to skip past any last “extra” attribute things, they shouldn’t affect anything.

Purchase and Activate Wildcard SSL certificate from Namecheap
Since we want to have an SSL certificate that works not only on our base domain (eg, example.com and www.example.com) but also our subdomains (blog.example.com, cdn.example.com, etc), we’ll need a wildcard certificate. On Namecheap, the wildcard certificates should be listed here:

They’ll run you anywhere from $94/year – $389/year (current prices: March 2015). If you are wondering what the more expensive wildcard certificates get you, some will give you more robust warranties (the biggest warranty being $1.2 million vs at the low end $5,000), while others will give you a green bar when you go to the website (see: https://globalsign.tbs-certificates.co.uk/images/ev2.jpg), higher levels of encryption, site seals, etc.

Since this guide is about PositiveSSL, let’s go ahead and buy the PositiveSSL Wildcard certificate, which costs $94/year.Once you have purchased some SSL certs, they should appear in your account here:

Click “Activate Now” next to the wildcard SSL certificate you have not yet initiated (the top one in the image, called POSITIVESSL WILDCARD). You will be taken to a new page that asks you to verify some details. First, go back to where you generated the server.csr, server.key, and server.pass.key files. Open up server.csr, and copy everything between the BEGINNING and END blocks. It should look something like:

I’ve obviously put a non working key here, you’ll have to use your own 😉 It might ask for an admin email to send to. While you could setup your own email server, email forwarding will work as well. Go to the list of all your domains, click on your domain, and select “Email Forwarding Setup” from the left hand side. Then create a forwarding email like [email protected]that forwards to [email protected]. After a few minutes, you should get an email that asks you to confirm that you asked to issue a SSL certificate. Click the link provided and enter in the verification code they provided for you.

Create server.crt from certificates emailed to you
We’re almost there! After confirming our SSL certificates, you will get emailed a zip file with the following four files:

It’s now as simple as running the following command from the terminal:
cat STAR_example_com.crt COMODORSADomainValidationSecureServerCA.crt COMODORSAAddTrustCA.crt AddTrustExternalCARoot.crt > server.crt
No need to worry about forgetting to copy certain pieces, or forgetting line breaks, or any of that! Boom! File!

Provision Heroku SSL endpoint
In your rails app folder that you want to add SSL to, run:
heroku addons:add ssl:endpoint
Now gather your server.crt file that you created just a second ago, and find your server.key that you generated from one of the first beginning steps. Once they are all in the same location, run:
heroku certs:add server.crt server.key
You should now see your console say something like:
Adding SSL Endpoint to example... done example now served by xxxx-9999.herokussl.com.
Where XXXX is a fancy name (rosebud), and 9999 is a number (very similar to generating an app on heroku without naming it)

Update your DNS settings on Namecheap
Now either update or create your DNS records on NameCheap to point to the new domains. Go back to all your domains (https://manage.www.namecheap.com/myaccount/domain-list.asp), click on your domain, then click on “All Host records” once that page loads (on the left side list). Your records should look something like: HOST NAME IP ADDRESS/URL RECORD TYPE @ https://www.example.com URL REDIRECT www xxxx-9999.herokussl.com CNAME(ALIAS)

Force SSL on Production
Go to config/environments/production.rb and there should be a commented out line that says: config.force_ssl = true Go ahead and uncomment that line out and push up to Heroku.

Check to make sure SSL is working properly
Did it work? Are we done? Only one way to check. Wait about 10 minutes (usually sooner, mine worked about 2-3 minutes after), and then visit your https website — it should work! Problems? Try using https://www.digicert.com/help/ to check to see what problems it can find with your SSL certificate.

Once installed, it needs to be configured properly. run:
aws configure
And be ready to provide it with an access key id and secret access key. If you don’t have one, create one through the IAM Management console on Amazon, by creating a new user with name something like “example.com-cloudfront-access”, and giving it a policy for CloudFront access.

Once your aws-cli tool is configured properly, we can push up our wildcard certificate to CloudFront. First CD from the terminal into the directory where your server certificate information was (STAR_example_com folder). Before we run the command to upload the SSL certificate, we need to include all intermediary certificates together (COMODORSADomainValidationSecureServerCA.crt, COMODORSAAddTrustCA.crt, and AddTrustExternalCARoot.crt) into a single crt file. This is a huge thing that people miss, and it can cause a bunch of errors / failures when a site does not show up as trusted because an intermediary certificate wasn’t included. So if from ruby, you get some error that looks like:
OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
You might very well check the URL you are looking up to make sure it’s SSL certificate is properly installed (again, I recommend using https://www.digicert.com/help/ to help diagnose any issues).

Now we can upload everything to Cloudfront. Run the following command (I’ll explain the variables after the code):
aws iam upload-server-certificate --server-certificate-name DEMO_DEMO_DEMO --certificate-body file://STAR_example_com.crt --private-key file://server.key --certificate-chain file://certificate-chain.crt --path /cloudfront/
Where DEMO_DEMO_DEMO is a name you’ll recognize once it’s up on Cloudfront, STAR_example_com.crt is a file in the STAR_example_com directory, server.key is the key we generated near the beginning of this guide, certificate-chain.crt is the concatenated intermediary certs that help establish “Trust”, and cloudfront is the path we are uploading to.

Now, login to the Amazon AWS console and go to Cloudfront, clicking on the Cloudfront domain you want to associate with your website. Click the general tab (if you aren’t there already), and then click edit. Then choose the following options:

For “Alternate Domain Names (CNAMEs)”, put down the subdomain you want to use for your CDN (in this example, cdn.example.com). Then select the “Custom SSL Certificate (stored in AWS IAM)” option, and choose the certificate from the dropdown that you uploaded (in this example, DEMO_DEMO_DEMO). For “Custom SSL Client Support”, choose “Only Clients that Support Server Name Indication (SNI)”. While it might be tempting to choose the All Clients option here, if you click through to pricing you get a sticker shock — selecting this option will set you back $600/month. Not for me! Go ahead and click save now that everything is chosen.

Now head back over to Namecheap to complete the subdomain setup. Click on your domain, and go to the host records for your domain (All Host Records from the left sidebar), and setup your CDN subdomain as follows:

Set a new host record with “cdn” as the HOSTNAME, your Cloudfront url (a1b2c3d4e5.cloudfront.net for example) as the IP ADDRESS/ URL, and CNAME as the ALIAS/RECORD TYPE.

20 minutes from now, if everything was configured correctly, https://cdn.example.com should work (but make sure and go and check for errors through https://www.digicert.com/help/ anyways)! Now all that’s left to do is update your heroku config with the right settings. If you originally setup Cloudfront using Heroku’s guide, you’ll have a line in your config/production.rb file that looks like:
config.action_controller.asset_host = ENV["CDN_HOST"]

To set or reset the variable on heroku, simply run from the terminal:
heroku config:set CDN_HOST=cdn.example.com