How do you install a LetsEncrypt SSL Certificate on Heroku - ruby-on-rails

Since Heroku is read-only and does not allow sudo, what do I need to do to be able to install the LetsEncrypt.org certificate on their server for my app?
If I have already set config.force_ssl = true does that matter?

I read the blog post in the first answer here, but I didn't want to pollute my code-base with ACME urls & logic. So I did something similar, but used DNS domain validation ...
With certbot, specify DNS as your preferred challenge:
sudo certbot certonly --manual --preferred-challenges dns
After a couple of prompts, certbot will tell you to deply a DNS TXT record to validate your domain:
Please deploy a DNS TXT record under the name
_acme-challenge.www.codesy.io with the following value:
CxYdvM...5WvXR0
Once this is deployed,
Press ENTER to continue
Your domain registrar probably has its own docs for deploying a TXT record. Do that, and go back to certbot and press ENTER - Let's Encrypt will check the TXT record, sign the cert, and certbot will save it for you to upload to heroku.
See my own blog post for more detail.
Here are two bash functions that you can use to automate the process for you
function makessl {
sudo certbot certonly --manual --rsa-key-size 4096 --preferred-challenges dns -d ${1}
sudo heroku certs:add --type=sni /etc/letsencrypt/live/${1}/fullchain.pem /etc/letsencrypt/live/${1}/privkey.pem
}
function renewssl {
sudo certbot certonly --manual --rsa-key-size 4096 --preferred-challenges dns -d ${1}
sudo heroku certs:update /etc/letsencrypt/live/${1}/fullchain.pem /etc/letsencrypt/live/${1}/privkey.pem
}
They take an arguement for the domain name and as long as you run them from within your heroku app folder you will not have to specify an --app NAME
Example: makessl www.domain.com
Example: renewssl www.domain.com
Combine this is #Eric's answer and you're good to go:
heroku certs:auto:enable

FYI, Heroku now offers automated certificate management w/ Let's Encrypt if you run a paid dyno. You can enable it with:
heroku certs:auto:enable
More info:
https://devcenter.heroku.com/articles/automated-certificate-management

Edit: This answer no longer applies.
It was written before Heroku implemented native support for LetsEncrypt. Leaving the rest for posterity, but this is no longer necessary. Use #Eric's answer now.
Installing the initial certificate
You can use certbot in manual mode to generate the challenge response, modify your site to return that response, then finally complete the certbot manual process.
See this blog post by Daniel Morrison, or the linked answer under Certificate Updates below, for more details.
Certificate updates
As #Flimm mentioned, and as is mentioned in the linked blog post, you'll have to update this every 3 months until Heroku provides better support for LetsEncrypt. You can make that process smoother (no code changes to upload) using an environment variable as described in this answer (Node/Express but the concepts are the same): https://stackoverflow.com/a/40199581/37168
Sabayon
There is a GitHub project that can automate all of this for you by setting your Heroku environment variables. It's a tiny webapp you install as another Heroku app that in turn configures your primary app. I haven't tried it yet but am planning to use it instead of updating my cert next time: https://github.com/dmathieu/sabayon

The default recommendation of Heroku is SSL using Server Name Indication
(SNI), which is free. Since you already obtained your certificate and key, you can add them by:
heroku certs:add <cert>.pem <key>.key
If you need to support legacy browser clients which do not support SNI use the Herkou SSL Endpoint addon which costs $20/mo:
Add that addon by running
heroku addons:create ssl:endpoint
And then add your LetsEncrypt.org certificates:
heroku certs:add <cert>.pem <key>.key

the best way can be to assign the new ssl domain(that starts with https) to your domain which automatically overrides the non-http domain

I created a certbot plugin that uses the Heroku CLI to automate authentication and installation of Let's Encrypt certificates: https://github.com/gboudreau/certbot-heroku
I only have an example that uses the php-nginx Heroku buildpack, but reading that example and finding the equivalent for other buildpacks should be easy enough.
Pull Requests are welcome to help others!

Related

Rails - Configuring DNS to host with Heroku (123-reg)

I am trying to figure out how to publish my app on heroku. My DNS is with 123-reg. 123-reg does not provide any support for heroku deployment and vice versa.
I have previously asked this question (voted down and mocked in the comments)
Rails, Heroku - configuring 123-reg domain for heroku
I'm asking again in the hope of finding some substantive help on how to get this working.
Currently, when I try to render the page using my custom domain name, I get an error that says:
This site can’t be reached
www.mydomainname.com ’s server DNS address could not be found.
Try running Network Diagnostics.
DNS_PROBE_FINISHED_NXDOMAIN
When I try the following in the terminal, I get the responses noted below:
host www.mycustomdomainname.com
Host www.mycustomdomainname.com not found: 3(NXDOMAIN)
host https://www.mycustomdomainname.com
Host https://www.mycustomdomainname.com not found: 2(SERVFAIL)
dig www.mycustomdomainname.com cname +short
myherokualias.herokudns.com
heroku domains returns the heroku alias both with and without the www prefix.
In my DNS, I have a CNAME record with:
DNS ENTRY TYPE PRIORITY TTL DESTINATION/TARGET
www CNAME mycustomdomainname.herokudns.com.
Apart from that I have MX and TXT records for my email account.
Can anyone see what I need to do to get the page to render using my custom domain name?
When I try:
curl -vI https://www.mycustomdomainname.com
* Rebuilt URL to: https://www.mycustomdomainname.com/
* Could not resolve host: www.mycustomdomainname.com
* Closing connection 0
curl: (6) Could not resolve host: www.mycustomdomainname.com
I'm lost for things to try to get this working
HEROKU SETTINGS
I can see from inspecting my heroku Production Check, that I have the following issues:
FAILED DNS configuration
Your DNS is not configured correctly. Your domain "mycustomdomain.com"'s ALIAS or ANAME record should point to ancient-water-74339.herokuapp.com.
However, it also says:
PASSED Heroku SSL
The Heroku SSL instructions say:
Change your DNS for all domains on your app
Verify your DNS settings by running dig www.yourdomainname.com cname +short. If it returns www.yourdomainname.com.herokudns.com then 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.
You should note that it may take up to 24 hours before your DNS is fully propagated globally.
To me, that means I'm supposed to replace the reference to 'herokuapp' with a reference to 'herokudns'. Also, I am reading these instructions to require that I replace 'ancient-water-74339' with a 'mycustomdomainname'.
I have done this (as I understand the instructions) so that the CNAME on my DNS now points to 'mycustomdomainname'.herokudns.com.
The heroku production check says that this is incorrect. Am I supposed to have 2 CNAME records (one using the heroku alias.herokuapp) and another using 'mycustomdomainname'.herokudns?
I tried to use the LetsEncrypt_plugin gem for rails. I cannot verify whether there is an error in that config because that gem does not provide support for heroku.
Can anyone see what I'm supposed to do to get out of this configuration hell?
The heroku production check instructions for DNS with SSL give instructions to provision an SSL Endpoint. The SSL Endpoint instructions say they are only for legacy clients (I don't know what a legacy client is), but that page suggests using the Heroku SSL instead. Those instructions say to use 'herokudns.com' on the end of the app name.
I can't seem to get any combination of these instructions to work.
Checklist
On your DNS provider make sure your CNAME record is properly set:
Host: *
Points To: yourapp.herokussl.com
How to add a CNAME record in 123-reg
On Heroku go to 'Resources' and make sure you have the SSL add-on installed.
On Heroku go to 'Settings/Domains and certificates' and make sure you have your custom domains correctly set:
Domain Name: *.yourdomain.com
DNS Target: yourapp.herokussl.com
Please note the url on herokuapp.com and herokussl.com may differ. If you are using an SSL certificate you'll have to use the latter.
Gotchas
Using the heroku toolbelt make sure your SSL certificate is still trusted
heroku certs:info --app yourapp
Your registrar and your DNS provider may differ, this may lead you to be editing your CNAME records on the incorrect place.
To make sure you are at the right spot perform a whois on your domain:
whois yourdomain.com | grep 'Name Server'
If your domain is actually pointing to 123-reg, the output should be:
Name Server: ns1-123-reg.co.uk
Name Server: ns2-123-reg.co.uk
If the output is something else, then you probably should be setting your CNAME records elsewhere.
Hope this helps <3
After pointing your domain to Heroku app on your Heroku dashboard, go to settings tab and scroll down to custom domain. There click on ADD DOMAIN and add your custom domain.
According to your explanation, the CNAME record is set up correctly for the domain.
Please make sure the domain is added from the Heroku end properly. This guide may help you https://devcenter.heroku.com/articles/custom-domains

Can a Rails app be deployed without using Heroku Toolbelt? If so, how?

I want to deploy rails app without using Heroku ToolBelt. Is it possible? If so, how? I'm only allowed to use Heroku dashboard; I'm not allowed to use any other cloud service :(
I have to run PostgreSQL commands, adding add-ons and setting configuration variables and possibly other tasks for which we have Heroku Toolbelt to deploy a application in production environment.
Error:
user#xx ~/Desktop/github/blog (master)
$ git push git#heroku.com:herokugui.git master
Permission denied (publickey).
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
I don't want to use Heroku Toolbelt. That's why I am using Git commands to deploy code on Heroku. I am not able to push code to Heroku using Git commands. Is it possible to do this task without the toolbelt?
Another question I have is: is there any way to run PostgreSQL commands on Heroku GUI? If so, how?
It's not easy (as with Heroku toolbelt), but it's possible. It involves hanging around your Heroku dashboard at least, so make sure you can access it.
First off, you need a key. If you're on a Linux machine (as me), then in your home directory you should have a folder named .ssh (it may be hidden, hit Ctrl+H to reveal, again, if Linux) and a file id_rsa.pub in there. If not, you need to generate your SSH key first.
ssh-keygen -t rsa
That will prompt you for a folder, default is fine, just hit Enter, then enter the passphrase (twice) to protect your key from being accessed by anyone else on your computer: without a passphrase it's unencrypted and free for anyone to take and use from that machine.
Once that is done, locate your public key file: id_rsa.pub. Note: not id_rsa, it's a private key, you may not want to give it to anyone, it's much like your future Heroku password, except for it's insanely large for a password. Open id_rsa.pub, you should see stuff like:
ssh-rsa aWhOLELotofUnreadABLEGibbERishWHiCHiSactUALLyYourPubLIcKeY...
You need to enter that line into your account settings in Heroku dashboard, under SSH Keys. You can find more info on keys here, in Heroku docs. Make sure Heroku actually recognizes you by issuing this:
ssh -v git#heroku.com
It should state you're authenticated.
Now for the git address. I assume you know your way around git, so I'll keep it short: you'll need to derive your repository address from your app name. Heroku usually generates weird (yet somewhat poetic) names like falling-wind-1624 or shielded-fjord-1858. I'll take the first one as an example, this is how you add its address as a git remote:
git remote add heroku git#heroku.com:falling-wind-1624.git
I'll explain a bit of it below. So what the toolbelt does here, is to use your app name only, it just builds the URL the same way by adding a path to Heroku server. Once that's done, you should be able to push your code:
git push heroku master
I've named a Heroku remote heroku, above, that's why I'm using heroku name here, you can name it whatever you want and use this afterwards. Once you've pushed the code, the rest is up to you.

How should I refer to my SSL certificate in Heroku from my puma.rb?

I am using Heroku with RoR and Puma for my webserver. I am not using a custom domain (myapp.herokuapp.com). I want to add SSL support. Should I add the certificate to my repo and commit it with the config/puma.rb file that refers to them? It seems insecure to have my certificate in git.
Based on this I need to add a line like this:
bind 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert'
If you aren't using a custom domain you can piggy back on heroku's certificate.
Basically you can just run
heroku addons:add ssl:piggyback
If you decide to start using a custom domain and want to use your own certificate then you need to use the ssl-endpoint add on. It's fine to commit your certificate to source control IMO. So long as it's not a public repository.

Heroku SSL EndPoint -- update cert gives Internal server error

I have a COMODO wildcard SSL certificate that I am trying to replace my old SSL certificate with.
I followed the guides here:
https://devcenter.heroku.com/articles/ssl-endpoint
http://ryan.mcgeary.org/2011/09/16/how-to-add-a-dnsimple-ssl-certificate-to-heroku/
Based off of these, I combined them in to one .pem:
cat STAR_[domain]_com.crt /
EssentialSSLCA_2.crt /
ComodoUTNSGCCA.crt /
UTNAddTrustSGCCA.crt /
AddTrustExternalCARoot.crt >> STAR_[domain]_com-bundle.pem
I then ran:
heroku certs:update STAR_[domain]_com-bundle.pem server.key
and I receive:
Updating SSL Endpoint hyogo-2759.herokussl.com for [heroku-app]... failed
! Internal server error.
! Run `heroku status` to check for known platform issues.
Thanks for your time
So, the skinny is that Heroku's error messages were not very good and/or were not expecting what I gave them, hence the Internal Server Error lacking any specifics.
Heroku got back to me and said they will look in to better error messages for this, but I doubt that will happen.
The solution:
Instead of using the .pem extension, use .crt

Has anyone successfully deployed on heroku from a windows platform?

I've been reading all kinds of tutorials on how to deploy rails apps on heroku from windows.
I've tried installing git, heroku gem, generating ssh keys and setting paths and everything...
I get either public key error (without putty) or fatal no auth found (with putty)...
After some setup problems -- indeed related to SSH keys -- I've successfully developed Rails/Sinatra applications on Windows and deployed those to Heroku. It works fine.
Generating the keys was a challenge -- I didn't keep notes, but I think I generated the keys with the Git GUI in which you can create a OpenSSH key. That key file is stored in ~/.ssh (so within C:\Documents and Settings\<account>\.ssh) as id_rsa with an accompanying id_rsa.pub. Since I wanted a seperate key for use in Heroku, I've renamed both files of the key pair to id_heroku / id_heroku.pub.
Finally, in the same folder, I've created a file config. That file contains
Host heroku.com
Hostname heroku.com
Port 22
IdentitiesOnly yes
IdentityFile ~/.ssh/id_heroku
TCPKeepAlive yes
User user#example.com
Alternately, you may utilize puTTYgen.exe , and paste the OpenSSH public key into a mykey.pub file, and uploading that with heroku keys:add c:\mykey.pub

Resources