Browse Source

introduce a 'nginx' hook

- introduce an nginx hook
  the hook will resolve the new environment variables
   * NGINX_CONFDIR -> default: /etc/nginx/conf.d
   * NGINX_CHALLENGE_LOCTION -> default: 001-challenge-letsencrypt.conf
   * NGINX_TLS_CERTIFICATE -> default:002-tls-certificates.conf

  - group: nginx-config-challenge-location
    this will generate -> $NGINX_CONFDIR/$NGINX_CHALLENGE_LOCATION
  - group: nginx-config-certificate-location
    this will generate -> $NGINX_CONFDIR/$NGINX_TLS_CERTIFICATE

  ACMEd amims to minimize the amount of ReadWrite directories. The systemd.unit
  (acmed.service), takes advantage of sandbox capabilities.

  For nginx support, we need to ReadWrite to $NGINX_CONFDIR.  Since
  we are running with uid/gid of 'acmed' and probably aren't
  authorized, an user with administrative rights need to call once

     chmod g+w $NGINX_CONFIR

  on systemd managed systems, we are able to correct/rewrite the directory
  rights at installation time (tmpfiles.d/acmed.conf).

  A website admin needs to include

   * $NGINX_CHALLENGE_LOCATION and
   * $NGINX_TLS_CERTIFICATE

  inside the  [virtual-]host configuration block of websites to
  activate the templates (non automated task)

- adapt acmed.service
  will hint to NGINX environment variables
  defaults are handled inside the nginx hook
- adapt tempfiles.d/acmed.conf
  preset default directory to store challenges (if acmed isn't started
  via systemd)
- adapat Makefile
  add nginx_hooks.toml

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
pull/46/head
Ralf Zerres 5 years ago
parent
commit
12e033388c
No known key found for this signature in database GPG Key ID: D17312FD44A71C23
  1. 1
      Makefile
  2. 1
      acmed/config/acmed.toml
  3. 130
      acmed/config/nginx_hooks.toml
  4. 21
      contrib/acmed.service
  5. 3
      contrib/tmpfiles.d/acmed.conf

1
Makefile

@ -54,6 +54,7 @@ install:
install -m 0644 $(TARGET_DIR)/man/acmed.toml.5.gz $(DESTDIR)$(MAN5DIR)/acmed.toml.5.gz; \
install -m 0644 acmed/config/acmed.toml $(DESTDIR)$(SYSCONFDIR)/acmed/acmed.toml; \
install -m 0644 acmed/config/default_hooks.toml $(DESTDIR)$(SYSCONFDIR)/acmed/default_hooks.toml; \
install -m 0644 acmed/config/nginx_hooks.toml $(DESTDIR)$(SYSCONFDIR)/acmed/nginx_hooks.toml; \
install -m 0644 acmed/config/letsencrypt.toml $(DESTDIR)$(SYSCONFDIR)/acmed/letsencrypt.toml; \
fi
if test -f "$(TARGET_DIR)/tacd"; then \

1
acmed/config/acmed.toml

@ -5,6 +5,7 @@
include = [
"default_hooks.toml",
"nginx_hooks.toml",
"letsencrypt.toml",
#"my_server.toml",
]

130
acmed/config/nginx_hooks.toml

@ -0,0 +1,130 @@
# Copyright (c) 2021 Rodolphe Bréard <rodolphe@breard.tf>
#
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved. This file is offered as-is,
# without any warranty.
# ------------------------------------------------------------------------
# ACMEd hooks adapting nginx configuration
# You should not edit this file since it may be overridden by a newer one.
# ------------------------------------------------------------------------
###
# nginx file storing challenge root in "/etc/nginx/conf.d/{{challenge-location}}/"
# env: NGINX_CONFDIR -> /etc/nginx/conf.d
# env: NGINX_CHALLENGE_LOCTION -> 001-challenge-letsencrypt.conf
###
[[hook]]
name = "nginx-config-challenge-location-chmod"
type = ["challenge-http-01", "post-operation"]
cmd = "chmod"
args = [
"ug+rw",
"{{#if env.NGINX_CONFDIR}}{{env.NGINX_CONFDIR}}{{else}}/etc/nginx/conf.d{{/if}}/{{#if env.NGINX_CHALLENGE_LOCATION}}{{env.NGINX_CHALLENGE_LOCATION}}{{else}}001-challenge-letsencrypt.conf{{/if}}"
]
allow_failure = true
[[hook]]
name = "nginx-config-challenge-location-create"
type = ["challenge-http-01", "post-operation"]
cmd = "cat"
args = [ "-" ]
stdin_str = """###
# Let's Encrypt: acme-challenge location
###
location ^~ /.well-known/acme-challenge/ {
allow all;
root "{{#if env.HTTP_ROOT}}{{env.HTTP_ROOT}}{{else}}/var/lib/acmed/domains{{/if}}";
default_type "text/plain";
try_files $uri =404;
}
"""
stdout = "{{#if env.NGINX_CONFDIR}}{{env.NGINX_CONFDIR}}{{else}}/etc/nginx/conf.d{{/if}}/{{#if env.NGINX_CHALLENGE_LOCATION}}{{env.NGINX_CHALLENGE_LOCATION}}{{else}}001-challenge-letsencrypt.conf{{/if}}"
[[hook]]
name = "nginx-config-challenge-location-echo"
type = ["challenge-http-01", "post-operation"]
cmd = "echo"
args = [
"{{#if env.NGINX_CONFDIR}}{{env.NGINX_CONFDIR}}{{else}}/etc/nginx/conf.d{{/if}}/{{#if env.NGINX_CHALLENGE_LOCATION}}{{env.NGINX_CHALLENGE_LOCATION}}{{else}}001-challenge-letsencrypt.conf{{/if}}"
]
allow_failure = true
[[group]]
name = "nginx-config-challenge-location"
# hook execution in order of definition
hooks = [
"nginx-config-challenge-location-create",
"nginx-config-challenge-location-echo",
"nginx-config-challenge-location-chmod"
]
###
# nginx reference to TLS certificates
# env NGINX_TLS_CERTIFICATE -> 002-tls-certificates.conf
# global: {{certificates_directory}}
# certificate: {{name}}_{{key_type}}.{{file_type}}.{{ext}}
###
[[hook]]
name = "nginx-config-certificate-location-chmod"
type = ["challenge-http-01", "post-operation"]
cmd = "chmod"
args = [
"ug+rw",
"{{#if env.NGINX_CONFDIR}}{{env.NGINX_CONFDIR}}{{else}}/etc/nginx/conf.d{{/if}}/{{#if env.NGINX_TLS_CERTIFICATE}}{{env.NGINX_TLS_CERTIFICATE}}{{else}}002-tls-certificates.conf{{/if}}"
]
allow_failure = true
[[hook]]
name = "nginx-config-certificate-location-create"
type = ["challenge-http-01", "post-operation"]
cmd = "cat"
args = [ "-" ]
## TODO
# make following handlebars accessible in post-operation
# ssl_certificate {{certificates_directory}}/{{name}}_{{key_type}}.crt.{{ext}};
# ssl_certificate_key {{certificates_directory}}/{{name}}_{{key_type}}.pk.{{ext}};
# workaround: define a env:ACMED_CERTS pointing to {{certificates_directory}}
##
stdin_str = """###
# Let's Encrypt TLS certificats
###
ssl_certificate {{#if env.ACMED_CERTS}}{{env.ACMED_CERTS}}{{else}}/var/lib/acmed/certs{{/if}}/{{identifiers.[0]}}_{{key_type}}.crt.pem; # managed by ACMEd
ssl_certificate_key {{#if env.ACMED_CERTS}}{{env.ACMED_CERTS}}{{else}}/var/lib/acmed/certs{{/if}}/{{identifiers.[0]}}_{{key_type}}.pk.pem; # managed by ACMEd
ssl_session_cache shared:le_nginx_SSL:10m;
ssl_session_timeout 1440m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-PO
LY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
"""
stdout = "{{#if env.NGINX_CONFDIR}}{{env.NGINX_CONFDIR}}{{else}}/etc/nginx/conf.d{{/if}}/{{#if env.NGINX_TLS_CERTIFICATE}}{{env.NGINX_TLS_CERTIFICATE}}{{else}}002-tls-certificates.conf{{/if}}"
allow_failure = true
[[hook]]
name = "nginx-config-certificate-location-echo"
type = ["challenge-http-01", "post-operation"]
cmd = "echo"
args = [
"{{#if env.NGINX_CONFDIR}}{{env.NGINX_CONFDIR}}{{else}}/etc/nginx/conf.d{{/if}}/{{#if env.NGINX_TLS_CERTIFICATE}}{{env.NGINX_TLS_CERTIFICATE}}{{else}}002-tls-certificates.conf{{/if}}"
]
allow_failure = true
[[group]]
name = "nginx-config-certificate-location"
# hook execution in order of definition
hooks = [
"nginx-config-certificate-location-create",
"nginx-config-certificate-location-echo",
"nginx-config-certificate-location-chmod"
]

21
contrib/acmed.service

@ -6,13 +6,22 @@ After=network.target
User=acmed
Group=acmed
# Working directory equals to User-Home
#WorkingDirectory=/var/lib/acmed
WorkingDirectory=/etc/acmed
# Root directory used to store challenges
# prefered: preset HTTP_ROOT env in hooks
#Environment="HTTP_ROOT=/var/lib/acmed/domains"
#Environment="NGINX_CONFDIR=/etc/nginx/conf.d"
#Environment="NGINX_CHALLENGE_LOCATION="001-challenge-letsencrypt.conf"
#Environment="NGINX_TLS_CERTIFICATE="001-tls-certificates.conf"
# ACMEd home directory
WorkingDirectory=/var/lib/acmed
# ACMEd runtime diretory storing pid file
RuntimeDirectory=acmed
# daemon handling: start, stop, timeouts
#ExecStart=/usr/bin/acmed --foreground --pid-file /run/acmed/acmed.pid --log-level debug --log-stderr
#ExecStart=/usr/bin/acmed --foreground --pid-file /run/acmed/acmed.pid --log-level trace --log-stderr
ExecStart=/usr/bin/acmed --foreground --pid-file /run/acmed/acmed.pid --log-level warn
TimeoutStartSec=3
TimeoutStopSec=5
@ -20,7 +29,7 @@ Restart=on-failure
KillSignal=SIGINT
# Sandboxing: reduce privileges on filesystem and kernel-space
# restrict write access to acmed's directories with variable data
# restrict write access to directories, where acmed will store variable data
NoNewPrivileges=yes
PrivateDevices=yes
PrivateTmp=yes
@ -30,7 +39,7 @@ ProtectHostname=yes
ProtectKernelTunables=yes
ProtectKernelLogs=yes
ProtectSystem=strict
ReadWritePaths=/etc/acmed /var/lib/acmed
ReadWritePaths=/etc/acmed /etc/nginx/conf.d /var/lib/acmed
RestrictRealtime=yes
RestrictSUIDSGID=yes
SystemCallFilter=@system-service

3
contrib/tmpfiles.d/acmed.conf

@ -11,3 +11,6 @@ f /run/acmed/acmed.pid 0644 acmed acmed - -
d /var/lib/acmed 0755 acmed acmed - -
d /var/lib/acmed/accounts 0700 acmed acmed - -
d /var/lib/acmed/certs 0755 acmed acmed - -
d /var/lib/acmed/domains 0755 acmed acmed - -
d /etc/nginx/conf.d 0775 root acmed - -
Loading…
Cancel
Save