diff --git a/.Jenkinsfile b/.Jenkinsfile
index 3f591b98..d10526b2 100644
--- a/.Jenkinsfile
+++ b/.Jenkinsfile
@@ -6,6 +6,20 @@ pipeline {
}
stages {
+ stage('Anible Lint') {
+ agent {
+ docker {
+ image 'evolix/ansible-lint:latest'
+ }
+ }
+ steps {
+ script {
+ sh 'for role_dir in ./*/; do HOME=$WORKSPACE_TMP ansible-lint -p $role_dir || : ; done'
+ recordIssues(tools: [ansibleLint()])
+ }
+ }
+ }
+
stage('Build tagged docker image') {
when {
buildingTag()
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 00000000..ce271884
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,7 @@
+{
+ "files.associations": {
+ "*.yml": "ansible",
+ "*.yaml": "ansible"
+ },
+ "yaml.format.enable": false
+}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8f5e0e0c..dc0b7cc3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@ The **major** part of the version is the year
The **minor** part changes is the month
The **patch** part changes is incremented if multiple releases happen the same month
+
## [Unreleased]
### Added
@@ -20,6 +21,63 @@ The **patch** part changes is incremented if multiple releases happen the same m
### Security
+## [23.03] 2023-03-16
+
+### Added
+
+* apache: add task to enable mailgraph on default vhost and index.html
+* apt: add move-apt-keyrings script/tasks
+* apt: add tools to migrate sources to deb822 format
+* fail2ban: add "Internal login failure" to Dovecot filter
+* lxc: copy `/etc/profile.d/evolinux.sh` from host into container
+* nagios-nrpe: add tasks/files for a wrapper
+* nagios-nrpe: Print pool config path in check_phpfpm_multi output
+* php: add `php_version` variable when sury is activated for each Debian version
+* php: add a way to choose which version to install using sury repository
+* postfix: Add task to enable mailgraph on packmail
+* postgresql: configure max_connections
+* userlogrotate: create dedicated role, separated from packweb-apache
+* varnish: add `varnish_update_config` variable to disable configuration update
+
+### Changed
+
+* Use systemd module instead of command
+* Removed all `warn: False` args in command, shell and other modules as it's been deprecated and will give a hard fail in ansible-core 2.14.0.
+* apt: Use pub.evolix.org instead of pub.evolix.net
+* bind: refactor role
+* elasticsearch: Disable garabge collector logging (JDK >= 9)
+* evolinux-users: Update sudoers template to remove commands allowed without password
+* listupgrade: upstream release 23.03.3
+* kvmstats: use virsh domstats | awk to get guests informations
+* nagios-nrpe : Rewrite `check_vrrpd` for a better check (check `rp_filter`, `vrrpd` and `uvrrpd` compatible, use arguments, …)
+* openvpn: Change `check_openvpn` destination file to comply with recent EvoBSD change
+* postfix: come back to default value of `notify_classes` for pack mails.
+* userlogrotate: set rotate date format in right order (YYYY-MM-DD)!
+* webapps/nextcloud : Change default data directory to be outside web root
+* webapps/nextcloud : Small enhancement on the vhost template to lock out data dir
+* yarn: update apt key
+
+### Fixed
+
+* Proper jinja spacing
+* clamav: set `MaxConnectionQueueLength` to its default value (200), custom (15) was way too small and caused recurring failures in Postfix.
+* docker-host: fix type in `daemon.json` and remove host configuration that is already in the systemd service by default
+* evolinux-base: ensure dbus is started and enabled (not by default in the case of an offline netinst)
+* haproxy: fix missing admin ACL in stats module access permissions
+* openvpn: fix the client cipher configuration to match the server cipher configuration
+* php: fix error introduced in #33503e4538 (`False` evaluated as a String instead of Boolean)
+* php: install using Sury repositories on Bullseye
+* postfix (packmail only): disable `concurrency_failed_cohort_limit` for destination smtp-amavis to prevent the suspension of this destination when Amavis fails to answer. Indeed, we configure the suspension delay quite long in `minimal_backoff_time` (2h) and `maximal_backoff_time` (6h) to reduce the risk of ban from external SMTPs.
+* postfix: avoid Amavis transport to be considered dead when restarted.
+* postfix: remove unused `aliases_scope=sub` from virtual_aliases.cf (it generated warnings)
+* userlogrotate: fix bug introduced in commit 2e54944a246 (rotated files were not zipped)
+* userlogrotate: skip zipping if .gz log already exists (prevents interactive question)
+
+### Removed
+
+* evolinux-base: subversion is not installed anymore
+
+
## [22.12] 2022-12-14
### Added
@@ -34,6 +92,7 @@ The **patch** part changes is incremented if multiple releases happen the same m
* packweb-apache: enable `log_forensic` module
* rabbitmq: add link in default page
* varnish: create special tmp directory for syntax validation
+* postfix: add localhost.$mydomain to mydestination
### Changed
diff --git a/amazon-ec2/tasks/create-instance.yml b/amazon-ec2/tasks/create-instance.yml
index a3f84b1a..86e8f803 100644
--- a/amazon-ec2/tasks/create-instance.yml
+++ b/amazon-ec2/tasks/create-instance.yml
@@ -3,34 +3,34 @@
- name: Launch new instance(s)
ec2:
state: present
- aws_access_key: "{{aws_access_key}}"
- aws_secret_key: "{{aws_secret_key}}"
- region: "{{aws_region}}"
- image: "{{ec2_base_ami}}"
- instance_type: "{{ec2_instance_type}}"
- count: "{{ec2_instance_count}}"
- assign_public_ip: "{{ec2_public_ip}}"
- group: "{{ec2_security_group.name}}"
- key_name: "{{ec2_keyname}}"
+ aws_access_key: "{{ aws_access_key }}"
+ aws_secret_key: "{{ aws_secret_key }}"
+ region: "{{ aws_region }}"
+ image: "{{ ec2_base_ami }}"
+ instance_type: "{{ ec2_instance_type }}"
+ count: "{{ ec2_instance_count }}"
+ assign_public_ip: "{{ ec2_public_ip }}"
+ group: "{{ ec2_security_group.name }}"
+ key_name: "{{ ec2_keyname }}"
wait: yes
register: ec2
- name: Add newly created instance(s) to inventory
add_host:
- hostname: "{{item.public_dns_name}}"
+ hostname: "{{ item.public_dns_name }}"
groupname: launched-instances
ansible_user: admin
ansible_ssh_common_args: "-o StrictHostKeyChecking=no"
- loop: "{{ec2.instances}}"
+ loop: "{{ ec2.instances }}"
- debug:
- msg: "Your newly created instance is reachable at: {{item.public_dns_name}}"
- loop: "{{ec2.instances}}"
+ msg: "Your newly created instance is reachable at: {{ item.public_dns_name }}"
+ loop: "{{ ec2.instances }}"
- name: Wait for SSH to come up on all instances (give up after 2m)
wait_for:
state: started
- host: "{{item.public_dns_name}}"
+ host: "{{ item.public_dns_name }}"
port: 22
timeout: 120
- loop: "{{ec2.instances}}"
+ loop: "{{ ec2.instances }}"
diff --git a/apache/tasks/server_status.yml b/apache/tasks/server_status.yml
index efd2b00e..38daf285 100644
--- a/apache/tasks/server_status.yml
+++ b/apache/tasks/server_status.yml
@@ -68,3 +68,10 @@
insertafter: "[apache_*]"
create: no
notify: restart munin-node
+
+- name: add mailgraph URL in index.html
+ lineinfile:
+ dest: /var/www/index.html
+ state: present
+ line: '
Stats Mail'
+ insertbefore: ""
diff --git a/apache/templates/evolinux-default.conf.j2 b/apache/templates/evolinux-default.conf.j2
index 68cdcf84..effa55c6 100644
--- a/apache/templates/evolinux-default.conf.j2
+++ b/apache/templates/evolinux-default.conf.j2
@@ -35,6 +35,15 @@
Include /etc/apache2/ipaddr_whitelist.conf
+ # Mailgraph configuration
+ Alias /mailgraph /usr/share/mailgraph
+
+ DirectoryIndex mailgraph.cgi
+ Require all granted
+ Options +FollowSymLinks +ExecCGI
+ AddHandler cgi-script .cgi
+
+
CustomLog /var/log/apache2/access.log vhost_combined
ErrorLog /var/log/apache2/error.log
LogLevel warn
@@ -118,6 +127,15 @@
Include /etc/apache2/ipaddr_whitelist.conf
+ # Mailgraph configuration
+ Alias /mailgraph /usr/share/mailgraph
+
+ DirectoryIndex mailgraph.cgi
+ Require all granted
+ Options +FollowSymLinks +ExecCGI
+ AddHandler cgi-script .cgi
+
+
# BEGIN phpMyAdmin section
# END phpMyAdmin section
diff --git a/apt/files/deb822-migration.py b/apt/files/deb822-migration.py
new file mode 100644
index 00000000..10ee47ae
--- /dev/null
+++ b/apt/files/deb822-migration.py
@@ -0,0 +1,96 @@
+#!/bin/env python3
+
+import re
+import sys
+import os
+
+if len(sys.argv) > 1:
+ src_file = sys.argv[1]
+else:
+ print("You must provide a source file as first argument", file=sys.stderr)
+ sys.exit(1)
+
+if not os.access(src_file, os.R_OK):
+ print(src_file, "is not readable", file=sys.stderr)
+ sys.exit(2)
+
+pattern = re.compile('^(?Pdeb|deb-src) +(?P\[.+\] ?)*(?P\w+:\/\/\S+) +(?P\S+)(?: +(?P.*))?$')
+
+sources = {}
+
+def split_options(raw):
+ table = str.maketrans({
+ "[": None,
+ "]": None
+ })
+ options = raw.translate(table).split(' ')
+
+ return options
+
+with open(src_file,'r') as file:
+ for line in file:
+ matches = re.match(pattern, line)
+ if matches is not None:
+ # print(matches.groupdict())
+ uri = matches['uri']
+
+ options = {}
+ if matches.group('options'):
+ for option in split_options(matches['options']):
+ if "=" in option:
+ key, value = option.split("=")
+ options[key] = value
+
+ if uri in sources:
+ sources[uri]["Types"].add(matches["type"])
+ sources[uri]["URIs"] = matches["uri"]
+ sources[uri]["Suites"].add(matches["suite"])
+ sources[uri]["Components"].update(matches["components"].split(' '))
+ else:
+ source = {
+ "Types": {matches['type']},
+ "URIs": matches['uri'],
+ "Enabled": "yes",
+ }
+
+ if matches.group('suite'):
+ source["Suites"] = set(matches['suite'].split(' '))
+
+ if matches.group('components'):
+ source["Components"] = set(matches['components'].split(' '))
+
+ if "arch" in options:
+ if "Architectures" in source:
+ source["Architectures"].append(options["arch"])
+ else:
+ source["Architectures"] = {options["arch"]}
+
+ if "signed-by" in options:
+ if "Signed-by" in source:
+ source["Signed-by"].append(options["signed-by"])
+ else:
+ source["Signed-by"] = {options["signed-by"]}
+
+ if "lang" in options:
+ if "Languages" in source:
+ source["Languages"].append(options["lang"])
+ else:
+ source["Languages"] = {options["lang"]}
+
+ if "target" in options:
+ if "Targets" in source:
+ source["Targets"].append(options["target"])
+ else:
+ source["Targets"] = {options["target"]}
+
+ sources[uri] = source
+
+for i, (uri, source) in enumerate(sources.items()):
+ if i > 0:
+ print("")
+ for key, value in source.items():
+ if isinstance(value, str):
+ print("{}: {}".format(key, value) )
+ else:
+ print("{}: {}".format(key, ' '.join(value)) )
+ i += 1
\ No newline at end of file
diff --git a/apt/files/deb822-migration.sh b/apt/files/deb822-migration.sh
new file mode 100644
index 00000000..cffa2f95
--- /dev/null
+++ b/apt/files/deb822-migration.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+deb822_migrate_script=$(command -v deb822-migration.py)
+
+if [ -z "${deb822_migrate_script}" ]; then
+ deb822_migrate_script="./deb822-migration.py"
+fi
+if [ ! -x "${deb822_migrate_script}" ]; then
+ >&2 echo "ERROR: '${deb822_migrate_script}' not found or not executable"
+ exit 1
+fi
+
+dest_dir="/etc/apt/sources.list.d"
+rc=0
+
+migrate_file() {
+ legacy_file=$1
+ deb822_file=$2
+
+ if [ -f "${legacy_file}" ]; then
+ if [ -f "${deb822_file}" ]; then
+ >&2 echo "ERROR: '${deb822_file}' already exists"
+ rc=2
+ else
+ ${deb822_migrate_script} "${legacy_file}" > "${deb822_file}"
+ if [ $? -eq 0 ] && [ -f "${deb822_file}" ]; then
+ mv "${legacy_file}" "${legacy_file}.bak"
+ echo "Migrated ${legacy_file} to ${deb822_file} and renamed to ${legacy_file}.bak"
+ else
+ >&2 echo "ERROR: failed to convert '${legacy_file}' to '${deb822_file}'"
+ rc=2
+ fi
+ fi
+ else
+ >&2 echo "ERROR: '${legacy_file}' not found"
+ rc=2
+ fi
+}
+
+migrate_file "/etc/apt/sources.list" "${dest_dir}/system.sources"
+
+# shellcheck disable=SC2044
+for legacy_file in $(find /etc/apt/sources.list.d -mindepth 1 -maxdepth 1 -type f -name '*.list'); do
+ deb822_file=$(basename "${legacy_file}" .list)
+ migrate_file "${legacy_file}" "${dest_dir}/${deb822_file}.sources"
+done
+
+exit ${rc}
\ No newline at end of file
diff --git a/apt/files/move-apt-keyrings.sh b/apt/files/move-apt-keyrings.sh
new file mode 100644
index 00000000..2d266412
--- /dev/null
+++ b/apt/files/move-apt-keyrings.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+# Move apt repository key from /etc/apt/trusted.gpg.d/ to /etc/apt/keyrings/ and add "signed-by" tag in source list
+#
+# Example: move-apt-keyrings.sh http://repo.mongodb.org/apt/debian mongodb-server-[0-9\\.]+.asc
+
+repository_pattern=$1
+key=$2
+
+found_files=$(grep --files-with-matches --recursive --extended-regexp "${repository_pattern}" "/etc/apt/sources.list.d/*.list")
+
+old_key_file="/etc/apt/trusted.gpg.d/${key}"
+new_key_file="/etc/apt/keyrings/${key}"
+
+for file in ${found_files}; do
+ if ! grep --quiet "signed-by" "${file}"; then
+ signed_by="signed-by=${new_key_file}"
+ if grep --quiet "deb(-src)? \[" "${file}"; then
+ sed -i "s@deb\(-src\)\? \[\([^]]\+\)\]@deb\1 [\2 ${signed_by}]@" "${file}"
+ else
+ sed -i "s@deb\(-src\)\? @deb\1 [${signed_by}] @" "${file}"
+ fi
+ fi
+done
+
+if [ -f "${old_key_file}" ] && [ ! -f "${new_key_file}" ]; then
+ mv "${old_key_file}" "${new_key_file}"
+fi
+if [ -f "${new_key_file}" ]; then
+ chmod 644 "${new_key_file}"
+ chown root: "${new_key_file}"
+fi
diff --git a/apt/files/pub_evolix.asc b/apt/files/pub_evolix.asc
new file mode 100644
index 00000000..4a21bdfe
--- /dev/null
+++ b/apt/files/pub_evolix.asc
@@ -0,0 +1,87 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+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
+oA9QflpnDubMnCve
+=ZCml
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/apt/tasks/evolix_public.yml b/apt/tasks/evolix_public.yml
index 21062a32..8c4d5216 100644
--- a/apt/tasks/evolix_public.yml
+++ b/apt/tasks/evolix_public.yml
@@ -18,8 +18,8 @@
- name: Add Evolix GPG key
copy:
- src: reg.asc
- dest: "{{ apt_keyring_dir }}/reg.asc"
+ src: pub_evolix.asc
+ dest: "{{ apt_keyring_dir }}/pub_evolix.asc"
force: yes
mode: "0644"
owner: root
diff --git a/apt/tasks/hold_packages.yml b/apt/tasks/hold_packages.yml
index 691f3763..10f5b358 100644
--- a/apt/tasks/hold_packages.yml
+++ b/apt/tasks/hold_packages.yml
@@ -1,5 +1,8 @@
---
+- include_role:
+ name: evolix/remount-usr
+
- name: "hold packages (apt)"
shell: "set -o pipefail && (dpkg -l {{ item }} 2>/dev/null | grep -q -E '^(i|h)i') && ((apt-mark showhold | grep --quiet {{ item }}) || apt-mark hold {{ item }})"
args:
@@ -76,8 +79,8 @@
- name: Check if Cron is installed
shell: "dpkg --list 'cron' 2>/dev/null | grep -q -E '^(i|h)i'"
register: is_cron
- changed_when: false
- failed_when: false
+ changed_when: False
+ failed_when: False
check_mode: no
tags:
- apt
diff --git a/apt/tasks/migrate-to-deb822.yml b/apt/tasks/migrate-to-deb822.yml
new file mode 100644
index 00000000..642bcb4f
--- /dev/null
+++ b/apt/tasks/migrate-to-deb822.yml
@@ -0,0 +1,31 @@
+---
+- include_role:
+ name: evolix/remount-usr
+
+- name: /usr/share/scripts exists
+ file:
+ dest: /usr/share/scripts
+ mode: "0700"
+ owner: root
+ group: root
+ state: directory
+ tags:
+ - apt
+
+- name: Migration scripts are installed
+ copy:
+ src: "{{ item }}"
+ dest: "/usr/share/scripts/{{ item }}"
+ force: yes
+ mode: "0755"
+ loop:
+ - deb822-migration.py
+ - deb822-migration.sh
+ tags:
+ - apt
+
+- name: Exec migration script
+ command: /usr/share/scripts/deb822-migration.sh
+ ignore_errors: yes
+ tags:
+ - apt
\ No newline at end of file
diff --git a/apt/tasks/move-apt-keyring.yml b/apt/tasks/move-apt-keyring.yml
new file mode 100644
index 00000000..4214d2d6
--- /dev/null
+++ b/apt/tasks/move-apt-keyring.yml
@@ -0,0 +1,52 @@
+---
+
+- name: New APT keyrings directory is present
+ file:
+ path: /etc/apt/keyrings
+ state: directory
+ mode: "0755"
+ owner: root
+ group: root
+
+- include_role:
+ name: evolix/remount-usr
+
+- name: /usr/share/scripts exists
+ file:
+ dest: /usr/share/scripts
+ mode: "0700"
+ owner: root
+ group: root
+ state: directory
+ tags:
+ - apt
+
+- name: migration script is present
+ copy:
+ src: move-apt-keyrings.sh
+ dest: /usr/share/scripts/move-apt-keyrings.sh
+ mode: "0755"
+ owner: root
+ group: root
+
+- name: Move repository signing key
+ command: "/usr/share/scripts/move-apt-keyrings.sh \"{{ item.repository_pattern }}\" \"{{ item.key }}\""
+ loop:
+ - { repository_pattern: "http://pub.evolix.net/", key: "reg.asc" }
+ - { repository_pattern: "http://pub.evolix.org/evolix", key: "pub_evolix.asc" }
+ - { repository_pattern: "https://pub.evolix.org/evolix", key: "pub_evolix.asc" }
+ - { repository_pattern: "https://artifacts.elastic.co/packages/[^/]+/apt", key: "elastics.asc" }
+ - { repository_pattern: "https://download.docker.com/linux/debian", key: "docker-debian.asc" }
+ - { repository_pattern: "https://downloads.linux.hpe.com/SDR/repo/mcp", key: "hpePublicKey2048_key1.asc" }
+ - { repository_pattern: "http://pkg.jenkins-ci.org/debian-stable", key: "jenkins.asc" }
+ - { repository_pattern: "https://packages.sury.org/php/", key: "sury.gpg" }
+ - { repository_pattern: "http://repo.mongodb.org/apt/debian", key: "mongodb-server-[0-9\\.]+.asc" }
+ - { repository_pattern: "http://apt.newrelic.com/debian/", key: "newrelic.asc" }
+ - { repository_pattern: "https://deb.nodesource.com/", key: "nodesource.asc" }
+ - { repository_pattern: "https://dl.yarnpkg.com/debian/", key: "yarn.asc" }
+ - { repository_pattern: "http://apt.postgresql.org/pub/repos/apt/", key: "postgresql.asc" }
+ register: _cmd
+
+- name: Debug command
+ debug:
+ var: _cmd
diff --git a/apt/templates/evolix_public.list.j2 b/apt/templates/evolix_public.list.j2
index e0bc0de7..e00899e7 100644
--- a/apt/templates/evolix_public.list.j2
+++ b/apt/templates/evolix_public.list.j2
@@ -1,7 +1,3 @@
# {{ ansible_managed }}
-{% if ansible_distribution_release == "bookworm" %}
-deb [signed-by={{ apt_keyring_dir }}/reg.asc] http://pub.evolix.net/ bullseye/
-{% else %}
-deb [signed-by={{ apt_keyring_dir }}/reg.asc] http://pub.evolix.net/ {{ ansible_distribution_release }}/
-{% endif %}
\ No newline at end of file
+deb [signed-by={{ apt_keyring_dir }}/pub_evolix.asc] http://pub.evolix.org/evolix {{ ansible_distribution_release }} main
diff --git a/bind/defaults/main.yml b/bind/defaults/main.yml
index 99b33e13..c34490f8 100644
--- a/bind/defaults/main.yml
+++ b/bind/defaults/main.yml
@@ -8,4 +8,5 @@ bind_systemd_service_path: /etc/systemd/system/bind9.service
bind_statistics_file: /var/run/named.stats
bind_log_file: /var/log/bind.log
bind_query_file: /var/log/bind_queries.log
+bind_query_file_enabled: False
bind_cache_dir: /var/cache/bind
diff --git a/bind/handlers/main.yml b/bind/handlers/main.yml
index 8bb61a21..b426fcd1 100644
--- a/bind/handlers/main.yml
+++ b/bind/handlers/main.yml
@@ -1,19 +1,21 @@
---
- name: reload systemd
- command: systemctl daemon-reload
+ systemd:
+ daemon-reload: yes
+
- name: restart apparmor
- service:
+ systemd:
name: apparmor
state: restarted
- name: restart bind
- service:
+ systemd:
name: bind9
state: restarted
- name: restart munin-node
- service:
+ systemd:
name: munin-node
state: restarted
diff --git a/bind/tasks/authoritative.yml b/bind/tasks/authoritative.yml
new file mode 100644
index 00000000..52992fa1
--- /dev/null
+++ b/bind/tasks/authoritative.yml
@@ -0,0 +1,11 @@
+---
+
+- name: Set bind configuration for authoritative server
+ template:
+ src: named.conf.options_authoritative.j2
+ dest: /etc/bind/named.conf.options
+ owner: bind
+ group: bind
+ mode: "0644"
+ force: yes
+ notify: restart bind
\ No newline at end of file
diff --git a/bind/tasks/main.yml b/bind/tasks/main.yml
index d1348cd2..9b053b6c 100644
--- a/bind/tasks/main.yml
+++ b/bind/tasks/main.yml
@@ -1,22 +1,30 @@
# Until chroot-bind.sh is migrated to ansible, we hardcode the chroot paths.
- name: set chroot variables
set_fact:
- bind_log_file: /var/log/bind.log
- bind_query_file: /var/log/bind_queries.log
- bind_cache_dir: /var/cache/bind
- bind_statistics_file: /var/run/named.stats
- bind_chroot_path: /var/chroot-bind
+ bind_log_file: /var/log/bind.log
+ bind_query_file: /var/log/bind_queries.log
+ bind_cache_dir: /var/cache/bind
+ bind_statistics_file: /var/run/named.stats
+ bind_chroot_path: /var/chroot-bind
when: bind_chroot_set | bool
+- name: Check AppArmor
+ shell: systemctl is-active apparmor || systemctl is-enabled apparmor
+ failed_when: False
+ changed_when: False
+ check_mode: no
+ register: check_apparmor
+
- name: configure apparmor
template:
src: apparmor.usr.sbin.named.j2
dest: /etc/apparmor.d/usr.sbin.named
owner: root
group: root
- mode: '0644'
+ mode: "0644"
force: yes
notify: restart apparmor
+ when: check_apparmor.rc == 0
- name: package are installed
apt:
@@ -25,47 +33,23 @@
- dnstop
state: present
-- name: Set bind configuration for recursive server
- template:
- src: named.conf.options_recursive.j2
- dest: /etc/bind/named.conf.options
- owner: bind
- group: bind
- mode: "0644"
- force: yes
- notify: restart bind
- when: bind_recursive_server | bool
-
-- name: enable zones.rfc1918 for recursive server
- lineinfile:
- dest: /etc/bind/named.conf.local
- line: 'include "/etc/bind/zones.rfc1918";'
- regexp: "zones.rfc1918"
- notify: restart bind
- when: bind_recursive_server | bool
-
-- name: Set bind configuration for authoritative server
- template:
- src: named.conf.options_authoritative.j2
- dest: /etc/bind/named.conf.options
- owner: bind
- group: bind
- mode: "0644"
- force: yes
- notify: restart bind
+- include: authoritative.yml
when: bind_authoritative_server | bool
-- name: Create systemd service
+- include: recursive.yml
+ when: bind_recursive_server | bool
+
+- name: Create systemd service for Debian 8 (Jessie)
template:
- src: bind9.service.j2
+ src: bind9.service.jessie.j2
dest: "{{ bind_systemd_service_path }}"
owner: root
group: root
mode: "0644"
force: yes
notify:
- - reload systemd
- - restart bind
+ - reload systemd
+ - restart bind
when: ansible_distribution_release == "jessie"
- name: "touch {{ bind_log_file }} if non chroot"
diff --git a/bind/tasks/munin.yml b/bind/tasks/munin.yml
index f97ddf85..7bedfd2c 100644
--- a/bind/tasks/munin.yml
+++ b/bind/tasks/munin.yml
@@ -19,7 +19,7 @@
- bind9_rndc
notify: restart munin-node
when:
- - bind_authoritative_server
+ - bind_authoritative_server | bool
- munin_node_plugins_config.stat.exists
tags:
- bind
@@ -32,10 +32,10 @@
state: link
loop:
- bind9
- - bind9_rndc
notify: restart munin-node
when:
- - bind_recursive_server
+ - bind_recursive_server | bool
+ - bind_query_file_enabled | bool
- munin_node_plugins_config.stat.exists
tags:
- bind
diff --git a/bind/tasks/recursive.yml b/bind/tasks/recursive.yml
new file mode 100644
index 00000000..ddbeafbf
--- /dev/null
+++ b/bind/tasks/recursive.yml
@@ -0,0 +1,19 @@
+---
+
+
+- name: Set bind configuration for recursive server
+ template:
+ src: named.conf.options_recursive.j2
+ dest: /etc/bind/named.conf.options
+ owner: bind
+ group: bind
+ mode: "0644"
+ force: yes
+ notify: restart bind
+
+- name: enable zones.rfc1918 for recursive server
+ lineinfile:
+ dest: /etc/bind/named.conf.local
+ line: 'include "/etc/bind/zones.rfc1918";'
+ regexp: "zones.rfc1918"
+ notify: restart bind
diff --git a/bind/templates/apparmor.usr.sbin.named.j2 b/bind/templates/apparmor.usr.sbin.named.j2
index 9a554437..d9f0be04 100644
--- a/bind/templates/apparmor.usr.sbin.named.j2
+++ b/bind/templates/apparmor.usr.sbin.named.j2
@@ -56,7 +56,9 @@
# 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,
diff --git a/bind/templates/bind9.service.j2 b/bind/templates/bind9.service.jessie.j2
similarity index 100%
rename from bind/templates/bind9.service.j2
rename to bind/templates/bind9.service.jessie.j2
diff --git a/bind/templates/logrotate_bind.j2 b/bind/templates/logrotate_bind.j2
index 3fe1589e..c7ec3c30 100644
--- a/bind/templates/logrotate_bind.j2
+++ b/bind/templates/logrotate_bind.j2
@@ -1,7 +1,7 @@
-{% if bind_chroot_set %}
-{{ bind_chroot_path }}{{bind_log_file}} {
+{% if bind_chroot_set | bool %}
+{{ bind_chroot_path }}{{ bind_log_file }} {
{% else %}
-{{bind_log_file}} {
+{{ bind_log_file }} {
{% endif %}
weekly
missingok
diff --git a/bind/templates/munin-env_bind9.j2 b/bind/templates/munin-env_bind9.j2
index de88b27a..2af70548 100644
--- a/bind/templates/munin-env_bind9.j2
+++ b/bind/templates/munin-env_bind9.j2
@@ -1,9 +1,17 @@
[bind*]
user root
-env.logfile {% if bind_chroot_set %}{{ bind_chroot_path }}{% endif %}{{ bind_query_file }}
+{% if bind_query_file_enabled | bool %}
+{% if bind_chroot_set | bool %}
+env.logfile {{ bind_chroot_path }}{{ bind_query_file }}
+{% else %}
+env.logfile {{ bind_query_file }}
+{% endif %}
+{% endif %}
+
{% if bind_authoritative_server %}
env.querystats {% if bind_chroot_set %}{{ bind_chroot_path }}{% endif %}{{ bind_statistics_file }}
{% endif %}
+
env.MUNIN_PLUGSTATE /var/lib/munin
timeout 120
diff --git a/bind/templates/named.conf.options_authoritative.j2 b/bind/templates/named.conf.options_authoritative.j2
index 8f48cbb5..4b6065b6 100644
--- a/bind/templates/named.conf.options_authoritative.j2
+++ b/bind/templates/named.conf.options_authoritative.j2
@@ -1,7 +1,7 @@
-acl "foo" {
- ::ffff:192.0.2.21; 192.0.2.21;
- 2001:db8::21;
-};
+// acl "foo" {
+// ::ffff:192.0.2.21; 192.0.2.21;
+// 2001:db8::21;
+// };
options {
directory "{{ bind_cache_dir }}";
@@ -20,16 +20,20 @@ options {
logging {
category default { default_file; };
+{% if bind_query_file_enabled | bool %}
category queries { query_logging; };
+{% endif %}
channel default_file {
file "{{ bind_log_file }}";
severity info;
};
+{% if bind_query_file_enabled | bool %}
channel query_logging {
file "{{ bind_query_file }}" versions 2 size 128M;
print-category yes;
print-severity yes;
print-time yes;
};
+{% endif %}
};
diff --git a/bind/templates/named.conf.options_recursive.j2 b/bind/templates/named.conf.options_recursive.j2
index 27246d13..931ac71d 100644
--- a/bind/templates/named.conf.options_recursive.j2
+++ b/bind/templates/named.conf.options_recursive.j2
@@ -9,16 +9,20 @@ options {
logging {
category default { default_file; };
+{% if bind_query_file_enabled | bool %}
category queries { query_logging; };
+{% endif %}
channel default_file {
file "{{ bind_log_file }}";
severity info;
};
+{% if bind_query_file_enabled | bool %}
channel query_logging {
file "{{ bind_query_file }}" versions 2 size 128M;
print-category yes;
print-severity yes;
print-time yes;
};
+{% endif %}
};
diff --git a/clamav/tasks/main.yml b/clamav/tasks/main.yml
index 6d1da3eb..f74efae5 100644
--- a/clamav/tasks/main.yml
+++ b/clamav/tasks/main.yml
@@ -13,7 +13,7 @@
- { key: 'clamav-daemon/StreamMaxLength', type: 'string', value: '25' }
- { key: 'clamav-daemon/ReadTimeout', type: 'string', value: '180' }
- { key: 'clamav-daemon/StatsEnabled', type: 'boolean', value: 'false' }
- - { key: 'clamav-daemon/MaxConnectionQueueLength', type: 'string', value: '15' }
+ - { key: 'clamav-daemon/MaxConnectionQueueLength', type: 'string', value: '200' }
- { key: 'clamav-daemon/LogRotate', type: 'boolean', value: 'true' }
- { key: 'clamav-daemon/AllowAllMatchScan', type: 'boolean', value: 'true' }
- { key: 'clamav-daemon/ScanOnAccess', type: 'boolean', value: 'false' }
diff --git a/docker-host/defaults/main.yml b/docker-host/defaults/main.yml
index 44496203..42c9cecc 100644
--- a/docker-host/defaults/main.yml
+++ b/docker-host/defaults/main.yml
@@ -1,7 +1,7 @@
---
# If docher_home sets to /home/, the partition should be mounted with exec option.
docker_home: /var/lib/docker
-docker_tmpdir: "{{docker_home}}/tmp"
+docker_tmpdir: "{{ docker_home }}/tmp"
# Chose to use iptables instead of docker-proxy userland process
docker_conf_use_iptables: False
@@ -20,9 +20,9 @@ docker_remote_access_enabled: False
docker_daemon_port: 2376
docker_daemon_listening_ip: 0.0.0.0
-# TLS
+# TLS
docker_tls_enabled: False
-docker_tls_path: "{{docker_home}}/tls"
+docker_tls_path: "{{ docker_home }}/tls"
docker_tls_ca: ca/ca.pem
docker_tls_ca_key: ca/ca-key.pem
docker_tls_cert: server/cert.pem
diff --git a/docker-host/handlers/main.yml b/docker-host/handlers/main.yml
index 8b484b49..c21a84ef 100644
--- a/docker-host/handlers/main.yml
+++ b/docker-host/handlers/main.yml
@@ -1,6 +1,7 @@
---
- name: reload systemd
- command: systemctl daemon-reload
+ systemd:
+ daemon-reload: yes
- name: restart docker
service:
diff --git a/docker-host/templates/daemon.json.j2 b/docker-host/templates/daemon.json.j2
index 08dcb1b2..a044234b 100644
--- a/docker-host/templates/daemon.json.j2
+++ b/docker-host/templates/daemon.json.j2
@@ -1,40 +1,30 @@
{
- "debug": false,
-
+ "debug": false
{# Docker data-dir (default to /var/lib/docker) #}
- "data-root": "{{ docker_home }}",
-
+ ,"data-root": "{{ docker_home }}"
{# Keep containers running while docker daemon downtime #}
- "live-restore": {{ docker_conf_live_restore | to_json }},,
-
+ ,"live-restore": {{ docker_conf_live_restore | to_json }}
{# Turn on user namespace remaping #}
- "userns-remap": "default",
-
- {% if docker_conf_use_iptables %}
+ ,"userns-remap": "default"
+{% if docker_conf_use_iptables %}
{# Use iptables instead of docker-proxy #}
- "userland-proxy": false,
- "iptables": true,
- {% endif %}
-
+ ,"userland-proxy": false
+ ,"iptables": true
+{% endif %}
{# Disable the possibility for containers processes to gain new privileges #}
- "no-new-privileges": {{ docker_conf_no_newprivileges | to_json }},
-
- {% if docker_conf_disable_default_networking %}
+ ,"no-new-privileges": {{ docker_conf_no_newprivileges | to_json }}
+{% if docker_conf_disable_default_networking %}
{# Disable all default network connectivity #}
- "bridge": "none",
- "icc": false,
- {% endif %}
-
- {% if docker_tls_enabled %}
- "tls": true,
- "tlscert": "{{ docker_tls_path }}/{{ docker_tls_cert }}",
- "tlscacert": "{{ docker_tls_path }}/{{ docker_tls_ca }}",
- "tlskey": "{{ docker_tls_path }}/{{ docker_tls_key }}",
- {% endif %}
-
- {% if docker_remote_access_enabled %}
- "hosts": ["tcp://{{ docker_daemon_listening_ip }}:{{ docker_daemon_port }}", "fd://"]
- {% else %}
- "hosts": ["fd://"]
- {% endif %}
+ ,"bridge": "none"
+ ,"icc": false
+{% endif %}
+{% if docker_tls_enabled %}
+ ,"tls": true
+ ,"tlscert": "{{ docker_tls_path }}/{{ docker_tls_cert }}"
+ ,"tlscacert": "{{ docker_tls_path }}/{{ docker_tls_ca }}"
+ ,"tlskey": "{{ docker_tls_path }}/{{ docker_tls_key }}"
+{% endif %}
+{% if docker_remote_access_enabled %}
+ ,"hosts": ["tcp://{{ docker_daemon_listening_ip }}:{{ docker_daemon_port }}", "fd://"]
+{% endif %}
}
diff --git a/dovecot/tasks/main.yml b/dovecot/tasks/main.yml
index c9de6045..dddd951c 100644
--- a/dovecot/tasks/main.yml
+++ b/dovecot/tasks/main.yml
@@ -87,7 +87,7 @@
name: log2mail
state: present
tags: dovecot
-
+
- name: dovecot is configured in log2mail
blockinfile:
path: /etc/log2mail/config/mail.conf
diff --git a/elasticsearch/tasks/additional_scripts.yml b/elasticsearch/tasks/additional_scripts.yml
index 19e43535..e8373ef8 100644
--- a/elasticsearch/tasks/additional_scripts.yml
+++ b/elasticsearch/tasks/additional_scripts.yml
@@ -2,7 +2,7 @@
- include_role:
name: evolix/remount-usr
- when: elasticsearch_additional_scripts_dir is search ("/usr")
+ when: elasticsearch_additional_scripts_dir is search("/usr")
- name: "{{ elasticsearch_additional_scripts_dir }} exists"
file:
diff --git a/elasticsearch/tasks/configuration.yml b/elasticsearch/tasks/configuration.yml
index 99c311c2..7324f610 100644
--- a/elasticsearch/tasks/configuration.yml
+++ b/elasticsearch/tasks/configuration.yml
@@ -118,6 +118,17 @@
tags:
- config
+- name: Disable garbage collector logs (JDK >= 9)
+ lineinfile:
+ dest: /etc/elasticsearch/jvm.options
+ regexp: "Xlog:gc"
+ line: "#9-:-Xlog:gc*,gc+age=trace,safepoint:file=/opt/my-app/gc.log:utctime,pid,tags:filecount=32,filesize=64m"
+ owner: root
+ group: elasticsearch
+ mode: "0640"
+ tags:
+ - config
+
- name: Configure cluster members
lineinfile:
dest: /etc/elasticsearch/elasticsearch.yml
diff --git a/elasticsearch/tasks/datadir.yml b/elasticsearch/tasks/datadir.yml
index c0c20f05..ef91cf1d 100644
--- a/elasticsearch/tasks/datadir.yml
+++ b/elasticsearch/tasks/datadir.yml
@@ -10,7 +10,7 @@
- name: "read the real datadir"
command: readlink -f /var/lib/elasticsearch
- changed_when: false
+ changed_when: False
register: elasticsearch_current_real_datadir_test
check_mode: no
tags:
diff --git a/elasticsearch/tasks/logs.yml b/elasticsearch/tasks/logs.yml
index 01829dc9..8c5977a4 100644
--- a/elasticsearch/tasks/logs.yml
+++ b/elasticsearch/tasks/logs.yml
@@ -17,3 +17,4 @@
group: root
mode: "0750"
when: is_cron_installed.rc == 0
+
diff --git a/elasticsearch/templates/rotate_elasticsearch_logs.j2 b/elasticsearch/templates/rotate_elasticsearch_logs.j2
index 849a9ca1..981ca433 100644
--- a/elasticsearch/templates/rotate_elasticsearch_logs.j2
+++ b/elasticsearch/templates/rotate_elasticsearch_logs.j2
@@ -8,7 +8,6 @@ MAX_AGE={{ elasticsearch_log_rotate_days | mandatory }}
# Compress logs
find ${LOG_DIR} -type f -user ${USER} -name "*.log.????-??-??" -exec gzip --best {} \;
find ${LOG_DIR} -type f -user ${USER} -name "*-????-??-??.log" -exec gzip --best {} \;
-find ${LOG_DIR} -type f -user ${USER} -name "*.log.??" -not -name "*.gz" -exec gzip --best {} \;
# Delete old logs
-find ${LOG_DIR} -type f -user ${USER} -name "*gz" -ctime +${MAX_AGE} -delete
\ No newline at end of file
+find ${LOG_DIR} -type f -user ${USER} -name "*gz" -ctime +${MAX_AGE} -delete
diff --git a/etc-git/tasks/main.yml b/etc-git/tasks/main.yml
index f71ba552..ac28e1e7 100644
--- a/etc-git/tasks/main.yml
+++ b/etc-git/tasks/main.yml
@@ -6,7 +6,7 @@
state: present
tags:
- etc-git
- when:
+ when:
- ansible_distribution == "Debian"
- name: Install and configure utilities
diff --git a/etc-git/tasks/repository.yml b/etc-git/tasks/repository.yml
index 80987da2..7ebfc773 100644
--- a/etc-git/tasks/repository.yml
+++ b/etc-git/tasks/repository.yml
@@ -2,14 +2,13 @@
- include_role:
name: evolix/remount-usr
- when: repository_path is search ("/usr")
+ when: repository_path is search("/usr")
- name: "{{ repository_path }} is versioned with git"
command: "git init ."
args:
chdir: "{{ repository_path }}"
creates: "{{ repository_path }}/.git/"
- warn: no
register: git_init
tags:
- etc-git
@@ -54,7 +53,6 @@
command: "git log"
args:
chdir: "{{ repository_path }}"
- warn: no
changed_when: False
failed_when: False
register: git_log
@@ -66,7 +64,6 @@
shell: "git add -A . && git commit -m \"Initial commit via Ansible\""
args:
chdir: "{{ repository_path }}"
- warn: no
register: git_commit
when: git_log.rc != 0 or (git_init is defined and git_init is changed)
tags:
diff --git a/etc-git/tasks/utils.yml b/etc-git/tasks/utils.yml
index cd060de1..831f62a6 100644
--- a/etc-git/tasks/utils.yml
+++ b/etc-git/tasks/utils.yml
@@ -51,7 +51,7 @@
register: is_cron_installed
- block:
- - name: Legacy cron jobs for /etc/.git status are absent
+ - name: Legacy cron jobs for /etc/.git status are absent
file:
dest: "{{ item }}"
state: absent
diff --git a/evoacme/templates/evoacme.conf.j2 b/evoacme/templates/evoacme.conf.j2
index 27405f56..eae3ff45 100644
--- a/evoacme/templates/evoacme.conf.j2
+++ b/evoacme/templates/evoacme.conf.j2
@@ -1,9 +1,9 @@
### File generated by Ansible ###
-SSL_KEY_DIR=${SSL_KEY_DIR:-{{ evoacme_ssl_key_dir }}}
-ACME_DIR=${ACME_DIR:-{{ evoacme_acme_dir }}}
-CSR_DIR=${CSR_DIR:-{{ evoacme_csr_dir }}}
-CRT_DIR=${CRT_DIR:-{{ evoacme_crt_dir }}}
+SSL_KEY_DIR=${SSL_KEY_DIR:-{{ evoacme_ssl_key_dir }} }
+ACME_DIR=${ACME_DIR:-{{ evoacme_acme_dir }} }
+CSR_DIR=${CSR_DIR:-{{ evoacme_csr_dir }} }
+CRT_DIR=${CRT_DIR:-{{ evoacme_crt_dir }} }
HOOKS_DIR=${HOOKS_DIR:-"{{ evoacme_hooks_dir }}"}
-LOG_DIR=${LOG_DIR:-{{ evoacme_log_dir }}}
-SSL_MINDAY=${SSL_MINDAY:-{{ evoacme_ssl_minday }}}
+LOG_DIR=${LOG_DIR:-{{ evoacme_log_dir }} }
+SSL_MINDAY=${SSL_MINDAY:-{{ evoacme_ssl_minday }} }
diff --git a/evocheck/files/evocheck.cf b/evocheck/files/evocheck.cf
index 9eca204e..983363f9 100644
--- a/evocheck/files/evocheck.cf
+++ b/evocheck/files/evocheck.cf
@@ -1,5 +1,3 @@
-# Managed by Ansible
-#
# Configuration for evocheck
# Use this file to change configuration values defined in evocheck.sh
# Ex : IS_TMP_1777=0
diff --git a/evocheck/files/evocheck.jessie.sh b/evocheck/files/evocheck.jessie.sh
index a5a32a5a..5d1a186e 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="22.11"
+VERSION="23.03.01"
readonly VERSION
# base functions
diff --git a/evocheck/files/evocheck.sh b/evocheck/files/evocheck.sh
old mode 100644
new mode 100755
index c5cd8fbd..647192cc
--- 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="22.11"
+VERSION="23.03.01"
readonly VERSION
# base functions
@@ -100,6 +100,17 @@ is_installed(){
# logging
+log() {
+ date=$(/bin/date +"${DATE_FORMAT}")
+ if [ "${1}" != '' ]; then
+ printf "[%s] %s: %s\\n" "$date" "${PROGNAME}" "${1}" >> "${LOGFILE}"
+ else
+ while read line; do
+ printf "[%s] %s: %s\\n" "$date" "${PROGNAME}" "${line}" >> "${LOGFILE}"
+ done < /dev/stdin
+ fi
+}
+
failed() {
check_name=$1
shift
@@ -113,6 +124,9 @@ failed() {
printf "%s FAILED!\n" "${check_name}" >> "${main_output_file}"
fi
fi
+
+ # Always log verbose
+ log "${check_name} FAILED! ${check_comments}"
}
# check functions
@@ -131,6 +145,13 @@ check_dpkgwarning() {
test -e /etc/apt/apt.conf.d/z-evolinux.conf \
|| failed "IS_DPKGWARNING" "/etc/apt/apt.conf.d/z-evolinux.conf is missing"
}
+# Check if localhost, localhost.localdomain and localhost.$mydomain are set in Postfix mydestination option.
+check_localhost_in_postfix_mydestination() {
+ # shellcheck disable=SC2016
+ if ! grep mydestination /etc/postfix/main.cf | grep --quiet --extended-regexp '(localhost[^\\.]|localhost.localdomain|localhost.$mydomain)'; then
+ failed "IS_LOCALHOST_IN_POSTFIX_MYDESTINATION" "'localhost' and/or 'localhost.localdomain' and/or 'localhost.\$mydomain' are missing in Postfix mydestination option. Consider adding then."
+ fi
+}
# Verifying check_mailq in Nagios NRPE config file. (Option "-M postfix" need to be set if the MTA is Postfix)
check_nrpepostfix() {
if is_installed postfix; then
@@ -391,7 +412,7 @@ check_log2mailrunning() {
fi
}
check_log2mailapache() {
- conf=/etc/log2mail/config/Apache
+ conf=/etc/log2mail/config/apache
if is_pack_web && is_installed log2mail; then
grep -s -q "^file = /var/log/apache2/error.log" $conf \
|| failed "IS_LOG2MAILAPACHE" "missing log2mail directive for apache"
@@ -463,18 +484,26 @@ check_evobackup() {
evobackup_found=$(find /etc/cron* -name '*evobackup*' | wc -l)
test "$evobackup_found" -gt 0 || failed "IS_EVOBACKUP" "missing evobackup cron"
}
-# Vérification de la mise en place de la purge pour fail2ban
-check_purge_fail2ban() {
+# Vérification de la mise en place d'un cron de purge de la base SQLite de Fail2ban
+check_fail2ban_purge() {
if is_debian_stretch || is_debian_buster; then
if is_installed fail2ban; then
test -f /etc/cron.daily/fail2ban_dbpurge || failed "IS_FAIL2BAN_PURGE" "missing script fail2ban_dbpurge cron"
fi
fi
}
+# Vérification qu'il ne reste pas des jails nommées ssh non renommées en sshd
+check_ssh_fail2ban_jail_renamed() {
+ if is_installed fail2ban && [ -f /etc/fail2ban/jail.local ]; then
+ if grep --quiet --fixed-strings "[ssh]" /etc/fail2ban/jail.local; then
+ failed "IS_SSH_FAIL2BAN_JAIL_RENAMED" "Jail ssh must be renamed sshd in fail2ban >= 0.9."
+ fi
+ fi
+}
# Vérification de l'exclusion des montages (NFS) dans les sauvegardes
check_evobackup_exclude_mount() {
- excludes_file=$(mktemp --tmpdir="${TMPDIR:-/tmp}" "evocheck.evobackup_exclude_mount.XXXXX")
- files_to_cleanup="${files_to_cleanup} ${excludes_file}"
+ excludes_file=$(mktemp --tmpdir "evocheck.evobackup_exclude_mount.XXXXX")
+ files_to_cleanup+=("${excludes_file}")
# shellcheck disable=SC2044
for evobackup_file in $(find /etc/cron* -name '*evobackup*' | grep -v -E ".disabled$"); do
@@ -643,7 +672,7 @@ check_notupgraded() {
fi
done
if $upgraded; then
- last_upgrade=$(date +%s -d "$(zgrep -h upgrade /var/log/dpkg.log* | sort -n | tail -1 | cut -f1 -d ' ')")
+ last_upgrade=$(date +%s -d "$(zgrep --no-filename --no-messages upgrade /var/log/dpkg.log* | sort -n | tail -1 | cut -f1 -d ' ')")
fi
if grep -qs '^mailto="listupgrade-todo@' /etc/evolinux/listupgrade.cnf \
|| grep -qs -E '^[[:digit:]]+[[:space:]]+[[:digit:]]+[[:space:]]+[^\*]' /etc/cron.d/listupgrade; then
@@ -841,10 +870,17 @@ check_redis_backup() {
# You could change the default path in /etc/evocheck.cf
# REDIS_BACKUP_PATH may contain space-separated paths, example:
# REDIS_BACKUP_PATH='/home/backup/redis-instance1/dump.rdb /home/backup/redis-instance2/dump.rdb'
- REDIS_BACKUP_PATH=${REDIS_BACKUP_PATH:-"/home/backup/redis/dump.rdb"}
- for file in ${REDIS_BACKUP_PATH}; do
- test -f "${file}" || failed "IS_REDIS_BACKUP" "Redis dump is missing (${file})"
- done
+ # Old default path: /home/backup/dump.rdb
+ # New default path: /home/backup/redis/dump.rdb
+ if [ -z "${REDIS_BACKUP_PATH}" ]; then
+ if ! [ -f "/home/backup/dump.rdb" ] && ! [ -f "/home/backup/redis/dump.rdb" ]; then
+ failed "IS_REDIS_BACKUP" "Redis dump is missing (/home/backup/dump.rdb or /home/backup/redis/dump.rdb)."
+ fi
+ else
+ for file in ${REDIS_BACKUP_PATH}; do
+ test -f "${file}" || failed "IS_REDIS_BACKUP" "Redis dump ${file} is missing."
+ done
+ fi
fi
}
check_elastic_backup() {
@@ -895,15 +931,15 @@ check_mysqlnrpe() {
grep -q -F "command[check_mysql]=/usr/lib/nagios/plugins/check_mysql" /etc/nagios/nrpe.d/evolix.cfg \
|| failed "IS_MYSQLNRPE" "check_mysql is missing"
fi
- fi
+ fi
}
check_phpevolinuxconf() {
is_debian_stretch && phpVersion="7.0"
is_debian_buster && phpVersion="7.3"
is_debian_bullseye && phpVersion="7.4"
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
+ { test -f "/etc/php/${phpVersion}/cli/conf.d/z-evolinux-defaults.ini" \
+ && test -f "/etc/php/${phpVersion}/cli/conf.d/zzz-evolinux-custom.ini"
} || failed "IS_PHPEVOLINUXCONF" "missing php evolinux config"
fi
}
@@ -929,8 +965,8 @@ check_duplicate_fs_label() {
# Do it only if thereis blkid binary
BLKID_BIN=$(command -v blkid)
if [ -n "$BLKID_BIN" ]; then
- tmpFile=$(mktemp --tmpdir="${TMPDIR:-/tmp}" "evocheck.duplicate_fs_label.XXXXX")
- files_to_cleanup="${files_to_cleanup} ${tmpFile}"
+ tmpFile=$(mktemp --tmpdir "evocheck.duplicate_fs_label.XXXXX")
+ files_to_cleanup+=("${tmpFile}")
parts=$($BLKID_BIN -c /dev/null | grep -ve raid_member -e EFI_SYSPART | grep -Eo ' LABEL=".*"' | cut -d'"' -f2)
for part in $parts; do
@@ -1097,8 +1133,8 @@ check_evobackup_incs() {
bkctld_cron_file=${bkctld_cron_file:-/etc/cron.d/bkctld}
if [ -f "${bkctld_cron_file}" ]; then
root_crontab=$(grep -v "^#" "${bkctld_cron_file}")
- echo "${root_crontab}" | grep -q "bkctld inc" || failed "IS_EVOBACKUP_INCS" "\`bkctld inc' is missing in ${bkctld_cron_file}"
- echo "${root_crontab}" | grep -qE "(check-incs.sh|bkctld check-incs)" || failed "IS_EVOBACKUP_INCS" "\`check-incs.sh' is missing in ${bkctld_cron_file}"
+ echo "${root_crontab}" | grep -q "bkctld inc" || failed "IS_EVOBACKUP_INCS" "'bkctld inc' is missing in ${bkctld_cron_file}"
+ echo "${root_crontab}" | grep -qE "(check-incs.sh|bkctld check-incs)" || failed "IS_EVOBACKUP_INCS" "'check-incs.sh' is missing in ${bkctld_cron_file}"
else
failed "IS_EVOBACKUP_INCS" "Crontab \`${bkctld_cron_file}' is missing"
fi
@@ -1129,7 +1165,7 @@ check_chrooted_binary_uptodate() {
for process_name in ${process_list}; do
# what is the binary path?
original_bin=$(command -v "${process_name}")
- for pid in $(pgrep ${process_name}); do
+ for pid in $(pgrep "${process_name}"); do
process_bin=$(realpath "/proc/${pid}/exe")
# Is the process chrooted?
real_root=$(realpath "/proc/${pid}/root")
@@ -1157,7 +1193,6 @@ check_nginx_letsencrypt_uptodate() {
fi
fi
}
-
check_lxc_container_resolv_conf() {
if is_installed lxc; then
container_list=$(lxc-ls)
@@ -1178,6 +1213,38 @@ check_lxc_container_resolv_conf() {
done
fi
}
+# Check that there are containers if lxc is installed.
+check_no_lxc_container() {
+ if is_installed lxc; then
+ containers_count=$(lxc-ls | wc -l)
+ if [ "$containers_count" -eq 0 ]; then
+ failed "IS_NO_LXC_CONTAINER" "LXC is installed but have no container. Consider removing it."
+ fi
+ fi
+}
+# Check that in LXC containers, phpXX-fpm services have UMask set to 0007.
+check_lxc_php_fpm_service_umask_set() {
+ if is_installed lxc; then
+ php_containers_list=$(lxc-ls --filter php)
+ missing_umask=""
+ for container in $php_containers_list; do
+ # Translate container name in service name
+ if [ "$container" = "php56" ]; then
+ service="php5-fpm"
+ else
+ service="${container:0:4}.${container:4}-fpm"
+ fi
+ umask=$(lxc-attach --name "${container}" -- systemctl show -p UMask "$service" | cut -d "=" -f2)
+ if [ "$umask" != "0007" ]; then
+ missing_umask="${missing_umask} ${container}"
+ fi
+ done
+ if [ -n "${missing_umask}" ]; then
+ failed "IS_LXC_PHP_FPM_SERVICE_UMASK_SET" "UMask is not set to 0007 in PHP-FPM services of theses containers : ${missing_umask}."
+ fi
+ fi
+}
+
download_versions() {
local file
file=${1:-}
@@ -1280,8 +1347,8 @@ add_to_path() {
echo "$PATH" | grep -qF "${new_path}" || export PATH="${PATH}:${new_path}"
}
check_versions() {
- versions_file=$(mktemp --tmpdir="${TMPDIR:-/tmp}" "evocheck.versions.XXXXX")
- files_to_cleanup="${files_to_cleanup} ${versions_file}"
+ versions_file=$(mktemp --tmpdir "evocheck.versions.XXXXX")
+ files_to_cleanup+=("${versions_file}")
download_versions "${versions_file}"
add_to_path "/usr/share/scripts"
@@ -1308,8 +1375,8 @@ main() {
# Detect operating system name, version and release
detect_os
- main_output_file=$(mktemp --tmpdir="${TMPDIR:-/tmp}" "evocheck.main.XXXXX")
- files_to_cleanup="${files_to_cleanup} ${main_output_file}"
+ main_output_file=$(mktemp --tmpdir "evocheck.main.XXXXX")
+ files_to_cleanup+=("${main_output_file}")
test "${IS_TMP_1777:=1}" = 1 && check_tmp_1777
test "${IS_ROOT_0700:=1}" = 1 && check_root_0700
@@ -1322,6 +1389,7 @@ main() {
test "${IS_LSBRELEASE:=1}" = 1 && check_lsbrelease
test "${IS_DPKGWARNING:=1}" = 1 && check_dpkgwarning
+ test "${IS_LOCALHOST_IN_POSTFIX_MYDESTINATION:=1}" = 1 && check_localhost_in_postfix_mydestination
test "${IS_NRPEPOSTFIX:=1}" = 1 && check_nrpepostfix
test "${IS_CUSTOMSUDOERS:=1}" = 1 && check_customsudoers
test "${IS_VARTMPFS:=1}" = 1 && check_vartmpfs
@@ -1367,6 +1435,8 @@ main() {
test "${IS_INTERFACESGW:=1}" = 1 && check_interfacesgw
test "${IS_NETWORKING_SERVICE:=1}" = 1 && check_networking_service
test "${IS_EVOBACKUP:=1}" = 1 && check_evobackup
+ test "${IS_PURGE_FAIL2BAN:=1}" = 1 && check_fail2ban_purge
+ test "${IS_SSH_FAIL2BAN_JAIL_RENAMED:=1}" = 1 && check_ssh_fail2ban_jail_renamed
test "${IS_EVOBACKUP_EXCLUDE_MOUNT:=1}" = 1 && check_evobackup_exclude_mount
test "${IS_USERLOGROTATE:=1}" = 1 && check_userlogrotate
test "${IS_APACHECTL:=1}" = 1 && check_apachectl
@@ -1418,6 +1488,8 @@ main() {
test "${IS_CHROOTED_BINARY_UPTODATE:=1}" = 1 && check_chrooted_binary_uptodate
test "${IS_NGINX_LETSENCRYPT_UPTODATE:=1}" = 1 && check_nginx_letsencrypt_uptodate
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_CHECK_VERSIONS:=1}" = 1 && check_versions
if [ -f "${main_output_file}" ]; then
@@ -1431,9 +1503,12 @@ main() {
exit ${RC}
}
-cleanup_temp_files() {
- # shellcheck disable=SC2086
- rm -f ${files_to_cleanup}
+cleanup() {
+ # Cleanup tmp files
+ # shellcheck disable=SC2086,SC2317
+ rm -f ${files_to_cleanup[@]}
+
+ log "$PROGNAME exit."
}
PROGNAME=$(basename "$0")
@@ -1444,17 +1519,23 @@ readonly PROGNAME
ARGS=$@
readonly ARGS
+LOGFILE="/var/log/evocheck.log"
+readonly LOGFILE
+
+CONFIGFILE="/etc/evocheck.cf"
+readonly CONFIGFILE
+
+DATE_FORMAT="%Y-%m-%d %H:%M:%S"
+# shellcheck disable=SC2034
+readonly DATEFORMAT
+
# Disable LANG*
export LANG=C
export LANGUAGE=C
-files_to_cleanup=""
-# shellcheck disable=SC2064
-trap cleanup_temp_files 0
-
# Source configuration file
# shellcheck disable=SC1091
-test -f /etc/evocheck.cf && . /etc/evocheck.cf
+test -f "${CONFIGFILE}" && . "${CONFIGFILE}"
# Parse options
# based on https://gist.github.com/deshion/10d3cb5f88a21671e17a
@@ -1502,5 +1583,24 @@ while :; do
shift
done
+# Keep this after "show_version(); exit 0" which is called by check_versions
+# to avoid logging exit twice.
+declare -a files_to_cleanup
+files_to_cleanup=""
+# shellcheck disable=SC2064
+trap cleanup EXIT INT TERM
+
+log '-----------------------------------------------'
+log "Running $PROGNAME $VERSION..."
+
+# Log config file content
+if [ -f "${CONFIGFILE}" ]; then
+ log "Runtime configuration (${CONFIGFILE}):"
+ sed -e '/^[[:blank:]]*#/d; s/#.*//; /^[[:blank:]]*$/d' "${CONFIGFILE}" | log
+fi
+
# shellcheck disable=SC2086
main ${ARGS}
+
+log "End of $PROGNAME execution."
+
diff --git a/evocheck/files/evocheck.wheezy.sh b/evocheck/files/evocheck.wheezy.sh
index cd41cb50..cd038268 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="22.11"
+VERSION="23.03.01"
readonly VERSION
# base functions
diff --git a/evocheck/tasks/install.yml b/evocheck/tasks/install.yml
index c996542e..8abd7d57 100644
--- a/evocheck/tasks/install.yml
+++ b/evocheck/tasks/install.yml
@@ -1,7 +1,7 @@
---
- include_role:
name: evolix/remount-usr
- when: evocheck_bin_dir is search ("/usr")
+ when: evocheck_bin_dir is search("/usr")
tags:
- evocheck
diff --git a/evolinux-base/handlers/main.yml b/evolinux-base/handlers/main.yml
index 7331a245..388bf051 100644
--- a/evolinux-base/handlers/main.yml
+++ b/evolinux-base/handlers/main.yml
@@ -23,13 +23,9 @@
- name: remount /home
command: mount -o remount /home
- args:
- warn: no
- name: remount /var
command: mount -o remount /var
- args:
- warn: no
- name: restart nginx
diff --git a/evolinux-base/tasks/hostname.yml b/evolinux-base/tasks/hostname.yml
index 2b9cfa93..ec3f99d1 100644
--- a/evolinux-base/tasks/hostname.yml
+++ b/evolinux-base/tasks/hostname.yml
@@ -4,6 +4,12 @@
name: dbus
state: present
+- name: dbus is enabled and started
+ service:
+ name: dbus
+ state: started
+ enabled: true
+
- name: Set hostname "{{ evolinux_hostname }}"
hostname:
name: "{{ evolinux_hostname }}"
diff --git a/evolinux-base/tasks/packages.yml b/evolinux-base/tasks/packages.yml
index b4a1d666..4c2249e3 100644
--- a/evolinux-base/tasks/packages.yml
+++ b/evolinux-base/tasks/packages.yml
@@ -55,7 +55,6 @@
- mutt
- tree
- git
- - subversion
- rsync
- bc
- pinentry-curses
diff --git a/evolinux-users/tasks/main.yml b/evolinux-users/tasks/main.yml
index d105aefe..1e9cc5a3 100644
--- a/evolinux-users/tasks/main.yml
+++ b/evolinux-users/tasks/main.yml
@@ -16,7 +16,7 @@
vars:
user: "{{ item.value }}"
loop: "{{ evolinux_users | dict2items }}"
- when:
+ when:
- user.create == evolinux_users_create
- evolinux_users | length > 0
diff --git a/evolinux-users/templates/sudoers_jessie.j2 b/evolinux-users/templates/sudoers_jessie.j2
index c0703c49..6bc3e57b 100644
--- a/evolinux-users/templates/sudoers_jessie.j2
+++ b/evolinux-users/templates/sudoers_jessie.j2
@@ -1,6 +1,6 @@
Defaults umask=0077
-Cmnd_Alias MAINT = /usr/share/scripts/evomaintenance.sh, /usr/share/scripts/listupgrade.sh, /usr/bin/apt, /bin/mount
+Cmnd_Alias MAINT = /usr/share/scripts/evomaintenance.sh, /usr/share/scripts/listupgrade.sh
User_Alias ADMINS = {{ user.name }}
nagios ALL = NOPASSWD: /usr/lib/nagios/plugins/check_procs
diff --git a/evolinux-users/templates/sudoers_stretch.j2 b/evolinux-users/templates/sudoers_stretch.j2
index 8211f121..287483d9 100644
--- a/evolinux-users/templates/sudoers_stretch.j2
+++ b/evolinux-users/templates/sudoers_stretch.j2
@@ -1,6 +1,6 @@
Defaults umask=0077
-Cmnd_Alias MAINT = /usr/share/scripts/evomaintenance.sh, /usr/share/scripts/listupgrade.sh, /usr/bin/apt, /bin/mount
+Cmnd_Alias MAINT = /usr/share/scripts/evomaintenance.sh, /usr/share/scripts/listupgrade.sh
nagios ALL = NOPASSWD: /usr/lib/nagios/plugins/check_procs
nagios ALL = NOPASSWD: /usr/local/lib/nagios/plugins/check_minifirewall
diff --git a/fail2ban/files/dovecot-evolix.conf b/fail2ban/files/dovecot-evolix.conf
index e1ef1a3f..5c18fb9f 100644
--- a/fail2ban/files/dovecot-evolix.conf
+++ b/fail2ban/files/dovecot-evolix.conf
@@ -1,3 +1,3 @@
[Definition]
-failregex = (?: pop3-login|imap-login): .*(?:Authentication failure|Aborted login \(auth failed|Aborted login \(tried to use disabled|Disconnected \(auth failed|Aborted login \(\d+ authentication attempts).*rip=,.*
+failregex = (?: pop3-login|imap-login): .*(?:Authentication failure|Internal login failure|Aborted login \(auth failed|Aborted login \(tried to use disabled|Disconnected \(auth failed|Aborted login \(\d+ authentication attempts).*rip=,.*
ignoreregex =
diff --git a/fail2ban/tasks/fix-dbpurgeage.yml b/fail2ban/tasks/fix-dbpurgeage.yml
index 67819a3f..dbf9c0d9 100644
--- a/fail2ban/tasks/fix-dbpurgeage.yml
+++ b/fail2ban/tasks/fix-dbpurgeage.yml
@@ -1,3 +1,4 @@
+---
- name: Sqlite needed
ansible.builtin.apt:
name:
@@ -6,10 +7,20 @@
- name: Register bantime from default config from package
shell: "grep -R -E 'dbpurgeage[[:blank:]]*=[[:blank:]]*[0-9]+' /etc/fail2ban/fail2ban.conf |awk '{print $3}'|head -n1"
- register: default_dbpurgeage
- changed_when: false
+ register: dbpurgeage
+ changed_when: False
check_mode: false
+- name:
+ set_fact:
+ dbpurgeage_default : "{{ dbpurgeage.stdout }}"
+ when: dbpurgeage.stdout | regex_search("^\\d+\w+$")
+
+- name:
+ set_fact:
+ dbpurgeage_default : "{{ dbpurgeage.stdout }} second"
+ when: dbpurgeage.stdout | regex_search("^\\d+$")
+
- name: Add crontab
template:
src: fail2ban_dbpurge.j2
diff --git a/fail2ban/tasks/main.yml b/fail2ban/tasks/main.yml
index 08478112..b9c2d109 100644
--- a/fail2ban/tasks/main.yml
+++ b/fail2ban/tasks/main.yml
@@ -97,7 +97,7 @@
marker: "# ANSIBLE MANAGED"
block: |
[DEFAULT]
- dbpurgeage = {{ fail2ban_recidive_bantime}}
+ dbpurgeage = {{ fail2ban_recidive_bantime }}
insertafter: EOF
create: yes
mode: "0644"
diff --git a/fail2ban/templates/fail2ban_dbpurge.j2 b/fail2ban/templates/fail2ban_dbpurge.j2
index ee984438..8b6d9612 100644
--- a/fail2ban/templates/fail2ban_dbpurge.j2
+++ b/fail2ban/templates/fail2ban_dbpurge.j2
@@ -2,7 +2,7 @@
# Juin - Decembre 2022 : #64088
# Purge pour Stretch et Buster
-/usr/bin/ionice -c3 /usr/bin/sqlite3 /var/lib/fail2ban/fail2ban.sqlite3 "DELETE FROM bans WHERE datetime('now', '-{{ bantime.stdout }} second') > datetime(timeofban, 'unixepoch');"
+/usr/bin/ionice -c3 /usr/bin/sqlite3 /var/lib/fail2ban/fail2ban.sqlite3 "DELETE FROM bans WHERE datetime('now', '-{{ dbpurgeage_default }}') > datetime(timeofban, 'unixepoch');"
place_dispo=$( df -h /var/lib/fail2ban/fail2ban.sqlite3 --output="avail" -h --block-size=1 |tail -n1 )
place_pris=$( echo $(("$(stat --format %s /var/lib/fail2ban/fail2ban.sqlite3 ) * 2" )) )
diff --git a/fail2ban/templates/jail.local.j2 b/fail2ban/templates/jail.local.j2
index 3738ee33..6713c92e 100644
--- a/fail2ban/templates/jail.local.j2
+++ b/fail2ban/templates/jail.local.j2
@@ -16,7 +16,7 @@ destemail = {{ fail2ban_alert_email or general_alert_email | mandatory }}
# ACTIONS
banaction = iptables-multiport
-action = %({{fail2ban_default_action}})s
+action = %({{ fail2ban_default_action }})s
[sshd]
diff --git a/filebeat/tasks/main.yml b/filebeat/tasks/main.yml
index fa24a893..20858669 100644
--- a/filebeat/tasks/main.yml
+++ b/filebeat/tasks/main.yml
@@ -84,8 +84,8 @@
command: grep logstash-input-beats /usr/share/logstash/Gemfile
check_mode: no
register: logstash_plugin_installed
- failed_when: false
- changed_when: false
+ failed_when: False
+ changed_when: False
when:
- filebeat_logstash_plugin | bool
- logstash_plugin.stat.exists
diff --git a/haproxy/templates/haproxy.default.cfg.j2 b/haproxy/templates/haproxy.default.cfg.j2
index e33d111a..0f13e54d 100644
--- a/haproxy/templates/haproxy.default.cfg.j2
+++ b/haproxy/templates/haproxy.default.cfg.j2
@@ -63,7 +63,7 @@ listen stats
acl stats_users http_auth(stats_users)
stats http-request auth realm "HAProxy admin" if !stats_access_ips !stats_users
{% else %}
- stats http-request deny if !stats_access_ips
+ stats http-request deny if !stats_access_ips !stats_admin_ips
{% endif %}
http-request set-log-level silent
diff --git a/java/tasks/openjdk.yml b/java/tasks/openjdk.yml
index 4af3cec1..13135d9c 100644
--- a/java/tasks/openjdk.yml
+++ b/java/tasks/openjdk.yml
@@ -25,7 +25,7 @@
- name: Install specific openjdk package
apt:
- name: "openjdk-{{ java_version}}-jre-headless"
+ name: "openjdk-{{ java_version }}-jre-headless"
default_release: "{{ java_apt_release }}"
state: present
tags:
diff --git a/keepalived/files/notify.sh b/keepalived/files/notify.sh
index b99c0489..7844a341 100644
--- a/keepalived/files/notify.sh
+++ b/keepalived/files/notify.sh
@@ -1,2 +1,3 @@
#!/bin/bash
echo $1 $2 is in $3 state > /var/run/keepalive.state
+chmod og+r /var/run/keepalive.state
diff --git a/kibana/tasks/main.yml b/kibana/tasks/main.yml
index e6377dde..341bfd13 100644
--- a/kibana/tasks/main.yml
+++ b/kibana/tasks/main.yml
@@ -126,8 +126,6 @@
# - name: Get mount options for /usr partition
# shell: "mount | grep 'on /usr type'"
-# args:
-# warn: no
# register: mount
# changed_when: False
# failed_when: False
diff --git a/kvm-host/files/kvmstats.sh b/kvm-host/files/kvmstats.sh
index 0dcfb4e8..0258b322 100755
--- a/kvm-host/files/kvmstats.sh
+++ b/kvm-host/files/kvmstats.sh
@@ -42,25 +42,34 @@ error () {
main() {
for VM in $(virsh list --name --all | sed '/^$/d' | sort)
do
- echo "$VM"
-
- # cpu
- virsh vcpucount --current "$VM"
-
- # mem
- # libvirt stores memory in KiB, POW must be lowered by 1
- virsh dommemstat "$VM" 2>/dev/null | awk 'BEGIN{ret=1}$1~/^actual$/{print $2 / '$((POW / 1024))';ret=0}END{exit ret}' ||
- virsh dumpxml "$VM" | awk -F'[<>]' '$2~/^memory unit/{print $3/'$((POW / 1024))'}'
-
- # disk
- for BLK in $(virsh domblklist "$VM" | sed '1,2d;/-$/d;/^$/d' | awk '{print $1}')
- do
- virsh domblkinfo "$VM" "$BLK" 2>/dev/null
- done | awk '/Physical:/ { size += $2 } END { print int(size / '${POW}') }'
-
- # state
- virsh domstate "$VM" | grep -q '^running$' && echo yes || echo no
- done | xargs -n5 | {
+ printf '%s ' "${VM}"
+ virsh domstats "${VM}" | awk '
+BEGIN {
+ FS = "="
+}
+/vcpu\.current/ {
+ vcpu = $2
+}
+/balloon\.current/ {
+ mem = $2
+}
+/balloon\.maximum/ {
+ if (!mem)
+ mem = $2
+}
+/block\.[0-9]+\.physical/ {
+ disksize += $2
+}
+/state\.state/ {
+ if ($2 == 1)
+ running = "yes"
+ else
+ running = "no"
+}
+END {
+ print vcpu, mem / 1024 ^ 2, disksize / 1024 ^ 3, running
+}'
+ done | {
echo vm vcpu ram disk running
awk '{ print } /yes$/ { vcpu += $2; ram += $3; disk += $4; running++ } END { print "TOTAL(running)", vcpu, ram, disk, running }'
test "$SHOW_AVAIL" && {
@@ -72,7 +81,19 @@ main() {
column -t
;;
'html')
- awk 'BEGIN{print "\n"}{printf "";for(i=1;i<=NF;i++)printf "%s | ", $i;print "
"}END{print "
\n"}'
+ awk '
+BEGIN {
+ print "\n"
+}
+{
+ printf ""
+ for(i = 1; i <= NF; i++)
+ printf "%s | ", $i
+ print "
"
+}
+END {
+ print "
\n"
+}'
;;
'csv')
tr ' ' ','
diff --git a/kvm-host/tasks/ssh.yml b/kvm-host/tasks/ssh.yml
index 3c097abc..d954bc06 100644
--- a/kvm-host/tasks/ssh.yml
+++ b/kvm-host/tasks/ssh.yml
@@ -9,7 +9,7 @@
command: cat /root/.ssh/id_rsa.pub
register: ssh_keys
check_mode: no
- changed_when: false
+ changed_when: False
- name: Print ssh public keys
debug:
diff --git a/kvm-host/tasks/tools.yml b/kvm-host/tasks/tools.yml
index 83845a31..1e114bb7 100644
--- a/kvm-host/tasks/tools.yml
+++ b/kvm-host/tasks/tools.yml
@@ -8,7 +8,7 @@
- include_role:
name: remount-usr
- when: kvm_scripts_dir is search ("/usr")
+ when: kvm_scripts_dir is search("/usr")
- name: add-vm script is present
copy:
diff --git a/listupgrade/files/listupgrade.sh b/listupgrade/files/listupgrade.sh
index 3e1baa39..e6518f43 100644
--- a/listupgrade/files/listupgrade.sh
+++ b/listupgrade/files/listupgrade.sh
@@ -9,13 +9,13 @@
# - 60 : current release is not in the $r_releases list
# - 70 : at least an upgradable package is not in the $r_packages list
-VERSION="21.06.3"
+VERSION="23.03.3"
show_version() {
cat <,
+Copyright 2018-2023 Evolix ,
Gregory Colpart ,
Romain Dessort ,
Ludovic Poujol ,
@@ -84,6 +84,7 @@ Subject: Prochain creneau pour mise a jour de votre serveur ${hostname}
X-Debian-Release: ${local_release}
X-Packages: ${packagesParsable}
X-Date: ${date}
+X-Listupgrade-Version: ${VERSION}
Bonjour,
@@ -100,15 +101,15 @@ semaine prochaine.
Voici la listes de packages qui seront mis à jour :
-$(cat "${packages}" | sort | uniq)
+$(sort -h "${packages}" | uniq)
Liste des packages dont la mise-à-jour a été manuellement suspendue :
-$(cat "${packagesHold}" | sort | uniq)
+$(sort -h "${packagesHold}" | uniq)
Liste des services qui seront redémarrés :
-$(cat "${servicesToRestart}" | sort | uniq)
+$(sort -h "${servicesToRestart}" | uniq)
N'hésitez pas à nous faire toute remarque sur ce créneau d'intervention le plus
tôt possible.
@@ -181,6 +182,28 @@ main() {
fi
local_release=$(cut -f 1 -d . &2
else
- # store current state
+ # store current state (without colors)
mkdir -p "$(dirname "${STATE_FILE_CURRENT}")"
- status_without_numbers > "${STATE_FILE_CURRENT}"
+ status_without_numbers | remove_colors > "${STATE_FILE_CURRENT}"
# clean previous diff file
rm -f "${STATE_FILE_DIFF}"
@@ -310,9 +313,9 @@ report_state_changes() {
check_unpersisted_state
fi
- # Then reset the known state
+ # Then reset the known state (without colors)
mkdir -p "$(dirname "${STATE_FILE_LATEST}")"
- status_without_numbers > "${STATE_FILE_LATEST}"
+ status_without_numbers | remove_colors > "${STATE_FILE_LATEST}"
# But if there is a previous known state
# let's compare with the new known state
@@ -920,8 +923,9 @@ stop() {
printf "${BLUE}flushing all rules and accepting everything${RESET}\n"
+ # Save previous state (without colors)
mkdir -p "$(dirname "${STATE_FILE_PREVIOUS}")"
- status_without_numbers > "${STATE_FILE_PREVIOUS}"
+ status_without_numbers | remove_colors > "${STATE_FILE_PREVIOUS}"
# Delete all rules
${IPT} -F INPUT
diff --git a/minifirewall/tasks/main.yml b/minifirewall/tasks/main.yml
index bc56b7dc..e0dbcaf0 100644
--- a/minifirewall/tasks/main.yml
+++ b/minifirewall/tasks/main.yml
@@ -6,6 +6,8 @@
stat:
path: /etc/init.d/minifirewall
register: _minifirewall_check
+ tags:
+ - always
# Legacy versions of minifirewall don't define the VERSION variable
- name: Look for minifirewall version
@@ -14,6 +16,8 @@
changed_when: False
check_mode: False
register: _minifirewall_version_check
+ tags:
+ - always
- name: Set install mode to legacy if needed
set_fact:
@@ -24,21 +28,30 @@
- minifirewall_install_mode != 'modern'
- not (minifirewall_force_upgrade_script | bool)
- _minifirewall_version_check.rc == 1 # grep didn't find but the file exists
+ tags:
+ - always
- name: Set install mode to modern if not legacy
set_fact:
minifirewall_install_mode: modern
when: minifirewall_install_mode != 'legacy'
+ tags:
+ - always
- name: Debug install mode
debug:
var: minifirewall_install_mode
verbosity: 1
+ tags:
+ - always
- name: 'Set minifirewall_restart_handler_name to "noop"'
set_fact:
minifirewall_restart_handler_name: "restart minifirewall (noop)"
- when: not (minifirewall_restart_if_needed | bool)
+ when:
+ - not (minifirewall_restart_if_needed | bool)
+ tags:
+ - always
- name: 'Set minifirewall_restart_handler_name to "legacy"'
set_fact:
@@ -46,6 +59,8 @@
when:
- minifirewall_restart_if_needed | bool
- minifirewall_install_mode == 'legacy'
+ tags:
+ - always
- name: 'Set minifirewall_restart_handler_name to "modern"'
set_fact:
@@ -53,6 +68,8 @@
when:
- minifirewall_restart_if_needed | bool
- minifirewall_install_mode != 'legacy'
+ tags:
+ - always
#######################################################################
@@ -62,54 +79,74 @@
when:
- minifirewall_install_mode != 'legacy'
- minifirewall_main_file is defined
+ tags:
+ - always
- name: Install tasks (modern mode)
- include: install.yml
+ import_tasks: install.yml
when: minifirewall_install_mode != 'legacy'
- name: Install tasks (legacy mode)
- include: install.legacy.yml
+ import_tasks: install.legacy.yml
when: minifirewall_install_mode == 'legacy'
- name: Debug minifirewall_update_config
debug:
var: minifirewall_update_config | bool
verbosity: 1
+ tags:
+ - always
- name: Config tasks (modern mode)
- include: config.yml
+ include_tasks: config.yml
when:
- minifirewall_install_mode != 'legacy'
- minifirewall_update_config | bool
+ tags:
+ - manage
- name: Config tasks (legacy mode)
- include: config.legacy.yml
+ include_tasks: config.legacy.yml
+ args:
+ apply:
+ tags:
+ - manage
when:
- minifirewall_install_mode == 'legacy'
- minifirewall_update_config | bool
- name: Utils tasks
- include: utils.yml
+ include_tasks: utils.yml
- name: NRPE tasks
- include: nrpe.yml
+ include_tasks: nrpe.yml
- name: Activation tasks
- include: activate.yml
+ include_tasks: activate.yml
- name: Debug minifirewall_tail_included
debug:
var: minifirewall_tail_included | bool
verbosity: 1
+ tags:
+ - always
- name: Tail tasks (modern mode)
- include: tail.yml
+ include_tasks: tail.yml
+ args:
+ apply:
+ tags:
+ - manage
when:
- minifirewall_install_mode != 'legacy'
- minifirewall_tail_included | bool
- name: Tail tasks (legacy mode)
- include: tail.legacy.yml
+ include_tasks: tail.legacy.yml
+ args:
+ apply:
+ tags:
+ - manage
when:
- minifirewall_install_mode == 'legacy'
- minifirewall_tail_included | bool
@@ -120,10 +157,14 @@
debug:
var: minifirewall_restart_force | bool
verbosity: 1
+ tags:
+ - always
- name: Force restart minifirewall (legacy)
command: /bin/true
notify: "restart minifirewall (legacy)"
+ tags:
+ - always
when:
- minifirewall_install_mode == 'legacy'
- minifirewall_restart_force | bool
@@ -131,6 +172,8 @@
- name: Force restart minifirewall (modern)
command: /bin/true
notify: "restart minifirewall (modern)"
+ tags:
+ - always
when:
- minifirewall_install_mode != 'legacy'
- minifirewall_restart_force | bool
\ No newline at end of file
diff --git a/mongodb/tasks/main_bullseye.yml b/mongodb/tasks/main_bullseye.yml
index cd8bb15f..c17642ea 100644
--- a/mongodb/tasks/main_bullseye.yml
+++ b/mongodb/tasks/main_bullseye.yml
@@ -3,7 +3,7 @@
- fail:
msg: Not compatible with Debian 11 (Bullseye)
when:
- - ansible_distribution_release == "bullseye"
+ - ansible_distribution_release == "bullseye"
- mongodb_version is version('5.0', '<')
- name: Look for legacy apt keyring
@@ -20,8 +20,8 @@
- name: Add MongoDB GPG key
copy:
- src: "server-{{mongodb_version}}.asc"
- dest: "{{ apt_keyring_dir }}/mongodb-server-{{mongodb_version}}.asc"
+ src: "server-{{ mongodb_version }}.asc"
+ dest: "{{ apt_keyring_dir }}/mongodb-server-{{ mongodb_version }}.asc"
force: yes
mode: "0644"
owner: root
@@ -29,16 +29,16 @@
- name: Enable APT sources list
apt_repository:
- repo: "deb [signed-by={{ apt_keyring_dir }}/mongodb-server-{{mongodb_version}}.asc] http://repo.mongodb.org/apt/debian bullseye/mongodb-org/{{mongodb_version}} main"
+ repo: "deb [signed-by={{ apt_keyring_dir }}/mongodb-server-{{ mongodb_version }}.asc] http://repo.mongodb.org/apt/debian bullseye/mongodb-org/{{ mongodb_version }} main"
state: present
- filename: "mongodb-org-{{mongodb_version}}"
+ filename: "mongodb-org-{{ mongodb_version }}"
update_cache: yes
- name: Disable unsigned APT sources list
apt_repository:
- repo: "deb http://repo.mongodb.org/apt/debian bullseye/mongodb-org/{{mongodb_version}} main"
+ repo: "deb http://repo.mongodb.org/apt/debian bullseye/mongodb-org/{{ mongodb_version }} main"
state: absent
- filename: "mongodb-org-{{mongodb_version}}"
+ filename: "mongodb-org-{{ mongodb_version }}"
update_cache: yes
- name: Install packages
diff --git a/mongodb/tasks/main_buster.yml b/mongodb/tasks/main_buster.yml
index 5d2024c8..44baabc9 100644
--- a/mongodb/tasks/main_buster.yml
+++ b/mongodb/tasks/main_buster.yml
@@ -14,7 +14,7 @@
- name: Add MongoDB GPG key
copy:
- src: "server-{{mongodb_version}}.asc"
+ src: "server-{{ mongodb_version }}.asc"
dest: "{{ apt_keyring_dir }}/mongodb-server-{{ mongodb_version }}.asc"
force: yes
mode: "0644"
@@ -25,14 +25,14 @@
apt_repository:
repo: "deb [signed-by={{ apt_keyring_dir }}/mongodb-server-{{ mongodb_version }}.asc] http://repo.mongodb.org/apt/debian buster/mongodb-org/{{ mongodb_version }} main"
state: present
- filename: "mongodb-org-{{mongodb_version}}"
+ filename: "mongodb-org-{{ mongodb_version }}"
update_cache: yes
- name: Disable unsigned APT sources list
apt_repository:
repo: "deb http://repo.mongodb.org/apt/debian buster/mongodb-org/{{ mongodb_version }} main"
state: absent
- filename: "mongodb-org-{{mongodb_version}}"
+ filename: "mongodb-org-{{ mongodb_version }}"
update_cache: yes
- name: Install packages
diff --git a/mongodb/tasks/main_jessie.yml b/mongodb/tasks/main_jessie.yml
index 7fdb3df5..bc239393 100644
--- a/mongodb/tasks/main_jessie.yml
+++ b/mongodb/tasks/main_jessie.yml
@@ -14,8 +14,8 @@
- name: Add MongoDB GPG key
copy:
- src: "server-{{mongodb_version}}.asc"
- dest: "/etc/apt/trusted.gpg.d/mongodb-server-{{mongodb_version}}.asc"
+ src: "server-{{ mongodb_version }}.asc"
+ dest: "/etc/apt/trusted.gpg.d/mongodb-server-{{ mongodb_version }}.asc"
force: yes
mode: "0644"
owner: root
@@ -23,16 +23,16 @@
- name: Enable APT sources list
apt_repository:
- repo: "deb http://repo.mongodb.org/apt/debian jessie/mongodb-org/{{mongodb_version}} main"
+ repo: "deb http://repo.mongodb.org/apt/debian jessie/mongodb-org/{{ mongodb_version }} main"
state: present
- filename: "mongodb-org-{{mongodb_version}}"
+ filename: "mongodb-org-{{ mongodb_version }}"
update_cache: yes
- name: Disable APT sources list
apt_repository:
- repo: "deb http://repo.mongodb.org/apt/debian jessie/mongodb-org/{{mongodb_version}} main"
+ repo: "deb http://repo.mongodb.org/apt/debian jessie/mongodb-org/{{ mongodb_version }} main"
state: absent
- filename: "mongodb-org-{{mongodb_version}}"
+ filename: "mongodb-org-{{ mongodb_version }}"
update_cache: yes
- name: Install packages
diff --git a/munin/tasks/main.yml b/munin/tasks/main.yml
index a4ea9a49..6d3098dd 100644
--- a/munin/tasks/main.yml
+++ b/munin/tasks/main.yml
@@ -85,7 +85,7 @@
src: /usr/share/munin/plugins/sensors_
dest: "/etc/munin/plugins/sensors_{{ item }}"
state: link
- with_items:
+ with_items:
- fan
- temp
when: ansible_virtualization_role == "host"
diff --git a/mysql-oracle/tasks/utils.yml b/mysql-oracle/tasks/utils.yml
index e0520cee..82b0ddbe 100644
--- a/mysql-oracle/tasks/utils.yml
+++ b/mysql-oracle/tasks/utils.yml
@@ -5,7 +5,7 @@
- include_role:
name: evolix/remount-usr
- when: _mysql_scripts_dir is search ("/usr")
+ when: _mysql_scripts_dir is search("/usr")
- name: Scripts directory exists
file:
@@ -106,7 +106,7 @@
name: evolix/remount-usr
tags:
- mysql
- when: _mysql_scripts_dir is search ("/usr")
+ when: _mysql_scripts_dir is search("/usr")
- name: mysqltuner is installed
# copy:
@@ -132,7 +132,7 @@
name: evolix/remount-usr
tags:
- mysql
- when: _mysql_scripts_dir is search ("/usr")
+ when: _mysql_scripts_dir is search("/usr")
- name: mysql-optimize.sh is installed
copy:
@@ -203,7 +203,7 @@
- include_role:
name: evolix/remount-usr
- when: _mysql_scripts_dir is search ("/usr")
+ when: _mysql_scripts_dir is search("/usr")
- name: Install my-add.sh
copy:
diff --git a/mysql/defaults/main.yml b/mysql/defaults/main.yml
index 80f526c6..af43f495 100644
--- a/mysql/defaults/main.yml
+++ b/mysql/defaults/main.yml
@@ -50,8 +50,10 @@ mysql_restart_if_needed: True
mysql_performance_schema: True
+mysql_skip_enabled: False
+
# replication variables:
-mysql_replication: false
+mysql_replication: False
mysql_log_bin: null
mysql_binlog_format: mixed
mysql_server_id: null
diff --git a/mysql/files/mysql_skip.sh b/mysql/files/mysql_skip.sh
new file mode 100644
index 00000000..95bc28f7
--- /dev/null
+++ b/mysql/files/mysql_skip.sh
@@ -0,0 +1,47 @@
+#!/bin/sh
+
+# File containing error messages to skip (one per line).
+error_messages="/etc/mysql_skip.conf"
+
+# Sleep interval between 2 check.
+sleep_interval="1"
+
+# Exit when Seconds_Behind_Master reached 0.
+exit_when_uptodate="false"
+
+# Options to pass to mysql.
+#mysql_opt="-P 3307"
+
+# File to log skipped queries to (leave empty for no logs).
+log_file="/var/log/mysql_skip.log"
+
+mysql_skip_error() {
+ error="$1"
+
+ error="$(date --iso-8601=seconds) Skiping: $error"
+ printf "Skipping: $error\n"
+ mysql $mysql_opt -e 'SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; START SLAVE;'
+
+ [ -n "$log_file" ] && echo "$error" >>"$log_file"
+}
+
+while true; do
+ slave_status="$(mysql $mysql_opt -e 'SHOW SLAVE STATUS\G')"
+ seconds_behind_master=$(echo "$slave_status" |grep 'Seconds_Behind_Master: ' |awk -F ' ' '{print $2}')
+ last_SQL_error="$(echo "$slave_status" |grep 'Last_SQL_Error: ' |sed 's/^.\+Last_SQL_Error: //')"
+
+ if [ "$seconds_behind_master" = "0" ]; then
+ #printf 'Replication is up to date!\n'
+ if [ "$exit_when_uptodate" = "true" ]; then
+ exit 0
+ fi
+
+ elif [ -z "$last_SQL_error" ]; then
+ sleep $sleep_interval
+
+ elif echo "$last_SQL_error" |grep -q -f $error_messages; then
+ mysql_skip_error "$last_SQL_error"
+
+ fi
+ sleep 1
+done
diff --git a/mysql/tasks/main.yml b/mysql/tasks/main.yml
index 70a972f3..95cde4a1 100644
--- a/mysql/tasks/main.yml
+++ b/mysql/tasks/main.yml
@@ -45,3 +45,5 @@
- include_tasks: log2mail.yml
- include_tasks: utils.yml
+
+- include_tasks: mysql_skip.yml
diff --git a/mysql/tasks/mysql_skip.yml b/mysql/tasks/mysql_skip.yml
new file mode 100644
index 00000000..65d1c13f
--- /dev/null
+++ b/mysql/tasks/mysql_skip.yml
@@ -0,0 +1,54 @@
+---
+
+- name: "Copy script mysql_skip.sh into /usr/local/bin/"
+ copy:
+ src: mysql_skip.sh
+ dest: "/usr/local/bin/mysql_skip.sh"
+ owner: root
+ group: root
+ mode: "0700"
+ force: yes
+ tags:
+ - mysql_skip
+
+- name: "Copy config file for mysql_skip.sh"
+ template:
+ src: mysql_skip.conf.j2
+ dest: "/etc/mysql_skip.conf"
+ owner: root
+ group: root
+ mode: "0600"
+ tags:
+ - mysql_skip
+
+- name: "Create log file for mysql_skip.sh"
+ file:
+ path: "/var/log/mysql_skip.log"
+ state: touch
+ owner: root
+ group: adm
+ mode: "0640"
+ tags:
+ - mysql_skip
+
+- name: "Copy logrotate file for mysql_skip.sh"
+ template:
+ src: mysql_skip.logrotate.j2
+ dest: "/etc/logrotate.d/mysql_skip"
+ owner: root
+ group: root
+ mode: "0600"
+ tags:
+ - mysql_skip
+
+- name: "Copy mysql_skip.sh systemd unit"
+ template:
+ src: mysql_skip.systemd.j2
+ dest: /etc/systemd/system/mysql_skip.service
+ force: yes
+
+- name: "Start or stop systemd unit"
+ systemd:
+ name: mysql_skip
+ daemon_reload: yes
+ state: "{{ mysql_skip_enabled | bool | ternary('started', 'stopped') }}"
\ No newline at end of file
diff --git a/mysql/tasks/utils.yml b/mysql/tasks/utils.yml
index 1ac8f2df..8adbb1be 100644
--- a/mysql/tasks/utils.yml
+++ b/mysql/tasks/utils.yml
@@ -5,7 +5,7 @@
- include_role:
name: evolix/remount-usr
- when: _mysql_scripts_dir is search ("/usr")
+ when: _mysql_scripts_dir is search("/usr")
- name: Ensure scripts directory exists
file:
@@ -96,7 +96,7 @@
- include_role:
name: evolix/remount-usr
- when: _mysql_scripts_dir is search ("/usr")
+ when: _mysql_scripts_dir is search("/usr")
- name: Install mysqltuner
# copy:
@@ -132,7 +132,7 @@
- include_role:
name: evolix/remount-usr
- when: _mysql_scripts_dir is search ("/usr")
+ when: _mysql_scripts_dir is search("/usr")
- name: Optimize script for MySQL
copy:
@@ -196,7 +196,7 @@
- include_role:
name: evolix/remount-usr
- when: _mysql_scripts_dir is search ("/usr")
+ when: _mysql_scripts_dir is search("/usr")
- name: Install my-add.sh
copy:
diff --git a/mysql/templates/mysql_skip.conf.j2 b/mysql/templates/mysql_skip.conf.j2
new file mode 100644
index 00000000..3c8ef5fc
--- /dev/null
+++ b/mysql/templates/mysql_skip.conf.j2
@@ -0,0 +1 @@
+## Put your matched patern here ##
diff --git a/mysql/templates/mysql_skip.logrotate.j2 b/mysql/templates/mysql_skip.logrotate.j2
new file mode 100644
index 00000000..4a75b3ea
--- /dev/null
+++ b/mysql/templates/mysql_skip.logrotate.j2
@@ -0,0 +1,10 @@
+/var/log/mysql_skip.log {
+ missingok
+ notifempty
+ monthly
+ rotate 12
+ compress
+ create 640 root adm
+ dateext
+ dateformat -%Y%m%d%H
+}
\ No newline at end of file
diff --git a/mysql/templates/mysql_skip.systemd.j2 b/mysql/templates/mysql_skip.systemd.j2
new file mode 100644
index 00000000..afe44700
--- /dev/null
+++ b/mysql/templates/mysql_skip.systemd.j2
@@ -0,0 +1,16 @@
+[Unit]
+Description=Script for skip define mysql replication errors
+
+[Service]
+ExecStart=/usr/local/bin/mysql_skip.sh
+Type=simple
+User=root
+Group=root
+PIDFile=/run/mysql_skip.pid
+ExecStop=/bin/kill -- $MAINPID
+KillMode=process
+Restart=on-failure
+RestartSec=5s
+
+[Install]
+WantedBy=multi-user.target
diff --git a/mysql/templates/replication.cnf.j2 b/mysql/templates/replication.cnf.j2
index 030f2470..460f0833 100644
--- a/mysql/templates/replication.cnf.j2
+++ b/mysql/templates/replication.cnf.j2
@@ -1,4 +1,4 @@
-# {{ansible_managed}}
+# {{ ansible_managed }}
[mysqld]
{% if mysql_log_bin %}
diff --git a/nagios-nrpe/files/alerts_switch b/nagios-nrpe/files/alerts_switch
new file mode 100644
index 00000000..3c5a1417
--- /dev/null
+++ b/nagios-nrpe/files/alerts_switch
@@ -0,0 +1,83 @@
+#!/bin/bash
+
+# https://forge.evolix.org/projects/evolix-private/repository
+#
+# You should not alter this file.
+# If you need to, create and customize a copy.
+
+set -e
+
+readonly PROGNAME=$(basename $0)
+readonly PROGDIR=$(readlink -m $(dirname $0))
+readonly ARGS="$@"
+
+usage() {
+ echo "$PROGNAME action prefix"
+}
+
+disable_alerts () {
+ disabled_file="$1_disabled"
+ enabled_file="$1_enabled"
+
+ if [ -e "${enabled_file}" ]; then
+ mv "${enabled_file}" "${disabled_file}"
+ else
+ touch "${disabled_file}"
+ chmod 0644 "${disabled_file}"
+ fi
+}
+
+enable_alerts () {
+ disabled_file="$1_disabled"
+ enabled_file="$1_enabled"
+
+ if [ -e "${disabled_file}" ]; then
+ mv "${disabled_file}" "${enabled_file}"
+ else
+ touch "${enabled_file}"
+ chmod 0644 "${enabled_file}"
+ fi
+}
+
+now () {
+ date --iso-8601=seconds
+}
+
+log_disable () {
+ echo "$(now) - alerts disabled by $(logname || echo unknown)" >> $1
+}
+
+log_enable () {
+ echo "$(now) - alerts enabled by $(logname || echo unknown)" >> $1
+}
+
+main () {
+ local action=$1
+ local prefix=$2
+
+ local base_dir="/var/lib/misc"
+ mkdir -p "${base_dir}"
+
+ local file_path="${base_dir}/${prefix}_alerts"
+ local log_file="/var/log/${prefix}_alerts.log"
+
+ case "$action" in
+ enable)
+ enable_alerts ${file_path}
+ log_enable ${log_file}
+ ;;
+ disable)
+ disable_alerts ${file_path}
+ log_disable ${log_file}
+ ;;
+ help)
+ usage
+ ;;
+ *)
+ >&2 echo "Unknown action '$action'"
+ exit 1
+ ;;
+ esac
+}
+
+main $ARGS
diff --git a/nagios-nrpe/files/alerts_wrapper b/nagios-nrpe/files/alerts_wrapper
new file mode 100644
index 00000000..d4524fdd
--- /dev/null
+++ b/nagios-nrpe/files/alerts_wrapper
@@ -0,0 +1,217 @@
+#!/bin/bash
+
+# https://forge.evolix.org/projects/evolix-private/repository
+#
+# You should not alter this file.
+# If you need to, create and customize a copy.
+
+VERSION="21.04"
+readonly VERSION
+
+# base functions
+
+show_version() {
+ cat <,
+ Jérémy Lecour
+ and others.
+
+alerts_wrapper comes with ABSOLUTELY NO WARRANTY.This is free software,
+and you are welcome to redistribute it under certain conditions.
+See the GNU General Public License v3.0 for details.
+END
+}
+show_help() {
+ cat < "${check_stdout}"
+ check_rc=$?
+ readonly check_rc
+
+ delay=0
+
+ if [ -e "${alerts_disabled_file}" ]; then
+ delay=$(delay_from_alerts_disabled_file)
+
+ if [ "${delay}" -le "0" ]; then
+ enable_check
+ fi
+ fi
+
+ if [ -e "${alerts_disabled_file}" ]; then
+ formatted_last_change=$(date --date "@$(stat -c %Z "${alerts_disabled_file}")" +'%c')
+ readonly formatted_last_change
+
+ echo "ALERTS DISABLED for ${check_name} (since ${formatted_last_change}, delay: ${delay} sec) - $(cat "${check_stdout}")"
+ if [ ${check_rc} = 0 ]; then
+ # Nagios OK
+ exit 0
+ else
+ # Nagios WARNING
+ exit 1
+ fi
+ else
+ cat "${check_stdout}"
+ exit ${check_rc}
+ fi
+}
+
+# Default: 1 day before re-enabling the check
+wrapper_limit_default="1d"
+readonly wrapper_limit_default
+
+if [[ "${1}" =~ -.* ]]; then
+ # parse options
+ # based on https://gist.github.com/deshion/10d3cb5f88a21671e17a
+ while :; do
+ case $1 in
+ -h|-\?|--help)
+ show_help
+ exit 0
+ ;;
+ -V|--version)
+ show_version
+ exit 0
+ ;;
+
+ --limit)
+ # with value separated by space
+ if [ -n "$2" ]; then
+ wrapper_limit=$2
+ shift
+ else
+ printf 'ERROR: "--limit" requires a non-empty option argument.\n' >&2
+ exit 1
+ fi
+ ;;
+ --limit=?*)
+ # with value speparated by =
+ wrapper_limit=${1#*=}
+ ;;
+ --limit=)
+ # without value
+ printf 'ERROR: "--limit" requires a non-empty option argument.\n' >&2
+ exit 1
+ ;;
+
+ --name)
+ # with value separated by space
+ if [ -n "$2" ]; then
+ check_name=$2
+ shift
+ else
+ printf 'ERROR: "--name" requires a non-empty option argument.\n' >&2
+ exit 1
+ fi
+ ;;
+ --name=?*)
+ # with value speparated by =
+ check_name=${1#*=}
+ ;;
+ --name=)
+ # without value
+ printf 'ERROR: "--name" requires a non-empty option argument.\n' >&2
+ exit 1
+ ;;
+
+ --)
+ # End of all options.
+ shift
+ break
+ ;;
+ -?*)
+ # ignore unknown options
+ printf 'WARN: Unknown option : %s\n' "$1" >&2
+ exit 1
+ ;;
+ *)
+ # Default case: If no more options then break out of the loop.
+ break
+ ;;
+ esac
+
+ shift
+ done
+ # The rest is the command
+ check_command="$*"
+else
+ # no option is passed (backward compatibility with previous version)
+ # treat the first argument as check_name and the rest as the command
+ check_name="${1}"
+ shift
+ check_command="$*"
+fi
+
+# Default values or errors
+if [ -z "${wrapper_limit}" ]; then
+ wrapper_limit="${wrapper_limit_default}"
+fi
+if [ -z "${check_name}" ]; then
+ printf 'ERROR: You must specify a check name, with --name.\n' >&2
+ exit 1
+fi
+if [ -z "${check_command}" ]; then
+ printf 'ERROR: You must specify a command to execute.\n' >&2
+ exit 1
+fi
+
+readonly check_name
+readonly check_command
+readonly wrapper_limit
+alerts_disabled_file="/var/lib/misc/${check_name}_alerts_disabled"
+readonly alerts_disabled_file
+
+check_file="/var/lib/misc/${check_name}_alerts_disabled"
+readonly check_file
+
+check_stdout=$(mktemp --tmpdir=/tmp "${check_name}_stdout.XXXX")
+readonly check_stdout
+
+# shellcheck disable=SC2064
+trap "rm ${check_stdout}" EXIT
+
+main
diff --git a/nagios-nrpe/files/check_async b/nagios-nrpe/files/check_async
index 5ff8ad24..2a54f920 100644
--- a/nagios-nrpe/files/check_async
+++ b/nagios-nrpe/files/check_async
@@ -59,9 +59,9 @@ delay_from_check_file() {
enable_check() {
if [ "$(id -u)" -eq "0" ] ; then
- /usr/share/scripts/alerts_switch enable "${check_name}"
+ /usr/local/bin/alerts_switch enable "${check_name}"
else
- sudo /usr/share/scripts/alerts_switch enable "${check_name}"
+ sudo /usr/local/bin/alerts_switch enable "${check_name}"
fi
}
diff --git a/nagios-nrpe/files/plugins/check_phpfpm_multi b/nagios-nrpe/files/plugins/check_phpfpm_multi
index 865c31d3..b02fc7e2 100644
--- a/nagios-nrpe/files/plugins/check_phpfpm_multi
+++ b/nagios-nrpe/files/plugins/check_phpfpm_multi
@@ -56,20 +56,20 @@ for pool_file in $POOL_FILES; do
if [ "${ret}" -ge 2 ]; then
nb_crit=$((nb_crit + 1))
- output="${output}${result}\n"
[ "${return}" -le 2 ] && return=2
elif [ "${ret}" -ge 1 ]; then
nb_warn=$((nb_warn + 1))
- output="${output}${result}\n"
[ "${return}" -le 1 ] && return=1
else
nb_ok=$((nb_ok + 1))
- output="${output}$(echo "$result" | cut -d '|' -f1)\n"
[ "${return}" -le 0 ] && return=0
fi
+ result_status=$(echo ${result} | awk -F' - ' '{ print $1}')
+ result_content=$(echo ${result} | awk -F' - ' '{ print $2}')
+ output="${output}${result_status} - ${pool_file} - ${result_content}\n"
-done;
+done
[ "${return}" -ge 0 ] && header="OK"
diff --git a/nagios-nrpe/files/plugins/check_vrrpd b/nagios-nrpe/files/plugins/check_vrrpd
index 9390aa6e..a82c379b 100755
--- a/nagios-nrpe/files/plugins/check_vrrpd
+++ b/nagios-nrpe/files/plugins/check_vrrpd
@@ -1,94 +1,190 @@
#!/bin/bash
+# shellcheck disable=SC2207,SC2009,SC2076
-# README
-#
-# Variable to adjust : is_master and vrrpd_processes.
-# vrrpd_processes is the number of vrrpd processes that should run on the server.
-# is_master defines whether the vrrpd group should be master (1) or backup (0).
-#
-# If some instances have to be master and some other have to be backup,
-# then the value of is_master is 2 and the states has to be precised in arguments.
-# e.g. : ./check_vrrpd master backup master
-# The order is defined by the output order of `ps auwx | grep vrrp`
+usage() {
+cat << EOL
+ Usage :
-RC=0
-IFS='
-'
+ $0 --master X,Y --backup Z
-is_master=2 # 1 if master ; 0 if backup ; 2 if mixed master and backup, in this case, it has to be precised in arguments
-vrrpd_processes=3 # number of vrrpd processes that should be running
-is_vrrpd_running=$(sudo /usr/lib/nagios//plugins/check_procs -C vrrpd -c $vrrpd_processes:$vrrpd_processes)
-rc_is_vrrpd_running=$?
-IP_vrrpd=($(for i in $(ps auwx | grep vrrpd | grep -v grep | grep -v check); do echo $i | awk '{print $--NF}'; done))
-INT_vrrpd=($(for i in $(ps auwx | grep vrrpd | grep -v grep | grep -v check); do echo $i | awk '{print $13}'; done))
-ID_vrrpd=($(for i in $(ps auwx | grep vrrpd | grep -v grep | grep -v check); do echo $i | awk '{print $19}'; done))
+ -m|--master ID_MASTER # VRRP ID that should be master, separated by a comma ","
+ -b|--backup ID_BACKUP # VRRP ID that should be backup, separated by a comma ","
+ [--vrrpd] # Check for vrrpd daemon (default)
+ [--uvrrpd] # Check for uvrrpd daemon
+EOL
+}
-if [[ $rc_is_vrrpd_running -ne 0 ]]; then
- echo $is_vrrpd_running instead of $vrrpd_processes
+unset ID_master
+unset ID_backup
+vrrpd_option="unset"
+uvrrpd_option="unset"
+unset critical_output
+critical_state="unset"
+unset warning_output
+warning_state="unset"
+unset ok_output
+ok_state="unset"
+exit_code=0
+used_daemon="vrrpd"
+IFS="
+"
+
+# If no argument then show usage
+if [ "$#" -eq 0 ]; then
+ usage
exit 2
fi
-for i in $(seq 0 $((${#ID_vrrpd[*]}-1))); do
- ifconfig vrrp_${ID_vrrpd[$i]}_${INT_vrrpd[$i]} >/dev/null 2>&1
- # If has interface
- if [[ $? -eq 0 ]]; then
- # If has to be master : OK
- if [[ $is_master -eq 1 ]]; then
- echo OK - ${IP_vrrpd[$i]} exists and is master
- # If has to be backup : KO
- elif [[ $is_master -eq 0 ]]; then
- echo CRITICAL - ${IP_vrrpd[$i]} exists whereas it should be backup
- RC=2
- # We retrieve the state it should be from args
- elif [[ $is_master -eq 2 ]]; then
- arg=$(($i+1))
- state=${!arg}
- # If has to be master : OK
- if [[ $state = master ]]; then
- echo OK - ${IP_vrrpd[$i]} exists and is master
- # If has to be backup : KO
- elif [[ $state = backup ]]; then
- echo CRITICAL - ${IP_vrrpd[$i]} exists whereas it should be backup
- RC=2
+while :; do
+ case $1 in
+ -h|-\?|--help) # Call a "usage" function to display a synopsis, then exit.
+ usage
+ exit
+ ;;
+ -m|--master) # Takes an option argument, ensuring it has been specified.
+ if [ -n "$2" ]; then
+ ID_master=($(echo "$2" | tr "," "\n")) # Make an array with values separated by ","
+ shift
else
- echo "CRITICAL - The arguments have to be master or backup. Exiting"
+ printf 'ERROR: "--master" requires a non-empty option argument.\n' >&2
exit 2
fi
- # Unknown
- else
- RC=3
- fi
- # If hasn't interface
- elif [[ $? -ne 0 ]]; then
- # If has to be master : KO
- if [[ $is_master -eq 1 ]]; then
- echo CRITICAL - ${IP_vrrpd[$i]} does not exist whereas it should be master
- RC=2
- # If has to be backup : OK
- elif [[ $is_master -eq 0 ]]; then
- echo OK - ${IP_vrrpd[$i]} is backup
- # We retrieve the state it should be from args
- elif [[ $is_master -eq 2 ]]; then
- arg=$(($i+1))
- state=${!arg}
- # If has to be master : KO
- if [[ $state = master ]]; then
- echo CRITICAL - ${IP_vrrpd[$i]} does not exist whereas it should be master
- RC=2
- # If has to be backup : OK
- elif [[ $state = backup ]]; then
- echo OK - ${IP_vrrpd[$i]} is backup
+ ;;
+ -b|--backup) # Takes an option argument, ensuring it has been specified.
+ if [ -n "$2" ]; then
+ ID_backup=($(echo "$2" | tr "," "\n")) # Make an array with values separated by ","
+ shift
else
- echo "CRITICAL - The arguments have to be master or backup. Exiting"
+ printf 'ERROR: "--backup" requires a non-empty option argument.\n' >&2
exit 2
fi
- # Unknown
- else
- RC=3
- fi
- # Unknown
- else
- RC=3
- fi
+ ;;
+ --vrrpd)
+ used_daemon="vrrpd"
+ vrrpd_option="set"
+ ;;
+ --uvrrpd)
+ used_daemon="uvrrpd"
+ uvrrpd_option="set"
+ ;;
+ -?*)
+ printf 'WARNING: Unknown option (ignored): %s\n' "$1" >&2
+ ;;
+ *) # Default case: If no more options then break out of the loop.
+ break
+ esac
+ shift
done
-exit $RC
+
+# Make sure that each given ID is given once only
+all_ID=("${ID_master[@]}" "${ID_backup[@]}")
+uniqueNum=$(printf '%s\n' "${all_ID[@]}"|awk '!($0 in seen){seen[$0];c++} END {print c}')
+if [ "$uniqueNum" != ${#all_ID[@]} ]; then
+ echo "ERROR : At least one VRRP ID is given multiple times"
+ exit 2
+fi
+
+# Make sure --vrrpd and --uvrrpd are not both set
+if [ $vrrpd_option = "set" ] && [ $uvrrpd_option = "set" ]; then
+ echo "ERROR : You cannot set both parameters --vrrpd and --uvrrpd"
+ exit 2
+fi
+
+# Make sure no sysclt parameter "rp_filter" is set to 1
+if grep -q 1 /proc/sys/net/ipv4/conf/*/rp_filter; then
+ critical_output="${critical_output}CRITICAL - rp_filter is set to 1 at least for one interface\n"
+ critical_state="set"
+fi
+
+vrrpd_processes_number=$((${#ID_master[@]}+${#ID_backup[@]})) # Number of vrrpd processes that should be running = length of arrays ID_master + ID_backup
+regex_ipv4="((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])"
+regex_ipv6="(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))"
+vrrpd_processes=$(ps auwx | grep "$used_daemon" | grep -v -e grep -e check)
+ID_running_vrrpd=($(for i in ${vrrpd_processes}; do echo "$i" | grep -Eo -- "-v [0-9]+" | awk '{print $2}'; done))
+
+# Check the number of running vrrpd processes in comparison to the number of ID given
+if ! sudo /usr/lib/nagios/plugins/check_procs -C "$used_daemon" -c $vrrpd_processes_number:$vrrpd_processes_number >/dev/null; then
+ critical_output="${critical_output}CRITICAL : $vrrpd_processes_number VRRP ID are given but $(ps auwx | grep "$used_daemon" | grep -v -e grep -e check -c) $used_daemon processes are running\n"
+ if pgrep uvrrp >/dev/null && [ $uvrrpd_option = "unset" ]; then
+ critical_output="${critical_output}It seems that uvrrpd is running. Use parameter --uvrrpd\n"
+ fi
+ critical_state="set"
+fi
+
+IFS=" "
+
+# For each ID_master, make sure a process exist
+if [ ${#ID_master[@]} -ne 0 ]; then
+ for i in "${ID_master[@]}"; do
+ # If array contains the current ID, then a process exist, and we have to make sure the corresponding interface exists
+ if [[ " ${ID_running_vrrpd[*]} " =~ " $i " ]]; then
+ vrrpd_current_proccess=$(echo "$vrrpd_processes" | grep -E -- "-v $i ")
+ INT_current_vrrpd=$(echo "$vrrpd_current_proccess" | grep -Eo -- "-i \S+" | awk '{print $2}')
+ IP_current_vrrpd=$(echo "$vrrpd_current_proccess" | grep -Eo "${regex_ipv4}|${regex_ipv6}")
+ if [ "$used_daemon" = "vrrpd" ]; then
+ int_name="vrrp_${i}_${INT_current_vrrpd}"
+ elif [ "$used_daemon" = "uvrrpd" ]; then
+ int_name="${INT_current_vrrpd}_${i}"
+ fi
+ if /sbin/ifconfig "$int_name" 2> /dev/null | grep -q "$IP_current_vrrpd"; then
+ ok_output="${ok_output}OK - ID $i has a process and $IP_current_vrrpd is master\n"
+ ok_state="set"
+ else
+ warning_output="${warning_output}WARNING - The IP $IP_current_vrrpd for ID $i is backup while it should be master\n"
+ warning_state="set"
+ fi
+ else
+ critical_output="${critical_output}CRITICAL - No process is running for VRRP ID $i\n"
+ critical_state="set"
+ fi
+ done
+fi
+
+# For each ID_backup, make sure a process exist
+if [ ${#ID_backup[@]} -ne 0 ]; then
+ for i in "${ID_backup[@]}"; do
+ # If array contains the current ID, then a process exist, and we have to make sure the corresponding interface does not exist
+ if [[ " ${ID_running_vrrpd[*]} " =~ " $i " ]]; then
+ vrrpd_current_proccess=$(echo "$vrrpd_processes" | grep -E -- "-v $i ")
+ INT_current_vrrpd=$(echo "$vrrpd_current_proccess" | grep -Eo -- "-i \S+" | awk '{print $2}')
+ IP_current_vrrpd=$(echo "$vrrpd_current_proccess" | grep -Eo "${regex_ipv4}|${regex_ipv6}")
+ if [ "$used_daemon" = "vrrpd" ]; then
+ int_name="vrrp_${i}_${INT_current_vrrpd}"
+ elif [ "$used_daemon" = "uvrrpd" ]; then
+ int_name="${INT_current_vrrpd}_${i}"
+ fi
+ if ! /sbin/ifconfig "$int_name" 2> /dev/null | grep -q "$IP_current_vrrpd"; then
+ ok_output="${ok_output}OK - ID $i has a process and $IP_current_vrrpd is backup\n"
+ ok_state="set"
+ else
+ warning_output="${warning_output}WARNING - The IP $IP_current_vrrpd for ID $i is master while it should be backup\n"
+ warning_state="set"
+ fi
+ else
+ critical_output="${critical_output}CRITICAL - No process is running for VRRP ID $i\n"
+ critical_state="set"
+ fi
+ done
+fi
+
+# Make $exit_code the highest set
+if [ "$critical_state" = "set" ]; then
+ exit_code=2
+elif [ "$warning_state" = "set" ]; then
+ exit_code=1
+elif [ "$ok_state" = "set" ]; then
+ exit_code=0
+fi
+
+# Echo most critical output first, least last
+if [ -n "$critical_output" ]; then
+ echo -e "$critical_output" | grep -v "^$"
+fi
+if [ -n "$warning_output" ]; then
+ echo -e "$warning_output" | grep -v "^$"
+fi
+if [ -n "$ok_output" ]; then
+ echo -e "$ok_output" | grep -v "^$"
+fi
+
+exit $exit_code
diff --git a/nagios-nrpe/tasks/main.yml b/nagios-nrpe/tasks/main.yml
index 77770020..5a77c4ee 100644
--- a/nagios-nrpe/tasks/main.yml
+++ b/nagios-nrpe/tasks/main.yml
@@ -58,7 +58,7 @@
- include_role:
name: evolix/remount-usr
- when: nagios_plugins_directory is search ("/usr")
+ when: nagios_plugins_directory is search("/usr")
tags:
- nagios-nrpe
- nagios-plugins
@@ -83,3 +83,5 @@
notify: restart nagios-nrpe-server
tags:
- nagios-nrpe
+
+- include_tasks: wrapper.yml
\ No newline at end of file
diff --git a/nagios-nrpe/tasks/wrapper.yml b/nagios-nrpe/tasks/wrapper.yml
new file mode 100644
index 00000000..f49c7509
--- /dev/null
+++ b/nagios-nrpe/tasks/wrapper.yml
@@ -0,0 +1,42 @@
+---
+
+
+- name: "Remount /usr if needed"
+ include_role:
+ name: remount-usr
+
+- name: check if old script is present
+ stat:
+ path: /usr/share/scripts/alerts_switch
+ register: old_alerts_switch
+
+- name: alerts_switch is at the right place
+ command: "mv /usr/share/scripts/alerts_switch /usr/local/bin/alerts_switch"
+ args:
+ creates: /usr/local/bin/alerts_switch
+ when: old_alerts_switch.stat.exists
+
+- name: "copy alerts_switch"
+ copy:
+ src: alerts_switch
+ dest: /usr/local/bin/alerts_switch
+ owner: root
+ group: root
+ mode: "0750"
+ force: yes
+
+- name: "symlink for backward compatibility"
+ file:
+ src: /usr/local/bin/alerts_switch
+ dest: /usr/share/scripts/alerts_switch
+ state: link
+ when: old_alerts_switch.stat.exists
+
+- name: "copy alerts_wrapper"
+ copy:
+ src: alerts_wrapper
+ dest: "{{ nagios_plugins_directory }}/alerts_wrapper"
+ owner: root
+ group: staff
+ mode: "0755"
+ force: yes
\ No newline at end of file
diff --git a/nameserver/tasks/main.yml b/nameserver/tasks/main.yml
index 420e65af..83ba2a34 100644
--- a/nameserver/tasks/main.yml
+++ b/nameserver/tasks/main.yml
@@ -3,7 +3,7 @@
shell: grep nameserver /etc/resolv.conf | awk '{ print $2 }'
register: grep_nameserver
check_mode: no
- changed_when: false
+ changed_when: False
tags:
- nameserver
diff --git a/newrelic/tasks/php.yml b/newrelic/tasks/php.yml
index c41dbac9..3bd4d809 100644
--- a/newrelic/tasks/php.yml
+++ b/newrelic/tasks/php.yml
@@ -18,7 +18,7 @@
- name: list newrelic config files
shell: "find /etc/php* -type f -name newrelic.ini"
- changed_when: false
+ changed_when: False
check_mode: no
register: find_newrelic_ini
diff --git a/nginx/tasks/main.yml b/nginx/tasks/main.yml
index b3f1c313..e7abc1b5 100644
--- a/nginx/tasks/main.yml
+++ b/nginx/tasks/main.yml
@@ -66,7 +66,7 @@
- name: Include IP address whitelist task
include: ip_whitelist.yml
-- name: Copy evolinux_server_custom
+- name: Copy evolinux_server_custom
copy:
src: nginx/snippets/evolinux_server_custom
dest: /etc/nginx/snippets/evolinux_server_custom
diff --git a/nginx/tasks/munin_vhost.yml b/nginx/tasks/munin_vhost.yml
index ff9f8423..5aa137c9 100644
--- a/nginx/tasks/munin_vhost.yml
+++ b/nginx/tasks/munin_vhost.yml
@@ -18,15 +18,11 @@
shell: "chown --verbose www-data:munin /var/log/munin/munin-cgi-*"
register: command_result
changed_when: "'changed' in command_result.stdout"
- args:
- warn: no
- name: Mode for munin-cgi is set to 660
shell: "chmod --verbose 660 /var/log/munin/munin-cgi-*"
register: command_result
changed_when: "'changed' in command_result.stdout"
- args:
- warn: no
- name: Systemd unit for Munin-fcgi is installed
copy:
diff --git a/nodejs/files/yarn.asc b/nodejs/files/yarn.asc
index e8d9cabb..03d9338a 100644
--- a/nodejs/files/yarn.asc
+++ b/nodejs/files/yarn.asc
@@ -158,86 +158,63 @@ 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
-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
-=IgpF
------END PGP PUBLIC KEY BLOCK-----
+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
+=e4wy
+-----END PGP PUBLIC KEY BLOCK-----
\ No newline at end of file
diff --git a/openvpn/tasks/debian.yml b/openvpn/tasks/debian.yml
index b0201f0c..bee05d9e 100644
--- a/openvpn/tasks/debian.yml
+++ b/openvpn/tasks/debian.yml
@@ -89,13 +89,13 @@
stat:
path: "/etc/default/minifirewall"
check_mode: no
- changed_when: false
+ changed_when: False
register: minifirewall_config
- name: Retrieve the default interface
shell: "grep '^INT=' /etc/default/minifirewall | cut -d\\' -f 2"
check_mode: no
- changed_when: false
+ changed_when: False
register: minifirewall_int
when: minifirewall_config.stat.exists
@@ -176,7 +176,7 @@
stat:
path: "/etc/nagios/nrpe.d/evolix.cfg"
check_mode: no
- changed_when: false
+ changed_when: False
register: nrpe_evolix_config
- name: Install NRPE check dependencies
@@ -290,6 +290,6 @@
The "push" parameter may be needed to push a route to the client, so that the client can access that route through OpenVPN.
Take note of the generated CA password and store it in your password manager : {{ ca_pwd }}
-
+
Press enter to exit when it's done.
diff --git a/openvpn/tasks/openbsd.yml b/openvpn/tasks/openbsd.yml
index b0e629be..e33923e1 100644
--- a/openvpn/tasks/openbsd.yml
+++ b/openvpn/tasks/openbsd.yml
@@ -132,7 +132,7 @@
- name: Configure NRPE OpenVPN check
lineinfile:
- dest: "/etc/nrpe.d/zzz_evolix.cfg"
+ dest: "/etc/nrpe.d/evolix.cfg"
regexp: '^command\[check_openvpn\]='
line: "command[check_openvpn]=/usr/local/libexec/nagios/plugins/check_openvpn.pl -H 127.0.0.1 -p 1195 -P {{ management_pwd }}"
create: yes
@@ -218,6 +218,6 @@
The "push" parameter may be needed to push a route to the client, so that the client can access that route through OpenVPN.
Take note of the generated CA password and store it in your password manager : {{ ca_pwd }}
-
+
Press enter to exit when it's done.
diff --git a/openvpn/templates/ovpn.conf.j2 b/openvpn/templates/ovpn.conf.j2
index d1b3c214..f65d43fd 100644
--- a/openvpn/templates/ovpn.conf.j2
+++ b/openvpn/templates/ovpn.conf.j2
@@ -9,5 +9,5 @@ nobind
persist-key
persist-tun
-cipher AES-256-CBC
+cipher AES-256-GCM
diff --git a/packweb-apache/files/userlogrotate_jessie b/packweb-apache/files/userlogrotate_jessie
deleted file mode 100644
index 339101a9..00000000
--- a/packweb-apache/files/userlogrotate_jessie
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/bash
-
-DATE=`/bin/date +"%d-%m-%Y"`
-HOMEPREFIX="/home"
-
-rotate () {
- mv $1 $1.$DATE
- gzip $1.$DATE
- touch $1
- chown $2 $1
- chmod g+r $1
-}
-
-user_for() {
- homedir=`echo $1 | sed "s#\($HOMEPREFIX/\([^/]\+\)\).*#\1#"`
- stat -L -c '%G' $homedir
-}
-
-for log in access.log access-*.log error.log; do
- for i in `ls -1 -d $HOMEPREFIX/*/log/$log 2>/dev/null | grep -v \.bak\.`; do
- USER=`user_for $i`
- rotate $i root:$USER
- done
-done
-
-for i in `ls -1 -d $HOMEPREFIX/*/log/php.log 2>/dev/null | grep -v \.bak\.`; do
- USER=`user_for $i`
- rotate $i www-$USER:$USER
-done
-
-for log in production.log delayed_job.log development.log test.log; do
- for i in `ls -1 -d $HOMEPREFIX/*/www/{,current/}log/$log 2>/dev/null | grep -v \.bak\.`; do
- USER=`user_for $i`
- rotate $i $USER:$USER
- done
-done
-
-apache2ctl restart > /dev/null
diff --git a/packweb-apache/tasks/main.yml b/packweb-apache/tasks/main.yml
index ff3cd9a7..c0a44935 100644
--- a/packweb-apache/tasks/main.yml
+++ b/packweb-apache/tasks/main.yml
@@ -65,19 +65,8 @@
- access.log
- error.log
-- name: "Install userlogrotate (jessie)"
- copy:
- src: userlogrotate_jessie
- dest: /etc/cron.weekly/userlogrotate
- mode: "0755"
- when: ansible_distribution_release == "jessie"
-
-- name: "Install userlogrotate (Debian 9 or later)"
- copy:
- src: userlogrotate
- dest: /etc/cron.weekly/userlogrotate
- mode: "0755"
- when: ansible_distribution_major_version is version('9', '>=')
+- include_role:
+ name: userlogrotate
- name: Force DIR_MODE to 0750 in /etc/adduser.conf
lineinfile:
@@ -102,3 +91,4 @@
- include: multiphp.yml
when: packweb_multiphp_versions | length > 0
+
diff --git a/packweb-apache/tasks/update_userlogrotate.yml b/packweb-apache/tasks/update_userlogrotate.yml
deleted file mode 100644
index 1e8a6d85..00000000
--- a/packweb-apache/tasks/update_userlogrotate.yml
+++ /dev/null
@@ -1,16 +0,0 @@
----
-
-- name: "Cherche l'emplacement de userlogrotate"
- ansible.builtin.find:
- path: /etc
- patterns: userlogrotate
- register: find_logrotate
-
-- name: "Met-à-jour userlogrotate"
- ansible.builtin.copy:
- src: userlogrotate
- dest: "{{ item }}"
- mode: "0755"
- loop: "{{ find_logrotate.files }}"
- when: find_logrotate.files | length>0
-
diff --git a/php/README.md b/php/README.md
index e0a194ac..e2190a3c 100644
--- a/php/README.md
+++ b/php/README.md
@@ -6,6 +6,8 @@ Installation and basic configuration of PHP
Minimal configuration is in `tasks/main.yml`
+Set variable `php_version` in your playbook.
+
## Available variables
The full list of variables (with default values) can be found in `defaults/main.yml`.
diff --git a/php/files/reg.asc b/php/files/reg.asc
new file mode 100644
index 00000000..3fadeb07
--- /dev/null
+++ b/php/files/reg.asc
@@ -0,0 +1,920 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: SKS 1.1.6
+Comment: Hostname: keyserver.ubuntu.com
+
+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
+BWcdiQ==
+=iUyJ
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/php/files/sury.preferences b/php/files/sury.preferences
index 15aa9c16..adcc5918 100644
--- a/php/files/sury.preferences
+++ b/php/files/sury.preferences
@@ -1,4 +1,4 @@
-Package: php* libapache2-mod-php* libpcre2* libzip4* libgd*
+Package: php* libapache2-mod-php* libpcre2* libzip4* libgd* libpcre3*
Pin: origin packages.sury.org
Pin-Priority: 999
diff --git a/php/handlers/main.yml b/php/handlers/main.yml
index 079a14d5..206eab3a 100644
--- a/php/handlers/main.yml
+++ b/php/handlers/main.yml
@@ -5,6 +5,11 @@
name: php5-fpm
state: restarted
+- name: restart php5.6-fpm
+ service:
+ name: php5.6-fpm
+ state: restarted
+
- name: restart php7.0-fpm
service:
name: php7.0-fpm
@@ -24,3 +29,8 @@
service:
name: php8.1-fpm
state: restarted
+
+- name: restart php8.2-fpm
+ service:
+ name: php8.2-fpm
+ state: restarted
diff --git a/php/tasks/main_bookworm.yml b/php/tasks/main_bookworm.yml
index 4dcde767..6ad64399 100644
--- a/php/tasks/main_bookworm.yml
+++ b/php/tasks/main_bookworm.yml
@@ -1,8 +1,11 @@
---
-- name: "Set php version to 8.1 (Debian 12)"
+- name: "Set php version to 8.2 (Debian 12)"
set_fact:
- php_version: "8.1"
+ php_version: "8.2"
+ when:
+ - php_sury_enable == false
+ check_mode: no
- name: "Set php config directories (Debian 12)"
set_fact:
@@ -19,9 +22,9 @@
php_apache_custom_ini_file: "{{ php_apache_conf_dir }}/zzz-evolinux-custom.ini"
php_fpm_defaults_ini_file: "{{ php_fpm_conf_dir }}/z-evolinux-defaults.ini"
php_fpm_custom_ini_file: "{{ php_fpm_conf_dir }}/zzz-evolinux-custom.ini"
- php_fpm_debian_default_pool_file: "{{ php_fpm_pool_dir}}/www.conf"
- php_fpm_default_pool_file: "{{ php_fpm_pool_dir}}/www-evolinux-defaults.conf"
- php_fpm_default_pool_custom_file: "{{ php_fpm_pool_dir}}/www-evolinux-zcustom.conf"
+ php_fpm_debian_default_pool_file: "{{ php_fpm_pool_dir }}/www.conf"
+ php_fpm_default_pool_file: "{{ php_fpm_pool_dir }}/www-evolinux-defaults.conf"
+ php_fpm_default_pool_custom_file: "{{ php_fpm_pool_dir }}/www-evolinux-zcustom.conf"
php_fpm_default_pool_socket: "/var/run/php/php{{ php_version }}-fpm.sock"
php_fpm_service_name: "php{{ php_version }}-fpm"
diff --git a/php/tasks/main_bullseye.yml b/php/tasks/main_bullseye.yml
index 403a7b76..4cb185b7 100644
--- a/php/tasks/main_bullseye.yml
+++ b/php/tasks/main_bullseye.yml
@@ -1,18 +1,25 @@
---
+- name: "Set php version to 7.4 if Sury repo is not enabled"
+ set_fact:
+ php_version: "7.4"
+ when:
+ - php_sury_enable == False
+ check_mode: no
+
- name: "Set variables (Debian 11)"
set_fact:
- php_cli_defaults_ini_file: /etc/php/7.4/cli/conf.d/z-evolinux-defaults.ini
- php_cli_custom_ini_file: /etc/php/7.4/cli/conf.d/zzz-evolinux-custom.ini
- php_apache_defaults_ini_file: /etc/php/7.4/apache2/conf.d/z-evolinux-defaults.ini
- php_apache_custom_ini_file: /etc/php/7.4/apache2/conf.d/zzz-evolinux-custom.ini
- php_fpm_defaults_ini_file: /etc/php/7.4/fpm/conf.d/z-evolinux-defaults.ini
- php_fpm_custom_ini_file: /etc/php/7.4/fpm/conf.d/zzz-evolinux-custom.ini
- php_fpm_debian_default_pool_file: /etc/php/7.4/fpm/pool.d/www.conf
- php_fpm_default_pool_file: /etc/php/7.4/fpm/pool.d/www-evolinux-defaults.conf
- php_fpm_default_pool_custom_file: /etc/php/7.4/fpm/pool.d/www-evolinux-zcustom.conf
- php_fpm_default_pool_socket: /var/run/php/php7.4-fpm.sock
- php_fpm_service_name: php7.4-fpm
+ php_cli_defaults_ini_file: /etc/php/{{ php_version }}/cli/conf.d/z-evolinux-defaults.ini
+ php_cli_custom_ini_file: /etc/php/{{ php_version }}/cli/conf.d/zzz-evolinux-custom.ini
+ php_apache_defaults_ini_file: /etc/php/{{ php_version }}/apache2/conf.d/z-evolinux-defaults.ini
+ php_apache_custom_ini_file: /etc/php/{{ php_version }}/apache2/conf.d/zzz-evolinux-custom.ini
+ php_fpm_defaults_ini_file: /etc/php/{{ php_version }}/fpm/conf.d/z-evolinux-defaults.ini
+ php_fpm_custom_ini_file: /etc/php/{{ php_version }}/fpm/conf.d/zzz-evolinux-custom.ini
+ php_fpm_debian_default_pool_file: /etc/php/{{ php_version }}/fpm/pool.d/www.conf
+ php_fpm_default_pool_file: /etc/php/{{ php_version }}/fpm/pool.d/www-evolinux-defaults.conf
+ php_fpm_default_pool_custom_file: /etc/php/{{ php_version }}/fpm/pool.d/www-evolinux-zcustom.conf
+ php_fpm_default_pool_socket: /var/run/php/php{{ php_version }}-fpm.sock
+ php_fpm_service_name: php{{ php_version }}-fpm
# Packages
@@ -25,7 +32,6 @@
- php-imap
- php-ldap
- php-mysql
- # php-mcrypt is no longer packaged for PHP 7.2
- php-pgsql
- php-sqlite3
- php-curl
@@ -54,8 +60,8 @@
- name: "Install PHP FPM packages (Debian 11)"
apt:
name:
- - php-fpm
- - php
+ - php{{ php_version }}-fpm
+ - php{{ php_version }}
state: present
when: php_fpm_enable
@@ -67,12 +73,12 @@
mode: "0755"
with_items:
- /etc/php
- - /etc/php/7.4
+ - /etc/php/{{ php_version }}
- include: config_cli.yml
- name: "Enforce permissions on PHP cli directory (Debian 11)"
file:
- dest: /etc/php/7.4/cli
+ dest: /etc/php/{{ php_version }}/cli
mode: "0755"
- include: config_fpm.yml
@@ -80,7 +86,7 @@
- name: "Enforce permissions on PHP fpm directory (Debian 11)"
file:
- dest: /etc/php/7.4/fpm
+ dest: /etc/php/{{ php_version }}/fpm
mode: "0755"
when: php_fpm_enable
@@ -89,9 +95,9 @@
- name: "Enforce permissions on PHP apache2 directory (Debian 11)"
file:
- dest: /etc/php/7.4/apache2
+ dest: /etc/php/{{ php_version }}/apache2
mode: "0755"
when: php_apache_enable
-- include: sury_post.yml
- when: php_sury_enable
+#- include: sury_post.yml
+# when: php_sury_enable
diff --git a/php/tasks/main_buster.yml b/php/tasks/main_buster.yml
index 2fc4293e..24673378 100644
--- a/php/tasks/main_buster.yml
+++ b/php/tasks/main_buster.yml
@@ -1,18 +1,28 @@
---
+- debug:
+ msg: "{{ php_sury_enable }}"
+
+- name: "Set php version to 7.3 if Sury repo is not enabled"
+ set_fact:
+ php_version: "7.3"
+ when:
+ - php_sury_enable == false
+ check_mode: no
+
- name: "Set variables (Debian 10)"
set_fact:
- php_cli_defaults_ini_file: /etc/php/7.3/cli/conf.d/z-evolinux-defaults.ini
- php_cli_custom_ini_file: /etc/php/7.3/cli/conf.d/zzz-evolinux-custom.ini
- php_apache_defaults_ini_file: /etc/php/7.3/apache2/conf.d/z-evolinux-defaults.ini
- php_apache_custom_ini_file: /etc/php/7.3/apache2/conf.d/zzz-evolinux-custom.ini
- php_fpm_defaults_ini_file: /etc/php/7.3/fpm/conf.d/z-evolinux-defaults.ini
- php_fpm_custom_ini_file: /etc/php/7.3/fpm/conf.d/zzz-evolinux-custom.ini
- php_fpm_debian_default_pool_file: /etc/php/7.3/fpm/pool.d/www.conf
- php_fpm_default_pool_file: /etc/php/7.3/fpm/pool.d/www-evolinux-defaults.conf
- php_fpm_default_pool_custom_file: /etc/php/7.3/fpm/pool.d/www-evolinux-zcustom.conf
- php_fpm_default_pool_socket: /var/run/php/php7.3-fpm.sock
- php_fpm_service_name: php7.3-fpm
+ php_cli_defaults_ini_file: /etc/php/{{ php_version }}/cli/conf.d/zvolinux-defaults.ini
+ php_cli_custom_ini_file: /etc/php/{{ php_version }}/cli/conf.d/zzz-evolinux-custom.ini
+ php_apache_defaults_ini_file: /etc/php/{{ php_version }}/apache2/conf.d/z-evolinux-defaults.ini
+ php_apache_custom_ini_file: /etc/php/{{ php_version }}/apache2/conf.d/zzz-evolinux-custom.ini
+ php_fpm_defaults_ini_file: /etc/php/{{ php_version }}/fpm/conf.d/z-evolinux-defaults.ini
+ php_fpm_custom_ini_file: /etc/php/{{ php_version }}/fpm/conf.d/zzz-evolinux-custom.ini
+ php_fpm_debian_default_pool_file: /etc/php/{{ php_version }}/fpm/pool.d/www.conf
+ php_fpm_default_pool_file: /etc/php/{{ php_version }}/fpm/pool.d/www-evolinux-defaults.conf
+ php_fpm_default_pool_custom_file: /etc/php/{{ php_version }}/fpm/pool.d/www-evolinux-zcustom.conf
+ php_fpm_default_pool_socket: /var/run/php/php{{ php_version }}-fpm.sock
+ php_fpm_service_name: php{{ php_version }}-fpm
# Packages
@@ -54,8 +64,8 @@
- name: "Install PHP FPM packages (Debian 10)"
apt:
name:
- - php-fpm
- - php
+ - php{{ php_version }}-fpm
+ - php{{ php_version }}
state: present
when: php_fpm_enable | bool
@@ -67,12 +77,12 @@
mode: "0755"
loop:
- /etc/php
- - /etc/php/7.3
+ - /etc/php/{{ php_version }}
- include: config_cli.yml
- name: "Enforce permissions on PHP cli directory (Debian 10)"
file:
- dest: /etc/php/7.3/cli
+ dest: /etc/php/{{ php_version }}/cli
mode: "0755"
- include: config_fpm.yml
@@ -80,7 +90,7 @@
- name: "Enforce permissions on PHP fpm directory (Debian 10)"
file:
- dest: /etc/php/7.3/fpm
+ dest: /etc/php/{{ php_version }}/fpm
mode: "0755"
when: php_fpm_enable | bool
@@ -89,9 +99,9 @@
- name: "Enforce permissions on PHP apache2 directory (Debian 10)"
file:
- dest: /etc/php/7.3/apache2
+ dest: /etc/php/{{ php_version }}/apache2
mode: "0755"
when: php_apache_enable | bool
-- include: sury_post.yml
- when: php_sury_enable | bool
+#- include: sury_post.yml
+# when: php_sury_enable | bool
diff --git a/php/tasks/sury_pre.yml b/php/tasks/sury_pre.yml
index a1dcbb0e..0d146555 100644
--- a/php/tasks/sury_pre.yml
+++ b/php/tasks/sury_pre.yml
@@ -8,6 +8,14 @@
owner: root
group: root
+- name: copy pub.evolix.org GPG key
+ copy:
+ src: pub_evolix.asc
+ dest: "{{ apt_keyring_dir }}/pub_evolix.asc"
+ mode: "0644"
+ owner: root
+ group: root
+
- name: Setup deb.sury.org repository - Install apt-transport-https
apt:
state: present
@@ -17,6 +25,16 @@
copy:
src: sury.preferences
dest: /etc/apt/preferences.d/z-sury
+ when:
+ - ansible_distribution_release != "bullseye"
+
+- name: Setup pub.evolix.org repository - Add source list
+ apt_repository:
+ repo: "deb [signed-by={{ apt_keyring_dir }}/pub_evolix.asc] http://pub.evolix.org/evolix {{ ansible_distribution_release }}-php81 main"
+ filename: evolix-php
+ state: present
+ when:
+ - ansible_distribution_release == "bullseye"
- name: Setup deb.sury.org repository - Add source list
apt_repository:
@@ -33,17 +51,16 @@
- name: "Override package list for Sury (Debian 9 or later)"
set_fact:
php_stretch_packages:
- - php-cli
- - php-gd
- - php-intl
- - php-imap
- - php-ldap
- - php-mysql
+ - php{{ php_version }}-cli
+ - php{{ php_version }}-gd
+ - php{{ php_version }}-intl
+ - php{{ php_version }}-imap
+ - php{{ php_version }}-ldap
+ - php{{ php_version }}-mysql
# php-mcrypt is no longer packaged for PHP 7.2
- - php-pgsql
- - php-gettext
- - php-curl
- - php-ssh2
- - composer
- - libphp-phpmailer
- when: ansible_distribution_release != "bullseye"
+ - php{{ php_version }}-pgsql
+ - php{{ php_version }}-gettext
+ - php{{ php_version }}-curl
+ - php{{ php_version }}-ssh2
+# - composer
+# - libphp-phpmailer
diff --git a/postfix/tasks/packmail.yml b/postfix/tasks/packmail.yml
index 90d424b2..0407a72b 100644
--- a/postfix/tasks/packmail.yml
+++ b/postfix/tasks/packmail.yml
@@ -10,6 +10,20 @@
tags:
- postfix
+- name: make /var/lib/mailgraph accessible by www-data
+ file:
+ path: "/var/lib/mailgraph"
+ state: directory
+ owner: www-data
+ group: www-data
+ mode: '0755'
+
+- name: make sure a service Mailgraph is running
+ systemd:
+ name: mailgraph.service
+ state: started
+ enabled: true
+
- name: create packmail main.cf
template:
src: packmail_main.cf.j2
@@ -119,6 +133,6 @@
- name: update antispam list
command: /usr/share/scripts/spam.sh
- changed_when: false
+ changed_when: False
tags:
- postfix
diff --git a/postfix/templates/evolinux_main.cf.j2 b/postfix/templates/evolinux_main.cf.j2
index 0c871546..5d298f1d 100644
--- a/postfix/templates/evolinux_main.cf.j2
+++ b/postfix/templates/evolinux_main.cf.j2
@@ -5,7 +5,7 @@ myhostname = {{ postfix_hostname }}
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = $myhostname
-mydestination = $myhostname localhost.localdomain localhost
+mydestination = $myhostname localhost localhost.localdomain localhost.$mydomain
relayhost =
mynetworks = 127.0.0.0/8
mailbox_size_limit = 0
diff --git a/postfix/templates/packmail_main.cf.j2 b/postfix/templates/packmail_main.cf.j2
index 82b94afa..b803389e 100644
--- a/postfix/templates/packmail_main.cf.j2
+++ b/postfix/templates/packmail_main.cf.j2
@@ -74,7 +74,7 @@ myhostname = {{ ansible_fqdn }}
# Liste des noms de domaine (ou IP) consideres comme local
#par defaut, = $myhostname, localhost.$mydomain, localhost
-mydestination = $myhostname localhost.localdomain localhost
+mydestination = $myhostname localhost localhost.localdomain localhost.$mydomain
# Indique le domaine apparaissant dans le courrier envoye
#par defaut, = $myhostname
@@ -294,7 +294,7 @@ slow_destination_concurrency_failed_cohort_limit = 100
# bounce : envoie les entetes de tous les message renvoyes
# 2bounce : envoie les entetes de tous les messages renvoyes non delivres
#par defaut, = resource, software
-notify_classes = resource, software, bounce, 2bounce, delay, policy, protocol
+#notify_classes = resource, software
# A qui les reporter ?
#Pour delay
@@ -412,8 +412,10 @@ smtpd_sasl_path = private/auth-client
# Amavis and OpenDKIM
content_filter = smtp-amavis:[127.0.0.1]:10024
+smtp-amavis_destination_concurrency_failed_cohort_limit = 0
smtpd_milters = inet:[127.0.0.1]:8891
non_smtpd_milters = inet:[127.0.0.1]:8891
+smtp-amavis_destination_concurrency_failed_cohort_limit = 0
{% if postfix_slow_transport_include == True %}
# Slow transports configuration
@@ -430,3 +432,4 @@ slow_destination_concurrency_failed_cohort_limit = 100
slow_destination_recipient_limit = 25
transport_maps = hash:$config_directory/transport
{% endif %}
+
diff --git a/postfix/templates/virtual_aliases.cf.j2 b/postfix/templates/virtual_aliases.cf.j2
index 1a6e5f9c..97f4baf3 100644
--- a/postfix/templates/virtual_aliases.cf.j2
+++ b/postfix/templates/virtual_aliases.cf.j2
@@ -2,4 +2,3 @@ search_base = {{ ldap_suffix }}
query_filter = (&(mailacceptinggeneralid=%u@%d)(isActive=TRUE))
result_attribute = maildrop
version = 3
-aliases_scope = sub
diff --git a/postgresql/defaults/main.yml b/postgresql/defaults/main.yml
index ffc3007c..634ea4f1 100644
--- a/postgresql/defaults/main.yml
+++ b/postgresql/defaults/main.yml
@@ -7,6 +7,7 @@ postgresql_shared_buffers: "{{ (ansible_memtotal_mb * 0.25) | int }}MB"
postgresql_work_mem: 8MB
postgresql_random_page_cost: 1.5
postgresql_effective_cache_size: "{{ (ansible_memtotal_mb * 0.5) | int }}MB"
+postgresql_max_connections: None
# Binding
postgresql_listen_addresses:
diff --git a/postgresql/files/logrotate_postgresql b/postgresql/files/logrotate_postgresql
index a9306aa3..656e2991 100644
--- a/postgresql/files/logrotate_postgresql
+++ b/postgresql/files/logrotate_postgresql
@@ -1,11 +1,10 @@
/var/log/postgresql/*.log {
+ su postgres postgres
daily
rotate 10
copytruncate
nodelaycompress
compress
- notifempty
missingok
- su root root
+ dateext
}
-
diff --git a/postgresql/handlers/main.yml b/postgresql/handlers/main.yml
index 5275b6a1..15a773dd 100644
--- a/postgresql/handlers/main.yml
+++ b/postgresql/handlers/main.yml
@@ -16,7 +16,8 @@
daemon_reload: yes
- name: reload systemd
- command: systemctl daemon-reload
+ systemd:
+ daemon-reload: yes
- name: Restart minifirewall
command: /etc/init.d/minifirewall restart
diff --git a/postgresql/tasks/config.yml b/postgresql/tasks/config.yml
index f29026df..966f0930 100644
--- a/postgresql/tasks/config.yml
+++ b/postgresql/tasks/config.yml
@@ -17,13 +17,13 @@
- name: Allow conf.d/*.conf files to be included in PostgreSQL configuration
lineinfile:
- name: "/etc/postgresql/{{postgresql_version}}/main/postgresql.conf"
+ name: "/etc/postgresql/{{ postgresql_version }}/main/postgresql.conf"
line: include_dir = 'conf.d'
notify: restart postgresql
- name: Create conf.d directory
file:
- name: "/etc/postgresql/{{postgresql_version}}/main/conf.d/"
+ name: "/etc/postgresql/{{ postgresql_version }}/main/conf.d/"
state: directory
owner: postgres
group: postgres
@@ -32,7 +32,7 @@
- name: Copy PostgreSQL config file
template:
src: postgresql.conf.j2
- dest: "/etc/postgresql/{{postgresql_version}}/main/conf.d/zz-evolinux.conf"
+ dest: "/etc/postgresql/{{ postgresql_version }}/main/conf.d/zz-evolinux.conf"
owner: postgres
group: postgres
mode: "0644"
diff --git a/postgresql/tasks/munin.yml b/postgresql/tasks/munin.yml
index 227304c8..feb0b678 100644
--- a/postgresql/tasks/munin.yml
+++ b/postgresql/tasks/munin.yml
@@ -12,8 +12,8 @@
- name: Add Munin plugins for PostgreSQL
file:
state: link
- src: '/usr/share/munin/plugins/{{item}}'
- dest: '/etc/munin/plugins/{{item}}'
+ src: '/usr/share/munin/plugins/{{ item }}'
+ dest: '/etc/munin/plugins/{{ item }}'
loop:
- postgres_bgwriter
- postgres_checkpoints
@@ -26,8 +26,8 @@
- name: Add Munin plugins for PostgreSQL (for specific databases)
file:
state: link
- src: '/usr/share/munin/plugins/{{item[0]}}'
- dest: '/etc/munin/plugins/{{item[0]}}{{item[1]}}'
+ src: '/usr/share/munin/plugins/{{ item[0] }}'
+ dest: '/etc/munin/plugins/{{ item[0] }}{{ item[1] }}'
loop: "{{ _plugins | product(_databases) | list }}"
vars:
_plugins:
diff --git a/postgresql/tasks/nrpe.yml b/postgresql/tasks/nrpe.yml
index 4aea2d81..833ab1ea 100644
--- a/postgresql/tasks/nrpe.yml
+++ b/postgresql/tasks/nrpe.yml
@@ -42,7 +42,7 @@
lineinfile:
name: /etc/nagios/nrpe.d/evolix.cfg
regexp: '^command\[check_pgsql\]='
- line: 'command[check_pgsql]=/usr/lib/nagios/plugins/check_pgsql -H localhost -l nrpe -p "{{postgresql_nrpe_password.stdout}}"'
+ line: 'command[check_pgsql]=/usr/lib/nagios/plugins/check_pgsql -H localhost -l nrpe -p "{{ postgresql_nrpe_password.stdout }}"'
notify: restart nagios-nrpe-server
when: postgresql_create_nrpe_user is changed
when: nrpe_evolix_config.stat.exists
diff --git a/postgresql/tasks/packages_bookworm.yml b/postgresql/tasks/packages_bookworm.yml
index 2a78b967..8db31b9b 100644
--- a/postgresql/tasks/packages_bookworm.yml
+++ b/postgresql/tasks/packages_bookworm.yml
@@ -1,5 +1,5 @@
---
-
+
- name: "Set variables (Debian 12)"
set_fact:
postgresql_version: '15'
@@ -11,6 +11,6 @@
- name: Install postgresql package
apt:
name:
- - "postgresql-{{postgresql_version}}"
+ - "postgresql-{{ postgresql_version }}"
- pgtop
- libdbd-pg-perl
diff --git a/postgresql/tasks/packages_bullseye.yml b/postgresql/tasks/packages_bullseye.yml
index 1b4cb0ac..e825b799 100644
--- a/postgresql/tasks/packages_bullseye.yml
+++ b/postgresql/tasks/packages_bullseye.yml
@@ -1,5 +1,5 @@
---
-
+
- name: "Set variables (Debian 11)"
set_fact:
postgresql_version: '13'
@@ -11,6 +11,6 @@
- name: Install postgresql package
apt:
name:
- - "postgresql-{{postgresql_version}}"
+ - "postgresql-{{ postgresql_version }}"
- pgtop
- libdbd-pg-perl
diff --git a/postgresql/tasks/packages_buster.yml b/postgresql/tasks/packages_buster.yml
index 815e741d..7ecf11be 100644
--- a/postgresql/tasks/packages_buster.yml
+++ b/postgresql/tasks/packages_buster.yml
@@ -11,6 +11,6 @@
- name: Install postgresql package
apt:
name:
- - "postgresql-{{postgresql_version}}"
+ - "postgresql-{{ postgresql_version }}"
- pgtop
- libdbd-pg-perl
diff --git a/postgresql/tasks/packages_jessie.yml b/postgresql/tasks/packages_jessie.yml
index b9f9b31b..60bb2247 100644
--- a/postgresql/tasks/packages_jessie.yml
+++ b/postgresql/tasks/packages_jessie.yml
@@ -10,8 +10,8 @@
- name: Install postgresql package
apt:
- name: '{{item}}'
+ name: '{{ item }}'
loop:
- - "postgresql-{{postgresql_version}}"
+ - "postgresql-{{ postgresql_version }}"
- ptop
- libdbd-pg-perl
diff --git a/postgresql/tasks/packages_stretch.yml b/postgresql/tasks/packages_stretch.yml
index a43c313b..45b8840c 100644
--- a/postgresql/tasks/packages_stretch.yml
+++ b/postgresql/tasks/packages_stretch.yml
@@ -11,6 +11,6 @@
- name: Install postgresql package
apt:
name:
- - "postgresql-{{postgresql_version}}"
+ - "postgresql-{{ postgresql_version }}"
- ptop
- libdbd-pg-perl
diff --git a/postgresql/tasks/pgdg-repo.yml b/postgresql/tasks/pgdg-repo.yml
index f03ae52f..ef467f97 100644
--- a/postgresql/tasks/pgdg-repo.yml
+++ b/postgresql/tasks/pgdg-repo.yml
@@ -31,12 +31,12 @@
- name: Add PGDG repository
apt_repository:
- repo: "deb [signed-by={{ apt_keyring_dir }}/postgresql.asc] http://apt.postgresql.org/pub/repos/apt/ {{ansible_distribution_release}}-pgdg main"
+ repo: "deb [signed-by={{ apt_keyring_dir }}/postgresql.asc] http://apt.postgresql.org/pub/repos/apt/ {{ ansible_distribution_release }}-pgdg main"
update_cache: yes
- name: Remove unsigned PGDG repository
apt_repository:
- repo: "deb http://apt.postgresql.org/pub/repos/apt/ {{ansible_distribution_release}}-pgdg main"
+ repo: "deb http://apt.postgresql.org/pub/repos/apt/ {{ ansible_distribution_release }}-pgdg main"
update_cache: yes
state: absent
diff --git a/postgresql/templates/postgresql.conf.j2 b/postgresql/templates/postgresql.conf.j2
index 9adce0b4..2f39937f 100644
--- a/postgresql/templates/postgresql.conf.j2
+++ b/postgresql/templates/postgresql.conf.j2
@@ -9,6 +9,9 @@ checkpoint_segments = 30
{% else %}
max_wal_size = 15GB
{% endif %}
+{% if postgresql_max_connections and postgresql_max_connections | int > 0 %}
+max_connections = {{ postgresql_max_connections }}
+{% endif %}
checkpoint_completion_target = 0.9
random_page_cost = {{ postgresql_random_page_cost }}
@@ -20,6 +23,8 @@ log_checkpoints = on
log_lock_waits = on
log_temp_files = 5MB
log_autovacuum_min_duration = 1s
+log_line_prefix = '%t [%p]: user=%u,db=%d,app=%a,client=%h '
+lc_messages = 'C'
# Locales
lc_monetary = 'fr_FR.UTF-8'
diff --git a/postgresql/templates/postgresql.pref.j2 b/postgresql/templates/postgresql.pref.j2
index 74196cf6..5d252e05 100644
--- a/postgresql/templates/postgresql.pref.j2
+++ b/postgresql/templates/postgresql.pref.j2
@@ -1,3 +1,3 @@
-Package: postgresql-{{postgresql_version}} postgresql-client-common postgresql-common libpq5 ptop
-Pin: release a={{ansible_distribution_release}}-pgdg
+Package: postgresql-{{ postgresql_version }} postgresql-client-common postgresql-common libpq5 ptop
+Pin: release a={{ ansible_distribution_release }}-pgdg
Pin-Priority: 999
diff --git a/postgresql/tests/test.yml b/postgresql/tests/test.yml
index 438eddee..88714dd1 100644
--- a/postgresql/tests/test.yml
+++ b/postgresql/tests/test.yml
@@ -6,7 +6,7 @@
apt:
name: locales
state: present
- changed_when: false
+ changed_when: False
- name: Setting default locales
lineinfile:
@@ -14,7 +14,7 @@
line: "{{ item }}"
create: yes
state: present
- changed_when: false
+ changed_when: False
loop:
- "en_US.UTF-8 UTF-8"
- "fr_FR ISO-8859-1"
@@ -23,7 +23,7 @@
- name: Reconfigure locales
command: /usr/sbin/locale-gen
- changed_when: false
+ changed_when: False
when: test_locales is changed
roles:
diff --git a/proftpd/tasks/account.yml b/proftpd/tasks/account.yml
index a03fd1f1..cfe82156 100644
--- a/proftpd/tasks/account.yml
+++ b/proftpd/tasks/account.yml
@@ -1,7 +1,7 @@
---
- name: Check if FTP account exist
command: grep "^{{ proftpd_name }}:" /etc/proftpd/vpasswd
- failed_when: false
+ failed_when: False
check_mode: no
changed_when: check_ftp_account.rc != 0
register: check_ftp_account
@@ -36,7 +36,7 @@
register: hashed_ftp_password
check_mode: no
when: check_ftp_account.rc == 0
- changed_when: false
+ changed_when: False
tags:
- proftpd
@@ -45,7 +45,7 @@
proftpd_password: "{{ hashed_ftp_password.stdout }}"
check_mode: no
when: check_ftp_account.rc == 0
- changed_when: false
+ changed_when: False
tags:
- proftpd
diff --git a/proftpd/tasks/accounts.yml b/proftpd/tasks/accounts.yml
index 4db814ef..b5cc5e85 100644
--- a/proftpd/tasks/accounts.yml
+++ b/proftpd/tasks/accounts.yml
@@ -70,7 +70,7 @@
loop_control:
loop_var: _proftpd_account
notify: restart proftpd
- when:
+ when:
- proftpd_sftp_enable | bool
- proftpd_sftp_use_publickeys | bool
tags:
diff --git a/proftpd/tasks/accounts_password.yml b/proftpd/tasks/accounts_password.yml
index 01517083..3ae37c88 100644
--- a/proftpd/tasks/accounts_password.yml
+++ b/proftpd/tasks/accounts_password.yml
@@ -1,7 +1,7 @@
---
- name: Check if FTP account exist
command: grep "^{{ item.name }}:" /etc/proftpd/vpasswd
- failed_when: false
+ failed_when: False
check_mode: no
changed_when: check_ftp_account.rc != 0
register: check_ftp_account
@@ -12,7 +12,7 @@
shell: grep "^{{ item.name }}:" /etc/proftpd/vpasswd | cut -d':' -f2
register: protftpd_cur_password
check_mode: no
- changed_when: false
+ changed_when: False
- name: Set password for this account
set_fact:
diff --git a/proftpd/tasks/main.yml b/proftpd/tasks/main.yml
index f45958a9..3afc69cb 100644
--- a/proftpd/tasks/main.yml
+++ b/proftpd/tasks/main.yml
@@ -56,7 +56,7 @@
owner: root
group: root
notify: restart proftpd
- when:
+ when:
- proftpd_sftp_enable | bool
- proftpd_sftp_use_publickeys | bool
tags:
diff --git a/rbenv/tasks/main.yml b/rbenv/tasks/main.yml
index de366e78..8294cfdc 100644
--- a/rbenv/tasks/main.yml
+++ b/rbenv/tasks/main.yml
@@ -88,8 +88,6 @@
- name: "is Ruby {{ rbenv_ruby_version }} available for {{ username }} ?"
shell: /bin/bash -lc "rbenv versions | grep {{ rbenv_ruby_version }}"
- args:
- warn: no
failed_when: False
changed_when: False
check_mode: False
@@ -101,8 +99,6 @@
- name: "Ruby {{ rbenv_ruby_version }} is available for {{ username }} (be patient... could be long)"
shell: /bin/bash -lc "TMPDIR=~/tmp rbenv install {{ rbenv_ruby_version }}"
- args:
- warn: no
when: ruby_installed.rc != 0
become_user: "{{ username }}"
become: yes
@@ -111,8 +107,6 @@
- name: "is Ruby {{ rbenv_ruby_version }} selected for {{ username }} ?"
shell: /bin/bash -lc "rbenv version | cut -d ' ' -f 1 | grep -Fx '{{ rbenv_ruby_version }}'"
- args:
- warn: no
register: ruby_selected
changed_when: False
failed_when: False
@@ -124,8 +118,6 @@
- name: "select Ruby {{ rbenv_ruby_version }} for {{ username }}"
shell: /bin/bash -lc "rbenv global {{ rbenv_ruby_version }} && rbenv rehash"
- args:
- warn: no
when: ruby_selected.rc != 0
become_user: "{{ username }}"
become: yes
diff --git a/redis/tasks/main.yml b/redis/tasks/main.yml
index d9a57bb2..24315b42 100644
--- a/redis/tasks/main.yml
+++ b/redis/tasks/main.yml
@@ -36,7 +36,7 @@
- name: Get Redis version
shell: "redis-server -v | grep -Eo '(v=\\S+)' | cut -d'=' -f 2 | grep -E '^([0-9]|\\.)+$'"
- changed_when: false
+ changed_when: False
check_mode: no
register: _redis_installed_version
tags:
diff --git a/redmine/tasks/mysql.yml b/redmine/tasks/mysql.yml
index 6c40a338..5f1f6631 100644
--- a/redmine/tasks/mysql.yml
+++ b/redmine/tasks/mysql.yml
@@ -4,7 +4,7 @@
register: redmine_get_mysql_password
check_mode: no
changed_when: False
- failed_when: false
+ failed_when: False
tags:
- redmine
diff --git a/redmine/tasks/user.yml b/redmine/tasks/user.yml
index 932e049c..dc959db1 100644
--- a/redmine/tasks/user.yml
+++ b/redmine/tasks/user.yml
@@ -41,4 +41,4 @@
- name: Enable systemd user mode
command: "loginctl enable-linger {{ redmine_user }}"
- changed_when: false
+ changed_when: False
diff --git a/remount-usr/handlers/main.yml b/remount-usr/handlers/main.yml
index 5f197e78..854a8883 100644
--- a/remount-usr/handlers/main.yml
+++ b/remount-usr/handlers/main.yml
@@ -1,6 +1,4 @@
---
- name: remount usr
command: "mount -o remount /usr"
- failed_when: false
- args:
- warn: no
+ failed_when: False
\ No newline at end of file
diff --git a/remount-usr/tasks/main.yml b/remount-usr/tasks/main.yml
index 1bfedc64..e4cf9d36 100644
--- a/remount-usr/tasks/main.yml
+++ b/remount-usr/tasks/main.yml
@@ -10,8 +10,6 @@
- name: "mount /usr in rw"
command: 'mount -o remount,rw /usr'
- args:
- warn: no
changed_when: False
when: usr_partition.rc == 0
notify: remount usr
diff --git a/spamassasin/tasks/main.yml b/spamassasin/tasks/main.yml
index a7568391..a2cbaf9a 100644
--- a/spamassasin/tasks/main.yml
+++ b/spamassasin/tasks/main.yml
@@ -87,7 +87,7 @@
- name: update SpamAssasin's rules
command: "/usr/share/scripts/sa-update.sh"
- changed_when: false
+ changed_when: False
tags:
- spamassassin
diff --git a/squid/tasks/main.yml b/squid/tasks/main.yml
index 4a3cab4d..5cb60ea9 100644
--- a/squid/tasks/main.yml
+++ b/squid/tasks/main.yml
@@ -24,7 +24,7 @@
- name: Fetch packages
package_facts:
- manager: auto
+ manager: auto
- debug:
var: ansible_facts.packages[squid_daemon_name]
diff --git a/tomcat-instance/tasks/check.yml b/tomcat-instance/tasks/check.yml
index eff9d236..b9426a33 100644
--- a/tomcat-instance/tasks/check.yml
+++ b/tomcat-instance/tasks/check.yml
@@ -6,7 +6,7 @@
- name: Check use of gid
command: id -ng "{{ tomcat_instance_port }}"
register: check_port_gid
- changed_when: false
+ changed_when: False
failed_when:
- check_port_gid | success
- check_port_gid.stdout != "{{ tomcat_instance_name }}"
@@ -14,7 +14,7 @@
- name: Check use of uid
command: id -nu "{{ tomcat_instance_port }}"
register: check_port_uid
- changed_when: false
+ changed_when: False
failed_when:
- check_port_uid | success
- check_port_uid.stdout != "{{ tomcat_instance_name }}"
diff --git a/tomcat-instance/tasks/systemd.yml b/tomcat-instance/tasks/systemd.yml
index 7558bbaa..c3a6a877 100644
--- a/tomcat-instance/tasks/systemd.yml
+++ b/tomcat-instance/tasks/systemd.yml
@@ -1,7 +1,7 @@
---
- name: Enable systemd user mode
command: "loginctl enable-linger {{ tomcat_instance_name }}"
- changed_when: false
+ changed_when: False
- name: Set systemd conf var
lineinfile:
diff --git a/userlogrotate/files/userlogrotate b/userlogrotate/files/userlogrotate
new file mode 100644
index 00000000..dfa51738
--- /dev/null
+++ b/userlogrotate/files/userlogrotate
@@ -0,0 +1,58 @@
+#!/bin/bash
+
+DATE="$(/bin/date +"%Y-%m-%d")"
+HOMEPREFIX="/home"
+
+rotate () {
+ mv $1 $1.$DATE
+ touch $1
+ chown $2 $1
+ chmod g+r $1
+}
+
+user_for() {
+ homedir="$(echo $1 | sed "s#\($HOMEPREFIX/\([^/]\+\)\).*#\1#")"
+ stat -L -c '%G' $homedir
+}
+
+for log in access.log access-*.log error.log; do
+ for i in $(ls -1 -d $HOMEPREFIX/*/log/$log 2>/dev/null | grep -v \.bak\.); do
+ USER="$(user_for $i)"
+ rotate $i root:$USER
+ done
+done
+
+for log in production.log delayed_job.log development.log test.log; do
+ for i in $(ls -1 -d $HOMEPREFIX/*/www/{,current/}log/$log 2>/dev/null | grep -v \.bak\.); do
+ USER="$(user_for $i)"
+ rotate $i $USER:$USER
+ done
+done
+
+test -x /usr/sbin/apache2ctl && if /etc/init.d/apache2 status > /dev/null ; then \
+ /etc/init.d/apache2 reload > /dev/null; \
+fi;
+
+test -x /usr/sbin/nginx && invoke-rc.d nginx rotate >/dev/null 2>&1
+
+# Zipping is done after web server reload, so that the file descriptor is released.
+# Else, an error is raised (gzip file size changed while zipping)
+# and logs written during the zipping process might be lost.
+
+for log in access.log*[!\.gz] access-*.log*[!\.gz] error.log*[!\.gz]; do
+ for i in $(ls -1 -d $HOMEPREFIX/*/log/$log 2>/dev/null | grep -v \.bak\.); do
+ if test -f "$i"; then
+ gzip "$i"
+ fi
+ done
+done
+
+for log in production.log*[!\.gz] delayed_job.log*[!\.gz] development.log*[!\.gz] test.log*[!\.gz]; do
+ for i in $(ls -1 -d $HOMEPREFIX/*/www/{,current/}log/$log 2>/dev/null | grep -v \.bak\.); do
+ if test -f "$i"; then
+ gzip "$i"
+ fi
+ done
+done
+
+exit 0
\ No newline at end of file
diff --git a/packweb-apache/files/userlogrotate b/userlogrotate/files/userlogrotate_jessie
similarity index 70%
rename from packweb-apache/files/userlogrotate
rename to userlogrotate/files/userlogrotate_jessie
index 7ed42668..347736fc 100644
--- a/packweb-apache/files/userlogrotate
+++ b/userlogrotate/files/userlogrotate_jessie
@@ -22,6 +22,11 @@ for log in access.log access-*.log error.log; do
done
done
+for i in `ls -1 -d $HOMEPREFIX/*/log/php.log 2>/dev/null | grep -v \.bak\.`; do
+ USER=`user_for $i`
+ rotate $i www-$USER:$USER
+done
+
for log in production.log delayed_job.log development.log test.log; do
for i in `ls -1 -d $HOMEPREFIX/*/www/{,current/}log/$log 2>/dev/null | grep -v \.bak\.`; do
USER=`user_for $i`
@@ -29,27 +34,26 @@ for log in production.log delayed_job.log development.log test.log; do
done
done
-test -x /usr/sbin/apache2ctl && if /etc/init.d/apache2 status > /dev/null ; then \
- /etc/init.d/apache2 reload > /dev/null; \
-fi;
-
-test -x /usr/sbin/nginx && invoke-rc.d nginx rotate >/dev/null 2>&1
+apache2ctl restart > /dev/null
# Zipping is done after web server reload, so that the file descriptor is released.
# Else, an error is raised (gzip file size changed while zipping)
# and logs written during the zipping process might be lost.
-for log in access.log access-*.log error.log; do
+for log in access.log*[!\.gz] access-*.log*[!\.gz] error.log*[!\.gz]; do
for i in `ls -1 -d $HOMEPREFIX/*/log/$log 2>/dev/null | grep -v \.bak\.`; do
- gzip $i
+ if test -f "$i"; then
+ gzip "$i"
+ fi
done
done
-for log in production.log delayed_job.log development.log test.log; do
+for log in production.log*[!\.gz] delayed_job.log*[!\.gz] development.log*[!\.gz] test.log*[!\.gz]; do
for i in `ls -1 -d $HOMEPREFIX/*/www/{,current/}log/$log 2>/dev/null | grep -v \.bak\.`; do
- gzip $i
+ if test -f "$i"; then
+ gzip "$i"
+ fi
done
done
-# we want exit 0
-true
+
diff --git a/userlogrotate/tasks/main.yml b/userlogrotate/tasks/main.yml
new file mode 100644
index 00000000..2642186c
--- /dev/null
+++ b/userlogrotate/tasks/main.yml
@@ -0,0 +1,34 @@
+---
+- name: "Is userlogrotate present ?"
+ ansible.builtin.find:
+ paths: ["/etc/cron.weekly", "/etc/cron.daily"]
+ patterns: ["userlogrotate"]
+ register: find_logrotate
+ check_mode: no
+
+- name: "Update userlogrotate"
+ ansible.builtin.copy:
+ src: userlogrotate
+ dest: "{{ item.path }}"
+ mode: "0755"
+ loop: "{{ find_logrotate.files }}"
+ when: find_logrotate.files | length>0
+
+- name: "Install userlogrotate (jessie)"
+ copy:
+ src: userlogrotate_jessie
+ dest: /etc/cron.weekly/userlogrotate
+ mode: "0755"
+ when:
+ - ansible_distribution_release == "jessie"
+ - find_logrotate.files | length==0
+
+- name: "Install userlogrotate (Debian 9 or later)"
+ copy:
+ src: userlogrotate
+ dest: /etc/cron.weekly/userlogrotate
+ mode: "0755"
+ when:
+ - ansible_distribution_major_version is version('9', '>=')
+ - find_logrotate.files | length==0
+
diff --git a/varnish/defaults/main.yml b/varnish/defaults/main.yml
index acc9b114..ec8a251e 100644
--- a/varnish/defaults/main.yml
+++ b/varnish/defaults/main.yml
@@ -17,6 +17,7 @@ varnish_jail: "unix,user=vcache"
varnish_additional_options: ""
varnish_config_file: /etc/varnish/default.vcl
+varnish_update_config: True
varnish_secret_file: /etc/varnish/secret
varnish_tmp_dir: /var/tmp-vcache
\ No newline at end of file
diff --git a/varnish/handlers/main.yml b/varnish/handlers/main.yml
index 7f9fd3ff..6e47bc10 100644
--- a/varnish/handlers/main.yml
+++ b/varnish/handlers/main.yml
@@ -12,7 +12,8 @@
daemon_reload: yes
- name: reload systemd
- command: systemctl daemon-reload
+ systemd:
+ daemon-reload: yes
- name: restart munin-node
service:
diff --git a/varnish/tasks/main.yml b/varnish/tasks/main.yml
index 43399f0d..cca302bb 100644
--- a/varnish/tasks/main.yml
+++ b/varnish/tasks/main.yml
@@ -122,8 +122,8 @@
- name: Patch logrotate conf
replace:
name: /etc/logrotate.d/varnish
- regexp: '^(\s+)(/usr/sbin/invoke-rc.d {{item}}.*)'
- replace: '\1systemctl -q is-active {{item}} && \2'
+ regexp: '^(\s+)(/usr/sbin/invoke-rc.d {{ item }}.*)'
+ replace: '\1systemctl -q is-active {{ item }} && \2'
loop:
- varnishlog
- varnishncsa
@@ -137,6 +137,7 @@
dest: "{{ varnish_config_file }}"
mode: "0644"
force: yes
+ when: "{{ varnish_update_config }}"
loop: "{{ query('first_found', templates) }}"
vars:
templates:
diff --git a/varnish/tasks/munin.yml b/varnish/tasks/munin.yml
index 1ccf5f88..77637a98 100644
--- a/varnish/tasks/munin.yml
+++ b/varnish/tasks/munin.yml
@@ -33,7 +33,7 @@
- name: Enable varnish5 munin plugin
file:
src: /usr/local/share/munin/plugins/varnish5_
- dest: "/etc/munin/plugins/varnish5_{{item}}"
+ dest: "/etc/munin/plugins/varnish5_{{ item }}"
state: link
loop:
- memory_usage
diff --git a/vrrpd/tasks/ip.yml b/vrrpd/tasks/ip.yml
index 273c882e..e58595a2 100644
--- a/vrrpd/tasks/ip.yml
+++ b/vrrpd/tasks/ip.yml
@@ -17,6 +17,6 @@
daemon_reload: yes
enabled: yes
state: "{{ vrrp_address.state }}"
- when:
+ when:
- vrrp_systemd_unit is changed
- not ansible_check_mode
\ No newline at end of file
diff --git a/webapps/evoadmin-web/tasks/user.yml b/webapps/evoadmin-web/tasks/user.yml
index bbad1b8f..0d453e9a 100644
--- a/webapps/evoadmin-web/tasks/user.yml
+++ b/webapps/evoadmin-web/tasks/user.yml
@@ -80,7 +80,7 @@
- include_role:
name: evolix/remount-usr
- when: evoadmin_scripts_dir is search ("/usr")
+ when: evoadmin_scripts_dir is search("/usr")
- name: "Create {{ evoadmin_scripts_dir }}"
file:
@@ -100,8 +100,6 @@
register: command_result
changed_when: "'changed' in command_result.stdout"
# failed_when: False
- args:
- warn: False
- name: Add evoadmin sudoers file
template:
diff --git a/webapps/nextcloud/defaults/main.yml b/webapps/nextcloud/defaults/main.yml
index 5c586620..c6e0a316 100644
--- a/webapps/nextcloud/defaults/main.yml
+++ b/webapps/nextcloud/defaults/main.yml
@@ -9,7 +9,7 @@ nextcloud_domains: []
nextcloud_home: "/home/{{ nextcloud_user }}"
nextcloud_webroot: "{{ nextcloud_home }}/nextcloud"
-nextcloud_data: "{{ nextcloud_webroot }}/data"
+nextcloud_data: "{{ nextcloud_home }}/data"
nextcloud_db_user: "{{ nextcloud_user }}"
nextcloud_db_name: "{{ nextcloud_instance_name }}"
diff --git a/webapps/nextcloud/templates/apache-vhost.conf.j2 b/webapps/nextcloud/templates/apache-vhost.conf.j2
index ff9f621c..556fa4cb 100644
--- a/webapps/nextcloud/templates/apache-vhost.conf.j2
+++ b/webapps/nextcloud/templates/apache-vhost.conf.j2
@@ -5,9 +5,11 @@
ServerAlias {{ domain_alias }}
{% endfor %}
+ # SSL
# SSLEngine on
# SSLCertificateFile /etc/letsencrypt/live/{{ nextcloud_instance_name }}/fullchain.pem
# SSLCertificateKeyFile /etc/letsencrypt/live/{{ nextcloud_instance_name }}/privkey.pem
+ # Header always set Strict-Transport-Security "max-age=15552000"
DocumentRoot {{ nextcloud_webroot }}/
@@ -21,6 +23,15 @@
+
+ Require all denied
+ AllowOverride None
+
+
+ Dav off
+
+
+
# SSL Redirect
# RewriteEngine On
# RewriteCond %{HTTPS} !=on
diff --git a/webapps/wordpress/tasks/main.yml b/webapps/wordpress/tasks/main.yml
index e1f442c0..32eda170 100644
--- a/webapps/wordpress/tasks/main.yml
+++ b/webapps/wordpress/tasks/main.yml
@@ -25,7 +25,7 @@
- name: Generate random password
command: apg -n1 -m 12 -M LCN
register: shell_password
- changed_when: false
+ changed_when: False
- name: Read mysql config from .my.cnf
set_fact:
@@ -48,13 +48,13 @@
- name: Configure site
shell: '{{ wordpress_wpcli }} core install --url={{ wordpress_host | quote }} --title={{ wordpress_title | quote }} --admin_user=admin --admin_password="{{ admin_pwd | quote }}" --admin_email={{ wordpress_email }} --skip-email'
- changed_when: false
+ changed_when: False
- name: Check if Wordpress is up to date
shell: '{{ wordpress_wpcli }} core check-update | grep -q Success'
register: check_version
check_mode: no
- failed_when: false
+ failed_when: False
changed_when: check_version.rc == 1
- name: Update Wordpress
@@ -65,17 +65,17 @@
- name: Install default plugin
shell: '{{ wordpress_wpcli }} plugin is-installed {{ item }} || {{ wordpress_wpcli }} plugin install {{ item }}'
- changed_when: false
+ changed_when: False
loop: "{{ wordpress_plugins }}"
- name: Update default plugins
shell: '{{ wordpress_wpcli }} plugin is-installed {{ item }} && {{ wordpress_wpcli }} plugin update {{ item }}'
- changed_when: false
+ changed_when: False
loop: "{{ wordpress_plugins }}"
- name: Activate default plugins
shell: '{{ wordpress_wpcli }} plugin is-installed {{ item }} && {{ wordpress_wpcli }} plugin activate {{ item }}'
- changed_when: false
+ changed_when: False
loop: "{{ wordpress_plugins }}"
- name: Send a summary mail