From 2c50b3398e121bb8136fb143d6afaa189dfcbe9c Mon Sep 17 00:00:00 2001 From: "Yves G." Date: Sat, 30 Dec 2023 16:32:52 +0100 Subject: [PATCH] WIP --- bootstrap.adoc | 26 +- env/00_common_all.yaml | 63 ++++- roles/acme_back/tasks/main.yml | 46 ++++ roles/acme_back/templates/hook.sh.j2 | 27 ++- roles/acme_front/handlers/main.yml | 4 +- roles/acme_front/tasks/main.yml | 2 +- roles/aur.inc/tasks/install.yml | 4 +- roles/ddclient_HE_example/tasks/main.yml | 2 +- roles/dev.inc/tasks/arch-chroot.yml | 2 +- roles/dmz_dotclear_front/handlers/main.yml | 4 +- roles/dmz_dotclear_front/tasks/main.yml | 2 +- roles/dmz_exim/tasks/main.yml | 73 +++--- roles/dmz_haproxy/tasks/main.yml | 4 +- roles/dmz_haproxy/templates/haproxy.conf.j2 | 4 + roles/dmz_ihmgit_front/handlers/main.yml | 4 +- roles/dmz_ihmgit_front/tasks/main.yml | 25 +- roles/dmz_ihmldap/handlers/main.yml | 4 +- roles/dmz_ihmldap/tasks/main.yml | 2 +- roles/dmz_motion_front/handlers/main.yml | 4 +- roles/dmz_motion_front/tasks/main.yml | 2 +- roles/dmz_movim_front/handlers/main.yml | 4 +- roles/dmz_movim_front/tasks/main.yml | 2 +- roles/dmz_nextcloud_front/handlers/main.yml | 4 +- roles/dmz_nextcloud_front/tasks/main.yml | 4 +- roles/dmz_nginx/handlers/main.yml | 4 +- roles/dmz_nginx/tasks/main.yml | 227 +++++++++--------- roles/dmz_nginx/tasks/opm.yaml | 16 ++ roles/dmz_nginx/templates/10.conf.j2 | 5 + roles/dmz_prosody_front/handlers/main.yml | 4 +- roles/dmz_prosody_front/tasks/main.yml | 2 +- .../handlers/main.yml | 4 +- .../meta.OK/main.yml | 2 +- .../tasks/main.yml | 60 ++++- roles/dmz_wallabag_front/handlers/main.yml | 4 +- roles/dmz_wallabag_front/tasks/main.yml | 2 +- roles/front/tasks/main.yml | 2 +- roles/front/templates/DMZ.dev.j2 | 11 + roles/front/templates/{DMZ.j2 => DMZ.prod.j2} | 4 +- roles/init/files/bin/etc_start_upstream | 2 +- roles/init/files/bin/etc_stop_local | 2 +- roles/init/files/bin/etc_stop_upstream | 2 +- roles/init/templates/etc_init.j2 | 2 +- roles/mediaplayer/tasks/main.yml | 2 +- roles/motion_back/templates/email.sh.j2 | 2 +- roles/motion_back/templates/upload.sh.j2 | 2 +- .../nftables_front/templates/nftables.conf.j2 | 51 +++- roles/openvpn/handlers/main.yml | 16 ++ roles/openvpn/meta.OK/main.yml | 7 + roles/openvpn/tasks/main.yml | 195 +++++++++++++++ roles/openvpn/templates/nftables.conf.j2 | 105 ++++++++ roles/openvpn/templates/vpn.conf.j2 | 104 ++++++++ roles/php/handlers/main.yml | 3 + roles/php/tasks/main.yml | 103 ++++++++ roles/privatebin/handlers/main.yml | 4 +- roles/privatebin/tasks/main.yml | 2 +- roles/ssh/tasks/main.yml | 2 +- roles/sso/handlers/main.yml | 10 + roles/sso/meta.OK/main.yml | 8 + roles/sso/tasks/main.yml | 93 +++++++ roles/sso/templates/conf.json.j2 | 8 + site.yaml | 134 +++++------ tools/graphviz_roles.sh | 2 +- tools/podman/Makefile | 10 +- tools/podman/id-chroot | 7 + tools/podman/id-chroot.pub | 1 + tools/podman/id-dev | 7 + tools/podman/id-dev.pub | 1 + yalis.fr.key | 52 ++++ yalis.fr.pubkey | 14 ++ 69 files changed, 1298 insertions(+), 320 deletions(-) create mode 100644 roles/dmz_nginx/tasks/opm.yaml rename roles/{transmission => dmz_transmission}/handlers/main.yml (83%) rename roles/{transmission => dmz_transmission}/meta.OK/main.yml (92%) rename roles/{transmission => dmz_transmission}/tasks/main.yml (75%) create mode 100644 roles/front/templates/DMZ.dev.j2 rename roles/front/templates/{DMZ.j2 => DMZ.prod.j2} (86%) create mode 100644 roles/openvpn/handlers/main.yml create mode 100644 roles/openvpn/meta.OK/main.yml create mode 100644 roles/openvpn/tasks/main.yml create mode 100644 roles/openvpn/templates/nftables.conf.j2 create mode 100644 roles/openvpn/templates/vpn.conf.j2 create mode 100644 roles/sso/handlers/main.yml create mode 100644 roles/sso/meta.OK/main.yml create mode 100644 roles/sso/tasks/main.yml create mode 100644 roles/sso/templates/conf.json.j2 create mode 100644 tools/podman/id-chroot create mode 100644 tools/podman/id-chroot.pub create mode 100644 tools/podman/id-dev create mode 100644 tools/podman/id-dev.pub create mode 100644 yalis.fr.key create mode 100644 yalis.fr.pubkey diff --git a/bootstrap.adoc b/bootstrap.adoc index 8450238..0834088 100644 --- a/bootstrap.adoc +++ b/bootstrap.adoc @@ -74,8 +74,8 @@ Command (m for help): g Created a new GPT disklabel… Command (m for help): n -Partition number (1-128, default 1): -First sector (…): +Partition number (1-128, default 1): +First sector (…): Last sector, +sectors or +size{K,M,G,T,P} (…): +128M Created a new partition 1… @@ -86,14 +86,14 @@ Hex code (type L to list all codes): 1 Changed type of partition 'Linux filesystem' to 'EFI System'. Command (m for help): n -Partition number (2-128, default 2): -First sector (…): +Partition number (2-128, default 2): +First sector (…): Last sector, +sectors or +size{K,M,G,T,P} (…): Created a new partition 2… Command (m for help): t -Partition number (1,2, default 2): +Partition number (1,2, default 2): Hex code (type L to list all codes): 31 Changed type of partition 'Linux filesystem' to 'Linux LVM'. @@ -304,7 +304,7 @@ root@archiso ~ # arch-chroot /mnt [root@archiso /]# cat >/etc/systemd/network/bridge.network <<-"THEEND" > [Match] > Name=wire -> +> > [Network] > IPForward=yes > Address={back-ip}/{net-bits} @@ -313,7 +313,7 @@ root@archiso ~ # arch-chroot /mnt [root@archiso /]# cat >/etc/systemd/network/wired.network <<-"THEEND" > [Match] > Name=en* -> +> > [Network] > Bridge=wire > THEEND @@ -390,12 +390,12 @@ NOTE: Most values and paths here are examples, and shall be adapted. [subs="+attributes"] ```bash [root@{back-name} ~]# systemctl -M {front-name} stop haproxy.service -[root@{back-name} ~]# systemctl -M {front-name} stop nginx.service +[root@{back-name} ~]# systemctl -M {front-name} stop openresty.service [root@{back-name} ~]# systemctl -M {front-name} stop php-fpm.service [root@{back-name} ~]# sudo -u postgres pg_restore -c -C -F c -d postgres \ > + /etc/dehydrated/{{nickname}}-hook.sh deploy_cert + {{net_soa}} + /var/lib/acme/self-signed.key + /var/lib/acme/self-signed.pem + /var/lib/acme/self-signed.pem + /dev/null + {{ansible_date_time.epoch}} + when: (env == 'dev') ### LOCAL COMMIT ⇒ ### - name: commit local changes diff --git a/roles/acme_back/templates/hook.sh.j2 b/roles/acme_back/templates/hook.sh.j2 index e86e25d..3f17cd5 100644 --- a/roles/acme_back/templates/hook.sh.j2 +++ b/roles/acme_back/templates/hook.sh.j2 @@ -2,17 +2,20 @@ # The home-server project produces a multi-purpose setup using Ansible. # Copyright © 2018–2023 Y. Gablin, under the GPL-3.0-or-later license. # Full licensing information in the LICENSE file, or gnu.org/licences/gpl-3.0.txt if the file is missing. +# +# NOTE: on 1st run, DMZ software is NOT YET INSTALLED! +set -e RSH=/usr/local/bin/{{DMZ}} -ETC_CHANGED_{{hostname}}= -ETC_CHANGED_{{DMZ}}= +ETC_CHANGED_{{hostname | regex_replace('-', '_')}}= +ETC_CHANGED_{{DMZ | regex_replace('-', '_')}}= etckeeper_hook() { if [ -n "$ETC_CHANGED_{{hostname}}" ]; then etc_stop_local 'ACME update' fi if [ -n "$ETC_CHANGED_{{DMZ}}" ]; then - $RSH "etc_stop_local 'ACME update'" + $RSH "etc_stop_local 'ACME update' || true" fi } @@ -37,11 +40,11 @@ deploy_exim() { && $RSH 'find /etc/mail/exim.{pem,crt} -mmin -$((1+($(date +%s)-${1})/60)) -printf . | grep -q ..' ${6%.*}; then return 0 fi - local copy='cat >$1; chown exim $1; chmod 400 $1; touch -t $(date +%Y%m%d%H%M -d @$2) $1' + local copy='[ -d /etc/mail ] || mkdir -p /etc/mail; cat >$1; if id exim 2>/dev/null; then chown exim $1; chmod 400 $1; else chmod 444 $1; fi; touch -t $(date +%Y%m%d%H%M -d @$2) $1' $RSH "$copy" /etc/mail/exim.pem $6 <"$2" $RSH "$copy" /etc/mail/exim.crt $6 <"$4" - systemctl -M {{DMZ}} reload exim.service - ETC_CHANGED_{{DMZ}}=1 + $RSH 'systemctl reload exim.service || true' + ETC_CHANGED_{{DMZ | regex_replace('-', '_')}}=1 } # $1: force|test; $2: KEYFILE; $3: CERTFILE; $4: FULLCHAINFILE; $5: CHAINFILE; $6: TIMESTAMP @@ -51,11 +54,11 @@ deploy_prosody() { && $RSH 'find /etc/prosody/certs/{{net_soa}}.{key,crt} -mmin -$((1+($(date +%s)-${1})/60)) -printf . | grep -q ..' ${6%.*}; then return 0 fi - local copy='cat >$1; chown prosody $1; chmod 400 $1; touch -t $(date +%Y%m%d%H%M -d @$2) $1' + local copy='[ -d /etc/prosody/certs ] || mkdir -p /etc/prosody/certs; cat >$1; if id prosody 2>/dev/null; then chown prosody $1; chmod 400 $1; else chmod 444 $1; fi; touch -t $(date +%Y%m%d%H%M -d @$2) $1' $RSH "$copy" /etc/prosody/certs/{{net_soa}}.key $6 <"$2" $RSH "$copy" /etc/prosody/certs/{{net_soa}}.crt $6 <"$4" - systemctl -M {{DMZ}} reload prosody.service - ETC_CHANGED_{{DMZ}}=1 + $RSH 'systemctl reload prosody.service || true' + ETC_CHANGED_{{DMZ | regex_replace('-', '_')}}=1 } # $1: force|test; $2: KEYFILE; $3: CERTFILE; $4: FULLCHAINFILE; $5: CHAINFILE; $6: TIMESTAMP @@ -65,10 +68,10 @@ deploy_haproxy() { && $RSH 'find /etc/haproxy/tls.pem -mmin -$((1+($(date +%s)-${1})/60)) -printf . | grep -q .' ${6%.*}; then return 0 fi - local copy='cat >$1; chmod 400 $1; touch -t $(date +%Y%m%d%H%M -d @$2) $1' + local copy='[ -d /etc/haproxy ] || mkdir -p /etc/haproxy; cat >$1; chmod 400 $1; touch -t $(date +%Y%m%d%H%M -d @$2) $1' cat "$4" "$2" | $RSH "$copy" /etc/haproxy/tls.pem $6 - systemctl -M {{DMZ}} reload haproxy.service - ETC_CHANGED_{{DMZ}}=1 + $RSH 'systemctl reload haproxy.service || true' + ETC_CHANGED_{{DMZ | regex_replace('-', '_')}}=1 } deploy_cert() { diff --git a/roles/acme_front/handlers/main.yml b/roles/acme_front/handlers/main.yml index f09e84f..e4dc070 100644 --- a/roles/acme_front/handlers/main.yml +++ b/roles/acme_front/handlers/main.yml @@ -3,8 +3,8 @@ # Copyright © 2018–2023 Y. Gablin, under the GPL-3.0-or-later license. # Full licensing information in the LICENSE file, or gnu.org/licences/gpl-3.0.txt if the file is missing. -- name: restart nginx.service +- name: restart openresty.service systemd: daemon_reload: true - name: nginx.service + name: openresty.service state: restarted diff --git a/roles/acme_front/tasks/main.yml b/roles/acme_front/tasks/main.yml index 00f08b6..2c00dc5 100644 --- a/roles/acme_front/tasks/main.yml +++ b/roles/acme_front/tasks/main.yml @@ -20,7 +20,7 @@ owner: http group: http notify: - - restart nginx.service + - restart openresty.service ### LOCAL COMMIT ⇒ ### - name: commit local changes diff --git a/roles/aur.inc/tasks/install.yml b/roles/aur.inc/tasks/install.yml index 1bcfa19..d0065ab 100644 --- a/roles/aur.inc/tasks/install.yml +++ b/roles/aur.inc/tasks/install.yml @@ -41,7 +41,9 @@ block: - name: AUR → {{pkg_name}} → run custom pre-processing commands - shell: "{{pre_cmd}}" + shell: | + set -x + {{pre_cmd}} args: chdir: /var/tmp/{{aurjson.json.results[0].PackageBase}} when: pre_cmd diff --git a/roles/ddclient_HE_example/tasks/main.yml b/roles/ddclient_HE_example/tasks/main.yml index 68a6261..43cbdce 100644 --- a/roles/ddclient_HE_example/tasks/main.yml +++ b/roles/ddclient_HE_example/tasks/main.yml @@ -46,7 +46,7 @@ - name: post-update script for he.net copy: content: | - #!/bin/bash + #!/usr/bin/env bash # $1: new IP address if [ -f /etc/conf.d/iodined ]; then sed -i "s/^IODINE_EXT_IP=.*/IODINE_EXT_IP='$1'/" /etc/conf.d/iodined diff --git a/roles/dev.inc/tasks/arch-chroot.yml b/roles/dev.inc/tasks/arch-chroot.yml index b07bc51..56fc28d 100644 --- a/roles/dev.inc/tasks/arch-chroot.yml +++ b/roles/dev.inc/tasks/arch-chroot.yml @@ -1,7 +1,7 @@ - name: replace /usr/bin/arch-chroot in Podman copy: content: | - #!/bin/bash + #!/usr/bin/env bash args=() while [ $# -gt 1 ]; do shift; args+=("$(printf "%q" "$1")"); done [ -t 0 ] && t=-t || t=-T diff --git a/roles/dmz_dotclear_front/handlers/main.yml b/roles/dmz_dotclear_front/handlers/main.yml index f09e84f..e4dc070 100644 --- a/roles/dmz_dotclear_front/handlers/main.yml +++ b/roles/dmz_dotclear_front/handlers/main.yml @@ -3,8 +3,8 @@ # Copyright © 2018–2023 Y. Gablin, under the GPL-3.0-or-later license. # Full licensing information in the LICENSE file, or gnu.org/licences/gpl-3.0.txt if the file is missing. -- name: restart nginx.service +- name: restart openresty.service systemd: daemon_reload: true - name: nginx.service + name: openresty.service state: restarted diff --git a/roles/dmz_dotclear_front/tasks/main.yml b/roles/dmz_dotclear_front/tasks/main.yml index c91b3ae..7f4f6da 100644 --- a/roles/dmz_dotclear_front/tasks/main.yml +++ b/roles/dmz_dotclear_front/tasks/main.yml @@ -58,7 +58,7 @@ owner: http group: http notify: - - restart nginx.service + - restart openresty.service ### LOCAL COMMIT ⇒ ### - name: commit local changes diff --git a/roles/dmz_exim/tasks/main.yml b/roles/dmz_exim/tasks/main.yml index 5ece871..323bce5 100644 --- a/roles/dmz_exim/tasks/main.yml +++ b/roles/dmz_exim/tasks/main.yml @@ -193,22 +193,34 @@ regexp: '^(?:#\s*)?root:' line: "root: {{mail_forward_root_to}}" -- name: send DKIM private key +- name: send DKIM private key (prod) copy: src: files/{{net_soa}}_dkim.privk.pem dest: /etc/mail/{{net_soa}}_dkim.privk.pem owner: exim group: exim mode: 0400 + when: (env == 'prod') notify: - restart exim.service -- name: set smarthost name +- name: create DKIM private key (dev) + shell: | + # https://dkimcore.org/specification.html + openssl genrsa -out /etc/mail/{{net_soa}}_dkim.privk.pem 1024 + openssl rsa -in /etc/mail/{{net_soa}}_dkim.privk.pem -pubout >/etc/mail/{{net_soa}}_dkim.pubk.pem + chown exim:exim /etc/mail/{{net_soa}}_dkim.*.pem + chmod 0400 /etc/mail/{{net_soa}}_dkim.*.pem + when: (env == 'dev') + notify: + - restart exim.service + +- name: disable smarthost lineinfile: path: /etc/mail/exim.conf - regexp: '^(?:#\s*)?ROUTER_SMARTHOST\s*=' - line: | - ROUTER_SMARTHOST={{mail_smtp_smarthost}} + regexp: '^(\s*ROUTER_SMARTHOST\s*=.*)' + backrefs: true + line: '#\\1' notify: - restart exim.service @@ -278,18 +290,11 @@ notify: - restart exim.service -- name: set TLS parameters for OpenSSL (old) - blockinfile: +- name: set TLS parameters for OpenSSL + replace: path: /etc/mail/exim.conf - marker: '# {mark} OpenSSL parameters' - block: | - insertafter: '^tls_advertise_hosts\s*=' - -- name: set TLS parameters for OpenSSL (new) - lineinfile: - path: /etc/mail/exim.conf - regexp: '^(?:#\s*)?tls_require_ciphers\s*=' - line: 'tls_require_ciphers = {{tls_ciphers}}' + regexp: '(.ifdef\s+_HAVE_OPENSSL\s*\n\s*)#?(\s*)tls_require_ciphers\s*=.*$' + replace: '\1\2tls_require_ciphers = {{tls_ciphers}}' notify: - restart exim.service @@ -365,14 +370,15 @@ notify: - restart exim.service +# 2023-05-20: disabled because too many legitimate rejected emails coming from GMail - name: deny mail RCPT from SpamHaus SBL blockinfile: path: /etc/mail/exim.conf marker: ' # {mark} SpamHaus SBL ACL' block: | - deny message = rejected because $sender_host_address is in a \ - black list at SpamHaus SBL - dnslists = sbl.spamhaus.org + # deny message = rejected because $sender_host_address is in a \ + # black list at SpamHaus SBL + # dnslists = sbl.spamhaus.org insertbefore: '^\s*#\s*warn\s+dnslists\s*=' notify: - restart exim.service @@ -399,21 +405,19 @@ # TODO: https://github.com/Exim/exim/wiki/SimpleGreylisting (with SPAM≥1.0) -- name: use remote_smtp for smarthost delivery - lineinfile: +- name: set IP addresses to be ignored (base) + replace: path: /etc/mail/exim.conf - regexp: '^(\s*transport\s*=)' - backrefs: true - line: "\\1 remote_smtp" + regexp: '^(\s*ignore_target_hosts\s*=)(?! <; 0\.0\.0\.0 ; 127\.0\.0\.0/8 ; ::1).*$' + replace: "\1 <; 0.0.0.0 ; 127.0.0.0/8 ; ::1" notify: - restart exim.service -- name: set IP addresses to be ignored - lineinfile: +- name: set IP addresses to be ignored (addition) + replace: path: /etc/mail/exim.conf - regexp: '^(\s*ignore_target_hosts\s*=.*::1)(?! ; {{mail_ignore_ip | replace(" ", " ; ")}}$)' - backrefs: true - line: "\\1 ; {{mail_ignore_ip | replace(' ', ' ; ')}}" + regexp: '^(\s*ignore_target_hosts\s*= <; 0\.0\.0\.0 ; 127\.0\.0\.0/8 ; ::1)$' + replace: "\1 ; {{mail_ignore_ip | replace(' ', ' ; ')}}" when: - mail_ignore_ip != "" notify: @@ -505,16 +509,17 @@ notify: - restart exim.service -- name: enable DKIM on outgoing emails - blockinfile: +- name: configure remote SMTP for outgoing emails + replace: path: /etc/mail/exim.conf - marker: ' # {mark} outgoing DKIM signing' - block: | + regexp: '^(remote_smtp:\s*\n\s*driver\s*=\s*smtp\s*)$(?!\n\s*dkim_canon =) + replace: | + \1 dkim_canon = relaxed dkim_domain = {{net_soa}} dkim_private_key = /etc/mail/{{net_soa}}_dkim.privk.pem dkim_selector = {{mail_dkim_selector}} - insertafter: '^\s*driver\s*=\s*smtp\s*$' + helo_data = {{net_soa}} notify: - restart exim.service diff --git a/roles/dmz_haproxy/tasks/main.yml b/roles/dmz_haproxy/tasks/main.yml index 2c0bf79..814d7a6 100644 --- a/roles/dmz_haproxy/tasks/main.yml +++ b/roles/dmz_haproxy/tasks/main.yml @@ -34,8 +34,8 @@ copy: content: | [Unit] - Wants=nginx.service - After=nginx.service + Wants=openresty.service + After=openresty.service dest: /etc/systemd/system/haproxy.service.d/wants_nginx.conf mode: 0644 notify: diff --git a/roles/dmz_haproxy/templates/haproxy.conf.j2 b/roles/dmz_haproxy/templates/haproxy.conf.j2 index a3b5da3..6e01980 100644 --- a/roles/dmz_haproxy/templates/haproxy.conf.j2 +++ b/roles/dmz_haproxy/templates/haproxy.conf.j2 @@ -27,6 +27,7 @@ defaults frontend imaps bind :993 ssl crt /etc/haproxy/tls.pem + bind :::993 ssl crt /etc/haproxy/tls.pem default_backend imap backend imap @@ -34,10 +35,12 @@ backend imap frontend text bind :80 + bind :::80 default_backend http frontend tls bind :443 ssl crt /etc/haproxy/tls.pem + bind :::443 ssl crt /etc/haproxy/tls.pem tcp-request inspect-delay 2s # check SNI for the SSH domain @@ -57,6 +60,7 @@ frontend tls frontend tls_plus bind :444 ssl crt /etc/haproxy/tls.pem + bind :::444 ssl crt /etc/haproxy/tls.pem default_backend https_plus backend ssh diff --git a/roles/dmz_ihmgit_front/handlers/main.yml b/roles/dmz_ihmgit_front/handlers/main.yml index f09e84f..e4dc070 100644 --- a/roles/dmz_ihmgit_front/handlers/main.yml +++ b/roles/dmz_ihmgit_front/handlers/main.yml @@ -3,8 +3,8 @@ # Copyright © 2018–2023 Y. Gablin, under the GPL-3.0-or-later license. # Full licensing information in the LICENSE file, or gnu.org/licences/gpl-3.0.txt if the file is missing. -- name: restart nginx.service +- name: restart openresty.service systemd: daemon_reload: true - name: nginx.service + name: openresty.service state: restarted diff --git a/roles/dmz_ihmgit_front/tasks/main.yml b/roles/dmz_ihmgit_front/tasks/main.yml index 84c7128..ed0b520 100644 --- a/roles/dmz_ihmgit_front/tasks/main.yml +++ b/roles/dmz_ihmgit_front/tasks/main.yml @@ -19,7 +19,30 @@ owner: http group: http notify: - - restart nginx.service + - restart openresty.service + +- name: configure SSO + copy: + content: | + { "patterns": [{ + "lua_regex": [ + "^{{http_pfx_gitea}}/admin", + "^{{http_pfx_gitea}}/repo/create", + "^{{http_pfx_gitea}}/repo/migrate", + "^{{http_pfx_gitea}}/org/create", + "^{{http_pfx_gitea}}/.-/wiki/_new" + ], + "allow": ["*"] + },{ + "lua_regex": ["^{{http_pfx_gitea}}/"], + "public": true, + "portal": {"{{http_pfx_gitea}}/": "Git"} + }] + } + dest: /etc/nginx/ssso/sites/git.json + when: (is_sso_used is defined) + notify: + - restart openresty.service ### LOCAL COMMIT ⇒ ### - name: commit local changes diff --git a/roles/dmz_ihmldap/handlers/main.yml b/roles/dmz_ihmldap/handlers/main.yml index f09e84f..e4dc070 100644 --- a/roles/dmz_ihmldap/handlers/main.yml +++ b/roles/dmz_ihmldap/handlers/main.yml @@ -3,8 +3,8 @@ # Copyright © 2018–2023 Y. Gablin, under the GPL-3.0-or-later license. # Full licensing information in the LICENSE file, or gnu.org/licences/gpl-3.0.txt if the file is missing. -- name: restart nginx.service +- name: restart openresty.service systemd: daemon_reload: true - name: nginx.service + name: openresty.service state: restarted diff --git a/roles/dmz_ihmldap/tasks/main.yml b/roles/dmz_ihmldap/tasks/main.yml index 7f9f7df..bab1da4 100644 --- a/roles/dmz_ihmldap/tasks/main.yml +++ b/roles/dmz_ihmldap/tasks/main.yml @@ -171,7 +171,7 @@ owner: http group: http notify: - - restart nginx.service + - restart openresty.service ### LOCAL COMMIT ⇒ ### - name: commit local changes diff --git a/roles/dmz_motion_front/handlers/main.yml b/roles/dmz_motion_front/handlers/main.yml index f09e84f..e4dc070 100644 --- a/roles/dmz_motion_front/handlers/main.yml +++ b/roles/dmz_motion_front/handlers/main.yml @@ -3,8 +3,8 @@ # Copyright © 2018–2023 Y. Gablin, under the GPL-3.0-or-later license. # Full licensing information in the LICENSE file, or gnu.org/licences/gpl-3.0.txt if the file is missing. -- name: restart nginx.service +- name: restart openresty.service systemd: daemon_reload: true - name: nginx.service + name: openresty.service state: restarted diff --git a/roles/dmz_motion_front/tasks/main.yml b/roles/dmz_motion_front/tasks/main.yml index 80eb6c5..c5fef7b 100644 --- a/roles/dmz_motion_front/tasks/main.yml +++ b/roles/dmz_motion_front/tasks/main.yml @@ -45,7 +45,7 @@ owner: http group: http notify: - - restart nginx.service + - restart openresty.service ### LOCAL COMMIT ⇒ ### - name: commit local changes diff --git a/roles/dmz_movim_front/handlers/main.yml b/roles/dmz_movim_front/handlers/main.yml index da28957..2344871 100644 --- a/roles/dmz_movim_front/handlers/main.yml +++ b/roles/dmz_movim_front/handlers/main.yml @@ -9,8 +9,8 @@ name: movim.service state: restarted -- name: restart nginx.service +- name: restart openresty.service systemd: daemon_reload: true - name: nginx.service + name: openresty.service state: restarted diff --git a/roles/dmz_movim_front/tasks/main.yml b/roles/dmz_movim_front/tasks/main.yml index 1cbdc10..caa740f 100644 --- a/roles/dmz_movim_front/tasks/main.yml +++ b/roles/dmz_movim_front/tasks/main.yml @@ -122,7 +122,7 @@ owner: http group: http notify: - - restart nginx.service + - restart openresty.service ### LOCAL COMMIT ⇒ ### - name: commit local changes diff --git a/roles/dmz_nextcloud_front/handlers/main.yml b/roles/dmz_nextcloud_front/handlers/main.yml index f09e84f..e4dc070 100644 --- a/roles/dmz_nextcloud_front/handlers/main.yml +++ b/roles/dmz_nextcloud_front/handlers/main.yml @@ -3,8 +3,8 @@ # Copyright © 2018–2023 Y. Gablin, under the GPL-3.0-or-later license. # Full licensing information in the LICENSE file, or gnu.org/licences/gpl-3.0.txt if the file is missing. -- name: restart nginx.service +- name: restart openresty.service systemd: daemon_reload: true - name: nginx.service + name: openresty.service state: restarted diff --git a/roles/dmz_nextcloud_front/tasks/main.yml b/roles/dmz_nextcloud_front/tasks/main.yml index 2f0945e..2f4e68e 100644 --- a/roles/dmz_nextcloud_front/tasks/main.yml +++ b/roles/dmz_nextcloud_front/tasks/main.yml @@ -11,7 +11,7 @@ owner: http group: http notify: - - restart nginx.service + - restart openresty.service - name: configure Nginx for LibreOffice OnLine template: @@ -21,7 +21,7 @@ owner: http group: http notify: - - restart nginx.service + - restart openresty.service ### LOCAL COMMIT ⇒ ### - name: commit local changes diff --git a/roles/dmz_nginx/handlers/main.yml b/roles/dmz_nginx/handlers/main.yml index 10ee9cb..b9be3bc 100644 --- a/roles/dmz_nginx/handlers/main.yml +++ b/roles/dmz_nginx/handlers/main.yml @@ -6,10 +6,10 @@ - name: create tmpfiles command: systemd-tmpfiles --create /etc/tmpfiles.d/run_http.conf -- name: restart nginx.service +- name: restart openresty.service systemd: daemon_reload: true - name: nginx.service + name: openresty.service state: restarted - name: restart php-fpm.service diff --git a/roles/dmz_nginx/tasks/main.yml b/roles/dmz_nginx/tasks/main.yml index 6663f90..956217d 100644 --- a/roles/dmz_nginx/tasks/main.yml +++ b/roles/dmz_nginx/tasks/main.yml @@ -10,13 +10,71 @@ msg: nginx ### ⇐ UPSTREAM BEGIN ### -#- name: install software -# package: -# name: "{{item}}" -# state: present -# with_items: -# - nginx-mainline # nginx-mainline must now be built from official PKGBUILD :-( -# - php-fpm +- name: uninstall software + package: + name: "{{item}}" + state: absent + with_items: + # 2023-05-20: removed + - nginx-mainline + +- name: install AUR software + include_role: + name: aur.inc + allow_duplicates: true + vars: + packages: + - pkg: openresty + pre: | + # harden the systemd service + sed -ri ' + /\[Unit\]/ a\ + After=systemd-tmpfiles-setup.service\ + After=php-fpm.service + /\[Service\]/ a\ + User=http\ + Group=http\ + CapabilityBoundingSet=CAP_AUDIT_WRITE CAP_LEASE CAP_SYS_CHROOT\ + PrivateTmp=true\ + PrivateDevices=true\ + ProtectSystem=full\ + ProtectHome=true\ + ReadWritePaths=/var/log/nginx\ + NoNewPrivileges=true\ + ExecStartPre=-/usr/bin/find /var/log/nginx/ -type f -user root -delete\ + ExecStartPre=/usr/bin/sh -c '"'"'rm -f /run/shared_sockets/http*.pp'"'"' + s|/run/openresty.pid|/run/http/nginx.pid|g + ' service + # compute the hash of the new service file + srvHash=$(sha256sum service | awk '{print $1}') + # — choose /etc/nginx as Nginx configuration location + # — choose /run/http/ for Nginx PID and lock files location + # — choose /var/log/nginx/ as Nginx compiled-in logs location + # — choose /var/tmp/ as Nginx runtime temporary folder + # — replace the old service hash with the computed one + # — remove signature source files as they make the build fail + # — disable unused features of OpenResty/Nginx + sed -ri " + s#_cfgdir=.*#_cfgdir=/etc/nginx# + /build\\(\\)/ i\\ + for ((_src=0; _src<\${{ '{#source[*]}' }}; _src++)); do if [ "\${source[\$_src]}" == service ]; then\\ + sha256sums[\$_src]='$srvHash'\\ + fi; done\\ + for ((_src=\${{ '{#source[*]}' }}-1; _src>=0; _src--)); do if [[ "\${source[\$_src]}" =~ \\\\.asc\$ ]]; then\\ + _last=\$((\${{ '{#source[*]}' }}-1))\\ + source[\$_src]=\"\${source[\$_last]}\"; unset source[\$_last]\\ + sha256sums[\$_src]=\"\${sha256sums[\$_last]}\"; unset sha256sums[\$_last]\\ + fi; done\\ + unset _last _src + s/^( *)#( *--(without-.*redis|without-lua_rds|without-.*mysql|without-.*scgi))/\\1\\2/ + s|^( *)#( *--pid-path=).*|\\1\\2/run/http/nginx.pid \\\\| + s|^( *)#( *--lock-path=).*|\\1\\2/run/http/nginx.lock \\\\| + s|^( *)#( *--error-log-path=).*|\\1\\2/var/log/nginx/error.log \\\\| + s|^( *)#( *--http-log-path=).*|\\1\\2/var/log/nginx/access.log \\\\| + /^ *--with-mail|^ *#/d + s| +#.*|| + " PKGBUILD + cat PKGBUILD ### UPSTREAM END ⇒ ### - name: merge upstream @@ -25,11 +83,19 @@ msg: nginx ### ⇐ UPSTREAM END ### -- name: create a directory for the PID files +- name: fix logrotate.d/openresty + lineinfile: + path: /etc/logrotate.d/openresty + backrefs: true + regexp: '^(\s*test -r )/run/' + line: '\1/run/http/nginx.pid && kill -USR1 `cat /run/http/nginx.pid`' + +- name: create Nginx working directories copy: content: | - #Type Path Mode UID GID Age Argument - d /run/http 775 http http - - + #Type Path Mode UID GID Age Argument + d /run/http 775 http http - - + d /var/log/nginx 775 http http - - dest: /etc/tmpfiles.d/run_http.conf mode: 0644 notify: @@ -37,69 +103,15 @@ - meta: flush_handlers -- name: prepare to override systemd settings - file: - name: /etc/systemd/system/{{item}}.service.d - state: directory - mode: 0755 +- name: update already-installed OpenResty packages + shell: /opt/openresty/bin/opm update + +- name: OPM = install OpenResty packages (if necessary) + include_tasks: opm.yaml + vars: + pkg_name: "{{item}}" with_items: - - nginx - - php-fpm - -- name: secure systemd settings for php-fpm - copy: - content: | - [Unit] - After=systemd-tmpfiles-setup.service - [Service] - User=http - Group=http - CapabilityBoundingSet=CAP_AUDIT_WRITE CAP_LEASE CAP_SYS_CHROOT - PrivateTmp=true - PrivateDevices=true - ProtectSystem=true - ProtectHome=true - NoNewPrivileges=true - PIDFile=/run/http/php-fpm.pid - dest: /etc/systemd/system/php-fpm.service.d/secure-{{nickname}}.conf - mode: 0644 - notify: - - restart php-fpm.service - -- name: secure systemd settings for nginx - copy: - content: | - [Unit] - After=systemd-tmpfiles-setup.service - After=php-fpm.service - [Service] - User=http - Group=http - CapabilityBoundingSet=CAP_AUDIT_WRITE CAP_LEASE CAP_SYS_CHROOT - PrivateTmp=true - PrivateDevices=true - ProtectSystem=full - ProtectHome=true - NoNewPrivileges=true - PIDFile=/run/http/nginx.pid - ExecStartPre=/usr/bin/sh -c 'rm -f /run/shared_sockets/http*.pp' - ExecStart= - ExecStart=/usr/bin/nginx -g 'pid /run/http/nginx.pid; error_log stderr;' - dest: /etc/systemd/system/nginx.service.d/secure-{{nickname}}.conf - mode: 0644 - notify: - - restart nginx.service - -- name: set ownership of nginx’ working directories to nginx - file: - path: /var/{{item}}/nginx - state: directory - owner: http - group: http - recurse: true - with_items: - - lib - - log + - fffonion/lua-resty-openssl - name: set the number of nginx worker processes lineinfile: @@ -107,7 +119,7 @@ regexp: '^#?\s*worker_processes\s' line: "worker_processes auto;" notify: - - restart nginx.service + - restart openresty.service - name: log to systemd-journal lineinfile: @@ -115,7 +127,7 @@ regexp: '^#?\s*error_log\s' line: "error_log syslog:server=unix:/dev/log,nohostname {{nginx_loglevel}};" notify: - - restart nginx.service + - restart openresty.service - name: create directories for custom nginx configuration file: @@ -136,7 +148,7 @@ line: include /etc/nginx/main.inc.d/*.inc; insertbefore: BOF notify: - - restart nginx.service + - restart openresty.service - name: include custom nginx configuration lineinfile: @@ -145,7 +157,7 @@ line: include /etc/nginx/conf.d/*.conf; insertbefore: '^\s*#gzip\s' notify: - - restart nginx.service + - restart openresty.service - name: set custom nginx configuration template: @@ -155,7 +167,7 @@ group: http mode: 0640 notify: - - restart nginx.service + - restart openresty.service - name: send included conf files template: @@ -198,54 +210,33 @@ when: - test_srv.changed notify: - - restart nginx.service + - restart openresty.service -- name: set the php-fpm settings - lineinfile: - path: /etc/php/php-fpm.d/www.conf - regexp: '^;*{{item.key}}\s*=' - line: '{{item.key}} = {{item.value}}' - with_dict: - listen: /run/shared_sockets/php-fpm - pm: dynamic - 'pm.max_children': '{{php_max_workers}}' - 'pm.start_servers': 1 - 'pm.min_spare_servers': 1 - 'pm.max_spare_servers': '{{php_max_workers}}' - 'pm.max_requests': '{{php_worker_max_reqs}}' - notify: - - restart php-fpm.service - -- name: disable useless user/group specs - lineinfile: - path: /etc/php/php-fpm.d/www.conf - backrefs: true - regexp: '^({{item}}\s*=.*)' - line: ';\1' +- name: create web files locations + file: + path: "{{item}}" + state: directory with_items: - - user - - group - - 'listen.group' + - /srv/http + - /srv/webapps -- name: set the PID file path for php-fpm - lineinfile: - path: /etc/php/php-fpm.conf - regexp: '^;*pid\s*=' - line: 'pid = /run/http/php-fpm.pid' - notify: - - restart php-fpm.service - -- name: enable php-fpm.service +- name: enable openresty.service systemd: daemon_reload: true - name: php-fpm.service + name: openresty.service enabled: true -- name: enable nginx.service - systemd: - daemon_reload: true - name: nginx.service - enabled: true +- name: HTML test-page in test environment + copy: + content: | + + + TEST +

HTML served by Nginx

It works!

+ + dest: /srv/http/index.html + mode: 0644 + when: (env == 'dev') ### LOCAL COMMIT ⇒ ### - name: commit local changes diff --git a/roles/dmz_nginx/tasks/opm.yaml b/roles/dmz_nginx/tasks/opm.yaml new file mode 100644 index 0000000..e341abd --- /dev/null +++ b/roles/dmz_nginx/tasks/opm.yaml @@ -0,0 +1,16 @@ +--- +# The home-server project produces a multi-purpose setup using Ansible. +# Copyright © 2018–2023 Y. Gablin, under the GPL-3.0-or-later license. +# Full licensing information in the LICENSE file, or gnu.org/licences/gpl-3.0.txt if the file is missing. + +# mandatory parameters: pkg_name + +- name: OPM → check existence of {{pkg_name}} + shell: /opt/openresty/bin/opm list | grep -q '^{{pkg_name}}[[:blank:]]' + ignore_errors: true + changed_when: false + register: opm_check + +- name: OPM → install {{pkg_name}} + command: /opt/openresty/bin/opm get {{pkg_name}} + when: opm_check is failed diff --git a/roles/dmz_nginx/templates/10.conf.j2 b/roles/dmz_nginx/templates/10.conf.j2 index 557a407..d735439 100644 --- a/roles/dmz_nginx/templates/10.conf.j2 +++ b/roles/dmz_nginx/templates/10.conf.j2 @@ -2,6 +2,11 @@ # Copyright © 2018–2023 Y. Gablin, under the GPL-3.0-or-later license. # Full licensing information in the LICENSE file, or gnu.org/licences/gpl-3.0.txt if the file is missing. +client_body_temp_path /var/tmp/client_body_temp; +proxy_temp_path /var/tmp/proxy_temp; +fastcgi_temp_path /var/tmp/fastcgi_temp; +uwsgi_temp_path /var/tmp/uwsgi_temp; +#scgi_temp_path /var/tmp/scgi_temp; client_max_body_size {{http_max_upload}}; gzip on; gzip_comp_level 6; diff --git a/roles/dmz_prosody_front/handlers/main.yml b/roles/dmz_prosody_front/handlers/main.yml index 892ccd5..a0975e9 100644 --- a/roles/dmz_prosody_front/handlers/main.yml +++ b/roles/dmz_prosody_front/handlers/main.yml @@ -9,8 +9,8 @@ name: prosody.service state: restarted -- name: restart nginx.service +- name: restart openresty.service systemd: daemon_reload: true - name: nginx.service + name: openresty.service state: restarted diff --git a/roles/dmz_prosody_front/tasks/main.yml b/roles/dmz_prosody_front/tasks/main.yml index 54a07ae..ff1e83d 100644 --- a/roles/dmz_prosody_front/tasks/main.yml +++ b/roles/dmz_prosody_front/tasks/main.yml @@ -277,7 +277,7 @@ owner: http group: http notify: - - restart nginx.service + - restart openresty.service - name: enable prosody systemd: diff --git a/roles/transmission/handlers/main.yml b/roles/dmz_transmission/handlers/main.yml similarity index 83% rename from roles/transmission/handlers/main.yml rename to roles/dmz_transmission/handlers/main.yml index f09e84f..e4dc070 100644 --- a/roles/transmission/handlers/main.yml +++ b/roles/dmz_transmission/handlers/main.yml @@ -3,8 +3,8 @@ # Copyright © 2018–2023 Y. Gablin, under the GPL-3.0-or-later license. # Full licensing information in the LICENSE file, or gnu.org/licences/gpl-3.0.txt if the file is missing. -- name: restart nginx.service +- name: restart openresty.service systemd: daemon_reload: true - name: nginx.service + name: openresty.service state: restarted diff --git a/roles/transmission/meta.OK/main.yml b/roles/dmz_transmission/meta.OK/main.yml similarity index 92% rename from roles/transmission/meta.OK/main.yml rename to roles/dmz_transmission/meta.OK/main.yml index 9bd4981..05474ff 100644 --- a/roles/transmission/meta.OK/main.yml +++ b/roles/dmz_transmission/meta.OK/main.yml @@ -6,4 +6,4 @@ dependencies: - role: cleanupdate - role: ldap - - role: ssowat +# - role: ssowat #FIXME diff --git a/roles/transmission/tasks/main.yml b/roles/dmz_transmission/tasks/main.yml similarity index 75% rename from roles/transmission/tasks/main.yml rename to roles/dmz_transmission/tasks/main.yml index 2116686..976cd6c 100644 --- a/roles/transmission/tasks/main.yml +++ b/roles/dmz_transmission/tasks/main.yml @@ -34,9 +34,10 @@ Requires=nslcd.service After=nslcd.service [Service] + {% if is_vpn_used is not defined %} CapabilityBoundingSet=CAP_AUDIT_WRITE CAP_LEASE CAP_SYS_CHROOT CAP_SYS_NICE + {% endif %} PrivateDevices=yes - PrivateTmp=yes ProtectHome=yes ProtectSystem=full LimitNOFILE=4096 @@ -44,6 +45,22 @@ dest: /etc/systemd/system/transmission.service.d/secure-{{nickname}}.conf mode: 0644 +- name: override network settings for transmission + copy: + content: | + [Unit] + Requires=no-vpn-network-namespace.service + After=no-vpn-network-namespace.service + [Service] + Type=exec + User=root + Group=root + ExecStart= + ExecStart=/usr/bin/ip netns exec no-vpn /usr/bin/sudo -g {{media_group}} -u transmission -H -n /usr/bin/transmission-daemon -f --log-level=error + dest: /etc/systemd/system/transmission.service.d/zz-no-vpn.conf + mode: 0644 + when: (is_vpn_used is defined) + - name: ensure existence and mode of Transmission working directories file: path: /var/lib/transmission{{item}} @@ -104,6 +121,18 @@ name: transmission.service state: stopped +- name: store DMZ IP (direct) + set_fact: + no_vpn_front_IP: "{{DMZ_IP}}" + when: + - (is_vpn_used is not defined) + +- name: store DMZ IP (avoid VPN) + set_fact: + no_vpn_front_IP: "{{vpn_avoiding_ip_cidr | replace('/.*', '')}}" + when: + - (is_vpn_used is defined) + - name: put a JSON terminator to avoid a trailing comma lineinfile: path: /var/lib/transmission/.config/transmission-daemon/settings.json @@ -118,7 +147,7 @@ line: ' "{{item.key}}": {{item.value}},' insertbefore: '"zzz"' with_dict: - speed-limit-up: '50' + speed-limit-up: '500' speed-limit-up-enabled: 'true' download-dir: '"/var/lib/transmission/Done"' incomplete-dir: '"/var/lib/transmission/Doing"' @@ -130,13 +159,14 @@ watch-dir-enabled: 'true' encryption: '2' message-level: '1' - bind-address-ipv4: '"{{DMZ_IP}}"' + bind-address-ipv4: '"{{no_vpn_front_IP}}"' peer-port: '{{transmission_bt_port}}' peer-port-random-on-start: 'false' - port-forwarding-enabled: 'false' + port-forwarding-enabled: '{{is_vpn_used is defined}}' queue-stalled-minutes: '5' rpc-authentication-required: 'false' - rpc-bind-address: '"127.0.0.1"' + rpc-bind-address: '"unix:/run/shared_sockets/transmission-rpc.sock"' + rpc-socket-mode: '"0777"' rpc-port: '{{transmission_rpc_port}}' rpc-url: '"{{http_pfx_transmission}}/"' rpc-whitelist-enabled: 'false' @@ -151,13 +181,13 @@ copy: content: | location {{http_pfx_transmission}}/web { - alias /usr/share/transmission/web; + alias /usr/share/transmission/public_html; } location ~ ^{{http_pfx_transmission}}/?$ { return 307 https://{{net_soa}}{{http_pfx_transmission}}/web/; } location ~ ^{{http_pfx_transmission}}.*$(?/dev/null; then + ip link add link $host_if if_isp netns no-vpn type ipvlan mode l2 + fi + setup if_isp {{vpn_avoiding_ip_cidr}} + setup lo 127.0.0.1/8 + + # set gateway if not set + if ! ip -n no-vpn -4 route | grep -q ^default; then + ip -n no-vpn route add default via $gateway dev if_isp + fi + dest: /usr/local/bin/create-no-vpn-namespace.sh + mode: 0700 + notify: + - restart no-vpn network namespace + +- name: removal script for no-VPN network namespace + copy: + content: | + #!/bin/sh + ip netns delete no-vpn + dest: /usr/local/bin/delete-no-vpn-namespace.sh + mode: 0700 + notify: + - restart no-vpn network namespace + +- name: no-VPN network namespace firewall + template: + src: templates/nftables.conf.j2 + dest: /etc/netns/no-vpn/nftables.conf + mode: 0600 + notify: + - restart no-vpn network namespace + +# https://github.com/mqus/nft-rules/blob/master/files/SSDP_client.md +- name: systemctl service for no-VPN network namespace + copy: + content: | + [Unit] + Description=No-VPN network namespace + After=network-online.target openvpn.service + Wants=network-online.target openvpn.service + [Service] + Type=oneshot + RemainAfterExit=true + ExecStart=/usr/local/bin/create-no-vpn-namespace.sh + ExecStartPost=/usr/bin/ip netns exec no-vpn /usr/bin/nft -f /etc/nftables.conf + ExecStop=/usr/local/bin/delete-no-vpn-namespace.sh + [Install] + WantedBy=multi-user.target + dest: /etc/systemd/system/no-vpn-network-namespace.service + mode: 0644 + notify: + - restart no-vpn network namespace + +- name: enable service for no-VPN network namespace + systemd: + daemon_reload: true + name: no-vpn-network-namespace.service + enabled: true + +- name: enable OpenVPN client service + systemd: + daemon_reload: true + name: openvpn-client@{{vpn_name}}.service + enabled: true + +- name: register the fact that a VPN is enabled + set_fact: + is_vpn_used: true + +### LOCAL COMMIT ⇒ ### +- name: commit local changes + include_role: name=etckeeper.inc allow_duplicates=true tasks_from=local.yml + vars: + msg: OpenVPN +### ⇐ LOCAL COMMIT ### +- meta: flush_handlers diff --git a/roles/openvpn/templates/nftables.conf.j2 b/roles/openvpn/templates/nftables.conf.j2 new file mode 100644 index 0000000..3501fd8 --- /dev/null +++ b/roles/openvpn/templates/nftables.conf.j2 @@ -0,0 +1,105 @@ +#!/usr/bin/env nft -f +# The home-server project produces a multi-purpose setup using Ansible. +# Copyright © 2018–2023 Y. Gablin, under the GPL-3.0-or-later license. +# Full licensing information in the LICENSE file, or gnu.org/licences/gpl-3.0.txt if the file is missing. + +flush ruleset + + +table arp RateLimiter { + chain ArpIn { + type filter hook input priority 0 + policy accept + meta iif if_isp limit rate 2/second burst 10 packets accept + } + + chain ArpOut { + type filter hook output priority 0 + policy accept + } +} + +{% for V in ['4', '6'] %} +{% set v = V | replace('4', '') %} +{% macro trust(list) %} +{% for net in list.split(' ') %} +{% if not net is match('127(?:\.\d{1,3}){3}(?:/\d+)?|::1|^$') %} +{% if (net is match('\d{1,3}(?:\.\d{1,3}){3}(?:/\d+)?') + and V == '4') or (net is search(':') and V == '6') %} +{{caller(net)}} +{% endif %} +{% endif %} +{% endfor %} +{% endmacro %} + +table ip{{v}} Inet{{V}} { + set ssdp_out { + type inet_service + timeout 5s + } + + chain FilterIn { + type filter hook input priority 0 + policy drop + + # early drop of invalid connections + ct state invalid drop + + # allow icmp +{% if V == '4' %} + icmp type { echo-reply, destination-unreachable, router-advertisement, time-exceeded, parameter-problem } accept + icmp type { source-quench, redirect, info-request, info-reply, address-mask-request, address-mask-reply } drop + meta l4proto icmp limit rate 2/second burst 4 packets accept +{% else %} + icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-reply, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept + meta l4proto ipv6-icmp limit rate 2/second burst 4 packets accept +{% endif %} + + # allow established/related connections + ct state {established, related} accept + + # allow from loopback +{% if V == '4' %} + meta iif lo ip saddr != 127.0.0.0/8 drop +{% else %} + meta iif lo ip6 saddr != ::1/128 drop +{% endif %} + meta iif lo accept + + # allow ssdp replies + udp dport @ssdp_out accept + + # zeroconf +{% call(net) trust(net_trusted_ranges) %} + udp dport 5353 ip{{v}} saddr {{net}} accept +{% endcall %} + + # transmission + tcp dport {{transmission_bt_port}} accept + udp dport {{transmission_bt_port}} accept + } + + chain FilterOut { + type filter hook output priority 0 + policy drop +{% if V == '4' %} + icmp type { echo-reply, destination-unreachable, router-advertisement, time-exceeded, parameter-problem } accept + icmp type { source-quench, redirect, info-request, info-reply, address-mask-request, address-mask-reply } drop + meta l4proto icmp limit rate 2/second burst 4 packets accept +{% else %} + icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-reply, nd-router-solicit, nd-neighbor-solicit, nd-neighbor-advert } accept + meta l4proto ipv6-icmp limit rate 2/second burst 4 packets accept +{% endif %} + ct state {established, related} accept + meta oif lo accept + meta oif if_isp udp dport 1900 set add udp sport @ssdp_out accept +{% call(net) trust(SafeZone_IP + ' ' + dns_hosts + ' ' + allowed_domains_ip + ' ' + ntp_hosts) %} + ip{{v}} daddr {{net}} accept +{% endcall %} + meta skuid transmission tcp dport 443 accept + meta skuid transmission udp dport 443 accept + meta skuid transmission tcp dport > 1024 accept + meta skuid transmission udp dport > 1024 accept + } +} +{% endfor %} diff --git a/roles/openvpn/templates/vpn.conf.j2 b/roles/openvpn/templates/vpn.conf.j2 new file mode 100644 index 0000000..76cb937 --- /dev/null +++ b/roles/openvpn/templates/vpn.conf.j2 @@ -0,0 +1,104 @@ +# Specify that we are a client and that we will be pulling certain config file +# directives from the server. +client + +# Use the same setting as you are using on the server. +# On most systems, the VPN will not function unless you partially or fully +# disable the firewall for the TUN/TAP interface. +dev {{vpn_interface_type}} + +# Are we connecting to a TCP or UDP server? +# Use the same setting as on the server. +proto {{vpn_protocol}} +port {{vpn_server_port}} + +# The hostname/IP and port of the server. +# You can have multiple remote entries to load balance between the servers. +remote {{vpn_server_host}} {{vpn_server_port}} + +# Choose a random host from the remote list for load-balancing. +# Otherwise try hosts in the order specified. +remote-random + +# Keep trying indefinitely to resolve the host name of the OpenVPN server. +# Very useful on machines which are not permanently connected to the internet +# such as laptops. +resolv-retry infinite +route-delay 2 + +# Use the VPN as the default network connection +redirect-gateway def1 bypass-dhcp # IPv4 +route-ipv6 2000::/3 # IPv6 + +# Most clients don't need to bind to a specific local port number. +nobind + +# Downgrade privileges after initialization. +;user openvpn +;group openvpn + +# Try to preserve some state across restarts. +persist-key +persist-tun + +# Try and avoid fragmentation issues. +fragment 1300 +mssfix 1300 + +# If you are connecting through an HTTP proxy to reach the actual OpenVPN +# server, put the proxy server/IP and port number here. +# See the man page if your proxy server requires authentication. +;http-proxy-retry # retry on connection failures +;http-proxy [proxy server] [proxy port #] + +# Wireless networks often produce a lot of duplicate packets. +# Set this flag to silence duplicate packet warnings. +;mute-replay-warnings + +# SSL/TLS parms. +# See the server config file for more description. +# It's best to use a separate .crt/.key file pair for each client. +# A single ca file can be used for all clients. +#ca ca.crt +#cert client.crt +#key client.key + +# Verify server certificate by checking that the certificate has the correct +# key usage set. +# This is an important precaution to protect against a potential attack +# discussed here: http://openvpn.net/howto.html#mitm +# +# To use this feature, you will need to generate your server certificates with +# the keyUsage set to +# digitalSignature, keyEncipherment +# and the extendedKeyUsage to +# serverAuth +# EasyRSA can do this for you. +remote-cert-tls server + +# If a tls-auth key is used on the server then every client must also have the +# key. +tls-auth {{vpn_name}}-ta.key 1 +auth-user-pass + +# Select a cryptographic cipher. +# If the cipher option is used on the server then you must also specify it +# here. +# Note that v2.4 client/server will automatically negotiate AES-256-GCM in TLS +# mode. +# See also the data-ciphers option in the manpage +cipher AES-256-CBC + +# Enable compression on the VPN link. +# Don't enable this unless it is also enabled in the server config file. +comp-lzo + +# Set log file verbosity. +verb 3 + +# Silence repeating messages +;mute 20 + + +{{vpn_ca_certificate}} + diff --git a/roles/php/handlers/main.yml b/roles/php/handlers/main.yml index 1dfe3e2..cb550c9 100644 --- a/roles/php/handlers/main.yml +++ b/roles/php/handlers/main.yml @@ -3,6 +3,9 @@ # Copyright © 2018–2023 Y. Gablin, under the GPL-3.0-or-later license. # Full licensing information in the LICENSE file, or gnu.org/licences/gpl-3.0.txt if the file is missing. +- name: create php-fpm tmpfiles + command: systemd-tmpfiles --create /etc/tmpfiles.d/run_php.conf + - name: restart php-fpm.service (front) systemd: daemon_reload: true diff --git a/roles/php/tasks/main.yml b/roles/php/tasks/main.yml index 42e27ce..2b6cdbd 100644 --- a/roles/php/tasks/main.yml +++ b/roles/php/tasks/main.yml @@ -26,6 +26,15 @@ - php-geoip - geoip-database-extra +- name: install front software + package: + name: "{{item}}" + state: present + with_items: + - php-fpm + when: + - (inventory_hostname in groups['front']) + ### UPSTREAM END ⇒ ### - name: merge upstream include_role: name=etckeeper.inc allow_duplicates=true tasks_from=merge.yml @@ -115,6 +124,100 @@ notify: - restart php-fpm.service (front) +- name: configure php-fpm + block: + + - name: create php-fpm working directories + copy: + content: | + #Type Path Mode UID GID Age Argument + d /run/php-fpm 775 http http - - + dest: /etc/tmpfiles.d/run_php.conf + mode: 0644 + notify: + - create php-fpm tmpfiles + + - name: prepare to override systemd settings + file: + name: /etc/systemd/system/{{item}}.service.d + state: directory + mode: 0755 + with_items: + - php-fpm + + - name: secure systemd settings for php-fpm + copy: + content: | + [Unit] + After=systemd-tmpfiles-setup.service + [Service] + User=http + Group=http + CapabilityBoundingSet=CAP_AUDIT_WRITE CAP_LEASE CAP_SYS_CHROOT + PrivateTmp=true + PrivateDevices=true + ProtectSystem=true + ProtectHome=true + NoNewPrivileges=true + PIDFile=/run/php-fpm/php-fpm.pid + dest: /etc/systemd/system/php-fpm.service.d/secure-{{nickname}}.conf + mode: 0644 + notify: + - restart php-fpm.service (front) + + - name: set the php-fpm settings + lineinfile: + path: /etc/php/php-fpm.d/www.conf + regexp: '^;*{{item.key}}\s*=' + line: '{{item.key}} = {{item.value}}' + with_dict: + listen: /run/shared_sockets/php-fpm + pm: dynamic + 'pm.max_children': '{{php_max_workers}}' + 'pm.start_servers': 1 + 'pm.min_spare_servers': 1 + 'pm.max_spare_servers': '{{php_max_workers}}' + 'pm.max_requests': '{{php_worker_max_reqs}}' + notify: + - restart php-fpm.service (front) + + - name: disable useless user/group specs + lineinfile: + path: /etc/php/php-fpm.d/www.conf + backrefs: true + regexp: '^({{item}}\s*=.*)' + line: ';\1' + with_items: + - user + - group + - 'listen.group' + notify: + - restart php-fpm.service (front) + + - name: set the PID file path for php-fpm + lineinfile: + path: /etc/php/php-fpm.conf + regexp: '^;*pid\s*=' + line: 'pid = /run/php-fpm/php-fpm.pid' + notify: + - restart php-fpm.service (front) + + - name: enable php-fpm.service + systemd: + daemon_reload: true + name: php-fpm.service + enabled: true + + - name: PHP test-page in test environment + copy: + content: