Merge pull request 'Release 10.0.0' (#100) from unstable into stable
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details

This commit is contained in:
Jérémy Lecour 2020-05-13 11:25:48 +02:00
commit 3a26f18201
309 changed files with 12614 additions and 1825 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
.kitchen/
.kateproject.d
.vagrant/
*.swp

View File

@ -16,8 +16,120 @@ The **patch** part changes incrementally at each release.
### Fixed
### Removed
### Security
## [10.0.0] - 2020-05-13
### Added
* apache: the default VHost doesn't redirect to https for ".well-known" paths
* apt: added buster backports prerferences
* apt: check if cron is installed before adding a cron job
* apt: remove jessie/buster sources from Gandi servers
* apt: verify that /etc/evolinux is present
* certbot : new role to install and configure certbot
* etc-git: add versioning for /usr/share/scripts on Debian 10+
* evoacme: upstream version 19.11
* evolinux-base: default value for "evolinux_ssh_group"
* evolinux-base: install /sbin/deny
* evolinux-base: install Evocheck (default: `True`)
* evolinux-base: on debian 10 and later, add noexec on /dev/shm
* evolinux-base: on debian 10 and later, add /usr/share/scripts in root's PATH
* evolinux-base: remove the chrony package
* evomaintenance: don't configure firewall for database if not necessary
* generate-ldif: support MariaDB 10.3
* haproxy: add a variable to keep the existing configuration
* java: add Java 11 as possible version to install
* listupgrade: install old-kernel-autoremoval script
* minifirewall: add a variable to force the check scripts update
* mongodb: mongodb: compatibility with Debian 10
* mysql-oracle: backport tasks from mysql role
* mysql: activate binary logs by specifying log_bin path
* mysql: specify a custom server_id
* networkd-to-ifconfig: add variables for configuration by variables
* packweb-apache: Deploy opcache.php to give some insights on PHP's opcache status
* php: variable to install the mysqlnd module instead of the default mysql module
* postgresql : variable to install PostGIS (default: `False`)
* redis: rewrite of the role (separate instances, better systemd units…)
* webapps/evoadmin-web Add an htpasswd to evoadmin if you cant use an apache IP whitelist
* webapps/evoadmin-web Overload templates if needed
* evolinux-base: install ssacli for HP Smart Array
* evobackup-client role to configure a machine for backups with bkctld(8)
* bind: enable query logging for recursive resolvers
* bind: enable logrotate for recursive resolvers
* bind: enable bind9 munin plugin for recursive resolvers
### Changed
* replace version_compare() with version()s
* removed some deprecations for Ansible 2.7
* apache: improve permissions in save_apache_status script
* apt: hold packages only if package is installed
* bind: the munin task was present, but not included
* bind: change name of logrotate file to bind9
* certbot: commit hook must be executed at the end
* elasticsearch: listen on local interface only by default
* evocheck: upstream version 20.04.4
* evocheck: cron jobs execute in verbose
* evolinux-base: use "evolinux_internal_group" for SSH authentication
* evolinux-base: Don't customize the logcheck recipient by default.
* evolinux-base: configure cciss-vol-statusd in the proper file
* evomaintenance: upstream release 0.6.3
* evomaintenance: Turn on API by default (instead of DB)
* evomaintenance: install PG dependencies only when needed
* listupgrade: update from upstream
* lxc: rely on lxc_container module instead of command module
* lxc: remove useless loop in apt execution
* lxc: update our default template to be compatible with Debian 10
* lxc-php: refactor tasks for better maintainability
* lxc-php: Use OpenSMTPD for Stretch/Buster containers, and ssmtp for Jessie containers
* lxc-solr: changed default Solr version to 8.4.1
* minifirewall: better alert5 activation
* minifirewall: no http filtering by default
* minifirewall: /bin/true command doesn't report "changed" anymore
* nagios-nrpe: update check_redis_instances (same as redis role)
* nagios-nrpe: change default haproxy socket path
* nagios-nrpe: check_mode per cpu dynamically
* nodejs: change default version to 12 (new LTS)
* packweb-apache: Do the install & conffigure phpContainer script (instead of evoadmin-web role)
* php: By default, allow 128M for OpCache (instead of 64M)
* php: Don't set a chroot for the default fpm pool
* php: Make sure the default pool we define can be fully functionnal witout debian's default pool file
* php: Change the default pool names to something more explicit (and same for the variables names)
* php: Add a task to remove Debian's default FPM pool file (off by default)
* php: Cleanup CLI Settings. Also, allow url fopen and don't disable functions (in CLI only)
* postgresql : changed logrotate config to 10 days (and fixed permissions)
* rbenv: changed default Ruby version to 2.7.0
* squid: Remove wait time when we turn off squid
* squid: compatibility wit Debian 10
* tomcat: package version derived from Debian version if missing
* varnish: remove custom ExecReload= script for Debian 10+
### Fixed
* etc-git: fix warnings ansible-lint
* evoadmin-web: Put the php config at the right place for Buster
* lxc: Don't stop the container if it already exists
* lxc: Fix container existance check to be able to run in check_mode
* lxc-php: Don't remove the default pool
* minifirewall: fix warnings ansible-lint
* nginx: fix munin fcgi not working (missing chmod 660 on logs)
* php: add missing handler for php7.3-fpm
* roundcube: fix typo for roundcube vhost
* tomcat: fix typo for default tomcat_version
* evolinux-base: Fix our zsyslog rotate config that doesn't work on Debian 10
* certbot: Properly evaluate when apache is installed
* evolinux-base: Don't make alert5.service executable as systemd will complain
* webapps/evoadmin-web: Set default evoadmin_mail_tpl_force to True to fix a regression where the mail template would not get updated because the file is created before the role is first run.
* minifirewall: Backport changes from minifirewall (properly open outgoing smtp(s))
* minifirewall: Properly detect alert5.sh to turn on firewall at boot
* packweb-apache: Add missing dependency to evoacme role
* php: Chose the debian version repo archive for packages.sury.org
* php: update surry_post.yml to match current latest PHP release
* packweb-apache: Don't try to install PHPMyAdmin on Buster as it's not available
### Removed
* clamav : do not install the zoo package anymore
## [9.10.1] - 2019-06-21
### Changed

View File

@ -1,11 +1,10 @@
---
- name: install Amavis
apt:
name: "{{ item }}"
name:
- postgrey
- amavisd-new
state: present
with_items:
- postgrey
- amavisd-new
tags:
- amavis

View File

@ -52,7 +52,7 @@ In your main evolinux playbook put this play before Evolinux one:
tasks:
- include_role:
name: amazon-ec2
name: evolix/amazon-ec2
tasks_from: create-instance.yml
```

View File

@ -10,10 +10,10 @@
tasks:
- include_role:
name: amazon-ec2
name: evolix/amazon-ec2
tasks_from: setup.yml
- include_role:
name: amazon-ec2
name: evolix/amazon-ec2
tasks_from: create-instance.yml
- name: Install Evolinux
@ -52,11 +52,11 @@
post_tasks:
- include_role:
name: etc-git
name: evolix/etc-git
tasks_from: commit.yml
vars:
commit_message: "Ansible post-run Evolinux playbook"
- include_role:
name: evocheck
name: evolix/evocheck
tasks_from: exec.yml

View File

@ -7,11 +7,15 @@ URL="http://127.0.0.1/server-status"
TS=`date +%Y%m%d%H%M%S`
FILE="${DIR}/${TS}.html"
mkdir -p "${DIR}"
wget -q -O "${FILE}" "${URL}"
if [ ! -d "${DIR}" ]; then
mkdir -p "${DIR}"
chown root:adm "${DIR}"
chmod 750 "${DIR}"
fi
wget -q -U "save_apache_status" -O "${FILE}" "${URL}"
chmod 640 "${FILE}"
chown root:adm "${FILE}"
find "${DIR}" -type f -mtime +1 -delete

View File

@ -2,28 +2,26 @@
- name: packages are installed (Debian 9 or later)
apt:
name: '{{ item }}'
name:
- apache2
- libapache2-mpm-itk
- libapache2-mod-evasive
- apachetop
- libwww-perl
state: present
with_items:
- apache2
- libapache2-mpm-itk
- libapache2-mod-evasive
- apachetop
- libwww-perl
tags:
- apache
- packages
when: ansible_distribution_major_version | version_compare('9', '>=')
when: ansible_distribution_major_version is version('9', '>=')
- name: packages are installed (jessie)
apt:
name: '{{ item }}'
name:
- apache2-mpm-itk
- libapache2-mod-evasive
- apachetop
- libwww-perl
state: present
with_items:
- apache2-mpm-itk
- libapache2-mod-evasive
- apachetop
- libwww-perl
tags:
- apache
- packages
@ -140,7 +138,7 @@
- apache
- include_role:
name: remount-usr
name: evolix/remount-usr
tags:
- apache

View File

@ -2,11 +2,10 @@
- name: "Install munin-node and core plugins packages"
apt:
name: "{{ item }}"
name:
- munin-node
- munin-plugins-core
state: present
with_items:
- munin-node
- munin-plugins-core
tags:
- apache
- munin
@ -27,11 +26,10 @@
- name: "Install fcgi packages for Munin graphs"
apt:
name: "{{ item }}"
name:
- libapache2-mod-fcgid
- libcgi-fast-perl
state: present
with_items:
- libapache2-mod-fcgid
- libcgi-fast-perl
notify: reload apache
tags:
- apache

View File

@ -43,6 +43,7 @@
RewriteEngine on
# Redirect to HTTPS, execpt for munin, because some plugins
# can't handle HTTPS! :(
RewriteCond %{REQUEST_URI} !^/.well-known.*$ [NC] [OR]
RewriteCond %{REQUEST_URI} !^/server-status.*$ [NC] [OR]
RewriteCond %{REQUEST_URI} !^/munin_opcache.php$ [NC]
RewriteRule ^/(.*) https://{{ ansible_fqdn }}/$1 [L,R=permanent]
@ -107,6 +108,15 @@
Require all denied
Include /etc/apache2/ipaddr_whitelist.conf
</Directory>
ScriptAlias /munin-cgi/munin-cgi-graph /usr/lib/munin/cgi/munin-cgi-graph
<Location /munin-cgi/munin-cgi-graph>
Options +ExecCGI
<IfModule mod_fcgid.c>
SetHandler fcgid-script
</IfModule>
Require all denied
Include /etc/apache2/ipaddr_whitelist.conf
</Location>
# BEGIN phpMyAdmin section
# END phpMyAdmin section

View File

@ -0,0 +1,3 @@
Package: *
Pin: release a=buster-backports
Pin-Priority: 50

View File

@ -40,6 +40,6 @@
- name: Apt update
apt:
update_cache: yes
when: apt_backports_list | changed or apt_backports_config | changed
when: apt_backports_list is changed or apt_backports_config is changed
tags:
- apt

View File

@ -16,7 +16,9 @@
state: absent
with_items:
- /etc/apt/sources.list.d/debian-security.list
- /etc/apt/sources.list.d/debian-jessie.list
- /etc/apt/sources.list.d/debian-stretch.list
- /etc/apt/sources.list.d/debian-buster.list
- /etc/apt/sources.list.d/debian-update.list
when: apt_clean_gandi_sourceslist
tags:
@ -25,6 +27,6 @@
- name: Apt update
apt:
update_cache: yes
when: apt_basic_list | changed
when: apt_basic_list is changed
tags:
- apt

View File

@ -28,6 +28,6 @@
- name: Apt update
apt:
update_cache: yes
when: apt_evolix_public | changed
when: apt_evolix_public is changed
tags:
- apt

View File

@ -1,10 +1,19 @@
---
- name: "hold packages (apt)"
shell: "(apt-mark showhold | grep --quiet {{ item }}) || apt-mark hold {{ item }}"
shell: "(dpkg -l {{ item }} 2>/dev/null | grep -q -E '^(i|h)i') && ((apt-mark showhold | grep --quiet {{ item }}) || apt-mark hold {{ item }})"
register: apt_mark
changed_when: "'{{ item }} set on hold.' in apt_mark.stdout"
with_items: "{{ apt_hold_packages }}"
changed_when: "item + ' set on hold.' in apt_mark.stdout"
failed_when: apt_mark.rc != 0 and not apt_mark.stdout == ''
loop: "{{ apt_hold_packages }}"
tags:
- apt
- name: "/etc/evolinux is present"
file:
dest: /etc/evolinux
mode: "0700"
state: directory
tags:
- apt
@ -14,15 +23,16 @@
line: "{{ item }}"
create: True
state: present
with_items: "{{ apt_hold_packages }}"
loop: "{{ apt_hold_packages }}"
tags:
- apt
- name: "unhold packages (apt)"
shell: "(apt-mark showhold | grep --quiet {{ item }}) && apt-mark unhold {{ item }}"
shell: "(dpkg -l {{ item }} 2>/dev/null | grep -q -E '^(i|h)i') && ((apt-mark showhold | grep --quiet {{ item }}) && apt-mark unhold {{ item }})"
register: apt_mark
changed_when: "'Canceled hold on {{ item }}.' in apt_mark.stdout"
with_items: "{{ apt_unhold_packages }}"
changed_when: "'Canceled hold on' + item in apt_mark.stdout"
failed_when: apt_mark.rc != 0 and not apt_mark.stdout = ''
loop: "{{ apt_unhold_packages }}"
tags:
- apt
@ -32,7 +42,7 @@
line: "{{ item }}"
create: True
state: absent
with_items: "{{ apt_unhold_packages }}"
loop: "{{ apt_unhold_packages }}"
tags:
- apt
@ -55,6 +65,15 @@
tags:
- apt
- 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
check_mode: no
tags:
- apt
- name: Check for held packages (script)
cron:
cron_file: apt-hold-packages
@ -67,5 +86,6 @@
day: "{{ apt_check_hold_cron_day }}"
month: "{{ apt_check_hold_cron_month }}"
state: "present"
when: is_cron.rc == 0
tags:
- apt

View File

@ -4,7 +4,7 @@
fail:
msg: only compatible with Debian >= 8
when:
- ansible_distribution != "Debian" or ansible_distribution_major_version | version_compare('8', '<')
- ansible_distribution != "Debian" or ansible_distribution_major_version is version('8', '<')
tags:
- apt

View File

@ -2,8 +2,10 @@
bind_recursive_server: False
bind_authoritative_server: True
bind_chroot_set: True
bind_chroot_path: /var/chroot-bind
# Until chroot-bind.sh is migrated to ansible, we hardcode the chroot paths.
#bind_chroot_path: /var/chroot-bind
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_cache_dir: /var/cache/bind

View File

@ -1,10 +1,19 @@
# 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
when: bind_chroot_set
- name: package are installed
apt:
name: '{{ item }}'
name:
- bind9
- dnstop
state: present
with_items:
- bind9
- dnstop
- name: Set bind configuration for recursive server
template:
@ -49,23 +58,23 @@
- restart bind
when: ansible_distribution_release == "jessie"
- name: touch /var/log/bind.log if non chroot
- name: "touch {{ bind_log_file }} if non chroot"
file:
path: /var/log/bind.log
path: "{{ bind_log_file }}"
owner: bind
group: adm
mode: "0640"
state: touch
when: bind_chroot_set == False
when: not bind_chroot_set
- name: touch /var/log/bind_queries.log if non chroot
- name: "touch {{ bind_query_file }} if non chroot"
file:
path: /var/log/bind_queries.log
path: "{{ bind_query_file }}"
owner: bind
group: adm
mode: "0640"
state: touch
when: bind_authoritative_server and bind_chroot_set == False
when: not bind_chroot_set
- name: send chroot-bind.sh in /root
copy:
@ -95,24 +104,14 @@
notify: restart bind
when: bind_chroot_set
- name: logrotate for non chroot bind
- name: logrotate for bind
template:
src: logrotate_bind
dest: /etc/logrotate.d/bind
src: logrotate_bind.j2
dest: /etc/logrotate.d/bind9
owner: root
group: root
mode: "0644"
force: yes
notify: restart bind
when: bind_chroot_set == False
- name: logrotate for chroot bind
template:
src: logrotate_bind_chroot.j2
dest: /etc/logrotate.d/bind
owner: root
group: root
mode: "0644"
force: yes
notify: restart bind
when: bind_chroot_set
- include: munin.yml

View File

@ -8,9 +8,8 @@
tags:
- bind
- munin
when: bind_authoritative_server
- name: Enable munin plugins
- name: Enable munin plugins for authoritative server
file:
src: "/usr/share/munin/plugins/{{ item }}"
dest: "/etc/munin/plugins/{{ item }}"
@ -19,7 +18,25 @@
- bind9
- bind9_rndc
notify: restart munin-node
when: bind_authoritative_server and munin_node_plugins_config.stat.exists
when:
- bind_authoritative_server
- munin_node_plugins_config.stat.exists
tags:
- bind
- munin
- name: Enable munin plugins for recursive server
file:
src: "/usr/share/munin/plugins/{{ item }}"
dest: "/etc/munin/plugins/{{ item }}"
state: link
with_items:
- bind9
- bind9_rndc
notify: restart munin-node
when:
- bind_recursive_server
- munin_node_plugins_config.stat.exists
tags:
- bind
- munin
@ -33,7 +50,7 @@
mode: "0644"
force: yes
notify: restart munin-node
when: bind_authoritative_server and munin_node_plugins_config.stat.exists
when: munin_node_plugins_config.stat.exists
tags:
- bind
- munin

View File

@ -1,4 +1,8 @@
/var/log/bind.log {
{% if bind_chroot_set %}
{{ bind_chroot_path }}{{bind_log_file}} {
{% else %}
{{bind_log_file}} {
{% endif %}
weekly
missingok
rotate 52

View File

@ -1,10 +0,0 @@
{{ bind_chroot_path }}/var/log/bind.log {
weekly
missingok
rotate 52
create 640 bind bind
sharedscripts
postrotate
rndc reload > /dev/null
endscript
}

View File

@ -1,6 +1,9 @@
[bind*]
user root
env.logfile {{ bind_query_file }}
env.querystats {{ bind_chroot_path }}{{ bind_statistics_file }}
env.logfile {% if bind_chroot_set %}{{ bind_chroot_path }}{% endif %}{{ bind_query_file }}
{% 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

View File

@ -4,11 +4,11 @@ acl "foo" {
};
options {
directory "/var/cache/bind";
directory "{{ bind_cache_dir }}";
version "Bingo";
auth-nxdomain no;
masterfile-format text;
statistics-file "/var/run/named.stats";
statistics-file "{{ bind_statistics_file }}";
listen-on-v6 { any; };
listen-on { any; };
@ -23,11 +23,11 @@ logging {
category queries { query_logging; };
channel default_file {
file "/var/log/bind.log";
file "{{ bind_log_file }}";
severity info;
};
channel query_logging {
file "/var/log/bind_queries.log" versions 2 size 128M;
file "{{ bind_query_file }}" versions 2 size 128M;
print-category yes;
print-severity yes;
print-time yes;

View File

@ -1,5 +1,5 @@
options {
directory "/var/cache/bind";
directory "{{ bind_cache_dir }}";
version "Bingo";
auth-nxdomain no;
listen-on-v6 { ::1; };
@ -8,9 +8,17 @@ options {
};
logging {
category default { default_file; };
channel default_file {
file "/var/log/bind.log";
severity info;
};
category default { default_file; };
category queries { query_logging; };
channel default_file {
file "{{ bind_log_file }}";
severity info;
};
channel query_logging {
file "{{ bind_query_file }}" versions 2 size 128M;
print-category yes;
print-severity yes;
print-time yes;
};
};

View File

@ -0,0 +1,3 @@
---
certbot_work_dir: /var/lib/letsencrypt

11
certbot/files/cron_jessie Normal file
View File

@ -0,0 +1,11 @@
# /etc/cron.d/certbot: crontab entries for the certbot package
#
# Upstream recommends attempting renewal twice a day
#
# Eventually, this will be an opportunity to validate certificates
# haven't been revoked, etc. Renewal will only occur if expiration
# is within 30 days.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
0 */12 * * * root test -x /usr/local/bin/certbot && perl -e 'sleep int(rand(3600))' && /usr/local/bin/certbot --no-self-update -q renew

View File

@ -0,0 +1,44 @@
#!/bin/sh
error() {
>&2 echo "${PROGNAME}: $1"
exit 1
}
debug() {
if [ "${VERBOSE}" = "1" ] && [ "${QUIET}" != "1" ]; then
>&2 echo "${PROGNAME}: $1"
fi
}
daemon_found_and_running() {
test -n "$(pidof apache2)" && test -n "${apache2ctl_bin}"
}
config_check() {
${apache2ctl_bin} configtest > /dev/null 2>&1
}
letsencrypt_used() {
grep -q -r -E "letsencrypt" /etc/apache2/
}
main() {
if daemon_found_and_running; then
if letsencrypt_used; then
if config_check; then
debug "Apache detected... reloading"
systemctl reload apache2
else
error "Apache config is broken, you must fix it !"
fi
else
debug "Apache doesn't use Let's Encrypt certificate. Skip."
fi
else
debug "Apache is not running or missing. Skip."
fi
}
readonly PROGNAME=$(basename "$0")
readonly VERBOSE=${VERBOSE:-"0"}
readonly QUIET=${QUIET:-"0"}
readonly apache2ctl_bin=$(command -v apache2ctl)
main

View File

@ -0,0 +1,44 @@
#!/bin/sh
error() {
>&2 echo "${PROGNAME}: $1"
exit 1
}
debug() {
if [ "${VERBOSE}" = "1" ] && [ "${QUIET}" != "1" ]; then
>&2 echo "${PROGNAME}: $1"
fi
}
daemon_found_and_running() {
test -n "$(pidof dovecot)" && test -n "${doveconf_bin}"
}
config_check() {
${doveconf_bin} > /dev/null 2>&1
}
letsencrypt_used() {
${doveconf_bin} | grep -E "^ssl_cert[^_]" | grep -q "letsencrypt"
}
main() {
if daemon_found_and_running; then
if letsencrypt_used; then
if config_check; then
debug "Dovecot detected... reloading"
systemctl reload dovecot
else
error "Dovecot config is broken, you must fix it !"
fi
else
debug "Dovecot doesn't use Let's Encrypt certificate. Skip."
fi
else
debug "Dovecot is not running or missing. Skip."
fi
}
readonly PROGNAME=$(basename "$0")
readonly VERBOSE=${VERBOSE:-"0"}
readonly QUIET=${QUIET:-"0"}
readonly doveconf_bin=$(command -v doveconf)
main

View File

@ -0,0 +1,75 @@
#!/bin/sh
error() {
>&2 echo "${PROGNAME}: $1"
exit 1
}
debug() {
if [ "${VERBOSE}" = "1" ] && [ "${QUIET}" != "1" ]; then
>&2 echo "${PROGNAME}: $1"
fi
}
daemon_found_and_running() {
test -n "$(pidof haproxy)" && test -n "${haproxy_bin}"
}
found_renewed_lineage() {
test -f "${RENEWED_LINEAGE}/fullchain.pem" && test -f "${RENEWED_LINEAGE}/privkey.pem"
}
config_check() {
${haproxy_bin} -c -f /etc/haproxy/haproxy.cfg > /dev/null 2>&1
}
concat_files() {
# shellcheck disable=SC2174
mkdir --mode=700 --parents "${haproxy_cert_dir}"
chown root: "${haproxy_cert_dir}"
debug "Concatenating certificate files to ${haproxy_cert_file}"
cat "${RENEWED_LINEAGE}/fullchain.pem" "${RENEWED_LINEAGE}/privkey.pem" > "${haproxy_cert_file}"
chmod 600 "${haproxy_cert_file}"
chown root: "${haproxy_cert_file}"
}
cert_and_key_mismatch() {
haproxy_cert_md5=$(openssl x509 -noout -modulus -in "${haproxy_cert_file}" | openssl md5)
haproxy_key_md5=$(openssl rsa -noout -modulus -in "${haproxy_cert_file}" | openssl md5)
test "${haproxy_cert_md5}" != "${haproxy_key_md5}"
}
main() {
if [ -z "${RENEWED_LINEAGE}" ]; then
error "This script must be called only by certbot!"
fi
if daemon_found_and_running; then
if found_renewed_lineage; then
haproxy_cert_file="${haproxy_cert_dir}/$(basename "${RENEWED_LINEAGE}").pem"
failed_cert_file="/root/$(basename "${RENEWED_LINEAGE}").failed.pem"
concat_files
if cert_and_key_mismatch; then
mv "${haproxy_cert_file}" "${failed_cert_file}"
error "Key and cert don't match, we moved the file to ${failed_cert_file} for inspection"
fi
if config_check; then
debug "HAProxy detected... reloading"
systemctl reload haproxy
else
error "HAProxy config is broken, you must fix it !"
fi
else
error "Couldn't find ${RENEWED_LINEAGE}/fullchain.pem or ${RENEWED_LINEAGE}/privkey.pem"
fi
else
debug "HAProxy is not running or missing. Skip."
fi
}
readonly PROGNAME=$(basename "$0")
readonly VERBOSE=${VERBOSE:-"0"}
readonly QUIET=${QUIET:-"0"}
readonly haproxy_bin=$(command -v haproxy)
readonly haproxy_cert_dir="/etc/ssl/haproxy"
main

View File

@ -0,0 +1,44 @@
#!/bin/sh
error() {
>&2 echo "${PROGNAME}: $1"
exit 1
}
debug() {
if [ "${VERBOSE}" = "1" ] && [ "${QUIET}" != "1" ]; then
>&2 echo "${PROGNAME}: $1"
fi
}
daemon_found_and_running() {
test -n "$(pidof nginx)" && test -n "${nginx_bin}"
}
config_check() {
${nginx_bin} -t > /dev/null 2>&1
}
letsencrypt_used() {
grep -q --dereference-recursive -E "letsencrypt" /etc/nginx/sites-enabled
}
main() {
if daemon_found_and_running; then
if letsencrypt_used; then
if config_check; then
debug "Nginx detected... reloading"
systemctl reload nginx
else
error "Nginx config is broken, you must fix it !"
fi
else
debug "Nginx doesn't use Let's Encrypt certificate. Skip."
fi
else
debug "Nginx is not running or missing. Skip."
fi
}
readonly PROGNAME=$(basename "$0")
readonly VERBOSE=${VERBOSE:-"0"}
readonly QUIET=${QUIET:-"0"}
readonly nginx_bin=$(command -v nginx)
main

View File

@ -0,0 +1,44 @@
#!/bin/sh
error() {
>&2 echo "${PROGNAME}: $1"
exit 1
}
debug() {
if [ "${VERBOSE}" = "1" ] && [ "${QUIET}" != "1" ]; then
>&2 echo "${PROGNAME}: $1"
fi
}
daemon_found_and_running() {
test -n "$(pidof master)" && test -n "${postconf_bin}"
}
config_check() {
${postconf_bin} > /dev/null 2>&1
}
letsencrypt_used() {
${postconf_bin} | grep -E "^smtpd_tls_cert_file" | grep -q "letsencrypt"
}
main() {
if daemon_found_and_running; then
if letsencrypt_used; then
if config_check; then
debug "Postfix detected... reloading"
systemctl reload postfix
else
error "Postfix config is broken, you must fix it !"
fi
else
debug "Postfix doesn't use Let's Encrypt certificate. Skip."
fi
else
debug "Postfix is not running or missing. Skip."
fi
}
readonly PROGNAME=$(basename "$0")
readonly VERBOSE=${VERBOSE:-"0"}
readonly QUIET=${QUIET:-"0"}
readonly postconf_bin=$(command -v postconf)
main

View File

@ -0,0 +1,37 @@
#!/bin/sh
error() {
>&2 echo "${PROGNAME}: $1"
exit 1
}
debug() {
if [ "${VERBOSE}" = "1" ] && [ "${QUIET}" != "1" ]; then
>&2 echo "${PROGNAME}: $1"
fi
}
main() {
export GIT_DIR="/etc/.git"
export GIT_WORK_TREE="/etc"
if test -x "${git_bin}" && test -d "${GIT_DIR}" && test -d "${GIT_WORK_TREE}"; then
changed_lines=$(${git_bin} status --porcelain | wc -l | tr -d ' ')
if [ "${changed_lines}" != "0" ]; then
debug "Committing for ${RENEWED_DOMAINS}"
${git_bin} add --all
message="[letsencrypt] certificates renewal (${RENEWED_DOMAINS})"
${git_bin} commit --message "${message}" --quiet
else
error "Weird, nothing has changed but the hook has been executed for '${RENEWED_DOMAINS}'"
fi
fi
}
readonly PROGNAME=$(basename "$0")
readonly VERBOSE=${VERBOSE:-"0"}
readonly QUIET=${QUIET:-"0"}
readonly git_bin=$(command -v git)
readonly letsencrypt_dir=/etc/letsencrypt
main

23
certbot/handlers/main.yml Normal file
View File

@ -0,0 +1,23 @@
---
- name: reload nginx
service:
name: nginx
state: reloaded
- name: reload apache
service:
name: apache2
state: reloaded
- name: reload haproxy
service:
name: haproxy
state: reloaded
- name: systemd daemon-reload
systemd:
daemon_reload: yes
- name: install certbot-auto
command: /usr/local/bin/certbot --install-only

View File

@ -0,0 +1,51 @@
---
- name: Certbot work directory is present
file:
dest: "{{ certbot_work_dir }}"
state: directory
mode: "0755"
- name: Check if Nginx is installed
stat:
path: /etc/nginx
register: is_nginx
- name: ACME challenge for Nginx is installed
template:
src: acme-challenge/nginx.conf.j2
dest: /etc/nginx/snippets/letsencrypt.conf
force: yes
notify: reload nginx
when: is_nginx.stat.exists
- name: Check if Apache is installed
stat:
path: /usr/sbin/apachectl
register: is_apache
- name: ACME challenge for Apache
block:
- name: ACME challenge for Apache is installed
template:
src: acme-challenge/apache.conf.j2
dest: /etc/apache2/conf-available/letsencrypt.conf
force: yes
notify: reload apache
- name: ACME challenge for Apache is enabled
command: "a2enconf letsencrypt"
register: command_result
changed_when: "'Enabling' in command_result.stderr"
notify: reload apache
when: is_apache.stat.exists
- name: Check if HAProxy is installed
stat:
path: /etc/haproxy
register: is_haproxy
- name: ACME challenge for HAProxy is installed
debug:
msg: "ACME challenge configuration for HAProxy must be configured manually"
when: is_haproxy.stat.exists

View File

@ -0,0 +1,6 @@
---
- name: certbot package is installed
apt:
name: certbot
state: latest

View File

@ -0,0 +1,35 @@
---
- name: certbot package is removed
apt:
name: certbot
state: absent
- include_role:
name: evolix/remount-usr
- name: Certbot script is downloaded
get_url:
url: https://dl.eff.org/certbot-auto
dest: /usr/local/bin/certbot
mode: '0755'
owner: root
group: root
force: no
notify: install certbot-auto
- name: systemd artefacts are absent
file:
dest: "{{ item }}"
state: absent
loop:
- /etc/systemd/system/certbot.service
- /etc/systemd/system/certbot.service.d
- /etc/systemd/system/certbot.timer
notify: systemd daemon-reload
- name: custom crontab is present
copy:
src: cron_jessie
dest: /etc/cron.d/certbot
force: yes

44
certbot/tasks/main.yml Normal file
View File

@ -0,0 +1,44 @@
---
- name: "System compatibility checks"
assert:
that:
- ansible_distribution == "Debian"
- ansible_distribution_major_version is version('8', '>=')
msg: only compatible with Debian 9+
- name: Install from sources on Debian 8
include: install-sources.yml
when:
- ansible_distribution == "Debian"
- ansible_distribution_major_version is version('8', '=')
- name: Install package on Debian 9+
include: install-package.yml
when:
- ansible_distribution == "Debian"
- ansible_distribution_major_version is version('9', '>=')
- include: acme-challenge.yml
- name: Deploy hooks are present
copy:
src: hooks/
dest: /etc/letsencrypt/renewal-hooks/deploy/
mode: "0700"
owner: root
group: root
- name: Move commit-etc.sh to z-commit-etc.sh if present
command: "mv /etc/letsencrypt/renewal-hooks/deploy/commit-etc.sh /etc/letsencrypt/renewal-hooks/deploy/z-commit-etc.sh"
args:
removes: /etc/letsencrypt/renewal-hooks/deploy/commit-etc.sh
creates: /etc/letsencrypt/renewal-hooks/deploy/z-commit-etc.sh
- name: "certbot lock is ignored by Git"
lineinfile:
dest: /etc/.gitignore
line: letsencrypt/.certbot.lock
create: yes
owner: root
mode: "0600"

View File

@ -0,0 +1,12 @@
<IfModule jk_module>
SetEnvIf Request_URI "/.well-known/acme-challenge/*" no-jk
</IfModule>
<IfModule proxy_module>
ProxyPass /.well-known/acme-challenge/ !
</IfModule>
Alias /.well-known/acme-challenge /var/lib/letsencrypt/.well-known/acme-challenge
<Directory "/var/lib/letsencrypt/.well-known/acme-challenge">
Options -Indexes
Allow from all
Require all granted
</Directory>

View File

@ -0,0 +1,5 @@
location ~ /.well-known/acme-challenge {
alias {{ certbot_work_dir }}/;
try_files $uri =404;
allow all;
}

View File

@ -1,3 +1,3 @@
---
dependencies:
- { role: amavis }
- { role: evolix/amavis }

View File

@ -74,22 +74,20 @@
- name: install ClamAV
apt:
name: "{{ item }}"
name:
- clamav-daemon
- clamav
- clamdscan
- clamav-freshclam
- arc
- arj
- pax
- bzip2
- cabextract
- rpm
- lzop
- razor
state: present
with_items:
- clamav-daemon
- clamav
- clamdscan
- clamav-freshclam
- arc
- arj
- zoo
- pax
- bzip2
- cabextract
- rpm
- lzop
- razor
tags:
- clamav

View File

@ -1,6 +1,6 @@
---
- include_role:
name: apt
name: evolix/apt
tasks_from: backports.yml
tags:
- packages
@ -18,6 +18,6 @@
- name: update apt
apt:
update_cache: yes
when: docker_apt_preferences | changed
when: docker_apt_preferences is changed
tags:
- packages

View File

@ -2,22 +2,20 @@
---
- name: Remove older docker packages
apt:
name: '{{ item }}'
name:
- docker
- docker-engine
- docker.io
state: absent
with_items:
- docker
- docker-engine
- docker.io
- name: Install source requirements
apt:
name: '{{ item }}'
name:
- apt-transport-https
- ca-certificates
- gnupg2
state: present
update_cache: yes
with_items:
- apt-transport-https
- ca-certificates
- gnupg2
- name: Add Docker repository
apt_repository:
@ -36,11 +34,10 @@
- name: Install docker and python-docker
apt:
name: "{{ item }}"
name:
- docker-ce
- python-docker
update_cache: yes
with_items:
- docker-ce
- python-docker
- name: Copy Docker daemon configuration file
template:

View File

@ -1,13 +1,12 @@
- name: ensure packages are installed
apt:
name: '{{ item }}'
name:
- dovecot-ldap
- dovecot-imapd
- dovecot-pop3d
- dovecot-sieve
- dovecot-managesieved
state: present
with_items:
- dovecot-ldap
- dovecot-imapd
- dovecot-pop3d
- dovecot-sieve
- dovecot-managesieved
tags:
- dovecot
@ -26,13 +25,13 @@
regexp: "^#*{{ item.key }}"
state: present
with_items:
- { key: 'hosts', value: '127.0.0.1' }
- { key: 'auth_bind', value: 'yes' }
- { key: 'ldap_version', value: 3 }
- { key: 'base', value: "{{ ldap_suffix }}" }
- { key: 'user_attrs', value: 'homeDirectory=home' }
- { key: 'user_filter', value: '(&(isActive=TRUE)(uid=%u))' }
- { key: 'pass_attrs', value: 'uid=user,userPassword=password' }
- { key: 'hosts', value: '127.0.0.1' }
- { key: 'auth_bind', value: 'yes' }
- { key: 'ldap_version', value: 3 }
- { key: 'base', value: "{{ ldap_suffix }}" }
- { key: 'user_attrs', value: 'homeDirectory=home' }
- { key: 'user_filter', value: '(&(isActive=TRUE)(uid=%u))' }
- { key: 'pass_attrs', value: 'uid=user,userPassword=password' }
when: ldap_suffix is defined
notify: reload dovecot
tags:

View File

@ -6,12 +6,13 @@
check_mode: no
register: munin_node_plugins_config
- block:
- name: Install munin plugin
copy:
src: munin_plugin
dest: /etc/munin/plugins/dovecot
mode: "0755"
- name: Munin plugins are present and configured
block:
- name: Install munin plugin
copy:
src: munin_plugin
dest: /etc/munin/plugins/dovecot
mode: "0755"
# TODO : add in /etc/munin/plugin-conf.d/munin-node
# [dovecot]

View File

@ -9,7 +9,7 @@
- drbd
- include_role:
name: remount-usr
name: evolix/remount-usr
tags:
- drbd

View File

@ -1,9 +1,8 @@
- name: Install dependency
apt:
name: "{{ item }}"
with_items:
- drbd-utils
- lvm2
name:
- drbd-utils
- lvm2
tags:
- drbd

View File

@ -27,7 +27,7 @@ Tasks are extracted in several files, included in `tasks/main.yml` :
* `elasticsearch_jvm_xmx`: maximum heap size reserved for the JVM (default: `2g`).
* `elasticsearch_restart_on_upgrade`: restart the service after package upgrade (default: `true`)
By default, Elasticsearch will listen to the public interfaces (`_site_` cf. https://www.elastic.co/guide/en/elasticsearch/reference/5.0/important-settings.html#network.host), so you will have to secure it, with firewall rules for example.
By default, Elasticsearch will listen to the local interface (`_local_` cf. https://www.elastic.co/guide/en/elasticsearch/reference/5.0/important-settings.html#network.host).
## Curator

View File

@ -5,7 +5,7 @@ elasticsearch_cluster_name: Null
elasticsearch_cluster_members: Null
elasticsearch_minimum_master_nodes: Null
elasticsearch_node_name: "${HOSTNAME}"
elasticsearch_network_host: "[_site_, _local_]"
elasticsearch_network_host: "[_local_]"
elasticsearch_network_publish_host: Null
elasticsearch_http_publish_host: Null
elasticsearch_custom_datadir: Null

View File

@ -25,4 +25,4 @@ galaxy_info:
# alphanumeric characters. Maximum 20 tags per role.
dependencies:
- { role: java, alternative: 'openjdk', java_version: 8 }
- { role: evolix/java, alternative: 'openjdk' }

View File

@ -1,8 +1,8 @@
---
- include_role:
name: remount-usr
when: elasticsearch_additional_scripts_dir | search ("/usr")
name: evolix/remount-usr
when: elasticsearch_additional_scripts_dir is search ("/usr")
- name: "{{ elasticsearch_additional_scripts_dir }} exists"
file:

View File

@ -1,44 +1,46 @@
---
- block:
- name: "Is custom datadir present ?"
stat:
path: "{{ elasticsearch_custom_datadir }}"
register: elasticsearch_custom_datadir_test
check_mode: no
- name: Set real datadir value when customized
block:
- name: "Is custom datadir present ?"
stat:
path: "{{ elasticsearch_custom_datadir }}"
register: elasticsearch_custom_datadir_test
check_mode: no
- name: "read the real datadir"
command: readlink -f /var/lib/elasticsearch
changed_when: false
register: elasticsearch_current_real_datadir_test
check_mode: no
- name: "read the real datadir"
command: readlink -f /var/lib/elasticsearch
changed_when: false
register: elasticsearch_current_real_datadir_test
check_mode: no
tags:
- elasticsearch
when:
- elasticsearch_custom_datadir != ''
- elasticsearch_custom_datadir != None
- block:
- name: elasticsearch is stopped
service:
name: elasticsearch
state: stopped
- name: Datadir is moved to custom path
block:
- name: elasticsearch is stopped
service:
name: elasticsearch
state: stopped
- name: Move elasticsearch datadir to custom datadir
command: mv {{ elasticsearch_current_real_datadir_test.stdout }} {{ elasticsearch_custom_datadir }}
args:
creates: "{{ elasticsearch_custom_datadir }}"
- name: Move elasticsearch datadir to custom datadir
command: mv {{ elasticsearch_current_real_datadir_test.stdout }} {{ elasticsearch_custom_datadir }}
args:
creates: "{{ elasticsearch_custom_datadir }}"
- name: Symlink {{ elasticsearch_custom_datadir }} to /var/lib/elasticsearch
file:
src: "{{ elasticsearch_custom_datadir }}"
dest: '/var/lib/elasticsearch'
state: link
- name: Symlink {{ elasticsearch_custom_datadir }} to /var/lib/elasticsearch
file:
src: "{{ elasticsearch_custom_datadir }}"
dest: '/var/lib/elasticsearch'
state: link
- name: elasticsearch is started
service:
name: elasticsearch
state: started
- name: elasticsearch is started
service:
name: elasticsearch
state: started
tags:
- elasticsearch
when:

View File

@ -1,5 +1,11 @@
---
- name: Check if cron is installed
shell: "dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'"
failed_when: False
changed_when: False
register: is_cron_installed
- name: "log rotation script"
template:
src: rotate_elasticsearch_logs.j2
@ -7,3 +13,4 @@
owner: root
group: root
mode: "0750"
when: is_cron_installed.rc == 0

View File

@ -8,28 +8,29 @@
system: yes
shell: /bin/false
- block:
- name: Head repository is checked-out
git:
repo: "https://github.com/mobz/elasticsearch-head.git"
dest: "{{ elasticsearch_plugin_head_clone_dir }}"
clone: yes
tags:
- packages
- name: Head plugin is installed
block:
- name: Head repository is checked-out
git:
repo: "https://github.com/mobz/elasticsearch-head.git"
dest: "{{ elasticsearch_plugin_head_clone_dir }}"
clone: yes
tags:
- packages
- name: Create tmpdir
file:
dest: "{{ elasticsearch_plugin_head_tmp_dir }}"
state: directory
- name: Create tmpdir
file:
dest: "{{ elasticsearch_plugin_head_tmp_dir }}"
state: directory
- name: NPM packages for head are installed
npm:
path: "{{ elasticsearch_plugin_head_clone_dir }}"
tags:
- packages
- npm
environment:
TMPDIR: "{{ elasticsearch_plugin_head_tmp_dir }}"
- name: NPM packages for head are installed
npm:
path: "{{ elasticsearch_plugin_head_clone_dir }}"
tags:
- packages
- npm
environment:
TMPDIR: "{{ elasticsearch_plugin_head_tmp_dir }}"
become_user: "{{ elasticsearch_plugin_head_owner }}"
become: yes

View File

@ -7,50 +7,51 @@
changed_when: False
check_mode: no
- block:
- name: "Create {{ elasticsearch_custom_tmpdir or elasticsearch_default_tmpdir | mandatory }}"
file:
path: "{{ elasticsearch_custom_tmpdir or elasticsearch_default_tmpdir | mandatory }}"
owner: elasticsearch
group: elasticsearch
mode: "0755"
state: directory
tags:
- elasticsearch
- name: Tmpdir is moved to custom path
block:
- name: "Create {{ elasticsearch_custom_tmpdir or elasticsearch_default_tmpdir | mandatory }}"
file:
path: "{{ elasticsearch_custom_tmpdir or elasticsearch_default_tmpdir | mandatory }}"
owner: elasticsearch
group: elasticsearch
mode: "0755"
state: directory
tags:
- elasticsearch
- name: change JVM tmpdir (< 6.x)
lineinfile:
dest: /etc/elasticsearch/jvm.options
line: "-Djava.io.tmpdir={{ elasticsearch_custom_tmpdir or elasticsearch_default_tmpdir | mandatory }}"
regexp: "^-Djava.io.tmpdir="
insertafter: "## JVM configuration"
notify:
- restart elasticsearch
tags:
- elasticsearch
when: elastic_stack_version | version_compare('6', '<')
- name: change JVM tmpdir (< 6.x)
lineinfile:
dest: /etc/elasticsearch/jvm.options
line: "-Djava.io.tmpdir={{ elasticsearch_custom_tmpdir or elasticsearch_default_tmpdir | mandatory }}"
regexp: "^-Djava.io.tmpdir="
insertafter: "## JVM configuration"
notify:
- restart elasticsearch
tags:
- elasticsearch
when: elastic_stack_version is version('6', '<')
- name: check if ES_TMPDIR is available (>= 6.x)
lineinfile:
dest: /etc/default/elasticsearch
line: "ES_TMPDIR={{ elasticsearch_custom_tmpdir or elasticsearch_default_tmpdir | mandatory }}"
regexp: "^ES_TMPDIR="
insertafter: "JAVA_HOME"
notify:
- restart elasticsearch
tags:
- elasticsearch
when: elastic_stack_version | version_compare('6', '>=')
- name: check if ES_TMPDIR is available (>= 6.x)
lineinfile:
dest: /etc/default/elasticsearch
line: "ES_TMPDIR={{ elasticsearch_custom_tmpdir or elasticsearch_default_tmpdir | mandatory }}"
regexp: "^ES_TMPDIR="
insertafter: "JAVA_HOME"
notify:
- restart elasticsearch
tags:
- elasticsearch
when: elastic_stack_version is version('6', '>=')
- name: change JVM tmpdir (>= 6.x)
lineinfile:
dest: /etc/elasticsearch/jvm.options
line: "-Djava.io.tmpdir=${ES_TMPDIR}"
regexp: "^-Djava.io.tmpdir="
insertafter: "## JVM configuration"
notify:
- restart elasticsearch
tags:
- elasticsearch
when: elastic_stack_version | version_compare('6', '>=')
- name: change JVM tmpdir (>= 6.x)
lineinfile:
dest: /etc/elasticsearch/jvm.options
line: "-Djava.io.tmpdir=${ES_TMPDIR}"
regexp: "^-Djava.io.tmpdir="
insertafter: "## JVM configuration"
notify:
- restart elasticsearch
tags:
- elasticsearch
when: elastic_stack_version is version('6', '>=')
when: (elasticsearch_custom_tmpdir != '' and elasticsearch_custom_tmpdir != None) or fstab_tmp_noexec.rc == 0

View File

@ -14,7 +14,7 @@ There is also an independant task that can be executed to commit changes made in
pre_tasks:
- include_role:
name: etc-git
name: evolix/etc-git
tasks_from: commit.yml
vars:
commit_message: "Ansible pre-run my splendid playbook"
@ -24,7 +24,7 @@ There is also an independant task that can be executed to commit changes made in
post_tasks:
- include_role:
name: etc-git
name: evolix/etc-git
tasks_from: commit.yml
vars:
commit_message: "Ansible post-run my splendid playbook"

View File

@ -31,7 +31,7 @@
- name: "set commit author"
set_fact:
commit_author: '{% if ansible_env.SUDO_USER is not defined %}root{% else %}{{ ansible_env.SUDO_USER }}{% endif %}'
commit_email: '{% if git_config_user_email.config_value is not defined or git_config_user_email.config_value == "" %}root@localhost{% else %}{{ git_config_user_email.config_value }}{% endif %}'
commit_email: '{% if git_config_user_email.config_value is not defined or not git_config_user_email.config_value %}root@localhost{% else %}{{ git_config_user_email.config_value }}{% endif %}' # noqa 204
tags:
- etc-git
- commit-etc
@ -41,7 +41,9 @@
args:
chdir: /etc
register: etc_commit_end_run
when: not ansible_check_mode and git_status.stdout != ""
when:
- not ansible_check_mode
- git_status.stdout
ignore_errors: yes
tags:
- etc-git

View File

@ -7,80 +7,37 @@
tags:
- etc-git
- name: /etc is versioned with git
command: "git init ."
args:
chdir: /etc
creates: /etc/.git/
warn: no
register: git_init
tags:
- etc-git
- include: repository.yml
vars:
repository_path: "/etc"
gitignore_items:
- "aliases.db"
- "*.swp"
- "postfix/sa-blacklist.access"
- "postfix/*.db"
- "postfix/spamd.cidr"
- "evobackup/.keep-*"
- "letsencrypt/.certbot.lock"
- name: Git user.email is configured
git_config:
name: user.email
repo: /etc
scope: local
value: "root@{{ ansible_fqdn | default('localhost') }}"
tags:
- etc-git
- name: verify /usr/share/scripts presence
stat:
path: /usr/share/scripts
register: _usr_share_scripts
- name: /etc/.git is restricted to root
file:
path: /etc/.git
owner: root
mode: "0700"
state: directory
tags:
- etc-git
- include: repository.yml
vars:
repository_path: "/usr/share/scripts"
gitignore_items: []
when:
- _usr_share_scripts.stat.isdir
- ansible_distribution_major_version is version('10', '>=')
- name: /etc/.gitignore is present
copy:
src: gitignore
dest: /etc/.gitignore
owner: root
mode: "0600"
force: no
tags:
- etc-git
- name: Some entries MUST be in the /etc/.gitignore file
lineinfile:
dest: /etc/.gitignore
line: "{{ item }}"
with_items:
- "aliases.db"
- "*.swp"
- "postfix/sa-blacklist.access"
- "postfix/*.db"
- "postfix/spamd.cidr"
- "evobackup/.keep-*"
- "letsencrypt/.certbot.lock"
tags:
- etc-git
- name: does /etc/ have any commit?
command: "git log"
args:
chdir: /etc
warn: no
changed_when: False
- name: Check if cron is installed
shell: "dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'"
failed_when: False
register: git_log
changed_when: False
check_mode: no
tags:
- etc-git
- name: initial commit is present?
shell: "git add -A . && git commit -m \"Initial commit via Ansible\""
args:
chdir: /etc
warn: no
register: git_commit
when: git_log.rc != 0 or (git_init is defined and git_init.changed)
tags:
- etc-git
register: is_cron_installed
- name: Optimize script is installed in monthly crontab
copy:
@ -88,6 +45,7 @@
dest: /etc/cron.monthly/optimize-etc-git
mode: "0750"
force: no
when: is_cron_installed.rc == 0
tags:
- etc-git
@ -96,7 +54,7 @@
src: etc-git-status.j2
dest: /etc/cron.d/etc-git-status
mode: "0644"
when: etc_git_monitor_status
when: is_cron_installed.rc == 0 and etc_git_monitor_status
tags:
- etc-git
@ -104,6 +62,6 @@
file:
dest: /etc/cron.d/etc-git-status
state: absent
when: not etc_git_monitor_status
when: is_cron_installed.rc == 0 and not etc_git_monitor_status
tags:
- etc-git

View File

@ -0,0 +1,73 @@
---
- include_role:
name: evolix/remount-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
- name: Git user.email is configured
git_config:
name: user.email
repo: "{{ repository_path }}"
scope: local
value: "root@{{ ansible_fqdn | default('localhost') }}"
tags:
- etc-git
- name: "{{ repository_path }}/.git is restricted to root"
file:
path: "{{ repository_path }}/.git"
owner: root
mode: "0700"
state: directory
tags:
- etc-git
- name: "{{ repository_path }}/.gitignore is present"
copy:
src: gitignore
dest: "{{ repository_path }}/.gitignore"
owner: root
mode: "0600"
force: no
tags:
- etc-git
- name: "Some entries MUST be in the {{ repository_path }}/.gitignore file"
lineinfile:
dest: "{{ repository_path }}/.gitignore"
line: "{{ item }}"
with_items: "{{ gitignore_items | default([]) }}"
tags:
- etc-git
- name: "does {{ repository_path }}/ have any commit?"
command: "git log"
args:
chdir: "{{ repository_path }}"
warn: no
changed_when: False
failed_when: False
register: git_log
check_mode: no
tags:
- etc-git
- name: initial commit is present?
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.changed)
tags:
- etc-git

View File

@ -1,10 +1,9 @@
# Evoacme 2.0
EvoAcme is an [Ansible](https://www.ansible.com/) role and a [Certbot](https://certbot.eff.org) wrapper for generate [Let's Encrypt](https://letsencrypt.org/) certificates.
The upstream repository of EvoAcme is at <https://gitea.evolix.org/evolix/evoacme>
It is a project hosted at [Evolix's forge](https://gitea.evolix.org/evolix/ansible-roles/)
Evoacme is open source software licensed under the AGPLv3 License.
Shell scripts are copied from the upstream repository after each release.
No changes must be applied directly here ; patch upstream, release then copy here.
## Install
@ -21,7 +20,7 @@ Evoacme is open source software licensed under the AGPLv3 License.
### 2 - Install evoacme prerequisite with ansible
~~~
# ansible-playbook playbook.yml -K --diff --check --limit hostname
# ansible-playbook playbook.yml -K --limit hostname
~~~
### 3 - Include letsencrypt.conf in your webserver

View File

@ -10,17 +10,33 @@
set -e
set -u
usage() {
show_version() {
cat <<END
evoacme version ${VERSION}
Copyright 2009-2019 Evolix <info@evolix.fr>,
Victor Laborie <vlaborie@evolix.fr>,
Jérémy Lecour <jlecour@evolix.fr>,
Benoit Série <bserie@evolix.fr>
and others.
evoacme comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to redistribute it under certain conditions.
See the GNU Affero General Public License v3.0 for details.
END
}
show_help() {
cat <<EOT
Usage: ${PROGNAME} NAME
NAME must be correspond to :
- a CSR in ${CSR_DIR}/NAME.csr
- a KEY in ${SSL_KEY_DIR}/NAME.key
NAME must be correspond to :
- a CSR in ${CSR_DIR}/NAME.csr
- a KEY in ${SSL_KEY_DIR}/NAME.key
If env variable TEST=1, certbot is run in staging mode
If env variable DRY_RUN=1, certbot is run in dry-run mode
If env variable QUIET=1, no message is output
If env variable VERBOSE=1, debug messages are output
If env variable TEST=1, certbot is run in staging mode
If env variable DRY_RUN=1, certbot is run in dry-run mode
If env variable QUIET=1, no message is output
If env variable VERBOSE=1, debug messages are output
EOT
}
@ -36,7 +52,7 @@ debug() {
}
error() {
>&2 echo "${PROGNAME}: $1"
[ "$1" = "invalid argument(s)" ] && >&2 usage
[ "$1" = "invalid argument(s)" ] && >&2 show_help
exit 1
}
@ -75,7 +91,7 @@ sed_cert_path_for_nginx() {
sed -i "s~${search}~${replace}~" "${vhost_full_path}"
debug "Config in ${vhost_full_path} has been updated"
$(command -v nginx) -t 2>/dev/null
[ "${?}" -eq 0 ] || $(command -v nginx) -t
[ "${?}" -eq 0 ] || $(command -v nginx) -t -q
fi
}
x509_verify() {
@ -98,7 +114,8 @@ main() {
# check arguments
[ "$#" -eq 1 ] || error "invalid argument(s)"
[ "$1" = "-h" ] || [ "$1" = "--help" ] && usage && exit 0
[ "$1" = "-h" ] || [ "$1" = "--help" ] && show_help && exit 0
[ "$1" = "-V" ] || [ "$1" = "--version" ] && show_version && exit 0
mkdir -p "${ACME_DIR}"
chown acme: "${ACME_DIR}"
@ -287,6 +304,8 @@ readonly QUIET=${QUIET:-"0"}
readonly TEST=${TEST:-"0"}
readonly DRY_RUN=${DRY_RUN:-"0"}
readonly VERSION="19.11"
# Read configuration file, if it exists
[ -r /etc/default/evoacme ] && . /etc/default/evoacme

View File

@ -1,6 +1,7 @@
#!/bin/sh
readonly PROGNAME=$(basename "$0")
# shellcheck disable=SC2124,SC2034
readonly ARGS=$@
readonly VERBOSE=${VERBOSE:-"0"}
@ -17,6 +18,7 @@ debug() {
}
if [ -n "$(pidof apache2)" ]; then
# shellcheck disable=SC2091
if $($(command -v apache2ctl) -t 2> /dev/null); then
debug "Apache detected... reloading"
service apache2 reload

View File

@ -1,6 +1,7 @@
#!/bin/sh
readonly PROGNAME=$(basename "$0")
# shellcheck disable=SC2124,SC2034
readonly ARGS=$@
readonly VERBOSE=${VERBOSE:-"0"}
@ -17,7 +18,9 @@ debug() {
}
if [ -n "$(pidof dovecot)" ]; then
# shellcheck disable=SC2091
if $($(command -v doveconf) > /dev/null); then
# shellcheck disable=SC2091
if $($(command -v doveconf)|grep -E "^ssl_cert[^_]"|grep -q "letsencrypt"); then
debug "Dovecot detected... reloading"
service dovecot reload

View File

@ -1,6 +1,7 @@
#!/bin/sh
readonly PROGNAME=$(basename "$0")
# shellcheck disable=SC2124,SC2034
readonly ARGS=$@
readonly VERBOSE=${VERBOSE:-"0"}
@ -17,6 +18,7 @@ debug() {
}
if [ -n "$(pidof nginx)" ]; then
# shellcheck disable=SC2091
if $($(command -v nginx) -t 2> /dev/null); then
debug "Nginx detected... reloading"
service nginx reload

View File

@ -1,6 +1,7 @@
#!/bin/sh
readonly PROGNAME=$(basename "$0")
# shellcheck disable=SC2124,SC2034
readonly ARGS=$@
readonly VERBOSE=${VERBOSE:-"0"}
@ -17,7 +18,9 @@ debug() {
}
if [ -n "$(pidof master)" ]; then
# shellcheck disable=SC2091
if $($(command -v postconf) > /dev/null); then
# shellcheck disable=SC2091
if $($(command -v postconf)|grep -E "^smtpd_tls_cert_file"|grep -q "letsencrypt"); then
debug "Postfix detected... reloading"
service postfix reload

View File

@ -9,27 +9,52 @@
set -u
usage() {
cat <<EOT
Usage: ${PROGNAME} VHOST DOMAIN...
VHOST must correspond to an Apache or Nginx enabled VHost
If VHOST ends with ".conf" it is stripped,
then files are seached at those paths:
- /etc/apache2/sites-enables/VHOST.conf
- /etc/nginx/sites-enabled/VHOST.conf
- /etc/nginx/sites-enabled/VHOST
DOMAIN... is a list of domains for the CSR (passed as arguments or input)
show_version() {
cat <<END
make-csr version ${VERSION}
If env variable VERBOSE=1, debug messages are sent to stderr
Copyright 2009-2019 Evolix <info@evolix.fr>,
Victor Laborie <vlaborie@evolix.fr>,
Jérémy Lecour <jlecour@evolix.fr>,
Benoit Série <bserie@evolix.fr>
and others.
make-csr comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to redistribute it under certain conditions.
See the GNU Affero General Public License v3.0 for details.
END
}
show_help() {
cat <<EOT
Usage: ${PROGNAME} VHOST DOMAIN [DOMAIN]
VHOST must correspond to an Apache or Nginx enabled VHost
If VHOST ends with ".conf" it is stripped,
then files are seached at those paths:
- /etc/apache2/sites-enables/VHOST.conf
- /etc/nginx/sites-enabled/VHOST.conf
- /etc/nginx/sites-enabled/VHOST
DOMAIN is a list of domains for the CSR (passed as arguments or input)
If env variable QUIET=1, no message is output
If env variable VERBOSE=1, debug messages are output
EOT
}
log() {
if [ "${QUIET}" != "1" ]; then
echo "${PROGNAME}: $1"
fi
}
debug() {
if [ "${VERBOSE}" = 1 ]; then
if [ "${VERBOSE}" = "1" ] && [ "${QUIET}" != "1" ]; then
>&2 echo "${PROGNAME}: $1"
fi
}
error() {
>&2 echo "${PROGNAME}: $1"
[ "$1" = "invalid argument(s)" ] && >&2 show_help
exit 1
}
@ -173,13 +198,15 @@ EOF
}
main() {
# We must have at least 1 argument
[ "$#" -ge 1 ] || error "invalid argument(s)"
[ "$1" = "-h" ] || [ "$1" = "--help" ] && show_help && exit 0
[ "$1" = "-V" ] || [ "$1" = "--version" ] && show_version && exit 0
if [ -t 0 ]; then
# We have STDIN, so we should have at least 2 arguments
if [ "$#" -lt 2 ]; then
>&2 echo "invalid arguments"
>&2 usage
exit 1
fi
# We have STDIN, so we should have 2 arguments
[ "$#" -eq 2 ] || error "invalid argument(s)"
# read VHOST from first argument
VHOST="$1"
# remove the first argument
@ -187,12 +214,9 @@ main() {
# read domains from remaining arguments
DOMAINS=$@
else
# We don't have STDIN, so we should have only 1 argument
if [ "$#" != 1 ]; then
>&2 echo "invalid arguments"
>&2 usage
exit 1
fi
# We don't have STDIN, so we should have 1 argument
[ "$#" -eq 1 ] || error "invalid argument(s)"
# read VHOST from first argument
VHOST="$1"
# read domains from input
@ -239,6 +263,9 @@ readonly PROGDIR=$(realpath -m $(dirname "$0"))
readonly ARGS=$@
readonly VERBOSE=${VERBOSE:-"0"}
readonly QUIET=${QUIET:-"0"}
readonly VERSION="19.11"
# Read configuration file, if it exists
[ -r /etc/default/evoacme ] && . /etc/default/evoacme

View File

@ -9,27 +9,50 @@
set -u
usage() {
show_version() {
cat <<END
vhost-domains version ${VERSION}
Copyright 2009-2019 Evolix <info@evolix.fr>,
Victor Laborie <vlaborie@evolix.fr>,
Jérémy Lecour <jlecour@evolix.fr>,
Benoit Série <bserie@evolix.fr>
and others.
vhost-domains comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to redistribute it under certain conditions.
See the GNU Affero General Public License v3.0 for details.
END
}
show_help() {
cat <<EOT
Usage: ${PROGNAME} VHOST
VHOST must correspond to an Apache or Nginx enabled VHost
If VHOST ends with ".conf" it is stripped,
then files are seached at those paths:
- /etc/apache2/sites-enables/VHOST.conf
- /etc/nginx/sites-enabled/VHOST.conf
- /etc/nginx/sites-enabled/VHOST
VHOST must correspond to an Apache or Nginx enabled VHost
If VHOST ends with ".conf" it is stripped,
then files are seached at those paths:
- /etc/apache2/sites-enables/VHOST.conf
- /etc/nginx/sites-enabled/VHOST.conf
- /etc/nginx/sites-enabled/VHOST
If env variable VERBOSE=1, debug messages are sent to stderr
If env variable QUIET=1, no message is output
If env variable VERBOSE=1, debug messages are output
EOT
}
log() {
if [ "${QUIET}" != "1" ]; then
echo "${PROGNAME}: $1"
fi
}
debug() {
if [ "${VERBOSE}" = 1 ]; then
if [ "${VERBOSE}" = "1" ] && [ "${QUIET}" != "1" ]; then
>&2 echo "${PROGNAME}: $1"
fi
}
error() {
>&2 echo "${PROGNAME}: $1"
[ "$1" = "invalid argument(s)" ] && >&2 show_help
exit 1
}
@ -118,14 +141,11 @@ first_vhost_file_found() {
}
main() {
if [ "$#" != 1 ]; then
>&2 usage
exit 1
fi
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
usage
exit 0
fi
# check arguments
[ "$#" -eq 1 ] || error "invalid argument(s)"
[ "$1" = "-h" ] || [ "$1" = "--help" ] && show_help && exit 0
[ "$1" = "-V" ] || [ "$1" = "--version" ] && show_version && exit 0
local vhost_name=$(basename "$1" .conf)
local vhost_file=$(first_vhost_file_found "${vhost_name}")
@ -148,6 +168,10 @@ readonly PROGDIR=$(realpath -m $(dirname "$0"))
readonly ARGS=$@
readonly VERBOSE=${VERBOSE:-"0"}
readonly QUIET=${QUIET:-"0"}
readonly VERSION="19.11"
readonly SRV_IP=${SRV_IP:-""}
main $ARGS

View File

@ -1,18 +1,19 @@
---
- block:
- name: install jessie-backports
include_role:
name: apt
tasks_from: backports.yml
- name: Use backports for jessie
block:
- name: install jessie-backports
include_role:
name: evolix/apt
tasks_from: backports.yml
- name: Add exceptions for certbot dependencies
copy:
src: backports-certbot
dest: /etc/apt/preferences.d/z-backports-certbot
notify: apt update
- name: Add exceptions for certbot dependencies
copy:
src: backports-certbot
dest: /etc/apt/preferences.d/z-backports-certbot
notify: apt update
- meta: flush_handlers
- meta: flush_handlers
when: ansible_distribution_release == "jessie"
- name: Install certbot with apt
@ -21,7 +22,7 @@
state: latest
- include_role:
name: remount-usr
name: evolix/remount-usr
- name: Remove certbot symlink for apt install
file:

View File

@ -3,7 +3,7 @@
- fail:
msg: only compatible with Debian >= 8
when:
- ansible_distribution != "Debian" or ansible_distribution_major_version | version_compare('8', '<')
- ansible_distribution != "Debian" or ansible_distribution_major_version is version('8', '<')
- include: certbot.yml

View File

@ -1,5 +1,5 @@
location ~ /.well-known/acme-challenge {
{% if ansible_distribution_major_version | version_compare('9', '>=') %}
{% if ansible_distribution_major_version is version('9', '>=') %}
alias {{ evoacme_acme_dir }}/;
{% else %}
alias {{ evoacme_acme_dir }}/.well-known/acme-challenge;

View File

@ -0,0 +1,23 @@
# evobackup-client
Allows the configuration of backups to one or more remote filesystems.
The backup hosts and the ports in use need to be defined in
evobackup-client__hosts before running it.
The default zzz_evobackup.sh configures a system only backup, but the
template can be overriden to configure a full backup instead. If
you change the variables in defaults/main.yml you can easily run
this again and configure backups to a second set of hosts.
Do not forget to set the evobackup-client__mail variable to an
email adress you control.
You can add this example to an installation playbook to create the
ssh key without running the rest of the role.
~~~
post_tasks:
- include_role:
name: evobackup-client tasks_from: ssh_key.yml
~~~

View File

@ -0,0 +1,15 @@
---
evobackup_client__root_key_path: "/root/.ssh/id_ed25519"
evobackup_client__root_key_type: "ed25519"
evobackup_client__cron_path: "/etc/cron.daily/zzz_evobackup"
evobackup_client__cron_template_name: "zzz_evobackup"
evobackup_client__mail: null
evobackup_client__servers_fallback: -1
evobackup_client__pid_path: "/var/run/evobackup.pid"
evobackup_client__log_path: "/var/log/evobackup.log"
evobackup_client__backup_path: "/home/backup"
evobackup_client__hosts: null
# - name: "backups.example.org"
# ip: "xxx.xxx.xxx.xxx"
# fingerprint: "ecdsa-sha2-nistp256 ..."
# port: xxxx

View File

@ -0,0 +1,16 @@
---
- name: restart minifirewall
command: /etc/init.d/minifirewall restart
register: minifirewall_init_restart
failed_when: "'starting IPTables rules is now finish : OK' not in minifirewall_init_restart.stdout"
changed_when: "'starting IPTables rules is now finish : OK' in minifirewall_init_restart.stdout"
- name: 'created new jail'
command: "bkctld restart {{ evolinux_hostname }}"
delegate_to: "{{ evobackup_client__hosts[0].ip }}"
- name: 'jail updated'
command: "bkctld restart {{ evolinux_hostname }}"
# - "bkctld sync {{ evolinux_hostname }}"
delegate_to: "{{ evobackup_client__hosts[0].ip }}"
when: evobackup_client__hosts|length > 1

View File

@ -0,0 +1,57 @@
---
- name: 'create jail'
command: "bkctld init {{ evolinux_hostname }}"
args:
creates: "/backup/jails/{{ evolinux_hostname }}/"
become: true
delegate_to: "{{ evobackup_client__hosts[0].ip }}"
notify:
- 'created new jail'
tags:
- evobackup_client
- evobackup_client_jail
# temp fix for bkctld 2.x because the ip and key command return 1
# if the jail is not started, see https://gitea.evolix.org/evolix/evobackup/issues/31
- name: 'start jail'
command: "bkctld restart {{ evolinux_hostname }}"
become: true
delegate_to: "{{ evobackup_client__hosts[0].ip }}"
tags:
- evobackup_client
- evobackup_client_jail
- name: 'add ip to jail'
command: "bkctld ip {{ evolinux_hostname }} {{ ansible_host }}"
become: true
delegate_to: "{{ evobackup_client__hosts[0].ip }}"
notify: 'jail updated'
tags:
- evobackup_client
- evobackup_client_jail
- name: 'add key to jail'
command: "bkctld key {{ evolinux_hostname }} /root/{{ evolinux_hostname }}.pub"
become: true
delegate_to: "{{ evobackup_client__hosts[0].ip }}"
notify: 'jail updated'
tags:
- evobackup_client
- evobackup_client_jail
- name: 'get jail port'
command: "bkctld port {{ evolinux_hostname }}"
become: true
register: bkctld_port
delegate_to: "{{ evobackup_client__hosts[0].ip }}"
tags:
- evobackup_client
- evobackup_client_jail
- name: 'register jail port'
set_fact:
evobackup_ssh_port={{ bkctld_port.stdout }}
tags:
- evobackup_client
- evobackup_client_jail

View File

@ -0,0 +1,26 @@
---
- include: "ssh_key.yml"
tags:
- evobackup_client
- evobackup_client_backup_ssh_key
- include: "jail.yml"
tags:
- evobackup_client
- evobackup_client_jail
- include: "upload_scripts.yml"
tags:
- evobackup_client
- evobackup_client_backup_scripts
- include: "open_ssh_ports.yml"
tags:
- evobackup_client
- evobackup_client_backup_firewall
- include: "verify_ssh.yml"
tags:
- evobackup_client
- evobackup_client_backup_hosts

View File

@ -0,0 +1,22 @@
---
- name: Is there a Minifirewall ?
stat:
path: /etc/default/minifirewall
register: evobackup_client__minifirewall
tags:
- evobackup_client
- evobackup_client_backup_firewall
- name: Add backup SSH port in /etc/default/minifirewall
blockinfile:
dest: /etc/default/minifirewall
marker: "# {mark} {{ item.name }}"
block: |
/sbin/iptables -A INPUT -p tcp --sport {{ item.port }} --dport 1024:65535 -s {{ item.ip }} -m state --state ESTABLISHED,RELATED -j ACCEPT
with_items: "{{ evobackup_client__hosts }}"
notify: restart minifirewall
when: evobackup_client__minifirewall.stat.exists
tags:
- evobackup_client
- evobackup_client_backup_firewall

View File

@ -0,0 +1,31 @@
---
- name: Create SSH key
user:
name: root
generate_ssh_key: true
ssh_key_file: "{{ evobackup_client__root_key_path }}"
ssh_key_type: "{{ evobackup_client__root_key_type }}"
register: evobackup_client__root_key
tags:
- evobackup_client
- evobackup_client_backup_ssh_key
- name: Print SSH key
debug:
var: evobackup_client__root_key.ssh_public_key
when: evobackup_client__root_key.ssh_public_key is defined
tags:
- evobackup_client
- evobackup_client_backup_ssh_key
- name: 'copy ssh public key to backup server'
copy:
content: "{{ evobackup_client__root_key.ssh_public_key }}"
dest: "/root/{{ evolinux_hostname }}.pub"
become: true
delegate_to: "{{ evobackup_client__hosts[0].ip }}"
tags:
- evobackup_client
- evobackup_client_backup_ssh_key
- evobackup_client_jail

View File

@ -0,0 +1,16 @@
---
- name: Upload evobackup script
template:
src: "{{ item }}"
dest: "{{ evobackup_client__cron_path }}"
force: true
mode: 0755
with_first_found:
- "templates/evobackup-client/{{ evobackup_client__cron_template_name }}.{{ inventory_hostname }}.sh.j2"
- "templates/evobackup-client/{{ evobackup_client__cron_template_name }}.{{ host_group }}.sh.j2"
- "templates/evobackup-client/{{ evobackup_client__cron_template_name }}.sh.j2"
- "zzz_evobackup.default.sh.j2"
tags:
- evobackup_client
- evobackup_client_backup_scripts

View File

@ -0,0 +1,11 @@
---
- name: Verify evolix backup servers
known_hosts:
path: /root/.ssh/known_hosts
name: "[{{ item.name }}]:{{ item.port }}"
key: "[{{ item.name }}]:{{ item.port }} {{ item.fingerprint }}"
with_list: "{{ evobackup_client__hosts }}"
tags:
- evobackup_client
- evobackup_client_backup_hosts

View File

@ -0,0 +1,305 @@
#!/bin/sh
# Careful, the zzz_evobackup template was last updated on 2020/04/15
#
# Script Evobackup client
# See https://gitea.evolix.org/evolix/evobackup
#
# Author: Gregory Colpart <reg@evolix.fr>
# Contributors:
# Romain Dessort <rdessort@evolix.fr>
# Benoît Série <bserie@evolix.fr>
# Tristan Pilat <tpilat@evolix.fr>
# Victor Laborie <vlaborie@evolix.fr>
# Jérémy Lecour <jlecour@evolix.fr>
#
# Licence: AGPLv3
#
# /!\ DON'T FORGET TO SET "MAIL" and "SERVERS" VARIABLES
# Fail on unassigned variables
set -u
##### Configuration ###################################################
# email adress for notifications
MAIL={{ evobackup_client__mail }}
# list of hosts (hostname or IP) and SSH port for Rsync
SERVERS="{% for host in evobackup_client__hosts %}{{ host.name }}:{{ host.port }}{% if loop.index != loop.length %} {% endif %}{% endfor %}"
# Should we fallback on servers when the first is unreachable ?
SERVERS_FALLBACK={{ evobackup_client__servers_fallback }}
# timeout (in seconds) for SSH connections
SSH_CONNECT_TIMEOUT=${SSH_CONNECT_TIMEOUT:-30}
## We use /home/backup : feel free to use your own dir
LOCAL_BACKUP_DIR="{{ evobackup_client__backup_path }}"
# You can set "linux" or "bsd" manually or let it choose automatically
SYSTEM=$(uname | tr '[:upper:]' '[:lower:]')
# Change these 2 variables if you have more than one backup cron
PIDFILE="{{ evobackup_client__pid_path }}"
LOGFILE="{{ evobackup_client__log_path }}"
## Enable/Disable tasks
LOCAL_TASKS=${LOCAL_TASKS:-1}
SYNC_TASKS=${SYNC_TASKS:-1}
##### SETUP AND FUNCTIONS #############################################
BEGINNING=$(/bin/date +"%d-%m-%Y ; %H:%M")
# shellcheck disable=SC2174
mkdir -p -m 700 ${LOCAL_BACKUP_DIR}
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin
## lang = C for english outputs
export LANGUAGE=C
export LANG=C
## Force umask
umask 077
## Initialize variable to store SSH connection errors
SERVERS_SSH_ERRORS=""
# Call test_server with "HOST:PORT" string
# It will return with 0 if the server is reachable.
# It will return with 1 and a message on stderr if not.
test_server() {
item=$1
# split HOST and PORT from the input string
host=$(echo "${item}" | cut -d':' -f1)
port=$(echo "${item}" | cut -d':' -f2)
# Test if the server is accepting connections
ssh -q -o "ConnectTimeout ${SSH_CONNECT_TIMEOUT}" -i /root/.ssh/evobackup_id "${host}" -p "${port}" -t "exit"
# shellcheck disable=SC2181
if [ $? = 0 ]; then
# SSH connection is OK
return 0
else
# SSH connection failed
new_error=$(printf "Failed to connect to \`%s' within %s seconds" "${item}" "${SSH_CONNECT_TIMEOUT}")
SERVERS_SSH_ERRORS=$(printf "%s\\n%s" "${SERVERS_SSH_ERRORS}" "${new_error}" | sed -e '/^$/d')
return 1
fi
}
# Call pick_server with an optional positive integer to get the nth server in the list.
pick_server() {
increment=${1:-0}
list_length=$(echo "${SERVERS}" | wc -w)
if [ "${increment}" -ge "${list_length}" ]; then
# We've reached the end of the list
new_error="No more server available"
SERVERS_SSH_ERRORS=$(printf "%s\\n%s" "${SERVERS_SSH_ERRORS}" "${new_error}" | sed -e '/^$/d')
# Log errors to stderr
printf "%s\\n" "${SERVERS_SSH_ERRORS}" >&2
# Log errors to logfile
printf "%s\\n" "${SERVERS_SSH_ERRORS}" >> $LOGFILE
return 1
fi
# Extract the day of month, without leading 0 (which would give an octal based number)
today=$(date +%e)
# A salt is useful to randomize the starting point in the list
# but stay identical each time it's called for a server (based on hostname).
salt=$(hostname | cksum | cut -d' ' -f1)
# Pick an integer between 0 and the length of the SERVERS list
# It changes each day
item=$(( (today + salt + increment) % list_length ))
# cut starts counting fields at 1, not 0.
field=$(( item + 1 ))
echo "${SERVERS}" | cut -d' ' -f${field}
}
## Verify other evobackup process and kill if needed
if [ -e "${PIDFILE}" ]; then
pid=$(cat "${PIDFILE}")
# Does process still exist ?
if kill -0 "${pid}" 2> /dev/null; then
# Killing the childs of evobackup.
for ppid in $(pgrep -P "${pid}"); do
kill -9 "${ppid}";
done
# Then kill the main PID.
kill -9 "${pid}"
printf "%s is still running (PID %s). Process has been killed" "$0" "${pid}\\n" >&2
else
rm -f ${PIDFILE}
fi
fi
echo "$$" > ${PIDFILE}
# shellcheck disable=SC2064
trap "rm -f ${PIDFILE}" EXIT
##### LOCAL BACKUP ####################################################
if [ "${LOCAL_TASKS}" = "1" ]; then
## Dump system and kernel versions
uname -a > ${LOCAL_BACKUP_DIR}/uname
## Dump network routes with mtr and traceroute (warning: could be long with aggressive firewalls)
for addr in 8.8.8.8 www.evolix.fr travaux.evolix.net; do
mtr -r ${addr} > ${LOCAL_BACKUP_DIR}/mtr-${addr}
traceroute -n ${addr} > ${LOCAL_BACKUP_DIR}/traceroute-${addr} 2>&1
done
## Dump process with ps
ps auwwx >${LOCAL_BACKUP_DIR}/ps.out
if [ "${SYSTEM}" = "linux" ]; then
## Dump network connections with ss
ss -taupen > ${LOCAL_BACKUP_DIR}/netstat.out
## List Debian packages
dpkg -l > ${LOCAL_BACKUP_DIR}/packages
dpkg --get-selections > ${LOCAL_BACKUP_DIR}/packages.getselections
apt-cache dumpavail > ${LOCAL_BACKUP_DIR}/packages.available
## Dump MBR / table partitions
disks=$(lsblk -l | grep disk | grep -v -E '(drbd|fd[0-9]+)' | awk '{print $1}')
for disk in ${disks}; do
dd if="/dev/${disk}" of="${LOCAL_BACKUP_DIR}/MBR-${disk}" bs=512 count=1 2>&1 | grep -Ev "(records in|records out|512 bytes)"
fdisk -l "/dev/${disk}" > "${LOCAL_BACKUP_DIR}/partitions-${disk}" 2>&1
done
cat ${LOCAL_BACKUP_DIR}/partitions-* > ${LOCAL_BACKUP_DIR}/partitions
## Dump iptables
if [ -x /sbin/iptables ]; then
{ /sbin/iptables -L -n -v; /sbin/iptables -t filter -L -n -v; } > ${LOCAL_BACKUP_DIR}/iptables.txt
fi
## Dump findmnt(8) output
FINDMNT_BIN=$(command -v findmnt)
if [ -x "${FINDMNT_BIN}" ]; then
${FINDMNT_BIN} > ${LOCAL_BACKUP_DIR}/findmnt.txt
fi
else
## Dump network connections with netstat
netstat -finet -atn > ${LOCAL_BACKUP_DIR}/netstat.out
## List OpenBSD packages
pkg_info -m > ${LOCAL_BACKUP_DIR}/packages
## Dump MBR / table partitions
disklabel sd0 > ${LOCAL_BACKUP_DIR}/partitions
## Dump pf infos
pfctl -sa > ${LOCAL_BACKUP_DIR}/pfctl-sa.txt
fi
## Dump rights
#getfacl -R /var > ${LOCAL_BACKUP_DIR}/rights-var.txt
#getfacl -R /etc > ${LOCAL_BACKUP_DIR}/rights-etc.txt
#getfacl -R /usr > ${LOCAL_BACKUP_DIR}/rights-usr.txt
#getfacl -R /home > ${LOCAL_BACKUP_DIR}/rights-home.txt
fi
##### REMOTE BACKUP ###################################################
n=0
server=""
if [ "${SERVERS_FALLBACK}" = "1" ]; then
# We try to find a suitable server
while :; do
server=$(pick_server "${n}")
test $? = 0 || exit 2
if test_server "${server}"; then
break
else
server=""
n=$(( n + 1 ))
fi
done
else
# we force the server
server=$(pick_server "${n}")
fi
SSH_SERVER=$(echo "${server}" | cut -d':' -f1)
SSH_PORT=$(echo "${server}" | cut -d':' -f2)
HOSTNAME=$(hostname)
if [ "${SYSTEM}" = "linux" ]; then
rep="/bin /boot /lib /opt /sbin /usr /srv"
else
rep="/bsd /bin /sbin /usr"
fi
if [ "${SYNC_TASKS}" = "1" ]; then
# /!\ DO NOT USE COMMENTS in the rsync command /!\
# It breaks the command and destroys data, simply remove (or add) lines.
# Remote shell command
RSH_COMMAND="ssh -i {{ evobackup_client__root_key_path }} -p ${SSH_PORT} -o 'ConnectTimeout ${SSH_CONNECT_TIMEOUT}'"
# ignore check because we want it to split the different arguments to $rep
# shellcheck disable=SC2086
rsync -avzh --stats --delete --delete-excluded --force --ignore-errors --partial \
--exclude "lost+found" \
--exclude ".nfs.*" \
--exclude "/var/log" \
--exclude "/var/log/evobackup*" \
--exclude "/var/lib/mysql" \
--exclude "/var/lib/postgres" \
--exclude "/var/lib/postgresql" \
--exclude "/var/lib/sympa" \
--exclude "/var/lib/metche" \
--exclude "/var/run" \
--exclude "/var/lock" \
--exclude "/var/state" \
--exclude "/var/apt" \
--exclude "/var/cache" \
--exclude "/usr/src" \
--exclude "/usr/doc" \
--exclude "/usr/share/doc" \
--exclude "/usr/obj" \
--exclude "dev" \
--exclude "/var/spool/postfix" \
--exclude "/var/lib/amavis/amavisd.sock" \
--exclude "/var/lib/munin/*tmp*" \
--exclude "/var/lib/php5" \
--exclude "/var/spool/squid" \
--exclude "/var/lib/elasticsearch" \
--exclude "/var/lib/amavis/tmp" \
--exclude "/var/lib/clamav/*.tmp" \
--exclude "/home/mysqltmp" \
--exclude "/var/lib/php/sessions" \
${rep} \
/etc \
/root \
/var \
-e "${RSH_COMMAND}" \
"root@${SSH_SERVER}:/var/backup/" \
| tail -30 >> $LOGFILE
fi
##### REPORTING #######################################################
END=$(/bin/date +"%d-%m-%Y ; %H:%M")
printf "EvoBackup - %s - START %s ON %s (LOCAL_TASKS=%s SYNC_TASKS=%s)\\n" \
"${HOSTNAME}" "${BEGINNING}" "${SSH_SERVER}" "${LOCAL_TASKS}" "${SYNC_TASKS}" \
>> $LOGFILE
printf "EvoBackup - %s - STOP %s ON %s (LOCAL_TASKS=%s SYNC_TASKS=%s)\\n" \
"${HOSTNAME}" "${END}" "${SSH_SERVER}" "${LOCAL_TASKS}" "${SYNC_TASKS}" \
>> $LOGFILE
tail -10 $LOGFILE | \
mail -s "[info] EvoBackup - Client ${HOSTNAME}" \
${MAIL}

View File

@ -10,7 +10,7 @@ A separate `exec.yml` file can be imported manually in playbooks or roles to exe
```
- include_role:
name: evocheck
name: evolix/evocheck
tasks_from: exec.yml
```
## Variables

View File

@ -4,6 +4,8 @@
# Script to verify compliance of a Debian/OpenBSD server
# powered by Evolix
readonly VERSION="20.04.3"
# base functions
show_version() {
@ -59,6 +61,7 @@ detect_os() {
7) DEBIAN_RELEASE="wheezy";;
8) DEBIAN_RELEASE="jessie";;
9) DEBIAN_RELEASE="stretch";;
10) DEBIAN_RELEASE="buster";;
esac
fi
elif [ "$(uname -s)" = "OpenBSD" ]; then
@ -85,6 +88,9 @@ is_debian_jessie() {
is_debian_stretch() {
test "${DEBIAN_RELEASE}" = "stretch"
}
is_debian_buster() {
test "${DEBIAN_RELEASE}" = "buster"
}
debian_release() {
printf "%s" "${DEBIAN_RELEASE}"
}
@ -159,7 +165,7 @@ check_dpkgwarning() {
test -e /etc/apt/apt.conf \
&& failed "IS_DPKGWARNING" "/etc/apt/apt.conf is missing"
fi
elif is_debian_stretch; then
elif is_debian_stretch || is_debian_buster; then
test -e /etc/apt/apt.conf.d/z-evolinux.conf \
|| failed "IS_DPKGWARNING" "/etc/apt/apt.conf.d/z-evolinux.conf is missing"
fi
@ -196,7 +202,7 @@ check_modsecurity() {
fi
}
check_customsudoers() {
grep -E -qr "umask=0077" /etc/sudoers* || failed "IS_CUSTOMSUDOERS"
grep -E -qr "umask=0077" /etc/sudoers* || failed "IS_CUSTOMSUDOERS" "missing umask=0077 in sudoers file"
}
check_vartmpfs() {
df /var/tmp | grep -q tmpfs || failed "IS_VARTMPFS" "/var/tmp is not a tmpfs"
@ -208,29 +214,30 @@ check_serveurbase() {
is_installed serveur-base || failed "IS_SERVEURBASE" "serveur-base package is not installed"
}
check_logrotateconf() {
test -e /etc/logrotate.d/zsyslog || failed "IS_LOGROTATECONF"
test -e /etc/logrotate.d/zsyslog || failed "IS_LOGROTATECONF" "missing zsyslog in logrotate.d"
}
check_syslogconf() {
grep -q "^# Syslog for Pack Evolix serveur" /etc/*syslog.conf \
|| failed "IS_SYSLOGCONF"
|| failed "IS_SYSLOGCONF" "syslog evolix config file missing"
}
check_debiansecurity() {
grep -q "^deb.*security" /etc/apt/sources.list \
|| failed "IS_DEBIANSECURITY"
|| failed "IS_DEBIANSECURITY" "missing debian security repository"
}
check_aptitudeonly() {
if is_debian_squeeze || is_debian_wheezy; then
test -e /usr/bin/apt-get && failed "IS_APTITUDEONLY"
test -e /usr/bin/apt-get && failed "IS_APTITUDEONLY" \
"only aptitude may be enabled on Debian <=7, apt-get should be disabled"
fi
}
check_aptitude() {
if is_debian_jessie || is_debian_stretch; then
test -e /usr/bin/aptitude && failed "IS_APTITUDE"
if is_debian_jessie || is_debian_stretch || is_debian_buster; then
test -e /usr/bin/aptitude && failed "IS_APTITUDE" "aptitude may not be installed on Debian >=8"
fi
}
check_aptgetbak() {
if is_debian_jessie || is_debian_stretch; then
test -e /usr/bin/apt-get.bak && failed "IS_APTGETBAK"
if is_debian_jessie || is_debian_stretch || is_debian_buster; then
test -e /usr/bin/apt-get.bak && failed "IS_APTGETBAK" "missing dpkg-divert apt-get.bak"
fi
}
check_apticron() {
@ -240,28 +247,35 @@ check_apticron() {
test "$status" = "fail" || test -e /usr/bin/apt-get.bak || status="fail"
if is_debian_squeeze || is_debian_wheezy; then
test "$status" = "fail" && failed "IS_APTICRON"
test "$status" = "fail" && failed "IS_APTICRON" "apticron must be in cron.d not cron.daily"
fi
}
check_usrro() {
grep /usr /etc/fstab | grep -q ro || failed "IS_USRRO"
grep /usr /etc/fstab | grep -qE "\bro\b" || failed "IS_USRRO" "missing ro directive on fstab for /usr"
}
check_tmpnoexec() {
mount | grep "on /tmp" | grep -q noexec || failed "IS_TMPNOEXEC"
FINDMNT_BIN=$(command -v findmnt)
if [ -x "${FINDMNT_BIN}" ]; then
options=$(${FINDMNT_BIN} --noheadings --first-only --output OPTIONS /tmp)
echo "${options}" | grep -qE "\bnoexec\b" || failed "IS_TMPNOEXEC" "/tmp is not mounted with 'noexec'"
else
mount | grep "on /tmp" | grep -qE "\bnoexec\b" || failed "IS_TMPNOEXEC" "/tmp is not mounted with 'noexec' (WARNING: findmnt(8) is not found)"
fi
}
check_mountfstab() {
# Test if lsblk available, if not skip this test...
LSBLK_BIN=$(command -v lsblk)
if test -x "${LSBLK_BIN}"; then
for mountPoint in $(${LSBLK_BIN} -o MOUNTPOINT -l -n | grep '/'); do
grep -Eq "$mountPoint\W" /etc/fstab || failed "IS_MOUNT_FSTAB"
grep -Eq "$mountPoint\W" /etc/fstab \
|| failed "IS_MOUNT_FSTAB" "partition(s) detected mounted but no presence in fstab"
done
fi
}
check_listchangesconf() {
if is_debian_stretch; then
if is_debian_stretch || is_debian_buster; then
if is_installed apt-listchanges; then
failed "IS_LISTCHANGESCONF" "apt-listchanges must not be installed on Stretch"
failed "IS_LISTCHANGESCONF" "apt-listchanges must not be installed on Debian >=9"
fi
else
if [ -e "/etc/apt/listchanges.conf" ]; then
@ -276,72 +290,86 @@ check_listchangesconf() {
}
check_customcrontab() {
found_lines=$(grep -c -E "^(17 \*|25 6|47 6|52 6)" /etc/crontab)
test "$found_lines" = 4 && failed "IS_CUSTOMCRONTAB"
test "$found_lines" = 4 && failed "IS_CUSTOMCRONTAB" "missing custom field in crontab"
}
check_sshallowusers() {
grep -E -qi "(AllowUsers|AllowGroups)" /etc/ssh/sshd_config || failed "IS_SSHALLOWUSERS"
grep -E -qi "(AllowUsers|AllowGroups)" /etc/ssh/sshd_config \
|| failed "IS_SSHALLOWUSERS" "missing AllowUsers or AllowGroups directive in sshd_config"
}
check_diskperf() {
test -e /root/disk-perf.txt || failed "IS_DISKPERF"
perfFile="/root/disk-perf.txt"
test -e $perfFile || failed "IS_DISKPERF" "missing ${perfFile}"
}
check_tmoutprofile() {
grep -sq "TMOUT=" /etc/profile /etc/profile.d/evolinux.sh || failed "IS_TMOUTPROFILE" "TMOUT is not set"
}
check_alert5boot() {
if [ -n "$(find /etc/rc2.d/ -name 'S*alert5')" ]; then
grep -q "^date" /etc/rc2.d/S*alert5 || failed "IS_ALERT5BOOT" "boot mail is not sent by alert5 init script"
if is_debian_buster; then
grep -qs "^date" /usr/share/scripts/alert5.sh || failed "IS_ALERT5BOOT" "boot mail is not sent by alert5 init script"
test -f /etc/systemd/system/alert5.service || failed "IS_ALERT5BOOT" "alert5 unit file is missing"
systemctl is-enabled alert5 -q || failed "IS_ALERT5BOOT" "alert5 unit is not enabled"
else
failed "IS_ALERT5BOOT" "alert5 init script is missing"
if [ -n "$(find /etc/rc2.d/ -name 'S*alert5')" ]; then
grep -q "^date" /etc/rc2.d/S*alert5 || failed "IS_ALERT5BOOT" "boot mail is not sent by alert5 init script"
else
failed "IS_ALERT5BOOT" "alert5 init script is missing"
fi
fi
}
check_alert5minifw() {
if [ -n "$(find /etc/rc2.d/ -name 'S*alert5')" ]; then
grep -q "^/etc/init.d/minifirewall" /etc/rc2.d/S*alert5 \
|| failed "IS_ALERT5MINIFW" "Minifirewall is not started by alert5 init script"
if is_debian_buster; then
grep -qs "^/etc/init.d/minifirewall" /usr/share/scripts/alert5.sh \
|| failed "IS_ALERT5MINIFW" "Minifirewall is not started by alert5 script or script is missing"
else
failed "IS_ALERT5MINIFW" "alert5 init script is missing"
if [ -n "$(find /etc/rc2.d/ -name 'S*alert5')" ]; then
grep -q "^/etc/init.d/minifirewall" /etc/rc2.d/S*alert5 \
|| failed "IS_ALERT5MINIFW" "Minifirewall is not started by alert5 init script"
else
failed "IS_ALERT5MINIFW" "alert5 init script is missing"
fi
fi
}
check_minifw() {
/sbin/iptables -L -n | grep -q -E "^ACCEPT\s*all\s*--\s*31\.170\.8\.4\s*0\.0\.0\.0/0\s*$" \
|| failed "IS_MINIFW"
|| failed "IS_MINIFW" "minifirewall seems not starded"
}
check_nrpeperms() {
if [ -d /etc/nagios ]; then
actual=$(stat --format "%a" /etc/nagios)
nagiosDir="/etc/nagios"
actual=$(stat --format "%a" $nagiosDir)
expected="750"
test "$expected" = "$actual" || failed "IS_NRPEPERMS"
test "$expected" = "$actual" || failed "IS_NRPEPERMS" "${nagiosDir} must be ${expected}"
fi
}
check_minifwperms() {
if [ -f "$MINIFW_FILE" ]; then
actual=$(stat --format "%a" "$MINIFW_FILE")
expected="600"
test "$expected" = "$actual" || failed "IS_MINIFWPERMS"
test "$expected" = "$actual" || failed "IS_MINIFWPERMS" "${MINIFW_FILE} must be ${expected}"
fi
}
check_nrpedisks() {
NRPEDISKS=$(grep command.check_disk /etc/nagios/nrpe.cfg | grep "^command.check_disk[0-9]" | sed -e "s/^command.check_disk\([0-9]\+\).*/\1/" | sort -n | tail -1)
DFDISKS=$(df -Pl | grep -c -E -v "(^Filesystem|/lib/init/rw|/dev/shm|udev|rpc_pipefs)")
test "$NRPEDISKS" = "$DFDISKS" || failed "IS_NRPEDISKS"
test "$NRPEDISKS" = "$DFDISKS" || failed "IS_NRPEDISKS" "there must be $DFDISKS check_disk in nrpe.cfg"
}
check_nrpepid() {
if ! is_debian_squeeze; then
{ test -e /etc/nagios/nrpe.cfg \
&& grep -q "^pid_file=/var/run/nagios/nrpe.pid" /etc/nagios/nrpe.cfg;
} || failed "IS_NRPEPID"
} || failed "IS_NRPEPID" "missing or wrong pid_file directive in nrpe.cfg"
fi
}
check_grsecprocs() {
if uname -a | grep -q grsec; then
{ grep -q "^command.check_total_procs..sudo" /etc/nagios/nrpe.cfg \
&& grep -A1 "^\[processes\]" /etc/munin/plugin-conf.d/munin-node | grep -q "^user root";
} || failed "IS_GRSECPROCS"
} || failed "IS_GRSECPROCS" "missing munin's plugin processes directive for grsec"
fi
}
check_apachemunin() {
if test -e /etc/apache2/apache2.conf; then
if is_debian_stretch; then
if is_debian_stretch || is_debian_buster; then
{ test -h /etc/apache2/mods-enabled/status.load \
&& test -h /etc/munin/plugins/apache_accesses \
&& test -h /etc/munin/plugins/apache_processes \
@ -381,25 +409,26 @@ check_raidsoft() {
{ grep -q "^AUTOCHECK=true" /etc/default/mdadm \
&& grep -q "^START_DAEMON=true" /etc/default/mdadm \
&& grep -qv "^MAILADDR ___MAIL___" /etc/mdadm/mdadm.conf;
} || failed "IS_RAIDSOFT"
} || failed "IS_RAIDSOFT" "missing or wrong config for mdadm"
fi
}
# Verification du LogFormat de AWStats
check_awstatslogformat() {
if is_installed apache2 awstats; then
grep -qE '^LogFormat=1' /etc/awstats/awstats.conf.local \
|| failed "IS_AWSTATSLOGFORMAT"
awstatsFile="/etc/awstats/awstats.conf.local"
grep -qE '^LogFormat=1' $awstatsFile \
|| failed "IS_AWSTATSLOGFORMAT" "missing or wrong LogFormat directive in $awstatsFile"
fi
}
# Verification de la présence de la config logrotate pour Munin
check_muninlogrotate() {
{ test -e /etc/logrotate.d/munin-node \
&& test -e /etc/logrotate.d/munin;
} || failed "IS_MUNINLOGROTATE"
} || failed "IS_MUNINLOGROTATE" "missing lorotate file for munin"
}
# Verification de l'activation de Squid dans le cas d'un pack mail
check_squid() {
if is_debian_stretch; then
if is_debian_stretch || is_debian_buster; then
squidconffile="/etc/squid/evolinux-custom.conf"
else
squidconffile="/etc/squid*/squid.conf"
@ -407,19 +436,20 @@ check_squid() {
if is_pack_web && (is_installed squid || is_installed squid3); then
host=$(hostname -i)
# shellcheck disable=SC2086
http_port=$(grep "http_port" $squidconffile | cut -f 2 -d " ")
http_port=$(grep -E "^http_port\s+[0-9]+" $squidconffile | awk '{ print $2 }')
{ grep -qE "^[^#]*iptables -t nat -A OUTPUT -p tcp --dport 80 -m owner --uid-owner proxy -j ACCEPT" "$MINIFW_FILE" \
&& grep -qE "^[^#]*iptables -t nat -A OUTPUT -p tcp --dport 80 -d $host -j ACCEPT" "$MINIFW_FILE" \
&& grep -qE "^[^#]*iptables -t nat -A OUTPUT -p tcp --dport 80 -d 127.0.0.(1|0/8) -j ACCEPT" "$MINIFW_FILE" \
&& grep -qE "^[^#]*iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-port.* $http_port" "$MINIFW_FILE";
} || failed "IS_SQUID"
} || failed "IS_SQUID" "missing squid rules in minifirewall"
fi
}
check_evomaintenance_fw() {
if [ -f "$MINIFW_FILE" ]; then
hook_db=$(grep -E '^\s*HOOK_DB' /etc/evomaintenance.cf | tr -d ' ' | cut -d= -f2)
rulesNumber=$(grep -c "/sbin/iptables -A INPUT -p tcp --sport 5432 --dport 1024:65535 -s .* -m state --state ESTABLISHED,RELATED -j ACCEPT" "$MINIFW_FILE")
if [ "$rulesNumber" -lt 2 ]; then
failed "IS_EVOMAINTENANCE_FW"
if [ "$hook_db" = "1" ] && [ "$rulesNumber" -lt 2 ]; then
failed "IS_EVOMAINTENANCE_FW" "HOOK_DB is enabled but missing evomaintenance rules in minifirewall"
fi
fi
}
@ -430,36 +460,36 @@ check_moddeflate() {
{ test -e $f && grep -q "AddOutputFilterByType DEFLATE text/html text/plain text/xml" $f \
&& grep -q "AddOutputFilterByType DEFLATE text/css" $f \
&& grep -q "AddOutputFilterByType DEFLATE application/x-javascript application/javascript" $f;
} || failed "IS_MODDEFLATE"
} || failed "IS_MODDEFLATE" "missing AddOutputFilterByType directive for apache mod deflate"
fi
}
# Verification de la conf log2mail
check_log2mailrunning() {
if is_pack_web && is_installed log2mail; then
pgrep log2mail >/dev/null || failed 'IS_LOG2MAILRUNNING'
pgrep log2mail >/dev/null || failed "IS_LOG2MAILRUNNING" "log2mail is not running"
fi
}
check_log2mailapache() {
if is_debian_stretch; then
if is_debian_stretch || is_debian_buster; then
conf=/etc/log2mail/config/apache
else
conf=/etc/log2mail/config/default
fi
if is_pack_web && is_installed log2mail; then
grep -s -q "^file = /var/log/apache2/error.log" $conf \
|| failed "IS_LOG2MAILAPACHE"
|| failed "IS_LOG2MAILAPACHE" "missing log2mail directive for apache"
fi
}
check_log2mailmysql() {
if is_pack_web && is_installed log2mail; then
grep -s -q "^file = /var/log/syslog" /etc/log2mail/config/{default,mysql,mysql.conf} \
|| failed "IS_LOG2MAILMYSQL"
|| failed "IS_LOG2MAILMYSQL" "missing log2mail directive for mysql"
fi
}
check_log2mailsquid() {
if is_pack_web && is_installed log2mail; then
grep -s -q "^file = /var/log/squid.*/access.log" /etc/log2mail/config/* \
|| failed "IS_LOG2MAILSQUID"
|| failed "IS_LOG2MAILSQUID" "missing log2mail directive for squid"
fi
}
# Verification si bind est chroote
@ -470,7 +500,7 @@ check_bindchroot() {
md5_original=$(md5sum /usr/sbin/named | cut -f 1 -d ' ')
md5_chrooted=$(md5sum /var/chroot-bind/usr/sbin/named | cut -f 1 -d ' ')
if [ "$md5_original" != "$md5_chrooted" ]; then
failed "IS_BINDCHROOT" "The chrooted bind binary is differet than the original binary"
failed "IS_BINDCHROOT" "the chrooted bind binary is different than the original binary"
fi
else
failed "IS_BINDCHROOT" "bind process is not chrooted"
@ -482,11 +512,11 @@ check_bindchroot() {
check_repvolatile() {
if is_debian_lenny; then
grep -qE "^deb http://volatile.debian.org/debian-volatile" /etc/apt/sources.list \
|| failed "IS_REPVOLATILE"
|| failed "IS_REPVOLATILE" "missing debian-volatile repository"
fi
if is_debian_squeeze; then
grep -qE "^deb.*squeeze-updates" /etc/apt/sources.list \
|| failed "IS_REPVOLATILE"
|| failed "IS_REPVOLATILE" "missing squeeze-updates repository"
fi
}
# /etc/network/interfaces should be present, we don't manage systemd-network yet
@ -499,7 +529,7 @@ check_network_interfaces() {
}
# Verify if all if are in auto
check_autoif() {
if is_debian_stretch; then
if is_debian_stretch || is_debian_buster; then
interfaces=$(/sbin/ip address show up | grep "^[0-9]*:" | grep -E -v "(lo|vnet|docker|veth|tun|tap|macvtap)" | cut -d " " -f 2 | tr -d : | cut -d@ -f1 | tr "\n" " ")
else
interfaces=$(/sbin/ifconfig -s | tail -n +2 | grep -E -v "^(lo|vnet|docker|veth|tun|tap|macvtap)" | cut -d " " -f 1 |tr "\n" " ")
@ -521,18 +551,33 @@ check_interfacesgw() {
# Verification de la mise en place d'evobackup
check_evobackup() {
evobackup_found=$(find /etc/cron* -name '*evobackup*' | wc -l)
test "$evobackup_found" -gt 0 || failed "IS_EVOBACKUP"
test "$evobackup_found" -gt 0 || failed "IS_EVOBACKUP" "missing evobackup cron"
}
# Vérification de l'exclusion des montages (NFS) dans les sauvegardes
check_evobackup_exclude_mount() {
excludes_file=$(mktemp)
# shellcheck disable=SC2064
trap "rm -f ${excludes_file}" 0
# shellcheck disable=SC2044
for evobackup_file in $(find /etc/cron* -name '*evobackup*'); do
grep -- "--exclude " "${evobackup_file}" | grep -E -o "\"[^\"]+\"" | tr -d '"' > "${excludes_file}"
not_excluded=$(findmnt --type nfs,nfs4,fuse.sshfs, -o target --noheadings | grep -v -f "${excludes_file}")
for mount in ${not_excluded}; do
failed "IS_EVOBACKUP_EXCLUDE_MOUNT" "${mount} is not excluded from ${evobackup_file} backup script"
done
done
}
# Verification de la presence du userlogrotate
check_userlogrotate() {
if is_pack_web; then
test -x /etc/cron.weekly/userlogrotate || failed "IS_USERLOGROTATE"
test -x /etc/cron.weekly/userlogrotate || failed "IS_USERLOGROTATE" "missing userlogrotate cron"
fi
}
# Verification de la syntaxe de la conf d'Apache
check_apachectl() {
if is_installed apache2; then
/usr/sbin/apache2ctl configtest 2>&1 | grep -q "^Syntax OK$" || failed "IS_APACHECTL"
/usr/sbin/apache2ctl configtest 2>&1 | grep -q "^Syntax OK$" \
|| failed "IS_APACHECTL" "apache errors detected, run a configtest"
fi
}
# Check if there is regular files in Apache sites-enabled.
@ -559,7 +604,7 @@ check_apacheipinallow() {
| grep -iv "from all" \
| grep -iv "env=" \
| perl -ne 'exit 1 unless (/from( [\da-f:.\/]+)+$/i)' \
|| failed "IS_APACHEIPINALLOW"
|| failed "IS_APACHEIPINALLOW" "bad (Allow|Deny) directives in apache"
fi
}
# Check if default Apache configuration file for munin is absent (or empty or commented).
@ -570,7 +615,8 @@ check_muninapacheconf() {
muninconf="/etc/apache2/conf-available/munin.conf"
fi
if is_installed apache2; then
test -e $muninconf && grep -vEq "^( |\t)*#" "$muninconf" && failed "IS_MUNINAPACHECONF"
test -e $muninconf && grep -vEq "^( |\t)*#" "$muninconf" \
&& failed "IS_MUNINAPACHECONF" "default munin configuration may be commented or disabled"
fi
}
# Verification de la priorité du package samba si les backports sont utilisés
@ -578,7 +624,7 @@ check_sambainpriority() {
if is_debian_lenny && is_pack_samba; then
if grep -qrE "^[^#].*backport" /etc/apt/sources.list{,.d}; then
priority=$(grep -E -A2 "^Package:.*samba" /etc/apt/preferences | grep -A1 "^Pin: release a=lenny-backports" | grep "^Pin-Priority:" | cut -f2 -d" ")
test "$priority" -gt 500 || failed "IS_SAMBAPINPRIORITY"
test "$priority" -gt 500 || failed "IS_SAMBAPINPRIORITY" "bad pinning priority for samba"
fi
fi
}
@ -589,7 +635,7 @@ check_kerneluptodate() {
kernel_installed_at=$(date -d "$(ls --full-time -lcrt /boot | tail -n1 | awk '{print $6}')" +%s)
last_reboot_at=$(($(date +%s) - $(cut -f1 -d '.' /proc/uptime)))
if [ "$kernel_installed_at" -gt "$last_reboot_at" ]; then
failed "IS_KERNELUPTODATE"
failed "IS_KERNELUPTODATE" "machine is running an outdated kernel, reboot advised"
fi
fi
}
@ -599,7 +645,7 @@ check_uptime() {
limit=$(date -d "now - 2 year" +%s)
last_reboot_at=$(($(date +%s) - $(cut -f1 -d '.' /proc/uptime)))
if [ "$limit" -gt "$last_reboot_at" ]; then
failed "IS_UPTIME"
failed "IS_UPTIME" "machine has an uptime of more than 2 years, reboot on new kernel advised"
fi
fi
}
@ -629,9 +675,10 @@ check_muninrunning() {
}
# Check if files in /home/backup/ are up-to-date
check_backupuptodate() {
if [ -d /home/backup/ ]; then
if [ -n "$(ls -A /home/backup/)" ]; then
for file in /home/backup/*; do
backup_dir="/home/backup"
if [ -d "${backup_dir}" ]; then
if [ -n "$(ls -A ${backup_dir})" ]; then
for file in ${backup_dir}/*; do
limit=$(date +"%s" -d "now - 2 day")
updated_at=$(stat -c "%Y" "$file")
@ -641,21 +688,24 @@ check_backupuptodate() {
fi
done
else
failed "IS_BACKUPUPTODATE" "/home/backup/ is empty"
failed "IS_BACKUPUPTODATE" "${backup_dir}/ is empty"
fi
else
failed "IS_BACKUPUPTODATE" "/home/backup/ is missing"
failed "IS_BACKUPUPTODATE" "${backup_dir}/ is missing"
fi
}
check_etcgit() {
(cd /etc; git rev-parse --is-inside-work-tree > /dev/null 2>&1) || failed "IS_ETCGIT" "/etc is not a Git repository"
export GIT_DIR="/etc/.git" GIT_WORK_TREE="/etc"
git rev-parse --is-inside-work-tree > /dev/null 2>&1 \
|| failed "IS_ETCGIT" "/etc is not a git repository"
}
# Check if /etc/.git/ has read/write permissions for root only.
check_gitperms() {
if test -d /etc/.git; then
GIT_DIR="/etc/.git"
if test -d $GIT_DIR; then
expected="700"
actual=$(stat -c "%a" /etc/.git/)
[ "$expected" = "$actual" ] || failed "IS_GITPERMS"
actual=$(stat -c "%a" $GIT_DIR)
[ "$expected" = "$actual" ] || failed "IS_GITPERMS" "$GIT_DIR must be $expected"
fi
}
# Check if no package has been upgraded since $limit.
@ -695,6 +745,7 @@ check_notupgraded() {
check_tune2fs_m5() {
min=5
parts=$(grep -E "ext(3|4)" /proc/mounts | cut -d ' ' -f1 | tr -s '\n' ' ')
FINDMNT_BIN=$(command -v findmnt)
for part in $parts; do
blockCount=$(dumpe2fs -h "$part" 2>/dev/null | grep -e "Block count:" | grep -Eo "[0-9]+")
# If buggy partition, skip it.
@ -707,20 +758,25 @@ check_tune2fs_m5() {
percentage=$(awk "BEGIN { pc=100*${reservedBlockCount}/${blockCount}; i=int(pc); print (pc-i<0.5)?i:i+1 }")
if [ "$percentage" -lt "${min}" ]; then
failed "IS_TUNE2FS_M5" "Partition ${part} has less than ${min}% reserved blocks (${percentage}%)"
if [ -x "${FINDMNT_BIN}" ]; then
mount=$(${FINDMNT_BIN} --noheadings --first-only --output TARGET "${part}")
else
mount="unknown mount point"
fi
failed "IS_TUNE2FS_M5" "Partition ${part} (${mount}) has less than ${min}% reserved blocks (${percentage}%)"
fi
done
}
check_evolinuxsudogroup() {
if is_debian_stretch; then
if is_debian_stretch || is_debian_buster; then
if grep -q "^evolinux-sudo:" /etc/group; then
grep -q '^%evolinux-sudo ALL=(ALL:ALL) ALL' /etc/sudoers.d/evolinux \
|| failed "IS_EVOLINUXSUDOGROUP"
grep -qE '^%evolinux-sudo +ALL ?= ?\(ALL:ALL\) ALL' /etc/sudoers.d/evolinux \
|| failed "IS_EVOLINUXSUDOGROUP" "missing evolinux-sudo directive in sudoers file"
fi
fi
}
check_userinadmgroup() {
if is_debian_stretch; then
if is_debian_stretch || is_debian_buster; then
users=$(grep "^evolinux-sudo:" /etc/group | awk -F: '{print $4}' | tr ',' ' ')
for user in $users; do
if ! groups "$user" | grep -q adm; then
@ -731,15 +787,17 @@ check_userinadmgroup() {
fi
}
check_apache2evolinuxconf() {
if is_debian_stretch && test -d /etc/apache2; then
{ test -L /etc/apache2/conf-enabled/z-evolinux-defaults.conf \
&& test -L /etc/apache2/conf-enabled/zzz-evolinux-custom.conf \
&& test -f /etc/apache2/ipaddr_whitelist.conf;
} || failed "IS_APACHE2EVOLINUXCONF"
if is_debian_stretch || is_debian_buster; then
if test -d /etc/apache2; then
{ test -L /etc/apache2/conf-enabled/z-evolinux-defaults.conf \
&& test -L /etc/apache2/conf-enabled/zzz-evolinux-custom.conf \
&& test -f /etc/apache2/ipaddr_whitelist.conf;
} || failed "IS_APACHE2EVOLINUXCONF" "missing custom evolinux apache config"
fi
fi
}
check_backportsconf() {
if is_debian_stretch; then
if is_debian_stretch || is_debian_buster; then
grep -qsE "^[^#].*backports" /etc/apt/sources.list \
&& failed "IS_BACKPORTSCONF" "backports can't be in main sources list"
if grep -qsE "^[^#].*backports" /etc/apt/sources.list.d/*.list; then
@ -749,15 +807,19 @@ check_backportsconf() {
fi
}
check_bind9munin() {
if is_debian_stretch && is_installed bind9; then
{ test -L /etc/munin/plugins/bind9 \
&& test -e /etc/munin/plugin-conf.d/bind9;
} || failed "IS_BIND9MUNIN"
if is_debian_stretch || is_debian_buster; then
if is_installed bind9; then
{ test -L /etc/munin/plugins/bind9 \
&& test -e /etc/munin/plugin-conf.d/bind9;
} || failed "IS_BIND9MUNIN" "missing bind plugin for munin"
fi
fi
}
check_bind9logrotate() {
if is_debian_stretch && is_installed bind9; then
test -e /etc/logrotate.d/bind9 || failed "IS_BIND9LOGROTATE"
if is_debian_stretch || is_debian_buster; then
if is_installed bind9; then
test -e /etc/logrotate.d/bind9 || failed "IS_BIND9LOGROTATE" "missing bind logrotate file"
fi
fi
}
check_broadcomfirmware() {
@ -766,10 +828,10 @@ check_broadcomfirmware() {
if ${LSPCI_BIN} | grep -q 'NetXtreme II'; then
{ is_installed firmware-bnx2 \
&& grep -q "^deb http://mirror.evolix.org/debian.* non-free" /etc/apt/sources.list;
} || failed "IS_BROADCOMFIRMWARE"
} || failed "IS_BROADCOMFIRMWARE" "missing non-free repository"
fi
else
failed "IS_BROADCOMFIRMWARE" "lspci is missing"
failed "IS_BROADCOMFIRMWARE" "lspci not found in ${PATH}"
fi
}
check_hardwareraidtool() {
@ -784,28 +846,31 @@ check_hardwareraidtool() {
is_installed cciss-vol-status || failed "IS_HARDWARERAIDTOOL" "cciss-vol-status not installed"
fi
else
failed "IS_HARDWARERAIDTOOL" "lspci is missing"
failed "IS_HARDWARERAIDTOOL" "lspci not found in ${PATH}"
fi
}
check_log2mailsystemdunit() {
if is_debian_stretch; then
{ systemctl -q is-active log2mail.service \
&& test -f /etc/systemd/system/log2mail.service \
&& ! test -f /etc/init.d/log2mail;
} || failed "IS_LOG2MAILSYSTEMDUNIT"
if is_debian_stretch || is_debian_buster; then
systemctl -q is-active log2mail.service \
|| failed "IS_LOG2MAILSYSTEMDUNIT" "log2mail unit not running"
test -f /etc/systemd/system/log2mail.service \
|| failed "IS_LOG2MAILSYSTEMDUNIT" "missing log2mail unit file"
test -f /etc/init.d/log2mail \
&& failed "IS_LOG2MAILSYSTEMDUNIT" "/etc/init.d/log2mail may be deleted (use systemd unit)"
fi
}
check_listupgrade() {
{ test -f /etc/cron.d/listupgrade \
&& test -x /usr/share/scripts/listupgrade.sh;
} || failed "IS_LISTUPGRADE"
test -f /etc/cron.d/listupgrade \
|| failed "IS_LISTUPGRADE" "missing listupgrade cron"
test -x /usr/share/scripts/listupgrade.sh \
|| failed "IS_LISTUPGRADE" "missing listupgrade script or not executable"
}
check_mariadbevolinuxconf() {
if is_debian_stretch; then
if is_debian_stretch || is_debian_buster; then
if is_installed mariadb-server; then
{ test -f /etc/mysql/mariadb.conf.d/z-evolinux-defaults.cnf \
&& test -f /etc/mysql/mariadb.conf.d/zzz-evolinux-custom.cnf;
} || failed "IS_MARIADBEVOLINUXCONF"
} || failed "IS_MARIADBEVOLINUXCONF" "missing mariadb custom config"
fi
fi
}
@ -862,70 +927,85 @@ check_redis_backup() {
check_elastic_backup() {
if is_installed elasticsearch; then
# You could change the default path in /etc/evocheck.cf
ELASTIC_BACKUP_PATH=${ELASTIC_BACKUP_PATH:-"/home/backup/elasticsearch"}
ELASTIC_BACKUP_PATH=${ELASTIC_BACKUP_PATH:-"/home/backup-elasticsearch"}
test -d "$ELASTIC_BACKUP_PATH" || failed "IS_ELASTIC_BACKUP" "Elastic snapshot is missing (${ELASTIC_BACKUP_PATH})"
fi
}
check_mariadbsystemdunit() {
if is_debian_stretch && is_installed mariadb-server; then
{ systemctl -q is-active mariadb.service \
&& test -f /etc/systemd/system/mariadb.service.d/evolinux.conf;
} || failed "IS_MARIADBSYSTEMDUNIT"
if is_debian_stretch || is_debian_buster; then
if is_installed mariadb-server; then
if systemctl -q is-active mariadb.service; then
test -f /etc/systemd/system/mariadb.service.d/evolinux.conf \
|| failed "IS_MARIADBSYSTEMDUNIT" "missing systemd override for mariadb unit"
fi
fi
fi
}
check_mysqlmunin() {
if is_debian_stretch && is_installed mariadb-server; then
for file in mysql_bytes mysql_queries mysql_slowqueries \
mysql_threads mysql_connections mysql_files_tables \
mysql_innodb_bpool mysql_innodb_bpool_act mysql_innodb_io \
mysql_innodb_log mysql_innodb_rows mysql_innodb_semaphores \
mysql_myisam_indexes mysql_qcache mysql_qcache_mem \
mysql_sorts mysql_tmp_tables; do
if is_debian_stretch || is_debian_buster; then
if is_installed mariadb-server; then
for file in mysql_bytes mysql_queries mysql_slowqueries \
mysql_threads mysql_connections mysql_files_tables \
mysql_innodb_bpool mysql_innodb_bpool_act mysql_innodb_io \
mysql_innodb_log mysql_innodb_rows mysql_innodb_semaphores \
mysql_myisam_indexes mysql_qcache mysql_qcache_mem \
mysql_sorts mysql_tmp_tables; do
if [[ ! -L /etc/munin/plugins/$file ]]; then
failed "IS_MYSQLMUNIN" "Munin plugin '$file' is missing"
test "${VERBOSE}" = 1 || break
fi
done
if [[ ! -L /etc/munin/plugins/$file ]]; then
failed "IS_MYSQLMUNIN" "missing munin plugin '$file'"
test "${VERBOSE}" = 1 || break
fi
done
fi
fi
}
check_mysqlnrpe() {
if is_debian_stretch && is_installed mariadb-server; then
nagios_file=~nagios/.my.cnf
if ! test -f ${nagios_file}; then
failed "IS_MYSQLNRPE" "${nagios_file} is missing"
elif [ "$(stat -c %U ${nagios_file})" != "nagios" ] \
|| [ "$(stat -c %a ${nagios_file})" != "600" ]; then
failed "IS_MYSQLNRPE" "${nagios_file} has wrong permissions"
else
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"
if is_debian_stretch || is_debian_buster; then
if is_installed mariadb-server; then
nagios_file=~nagios/.my.cnf
if ! test -f ${nagios_file}; then
failed "IS_MYSQLNRPE" "${nagios_file} is missing"
elif [ "$(stat -c %U ${nagios_file})" != "nagios" ] \
|| [ "$(stat -c %a ${nagios_file})" != "600" ]; then
failed "IS_MYSQLNRPE" "${nagios_file} has wrong permissions"
else
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() {
if is_debian_stretch && is_installed php; then
{ test -f /etc/php/7.0/cli/conf.d/z-evolinux-defaults.ini \
&& test -f /etc/php/7.0/cli/conf.d/zzz-evolinux-custom.ini;
} || failed "IS_PHPEVOLINUXCONF"
if is_debian_stretch || is_debian_buster; then
is_debian_stretch && phpVersion="7.0"
is_debian_buster && phpVersion="7.3"
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
} || failed "IS_PHPEVOLINUXCONF" "missing php evolinux config"
fi
fi
}
check_squidlogrotate() {
if is_debian_stretch && is_installed squid; then
grep -q monthly /etc/logrotate.d/squid || failed "IS_SQUIDLOGROTATE"
if is_debian_stretch || is_debian_buster; then
if is_installed squid; then
grep -q monthly /etc/logrotate.d/squid \
|| failed "IS_SQUIDLOGROTATE" "missing squid logrotate file"
fi
fi
}
check_squidevolinuxconf() {
if is_debian_stretch && is_installed squid; then
{ grep -qs "^CONFIG=/etc/squid/evolinux-defaults.conf$" /etc/default/squid \
&& test -f /etc/squid/evolinux-defaults.conf \
&& test -f /etc/squid/evolinux-whitelist-defaults.conf \
&& test -f /etc/squid/evolinux-whitelist-custom.conf \
&& test -f /etc/squid/evolinux-acl.conf \
&& test -f /etc/squid/evolinux-httpaccess.conf \
&& test -f /etc/squid/evolinux-custom.conf;
} || failed "IS_SQUIDEVOLINUXCONF"
if is_debian_stretch || is_debian_buster; then
if is_installed squid; then
{ grep -qs "^CONFIG=/etc/squid/evolinux-defaults.conf$" /etc/default/squid \
&& test -f /etc/squid/evolinux-defaults.conf \
&& test -f /etc/squid/evolinux-whitelist-defaults.conf \
&& test -f /etc/squid/evolinux-whitelist-custom.conf \
&& test -f /etc/squid/evolinux-acl.conf \
&& test -f /etc/squid/evolinux-httpaccess.conf \
&& test -f /etc/squid/evolinux-custom.conf;
} || failed "IS_SQUIDEVOLINUXCONF" "missing squid evolinux config"
fi
fi
}
check_duplicate_fs_label() {
@ -947,11 +1027,12 @@ check_duplicate_fs_label() {
fi
rm "$tmpFile"
else
failed "IS_DUPLICATE_FS_LABEL" "blkid not found"
failed "IS_DUPLICATE_FS_LABEL" "blkid not found in ${PATH}"
fi
}
check_evolix_user() {
grep -q "evolix:" /etc/passwd && failed "IS_EVOLIX_USER"
grep -q "evolix:" /etc/passwd \
&& failed "IS_EVOLIX_USER" "evolix user should be deleted, used only for install"
}
check_evoacme_cron() {
if [ -f "/usr/local/sbin/evoacme" ]; then
@ -989,20 +1070,23 @@ check_apache_confenabled() {
# Starting from Jessie and Apache 2.4, /etc/apache2/conf.d/
# must be replaced by conf-available/ and config files symlinked
# to conf-enabled/
if is_debian_jessie || is_debian_stretch; then
if is_debian_jessie || is_debian_stretch || is_debian_buster; then
if [ -f /etc/apache2/apache2.conf ]; then
test -d /etc/apache2/conf.d/ && failed "IS_APACHE_CONFENABLED"
grep -q 'Include conf.d' /etc/apache2/apache2.conf && failed "IS_APACHE_CONFENABLED"
test -d /etc/apache2/conf.d/ \
&& failed "IS_APACHE_CONFENABLED" "apache's conf.d directory must not exists"
grep -q 'Include conf.d' /etc/apache2/apache2.conf \
&& failed "IS_APACHE_CONFENABLED" "apache2.conf must not Include conf.d"
fi
fi
}
check_meltdown_spectre() {
# For Stretch, detection is easy as the kernel use
# /sys/devices/system/cpu/vulnerabilities/
if is_debian_stretch; then
if is_debian_stretch || is_debian_buster; then
for vuln in meltdown spectre_v1 spectre_v2; do
test -f "/sys/devices/system/cpu/vulnerabilities/$vuln" \
|| failed "IS_MELTDOWN_SPECTRE"
|| failed "IS_MELTDOWN_SPECTRE" "vulnerable to $vuln"
test "${VERBOSE}" = 1 || break
done
# For Jessie this is quite complicated to verify and we need to use kernel config file
elif is_debian_jessie; then
@ -1013,9 +1097,11 @@ check_meltdown_spectre() {
# Sometimes autodetection of kernel config file fail, so we test if the file really exists.
if [ -f "/boot/${kernelConfig}" ]; then
grep -Eq '^CONFIG_PAGE_TABLE_ISOLATION=y' "/boot/$kernelConfig" \
|| failed "IS_MELTDOWN_SPECTRE" "PAGE_TABLE_ISOLATION vulnerability is not patched"
|| failed "IS_MELTDOWN_SPECTRE" \
"PAGE_TABLE_ISOLATION must be enabled in kernel, outdated kernel?"
grep -Eq '^CONFIG_RETPOLINE=y' "/boot/$kernelConfig" \
|| failed "IS_MELTDOWN_SPECTRE" "RETPOLINE vulnerability is not patched"
|| failed "IS_MELTDOWN_SPECTRE" \
"RETPOLINE must be enabled in kernel, outdated kernel?"
fi
fi
fi
@ -1036,29 +1122,31 @@ check_old_home_dir() {
check_tmp_1777() {
actual=$(stat --format "%a" /tmp)
expected="1777"
test "$expected" = "$actual" || failed "IS_TMP_1777"
test "$expected" = "$actual" || failed "IS_TMP_1777" "/tmp must be $expected"
}
check_root_0700() {
actual=$(stat --format "%a" /root)
expected="700"
test "$expected" = "$actual" || failed "IS_ROOT_0700"
test "$expected" = "$actual" || failed "IS_ROOT_0700" "/root must be $expected"
}
check_usrsharescripts() {
actual=$(stat --format "%a" /usr/share/scripts)
expected="700"
test "$expected" = "$actual" || failed "IS_USRSHARESCRIPTS"
test "$expected" = "$actual" || failed "IS_USRSHARESCRIPTS" "/usr/share/scripts must be $expected"
}
check_sshpermitrootno() {
if is_debian_stretch; then
if is_debian_stretch || is_debian_buster; then
if grep -q "^PermitRoot" /etc/ssh/sshd_config; then
grep -E -qi "PermitRoot.*no" /etc/ssh/sshd_config || failed "IS_SSHPERMITROOTNO"
grep -E -qi "PermitRoot.*no" /etc/ssh/sshd_config \
|| failed "IS_SSHPERMITROOTNO" "PermitRoot should be set at no"
fi
else
grep -E -qi "PermitRoot.*no" /etc/ssh/sshd_config || failed "IS_SSHPERMITROOTNO"
grep -E -qi "PermitRoot.*no" /etc/ssh/sshd_config \
|| failed "IS_SSHPERMITROOTNO" "PermitRoot should be set at no"
fi
}
check_evomaintenanceusers() {
if is_debian_stretch; then
if is_debian_stretch || is_debian_buster; then
users=$(getent group evolinux-sudo | cut -d':' -f4 | tr ',' ' ')
else
if [ -f /etc/sudoers.d/evolinux ]; then
@ -1117,7 +1205,7 @@ check_evobackup_incs() {
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 -q "check-incs.sh" || failed "IS_EVOBACKUP_INCS" "\`check-incs.sh' 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
@ -1126,7 +1214,71 @@ check_evobackup_incs() {
check_osprober() {
if is_installed os-prober qemu-kvm; then
failed "IS_OSPROBER" "Removal of os-prober package is recommended as it can cause serious issue on KVM server"
failed "IS_OSPROBER" \
"Removal of os-prober package is recommended as it can cause serious issue on KVM server"
fi
}
check_jessie_backports() {
if is_debian_jessie; then
jessieBackports=$(grep -hs "jessie-backports" /etc/apt/sources.list /etc/apt/sources.list.d/*)
if test -n "$jessieBackports"; then
if ! grep -q "archive.debian.org" <<< "$jessieBackports"; then
failed "IS_JESSIE_BACKPORTS" "You must use deb http://archive.debian.org/debian/ jessie-backports main"
fi
fi
fi
}
check_apt_valid_until() {
aptvalidFile="/etc/apt/apt.conf.d/99no-check-valid-until"
aptvalidText="Acquire::Check-Valid-Until no;"
if grep -qs "archive.debian.org" /etc/apt/sources.list /etc/apt/sources.list.d/*; then
if ! grep -qs "$aptvalidText" /etc/apt/apt.conf.d/*; then
failed "IS_APT_VALID_UNTIL" \
"As you use archive.mirror.org you need ${aptvalidFile}: ${aptvalidText}"
fi
fi
}
check_chrooted_binary_uptodate() {
# list of processes to check
process_list="sshd"
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
process_bin=$(realpath "/proc/${pid}/exe")
# Is the process chrooted?
real_root=$(realpath "/proc/${pid}/root")
if [ "${real_root}" != "/" ]; then
chrooted_md5=$(md5sum "${process_bin}" | cut -f 1 -d ' ')
original_md5=$(md5sum "${original_bin}" | cut -f 1 -d ' ')
# compare md5 checksums
if [ "$original_md5" != "$chrooted_md5" ]; then
failed "IS_CHROOTED_BINARY_UPTODATE" "${process_bin} (${pid}) is different than ${original_bin}."
test "${VERBOSE}" = 1 || break
fi
fi
done
done
}
check_nginx_letsencrypt_uptodate() {
if [ -d /etc/nginx ]; then
snippets=$(find /etc/nginx -type f -name "letsencrypt.conf")
if [ -n "${snippets}" ]; then
while read -r snippet; do
if is_debian_jessie; then
if ! grep -qE "^\s*alias\s+/.+/\.well-known/acme-challenge" "${snippet}"; then
failed "IS_NGINX_LETSENCRYPT_UPTODATE" "Nginx snippet ${snippet} is not compatible with Nginx on Debian 8."
fi
else
if grep -qE "^\s*alias\s+/.+/\.well-known/acme-challenge" "${snippet}"; then
failed "IS_NGINX_LETSENCRYPT_UPTODATE" "Nginx snippet ${snippet} is not compatible with Nginx on Debian 9+."
fi
fi
done <<< "${snippets}"
fi
fi
}
@ -1205,6 +1357,7 @@ main() {
test "${IS_AUTOIF:=1}" = 1 && check_autoif
test "${IS_INTERFACESGW:=1}" = 1 && check_interfacesgw
test "${IS_EVOBACKUP:=1}" = 1 && check_evobackup
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
test "${IS_APACHESYMLINK:=1}" = 1 && check_apachesymlink
@ -1229,7 +1382,7 @@ main() {
test "${IS_HARDWARERAIDTOOL:=1}" = 1 && check_hardwareraidtool
test "${IS_LOG2MAILSYSTEMDUNIT:=1}" = 1 && check_log2mailsystemdunit
test "${IS_LISTUPGRADE:=1}" = 1 && check_listupgrade
test "${IS_MARIADBEVOLINUXCONF:=1}" = 1 && check_mariadbevolinuxconf
test "${IS_MARIADBEVOLINUXCONF:=0}" = 1 && check_mariadbevolinuxconf
test "${IS_SQL_BACKUP:=1}" = 1 && check_sql_backup
test "${IS_POSTGRES_BACKUP:=1}" = 1 && check_postgres_backup
test "${IS_MONGO_BACKUP:=1}" = 1 && check_mongo_backup
@ -1239,7 +1392,7 @@ main() {
test "${IS_MARIADBSYSTEMDUNIT:=1}" = 1 && check_mariadbsystemdunit
test "${IS_MYSQLMUNIN:=1}" = 1 && check_mysqlmunin
test "${IS_MYSQLNRPE:=1}" = 1 && check_mysqlnrpe
test "${IS_PHPEVOLINUXCONF:=1}" = 1 && check_phpevolinuxconf
test "${IS_PHPEVOLINUXCONF:=0}" = 1 && check_phpevolinuxconf
test "${IS_SQUIDLOGROTATE:=1}" = 1 && check_squidlogrotate
test "${IS_SQUIDEVOLINUXCONF:=1}" = 1 && check_squidevolinuxconf
test "${IS_DUPLICATE_FS_LABEL:=1}" = 1 && check_duplicate_fs_label
@ -1248,9 +1401,13 @@ main() {
test "${IS_EVOACME_LIVELINKS:=1}" = 1 && check_evoacme_livelinks
test "${IS_APACHE_CONFENABLED:=1}" = 1 && check_apache_confenabled
test "${IS_MELTDOWN_SPECTRE:=1}" = 1 && check_meltdown_spectre
test "${IS_OLD_HOME_DIR:=1}" = 1 && check_old_home_dir
test "${IS_OLD_HOME_DIR:=0}" = 1 && check_old_home_dir
test "${IS_EVOBACKUP_INCS:=1}" = 1 && check_evobackup_incs
test "${IS_OSPROBER:=1}" = 1 && check_osprober
test "${IS_JESSIE_BACKPORTS:=1}" = 1 && check_jessie_backports
test "${IS_APT_VALID_UNTIL:=1}" = 1 && check_apt_valid_until
test "${IS_CHROOTED_BINARY_UPTODATE:=1}" = 1 && check_chrooted_binary_uptodate
test "${IS_NGINX_LETSENCRYPT_UPTODATE:=1}" = 1 && check_nginx_letsencrypt_uptodate
fi
#-----------------------------------------------------------
@ -1358,13 +1515,13 @@ main() {
exit ${RC}
}
# shellcheck disable=SC2034
readonly PROGNAME=$(basename "$0")
# shellcheck disable=SC2034
readonly PROGDIR=$(realpath -m "$(dirname "$0")")
# shellcheck disable=2124
readonly ARGS=$@
readonly VERSION="19.06"
# Disable LANG*
export LANG=C
export LANGUAGE=C
@ -1388,6 +1545,7 @@ while :; do
--cron)
IS_KERNELUPTODATE=0
IS_UPTIME=0
IS_MELTDOWN_SPECTRE=0
;;
-v|--verbose)
VERBOSE=1

View File

@ -1,5 +1,12 @@
---
- name: Check if cron is installed
shell: "dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'"
failed_when: False
changed_when: False
check_mode: no
register: is_cron_installed
- name: evocheck crontab is updated
template:
src: crontab.j2
@ -8,3 +15,4 @@
owner: root
group: root
force: yes
when: is_cron_installed.rc == 0

View File

@ -1,7 +1,7 @@
---
- include_role:
name: remount-usr
when: evocheck_bin_dir | search ("/usr")
name: evolix/remount-usr
when: evocheck_bin_dir is search ("/usr")
tags:
- evocheck

View File

@ -1,4 +1,5 @@
# {{ ansible_managed }}
33 1 1 * * root /usr/share/scripts/evocheck.sh
33 1 2-31 * * root /usr/share/scripts/evocheck.sh --cron
PATH=/usr/sbin:/usr/bin:/sbin:/bin
33 1 1 * * root /usr/share/scripts/evocheck.sh --verbose
33 1 2-31 * * root /usr/share/scripts/evocheck.sh --verbose --cron

View File

@ -67,6 +67,8 @@ evolinux_fstab_home: True
evolinux_fstab_home_options: defaults,noexec,nosuid,nodev
evolinux_fstab_var_tmp: True
evolinux_fstab_var_tmp_options: defaults,noexec,nosuid,nodev,size=1024m
evolinux_fstab_dev_shm: True
evolinux_fstab_dev_shm_options: defaults,nodev,nosuid,noexec
# packages
@ -77,13 +79,15 @@ evolinux_packages_diagnostic: True
evolinux_packages_hardware: True
evolinux_packages_common: True
evolinux_packages_stretch: True
evolinux_packages_buster: True
evolinux_packages_serveur_base: True
evolinux_packages_purge_openntpd: True
evolinux_packages_purge_chrony: True
evolinux_packages_purge_locate: True
evolinux_packages_invalid_mta: True
evolinux_packages_delete_nfs: True
evolinux_packages_listchanges: True
evolinux_packages_logcheck_recipient: True
evolinux_packages_logcheck_recipient: False
# system
@ -122,6 +126,7 @@ evolinux_ssh_password_auth_addresses: "{{ evolinux_default_ssh_password_auth_add
evolinux_ssh_match_address: True
evolinux_ssh_disable_acceptenv: True
evolinux_ssh_allow_current_user: False
evolinux_ssh_group: "evolinux-ssh"
### disabled because of a memory leak
# # evolinux users
@ -197,6 +202,11 @@ evolinux_nagios_nrpe_include: True
evolinux_fail2ban_include: False
# Evocheck
evolinux_evocheck_include: True
evolinux_evocheck_force_install: "local"
# Listupgrade
evolinux_listupgrade_include: True

View File

@ -0,0 +1,3 @@
#!/bin/sh
iptables -I INPUT -s $1 -j DROP
echo $1 >> /root/BLACKLIST-SSH

View File

@ -0,0 +1,19 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.12 (GNU/Linux)
mQENBFZp0LkBCACXajRw3b4x7G7dulNYj0hUID4BtVFq/MjEb6PHckTxGxZDoQRX
RK54tiTFA9wq3b4P3yEFnOjbjRoI0d7Ls67FADugFO+cDCtsV9yuDlaYP/U/h2nX
N0R4AdYbsVd5yr6xr+GAy66Hmx5jFH3kbC+zJpOcI0tU9hcyU7gjbxu6KQ1ypI2Q
VRKf8sRBJXgmkOlbYx35ZUMFcmVxrLJXvUuxmAVXgT9f5M3Z3rsGt/ab+/+1TFSb
RsaqHsIPE0QH8ikqW4IeDQAo1T99pCdf7FWr45KFFTo7O4AZdLMWVgqeFHaSoZxJ
307VIINsWiwQoPp0tfU5NOOOwB1Sv3x9QgFtABEBAAG0P0hld2xldHQgUGFja2Fy
ZCBFbnRlcnByaXNlIENvbXBhbnkgUlNBLTIwNDgtMjUgPHNpZ25ocEBocGUuY29t
PokBPQQTAQIAJwUCVmnQuQIbLwUJEswDAAYLCQgHAwIGFQgCCQoLAxYCAQIeAQIX
gAAKCRDCCK3eJsK3l9G+B/0ekblsBeN+xHIJ28pvo2aGb2KtWBwbT1ugI+aIS17K
UQyHZJUQH+ZeRLvosuoiQEdcGIqmOxi2hVhSCQAOV1LAonY16ACveA5DFAEBz1+a
WQyx6sOLLEAVX1VqGlBXxh3XLEUWOhlAf1gZPNtHsmURTUy2h1Lv/Yoj8KLyuK2n
DmrLOS3Ro+RqWocaJfvAgXKgt6Fq/ChDUHOnar7lGswzMsbE/yzLJ7He4y89ImK+
2ktR5HhDuxqgCe9CWH6Q/1WGhUa0hZ3nbluq7maa+kPe2g7JcRzPH/nJuDCAOZ7U
6mHE8j0kMQMYjgaYEx2wc02aQRmPyxhbDLjSbtjomXRr
=voON
-----END PGP PUBLIC KEY BLOCK-----

View File

@ -25,24 +25,24 @@
# SSL cert
- block:
- name: Default certificate is present
block:
- name: Create private key and csr for default site ({{ ansible_fqdn }})
command: openssl req -newkey rsa:2048 -sha256 -nodes -keyout /etc/ssl/private/{{ ansible_fqdn }}.key -out /etc/ssl/{{ ansible_fqdn }}.csr -batch -subj "/CN={{ ansible_fqdn }}"
args:
creates: "/etc/ssl/private/{{ ansible_fqdn }}.key"
- name: Create private key and csr for default site ({{ ansible_fqdn }})
command: openssl req -newkey rsa:2048 -sha256 -nodes -keyout /etc/ssl/private/{{ ansible_fqdn }}.key -out /etc/ssl/{{ ansible_fqdn }}.csr -batch -subj "/CN={{ ansible_fqdn }}"
args:
creates: "/etc/ssl/private/{{ ansible_fqdn }}.key"
- name: Adjust rights on private key
file:
path: /etc/ssl/private/{{ ansible_fqdn }}.key
owner: root
group: ssl-cert
mode: "0640"
- name: Adjust rights on private key
file:
path: /etc/ssl/private/{{ ansible_fqdn }}.key
owner: root
group: ssl-cert
mode: "0640"
- name: Create certificate for default site
command: openssl x509 -req -days 3650 -sha256 -in /etc/ssl/{{ ansible_fqdn }}.csr -signkey /etc/ssl/private/{{ ansible_fqdn }}.key -out /etc/ssl/certs/{{ ansible_fqdn }}.crt
args:
creates: "/etc/ssl/certs/{{ ansible_fqdn }}.crt"
- name: Create certificate for default site
command: openssl x509 -req -days 3650 -sha256 -in /etc/ssl/{{ ansible_fqdn }}.csr -signkey /etc/ssl/private/{{ ansible_fqdn }}.key -out /etc/ssl/certs/{{ ansible_fqdn }}.crt
args:
creates: "/etc/ssl/certs/{{ ansible_fqdn }}.crt"
when: evolinux_default_www_ssl_cert
- meta: flush_handlers

View File

@ -10,4 +10,4 @@
# state: directory
- include_role:
name: evolinux-todo
name: evolix/evolinux-todo

View File

@ -57,4 +57,15 @@
when:
- evolinux_fstab_var_tmp
- name: /dev/shm is created (Debian 10 and later)
mount:
src: tmpfs
name: /dev/shm
fstype: tmpfs
opts: "{{ evolinux_fstab_dev_shm_options | mandatory }}"
state: mounted
when:
- evolinux_fstab_dev_shm
- ansible_distribution_major_version is version('10', '>=')
- meta: flush_handlers

View File

@ -18,7 +18,7 @@
- name: Add non-free repo for Broadcom NetXtreme II
include_role:
name: apt
name: evolix/apt
tasks_from: basics.yml
vars:
apt_basics_components: "main contrib non-free"
@ -33,57 +33,76 @@
changed_when: "'FAILED' in raidmodel.stdout"
failed_when: "'FAILED' in raidmodel.stdout"
- block:
- name: Install packages for HP hardware
apt:
name: cciss-vol-status
state: present
- name: HP Smart Array package is present
block:
- name: Add HPE GPG key
apt_key:
#url: https://downloads.linux.hpe.com/SDR/hpePublicKey2048_key1.pub
data: "{{ lookup('file', 'hpePublicKey2048_key1.pub') }}"
- name: Configure packages for HP hardware
template:
src: hardware/cciss-vol-statusd.j2
dest: /etc/init.d/cciss-vol-statusd
mode: "0755"
- name: Add HPE repository
apt_repository:
repo: 'deb https://downloads.linux.hpe.com/SDR/repo/mcp {{ ansible_distribution_release }}/current non-free'
state: present
- name: Enable HP hardware in systemd
service:
name: cciss-vol-statusd
enabled: true
state: started
- name: Install packages for HP hardware
apt:
name:
- cciss-vol-status
- ssacli
state: present
- name: cciss-vol-statusd init script is present
template:
src: hardware/cciss-vol-statusd.j2
dest: /etc/init.d/cciss-vol-statusd
mode: "0755"
- name: Configure cciss-vol-statusd
lineinfile:
dest: /etc/default/cciss-vol-statusd
line: 'MAILTO="{{ raid_alert_email or general_alert_email | mandatory }}"'
regexp: 'MAILTO='
create: yes
- name: Enable HP hardware in systemd
service:
name: cciss-vol-statusd
enabled: true
state: restarted
when: "'Hewlett-Packard Company Smart Array' in raidmodel.stdout"
- block:
- name: Add HW tool GPG key
apt_key:
# url: https://hwraid.le-vert.net/debian/hwraid.le-vert.net.gpg.key
data: "{{ lookup('file', 'hwraid.le-vert.net.gpg.key') }}"
when: ansible_distribution_release == "stretch"
- name: MegaRAID SAS package is present
block:
- name: Add HW tool GPG key
apt_key:
# url: https://hwraid.le-vert.net/debian/hwraid.le-vert.net.gpg.key
data: "{{ lookup('file', 'hwraid.le-vert.net.gpg.key') }}"
when: ansible_distribution_major_version is version('9', '>=')
- name: Add HW tool repository
apt_repository:
repo: 'deb http://hwraid.le-vert.net/debian stretch main'
state: present
when: ansible_distribution_release == "stretch"
- name: Add HW tool repository
apt_repository:
repo: 'deb http://hwraid.le-vert.net/debian {{ ansible_distribution_release }} main'
state: present
- name: Install packages for DELL/LSI hardware
apt:
name: "{{ item }}"
allow_unauthenticated: yes
with_items:
- megacli
- megaclisas-status
- name: Install packages for DELL/LSI hardware
apt:
name:
- megacli
- megaclisas-status
allow_unauthenticated: yes
- name: Configure packages for DELL/LSI hardware
template:
src: hardware/megaclisas-statusd.j2
dest: /etc/default/megaclisas-statusd
mode: "0755"
- name: Configure packages for DELL/LSI hardware
template:
src: hardware/megaclisas-statusd.j2
dest: /etc/default/megaclisas-statusd
mode: "0755"
- name: Enable DELL/LSI hardware in systemd
service:
name: megaclisas-statusd
enabled: true
state: started
- name: Enable DELL/LSI hardware in systemd
service:
name: megaclisas-statusd
enabled: true
state: started
when: "'MegaRAID SAS' in raidmodel.stdout"
- meta: flush_handlers

View File

@ -24,6 +24,12 @@
dest: /etc/logrotate.d/
when: evolinux_logs_logrotate_confs
- name: Copy rsyslog logrotate file
template:
src: logs/zsyslog.j2
dest: /etc/logrotate.d/zsyslog
when: evolinux_logs_logrotate_confs
- name: Configure logrotate.conf
replace:
dest: /etc/logrotate.conf

View File

@ -4,12 +4,12 @@
assert:
that:
- ansible_distribution == "Debian"
- ansible_distribution_major_version | version_compare('8', '>=')
- ansible_distribution_major_version is version('8', '>=')
msg: only compatible with Debian >= 8
- name: Apt configuration
include_role:
name: apt
name: evolix/apt
vars:
apt_install_basics: "{{ evolinux_apt_replace_default_sources }}"
apt_install_evolix_public: "{{ evolinux_apt_public_sources }}"
@ -17,7 +17,7 @@
- name: /etc versioning with Git
include_role:
name: etc-git
name: evolix/etc-git
when: evolinux_etcgit_include
- name: /etc/evolinux base
@ -46,12 +46,12 @@
- name: Minifirewall
include_role:
name: minifirewall
name: evolix/minifirewall
when: evolinux_minifirewall_include
- name: Evomaintenance
include_role:
name: evomaintenance
name: evolix/evomaintenance
when: evolinux_evomaintenance_include
- name: SSH configuration
@ -61,7 +61,7 @@
### disabled because of a memory leak
# - name: Create evolinux users
# include_role:
# name: evolinux-users
# name: evolix/evolinux-users
# when: evolinux_users_include
- name: Root user configuration
@ -92,7 +92,7 @@
include: provider_orange_fce.yml
when: evolinux_provider_orange_fce_include
- name: Override Logmail service
- name: Override Log2mail service
include: log2mail.yml
when: evolinux_log2mail_include
@ -100,25 +100,32 @@
- name: Munin
include_role:
name: munin
name: evolix/munin
when: evolinux_munin_include
- name: Nagios/NRPE
include_role:
name: nagios-nrpe
name: evolix/nagios-nrpe
when: evolinux_nagios_nrpe_include
- name: fail2ban
include_role:
name: fail2ban
name: evolix/fail2ban
when: evolinux_fail2ban_include
- name: Evocheck
include_role:
name: evolix/evocheck
vars:
evocheck_force_install: "{{ evolinux_evocheck_force_install }}"
when: evolinux_evocheck_include
- name: Listupgrade
include_role:
name: listupgrade
name: evolix/listupgrade
when: evolinux_listupgrade_include
- name: Generate ldif script
include_role:
name: generate-ldif
name: evolix/generate-ldif
when: evolinux_generateldif_include

View File

@ -2,82 +2,84 @@
- name: Install/Update system tools
apt:
name: "{{ item }}"
with_items:
- locales
- sudo
- ntpdate
- lsb-release
- dnsutils
- pv
- apg
- conntrack
- logrotate
- bash-completion
- ssl-cert
- ca-certificates
- rename
name:
- locales
- sudo
- ntpdate
- lsb-release
- dnsutils
- pv
- apg
- conntrack
- logrotate
- bash-completion
- ssl-cert
- ca-certificates
- rename
when: evolinux_packages_system
- name: Install/Update diagnostic tools
apt:
name: "{{ item }}"
with_items:
- strace
- htop
- iftop
- iptraf
- ncdu
- iotop
- tcpdump
- mtr-tiny
- curl
- telnet
- traceroute
- man
name:
- strace
- htop
- iftop
- iptraf
- ncdu
- iotop
- tcpdump
- mtr-tiny
- curl
- telnet
- traceroute
- man
when: evolinux_packages_diagnostic
- name: Install/Update hardware tools
apt:
name: "{{ item }}"
with_items:
- hdparm
- smartmontools
- lm-sensors
name:
- hdparm
- smartmontools
- lm-sensors
when: evolinux_packages_hardware
- name: Install/Update common tools
apt:
name: "{{ item }}"
with_items:
- vim
- screen
- tmux
- mutt
- tree
- git
- subversion
- rsync
- bc
- pinentry-curses
- ncurses-term
name:
- vim
- screen
- tmux
- mutt
- tree
- git
- subversion
- rsync
- bc
- pinentry-curses
- ncurses-term
when: evolinux_packages_common
- name: Be sure that openntpd package is absent/purged
apt:
name: openntpd
state: absent
purge: yes
purge: True
when: evolinux_packages_purge_openntpd
- name: the chrony package is absent
apt:
name: chrony
purge: True
state: absent
when: evolinux_packages_purge_chrony
- name: Be sure locate/mlocate is absent/purged
apt:
name: "{{ item }}"
name:
- locate
- mlocate
state: absent
purge: yes
with_items:
- locate
- mlocate
when: evolinux_packages_purge_locate
- name: Install/Update serveur-base meta-package
@ -88,12 +90,19 @@
- name: Install/Update packages for Stretch and later
apt:
name: "{{ item }}"
with_items:
- net-tools
name: net-tools
when:
- evolinux_packages_stretch
- ansible_distribution_major_version | version_compare('9', '>=')
- evolinux_packages_stretch
- ansible_distribution_major_version is version('9', '>=')
- name: Install/Update packages for Buster and later
apt:
name:
- spectre-meltdown-checker
- binutils
when:
- evolinux_packages_buster
- ansible_distribution_major_version is version('10', '>=')
- name: Customize logcheck recipient
lineinfile:
@ -104,11 +113,10 @@
- name: Deleting rpcbind and nfs-common
apt:
name: "{{ item }}"
name:
- rpcbind
- nfs-common
state: absent
with_items:
- rpcbind
- nfs-common
when: evolinux_packages_delete_nfs
@ -133,6 +141,6 @@
state: absent
when:
- ansible_distribution == "Debian"
- ansible_distribution_major_version | version_compare('9', '>=')
- ansible_distribution_major_version is version('9', '>=')
- meta: flush_handlers

View File

@ -2,11 +2,10 @@
- name: Postfix packages are installed
apt:
name: "{{ item }}"
name:
- postfix
- mailgraph
state: present
with_items:
- postfix
- mailgraph
when: evolinux_postfix_packages
tags:
- packages
@ -83,14 +82,13 @@
- name: exim4 is absent
apt:
name: "{{ item }}"
name:
- exim4
- exim4-base
- exim4-config
- exim4-daemon-light
purge: yes
state: absent
with_items:
- exim4
- exim4-base
- exim4-config
- exim4-daemon-light
when: evolinux_postfix_purge_exim
tags:
- packages

View File

@ -37,6 +37,12 @@
regexp: "umask [0-9]+"
when: evolinux_root_umask
- name: "/usr/share/scripts is present in root's PATH"
lineinfile:
dest: "/root/.profile"
line: "PATH=\"${PATH}:/usr/share/scripts\""
when: ansible_distribution_major_version is version('10', '>=')
- name: Custom git config for root
copy:
src: root/gitconfig
@ -87,7 +93,7 @@
dest: /etc/ssh/sshd_config
regexp: '^PermitRootLogin (yes|without-password|prohibit-password)'
replace: "PermitRootLogin no"
validate: '/usr/sbin/sshd -T -f %s'
validate: '/usr/sbin/sshd -t -f %s'
notify: reload sshd
when: evolinux_root_disable_ssh

View File

@ -11,7 +11,7 @@
# only the first instance of the keyword is applied. »
#
# We want to allow any user from a list of IP addresses to login with password,
# but users of the "evolix" group can't login with password from other IP addresses
# but users of the "{{ evolinux_internal_group }}" group can't login with password from other IP addresses
- name: "Security directives for Evolinux (Debian 10 or later)"
blockinfile:
@ -20,14 +20,14 @@
block: |
Match Address {{ evolinux_ssh_password_auth_addresses | join(',') }}
PasswordAuthentication yes
Match Group evolix
Match Group {{ evolinux_internal_group }}
PasswordAuthentication no
insertafter: EOF
validate: '/usr/sbin/sshd -t -f %s'
notify: reload sshd
when:
- evolinux_ssh_password_auth_addresses != []
- ansible_distribution_major_version | version_compare('10', '>=')
- ansible_distribution_major_version is version('10', '>=')
- name: Security directives for Evolinux (Jessie/Stretch)
blockinfile:
@ -41,7 +41,7 @@
notify: reload sshd
when:
- evolinux_ssh_password_auth_addresses != []
- ansible_distribution_major_version | version_compare('10', '<')
- ansible_distribution_major_version is version('10', '<')
# We disable AcceptEnv because it can be a security issue, but also because we
# do not want clients to push their environment variables like LANG.
@ -59,7 +59,7 @@
regexp: '^#?LogLevel [A-Z]+'
replace: "LogLevel VERBOSE"
notify: reload sshd
when: ansible_distribution_major_version | version_compare('9', '>=')
when: ansible_distribution_major_version is version('9', '>=')
- name: "Get current user"
command: logname

View File

@ -22,7 +22,7 @@
- name: Reconfigure locales
command: /usr/sbin/locale-gen
when: evolinux_system_locales and default_locales | changed
when: evolinux_system_locales and default_locales is changed
- name: Setting default timezone
timezone:
@ -34,7 +34,7 @@
# non-interactively (like tzdata ↑)
- include_role:
name: remount-usr
name: evolix/remount-usr
- name: Ensure automagic vim conf is disabled
lineinfile:
@ -84,13 +84,20 @@
#- name: Customizing /etc/fstab
- name: Check if cron is installed
shell: "dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'"
failed_when: False
changed_when: False
check_mode: no
register: is_cron_installed
- name: Set verbose logging for cron deamon
lineinfile:
dest: /etc/default/cron
line: "EXTRA_OPTS='-L 15'"
create: yes
state: present
when: evolinux_system_cron_verboselog
when: is_cron_installed.rc == 0 and evolinux_system_cron_verboselog
- name: Modify default umask for cron deamon
lineinfile:
@ -98,7 +105,7 @@
line: "umask 022"
create: yes
state: present
when: evolinux_system_cron_umask
when: is_cron_installed.rc == 0 and evolinux_system_cron_umask
- name: Randomize periodic crontabs
replace:
@ -110,10 +117,10 @@
- { regexp: '^25\s*6((\s*\*){3})', replace: '{{ 59|random(start=1) }} {{ [0,1,3,4,5,6,7]|random }}\1' }
- { regexp: '^47\s*6((\s*\*){2}\s*7)', replace: '{{ 59|random(start=1) }} {{ [0,1,3,4,5,6,7]|random }}\1' }
- { regexp: '^52\s*6(\s*1(\s*\*){2})', replace: '{{ 59|random(start=1) }} {{ [0,1,3,4,5,6,7]|random }}\1' }
when: evolinux_system_cron_random
when: is_cron_installed.rc == 0 and evolinux_system_cron_random
- include_role:
name: ntpd
name: evolix/ntpd
## alert5
@ -146,17 +153,17 @@
mode: "0755"
when:
- evolinux_system_alert5_init
- ansible_distribution_major_version | version_compare('10', '>=')
- ansible_distribution_major_version is version('10', '>=')
- name: Install alert5 service (buster)
copy:
src: alert5.service
dest: /etc/systemd/system/alert5.service
force: yes
mode: "0755"
mode: "0644"
when:
- evolinux_system_alert5_init
- ansible_distribution_major_version | version_compare('10', '>=')
- ansible_distribution_major_version is version('10', '>=')
- name: Enable alert5 init script (buster)
systemd:
@ -166,7 +173,7 @@
when:
- evolinux_system_alert5_init
- evolinux_system_alert5_enable
- ansible_distribution_major_version | version_compare('10', '>=')
- ansible_distribution_major_version is version('10', '>=')
## network interfaces
@ -184,4 +191,15 @@
replace: "auto"
when: evolinux_system_eni_auto and grep_hotplug_eni.rc == 0
## /sbin/deny
- name: "/sbin/deny script is present"
copy:
src: deny.sh
dest: /sbin/deny
mode: "0700"
owner: root
group: root
force: no
- meta: flush_handlers

View File

@ -20,7 +20,7 @@ PIDFILE=/var/run/$NAME.pid
STATUSFILE=/var/run/$NAME.status
SCRIPTNAME=/etc/init.d/$NAME
MAILTO="{{ raid_alert_email or general_alert_email | mandatory }}" # Where to report problems
MAILTO="root" # Where to report problems
PERIOD=600 # Seconds between each check (default 10 minutes)
REMIND=86400 # Seconds between each reminder (default 2 hours)
RUN_DAEMON=yes

View File

@ -8,7 +8,11 @@ notifempty
delaycompress
compress
postrotate
{% if ansible_distribution_major_version is version('10', '>=') %}
/usr/lib/rsyslog/rsyslog-rotate
{% else %}
invoke-rc.d rsyslog rotate > /dev/null
{% endif %}
endscript
/var/log/daemon.log
@ -32,4 +36,4 @@ endscript
{
daily
rotate 365
}
}

Some files were not shown because too many files have changed in this diff Show More