Commit 084a58d7 by Martin Fitzpatrick Committed by Fred Smith

Support for Let's Encrypt

Implements automatic installation of SSL certificates for nginx using
Let's Encrypt certbot service.

Installs the certbot-auto and runs with list of domains specified in
LETS_ENCRYPT_DOMAINS. Validates with the Let's Encrypt server using
ACME http-01 (.well-known/acme) on a customisable port. This requires
an nginx server to be running.

Resulting certificates are symlinked to nginx certificate folder
and nginx configuration updated to match. To simplify the nginx
config-changing setup the ssl certificate configuration is moved
to a separate file for all dependent nginx sites.

Cronjob is installed to auto-update the certs in place on the
recommended twice-daily schedule.

Based on initial work by @tkeemon at:
https://github.com/tkeemon/configuration/tree/hackathon2016/lets-encrypt
parent 5557f1f9
---
- hosts: localhost
gather_facts: False
vars:
EDXAPP_LMS_NGINX_PORT: '80'
EDXAPP_LMS_NGINX_PORT: '80'
roles:
- role: nginx
nginx_sites:
- lms
- cms
nginx_default_site:
- lms
- lets_encrypt
......@@ -14,6 +14,7 @@
LETS_ENCRYPT_DOMAINS: []
LETS_ENCRYPT_EMAIL: !!null
LETS_ENCRYPT_PORT: 80
#
# OS packages
......
......@@ -25,14 +25,16 @@
fail:
msg: "Domain list is empty"
when: LETS_ENCRYPT_DOMAINS|length < 1
tags:
- install
- update
- name: install deps
debug: TODO
- name: "Install let's encrypt"
- name: install certbot
git:
repo: https://github.com/letsencrypt/letsencrypt
dest: /opt/letsencrypt
repo: https://github.com/certbot/certbot
dest: /opt/certbot
tags:
- install
- name: create .well-known directory
file:
......@@ -40,20 +42,67 @@
state: directory
owner: www-data
group: www-data
- name: "render let's encrypt script"
tags:
- install
- update
- name: render certbot script
template:
src: run_lets_encrypt.sh.j2
dest: /tmp/run_lets_encrypt.sh
src: run_certbot.sh.j2
dest: /tmp/run_certbot.sh
mode: u+x
tags:
- install
- update
- name: run certbot
command: /tmp/run_certbot.sh
tags:
- install
- update
- name: "run let's encrypt"
command: /tmp/run_lets_encrypt.sh
# Create symlinks to the letsencrypt certificates into
# the main cert folder. When requesting multi-domain
# certs they are shared: symlink only required to the first
- name: symlink certificates
file: >
src=/etc/letsencrypt/live/{{ LETS_ENCRYPT_DOMAINS|first }}/{{ item.src }}
dest=/etc/ssl/{{ item.dest }}
state=link
with_items:
- { src: 'fullchain.pem', dest: 'certs/fullchain.pem' }
- { src: 'privkey.pem', dest: 'private/privkey.pem' }
tags:
- install
- name: replace nginx cert configuration file
template:
src: ssl-certs.conf.j2
dest: /etc/nginx/ssl-certs.conf
owner: root
tags:
- install
- install:configuration
- name: create auto-renew cron job
debug: Ask the intern
# Renewal will auto-update the certs in place at the linked-to locations
# checks twice daily @ 6hr±60mins
- name: create monthly auto-renew cron job
cron:
name : "Renew Let's Encrypt certificates via certbot"
hour : 0,12
cron_file : "lets-encrypt-renew"
user : "root"
job : sleep $[RANDOM\%60]m; /opt/certbot/certbot-auto renew
state : present
tags:
- install
- install:cron
- name: reload nginx config
service:
name: nginx
state: reloaded
tags:
- install
- update
#!/bin/bash
/opt/certbot/certbot-auto certonly --webroot --webroot-path=/usr/share/nginx/www --non-interactive --email {{ LETS_ENCRYPT_EMAIL }} --agree-tos --http-01-port {{ LETS_ENCRYPT_PORT }} {% for domain in LETS_ENCRYPT_DOMAINS -%} -d {{ domain }} {%- endfor -%}
#!/bin/bash
/opt/letsencrypt/letsencrypt-auto certonly -a webroot --webroot-path=/usr/share/nginx/www --non-interactive --email {{ LETS_ENCRYPT_EMAIL }} --agree-tos {% for domain in LETS_ENCRYPT_DOMAINS -%} -d {{ domain }} {%- endfor -%}
ssl_certificate /etc/ssl/certs/fullchain.pem;
ssl_certificate_key /etc/ssl/private/privkey.pem;
......@@ -91,6 +91,7 @@
with_items:
- { src: 'etc/nginx/nginx.conf.j2', dest: '/etc/nginx/nginx.conf', group: '{{ common_web_user }}', mode: "0644" }
- { src: 'edx/app/nginx/sites-available/edx-release.j2', dest: '{{ nginx_sites_available_dir }}/edx-release', group: 'root', mode: "0600" }
- { src: 'etc/nginx/ssl-certs.conf.j2', dest: '/etc/nginx/ssl-certs.conf', group: '{{ common_web_user }}', mode: "0644" }
notify: restart nginx
tags:
- install
......
......@@ -36,8 +36,8 @@ error_page {{ k }} {{ v }};
listen {{ EDXAPP_CMS_SSL_NGINX_PORT }} ssl;
ssl_certificate /etc/ssl/certs/{{ NGINX_SSL_CERTIFICATE|basename }};
ssl_certificate_key /etc/ssl/private/{{ NGINX_SSL_KEY|basename }};
include /etc/nginx/ssl-certs.conf;
# request the browser to use SSL for all connections
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
{% endif %}
......
......@@ -22,9 +22,9 @@ server {
listen {{ CREDENTIALS_NGINX_PORT }} {{ default_site }};
listen {{ CREDENTIALS_SSL_NGINX_PORT }} ssl;
include /etc/nginx/ssl-certs.conf;
ssl_certificate /etc/ssl/certs/{{ NGINX_SSL_CERTIFICATE|basename }};
ssl_certificate_key /etc/ssl/private/{{ NGINX_SSL_KEY|basename }};
# request the browser to use SSL for all connections
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
......
......@@ -24,8 +24,8 @@ server {
listen {{ ECOMMERCE_SSL_NGINX_PORT }} ssl;
ssl_certificate /etc/ssl/certs/{{ NGINX_SSL_CERTIFICATE|basename }};
ssl_certificate_key /etc/ssl/private/{{ NGINX_SSL_KEY|basename }};
include /etc/nginx/ssl-certs.conf;
# request the browser to use SSL for all connections
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
{% endif %}
......
......@@ -23,8 +23,8 @@ server {
listen {{ HARSTORAGE_NGINX_PORT }} {{ default_site }};
listen {{ HARSTORAGE_SSL_NGINX_PORT }} ssl;
ssl_certificate /etc/ssl/certs/{{ NGINX_SSL_CERTIFICATE|basename }};
ssl_certificate_key /etc/ssl/private/{{ NGINX_SSL_KEY|basename }};
include /etc/nginx/ssl-certs.conf;
# request the browser to use SSL for all connections
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
......
......@@ -10,8 +10,8 @@ server {
{% if NGINX_ENABLE_SSL %}
listen {{ INSIGHTS_NGINX_SSL_PORT }} ssl;
ssl_certificate /etc/ssl/certs/{{ NGINX_SSL_CERTIFICATE|basename }};
ssl_certificate_key /etc/ssl/private/{{ NGINX_SSL_KEY|basename }};
include /etc/nginx/ssl-certs.conf;
# request the browser to use SSL for all connections
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
{% endif %}
......
......@@ -16,8 +16,7 @@ server {
listen {{ KIBANA_NGINX_PORT }} {{ default_site }};
listen {{ KIBANA_SSL_NGINX_PORT }} {{ default_site }} ssl;
ssl_certificate /etc/ssl/certs/{{ NGINX_SSL_CERTIFICATE|basename }};
ssl_certificate_key /etc/ssl/private/{{ NGINX_SSL_KEY|basename }};
include /etc/nginx/ssl-certs.conf;
{% else %}
listen {{ KIBANA_NGINX_PORT }} {{ default_site }};
......
......@@ -69,8 +69,8 @@ error_page {{ k }} {{ v }};
{% if NGINX_ENABLE_SSL %}
listen {{ EDXAPP_LMS_SSL_NGINX_PORT }} {{ default_site }} ssl;
ssl_certificate /etc/ssl/certs/{{ NGINX_SSL_CERTIFICATE|basename }};
ssl_certificate_key /etc/ssl/private/{{ NGINX_SSL_KEY|basename }};
include /etc/nginx/ssl-certs.conf;
# request the browser to use SSL for all connections
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
{% endif %}
......
......@@ -9,8 +9,9 @@ server {
{% if "ssl" in item.value and item.value['ssl'] == true -%}
listen {{ EDXAPP_LMS_SSL_NGINX_PORT }} {{ default_site }} ssl;
ssl_certificate /etc/ssl/certs/{{ NGINX_SSL_CERTIFICATE|basename }};
ssl_certificate_key /etc/ssl/private/{{ NGINX_SSL_KEY|basename }};
include /etc/nginx/ssl-certs.conf;
{% endif -%}
server_name {% for server in item.value['server_names'] %}
......
......@@ -24,8 +24,8 @@ server {
listen {{ PROGRAMS_SSL_NGINX_PORT }} ssl;
ssl_certificate /etc/ssl/certs/{{ NGINX_SSL_CERTIFICATE|basename }};
ssl_certificate_key /etc/ssl/private/{{ NGINX_SSL_KEY|basename }};
include /etc/nginx/ssl-certs.conf;
# Request that the browser use SSL for all connections.
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
......
ssl_certificate /etc/ssl/certs/{{ NGINX_SSL_CERTIFICATE|basename }};
ssl_certificate_key /etc/ssl/private/{{ NGINX_SSL_KEY|basename }};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment