Skip to content

Rails engine for automatically renewing SSL certificates.

License

Notifications You must be signed in to change notification settings

codevise/cert_watch

Repository files navigation

CertWatch

Gem Version Dependency Status Build Status Coverage Status Code Climate

A Rails engine to manage and automatically obtain, install and renew SSL certificates.

Ingredients

CertWatch consists of the following components:

  • Resque jobs to renew and install certificates.
  • A mixin for models with a cname attribute to request certificats on attribute change.
  • Rake tasks to reinstall certificates on a fresh server

Optionally:

  • An Active Admin resource to manage certificates.
  • An Arbre view component to display certificate status for a given domain.

Requirements

Limitations

  • Requires sudo on the server. The certbot script used to obtain certificates needs root priviledges. This could probably be avoided by using the acme-client gem instead.
  • Works only with webservers that can read certificates from a directory (Tested with HAProxy).

Installation

Add the following lines to your Gemfile and run bundle install:

gem 'cert_watch'

# Required since state_machine gem is unmaintained
gem 'state_machine', git: 'https://github.com/codevise/state_machine.git'

Add an initializer:

# config/initializers/cert_watch.rb
CertWatch.setup do |config|
  # Uncomment any of the below options to change the default

  # Maximum age of certificates before renewal.
  # config.renewal_interval = 1.month

  # Number of expiring certificates to renew in one run of the
  # `RenewExpiringCertificatesJob`.
  # config.renewal_batch_size = 10

  # File name of the certbot executable.
  # config.certbot_executable = '/usr/local/share/letsencrypt/bin/certbot'

  # Port for the standalone certbot HTTP server
  # config.certbot_port = 9999

  # Directory certbot outputs certificates to
  # config.certbot_output_directory = '/etc/letsencrypt/live'

  # Directory the web server reads pem files from
  # config.pem_directory = '/etc/haproxy/ssl/'

  # Place pem files in provider specific subdirectories of pem directory.
  # By default, all pem files are placed in pem directory itself.
  # config.provider_install_directory_mapping = {
  #   certbot: 'letsencrypt',
  #   custom: 'custom'
  # }

  # Command to make server reload pem files
  # config.server_reload_command = '/etc/init.d/haproxy reload'
end

Ensure private keys do not show up in log files:

# config/initializers/filter_parameter_logging.rb
Rails.application.config.filter_parameters += [:private_key]

Include the DomainOwner mixin into a model with a domain attribute. This makes CertWatch obtain or renew certificates whenever the attribute changes. Validation has to be provided by the host application.

# app/models/account.rb
# assuming Account has a cname attribute
class Account
  include CertWatch.domain_owner(attribute: :cname)
end

If you want to use the Active Admin resource, add the following line to the top of your Active Admin initializer:

# config/initializers/active_admin.rb
ActiveAdmin.application.load_paths.unshift(CertWatch.active_admin_load_path)

If you use the CanCan authorization adapter, you also need to add the following rule for users that should be allowed to manage certificats:

# app/models/ability.rb
can :manage, CertWatch::Certificate

Now install migrations and migrate your database:

$ bin/rake cert_watch:install:migrations
$ bin/rake db:migrate

Setup your resque_schedule.yml to check for expiring certificates:

# config/resque_schedule.yml
fetch_billed_traffic_usages:
  every:
    - "5h"
    - :first_in: "1m"
  class: "CertWatch::RenewExpiringCertificatesJob"
  queue: cert_watch
  description: "Check for expiring SSL certificates"

Finally ensure Resque workers have been assigned to the cert_watch queue.

Rake Tasks

Add the following line to your application's Rakefile:

# Rakefile
require 'cert_watch/tasks'

To reinstall all certificates (i.e. on a new server), run:

$ bin/rake cert_watch:reinstall:all

Active Admin View Components

You can render a status tag displaying the current certificate state for a given domain:

# app/admin/dashboard.rb
require 'cert_watch/views/certificate_state'

div(class: 'account_cname') do
  text_node(account.cname)
  cert_watch_certificate_state(account.cname)
end

Troubleshooting

If you run into problems or want to discuss a feature request, please file an issue.

About

Rails engine for automatically renewing SSL certificates.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages