pixielabs / letsencrypt-rails-heroku

Automatic LetsEncrypt SSL certificates in your Rails app on Heroku.
MIT License
220 stars 33 forks source link
heroku-api letsencrypt letsencrypt-certificates middleware rails sni ssl-certificate

LetsEncrypt & Rails & Heroku

WATCH OUT! This gem is deprecated

Since this gem was created, Heroku have added support for free automated SSL certificates for paid dynos (ACM). You should use ACM instead of this gem unless your situation is covered by the known limitations of ACM, e.g. your app runs in Heroku Private Spaces. When we've had issues with ACM, we've had success with the Expedited WAF addon, and you might too.


Gem Version

This gem is a complete solution for securing your Ruby on Rails application on Heroku using their free SNI-based SSL and LetsEncrypt. It will automatically handle renewals and keeping your certificate up to date.

With some extra steps, this gem can also be used with Sinatra. For an example of how to do this, see the letsencrypt-rails-heroku-sinatra-example repository.

Requirements

Installation

Add the gem to your Gemfile:

gem 'letsencrypt-rails-heroku', group: 'production'

And add it as middleware in your config/environments/production.rb:

Rails.application.configure do
  <...>

  config.middleware.use Letsencrypt::Middleware

  <...>
end

If you have configured your app to enforce SSL with the configuration option config.force_ssl = true you will need to insert the middleware in front of the middleware performing that enforcement instead, as LetsEncrypt do not allow redirects on their verification requests:

Rails.application.configure do
  # <...>

  config.middleware.insert_before ActionDispatch::SSL, Letsencrypt::Middleware

  # <...>
end

Configuring

By default the gem will try to use the following set of configuration variables. You must set:

You can also set:

The gem itself will temporarily create additional environment variables during the challenge / validation process:

It will also create two permanent environment variables after the first run:

If you remove these, a new account will be created and new environment variables will be set.

Creating a Heroku token

Use the heroku-oauth toolbelt plugin to generate an access token suitable for accessing the Heroku API to update the certificates. From within your project directory:

> heroku plugins:install heroku-cli-oauth
> heroku authorizations:create -d "LetsEncrypt"
Created OAuth authorization.
  ID:          <heroku-client-id>
  Description: LetsEncrypt
  Scope:       global
  Token:       <heroku-token>

Use the output of that to set the token (HEROKU_TOKEN).

Using for the first time

After deploying, run heroku run rake letsencrypt:renew. Ensure that the output looks good:

$ heroku run rake letsencrypt:renew
Running rake letsencrypt:renew on ⬢ yourapp... ⣷ connecting, run.1234
Creating account key...Done!
Registering with LetsEncrypt...Done!
Setting config vars on Heroku...Done!
Giving config vars time to change...Done!
Testing filename works (to bring up app)...done!
Adding new certificate...Done!
$ 

If this is the first time you have used an SNI-based SSL certificate on your app, you may need to alter your DNS configuration as per Heroku's instructions.

You can see these details by typing heroku domains.

Adding a scheduled task

You should add a scheduled task on Heroku to renew the certificate. If you are unfamiliar with how to do this, take a look at Heroku's documentation on their scheduler addon.

The scheduled task should be configured to run rake letsencrypt:renew as often as you want to renew your certificate. Letsencrypt certificates are valid for 90 days, but there's no harm renewing them more frequently than that.

Heroku Scheduler only lets you run a task as infrequently as once a day, but you don't want to renew your SSL certificate every day (you will hit the rate limit). You can make it run less frequently using a shell control statement. For example to renew your certificate on the 1st day of every month:

if [ "$(date +%d)" = 01 ]; then bundle exec rake letsencrypt:renew; fi

Source: blog.dbrgn.ch

Security considerations

Suggestions and pull requests are welcome in improving the situation with the following security considerations:

Troubleshooting

Common name invalid errors (security certificate is from *.herokuapp.com)

Your domain is still configured as a CNAME or ALIAS to your-app.herokuapp.com. Check the output of heroku domains matches your DNS configuration. When you add an SNI cert to an app for the first time the DNS target changes.

To-do list

Contributing

Generating a new release

  1. Bump the version: rake version:bump:{major,minor,patch}.
  2. Update CHANGELOG.md & commit.
  3. Use rake release to regenerate gemspec, push a tag to git, and push a new .gem to rubygems.org.