diff --git a/CHANGELOG.md b/CHANGELOG.md index c391df9a..2d30104f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,19 @@ The **patch** part changes incrementally at each release. ### Security +## [10.4.0] 2020-12-24 + +### Added + +* certbot: detect domains if missing +* certbot: new "sync_remote.sh" hook to sync certificates and execute hooks on remote servers +* varnish: variable for jail configuration + +### Changed + +* certbot: disable auth for Let's Encrypt challenge +* nginx: change from "nginx_status-XXX" to "server-status-XXX" + ## [10.3.0] 2020-12-21 ### Added diff --git a/certbot/files/hooks/sync_remote.sh b/certbot/files/hooks/sync_remote.sh new file mode 100644 index 00000000..d041f895 --- /dev/null +++ b/certbot/files/hooks/sync_remote.sh @@ -0,0 +1,62 @@ +#!/bin/sh + +set -u + +error() { + >&2 echo "${PROGNAME}: $1" + exit 1 +} +debug() { + if [ "${VERBOSE}" = "1" ] && [ "${QUIET}" != "1" ]; then + >&2 echo "${PROGNAME}: $1" + fi +} +found_renewed_lineage() { + test -f "${RENEWED_LINEAGE}/fullchain.pem" && test -f "${RENEWED_LINEAGE}/privkey.pem" +} +domain_from_cert() { + openssl x509 -noout -subject -in "${RENEWED_LINEAGE}/fullchain.pem" | sed 's/^.*CN\ *=\ *//' +} +main() { + if [ -z "${RENEWED_LINEAGE}" ]; then + error "Missing RENEWED_LINEAGE environment variable (usually provided by certbot)." + fi + if [ -z "${servers}" ]; then + debug "Empty server list, skip." + exit 0 + fi + + if found_renewed_lineage; then + RENEWED_DOMAINS=${RENEWED_DOMAINS:-$(domain_from_cert)} + + remore_lineage=${remote_dir}/renewed_lineage/$(basename ${RENEWED_LINEAGE}) + + for server in ${servers}; do + remote_host="root@${server}" + ssh ${remote_host} "mkdir -p ${remote_dir}" \ + || error "Couldn't create ${remote_dir} directory ${server}" + + rsync --archive --copy-links --delete ${RENEWED_LINEAGE}/ ${remote_host}:${remore_lineage}/ \ + || error "Couldn't sync certificate on ${server}" + + rsync --archive --copy-links --delete --exclude $0 --delete-excluded ${hooks_dir}/ ${remote_host}:${remote_dir}/hooks/ \ + || error "Couldn't sync hooks on ${server}" + + ssh ${remote_host} "export RENEWED_LINEAGE=\"${remore_lineage}/\" RENEWED_DOMAINS=${RENEWED_DOMAINS}; find ${remote_dir}/hooks/ -mindepth 1 -maxdepth 1 -type f -executable -exec {} \;" \ + || error "Something went wrong on ${server} for deploy hooks" + done + else + error "Couldn't find required files in \`${RENEWED_LINEAGE}'" + fi +} + +readonly PROGNAME=$(basename "$0") +readonly VERBOSE=${VERBOSE:-"0"} +readonly QUIET=${QUIET:-"0"} + +readonly hooks_dir="/etc/letsencrypt/renewal-hooks/deploy" +readonly remote_dir="/root/cert_sync" + +readonly servers="" + +main diff --git a/certbot/files/hooks/z-commit-etc.sh b/certbot/files/hooks/z-commit-etc.sh index c83a4039..5442bbc6 100644 --- a/certbot/files/hooks/z-commit-etc.sh +++ b/certbot/files/hooks/z-commit-etc.sh @@ -9,6 +9,13 @@ debug() { >&2 echo "${PROGNAME}: $1" fi } +domain_from_cert() { + if [ -f "${RENEWED_LINEAGE}/fullchain.pem" ]; then + openssl x509 -noout -subject -in "${RENEWED_LINEAGE}/fullchain.pem" | sed 's/^.*CN\ *=\ *//' + else + debug "Unable to find \`${RENEWED_LINEAGE}/fullchain.pem', skip domain detection." + fi +} main() { export GIT_DIR="/etc/.git" export GIT_WORK_TREE="/etc" @@ -17,6 +24,9 @@ main() { changed_lines=$(${git_bin} status --porcelain | wc -l | tr -d ' ') if [ "${changed_lines}" != "0" ]; then + if [ -z "${RENEWED_DOMAINS}" ] && [ -n "${RENEWED_LINEAGE}" ]; then + RENEWED_DOMAINS=$(domain_from_cert) + fi debug "Committing for ${RENEWED_DOMAINS}" ${git_bin} add --all message="[letsencrypt] certificates renewal (${RENEWED_DOMAINS})" @@ -32,6 +42,5 @@ readonly VERBOSE=${VERBOSE:-"0"} readonly QUIET=${QUIET:-"0"} readonly git_bin=$(command -v git) -readonly letsencrypt_dir=/etc/letsencrypt main diff --git a/certbot/templates/acme-challenge/nginx.conf.j2 b/certbot/templates/acme-challenge/nginx.conf.j2 index e4d3244b..aeb42ea1 100644 --- a/certbot/templates/acme-challenge/nginx.conf.j2 +++ b/certbot/templates/acme-challenge/nginx.conf.j2 @@ -5,5 +5,6 @@ location ~ /.well-known/acme-challenge { alias {{ certbot_work_dir }}/; {% endif %} try_files $uri =404; + auth_basic off; allow all; } diff --git a/evoacme/templates/nginx.conf.j2 b/evoacme/templates/nginx.conf.j2 index f76d927d..3b0d3982 100644 --- a/evoacme/templates/nginx.conf.j2 +++ b/evoacme/templates/nginx.conf.j2 @@ -5,5 +5,6 @@ location ~ /.well-known/acme-challenge { alias {{ evoacme_acme_dir }}/.well-known/acme-challenge; {% endif %} try_files $uri =404; + auth_basic off; allow all; } diff --git a/haproxy/tasks/main.yml b/haproxy/tasks/main.yml index 78929bb0..972429c4 100644 --- a/haproxy/tasks/main.yml +++ b/haproxy/tasks/main.yml @@ -16,7 +16,7 @@ state: directory tags: - haproxy - - config + - ssl - name: Self-signed certificate is present in HAProxy ssl directory shell: "cat /etc/ssl/certs/ssl-cert-snakeoil.pem /etc/ssl/private/ssl-cert-snakeoil.key > /etc/haproxy/ssl/ssl-cert-snakeoil.pem" @@ -25,7 +25,7 @@ notify: reload haproxy tags: - haproxy - - config + - ssl - name: HAProxy stats_access_ips are present blockinfile: @@ -39,6 +39,7 @@ tags: - haproxy - config + - update-config - name: HAProxy stats_admin_ips are present blockinfile: @@ -52,6 +53,7 @@ tags: - haproxy - config + - update-config - name: HAProxy maintenance_ips are present blockinfile: @@ -62,6 +64,10 @@ {{ ip }} {% endfor %} notify: reload haproxy + tags: + - haproxy + - config + - update-config - name: HAProxy deny_ips are present blockinfile: @@ -72,6 +78,10 @@ {{ ip }} {% endfor %} notify: reload haproxy + tags: + - haproxy + - config + - update-config - include: packages_backports.yml when: haproxy_backports @@ -100,6 +110,7 @@ tags: - haproxy - config + - update-config - name: Rotate logs with dateext lineinfile: @@ -109,7 +120,7 @@ insertbefore: '}' tags: - haproxy - - config + - logrotate - name: Rotate logs with nodelaycompress lineinfile: @@ -119,6 +130,6 @@ insertbefore: '}' tags: - haproxy - - config + - logrotate - include: munin.yml diff --git a/nginx/tasks/server_status_write.yml b/nginx/tasks/server_status_write.yml index e0b069db..beb56c67 100644 --- a/nginx/tasks/server_status_write.yml +++ b/nginx/tasks/server_status_write.yml @@ -9,12 +9,12 @@ - name: add server-status suffix in default site index if missing replace: dest: /var/www/index.html - regexp: '"/nginx_status-?"' - replace: '"/nginx_status-{{ nginx_serverstatus_suffix }}"' + regexp: '"/server-status-?"' + replace: '"/server-status-{{ nginx_serverstatus_suffix }}"' - name: add server-status suffix in default VHost replace: dest: /etc/nginx/sites-available/evolinux-default.conf - regexp: 'location /nginx_status-? {' - replace: 'location /nginx_status-{{ nginx_serverstatus_suffix }} {' + regexp: 'location /server-status-? {' + replace: 'location /server-status-{{ nginx_serverstatus_suffix }} {' notify: reload nginx diff --git a/nginx/templates/evolinux-default.conf.j2 b/nginx/templates/evolinux-default.conf.j2 index 5662ba51..ab4f8803 100644 --- a/nginx/templates/evolinux-default.conf.j2 +++ b/nginx/templates/evolinux-default.conf.j2 @@ -50,7 +50,7 @@ server { listen 80; server_name munin; - location /nginx_status-{{ nginx_serverstatus_suffix | mandatory }} { + location /server-status-{{ nginx_serverstatus_suffix | mandatory }} { stub_status on; access_log off; } diff --git a/nginx/templates/munin/evolinux.nginx b/nginx/templates/munin/evolinux.nginx index f58c0078..f5633139 100644 --- a/nginx/templates/munin/evolinux.nginx +++ b/nginx/templates/munin/evolinux.nginx @@ -1,2 +1,2 @@ [nginx_*] -env.url http://munin/nginx_status-{{ nginx_serverstatus_suffix }} +env.url http://munin/server-status-{{ nginx_serverstatus_suffix }} diff --git a/varnish/defaults/main.yml b/varnish/defaults/main.yml index 7a7d8c2f..fd22bfe2 100644 --- a/varnish/defaults/main.yml +++ b/varnish/defaults/main.yml @@ -13,6 +13,7 @@ varnish_thread_pools: "{{ ansible_processor_cores * ansible_processor_count }}" varnish_thread_pool_add_delay: 0 varnish_thread_pool_min: 500 varnish_thread_pool_max: 5000 +varnish_jail: "unix,user=vcache" varnish_config_file: /etc/varnish/default.vcl varnish_secret_file: /etc/varnish/secret diff --git a/varnish/tasks/main.yml b/varnish/tasks/main.yml index 7274cba8..035ae4a4 100644 --- a/varnish/tasks/main.yml +++ b/varnish/tasks/main.yml @@ -17,6 +17,7 @@ notify: reload varnish tags: - varnish + - config - name: Copy Custom Varnish ExecReload script (Debian <10) template: @@ -48,6 +49,8 @@ - restart varnish tags: - varnish + - config + - update-config - name: Override Varnish systemd unit (Buster and later) template: @@ -60,17 +63,20 @@ - restart varnish tags: - varnish + - config + - update-config - name: Patch logrotate conf replace: name: /etc/logrotate.d/varnish regexp: '^(\s+)(/usr/sbin/invoke-rc.d {{item}}.*)' replace: '\1systemctl -q is-active {{item}} && \2' - with_items: + loop: - varnishlog - varnishncsa tags: - varnish + - logrotate - name: Copy Varnish configuration template: @@ -90,6 +96,8 @@ notify: reload varnish tags: - varnish + - config + - update-config - name: Create Varnish config dir file: @@ -98,6 +106,7 @@ mode: "0755" tags: - varnish + - config - name: Copy included Varnish config template: @@ -106,9 +115,11 @@ force: yes mode: "0644" with_fileglob: - - "templates/varnish/conf.d/*.vcl" + - "templates/varnish/conf.d/*.vcl" notify: reload varnish tags: - varnish + - config + - update-config - include: munin.yml diff --git a/varnish/templates/varnish.conf.buster.j2 b/varnish/templates/varnish.conf.buster.j2 index 09dcf7c4..63439b61 100644 --- a/varnish/templates/varnish.conf.buster.j2 +++ b/varnish/templates/varnish.conf.buster.j2 @@ -2,4 +2,4 @@ [Service] ExecStart= -ExecStart=/usr/sbin/varnishd -j unix,user=vcache -F {{ varnish_addresses | map('regex_replace', '^(.*)$', '-a \\1') | list | join(' ') }} -T {{ varnish_management_address }} -f {{ varnish_config_file }} -S {{ varnish_secret_file }} -s {{ varnish_storage }} -p thread_pools={{ varnish_thread_pools }} -p thread_pool_add_delay={{ varnish_thread_pool_add_delay }} -p thread_pool_min={{ varnish_thread_pool_min }} -p thread_pool_max={{ varnish_thread_pool_max }} +ExecStart=/usr/sbin/varnishd -F -j {{ varnish_jail }} {{ varnish_addresses | map('regex_replace', '^(.*)$', '-a \\1') | list | join(' ') }} -T {{ varnish_management_address }} -f {{ varnish_config_file }} -S {{ varnish_secret_file }} -s {{ varnish_storage }} -p thread_pools={{ varnish_thread_pools }} -p thread_pool_add_delay={{ varnish_thread_pool_add_delay }} -p thread_pool_min={{ varnish_thread_pool_min }} -p thread_pool_max={{ varnish_thread_pool_max }} diff --git a/varnish/templates/varnish.conf.jessie.j2 b/varnish/templates/varnish.conf.jessie.j2 index 59651b36..f340323d 100644 --- a/varnish/templates/varnish.conf.jessie.j2 +++ b/varnish/templates/varnish.conf.jessie.j2 @@ -2,6 +2,6 @@ [Service] ExecStart= -ExecStart=/usr/sbin/varnishd -j unix,user=vcache -F {{ varnish_addresses | map('regex_replace', '^(.*)$', '-a \\1') | list | join(' ') }} -T {{ varnish_management_address }} -f {{ varnish_config_file }} -S {{ varnish_secret_file }} -s {{ varnish_storage }} -p thread_pools={{ varnish_thread_pools }} -p thread_pool_add_delay={{ varnish_thread_pool_add_delay }} -p thread_pool_min={{ varnish_thread_pool_min }} -p thread_pool_max={{ varnish_thread_pool_max }} +ExecStart=/usr/sbin/varnishd -F -j {{ varnish_jail }} {{ varnish_addresses | map('regex_replace', '^(.*)$', '-a \\1') | list | join(' ') }} -T {{ varnish_management_address }} -f {{ varnish_config_file }} -S {{ varnish_secret_file }} -s {{ varnish_storage }} -p thread_pools={{ varnish_thread_pools }} -p thread_pool_add_delay={{ varnish_thread_pool_add_delay }} -p thread_pool_min={{ varnish_thread_pool_min }} -p thread_pool_max={{ varnish_thread_pool_max }} ExecReload= ExecReload=/etc/varnish/reload-vcl.sh diff --git a/webapps/evoadmin-mail/templates/nginx_evoadminmail.conf.j2 b/webapps/evoadmin-mail/templates/nginx_evoadminmail.conf.j2 index b8ef073e..3c2750d3 100644 --- a/webapps/evoadmin-mail/templates/nginx_evoadminmail.conf.j2 +++ b/webapps/evoadmin-mail/templates/nginx_evoadminmail.conf.j2 @@ -4,36 +4,35 @@ server { server_name {{ evoadminmail_host }}; return 301 https://{{ evoadminmail_host }}$request_uri; -} +} server { - listen 443 ssl; - # listen [::]:80 default_server ipv6only=on; ## listen for ipv6 - + listen 443 ssl; + # listen [::]:80 default_server ipv6only=on; ## listen for ipv6 + ssl_certificate /etc/ssl/certs/{{ evoadminmail_host }}.crt; ssl_certificate_key /etc/ssl/private/{{ evoadminmail_host }}.key; - + server_name {{ evoadminmail_host }}; - index index.php; - + access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; - + root /usr/share/evoadmin-mail/; - + location / { try_files $uri $uri/ /index.php?$args; - } - - location ~ \.php$ { - fastcgi_pass unix:/run/php/php7.0-evoadmin-mail-fpm.sock; + } + + location ~ \.php$ { + fastcgi_pass unix:/run/php/php7.0-evoadmin-mail-fpm.sock; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; fastcgi_param DOCUMENT_ROOT $realpath_root; - } - - location /fpm-status { - fastcgi_pass unix:/run/php/php7.0-evoadmin-mail-fpm.sock; - fastcgi_index index.php; + } + + location /fpm-status { + fastcgi_pass unix:/run/php/php7.0-evoadmin-mail-fpm.sock; + fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; allow 127.0.0.1;