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/ .kitchen/
.kateproject.d .kateproject.d
.vagrant/ .vagrant/
*.swp

View File

@ -16,8 +16,120 @@ The **patch** part changes incrementally at each release.
### Fixed ### Fixed
### Removed
### Security ### 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 ## [9.10.1] - 2019-06-21
### Changed ### Changed

View File

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

View File

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

View File

@ -10,10 +10,10 @@
tasks: tasks:
- include_role: - include_role:
name: amazon-ec2 name: evolix/amazon-ec2
tasks_from: setup.yml tasks_from: setup.yml
- include_role: - include_role:
name: amazon-ec2 name: evolix/amazon-ec2
tasks_from: create-instance.yml tasks_from: create-instance.yml
- name: Install Evolinux - name: Install Evolinux
@ -52,11 +52,11 @@
post_tasks: post_tasks:
- include_role: - include_role:
name: etc-git name: evolix/etc-git
tasks_from: commit.yml tasks_from: commit.yml
vars: vars:
commit_message: "Ansible post-run Evolinux playbook" commit_message: "Ansible post-run Evolinux playbook"
- include_role: - include_role:
name: evocheck name: evolix/evocheck
tasks_from: exec.yml 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` TS=`date +%Y%m%d%H%M%S`
FILE="${DIR}/${TS}.html" FILE="${DIR}/${TS}.html"
mkdir -p "${DIR}" if [ ! -d "${DIR}" ]; then
mkdir -p "${DIR}"
wget -q -O "${FILE}" "${URL}" chown root:adm "${DIR}"
chmod 750 "${DIR}"
fi
wget -q -U "save_apache_status" -O "${FILE}" "${URL}"
chmod 640 "${FILE}" chmod 640 "${FILE}"
chown root:adm "${FILE}"
find "${DIR}" -type f -mtime +1 -delete find "${DIR}" -type f -mtime +1 -delete

View File

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

View File

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

View File

@ -43,6 +43,7 @@
RewriteEngine on RewriteEngine on
# Redirect to HTTPS, execpt for munin, because some plugins # Redirect to HTTPS, execpt for munin, because some plugins
# can't handle HTTPS! :( # can't handle HTTPS! :(
RewriteCond %{REQUEST_URI} !^/.well-known.*$ [NC] [OR]
RewriteCond %{REQUEST_URI} !^/server-status.*$ [NC] [OR] RewriteCond %{REQUEST_URI} !^/server-status.*$ [NC] [OR]
RewriteCond %{REQUEST_URI} !^/munin_opcache.php$ [NC] RewriteCond %{REQUEST_URI} !^/munin_opcache.php$ [NC]
RewriteRule ^/(.*) https://{{ ansible_fqdn }}/$1 [L,R=permanent] RewriteRule ^/(.*) https://{{ ansible_fqdn }}/$1 [L,R=permanent]
@ -107,6 +108,15 @@
Require all denied Require all denied
Include /etc/apache2/ipaddr_whitelist.conf Include /etc/apache2/ipaddr_whitelist.conf
</Directory> </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 # BEGIN phpMyAdmin section
# END 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 - name: Apt update
apt: apt:
update_cache: yes 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: tags:
- apt - apt

View File

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

View File

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

View File

@ -1,10 +1,19 @@
--- ---
- name: "hold packages (apt)" - 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 register: apt_mark
changed_when: "'{{ item }} set on hold.' in apt_mark.stdout" changed_when: "item + ' set on hold.' in apt_mark.stdout"
with_items: "{{ apt_hold_packages }}" 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: tags:
- apt - apt
@ -14,15 +23,16 @@
line: "{{ item }}" line: "{{ item }}"
create: True create: True
state: present state: present
with_items: "{{ apt_hold_packages }}" loop: "{{ apt_hold_packages }}"
tags: tags:
- apt - apt
- name: "unhold packages (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 register: apt_mark
changed_when: "'Canceled hold on {{ item }}.' in apt_mark.stdout" changed_when: "'Canceled hold on' + item in apt_mark.stdout"
with_items: "{{ apt_unhold_packages }}" failed_when: apt_mark.rc != 0 and not apt_mark.stdout = ''
loop: "{{ apt_unhold_packages }}"
tags: tags:
- apt - apt
@ -32,7 +42,7 @@
line: "{{ item }}" line: "{{ item }}"
create: True create: True
state: absent state: absent
with_items: "{{ apt_unhold_packages }}" loop: "{{ apt_unhold_packages }}"
tags: tags:
- apt - apt
@ -55,6 +65,15 @@
tags: tags:
- apt - 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) - name: Check for held packages (script)
cron: cron:
cron_file: apt-hold-packages cron_file: apt-hold-packages
@ -67,5 +86,6 @@
day: "{{ apt_check_hold_cron_day }}" day: "{{ apt_check_hold_cron_day }}"
month: "{{ apt_check_hold_cron_month }}" month: "{{ apt_check_hold_cron_month }}"
state: "present" state: "present"
when: is_cron.rc == 0
tags: tags:
- apt - apt

View File

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

View File

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

View File

@ -8,9 +8,8 @@
tags: tags:
- bind - bind
- munin - munin
when: bind_authoritative_server
- name: Enable munin plugins - name: Enable munin plugins for authoritative server
file: file:
src: "/usr/share/munin/plugins/{{ item }}" src: "/usr/share/munin/plugins/{{ item }}"
dest: "/etc/munin/plugins/{{ item }}" dest: "/etc/munin/plugins/{{ item }}"
@ -19,7 +18,25 @@
- bind9 - bind9
- bind9_rndc - bind9_rndc
notify: restart munin-node 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: tags:
- bind - bind
- munin - munin
@ -33,7 +50,7 @@
mode: "0644" mode: "0644"
force: yes force: yes
notify: restart munin-node notify: restart munin-node
when: bind_authoritative_server and munin_node_plugins_config.stat.exists when: munin_node_plugins_config.stat.exists
tags: tags:
- bind - bind
- munin - 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 weekly
missingok missingok
rotate 52 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*] [bind*]
user root 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 env.MUNIN_PLUGSTATE /var/lib/munin
timeout 120 timeout 120

View File

@ -4,11 +4,11 @@ acl "foo" {
}; };
options { options {
directory "/var/cache/bind"; directory "{{ bind_cache_dir }}";
version "Bingo"; version "Bingo";
auth-nxdomain no; auth-nxdomain no;
masterfile-format text; masterfile-format text;
statistics-file "/var/run/named.stats"; statistics-file "{{ bind_statistics_file }}";
listen-on-v6 { any; }; listen-on-v6 { any; };
listen-on { any; }; listen-on { any; };
@ -23,11 +23,11 @@ logging {
category queries { query_logging; }; category queries { query_logging; };
channel default_file { channel default_file {
file "/var/log/bind.log"; file "{{ bind_log_file }}";
severity info; severity info;
}; };
channel query_logging { 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-category yes;
print-severity yes; print-severity yes;
print-time yes; print-time yes;

View File

@ -1,5 +1,5 @@
options { options {
directory "/var/cache/bind"; directory "{{ bind_cache_dir }}";
version "Bingo"; version "Bingo";
auth-nxdomain no; auth-nxdomain no;
listen-on-v6 { ::1; }; listen-on-v6 { ::1; };
@ -8,9 +8,17 @@ options {
}; };
logging { logging {
category default { default_file; }; category default { default_file; };
channel default_file { category queries { query_logging; };
file "/var/log/bind.log";
severity info; 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: dependencies:
- { role: amavis } - { role: evolix/amavis }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,9 +1,8 @@
- name: Install dependency - name: Install dependency
apt: apt:
name: "{{ item }}" name:
with_items: - drbd-utils
- drbd-utils - lvm2
- lvm2
tags: tags:
- drbd - 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_jvm_xmx`: maximum heap size reserved for the JVM (default: `2g`).
* `elasticsearch_restart_on_upgrade`: restart the service after package upgrade (default: `true`) * `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 ## Curator

View File

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

View File

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

View File

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

View File

@ -1,44 +1,46 @@
--- ---
- block: - name: Set real datadir value when customized
- name: "Is custom datadir present ?" block:
stat: - name: "Is custom datadir present ?"
path: "{{ elasticsearch_custom_datadir }}" stat:
register: elasticsearch_custom_datadir_test path: "{{ elasticsearch_custom_datadir }}"
check_mode: no register: elasticsearch_custom_datadir_test
check_mode: no
- name: "read the real datadir" - name: "read the real datadir"
command: readlink -f /var/lib/elasticsearch command: readlink -f /var/lib/elasticsearch
changed_when: false changed_when: false
register: elasticsearch_current_real_datadir_test register: elasticsearch_current_real_datadir_test
check_mode: no check_mode: no
tags: tags:
- elasticsearch - elasticsearch
when: when:
- elasticsearch_custom_datadir != '' - elasticsearch_custom_datadir != ''
- elasticsearch_custom_datadir != None - elasticsearch_custom_datadir != None
- block: - name: Datadir is moved to custom path
- name: elasticsearch is stopped block:
service: - name: elasticsearch is stopped
name: elasticsearch service:
state: stopped name: elasticsearch
state: stopped
- name: Move elasticsearch datadir to custom datadir - name: Move elasticsearch datadir to custom datadir
command: mv {{ elasticsearch_current_real_datadir_test.stdout }} {{ elasticsearch_custom_datadir }} command: mv {{ elasticsearch_current_real_datadir_test.stdout }} {{ elasticsearch_custom_datadir }}
args: args:
creates: "{{ elasticsearch_custom_datadir }}" creates: "{{ elasticsearch_custom_datadir }}"
- name: Symlink {{ elasticsearch_custom_datadir }} to /var/lib/elasticsearch - name: Symlink {{ elasticsearch_custom_datadir }} to /var/lib/elasticsearch
file: file:
src: "{{ elasticsearch_custom_datadir }}" src: "{{ elasticsearch_custom_datadir }}"
dest: '/var/lib/elasticsearch' dest: '/var/lib/elasticsearch'
state: link state: link
- name: elasticsearch is started - name: elasticsearch is started
service: service:
name: elasticsearch name: elasticsearch
state: started state: started
tags: tags:
- elasticsearch - elasticsearch
when: 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" - name: "log rotation script"
template: template:
src: rotate_elasticsearch_logs.j2 src: rotate_elasticsearch_logs.j2
@ -7,3 +13,4 @@
owner: root owner: root
group: root group: root
mode: "0750" mode: "0750"
when: is_cron_installed.rc == 0

View File

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

View File

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

View File

@ -31,7 +31,7 @@
- name: "set commit author" - name: "set commit author"
set_fact: set_fact:
commit_author: '{% if ansible_env.SUDO_USER is not defined %}root{% else %}{{ ansible_env.SUDO_USER }}{% endif %}' 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: tags:
- etc-git - etc-git
- commit-etc - commit-etc
@ -41,7 +41,9 @@
args: args:
chdir: /etc chdir: /etc
register: etc_commit_end_run 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 ignore_errors: yes
tags: tags:
- etc-git - etc-git

View File

@ -7,80 +7,37 @@
tags: tags:
- etc-git - etc-git
- name: /etc is versioned with git - include: repository.yml
command: "git init ." vars:
args: repository_path: "/etc"
chdir: /etc gitignore_items:
creates: /etc/.git/ - "aliases.db"
warn: no - "*.swp"
register: git_init - "postfix/sa-blacklist.access"
tags: - "postfix/*.db"
- etc-git - "postfix/spamd.cidr"
- "evobackup/.keep-*"
- "letsencrypt/.certbot.lock"
- name: Git user.email is configured - name: verify /usr/share/scripts presence
git_config: stat:
name: user.email path: /usr/share/scripts
repo: /etc register: _usr_share_scripts
scope: local
value: "root@{{ ansible_fqdn | default('localhost') }}"
tags:
- etc-git
- name: /etc/.git is restricted to root - include: repository.yml
file: vars:
path: /etc/.git repository_path: "/usr/share/scripts"
owner: root gitignore_items: []
mode: "0700" when:
state: directory - _usr_share_scripts.stat.isdir
tags: - ansible_distribution_major_version is version('10', '>=')
- etc-git
- name: /etc/.gitignore is present - name: Check if cron is installed
copy: shell: "dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'"
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
failed_when: False failed_when: False
register: git_log changed_when: False
check_mode: no check_mode: no
tags: register: is_cron_installed
- 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
- name: Optimize script is installed in monthly crontab - name: Optimize script is installed in monthly crontab
copy: copy:
@ -88,6 +45,7 @@
dest: /etc/cron.monthly/optimize-etc-git dest: /etc/cron.monthly/optimize-etc-git
mode: "0750" mode: "0750"
force: no force: no
when: is_cron_installed.rc == 0
tags: tags:
- etc-git - etc-git
@ -96,7 +54,7 @@
src: etc-git-status.j2 src: etc-git-status.j2
dest: /etc/cron.d/etc-git-status dest: /etc/cron.d/etc-git-status
mode: "0644" mode: "0644"
when: etc_git_monitor_status when: is_cron_installed.rc == 0 and etc_git_monitor_status
tags: tags:
- etc-git - etc-git
@ -104,6 +62,6 @@
file: file:
dest: /etc/cron.d/etc-git-status dest: /etc/cron.d/etc-git-status
state: absent state: absent
when: not etc_git_monitor_status when: is_cron_installed.rc == 0 and not etc_git_monitor_status
tags: tags:
- etc-git - 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 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/) Shell scripts are copied from the upstream repository after each release.
No changes must be applied directly here ; patch upstream, release then copy here.
Evoacme is open source software licensed under the AGPLv3 License.
## Install ## Install
@ -21,7 +20,7 @@ Evoacme is open source software licensed under the AGPLv3 License.
### 2 - Install evoacme prerequisite with ansible ### 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 ### 3 - Include letsencrypt.conf in your webserver

View File

@ -10,17 +10,33 @@
set -e set -e
set -u 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 cat <<EOT
Usage: ${PROGNAME} NAME Usage: ${PROGNAME} NAME
NAME must be correspond to : NAME must be correspond to :
- a CSR in ${CSR_DIR}/NAME.csr - a CSR in ${CSR_DIR}/NAME.csr
- a KEY in ${SSL_KEY_DIR}/NAME.key - a KEY in ${SSL_KEY_DIR}/NAME.key
If env variable TEST=1, certbot is run in staging mode 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 DRY_RUN=1, certbot is run in dry-run mode
If env variable QUIET=1, no message is output If env variable QUIET=1, no message is output
If env variable VERBOSE=1, debug messages are output If env variable VERBOSE=1, debug messages are output
EOT EOT
} }
@ -36,7 +52,7 @@ debug() {
} }
error() { error() {
>&2 echo "${PROGNAME}: $1" >&2 echo "${PROGNAME}: $1"
[ "$1" = "invalid argument(s)" ] && >&2 usage [ "$1" = "invalid argument(s)" ] && >&2 show_help
exit 1 exit 1
} }
@ -75,7 +91,7 @@ sed_cert_path_for_nginx() {
sed -i "s~${search}~${replace}~" "${vhost_full_path}" sed -i "s~${search}~${replace}~" "${vhost_full_path}"
debug "Config in ${vhost_full_path} has been updated" debug "Config in ${vhost_full_path} has been updated"
$(command -v nginx) -t 2>/dev/null $(command -v nginx) -t 2>/dev/null
[ "${?}" -eq 0 ] || $(command -v nginx) -t [ "${?}" -eq 0 ] || $(command -v nginx) -t -q
fi fi
} }
x509_verify() { x509_verify() {
@ -98,7 +114,8 @@ main() {
# check arguments # check arguments
[ "$#" -eq 1 ] || error "invalid argument(s)" [ "$#" -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}" mkdir -p "${ACME_DIR}"
chown acme: "${ACME_DIR}" chown acme: "${ACME_DIR}"
@ -287,6 +304,8 @@ readonly QUIET=${QUIET:-"0"}
readonly TEST=${TEST:-"0"} readonly TEST=${TEST:-"0"}
readonly DRY_RUN=${DRY_RUN:-"0"} readonly DRY_RUN=${DRY_RUN:-"0"}
readonly VERSION="19.11"
# Read configuration file, if it exists # Read configuration file, if it exists
[ -r /etc/default/evoacme ] && . /etc/default/evoacme [ -r /etc/default/evoacme ] && . /etc/default/evoacme

View File

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

View File

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

View File

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

View File

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

View File

@ -9,27 +9,52 @@
set -u set -u
usage() { show_version() {
cat <<EOT cat <<END
Usage: ${PROGNAME} VHOST DOMAIN... make-csr version ${VERSION}
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 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 EOT
} }
log() {
if [ "${QUIET}" != "1" ]; then
echo "${PROGNAME}: $1"
fi
}
debug() { debug() {
if [ "${VERBOSE}" = 1 ]; then if [ "${VERBOSE}" = "1" ] && [ "${QUIET}" != "1" ]; then
>&2 echo "${PROGNAME}: $1" >&2 echo "${PROGNAME}: $1"
fi fi
} }
error() { error() {
>&2 echo "${PROGNAME}: $1" >&2 echo "${PROGNAME}: $1"
[ "$1" = "invalid argument(s)" ] && >&2 show_help
exit 1 exit 1
} }
@ -173,13 +198,15 @@ EOF
} }
main() { 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 if [ -t 0 ]; then
# We have STDIN, so we should have at least 2 arguments # We have STDIN, so we should have 2 arguments
if [ "$#" -lt 2 ]; then [ "$#" -eq 2 ] || error "invalid argument(s)"
>&2 echo "invalid arguments"
>&2 usage
exit 1
fi
# read VHOST from first argument # read VHOST from first argument
VHOST="$1" VHOST="$1"
# remove the first argument # remove the first argument
@ -187,12 +214,9 @@ main() {
# read domains from remaining arguments # read domains from remaining arguments
DOMAINS=$@ DOMAINS=$@
else else
# We don't have STDIN, so we should have only 1 argument # We don't have STDIN, so we should have 1 argument
if [ "$#" != 1 ]; then [ "$#" -eq 1 ] || error "invalid argument(s)"
>&2 echo "invalid arguments"
>&2 usage
exit 1
fi
# read VHOST from first argument # read VHOST from first argument
VHOST="$1" VHOST="$1"
# read domains from input # read domains from input
@ -239,6 +263,9 @@ readonly PROGDIR=$(realpath -m $(dirname "$0"))
readonly ARGS=$@ readonly ARGS=$@
readonly VERBOSE=${VERBOSE:-"0"} readonly VERBOSE=${VERBOSE:-"0"}
readonly QUIET=${QUIET:-"0"}
readonly VERSION="19.11"
# Read configuration file, if it exists # Read configuration file, if it exists
[ -r /etc/default/evoacme ] && . /etc/default/evoacme [ -r /etc/default/evoacme ] && . /etc/default/evoacme

View File

@ -9,27 +9,50 @@
set -u 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 cat <<EOT
Usage: ${PROGNAME} VHOST Usage: ${PROGNAME} VHOST
VHOST must correspond to an Apache or Nginx enabled VHost VHOST must correspond to an Apache or Nginx enabled VHost
If VHOST ends with ".conf" it is stripped, If VHOST ends with ".conf" it is stripped,
then files are seached at those paths: then files are seached at those paths:
- /etc/apache2/sites-enables/VHOST.conf - /etc/apache2/sites-enables/VHOST.conf
- /etc/nginx/sites-enabled/VHOST.conf - /etc/nginx/sites-enabled/VHOST.conf
- /etc/nginx/sites-enabled/VHOST - /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 EOT
} }
log() {
if [ "${QUIET}" != "1" ]; then
echo "${PROGNAME}: $1"
fi
}
debug() { debug() {
if [ "${VERBOSE}" = 1 ]; then if [ "${VERBOSE}" = "1" ] && [ "${QUIET}" != "1" ]; then
>&2 echo "${PROGNAME}: $1" >&2 echo "${PROGNAME}: $1"
fi fi
} }
error() { error() {
>&2 echo "${PROGNAME}: $1" >&2 echo "${PROGNAME}: $1"
[ "$1" = "invalid argument(s)" ] && >&2 show_help
exit 1 exit 1
} }
@ -118,14 +141,11 @@ first_vhost_file_found() {
} }
main() { main() {
if [ "$#" != 1 ]; then # check arguments
>&2 usage [ "$#" -eq 1 ] || error "invalid argument(s)"
exit 1
fi [ "$1" = "-h" ] || [ "$1" = "--help" ] && show_help && exit 0
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then [ "$1" = "-V" ] || [ "$1" = "--version" ] && show_version && exit 0
usage
exit 0
fi
local vhost_name=$(basename "$1" .conf) local vhost_name=$(basename "$1" .conf)
local vhost_file=$(first_vhost_file_found "${vhost_name}") local vhost_file=$(first_vhost_file_found "${vhost_name}")
@ -148,6 +168,10 @@ readonly PROGDIR=$(realpath -m $(dirname "$0"))
readonly ARGS=$@ readonly ARGS=$@
readonly VERBOSE=${VERBOSE:-"0"} readonly VERBOSE=${VERBOSE:-"0"}
readonly QUIET=${QUIET:-"0"}
readonly VERSION="19.11"
readonly SRV_IP=${SRV_IP:-""} readonly SRV_IP=${SRV_IP:-""}
main $ARGS main $ARGS

View File

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

View File

@ -3,7 +3,7 @@
- fail: - fail:
msg: only compatible with Debian >= 8 msg: only compatible with Debian >= 8
when: 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 - include: certbot.yml

View File

@ -1,5 +1,5 @@
location ~ /.well-known/acme-challenge { 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 }}/; alias {{ evoacme_acme_dir }}/;
{% else %} {% else %}
alias {{ evoacme_acme_dir }}/.well-known/acme-challenge; 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: - include_role:
name: evocheck name: evolix/evocheck
tasks_from: exec.yml tasks_from: exec.yml
``` ```
## Variables ## Variables

View File

@ -4,6 +4,8 @@
# Script to verify compliance of a Debian/OpenBSD server # Script to verify compliance of a Debian/OpenBSD server
# powered by Evolix # powered by Evolix
readonly VERSION="20.04.3"
# base functions # base functions
show_version() { show_version() {
@ -59,6 +61,7 @@ detect_os() {
7) DEBIAN_RELEASE="wheezy";; 7) DEBIAN_RELEASE="wheezy";;
8) DEBIAN_RELEASE="jessie";; 8) DEBIAN_RELEASE="jessie";;
9) DEBIAN_RELEASE="stretch";; 9) DEBIAN_RELEASE="stretch";;
10) DEBIAN_RELEASE="buster";;
esac esac
fi fi
elif [ "$(uname -s)" = "OpenBSD" ]; then elif [ "$(uname -s)" = "OpenBSD" ]; then
@ -85,6 +88,9 @@ is_debian_jessie() {
is_debian_stretch() { is_debian_stretch() {
test "${DEBIAN_RELEASE}" = "stretch" test "${DEBIAN_RELEASE}" = "stretch"
} }
is_debian_buster() {
test "${DEBIAN_RELEASE}" = "buster"
}
debian_release() { debian_release() {
printf "%s" "${DEBIAN_RELEASE}" printf "%s" "${DEBIAN_RELEASE}"
} }
@ -159,7 +165,7 @@ check_dpkgwarning() {
test -e /etc/apt/apt.conf \ test -e /etc/apt/apt.conf \
&& failed "IS_DPKGWARNING" "/etc/apt/apt.conf is missing" && failed "IS_DPKGWARNING" "/etc/apt/apt.conf is missing"
fi fi
elif is_debian_stretch; then elif is_debian_stretch || is_debian_buster; then
test -e /etc/apt/apt.conf.d/z-evolinux.conf \ test -e /etc/apt/apt.conf.d/z-evolinux.conf \
|| failed "IS_DPKGWARNING" "/etc/apt/apt.conf.d/z-evolinux.conf is missing" || failed "IS_DPKGWARNING" "/etc/apt/apt.conf.d/z-evolinux.conf is missing"
fi fi
@ -196,7 +202,7 @@ check_modsecurity() {
fi fi
} }
check_customsudoers() { 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() { check_vartmpfs() {
df /var/tmp | grep -q tmpfs || failed "IS_VARTMPFS" "/var/tmp is not a tmpfs" 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" is_installed serveur-base || failed "IS_SERVEURBASE" "serveur-base package is not installed"
} }
check_logrotateconf() { 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() { check_syslogconf() {
grep -q "^# Syslog for Pack Evolix serveur" /etc/*syslog.conf \ grep -q "^# Syslog for Pack Evolix serveur" /etc/*syslog.conf \
|| failed "IS_SYSLOGCONF" || failed "IS_SYSLOGCONF" "syslog evolix config file missing"
} }
check_debiansecurity() { check_debiansecurity() {
grep -q "^deb.*security" /etc/apt/sources.list \ grep -q "^deb.*security" /etc/apt/sources.list \
|| failed "IS_DEBIANSECURITY" || failed "IS_DEBIANSECURITY" "missing debian security repository"
} }
check_aptitudeonly() { check_aptitudeonly() {
if is_debian_squeeze || is_debian_wheezy; then 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 fi
} }
check_aptitude() { check_aptitude() {
if is_debian_jessie || is_debian_stretch; then if is_debian_jessie || is_debian_stretch || is_debian_buster; then
test -e /usr/bin/aptitude && failed "IS_APTITUDE" test -e /usr/bin/aptitude && failed "IS_APTITUDE" "aptitude may not be installed on Debian >=8"
fi fi
} }
check_aptgetbak() { check_aptgetbak() {
if is_debian_jessie || is_debian_stretch; then if is_debian_jessie || is_debian_stretch || is_debian_buster; then
test -e /usr/bin/apt-get.bak && failed "IS_APTGETBAK" test -e /usr/bin/apt-get.bak && failed "IS_APTGETBAK" "missing dpkg-divert apt-get.bak"
fi fi
} }
check_apticron() { check_apticron() {
@ -240,28 +247,35 @@ check_apticron() {
test "$status" = "fail" || test -e /usr/bin/apt-get.bak || status="fail" test "$status" = "fail" || test -e /usr/bin/apt-get.bak || status="fail"
if is_debian_squeeze || is_debian_wheezy; then 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 fi
} }
check_usrro() { 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() { 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() { check_mountfstab() {
# Test if lsblk available, if not skip this test... # Test if lsblk available, if not skip this test...
LSBLK_BIN=$(command -v lsblk) LSBLK_BIN=$(command -v lsblk)
if test -x "${LSBLK_BIN}"; then if test -x "${LSBLK_BIN}"; then
for mountPoint in $(${LSBLK_BIN} -o MOUNTPOINT -l -n | grep '/'); do 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 done
fi fi
} }
check_listchangesconf() { check_listchangesconf() {
if is_debian_stretch; then if is_debian_stretch || is_debian_buster; then
if is_installed apt-listchanges; 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 fi
else else
if [ -e "/etc/apt/listchanges.conf" ]; then if [ -e "/etc/apt/listchanges.conf" ]; then
@ -276,72 +290,86 @@ check_listchangesconf() {
} }
check_customcrontab() { check_customcrontab() {
found_lines=$(grep -c -E "^(17 \*|25 6|47 6|52 6)" /etc/crontab) 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() { 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() { 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() { check_tmoutprofile() {
grep -sq "TMOUT=" /etc/profile /etc/profile.d/evolinux.sh || failed "IS_TMOUTPROFILE" "TMOUT is not set" grep -sq "TMOUT=" /etc/profile /etc/profile.d/evolinux.sh || failed "IS_TMOUTPROFILE" "TMOUT is not set"
} }
check_alert5boot() { check_alert5boot() {
if [ -n "$(find /etc/rc2.d/ -name 'S*alert5')" ]; then if is_debian_buster; then
grep -q "^date" /etc/rc2.d/S*alert5 || failed "IS_ALERT5BOOT" "boot mail is not sent by alert5 init script" 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 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 fi
} }
check_alert5minifw() { check_alert5minifw() {
if [ -n "$(find /etc/rc2.d/ -name 'S*alert5')" ]; then if is_debian_buster; then
grep -q "^/etc/init.d/minifirewall" /etc/rc2.d/S*alert5 \ grep -qs "^/etc/init.d/minifirewall" /usr/share/scripts/alert5.sh \
|| failed "IS_ALERT5MINIFW" "Minifirewall is not started by alert5 init script" || failed "IS_ALERT5MINIFW" "Minifirewall is not started by alert5 script or script is missing"
else 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 fi
} }
check_minifw() { 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*$" \ /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() { check_nrpeperms() {
if [ -d /etc/nagios ]; then if [ -d /etc/nagios ]; then
actual=$(stat --format "%a" /etc/nagios) nagiosDir="/etc/nagios"
actual=$(stat --format "%a" $nagiosDir)
expected="750" expected="750"
test "$expected" = "$actual" || failed "IS_NRPEPERMS" test "$expected" = "$actual" || failed "IS_NRPEPERMS" "${nagiosDir} must be ${expected}"
fi fi
} }
check_minifwperms() { check_minifwperms() {
if [ -f "$MINIFW_FILE" ]; then if [ -f "$MINIFW_FILE" ]; then
actual=$(stat --format "%a" "$MINIFW_FILE") actual=$(stat --format "%a" "$MINIFW_FILE")
expected="600" expected="600"
test "$expected" = "$actual" || failed "IS_MINIFWPERMS" test "$expected" = "$actual" || failed "IS_MINIFWPERMS" "${MINIFW_FILE} must be ${expected}"
fi fi
} }
check_nrpedisks() { 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) 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)") 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() { check_nrpepid() {
if ! is_debian_squeeze; then if ! is_debian_squeeze; then
{ test -e /etc/nagios/nrpe.cfg \ { test -e /etc/nagios/nrpe.cfg \
&& grep -q "^pid_file=/var/run/nagios/nrpe.pid" /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 fi
} }
check_grsecprocs() { check_grsecprocs() {
if uname -a | grep -q grsec; then if uname -a | grep -q grsec; then
{ grep -q "^command.check_total_procs..sudo" /etc/nagios/nrpe.cfg \ { 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"; && 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 fi
} }
check_apachemunin() { check_apachemunin() {
if test -e /etc/apache2/apache2.conf; then 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/apache2/mods-enabled/status.load \
&& test -h /etc/munin/plugins/apache_accesses \ && test -h /etc/munin/plugins/apache_accesses \
&& test -h /etc/munin/plugins/apache_processes \ && test -h /etc/munin/plugins/apache_processes \
@ -381,25 +409,26 @@ check_raidsoft() {
{ grep -q "^AUTOCHECK=true" /etc/default/mdadm \ { grep -q "^AUTOCHECK=true" /etc/default/mdadm \
&& grep -q "^START_DAEMON=true" /etc/default/mdadm \ && grep -q "^START_DAEMON=true" /etc/default/mdadm \
&& grep -qv "^MAILADDR ___MAIL___" /etc/mdadm/mdadm.conf; && grep -qv "^MAILADDR ___MAIL___" /etc/mdadm/mdadm.conf;
} || failed "IS_RAIDSOFT" } || failed "IS_RAIDSOFT" "missing or wrong config for mdadm"
fi fi
} }
# Verification du LogFormat de AWStats # Verification du LogFormat de AWStats
check_awstatslogformat() { check_awstatslogformat() {
if is_installed apache2 awstats; then if is_installed apache2 awstats; then
grep -qE '^LogFormat=1' /etc/awstats/awstats.conf.local \ awstatsFile="/etc/awstats/awstats.conf.local"
|| failed "IS_AWSTATSLOGFORMAT" grep -qE '^LogFormat=1' $awstatsFile \
|| failed "IS_AWSTATSLOGFORMAT" "missing or wrong LogFormat directive in $awstatsFile"
fi fi
} }
# Verification de la présence de la config logrotate pour Munin # Verification de la présence de la config logrotate pour Munin
check_muninlogrotate() { check_muninlogrotate() {
{ test -e /etc/logrotate.d/munin-node \ { test -e /etc/logrotate.d/munin-node \
&& test -e /etc/logrotate.d/munin; && 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 # Verification de l'activation de Squid dans le cas d'un pack mail
check_squid() { check_squid() {
if is_debian_stretch; then if is_debian_stretch || is_debian_buster; then
squidconffile="/etc/squid/evolinux-custom.conf" squidconffile="/etc/squid/evolinux-custom.conf"
else else
squidconffile="/etc/squid*/squid.conf" squidconffile="/etc/squid*/squid.conf"
@ -407,19 +436,20 @@ check_squid() {
if is_pack_web && (is_installed squid || is_installed squid3); then if is_pack_web && (is_installed squid || is_installed squid3); then
host=$(hostname -i) host=$(hostname -i)
# shellcheck disable=SC2086 # 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 -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 $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 -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"; && 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 fi
} }
check_evomaintenance_fw() { check_evomaintenance_fw() {
if [ -f "$MINIFW_FILE" ]; then 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") 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 if [ "$hook_db" = "1" ] && [ "$rulesNumber" -lt 2 ]; then
failed "IS_EVOMAINTENANCE_FW" failed "IS_EVOMAINTENANCE_FW" "HOOK_DB is enabled but missing evomaintenance rules in minifirewall"
fi fi
fi fi
} }
@ -430,36 +460,36 @@ check_moddeflate() {
{ test -e $f && grep -q "AddOutputFilterByType DEFLATE text/html text/plain text/xml" $f \ { 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 text/css" $f \
&& grep -q "AddOutputFilterByType DEFLATE application/x-javascript application/javascript" $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 fi
} }
# Verification de la conf log2mail # Verification de la conf log2mail
check_log2mailrunning() { check_log2mailrunning() {
if is_pack_web && is_installed log2mail; then 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 fi
} }
check_log2mailapache() { check_log2mailapache() {
if is_debian_stretch; then if is_debian_stretch || is_debian_buster; then
conf=/etc/log2mail/config/apache conf=/etc/log2mail/config/apache
else else
conf=/etc/log2mail/config/default conf=/etc/log2mail/config/default
fi fi
if is_pack_web && is_installed log2mail; then if is_pack_web && is_installed log2mail; then
grep -s -q "^file = /var/log/apache2/error.log" $conf \ grep -s -q "^file = /var/log/apache2/error.log" $conf \
|| failed "IS_LOG2MAILAPACHE" || failed "IS_LOG2MAILAPACHE" "missing log2mail directive for apache"
fi fi
} }
check_log2mailmysql() { check_log2mailmysql() {
if is_pack_web && is_installed log2mail; then if is_pack_web && is_installed log2mail; then
grep -s -q "^file = /var/log/syslog" /etc/log2mail/config/{default,mysql,mysql.conf} \ 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 fi
} }
check_log2mailsquid() { check_log2mailsquid() {
if is_pack_web && is_installed log2mail; then if is_pack_web && is_installed log2mail; then
grep -s -q "^file = /var/log/squid.*/access.log" /etc/log2mail/config/* \ grep -s -q "^file = /var/log/squid.*/access.log" /etc/log2mail/config/* \
|| failed "IS_LOG2MAILSQUID" || failed "IS_LOG2MAILSQUID" "missing log2mail directive for squid"
fi fi
} }
# Verification si bind est chroote # Verification si bind est chroote
@ -470,7 +500,7 @@ check_bindchroot() {
md5_original=$(md5sum /usr/sbin/named | cut -f 1 -d ' ') md5_original=$(md5sum /usr/sbin/named | cut -f 1 -d ' ')
md5_chrooted=$(md5sum /var/chroot-bind/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 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 fi
else else
failed "IS_BINDCHROOT" "bind process is not chrooted" failed "IS_BINDCHROOT" "bind process is not chrooted"
@ -482,11 +512,11 @@ check_bindchroot() {
check_repvolatile() { check_repvolatile() {
if is_debian_lenny; then if is_debian_lenny; then
grep -qE "^deb http://volatile.debian.org/debian-volatile" /etc/apt/sources.list \ grep -qE "^deb http://volatile.debian.org/debian-volatile" /etc/apt/sources.list \
|| failed "IS_REPVOLATILE" || failed "IS_REPVOLATILE" "missing debian-volatile repository"
fi fi
if is_debian_squeeze; then if is_debian_squeeze; then
grep -qE "^deb.*squeeze-updates" /etc/apt/sources.list \ grep -qE "^deb.*squeeze-updates" /etc/apt/sources.list \
|| failed "IS_REPVOLATILE" || failed "IS_REPVOLATILE" "missing squeeze-updates repository"
fi fi
} }
# /etc/network/interfaces should be present, we don't manage systemd-network yet # /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 # Verify if all if are in auto
check_autoif() { 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" " ") 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 else
interfaces=$(/sbin/ifconfig -s | tail -n +2 | grep -E -v "^(lo|vnet|docker|veth|tun|tap|macvtap)" | cut -d " " -f 1 |tr "\n" " ") 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 # Verification de la mise en place d'evobackup
check_evobackup() { check_evobackup() {
evobackup_found=$(find /etc/cron* -name '*evobackup*' | wc -l) 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 # Verification de la presence du userlogrotate
check_userlogrotate() { check_userlogrotate() {
if is_pack_web; then 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 fi
} }
# Verification de la syntaxe de la conf d'Apache # Verification de la syntaxe de la conf d'Apache
check_apachectl() { check_apachectl() {
if is_installed apache2; then 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 fi
} }
# Check if there is regular files in Apache sites-enabled. # Check if there is regular files in Apache sites-enabled.
@ -559,7 +604,7 @@ check_apacheipinallow() {
| grep -iv "from all" \ | grep -iv "from all" \
| grep -iv "env=" \ | grep -iv "env=" \
| perl -ne 'exit 1 unless (/from( [\da-f:.\/]+)+$/i)' \ | perl -ne 'exit 1 unless (/from( [\da-f:.\/]+)+$/i)' \
|| failed "IS_APACHEIPINALLOW" || failed "IS_APACHEIPINALLOW" "bad (Allow|Deny) directives in apache"
fi fi
} }
# Check if default Apache configuration file for munin is absent (or empty or commented). # 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" muninconf="/etc/apache2/conf-available/munin.conf"
fi fi
if is_installed apache2; then 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 fi
} }
# Verification de la priorité du package samba si les backports sont utilisés # 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 is_debian_lenny && is_pack_samba; then
if grep -qrE "^[^#].*backport" /etc/apt/sources.list{,.d}; 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" ") 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
fi fi
} }
@ -589,7 +635,7 @@ check_kerneluptodate() {
kernel_installed_at=$(date -d "$(ls --full-time -lcrt /boot | tail -n1 | awk '{print $6}')" +%s) kernel_installed_at=$(date -d "$(ls --full-time -lcrt /boot | tail -n1 | awk '{print $6}')" +%s)
last_reboot_at=$(($(date +%s) - $(cut -f1 -d '.' /proc/uptime))) last_reboot_at=$(($(date +%s) - $(cut -f1 -d '.' /proc/uptime)))
if [ "$kernel_installed_at" -gt "$last_reboot_at" ]; then 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
fi fi
} }
@ -599,7 +645,7 @@ check_uptime() {
limit=$(date -d "now - 2 year" +%s) limit=$(date -d "now - 2 year" +%s)
last_reboot_at=$(($(date +%s) - $(cut -f1 -d '.' /proc/uptime))) last_reboot_at=$(($(date +%s) - $(cut -f1 -d '.' /proc/uptime)))
if [ "$limit" -gt "$last_reboot_at" ]; then 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
fi fi
} }
@ -629,9 +675,10 @@ check_muninrunning() {
} }
# Check if files in /home/backup/ are up-to-date # Check if files in /home/backup/ are up-to-date
check_backupuptodate() { check_backupuptodate() {
if [ -d /home/backup/ ]; then backup_dir="/home/backup"
if [ -n "$(ls -A /home/backup/)" ]; then if [ -d "${backup_dir}" ]; then
for file in /home/backup/*; do if [ -n "$(ls -A ${backup_dir})" ]; then
for file in ${backup_dir}/*; do
limit=$(date +"%s" -d "now - 2 day") limit=$(date +"%s" -d "now - 2 day")
updated_at=$(stat -c "%Y" "$file") updated_at=$(stat -c "%Y" "$file")
@ -641,21 +688,24 @@ check_backupuptodate() {
fi fi
done done
else else
failed "IS_BACKUPUPTODATE" "/home/backup/ is empty" failed "IS_BACKUPUPTODATE" "${backup_dir}/ is empty"
fi fi
else else
failed "IS_BACKUPUPTODATE" "/home/backup/ is missing" failed "IS_BACKUPUPTODATE" "${backup_dir}/ is missing"
fi fi
} }
check_etcgit() { 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 if /etc/.git/ has read/write permissions for root only.
check_gitperms() { check_gitperms() {
if test -d /etc/.git; then GIT_DIR="/etc/.git"
if test -d $GIT_DIR; then
expected="700" expected="700"
actual=$(stat -c "%a" /etc/.git/) actual=$(stat -c "%a" $GIT_DIR)
[ "$expected" = "$actual" ] || failed "IS_GITPERMS" [ "$expected" = "$actual" ] || failed "IS_GITPERMS" "$GIT_DIR must be $expected"
fi fi
} }
# Check if no package has been upgraded since $limit. # Check if no package has been upgraded since $limit.
@ -695,6 +745,7 @@ check_notupgraded() {
check_tune2fs_m5() { check_tune2fs_m5() {
min=5 min=5
parts=$(grep -E "ext(3|4)" /proc/mounts | cut -d ' ' -f1 | tr -s '\n' ' ') parts=$(grep -E "ext(3|4)" /proc/mounts | cut -d ' ' -f1 | tr -s '\n' ' ')
FINDMNT_BIN=$(command -v findmnt)
for part in $parts; do for part in $parts; do
blockCount=$(dumpe2fs -h "$part" 2>/dev/null | grep -e "Block count:" | grep -Eo "[0-9]+") blockCount=$(dumpe2fs -h "$part" 2>/dev/null | grep -e "Block count:" | grep -Eo "[0-9]+")
# If buggy partition, skip it. # 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 }") percentage=$(awk "BEGIN { pc=100*${reservedBlockCount}/${blockCount}; i=int(pc); print (pc-i<0.5)?i:i+1 }")
if [ "$percentage" -lt "${min}" ]; then 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 fi
done done
} }
check_evolinuxsudogroup() { check_evolinuxsudogroup() {
if is_debian_stretch; then if is_debian_stretch || is_debian_buster; then
if grep -q "^evolinux-sudo:" /etc/group; then if grep -q "^evolinux-sudo:" /etc/group; then
grep -q '^%evolinux-sudo ALL=(ALL:ALL) ALL' /etc/sudoers.d/evolinux \ grep -qE '^%evolinux-sudo +ALL ?= ?\(ALL:ALL\) ALL' /etc/sudoers.d/evolinux \
|| failed "IS_EVOLINUXSUDOGROUP" || failed "IS_EVOLINUXSUDOGROUP" "missing evolinux-sudo directive in sudoers file"
fi fi
fi fi
} }
check_userinadmgroup() { 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 ',' ' ') users=$(grep "^evolinux-sudo:" /etc/group | awk -F: '{print $4}' | tr ',' ' ')
for user in $users; do for user in $users; do
if ! groups "$user" | grep -q adm; then if ! groups "$user" | grep -q adm; then
@ -731,15 +787,17 @@ check_userinadmgroup() {
fi fi
} }
check_apache2evolinuxconf() { check_apache2evolinuxconf() {
if is_debian_stretch && test -d /etc/apache2; then if is_debian_stretch || is_debian_buster; then
{ test -L /etc/apache2/conf-enabled/z-evolinux-defaults.conf \ if test -d /etc/apache2; then
&& test -L /etc/apache2/conf-enabled/zzz-evolinux-custom.conf \ { test -L /etc/apache2/conf-enabled/z-evolinux-defaults.conf \
&& test -f /etc/apache2/ipaddr_whitelist.conf; && test -L /etc/apache2/conf-enabled/zzz-evolinux-custom.conf \
} || failed "IS_APACHE2EVOLINUXCONF" && test -f /etc/apache2/ipaddr_whitelist.conf;
} || failed "IS_APACHE2EVOLINUXCONF" "missing custom evolinux apache config"
fi
fi fi
} }
check_backportsconf() { check_backportsconf() {
if is_debian_stretch; then if is_debian_stretch || is_debian_buster; then
grep -qsE "^[^#].*backports" /etc/apt/sources.list \ grep -qsE "^[^#].*backports" /etc/apt/sources.list \
&& failed "IS_BACKPORTSCONF" "backports can't be in main sources list" && failed "IS_BACKPORTSCONF" "backports can't be in main sources list"
if grep -qsE "^[^#].*backports" /etc/apt/sources.list.d/*.list; then if grep -qsE "^[^#].*backports" /etc/apt/sources.list.d/*.list; then
@ -749,15 +807,19 @@ check_backportsconf() {
fi fi
} }
check_bind9munin() { check_bind9munin() {
if is_debian_stretch && is_installed bind9; then if is_debian_stretch || is_debian_buster; then
{ test -L /etc/munin/plugins/bind9 \ if is_installed bind9; then
&& test -e /etc/munin/plugin-conf.d/bind9; { test -L /etc/munin/plugins/bind9 \
} || failed "IS_BIND9MUNIN" && test -e /etc/munin/plugin-conf.d/bind9;
} || failed "IS_BIND9MUNIN" "missing bind plugin for munin"
fi
fi fi
} }
check_bind9logrotate() { check_bind9logrotate() {
if is_debian_stretch && is_installed bind9; then if is_debian_stretch || is_debian_buster; then
test -e /etc/logrotate.d/bind9 || failed "IS_BIND9LOGROTATE" if is_installed bind9; then
test -e /etc/logrotate.d/bind9 || failed "IS_BIND9LOGROTATE" "missing bind logrotate file"
fi
fi fi
} }
check_broadcomfirmware() { check_broadcomfirmware() {
@ -766,10 +828,10 @@ check_broadcomfirmware() {
if ${LSPCI_BIN} | grep -q 'NetXtreme II'; then if ${LSPCI_BIN} | grep -q 'NetXtreme II'; then
{ is_installed firmware-bnx2 \ { is_installed firmware-bnx2 \
&& grep -q "^deb http://mirror.evolix.org/debian.* non-free" /etc/apt/sources.list; && 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 fi
else else
failed "IS_BROADCOMFIRMWARE" "lspci is missing" failed "IS_BROADCOMFIRMWARE" "lspci not found in ${PATH}"
fi fi
} }
check_hardwareraidtool() { check_hardwareraidtool() {
@ -784,28 +846,31 @@ check_hardwareraidtool() {
is_installed cciss-vol-status || failed "IS_HARDWARERAIDTOOL" "cciss-vol-status not installed" is_installed cciss-vol-status || failed "IS_HARDWARERAIDTOOL" "cciss-vol-status not installed"
fi fi
else else
failed "IS_HARDWARERAIDTOOL" "lspci is missing" failed "IS_HARDWARERAIDTOOL" "lspci not found in ${PATH}"
fi fi
} }
check_log2mailsystemdunit() { check_log2mailsystemdunit() {
if is_debian_stretch; then if is_debian_stretch || is_debian_buster; then
{ systemctl -q is-active log2mail.service \ systemctl -q is-active log2mail.service \
&& test -f /etc/systemd/system/log2mail.service \ || failed "IS_LOG2MAILSYSTEMDUNIT" "log2mail unit not running"
&& ! test -f /etc/init.d/log2mail; test -f /etc/systemd/system/log2mail.service \
} || failed "IS_LOG2MAILSYSTEMDUNIT" || 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 fi
} }
check_listupgrade() { check_listupgrade() {
{ test -f /etc/cron.d/listupgrade \ test -f /etc/cron.d/listupgrade \
&& test -x /usr/share/scripts/listupgrade.sh; || failed "IS_LISTUPGRADE" "missing listupgrade cron"
} || failed "IS_LISTUPGRADE" test -x /usr/share/scripts/listupgrade.sh \
|| failed "IS_LISTUPGRADE" "missing listupgrade script or not executable"
} }
check_mariadbevolinuxconf() { check_mariadbevolinuxconf() {
if is_debian_stretch; then if is_debian_stretch || is_debian_buster; then
if is_installed mariadb-server; 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/z-evolinux-defaults.cnf \
&& test -f /etc/mysql/mariadb.conf.d/zzz-evolinux-custom.cnf; && test -f /etc/mysql/mariadb.conf.d/zzz-evolinux-custom.cnf;
} || failed "IS_MARIADBEVOLINUXCONF" } || failed "IS_MARIADBEVOLINUXCONF" "missing mariadb custom config"
fi fi
fi fi
} }
@ -862,70 +927,85 @@ check_redis_backup() {
check_elastic_backup() { check_elastic_backup() {
if is_installed elasticsearch; then if is_installed elasticsearch; then
# You could change the default path in /etc/evocheck.cf # 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})" test -d "$ELASTIC_BACKUP_PATH" || failed "IS_ELASTIC_BACKUP" "Elastic snapshot is missing (${ELASTIC_BACKUP_PATH})"
fi fi
} }
check_mariadbsystemdunit() { check_mariadbsystemdunit() {
if is_debian_stretch && is_installed mariadb-server; then if is_debian_stretch || is_debian_buster; then
{ systemctl -q is-active mariadb.service \ if is_installed mariadb-server; then
&& test -f /etc/systemd/system/mariadb.service.d/evolinux.conf; if systemctl -q is-active mariadb.service; then
} || failed "IS_MARIADBSYSTEMDUNIT" test -f /etc/systemd/system/mariadb.service.d/evolinux.conf \
|| failed "IS_MARIADBSYSTEMDUNIT" "missing systemd override for mariadb unit"
fi
fi
fi fi
} }
check_mysqlmunin() { check_mysqlmunin() {
if is_debian_stretch && is_installed mariadb-server; then if is_debian_stretch || is_debian_buster; then
for file in mysql_bytes mysql_queries mysql_slowqueries \ if is_installed mariadb-server; then
mysql_threads mysql_connections mysql_files_tables \ for file in mysql_bytes mysql_queries mysql_slowqueries \
mysql_innodb_bpool mysql_innodb_bpool_act mysql_innodb_io \ mysql_threads mysql_connections mysql_files_tables \
mysql_innodb_log mysql_innodb_rows mysql_innodb_semaphores \ mysql_innodb_bpool mysql_innodb_bpool_act mysql_innodb_io \
mysql_myisam_indexes mysql_qcache mysql_qcache_mem \ mysql_innodb_log mysql_innodb_rows mysql_innodb_semaphores \
mysql_sorts mysql_tmp_tables; do mysql_myisam_indexes mysql_qcache mysql_qcache_mem \
mysql_sorts mysql_tmp_tables; do
if [[ ! -L /etc/munin/plugins/$file ]]; then if [[ ! -L /etc/munin/plugins/$file ]]; then
failed "IS_MYSQLMUNIN" "Munin plugin '$file' is missing" failed "IS_MYSQLMUNIN" "missing munin plugin '$file'"
test "${VERBOSE}" = 1 || break test "${VERBOSE}" = 1 || break
fi fi
done done
fi
fi fi
} }
check_mysqlnrpe() { check_mysqlnrpe() {
if is_debian_stretch && is_installed mariadb-server; then if is_debian_stretch || is_debian_buster; then
nagios_file=~nagios/.my.cnf if is_installed mariadb-server; then
nagios_file=~nagios/.my.cnf
if ! test -f ${nagios_file}; then if ! test -f ${nagios_file}; then
failed "IS_MYSQLNRPE" "${nagios_file} is missing" failed "IS_MYSQLNRPE" "${nagios_file} is missing"
elif [ "$(stat -c %U ${nagios_file})" != "nagios" ] \ elif [ "$(stat -c %U ${nagios_file})" != "nagios" ] \
|| [ "$(stat -c %a ${nagios_file})" != "600" ]; then || [ "$(stat -c %a ${nagios_file})" != "600" ]; then
failed "IS_MYSQLNRPE" "${nagios_file} has wrong permissions" failed "IS_MYSQLNRPE" "${nagios_file} has wrong permissions"
else else
grep -q -F "command[check_mysql]=/usr/lib/nagios/plugins/check_mysql" /etc/nagios/nrpe.d/evolix.cfg \ 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" || failed "IS_MYSQLNRPE" "check_mysql is missing"
fi
fi fi
fi fi
} }
check_phpevolinuxconf() { check_phpevolinuxconf() {
if is_debian_stretch && is_installed php; then if is_debian_stretch || is_debian_buster; then
{ test -f /etc/php/7.0/cli/conf.d/z-evolinux-defaults.ini \ is_debian_stretch && phpVersion="7.0"
&& test -f /etc/php/7.0/cli/conf.d/zzz-evolinux-custom.ini; is_debian_buster && phpVersion="7.3"
} || failed "IS_PHPEVOLINUXCONF" 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 fi
} }
check_squidlogrotate() { check_squidlogrotate() {
if is_debian_stretch && is_installed squid; then if is_debian_stretch || is_debian_buster; then
grep -q monthly /etc/logrotate.d/squid || failed "IS_SQUIDLOGROTATE" if is_installed squid; then
grep -q monthly /etc/logrotate.d/squid \
|| failed "IS_SQUIDLOGROTATE" "missing squid logrotate file"
fi
fi fi
} }
check_squidevolinuxconf() { check_squidevolinuxconf() {
if is_debian_stretch && is_installed squid; then if is_debian_stretch || is_debian_buster; then
{ grep -qs "^CONFIG=/etc/squid/evolinux-defaults.conf$" /etc/default/squid \ if is_installed squid; then
&& test -f /etc/squid/evolinux-defaults.conf \ { grep -qs "^CONFIG=/etc/squid/evolinux-defaults.conf$" /etc/default/squid \
&& test -f /etc/squid/evolinux-whitelist-defaults.conf \ && test -f /etc/squid/evolinux-defaults.conf \
&& test -f /etc/squid/evolinux-whitelist-custom.conf \ && test -f /etc/squid/evolinux-whitelist-defaults.conf \
&& test -f /etc/squid/evolinux-acl.conf \ && test -f /etc/squid/evolinux-whitelist-custom.conf \
&& test -f /etc/squid/evolinux-httpaccess.conf \ && test -f /etc/squid/evolinux-acl.conf \
&& test -f /etc/squid/evolinux-custom.conf; && test -f /etc/squid/evolinux-httpaccess.conf \
} || failed "IS_SQUIDEVOLINUXCONF" && test -f /etc/squid/evolinux-custom.conf;
} || failed "IS_SQUIDEVOLINUXCONF" "missing squid evolinux config"
fi
fi fi
} }
check_duplicate_fs_label() { check_duplicate_fs_label() {
@ -947,11 +1027,12 @@ check_duplicate_fs_label() {
fi fi
rm "$tmpFile" rm "$tmpFile"
else else
failed "IS_DUPLICATE_FS_LABEL" "blkid not found" failed "IS_DUPLICATE_FS_LABEL" "blkid not found in ${PATH}"
fi fi
} }
check_evolix_user() { 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() { check_evoacme_cron() {
if [ -f "/usr/local/sbin/evoacme" ]; then 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/ # Starting from Jessie and Apache 2.4, /etc/apache2/conf.d/
# must be replaced by conf-available/ and config files symlinked # must be replaced by conf-available/ and config files symlinked
# to conf-enabled/ # 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 if [ -f /etc/apache2/apache2.conf ]; then
test -d /etc/apache2/conf.d/ && failed "IS_APACHE_CONFENABLED" test -d /etc/apache2/conf.d/ \
grep -q 'Include conf.d' /etc/apache2/apache2.conf && failed "IS_APACHE_CONFENABLED" && 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
fi fi
} }
check_meltdown_spectre() { check_meltdown_spectre() {
# For Stretch, detection is easy as the kernel use # For Stretch, detection is easy as the kernel use
# /sys/devices/system/cpu/vulnerabilities/ # /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 for vuln in meltdown spectre_v1 spectre_v2; do
test -f "/sys/devices/system/cpu/vulnerabilities/$vuln" \ test -f "/sys/devices/system/cpu/vulnerabilities/$vuln" \
|| failed "IS_MELTDOWN_SPECTRE" || failed "IS_MELTDOWN_SPECTRE" "vulnerable to $vuln"
test "${VERBOSE}" = 1 || break
done done
# For Jessie this is quite complicated to verify and we need to use kernel config file # For Jessie this is quite complicated to verify and we need to use kernel config file
elif is_debian_jessie; then 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. # Sometimes autodetection of kernel config file fail, so we test if the file really exists.
if [ -f "/boot/${kernelConfig}" ]; then if [ -f "/boot/${kernelConfig}" ]; then
grep -Eq '^CONFIG_PAGE_TABLE_ISOLATION=y' "/boot/$kernelConfig" \ 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" \ 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 fi
fi fi
@ -1036,29 +1122,31 @@ check_old_home_dir() {
check_tmp_1777() { check_tmp_1777() {
actual=$(stat --format "%a" /tmp) actual=$(stat --format "%a" /tmp)
expected="1777" expected="1777"
test "$expected" = "$actual" || failed "IS_TMP_1777" test "$expected" = "$actual" || failed "IS_TMP_1777" "/tmp must be $expected"
} }
check_root_0700() { check_root_0700() {
actual=$(stat --format "%a" /root) actual=$(stat --format "%a" /root)
expected="700" expected="700"
test "$expected" = "$actual" || failed "IS_ROOT_0700" test "$expected" = "$actual" || failed "IS_ROOT_0700" "/root must be $expected"
} }
check_usrsharescripts() { check_usrsharescripts() {
actual=$(stat --format "%a" /usr/share/scripts) actual=$(stat --format "%a" /usr/share/scripts)
expected="700" expected="700"
test "$expected" = "$actual" || failed "IS_USRSHARESCRIPTS" test "$expected" = "$actual" || failed "IS_USRSHARESCRIPTS" "/usr/share/scripts must be $expected"
} }
check_sshpermitrootno() { check_sshpermitrootno() {
if is_debian_stretch; then if is_debian_stretch || is_debian_buster; then
if grep -q "^PermitRoot" /etc/ssh/sshd_config; 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 fi
else 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 fi
} }
check_evomaintenanceusers() { check_evomaintenanceusers() {
if is_debian_stretch; then if is_debian_stretch || is_debian_buster; then
users=$(getent group evolinux-sudo | cut -d':' -f4 | tr ',' ' ') users=$(getent group evolinux-sudo | cut -d':' -f4 | tr ',' ' ')
else else
if [ -f /etc/sudoers.d/evolinux ]; then if [ -f /etc/sudoers.d/evolinux ]; then
@ -1117,7 +1205,7 @@ check_evobackup_incs() {
if [ -f "${bkctld_cron_file}" ]; then if [ -f "${bkctld_cron_file}" ]; then
root_crontab=$(grep -v "^#" "${bkctld_cron_file}") 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 "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 else
failed "IS_EVOBACKUP_INCS" "Crontab \`${bkctld_cron_file}' is missing" failed "IS_EVOBACKUP_INCS" "Crontab \`${bkctld_cron_file}' is missing"
fi fi
@ -1126,7 +1214,71 @@ check_evobackup_incs() {
check_osprober() { check_osprober() {
if is_installed os-prober qemu-kvm; then 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 fi
} }
@ -1205,6 +1357,7 @@ main() {
test "${IS_AUTOIF:=1}" = 1 && check_autoif test "${IS_AUTOIF:=1}" = 1 && check_autoif
test "${IS_INTERFACESGW:=1}" = 1 && check_interfacesgw test "${IS_INTERFACESGW:=1}" = 1 && check_interfacesgw
test "${IS_EVOBACKUP:=1}" = 1 && check_evobackup 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_USERLOGROTATE:=1}" = 1 && check_userlogrotate
test "${IS_APACHECTL:=1}" = 1 && check_apachectl test "${IS_APACHECTL:=1}" = 1 && check_apachectl
test "${IS_APACHESYMLINK:=1}" = 1 && check_apachesymlink test "${IS_APACHESYMLINK:=1}" = 1 && check_apachesymlink
@ -1229,7 +1382,7 @@ main() {
test "${IS_HARDWARERAIDTOOL:=1}" = 1 && check_hardwareraidtool test "${IS_HARDWARERAIDTOOL:=1}" = 1 && check_hardwareraidtool
test "${IS_LOG2MAILSYSTEMDUNIT:=1}" = 1 && check_log2mailsystemdunit test "${IS_LOG2MAILSYSTEMDUNIT:=1}" = 1 && check_log2mailsystemdunit
test "${IS_LISTUPGRADE:=1}" = 1 && check_listupgrade 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_SQL_BACKUP:=1}" = 1 && check_sql_backup
test "${IS_POSTGRES_BACKUP:=1}" = 1 && check_postgres_backup test "${IS_POSTGRES_BACKUP:=1}" = 1 && check_postgres_backup
test "${IS_MONGO_BACKUP:=1}" = 1 && check_mongo_backup test "${IS_MONGO_BACKUP:=1}" = 1 && check_mongo_backup
@ -1239,7 +1392,7 @@ main() {
test "${IS_MARIADBSYSTEMDUNIT:=1}" = 1 && check_mariadbsystemdunit test "${IS_MARIADBSYSTEMDUNIT:=1}" = 1 && check_mariadbsystemdunit
test "${IS_MYSQLMUNIN:=1}" = 1 && check_mysqlmunin test "${IS_MYSQLMUNIN:=1}" = 1 && check_mysqlmunin
test "${IS_MYSQLNRPE:=1}" = 1 && check_mysqlnrpe 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_SQUIDLOGROTATE:=1}" = 1 && check_squidlogrotate
test "${IS_SQUIDEVOLINUXCONF:=1}" = 1 && check_squidevolinuxconf test "${IS_SQUIDEVOLINUXCONF:=1}" = 1 && check_squidevolinuxconf
test "${IS_DUPLICATE_FS_LABEL:=1}" = 1 && check_duplicate_fs_label 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_EVOACME_LIVELINKS:=1}" = 1 && check_evoacme_livelinks
test "${IS_APACHE_CONFENABLED:=1}" = 1 && check_apache_confenabled test "${IS_APACHE_CONFENABLED:=1}" = 1 && check_apache_confenabled
test "${IS_MELTDOWN_SPECTRE:=1}" = 1 && check_meltdown_spectre 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_EVOBACKUP_INCS:=1}" = 1 && check_evobackup_incs
test "${IS_OSPROBER:=1}" = 1 && check_osprober 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 fi
#----------------------------------------------------------- #-----------------------------------------------------------
@ -1358,13 +1515,13 @@ main() {
exit ${RC} exit ${RC}
} }
# shellcheck disable=SC2034
readonly PROGNAME=$(basename "$0") readonly PROGNAME=$(basename "$0")
# shellcheck disable=SC2034
readonly PROGDIR=$(realpath -m "$(dirname "$0")") readonly PROGDIR=$(realpath -m "$(dirname "$0")")
# shellcheck disable=2124 # shellcheck disable=2124
readonly ARGS=$@ readonly ARGS=$@
readonly VERSION="19.06"
# Disable LANG* # Disable LANG*
export LANG=C export LANG=C
export LANGUAGE=C export LANGUAGE=C
@ -1388,6 +1545,7 @@ while :; do
--cron) --cron)
IS_KERNELUPTODATE=0 IS_KERNELUPTODATE=0
IS_UPTIME=0 IS_UPTIME=0
IS_MELTDOWN_SPECTRE=0
;; ;;
-v|--verbose) -v|--verbose)
VERBOSE=1 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 - name: evocheck crontab is updated
template: template:
src: crontab.j2 src: crontab.j2
@ -8,3 +15,4 @@
owner: root owner: root
group: root group: root
force: yes force: yes
when: is_cron_installed.rc == 0

View File

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

View File

@ -1,4 +1,5 @@
# {{ ansible_managed }} # {{ ansible_managed }}
33 1 1 * * root /usr/share/scripts/evocheck.sh PATH=/usr/sbin:/usr/bin:/sbin:/bin
33 1 2-31 * * root /usr/share/scripts/evocheck.sh --cron 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_home_options: defaults,noexec,nosuid,nodev
evolinux_fstab_var_tmp: True evolinux_fstab_var_tmp: True
evolinux_fstab_var_tmp_options: defaults,noexec,nosuid,nodev,size=1024m 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 # packages
@ -77,13 +79,15 @@ evolinux_packages_diagnostic: True
evolinux_packages_hardware: True evolinux_packages_hardware: True
evolinux_packages_common: True evolinux_packages_common: True
evolinux_packages_stretch: True evolinux_packages_stretch: True
evolinux_packages_buster: True
evolinux_packages_serveur_base: True evolinux_packages_serveur_base: True
evolinux_packages_purge_openntpd: True evolinux_packages_purge_openntpd: True
evolinux_packages_purge_chrony: True
evolinux_packages_purge_locate: True evolinux_packages_purge_locate: True
evolinux_packages_invalid_mta: True evolinux_packages_invalid_mta: True
evolinux_packages_delete_nfs: True evolinux_packages_delete_nfs: True
evolinux_packages_listchanges: True evolinux_packages_listchanges: True
evolinux_packages_logcheck_recipient: True evolinux_packages_logcheck_recipient: False
# system # system
@ -122,6 +126,7 @@ evolinux_ssh_password_auth_addresses: "{{ evolinux_default_ssh_password_auth_add
evolinux_ssh_match_address: True evolinux_ssh_match_address: True
evolinux_ssh_disable_acceptenv: True evolinux_ssh_disable_acceptenv: True
evolinux_ssh_allow_current_user: False evolinux_ssh_allow_current_user: False
evolinux_ssh_group: "evolinux-ssh"
### disabled because of a memory leak ### disabled because of a memory leak
# # evolinux users # # evolinux users
@ -197,6 +202,11 @@ evolinux_nagios_nrpe_include: True
evolinux_fail2ban_include: False evolinux_fail2ban_include: False
# Evocheck
evolinux_evocheck_include: True
evolinux_evocheck_force_install: "local"
# Listupgrade # Listupgrade
evolinux_listupgrade_include: True 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 # 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 }}) - name: Adjust rights on private key
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 }}" file:
args: path: /etc/ssl/private/{{ ansible_fqdn }}.key
creates: "/etc/ssl/private/{{ ansible_fqdn }}.key" owner: root
group: ssl-cert
mode: "0640"
- name: Adjust rights on private key - name: Create certificate for default site
file: 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
path: /etc/ssl/private/{{ ansible_fqdn }}.key args:
owner: root creates: "/etc/ssl/certs/{{ ansible_fqdn }}.crt"
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"
when: evolinux_default_www_ssl_cert when: evolinux_default_www_ssl_cert
- meta: flush_handlers - meta: flush_handlers

View File

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

View File

@ -57,4 +57,15 @@
when: when:
- evolinux_fstab_var_tmp - 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 - meta: flush_handlers

View File

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

View File

@ -24,6 +24,12 @@
dest: /etc/logrotate.d/ dest: /etc/logrotate.d/
when: evolinux_logs_logrotate_confs 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 - name: Configure logrotate.conf
replace: replace:
dest: /etc/logrotate.conf dest: /etc/logrotate.conf

View File

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

View File

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

View File

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

View File

@ -37,6 +37,12 @@
regexp: "umask [0-9]+" regexp: "umask [0-9]+"
when: evolinux_root_umask 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 - name: Custom git config for root
copy: copy:
src: root/gitconfig src: root/gitconfig
@ -87,7 +93,7 @@
dest: /etc/ssh/sshd_config dest: /etc/ssh/sshd_config
regexp: '^PermitRootLogin (yes|without-password|prohibit-password)' regexp: '^PermitRootLogin (yes|without-password|prohibit-password)'
replace: "PermitRootLogin no" replace: "PermitRootLogin no"
validate: '/usr/sbin/sshd -T -f %s' validate: '/usr/sbin/sshd -t -f %s'
notify: reload sshd notify: reload sshd
when: evolinux_root_disable_ssh when: evolinux_root_disable_ssh

View File

@ -11,7 +11,7 @@
# only the first instance of the keyword is applied. » # 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, # 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)" - name: "Security directives for Evolinux (Debian 10 or later)"
blockinfile: blockinfile:
@ -20,14 +20,14 @@
block: | block: |
Match Address {{ evolinux_ssh_password_auth_addresses | join(',') }} Match Address {{ evolinux_ssh_password_auth_addresses | join(',') }}
PasswordAuthentication yes PasswordAuthentication yes
Match Group evolix Match Group {{ evolinux_internal_group }}
PasswordAuthentication no PasswordAuthentication no
insertafter: EOF insertafter: EOF
validate: '/usr/sbin/sshd -t -f %s' validate: '/usr/sbin/sshd -t -f %s'
notify: reload sshd notify: reload sshd
when: when:
- evolinux_ssh_password_auth_addresses != [] - 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) - name: Security directives for Evolinux (Jessie/Stretch)
blockinfile: blockinfile:
@ -41,7 +41,7 @@
notify: reload sshd notify: reload sshd
when: when:
- evolinux_ssh_password_auth_addresses != [] - 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 # 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. # do not want clients to push their environment variables like LANG.
@ -59,7 +59,7 @@
regexp: '^#?LogLevel [A-Z]+' regexp: '^#?LogLevel [A-Z]+'
replace: "LogLevel VERBOSE" replace: "LogLevel VERBOSE"
notify: reload sshd notify: reload sshd
when: ansible_distribution_major_version | version_compare('9', '>=') when: ansible_distribution_major_version is version('9', '>=')
- name: "Get current user" - name: "Get current user"
command: logname command: logname

View File

@ -22,7 +22,7 @@
- name: Reconfigure locales - name: Reconfigure locales
command: /usr/sbin/locale-gen 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 - name: Setting default timezone
timezone: timezone:
@ -34,7 +34,7 @@
# non-interactively (like tzdata ↑) # non-interactively (like tzdata ↑)
- include_role: - include_role:
name: remount-usr name: evolix/remount-usr
- name: Ensure automagic vim conf is disabled - name: Ensure automagic vim conf is disabled
lineinfile: lineinfile:
@ -84,13 +84,20 @@
#- name: Customizing /etc/fstab #- 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 - name: Set verbose logging for cron deamon
lineinfile: lineinfile:
dest: /etc/default/cron dest: /etc/default/cron
line: "EXTRA_OPTS='-L 15'" line: "EXTRA_OPTS='-L 15'"
create: yes create: yes
state: present 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 - name: Modify default umask for cron deamon
lineinfile: lineinfile:
@ -98,7 +105,7 @@
line: "umask 022" line: "umask 022"
create: yes create: yes
state: present state: present
when: evolinux_system_cron_umask when: is_cron_installed.rc == 0 and evolinux_system_cron_umask
- name: Randomize periodic crontabs - name: Randomize periodic crontabs
replace: 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: '^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: '^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' } - { 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: - include_role:
name: ntpd name: evolix/ntpd
## alert5 ## alert5
@ -146,17 +153,17 @@
mode: "0755" mode: "0755"
when: when:
- evolinux_system_alert5_init - evolinux_system_alert5_init
- ansible_distribution_major_version | version_compare('10', '>=') - ansible_distribution_major_version is version('10', '>=')
- name: Install alert5 service (buster) - name: Install alert5 service (buster)
copy: copy:
src: alert5.service src: alert5.service
dest: /etc/systemd/system/alert5.service dest: /etc/systemd/system/alert5.service
force: yes force: yes
mode: "0755" mode: "0644"
when: when:
- evolinux_system_alert5_init - evolinux_system_alert5_init
- ansible_distribution_major_version | version_compare('10', '>=') - ansible_distribution_major_version is version('10', '>=')
- name: Enable alert5 init script (buster) - name: Enable alert5 init script (buster)
systemd: systemd:
@ -166,7 +173,7 @@
when: when:
- evolinux_system_alert5_init - evolinux_system_alert5_init
- evolinux_system_alert5_enable - evolinux_system_alert5_enable
- ansible_distribution_major_version | version_compare('10', '>=') - ansible_distribution_major_version is version('10', '>=')
## network interfaces ## network interfaces
@ -184,4 +191,15 @@
replace: "auto" replace: "auto"
when: evolinux_system_eni_auto and grep_hotplug_eni.rc == 0 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 - meta: flush_handlers

View File

@ -20,7 +20,7 @@ PIDFILE=/var/run/$NAME.pid
STATUSFILE=/var/run/$NAME.status STATUSFILE=/var/run/$NAME.status
SCRIPTNAME=/etc/init.d/$NAME 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) PERIOD=600 # Seconds between each check (default 10 minutes)
REMIND=86400 # Seconds between each reminder (default 2 hours) REMIND=86400 # Seconds between each reminder (default 2 hours)
RUN_DAEMON=yes RUN_DAEMON=yes

View File

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

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