codevise/cert_watch

View on GitHub
README.md

Summary

Maintainability
Test Coverage
# CertWatch

[![Gem Version](https://badge.fury.io/rb/cert_watch.svg)](http://badge.fury.io/rb/cert_watch)
[![Dependency Status](https://gemnasium.com/badges/github.com/codevise/cert_watch.svg)](https://gemnasium.com/github.com/codevise/cert_watch)
[![Build Status](https://travis-ci.org/codevise/cert_watch.svg?branch=master)](https://travis-ci.org/codevise/cert_watch)
[![Coverage Status](https://coveralls.io/repos/github/codevise/cert_watch/badge.svg?branch=master)](https://coveralls.io/github/codevise/cert_watch?branch=master)
[![Code Climate](https://codeclimate.com/github/codevise/cert_watch/badges/gpa.svg)](https://codeclimate.com/github/codevise/cert_watch)

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

* Rails 4
* [Resque](https://github.com/resque/resque)
* [Resque Scheduler](https://github.com/resque/resque-scheduler)
* [Resque Logger](https://github.com/salizzar/resque-logger)
* [Certbot](https://certbot.eff.org/)

## 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](https://github.com/unixcharles/acme-client)
  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`:

```ruby
gem 'cert_watch'

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

Add an initializer:

```ruby
# 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:

```ruby
# 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.

```ruby
# 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:

```ruby
# 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:

```ruby
# 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`:

```ruby
# 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:

```ruby
# 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](https://github.com/codevise/cert_watch/issues?state=open).