diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2a4c9e60..ba289fd4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -21,6 +21,111 @@ The **patch** part changes is incremented if multiple releases happen the same m
### Security
+## [24.02] 2024-02-08
+
+### Added
+
+* Support for PHP 8.3 with bookworm LXC containers
+* apt: add task file to install ELTS repository (default: False)
+* autosysadmin: Add a role to automatically deploy autosysadmin on evolixisation
+* check_free_space: added role
+* etc-git: add /var/chroot-bind/etc/bind repo
+* fail2ban: add script unban_ip
+* generateldif: new Services for check_pressure_{cpu,io,mem}
+* kvm-host: Automatically add an LVM filter when LVM is present
+* lxc-php: Allow one to install php83 on Bookworm container
+* minifirewall: Fix nagios check for old versions of minifirewall
+* mongodb: add gpg key for 7.0
+* nagios-nrpe: add check_sentinel for monitoring Redis Sentinel
+* nagios-nrpe: new check_pressure_{cpu,io,mem}
+* remount-usr: do not try to remount /usr RW if /usr is not a mounted partition
+* vrrpd: configure minifirewall
+* vrrpd: test if interface exists before deleting it
+* webapps/evoadmin-mail: package installed via public.evolix.org/evolix repo starting with Bookworm
+* webapps/nextcloud: Add condition for archive tasks
+* webapps/nextcloud: Add condition for config tasks
+* webapps/nextcloud: Added var nextcloud_user_uid to enforce uid for nextcloud user
+* webapps/nextcloud: Set ownership and permissions of data directory
+
+### Changed
+
+* add-vm.sh: allow VM name max length > 20
+* amavis: make ldap_suffix mandatory
+* apache : fix goaway pattern for bad bots
+* apache : rename MaxRequestsPerChild to MaxConnectionsPerChild (new name)
+* apache: use backward compatible Redirect directive
+* apt: Disable archive repository for Debian 8
+* apt: Use the GPG version of the key for Debian 8-9
+* bind: Update role for Buster, Bullseye and Bookworm support
+* dovecot: add variables for LDAP
+* dovecot: Munin plugin conf path is now `/etc/munin/plugin-conf.d/zzz-dovecot` (instead of `z-evolinux-dovecot`)
+* evocheck: upstream release 24.01
+* evolinux-base: dump-server-state upstream release 23.11
+* evolinux-base: use separate default config file for rsyslog
+* kvmstats: use .capacity instead of .physical for disk size
+* ldap: make ldap_suffix mandatory
+* listupgrade : old-kernel-removal.sh upstream release 24.01
+* log2mail: move custom config in separate file
+* lxc: init /etc git repository in lxc container
+* mysql: disable performance schema for Debian 8
+* nagios: add dockerd check in nrpe check template
+* nagios: cleaning nrpe check template
+* nagios: rename var `nagios_nrpe_process_processes` into `nagios_nrpe_processes` and check systemd-timesyncd instead of ntpd in Debian 12
+* proftpd: in SFTP vhost, enable SSH keys login, enable ed25549 host key for Debian >= 11
+* redis: manage config template inside a block, to allow custom modifications outside
+* spamassassin: Use spamd starting with Bookworm
+* squid: config directory seems to have changed from /etc/squid3 to /etc/squid in Debian 8
+* unbound: Add config file to allow configuration reload on Debian 11 and lower
+* unbound: Add munin configuration & setup plugin
+* unbound: Big cleanup
+* unbound: Move generated config file to `/etc/unbound/unbound.conf.d/evolinux.conf`
+* unbound: Use root hints provided by debian package dns-root-data instead of downloading them
+* vrrpd: replace switch script with custom one (fix MAC issue, use `ip(8)`, shell cleanup…)
+* vrrpd: variable to force update the switch script (default: false)
+* webapps/nextcloud: Add Ceph volume to fstab
+* webapps/nextcloud: Set home directory's mode
+
+### Fixed
+
+* Add php-fpm82 to LDAP when relevant
+* Check stat.exists before stat.isdir
+* apache: fix MaxRequestsPerChild value to be sync with wiki.e.o
+* apt: use archive.debian.org with Stretch
+* certbot: fix hook for dovecot when more than one certificate is used (eg. different certificates for POP3 and IMAP)
+* dovecot: add missing LDAP conf iterate_filter to exclude disabled accounts in users list (caused « User no longer exists » errors in commands listing users like « doveadm user -u '*' » or « doveadm expunge -u "*" mailbox INBOX savedbefore 7d »).
+* dovecot: fix missing default mails
+* dovecot: fix plugin dovecot1
+* evoadmin-web: Fix PHP version for Bookworm
+* evolinux-base: fix hardware.yml (wrong repo, missing update cache)
+* evolinux-base: start to install linux-image-cloud-amd64 with Buster
+* fail2ban: fix template marker
+* minifirewall: ports 25, 53, 443, 993, 995 not opened publicly by default anymore, ports 20, 21, 110, 143 not opened semi-publicly by default anymore.
+* nagios: fix default file to monitor for check_clamav_db
+* nginx: add "when: not ansible_check_mode" in various tasks to prevent fail in check mode
+* nginx: fix mistake between "check_mode: no" and "when: not ansible_check_mode" (fail in check mode)
+* nginx: fix mistake between "check_mode: no" and "when: not ansible_check_mode" (fail in check mode)
+* nginx: keep indentation
+* nginx: take care of « already defined » and « not yet defined » server status suffix in check mode
+* php: Bullseye/Sury > Honor the php_version asked in the pub.evolix.org repository
+* php: drop apt_preferences(5) file for sury
+* postfix: remove dependency on evolinux_fqdn var
+* proftpd: set missing default listen IP for SFTP
+* roundcube: set default SMTP port to 25 instead of 587, which failed because of missing SSL conf (local connexion does not need SSL)
+* ssl: no not execute haproxy tasks and reload if haproxy is disabled
+* unbound: Add a apt cache validity to enforce an apt update if needed
+* webapps/nextcloud: added check that nextcloud uid is over 3000
+* webapps/nextcloud: fix Add Ceph volume to fstab : missing UUID= in src
+* webapps/nextcloud: fix misplaced gid attribute
+* webapps/nextcloud: fix missing gid
+* webapps/roundcube & evoadminmail: make roles more idempotent (were failing when played twice)
+* amavis: Add variables for generate "ldap_suffix"
+* proftpd: fix error when no SSH key is provided
+
+### Removed
+
+* evolinux-base: no need to remove update-evobackup-canary from sbin anymore
+* evolinux-base: no need to symlink backup-server-state to dump-server-state anymore
+
## [23.10] 2023-10-14
### Added
@@ -381,16 +486,16 @@ The **patch** part changes is incremented if multiple releases happen the same m
### Added
-* docker : Introduce new default settings + allow to change the docker data directory
-* docker : Introduce new variables to tweak daemon settings
+* docker: Introduce new default settings + allow to change the docker data directory
+* docker: Introduce new variables to tweak daemon settings
### Changed
-* evocheck: upstream release 22.05
+* evocheck: Upstream release 22.05
### Removed
-* docker : Removed Debian Jessie support
+* docker: Removed Debian Jessie support
## [22.05] 2022-05-10
diff --git a/amavis/defaults/main.yml b/amavis/defaults/main.yml
new file mode 100644
index 00000000..c353a3ba
--- /dev/null
+++ b/amavis/defaults/main.yml
@@ -0,0 +1,5 @@
+---
+
+ldap_hostname: "{{ ansible_hostname }}"
+ldap_domain: "{{ ansible_domain }}"
+ldap_suffix: "dc={{ ldap_hostname }},dc={{ ldap_domain.split('.')[-2] }},dc={{ ldap_domain.split('.')[-1] }}"
diff --git a/amavis/tasks/main.yml b/amavis/tasks/main.yml
index da46721e..e9f67b4d 100644
--- a/amavis/tasks/main.yml
+++ b/amavis/tasks/main.yml
@@ -6,7 +6,7 @@
- amavisd-new
state: present
tags:
- - amavis
+ - amavis
- name: configure Amavis
ansible.builtin.template:
@@ -15,7 +15,7 @@
mode: "0644"
notify: restart amavis
tags:
- - amavis
+ - amavis
- name: Install purge custom cron
ansible.builtin.copy:
@@ -23,5 +23,5 @@
dest: /etc/cron.daily/amavis_purge_virusmails
mode: "0755"
tags:
- - amavis
- - amavis_purge_cron
+ - amavis
+ - amavis_purge_cron
diff --git a/amavis/templates/amavis.conf.j2 b/amavis/templates/amavis.conf.j2
index cbe597a2..8bc9bae8 100644
--- a/amavis/templates/amavis.conf.j2
+++ b/amavis/templates/amavis.conf.j2
@@ -44,7 +44,7 @@ $max_servers = 2;
$enable_ldap = 1;
$default_ldap = {
hostname => '127.0.0.1', tls => 0,
- base => '{{ ldap_suffix }}', scope => 'sub',
+ base => '{{ ldap_suffix | mandatory }}', scope => 'sub',
query_filter => '(&(mailacceptinggeneralid=%m)(isActive=TRUE))'
};
diff --git a/apache/files/evolinux-defaults.conf b/apache/files/evolinux-defaults.conf
index 65c8c921..c05f77f2 100644
--- a/apache/files/evolinux-defaults.conf
+++ b/apache/files/evolinux-defaults.conf
@@ -10,7 +10,7 @@ MaxKeepAliveRequests 10
StartServers 50
MinSpareServers 20
MaxSpareServers 30
- MaxRequestsPerChild 0
+ MaxConnectionsPerChild 100
@@ -20,7 +20,7 @@ MaxKeepAliveRequests 10
ThreadLimit 64
ThreadsPerChild 25
MaxRequestWorkers 150
- MaxConnectionsPerChild 0
+ MaxConnectionsPerChild 100
@@ -40,28 +40,25 @@ MaxKeepAliveRequests 10
-
-
- AllowOverride None
- Require all granted
- # "Require not env XXX" is not supported :(
- Deny from env=GoAway
-
+# Go away bad bots (define "bad bots" in zzz-evolinux-custom.conf)
+
+ Require all denied
+
# We don't want to let the client know a file exist on the server,
# so we return 404 "Not found" instead of 403 "Forbidden".
- Redirect 404
+ Redirect 404 "-"
# File names starting with
- Redirect 404
+ Redirect 404 "-"
# File names ending with
- Redirect 404
+ Redirect 404 "-"
diff --git a/apache/tasks/ip_whitelist.yml b/apache/tasks/ip_whitelist.yml
index 5060f56e..bb7e8f46 100644
--- a/apache/tasks/ip_whitelist.yml
+++ b/apache/tasks/ip_whitelist.yml
@@ -5,6 +5,7 @@
dest: /etc/apache2/ipaddr_whitelist.conf
line: "Require ip {{ item }}"
state: present
+ create: yes
loop: "{{ apache_ipaddr_whitelist_present }}"
notify: reload apache
tags:
diff --git a/apt/defaults/main.yml b/apt/defaults/main.yml
index 3720d893..772a8fb9 100644
--- a/apt/defaults/main.yml
+++ b/apt/defaults/main.yml
@@ -14,6 +14,7 @@ apt_install_backports: False
apt_backports_components: "main"
apt_install_evolix_public: True
+apt_install_extended_lts: False
apt_clean_gandi_sourceslist: False
@@ -28,4 +29,4 @@ apt_check_hold_cron_weekday: "*"
apt_check_hold_cron_day: "*"
apt_check_hold_cron_month: "*"
-apt_keyring_dir: "{{ ansible_distribution_major_version is version('12', '<') | ternary('/etc/apt/trusted.gpg.d', '/etc/apt/keyrings') }}"
\ No newline at end of file
+apt_keyring_dir: "{{ ansible_distribution_major_version is version('12', '<') | ternary('/etc/apt/trusted.gpg.d', '/etc/apt/keyrings') }}"
diff --git a/apt/files/bookworm_backports_preferences b/apt/files/bookworm_backports_preferences
deleted file mode 100644
index eaf76d52..00000000
--- a/apt/files/bookworm_backports_preferences
+++ /dev/null
@@ -1,3 +0,0 @@
-Package: *
-Pin: release a=bookworm-backports
-Pin-Priority: 50
diff --git a/apt/files/bullseye_backports_preferences b/apt/files/bullseye_backports_preferences
deleted file mode 100644
index 3a667c93..00000000
--- a/apt/files/bullseye_backports_preferences
+++ /dev/null
@@ -1,3 +0,0 @@
-Package: *
-Pin: release a=bullseye-backports
-Pin-Priority: 50
diff --git a/apt/files/buster_backports_preferences b/apt/files/buster_backports_preferences
deleted file mode 100644
index 30fef48d..00000000
--- a/apt/files/buster_backports_preferences
+++ /dev/null
@@ -1,3 +0,0 @@
-Package: *
-Pin: release a=buster-backports
-Pin-Priority: 50
diff --git a/apt/files/freexian-archive-extended-lts.gpg b/apt/files/freexian-archive-extended-lts.gpg
new file mode 100644
index 00000000..819c10ff
Binary files /dev/null and b/apt/files/freexian-archive-extended-lts.gpg differ
diff --git a/apt/files/jessie_backports_preferences b/apt/files/jessie_backports_preferences
deleted file mode 100644
index dd3cef12..00000000
--- a/apt/files/jessie_backports_preferences
+++ /dev/null
@@ -1,3 +0,0 @@
-Package: *
-Pin: release a=jessie-backports
-Pin-Priority: 50
diff --git a/apt/files/stretch_backports_preferences b/apt/files/stretch_backports_preferences
deleted file mode 100644
index 6d5d03be..00000000
--- a/apt/files/stretch_backports_preferences
+++ /dev/null
@@ -1,3 +0,0 @@
-Package: *
-Pin: release a=stretch-backports
-Pin-Priority: 50
diff --git a/apt/tasks/backports.deb822.yml b/apt/tasks/backports.deb822.yml
index 0382892d..db117d94 100644
--- a/apt/tasks/backports.deb822.yml
+++ b/apt/tasks/backports.deb822.yml
@@ -10,19 +10,9 @@
tags:
- apt
-- name: Backports configuration
- ansible.builtin.copy:
- src: '{{ ansible_distribution_release }}_backports_preferences'
- dest: /etc/apt/preferences.d/0-backports-defaults
- force: true
- mode: "0640"
- register: apt_backports_config
- tags:
- - apt
-
- name: Apt update
ansible.builtin.apt:
update_cache: yes
- when: apt_backports_sources is changed or apt_backports_config is changed
+ when: apt_backports_sources is changed
tags:
- apt
diff --git a/apt/tasks/backports.oneline.yml b/apt/tasks/backports.oneline.yml
index 11de5c52..1630de19 100644
--- a/apt/tasks/backports.oneline.yml
+++ b/apt/tasks/backports.oneline.yml
@@ -17,16 +17,6 @@
tags:
- apt
-- name: Backports configuration
- ansible.builtin.copy:
- src: '{{ ansible_distribution_release }}_backports_preferences'
- dest: /etc/apt/preferences.d/0-backports-defaults
- force: true
- mode: "0640"
- register: apt_backports_config
- tags:
- - apt
-
- name: Archived backport are accepted (jessie)
ansible.builtin.lineinfile:
dest: '/etc/apt/apt.conf.d/99no-check-valid-until'
@@ -42,4 +32,4 @@
update_cache: yes
tags:
- apt
- when: apt_backports_list is changed or apt_backports_config is changed
+ when: apt_backports_list is changed
diff --git a/apt/tasks/evolix_public.deb822.yml b/apt/tasks/evolix_public.deb822.yml
index 0a91dddf..0e6639c3 100644
--- a/apt/tasks/evolix_public.deb822.yml
+++ b/apt/tasks/evolix_public.deb822.yml
@@ -24,10 +24,16 @@
owner: root
group: root
+- name: Set Evolix GPG key format to ASC
+ set_fact:
+ apt_evolix_public_key: "{{ apt_keyring_dir }}/pub_evolix.asc"
+ tags:
+ - apt
+
- name: Add Evolix GPG key
ansible.builtin.copy:
src: pub_evolix.asc
- dest: "{{ apt_keyring_dir }}/pub_evolix.asc"
+ dest: "{{ apt_evolix_public_key }}"
force: true
mode: "0644"
owner: root
diff --git a/apt/tasks/evolix_public.oneline.yml b/apt/tasks/evolix_public.oneline.yml
index 9501e595..165a7b93 100644
--- a/apt/tasks/evolix_public.oneline.yml
+++ b/apt/tasks/evolix_public.oneline.yml
@@ -24,10 +24,26 @@
owner: root
group: root
+- name: Set Evolix GPG key format to GPG (Debian < 9)
+ set_fact:
+ apt_evolix_public_key: "pub_evolix.gpg"
+ when:
+ - ansible_distribution_major_version is version('9', '<')
+ tags:
+ - apt
+
+- name: Set Evolix GPG key format to ASC (Debian >= 9)
+ set_fact:
+ apt_evolix_public_key: "pub_evolix.asc"
+ when:
+ - ansible_distribution_major_version is version('9', '>=')
+ tags:
+ - apt
+
- name: Add Evolix GPG key
ansible.builtin.copy:
- src: pub_evolix.asc
- dest: "{{ apt_keyring_dir }}/pub_evolix.asc"
+ src: "{{ apt_evolix_public_key }}"
+ dest: "{{ apt_keyring_dir }}/{{ apt_evolix_public_key }}"
force: true
mode: "0644"
owner: root
diff --git a/apt/tasks/extended-lts.oneline.yml b/apt/tasks/extended-lts.oneline.yml
new file mode 100644
index 00000000..09974684
--- /dev/null
+++ b/apt/tasks/extended-lts.oneline.yml
@@ -0,0 +1,37 @@
+---
+
+- name: "Ensure {{ apt_keyring_dir }} directory exists"
+ file:
+ path: "{{ apt_keyring_dir }}"
+ state: directory
+ mode: "755"
+ owner: root
+ group: root
+
+- name: Add Evolix GPG key
+ ansible.builtin.copy:
+ src: "freexian-archive-extended-lts.gpg"
+ dest: "{{ apt_keyring_dir }}/freexian-archive-extended-lts.gpg"
+ force: true
+ mode: "0644"
+ owner: root
+ group: root
+ tags:
+ - apt
+
+- name: ELTS list is installed
+ ansible.builtin.template:
+ src: "{{ ansible_distribution_release }}_extended-lts.list.j2"
+ dest: /etc/apt/sources.list.d/extended-lts.list
+ force: true
+ mode: "0640"
+ register: apt_extended_lts
+ tags:
+ - apt
+
+- name: Apt update
+ ansible.builtin.apt:
+ update_cache: yes
+ tags:
+ - apt
+ when: apt_extended_lts is changed
diff --git a/apt/tasks/main.yml b/apt/tasks/main.yml
index 4d357f8b..bc65d7b9 100644
--- a/apt/tasks/main.yml
+++ b/apt/tasks/main.yml
@@ -80,6 +80,14 @@
- apt_install_evolix_public | bool
- ansible_distribution_major_version is version('12', '>=')
+- name: Install Extended-LTS repositories (Debian < 10)
+ ansible.builtin.import_tasks: extended-lts.oneline.yml
+ tags:
+ - apt
+ when:
+ - apt_install_extended_lts | bool
+ - ansible_distribution_major_version is version('10', '<')
+
- name: Clean GANDI sources
ansible.builtin.file:
path: '{{ item }}'
@@ -126,4 +134,4 @@
upgrade: dist
when: apt_upgrade | bool
tags:
- - apt
\ No newline at end of file
+ - apt
diff --git a/apt/tasks/migrate-to-deb822.yml b/apt/tasks/migrate-to-deb822.yml
index e7339e8b..e79ddf82 100644
--- a/apt/tasks/migrate-to-deb822.yml
+++ b/apt/tasks/migrate-to-deb822.yml
@@ -31,6 +31,11 @@
tags:
- apt
+- name: Is system.sources present?
+ ansible.builtin.stat:
+ path: /etc/apt/sources.list.d/system.sources
+ register: _system_sources
+
- name: Add signed-by when relevant for bookworm
ansible.builtin.lineinfile:
dest: /etc/apt/sources.list.d/system.sources
@@ -39,6 +44,12 @@
state: present
tags:
- apt
+ when: _system_sources.stat.exists or not ansible_check_mode
+
+- name: Is security.sources present?
+ ansible.builtin.stat:
+ path: /etc/apt/sources.list.d/security.sources
+ register: _security_sources
- name: Add signed-by when relevant for bookworm-security
ansible.builtin.lineinfile:
@@ -48,3 +59,4 @@
state: present
tags:
- apt
+ when: _security_sources.stat.exists or not ansible_check_mode
diff --git a/apt/templates/bookworm_basics.sources.j2 b/apt/templates/bookworm_basics.sources.j2
index 948c4adf..747e2e53 100644
--- a/apt/templates/bookworm_basics.sources.j2
+++ b/apt/templates/bookworm_basics.sources.j2
@@ -3,6 +3,6 @@
Types: deb
URIs: http://mirror.evolix.org/debian
Suites: bookworm bookworm-updates
-Components: {{ apt_basics_components | mandatory }}
+Components: {{ apt_basics_components | mandatory }}
Enabled: yes
Signed-By: /usr/share/keyrings/debian-archive-bookworm-automatic.gpg
diff --git a/apt/templates/bookworm_security.sources.j2 b/apt/templates/bookworm_security.sources.j2
index 07f1345b..b70fcec1 100644
--- a/apt/templates/bookworm_security.sources.j2
+++ b/apt/templates/bookworm_security.sources.j2
@@ -3,6 +3,6 @@
Types: deb
URIs: https://security.debian.org/debian-security
Suites: bookworm-security
-Components: {{ apt_basics_components | mandatory }}
+Components: {{ apt_basics_components | mandatory }}
Enabled: yes
-Signed-By: /usr/share/keyrings/debian-archive-bookworm-security-automatic.gpg
\ No newline at end of file
+Signed-By: /usr/share/keyrings/debian-archive-bookworm-security-automatic.gpg
diff --git a/apt/templates/bullseye_basics.list.j2 b/apt/templates/bullseye_basics.list.j2
index 55f32b8d..d1820d0f 100644
--- a/apt/templates/bullseye_basics.list.j2
+++ b/apt/templates/bullseye_basics.list.j2
@@ -1,5 +1,5 @@
# {{ ansible_managed }}
deb http://mirror.evolix.org/debian bullseye {{ apt_basics_components | mandatory }}
-deb http://mirror.evolix.org/debian/ bullseye-updates {{ apt_basics_components | mandatory }}
+deb http://mirror.evolix.org/debian bullseye-updates {{ apt_basics_components | mandatory }}
deb http://security.debian.org/debian-security bullseye-security {{ apt_basics_components | mandatory }}
diff --git a/apt/templates/buster_basics.list.j2 b/apt/templates/buster_basics.list.j2
index 58209ba0..b392ce58 100644
--- a/apt/templates/buster_basics.list.j2
+++ b/apt/templates/buster_basics.list.j2
@@ -1,5 +1,5 @@
# {{ ansible_managed }}
deb http://mirror.evolix.org/debian buster {{ apt_basics_components | mandatory }}
-deb http://mirror.evolix.org/debian/ buster-updates {{ apt_basics_components | mandatory }}
+deb http://mirror.evolix.org/debian buster-updates {{ apt_basics_components | mandatory }}
deb http://security.debian.org/debian-security buster/updates {{ apt_basics_components | mandatory }}
diff --git a/apt/templates/evolix_public.list.j2 b/apt/templates/evolix_public.list.j2
index e00899e7..7ed18708 100644
--- a/apt/templates/evolix_public.list.j2
+++ b/apt/templates/evolix_public.list.j2
@@ -1,3 +1,3 @@
# {{ ansible_managed }}
-deb [signed-by={{ apt_keyring_dir }}/pub_evolix.asc] http://pub.evolix.org/evolix {{ ansible_distribution_release }} main
+deb [signed-by={{ apt_keyring_dir }}/{{ apt_evolix_public_key }}] http://pub.evolix.org/evolix {{ ansible_distribution_release }} main
diff --git a/apt/templates/evolix_public.sources.j2 b/apt/templates/evolix_public.sources.j2
index defd1282..76bea737 100644
--- a/apt/templates/evolix_public.sources.j2
+++ b/apt/templates/evolix_public.sources.j2
@@ -1,6 +1,6 @@
# {{ ansible_managed }}
-Types:deb
+Types: deb
URIs: http://pub.evolix.org/evolix
Suites: {{ ansible_distribution_release }}
Components: main
diff --git a/apt/templates/jessie_basics.list.j2 b/apt/templates/jessie_basics.list.j2
index 467e7f30..7d72bfbd 100644
--- a/apt/templates/jessie_basics.list.j2
+++ b/apt/templates/jessie_basics.list.j2
@@ -1,4 +1,5 @@
# {{ ansible_managed }}
-deb http://mirror.evolix.org/debian/ jessie {{ apt_basics_components | mandatory }}
-deb http://security.debian.org/ jessie/updates {{ apt_basics_components | mandatory }}
+### Those repositories are unusable. Move to ELTS (manually).
+# deb http://archive.debian.org/debian jessie {{ apt_basics_components | mandatory }}
+# deb http://archive.debian.org/debian-security jessie/updates {{ apt_basics_components | mandatory }}
diff --git a/apt/templates/jessie_extended-lts.list.j2 b/apt/templates/jessie_extended-lts.list.j2
new file mode 100644
index 00000000..c20be4e7
--- /dev/null
+++ b/apt/templates/jessie_extended-lts.list.j2
@@ -0,0 +1,4 @@
+# {{ ansible_managed }}
+
+deb [signed-by="{{ apt_keyring_dir }}/freexian-archive-extended-lts.gpg"] http://elts.evolix.org/extended-lts jessie main
+deb [signed-by="{{ apt_keyring_dir }}/freexian-archive-extended-lts.gpg"] http://elts.evolix.org/extended-lts jessie-lts main
diff --git a/apt/templates/stretch_basics.list.j2 b/apt/templates/stretch_basics.list.j2
index 2f0bf99e..f679e354 100644
--- a/apt/templates/stretch_basics.list.j2
+++ b/apt/templates/stretch_basics.list.j2
@@ -1,5 +1,4 @@
# {{ ansible_managed }}
-deb http://mirror.evolix.org/debian stretch {{ apt_basics_components | mandatory }}
-deb http://mirror.evolix.org/debian/ stretch-updates {{ apt_basics_components | mandatory }}
-deb http://security.debian.org/debian-security stretch/updates {{ apt_basics_components | mandatory }}
+deb http://archive.debian.org/debian stretch {{ apt_basics_components | mandatory }}
+deb http://archive.debian.org/debian-security stretch/updates {{ apt_basics_components | mandatory }}
diff --git a/apt/templates/stretch_extended-lts.list.j2 b/apt/templates/stretch_extended-lts.list.j2
new file mode 100644
index 00000000..374e571e
--- /dev/null
+++ b/apt/templates/stretch_extended-lts.list.j2
@@ -0,0 +1,4 @@
+# {{ ansible_managed }}
+
+deb [signed-by="{{ apt_keyring_dir }}/freexian-archive-extended-lts.gpg"] http://elts.evolix.org/extended-lts stretch main
+deb [signed-by="{{ apt_keyring_dir }}/freexian-archive-extended-lts.gpg"] http://elts.evolix.org/extended-lts stretch-lts main
diff --git a/autosysadmin/defaults/main.yml b/autosysadmin/defaults/main.yml
new file mode 100644
index 00000000..56190633
--- /dev/null
+++ b/autosysadmin/defaults/main.yml
@@ -0,0 +1,22 @@
+---
+
+general_scripts_dir: "/usr/share/scripts"
+autosysadmin_dir: "{{ general_scripts_dir }}/autosysadmin"
+
+# Default values for enabled checks
+repair_amavis: 'on'
+repair_disk: 'on'
+repair_elasticsearch: 'on'
+repair_http: 'on'
+repair_mysql: 'on'
+repair_opendkim: 'off'
+repair_php_fpm56: 'off'
+repair_php_fpm70: 'off'
+repair_php_fpm73: 'off'
+repair_php_fpm74: 'off'
+repair_php_fpm80: 'off'
+repair_php_fpm81: 'off'
+repair_php_fpm82: 'off'
+repair_php_fpm83: 'off'
+repair_redis: 'off'
+repair_tomcat_instance: 'off'
diff --git a/autosysadmin/files/logrotate_autosysadmin.conf b/autosysadmin/files/logrotate_autosysadmin.conf
new file mode 100644
index 00000000..41606de5
--- /dev/null
+++ b/autosysadmin/files/logrotate_autosysadmin.conf
@@ -0,0 +1,13 @@
+/var/log/autosysadmin.log {
+ daily
+ missingok
+ rotate 365
+ compress
+ nodelaycompress
+ notifempty
+ dateext
+ dateformat .%Y-%m-%d
+ dateyesterday
+ copytruncate
+ create 0640 root adm
+}
diff --git a/autosysadmin/files/rsyslog_autosysadmin.conf b/autosysadmin/files/rsyslog_autosysadmin.conf
new file mode 100644
index 00000000..dd3c037f
--- /dev/null
+++ b/autosysadmin/files/rsyslog_autosysadmin.conf
@@ -0,0 +1,3 @@
+$template autosysadmin, "/var/log/autosysadmin.log"
+if $programname contains 'autosysadmin' then ?autosysadmin
+& stop
diff --git a/autosysadmin/files/scripts/functions.sh b/autosysadmin/files/scripts/functions.sh
new file mode 100644
index 00000000..95f1a901
--- /dev/null
+++ b/autosysadmin/files/scripts/functions.sh
@@ -0,0 +1,478 @@
+#!/bin/bash
+
+get_system() {
+ uname -s
+}
+
+get_fqdn() {
+ if [ "$(get_system)" = "Linux" ]; then
+ hostname --fqdn
+ elif [ "$(get_system)" = "OpenBSD" ]; then
+ hostname
+ else
+ log_error_exit "OS not detected!"
+ fi
+}
+
+get_complete_hostname() {
+ REAL_HOSTNAME="$(get_fqdn)"
+ if [ "${HOSTNAME}" = "${REAL_HOSTNAME}" ]; then
+ echo "${HOSTNAME}"
+ else
+ echo "${HOSTNAME} (${REAL_HOSTNAME})"
+ fi
+}
+
+get_evomaintenance_mail() {
+ email="$(grep "EVOMAINTMAIL=" /etc/evomaintenance.cf | cut -d '=' -f2)"
+
+ if [[ -z "$email" ]]; then
+ email='alert5@evolix.fr'
+ fi
+
+ echo "${email}"
+}
+
+arguments="${*}"
+
+get_argument() {
+ no_found=1
+ for argument in ${arguments} ; do
+ if [ "${argument}" = "${1}" ] ;
+ then
+ no_found=0
+ fi
+ done
+ return ${no_found}
+}
+
+internal_info() {
+ INTERNAL_INFO="$(printf '%b\n%s' "${INTERNAL_INFO}" "$*")"
+}
+
+log_action() {
+ log "Action : $*"
+ ACTIONS="$(printf '%s\n%s' "${ACTIONS}" "$*")"
+}
+
+log() {
+ INTERNAL_LOG="$(printf '%s\n%s %s %s %s' "${INTERNAL_LOG}" "$(date -Isec)" "$(hostname)" "$(basename "$0")" "$*")"
+ printf '%s %s %s %s\n' "$(date -Isec)" "$(hostname)" "$(basename "$0")" "$*" | tee -a "${LOG_DIR}/autosysadmin.log"
+ echo "$*" | /usr/bin/logger -p local0.notice -t autosysadmin."$0"
+}
+
+log_error_exit() {
+ log "ERROR : $*"
+ AUTOSYSADMIN=1 /usr/share/scripts/evomaintenance.sh -m "$0: $*" --no-commit --no-mail
+ exit 1
+}
+
+log_check_php_fpm() {
+
+ # Extraire seulement les chiffres du nom du script exécuté
+ # ./repair_php_fpm81.sh ==> 81
+ PHP_VERSION="${0//[^0-9]/}"
+
+ PHP_PATH_POOL=$(find /var/lib/lxc/php"${PHP_VERSION}"/ -type d -name "pool.d")
+ /usr/local/lib/nagios/plugins/check_phpfpm_multi "${PHP_PATH_POOL}" > "${LOG_DIR}/nrpe.txt"
+}
+
+log_system_status() {
+ DUMP_SERVER_STATE_BIN="$(command -v dump-server-state || command -v backup-server-state)"
+
+ if [ -z "${DUMP_SERVER_STATE_BIN}" ]; then
+ log "Warning: dump-server-state is not present. No server state recorded...."
+ fi
+
+ if [ -x "${DUMP_SERVER_STATE_BIN}" ]; then
+
+ # NOTE We don't want the logging to take too much time, so we kill it
+ # if it take more than 20 seconds.
+ timeout --signal 9 20 \
+ "${DUMP_SERVER_STATE_BIN}" \
+ --dump-dir="$LOG_DIR" \
+ --df \
+ --dmesg \
+ --iptables \
+ --lxc \
+ --netcfg \
+ --netstat \
+ --uname \
+ --processes \
+ --systemctl \
+ --uptime \
+ --virsh \
+ --disks \
+ --mysql-processes \
+ --no-apt-states \
+ --no-apt-config \
+ --no-dpkg-full \
+ --no-dpkg-status \
+ --no-mount \
+ --no-packages \
+ --no-sysctl \
+ --no-etc
+
+ log "System status logged in ${LOG_DIR}"
+ fi
+}
+
+read_log_system_status(){
+ files="df.txt dmesg.txt lxc-list.txt netstat-legacy.txt netstat-ss.txt pstree.txt ps.txt systemctl-failed-services.txt"
+ echo -e "\n\n#### Détails de dump-server-state"
+ for file in ${files} ; do
+ echo -e "\n### cat ${LOG_DIR}/${file} :"
+ tail -n 1000 "${LOG_DIR}"/"${file}"
+ done
+}
+
+ensure_no_active_users_or_exit() {
+ if is_debug; then return; fi
+
+ # Is there any active user ?
+ for user in $(LC_ALL=C who --users|awk '{print $1}'); do
+ idle_time="$(LC_ALL=C who --users | grep "${user}" | awk '{ print $6}')"
+ for sameusertime in $(LC_ALL=C who --users | grep "${user}" | awk '{ print $6}'); do
+ if is_active_user "$sameusertime"; then
+ hook_mail abort_active_users
+ log_error_exit 'At least one user was recently active. That requires human intervention. Nothing to do here!'
+ fi
+ done
+ done
+}
+
+is_active_user() {
+ # Check if a user was active in the last 30 minutes
+ idle_time="$1"
+
+ if [ "${idle_time}" = "old" ];
+ then
+ return 1
+ elif [ "${idle_time}" = "." ];
+ then
+ return 0
+ else
+ hh="$(echo "${idle_time}" | awk -F':' '{print $1}')"
+ mm="$(echo "${idle_time}" | awk -F':' '{print $2}')"
+ idle_minutes="$(( 60 * "${hh}" + "${mm}" ))"
+ if [ "${idle_minutes}" -ge 30 ];
+ then
+ return 1
+ else
+ return 0
+ fi
+ fi
+}
+
+is_debug() {
+ debug_file="/etc/evolinux/autosysadmin.debug"
+
+ if [ -e "${debug_file}" ]; then
+ last_change=$(stat -c %Z "${debug_file}")
+ limit_date=$(date --date "14400 seconds ago" +"%s")
+
+ if [ $(( last_change - limit_date )) -le "0" ]; then
+ rm "${debug_file}"
+ else
+ return 0
+ fi
+ fi
+
+ return 1
+}
+
+check_nrpe() {
+ check="$1"
+ list_command_nrpe=$( grep --exclude=*~ -E "\[${check}\]" -r /etc/nagios/ | grep -v '#command' )
+ command_nrpe_primary=$( echo "${list_command_nrpe}" | grep "/etc/nagios/nrpe.d/evolix.cfg" | cut -d'=' -f2- )
+ command_nrpe_secondary=$( echo "${list_command_nrpe}" | head -n1 | cut -d'=' -f2- )
+
+ if [ -z "${command_nrpe_primary}" ] && [ -z "${command_nrpe_secondary}" ]
+ then
+ return 1
+ else
+ if [ -n "${command_nrpe_primary}" ]
+ then
+ ${command_nrpe_primary}
+ else
+ ${command_nrpe_secondary}
+ fi
+ fi
+}
+
+acquire_lock_or_exit() {
+ lockfile="$1"
+ waittime="$2"
+
+ # si le temps d’attente n’est pas compréhensible par sleep(1), il vaut 0
+ if ! echo "${waittime}" | grep -Eq '^[0-9]+[smhd]?$'
+ then
+ waittime=0
+ fi
+
+ # si le temps d’attente est supérieur à 0 et si le lock existe, on attend
+ if test "${waittime}" -gt 0 && test -f "${lockfile}"
+ then
+ sleep "${waittime}"
+ fi
+
+ # si le lock existe, on s’arrête
+ if test -f "${lockfile}"
+ then
+ log_error_exit "lock file ${lockfile} exists"
+ fi
+ touch "${lockfile}"
+}
+
+is_too_soon() {
+ if is_debug; then return; fi
+
+ witness="/tmp/autosysadmin_witness_$(basename "$0")"
+ if test -f "${witness}"
+ then
+ compare="$(($(date +%s)-$(stat -c "%Y" "${witness}")))"
+ if [ "${compare}" -lt 1800 ];
+ then
+ log_error_exit 'already executed less than 30 minutes ago'
+ fi
+ rm "${witness}"
+ fi
+ touch "${witness}"
+}
+
+init_autosysadmin() {
+ PATH="${PATH}":/usr/sbin:/sbin↩
+ unset ACTIONS
+
+ SCRIPTNAME=$(basename "$0")
+ PROGNAME=${SCRIPTNAME%.sh}
+
+ RUN_ID="$(date +"%Y-%m-%d_%H-%M")_${SCRIPTNAME}_$(openssl rand -hex 6)"
+ LOG_DIR="/var/log/autosysadmin/${RUN_ID}"
+ mkdir -p "${LOG_DIR}"
+
+ log "Autosysadmin : Script ${SCRIPTNAME} triggered"
+
+ # Detect operating system name, version and release↩
+ detect_os
+}
+
+load_conf() {
+ # Load conf and enable script by default.
+ # To disable script locally, set "$PROGNAME"=off in /etc/evolinux/autosysadmin.
+ # To disable script globally, set "$PROGNAME"=off in the script, after load_conf() call.
+ declare -g "$PROGNAME"=on # dynamic variable assignment ($PROGNAME == repair_*)
+
+ # Source configuration file
+ # shellcheck source=../roles/deploy_autosysadmin/templates/autosysadmin.cfg.j2
+ test -f /etc/evolinux/autosysadmin && source /etc/evolinux/autosysadmin
+}
+
+detect_os() {
+ # OS detection
+ DEBIAN_RELEASE=""
+ LSB_RELEASE_BIN="$(command -v lsb_release)"
+
+ if [ -e /etc/debian_version ]; then
+ DEBIAN_VERSION="$(cut -d "." -f 1 < /etc/debian_version)"
+ if [ -x "${LSB_RELEASE_BIN}" ]; then
+ DEBIAN_RELEASE="$("${LSB_RELEASE_BIN}" --codename --short)"
+ else
+ case "${DEBIAN_VERSION}" in
+ 8) DEBIAN_RELEASE="jessie";;
+ 9) DEBIAN_RELEASE="stretch";;
+ 10) DEBIAN_RELEASE="buster";;
+ 11) DEBIAN_RELEASE="bullseye";;
+ esac
+ fi
+ fi
+}
+
+is_debian_jessie() {
+ test "${DEBIAN_RELEASE}" = "jessie"
+}
+is_debian_stretch() {
+ test "${DEBIAN_RELEASE}" = "stretch"
+}
+is_debian_buster() {
+ test "${DEBIAN_RELEASE}" = "buster"
+}
+is_debian_bullseye() {
+ test "${DEBIAN_RELEASE}" = "bullseye"
+}
+
+systemd_list_service_failed() {
+ systemctl list-units --failed --no-legend --full --type=service "$1" |
+ awk '{print $1}'
+}
+
+systemd_list_units_enabled() {
+ list_units_enabled=$(systemctl list-unit-files --state=enabled --no-legend | awk "/$1/{print \$1}")
+ if [ -z "${list_units_enabled}" ]
+ then
+ return 1
+ else
+ echo "${list_units_enabled}"
+ fi
+}
+
+format_mail_success() {
+ cat <
+Content-Type: text/plain; charset=UTF-8
+MIME-Version: 1.0
+Content-Transfer-Encoding: 8bit
+X-Script: $(basename "$0")
+X-RunId: ${RUN_ID}
+To: ${EMAIL_CLIENT:-alert5@evolix.fr}
+Cc: autosysadmin@evolix.fr
+Subject: [autosysadmin] Intervention sur ${HOSTNAME_TEXT}
+
+Bonjour,
+
+Une intervention automatique vient de se terminer.
+
+Nom du serveur : ${HOSTNAME_TEXT}
+Heure d'intervention : $(LC_ALL=fr_FR.utf8 date)
+
+### Renseignements sur l'intervention
+
+${ACTIONS}
+
+### Réagir à cette intervention
+
+Vous pouvez répondre à ce message (sur l'adresse mail equipe@evolix.net).
+En cas d'urgence, utilisez l'adresse maintenance@evolix.fr ou
+notre téléphone portable d'astreinte (04.26.99.99.26)
+
+--
+Votre AutoSysadmin
+EOTEMPLATE
+}
+
+format_mail_abort_active_users() {
+ cat <
+Content-Type: text/plain; charset=UTF-8
+MIME-Version: 1.0
+Content-Transfer-Encoding: 8bit
+X-Script: $(basename "$0")
+X-RunId: ${RUN_ID}
+To: ${EMAIL_CLIENT:-alert5@evolix.fr}
+Cc: autosysadmin@evolix.fr
+Subject: [autosysadmin] Intervention interrompue sur ${HOSTNAME_TEXT}
+
+Bonjour,
+
+Une intervention automatique a été interrompue en raison
+d'un utilisateur actuellement actif sur le serveur.
+
+Nom du serveur : ${HOSTNAME_TEXT}
+Heure d'intervention : $(LC_ALL=fr_FR.utf8 date)
+
+### Utilisateur(s) connecté(s)
+$(w)
+
+--
+Votre AutoSysadmin
+EOTEMPLATE
+}
+
+format_mail_internal_info() {
+ cat <
+Content-Type: text/plain; charset=UTF-8
+MIME-Version: 1.0
+Content-Transfer-Encoding: 8bit
+X-Script: $(basename "$0")
+X-RunId: ${RUN_ID}
+To: autosysadmin@evolix.fr
+Subject: [autosysadmin] Complements (interne) - Intervention sur ${HOSTNAME_TEXT}
+
+Bonjour,
+
+Une intervention automatique vient de se terminer.
+
+Nom du serveur : ${HOSTNAME_TEXT}
+Heure d'intervention : $(LC_ALL=fr_FR.utf8 date)
+Script déclenché : $(basename "$0")
+
+### Actions effectuées
+
+${ACTIONS}
+
+### Logs autosysadmin
+
+${INTERNAL_LOG}
+
+### Utilisateur(s) connecté(s)
+
+$(w)
+
+### Informations additionnelles données par le script $(basename "$0")
+
+${INTERNAL_INFO}
+
+--
+Votre AutoSysadmin
+EOTEMPLATE
+}
+
+hook_mail() {
+ if is_debug; then return; fi
+
+ HOSTNAME="${HOSTNAME:-"$(get_fqdn)"}"
+ HOSTNAME_TEXT="$(get_complete_hostname)"
+ EMAIL_CLIENT="$(get_evomaintenance_mail)"
+
+ MAIL_CONTENT="$(format_mail_"$1")"
+
+ SENDMAIL_BIN="$(command -v sendmail)"
+
+ if [ -z "${SENDMAIL_BIN}" ]; then
+ log "No \`sendmail' command has been found, can't send mail."
+ fi
+
+ if [ -x "${SENDMAIL_BIN}" ]; then
+ echo "${MAIL_CONTENT}" | "${SENDMAIL_BIN}" -oi -t -f "equipe@evolix.net"
+ fi
+}
+
+
+
+# We need stable output for gcal, so we force some language environment variables
+export TZ=Europe/Paris
+export LANGUAGE=fr_FR.UTF-8
+
+is_holiday() {
+ # gcal mark today as a holiday by surrounding with < and > the day
+ # of the month of that holiday line. For exemple if today is 2022-05-01 we'll
+ # get among other lines:
+ # Fête du Travail (FR) + Di, < 1>Mai 2022
+ # Jour de la Victoire (FR) + Di, : 8:Mai 2022 = +7 jours
+ gcal --cc-holidays=fr --holiday-list=short | grep -E '<[0-9 ]{2}>' --quiet
+}
+
+is_weekend() {
+ day_of_week=$(date +%u)
+ if [ "$day_of_week" != 6 ] && [ "$day_of_week" != 7 ]; then
+ return 1
+ fi
+}
+
+is_workday() {
+ if is_holiday || is_weekend; then
+ return 1
+ fi
+}
+
+is_worktime() {
+ if ! is_workday; then
+ return 1
+ fi
+
+ hour=$(date +%H)
+ if [ "${hour}" -lt 9 ] || { [ "${hour}" -ge 12 ] && [ "${hour}" -lt 14 ] ; } || [ "${hour}" -ge 18 ]; then
+ return 1
+ fi
+}
diff --git a/autosysadmin/files/scripts/repair_amavis.sh b/autosysadmin/files/scripts/repair_amavis.sh
new file mode 100644
index 00000000..5139b927
--- /dev/null
+++ b/autosysadmin/files/scripts/repair_amavis.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+# Source functions file
+# shellcheck source=./functions.sh
+source /usr/share/scripts/autosysadmin/functions.sh
+# shellcheck source=./restart_amavis.sh
+source /usr/share/scripts/autosysadmin/restart_amavis.sh
+
+init_autosysadmin
+load_conf
+
+test "${repair_amavis:=off}" = off && log_error_exit 'Script disabled, nothing to do here!'
+
+# Verify if check_nrpe are not OK
+check_nrpe "check_amavis" && log_error_exit 'check_amavis is OK, nothing to do here!'
+
+# Has it recently been run?
+get_argument "--no-delay" || is_too_soon
+
+lockfile="/run/lock/repair_amavis"
+cleanup() {
+ rm -f "${lockfile}"
+}
+trap 'cleanup' 0
+acquire_lock_or_exit "${lockfile}"
+
+ensure_no_active_users_or_exit
+
+# The actual work starts below !
+restart_amavis
+
+hook_mail success
+AUTOSYSADMIN=1 /usr/share/scripts/evomaintenance.sh -m "$0: done" --no-commit --no-mail
diff --git a/autosysadmin/files/scripts/repair_disk.sh b/autosysadmin/files/scripts/repair_disk.sh
new file mode 100644
index 00000000..fc35438c
--- /dev/null
+++ b/autosysadmin/files/scripts/repair_disk.sh
@@ -0,0 +1,173 @@
+#!/bin/bash
+
+# Source functions file
+# shellcheck source=./functions.sh
+source /usr/share/scripts/autosysadmin/functions.sh
+
+init_autosysadmin
+load_conf
+
+test "${repair_disk:=off}" = off && log_error_exit 'Script disabled, nothing to do here!'
+
+# Has it recently been run?
+is_too_soon
+
+lockfile="/run/lock/repair_disk"
+cleanup() {
+ rm -f "${lockfile}"
+}
+trap 'cleanup' 0
+acquire_lock_or_exit "${lockfile}"
+
+ensure_no_active_users_or_exit
+
+# The actual work starts below !
+
+get_mountpoints() {
+ # the $(...) get the check_disk1 command
+ # the cut command selects the critical part of the check_disk1 output
+ # the grep command extracts the mountpoints and available disk space
+ # the last cut command selects the mountpoints
+ $(grep check_disk1 /etc/nagios/nrpe.d/evolix.cfg | cut -d'=' -f2-) -e | cut -d'|' -f1 | grep -Eo '/[[:graph:]]* [0-9]+ [A-Z][A-Z]' | cut -f1 -d' '
+}
+
+is_reserved-blocks() {
+ fs_type="$(findmnt -n --output=fstype "$1")"
+ if [ "${fs_type}" = "ext4" ];
+ then
+ device="$(findmnt -n --output=source "$1")"
+ reserved_block_count="$(tune2fs -l "${device}" | grep 'Reserved block count' | awk -F':' '{ gsub (" ", "", $0); print $2}')"
+ block_count="$(tune2fs -l "${device}" | grep 'Block count' | awk -F':' '{ gsub (" ", "", $0); print $2}')"
+ percentage=$(awk "BEGIN { pc=100*${reserved_block_count}/${block_count}; i=int(pc); print (pc-i<0.5)?i:i+1 }")
+
+ log "Reserved blocks for $1 is curently at $percentage%"
+ if [ "${percentage}" -gt "1" ]
+ then
+ log "Allowing tune2fs action to reduce the number of reserved blocks"
+ return 0
+ else
+ log "Reserved blocks already at or bellow 1%, no automatic action possible"
+ return 1
+ fi
+ else
+ log "Filesystem for $1 partition is not ext4"
+
+ return 1
+ fi
+}
+
+change_reserved-blocks() {
+ # We alwasy keep some reserved blocks to avoid missing some logs
+ # https://gitea.evolix.org/evolix/autosysadmin/issues/22
+ tune2fs -m 1 "$(findmnt -n --output=source "$1")"
+ log_action "Reserved blocks for $1 changed to 1 percent"
+}
+
+is_tmp_to_delete() {
+ size="$(find /var/log/ -type f -ctime +1 -exec du {} \+ | awk '{s+=$1}END{print s / 1024}')"
+ if [ -n "${size}" ]
+ then
+ return 0
+ else
+ return 1
+ fi
+}
+
+is_log_to_delete() {
+ size="$(find /var/log/ -type f -mtime +365 -exec du {} \+ | awk '{s+=$1}END{print s / 1024}')"
+ if [ -n "${size}" ]
+ then
+ return 0
+ else
+ return 1
+ fi
+}
+
+clean_apt_cache() {
+ for lxc in $(du -ax /var | sort -nr | head -n10 | grep -E '/var/lib/lxc/php[0-9]+/rootfs/var/cache$' | grep -Eo 'php[0-9]+')
+ do
+ lxc-attach --name "${lxc}" -- apt-get clean
+ log_action '[lxc/'"${lxc}"'] Clean apt cache'
+ done
+ case "$(du -sx /var/* | sort -rn | sed 's/^[0-9]\+[[:space:]]\+//;q')" in
+ '/var/cache')
+ apt-get clean
+ log_action 'Clean apt cache'
+ ;;
+ esac
+}
+
+clean_amavis_virusmails() {
+ if du --inodes /var/lib/* | sort -n | tail -n3 | grep -q 'virusmails$'
+ then
+ find /var/lib/amavis/virusmails/ -type f -atime +30 -delete
+ log_action 'Clean /var/lib/amavis/virusmails'
+ fi
+}
+
+for mountpoint in $(get_mountpoints)
+do
+ case "${mountpoint}" in
+ /var)
+ #if is_log_to_delete
+ #then
+ # find /var/log/ -type f -mtime +365 -delete
+ # log_action "$size Mo of disk space freed in /var"
+ #fi
+ if is_reserved-blocks /var
+ then
+ change_reserved-blocks /var
+ clean_apt_cache
+ clean_amavis_virusmails
+ hook_mail success
+ fi
+ ;;
+ /tmp)
+ #if is_tmp_to_delete
+ #then
+ # find /tmp/ -type f -ctime +1 -delete
+ # log_action "$size Mo of disk space freed in /tmp"
+ #fi
+ if is_reserved-blocks /tmp
+ then
+ change_reserved-blocks /tmp
+ hook_mail success
+ fi
+ ;;
+ /home)
+ if is_reserved-blocks /home
+ then
+ change_reserved-blocks /home
+ hook_mail success
+ fi
+ ;;
+ /srv)
+ if is_reserved-blocks /srv
+ then
+ change_reserved-blocks /srv
+ hook_mail success
+ fi
+ ;;
+ /filer)
+ if is_reserved-blocks /filer
+ then
+ change_reserved-blocks /filer
+ hook_mail success
+ fi
+ ;;
+ /)
+ if is_reserved-blocks /
+ then
+ change_reserved-blocks /
+ hook_mail success
+ # Suggest remove old kernel ?
+ fi
+ ;;
+ *)
+ # unknown
+ log 'Unknown partition (or weird case) or nothing to do'
+ ;;
+ esac
+done
+
+AUTOSYSADMIN=1 /usr/share/scripts/evomaintenance.sh -m "$0: done" --no-commit --no-mail
diff --git a/autosysadmin/files/scripts/repair_elasticsearch.sh b/autosysadmin/files/scripts/repair_elasticsearch.sh
new file mode 100644
index 00000000..3b45c6e0
--- /dev/null
+++ b/autosysadmin/files/scripts/repair_elasticsearch.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+
+# Source functions file
+# shellcheck source=./functions.sh
+source /usr/share/scripts/autosysadmin/functions.sh
+
+init_autosysadmin
+load_conf
+
+test "${repair_elasticsearch:=off}" = off && log_error_exit 'Script disabled, nothing to do here!'
+
+# Has it recently been run?
+is_too_soon
+
+lockfile="/run/lock/repair_elasticsearch"
+cleanup() {
+ rm -f "${lockfile}"
+}
+trap 'cleanup' 0
+acquire_lock_or_exit "${lockfile}"
+
+ensure_no_active_users_or_exit
+
+# The actual work starts below !
+
+elasticsearch_is_enabled() {
+ systemd_list_units_enabled "elasticsearch.service"
+
+}
+
+elasticsearch_restart() {
+ if ! timeout 60 systemctl restart elasticsearch.service > /dev/null
+ then
+ log_error_exit 'failed to restart elasticsearch'
+ fi
+}
+
+# Test functions
+test_elasticsearch_process_present() {
+ pgrep -u elasticsearch > /dev/null
+}
+
+if elasticsearch_is_enabled
+then
+ if ! test_elasticsearch_process_present
+ then
+ log_action "Redémarrage de elasticsearch"
+ elasticsearch_restart
+ hook_mail success
+ else
+ log_error_exit "Elasticsearch process alive. Aborting"
+ fi
+else
+ log_error_exit "Elasticsearch is not enabled. Aborting"
+fi
+
+AUTOSYSADMIN=1 /usr/share/scripts/evomaintenance.sh -m "$0: done" --no-commit --no-mail
diff --git a/autosysadmin/files/scripts/repair_http.sh b/autosysadmin/files/scripts/repair_http.sh
new file mode 100644
index 00000000..b1642858
--- /dev/null
+++ b/autosysadmin/files/scripts/repair_http.sh
@@ -0,0 +1,141 @@
+#!/bin/bash
+
+# Source functions file
+# shellcheck source=./functions.sh
+source /usr/share/scripts/autosysadmin/functions.sh
+
+init_autosysadmin
+load_conf
+
+test "${repair_http:=off}" = off && log_error_exit 'Script disabled, nothing to do here!'
+
+# Has it recently been run?
+is_too_soon
+
+lockfile="/run/lock/repair_http"
+cleanup() {
+ rm -f "${lockfile}"
+}
+trap 'cleanup' 0
+acquire_lock_or_exit "${lockfile}"
+
+ensure_no_active_users_or_exit
+
+# The actual work starts below !
+
+log_system_status
+
+http_detect_service() {
+ # check whether nginx, apache or both are supposed to be running
+ if is_debian_jessie; then
+ find /etc/rc2.d/
+ else
+ systemctl list-unit-files --state=enabled
+ fi | awk '/nginx/ { nginx = 1 } /apache2/ { apache2 = 1 } END { if (nginx && apache2) { print "both" } else if (nginx) { print "nginx" } else if (apache2) { print "apache2" } }'
+ # The previous awk command looks for two patterns: "nginx"
+ # and "apache2". If a line matches the patterns, a variable
+ # "nginx" or "apache2" is set to 1 (true). The "END" checks
+ # if one or both patterns has been found.
+}
+
+http_handle_apache() {
+ # check syntax
+ if ! apache2ctl -t > /dev/null 2> /dev/null
+ then
+ log_error_exit 'apache2 configuration syntax is not valid'
+ fi
+
+ # try restart
+ if ! timeout 20 systemctl restart apache2.service > /dev/null 2> /dev/null
+ then
+ log_error_exit 'failed to restart apache2'
+ fi
+
+ log_action "Redémarrage de Apache"
+
+ internal_info "#### grep $(LANG=en_US.UTF-8 date '+%b %d') /home/*/log/error.log /var/log/apache2/*error.log (avec filtrage)"
+ ERROR_LOG=$(grep "$(LANG=en_US.UTF-8 date '+%b %d')" /home/*/log/error.log /var/log/apache2/*error.log | grep -v -e "Got error 'PHP message:" -e "No matching DirectoryIndex" -e "client denied by server configuration" -e "server certificate does NOT include an ID which matches the server name" )
+ internal_info "$ERROR_LOG"
+
+}
+
+http_handle_nginx() {
+ # check syntax
+ if ! nginx -t > /dev/null 2> /dev/null
+ then
+ log_error_exit 'nginx configuration syntax is not valid'
+ fi
+
+ # try restart
+ if ! timeout 20 systemctl restart nginx.service > /dev/null 2> /dev/null
+ then
+ log_error_exit 'failed to restart nginx'
+ fi
+
+ log_action "Redémarrage de Nginx"
+}
+
+http_handle_lxc_php() {
+ # check whether containers are used for PHP and reboot them if so
+ if systemd_list_units_enabled 'lxc'
+ then
+ for php in $(lxc-ls | grep 'php'); do
+ lxc-stop -n "$php"
+ lxc-start --daemon -n "$php"
+ log_action "lxc-fpm - Redémarrage container ${php}"
+ done
+
+ fi
+}
+
+http_handle_fpm_php() {
+ # check whether php-fpm is installed and restart it if so
+ if enabled_units="$(systemd_list_units_enabled "php.*-fpm")"
+ then
+ systemctl restart "${enabled_units}"
+ log_action 'php-fpm - Redémarrage de php-fpm'
+ fi
+}
+
+case "$(http_detect_service)" in
+nginx)
+
+ http_handle_nginx
+
+ http_handle_lxc_php
+ http_handle_fpm_php
+
+ hook_mail success
+ hook_mail internal_info
+ ;;
+
+apache2)
+
+ http_handle_apache
+
+ http_handle_lxc_php
+ http_handle_fpm_php
+
+ hook_mail success
+ hook_mail internal_info
+ ;;
+
+both)
+
+ http_handle_nginx
+ http_handle_apache
+
+ http_handle_lxc_php
+ http_handle_fpm_php
+
+ hook_mail success
+ hook_mail internal_info
+ ;;
+
+*)
+ # unknown
+ log 'nothing to do'
+ ;;
+esac
+
+AUTOSYSADMIN=1 /usr/share/scripts/evomaintenance.sh -m "$0: done" --no-commit --no-mail
diff --git a/autosysadmin/files/scripts/repair_mysql.sh b/autosysadmin/files/scripts/repair_mysql.sh
new file mode 100644
index 00000000..f80d5af7
--- /dev/null
+++ b/autosysadmin/files/scripts/repair_mysql.sh
@@ -0,0 +1,71 @@
+#!/bin/bash
+
+# Source functions file
+# shellcheck source=./functions.sh
+source /usr/share/scripts/autosysadmin/functions.sh
+
+init_autosysadmin
+load_conf
+
+test "${repair_mysql:=off}" = off && log_error_exit 'Script disabled, nothing to do here!'
+
+# Has it recently been run?
+is_too_soon
+
+lockfile="/run/lock/repair_mysql"
+cleanup() {
+ rm -f "${lockfile}"
+}
+trap 'cleanup' 0
+acquire_lock_or_exit "${lockfile}"
+
+ensure_no_active_users_or_exit
+
+# The actual work starts below !
+
+log_system_status
+
+mysql_is_enabled() {
+ if is_debian_jessie
+ then
+ find /etc/rc2.d/ -name '*mysql*' > /dev/null
+ else
+ systemd_list_units_enabled "mysql.service"
+ fi
+}
+
+mysql_restart() {
+ if is_debian_jessie
+ then
+ if ! timeout 60 /etc/init.d/mysql restart > /dev/null
+ then
+ log_error_exit 'failed to restart mysql'
+ fi
+ else
+ if ! timeout 60 systemctl restart mysql.service > /dev/null
+ then
+ log_error_exit 'failed to restart mysql'
+ fi
+ fi
+}
+
+# Test functions
+test_mysql_process_present() {
+ pgrep -u mysql mysqld > /dev/null
+}
+
+if mysql_is_enabled
+then
+ if ! test_mysql_process_present
+ then
+ log_action "Redémarrage de MySQL"
+ mysql_restart
+ hook_mail success
+ else
+ log_error_exit "mysqld process alive. Aborting"
+ fi
+else
+ log_error_exit "MySQL/MariaDB not enabled. Aborting"
+fi
+
+AUTOSYSADMIN=1 /usr/share/scripts/evomaintenance.sh -m "$0: done" --no-commit --no-mail
diff --git a/autosysadmin/files/scripts/repair_opendkim.sh b/autosysadmin/files/scripts/repair_opendkim.sh
new file mode 100644
index 00000000..f7735028
--- /dev/null
+++ b/autosysadmin/files/scripts/repair_opendkim.sh
@@ -0,0 +1,61 @@
+#!/bin/bash
+
+# Source functions file
+# shellcheck source=./functions.sh
+source /usr/share/scripts/autosysadmin/functions.sh
+
+init_autosysadmin
+load_conf
+
+test "${repair_opendkim:=off}" = off && log_error_exit 'Script disabled, nothing to do here!'
+
+# Has it recently been run?
+is_too_soon
+
+lockfile="/run/lock/repair_opendkim"
+cleanup() {
+ rm -f "${lockfile}"
+}
+trap 'cleanup' 0
+acquire_lock_or_exit "${lockfile}"
+
+ensure_no_active_users_or_exit
+
+log_system_status
+
+# Functions dedicated to this repair script
+
+opendkim_is_enabled() {
+ systemd_list_units_enabled "opendkim.service"
+
+}
+
+opendkim_restart() {
+ if ! timeout 60 systemctl restart opendkim.service > /dev/null
+ then
+ log_error_exit 'failed to restart opendkim'
+ fi
+}
+
+opendkim_test_process_present() {
+ pgrep -u opendkim > /dev/null
+}
+
+
+# Main logic
+
+if opendkim_is_enabled
+then
+ if ! opendkim_test_process_present
+ then
+ log_action "Redémarrage de opendkim"
+ opendkim_restart
+ hook_mail success
+ else
+ log_error_exit "opendkim process alive. Aborting"
+ fi
+else
+ log_error_exit "opendkim is not enabled. Aborting"
+fi
+
+AUTOSYSADMIN=1 /usr/share/scripts/evomaintenance.sh -m "$0: done" --no-commit --no-mail
diff --git a/autosysadmin/files/scripts/repair_php_fpm56.sh b/autosysadmin/files/scripts/repair_php_fpm56.sh
new file mode 100644
index 00000000..6c67e0b6
--- /dev/null
+++ b/autosysadmin/files/scripts/repair_php_fpm56.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+
+# Source functions file
+# shellcheck source=./functions.sh
+source /usr/share/scripts/autosysadmin/functions.sh
+
+init_autosysadmin
+load_conf
+
+test "${repair_php_fpm56:=off}" = off && log_error_exit 'Script disabled, nothing to do here!'
+
+# Has it recently been run?
+is_too_soon
+
+lockfile="/run/lock/repair_http"
+cleanup() {
+ rm -f "${lockfile}"
+}
+trap 'cleanup' 0
+acquire_lock_or_exit "${lockfile}" 15s
+
+ensure_no_active_users_or_exit
+
+# The actual work starts below !
+
+log_system_status
+log_check_php_fpm
+
+if systemd_list_units_enabled 'lxc'
+then
+
+ if lxc-ls | grep -q php56
+ then
+ lxc-stop -n php56
+ lxc-start --daemon -n php56
+ log_action "lxc-fpm - Redémarrage container php56"
+
+ internal_info "#### tail /var/lib/lxc/php56/rootfs/var/log/php5-fpm.log"
+ FPM_LOG=$(tail /var/lib/lxc/php56/rootfs/var/log/php5-fpm.log)
+ internal_info "$FPM_LOG" "$(read_log_system_status)"
+
+ hook_mail success
+ hook_mail internal_info
+
+ else
+ log 'Not possible :v'
+ fi
+
+else
+ log 'Error, not a multi-php install'
+fi
+
+AUTOSYSADMIN=1 /usr/share/scripts/evomaintenance.sh -m "$0: done" --no-commit --no-mail
diff --git a/autosysadmin/files/scripts/repair_php_fpm70.sh b/autosysadmin/files/scripts/repair_php_fpm70.sh
new file mode 100644
index 00000000..5bf8cab2
--- /dev/null
+++ b/autosysadmin/files/scripts/repair_php_fpm70.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+
+# Source functions file
+# shellcheck source=./functions.sh
+source /usr/share/scripts/autosysadmin/functions.sh
+
+init_autosysadmin
+load_conf
+
+test "${repair_php_fpm70:=off}" = off && log_error_exit 'Script disabled, nothing to do here!'
+
+# Has it recently been run?
+is_too_soon
+
+lockfile="/run/lock/repair_http"
+cleanup() {
+ rm -f "${lockfile}"
+}
+trap 'cleanup' 0
+acquire_lock_or_exit "${lockfile}" 15s
+
+ensure_no_active_users_or_exit
+
+# The actual work starts below !
+
+log_system_status
+log_check_php_fpm
+
+if systemd_list_units_enabled 'lxc'
+then
+
+ if lxc-ls | grep -q php70
+ then
+ lxc-stop -n php70
+ lxc-start --daemon -n php70
+ log_action "lxc-fpm - Redémarrage container php70"
+
+ internal_info "#### tail /var/lib/lxc/php70/rootfs/var/log/php7.0-fpm.log"
+ FPM_LOG=$(tail /var/lib/lxc/php70/rootfs/var/log/php7.0-fpm.log)
+ internal_info "$FPM_LOG" "$(read_log_system_status)"
+
+ hook_mail success
+ hook_mail internal_info
+
+ else
+ log 'Not possible :v'
+ fi
+
+else
+ log 'Error, not a multi-php install'
+fi
+
+AUTOSYSADMIN=1 /usr/share/scripts/evomaintenance.sh -m "$0: done" --no-commit --no-mail
diff --git a/autosysadmin/files/scripts/repair_php_fpm73.sh b/autosysadmin/files/scripts/repair_php_fpm73.sh
new file mode 100644
index 00000000..6b2094fd
--- /dev/null
+++ b/autosysadmin/files/scripts/repair_php_fpm73.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+
+# Source functions file
+# shellcheck source=./functions.sh
+source /usr/share/scripts/autosysadmin/functions.sh
+
+init_autosysadmin
+load_conf
+
+test "${repair_php_fpm73:=off}" = off && log_error_exit 'Script disabled, nothing to do here!'
+
+# Has it recently been run?
+is_too_soon
+
+lockfile="/run/lock/repair_http"
+cleanup() {
+ rm -f "${lockfile}"
+}
+trap 'cleanup' 0
+acquire_lock_or_exit "${lockfile}" 15s
+
+ensure_no_active_users_or_exit
+
+# The actual work starts below !
+
+log_system_status
+log_check_php_fpm
+
+if systemd_list_units_enabled 'lxc'
+then
+
+ if lxc-ls | grep -q php73
+ then
+ lxc-stop -n php73
+ lxc-start --daemon -n php73
+ log_action "lxc-fpm - Redémarrage container php73"
+
+ internal_info "#### tail /var/lib/lxc/php73/rootfs/var/log/php7.3-fpm.log"
+ FPM_LOG=$(tail /var/lib/lxc/php73/rootfs/var/log/php7.3-fpm.log)
+ internal_info "$FPM_LOG" "$(read_log_system_status)"
+
+ hook_mail success
+ hook_mail internal_info
+
+ else
+ log 'Not possible :v'
+ fi
+
+else
+ log 'Error, not a multi-php install'
+fi
+
+AUTOSYSADMIN=1 /usr/share/scripts/evomaintenance.sh -m "$0: done" --no-commit --no-mail
diff --git a/autosysadmin/files/scripts/repair_php_fpm74.sh b/autosysadmin/files/scripts/repair_php_fpm74.sh
new file mode 100644
index 00000000..dab16a8a
--- /dev/null
+++ b/autosysadmin/files/scripts/repair_php_fpm74.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+
+# Source functions file
+# shellcheck source=./functions.sh
+source /usr/share/scripts/autosysadmin/functions.sh
+
+init_autosysadmin
+load_conf
+
+test "${repair_php_fpm74:=off}" = off && log_error_exit 'Script disabled, nothing to do here!'
+
+# Has it recently been run?
+is_too_soon
+
+lockfile="/run/lock/repair_http"
+cleanup() {
+ rm -f "${lockfile}"
+}
+trap 'cleanup' 0
+acquire_lock_or_exit "${lockfile}" 15s
+
+ensure_no_active_users_or_exit
+
+# The actual work starts below !
+
+log_system_status
+log_check_php_fpm
+
+if systemd_list_units_enabled 'lxc'
+then
+
+ if lxc-ls | grep -q php74
+ then
+ lxc-stop -n php74
+ lxc-start --daemon -n php74
+ log_action "lxc-fpm - Redémarrage container php74"
+
+ internal_info "#### tail /var/lib/lxc/php74/rootfs/var/log/php7.4-fpm.log"
+ FPM_LOG=$(tail /var/lib/lxc/php74/rootfs/var/log/php7.4-fpm.log)
+ internal_info "$FPM_LOG" "$(read_log_system_status)"
+
+ hook_mail success
+ hook_mail internal_info
+
+ else
+ log 'Not possible :v'
+ fi
+
+else
+ log 'Error, not a multi-php install'
+fi
+
+AUTOSYSADMIN=1 /usr/share/scripts/evomaintenance.sh -m "$0: done" --no-commit --no-mail
diff --git a/autosysadmin/files/scripts/repair_php_fpm80.sh b/autosysadmin/files/scripts/repair_php_fpm80.sh
new file mode 100644
index 00000000..35b9e36c
--- /dev/null
+++ b/autosysadmin/files/scripts/repair_php_fpm80.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+
+# Source functions file
+# shellcheck source=./functions.sh
+source /usr/share/scripts/autosysadmin/functions.sh
+
+init_autosysadmin
+load_conf
+
+test "${repair_php_fpm80:=off}" = off && log_error_exit 'Script disabled, nothing to do here!'
+
+# Has it recently been run?
+is_too_soon
+
+lockfile="/run/lock/repair_http"
+cleanup() {
+ rm -f "${lockfile}"
+}
+trap 'cleanup' 0
+acquire_lock_or_exit "${lockfile}" 15s
+
+ensure_no_active_users_or_exit
+
+# The actual work starts below !
+
+log_system_status
+log_check_php_fpm
+
+if systemd_list_units_enabled 'lxc'
+then
+
+ if lxc-ls | grep -q php80
+ then
+ lxc-stop -n php80
+ lxc-start --daemon -n php80
+ log_action "lxc-fpm - Redémarrage container php80"
+
+ internal_info "#### tail /var/lib/lxc/php80/rootfs/var/log/php8.0-fpm.log"
+ FPM_LOG=$(tail /var/lib/lxc/php80/rootfs/var/log/php8.0-fpm.log)
+ internal_info "$FPM_LOG" "$(read_log_system_status)"
+
+ hook_mail success
+ hook_mail internal_info
+
+ else
+ log 'Not possible :v'
+ fi
+
+else
+ log 'Error, not a multi-php install'
+fi
+
+AUTOSYSADMIN=1 /usr/share/scripts/evomaintenance.sh -m "$0: done" --no-commit --no-mail
diff --git a/autosysadmin/files/scripts/repair_php_fpm81.sh b/autosysadmin/files/scripts/repair_php_fpm81.sh
new file mode 100644
index 00000000..e567f6aa
--- /dev/null
+++ b/autosysadmin/files/scripts/repair_php_fpm81.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+
+# Source functions file
+# shellcheck source=./functions.sh
+source /usr/share/scripts/autosysadmin/functions.sh
+
+init_autosysadmin
+load_conf
+
+test "${repair_php_fpm81:=off}" = off && log_error_exit 'Script disabled, nothing to do here!'
+
+# Has it recently been run?
+is_too_soon
+
+lockfile="/run/lock/repair_http"
+cleanup() {
+ rm -f "${lockfile}"
+}
+trap 'cleanup' 0
+acquire_lock_or_exit "${lockfile}" 15s
+
+ensure_no_active_users_or_exit
+
+# The actual work starts below !
+
+log_system_status
+log_check_php_fpm
+
+if systemd_list_units_enabled 'lxc'
+then
+
+ if lxc-ls | grep -q php81
+ then
+ lxc-stop -n php81
+ lxc-start --daemon -n php81
+ log_action "lxc-fpm - Redémarrage container php81"
+
+ internal_info "#### tail /var/lib/lxc/php81/rootfs/var/log/php8.1-fpm.log"
+ FPM_LOG=$(tail /var/lib/lxc/php81/rootfs/var/log/php8.1-fpm.log)
+ internal_info "$FPM_LOG" "$(read_log_system_status)"
+
+ hook_mail success
+ hook_mail internal_info
+
+ else
+ log 'Not possible :v'
+ fi
+
+else
+ log 'Error, not a multi-php install'
+fi
+
+AUTOSYSADMIN=1 /usr/share/scripts/evomaintenance.sh -m "$0: done" --no-commit --no-mail
diff --git a/autosysadmin/files/scripts/repair_php_fpm82.sh b/autosysadmin/files/scripts/repair_php_fpm82.sh
new file mode 100644
index 00000000..295abbcd
--- /dev/null
+++ b/autosysadmin/files/scripts/repair_php_fpm82.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+
+# Source functions file
+# shellcheck source=./functions.sh
+source /usr/share/scripts/autosysadmin/functions.sh
+
+init_autosysadmin
+load_conf
+
+test "${repair_php_fpm82:=off}" = off && log_error_exit 'Script disabled, nothing to do here!'
+
+# Has it recently been run?
+is_too_soon
+
+lockfile="/run/lock/repair_http"
+cleanup() {
+ rm -f "${lockfile}"
+}
+trap 'cleanup' 0
+acquire_lock_or_exit "${lockfile}" 15s
+
+ensure_no_active_users_or_exit
+
+# The actual work starts below !
+
+log_system_status
+log_check_php_fpm
+
+if systemd_list_units_enabled 'lxc'
+then
+
+ if lxc-ls | grep -q php82
+ then
+ lxc-stop -n php82
+ lxc-start --daemon -n php82
+ log_action "lxc-fpm - Redémarrage container php82"
+
+ internal_info "#### tail /var/lib/lxc/php82/rootfs/var/log/php8.2-fpm.log"
+ FPM_LOG=$(tail /var/lib/lxc/php82/rootfs/var/log/php8.2-fpm.log)
+ internal_info "$FPM_LOG" "$(read_log_system_status)"
+
+ hook_mail success
+ hook_mail internal_info
+
+ else
+ log 'Not possible :v'
+ fi
+
+else
+ log 'Error, not a multi-php install'
+fi
+
+AUTOSYSADMIN=1 /usr/share/scripts/evomaintenance.sh -m "$0: done" --no-commit --no-mail
diff --git a/autosysadmin/files/scripts/repair_php_fpm83.sh b/autosysadmin/files/scripts/repair_php_fpm83.sh
new file mode 100644
index 00000000..5344c2e4
--- /dev/null
+++ b/autosysadmin/files/scripts/repair_php_fpm83.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+
+# Source functions file
+# shellcheck source=./functions.sh
+source /usr/share/scripts/autosysadmin/functions.sh
+
+init_autosysadmin
+load_conf
+
+test "${repair_php_fpm83:=off}" = off && log_error_exit 'Script disabled, nothing to do here!'
+
+# Has it recently been run?
+is_too_soon
+
+lockfile="/run/lock/repair_http"
+cleanup() {
+ rm -f "${lockfile}"
+}
+trap 'cleanup' 0
+acquire_lock_or_exit "${lockfile}" 15s
+
+ensure_no_active_users_or_exit
+
+# The actual work starts below !
+
+log_system_status
+log_check_php_fpm
+
+if systemd_list_units_enabled 'lxc'
+then
+
+ if lxc-ls | grep -q php83
+ then
+ lxc-stop -n php83
+ lxc-start --daemon -n php83
+ log_action "lxc-fpm - Redémarrage container php83"
+
+ internal_info "#### tail /var/lib/lxc/php83/rootfs/var/log/php8.3-fpm.log"
+ FPM_LOG=$(tail /var/lib/lxc/php83/rootfs/var/log/php8.3-fpm.log)
+ internal_info "$FPM_LOG" "$(read_log_system_status)"
+
+ hook_mail success
+ hook_mail internal_info
+
+ else
+ log 'Not possible :v'
+ fi
+
+else
+ log 'Error, not a multi-php install'
+fi
+
+AUTOSYSADMIN=1 /usr/share/scripts/evomaintenance.sh -m "$0: done" --no-commit --no-mail
diff --git a/autosysadmin/files/scripts/repair_redis.sh b/autosysadmin/files/scripts/repair_redis.sh
new file mode 100644
index 00000000..be5cfd77
--- /dev/null
+++ b/autosysadmin/files/scripts/repair_redis.sh
@@ -0,0 +1,58 @@
+#!/bin/bash
+
+# Source functions file
+# shellcheck source=./functions.sh
+source /usr/share/scripts/autosysadmin/functions.sh
+
+init_autosysadmin
+load_conf
+
+test "${repair_redis:=off}" = off && log_error_exit 'Script disabled, nothing to do here!'
+
+# Has it recently been run?
+is_too_soon
+
+lockfile="/run/lock/repair_redis"
+cleanup() {
+ rm -f "${lockfile}"
+}
+trap 'cleanup' 0
+acquire_lock_or_exit "${lockfile}"
+
+ensure_no_active_users_or_exit
+
+# The actual work starts below !
+
+handle_redis() {
+ for service in $(systemd_list_service_failed redis*)
+ do
+ # ne rien faire si le service est désactivé
+ if ! systemctl is-enabled --quiet "${service}"
+ then
+ continue
+ fi
+
+ # ne rien faire si le service est actif
+ if systemctl is-active --quiet "${service}"
+ then
+ continue
+ fi
+
+ if ! timeout 20 systemctl restart redis.service > /dev/null 2> /dev/null
+ then
+ log_error_exit "failed to restart redis ${service}"
+ fi
+
+ log_action "Redémarrer service ${service}"
+ done
+}
+
+if ( systemd_list_units_enabled 'redis.*\.service$' ) > /dev/null
+then
+ handle_redis
+ hook_mail success
+else
+ log 'Error: redis service is not enabled'
+fi
+
+AUTOSYSADMIN=1 /usr/share/scripts/evomaintenance.sh -m "$0: done" --no-commit --no-mail
diff --git a/autosysadmin/files/scripts/repair_template.sh b/autosysadmin/files/scripts/repair_template.sh
new file mode 100644
index 00000000..33db0aac
--- /dev/null
+++ b/autosysadmin/files/scripts/repair_template.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+
+# Source functions file
+# shellcheck source=./functions.sh
+source /usr/share/scripts/autosysadmin/functions.sh
+
+init_autosysadmin
+load_conf
+
+# Comment this line to enable
+repair_template=off
+test "${repair_template:=off}" = off && log_error_exit 'Script disabled, nothing to do here!'
+
+# Has it recently been run?
+is_too_soon
+
+lockfile="/run/lock/repair_template"
+cleanup() {
+ rm -f "${lockfile}"
+}
+trap 'cleanup' 0
+acquire_lock_or_exit "${lockfile}"
+
+ensure_no_active_users_or_exit
+
+log_system_status
+
+# Functions dedicated to this repair script
+
+template_is_enabled() {
+ systemd_list_units_enabled "template.service"
+
+}
+
+template_restart() {
+ if ! timeout 60 systemctl restart template.service > /dev/null
+ then
+ log_error_exit 'failed to restart template'
+ fi
+}
+
+template_test_process_present() {
+ pgrep -u template > /dev/null
+}
+
+
+# Main logic
+
+if template_is_enabled
+then
+ if ! template_test_process_present
+ then
+ log_action "Redémarrage de template"
+ template_restart
+ hook_mail success
+ else
+ log_error_exit "template process alive. Aborting"
+ fi
+else
+ log_error_exit "template is not enabled. Aborting"
+fi
+
+AUTOSYSADMIN=1 /usr/share/scripts/evomaintenance.sh -m "$0: done" --no-commit --no-mail
diff --git a/autosysadmin/files/scripts/repair_tomcat_instance.sh b/autosysadmin/files/scripts/repair_tomcat_instance.sh
new file mode 100644
index 00000000..9bf9949c
--- /dev/null
+++ b/autosysadmin/files/scripts/repair_tomcat_instance.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+
+# Source functions file
+# shellcheck source=./functions.sh
+source /usr/share/scripts/autosysadmin/functions.sh
+
+init_autosysadmin
+load_conf
+
+test "${repair_tomcat_instance:=off}" = off && log_error_exit 'Script disabled, nothing to do here!'
+
+# Has it recently been run?
+is_too_soon
+
+lockfile="/run/lock/repair_tomcat_instance"
+cleanup() {
+ rm -f "${lockfile}"
+}
+trap 'cleanup' 0
+acquire_lock_or_exit "${lockfile}"
+
+ensure_no_active_users_or_exit
+
+# The actual work starts below !
+
+log_system_status
+
+repair_tomcat_instance_handle_tomcat() {
+
+ if /bin/su - "${1}" -c "/bin/systemctl --quiet --user is-active tomcat.service" ; then
+ if ! /bin/su - "${1}" -c "/usr/bin/timeout 20 /bin/systemctl --quiet --user restart tomcat.service"
+ then
+ log_error_exit "Echec de redémarrage instance tomcat utilisateur ${1}"
+ else
+ log_action "Redémarrage instance tomcat utilisateur ${1}"
+ fi
+ elif /bin/systemctl --quiet is-active "${1}".service ; then
+ if ! /usr/bin/timeout 20 systemctl --quiet restart "${1}".service
+ then
+ log_error_exit "Echec de redémarrage instance tomcat ${1}"
+ else
+ log_action "Redémarrage instance tomcat ${1}"
+ fi
+ fi
+
+}
+
+for instance in $( /usr/local/lib/nagios/plugins/check_tomcat_instance.sh |grep CRITICAL |awk '{print $3}' |sed '1d') ;
+do
+ repair_tomcat_instance_handle_tomcat "${instance}"
+done
+
+AUTOSYSADMIN=1 /usr/share/scripts/evomaintenance.sh -m "$0: done" --no-commit --no-mail
diff --git a/autosysadmin/files/scripts/restart_amavis.sh b/autosysadmin/files/scripts/restart_amavis.sh
new file mode 100644
index 00000000..ef8c255d
--- /dev/null
+++ b/autosysadmin/files/scripts/restart_amavis.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+
+restart_amavis() {
+ /etc/init.d/amavis stop 2>/dev/null
+ /etc/init.d/clamav-freshclam stop 2>/dev/null
+ /etc/init.d/clamav-daemon stop 2>/dev/null
+
+ if systemctl is-enabled --quiet 'clamav-freshclam.service'
+ then
+ freshclam
+ log_action "Mise à jour des définitions antivirus"
+ fi
+
+ if systemctl is-enabled --quiet 'clamav-daemon.service'
+ then
+ /etc/init.d/clamav-daemon start
+ log_action "Redémarrage de clamav-daemon"
+ else
+ log 'Error, clamav not installed'
+ fi
+
+ if systemctl is-enabled --quiet 'clamav-freshclam.service'
+ then
+ /etc/init.d/clamav-freshclam start
+ log_action "Redémarrage de clamav-freshclam"
+ fi
+
+ if systemctl is-enabled --quiet 'amavis.service'
+ then
+ /etc/init.d/amavis start
+ log_action "Redémarrage de amavis"
+ else
+ log 'Error, amavis not installed'
+ fi
+}
diff --git a/autosysadmin/handlers/main.yml b/autosysadmin/handlers/main.yml
new file mode 100644
index 00000000..2c0b1a7f
--- /dev/null
+++ b/autosysadmin/handlers/main.yml
@@ -0,0 +1,16 @@
+---
+
+- name: Restart nagios-nrpe-server
+ ansible.builtin.service:
+ name: nagios-nrpe-server
+ state: restarted
+
+- name: Restart nrpe
+ ansible.builtin.service:
+ name: nrpe
+ state: restarted
+
+- name: Restart rsyslog
+ ansible.builtin.service:
+ name: rsyslog
+ state: restarted
diff --git a/autosysadmin/tasks/autosysadmin_scripts.yml b/autosysadmin/tasks/autosysadmin_scripts.yml
new file mode 100644
index 00000000..4ff1c5be
--- /dev/null
+++ b/autosysadmin/tasks/autosysadmin_scripts.yml
@@ -0,0 +1,61 @@
+---
+- name: "Remount /usr if needed"
+ ansible.builtin.import_role:
+ name: remount-usr
+
+- name: Create autosysadmin directory
+ ansible.builtin.file:
+ path: "{{ autosysadmin_dir }}"
+ state: directory
+ owner: "root"
+ group: "root"
+ mode: "0750"
+ tags:
+ - autosysadmin
+
+- name: Copy scripts
+ ansible.builtin.copy:
+ src: "files/scripts/{{ item }}"
+ dest: "{{ autosysadmin_dir }}/{{ item }}"
+ owner: root
+ group: root
+ mode: "0750"
+ loop:
+ - "functions.sh"
+ - "restart_amavis.sh"
+ - "repair_amavis.sh"
+ - "repair_disk.sh"
+ - "repair_elasticsearch.sh"
+ - "repair_http.sh"
+ - "repair_mysql.sh"
+ - "repair_php_fpm56.sh"
+ - "repair_php_fpm70.sh"
+ - "repair_php_fpm73.sh"
+ - "repair_php_fpm74.sh"
+ - "repair_php_fpm80.sh"
+ - "repair_php_fpm81.sh"
+ - "repair_php_fpm82.sh"
+ - "repair_php_fpm83.sh"
+ - "repair_tomcat_instance.sh"
+ tags:
+ - autosysadmin
+
+- name: Ensure /etc/evolinux folder exists
+ ansible.builtin.file:
+ path: "/etc/evolinux"
+ state: directory
+ owner: "root"
+ group: "root"
+ mode: "0700"
+ tags:
+ - autosysadmin
+
+- name: Copy the configuration file
+ ansible.builtin.template:
+ src: "autosysadmin.cf.j2"
+ dest: "/etc/evolinux/autosysadmin"
+ owner: root
+ group: root
+ mode: "0640"
+ tags:
+ - autosysadmin
diff --git a/autosysadmin/tasks/dependencies.yml b/autosysadmin/tasks/dependencies.yml
new file mode 100644
index 00000000..4f120944
--- /dev/null
+++ b/autosysadmin/tasks/dependencies.yml
@@ -0,0 +1,4 @@
+---
+- name: Install gcal
+ ansible.builtin.apt:
+ name: gcal
diff --git a/autosysadmin/tasks/logrotate.yml b/autosysadmin/tasks/logrotate.yml
new file mode 100644
index 00000000..d4fe7a5c
--- /dev/null
+++ b/autosysadmin/tasks/logrotate.yml
@@ -0,0 +1,10 @@
+---
+- name: Copy logrotate configuration for autosysadmin
+ ansible.builtin.copy:
+ src: "files/logrotate_autosysadmin.conf"
+ dest: "/etc/logrotate.d/autosysadmin"
+ owner: root
+ group: root
+ mode: "0644"
+ tags:
+ - autosysadmin
diff --git a/autosysadmin/tasks/main.yml b/autosysadmin/tasks/main.yml
new file mode 100644
index 00000000..60204162
--- /dev/null
+++ b/autosysadmin/tasks/main.yml
@@ -0,0 +1,37 @@
+---
+- name: Install dependencies
+ ansible.builtin.import_tasks: dependencies.yml
+ tags:
+ - autosysadmin
+
+- name: Install autosysadmin scripts
+ ansible.builtin.import_tasks: autosysadmin_scripts.yml
+ tags:
+ - autosysadmin
+
+- name: Amend NRPE configuration
+ ansible.builtin.import_tasks: nrpe.yml
+ tags:
+ - autosysadmin
+
+- name: Amend sudo configuration
+ ansible.builtin.import_tasks: sudo.yml
+ tags:
+ - autosysadmin
+
+- name: Amend rsyslog configuration
+ ansible.builtin.import_tasks: rsyslog.yml
+ tags:
+ - autosysadmin
+
+- name: Amend logrotate configuration
+ ansible.builtin.import_tasks: logrotate.yml
+ tags:
+ - autosysadmin
+
+- name: Install last version of dump-server-state
+ ansible.builtin.import_role:
+ name: evolinux-base
+ tasks_from: dump-server-state.yml
+ tags:
+ - autosysadmin
diff --git a/autosysadmin/tasks/nrpe.yml b/autosysadmin/tasks/nrpe.yml
new file mode 100644
index 00000000..f6f5c78b
--- /dev/null
+++ b/autosysadmin/tasks/nrpe.yml
@@ -0,0 +1,11 @@
+---
+- name: Custom configuration is present
+ ansible.builtin.template:
+ src: autosysadmin.cfg.j2
+ dest: /etc/nagios/nrpe.d/autosysadmin.cfg
+ group: nagios
+ mode: "0640"
+ force: true
+ notify: Restart nagios-nrpe-server
+ tags:
+ - autosysadmin
diff --git a/autosysadmin/tasks/rsyslog.yml b/autosysadmin/tasks/rsyslog.yml
new file mode 100644
index 00000000..6f0702c5
--- /dev/null
+++ b/autosysadmin/tasks/rsyslog.yml
@@ -0,0 +1,11 @@
+---
+- name: Copy rsyslog configuration for autosysadmin
+ ansible.builtin.copy:
+ src: "files/rsyslog_autosysadmin.conf"
+ dest: "/etc/rsyslog.d/autosysadmin.conf"
+ owner: root
+ group: root
+ mode: "0644"
+ notify: Restart rsyslog
+ tags:
+ - autosysadmin
diff --git a/autosysadmin/tasks/sudo.yml b/autosysadmin/tasks/sudo.yml
new file mode 100644
index 00000000..24249ab7
--- /dev/null
+++ b/autosysadmin/tasks/sudo.yml
@@ -0,0 +1,9 @@
+---
+- name: Add autosysadmin sudoers file
+ ansible.builtin.template:
+ src: sudoers.j2
+ dest: /etc/sudoers.d/autosysadmin
+ mode: "0600"
+ validate: "visudo -cf %s"
+ tags:
+ - autosysadmin
diff --git a/autosysadmin/templates/autosysadmin.cf.j2 b/autosysadmin/templates/autosysadmin.cf.j2
new file mode 100644
index 00000000..0be506c2
--- /dev/null
+++ b/autosysadmin/templates/autosysadmin.cf.j2
@@ -0,0 +1,74 @@
+#
+# Ansible managed - DO NOT MODIFY, your changes will be **overwritten** !
+#
+# Update the hosts_vars/group_vars on the autosysadmin project
+# https://gitea.evolix.org/evolix/autosysadmin/src/branch/master
+#
+
+# Configuration for autosysadmin
+# Use this file to change configuration values defined in repair scripts
+# Ex : repair_http=off
+
+{% if repair_amavis == "off" %}
+repair_amavis=off
+{% endif %}
+
+{% if repair_disk == "off" %}
+repair_disk=off
+{% endif %}
+
+{% if repair_elasticsearch == "off" %}
+repair_elasticsearch=off
+{% endif %}
+
+{% if repair_http == "off" %}
+repair_http=off
+{% endif %}
+
+{% if repair_mysql == "off" %}
+repair_mysql=off
+{% endif %}
+
+{% if repair_opendkim == "off" %}
+repair_opendkim=off
+{% endif %}
+
+{% if repair_php_fpm56 == "off" %}
+repair_php_fpm56=off
+{% endif %}
+
+{% if repair_php_fpm70 == "off" %}
+repair_php_fpm70=off
+{% endif %}
+
+{% if repair_php_fpm73 == "off" %}
+repair_php_fpm73=off
+{% endif %}
+
+{% if repair_php_fpm74 == "off" %}
+repair_php_fpm74=off
+{% endif %}
+
+{% if repair_php_fpm80 == "off" %}
+repair_php_fpm80=off
+{% endif %}
+
+{% if repair_php_fpm81 == "off" %}
+repair_php_fpm81=off
+{% endif %}
+
+{% if repair_php_fpm82 == "off" %}
+repair_php_fpm82=off
+{% endif %}
+
+{% if repair_php_fpm83 == "off" %}
+repair_php_fpm83=off
+{% endif %}
+
+{% if repair_redis == "off" %}
+repair_redis=off
+{% endif %}
+
+{% if repair_tomcat_instance == "off" %}
+repair_tomcat_instance=off
+{% endif %}
diff --git a/autosysadmin/templates/autosysadmin.cfg.j2 b/autosysadmin/templates/autosysadmin.cfg.j2
new file mode 100644
index 00000000..fa6fcfd2
--- /dev/null
+++ b/autosysadmin/templates/autosysadmin.cfg.j2
@@ -0,0 +1,22 @@
+#
+# Ansible managed - DO NOT MODIFY, your changes will be overwritten !
+#
+
+# Autosysadmin repair commands
+command[repair_amavis]=sudo {{ autosysadmin_dir }}/repair_amavis.sh
+command[repair_disk]=sudo {{ autosysadmin_dir }}/repair_disk.sh
+command[repair_elasticsearch]=sudo {{ autosysadmin_dir }}/repair_elasticsearch.sh
+command[repair_http]=sudo {{ autosysadmin_dir }}/repair_http.sh
+command[repair_mysql]=sudo {{ autosysadmin_dir }}/repair_mysql.sh
+command[repair_opendkim]=sudo {{ autosysadmin_dir }}/repair_opendkim.sh
+command[repair_php_fpm56]=sudo {{ autosysadmin_dir }}/repair_php_fpm56.sh
+command[repair_php_fpm70]=sudo {{ autosysadmin_dir }}/repair_php_fpm70.sh
+command[repair_php_fpm73]=sudo {{ autosysadmin_dir }}/repair_php_fpm73.sh
+command[repair_php_fpm74]=sudo {{ autosysadmin_dir }}/repair_php_fpm74.sh
+command[repair_php_fpm80]=sudo {{ autosysadmin_dir }}/repair_php_fpm80.sh
+command[repair_php_fpm81]=sudo {{ autosysadmin_dir }}/repair_php_fpm81.sh
+command[repair_php_fpm82]=sudo {{ autosysadmin_dir }}/repair_php_fpm82.sh
+command[repair_php_fpm83]=sudo {{ autosysadmin_dir }}/repair_php_fpm83.sh
+command[repair_redis]=sudo {{ autosysadmin_dir }}/repair_redis.sh
+command[repair_tomcat_instance]=sudo {{ autosysadmin_dir }}/repair_tomcat_instance.sh
+
diff --git a/autosysadmin/templates/sudoers.j2 b/autosysadmin/templates/sudoers.j2
new file mode 100644
index 00000000..0a458292
--- /dev/null
+++ b/autosysadmin/templates/sudoers.j2
@@ -0,0 +1,21 @@
+#
+# Ansible managed - DO NOT MODIFY, your changes will be overwritten !
+#
+
+nagios ALL = NOPASSWD: {{ autosysadmin_dir }}/repair_amavis.sh
+nagios ALL = NOPASSWD: {{ autosysadmin_dir }}/repair_disk.sh
+nagios ALL = NOPASSWD: {{ autosysadmin_dir }}/repair_elasticsearch.sh
+nagios ALL = NOPASSWD: {{ autosysadmin_dir }}/repair_http.sh
+nagios ALL = NOPASSWD: {{ autosysadmin_dir }}/repair_mysql.sh
+nagios ALL = NOPASSWD: {{ autosysadmin_dir }}/repair_opendkim.sh
+nagios ALL = NOPASSWD: {{ autosysadmin_dir }}/repair_php_fpm56.sh
+nagios ALL = NOPASSWD: {{ autosysadmin_dir }}/repair_php_fpm70.sh
+nagios ALL = NOPASSWD: {{ autosysadmin_dir }}/repair_php_fpm73.sh
+nagios ALL = NOPASSWD: {{ autosysadmin_dir }}/repair_php_fpm74.sh
+nagios ALL = NOPASSWD: {{ autosysadmin_dir }}/repair_php_fpm80.sh
+nagios ALL = NOPASSWD: {{ autosysadmin_dir }}/repair_php_fpm81.sh
+nagios ALL = NOPASSWD: {{ autosysadmin_dir }}/repair_php_fpm82.sh
+nagios ALL = NOPASSWD: {{ autosysadmin_dir }}/repair_php_fpm83.sh
+nagios ALL = NOPASSWD: {{ autosysadmin_dir }}/repair_redis.sh
+nagios ALL = NOPASSWD: {{ autosysadmin_dir }}/repair_tomcat_instance.sh
+
diff --git a/bind/README.md b/bind/README.md
index 53f693a8..8d75b1e6 100644
--- a/bind/README.md
+++ b/bind/README.md
@@ -10,4 +10,4 @@ Minimal configuration is in `tasks/main.yml`
The full list of variables (with default values) can be found in `defaults/main.yml`.
-waening : sync chroot-bind.sh
+warning : sync chroot-bind.sh
diff --git a/bind/files/apparmor.usr.sbin.named b/bind/files/apparmor.usr.sbin.named
new file mode 100644
index 00000000..3ee197b0
--- /dev/null
+++ b/bind/files/apparmor.usr.sbin.named
@@ -0,0 +1,5 @@
+/var/chroot-bind/etc/bind/** r,
+/var/chroot-bind/var/** rw,
+/var/chroot-bind/dev/** rw,
+/var/chroot-bind/run/** rw,
+/var/chroot-bind/usr/** r,
diff --git a/bind/files/bind-reload-zone.sh b/bind/files/bind-reload-zone.sh
new file mode 100755
index 00000000..550e5b64
--- /dev/null
+++ b/bind/files/bind-reload-zone.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+#
+# Script utilitaire pour tester et recharger facilement une zone dans Bind
+#
+
+usage() {
+ echo "Usage: bind-reload-zone "
+ echo " bind-reload-zone -h|--help"
+}
+
+if [ $# -ne 1 ] ; then
+ usage
+ exit 1
+fi
+
+while :; do
+ case $1 in
+ -h|--help)
+ usage
+ exit 0
+ ;;
+ *)
+ zone=$1
+ break
+ ;;
+ esac
+ shift
+done
+
+if ! [ -f "/etc/bind/db.${zone}" ]; then
+ >&2 echo "Error: zone for ${zone} not found."
+ usage
+ exit 1
+fi
+
+named-checkzone "${zone}" /etc/bind/db."${zone}" && rndc reload "${zone}"
+
diff --git a/bind/files/bind-reload-zone_completion.sh b/bind/files/bind-reload-zone_completion.sh
new file mode 100644
index 00000000..2e87b12c
--- /dev/null
+++ b/bind/files/bind-reload-zone_completion.sh
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+
+_bind_reload_zone_dynamic_completion() {
+ local cur;
+ cur=${COMP_WORDS[COMP_CWORD]};
+ COMPREPLY=();
+ COMPREPLY=( $( compgen -W '$(grep -v -h '"'"'//'"'"' /etc/bind/named.conf* | grep -B1 "type master" | grep zone | grep -v arpa | awk '"'"'{gsub(/"/, "", $2); print $2}'"'"' | sort | uniq)' -- $cur ) );
+
+ # reverse ipv4 :
+ #grep -v -h '//' /etc/bind/named.conf* | grep -B1 "type master" | grep zone | grep arpa | grep -v ip6 | awk '{gsub(/"/, "", $2); gsub(/.in-addr.arpa/, "", $2); print $2}' | sort | uniq | awk -F'.' '{ for (i=NF; i>1; i--) printf("%s.",$i); print $1 }'
+
+ # reveres ipv6 : je bloque sur l'inversion 4 par 4
+ #grep -v -h '//' /etc/bind/named.conf* | grep -B1 "type master" | grep zone | grep arpa | grep ip6 | awk '{gsub(/"/, "", $2); gsub(/.ip6.arpa/, "", $2); print $2}' | sort | uniq | awk -F'.' '{ for (i=NF; i>1; i--) { if ($i % 4 == 0) printf("%s.",$i); else printf("%s",$i); } print $1 }'
+
+}
+
+complete -F _bind_reload_zone_dynamic_completion bind-reload-zone
+
diff --git a/bind/files/chroot-bind.sh b/bind/files/chroot-bind.sh
index 08c665e8..95852e61 100644
--- a/bind/files/chroot-bind.sh
+++ b/bind/files/chroot-bind.sh
@@ -3,12 +3,17 @@
# Gregory Colpart
# chroot (or re-chroot) script for bind9
-# tested on Debian Wheezy/Jessie/Stretch
+# tested on Debian Wheezy/Jessie/Stretch/Buster/Bullseye/Bookworm
# Exec this script after `(apt-get|aptitude|apt) install bind9`
# and after *each* bind9 upgrade
# When the script is finished, ensure you have
-# 'OPTIONS="-u bind -t /var/chroot-bind"' in /etc/default/bind9
+# 'OPTIONS="-u bind -t /var/chroot-bind"' in /etc/default/named
+# (since Bullseye) or, until Buster, in /etc/default/bind9
+#
+# Since Bookmworm, one also needs to handle bind mount points
+# https://wiki.evolix.org/HowtoBind#bind-mount-%C3%A0-partir-de-bookworm-debian-12
+#
# and /etc/init.d/bind9 (re)start
#
# for Jessie/systemd only:
@@ -22,8 +27,10 @@ mkdir -p /var/chroot-bind
mkdir -p /var/chroot-bind/bin /var/chroot-bind/dev /var/chroot-bind/etc \
/var/chroot-bind/lib /var/chroot-bind/usr/lib \
/var/chroot-bind/usr/sbin /var/chroot-bind/var/cache/bind \
- /var/chroot-bind/var/log /var/chroot-bind/var/run/named/ \
- /var/chroot-bind/run/named/
+ /var/chroot-bind/var/log /var/chroot-bind/var/run/named \
+ /var/chroot-bind/run/named /var/chroot-bind/usr/share/dns
+
+chmod 750 /var/chroot-bind
# for conf
if [ ! -h "/etc/bind" ]; then
@@ -31,6 +38,11 @@ if [ ! -h "/etc/bind" ]; then
ln -s /var/chroot-bind/etc/bind/ /etc/bind
fi
+# for dns
+if [ -d "/usr/share/dns" ]; then
+ cp -a /usr/share/dns/* /var/chroot-bind/usr/share/dns/
+fi
+
# for logs
touch /var/chroot-bind/var/log/bind.log
if [ ! -h "/var/log/bind.log" ]; then
@@ -58,11 +70,16 @@ fi
#chmod 666 /var/chroot-bind/dev/{null,random}
# essential libs
-for i in `ldd $(which named) | grep -v linux-vdso.so.1 | cut -d">" -f2 | cut -d"(" -f1` \
- /usr/lib/x86_64-linux-gnu/openssl-1.0.*/engines/libgost.so ; do
- install -D $i /var/chroot-bind/${i##/}
+for i in `ldd $(which named) | grep -v linux-vdso.so.1 | cut -d">" -f2 | cut -d"(" -f1`
+ do install -D $i /var/chroot-bind/${i##/}
done
+if [ ls /usr/lib/x86_64-linux-gnu/openssl-1.0.*/engines/libgost.so 1>/dev/null 2>&1 ]; then
+ for i in /usr/lib/x86_64-linux-gnu/openssl-1.0.*/engines/libgost.so
+ do install -D $i /var/chroot-bind/${i##/}
+ done
+fi
+
# essential (hum, bash is required ??)
#cp /bin/bash /var/chroot-bind/bin/
cp /usr/sbin/named /var/chroot-bind/usr/sbin/
diff --git a/bind/files/reload-zone b/bind/files/reload-zone
deleted file mode 100755
index b9acc449..00000000
--- a/bind/files/reload-zone
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/bash
-#
-# Script utilitaire pour tester et recharger facilement un domaine dans Bind
-# Usage : reload-zone
-#
-# TODO:
-# - renommer le script (par ex bind-safe-reload)
-# - vérifier le serial
-# - ajouter un -h --help
-# - prendre en charge plusieurs zones (ou aucune)
-# - ajouter le script dans le role bind
-
-named-checkzone "$1" /etc/bind/db."$1" && rndc reload "$1"
-
diff --git a/bind/handlers/main.yml b/bind/handlers/main.yml
index 5461579d..85eaa680 100644
--- a/bind/handlers/main.yml
+++ b/bind/handlers/main.yml
@@ -3,7 +3,6 @@
ansible.builtin.systemd:
daemon-reload: yes
-
- name: restart apparmor
ansible.builtin.systemd:
name: apparmor
diff --git a/bind/meta/main.yml b/bind/meta/main.yml
index 6cf180b1..533f4335 100644
--- a/bind/meta/main.yml
+++ b/bind/meta/main.yml
@@ -14,6 +14,8 @@ galaxy_info:
- jessie
- stretch
- buster
+ - bullseye
+ - bookworm
galaxy_tags: []
# Be sure to remove the '[]' above if you add dependencies
diff --git a/bind/tasks/main.yml b/bind/tasks/main.yml
index 1e20eee2..ea5b87c7 100644
--- a/bind/tasks/main.yml
+++ b/bind/tasks/main.yml
@@ -17,13 +17,13 @@
register: check_apparmor
- name: configure apparmor
- ansible.builtin.template:
- src: apparmor.usr.sbin.named.j2
- dest: /etc/apparmor.d/usr.sbin.named
- owner: root
- group: root
+ ansible.builtin.copy:
+ src: apparmor.usr.sbin.named
+ dest: /etc/apparmor.d/local/usr.sbin.named
mode: "0644"
+ owner: root
force: true
+ backup: yes
notify: restart apparmor
when: check_apparmor.rc == 0
@@ -94,13 +94,67 @@
- bind_chroot_set | bool
- chrootbind_run.stdout | length > 0
-- name: Modify OPTIONS in /etc/default/bind9 for chroot
+- name: Modify OPTIONS in /etc/default/bind9 for chroot (until Buster)
ansible.builtin.replace:
dest: /etc/default/bind9
regexp: '^OPTIONS=.*'
replace: 'OPTIONS="-u bind -t {{ bind_chroot_path }}"'
notify: restart bind
- when: bind_chroot_set | bool
+ when:
+ - bind_chroot_set | bool
+ - ansible_distribution_major_version is version('11', '<')
+
+- name: Modify OPTIONS in /etc/default/named for chroot (since Bullseye)
+ ansible.builtin.replace:
+ dest: /etc/default/named
+ regexp: '^OPTIONS=.*'
+ replace: 'OPTIONS="-u bind -t {{ bind_chroot_path }}"'
+ notify: restart bind
+ when:
+ - bind_chroot_set | bool
+ - ansible_distribution_major_version is version('11', '>=')
+
+- name: Create mount target directory for chroot (since Bookworm)
+ ansible.builtin.file:
+ path: /var/chroot-bind/run/systemd/journal
+ state: directory
+ owner: bind
+ group: bind
+ notify: restart bind
+ when:
+ - bind_chroot_set | bool
+ - ansible_distribution_major_version is version('12', '>=')
+
+- name: Create mount targets for chroot (since Bookworm)
+ ansible.builtin.file:
+ path: '{{ item }}'
+ state: touch
+ owner: bind
+ group: bind
+ loop:
+ - /var/chroot-bind/run/systemd/journal/socket
+ - /var/chroot-bind/run/systemd/journal/stdout
+ - /var/chroot-bind/run/systemd/notify
+ notify: restart bind
+ when:
+ - bind_chroot_set | bool
+ - ansible_distribution_major_version is version('12', '>=')
+
+- name: Set up bind mount for chroot (since Bookworm)
+ ansible.posix.mount:
+ src: "{{ item }}"
+ path: "/var/chroot-bind{{ item }}"
+ opts: bind
+ state: mounted
+ fstype: none
+ loop:
+ - /run/systemd/journal/socket
+ - /run/systemd/journal/stdout
+ - /run/systemd/notify
+ notify: restart bind
+ when:
+ - bind_chroot_set | bool
+ - ansible_distribution_major_version is version('12', '>=')
- name: logrotate for bind
ansible.builtin.template:
diff --git a/bind/templates/apparmor.usr.sbin.named.j2 b/bind/templates/apparmor.usr.sbin.named.j2
deleted file mode 100644
index d9f0be04..00000000
--- a/bind/templates/apparmor.usr.sbin.named.j2
+++ /dev/null
@@ -1,97 +0,0 @@
-# vim:syntax=apparmor
-# Last Modified: Tue Mar 9 14:17:50 EST 2021
-#include
-
-/usr/sbin/named flags=(attach_disconnected) {
- #include
- #include
-
- capability net_bind_service,
- capability setgid,
- capability setuid,
- capability sys_chroot,
- capability sys_resource,
-
- # /etc/bind should be read-only for bind
- # /var/lib/bind is for dynamically updated zone (and journal) files.
- # /var/cache/bind is for slave/stub data, since we're not the origin of it.
- # See /usr/share/doc/bind9/README.Debian.gz
- /etc/bind/** r,
- /var/lib/bind/** rw,
- /var/lib/bind/ rw,
- /var/cache/bind/** lrw,
- /var/cache/bind/ rw,
-
- # Database file used by allow-new-zones
- /var/cache/bind/_default.nzd-lock rwk,
-
- # gssapi
- /etc/krb5.keytab kr,
- /etc/bind/krb5.keytab kr,
-
- # ssl
- /etc/ssl/openssl.cnf r,
-
- # root hints from dns-data-root
- /usr/share/dns/root.* r,
-
- # GeoIP data files for GeoIP ACLs
- /usr/share/GeoIP/** r,
-
- # dnscvsutil package
- /var/lib/dnscvsutil/compiled/** rw,
-
- # Allow changing worker thread names
- owner @{PROC}/@{pid}/task/@{tid}/comm rw,
-
- @{PROC}/net/if_inet6 r,
- @{PROC}/*/net/if_inet6 r,
- @{PROC}/sys/net/ipv4/ip_local_port_range r,
- /usr/sbin/named mr,
- /{,var/}run/named/named.pid w,
- /{,var/}run/named/session.key w,
- # support for resolvconf
- /{,var/}run/named/named.options r,
-
- # some people like to put logs in /var/log/named/ instead of having
- # syslog do the heavy lifting.
- {{ bind_log_file }} rw,
-{% if bind_query_file_enabled | bool %}
- {{ bind_query_file }} rw,
-{% endif %}
-
- # gssapi
- /var/lib/sss/pubconf/krb5.include.d/** r,
- /var/lib/sss/pubconf/krb5.include.d/ r,
- /var/lib/sss/mc/initgroups r,
- /etc/gss/mech.d/ r,
-
- # ldap
- /etc/ldap/ldap.conf r,
- /{,var/}run/slapd-*.socket rw,
-
- # dynamic updates
- /var/tmp/DNS_* rw,
-
- # dyndb backends
- /usr/lib/bind/*.so rm,
-
- # Samba DLZ
- /{usr/,}lib/@{multiarch}/samba/bind9/*.so rm,
- /{usr/,}lib/@{multiarch}/samba/gensec/*.so rm,
- /{usr/,}lib/@{multiarch}/samba/ldb/*.so rm,
- /{usr/,}lib/@{multiarch}/ldb/modules/ldb/*.so rm,
- /var/lib/samba/bind-dns/dns.keytab rk,
- /var/lib/samba/bind-dns/named.conf r,
- /var/lib/samba/bind-dns/dns/** rwk,
- /var/lib/samba/private/dns.keytab rk,
- /var/lib/samba/private/named.conf r,
- /var/lib/samba/private/dns/** rwk,
- /etc/samba/smb.conf r,
- /dev/urandom rwmk,
- owner /var/tmp/krb5_* rwk,
-
- # Site-specific additions and overrides. See local/README for details.
- #include
-}
-
diff --git a/certbot/files/hooks/deploy/dovecot.sh b/certbot/files/hooks/deploy/dovecot.sh
index 56e5b5ae..1ed4ab5d 100644
--- a/certbot/files/hooks/deploy/dovecot.sh
+++ b/certbot/files/hooks/deploy/dovecot.sh
@@ -16,7 +16,7 @@ config_check() {
${doveconf_bin} > /dev/null 2>&1
}
letsencrypt_used() {
- ${doveconf_bin} | grep -E "^ssl_cert[^_]" | grep -q "letsencrypt"
+ ${doveconf_bin} | grep -E "^[[:blank:]]*ssl_cert[^_]" | grep -q "letsencrypt"
}
main() {
if daemon_found_and_running; then
diff --git a/certbot/tasks/main.yml b/certbot/tasks/main.yml
index 3dcb1334..a32aa630 100644
--- a/certbot/tasks/main.yml
+++ b/certbot/tasks/main.yml
@@ -21,6 +21,8 @@
- ansible.builtin.include: acme-challenge.yml
+# This is always going to mark a "change".
+# Couldn't figure out why !
- name: Deploy hooks are present
ansible.builtin.copy:
src: hooks/deploy/
diff --git a/check_free_space/defaults/main.yml b/check_free_space/defaults/main.yml
new file mode 100644
index 00000000..c699ad91
--- /dev/null
+++ b/check_free_space/defaults/main.yml
@@ -0,0 +1,6 @@
+---
+check_free_space_partitions:
+ - "/home"
+ - "/srv"
+check_free_space_max_percent: 70
+check_free_space_mailto: Null
diff --git a/check_free_space/files/check_free_space.sh b/check_free_space/files/check_free_space.sh
new file mode 100755
index 00000000..f1b89d8c
--- /dev/null
+++ b/check_free_space/files/check_free_space.sh
@@ -0,0 +1,166 @@
+#!/bin/sh
+
+# This script verifies if the specified partitions on a machine are filled
+# at more than x%.
+#
+# If so, it sends a mail to the admin of that machine, warning him/her
+# that mesures should be taken.
+#
+# Two outputs are provided to the recipient of the mail:
+# * some general infos with `df`
+# * a more indepth inspection with `duc`
+#
+# This script takes 3 (mandatory) arguments:
+# * a list of the partitions to check (space separated)
+# * the maximum allowed percentage
+# * the email template to use
+#
+# This script should be ran by cron @daily.
+#
+#
+# Copyright (C) 2016 Louis-Philippe Véronneau
+#
+# This program is licensed under GPLv3 +
+
+
+# Check argument sanity
+
+PID_FILE='/var/run/check_free_space.pid'
+
+if test -f "$PID_FILE"
+then
+ pid=$(cat "$PID_FILE")
+ ps -p "$pid" > /dev/null
+ if test $? -eq 0
+ then
+ echo "$0 already run !" >&2
+ exit 1
+ else
+ rm $PID_FILE
+ fi
+fi
+
+echo $$ > $PID_FILE
+
+if test -z "$1" || test -z "$2" || test -z "$3" # is non null
+then
+ echo "Some arguments are missing. Please issue a partition list, a" \
+ "maximum percentage and an email template."
+ exit 1
+elif ! [ "$2" -le 100 -a "$2" -ge 0 ] # is a percentage
+then
+ echo "Please enter a maximum percentage value between 0 and 100."
+ exit 1
+fi
+
+# Argument processing
+
+partition_list=$1
+max_percentage=$((100-$2))
+email_template=$3
+
+HOSTNAME=$(hostname)
+debian_version=$(lsb_release -c)
+
+check_disk='/usr/lib/nagios/plugins/check_disk'
+
+test -f /etc/evomaintenance.cf && . /etc/evomaintenance.cf
+
+
+# Test what version of df we have
+
+old_df=false
+
+case "$debian_version" in
+ *squeeze* ) old_df=true ;;
+ *wheezy* ) old_df=true ;;
+esac
+
+
+# Check disk space
+
+df_options="size,avail,pcent,itotal,iavail,ipcent"
+
+for partition in $partition_list
+do
+ if ! $check_disk -w $max_percentage% -W $max_percentage% $partition > /dev/null
+ then
+ # the 'newline' is a hack to make sed behave
+ PARTITION_DATA="$PARTITION_DATA newline $partition newline"
+ if [ $old_df ]
+ then
+ PARTITION_DATA="$PARTITION_DATA $(/bin/df -h $partition) newline"
+ PARTITION_DATA="$PARTITION_DATA newline $(df -ih $partition) newlinenewline"
+ else
+ PARTITION_DATA="$PARTITION_DATA $(/bin/df -h --output=$df_options $partition) newline"
+ fi
+ full_partitions="$full_partitions $partition"
+ partname=$(echo $partition|tr -s '/' '-')
+ graph_list="$graph_list -a /home/duc${partname}.png"
+ fi
+done
+
+
+# Exit if everything is OK
+
+if test -z "$PARTITION_DATA"
+then
+ exit 0
+fi
+
+
+# If there is indeed a problem, get more infos with duc
+
+/usr/bin/ionice -c3 /usr/bin/duc index -H -d /home/duc.idx -x $full_partitions -q
+
+for partition in $full_partitions
+do
+ duc_temp=$(/usr/bin/duc ls -d /home/duc.idx -Fg $partition)
+ duc_temp=$(printf "$duc_temp" | sed -e "s@]@]newline@" | grep -v "lost+found")
+ DUC_OUTPUT="$DUC_OUTPUT newline$partition newline$duc_temp"
+ partname=$(echo $partition|tr -s '/' '-')
+ duc graph -d /home/duc.idx -o /home/duc${partname}.png -l8 -s 1024 $partition
+done
+
+
+# Replace placeholders & send the mail !
+
+PARTITION_DATA="$(echo "$PARTITION_DATA"|tr -d $'\n')" # make sed accept the input
+DUC_OUTPUT="$(echo "$DUC_OUTPUT"|tr -d $'\n')"
+
+if [ $old_df ]
+then
+ sed -e "s/__TO__/$EVOMAINTMAIL/" \
+ -e "s/__HOSTNAME__/$HOSTNAME/" \
+ -e "s@__PARTITION_DATA__@$PARTITION_DATA@" \
+ -e "s@__DUC_OUTPUT__@$DUC_OUTPUT@" \
+ -e "s/newline/\n/g" \
+ -e "s/IUse%/IUse%\n/g" \
+ -e "s/ Use%/ Use%\n/g" \
+ -e "s@Filesystem \{12\}@@g" \
+ -e "s@Mounted on\/dev\/[a-z]\{3\}[0-9]\+ \{13\}@@g" \
+ -e "s@% \/[a-z]\+@%@g" \
+ -e "s/__MAX_PERCENTAGE__/$max_percentage/" \
+ -e "s/__FULLFROM__/$FULLFROM/" \
+ -e "s/__FROM__/$FROM/" \
+ -e "s/__URGENCYFROM__/$URGENCYFROM/" \
+ -e "s/__URGENCYTEL__/$URGENCYTEL/" \
+ $email_template | \
+ /usr/bin/mutt -H - $graph_list
+else
+ sed -e "s/__TO__/$EVOMAINTMAIL/" \
+ -e "s/__HOSTNAME__/$HOSTNAME/" \
+ -e "s@__PARTITION_DATA__@$PARTITION_DATA@" \
+ -e "s@__DUC_OUTPUT__@$DUC_OUTPUT@" \
+ -e "s/newline/\n/g" \
+ -e "s/IUse%/IUse%\n/g" \
+ -e "s/__MAX_PERCENTAGE__/$max_percentage/" \
+ -e "s/__FULLFROM__/$FULLFROM/" \
+ -e "s/__FROM__/$FROM/" \
+ -e "s/__URGENCYFROM__/$URGENCYFROM/" \
+ -e "s/__URGENCYTEL__/$URGENCYTEL/" \
+ $email_template | \
+ /usr/bin/mutt -H - $graph_list
+fi
+
+rm -f $PID_FILE
diff --git a/check_free_space/files/check_free_space.tpl b/check_free_space/files/check_free_space.tpl
new file mode 100644
index 00000000..15ce5635
--- /dev/null
+++ b/check_free_space/files/check_free_space.tpl
@@ -0,0 +1,24 @@
+From: __FULLFROM__
+Content-Type: text/plain; charset=UTF-8
+MIME-Version: 1.0
+Content-Transfer-Encoding: 8bit
+To: __TO__
+Subject: [WARNING] Espace disque faible sur __HOSTNAME__
+
+Bonjour,
+
+Ceci est un message automatique pour vous informer qu'il y a un
+souci d'espace disque sur votre serveur __HOSTNAME__
+
+Voici les informations sur l'espace disque qui pose problème :
+__PARTITION_DATA__
+Détails sur les partitions problématiques :
+__DUC_OUTPUT__
+Un graphe par partition problématique est disponible en pièce jointe.
+
+Nous vous recommandons d'effectuer du ménage pour maintenir
+chaque partition avec un minimum de __MAX_PERCENTAGE__% d'espace disque libre.
+
+Cordialement,
+--
+__FULLFROM__
diff --git a/check_free_space/tasks/main.yml b/check_free_space/tasks/main.yml
new file mode 100644
index 00000000..b2b4aa07
--- /dev/null
+++ b/check_free_space/tasks/main.yml
@@ -0,0 +1,37 @@
+---
+- ansible.builtin.include_role:
+ name: evolix/remount-usr
+
+- name: Copy check_free_space.sh script
+ ansible.builtin.copy:
+ src: files/check_free_space.sh
+ dest: /usr/share/scripts/check_free_space
+ owner: root
+ group: root
+ mode: "0750"
+
+- name: Copy email template
+ ansible.builtin.copy:
+ src: files/check_free_space.tpl
+ dest: /usr/share/scripts/check_free_space.tpl
+ owner: root
+ group: root
+ mode: "0644"
+
+# not using the cron_module for this since it is buggy
+- name: check_free_space.sh is run by cron
+ ansible.builtin.template:
+ src: templates/cron_check_free_space.j2
+ dest: /etc/cron.d/check_free_space
+ owner: root
+ group: root
+ mode: "0644"
+ force: false
+
+- name: Duc and Mutt are installed
+ ansible.builtin.apt:
+ pkg:
+ - mutt
+ - duc
+ state: present
+
diff --git a/check_free_space/tasks/shell_script.yml b/check_free_space/tasks/shell_script.yml
new file mode 100644
index 00000000..716304a1
--- /dev/null
+++ b/check_free_space/tasks/shell_script.yml
@@ -0,0 +1,30 @@
+---
+
+- include_role:
+ name: evolix/remount-usr
+
+- name: shell script
+ copy:
+ src: files/check_free_space.sh
+ dest: /usr/share/scripts/check_free_space
+ owner: root
+ group: root
+ mode: "0750"
+
+- name: email template
+ copy:
+ src: files/check_free_space.tpl
+ dest: /usr/share/scripts/check_free_space.tpl
+ owner: root
+ group: root
+ mode: "0644"
+
+# not using the cron_module for this since it is buggy
+- name: cron
+ template:
+ src: templates/cron_check_free_space.j2
+ dest: /etc/cron.d/check_free_space
+ owner: root
+ group: root
+ mode: "0644"
+ force: false
diff --git a/check_free_space/templates/cron_check_free_space.j2 b/check_free_space/templates/cron_check_free_space.j2
new file mode 100644
index 00000000..5017a67b
--- /dev/null
+++ b/check_free_space/templates/cron_check_free_space.j2
@@ -0,0 +1,4 @@
+{% if check_free_space_mailto and check_free_space_mailto != "" %}
+MAILTO={{ check_free_space_mailto }}
+{% endif %}
+30 4 * * 1 root /usr/share/scripts/check_free_space "{{ check_free_space_partitions | join(' ') }}" {{ check_free_space_max_percent }} /usr/share/scripts/check_free_space.tpl
diff --git a/docker-host/tasks/main.yml b/docker-host/tasks/main.yml
index 556570f5..ec3781e7 100644
--- a/docker-host/tasks/main.yml
+++ b/docker-host/tasks/main.yml
@@ -119,4 +119,4 @@
cmd: "{{ docker_tls_path }}/shellpki.sh init"
when:
- docker_tls_enabled | bool
- - not tls_certs_stat.stat.isdir
+ - not (tls_certs_stat.stat.exists and tls_certs_stat.stat.isdir)
diff --git a/dovecot/defaults/main.yml b/dovecot/defaults/main.yml
index 52e06bda..e190adb6 100644
--- a/dovecot/defaults/main.yml
+++ b/dovecot/defaults/main.yml
@@ -1,4 +1,12 @@
---
+general_alert_email: "root@localhost"
+log2mail_alert_email: Null
+
dovecot_vmail_uid: 5000
dovecot_vmail_gid: 5000
+
+ldap_hostname: "{{ ansible_hostname }}"
+ldap_domain: "{{ ansible_domain }}"
+ldap_suffix: "dc={{ ldap_hostname }},dc={{ ldap_domain.split('.')[-2] }},dc={{ ldap_domain.split('.')[-1] }}"
+ldap_enabled: False
diff --git a/dovecot/files/munin_plugin_dovecot1 b/dovecot/files/munin_plugin_dovecot1
old mode 100644
new mode 100755
index 83f4d897..27139b73
--- a/dovecot/files/munin_plugin_dovecot1
+++ b/dovecot/files/munin_plugin_dovecot1
@@ -53,15 +53,17 @@ if ( $ARGV[0] and $ARGV[0] eq "autoconf" ) {
exit 0;
}
-if (-f "$logfile.0") {
- $rotlogfile = $logfile . ".0";
-} elsif (-f "$logfile.1") {
- $rotlogfile = $logfile . ".1";
-} elsif (-f "$logfile.01") {
- $rotlogfile = $logfile . ".01";
-} else {
- $rotlogfile = $logfile . ".0";
-}
+# Disable rotated log inpection because name is not deterministic across systems
+# and data loss is may 5 min
+#if (-f "$logfile.0") {
+# $rotlogfile = $logfile . ".0";
+#} elsif (-f "$logfile.1") {
+# $rotlogfile = $logfile . ".1";
+#} elsif (-f "$logfile.01") {
+# $rotlogfile = $logfile . ".01";
+#} else {
+# $rotlogfile = $logfile . ".0";
+#}
if ( $ARGV[0] and $ARGV[0] eq "config" ) {
print "multigraph dovecot_connections\n";
@@ -179,7 +181,9 @@ if (!defined $pos) {
if ($startsize < $pos) {
# Log rotated
- parseDovecotfile ($rotlogfile, $pos, (stat $rotlogfile)[7]);
+ # Disable rotated log inpection because name is not deterministic across systems
+ # and data loss is may 5 min
+ #parseDovecotfile ($rotlogfile, $pos, (stat $rotlogfile)[7]);
$pos = 0;
}
diff --git a/dovecot/files/z-evolinux-dovecot.conf b/dovecot/files/munin_plugins.conf
similarity index 100%
rename from dovecot/files/z-evolinux-dovecot.conf
rename to dovecot/files/munin_plugins.conf
diff --git a/dovecot/tasks/main.yml b/dovecot/tasks/main.yml
index adb81238..8589a701 100644
--- a/dovecot/tasks/main.yml
+++ b/dovecot/tasks/main.yml
@@ -1,3 +1,5 @@
+---
+
- name: ensure packages are installed
ansible.builtin.apt:
name:
@@ -8,7 +10,7 @@
- dovecot-managesieved
state: present
tags:
- - dovecot
+ - dovecot
- name: Generate 4096 bits Diffie-Hellman parameters (may take several minutes)
community.crypto.openssl_dhparam:
@@ -21,7 +23,7 @@
regexp: "[^#]!include auth-system.conf.ext"
replace: "#!include auth-system.conf.ext"
tags:
- - dovecot
+ - dovecot
- name: update ldap auth
ansible.builtin.lineinfile:
@@ -33,14 +35,15 @@
- { key: 'hosts', value: '127.0.0.1' }
- { key: 'auth_bind', value: 'yes' }
- { key: 'ldap_version', value: 3 }
- - { key: 'base', value: "{{ ldap_suffix }}" }
+ - { key: 'base', value: "{{ ldap_suffix | mandatory }}" }
- { key: 'user_attrs', value: 'homeDirectory=home' }
- { key: 'user_filter', value: '(&(isActive=TRUE)(uid=%u))' }
- { key: 'pass_attrs', value: 'uid=user,userPassword=password' }
- when: ldap_suffix is defined
+ - { key: 'iterate_filter', value: '(&(isActive=TRUE))' }
+ when: ldap_enabled | bool | default(False)
notify: reload dovecot
tags:
- - dovecot
+ - dovecot
- name: create vmail group
ansible.builtin.group:
@@ -48,7 +51,7 @@
gid: "{{ dovecot_vmail_gid }}"
system: True
tags:
- - dovecot
+ - dovecot
- name: create vmail user
ansible.builtin.user:
@@ -58,16 +61,16 @@
shell: /bin/false
system: True
tags:
- - dovecot
+ - dovecot
-- name: deploy evolix config
+- name: deploy evolix config for Dovecot
ansible.builtin.template:
src: z-evolinux-defaults.conf.j2
dest: /etc/dovecot/conf.d/z-evolinux-defaults.conf
mode: "0644"
notify: reload dovecot
tags:
- - dovecot
+ - dovecot
- name: deploy file for custom configuration
ansible.builtin.template:
@@ -76,7 +79,7 @@
mode: "0644"
notify: reload dovecot
tags:
- - dovecot
+ - dovecot
- ansible.builtin.include: munin.yml
tags:
@@ -86,7 +89,8 @@
ansible.builtin.apt:
name: log2mail
state: present
- tags: dovecot
+ tags:
+ - dovecot
- name: dovecot is configured in log2mail
ansible.builtin.blockinfile:
@@ -101,5 +105,6 @@
mailto = {{ log2mail_alert_email or general_alert_email | mandatory }}
template = /etc/log2mail/mail
notify: restart log2mail
- tags: dovecot
+ tags:
+ - dovecot
diff --git a/dovecot/tasks/munin.yml b/dovecot/tasks/munin.yml
index 7227e991..4c3daf4a 100644
--- a/dovecot/tasks/munin.yml
+++ b/dovecot/tasks/munin.yml
@@ -9,15 +9,18 @@
- name: Munin plugins are present and configured
block:
- - name: Disable dovecot plugin
+ - name: Disable Dovecot plugin
ansible.builtin.file:
path: /etc/munin/plugins/dovecot
state: absent
- - name: Remove dovecot plugin conf
+ - name: Remove old Dovecot plugin conf
ansible.builtin.file:
- path: /etc/munin/plugin-conf.d/dovecot
+ path: "/etc/munin/plugin-conf.d/{{ item }}"
state: absent
+ loop:
+ - dovecot
+ - z-evolinux-dovecot
- name: "Remount /usr if needed"
ansible.builtin.include_role:
@@ -46,8 +49,8 @@
- name: Copy Munin config
ansible.builtin.copy:
- src: z-evolinux-dovecot.conf
- dest: /etc/munin/plugin-conf.d/z-evolinux-dovecot
+ src: munin_plugins.conf
+ dest: /etc/munin/plugin-conf.d/zzz-dovecot
mode: '0644'
notify: restart munin-node
diff --git a/etc-git/tasks/repositories.yml b/etc-git/tasks/repositories.yml
index 6c76d265..7745183d 100644
--- a/etc-git/tasks/repositories.yml
+++ b/etc-git/tasks/repositories.yml
@@ -24,14 +24,36 @@
- ansible.builtin.include_role:
name: evolix/remount-usr
when:
- - _usr_share_scripts.stat.isdir
+ - _usr_share_scripts.stat.exists and _usr_share_scripts.stat.isdir
- ansible.builtin.import_tasks: repository.yml
vars:
repository_path: "/usr/share/scripts"
gitignore_items: []
when:
- - _usr_share_scripts.stat.isdir
+ - _usr_share_scripts.stat.exists and _usr_share_scripts.stat.isdir
- ansible_distribution_major_version is version('10', '>=')
tags:
- - etc-git
\ No newline at end of file
+ - etc-git
+
+
+- name: verify /var/chroot-bind/ presence
+ ansible.builtin.stat:
+ path: /var/chroot-bind
+ register: _var_chroot_bind
+ tags:
+ - etc-git
+
+- name: /var/chroot-bind/etc/bind is a safe directory
+ ansible.builtin.shell: git config --global --add safe.directory /var/chroot-bind/etc/bind
+
+- ansible.builtin.import_tasks: repository.yml
+ vars:
+ repository_path: "/var/chroot-bind/etc/bind"
+ gitignore_items: []
+ when:
+ - _var_chroot_bind.stat.exists and _var_chroot_bind.stat.isdir
+ - ansible_distribution_major_version is version('8', '>=')
+ tags:
+ - etc-git
+
diff --git a/evocheck/files/evocheck.jessie.sh b/evocheck/files/evocheck.jessie.sh
index 9cc1dcbb..585dd735 100755
--- a/evocheck/files/evocheck.jessie.sh
+++ b/evocheck/files/evocheck.jessie.sh
@@ -4,7 +4,7 @@
# Script to verify compliance of a Linux (Debian) server
# powered by Evolix
-VERSION="23.07"
+VERSION="24.01"
readonly VERSION
# base functions
diff --git a/evocheck/files/evocheck.sh b/evocheck/files/evocheck.sh
index 65a26a3e..f125e713 100755
--- a/evocheck/files/evocheck.sh
+++ b/evocheck/files/evocheck.sh
@@ -4,7 +4,7 @@
# Script to verify compliance of a Linux (Debian) server
# powered by Evolix
-VERSION="23.07"
+VERSION="24.01"
readonly VERSION
# base functions
@@ -68,6 +68,8 @@ detect_os() {
10) DEBIAN_RELEASE="buster";;
11) DEBIAN_RELEASE="bullseye";;
12) DEBIAN_RELEASE="bookworm";;
+ 13) DEBIAN_RELEASE="trixie";;
+ 14) DEBIAN_RELEASE="forky";;
esac
fi
fi
@@ -85,6 +87,12 @@ is_debian_bullseye() {
is_debian_bookworm() {
test "${DEBIAN_RELEASE}" = "bookworm"
}
+is_debian_trixie() {
+ test "${DEBIAN_RELEASE}" = "trixie"
+}
+is_debian_forky() {
+ test "${DEBIAN_RELEASE}" = "forky"
+}
is_pack_web(){
test -e /usr/share/scripts/web-add.sh || test -e /usr/share/scripts/evoadmin/web-add.sh
@@ -148,13 +156,13 @@ check_dpkgwarning() {
# Check if localhost, localhost.localdomain and localhost.$mydomain are set in Postfix mydestination option.
check_postfix_mydestination() {
# shellcheck disable=SC2016
- if ! grep mydestination /etc/postfix/main.cf | grep --quiet -E 'localhost([[:blank:]]|$)'; then
- failed "IS_POSTFIX_MYDESTINATION" "'localhost' s missing in Postfix mydestination option."
+ if ! grep mydestination /etc/postfix/main.cf | grep --quiet --extended-regexp 'localhost([[:blank:]]|$)'; then
+ failed "IS_POSTFIX_MYDESTINATION" "'localhost' is missing in Postfix mydestination option."
fi
- if ! grep mydestination /etc/postfix/main.cf | grep --quiet 'localhost\.localdomain'; then
+ if ! grep mydestination /etc/postfix/main.cf | grep --quiet --fixed-strings 'localhost.localdomain'; then
failed "IS_POSTFIX_MYDESTINATION" "'localhost.localdomain' is missing in Postfix mydestination option."
fi
- if ! grep mydestination /etc/postfix/main.cf | grep --quiet 'localhost\.\$mydomain'; then
+ if ! grep mydestination /etc/postfix/main.cf | grep --quiet --fixed-strings 'localhost.$mydomain'; then
failed "IS_POSTFIX_MYDESTINATION" "'localhost.\$mydomain' is missing in Postfix mydestination option."
fi
}
@@ -193,6 +201,65 @@ check_debiansecurity() {
apt-cache policy | grep "\bl=Debian-Security\b" | grep "\bo=Debian\b" | grep --quiet "\bc=main\b"
test $? -eq 0 || failed "IS_DEBIANSECURITY" "missing Debian-Security repository"
}
+check_debiansecurity_lxc() {
+ if is_installed lxc; then
+ container_list=$(lxc-ls)
+ for container in $container_list; do
+ DEBIAN_LXC_VERSION=$(cut -d "." -f 1 < /var/lib/lxc/${container}/rootfs/etc/debian_version)
+ if [ $DEBIAN_LXC_VERSION -ge 9 ]; then
+ lxc-attach --name $container apt-cache policy | grep "\bl=Debian-Security\b" | grep "\bo=Debian\b" | grep --quiet "\bc=main\b"
+ test $? -eq 0 || failed "IS_DEBIANSECURITY_LXC" "missing Debian-Security repository in container ${container}"
+ fi
+ done
+ fi
+}
+check_backports_version() {
+ # Look for enabled "Debian Backports" sources from the "Debian" origin
+ apt-cache policy | grep "\bl=Debian Backports\b" | grep "\bo=Debian\b" | grep --quiet "\bc=main\b"
+ test $? -eq 1 || ( \
+ apt-cache policy | grep "\bl=Debian Backports\b" | grep --quiet "\bn=${DEBIAN_RELEASE}-backports\b" && \
+ test $? -eq 0 || failed "IS_BACKPORTS_VERSION" "Debian Backports enabled for another release than ${DEBIAN_RELEASE}" )
+}
+check_oldpub() {
+ # Look for enabled pub.evolix.net sources (supersed by pub.evolix.org since Stretch)
+ apt-cache policy | grep --quiet pub.evolix.net
+ test $? -eq 1 || failed "IS_OLDPUB" "Old pub.evolix.net repository is still enabled"
+}
+check_oldpub_lxc() {
+ # Look for enabled pub.evolix.net sources (supersed by pub.evolix.org since Buster as Sury safeguard)
+ if is_installed lxc; then
+ container_list=$(lxc-ls)
+ for container in $container_list; do
+ lxc-attach --name $container apt-cache policy | grep --quiet pub.evolix.net
+ test $? -eq 1 || failed "IS_OLDPUB_LXC" "Old pub.evolix.net repository is still enabled in container ${container}"
+ done
+ fi
+}
+check_newpub() {
+ # Look for enabled pub.evolix.org sources
+ apt-cache policy | grep "\bl=Evolix\b" | grep --quiet -v php
+ test $? -eq 0 || failed "IS_NEWPUB" "New pub.evolix.org repository is missing"
+}
+check_sury() {
+ # Look for enabled packages.sury.org sources
+ apt-cache policy | grep --quiet packages.sury.org
+ if [ $? -eq 0 ]; then
+ apt-cache policy | grep "\bl=Evolix\b" | grep php --quiet
+ test $? -eq 0 || failed "IS_SURY" "packages.sury.org is present but our safeguard pub.evolix.org repository is missing"
+ fi
+}
+check_sury_lxc() {
+ if is_installed lxc; then
+ container_list=$(lxc-ls)
+ for container in $container_list; do
+ lxc-attach --name $container apt-cache policy | grep --quiet packages.sury.org
+ if [ $? -eq 0 ]; then
+ lxc-attach --name $container apt-cache policy | grep "\bl=Evolix\b" | grep php --quiet
+ test $? -eq 0 || failed "IS_SURY_LXC" "packages.sury.org is present but our safeguard pub.evolix.org repository is missing in container ${container}"
+ fi
+ done
+ fi
+}
check_aptitude() {
test -e /usr/bin/aptitude && failed "IS_APTITUDE" "aptitude may not be installed on Debian >=8"
}
@@ -283,11 +350,20 @@ check_alert5minifw() {
fi
}
check_minifw() {
- /sbin/iptables -L -n | grep -q -E "^ACCEPT\s*(all|0)\s*--\s*31\.170\.8\.4\s*0\.0\.0\.0/0\s*$" \
- || failed "IS_MINIFW" "minifirewall seems not started"
+ {
+ if [ -f /etc/systemd/system/minifirewall.service ]; then
+ systemctl is-active minifirewall > /dev/null 2>&1
+ else
+ if test -x /usr/share/scripts/minifirewall_status; then
+ /usr/share/scripts/minifirewall_status > /dev/null 2>&1
+ else
+ /sbin/iptables -L -n 2> /dev/null | grep -q -E "^(DROP\s+(udp|17)|ACCEPT\s+(icmp|1))\s+--\s+0\.0\.0\.0\/0\s+0\.0\.0\.0\/0\s*$"
+ fi
+ fi
+ } || failed "IS_MINIFW" "minifirewall seems not started"
}
check_minifw_includes() {
- if is_debian_bullseye; then
+ if { ! is_debian_stretch && ! is_debian_buster ; }; then
if grep -q -e '/sbin/iptables' -e '/sbin/ip6tables' "/etc/default/minifirewall"; then
failed "IS_MINIFWINCLUDES" "minifirewall has direct iptables invocations in /etc/default/minifirewall that should go in /etc/minifirewall.d/"
fi
@@ -314,13 +390,13 @@ check_nrpedisks() {
test "$NRPEDISKS" = "$DFDISKS" || failed "IS_NRPEDISKS" "there must be $DFDISKS check_disk in nrpe.cfg"
}
check_nrpepid() {
- if { is_debian_bullseye || is_debian_bookworm ; }; then
+ if { is_debian_stretch || is_debian_buster ; }; then
{ test -e /etc/nagios/nrpe.cfg \
- && grep -q "^pid_file=/run/nagios/nrpe.pid" /etc/nagios/nrpe.cfg;
+ && grep -q "^pid_file=/var/run/nagios/nrpe.pid" /etc/nagios/nrpe.cfg;
} || failed "IS_NRPEPID" "missing or wrong pid_file directive in nrpe.cfg"
else
{ test -e /etc/nagios/nrpe.cfg \
- && grep -q "^pid_file=/var/run/nagios/nrpe.pid" /etc/nagios/nrpe.cfg;
+ && grep -q "^pid_file=/run/nagios/nrpe.pid" /etc/nagios/nrpe.cfg;
} || failed "IS_NRPEPID" "missing or wrong pid_file directive in nrpe.cfg"
fi
}
@@ -447,7 +523,11 @@ check_log2mailsquid() {
check_bindchroot() {
if is_installed bind9; then
if netstat -utpln | grep "/named" | grep :53 | grep -qvE "(127.0.0.1|::1)"; then
- if grep -q '^OPTIONS=".*-t' /etc/default/bind9 && grep -q '^OPTIONS=".*-u' /etc/default/bind9; then
+ default_conf=/etc/default/named
+ if is_debian_buster || is_debian_stretch; then
+ default_conf=/etc/default/bind9
+ fi
+ if grep -q '^OPTIONS=".*-t' "${default_conf}" && grep -q '^OPTIONS=".*-u' "${default_conf}"; then
md5_original=$(md5sum /usr/sbin/named | cut -f 1 -d ' ')
md5_chrooted=$(md5sum /var/chroot-bind/usr/sbin/named | cut -f 1 -d ' ')
if [ "$md5_original" != "$md5_chrooted" ]; then
@@ -525,7 +605,12 @@ check_evobackup_exclude_mount() {
# If rsync is not limited by "one-file-system"
# then we verify that every mount is excluded
if ! grep -q -- "^\s*--one-file-system" "${evobackup_file}"; then
- grep -- "--exclude " "${evobackup_file}" | grep -E -o "\"[^\"]+\"" | tr -d '"' > "${excludes_file}"
+ # old releases of evobackups don't have version
+ if grep -q "^VERSION=" "${evobackup_file}" && dpkg --compare-versions "$(sed -E -n 's/VERSION="(.*)"/\1/p' "${evobackup_file}")" ge 22.12 ; then
+ sed -En '/RSYNC_EXCLUDES="/,/"/ {s/(RSYNC_EXCLUDES=|")//g;p}' "${evobackup_file}" > "${excludes_file}"
+ else
+ grep -- "--exclude " "${evobackup_file}" | grep -E -o "\"[^\"]+\"" | tr -d '"' > "${excludes_file}"
+ fi
not_excluded=$(findmnt --type nfs,nfs4,fuse.sshfs, -o target --noheadings | grep -v -f "${excludes_file}")
for mount in ${not_excluded}; do
failed "IS_EVOBACKUP_EXCLUDE_MOUNT" "${mount} is not excluded from ${evobackup_file} backup script"
@@ -578,7 +663,7 @@ check_apacheipinallow() {
check_muninapacheconf() {
muninconf="/etc/apache2/conf-available/munin.conf"
if is_installed apache2; then
- test -e $muninconf && grep -vEq "^( |\t)*#" "$muninconf" \
+ test -e $muninconf && grep --invert-match --extended-regexp --quiet "^( |\t)*#" "$muninconf" \
&& failed "IS_MUNINAPACHECONF" "default munin configuration may be commented or disabled"
fi
}
@@ -587,17 +672,17 @@ check_phpmyadminapacheconf() {
phpmyadminconf0="/etc/apache2/conf-available/phpmyadmin.conf"
phpmyadminconf1="/etc/apache2/conf-enabled/phpmyadmin.conf"
if is_installed apache2; then
- test -e $phpmyadminconf0 && grep -vEq "^( |\t)*#" "$phpmyadminconf0" \
- && failed "IS_PHPMYADMINAPACHECONF" "default phpmyadmin configuration ($phpmyadminconf0) may be commented or disabled"
- test -e $phpmyadminconf1 && grep -vEq "^( |\t)*#" "$phpmyadminconf1" \
- && failed "IS_PHPMYADMINAPACHECONF" "default phpmyadmin configuration ($phpmyadminconf1) may be commented or disabled"
+ test -e $phpmyadminconf0 && grep --invert-match --extended-regexp --quiet "^( |\t)*#" "$phpmyadminconf0" \
+ && failed "IS_PHPMYADMINAPACHECONF" "default phpmyadmin configuration ($phpmyadminconf0) should be commented or disabled"
+ test -e $phpmyadminconf1 && grep --invert-match --extended-regexp --quiet "^( |\t)*#" "$phpmyadminconf1" \
+ && failed "IS_PHPMYADMINAPACHECONF" "default phpmyadmin configuration ($phpmyadminconf1) should be commented or disabled"
fi
}
# Verification si le système doit redémarrer suite màj kernel.
check_kerneluptodate() {
if is_installed linux-image*; then
# shellcheck disable=SC2012
- kernel_installed_at=$(date -d "$(ls --full-time -lcrt /boot | tail -n1 | awk '{print $6}')" +%s)
+ kernel_installed_at=$(date -d "$(ls --full-time -lcrt /boot/*lin* | tail -n1 | awk '{print $6}')" +%s)
last_reboot_at=$(($(date +%s) - $(cut -f1 -d '.' /proc/uptime)))
if [ "$kernel_installed_at" -gt "$last_reboot_at" ]; then
failed "IS_KERNELUPTODATE" "machine is running an outdated kernel, reboot advised"
@@ -664,6 +749,16 @@ check_etcgit() {
git rev-parse --is-inside-work-tree > /dev/null 2>&1 \
|| failed "IS_ETCGIT" "/etc is not a git repository"
}
+check_etcgit_lxc() {
+ if is_installed lxc; then
+ container_list=$(lxc-ls)
+ for container in $container_list; do
+ export GIT_DIR="/var/lib/lxc/${container}/rootfs/etc/.git" GIT_WORK_TREE="/var/lib/lxc/${container}/rootfs/etc"
+ git rev-parse --is-inside-work-tree > /dev/null 2>&1 \
+ || failed "IS_ETCGIT_LXC" "/etc is not a git repository in container ${container}"
+ done
+ fi
+}
# Check if /etc/.git/ has read/write permissions for root only.
check_gitperms() {
GIT_DIR="/etc/.git"
@@ -673,6 +768,19 @@ check_gitperms() {
[ "$expected" = "$actual" ] || failed "IS_GITPERMS" "$GIT_DIR must be $expected"
fi
}
+check_gitperms_lxc() {
+ if is_installed lxc; then
+ container_list=$(lxc-ls)
+ for container in $container_list; do
+ GIT_DIR="/var/lib/lxc/${container}/rootfs/etc/.git"
+ if test -d $GIT_DIR; then
+ expected="700"
+ actual=$(stat -c "%a" $GIT_DIR)
+ [ "$expected" = "$actual" ] || failed "IS_GITPERMS_LXC" "$GIT_DIR must be $expected (in container ${container})"
+ fi
+ done
+ fi
+}
# Check if no package has been upgraded since $limit.
check_notupgraded() {
last_upgrade=0
@@ -760,10 +868,6 @@ check_apache2evolinuxconf() {
check_backportsconf() {
grep -qsE "^[^#].*backports" /etc/apt/sources.list \
&& failed "IS_BACKPORTSCONF" "backports can't be in main sources list"
- if grep -qsE "^[^#].*backports" /etc/apt/sources.list.d/*.list; then
- grep -qsE "^[^#].*backports" /etc/apt/preferences.d/* \
- || failed "IS_BACKPORTSCONF" "backports must have preferences"
- fi
}
check_bind9munin() {
if is_installed bind9; then
@@ -777,12 +881,25 @@ check_bind9logrotate() {
test -e /etc/logrotate.d/bind9 || failed "IS_BIND9LOGROTATE" "missing bind logrotate file"
fi
}
+check_drbd_two_primaries() {
+ if is_installed drbd-utils; then
+ if command -v drbd-overview >/dev/null; then
+ if drbd-overview 2>&1 | grep -q "Primary/Primary"; then
+ failed "IS_DRBDTWOPRIMARIES" "Some DRBD ressources have two primaries, you risk a split brain!"
+ fi
+ elif command -v drbdadm >/dev/null; then
+ if drbdadm role all 2>&1 | grep -q 'Primary/Primary'; then
+ failed "IS_DRBDTWOPRIMARIES" "Some DRBD ressources have two primaries, you risk a split brain!"
+ fi
+ fi
+ fi
+}
check_broadcomfirmware() {
LSPCI_BIN=$(command -v lspci)
if [ -x "${LSPCI_BIN}" ]; then
if ${LSPCI_BIN} | grep -q 'NetXtreme II'; then
{ is_installed firmware-bnx2 \
- && grep -q "^deb http://mirror.evolix.org/debian.* non-free" /etc/apt/sources.list;
+ && apt-cache policy | grep "\bl=Debian\b" | grep --quiet -v "\b,c=non-free\b"
} || failed "IS_BROADCOMFIRMWARE" "missing non-free repository"
fi
else
@@ -958,6 +1075,7 @@ check_phpevolinuxconf() {
is_debian_stretch && phpVersion="7.0"
is_debian_buster && phpVersion="7.3"
is_debian_bullseye && phpVersion="7.4"
+ is_debian_bookworm && phpVersion="8.2"
if is_installed php; then
{ test -f "/etc/php/${phpVersion}/cli/conf.d/z-evolinux-defaults.ini" \
&& test -f "/etc/php/${phpVersion}/cli/conf.d/zzz-evolinux-custom.ini"
@@ -1089,16 +1207,10 @@ check_usrsharescripts() {
test "$expected" = "$actual" || failed "IS_USRSHARESCRIPTS" "/usr/share/scripts must be $expected"
}
check_sshpermitrootno() {
- sshd_args="-C addr=,user=,host=,laddr=,lport=0"
- if is_debian_stretch; then
- # Noop, we'll use the default $sshd_args
- :
- elif is_debian_buster; then
+ # You could change the SSH port in /etc/evocheck.cf
+ sshd_args="-C addr=,user=,host=,laddr=,lport=${SSH_PORT:-22}"
+ if is_debian_buster; then
sshd_args="${sshd_args},rdomain="
- else
- # NOTE: From Debian Bullseye 11 onward, with OpenSSH 8.1, the argument
- # -T doesn't require the additional -C.
- sshd_args=
fi
# shellcheck disable=SC2086
if ! (sshd -T ${sshd_args} 2> /dev/null | grep -qi 'permitrootlogin no'); then
@@ -1219,7 +1331,7 @@ check_lxc_container_resolv_conf() {
container_list=$(lxc-ls)
current_resolvers=$(grep nameserver /etc/resolv.conf | sed 's/nameserver//g' )
- for container in $container_list; do
+ for container in $container_list; do
if [ -f "/var/lib/lxc/${container}/rootfs/etc/resolv.conf" ]; then
while read -r resolver; do
@@ -1265,6 +1377,34 @@ check_lxc_php_fpm_service_umask_set() {
fi
fi
}
+# Check that LXC containers have the proper Debian version.
+check_lxc_php_bad_debian_version() {
+ if is_installed lxc; then
+ php_containers_list=$(lxc-ls --filter php)
+ missing_umask=""
+ for container in $php_containers_list; do
+ if [ "$container" = "php56" ]; then
+ grep --quiet 'VERSION_ID="8"' /var/lib/lxc/${container}/rootfs/etc/os-release || failed "IS_LXC_PHP_BAD_DEBIAN_VERSION" "Container ${container} should use Jessie"
+ elif [ "$container" = "php70" ]; then
+ grep --quiet 'VERSION_ID="9"' /var/lib/lxc/${container}/rootfs/etc/os-release || failed "IS_LXC_PHP_BAD_DEBIAN_VERSION" "Container ${container} should use Stretch"
+ elif [ "$container" = "php73" ]; then
+ grep --quiet 'VERSION_ID="10"' /var/lib/lxc/${container}/rootfs/etc/os-release || failed "IS_LXC_PHP_BAD_DEBIAN_VERSION" "Container ${container} should use Buster"
+ elif [ "$container" = "php74" ]; then
+ grep --quiet 'VERSION_ID="11"' /var/lib/lxc/${container}/rootfs/etc/os-release || failed "IS_LXC_PHP_BAD_DEBIAN_VERSION" "Container ${container} should use Bullseye"
+ elif [ "$container" = "php82" ]; then
+ grep --quiet 'VERSION_ID="12"' /var/lib/lxc/${container}/rootfs/etc/os-release || failed "IS_LXC_PHP_BAD_DEBIAN_VERSION" "Container ${container} should use Bookworm"
+ fi
+ done
+ fi
+}
+check_lxc_openssh() {
+ if is_installed lxc; then
+ container_list=$(lxc-ls)
+ for container in $container_list; do
+ test -e /var/lib/lxc/${container}/rootfs/usr/sbin/sshd && failed "IS_LXC_OPENSSH" "openssh-server should not be installed in container ${container}"
+ done
+ fi
+}
download_versions() {
local file
@@ -1418,6 +1558,13 @@ main() {
test "${IS_LOGROTATECONF:=1}" = 1 && check_logrotateconf
test "${IS_SYSLOGCONF:=1}" = 1 && check_syslogconf
test "${IS_DEBIANSECURITY:=1}" = 1 && check_debiansecurity
+ test "${IS_DEBIANSECURITY_LXC:=1}" = 1 && check_debiansecurity_lxc
+ test "${IS_BACKPORTS_VERSION:=1}" = 1 && check_backports_version
+ test "${IS_OLDPUB:=1}" = 1 && check_oldpub
+ test "${IS_OLDPUB_LXC:=1}" = 1 && check_oldpub_lxc
+ test "${IS_NEWPUB:=1}" = 1 && check_newpub
+ test "${IS_SURY:=1}" = 1 && check_sury
+ test "${IS_SURY_LXC:=1}" = 1 && check_sury_lxc
test "${IS_APTITUDE:=1}" = 1 && check_aptitude
test "${IS_APTGETBAK:=1}" = 1 && check_aptgetbak
test "${IS_USRRO:=1}" = 1 && check_usrro
@@ -1470,7 +1617,9 @@ main() {
test "${IS_MUNINRUNNING:=1}" = 1 && check_muninrunning
test "${IS_BACKUPUPTODATE:=1}" = 1 && check_backupuptodate
test "${IS_ETCGIT:=1}" = 1 && check_etcgit
+ test "${IS_ETCGIT_LXC:=1}" = 1 && check_etcgit_lxc
test "${IS_GITPERMS:=1}" = 1 && check_gitperms
+ test "${IS_GITPERMS_LXC:=1}" = 1 && check_gitperms_lxc
test "${IS_NOTUPGRADED:=1}" = 1 && check_notupgraded
test "${IS_TUNE2FS_M5:=1}" = 1 && check_tune2fs_m5
test "${IS_EVOLINUXSUDOGROUP:=1}" = 1 && check_evolinuxsudogroup
@@ -1479,6 +1628,7 @@ main() {
test "${IS_BACKPORTSCONF:=1}" = 1 && check_backportsconf
test "${IS_BIND9MUNIN:=1}" = 1 && check_bind9munin
test "${IS_BIND9LOGROTATE:=1}" = 1 && check_bind9logrotate
+ test "${IS_DRBDTWOPRIMARIES:=1}" = 1 && check_drbd_two_primaries
test "${IS_BROADCOMFIRMWARE:=1}" = 1 && check_broadcomfirmware
test "${IS_HARDWARERAIDTOOL:=1}" = 1 && check_hardwareraidtool
test "${IS_LOG2MAILSYSTEMDUNIT:=1}" = 1 && check_log2mailsystemdunit
@@ -1511,6 +1661,8 @@ main() {
test "${IS_LXC_CONTAINER_RESOLV_CONF:=1}" = 1 && check_lxc_container_resolv_conf
test "${IS_NO_LXC_CONTAINER:=1}" = 1 && check_no_lxc_container
test "${IS_LXC_PHP_FPM_SERVICE_UMASK_SET:=1}" = 1 && check_lxc_php_fpm_service_umask_set
+ test "${IS_LXC_PHP_BAD_DEBIAN_VERSION:=1}" = 1 && check_lxc_php_bad_debian_version
+ test "${IS_LXC_OPENSSH:=1}" = 1 && check_lxc_openssh
test "${IS_CHECK_VERSIONS:=1}" = 1 && check_versions
if [ -f "${main_output_file}" ]; then
@@ -1526,7 +1678,7 @@ main() {
}
cleanup() {
# Cleanup tmp files
- # shellcheck disable=SC2086,SC2317
+ # shellcheck disable=SC2068,SC2317
rm -f ${files_to_cleanup[@]}
log "$PROGNAME exit."
diff --git a/evocheck/files/evocheck.wheezy.sh b/evocheck/files/evocheck.wheezy.sh
index 2df0e814..726a364f 100755
--- a/evocheck/files/evocheck.wheezy.sh
+++ b/evocheck/files/evocheck.wheezy.sh
@@ -4,7 +4,7 @@
# Script to verify compliance of a Linux (Debian) server
# powered by Evolix
-VERSION="23.07"
+VERSION="24.01"
readonly VERSION
# base functions
diff --git a/evolinux-base/defaults/main.yml b/evolinux-base/defaults/main.yml
index f92fa90b..97f5540e 100644
--- a/evolinux-base/defaults/main.yml
+++ b/evolinux-base/defaults/main.yml
@@ -159,12 +159,10 @@ evolinux_root_disable_ssh: False
# postfix
evolinux_postfix_include: True
-
-evolinux_postfix_packages: True
+evolinux_mail_aliases_include: True
evolinux_postfix_users_alias_root: True
evolinux_postfix_mailer_alias_root: True
evolinux_postfix_root_alias: True
-evolinux_postfix_purge_exim: True
# logs
@@ -211,6 +209,10 @@ evolinux_munin_include: True
evolinux_nagios_nrpe_include: True
+# check_free_space
+
+evolinux_check_free_space_include: True
+
# fail2ban
evolinux_fail2ban_include: False
@@ -235,3 +237,6 @@ evolinux_motd_include: True
# Utils
evolinux_utils_include: True
+
+# Autosysadmin
+evolinux_autosysadmin_include: false
diff --git a/evolinux-base/files/cert.sh b/evolinux-base/files/cert.sh
new file mode 100644
index 00000000..f43a9dad
--- /dev/null
+++ b/evolinux-base/files/cert.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+#
+# Shortcut to show certificate content or enddate.
+#
+
+usage() {
+ echo "Usage : cert [date] "
+}
+
+if [ "$#" -eq 1 ]; then
+ cert_path=$1
+ if [ -f "${cert_path}" ]; then
+ openssl x509 -noout -in "${cert_path}" -text
+ else
+ >&2 echo "Error, file ${cert_path} does not exist."
+ fi
+
+elif [ "$#" -eq 2 ]; then
+ if [ "$1" = "date" ]; then
+ cert_path=$2
+ if [ -f "${cert_path}" ]; then
+ openssl x509 -noout -in "$cert_path" -enddate
+ else
+ >&2 echo "Error, file ${cert_path} does not exist."
+ fi
+ else
+ >&2 echo "Error, two arguments provided but 'date' is only allowed as first."
+ usage
+ exit 1
+ fi
+
+else
+ >&2 echo "Error, more than two arguments provided."
+ usage
+ exit 1
+fi
+
diff --git a/evolinux-base/files/dump-server-state.sh b/evolinux-base/files/dump-server-state.sh
index 8ed50c7a..77e06bef 100644
--- a/evolinux-base/files/dump-server-state.sh
+++ b/evolinux-base/files/dump-server-state.sh
@@ -3,7 +3,7 @@
PROGNAME="dump-server-state"
REPOSITORY="https://gitea.evolix.org/evolix/dump-server-state"
-VERSION="23.08"
+VERSION="23.11"
readonly VERSION
dump_dir=
@@ -35,43 +35,44 @@ ${PROGNAME} is dumping information related to the state of the server.
Usage: ${PROGNAME} --dump-dir=/path/to/dump/directory [OPTIONS]
Main options
- -d, --dump-dir path to the directory where data will be stored
- --backup-dir legacy option for dump directory
- -f, --force keep existing dump directory and its content
- -v, --verbose print details about each task
- -V, --version print version and exit
- -h, --help print this message and exit
+ -d, --dump-dir path to the directory where data will be stored
+ --backup-dir legacy option for dump directory
+ -f, --force keep existing dump directory and its content
+ -v, --verbose print details about each task
+ -V, --version print version and exit
+ -h, --help print this message and exit
Tasks options
- --all reset options to execute all tasks
- --none reset options to execute no task
- --[no-]etc copy of /etc (default: no)
- --[no-]dpkg-full copy of /var/lib/dpkg (default: no)
- --[no-]dpkg-status copy of /var/lib/dpkg/status (default: yes)
- --[no-]apt-states copy of apt extended states (default: yes)
- --[no-]apt-config copy of apt configuration (default: yes)
- --[no-]packages copy of dpkg selections (default: yes)
- --[no-]processes copy of process list (default: yes)
- --[no-]uname copy of uname value (default: yes)
- --[no-]uptime copy of uptime value (default: yes)
- --[no-]netstat copy of netstat (default: yes)
- --[no-]netcfg copy of network configuration (default: yes)
- --[no-]iptables copy of iptables (default: yes)
- --[no-]sysctl copy of sysctl values (default: yes)
- --[no-]virsh copy of virsh list (default: yes)
- --[no-]lxc copy of lxc list (default: yes)
- --[no-]disks copy of MBR and partitions (default: yes)
- --[no-]mount copy of mount points (default: yes)
- --[no-]df copy of disk usage (default: yes)
- --[no-]dmesg copy of dmesg (default: yes)
- --[no-]mysql copy of mysql processes (default: yes)
- --[no-]systemctl copy of systemd services states (default: yes)
+ --all reset options to execute all tasks
+ --none reset options to execute no task
+ --[no-]etc copy of /etc (default: no)
+ --[no-]dpkg-full copy of /var/lib/dpkg (default: no)
+ --[no-]dpkg-status copy of /var/lib/dpkg/status (default: yes)
+ --[no-]apt-states copy of apt extended states (default: yes)
+ --[no-]apt-config copy of apt configuration (default: yes)
+ --[no-]packages copy of dpkg selections (default: yes)
+ --[no-]processes copy of process list (default: yes)
+ --[no-]uname copy of uname value (default: yes)
+ --[no-]uptime copy of uptime value (default: yes)
+ --[no-]netstat copy of netstat (default: yes)
+ --[no-]netcfg copy of network configuration (default: yes)
+ --[no-]iptables copy of iptables (default: yes)
+ --[no-]sysctl copy of sysctl values (default: yes)
+ --[no-]virsh copy of virsh list (default: yes)
+ --[no-]lxc copy of lxc list (default: yes)
+ --[no-]disks copy of MBR and partitions (default: yes)
+ --[no-]mount copy of mount points (default: yes)
+ --[no-]df copy of disk usage (default: yes)
+ --[no-]dmesg copy of dmesg (default: yes)
+ --[no-]mysql-processes copy of mysql processes (default: yes)
+ --[no-]mysql-summary copy of mysql summary (default: yes)
+ --[no-]systemctl copy of systemd services states (default: yes)
Tasks options order matters. They are evaluated from left to right.
Examples :
* "[…] --none --uname" will do only the uname task
* "[…] --all --no-etc" will do everything but the etc task
-* "[…] --etc --none --mysql" will do only the mysql task
+* "[…] --etc --none --mysql-summary" will do only the mysql task
END
}
debug() {
@@ -741,6 +742,41 @@ task_mysql_processes() {
fi
}
+task_mysql_summary() {
+ debug "Task: MySQL summary"
+
+ mysqladmin_bin=$(command -v mysqladmin)
+ pt_mysql_summary_bin=$(command -v pt-mysql-summary)
+
+ if [ -n "${mysqladmin_bin}" ] && [ -n "${pt_mysql_summary_bin}" ]; then
+ # Look for local MySQL or MariaDB process
+ if pgrep mysqld > /dev/null || pgrep mariadbd > /dev/null; then
+ if ${mysqladmin_bin} ping > /dev/null 2>&1; then
+ # important to set sleep to 0
+ # because we don't want to block
+ # even if we lose some insight.
+ ${pt_mysql_summary_bin} --sleep 0 > "${dump_dir}/mysql-summary.txt" 2> "${dump_dir}/mysql-summary.err"
+ last_rc=$?
+
+ if [ ${last_rc} -eq 0 ]; then
+ debug "* pt-mysql-summary OK"
+ else
+ debug "* pt-mysql-summary ERROR"
+ debug < "${dump_dir}/mysql-summary.err"
+ rm "${dump_dir}/mysql-summary.err"
+ rc=10
+ fi
+ else
+ debug "* unable to ping with mysqladmin"
+ fi
+ else
+ debug "* no mysqld or mariadbd process is running"
+ fi
+ else
+ debug "* pt-mysql-summary not found"
+ fi
+}
+
task_systemctl() {
debug "Task: Systemd services"
@@ -841,6 +877,9 @@ main() {
if [ "${TASK_MYSQL_PROCESSES}" -eq 1 ]; then
task_mysql_processes
fi
+ if [ "${TASK_MYSQL_SUMMARY}" -eq 1 ]; then
+ task_mysql_summary
+ fi
if [ "${TASK_SYSTEMCTL}" -eq 1 ]; then
task_systemctl
fi
@@ -950,6 +989,7 @@ while :; do
TASK_DF \
TASK_DMESG \
TASK_MYSQL_PROCESSES \
+ TASK_MYSQL_SUMMARY \
TASK_SYSTEMCTL
do
eval "${option}=1"
@@ -978,6 +1018,7 @@ while :; do
TASK_DF \
TASK_DMESG \
TASK_MYSQL_PROCESSES \
+ TASK_MYSQL_SUMMARY \
TASK_SYSTEMCTL
do
eval "${option}=0"
@@ -1124,6 +1165,13 @@ while :; do
TASK_MYSQL_PROCESSES=0
;;
+ --mysql-summary)
+ TASK_MYSQL_SUMMARY=1
+ ;;
+ --no-mysql-summary)
+ TASK_MYSQL_SUMMARY=0
+ ;;
+
--systemctl)
TASK_SYSTEMCTL=1
;;
@@ -1173,6 +1221,7 @@ done
: "${TASK_DF:=1}"
: "${TASK_DMESG:=1}"
: "${TASK_MYSQL_PROCESSES:=1}"
+: "${TASK_MYSQL_SUMMARY:=1}"
: "${TASK_SYSTEMCTL:=1}"
export LC_ALL=C
diff --git a/evolinux-base/files/logs/rsyslog.conf b/evolinux-base/files/logs/rsyslog.conf
deleted file mode 100644
index 9c2a2d22..00000000
--- a/evolinux-base/files/logs/rsyslog.conf
+++ /dev/null
@@ -1,122 +0,0 @@
-# Syslog for Pack Evolix serveur - Debian Squeeze
-
-
-#################
-#### MODULES ####
-#################
-
-$ModLoad imuxsock # provides support for local system logging
-$ModLoad imklog # provides kernel logging support (previously done by rklogd)
-#$ModLoad immark # provides --MARK-- message capability
-
-# provides UDP syslog reception
-#$ModLoad imudp
-#$UDPServerRun 514
-
-# provides TCP syslog reception
-#$ModLoad imtcp
-#$InputTCPServerRun 514
-
-
-###########################
-#### GLOBAL DIRECTIVES ####
-###########################
-
-#
-# Use traditional timestamp format.
-# To enable high precision timestamps, comment out the following line.
-#
-$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
-
-#
-# Set the default permissions for all log files.
-#
-$FileOwner root
-$FileGroup adm
-$FileCreateMode 0640
-$DirCreateMode 0755
-$Umask 0022
-
-#
-# Include all config files in /etc/rsyslog.d/
-#
-$IncludeConfig /etc/rsyslog.d/*.conf
-
-
-###############
-#### RULES ####
-###############
-
-#
-# First some standard log files. Log by facility.
-#
-auth,authpriv.* /var/log/auth.log
-*.*;auth,authpriv.none;cron,mail,local4,local5.none -/var/log/syslog
-cron.* /var/log/cron.log
-daemon.* -/var/log/daemon.log
-kern.* -/var/log/kern.log
-lpr.* -/var/log/lpr.log
-mail.* -/var/log/mail.log
-user.* -/var/log/user.log
-uucp.* /var/log/uucp.log
-news.* /var/log/news.log
-
-local4.* -/var/log/openldap.log
-local1.* /var/log/sympa.log
-local0.* /var/log/postgresql.log
-local7.* -/var/log/dhcp.log
-local5.* -/var/log/haproxy.log
-
-
-#
-# Logging for the mail system. Split it up so that
-# it is easy to write scripts to parse these files.
-#
-#mail.info -/var/log/mail.info
-#mail.warn -/var/log/mail.warn
-#mail.err /var/log/mail.err
-
-#
-# Logging for INN news system.
-#
-#news.crit /var/log/news/news.crit
-#news.err /var/log/news/news.err
-#news.notice -/var/log/news/news.notice
-
-#
-# Some "catch-all" log files.
-#
-#*.=debug;\
-# auth,authpriv.none;\
-# news.none;mail.none -/var/log/debug
-#*.=info;*.=notice;*.=warn;\
-# auth,authpriv.none;\
-# cron,daemon.none;\
-# mail,news.none -/var/log/messages
-
-#
-# Emergencies are sent to everybody logged in.
-#
-*.emerg *
-
-#
-# I like to have messages displayed on the console, but only on a virtual
-# console I usually leave idle.
-#
-#daemon,mail.*;\
-# news.=crit;news.=err;news.=notice;\
-# *.=debug;*.=info;\
-# *.=notice;*.=warn /dev/tty8
-
-# The named pipe /dev/xconsole is for the `xconsole' utility. To use it,
-# you must invoke `xconsole' with the `-file' option:
-#
-# $ xconsole -file /dev/xconsole [...]
-#
-# NOTE: adjust the list below, or you'll go crazy if you have a reasonably
-# busy site..
-#
-#daemon.*;mail.*;\
-# news.err;\
-# *.=debug;*.=info;\
-# *.=notice;*.=warn |/dev/xconsole
diff --git a/evolinux-base/files/logs/rsyslog.d/10-evolinux-default.conf b/evolinux-base/files/logs/rsyslog.d/10-evolinux-default.conf
new file mode 100644
index 00000000..c072df40
--- /dev/null
+++ b/evolinux-base/files/logs/rsyslog.d/10-evolinux-default.conf
@@ -0,0 +1,13 @@
+# RSyslog for Pack Evolix serveur - Debian Bookworm
+
+daemon.* action(type="omfile" file="/var/log/daemon.log")
+lpr.* action(type="omfile" file="/var/log/lpr.log")
+news.* action(type="omfile" file="/var/log/news.log")
+uucp.* action(type="omfile" file="/var/log/uucp.log")
+
+local0.* action(type="omfile" file="/var/log/postgresql.log")
+local1.* action(type="omfile" file="/var/log/sympa.log")
+# To be explicit we specify “sync="off"” even though it's the default
+local4.* action(type="omfile" sync="off" file="/var/log/openldap.log")
+local5.* action(type="omfile" sync="off" file="/var/log/haproxy.log")
+local7.* action(type="omfile" file="/var/log/dhcp.log")
diff --git a/evolinux-base/tasks/dump-server-state.yml b/evolinux-base/tasks/dump-server-state.yml
index 65ff2f45..e3fd48a7 100644
--- a/evolinux-base/tasks/dump-server-state.yml
+++ b/evolinux-base/tasks/dump-server-state.yml
@@ -5,11 +5,4 @@
force: True
owner: root
group: root
- mode: "0750"
-
-- name: symlink backup-server-state to dump-server-state
- ansible.builtin.file:
- src: /usr/local/sbin/dump-server-state
- dest: /usr/local/sbin/backup-server-state
- state: link
- force: true
+ mode: "0750"
\ No newline at end of file
diff --git a/evolinux-base/tasks/hardware.yml b/evolinux-base/tasks/hardware.yml
index 30badf70..b4280e09 100644
--- a/evolinux-base/tasks/hardware.yml
+++ b/evolinux-base/tasks/hardware.yml
@@ -6,11 +6,11 @@
tags:
- packages
-- name: firmware-non-free components are installed (Debian 12+)
+- name: non-free-firmware components are installed (Debian 12+)
ansible.builtin.replace:
dest: /etc/apt/sources.list.d/system.sources
- regexp: '^(Components: ((?!\bfirmware-non-free\b).)*)$'
- replace: '\1 firmware-non-free'
+ regexp: '^(Components: ((?!\bnon-free-firmware\b).)*)$'
+ replace: '\1 non-free-firmware'
when:
- ansible_distribution_major_version is version('12', '>=')
@@ -48,6 +48,7 @@
- firmware-linux-nonfree
- intel-microcode
state: present
+ update_cache: True
tags:
- packages
diff --git a/evolinux-base/tasks/kernel.yml b/evolinux-base/tasks/kernel.yml
index 231ec02f..148c72df 100644
--- a/evolinux-base/tasks/kernel.yml
+++ b/evolinux-base/tasks/kernel.yml
@@ -9,6 +9,7 @@
- ansible_machine == "x86_64"
- ansible_virtualization_role == "guest"
- evolinux_kernel_cloud_auto | bool
+ - ansible_distribution_major_version is version('10', '>=')
- name: "Remove non-Cloud kernel on virtual servers"
ansible.builtin.apt:
diff --git a/evolinux-base/tasks/log2mail.yml b/evolinux-base/tasks/log2mail.yml
index 9a1f3314..79e4f5e0 100644
--- a/evolinux-base/tasks/log2mail.yml
+++ b/evolinux-base/tasks/log2mail.yml
@@ -17,18 +17,23 @@
state: started
enabled: yes
-- name: log2mail config is present
+- name: log2mail evolinux config is absent from default config
ansible.builtin.blockinfile:
dest: /etc/log2mail/config/default
- owner: log2mail
- group: adm
- mode: "0640"
marker: "# {mark} ANSIBLE MANAGED RULES FOR DEFAULT INSTANCE"
- block: |
- file = /var/log/syslog
- pattern = "Out of memory: Kill"
- mailto = {{ log2mail_alert_email or general_alert_email | mandatory }}
- template = /etc/log2mail/mail
+ state: absent
+ notify: restart log2mail
+ tags:
+ - log2mail
+
+- name: log2mail evolinux-defaults config is present
+ ansible.builtin.template:
+ src: log2mail/evolinux-defaults.j2
+ dest: /etc/log2mail/config/evolinux-defaults
+ owner: log2mail
+ group: adm
+ mode: "0640"
+ force: yes
notify: restart log2mail
tags:
- log2mail
diff --git a/evolinux-base/tasks/logs.yml b/evolinux-base/tasks/logs.yml
index 75978711..46ada1d2 100644
--- a/evolinux-base/tasks/logs.yml
+++ b/evolinux-base/tasks/logs.yml
@@ -3,10 +3,10 @@
# TODO: voir comment faire des backups initiaux des fichiers
# RSyslog
-- name: Copy rsyslog.conf
+- name: Copy rsyslog evolinux defaut conf
ansible.builtin.copy:
- src: logs/rsyslog.conf
- dest: /etc/rsyslog.conf
+ src: logs/rsyslog.d/10-evolinux-default.conf
+ dest: /etc/rsyslog.d/10-evolinux-default.conf
mode: "0644"
notify: restart rsyslog
when: evolinux_logs_rsyslog_conf | bool
diff --git a/evolinux-base/tasks/postfix.yml b/evolinux-base/tasks/mail_aliases.yml
similarity index 52%
rename from evolinux-base/tasks/postfix.yml
rename to evolinux-base/tasks/mail_aliases.yml
index d9dba3e2..4007d415 100644
--- a/evolinux-base/tasks/postfix.yml
+++ b/evolinux-base/tasks/mail_aliases.yml
@@ -1,36 +1,5 @@
---
-- name: Postfix packages are installed
- ansible.builtin.apt:
- name:
- - postfix
- - mailgraph
- state: present
- tags:
- - packages
- - postfix
- when: evolinux_postfix_packages | bool
-
-- name: configure postfix myhostname
- ansible.builtin.lineinfile:
- dest: /etc/postfix/main.cf
- state: present
- line: "myhostname = {{ evolinux_fqdn }}"
- regexp: '^myhostname'
- notify: reload postfix
- tags:
- - postfix
-
-- name: configure postfix mynetworks
- ansible.builtin.lineinfile:
- dest: /etc/postfix/main.cf
- state: present
- line: "mydestination = {{ [evolinux_fqdn, evolinux_internal_fqdn] | unique | join(' ') }} localhost.localdomain localhost localhost.$mydomain"
- regexp: '^mydestination'
- notify: reload postfix
- tags:
- - postfix
-
- name: fetch users list
ansible.builtin.shell:
cmd: "set -o pipefail && getent passwd | cut -d':' -f 1 | grep -v root"
@@ -81,18 +50,3 @@
- ansible.builtin.meta: flush_handlers
-- name: exim4 is absent
- ansible.builtin.apt:
- name:
- - exim4
- - exim4-base
- - exim4-config
- - exim4-daemon-light
- purge: yes
- state: absent
- tags:
- - packages
- - postfix
- when: evolinux_postfix_purge_exim | bool
-
-- ansible.builtin.meta: flush_handlers
diff --git a/evolinux-base/tasks/main.yml b/evolinux-base/tasks/main.yml
index 582bcfe0..d27b69eb 100644
--- a/evolinux-base/tasks/main.yml
+++ b/evolinux-base/tasks/main.yml
@@ -81,9 +81,16 @@
ansible.builtin.import_tasks: root.yml
when: evolinux_root_include | bool
-- name: Postfix
- ansible.builtin.import_tasks: postfix.yml
+- name: Postfix role
+ ansible.builtin.include_role:
+ name: evolix/postfix
when: evolinux_postfix_include | bool
+ tags:
+ - postfix
+
+- name: Configure /etc/aliases
+ ansible.builtin.import_tasks: mail_aliases.yml
+ when: evolinux_mail_aliases_include | bool
- name: Logs management
ansible.builtin.import_tasks: logs.yml
@@ -127,6 +134,24 @@
name: evolix/nagios-nrpe
when: evolinux_nagios_nrpe_include | bool
+- name: check_free_space
+ ansible.builtin.include_role:
+ name: evolix/check_free_space
+ when: evolinux_check_free_space_include | bool
+
+# postfix role must be after nagios-nrpe role
+- name: Postfix role
+ ansible.builtin.include_role:
+ name: evolix/postfix
+ when: evolinux_postfix_include | bool
+ tags:
+ - postfix
+
+- name: Autosysadmin
+ ansible.builtin.include_role:
+ name: 'evolix/autosysadmin'
+ when: evolinux_autosysadmin_include | bool
+
- name: fail2ban
ansible.builtin.include_role:
name: evolix/fail2ban
diff --git a/evolinux-base/tasks/system.yml b/evolinux-base/tasks/system.yml
index 52766796..96a77a70 100644
--- a/evolinux-base/tasks/system.yml
+++ b/evolinux-base/tasks/system.yml
@@ -214,3 +214,16 @@
- grep_hotplug_eni.rc == 0
- ansible.builtin.meta: flush_handlers
+
+# Htop / top config
+
+- name: Deploy htop configuration
+ ansible.builtin.copy:
+ src: htoprc
+ dest: /etc/htoprc
+ mode: "0644"
+
+- name: Deploy top configuration file
+ ansible.builtin.file:
+ path: /etc/topdefaultrc
+ state: absent
\ No newline at end of file
diff --git a/evolinux-base/tasks/utils.yml b/evolinux-base/tasks/utils.yml
index a1c4d646..b9b76e3b 100644
--- a/evolinux-base/tasks/utils.yml
+++ b/evolinux-base/tasks/utils.yml
@@ -23,20 +23,3 @@
owner: root
group: root
mode: "0755"
-
-# TODO: delete when this has been run once on all our servers
-- name: update-evobackup-canary is removed from sbin
- ansible.builtin.file:
- path: /usr/local/sbin/update-evobackup-canary
- state: absent
-
-- name: Deploy htop configuration
- ansible.builtin.copy:
- src: htoprc
- dest: /etc/htoprc
- mode: "0644"
-
-- name: Deploy top configuration file
- ansible.builtin.file:
- path: /etc/topdefaultrc
- state: absent
diff --git a/evolinux-base/templates/hardware/hwraid.le-vert.net.sources.j2 b/evolinux-base/templates/hardware/hwraid.le-vert.net.sources.j2
index 9d424a5b..8fbc2d84 100644
--- a/evolinux-base/templates/hardware/hwraid.le-vert.net.sources.j2
+++ b/evolinux-base/templates/hardware/hwraid.le-vert.net.sources.j2
@@ -4,5 +4,5 @@ Types: deb
URIs: http://hwraid.le-vert.net/debian
Suites: {{ ansible_distribution_release }}
Components: main
-Signed-by: {{ apt_keyring_dir }}/hwraid.le-vert.net.asc]
+Signed-by: {{ apt_keyring_dir }}/hwraid.le-vert.net.asc
Enabled: yes
diff --git a/evolinux-base/templates/log2mail/evolinux-defaults.j2 b/evolinux-base/templates/log2mail/evolinux-defaults.j2
new file mode 100644
index 00000000..e5e15d10
--- /dev/null
+++ b/evolinux-base/templates/log2mail/evolinux-defaults.j2
@@ -0,0 +1,16 @@
+# {{ ansible_managed }}
+
+file = /var/log/syslog
+pattern = "Out of memory: Kill"
+mailto = {{ log2mail_alert_email or general_alert_email | mandatory }}
+template = /etc/log2mail/mail
+
+file = /var/log/syslog
+pattern = "memory read error"
+mailto = {{ log2mail_alert_email or general_alert_email | mandatory }}
+template = /etc/log2mail/mail
+
+file = /var/log/cron.log
+pattern = "Syntax error"
+mailto = {{ log2mail_alert_email or general_alert_email | mandatory }}
+template = /etc/log2mail/mail
diff --git a/evolinux-users/templates/sudoers.j2 b/evolinux-users/templates/sudoers.j2
index 60b5b782..0e8471bf 100644
--- a/evolinux-users/templates/sudoers.j2
+++ b/evolinux-users/templates/sudoers.j2
@@ -15,6 +15,7 @@ nagios ALL = NOPASSWD: /usr/local/lib/nagios/plugins/check_phpfpm_multi
nagios ALL = NOPASSWD: /usr/local/lib/nagios/plugins/check_phpfpm_multi /var/lib/lxc/php80/rootfs/etc/php/8.0/fpm/pool.d/
nagios ALL = NOPASSWD: /usr/local/lib/nagios/plugins/check_phpfpm_multi /var/lib/lxc/php81/rootfs/etc/php/8.1/fpm/pool.d/
nagios ALL = NOPASSWD: /usr/local/lib/nagios/plugins/check_phpfpm_multi /var/lib/lxc/php82/rootfs/etc/php/8.2/fpm/pool.d/
+nagios ALL = NOPASSWD: /usr/local/lib/nagios/plugins/check_phpfpm_multi /var/lib/lxc/php83/rootfs/etc/php/8.3/fpm/pool.d/
nagios ALL = NOPASSWD: /usr/sbin/megaclisas-status --nagios
nagios ALL = NOPASSWD: /usr/lib/nagios/plugins/check_ipmi_sensor
nagios ALL = NOPASSWD: /sbin/dmsetup status --noflush
diff --git a/fail2ban/files/unban_ip.sh b/fail2ban/files/unban_ip.sh
new file mode 100644
index 00000000..c13f2ecd
--- /dev/null
+++ b/fail2ban/files/unban_ip.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+function version_gt() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1"; }
+
+IP="$1"
+if [ "$IP" == "" ]; then
+ echo
+ echo -e "\033${TERM_COLOR_LIGHT_RED}Usage: $FUNCNAME \033${TERM_COLOR_NORMAL}"
+ echo
+ cat <&1 | grep -v "$IP is not banned";
+ else
+ iptables -D f2b-$JAIL -s $IP -j DROP 2>&1 | grep -v 'iptables: Bad rule' && sleep 5 || echo "$IP is not banned";
+ fi
+done
+
+exit 0
+
diff --git a/fail2ban/tasks/main.yml b/fail2ban/tasks/main.yml
index 1629a02a..182dbbd5 100644
--- a/fail2ban/tasks/main.yml
+++ b/fail2ban/tasks/main.yml
@@ -94,7 +94,7 @@
- name: "Extend dbpurgeage if recidive jail is enabled"
ansible.builtin.blockinfile:
dest: /etc/fail2ban/fail2ban.d/recidive_dbpurgeage
- marker: "# ANSIBLE MANAGED"
+ marker: "# {mark} ANSIBLE MANAGED"
block: |
[DEFAULT]
dbpurgeage = {{ fail2ban_recidive_bantime }}
@@ -111,3 +111,12 @@
- ansible_distribution_release == "stretch" or ansible_distribution_release == "buster"
tags:
- fail2ban
+
+- name: Script unban_ip is installed
+ ansible.builtin.copy:
+ src: unban_ip.sh
+ dst: /usr/local/sbin/unban_ip
+ mode: '0700'
+ tags:
+ - fail2ban
+
diff --git a/filebeat/handlers/main.yml b/filebeat/handlers/main.yml
index 8456ee33..c5f7001f 100644
--- a/filebeat/handlers/main.yml
+++ b/filebeat/handlers/main.yml
@@ -4,4 +4,3 @@
ansible.builtin.systemd:
name: filebeat
state: restarted
- when: not ansible_check_mode
diff --git a/generate-ldif/templates/generateldif.sh.j2 b/generate-ldif/templates/generateldif.sh.j2
index e306f075..39fc30cf 100755
--- a/generate-ldif/templates/generateldif.sh.j2
+++ b/generate-ldif/templates/generateldif.sh.j2
@@ -14,6 +14,7 @@ get_pkg_version() {
sed 's/[~+-].\+//' | sed 's/.\+://' | sed 's/p.*//' | cut -d'.' -f1,2
}
+debianVersion=$(cut -d "." -f 1 < /etc/debian_version)
clientNumber="{{ client_number | mandatory }}"
monitoringMode="{{ monitoring_mode | mandatory }}"
monitoringType="{{ monitoring_type | mandatory }}"
@@ -685,6 +686,34 @@ ServiceVersion: PHP-FPM 8.1 (multiphp)
EOT
fi
+if lxc-ls | grep -q php82 ; then
+ cat <> "${ldif_file}"
+
+dn: ServiceName=php-fpm82,${computer_dn}
+NagiosEnabled: TRUE
+ipServiceProtocol: tcp
+objectClass: EvoService
+ServiceName: php-fpm82
+ipServicePort: 443
+ServiceType: web
+ServiceVersion: PHP-FPM 8.2 (multiphp)
+EOT
+fi
+
+if lxc-ls | grep -q php83 ; then
+ cat <> "${ldif_file}"
+
+dn: ServiceName=php-fpm83,${computer_dn}
+NagiosEnabled: TRUE
+ipServiceProtocol: tcp
+objectClass: EvoService
+ServiceName: php-fpm83
+ipServicePort: 443
+ServiceType: web
+ServiceVersion: PHP-FPM 8.3 (multiphp)
+EOT
+fi
+
fi
# END - LXC (multiphp)
@@ -735,6 +764,32 @@ ServiceVersion: Undefined
EOT
fi
+# Check pressure
+if [ "${debianVersion}" -ge 12 ]; then
+ cat <> "${ldif_file}"
+
+dn: ServiceName=pressure_cpu,${computer_dn}
+objectClass: EvoService
+NagiosEnabled: TRUE
+ServiceName: pressure_cpu
+ServiceType: pressure
+ServiceVersion: Undefined
+
+dn: ServiceName=pressure_io,${computer_dn}
+objectClass: EvoService
+NagiosEnabled: TRUE
+ServiceName: pressure_io
+ServiceType: pressure
+ServiceVersion: Undefined
+
+dn: ServiceName=pressure_mem,${computer_dn}
+objectClass: EvoService
+NagiosEnabled: TRUE
+ServiceName: pressure_mem
+ServiceType: pressure
+ServiceVersion: Undefined
+EOT
+fi
# test if we have a stdout
if [ -t 1 ]; then
diff --git a/kvm-host/defaults/main.yml b/kvm-host/defaults/main.yml
index 574c249f..9cbdd9a3 100644
--- a/kvm-host/defaults/main.yml
+++ b/kvm-host/defaults/main.yml
@@ -3,4 +3,11 @@ kvm_custom_libvirt_images_path: ''
kvm_install_drbd: True
kvm_scripts_dir: /usr/local/sbin
-kvm_pair: null
\ No newline at end of file
+kvm_pair: null
+
+# A "r|.*/|" is always added in order to make this an allowlist
+# Default = all sata/scsi disks + all nvme + all md (+partitions)
+lvm_filter:
+ - '"a|^/dev/sd[a-zA-Z]+[0-9]*$|"'
+ - '"a|^/dev/nvme[0-9]+(n[0-9]+)?(p[0-9]+)?$|"'
+ - '"a|^/dev/md[0-9]+$|"'
\ No newline at end of file
diff --git a/kvm-host/files/add-vm.sh b/kvm-host/files/add-vm.sh
index f945d401..2dbe0ff2 100755
--- a/kvm-host/files/add-vm.sh
+++ b/kvm-host/files/add-vm.sh
@@ -88,7 +88,7 @@ ${DIALOG} \
"memory" 2 1 "${defaultRAM}" 2 10 20 0 \
"volRoot" 3 1 "${disks[0]}-${defaultRootSize}" 3 10 20 0 \
"volHome" 4 1 "${disks[1]}-${defaultHomeSize}" 4 10 20 0 \
- "vmName" 5 1 "${defaultVmName}" 5 10 20 0 \
+ "vmName" 5 1 "${defaultVmName}" 5 10 20 1024 \
2> "${DIALOGOUT}"
vCPU=$(sed 1'q;d' "${DIALOGOUT}")
@@ -231,7 +231,7 @@ EOT
if ! isDryRun; then
sleep 5
- drbdadm status | tail -4
+ ( drbdadm status || drbd-overview ) 2>/dev/null | tail -4
drbdDiskPath="/dev/drbd/by-res/${vmName}/0"
if ! [ -b "${drbdDiskPath}" ]; then
diff --git a/kvm-host/files/kvmstats.sh b/kvm-host/files/kvmstats.sh
index 0258b322..d8e27b81 100755
--- a/kvm-host/files/kvmstats.sh
+++ b/kvm-host/files/kvmstats.sh
@@ -57,7 +57,7 @@ BEGIN {
if (!mem)
mem = $2
}
-/block\.[0-9]+\.physical/ {
+/block\.[0-9]+\.capacity/ {
disksize += $2
}
/state\.state/ {
diff --git a/kvm-host/handlers/main.yml b/kvm-host/handlers/main.yml
index 5ca5295a..963105f9 100644
--- a/kvm-host/handlers/main.yml
+++ b/kvm-host/handlers/main.yml
@@ -3,3 +3,11 @@
ansible.builtin.service:
name: munin-node
state: restarted
+
+- name: Update initramfs
+ ansible.builtin.command:
+ argv:
+ - '/usr/sbin/update-initramfs'
+ - '-k'
+ - 'all'
+ - '-u'
\ No newline at end of file
diff --git a/kvm-host/tasks/lvm.yml b/kvm-host/tasks/lvm.yml
new file mode 100644
index 00000000..41b12b2d
--- /dev/null
+++ b/kvm-host/tasks/lvm.yml
@@ -0,0 +1,37 @@
+---
+
+- name: 'Figure out if /etc/lvm/lvm.conf exists'
+ ansible.builtin.stat:
+ path: '/etc/lvm/lvm.conf'
+ follow: true
+ get_checksum: false
+ get_mime: false
+ get_attributes: false
+ ignore_errors: true
+ register: lvm_conf_stat
+
+- name: Add LVM filter
+ ansible.builtin.lineinfile:
+ path: '/etc/lvm/lvm.conf'
+ insertafter: '# Configuration option devices/filter.'
+ regexp: '^\s*(#\s*)?filter\s*=\s*\[.*\]'
+ line: " filter = [ {{ lvm_filter | list | join(', ') }}, \"r|.*/|\" ]"
+ state: present
+ firstmatch: true
+ notify: 'Update initramfs'
+ when:
+ - lvm_conf_stat is succeeded
+ - lvm_conf_stat.stat.exists | bool
+
+- name: Add LVM global_filter
+ ansible.builtin.lineinfile:
+ path: '/etc/lvm/lvm.conf'
+ insertafter: '# Configuration option devices/global_filter.'
+ regexp: '^\s*(#\s*)?global_filter\s*=\s*\[.*\]'
+ line: " global_filter = [ {{ lvm_filter | list | join(', ') }}, \"r|.*/|\" ]"
+ state: present
+ firstmatch: true
+ notify: 'Update initramfs'
+ when:
+ - lvm_conf_stat is succeeded
+ - lvm_conf_stat.stat.exists | bool
diff --git a/kvm-host/tasks/main.yml b/kvm-host/tasks/main.yml
index c6004b7b..7aa3bdc2 100644
--- a/kvm-host/tasks/main.yml
+++ b/kvm-host/tasks/main.yml
@@ -4,6 +4,8 @@
name: evolix/drbd
when: kvm_install_drbd
+- ansible.builtin.import_tasks: lvm.yml
+
## TODO: check why it's disabled
- ansible.builtin.include: ssh.yml
diff --git a/ldap/tasks/nagios.yml b/ldap/tasks/nagios.yml
index 58120baa..1fa17241 100644
--- a/ldap/tasks/nagios.yml
+++ b/ldap/tasks/nagios.yml
@@ -50,8 +50,8 @@
mode: "0640"
loop:
- { option: 'hostname', value: '127.0.0.1' }
- - { option: 'base', value: "{{ ldap_suffix }}" }
- - { option: 'bind', value: "cn=nagios,ou=ldapusers,{{ ldap_suffix }}" }
+ - { option: 'base', value: "{{ ldap_suffix | mandatory }}" }
+ - { option: 'bind', value: "cn=nagios,ou=ldapusers,{{ ldap_suffix | mandatory }}" }
- { option: 'pass', value: "{{ ldap_nagios_password }}" }
when: not nagios_monitoring_plugins_path.stat.exists
@@ -73,4 +73,4 @@
ansible.builtin.command:
cmd: "slappasswd -s {{ ldap_nagios_password }}"
register: ldap_nagios_password_ssha
- changed_when: False
\ No newline at end of file
+ changed_when: False
diff --git a/listupgrade/files/old-kernel-autoremoval.sh b/listupgrade/files/old-kernel-autoremoval.sh
index ce1c6002..6ad762e1 100644
--- a/listupgrade/files/old-kernel-autoremoval.sh
+++ b/listupgrade/files/old-kernel-autoremoval.sh
@@ -4,7 +4,7 @@
# fork by reg from /etc/kernel/postinst.d/apt-auto-removal script
-VERSION="21.10"
+VERSION="24.01"
readonly VERSION
PROGNAME=$(basename "$0")
@@ -13,7 +13,7 @@ show_version() {
cat <,
+Copyright 2018-2024 Evolix ,
Gregory Colpart ,
Romain Dessort ,
Ludovic Poujol ,
@@ -105,7 +105,7 @@ main() {
echo "BEFORE"
dpkg -l | grep linux-image
- dpkg --get-selections | tr '\t' ' ' | cut -d" " -f1 | grep '^linux-image-[234]' | grep -v -E "(${kernels})" | xargs --no-run-if-empty ${APT} -o Dir::State::Lists="${listupgrade_state_dir}" -y purge
+ dpkg --get-selections | tr '\t' ' ' | cut -d" " -f1 | grep '^linux-image-[0-9]' | grep -v -E "(${kernels})" | xargs --no-run-if-empty ${APT} -o Dir::State::Lists="${listupgrade_state_dir}" -y purge
echo "
AFTER"
diff --git a/listupgrade/tasks/main.yml b/listupgrade/tasks/main.yml
index 8207266e..9261b3fa 100644
--- a/listupgrade/tasks/main.yml
+++ b/listupgrade/tasks/main.yml
@@ -46,7 +46,7 @@
group: root
- name: Remove old lisupgrade typo
- cron:
+ ansible.builtin.cron:
name: "lisupgrade.sh"
cron_file: "listupgrade"
state: absent
diff --git a/lxc-php/defaults/main.yml b/lxc-php/defaults/main.yml
index c0612f4e..561a11f3 100644
--- a/lxc-php/defaults/main.yml
+++ b/lxc-php/defaults/main.yml
@@ -13,6 +13,7 @@ php_conf_mysql_socket_dir: /mysqld
php_conf_mysql_default_socket: "{{ php_conf_mysql_socket_dir }}/mysqld.sock"
lxc_php_version: Null
+lxc_php_container_name: "{{ lxc_php_version }}"
lxc_php_container_releases:
php56: "jessie"
@@ -22,6 +23,7 @@ lxc_php_container_releases:
php80: "bullseye"
php81: "bullseye"
php82: "bookworm"
+ php83: "bookworm"
lxc_php_services:
php56: 'php5-fpm.service'
@@ -31,6 +33,7 @@ lxc_php_services:
php80: 'php8.0-fpm.service'
php81: 'php8.1-fpm.service'
php82: 'php8.2-fpm.service'
+ php83: 'php8.3-fpm.service'
apt_keyring_dir: "{{ ansible_distribution_major_version is version('12', '<') | ternary('/etc/apt/trusted.gpg.d', '/etc/apt/keyrings') }}"
apt_basics_components: "{{ (ansible_virtualization_role == 'host') | ternary('main contrib non-free', 'main') }}"
diff --git a/lxc-php/files/munin_php-fpm b/lxc-php/files/munin_php-fpm
new file mode 100755
index 00000000..3647767d
--- /dev/null
+++ b/lxc-php/files/munin_php-fpm
@@ -0,0 +1,234 @@
+#!/usr/bin/php
+
+ 0,
+ 'memory' => 0,
+ 'cpu' => 0,
+ 'time' => 0
+ );
+ }
+
+ //add values
+ $groups[$groupName]['count']++;
+ $groups[$groupName]['cpu'] += $cpu;
+ $groups[$groupName]['time'] += timeToSeconds($time);
+ $groups[$groupName]['memory'] += $ram / 1024;
+}
+foreach ($php_inactive_pools_list as $line) {
+ //split fields
+ $line = trim($line);
+ $groupName = $line;
+ //add group
+ if (!isset($groups[$groupName])) {
+ $groups[$groupName] = array(
+ 'count' => 0,
+ 'memory' => 0,
+ 'cpu' => 0,
+ 'time' => 0
+ );
+ }
+}
+
+//check args
+if(!isset($argv) || !isset($argv[0])) {
+ die("Error: No Plugin name provided\n");
+}
+
+$isConfig = isset($argv[1]) && $argv[1] == 'config';
+
+//which plugin?
+switch ($plugin_output) {
+// ------------------------------------------------------
+ case 'memory':
+// ------------------------------------------------------
+ $elements = array();
+ foreach ($groups as $name=>$array) {
+ $ramMb = 0;
+ if($array['count'] !== 0){
+ $ramMb = $array['memory'] / $array['count'];
+ }
+ $label = 'Pool ' . $name;
+ $elements[$name] = array(
+ 'label' => $label,
+ 'type' => 'GAUGE',
+ 'value' => $ramMb
+ );
+ }
+ $config = array(
+ 'params' => array(
+ 'graph_title' => "$php_container PHP-FPM Average Process Memory",
+ 'graph_vlabel' => 'MB'
+ ),
+ 'elements' => $elements
+ );
+ break;
+// ------------------------------------------------------
+ case 'cpu':
+// ------------------------------------------------------
+ $elements = array();
+ foreach ($groups as $name=>$array) {
+ $cpu = $array['cpu'];
+ $label = 'Pool ' . $name;
+ $elements[$name] = array(
+ 'label' => $label,
+ 'type' => 'GAUGE',
+ 'value' => $cpu
+ );
+ }
+ $config = array(
+ 'params' => array(
+ 'graph_title' => "$php_container PHP-FPM CPU",
+ 'graph_vlabel' => '%',
+ 'graph_scale' => 'no'
+ ),
+ 'elements' => $elements
+ );
+ break;
+// ------------------------------------------------------
+ case 'count':
+// ------------------------------------------------------
+ $elements = array();
+ foreach ($groups as $name=>$array) {
+ $label = 'Pool ' . $name;
+ $elements[$name] = array(
+ 'label' => $label,
+ 'type' => 'GAUGE',
+ 'value' => $array['count']
+ );
+ }
+ $config = array(
+ 'params' => array(
+ 'graph_title' => "$php_container PHP-FPM Processes",
+ 'graph_vlabel' => 'processes'
+ ),
+ 'elements' => $elements
+ );
+ break;
+// ------------------------------------------------------
+ case 'time':
+// ------------------------------------------------------
+ $elements = array();
+ foreach ($groups as $name=>$array) {
+ $time=0;
+ if( $array['count'] !== 0){
+ $time = round($array['time'] / $array['count']);
+ }
+ $label = 'Pool ' . $name;
+ $elements[$name] = array(
+ 'label' => $label,
+ 'type' => 'GAUGE',
+ 'value' => $time
+ );
+ }
+ $config = array(
+ 'params' => array(
+ 'graph_title' => "$php_container PHP-FPM Average Process Age",
+ 'graph_vlabel' => 'seconds',
+ 'graph_scale' => 'no'
+ ),
+ 'elements' => $elements
+ );
+ break;
+// ------------------------------------------------------
+ default:
+ die("Error: Unrecognized Plugin output name $plugin_output\n");
+}
+
+//output
+ksort($config['elements']);
+if ($isConfig) {
+ //graph params
+ echo "graph_category $php_container PHP-FPM\n";
+ foreach($config['params'] as $key=>$value) {
+ echo $key . ' ' . $value . "\n";
+ }
+
+ //element params
+ foreach($config['elements'] as $element=>$data) {
+ foreach ($data as $key=>$value) {
+ if ($key == 'value') continue;
+ echo $element . '.' . $key . ' ' . $value . "\n";
+ }
+ }
+} else {
+ //element values
+ foreach ($config['elements'] as $pool=>$element) {
+ echo $pool . '.value ' . $element['value'] . "\n";
+ }
+}
+
+//functions
+function timeToSeconds ($time) {
+ $seconds = 0;
+
+ //days
+ $parts = explode('-', $time);
+ if(count($parts) == 2) {
+ $seconds += $parts[0] * 86400;
+ $time = $parts[1];
+ }
+
+ //hours
+ $parts = explode(':', $time);
+ if(count($parts) == 3) {
+ $seconds += array_shift($parts) * 3600;
+ }
+
+ //minutes/seconds
+ $seconds += $parts[0] * 60 + $parts[1];
+ return $seconds;
+}
diff --git a/lxc-php/handlers/main.yml b/lxc-php/handlers/main.yml
index b703933b..c1f58f92 100644
--- a/lxc-php/handlers/main.yml
+++ b/lxc-php/handlers/main.yml
@@ -10,6 +10,11 @@
name: "{{ lxc_php_version }}"
container_command: "systemctl restart {{ lxc_php_services[lxc_php_version] }}"
+- name: Reload php83-fpm
+ community.general.lxc_container:
+ name: "{{ lxc_php_version }}"
+ container_command: "systemctl reload php8.3-fpm"
+
- name: Reload php82-fpm
community.general.lxc_container:
name: "{{ lxc_php_version }}"
diff --git a/lxc-php/tasks/mail_opensmtpd.yml b/lxc-php/tasks/mail_opensmtpd.yml
index 35d0e75b..f532e8e8 100644
--- a/lxc-php/tasks/mail_opensmtpd.yml
+++ b/lxc-php/tasks/mail_opensmtpd.yml
@@ -1,11 +1,11 @@
---
-- name: "{{ lxc_php_version }} - Install opensmtpd"
+- name: "{{ lxc_php_container_name }} - Install opensmtpd"
community.general.lxc_container:
- name: "{{ lxc_php_version }}"
+ name: "{{ lxc_php_container_name }}"
container_command: "DEBIAN_FRONTEND=noninteractive apt install --no-install-recommends -y opensmtpd"
-- name: "{{ lxc_php_version }} - Configure opensmtpd (in the container)"
+- name: "{{ lxc_php_container_name }} - Configure opensmtpd (in the container)"
ansible.builtin.template:
src: smtpd.conf.j2
dest: "{{ lxc_rootfs }}/etc/smtpd.conf"
@@ -14,7 +14,7 @@
when: lxc_php_container_releases[lxc_php_version] in ["jessie", "stretch", "buster"]
-- name: "{{ lxc_php_version }} - Configure opensmtpd (in the container)"
+- name: "{{ lxc_php_container_name }} - Configure opensmtpd (in the container)"
ansible.builtin.template:
src: smtpd.conf.bullseye.j2
dest: "{{ lxc_rootfs }}/etc/smtpd.conf"
diff --git a/lxc-php/tasks/mail_ssmtp.yml b/lxc-php/tasks/mail_ssmtp.yml
index 07b54118..62066b2e 100644
--- a/lxc-php/tasks/mail_ssmtp.yml
+++ b/lxc-php/tasks/mail_ssmtp.yml
@@ -1,11 +1,11 @@
---
-- name: "{{ lxc_php_version }} - Install ssmtp"
+- name: "{{ lxc_php_container_name }} - Install ssmtp"
community.general.lxc_container:
- name: "{{ lxc_php_version }}"
+ name: "{{ lxc_php_container_name }}"
container_command: "DEBIAN_FRONTEND=noninteractive apt install --no-install-recommends --yes --force-yes ssmtp "
-- name: "{{ lxc_php_version }} - Configure ssmtp"
+- name: "{{ lxc_php_container_name }} - Configure ssmtp"
ansible.builtin.template:
src: ssmtp.conf.j2
dest: "{{ lxc_rootfs }}/etc/ssmtp/ssmtp.conf"
diff --git a/lxc-php/tasks/main.yml b/lxc-php/tasks/main.yml
index 035bfe15..770031fa 100644
--- a/lxc-php/tasks/main.yml
+++ b/lxc-php/tasks/main.yml
@@ -9,16 +9,16 @@
name: evolix/lxc
vars:
lxc_containers:
- - { name: "{{ lxc_php_version }}", release: "{{ lxc_php_container_releases[lxc_php_version] }}" }
+ - { name: "{{ lxc_php_container_name }}", release: "{{ lxc_php_container_releases[lxc_php_version] }}" }
when: lxc_php_version is defined
- name: set LXC rootfs
ansible.builtin.set_fact:
- lxc_rootfs: "/var/lib/lxc/{{ lxc_php_version }}/rootfs"
+ lxc_rootfs: "/var/lib/lxc/{{ lxc_php_container_name }}/rootfs"
-- name: "Update APT cache in container {{ lxc_php_version }}"
+- name: "Update APT cache in container {{ lxc_php_container_name }}"
community.general.lxc_container:
- name: "{{ lxc_php_version }}"
+ name: "{{ lxc_php_container_name }}"
container_command: "apt-get update"
- ansible.builtin.import_tasks: "php56.yml"
@@ -42,6 +42,9 @@
- ansible.builtin.import_tasks: "php82.yml"
when: lxc_php_version == "php82"
+- ansible.builtin.import_tasks: "php83.yml"
+ when: lxc_php_version == "php83"
+
- ansible.builtin.import_tasks: "umask.yml"
- ansible.builtin.import_tasks: "misc.yml"
diff --git a/lxc-php/tasks/misc.yml b/lxc-php/tasks/misc.yml
index 248aa8e2..7fc4575e 100644
--- a/lxc-php/tasks/misc.yml
+++ b/lxc-php/tasks/misc.yml
@@ -1,31 +1,31 @@
---
-- name: "{{ lxc_php_version }} - Configure timezone for the container"
+- name: "{{ lxc_php_container_name }} - Configure timezone for the container"
ansible.builtin.copy:
remote_src: yes
src: "/etc/timezone"
dest: "{{ lxc_rootfs }}/etc/timezone"
-- name: "{{ lxc_php_version }} - Ensure container's root directory is 755"
+- name: "{{ lxc_php_container_name }} - Ensure container's root directory is 755"
ansible.builtin.file:
path: "{{ lxc_rootfs }}"
state: directory
mode: '0755'
-- name: "{{ lxc_php_version }} - Configure mailname for the container"
+- name: "{{ lxc_php_container_name }} - Configure mailname for the container"
ansible.builtin.copy:
content: "{{ evolinux_hostname }}.{{ evolinux_domain }}\n"
dest: "{{ lxc_rootfs }}/etc/mailname"
notify: "Restart opensmtpd"
-- name: "{{ lxc_php_version }} - Install misc packages"
+- name: "{{ lxc_php_container_name }} - Install misc packages"
community.general.lxc_container:
- name: "{{ lxc_php_version }}"
+ name: "{{ lxc_php_container_name }}"
container_command: "DEBIAN_FRONTEND=noninteractive apt install -y cron logrotate git zip unzip"
-- name: "{{ lxc_php_version }} - Add MySQL socket to container default mounts"
+- name: "{{ lxc_php_container_name }} - Add MySQL socket to container default mounts"
community.general.lxc_container:
- name: "{{ lxc_php_version }}"
+ name: "{{ lxc_php_container_name }}"
container_config:
- "lxc.mount.entry = /run/mysqld {{ php_conf_mysql_socket_dir | replace('/', '', 1) }} none bind,create=dir 0 0"
when:
diff --git a/lxc-php/tasks/php73.yml b/lxc-php/tasks/php73.yml
index ade67b97..1335e8a1 100644
--- a/lxc-php/tasks/php73.yml
+++ b/lxc-php/tasks/php73.yml
@@ -1,11 +1,11 @@
---
-- name: "{{ lxc_php_version }} - Install PHP packages"
+- name: "{{ lxc_php_container_name }} - Install PHP packages"
community.general.lxc_container:
- name: "{{ lxc_php_version }}"
+ name: "{{ lxc_php_container_name }}"
container_command: "DEBIAN_FRONTEND=noninteractive apt install -y php-fpm php-cli php-gd php-intl php-imap php-ldap php-mysql php-pgsql php-sqlite3 php-gettext php-curl php-ssh2 php-zip php-mbstring php-zip composer libphp-phpmailer"
-- name: "{{ lxc_php_version }} - Copy evolinux PHP configuration"
+- name: "{{ lxc_php_container_name }} - Copy evolinux PHP configuration"
ansible.builtin.template:
src: z-evolinux-defaults.ini.j2
dest: "{{ line_item }}"
diff --git a/lxc-php/tasks/php83.yml b/lxc-php/tasks/php83.yml
new file mode 100644
index 00000000..80c33eb6
--- /dev/null
+++ b/lxc-php/tasks/php83.yml
@@ -0,0 +1,91 @@
+---
+
+- name: set APT keyring
+ ansible.builtin.set_fact:
+ lxc_apt_keyring_dir: /etc/apt/trusted.gpg.d
+
+- name: "{{ lxc_php_version }} - Install dependency packages"
+ community.general.lxc_container:
+ name: "{{ lxc_php_version }}"
+ container_command: "DEBIAN_FRONTEND=noninteractive apt install -y wget gnupg"
+
+- name: "{{ lxc_php_version }} - delete sources.list bookworm repository"
+ ansible.builtin.file:
+ path: "{{ lxc_rootfs }}/etc/apt/sources.list"
+ state: absent
+
+- name: "{{ lxc_php_version }} - system bookworm repository"
+ ansible.builtin.template:
+ src: bookworm_basics.sources.j2
+ dest: "{{ lxc_rootfs }}/etc/apt/sources.list.d/system.sources"
+ force: true
+ mode: "0644"
+
+- name: "{{ lxc_php_version }} - security bookworm repository"
+ ansible.builtin.template:
+ src: bookworm_security.sources.j2
+ dest: "{{ lxc_rootfs }}/etc/apt/sources.list.d/security.sources"
+ force: true
+ mode: "0644"
+
+- name: "{{ lxc_php_version }} - Add sury repo"
+ ansible.builtin.template:
+ src: sury.sources.j2
+ dest: "{{ lxc_rootfs }}/etc/apt/sources.list.d/sury.sources"
+ force: true
+ mode: "0644"
+
+- name: "{{ lxc_php_version }} - Add sury failsafe repo"
+ ansible.builtin.template:
+ src: evolix_sury.sources.j2
+ dest: "{{ lxc_rootfs }}/etc/apt/sources.list.d/evolix_sury.sources"
+ force: true
+ mode: "0644"
+
+- name: "Ensure {{ lxc_rootfs }}{{ lxc_apt_keyring_dir }} directory exists"
+ file:
+ path: "{{ lxc_rootfs }}{{ lxc_apt_keyring_dir }}"
+ state: directory
+ mode: "755"
+ owner: root
+ group: root
+
+- name: copy pub.evolix.org GPG key
+ ansible.builtin.copy:
+ src: pub_evolix.asc
+ dest: "{{ lxc_rootfs }}{{ lxc_apt_keyring_dir }}/pub_evolix.asc"
+ mode: "0644"
+ owner: root
+ group: root
+
+- name: copy packages.sury.org GPG Key
+ ansible.builtin.copy:
+ src: sury.gpg
+ dest: "{{ lxc_rootfs }}{{ lxc_apt_keyring_dir }}/sury.gpg"
+ mode: "0644"
+ owner: root
+ group: root
+
+- name: "{{ lxc_php_version }} - Update APT cache"
+ community.general.lxc_container:
+ name: "{{ lxc_php_version }}"
+ container_command: "DEBIAN_FRONTEND=noninteractive apt update"
+
+- name: "{{ lxc_php_version }} - Install PHP packages"
+ community.general.lxc_container:
+ name: "{{ lxc_php_version }}"
+ container_command: "DEBIAN_FRONTEND=noninteractive apt install -y php-fpm php-cli php-gd php-intl php-imap php-ldap php-mysql php-pgsql php-sqlite3 php-curl php-zip php-mbstring php-xml php-zip composer libphp-phpmailer"
+
+- name: "{{ lxc_php_version }} - Copy evolinux PHP configuration"
+ ansible.builtin.template:
+ src: z-evolinux-defaults.ini.j2
+ dest: "{{ line_item }}"
+ mode: "0644"
+ notify: "Reload {{ lxc_php_version }}-fpm"
+ loop:
+ - "{{ lxc_rootfs }}/etc/php/8.3/fpm/conf.d/z-evolinux-defaults.ini"
+ - "{{ lxc_rootfs }}/etc/php/8.3/cli/conf.d/z-evolinux-defaults.ini"
+ loop_control:
+ loop_var: line_item
+
+- ansible.builtin.include: "mail_opensmtpd.yml"
diff --git a/lxc-php/templates/bookworm_basics.sources.j2 b/lxc-php/templates/bookworm_basics.sources.j2
index 948c4adf..8599143d 100644
--- a/lxc-php/templates/bookworm_basics.sources.j2
+++ b/lxc-php/templates/bookworm_basics.sources.j2
@@ -2,7 +2,7 @@
Types: deb
URIs: http://mirror.evolix.org/debian
-Suites: bookworm bookworm-updates
+Suites: {{ lxc_php_container_releases[lxc_php_version] }} {{ lxc_php_container_releases[lxc_php_version] }}-updates
Components: {{ apt_basics_components | mandatory }}
Enabled: yes
Signed-By: /usr/share/keyrings/debian-archive-bookworm-automatic.gpg
diff --git a/lxc-php/templates/bookworm_security.sources.j2 b/lxc-php/templates/bookworm_security.sources.j2
index c98d5671..a3ccc581 100644
--- a/lxc-php/templates/bookworm_security.sources.j2
+++ b/lxc-php/templates/bookworm_security.sources.j2
@@ -2,7 +2,7 @@
Types: deb
URIs: https://security.debian.org/debian-security
-Suites: bookworm-security
+Suites: {{ lxc_php_container_releases[lxc_php_version] }}-security
Components: {{ apt_basics_components | mandatory }}
Enabled: yes
Signed-By: /usr/share/keyrings/debian-archive-bookworm-security-automatic.gpg
diff --git a/lxc-php/templates/evolix_sury.sources.j2 b/lxc-php/templates/evolix_sury.sources.j2
new file mode 100644
index 00000000..ee09a474
--- /dev/null
+++ b/lxc-php/templates/evolix_sury.sources.j2
@@ -0,0 +1,8 @@
+# {{ ansible_managed }}
+
+Types:deb
+URIs: http://pub.evolix.org/evolix
+Suites: {{ lxc_php_container_releases[lxc_php_version] }}-{{ lxc_php_version }}
+Components: main
+Signed-by: {{ apt_keyring_dir }}/pub_evolix.asc
+Enabled: yes
diff --git a/lxc-php/templates/sury.sources.j2 b/lxc-php/templates/sury.sources.j2
index 22725a58..2c17ef9d 100644
--- a/lxc-php/templates/sury.sources.j2
+++ b/lxc-php/templates/sury.sources.j2
@@ -2,7 +2,7 @@
Types: deb
URIs: https://packages.sury.org/php/
-Suites: {{ ansible_distribution_release }}
+Suites: {{ lxc_php_container_releases[lxc_php_version] }}
Components: main
Signed-by: {{ lxc_apt_keyring_dir }}/sury.gpg
-Enabled: yes
\ No newline at end of file
+Enabled: yes
diff --git a/lxc/tasks/create-container.yml b/lxc/tasks/create-container.yml
index 4d3851b6..45f7270b 100644
--- a/lxc/tasks/create-container.yml
+++ b/lxc/tasks/create-container.yml
@@ -58,13 +58,13 @@
name: "{{ name }}"
state: started
-- name: "Ensure /etc/profile.d exists in container"
+- name: "Ensure /etc/profile.d exists in container {{ name }}"
ansible.builtin.file:
path: "/var/lib/lxc/{{ name }}/rootfs/etc/profile.d"
mode: '0755'
state: directory
-- name: "Copy host /etc/profile.d/evolinux into container"
+- name: "Copy host /etc/profile.d/evolinux into container {{ name }}"
ansible.builtin.copy:
src: "/etc/profile.d/evolinux.sh"
remote_src: true
@@ -75,3 +75,22 @@
community.general.lxc_container:
name: "{{ name }}"
container_command: "DEBIAN_FRONTEND=noninteractive apt-get purge -y openssh-server"
+
+- name: "Init /etc git repository in container {{ name }}"
+ ansible.builtin.include_role:
+ name: 'etc-git'
+ tasks_from: 'repository.yml'
+ apply:
+ vars:
+ gitignore_items:
+ - "aliases.db"
+ - "*.swp"
+ - "postfix/sa-blacklist.access"
+ - "postfix/*.db"
+ - "postfix/spamd.cidr"
+ - "evobackup/.keep-*"
+ - "letsencrypt/.certbot.lock"
+ become: yes
+ loop: ["/var/lib/lxc/{{ name }}/rootfs/etc/"]
+ loop_control:
+ loop_var: 'repository_path'
diff --git a/minifirewall/defaults/main.yml b/minifirewall/defaults/main.yml
index 18d7d5b3..edb849b9 100644
--- a/minifirewall/defaults/main.yml
+++ b/minifirewall/defaults/main.yml
@@ -34,9 +34,9 @@ minifirewall_privilegied_ips: []
minifirewall_protected_ports_tcp: [22]
minifirewall_protected_ports_udp: []
-minifirewall_public_ports_tcp: [25, 53, 443, 993, 995, 22222]
-minifirewall_public_ports_udp: [53]
-minifirewall_semipublic_ports_tcp: [20, 21, 22, 80, 110, 143]
+minifirewall_public_ports_tcp: [22222]
+minifirewall_public_ports_udp: []
+minifirewall_semipublic_ports_tcp: [22, 80, 443]
minifirewall_semipublic_ports_udp: []
minifirewall_private_ports_tcp: [5666]
minifirewall_private_ports_udp: []
diff --git a/minifirewall/files/check_minifirewall b/minifirewall/files/check_minifirewall
index fc034de4..565a912d 100644
--- a/minifirewall/files/check_minifirewall
+++ b/minifirewall/files/check_minifirewall
@@ -87,7 +87,7 @@ main() {
append_details "configuration is up-to-date"
summary_ok "minifirewall is started and configuration is up-to-date"
else
- if echo "${check_result}" | grep --quiet --regexp 'usage'; then
+ if echo "${check_result}" | grep --ignore-case --quiet --regexp 'usage'; then
append_details "minifirewall is too old to check active configuration"
else
case "${check_rc}" in
diff --git a/mongodb/files/server-7.0.asc b/mongodb/files/server-7.0.asc
new file mode 100644
index 00000000..7f4911ae
--- /dev/null
+++ b/mongodb/files/server-7.0.asc
@@ -0,0 +1,30 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1
+
+mQINBGPILWABEACqeWP/ktugdlWEyk7YTXo3n19+5Om4AlSdIyKv49vAlKtzCfMA
+QkZq3mfvjXiKMuLnL2VeElAJQIYcPoqnHf6tJbdrNv4AX2uI1cTsvGW7YS/2WNwJ
+C/+vBa4o+yA2CG/MVWZRbtOjkFF/W07yRFtNHAcgdmpIjdWgSnPQr9eIqLuWXIhy
+H7EerKsba227Vd/HfvKnAy30Unlsdywy7wi1FupzGJck0TPoOVGmsSpSyIQu9A4Z
+uC6TE/NcJHvaN0JuHwM+bQo9oWirGsZ1NCoVqSY8/sasdUc7T9r90MbUcH674YAR
+8OKYVBzU0wch4VTFhfHZecKHQnZf+V4dmP9oXnu4fY0/0w3l4jaew7Ind7kPg3yN
+hvgAkBK8yRAbSu1NOtHDNiRoHGEQFgct6trVOvCqHbN/VToLNtGk0rhKGOp8kuSF
+OJ02PJPxF3/zHGP8n8khCjUJcrilYPqRghZC8ZWnCj6GJVg6WjwLi+hPwNMi8xK6
+cjKhRW3eCy5Wcn73PzVBX9f7fSeFDJec+IfS47eNkxunHAOUMXa2+D+1xSWgEfK0
+PClfyWPgLIXY2pGQ6v8l3A6P5gJv4o38/E1h1RTcO3H1Z6cgZLIORZHPyAj50SPQ
+cjzftEcz56Pl/Cyw3eMYC3qlbABBgsdeb6KB6G5dkNxI4or3MgmxcwfnkwARAQAB
+tDdNb25nb0RCIDcuMCBSZWxlYXNlIFNpZ25pbmcgS2V5IDxwYWNrYWdpbmdAbW9u
+Z29kYi5jb20+iQI+BBMBAgAoBQJjyC1gAhsDBQkJZgGABgsJCAcDAgYVCAIJCgsE
+FgIDAQIeAQIXgAAKCRAWDSa7F4W6OM+eD/sE7KbJyRNWyPCRTqqJXrXvyPqZtbFX
+8sio0lQ8ghn4f7lmb7LnFroUsmBeWaYirM8O3b2+iQ9oj4GeR3gbRZsEhFXQfL54
+SfrmG9hrWWpJllgPP7Six+jrzcjvkf1TENqw4jRP+cJhuihH1Gfizo9ktwwoN9Yr
+m7vgh+focEEmx8dysS38ApLxKlUEfTsE9bYsClgqyY1yrt3v4IpGbf66yfyBHNgY
+sObR3sngDRVbap7PwNyREGsuAFfKr/Dr37HfrjY7nsn3vH7hbDpSBh+H7a0b/chS
+mM60aaG4biWpvmSC7uxA/t0gz+NQuC4HL+qyNPUxvyIO+TwlaXfCI6ixazyrH+1t
+F7Bj5mVsne7oeWjRrSz85jK3Tpn9tj3Fa7PCDA6auAlPK8Upbhuoajev4lIydNd2
+70yO0idm/FtpX5a8Ck7KSHDvEnXpN70imayoB4Fs2Kigi2BdZOOdib16o5F/9cx9
+piNa7HotHCLTfR6xRmelGEPWKspU1Sm7u2A5vWgjfSab99hiNQ89n+I7BcK1M3R1
+w/ckl6qBtcxz4Py+7jYIJL8BYz2tdreWbdzWzjv+XQ8ZgOaMxhL9gtlfyYqeGfnp
+hYW8LV7a9pavxV2tLuVjMM+05ut/d38IkTV7OSJgisbSGcmycXIzxsipyXJVGMZt
+MFw3quqJhQMRsA==
+=gbRM
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/mysql/defaults/main.yml b/mysql/defaults/main.yml
index af43f495..871dd599 100644
--- a/mysql/defaults/main.yml
+++ b/mysql/defaults/main.yml
@@ -59,5 +59,5 @@ mysql_binlog_format: mixed
mysql_server_id: null
mysql_bind_address: null
mysql_repl_password: ''
-mysql_read_only: 0
+mysql_read_only: False
diff --git a/mysql/files/save_mysql_processlist.sh b/mysql/files/save_mysql_processlist.sh
index 95abc57d..e03036dd 100644
--- a/mysql/files/save_mysql_processlist.sh
+++ b/mysql/files/save_mysql_processlist.sh
@@ -7,7 +7,7 @@ processlist() {
}
DIR="/var/log/mysql-processlist"
-TS=`date +%Y%m%d%H%M%S`
+TS=$(date +%Y%m%d%H%M%S)
FILE="${DIR}/${TS}"
if [ ! -d "${DIR}" ]; then
diff --git a/mysql/tasks/config_jessie.yml b/mysql/tasks/config_jessie.yml
index 3d8c494d..364ee175 100644
--- a/mysql/tasks/config_jessie.yml
+++ b/mysql/tasks/config_jessie.yml
@@ -2,6 +2,7 @@
- ansible.builtin.set_fact:
mysql_config_directory: /etc/mysql/conf.d
+ mysql_performance_schema: False
- name: "Copy MySQL defaults config file (jessie)"
ansible.builtin.copy:
diff --git a/mysql/templates/evolinux-custom.cnf.j2 b/mysql/templates/evolinux-custom.cnf.j2
index 119943a1..cc66df94 100644
--- a/mysql/templates/evolinux-custom.cnf.j2
+++ b/mysql/templates/evolinux-custom.cnf.j2
@@ -38,7 +38,7 @@ lower_case_table_names = {{ mysql_lower_case_table_names }}
{% if mysql_innodb_log_file_size %}
innodb_log_file_size = {{ mysql_innodb_log_file_size }}
{% endif %}
-read_only = {{ mysql_read_only }}
+read_only = {{ mysql_read_only | bool | ternary('1','0') }}
{% if mysql_performance_schema %}
performance_schema = ON
performance-schema-instrument='stage/%=ON'
diff --git a/nagios-nrpe/defaults/main.yml b/nagios-nrpe/defaults/main.yml
index 28b85d99..c8695bc8 100644
--- a/nagios-nrpe/defaults/main.yml
+++ b/nagios-nrpe/defaults/main.yml
@@ -6,7 +6,21 @@ nagios_nrpe_pgsql_passwd: PGSQL_PASSWD
nagios_nrpe_amavis_from: "foobar@{{ ansible_domain }}"
nagios_nrpe_default_ntp_server: "pool.ntp.org"
nagios_nrpe_ntp_server: Null
-nagios_nrpe_process_processes: [ cron rsyslogd ntpd munin-node ]
+
+# Use nagios_nrpe_processes to override
+nagios_nrpe_processes_default_before_debian_12:
+ - cron
+ - rsyslogd
+ - ntpd
+ - munin-node
+nagios_nrpe_processes_default:
+ - cron
+ - rsyslogd
+ - systemd-timesyn
+ - munin-node
+
+# Built dynamically :
+nagios_nrpe_processes: Null
nagios_nrpe_force_update_allowed_hosts: False
diff --git a/nagios-nrpe/files/plugins/check_phpfpm_multi b/nagios-nrpe/files/plugins/check_phpfpm_multi
index b02fc7e2..e21ecf87 100644
--- a/nagios-nrpe/files/plugins/check_phpfpm_multi
+++ b/nagios-nrpe/files/plugins/check_phpfpm_multi
@@ -19,14 +19,21 @@ nb_ok=0
nb_unchk=0
output=""
-readonly POOL_FOLDER=${1:-$(detect_pool_dir)}
+# We want globbing to be expanded here
+# shellcheck disable=SC2206
+readonly POOL_FOLDER=( ${1:-$(detect_pool_dir)} )
-if [[ ! -d "$POOL_FOLDER" ]]; then
- echo "CRITICAL - $POOL_FOLDER does not exists"
+if [ "${#POOL_FOLDER[@]}" -gt 1 ]; then
+ echo "CRITICAL - '${POOL_FOLDER[*]}' contains more than one directories"
+ exit 2
+fi;
+
+if [[ ! -d "${POOL_FOLDER[0]}" ]]; then
+ echo "CRITICAL - ${POOL_FOLDER[0]} does not exists"
exit 2
fi;
-readonly POOL_FILES=$(find "$POOL_FOLDER" -name "*.conf")
+readonly POOL_FILES=$(find "${POOL_FOLDER[0]}" -name "*.conf")
for pool_file in $POOL_FILES; do
diff --git a/nagios-nrpe/files/plugins/check_sentinel b/nagios-nrpe/files/plugins/check_sentinel
new file mode 100755
index 00000000..a76e45e7
--- /dev/null
+++ b/nagios-nrpe/files/plugins/check_sentinel
@@ -0,0 +1,203 @@
+#!/bin/sh
+#
+# Verify the health of Redis instances using Redis Sentinel.
+#
+# Exemple output:
+# OK - 0 UNCHK / 0 CRIT / 0 WARN / 4 OK
+#
+# OK: Sentinels quorum reached / Active: 2 (quorum: 2)
+# OK: '10.11.24.217:6379' is a 'master' of 'redis'
+# OK: '10.11.24.227:6379' is a 'slave' of 'redis', in sync with '10.11.24.217'
+# OK: '10.11.24.208:6379' is a 'slave' of 'redis', in sync with '10.11.24.217'
+
+set -u
+
+usage() {
+ echo "Usage:"
+ echo " $0 -c "
+ exit 1
+}
+
+sentinel_config_file=
+while [ $# -gt 0 ]; do
+ case $1 in
+ -c)
+ sentinel_config_file="$2"
+ shift
+ shift
+ ;;
+ *)
+ echo "Invalid option: $1"
+ usage
+ ;;
+ esac
+done
+test -z "$sentinel_config_file" && usage
+
+# NRPE specific
+
+exit_code=0
+ok_count=0
+warn_count=0
+crit_count=0
+unchk_count=0
+
+output=$(mktemp --tmpdir $(basename "$0").XXXXXXXX)
+
+ok() {
+ message=$1
+ printf "OK: %s\n" "$message" >> "$output"
+ ok_count=$(( ok_count + 1))
+}
+
+warn() {
+ message=$1
+ printf "WARN: %s\n" "$message" >> "$output"
+ warn_count=$(( warn_count + 1))
+ [ "$exit_code" -lt 1 ] && exit_code=1
+}
+
+crit() {
+ message=$1
+ printf "CRIT: %s\n" "$message" >> "$output"
+ crit_count=$(( crit_count + 1))
+ [ "$exit_code" -lt 2 ] && exit_code=2
+}
+
+unchk() {
+ message=$1
+ printf "UNCHK: %s\n" "$message" >> "$output"
+ unchk_count=$(( unchk_count + 1))
+ [ "$exit_code" -lt 3 ] && exit_code=3
+ exit 1
+}
+
+nrpe_output() {
+ case "$exit_code" in
+ 0) output_header="OK" ;;
+ 1) output_header="WARNING" ;;
+ 2) output_header="CRITICAL" ;;
+ *) output_header="UNCHK" ;;
+ esac
+
+ printf "%s - %s UNCHK / %s CRIT / %s WARN / %s OK\n\n" \
+ "${output_header}" "${unchk_count}" "${crit_count}" "${warn_count}" "${ok_count}"
+
+ grep -E "^CRIT" "$output"
+ grep -E "^WARN" "$output"
+ grep -E "^UNCHK" "$output"
+ grep -E "^OK" "$output"
+
+ rm -f "$output"
+
+ exit "$exit_code"
+}
+trap nrpe_output EXIT
+
+# Redis specific
+
+test -r "$sentinel_config_file" || unchk "Can't read file '${sentinel_config_file}'"
+
+command -v redis-cli 1>/dev/null || unchk "Can't find executable 'redis-cli'"
+
+redis_cli_args=''
+sentinel_port=$(awk '/^port/{print $2}' "${sentinel_config_file}")
+! test -z "$sentinel_port" && redis_cli_args="${redis_cli_args} -p ${sentinel_port}"
+sentinel_pass=$(awk '/^requirepass/{print $2}' "${sentinel_config_file}")
+! test -z "$sentinel_pass" && redis_cli_args="${redis_cli_args} --pass ${sentinel_pass}"
+alias _redis-cli="redis-cli ${redis_cli_args}"
+
+# List all masters names known by sentinel
+redis_sentinel_masters() {
+ _redis-cli sentinel masters |
+ sed 'N;s/\n/=/' |
+ awk -F = '$1 ~ /^name$/ { print $2 }'
+}
+
+# Verify redis sentinel master
+check_master() {
+ master=$1
+ input=$(_redis-cli sentinel master "$master" | sed 'N;s/\n/=/')
+
+ for line in $input; do
+ case "$line" in
+ ip=*) ip=${line#ip=} ;;
+ port=*) port=${line#port=} ;;
+ flags=*) flags=${line#flags=} ;;
+ num-other-sentinels=*) num_sentinels=$(( ${line#num-other-sentinels=} + 1)) ;;
+ quorum=*) quorum=${line#quorum=} ;;
+ esac
+ done
+
+
+ if [ "$num_sentinels" -ge "$quorum" ]; then
+ ok "Sentinels quorum reached / Active: ${num_sentinels} (quorum: ${quorum})"
+ else
+ crit "No quorum of sentinels / Active: ${num_sentinels} (quorum: ${quorum})"
+ fi
+
+ if echo "$flags" | grep -q master; then
+ ok "'${ip}:${port}' is a '${flags}' of '${master}'"
+ else
+ crit "'${ip}:${port}' is not a 'master' of '${master}'"
+ fi
+
+ unset ip port flags status master_host
+}
+
+check_slaves_output() {
+ name=$1
+ flags=$2
+ status=$3
+ master_host=$4
+
+ if [ "$status" = ok ]; then
+ ok "'${name}' is a '${flags}' of '${master}', in sync with '${master_host}'"
+ else
+ crit "'${name}' is a '${flags}' of '${master}', not in sync"
+ fi
+}
+
+# Verify redis slaves are in sync with their master
+check_slaves() {
+ master=$1
+ input=$(_redis-cli sentinel slaves "$master" | sed 'N;s/\n/=/')
+
+ name=
+ flags=
+ status=
+ master_host=
+ for line in $input; do
+ case "$line" in
+ # "name" is the field begining a new record
+ name=*)
+ if [ -n "$name" ]; then
+ # output for all the slaves record, except the very last one
+ check_slaves_output "$name" "$flags" "$status" "$master_host"
+ unset name flags status master_host
+ fi
+ name=${line#name=}
+ ;;
+ flags=*) flags=${line#flags=} ;;
+ master-link-status=*) status=${line#master-link-status=} ;;
+ master-host=*) master_host=${line#master-host=} ;;
+ esac
+ done
+ # output for the last slave record in $input
+ check_slaves_output "$name" "$flags" "$status" "$master_host"
+ unset name flags status master_host
+}
+
+if ! systemctl is-active --quiet redis-sentinel.service; then
+ unchk "'redis-sentinel' process isn't running"
+else
+ masters=$(redis_sentinel_masters)
+ if [ -n "$masters" ]; then
+ for master in $masters; do
+ check_master "$master"
+ check_slaves "$master"
+ done
+ else
+ crit "No Redis master"
+ fi
+fi
diff --git a/nagios-nrpe/tasks/main.yml b/nagios-nrpe/tasks/main.yml
index 5d4c01aa..2a89da52 100644
--- a/nagios-nrpe/tasks/main.yml
+++ b/nagios-nrpe/tasks/main.yml
@@ -1,4 +1,10 @@
---
+
+- name:
+ ansible.builtin.set_fact:
+ nagios_nrpe_processes: "{{ ansible_distribution_major_version is version('12', '<') | ternary(nagios_nrpe_processes_default_before_debian_12, nagios_nrpe_processes_default) }}"
+ when: nagios_nrpe_processes == None or nagios_nrpe_processes | length <= 0
+
- name: base nrpe & plugins packages are installed
ansible.builtin.apt:
name:
diff --git a/nagios-nrpe/templates/evolix.cfg.j2 b/nagios-nrpe/templates/evolix.cfg.j2
index a7bcab7d..1f39bcff 100644
--- a/nagios-nrpe/templates/evolix.cfg.j2
+++ b/nagios-nrpe/templates/evolix.cfg.j2
@@ -46,9 +46,8 @@ command[check_tomcat-ajp13]=/usr/lib/nagios/plugins/check_tcp -p 8009
command[check_proxy]=/usr/lib/nagios/plugins/check_http -H {{ nagios_nrpe_check_proxy_host }}
command[check_redis]=/usr/lib/nagios/plugins/check_tcp -p 6379
command[check_clamd]=/usr/lib/nagios/plugins/check_clamd -H /var/run/clamav/clamd.ctl -v
-command[check_clamav_db]=/usr/lib/nagios/plugins/check_file_age -w 86400 -c 172800 -f /var/lib/clamav/evolix.ndb
+command[check_clamav_db]=/usr/lib/nagios/plugins/check_file_age -w 86400 -c 172800 -f /var/lib/clamav/daily.cld
command[check_ssl]=/usr/lib/nagios/plugins/check_http -f follow -I 127.0.0.1 -S -p 443 -H ssl.evolix.net -C 15,5
-command[check_ssl_local]={{ nagios_plugins_directory }}/check_ssl_local
command[check_elasticsearch]=/usr/lib/nagios/plugins/check_http -I 127.0.0.1 -u /_cat/health?h=st -p 9200 -r 'red' --invert-regex
command[check_memcached]=/usr/lib/nagios/plugins/check_tcp -H 127.0.0.1 -p 11211
command[check_opendkim]=/usr/lib/nagios/plugins/check_tcp -H 127.0.0.1 -p 8891
@@ -59,6 +58,9 @@ command[check_bkctld]=sudo /usr/sbin/bkctld check
command[check_postgrey]=/usr/lib/nagios/plugins/check_tcp -p10023
command[check_influxdb]=/usr/lib/nagios/plugins/check_http -I 127.0.0.1 -u /health -p 8086 -r '"status":"pass"'
command[check_dhcpd]=/usr/lib/nagios/plugins/check_procs -c1:1 -C dhcpd -t 60
+command[check_ipmi_sensors]=sudo /usr/lib/nagios/plugins/check_ipmi_sensor
+command[check_raid_status]=/usr/lib/nagios/plugins/check_raid
+command[check_dockerd]=/usr/lib/nagios/plugins/check_tcp -H /var/run/docker.sock --escape -s "GET /_ping HTTP/1.1\nHost: http\n\n" -e OK
# Local checks (not packaged)
command[check_mem]={{ nagios_plugins_directory }}/check_mem -f -C -w 20 -c 10
@@ -66,7 +68,7 @@ command[check_amavis]={{ nagios_plugins_directory }}/check_amavis --server 127.0
command[check_spamd]={{ nagios_plugins_directory }}/check_spamd -H 127.0.0.1
command[check_nfsclient]=sudo -u www-data {{ nagios_plugins_directory }}/check_nfsclient
command[check_evobackup]={{ nagios_plugins_directory }}/check_evobackup
-command[check_process]={{ nagios_plugins_directory }}/check_process {{ nagios_nrpe_process_processes | join(' ') }}
+command[check_process]={{ nagios_plugins_directory }}/check_process {{ nagios_nrpe_processes | join(' ') }}
command[check_drbd]={{ nagios_plugins_directory }}/check_drbd -d All -c StandAlone
command[check_mongodb_connect]={{ nagios_plugins_directory }}/check_mongodb -H localhost -P27017 -A connect
command[check_glusterfs]={{ nagios_plugins_directory }}/check_glusterfs -v all -n 0
@@ -75,6 +77,7 @@ command[check_varnish]={{ nagios_plugins_directory }}/check_varnish_health -i 12
command[check_haproxy]=sudo {{ nagios_plugins_directory }}/check_haproxy_stats -s /run/haproxy/admin.sock -w 80 -c 90 --ignore-maint --ignore-nolb --ignore-drain
command[check_minifirewall]=sudo {{ nagios_plugins_directory }}/check_minifirewall
command[check_redis_instances]={{ nagios_plugins_directory }}/check_redis_instances
+command[check_sentinel]=sudo {{ nagios_plugins_directory }}/check_sentinel -c /etc/redis/sentinel.conf
command[check_hpraid]={{ nagios_plugins_directory }}/check_hpraid
command[check_php-fpm]={{ nagios_plugins_directory }}/check_phpfpm_multi
command[check_php-fpm56]=sudo {{ nagios_plugins_directory }}/check_phpfpm_multi /var/lib/lxc/php56/rootfs/etc/php5/fpm/pool.d/
@@ -84,9 +87,12 @@ command[check_php-fpm74]=sudo {{ nagios_plugins_directory }}/check_phpfpm_multi
command[check_php-fpm80]=sudo {{ nagios_plugins_directory }}/check_phpfpm_multi /var/lib/lxc/php80/rootfs/etc/php/8.0/fpm/pool.d/
command[check_php-fpm81]=sudo {{ nagios_plugins_directory }}/check_phpfpm_multi /var/lib/lxc/php81/rootfs/etc/php/8.1/fpm/pool.d/
command[check_php-fpm82]=sudo {{ nagios_plugins_directory }}/check_phpfpm_multi /var/lib/lxc/php82/rootfs/etc/php/8.2/fpm/pool.d/
-command[check_ipmi_sensors]=sudo /usr/lib/nagios/plugins/check_ipmi_sensor
-command[check_raid_status]=/usr/lib/nagios/plugins/check_raid
+command[check_php-fpm83]=sudo {{ nagios_plugins_directory }}/check_phpfpm_multi /var/lib/lxc/php83/rootfs/etc/php/8.3/fpm/pool.d/
command[check_dhcp_pool]={{ nagios_plugins_directory }}/check_dhcp_pool
+command[check_ssl_local]={{ nagios_plugins_directory }}/check_ssl_local
+command[check_pressure_cpu]=/usr/lib/nagios/plugins/check_pressure --cpu -w 100000 -c 500000
+command[check_pressure_mem]=/usr/lib/nagios/plugins/check_pressure --mem -w 100000 -c 500000
+command[check_pressure_io]=/usr/lib/nagios/plugins/check_pressure --io -w 100000 -c 500000
# Check HTTP "many". Use this to check many websites (http, https, ports, sockets and SSL certificates).
# Beware! All checks must not take more than 10s!
diff --git a/nginx/tasks/ip_whitelist.yml b/nginx/tasks/ip_whitelist.yml
index fc4fd2d2..537e4a66 100644
--- a/nginx/tasks/ip_whitelist.yml
+++ b/nginx/tasks/ip_whitelist.yml
@@ -5,6 +5,7 @@
dest: /etc/nginx/snippets/ipaddr_whitelist
line: "allow {{ item }};"
state: present
+ create: yes
loop: "{{ nginx_ipaddr_whitelist_present }}"
notify: reload nginx
tags:
diff --git a/nginx/tasks/main.yml b/nginx/tasks/main.yml
index 1284a6a1..e8009804 100644
--- a/nginx/tasks/main.yml
+++ b/nginx/tasks/main.yml
@@ -20,18 +20,22 @@
- name: customize worker_connections
ansible.builtin.lineinfile:
dest: /etc/nginx/nginx.conf
- regexp: '^(\s*worker_connections)\s+.+;'
- line: ' worker_connections 1024;'
+ regexp: '^(\s*)worker_connections\s+.+;'
+ line: '\1worker_connections 1024;'
insertafter: 'events \{'
+ backrefs: yes
+ when: not ansible_check_mode
tags:
- nginx
- name: use epoll
ansible.builtin.lineinfile:
dest: /etc/nginx/nginx.conf
- regexp: '^(\s*use)\s+.+;'
- line: ' use epoll;'
+ regexp: '^(\s*)use\s+.+;'
+ line: '\1use epoll;'
insertafter: 'events \{'
+ backrefs: yes
+ when: not ansible_check_mode
tags:
- nginx
@@ -143,6 +147,7 @@
name: nginx
enabled: yes
state: started
+ when: not ansible_check_mode
tags:
- nginx
diff --git a/nginx/tasks/munin_vhost.yml b/nginx/tasks/munin_vhost.yml
index 98cc8672..2c9261f4 100644
--- a/nginx/tasks/munin_vhost.yml
+++ b/nginx/tasks/munin_vhost.yml
@@ -30,10 +30,14 @@
ansible.builtin.copy:
src: systemd/spawn-fcgi-munin-graph.service
dest: /etc/systemd/system/spawn-fcgi-munin-graph.service
+ force: yes
+# WARN: there is no (apparent) way to check if the service exists
+# so we disable this task in check mode.
- name: Systemd unit for Munin-fcgi is started
ansible.builtin.systemd:
name: spawn-fcgi-munin-graph
daemon_reload: yes
enabled: yes
state: started
+ when: not ansible_check_mode
diff --git a/nginx/tasks/server_status_read.yml b/nginx/tasks/server_status_read.yml
index d6cecbe3..eddc3fe8 100644
--- a/nginx/tasks/server_status_read.yml
+++ b/nginx/tasks/server_status_read.yml
@@ -18,20 +18,27 @@
- name: generate random string for server-status suffix
ansible.builtin.shell:
- cmd: "apg -a 1 -M N -n 1 > {{ nginx_serverstatus_suffix_file }}"
- args:
+ cmd: "apg -a 1 -M N -n 1 | tee {{ nginx_serverstatus_suffix_file }}"
creates: "{{ nginx_serverstatus_suffix_file }}"
+ register: generated_nginx_serverstatus_suffix
+
+- name: check if nginx suffix file exists
+ ansible.builtin.stat:
+ path: "{{ nginx_serverstatus_suffix_file }}"
+ register: nginx_serverstatus_suffix_file_check
- name: read nginx server status suffix
ansible.builtin.command:
cmd: "tail -n 1 {{ nginx_serverstatus_suffix_file }}"
changed_when: False
check_mode: no
- register: new_nginx_serverstatus_suffix
+ when: nginx_serverstatus_suffix_file_check.stat.exists
+ register: read_nginx_serverstatus_suffix
+# If the file exists and the read value is not empty, then use it, otherwhise use the generated value
- name: overwrite nginx_serverstatus_suffix
ansible.builtin.set_fact:
- nginx_serverstatus_suffix: "{{ new_nginx_serverstatus_suffix.stdout }}"
+ nginx_serverstatus_suffix: "{{ (nginx_serverstatus_suffix_file_check.stat.exists and (read_nginx_serverstatus_suffix.stdout | length > 0)) | ternary(read_nginx_serverstatus_suffix.stdout, generated_nginx_serverstatus_suffix.stdout) }}"
- ansible.builtin.debug:
var: nginx_serverstatus_suffix
diff --git a/nginx/tasks/server_status_write.yml b/nginx/tasks/server_status_write.yml
index dbed56cb..08031635 100644
--- a/nginx/tasks/server_status_write.yml
+++ b/nginx/tasks/server_status_write.yml
@@ -17,4 +17,5 @@
dest: /etc/nginx/sites-available/evolinux-default.conf
regexp: 'location /server-status-? {'
replace: 'location /server-status-{{ nginx_serverstatus_suffix }} {'
+ when: not ansible_check_mode
notify: reload nginx
diff --git a/php/files/munin_php-fpm b/php/files/munin_php-fpm
new file mode 100755
index 00000000..3647767d
--- /dev/null
+++ b/php/files/munin_php-fpm
@@ -0,0 +1,234 @@
+#!/usr/bin/php
+
+ 0,
+ 'memory' => 0,
+ 'cpu' => 0,
+ 'time' => 0
+ );
+ }
+
+ //add values
+ $groups[$groupName]['count']++;
+ $groups[$groupName]['cpu'] += $cpu;
+ $groups[$groupName]['time'] += timeToSeconds($time);
+ $groups[$groupName]['memory'] += $ram / 1024;
+}
+foreach ($php_inactive_pools_list as $line) {
+ //split fields
+ $line = trim($line);
+ $groupName = $line;
+ //add group
+ if (!isset($groups[$groupName])) {
+ $groups[$groupName] = array(
+ 'count' => 0,
+ 'memory' => 0,
+ 'cpu' => 0,
+ 'time' => 0
+ );
+ }
+}
+
+//check args
+if(!isset($argv) || !isset($argv[0])) {
+ die("Error: No Plugin name provided\n");
+}
+
+$isConfig = isset($argv[1]) && $argv[1] == 'config';
+
+//which plugin?
+switch ($plugin_output) {
+// ------------------------------------------------------
+ case 'memory':
+// ------------------------------------------------------
+ $elements = array();
+ foreach ($groups as $name=>$array) {
+ $ramMb = 0;
+ if($array['count'] !== 0){
+ $ramMb = $array['memory'] / $array['count'];
+ }
+ $label = 'Pool ' . $name;
+ $elements[$name] = array(
+ 'label' => $label,
+ 'type' => 'GAUGE',
+ 'value' => $ramMb
+ );
+ }
+ $config = array(
+ 'params' => array(
+ 'graph_title' => "$php_container PHP-FPM Average Process Memory",
+ 'graph_vlabel' => 'MB'
+ ),
+ 'elements' => $elements
+ );
+ break;
+// ------------------------------------------------------
+ case 'cpu':
+// ------------------------------------------------------
+ $elements = array();
+ foreach ($groups as $name=>$array) {
+ $cpu = $array['cpu'];
+ $label = 'Pool ' . $name;
+ $elements[$name] = array(
+ 'label' => $label,
+ 'type' => 'GAUGE',
+ 'value' => $cpu
+ );
+ }
+ $config = array(
+ 'params' => array(
+ 'graph_title' => "$php_container PHP-FPM CPU",
+ 'graph_vlabel' => '%',
+ 'graph_scale' => 'no'
+ ),
+ 'elements' => $elements
+ );
+ break;
+// ------------------------------------------------------
+ case 'count':
+// ------------------------------------------------------
+ $elements = array();
+ foreach ($groups as $name=>$array) {
+ $label = 'Pool ' . $name;
+ $elements[$name] = array(
+ 'label' => $label,
+ 'type' => 'GAUGE',
+ 'value' => $array['count']
+ );
+ }
+ $config = array(
+ 'params' => array(
+ 'graph_title' => "$php_container PHP-FPM Processes",
+ 'graph_vlabel' => 'processes'
+ ),
+ 'elements' => $elements
+ );
+ break;
+// ------------------------------------------------------
+ case 'time':
+// ------------------------------------------------------
+ $elements = array();
+ foreach ($groups as $name=>$array) {
+ $time=0;
+ if( $array['count'] !== 0){
+ $time = round($array['time'] / $array['count']);
+ }
+ $label = 'Pool ' . $name;
+ $elements[$name] = array(
+ 'label' => $label,
+ 'type' => 'GAUGE',
+ 'value' => $time
+ );
+ }
+ $config = array(
+ 'params' => array(
+ 'graph_title' => "$php_container PHP-FPM Average Process Age",
+ 'graph_vlabel' => 'seconds',
+ 'graph_scale' => 'no'
+ ),
+ 'elements' => $elements
+ );
+ break;
+// ------------------------------------------------------
+ default:
+ die("Error: Unrecognized Plugin output name $plugin_output\n");
+}
+
+//output
+ksort($config['elements']);
+if ($isConfig) {
+ //graph params
+ echo "graph_category $php_container PHP-FPM\n";
+ foreach($config['params'] as $key=>$value) {
+ echo $key . ' ' . $value . "\n";
+ }
+
+ //element params
+ foreach($config['elements'] as $element=>$data) {
+ foreach ($data as $key=>$value) {
+ if ($key == 'value') continue;
+ echo $element . '.' . $key . ' ' . $value . "\n";
+ }
+ }
+} else {
+ //element values
+ foreach ($config['elements'] as $pool=>$element) {
+ echo $pool . '.value ' . $element['value'] . "\n";
+ }
+}
+
+//functions
+function timeToSeconds ($time) {
+ $seconds = 0;
+
+ //days
+ $parts = explode('-', $time);
+ if(count($parts) == 2) {
+ $seconds += $parts[0] * 86400;
+ $time = $parts[1];
+ }
+
+ //hours
+ $parts = explode(':', $time);
+ if(count($parts) == 3) {
+ $seconds += array_shift($parts) * 3600;
+ }
+
+ //minutes/seconds
+ $seconds += $parts[0] * 60 + $parts[1];
+ return $seconds;
+}
diff --git a/php/files/sury.preferences b/php/files/sury.preferences
deleted file mode 100644
index adcc5918..00000000
--- a/php/files/sury.preferences
+++ /dev/null
@@ -1,7 +0,0 @@
-Package: php* libapache2-mod-php* libpcre2* libzip4* libgd* libpcre3*
-Pin: origin packages.sury.org
-Pin-Priority: 999
-
-Package: *
-Pin: origin packages.sury.org
-Pin-Priority: 50
diff --git a/php/handlers/main.yml b/php/handlers/main.yml
index b333fe9b..d2b96b99 100644
--- a/php/handlers/main.yml
+++ b/php/handlers/main.yml
@@ -34,3 +34,8 @@
ansible.builtin.service:
name: php8.2-fpm
state: restarted
+
+- name: restart php8.3-fpm
+ ansible.builtin.service:
+ name: php8.3-fpm
+ state: restarted
diff --git a/php/tasks/sury_pre.yml b/php/tasks/sury_pre.yml
index d38efe13..599f9425 100644
--- a/php/tasks/sury_pre.yml
+++ b/php/tasks/sury_pre.yml
@@ -24,18 +24,9 @@
- name: Setup pub.evolix.org repository - Add source list
ansible.builtin.apt_repository:
- repo: "deb [signed-by={{ apt_keyring_dir }}/pub_evolix.asc] http://pub.evolix.org/evolix {{ ansible_distribution_release }}-php81 main"
+ repo: "deb [signed-by={{ apt_keyring_dir }}/pub_evolix.asc] http://pub.evolix.org/evolix {{ ansible_distribution_release }}-php{{ php_version | replace('.', '')}} main"
filename: evolix-php
state: present
- when:
- - ansible_distribution_release == "bullseye"
-
-- name: Setup deb.sury.org repository - Add preferences file
- ansible.builtin.copy:
- src: sury.preferences
- dest: /etc/apt/preferences.d/z-sury
- when:
- - ansible_distribution_release != "bullseye"
- name: Setup deb.sury.org repository - Add GPG key
ansible.builtin.copy:
diff --git a/postfix/defaults/main.yml b/postfix/defaults/main.yml
index 55ab72cd..53ae5360 100644
--- a/postfix/defaults/main.yml
+++ b/postfix/defaults/main.yml
@@ -1,5 +1,7 @@
---
-postfix_hostname: "{{ ansible_fqdn }}"
+postfix_hostname: "{{ evolinux_fqdn }}"
postfix_force_main_cf: False
postfix_packmail: False
-postfix_slow_transport_include: "{{ postfix_packmail }}"
+postfix_slow_transport_include: False
+postfix_purge_exim: True
+
diff --git a/postfix/tasks/common.yml b/postfix/tasks/common.yml
index 29e6dd07..b2a09398 100644
--- a/postfix/tasks/common.yml
+++ b/postfix/tasks/common.yml
@@ -1,11 +1,32 @@
----
-- name: check if main.cf is default
+- name: Postfix packages are installed
+ ansible.builtin.apt:
+ name:
+ - postfix
+ - mailgraph
+ state: present
+ tags:
+ - postfix
+
+- name: exim4 is absent
+ ansible.builtin.apt:
+ name:
+ - exim4
+ - exim4-base
+ - exim4-config
+ - exim4-daemon-light
+ purge: yes
+ state: absent
+ tags:
+ - postfix
+ when: postfix_purge_exim | bool
+
+- name: compute main.cf SHA1 checksum
ansible.builtin.shell:
- cmd: 'grep -v -E "^(myhostname|mydestination|mailbox_command)" /etc/postfix/main.cf | md5sum -'
+ cmd: 'grep -v -E "^(myhostname|mydestination|mailbox_command)" /etc/postfix/main.cf | sha1sum | cut -d " " -f1'
changed_when: False
check_mode: no
- register: default_main_cf
+ register: main_cf_checksum
tags:
- postfix
diff --git a/postfix/tasks/minimal.yml b/postfix/tasks/minimal.yml
index 36327b3e..b7bd29d0 100644
--- a/postfix/tasks/minimal.yml
+++ b/postfix/tasks/minimal.yml
@@ -1,10 +1,8 @@
---
-- name: ensure packages are installed
- ansible.builtin.apt:
- name: postfix
- state: present
- tags:
- - postfix
+
+- name: display checksums of known main.cf files
+ debug:
+ var: main_cf_known_checksums
- name: create minimal main.cf
ansible.builtin.template:
@@ -15,6 +13,6 @@
mode: "0644"
force: true
notify: restart postfix
- when: (postfix_force_main_cf | bool) or (postfix_maincf_md5_jessie in default_main_cf.stdout) or (postfix_maincf_md5_stretch in default_main_cf.stdout)
+ when: (postfix_force_main_cf | bool) or (main_cf_checksum.stdout in main_cf_known_checksums)
tags:
- postfix
diff --git a/postfix/tasks/packmail-spam.yml b/postfix/tasks/packmail-spam.yml
index 114be769..f90f8cae 100644
--- a/postfix/tasks/packmail-spam.yml
+++ b/postfix/tasks/packmail-spam.yml
@@ -1,8 +1,6 @@
---
-- name: "mount /usr in rw"
- ansible.builtin.command:
- cmd: 'mount -o remount,rw /usr'
- changed_when: False
+- ansible.builtin.include_role:
+ name: evolix/remount-usr
tags: postfix
- name: copy spam.sh script
diff --git a/postfix/tasks/packmail.yml b/postfix/tasks/packmail.yml
index 6562e0d3..692024fa 100644
--- a/postfix/tasks/packmail.yml
+++ b/postfix/tasks/packmail.yml
@@ -1,11 +1,9 @@
---
-- name: ensure packages are installed
+- name: Complementary packmail packages are installed
ansible.builtin.apt:
name:
- - postfix
- postfix-ldap
- postfix-policyd-spf-python
- - mailgraph
state: present
tags:
- postfix
@@ -24,6 +22,10 @@
enabled: yes
state: started
+- name: display checksums of known main.cf files
+ debug:
+ var: main_cf_known_checksums
+
- name: create packmail main.cf
ansible.builtin.template:
src: packmail_main.cf.j2
@@ -33,7 +35,7 @@
mode: "0644"
force: true
notify: restart postfix
- when: (postfix_force_main_cf | bool) or (postfix_maincf_md5_jessie in default_main_cf.stdout) or (postfix_maincf_md5_stretch in default_main_cf.stdout)
+ when: (postfix_force_main_cf | bool) or (main_cf_checksum.stdout in main_cf_known_checksums)
tags:
- postfix
diff --git a/postfix/templates/packmail_main.cf.j2 b/postfix/templates/packmail_main.cf.j2
index 65c95866..4bcbb2dd 100644
--- a/postfix/templates/packmail_main.cf.j2
+++ b/postfix/templates/packmail_main.cf.j2
@@ -66,7 +66,7 @@ smtpd_banner = $myhostname ESMTP mail server
# Indique le nom d'hote pleinement qualifie ou se trouve postfix [OBLIGATOIRE]
#par defaut, = [retour de la commande Unix hostname]
-myhostname = {{ ansible_fqdn }}
+myhostname = {{ postfix_hostname }}
# Variable indiquant le domaine dans lequel se trouve la machine
#par defaut, = [partie domain de la variable $myhostname]
diff --git a/postfix/vars/main.yml b/postfix/vars/main.yml
index e8a773c9..8d612f2e 100644
--- a/postfix/vars/main.yml
+++ b/postfix/vars/main.yml
@@ -1,5 +1,9 @@
---
-## MD5 hash of default main.cf filter, obtained with this command :
-# grep -v -E "^(myhostname|mydestination|mailbox_command)" /etc/postfix/main.cf | md5sum -
-postfix_maincf_md5_jessie: "5450c05d65878e99dad696c7c722e511"
-postfix_maincf_md5_stretch: "30022953f1f61f002bfb72e163ecb27e"
+# Output of default main.cf:
+# grep -v -E "^(myhostname|mydestination|mailbox_command)" /etc/postfix/main.cf | sha1sum | cut -d " " -f1
+main_cf_known_checksums:
+ - 72bd6999f053ea89b359e233cf252616ee6e2fbb # bookworm
+ - efd078215285ad520addee5b11af869717627b95 # bullseye
+ - c7d1e008120565927b213be1bf646fddfa949dc6 # buster
+ - 8b4de47321a9c003bf414a683c0d056b4469b325 # stretch
+ - f72feb50754830a7d8ae46f28e86d758881bcfc3 # jessie
diff --git a/proftpd/defaults/main.yml b/proftpd/defaults/main.yml
index 25d60d5b..0bcaa40f 100644
--- a/proftpd/defaults/main.yml
+++ b/proftpd/defaults/main.yml
@@ -1,7 +1,7 @@
---
proftpd_hostname: "{{ ansible_hostname }}"
proftpd_fqdn: "{{ ansible_fqdn }}"
-proftpd_default_address: []
+proftpd_default_address: ["0.0.0.0"]
proftpd_ftp_enable: True
proftpd_ftp_override: False
proftpd_port: 21
@@ -12,7 +12,7 @@ proftpd_ftps_cert: "/etc/ssl/certs/ssl-cert-snakeoil.pem"
proftpd_ftps_key: "/etc/ssl/private/ssl-cert-snakeoil.key"
proftpd_sftp_enable: False
proftpd_sftp_override: False
-proftpd_sftp_use_publickeys: False
+proftpd_sftp_use_publickeys: True
proftpd_sftp_port: 22222
proftpd_accounts: []
proftpd_accounts_final: []
diff --git a/proftpd/tasks/accounts.yml b/proftpd/tasks/accounts.yml
index 99b036c9..fc97b55b 100644
--- a/proftpd/tasks/accounts.yml
+++ b/proftpd/tasks/accounts.yml
@@ -73,5 +73,6 @@
when:
- proftpd_sftp_enable | bool
- proftpd_sftp_use_publickeys | bool
+ - _proftpd_account.sshkeys is defined
tags:
- proftpd
diff --git a/proftpd/templates/sftp.conf.j2 b/proftpd/templates/sftp.conf.j2
index 457f638b..e70aa71c 100644
--- a/proftpd/templates/sftp.conf.j2
+++ b/proftpd/templates/sftp.conf.j2
@@ -27,6 +27,9 @@
SFTPHostKey /etc/ssh/ssh_host_ecdsa_key
SFTPHostKey /etc/ssh/ssh_host_rsa_key
+ {% if ansible_distribution_major_version is version('11', '>=') %}
+ SFTPHostKey /etc/ssh/ssh_host_ed25519_key
+ {% endif %}
RequireValidShell off
diff --git a/redis/defaults/main.yml b/redis/defaults/main.yml
index b5547597..dc5a5d06 100644
--- a/redis/defaults/main.yml
+++ b/redis/defaults/main.yml
@@ -3,6 +3,8 @@ redis_systemd_name: redis-server
redis_conf_dir_prefix: /etc/redis
+redis_conf_marker_label: "ANSIBLE MANAGED CONFIGURATION"
+
redis_force_instance_port: False
redis_port: 6379
diff --git a/redis/tasks/default-server.yml b/redis/tasks/default-server.yml
index 89a664e6..89ba641e 100644
--- a/redis/tasks/default-server.yml
+++ b/redis/tasks/default-server.yml
@@ -1,12 +1,32 @@
---
-- name: Redis is configured.
- ansible.builtin.template:
- src: redis.conf.j2
- dest: "{{ redis_conf_dir }}/redis.conf"
+- name: "Add begin marker if missing"
+ ansible.builtin.lineinfile:
+ path: "{{ redis_conf_dir }}/redis.conf"
+ line: "# BEGIN {{ redis_conf_marker_label }}"
+ insertbefore: BOF
+ create: yes
+ tags:
+ - redis
+
+- name: "Add end marker if missing"
+ ansible.builtin.lineinfile:
+ path: "{{ redis_conf_dir }}/redis.conf"
+ line: "# END {{ redis_conf_marker_label }}"
+ insertbefore: "Generated by CONFIG REWRITE"
+ create: yes
+ tags:
+ - redis
+
+- name: "Create config if missing"
+ ansible.builtin.blockinfile:
+ path: "{{ redis_conf_dir }}/redis.conf"
+ marker: "# {mark} {{ redis_conf_marker_label }}"
+ block: "{{ lookup('ansible.builtin.template', '../templates/redis.conf.j2') }}"
mode: "0640"
owner: redis
group: redis
+ create: yes
notify: "{{ redis_restart_handler_name }}"
tags:
- redis
diff --git a/redis/tasks/instance-server.yml b/redis/tasks/instance-server.yml
index 42dc1876..b5f11053 100644
--- a/redis/tasks/instance-server.yml
+++ b/redis/tasks/instance-server.yml
@@ -118,14 +118,33 @@
tags:
- redis
+- name: "Add begin marker if missing"
+ ansible.builtin.lineinfile:
+ path: "{{ redis_conf_dir }}/redis.conf"
+ line: "# BEGIN {{ redis_conf_marker_label }}"
+ insertbefore: BOF
+ create: yes
+ tags:
+ - redis
-- name: "Instance '{{ redis_instance_name }}' configuration file is present"
- ansible.builtin.template:
- src: redis.conf.j2
- dest: "{{ redis_conf_dir }}/redis.conf"
+- name: "Add end marker if missing"
+ ansible.builtin.lineinfile:
+ path: "{{ redis_conf_dir }}/redis.conf"
+ line: "# END {{ redis_conf_marker_label }}"
+ insertbefore: "# Generated by CONFIG REWRITE"
+ create: yes
+ tags:
+ - redis
+
+- name: "Create config if missing"
+ ansible.builtin.blockinfile:
+ path: "{{ redis_conf_dir }}/redis.conf"
+ marker: "# {mark} {{ redis_conf_marker_label }}"
+ block: "{{ lookup('ansible.builtin.template', '../templates/redis.conf.j2') }}"
mode: "0640"
owner: redis-{{ redis_instance_name }}
group: redis-{{ redis_instance_name }}
+ create: yes
notify: "{{ redis_restart_handler_name }}"
tags:
- redis
diff --git a/remount-usr/tasks/main.yml b/remount-usr/tasks/main.yml
index eb5c0109..034a66f5 100644
--- a/remount-usr/tasks/main.yml
+++ b/remount-usr/tasks/main.yml
@@ -1,17 +1,18 @@
---
# findmnt returns 0 on hit, 1 on miss
# If the return code is higher than 1, it's a blocking failure
+
- name: "check if /usr is a read-only partition"
ansible.builtin.command:
cmd: 'findmnt /usr --noheadings --options ro'
changed_when: False
failed_when: usr_partition.rc > 1
- check_mode: no
register: usr_partition
+ check_mode: False
- name: "mount /usr in rw"
ansible.builtin.command:
- cmd: 'mount -o remount,rw /usr'
- changed_when: False
+ cmd: 'mount --options remount,rw /usr'
when: usr_partition.rc == 0
notify: remount usr
+ changed_when: False
diff --git a/spamassasin/handlers/main.yml b/spamassasin/handlers/main.yml
index 78597a37..7dbc9c7f 100644
--- a/spamassasin/handlers/main.yml
+++ b/spamassasin/handlers/main.yml
@@ -3,3 +3,8 @@
ansible.builtin.service:
name: spamassassin
state: restarted
+
+- name: restart spamd
+ ansible.builtin.service:
+ name: spamd
+ state: restarted
diff --git a/spamassasin/tasks/main.yml b/spamassasin/tasks/main.yml
index 9f2889ca..0ee6f76a 100644
--- a/spamassasin/tasks/main.yml
+++ b/spamassasin/tasks/main.yml
@@ -1,29 +1,47 @@
---
-- name: install SpamAssasin
+
+- name: For Debian < 12
+ set_fact:
+ spamassassin_restart_handler: restart spamassassin
+ spamassassin_package_name: spamassassin
+ tags:
+ - spamassassin
+ when: ansible_distribution_major_version is version('12', '<')
+
+# the package is called "spamd" after Debian 12
+- name: For Debian >= 12
+ set_fact:
+ spamassassin_restart_handler: restart spamd
+ spamassassin_package_name: spamd
+ tags:
+ - spamassassin
+ when: ansible_distribution_major_version is version('12', '>=')
+
+- name: Install SpamAssassin
ansible.builtin.apt:
name:
- - spamassassin
+ - "{{ spamassassin_package_name }}"
state: present
tags:
- spamassassin
-- name: configure SpamAssasin
+- name: Configure SpamAssassin
ansible.builtin.copy:
src: spamassassin.cf
dest: /etc/spamassassin/local_evolix.cf
mode: "0644"
- notify: restart spamassassin
+ notify: "{{ spamassassin_restart_handler }}"
tags:
- spamassassin
-- name: enable SpamAssasin
+- name: Enable SpamAssassin
ansible.builtin.replace:
dest: /etc/default/spamassassin
regexp: 'ENABLED=0'
replace: 'ENABLED=1'
- notify: restart spamassassin
tags:
- spamassassin
+ when: ansible_distribution_major_version is version('12', '<')
- name: add amavis user to debian-spamd group
ansible.builtin.user:
@@ -97,5 +115,15 @@
name: spamassassin
state: started
enabled: True
+ when: ansible_distribution_major_version is version('12', '<')
+ tags:
+ - spamassassin
+
+- name: ensure spamd is started and enabled
+ ansible.builtin.systemd:
+ name: spamd
+ state: started
+ enabled: True
+ when: ansible_distribution_major_version is version('12', '>=')
tags:
- spamassassin
diff --git a/squid/README.md b/squid/README.md
index 8811a91f..aba25b4d 100644
--- a/squid/README.md
+++ b/squid/README.md
@@ -6,7 +6,7 @@ Installation and configuration of Squid
Everything is in the `tasks/main.yml` file.
-A blank file is created at `/etc/squid3/whitelist-custom.conf` to add addresses in the whitelist.
+A blank file is created at `/etc/squid/whitelist-custom.conf` to add addresses in the whitelist.
## Available variables
diff --git a/squid/tasks/main.yml b/squid/tasks/main.yml
index 2f0e94aa..965be04b 100644
--- a/squid/tasks/main.yml
+++ b/squid/tasks/main.yml
@@ -38,14 +38,14 @@
- name: "squid.conf is present (jessie)"
ansible.builtin.template:
src: squid.conf.j2
- dest: /etc/squid3/squid.conf
+ dest: /etc/squid/squid.conf
notify: "restart squid3"
when: ansible_distribution_release == "jessie"
- name: "evolix whitelist is present (jessie)"
ansible.builtin.copy:
src: whitelist-evolinux.conf
- dest: /etc/squid3/whitelist.conf
+ dest: /etc/squid/whitelist.conf
force: false
notify: "reload squid3"
when: ansible_distribution_release == "jessie"
@@ -135,7 +135,7 @@
- name: add some URL in whitelist (Debian 8)
ansible.builtin.lineinfile:
insertafter: EOF
- dest: /etc/squid3/whitelist.conf
+ dest: /etc/squid/whitelist.conf
line: "{{ item }}"
state: present
loop: '{{ squid_whitelist_items }}'
diff --git a/squid/templates/squid.conf.j2 b/squid/templates/squid.conf.j2
index 108a3bc1..4c89a777 100644
--- a/squid/templates/squid.conf.j2
+++ b/squid/templates/squid.conf.j2
@@ -8,7 +8,7 @@ acl localhost src 127.0.0.0/32
acl INTERNE src {{ squid_address }}/32 127.0.0.0/8
acl Safe_ports port 80 # http
acl SSL_ports port 443 563
-acl WHITELIST url_regex "/etc/squid3/whitelist.conf"
+acl WHITELIST url_regex "/etc/squid/whitelist.conf"
http_access deny !WHITELIST
http_access allow INTERNE
http_access deny all
diff --git a/ssl/tasks/main.yml b/ssl/tasks/main.yml
index 01398dec..cc092c84 100644
--- a/ssl/tasks/main.yml
+++ b/ssl/tasks/main.yml
@@ -39,5 +39,12 @@
tags:
- ssl
+- name: Collect facts about system services
+ service_facts:
+
- ansible.builtin.include: haproxy.yml
- when: haproxy_check.rc == 0
+ when:
+ - haproxy_check.rc == 0
+ - ansible_facts.services['haproxy.service']['state'] == "running"
+ - ansible_facts.services['haproxy.service']['status'] == "enabled"
+
diff --git a/timesyncd/templates/timesyncd.conf.j2 b/timesyncd/templates/timesyncd.conf.j2
index 8aebc1be..f58f81ee 100644
--- a/timesyncd/templates/timesyncd.conf.j2
+++ b/timesyncd/templates/timesyncd.conf.j2
@@ -1,3 +1,3 @@
# {{ ansible_managed }}
[Time]
-NTP="{{ timesyncd_ntp_servers | join(' ') }}"
+NTP={{ timesyncd_ntp_servers | join(' ') }}
diff --git a/unbound/defaults/main.yml b/unbound/defaults/main.yml
index 86f51822..0d7807c1 100644
--- a/unbound/defaults/main.yml
+++ b/unbound/defaults/main.yml
@@ -1,9 +1,11 @@
---
+
unbound_interfaces:
-- '127.0.0.1'
-- '::1'
+ - '127.0.0.1'
+ - '::1'
+
unbound_acls:
-- '0.0.0.0/0 refuse'
-- '127.0.0.0/8 allow_snoop'
-- '::0/0 refuse'
-- '::1 allow_snoop'
+ - '0.0.0.0/0 refuse'
+ - '127.0.0.0/8 allow_snoop'
+ - '::0/0 refuse'
+ - '::1 allow_snoop'
diff --git a/unbound/files/munin-plugin.conf b/unbound/files/munin-plugin.conf
new file mode 100644
index 00000000..cf008d48
--- /dev/null
+++ b/unbound/files/munin-plugin.conf
@@ -0,0 +1,5 @@
+[unbound*]
+user root
+env.statefile /tmp/munin-unbound-state
+env.unbound_conf /etc/unbound/unbound.conf
+env.unbound_control /usr/sbin/unbound-control
diff --git a/unbound/handlers/main.yml b/unbound/handlers/main.yml
index 7c801751..fdb9a629 100644
--- a/unbound/handlers/main.yml
+++ b/unbound/handlers/main.yml
@@ -1,5 +1,15 @@
---
-- name: reload unbound
+- name: Restart unbound
+ ansible.builtin.service:
+ name: unbound
+ state: restarted
+
+- name: Reload unbound
ansible.builtin.service:
name: unbound
state: reloaded
+
+- name: Restart munin-node
+ ansible.builtin.service:
+ name: munin-node
+ state: restarted
diff --git a/unbound/tasks/main.yml b/unbound/tasks/main.yml
index 976c6386..acc24812 100644
--- a/unbound/tasks/main.yml
+++ b/unbound/tasks/main.yml
@@ -1,38 +1,74 @@
---
- name: Install Unbound package
ansible.builtin.apt:
- name: unbound
+ name:
+ - unbound
+ - unbound-anchor
+ - dns-root-data
state: present
- when: ansible_distribution == "Debian"
+ cache_valid_time: 3600
tags:
- - unbound
-
-- name: Retrieve list of root DNS servers
- ansible.builtin.get_url:
- url: https://www.internic.net/domain/named.cache
- dest: /etc/unbound/root.hints
- force: true
- mode: "0644"
- notify: reload unbound
- tags:
- - unbound
+ - unbound
- name: Copy Unbound config
ansible.builtin.template:
- src: unbound.conf.j2
- dest: /etc/unbound/unbound.conf
+ src: evolinux.conf.j2
+ dest: /etc/unbound/unbound.conf.d/evolinux.conf
owner: root
group: root
mode: "0644"
- when: ansible_distribution == "Debian"
- notify: reload unbound
+ notify: Reload unbound
tags:
- - unbound
+ - unbound
+
+- name: Copy Unbound config for reloading (Debian 11 and older)
+ ansible.builtin.template:
+ src: evolinux-reload.conf.j2
+ dest: /etc/unbound/unbound.conf.d/evolinux-reload.conf
+ owner: root
+ group: root
+ mode: "0644"
+ when:
+ - ansible_distribution_major_version is version('11', '<=')
+ notify: Restart unbound
+ tags:
+ - unbound
+
+- name: Copy munin plugin config
+ ansible.builtin.copy:
+ src: munin-plugin.conf
+ dest: /etc/munin/plugin-conf.d/unbound
+ owner: root
+ group: root
+ mode: "0644"
+ tags:
+ - unbound
+
+- name: Enable unbound munin plugin
+ ansible.builtin.file:
+ src: /usr/share/munin/plugins/unbound_munin_
+ dest: "/etc/munin/plugins/unbound_munin_{{ plugin_name }}"
+ state: link
+ loop:
+ - hits
+ - queue
+ - memory
+ - by_type
+ - by_class
+ - by_opcode
+ - by_rcode
+ - by_flags
+ - histogram
+ loop_control:
+ loop_var: plugin_name
+ notify: Restart munin-node
+ tags:
+ - unbound
- name: Starting and enabling Unbound
ansible.builtin.service:
name: unbound
- enabled: yes
+ enabled: true
state: started
tags:
- - unbound
+ - unbound
diff --git a/unbound/templates/evolinux-reload.conf.j2 b/unbound/templates/evolinux-reload.conf.j2
new file mode 100644
index 00000000..f2f395ae
--- /dev/null
+++ b/unbound/templates/evolinux-reload.conf.j2
@@ -0,0 +1,7 @@
+# {{ ansible_managed }}
+
+remote-control:
+ control-enable: yes
+ # by default the control interface is is 127.0.0.1 and ::1 and port 8953
+ # it is possible to use a unix socket too
+ control-interface: /run/unbound.ctl
diff --git a/unbound/templates/evolinux.conf.j2 b/unbound/templates/evolinux.conf.j2
new file mode 100644
index 00000000..339dfe45
--- /dev/null
+++ b/unbound/templates/evolinux.conf.j2
@@ -0,0 +1,53 @@
+server:
+ #interface: X.X.X.X
+ #interface: 127.0.0.1@5353 # listen on alternative port
+{% for interface in unbound_interfaces %}
+ interface: {{ interface }}
+{% endfor %}
+
+{% for acl in unbound_acls %}
+ access-control: {{ acl }}
+{% endfor %}
+
+ hide-identity: yes
+ hide-version: yes
+
+ root-hints: "/usr/share/dns/root.hints"
+
+ # Uncomment to enable DNSSEC validation.
+ #auto-trust-anchor-file: "/etc/unbound/root.key"
+
+ # Enable extended stats for munin plugin
+ extended-statistics: yes
+ statistics-cumulative: no
+ statistics-interval: 0
+
+
+ # Serve zones authoritatively from Unbound to resolver clients.
+ # Not for external service.
+
+ #local-zone: "local." static
+ #local-data: "mycomputer.local. IN A 192.0.2.51"
+ #local-zone: "2.0.192.in-addr.arpa." static
+ #local-data-ptr: "192.0.2.51 mycomputer.local
+ # UDP EDNS reassembly buffer advertised to peers. Default 4096.
+ # May need lowering on broken networks with fragmentation/MTU issues,
+ # particularly if validating DNSSEC.
+
+ #edns-buffer-size: 1480
+ # Use TCP for "forward-zone" requests. Useful if you are making
+ # DNS requests over an SSH port forwarding.
+ #tcp-upstream: yes
+
+
+# Use an upstream forwarder (recursive resolver) for specific zones.
+# Example addresses given below are public resolvers valid as of 2014/03.
+#
+#forward-zone:
+# name: "." # use for ALL queries
+# forward-addr: 74.82.42.42 # he.net
+# forward-addr: 2001:470:20::2 # he.net v6
+# forward-addr: 8.8.8.8 # google.com
+# forward-addr: 2001:4860:4860::8888 # google.com v6
+# forward-addr: 208.67.222.222 # opendns.com
+# forward-first: yes # try direct if forwarder fails
diff --git a/unbound/templates/unbound.conf.j2 b/unbound/templates/unbound.conf.j2
deleted file mode 100644
index a97e725d..00000000
--- a/unbound/templates/unbound.conf.j2
+++ /dev/null
@@ -1,45 +0,0 @@
-server:
- #interface: X.X.X.X
- #interface: 127.0.0.1@5353 # listen on alternative port
-{% for interface in unbound_interfaces %}
- interface: {{ interface }}
-{% endfor %}
- #do-ip6: no
-
-{% for acl in unbound_acls %}
- access-control: {{ acl }}
-{% endfor %}
-
- hide-identity: yes
- hide-version: yes
-
- root-hints: "/etc/unbound/root.hints"
- # Uncomment to enable DNSSEC validation.
- #auto-trust-anchor-file: "/etc/unbound/root.key"
- # Serve zones authoritatively from Unbound to resolver clients.
- # Not for external service.
-
- #local-zone: "local." static
- #local-data: "mycomputer.local. IN A 192.0.2.51"
- #local-zone: "2.0.192.in-addr.arpa." static
- #local-data-ptr: "192.0.2.51 mycomputer.local
- # UDP EDNS reassembly buffer advertised to peers. Default 4096.
- # May need lowering on broken networks with fragmentation/MTU issues,
- # particularly if validating DNSSEC.
-
- #edns-buffer-size: 1480
- # Use TCP for "forward-zone" requests. Useful if you are making
- # DNS requests over an SSH port forwarding.
- #tcp-upstream: yes
-
-# Use an upstream forwarder (recursive resolver) for specific zones.
-# Example addresses given below are public resolvers valid as of 2014/03.
-#
-#forward-zone:
-# name: "." # use for ALL queries
-# forward-addr: 74.82.42.42 # he.net
-# forward-addr: 2001:470:20::2 # he.net v6
-# forward-addr: 8.8.8.8 # google.com
-# forward-addr: 2001:4860:4860::8888 # google.com v6
-# forward-addr: 208.67.222.222 # opendns.com
-# forward-first: yes # try direct if forwarder fails
diff --git a/vrrpd/defaults/main.yml b/vrrpd/defaults/main.yml
index f5950a14..1c7abb10 100644
--- a/vrrpd/defaults/main.yml
+++ b/vrrpd/defaults/main.yml
@@ -1,4 +1,5 @@
---
+vrrp_force_update_switch_script: false
vrrp_addresses: []
# - {
@@ -10,4 +11,7 @@ vrrp_addresses: []
# label: Null # use this name is syslog messages (helps when several vrid are running)
# ip: Null # the ip address(es) (and optionnaly subnet mask) of the virtual server
# state: Null # 'started' or 'stopped'
-# }
\ No newline at end of file
+# }
+
+minifirewall_restart_if_needed: True
+minifirewall_restart_force: False
diff --git a/vrrpd/files/vrrp_switch.sh b/vrrpd/files/vrrp_switch.sh
new file mode 100644
index 00000000..8806a7fe
--- /dev/null
+++ b/vrrpd/files/vrrp_switch.sh
@@ -0,0 +1,89 @@
+#!/bin/sh
+
+set -u
+set -e
+
+# Input values
+STATE=$1
+VRID=$2
+VIRTUAL_IP=$3
+INTERFACE_NAME=$4
+LABEL=$5
+PRIORITY=$6
+ADVERT_INT=$7
+PREEMPT=$8
+OTHER=${9:-}
+
+LOG_DIR=/var/log/vrrpd/
+[ ! -d "${LOG_DIR}" ] && mkdir -p "${LOG_DIR}"
+LOG_FILE="${LOG_DIR}/state.${VRID}"
+
+STATE_DIR=/var/run/vrrpd/
+[ ! -d "${STATE_DIR}" ] && mkdir -p "${STATE_DIR}"
+STATE_FILE="${STATE_DIR}/vrrp-${LABEL}"
+
+# Log state change to file
+printf "%s %s %s %s %s %s %s %s : %s\n" \
+ "${STATE}" \
+ "${VIRTUAL_IP}" \
+ "${INTERFACE_NAME}" \
+ "${LABEL}" \
+ "${PRIORITY}" \
+ "${ADVERT_INT}" \
+ "${PREEMPT}" \
+ "${OTHER}" \
+ "$(date)" \
+ >> "${LOG_FILE}"
+
+# Replace information in state file
+{
+ echo "VRRP - ${LABEL}"
+ echo "Group ${VRID}"
+ echo "State is ${STATE}"
+ echo "Virtual IP address is ${VIRTUAL_IP}"
+} > "${STATE_FILE}"
+
+# Choose virtual interface name (limited in size)
+INTERFACE_PREFIX="vrrp_${VRID}_"
+INTERFACE_PREFIX_LEN=${#INTERFACE_PREFIX}
+INTERFACE_LEN=$(( ${#INTERFACE_PREFIX} + ${#INTERFACE_NAME} ))
+INTERFACE_MAX_LEN=15
+
+if [ ${INTERFACE_LEN} -gt ${INTERFACE_MAX_LEN} ]; then
+ INTERFACE_SUFFIX=$(echo "${INTERFACE_NAME}" | tail -c $(( INTERFACE_MAX_LEN + 1 - INTERFACE_PREFIX_LEN )))
+else
+ INTERFACE_SUFFIX="${INTERFACE_NAME}"
+fi
+VIRTUAL_INTERFACE_NAME="${INTERFACE_PREFIX}${INTERFACE_SUFFIX}"
+
+# Apply state
+case "${STATE}" in
+
+ "master" )
+ # Choose a MAC address
+ MAC_SUFFIX=$(printf %02x "${VRID}")
+ MAC="00:00:5e:00:01:${MAC_SUFFIX}"
+ # Create macvlan interface
+ ip link add link "${INTERFACE_NAME}" address "${MAC}" "${VIRTUAL_INTERFACE_NAME}" type macvlan
+ # Add IP to interface
+ ip address add "${VIRTUAL_IP}" dev "${VIRTUAL_INTERFACE_NAME}"
+ # Enable interface
+ ip link set dev "${VIRTUAL_INTERFACE_NAME}" up
+ ;;
+
+ "slave" )
+ # Delete interface if it exists
+ if ip link show "${VIRTUAL_INTERFACE_NAME}" >/dev/null 2>&1; then
+ ip link delete "${VIRTUAL_INTERFACE_NAME}"
+ fi
+ ;;
+
+ * )
+ # Error on unknown value for state
+ echo "Unknown state '${STATE}'" >&2
+ exit 1
+ ;;
+
+esac
+
+exit 0
diff --git a/vrrpd/handlers/main.yml b/vrrpd/handlers/main.yml
new file mode 100644
index 00000000..63cfcd86
--- /dev/null
+++ b/vrrpd/handlers/main.yml
@@ -0,0 +1,15 @@
+---
+
+- name: restart minifirewall
+ ansible.builtin.command:
+ cmd: /etc/init.d/minifirewall restart
+ register: minifirewall_init_restart
+ failed_when:
+ - "'starting IPTables rules is now finish : OK' not in minifirewall_init_restart.stdout"
+ - "'minifirewall started' not in minifirewall_init_restart.stdout"
+
+- name: restart minifirewall (noop)
+ ansible.builtin.meta: noop
+ register: minifirewall_init_restart
+ failed_when: False
+ changed_when: False
diff --git a/vrrpd/tasks/ip.yml b/vrrpd/tasks/ip.yml
index b46a8954..81c9f08f 100644
--- a/vrrpd/tasks/ip.yml
+++ b/vrrpd/tasks/ip.yml
@@ -18,5 +18,40 @@
enabled: yes
state: "{{ vrrp_address.state }}"
when:
- - vrrp_systemd_unit is changed
- - not ansible_check_mode
\ No newline at end of file
+ - vrrp_systemd_unit is changed
+ - not ansible_check_mode
+
+- name: Check if a recent minifirewall is present
+ ansible.builtin.stat:
+ path: /etc/minifirewall.d/
+ register: _minifirewall_dir
+
+- ansible.builtin.set_fact:
+ minifirewall_restart_handler_name: "{{ minifirewall_restart_if_needed | bool | ternary('restart minifirewall', 'restart minifirewall (noop)') }}"
+
+- name: VRRP output is authorized in minifirewall
+ lineinfile:
+ path: /etc/minifirewall.d/vrrpd
+ line: "/sbin/iptables -A OUTPUT -o {{ vrrp_address.interface }} -p 112 -j ACCEPT # Allow VRRP output on {{ vrrp_address.interface }}"
+ regexp: "# Allow VRRP output on {{ vrrp_address.interface }}$"
+ create: yes
+ mode: "0600"
+ owner: "root"
+ group: "root"
+ notify: "{{ minifirewall_restart_handler_name }}"
+ when: _minifirewall_dir.stat.exists
+
+- name: VRRP input is authorized in minifirewall
+ lineinfile:
+ path: /etc/minifirewall.d/vrrpd
+ line: "/sbin/iptables -A INPUT -i {{ vrrp_address.interface }} -s {{ peer }} -d 224.0.0.0/8 -j ACCEPT # Allow VRRP input on {{ vrrp_address.interface }} from {{ peer }} for VRID {{ vrrp_address.id }}"
+ regexp: "# Allow VRRP input on {{ vrrp_address.interface }} from {{ peer }} for VRID {{ vrrp_address.id }}"
+ create: yes
+ mode: "0600"
+ owner: "root"
+ group: "root"
+ loop: "{{ vrrp_address.peers | default([]) }}"
+ loop_control:
+ loop_var: peer
+ notify: "{{ minifirewall_restart_handler_name }}"
+ when: _minifirewall_dir.stat.exists
diff --git a/vrrpd/tasks/main.yml b/vrrpd/tasks/main.yml
index 605fb0fd..78b0ee3b 100644
--- a/vrrpd/tasks/main.yml
+++ b/vrrpd/tasks/main.yml
@@ -1,4 +1,5 @@
---
+
- name: Install Evolix public repositry
ansible.builtin.include_role:
name: evolix/apt
@@ -14,6 +15,15 @@
tags:
- vrrpd
+- name: install custom switch script
+ ansible.builtin.copy:
+ src: vrrp_switch.sh
+ dest: /etc/vrrpd/vrrp_switch
+ mode: "0700"
+ owner: "root"
+ group: "root"
+ force: "{{ vrrp_force_update_switch_script | bool | ternary('yes','no') }}"
+
- name: Adjust sysctl config (except rp_filter)
ansible.posix.sysctl:
name: "{{ item.name }}"
@@ -62,4 +72,4 @@
ansible.builtin.include: ip.yml
loop: "{{ vrrp_addresses }}"
loop_control:
- loop_var: "vrrp_address"
\ No newline at end of file
+ loop_var: "vrrp_address"
diff --git a/webapps/evoadmin-mail/tasks/apache.yml b/webapps/evoadmin-mail/tasks/apache.yml
index 26c2b53b..87eb3d2a 100644
--- a/webapps/evoadmin-mail/tasks/apache.yml
+++ b/webapps/evoadmin-mail/tasks/apache.yml
@@ -12,6 +12,7 @@
src: "/etc/apache2/sites-available/evoadminmail.conf"
dest: "/etc/apache2/sites-enabled/evoadminmail.conf"
state: link
+ force: true
notify: reload apache2
when: evoadminmail_enable_vhost | bool
tags:
diff --git a/webapps/evoadmin-mail/tasks/main.yml b/webapps/evoadmin-mail/tasks/main.yml
index a1018eca..76b1b8f6 100644
--- a/webapps/evoadmin-mail/tasks/main.yml
+++ b/webapps/evoadmin-mail/tasks/main.yml
@@ -6,8 +6,17 @@
- name: Install evoadmin-mail package
ansible.builtin.apt:
- deb: /tmp/evoadmin-mail.deb
+ deb: https://pub.evolix.org/evolix/pool/main/e/evoadmin-mail/evoadmin-mail_1.0.9-2_all.deb
state: present
+ when: ansible_distribution_major_version is version('12', '<')
+ tags:
+ - evoadmin-mail
+
+- name: Install evoadmin-mail package
+ ansible.builtin.apt:
+ name: evoadmin-mail
+ state: present
+ when: ansible_distribution_major_version is version('12', '>=')
tags:
- evoadmin-mail
diff --git a/webapps/evoadmin-web/tasks/web.yml b/webapps/evoadmin-web/tasks/web.yml
index fc266462..db4d8e74 100644
--- a/webapps/evoadmin-web/tasks/web.yml
+++ b/webapps/evoadmin-web/tasks/web.yml
@@ -36,9 +36,9 @@
notify: reload apache2
when: ansible_distribution_release == "bullseye"
-- name: "Set custom values for PHP config (Debian 11)"
+- name: "Set custom values for PHP config (Debian 12)"
community.general.ini_file:
- dest: /etc/php/8.1/apache2/conf.d/zzz-evolinux-custom.ini
+ dest: /etc/php/8.2/apache2/conf.d/zzz-evolinux-custom.ini
section: PHP
option: "disable_functions"
value: "shell-exec,system,passthru,putenv,popen"
diff --git a/webapps/nextcloud/defaults/main.yml b/webapps/nextcloud/defaults/main.yml
index c6e0a316..d9366933 100644
--- a/webapps/nextcloud/defaults/main.yml
+++ b/webapps/nextcloud/defaults/main.yml
@@ -5,6 +5,7 @@ nextcloud_releases_baseurl: "https://download.nextcloud.com/server/releases/"
nextcloud_instance_name: "nextcloud"
nextcloud_user: "{{ nextcloud_instance_name }}"
+nextcloud_user_uid: 3000
nextcloud_domains: []
nextcloud_home: "/home/{{ nextcloud_user }}"
@@ -16,3 +17,6 @@ nextcloud_db_name: "{{ nextcloud_instance_name }}"
nextcloud_admin_login: "admin"
nextcloud_admin_password: ""
+
+nextcloud_get_archive: True
+nextcloud_do_config: True
diff --git a/webapps/nextcloud/tasks/main.yml b/webapps/nextcloud/tasks/main.yml
index 02304334..9bbab5b5 100644
--- a/webapps/nextcloud/tasks/main.yml
+++ b/webapps/nextcloud/tasks/main.yml
@@ -48,9 +48,11 @@
- ansible.builtin.include: user.yml
- ansible.builtin.include: archive.yml
+ when: nextcloud_get_archive
- ansible.builtin.include: apache-vhost.yml
- ansible.builtin.include: mysql-user.yml
- ansible.builtin.include: config.yml
+ when: nextcloud_do_config
diff --git a/webapps/nextcloud/tasks/user.yml b/webapps/nextcloud/tasks/user.yml
index fdc5b7a6..e9a398b9 100644
--- a/webapps/nextcloud/tasks/user.yml
+++ b/webapps/nextcloud/tasks/user.yml
@@ -1,9 +1,15 @@
---
+- name: Check nextcloud user id is over 2999
+ ansible.builtin.assert:
+ that:
+ - nextcloud_user_uid >= 3000
+
- name: Create {{ nextcloud_user }} unix group
ansible.builtin.group:
name: "{{ nextcloud_user | mandatory }}"
state: present
+ gid: "{{ nextcloud_user_uid | mandatory }}"
tags:
- nextcloud
@@ -12,6 +18,7 @@
name: "{{ nextcloud_user | mandatory }}"
group: "{{ nextcloud_user | mandatory }}"
home: "{{ nextcloud_home | mandatory }}"
+ uid: "{{ nextcloud_user_uid | mandatory }}"
shell: '/bin/bash'
create_home: True
state: present
@@ -19,6 +26,11 @@
tags:
- nextcloud
+- name: Set mode for home directory
+ ansible.builtin.file:
+ path: "{{ nextcloud_home }}"
+ mode: "0701"
+
- name: Create top-level directories
ansible.builtin.file:
dest: "{{ item }}"
@@ -36,7 +48,14 @@
- name: Mount up Ceph volume by UUID
ansible.posix.mount:
path: "{{ nextcloud_data }}"
- src: "{{ nextcloud_data_uuid }}"
+ src: "UUID={{ nextcloud_data_uuid }}"
fstype: ext4
opts: defaults,noexec,nosuid,nodev,relatime,lazytime
- state: present
+ state: mounted
+
+- name: Set volume's root permissions and ownership
+ ansible.builtin.file:
+ path: "{{ nextcloud_data }}"
+ owner: "{{ nextcloud_user }}"
+ group: "{{ nextcloud_user }}"
+ mode: "0700"
diff --git a/webapps/roundcube/tasks/main.yml b/webapps/roundcube/tasks/main.yml
index 17422246..a0fd25b9 100644
--- a/webapps/roundcube/tasks/main.yml
+++ b/webapps/roundcube/tasks/main.yml
@@ -58,7 +58,7 @@
tags:
- roundcube
-- name: configure roudcube imap port
+- name: configure roundcube imap port
ansible.builtin.lineinfile:
dest: /etc/roundcube/config.inc.php
regexp: "\\$config\\['default_port'\\]"
@@ -67,6 +67,15 @@
tags:
- roundcube
+- name: configure roundcube smtp port
+ ansible.builtin.lineinfile:
+ dest: /etc/roundcube/config.inc.php
+ regexp: "\\$config\\['smtp_port'\\]"
+ insertafter: "\\$config\\['smtp_port'\\]"
+ line: "$config['smtp_port'] = 25;"
+ tags:
+ - roundcube
+
- name: configure managesieve plugin
ansible.builtin.copy:
src: /usr/share/roundcube/plugins/managesieve/config.inc.php.dist
@@ -99,6 +108,7 @@
src: /etc/apache2/sites-available/roundcube.conf
dest: /etc/apache2/sites-enabled/roundcube.conf
state: link
+ force: true
notify: reload apache2
when: roundcube_webserver == "apache"
tags: