Switch from acmetool to certbot for SSL certificate retrieval

This commit is contained in:
Slavi Pantaleev
2018-08-29 09:37:44 +03:00
parent d5346656e3
commit 23e4a4734b
9 changed files with 164 additions and 75 deletions

View File

@ -1,24 +1,11 @@
MAILTO="{{ matrix_ssl_support_email }}"
# The goal of this cronjob is to ask acmetool to check
# The goal of this cronjob is to ask certbot to check
# the current SSL certificates and to see if some need renewal.
# If so, it would attempt to renew.
#
# Various services depend on these certificates and would need to be restarted.
# This is not our concern here. We simply make sure the certificates are up to date.
# Restarting of services happens on its own different schedule (other cronjobs).
#
#
# How renewal works?
#
# acmetool will fail to bind to port :80 (because matrix-nginx-proxy or some other server is running there),
# and will fall back to its "webroot" validation method.
#
# Thus, it would put validation files in `/var/run/acme/acme-challenge`.
# These files can be retrieved via any vhost on port 80 of matrix-nginx-proxy,
# because it aliases `/.well-known/acme-challenge` to that same directory.
#
# When a custom proxy server (not matrix-nginx-proxy provided by this playbook),
# you'd need to make sure you alias these files correctly or SSL renewal would not work.
{{ matrix_ssl_renew_cron_time_definition }} root /usr/bin/docker run --rm --net=host -v {{ matrix_ssl_certs_path }}:/certs -v {{ matrix_ssl_certs_path }}/run:/var/run/acme -e ACME_EMAIL={{ matrix_ssl_support_email }} willwill/acme-docker acmetool --batch reconcile # --xlog.severity=debug
{{ matrix_ssl_renew_cron_time_definition }} root /bin/bash /usr/local/bin/matrix-ssl-certificates-renew

View File

@ -5,17 +5,14 @@ server {
server_tokens off;
location /.well-known/acme-challenge {
{#
The proxy can access the files directly.
An external server likely does not have permission to read these files,
so we'll just proxy to acme's :402 port.
#}
{%- if matrix_nginx_proxy_enabled -%}
default_type "text/plain";
alias {{ matrix_ssl_certs_path }}/run/acme-challenge;
{%- else -%}
proxy_pass http://localhost:402;
{% if matrix_nginx_proxy_enabled %}
{# Use the embedded DNS resolver in Docker containers to discover the service #}
resolver 127.0.0.11 valid=5s;
set $backend "matrix-certbot:80";
proxy_pass http://$backend;
{% else %}
{# Generic configuration for use outside of our container setup #}
proxy_pass http://localhost:{{ matrix_ssl_certbot_standalone_http_port }};
{% endif %}
}
@ -36,8 +33,8 @@ server {
gzip on;
gzip_types text/plain application/json application/javascript text/css image/x-icon font/ttf image/gif;
ssl_certificate {{ matrix_ssl_certs_path }}/live/{{ hostname_riot }}/fullchain;
ssl_certificate_key {{ matrix_ssl_certs_path }}/live/{{ hostname_riot }}/privkey;
ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ hostname_riot }}/fullchain.pem;
ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ hostname_riot }}/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";

View File

@ -5,17 +5,14 @@ server {
server_tokens off;
location /.well-known/acme-challenge {
{#
The proxy can access the files directly.
An external server likely does not have permission to read these files,
so we'll just proxy to acme's :402 port.
#}
{%- if matrix_nginx_proxy_enabled -%}
default_type "text/plain";
alias {{ matrix_ssl_certs_path }}/run/acme-challenge;
{%- else -%}
proxy_pass http://localhost:402;
{% if matrix_nginx_proxy_enabled %}
{# Use the embedded DNS resolver in Docker containers to discover the service #}
resolver 127.0.0.11 valid=5s;
set $backend "matrix-certbot:80";
proxy_pass http://$backend;
{% else %}
{# Generic configuration for use outside of our container setup #}
proxy_pass http://localhost:{{ matrix_ssl_certbot_standalone_http_port }};
{% endif %}
}
@ -36,8 +33,8 @@ server {
gzip on;
gzip_types text/plain application/json;
ssl_certificate {{ matrix_ssl_certs_path }}/live/{{ hostname_matrix }}/fullchain;
ssl_certificate_key {{ matrix_ssl_certs_path }}/live/{{ hostname_matrix }}/privkey;
ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ hostname_matrix }}/fullchain.pem;
ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ hostname_matrix }}/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";

View File

@ -22,7 +22,7 @@ ExecStart=/usr/bin/docker run --rm --name matrix-nginx-proxy \
-p 80:80 \
-p 443:443 \
-v {{ matrix_nginx_proxy_confd_path }}:/etc/nginx/conf.d:ro \
-v {{ matrix_ssl_certs_path }}:{{ matrix_ssl_certs_path }}:ro \
-v {{ matrix_ssl_config_dir_path }}:{{ matrix_ssl_config_dir_path }}:ro \
{{ matrix_docker_image_nginx }}
ExecStop=-/usr/bin/docker kill matrix-nginx-proxy
ExecStop=-/usr/bin/docker rm matrix-nginx-proxy

View File

@ -0,0 +1,26 @@
#!/bin/bash
# For renewal to work, matrix-nginx-proxy (or another webserver, if matrix-nginx-proxy is disabled)
# need to forward requests for `/.well-known/acme-challenge` to the certbot container.
#
# This can happen inside the container network by proxying to `http://matrix-certbot:80`
# or outside (on the host) by proxying to `http://localhost:{{ matrix_ssl_certbot_standalone_http_port }}`.
docker run \
--rm \
--name=matrix-certbot \
--network="{{ matrix_docker_network }}" \
-p 127.0.0.1:{{ matrix_ssl_certbot_standalone_http_port }}:80 \
-v {{ matrix_ssl_config_dir_path }}:/etc/letsencrypt \
-v {{ matrix_ssl_log_dir_path }}:/var/log/letsencrypt \
{{ matrix_ssl_certbot_docker_image }} \
renew \
--non-interactive \
{% if matrix_ssl_use_staging %}
--staging \
{% endif %}
--quiet \
--standalone \
--preferred-challenges http \
--agree-tos \
--email={{ matrix_ssl_support_email }}