From abe052dbc6acc6ef7837037987288f0ca65c2c38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Rodier?= Date: Thu, 21 Sep 2023 18:46:20 +0100 Subject: [PATCH] Multiple updates --- docs/antispam-rspamd.md | 22 +++++++++++----- docs/index.md | 7 ++--- docs/installation.md | 19 +++++++++----- playbooks/check.yml | 20 +++++++------- roles/certificates/files/cert-renew.sh | 26 ++++++++++++++----- .../certificates/templates/cert-renew.service | 1 + roles/certificates/templates/renew.conf | 2 +- roles/common-init/tasks/check/main.yml | 6 +++++ roles/dns-pdns/files/dns-status.sh | 7 ++++- roles/ejabberd/templates/apparmor.conf | 6 ++++- roles/nginx/templates/apparmor-base.conf | 4 +++ roles/rspamd/templates/apparmor/redis.conf | 5 ++++ .../templates/apparmor.d/usr.sbin.sogo-backup | 3 ++- 13 files changed, 89 insertions(+), 39 deletions(-) diff --git a/docs/antispam-rspamd.md b/docs/antispam-rspamd.md index d16413139..0e06d3673 100644 --- a/docs/antispam-rspamd.md +++ b/docs/antispam-rspamd.md @@ -2,12 +2,21 @@ ## Default configuration -By default, the mail server is protected against spam with rspamd. +By default, the mail server is protected against spam with [rspamd](https://www.rspamd.com/). -Optionally, the web user interface is accessible from the LAN: +```yml +mail: + […] + antispam: # Check inbound and outbound emails for viruses + active: true # use false to disable +``` + +Optionally, the web user interface is accessible from the local network: -```yaml - antispam: # Check inbound and outbound emails for virusesyaml +```yml +mail: + [...] + antispam: # Check inbound and outbound emails for viruses webui: # rspamd web interface active: true # Activate or not allow: # a list of IP address that can access the web interface @@ -16,6 +25,5 @@ Optionally, the web user interface is accessible from the LAN: - 10.0.0.0/8 ``` -A strong password is generated for the administrator account. -After the deployment, the password is stored in the credentials store, -using `rspamd/admin.pwd`. +A strong password is generated for the administrator account. After the deployment, the password is stored in the +credentials store, using `rspamd/admin`. diff --git a/docs/index.md b/docs/index.md index 8784dd8c1..3e64e71e4 100644 --- a/docs/index.md +++ b/docs/index.md @@ -14,11 +14,8 @@ This project is for you if: ## Philosophy - You should be able to upgrade anything installed via the apt command. No git clone / wget / curl here, ever. -- If you are using your own hardware, the disk can be fully encrypted using - [LUKS](https://en.wikipedia.org/wiki/Linux_Unified_Key_Setup). - Nobody will be able to steal your hardware _and_ your information. -- AppArmor is activated on the first boot, and all the services are configured to support it. This makes your server - very safe against remote intrusion, even when using 0-day vulnerabilities. +- Most of the services are protected AppArmor kernel security module. This makes your server very safe against remote + intrusion and 0-day vulnerabilities. - You can set up multiple backup destination, local and remote, all encrypted. - A lot of default choices made towards simplicity, [KISS principle](https://en.wikipedia.org/wiki/KISS_principle), and safety. diff --git a/docs/installation.md b/docs/installation.md index cd78a3abc..856aadaca 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -22,10 +22,21 @@ all: ansible_port: 22 ``` +To use Python3 as the default interpreter: + +``` yaml hl_lines="7" +all: + hosts: + homebox: + ansible_host: 192.168.1.254 + ansible_user: root + ansible_port: 22 + ansible_python_interpreter: /usr/bin/python3 +``` + Using root during the installation process is a requirement. However, the system can be configured to use sudo once installed. See the security section, [Defining administrators](/security-configuration/#defining-administrators). - ## Step 2: Describe your system The main configuration file to create is in the config folder. There is an example named system-example.yml ready to @@ -58,7 +69,6 @@ Once you have modified the file, you are ready to start the installation. You need to be careful with the indentation in your Yaml file, the number of spaces is significant. - ## Step 3: Configure your system @@ -79,7 +89,6 @@ The hostname is important, use the real one. If you used the preseed configurati network domain. - ### External IP addresses It is important here to specify the external IP address(es) your system can be reached at. @@ -99,7 +108,6 @@ network: If you do not have a backup IP address, use "~", which means "None" or Null in yaml. - ### Users list The file format should be self-explanatory. The other piece of information you need to fill first is the user list. In @@ -129,7 +137,6 @@ You do not have to set the passwords for each user. A random password will be ge _pass_, in the ldap sub directory. - ### Email options This is the second most important settings. Here is an example of the email options you can override: @@ -146,7 +153,6 @@ mail: Advanced options are detailed on the [email configuration](email-configuration.md) page. - ### Security options Security options are detailed on the [security page](security-configuration.md). @@ -218,7 +224,6 @@ For instance, for the domain `example.net`, the API key need to be stored into p choice, using the following path: `example.net/gandi/api-key`. - ## Step 4: Start the installation You can choose a flavour to install, using a different playbook. Four playbooks are included by default: mini, small, diff --git a/playbooks/check.yml b/playbooks/check.yml index 568dae018..3f7d2550f 100644 --- a/playbooks/check.yml +++ b/playbooks/check.yml @@ -5,15 +5,6 @@ # export the roles you want to run in the ‘ROLE’ environment variable, # using a coma separated list. -- name: Load the common tasks - hosts: homebox - vars_files: - - '{{ playbook_dir }}/../config/system.yml' - - '{{ playbook_dir }}/../config/defaults.yml' - roles: - - role: common-init - tags: always - - name: Load the roles to run hosts: homebox tags: always @@ -24,13 +15,22 @@ - name: Run the checking tasks for each role hosts: homebox + vars: + debug: '{{ system.debug }}' + backup_directory: '{{ playbook_dir }}/../backup/{{ network.domain }}/' vars_files: + - '{{ playbook_dir }}/../config/defaults/common-security.yml' + - '{{ playbook_dir }}/../config/defaults/version-{{ version | default("small") }}.yml' - '{{ playbook_dir }}/../config/system.yml' - - '{{ playbook_dir }}/../config/defaults.yml' tasks: - name: Reset the SSH connection meta: reset_connection tags: always + - name: Run common initialisation tasks + include_role: + name: common-init + tasks_from: check/main.yml + tags: always - name: Run the roles selected include_role: name: '{{ role }}' diff --git a/roles/certificates/files/cert-renew.sh b/roles/certificates/files/cert-renew.sh index 144bd8899..1f6b888a4 100644 --- a/roles/certificates/files/cert-renew.sh +++ b/roles/certificates/files/cert-renew.sh @@ -91,6 +91,7 @@ for cert in $certs; do # Get the FQDN from the filename fqdn=$(basename "$cert" '.key') + cert_file="/var/lib/lego/certificates/${fqdn}.crt" if [ "$fqdn" = "_.$domain" ]; then fqdn="*.$domain" @@ -113,18 +114,31 @@ for cert in $certs; do common_options="$common_options --pem" fi - renew_options="--reuse-key" - renew_options="$renew_options --renew-hook run-parts /etc/lego/hooks/$fqdn/" - # When not live, just display the command that would be run if [ "$live" != "1" ]; then msg "lego $common_options renew $renew_options" continue fi - # Renew X certificate at a time. - if ! lego $common_options renew $renew_options; then - msg "Could not renew certificate '$cert'. Trying the next" + # If if it a temporary certificate, use run, instead of renew. + temp_ca=$(openssl x509 -in "$cert_file" -noout -issuer | grep -c "Temporary CA") + + msg "Temporary CA: $temp_ca" + + # By default, renew the certificate unless it is a temporary one + if [ "$temp_ca" = "1" ]; then + run_options="" + success=$(lego $common_options run $run_options) + msg "Generating new certificate $fqdn: $success" + else + renew_options="--reuse-key --renew-hook run-parts /etc/lego/hooks/$fqdn/" + success=$(lego $common_options renew $renew_options) + msg "Renewing certificate $fqdn: $success" + fi + + if ! $success; then + # Renew X certificate at a time. + msg "Could not run/renew certificate '$fqdn'. Trying the next" continue fi diff --git a/roles/certificates/templates/cert-renew.service b/roles/certificates/templates/cert-renew.service index 1b1dae27f..04075d63b 100644 --- a/roles/certificates/templates/cert-renew.service +++ b/roles/certificates/templates/cert-renew.service @@ -3,6 +3,7 @@ Description=Certificate renewal service After=network.target [Service] +WorkingDirectory=/etc/lego Type=oneshot ExecStart=/usr/local/sbin/cert-renew RemainAfterExit=false diff --git a/roles/certificates/templates/renew.conf b/roles/certificates/templates/renew.conf index 4129d1ea6..eee429a48 100644 --- a/roles/certificates/templates/renew.conf +++ b/roles/certificates/templates/renew.conf @@ -1,4 +1,4 @@ PDNS_API_KEY={{ api_key }} PDNS_API_URL=http://{{ pdns_api.address }}:{{ pdns_api.port }}/ CERT_SERVER={{ acme_url }} -CERT_EMAIL=security@{{ network.domain }} \ No newline at end of file +CERT_EMAIL=security@{{ network.domain }} diff --git a/roles/common-init/tasks/check/main.yml b/roles/common-init/tasks/check/main.yml index ed97d539c..8b5a454b0 100644 --- a/roles/common-init/tasks/check/main.yml +++ b/roles/common-init/tasks/check/main.yml @@ -1 +1,7 @@ --- + +- name: Load and merge user and default settings + ansible.builtin.include_tasks: install/load-defaults.yml + +- name: Parse external IP address types + ansible.builtin.include_tasks: install/external-ips.yml diff --git a/roles/dns-pdns/files/dns-status.sh b/roles/dns-pdns/files/dns-status.sh index fc175acb3..4dce91392 100644 --- a/roles/dns-pdns/files/dns-status.sh +++ b/roles/dns-pdns/files/dns-status.sh @@ -33,7 +33,11 @@ if host "$domain" 2606:4700:4700::64 2>&1 >/dev/null; then elif host "$domain" 1.1.1.1 2>&1 >/dev/null; then dns_server=1.1.1.1 else - printf "DNS server for ${domain} is not live." + printf "DNS server for ${domain} is not live.\n" + + # More detailed report + delv "$domain" + exit $DOMAIN_NOT_LIVE fi @@ -45,6 +49,7 @@ if [ "$public_keys" != "$local_keys" ]; then printf "DNS keys are not published\n" dnskeys_details + exit $DNSSEC_NOT_LIVE fi diff --git a/roles/ejabberd/templates/apparmor.conf b/roles/ejabberd/templates/apparmor.conf index 488083f8b..15019e465 100644 --- a/roles/ejabberd/templates/apparmor.conf +++ b/roles/ejabberd/templates/apparmor.conf @@ -15,10 +15,14 @@ capability dac_read_search, # for sed /{,usr/}bin/bash mrix, - /{,usr/}bin/cat ix, /{,usr/}bin/dash mrix, + + /{,usr/}bin/basename ix, + /{,usr/}bin/cat ix, /{,usr/}bin/date ix, /{,usr/}bin/df ix, + /{,usr/}bin/dirname ix, + /{,usr/}bin/mawk ix, /{,usr/}bin/{,p}grep ix, /{,usr/}bin/ps ix, /{,usr/}bin/sed ix, diff --git a/roles/nginx/templates/apparmor-base.conf b/roles/nginx/templates/apparmor-base.conf index a1398c263..c3e7e60b4 100644 --- a/roles/nginx/templates/apparmor-base.conf +++ b/roles/nginx/templates/apparmor-base.conf @@ -51,6 +51,10 @@ # Nginx need to access pam config /etc/pam.d/* r, + # sysfs access + /sys/devices/system/node/ r, + /sys/devices/system/node/** r, + # Local includes for homebox # End of local includes for homebox } diff --git a/roles/rspamd/templates/apparmor/redis.conf b/roles/rspamd/templates/apparmor/redis.conf index ae6b2b789..b34e358a6 100644 --- a/roles/rspamd/templates/apparmor/redis.conf +++ b/roles/rspamd/templates/apparmor/redis.conf @@ -5,6 +5,10 @@ #include #include + # allow to create inet streams + network inet stream, + network inet6 stream, + # Exeecutable /usr/bin/redis-check-rdb mr, @@ -12,6 +16,7 @@ owner /etc/redis/redis.conf r, # Database + owner /var/lib/redis/ rw, owner /var/lib/redis/* rwk, # Log files diff --git a/roles/sogo/templates/apparmor.d/usr.sbin.sogo-backup b/roles/sogo/templates/apparmor.d/usr.sbin.sogo-backup index 48b9f1a3b..6dec1cfd4 100644 --- a/roles/sogo/templates/apparmor.d/usr.sbin.sogo-backup +++ b/roles/sogo/templates/apparmor.d/usr.sbin.sogo-backup @@ -10,7 +10,6 @@ # capabilities capability dac_override, - # Executables /usr/sbin/sogo-backup r, /usr/sbin/sogo-tool mr, @@ -90,7 +89,9 @@ /usr/share/GNUstep/** r, # backup folders + owner /var/backups/sogo/ w, /var/backups/backups/ rw, /var/backups/backups/** r, /var/backups/backups/** rw, + }