Merge branch '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 2021-06-28 16:01:47 +02:00 committed by Jérémy Lecour
commit 1b8de7c524
317 changed files with 5741 additions and 1757 deletions

View File

@ -20,6 +20,48 @@ The **patch** part changes incrementally at each release.
### Security
## [10.6.0] 2021-06-28
### Added
* Add Elastic GPG key to kibana, filebeat, logstash, metricbeat roles
* apache: new variable for mpm mode (+ updated default config accordingly)
* evolinux-base: add default motd template
* kvm-host: add migrate-vm script
* mysql: variable to disable myadd script overwrite (default: True)
* nodejs: update apt cache before installing the package
* squid: add Yarn apt repository in default whitelist
### Changed
* Update Galaxy metadata (company, platforms and galaxy_tags)
* Use 'loop' syntax instead of 'with_first_found/with_items/with_dict/with_nested/with_list'
* Use Ansible syntax used in Ansible 2.8+
* apt: store keys in /etc/apt/trusted.gpg.d in ascii format
* certbot: sync_remote.sh is configurable
* evolinux-base: copy GPG key instead of using apt-key
* evomaintenance: upstream release 0.6.4
* kvm-host: replace the "kvm-tools" package with scripts deployed by Ansible
* listupgrade: upstream release 21.06.2
* nodejs: change GPG key name
* ntpd: Add leapfile configuration setting to ntpd on debian 10+
* packweb-apache: install phpMyAdmin from buster-backports
* spamassassin: change dependency on evomaintenance
* squid: remove obsolete variable on Squid 4
### Fixed
* add default (useless) value for file lookup (first_found)
* fix pipefail option for shell invocations
* elasticsearch: inline YAML formatting of seed_hosts and initial_master_nodes
* evolinux-base: fix motd lookup path
* ldap: fix edge cases where passwords were not set/get properly
* listupgrade: fix wget error + shellcheck cleanup
### Removed
* elasticsearch: recent versiond don't depend on external JRE
## [10.5.1] 2021-04-13
### Added
@ -37,7 +79,7 @@ The **patch** part changes incrementally at each release.
* apache: new variables for logrotate + server-status
* filebeat: package can be upgraded to latest (default: False)
* haproxy: possible admin access with login/pass
* lxc-php: Add PHP 7.4 support
* lxc-php: Add PHP 7.4 support
* metricbeat: package can be upgraded to latest (default: False)
* metricbeat: new variables to configure SSL mode
* nagios-nrpe: new script check_phpfpm_multi
@ -110,7 +152,7 @@ The **patch** part changes incrementally at each release.
* tomcat-instance: fail if uid already exists
* varnish: change template name for better readability
* varnish: no threadpool delay by default
* varnish: no custom reload script for Debian 10 and later
* varnish: no custom reload script for Debian 10 and later
### Fixed

View File

@ -21,11 +21,11 @@
groupname: launched-instances
ansible_user: admin
ansible_ssh_common_args: "-o StrictHostKeyChecking=no"
with_items: "{{ec2.instances}}"
loop: "{{ec2.instances}}"
- debug:
msg: "Your newly created instance is reachable at: {{item.public_dns_name}}"
with_items: "{{ec2.instances}}"
loop: "{{ec2.instances}}"
- name: Wait for SSH to come up on all instances (give up after 2m)
wait_for:
@ -33,4 +33,4 @@
host: "{{item.public_dns_name}}"
port: 22
timeout: 120
with_items: "{{ec2.instances}}"
loop: "{{ec2.instances}}"

View File

@ -23,3 +23,5 @@ log2mail_alert_email: Null
apache_logrotate_frequency: daily
apache_logrotate_rotate: 365
apache_mpm: "itk"

View File

@ -24,3 +24,6 @@ SetEnvIf User-Agent "ApacheBench" GoAway=1
#<FilesMatch ".(eot|ttf|otf|woff)">
# Header set Access-Control-Allow-Origin "*"
#</FilesMatch>
# you need disable EnableCapabilities to use data on NFS mounts
#EnableCapabilities off

View File

@ -3,12 +3,43 @@ Timeout 10
KeepAliveTimeout 2
MaxKeepAliveRequests 10
#MaxClients 250
MaxRequestWorkers 250
ServerLimit 250
StartServers 50
MinSpareServers 20
MaxSpareServers 30
MaxRequestsPerChild 0
<IfModule mpm_prefork_module>
MaxRequestWorkers 250
ServerLimit 250
StartServers 50
MinSpareServers 20
MaxSpareServers 30
MaxRequestsPerChild 0
</IfModule>
<IfModule mpm_worker_module>
StartServers 3
MinSpareThreads 25
MaxSpareThreads 75
ThreadLimit 64
ThreadsPerChild 25
MaxRequestWorkers 150
MaxConnectionsPerChild 0
</IfModule>
<IfModule mpm_itk_module>
LimitUIDRange 0 6000
LimitGIDRange 0 6000
</IfModule>
<IfModule ssl_module>
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!RC4
</IfModule>
<IfModule status_module>
ExtendedStatus On
<IfModule proxy_module>
ProxyStatus On
</IfModule>
</IfModule>
<Directory /home/>
AllowOverride None
@ -17,26 +48,11 @@ MaxRequestsPerChild 0
Deny from env=GoAway
</Directory>
<IfModule mod_ssl.c>
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!RC4
</IfModule>
<Files ~ "\.(inc|bak)$">
Require all denied
</Files>
<IfModule mod_status.c>
ExtendedStatus On
<IfModule mod_proxy.c>
ProxyStatus On
</IfModule>
</IfModule>
<IfModule mpm_itk.c>
LimitUIDRange 0 6000
LimitGIDRange 0 6000
</IfModule>
<LocationMatch "^/evolinux_fpm_status-.*">
Require all denied

View File

@ -4,7 +4,7 @@ set -e
DIR="/var/log/apache-status"
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"
if [ ! -d "${DIR}" ]; then

View File

@ -1,18 +1,24 @@
---
galaxy_info:
author: Evolix
company: Evolix
description: Installation and basic configuration of Apache
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
min_ansible_version: 2.2
min_ansible_version: "2.2"
platforms:
- name: Debian
versions:
- jessie
- stretch
- name: Debian
versions:
- jessie
- stretch
- buster
galaxy_tags: []
# Be sure to remove the '[]' above if you add dependencies
# to this list.
dependencies: []
# List your role dependencies here, one per line.

View File

@ -10,7 +10,7 @@
force: no
tags:
- apache
- name: Load IP whitelist task
include: ip_whitelist.yml
@ -40,7 +40,7 @@
dest: /etc/apache2/private_htpasswd
line: "{{ item }}"
state: present
with_items: "{{ apache_private_htpasswd_present }}"
loop: "{{ apache_private_htpasswd_present }}"
notify: reload apache
tags:
- apache
@ -50,7 +50,7 @@
dest: /etc/apache2/private_htpasswd
line: "{{ item }}"
state: absent
with_items: "{{ apache_private_htpasswd_absent }}"
loop: "{{ apache_private_htpasswd_absent }}"
notify: reload apache
tags:
- apache

View File

@ -5,7 +5,7 @@
dest: /etc/apache2/ipaddr_whitelist.conf
line: "Require ip {{ item }}"
state: present
with_items: "{{ apache_ipaddr_whitelist_present }}"
loop: "{{ apache_ipaddr_whitelist_present }}"
notify: reload apache
tags:
- apache
@ -16,7 +16,7 @@
dest: /etc/apache2/ipaddr_whitelist.conf
line: "Require ip {{ item }}"
state: absent
with_items: "{{ apache_ipaddr_whitelist_absent }}"
loop: "{{ apache_ipaddr_whitelist_absent }}"
notify: reload apache
tags:
- apache

View File

@ -4,7 +4,6 @@
apt:
name:
- apache2
- libapache2-mpm-itk
- libapache2-mod-evasive
- apachetop
- libwww-perl
@ -14,6 +13,18 @@
- packages
when: ansible_distribution_major_version is version('9', '>=')
- name: itk package is installed if required (Debian 9 or later)
apt:
name:
- libapache2-mpm-itk
state: present
tags:
- apache
- packages
when:
- ansible_distribution_major_version is version('9', '>=')
- apache_mpm == "itk"
- name: packages are installed (jessie)
apt:
name:
@ -31,11 +42,10 @@
apache2_module:
name: '{{ item }}'
state: present
with_items:
loop:
- rewrite
- expires
- headers
- cgi
- ssl
- include
- negotiation
@ -44,6 +54,18 @@
tags:
- apache
- name: basic modules are enabled
apache2_module:
name: '{{ item }}'
state: present
loop:
- cgi
notify: reload apache
when: apache_mpm == "prefork" or apache_mpm == "itk"
tags:
- apache
- name: Copy Apache defaults config file
copy:
src: evolinux-defaults.conf
@ -80,7 +102,7 @@
command: "a2enconf {{ item }}"
register: command_result
changed_when: "'Enabling' in command_result.stderr"
with_items:
loop:
- z-evolinux-defaults.conf
- zzz-evolinux-custom.conf
notify: reload apache
@ -108,7 +130,7 @@
state: link
force: yes
notify: reload apache
when: apache_evolinux_default_enabled
when: apache_evolinux_default_enabled | bool
tags:
- apache
@ -183,6 +205,6 @@
- apache
- include: munin.yml
when: apache_munin_include
when: apache_munin_include | bool
tags:
- apache

View File

@ -15,7 +15,7 @@
src: "/usr/share/munin/plugins/{{ item }}"
dest: "/etc/munin/plugins/{{ item }}"
state: link
with_items:
loop:
- apache_accesses
- apache_processes
- apache_volume

View File

@ -14,7 +14,7 @@
# The last character "\u000A" is a line feed (LF), it's better to keep it
content: "{{ apache_serverstatus_suffix }}\u000A"
force: yes
when: apache_serverstatus_suffix != ""
when: apache_serverstatus_suffix | length > 0
- name: generate random string for server-status suffix
shell: "apg -a 1 -M N -n 1 > {{ apache_serverstatus_suffix_file }}"

920
apt/files/reg.asc Normal file
View File

@ -0,0 +1,920 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: SKS 1.1.6
Comment: Hostname: keyserver.ubuntu.com
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
BWcdiQ==
=iUyJ
-----END PGP PUBLIC KEY BLOCK-----

Binary file not shown.

View File

@ -1,17 +1,23 @@
galaxy_info:
author: Evolix
company: Evolix
description: Add repositories to APT sources list.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
min_ansible_version: 2.2
min_ansible_version: "2.2"
platforms:
- name: Debian
versions:
- jessie
- name: Debian
versions:
- jessie
- stretch
- buster
galaxy_tags: []
# Be sure to remove the '[]' above if you add dependencies
# to this list.
dependencies: []
# List your role dependencies here, one per line.

View File

@ -14,13 +14,13 @@
file:
path: '{{ item }}'
state: absent
with_items:
loop:
- /etc/apt/sources.list.d/debian-security.list
- /etc/apt/sources.list.d/debian-jessie.list
- /etc/apt/sources.list.d/debian-stretch.list
- /etc/apt/sources.list.d/debian-buster.list
- /etc/apt/sources.list.d/debian-update.list
when: apt_clean_gandi_sourceslist
when: apt_clean_gandi_sourceslist | bool
tags:
- apt

View File

@ -8,11 +8,11 @@
create: yes
state: present
mode: "0640"
with_items:
loop:
- { line: "APT::Install-Recommends \"false\";", regexp: 'APT::Install-Recommends' }
- { line: "APT::Install-Suggests \"false\";", regexp: 'APT::Install-Suggests' }
- { line: "APT::Periodic::Enable \"0\";", regexp: 'APT::Periodic::Enable' }
when: apt_evolinux_config
when: apt_evolinux_config | bool
tags:
- apt
@ -23,12 +23,12 @@
create: yes
state: present
mode: "0640"
with_items:
loop:
- "DPkg::Pre-Invoke { \"df /tmp | grep -q /tmp && mount -oremount,exec /tmp || true\"; };"
- "DPkg::Pre-Invoke { \"df /usr | grep -q /usr && mount -oremount,rw /usr || true\"; };"
- "DPkg::Post-Invoke { \"df /tmp | grep -q /tmp && mount -oremount /tmp || true\"; };"
- "DPkg::Post-Invoke { \"df /usr | grep -q /usr && mount -oremount /usr || true\"; };"
when: apt_hooks
when: apt_hooks | bool
tags:
- apt
@ -36,7 +36,7 @@
apt:
name: aptitude
state: absent
when: apt_remove_aptitude
when: apt_remove_aptitude | bool
tags:
- apt
@ -50,6 +50,6 @@
- name: Upgrading system
apt:
upgrade: dist
when: apt_upgrade
when: apt_upgrade | bool
tags:
- apt

View File

@ -1,17 +1,21 @@
---
# - name: Fail if distribution is not supported
# fail:
# msg: "Error: Evolix public repository is not compatble with 'Debian Stretch' yet."
# when: ansible_distribution_release == "stretch"
# tags:
# - apt
- name: Evolix embedded GPG key is absent
apt_key:
id: "B8612B5D"
keyring: /etc/apt/trusted.gpg
state: absent
tags:
- apt
- name: Add Evolix GPG key
apt_key:
#url: http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x44975278B8612B5D
data: "{{ lookup('file', 'reg.gpg') }}"
copy:
src: reg.asc
dest: /etc/apt/trusted.gpg.d/reg.asc
force: yes
mode: "0644"
owner: root
group: root
tags:
- apt

View File

@ -1,10 +1,15 @@
---
- name: "hold packages (apt)"
shell: "(dpkg -l {{ item }} 2>/dev/null | grep -q -E '^(i|h)i') && ((apt-mark showhold | grep --quiet {{ item }}) || apt-mark hold {{ item }})"
shell: "set -o pipefail && (dpkg -l {{ item }} 2>/dev/null | grep -q -E '^(i|h)i') && ((apt-mark showhold | grep --quiet {{ item }}) || apt-mark hold {{ item }})"
args:
executable: /bin/bash
check_mode: no
register: apt_mark
changed_when: "item + ' set on hold.' in apt_mark.stdout"
failed_when: apt_mark.rc != 0 and not apt_mark.stdout == ''
failed_when:
- apt_mark.rc != 0
- apt_mark.stdout | length > 0
loop: "{{ apt_hold_packages }}"
tags:
- apt
@ -28,7 +33,10 @@
- apt
- name: "unhold packages (apt)"
shell: "(dpkg -l {{ item }} 2>/dev/null | grep -q -E '^(i|h)i') && ((apt-mark showhold | grep --quiet {{ item }}) && apt-mark unhold {{ item }})"
shell: "set -o pipefail && (dpkg -l {{ item }} 2>/dev/null | grep -q -E '^(i|h)i') && ((apt-mark showhold | grep --quiet {{ item }}) && apt-mark unhold {{ item }})"
args:
executable: /bin/bash
check_mode: no
register: apt_mark
changed_when: "'Canceled hold on' + item in apt_mark.stdout"
failed_when: apt_mark.rc != 0 and not apt_mark.stdout = ''

View File

@ -10,30 +10,30 @@
- name: Custom configuration
include: config.yml
when: apt_config
when: apt_config | bool
tags:
- apt
- name: Install basics repositories
include: basics.yml
when: apt_install_basics
when: apt_install_basics | bool
tags:
- apt
- name: Install APT Backports repository
include: backports.yml
when: apt_install_backports
when: apt_install_backports | bool
tags:
- apt
- name: Install Evolix Public APT repository
include: evolix_public.yml
when: apt_install_evolix_public
when: apt_install_evolix_public | bool
tags:
- apt
- name: Install check for packages marked hold
include: hold_packages.yml
when: apt_install_hold_packages
when: apt_install_hold_packages | bool
tags:
- apt

View File

@ -1,17 +1,23 @@
galaxy_info:
author: Evolix
company: Evolix
description: Installation and basic configuration of bind9.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
min_ansible_version: 2.2
min_ansible_version: "2.2"
platforms:
- name: Debian
versions:
- jessie
- name: Debian
versions:
- jessie
- stretch
- buster
galaxy_tags: []
# Be sure to remove the '[]' above if you add dependencies
# to this list.
dependencies: []
# List your role dependencies here, one per line.

View File

@ -6,7 +6,7 @@
bind_cache_dir: /var/cache/bind
bind_statistics_file: /var/run/named.stats
bind_chroot_path: /var/chroot-bind
when: bind_chroot_set
when: bind_chroot_set | bool
- name: configure apparmor
template:
@ -34,7 +34,7 @@
mode: "0644"
force: yes
notify: restart bind
when: bind_recursive_server
when: bind_recursive_server | bool
- name: enable zones.rfc1918 for recursive server
lineinfile:
@ -42,7 +42,7 @@
line: 'include "/etc/bind/zones.rfc1918";'
regexp: "zones.rfc1918"
notify: restart bind
when: bind_recursive_server
when: bind_recursive_server | bool
- name: Set bind configuration for authoritative server
template:
@ -53,7 +53,7 @@
mode: "0644"
force: yes
notify: restart bind
when: bind_authoritative_server
when: bind_authoritative_server | bool
- name: Create systemd service
template:
@ -75,7 +75,7 @@
group: adm
mode: "0640"
state: touch
when: not bind_chroot_set
when: not (bind_chroot_set | bool)
- name: "touch {{ bind_query_file }} if non chroot"
file:
@ -84,7 +84,7 @@
group: adm
mode: "0640"
state: touch
when: not bind_chroot_set
when: not (bind_chroot_set | bool)
- name: send chroot-bind.sh in /root
copy:
@ -94,17 +94,19 @@
owner: root
force: yes
backup: yes
when: bind_chroot_set
when: bind_chroot_set | bool
- name: exec chroot-bind.sh
command: "/root/chroot-bind.sh"
register: chrootbind_run
changed_when: False
when: bind_chroot_set
when: bind_chroot_set | bool
- debug:
var: chrootbind_run.stdout_lines
when: bind_chroot_set and chrootbind_run.stdout != ""
when:
- bind_chroot_set | bool
- chrootbind_run.stdout | length > 0
- name: Modify OPTIONS in /etc/default/bind9 for chroot
replace:
@ -112,7 +114,7 @@
regexp: '^OPTIONS=.*'
replace: 'OPTIONS="-u bind -t {{ bind_chroot_path }}"'
notify: restart bind
when: bind_chroot_set
when: bind_chroot_set | bool
- name: logrotate for bind
template:

View File

@ -14,7 +14,7 @@
src: "/usr/share/munin/plugins/{{ item }}"
dest: "/etc/munin/plugins/{{ item }}"
state: link
with_items:
loop:
- bind9
- bind9_rndc
notify: restart munin-node
@ -30,7 +30,7 @@
src: "/usr/share/munin/plugins/{{ item }}"
dest: "/etc/munin/plugins/{{ item }}"
state: link
with_items:
loop:
- bind9
- bind9_rndc
notify: restart munin-node

View File

@ -2,3 +2,5 @@
certbot_work_dir: /var/lib/letsencrypt
certbot_custom_crontab: True
certbot_hooks_sync_remote_servers: []

View File

@ -29,20 +29,22 @@ main() {
if found_renewed_lineage; then
RENEWED_DOMAINS=${RENEWED_DOMAINS:-$(domain_from_cert)}
remore_lineage=${remote_dir}/renewed_lineage/$(basename ${RENEWED_LINEAGE})
remote_lineage=${remote_dir}/renewed_lineage/$(basename "${RENEWED_LINEAGE}")
for server in ${servers}; do
remote_host="root@${server}"
ssh ${remote_host} "mkdir -p ${remote_dir}" \
# shellcheck disable=SC2029
ssh "${remote_host}" "mkdir -p ${remote_lineage}" \
|| error "Couldn't create ${remote_dir} directory ${server}"
rsync --archive --copy-links --delete ${RENEWED_LINEAGE}/ ${remote_host}:${remore_lineage}/ \
rsync --archive --copy-links --delete "${RENEWED_LINEAGE}/" "${remote_host}:${remote_lineage}/" \
|| error "Couldn't sync certificate on ${server}"
rsync --archive --copy-links --delete --exclude $0 --delete-excluded ${hooks_dir}/ ${remote_host}:${remote_dir}/hooks/ \
rsync --archive --copy-links --delete --exclude $0 --delete-excluded "${hooks_dir}/" "${remote_host}:${remote_dir}/hooks/" \
|| error "Couldn't sync hooks on ${server}"
ssh ${remote_host} "export RENEWED_LINEAGE=\"${remore_lineage}/\" RENEWED_DOMAINS=${RENEWED_DOMAINS}; find ${remote_dir}/hooks/ -mindepth 1 -maxdepth 1 -type f -executable -exec {} \;" \
# shellcheck disable=SC2029
ssh "${remote_host}" "export RENEWED_LINEAGE=\"${remote_lineage}/\" RENEWED_DOMAINS=${RENEWED_DOMAINS}; find ${remote_dir}/hooks/ -mindepth 1 -maxdepth 1 -type f -executable -exec {} \;" \
|| error "Something went wrong on ${server} for deploy hooks"
done
else
@ -50,13 +52,23 @@ main() {
fi
}
readonly PROGNAME=$(basename "$0")
readonly VERBOSE=${VERBOSE:-"0"}
readonly QUIET=${QUIET:-"0"}
PROGNAME=$(basename "$0")
VERBOSE=${VERBOSE:-"0"}
QUIET=${QUIET:-"0"}
readonly hooks_dir="/etc/letsencrypt/renewal-hooks/deploy"
readonly remote_dir="/root/cert_sync"
hooks_dir="/etc/letsencrypt/renewal-hooks/deploy"
# The config file lust have the same name as the script, with a different extension (.cf instead of .sh)
config_file="${0%.*}.cf"
remote_dir="/root/cert_sync"
readonly servers=""
if [ -f "${config_file}" ]; then
. "${config_file}"
fi
servers=${servers:-""}
if [ -z "${servers}" ]; then
echo "${PROGNAME}: No server provided. Skip." >&2
exit 0
fi
main

View File

@ -497,7 +497,7 @@ Python36SclIsAvailable() {
# Try to enable rh-python36 from SCL if it is necessary and possible.
EnablePython36SCL() {
if "$EXISTS" python3.6 > /dev/null 2> /dev/null; then
if "$EXISTS" python3.6 > /dev/null 2>/dev/null; then
return 0
fi
if [ ! -f /opt/rh/rh-python36/enable ]; then
@ -815,7 +815,7 @@ elif [ -f /etc/redhat-release ]; then
unset LE_PYTHON
DeterminePythonVersion "NOCRASH"
RPM_DIST_NAME=`(. /etc/os-release 2> /dev/null && echo $ID) || echo "unknown"`
RPM_DIST_NAME=`(. /etc/os-release 2>/dev/null && echo $ID) || echo "unknown"`
if [ "$PYVER" -eq 26 -a $(uname -m) != 'x86_64' ]; then
# 32 bits CentOS 6 and affiliates are not supported anymore by certbot-auto.
@ -825,7 +825,7 @@ elif [ -f /etc/redhat-release ]; then
# Set RPM_DIST_VERSION to VERSION_ID from /etc/os-release after splitting on
# '.' characters (e.g. "8.0" becomes "8"). If the command exits with an
# error, RPM_DIST_VERSION is set to "unknown".
RPM_DIST_VERSION=$( (. /etc/os-release 2> /dev/null && echo "$VERSION_ID") | cut -d '.' -f1 || echo "unknown")
RPM_DIST_VERSION=$( (. /etc/os-release 2>/dev/null && echo "$VERSION_ID") | cut -d '.' -f1 || echo "unknown")
# If RPM_DIST_VERSION is an empty string or it contains any nonnumeric
# characters, the value is unexpected so we set RPM_DIST_VERSION to 0.

View File

@ -48,7 +48,7 @@
src: cron_jessie
dest: /etc/cron.d/certbot
force: yes
when: certbot_custom_crontab
when: certbot_custom_crontab | bool
- name: disable self-upgrade
ini_file:

View File

@ -23,17 +23,26 @@
- name: Deploy hooks are present
copy:
src: hooks/
src: hooks/deploy/
dest: /etc/letsencrypt/renewal-hooks/deploy/
mode: "0700"
owner: root
group: root
- name: Move commit-etc.sh to z-commit-etc.sh if present
- name: "sync_remote is configured with servers"
lineinfile:
dest: /etc/letsencrypt/renewal-hooks/deploy/sync_remote.cf
regexp: "^servers="
line: "servers=\"{{ certbot_hooks_sync_remote_servers | join(' ') }}\""
create: yes
# begining of backward compatibility tasks
- name: Move deploy/commit-etc.sh to deploy/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
# end of backward compatibility tasks
- name: "certbot lock is ignored by Git"
lineinfile:

View File

@ -5,7 +5,7 @@
question: "{{ item.key }}"
value: "{{ item.value }}"
vtype: "{{ item.type }}"
with_items:
loop:
- { key: 'clamav-daemon/debconf', type: 'boolean', value: 'true' }
- { key: 'clamav-daemon/MaxHTMLNormalize', type: 'string', value: '10M' }
- { key: 'clamav-daemon/StatsPEDisabled', type: 'boolean', value: 'true' }
@ -57,7 +57,7 @@
question: "{{ item.key }}"
value: "{{ item.value }}"
vtype: "{{ item.type }}"
with_items:
loop:
- { key: 'clamav-freshclam/autoupdate_freshclam', type: 'select', value: 'daemon' }
- { key: 'clamav-freshclam/proxy_user', type: 'string', value: '' }
- { key: 'clamav-freshclam/NotifyClamd', type: 'boolean', value: 'true' }

View File

@ -1,17 +1,23 @@
galaxy_info:
author: Evolix
company: Evolix
description: Installation and basic configuration of isc-dhcp-server.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
min_ansible_version: 2.2
min_ansible_version: "2.2"
platforms:
- name: Debian
versions:
- jessie
- name: Debian
versions:
- jessie
- stretch
- buster
galaxy_tags: []
# Be sure to remove the '[]' above if you add dependencies
# to this list.
dependencies: []
# List your role dependencies here, one per line.

View File

@ -28,9 +28,13 @@
when: ansible_distribution_release == 'jessie'
- name: Add Docker's official GPG key
apt_key:
#url: https://download.docker.com/linux/debian/gpg
data: "{{ lookup('file', 'docker-debian.gpg') }}"
copy:
src: docker-debian.asc
dest: /etc/apt/trusted.gpg.d/docker-debian.asc
force: yes
mode: "0644"
owner: root
group: root
- name: Install docker and python-docker
apt:
@ -71,17 +75,17 @@
state: directory
mode: "0644"
owner: root
when: docker_tls_enabled
when: docker_tls_enabled | bool
- name: Copy shellpki utility to Docker TLS directory
template:
src: "{{ item }}.j2"
dest: "{{ docker_tls_path }}/{{ item }}"
mode: "0744"
with_items:
loop:
- shellpki.sh
- openssl.cnf
when: docker_tls_enabled
when: docker_tls_enabled | bool
- name: Check if certs are already created
stat:
@ -90,4 +94,6 @@
- name: Creating a CA, server key
command: "{{ docker_tls_path }}/shellpki.sh init"
when: docker_tls_enabled and not tls_certs_stat.stat.isdir is defined
when:
- docker_tls_enabled | bool
- not tls_certs_stat.stat.isdir

View File

@ -24,7 +24,7 @@
line: "{{ item.key }} = {{ item.value }}"
regexp: "^#*{{ item.key }}"
state: present
with_items:
loop:
- { key: 'hosts', value: '127.0.0.1' }
- { key: 'auth_bind', value: 'yes' }
- { key: 'ldap_version', value: 3 }

View File

@ -1,17 +1,23 @@
galaxy_info:
author: Evolix
company: Evolix
description: Install tools to setup DRBD replication accross servers.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
min_ansible_version: 2.2
min_ansible_version: "2.2"
platforms:
- name: Debian
versions:
- jessie
- name: Debian
versions:
- jessie
- stretch
- buster
galaxy_tags: []
# Be sure to remove the '[]' above if you add dependencies
# to this list.
dependencies: []
# List your role dependencies here, one per line.

View File

@ -1,20 +1,20 @@
---
galaxy_info:
author: Evolix
company: Evolix
description: Install Elasticsearch
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
min_ansible_version: 2.2
min_ansible_version: "2.2"
platforms:
- name: Debian
versions:
- jessie
- stretch
- buster
- name: Debian
versions:
- jessie
- stretch
- buster
galaxy_tags: []
# List tags for your role here, one per line. A tag is
@ -24,6 +24,3 @@ galaxy_info:
#
# NOTE: A tag is limited to a single word comprised of
# alphanumeric characters. Maximum 20 tags per role.
dependencies:
- { role: evolix/java, alternative: 'openjdk' }

View File

@ -6,7 +6,7 @@
line: "cluster.name: {{ elasticsearch_cluster_name }}"
regexp: "^cluster.name:"
insertafter: "^# *cluster.name:"
when: elasticsearch_cluster_name|default("", True)
when: elasticsearch_cluster_name | default("", True) | length > 0
tags:
- config
@ -25,7 +25,7 @@
line: "network.host: {{ elasticsearch_network_host }}"
regexp: "^network.host:"
insertafter: "^# *network.host:"
when: elasticsearch_network_host|default("", True)
when: elasticsearch_network_host | default("", True) | length > 0
tags:
- config
@ -35,7 +35,7 @@
line: "network.publish_host: {{ elasticsearch_network_publish_host }}"
regexp: "^network.publish_host:"
insertafter: "^network.host:"
when: elasticsearch_network_publish_host|default("", True)
when: elasticsearch_network_publish_host | default("", True) | length > 0
tags:
- config
@ -45,25 +45,43 @@
line: "http.publish_host: {{ elasticsearch_http_publish_host }}"
regexp: "^http.publish_host:"
insertafter: "^http.port:"
when: elasticsearch_http_publish_host|default("", True)
when: elasticsearch_http_publish_host | default("", True) | length > 0
tags:
- config
- name: Configure discovery seed hosts
lineinfile:
dest: /etc/elasticsearch/elasticsearch.yml
line: "discovery.seed_hosts: {{ elasticsearch_discovery_seed_hosts | to_yaml }}"
line: "discovery.seed_hosts: {{ elasticsearch_discovery_seed_hosts | to_yaml(default_flow_style=True) }}"
regexp: "^discovery.seed_hosts:"
when: elasticsearch_discovery_seed_hosts
when: elasticsearch_discovery_seed_hosts | default([], True) | length > 0
tags:
- config
- name: Configure empty discovery seed hosts
lineinfile:
dest: /etc/elasticsearch/elasticsearch.yml
regexp: "^discovery.seed_hosts:"
state: absent
when: elasticsearch_discovery_seed_hosts | default([], True) | length <= 0
tags:
- config
- name: Configure initial master nodes
lineinfile:
dest: /etc/elasticsearch/elasticsearch.yml
line: "cluster.initial_master_nodes: {{ elasticsearch_cluster_initial_master_nodes | to_yaml }}"
line: "cluster.initial_master_nodes: {{ elasticsearch_cluster_initial_master_nodes | to_yaml(default_flow_style=True) }}"
regexp: "^cluster.initial_master_nodes:"
when: elasticsearch_cluster_initial_master_nodes
when: elasticsearch_cluster_initial_master_nodes | default([], True) | length > 0
tags:
- config
- name: Configure empty initial master nodes
lineinfile:
dest: /etc/elasticsearch/elasticsearch.yml
regexp: "^cluster.initial_master_nodes:"
state: absent
when: elasticsearch_cluster_initial_master_nodes | default([], True) | length <= 0
tags:
- config
@ -98,7 +116,7 @@
line: "discovery.zen.ping.unicast.hosts: {{ elasticsearch_cluster_members }}"
regexp: "^discovery.zen.ping.unicast.hosts:"
insertafter: "^#discovery.zen.ping.unicast.hosts"
when: elasticsearch_cluster_members|default("", True)
when: elasticsearch_cluster_members | default("", True) | length > 0
tags:
- config
@ -108,6 +126,6 @@
line: "discovery.zen.minimum_master_nodes: {{ elasticsearch_minimum_master_nodes }}"
regexp: "^discovery.zen.minimum_master_nodes:"
insertafter: "^#discovery.zen.minimum_master_nodes"
when: elasticsearch_minimum_master_nodes|default("", True)
when: elasticsearch_minimum_master_nodes | default("", True) | length > 0
tags:
- config

View File

@ -16,8 +16,8 @@
tags:
- elasticsearch
when:
- elasticsearch_custom_datadir != ''
- elasticsearch_custom_datadir != None
- elasticsearch_custom_datadir is not none
- elasticsearch_custom_datadir | length > 0
- name: Datadir is moved to custom path
block:
@ -44,7 +44,7 @@
tags:
- elasticsearch
when:
- elasticsearch_custom_datadir != ''
- elasticsearch_custom_datadir != None
- elasticsearch_custom_datadir is not none
- elasticsearch_custom_datadir | length > 0
- elasticsearch_custom_datadir != elasticsearch_current_real_datadir_test.stdout
- not elasticsearch_custom_datadir_test.stat.exists

View File

@ -1,7 +1,10 @@
---
- name: Check if cron is installed
shell: "dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'"
shell: "set -o pipefail && dpkg -l cron 2>/dev/null | grep -q -E '^(i|h)i'"
args:
executable: /bin/bash
check_mode: no
failed_when: False
changed_when: False
register: is_cron_installed

View File

@ -15,7 +15,7 @@
- include: additional_scripts.yml
- include: plugin_head.yml
when: elasticsearch_plugin_head
when: elasticsearch_plugin_head | bool
- include: curator.yml
when: elasticsearch_curator
when: elasticsearch_curator | bool

View File

@ -5,17 +5,29 @@
name: apt-transport-https
state: present
tags:
- elasticsearch
- packages
- elasticsearch
- packages
- name: Elastic embedded GPG key is absent
apt_key:
id: "D88E42B4"
keyring: /etc/apt/trusted.gpg
state: absent
tags:
- elasticsearch
- packages
- name: Elastic GPG key is installed
apt_key:
# url: https://artifacts.elastic.co/GPG-KEY-elasticsearch
data: "{{ lookup('file', 'elasticsearch.key') }}"
state: present
copy:
src: elastic.asc
dest: /etc/apt/trusted.gpg.d/elastic.asc
force: yes
mode: "0644"
owner: root
group: root
tags:
- elasticsearch
- packages
- elasticsearch
- packages
- name: Elastic sources list is available
apt_repository:
@ -24,16 +36,16 @@
state: present
update_cache: yes
tags:
- elasticsearch
- packages
- elasticsearch
- packages
- name: Elasticsearch is installed
apt:
name: elasticsearch
state: present
tags:
- elasticsearch
- packages
- elasticsearch
- packages
- name: Elasticsearch service is enabled
service:

View File

@ -9,9 +9,14 @@
- name: Tmpdir is moved to custom path
block:
- name: "Create {{ elasticsearch_custom_tmpdir or elasticsearch_default_tmpdir | mandatory }}"
- set_fact:
_elasticsearch_custom_tmpdir: "{{ elasticsearch_custom_tmpdir | default(elasticsearch_default_tmpdir, True) | mandatory }}"
tags:
- elasticsearch
- name: "Create {{ _elasticsearch_custom_tmpdir }}"
file:
path: "{{ elasticsearch_custom_tmpdir or elasticsearch_default_tmpdir | mandatory }}"
path: "{{ _elasticsearch_custom_tmpdir }}"
owner: elasticsearch
group: elasticsearch
mode: "0755"
@ -22,7 +27,7 @@
- name: change JVM tmpdir (< 6.x)
lineinfile:
dest: /etc/elasticsearch/jvm.options
line: "-Djava.io.tmpdir={{ elasticsearch_custom_tmpdir or elasticsearch_default_tmpdir | mandatory }}"
line: "-Djava.io.tmpdir={{ _elasticsearch_custom_tmpdir }}"
regexp: "^-Djava.io.tmpdir="
insertafter: "## JVM configuration"
notify:
@ -34,7 +39,7 @@
- name: check if ES_TMPDIR is available (>= 6.x)
lineinfile:
dest: /etc/default/elasticsearch
line: "ES_TMPDIR={{ elasticsearch_custom_tmpdir or elasticsearch_default_tmpdir | mandatory }}"
line: "ES_TMPDIR={{ _elasticsearch_custom_tmpdir }}"
regexp: "^ES_TMPDIR="
insertafter: "JAVA_HOME"
notify:
@ -54,4 +59,4 @@
tags:
- elasticsearch
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 is not none and elasticsearch_custom_tmpdir | length > 0) or fstab_tmp_noexec.rc == 0

View File

@ -1,17 +1,28 @@
galaxy_info:
author: Evolix
company: Evolix
description: Put /etc under Git version control.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
min_ansible_version: 2.2
min_ansible_version: "2.2"
platforms:
- name: Debian
versions:
- jessie
- name: Debian
versions:
- jessie
- stretch
- buster
galaxy_tags: []
# List tags for your role here, one per line. A tag is
# a keyword that describes and categorizes the role.
# Users find roles by searching for tags. Be sure to
# remove the '[]' above if you add tags to this list.
#
# NOTE: A tag is limited to a single word comprised of
# alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.

View File

@ -8,11 +8,9 @@
- include: do_commit.yml
vars:
git_folder: "/etc"
when:
- _etc_git.stat.exists
- _etc_git.stat.isdir
when:
- _etc_git.stat.exists
- _etc_git.stat.isdir
- name: Is /usr/share/scripts a git repository
stat:
@ -23,5 +21,5 @@
vars:
git_folder: "/usr/share/scripts"
when:
- _usr_share_scripts_git.stat.exists
- _usr_share_scripts_git.stat.isdir
- _usr_share_scripts_git.stat.exists
- _usr_share_scripts_git.stat.isdir

View File

@ -5,7 +5,6 @@
name: remount-usr
when: git_folder is match('/usr/.*')
- name: "is {{ git_folder }} clean?"
command: git status --porcelain
args:
@ -50,7 +49,7 @@
register: commit_end_run
when:
- not ansible_check_mode
- git_status.stdout
- git_status.stdout | length > 0
ignore_errors: yes
tags:
- etc-git

View File

@ -33,7 +33,9 @@
- ansible_distribution_major_version is version('10', '>=')
- name: Check if cron is installed
shell: "dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'"
shell: "set -o pipefail && dpkg -l cron 2>/dev/null | grep -q -E '^(i|h)i'"
args:
executable: /bin/bash
failed_when: False
changed_when: False
check_mode: no

View File

@ -46,7 +46,7 @@
lineinfile:
dest: "{{ repository_path }}/.gitignore"
line: "{{ item }}"
with_items: "{{ gitignore_items | default([]) }}"
loop: "{{ gitignore_items | default([]) }}"
tags:
- etc-git
@ -68,6 +68,6 @@
chdir: "{{ repository_path }}"
warn: no
register: git_commit
when: git_log.rc != 0 or (git_init is defined and git_init.changed)
when: git_log.rc != 0 or (git_init is defined and git_init is changed)
tags:
- etc-git

View File

@ -112,9 +112,9 @@ openssl_selfsigned() {
[ -r "${key}" ] || error "File ${key} is not readable"
[ -w "${crt_dir}" ] || error "Directory ${crt_dir} is not writable"
if grep -q SAN "${cfg}"; then
"${OPENSSL_BIN}" x509 -req -sha256 -days 365 -in "${csr}" -extensions SAN -extfile "${cfg}" -signkey "${key}" -out "${crt}" 2> /dev/null
"${OPENSSL_BIN}" x509 -req -sha256 -days 365 -in "${csr}" -extensions SAN -extfile "${cfg}" -signkey "${key}" -out "${crt}" 2>/dev/null
else
"${OPENSSL_BIN}" x509 -req -sha256 -days 365 -in "${csr}" -signkey "${key}" -out "${crt}" 2> /dev/null
"${OPENSSL_BIN}" x509 -req -sha256 -days 365 -in "${csr}" -signkey "${key}" -out "${crt}" 2>/dev/null
fi
[ -r "${crt}" ] || error "Something went wrong, ${crt} has not been generated"
@ -126,7 +126,7 @@ openssl_key(){
[ -w "${key_dir}" ] || error "Directory ${key_dir} is not writable"
"${OPENSSL_BIN}" genrsa -out "${key}" "${size}" 2> /dev/null
"${OPENSSL_BIN}" genrsa -out "${key}" "${size}" 2>/dev/null
[ -r "${key}" ] || error "Something went wrong, ${key} has not been generated"
}

View File

@ -1,18 +1,28 @@
galaxy_info:
author: Evolix
company: Evolix
description: Install evoacme ; a wrapper for Certbot (Let's Encrypt)
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
min_ansible_version: 2.2
min_ansible_version: "2.2"
platforms:
- name: Debian
versions:
- stretch
- buster
- name: Debian
versions:
- jessie
- stretch
- buster
galaxy_tags: []
# List tags for your role here, one per line. A tag is
# a keyword that describes and categorizes the role.
# Users find roles by searching for tags. Be sure to
# remove the '[]' above if you add tags to this list.
#
# NOTE: A tag is limited to a single word comprised of
# alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.

View File

@ -4,7 +4,7 @@
section: 'req'
option: "{{ item.name }}"
value: "{{ item.var }}"
with_items:
loop:
- { name: 'default_bits', var: "{{ evoacme_ssl_key_size }}" }
- { name: 'encrypt_key', var: 'yes' }
- { name: 'distinguished_name', var: 'req_dn' }
@ -16,7 +16,7 @@
section: 'req_dn'
option: "{{ item.name }}"
value: "{{ item.var }}"
with_items:
loop:
- { name: 'C', var: "{{ evoacme_ssl_ct }}" }
- { name: 'ST', var: "{{ evoacme_ssl_state }}" }
- { name: 'L', var: "{{ evoacme_ssl_loc }}" }

View File

@ -16,4 +16,4 @@
src: "hooks/{{ hook_name }}"
dest: "{{ evoacme_hooks_dir }}/{{ hook_name }}"
mode: "0750"
when: _find_hook.stdout == ""
when: _find_hook.stdout | length == 0

View File

@ -6,7 +6,7 @@
- ansible_distribution == "Debian"
- ansible_distribution_major_version is version('9', '>=')
msg: only compatible with Debian >= 9
when: not evoacme_disable_debian_check
when: not (evoacme_disable_debian_check | bool)
- include: certbot.yml

View File

@ -39,6 +39,6 @@
file:
path: "/usr/local/bin/{{ item }}"
state: absent
with_items:
loop:
- 'make-csr'
- 'evoacme'

View File

@ -13,4 +13,4 @@
command: "bkctld restart {{ evolinux_hostname }}"
# - "bkctld sync {{ evolinux_hostname }}"
delegate_to: "{{ evobackup_client__hosts[0].ip }}"
when: evobackup_client__hosts|length > 1
when: evobackup_client__hosts | length > 1

View File

@ -14,7 +14,7 @@
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 }}"
loop: "{{ evobackup_client__hosts }}"
notify: restart minifirewall
when: evobackup_client__minifirewall.stat.exists
tags:

View File

@ -6,11 +6,13 @@
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"
loop: "{{ query('first_found', templates) }}"
vars:
templates:
- "templates/evobackup-client/{{ evobackup_client__cron_template_name }}.{{ inventory_hostname }}.sh.j2"
- "templates/evobackup-client/{{ evobackup_client__cron_template_name }}.{{ host_group | default('all') }}.sh.j2"
- "templates/evobackup-client/{{ evobackup_client__cron_template_name }}.sh.j2"
- "templates/zzz_evobackup.default.sh.j2"
tags:
- evobackup_client
- evobackup_client_backup_scripts

View File

@ -5,7 +5,7 @@
path: /root/.ssh/known_hosts
name: "[{{ item.name }}]:{{ item.port }}"
key: "[{{ item.name }}]:{{ item.port }} {{ item.fingerprint }}"
with_list: "{{ evobackup_client__hosts }}"
loop: "{{ evobackup_client__hosts }}"
tags:
- evobackup_client
- evobackup_client_backup_hosts

View File

@ -124,7 +124,7 @@ pick_server() {
if [ -e "${PIDFILE}" ]; then
pid=$(cat "${PIDFILE}")
# Does process still exist ?
if kill -0 "${pid}" 2> /dev/null; then
if kill -0 "${pid}" 2>/dev/null; then
# Killing the childs of evobackup.
for ppid in $(pgrep -P "${pid}"); do
kill -9 "${ppid}";

View File

@ -109,7 +109,7 @@ is_pack_samba(){
}
is_installed(){
for pkg in "$@"; do
dpkg -l "$pkg" 2> /dev/null | grep -q -E '^(i|h)i' || return 1
dpkg -l "$pkg" 2>/dev/null | grep -q -E '^(i|h)i' || return 1
done
}
minifirewall_file() {

View File

@ -7,13 +7,14 @@ galaxy_info:
license: GPLv2
min_ansible_version: 2.2
min_ansible_version: "2.2"
platforms:
- name: Debian
versions:
- jessie
- squeeze
- name: Debian
versions:
- jessie
- stretch
- buster
galaxy_tags: []
# List tags for your role here, one per line. A tag is

View File

@ -1,7 +1,9 @@
---
- name: Check if cron is installed
shell: "dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'"
shell: "set -o pipefail && dpkg -l cron 2>/dev/null | grep -q -E '^(i|h)i'"
args:
executable: /bin/bash
failed_when: False
changed_when: False
check_mode: no

View File

@ -10,6 +10,6 @@
- debug:
var: evocheck_run.stdout_lines
when: evocheck_run.stdout != ""
when: evocheck_run.stdout | length > 0
tags:
- evocheck-exec

View File

@ -7,4 +7,4 @@
when: evocheck_force_install == "package"
- include: cron.yml
when: evocheck_update_crontab
when: evocheck_update_crontab | bool

View File

@ -51,7 +51,7 @@ evolinux_kernel_include: True
evolinux_kernel_reboot_after_panic: True
evolinux_kernel_disable_tcp_timestamps: True
evolinux_kernel_customize_swappiness: True
evolinux_kernel_swappiness: 20
evolinux_kernel_swappiness: "20"
evolinux_kernel_cve20165696: True
# fstab

View File

@ -1,18 +1,28 @@
galaxy_info:
author: Evolix
company: Evolix
description: Evolix usual customizations for a Debian installation.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
min_ansible_version: 2.2
min_ansible_version: "2.2"
platforms:
- name: Debian
versions:
- jessie
- stretch
- name: Debian
versions:
- jessie
- stretch
- buster
galaxy_tags: []
# List tags for your role here, one per line. A tag is
# a keyword that describes and categorizes the role.
# Users find roles by searching for tags. Be sure to
# remove the '[]' above if you add tags to this list.
#
# NOTE: A tag is limited to a single word comprised of
# alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.

View File

@ -4,7 +4,7 @@
path: /var/www
state: directory
mode: "0755"
when: evolinux_default_www_files
when: evolinux_default_www_files | bool
- name: images are copied
copy:
@ -13,7 +13,7 @@
mode: "0644"
directory_mode: "0755"
follow: yes
when: evolinux_default_www_files
when: evolinux_default_www_files | bool
- name: index is copied
template:
@ -21,7 +21,7 @@
dest: /var/www/index.html
mode: "0644"
force: no
when: evolinux_default_www_files
when: evolinux_default_www_files | bool
# SSL cert
@ -43,6 +43,6 @@
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 | bool
- meta: flush_handlers

View File

@ -17,7 +17,7 @@
notify: remount /home
when:
- fstab_content.stdout | regex_search('\s/home\s')
- evolinux_fstab_home
- evolinux_fstab_home | bool
- name: /tmp partition is customized
replace:
@ -26,7 +26,7 @@
replace: '\1{{ evolinux_fstab_tmp_options | mandatory }}\3'
when:
- fstab_content.stdout | regex_search('\s/tmp\s')
- evolinux_fstab_tmp
- evolinux_fstab_tmp | bool
- name: /usr partition is customized
replace:
@ -35,7 +35,7 @@
replace: '\1{{ evolinux_fstab_usr_options | mandatory }}\3'
when:
- fstab_content.stdout | regex_search('\s/usr\s')
- evolinux_fstab_usr
- evolinux_fstab_usr | bool
- name: /var partition is customized
replace:
@ -45,7 +45,7 @@
notify: remount /var
when:
- fstab_content.stdout | regex_search('\s/var\s')
- evolinux_fstab_var
- evolinux_fstab_var | bool
- name: /var/tmp is created
mount:
@ -55,7 +55,7 @@
opts: "{{ evolinux_fstab_var_tmp_options | mandatory }}"
state: mounted
when:
- evolinux_fstab_var_tmp
- evolinux_fstab_var_tmp | bool
- name: /dev/shm is created (Debian 10 and later)
mount:
@ -65,7 +65,7 @@
opts: "{{ evolinux_fstab_dev_shm_options | mandatory }}"
state: mounted
when:
- evolinux_fstab_dev_shm
- evolinux_fstab_dev_shm | bool
- ansible_distribution_major_version is version('10', '>=')
- meta: flush_handlers

View File

@ -29,7 +29,7 @@
# HP gen <10: Hewlett-Packard Company Smart Array
# HP gen >=10: Adaptec Smart Storage PQI
- name: Detect if RAID is installed
shell: lspci -q | grep -e "RAID bus controller" -e "Serial Attached SCSI controller"
shell: "set -o pipefail && lspci -q | grep -e 'RAID bus controller' -e 'Serial Attached SCSI controller'"
check_mode: no
register: raidmodel
changed_when: "'FAILED' in raidmodel.stdout"
@ -37,10 +37,20 @@
- name: HPE Smart Storage Administrator (ssacli) is present
block:
- name: Add HPE GPG key
- name: HPE GPG embedded key is absent
apt_key:
#url: https://downloads.linux.hpe.com/SDR/hpePublicKey2048_key1.pub
data: "{{ lookup('file', 'hpePublicKey2048_key1.pub') }}"
id: "26C2B797"
keyring: /etc/apt/trusted.gpg
state: absent
- name: HPE GPG key is installed
copy:
src: hpePublicKey2048_key1.asc
dest: /etc/apt/trusted.gpg.d/hpePublicKey2048_key1.asc
force: yes
mode: "0644"
owner: root
group: root
- name: Add HPE repository
apt_repository:
@ -93,10 +103,21 @@
- name: MegaRAID SAS package is present
block:
- name: Add HW tool GPG key
- name: HWRaid embedded GPG key is absent
apt_key:
# url: https://hwraid.le-vert.net/debian/hwraid.le-vert.net.gpg.key
data: "{{ lookup('file', 'hwraid.le-vert.net.gpg.key') }}"
id: "23B3D3B4"
keyring: /etc/apt/trusted.gpg
state: absent
when: ansible_distribution_major_version is version('9', '>=')
- name: HWRaid GPG key is installed
copy:
src: hwraid.le-vert.net.asc
dest: /etc/apt/trusted.gpg.d/hwraid.le-vert.net.asc
force: yes
mode: "0644"
owner: root
group: root
when: ansible_distribution_major_version is version('9', '>=')
- name: Add HW tool repository

View File

@ -7,14 +7,14 @@
- name: Set hostname "{{ evolinux_hostname }}"
hostname:
name: "{{ evolinux_hostname }}"
when: evolinux_hostname_hosts
when: evolinux_hostname_hosts | bool
- name: Set right localhost line in /etc/hosts
replace:
dest: /etc/hosts
regexp: '^127.0.0.1(\s+)localhost.*$'
replace: '127.0.0.1\1localhost.localdomain localhost'
when: evolinux_hostname_hosts
when: evolinux_hostname_hosts | bool
- name: Set ip+fqdn+hostname in /etc/hosts
lineinfile:
@ -22,21 +22,21 @@
regexp: '^{{ ansible_default_ipv4.address }}\s+'
line: "{{ ansible_default_ipv4.address }} {{ [evolinux_fqdn, evolinux_internal_fqdn] | unique | join(' ') }} {{ [evolinux_hostname, evolinux_internal_hostname] | unique | join(' ') }}"
insertafter: '127.0.0.1\s+localhost.localdomain'
when: evolinux_hostname_hosts
when: evolinux_hostname_hosts | bool
- name: 127.0.1.1 is removed
lineinfile:
dest: /etc/hosts
regexp: '^127.0.1.1\s+'
state: absent
when: evolinux_hostname_hosts
when: evolinux_hostname_hosts | bool
- name: /etc/mailname is up-to-date
copy:
dest: /etc/mailname
content: "{{ evolinux_fqdn }}\n"
force: yes
when: evolinux_hostname_mailname
when: evolinux_hostname_mailname | bool
# Override facts

View File

@ -7,10 +7,10 @@
sysctl_file: "{{ evolinux_kernel_sysctl_path }}"
state: present
reload: yes
with_items:
loop:
- { name: kernel.panic_on_oops, value: 1 }
- { name: kernel.panic, value: 60 }
when: evolinux_kernel_reboot_after_panic
when: evolinux_kernel_reboot_after_panic | bool
- name: Don't reboot after panic
sysctl:
@ -18,10 +18,10 @@
sysctl_file: "{{ evolinux_kernel_sysctl_path }}"
state: absent
reload: yes
with_items:
loop:
- kernel.panic_on_oops
- kernel.panic
when: not evolinux_kernel_reboot_after_panic
when: not evolinux_kernel_reboot_after_panic | bool
- name: Disable net.ipv4.tcp_timestamps
sysctl:
@ -30,7 +30,7 @@
sysctl_file: "{{ evolinux_kernel_sysctl_path }}"
state: present
reload: yes
when: evolinux_kernel_disable_tcp_timestamps
when: evolinux_kernel_disable_tcp_timestamps | bool
- name: Customize the swappiness
sysctl:
@ -39,16 +39,16 @@
sysctl_file: "{{ evolinux_kernel_sysctl_path }}"
state: present
reload: yes
when: evolinux_kernel_customize_swappiness
when: evolinux_kernel_customize_swappiness | bool
- name: Patch for TCP stack vulnerability CVE-2016-5696
sysctl:
name: net.ipv4.tcp_challenge_ack_limit
value: 1073741823
value: "1073741823"
sysctl_file: "{{ evolinux_kernel_sysctl_path }}"
state: present
reload: yes
when: evolinux_kernel_cve20165696
when: evolinux_kernel_cve20165696 | bool
- name: Patch for TCP stack vulnerability CVE-2018-5391 (FragmentSmack)
sysctl:
@ -57,10 +57,10 @@
sysctl_file: "{{ evolinux_kernel_sysctl_path }}"
state: present
reload: yes
with_items:
- { name: "net.ipv4.ipfrag_low_thresh", value: 196608 }
- { name: "net.ipv6.ip6frag_low_thresh", value: 196608 }
- { name: "net.ipv4.ipfrag_high_thresh", value: 262144 }
- { name: "net.ipv6.ip6frag_high_thresh", value: 262144 }
loop:
- { name: "net.ipv4.ipfrag_low_thresh", value: "196608" }
- { name: "net.ipv6.ip6frag_low_thresh", value: "196608" }
- { name: "net.ipv4.ipfrag_high_thresh", value: "262144" }
- { name: "net.ipv6.ip6frag_high_thresh", value: "262144" }
- meta: flush_handlers

View File

@ -8,7 +8,7 @@
dest: /etc/rsyslog.conf
mode: "0644"
notify: restart rsyslog
when: evolinux_logs_rsyslog_conf
when: evolinux_logs_rsyslog_conf | bool
- name: Disable logrotate default conf
command: mv /etc/logrotate.d/rsyslog /etc/logrotate.d/rsyslog.disabled
@ -16,25 +16,25 @@
removes: /etc/logrotate.d/rsyslog
creates: /etc/logrotate.d/rsyslog.disabled
notify: restart rsyslog
when: evolinux_logs_disable_logrotate_rsyslog
when: evolinux_logs_disable_logrotate_rsyslog | bool
- name: Copy many logrotate files
copy:
src: logs/logrotate.d/
dest: /etc/logrotate.d/
when: evolinux_logs_logrotate_confs
when: evolinux_logs_logrotate_confs | bool
- name: Copy rsyslog logrotate file
template:
src: logs/zsyslog.j2
dest: /etc/logrotate.d/zsyslog
when: evolinux_logs_logrotate_confs
when: evolinux_logs_logrotate_confs | bool
- name: Configure logrotate.conf
replace:
dest: /etc/logrotate.conf
regexp: "rotate [0-9]+"
replace: "rotate 12"
when: evolinux_logs_default_rotate
when: evolinux_logs_default_rotate | bool
- meta: flush_handlers

View File

@ -13,50 +13,50 @@
vars:
apt_install_basics: "{{ evolinux_apt_replace_default_sources }}"
apt_install_evolix_public: "{{ evolinux_apt_public_sources }}"
when: evolinux_apt_include
when: evolinux_apt_include | bool
- name: /etc versioning with Git
include_role:
name: evolix/etc-git
when: evolinux_etcgit_include
when: evolinux_etcgit_include | bool
- name: /etc/evolinux base
include: etc-evolinux.yml
when: evolinux_etcevolinux_include
when: evolinux_etcevolinux_include | bool
- name: Hostname
include: hostname.yml
when: evolinux_hostname_include
when: evolinux_hostname_include | bool
- name: Kernel tuning
include: kernel.yml
when: evolinux_kernel_include
when: evolinux_kernel_include | bool
- name: Fstab configuration
include: fstab.yml
when: evolinux_fstab_include
when: evolinux_fstab_include | bool
- name: Packages
include: packages.yml
when: evolinux_packages_include
when: evolinux_packages_include | bool
- name: System settings
include: system.yml
when: evolinux_system_include
when: evolinux_system_include | bool
- name: Minifirewall
include_role:
name: evolix/minifirewall
when: evolinux_minifirewall_include
when: evolinux_minifirewall_include | bool
- name: Evomaintenance
include_role:
name: evolix/evomaintenance
when: evolinux_evomaintenance_include
when: evolinux_evomaintenance_include | bool
- name: SSH configuration
include: ssh.yml
when: evolinux_ssh_include
when: evolinux_ssh_include | bool
### disabled because of a memory leak
# - name: Create evolinux users
@ -66,66 +66,66 @@
- name: Root user configuration
include: root.yml
when: evolinux_root_include
when: evolinux_root_include | bool
- name: Postfix
include: postfix.yml
when: evolinux_postfix_include
when: evolinux_postfix_include | bool
- name: Logs management
include: logs.yml
when: evolinux_logs_include
when: evolinux_logs_include | bool
- name: Default index page
include: default_www.yml
when: evolinux_default_www_include
when: evolinux_default_www_include | bool
- name: Hardware drivers and tools
include: hardware.yml
when: evolinux_hardware_include
when: evolinux_hardware_include | bool
- name: Customize for Online.net
include: provider_online.yml
when: evolinux_provider_online_include
when: evolinux_provider_online_include | bool
- name: Customize for Orange FCE
include: provider_orange_fce.yml
when: evolinux_provider_orange_fce_include
when: evolinux_provider_orange_fce_include | bool
- name: Override Log2mail service
include: log2mail.yml
when: evolinux_log2mail_include
when: evolinux_log2mail_include | bool
- include: motd.yml
- name: Munin
include_role:
name: evolix/munin
when: evolinux_munin_include
when: evolinux_munin_include | bool
- name: Nagios/NRPE
include_role:
name: evolix/nagios-nrpe
when: evolinux_nagios_nrpe_include
when: evolinux_nagios_nrpe_include | bool
- name: fail2ban
include_role:
name: evolix/fail2ban
when: evolinux_fail2ban_include
when: evolinux_fail2ban_include | bool
- name: Evocheck
include_role:
name: evolix/evocheck
vars:
evocheck_force_install: "{{ evolinux_evocheck_force_install }}"
when: evolinux_evocheck_include
when: evolinux_evocheck_include | bool
- name: Listupgrade
include_role:
name: evolix/listupgrade
when: evolinux_listupgrade_include
when: evolinux_listupgrade_include | bool
- name: Generate ldif script
include_role:
name: evolix/generate-ldif
when: evolinux_generateldif_include
when: evolinux_generateldif_include | bool

View File

@ -7,11 +7,12 @@
owner: root
group: root
mode: "0644"
with_first_found:
- files:
- "motd/motd.{{ inventory_hostname }}.j2"
- "motd/motd.{{ host_group }}.j2"
- "motd/motd.default.j2"
skip: True
loop: "{{ query('first_found', templates) }}"
vars:
templates:
- "templates/motd/motd.{{ inventory_hostname }}.j2"
- "templates/motd/motd.{{ host_group | default('all') }}.j2"
- "templates/motd/motd.default.j2"
- "templates/motd.default.j2"
tags:
- motd

View File

@ -16,7 +16,7 @@
- ssl-cert
- ca-certificates
- rename
when: evolinux_packages_system
when: evolinux_packages_system | bool
- name: Install/Update diagnostic tools
apt:
@ -34,7 +34,7 @@
- telnet
- traceroute
- man
when: evolinux_packages_diagnostic
when: evolinux_packages_diagnostic | bool
- name: Install/Update hardware tools
apt:
@ -42,7 +42,7 @@
- hdparm
- smartmontools
- lm-sensors
when: evolinux_packages_hardware
when: evolinux_packages_hardware | bool
- name: Install/Update common tools
apt:
@ -58,21 +58,21 @@
- bc
- pinentry-curses
- ncurses-term
when: evolinux_packages_common
when: evolinux_packages_common | bool
- name: Be sure that openntpd package is absent/purged
apt:
name: openntpd
state: absent
purge: True
when: evolinux_packages_purge_openntpd
when: evolinux_packages_purge_openntpd | bool
- name: the chrony package is absent
apt:
name: chrony
purge: True
state: absent
when: evolinux_packages_purge_chrony
when: evolinux_packages_purge_chrony | bool
- name: Be sure locate/mlocate is absent/purged
apt:
@ -81,19 +81,19 @@
- mlocate
state: absent
purge: yes
when: evolinux_packages_purge_locate
when: evolinux_packages_purge_locate | bool
- name: Install/Update serveur-base meta-package
apt:
name: serveur-base
allow_unauthenticated: yes
when: evolinux_packages_serveur_base
when: evolinux_packages_serveur_base | bool
- name: Install/Update packages for Stretch and later
apt:
name: net-tools
when:
- evolinux_packages_stretch
- evolinux_packages_stretch | bool
- ansible_distribution_major_version is version('9', '>=')
- name: Install/Update packages for Buster and later
@ -102,7 +102,7 @@
- spectre-meltdown-checker
- binutils
when:
- evolinux_packages_buster
- evolinux_packages_buster | bool
- ansible_distribution_major_version is version('10', '>=')
- name: Customize logcheck recipient
@ -110,7 +110,7 @@
dest: /etc/logcheck/logcheck.conf
regexp: '^SENDMAILTO=".*"$'
line: 'SENDMAILTO="{{ logcheck_alert_email or general_alert_email | mandatory }}"'
when: evolinux_packages_logcheck_recipient
when: evolinux_packages_logcheck_recipient | bool
- name: Deleting rpcbind and nfs-common
apt:
@ -118,7 +118,7 @@
- rpcbind
- nfs-common
state: absent
when: evolinux_packages_delete_nfs
when: evolinux_packages_delete_nfs | bool
# TODO: use ini_file when Ansible > 2.1 (no_extra_spaces: yes)
@ -128,11 +128,11 @@
dest: /etc/apt/listchanges.conf
regexp: '^{{ item.option }}\s*='
line: "{{ item.option }}={{ item.value }}"
with_items:
loop:
- { option: "confirm", value: "1" }
- { option: "which", value: "both" }
when:
- evolinux_packages_listchanges
- evolinux_packages_listchanges | bool
- ansible_distribution == "Debian"
- ansible_distribution_release == "jessie"

View File

@ -6,7 +6,7 @@
- postfix
- mailgraph
state: present
when: evolinux_postfix_packages
when: evolinux_postfix_packages | bool
tags:
- packages
- postfix
@ -32,9 +32,10 @@
- postfix
- name: fetch users list
shell: getent passwd | cut -d":" -f 1 | grep -v root
shell: "set -o pipefail && getent passwd | cut -d':' -f 1 | grep -v root"
args:
executable: /bin/bash
check_mode: no
register: non_root_users_list
changed_when: False
tags:
@ -45,9 +46,9 @@
dest: /etc/aliases
regexp: "^{{ item }}:.*"
line: "{{ item }}: root"
with_items: "{{ non_root_users_list.stdout_lines }}"
loop: "{{ non_root_users_list.stdout_lines }}"
notify: newaliases
when: evolinux_postfix_users_alias_root
when: evolinux_postfix_users_alias_root | bool
tags:
- postfix
@ -56,7 +57,7 @@
dest: /etc/aliases
regexp: "^{{ item }}:.*"
line: "{{ item }}: root"
with_items:
loop:
- postmaster
- abuse
- mailer-daemon
@ -64,7 +65,7 @@
- error
- bounce
notify: newaliases
when: evolinux_postfix_mailer_alias_root
when: evolinux_postfix_mailer_alias_root | bool
tags:
- postfix
@ -74,7 +75,7 @@
regexp: "^root:"
line: "root: {{ postfix_alias_email or general_alert_email | mandatory }}"
notify: newaliases
when: evolinux_postfix_root_alias
when: evolinux_postfix_root_alias | bool
tags:
- postfix
@ -89,7 +90,7 @@
- exim4-daemon-light
purge: yes
state: absent
when: evolinux_postfix_purge_exim
when: evolinux_postfix_purge_exim | bool
tags:
- packages
- postfix

View File

@ -5,7 +5,7 @@
sysctl_file: /etc/sysctl.d/evolinux_fce.conf
state: present
reload: yes
with_items:
loop:
- { name: net.ipv4.tcp_keepalive_time, value: 250 }
- { name: net.ipv4.tcp_keepalive_intvl, value: 60 }
- { name: net.ipv6.conf.all.disable_ipv6, value: 1 }

View File

@ -5,7 +5,7 @@
path: /root
state: directory
mode: "0700"
when: evolinux_root_chmod
when: evolinux_root_chmod | bool
- name: "Customize root's bashrc..."
lineinfile:
@ -13,13 +13,13 @@
line: "{{ item }}"
create: yes
state: present
with_items:
loop:
- "export HISTCONTROL=$HISTCONTROL${HISTCONTROL+,}ignoreboth,erasedups"
- "export HISTSIZE=65535"
- "export HISTTIMEFORMAT=\"%c : \""
- "shopt -s histappend"
- "PROMPT_COMMAND=\"history -a;${PROMPT_COMMAND}\""
when: evolinux_root_bashrc
when: evolinux_root_bashrc | bool
## .bash_history should be append-only
@ -28,14 +28,14 @@
content: ""
dest: "/root/.bash_history"
force: no
when: evolinux_root_bash_history
when: evolinux_root_bash_history | bool
- name: Set umask in /root/.profile
lineinfile:
dest: "/root/.profile"
line: "umask 0077"
regexp: "umask [0-9]+"
when: evolinux_root_umask
when: evolinux_root_umask | bool
- name: "/usr/share/scripts is present in root's PATH"
lineinfile:
@ -48,7 +48,7 @@
src: root/gitconfig
dest: "/root/.gitconfig"
force: no
when: evolinux_root_gitconfig
when: evolinux_root_gitconfig | bool
- name: Is .bash_history append-only
shell: lsattr /root/.bash_history | grep -E "^.*a.* "
@ -61,7 +61,7 @@
- name: Set .bash_history append-only
command: chattr +a /root/.bash_history
when:
- evolinux_root_bash_history_appendonly
- evolinux_root_bash_history_appendonly | bool
- bash_history_append_only.rc != 0
- "'Inappropriate ioctl' not in bash_history_append_only.stderr"
@ -71,7 +71,7 @@
regexp: '^SELECTED_EDITOR='
line: "SELECTED_EDITOR=\"/usr/bin/vim.basic\""
create: yes
when: evolinux_root_vim_default
when: evolinux_root_vim_default | bool
- name: Setting vim root configuration
lineinfile:
@ -79,14 +79,14 @@
line: "{{ item }}"
create: yes
state: present
with_items:
loop:
- "syntax on"
- "set background=dark"
- "set expandtab"
- "set tabstop=4"
- "set softtabstop=4"
- "set shiftwidth=4"
when: evolinux_root_vim_conf
when: evolinux_root_vim_conf | bool
- name: disable SSH access for root
replace:
@ -95,7 +95,7 @@
replace: "PermitRootLogin no"
validate: '/usr/sbin/sshd -t -f %s'
notify: reload sshd
when: evolinux_root_disable_ssh
when: evolinux_root_disable_ssh | bool
### Disabled : it seems useless and too dangerous for now
# - name: remove root from AllowUsers directive

View File

@ -51,7 +51,7 @@
regexp: '^AcceptEnv'
replace: "#AcceptEnv"
notify: reload sshd
when: evolinux_ssh_disable_acceptenv
when: evolinux_ssh_disable_acceptenv | bool
- name: Set log level to verbose (for Debian >= 9)
replace:
@ -66,7 +66,7 @@
changed_when: False
register: logname
check_mode: no
when: evolinux_ssh_allow_current_user
when: evolinux_ssh_allow_current_user | bool
# we must double-escape caracters, because python
- name: verify AllowUsers directive
@ -75,7 +75,7 @@
changed_when: False
register: grep_allowusers_ssh
check_mode: no
when: evolinux_ssh_allow_current_user
when: evolinux_ssh_allow_current_user | bool
- name: "Add AllowUsers sshd directive for current user"
lineinfile:

View File

@ -5,7 +5,7 @@
path: /tmp
state: directory
mode: "u=rwx,g=rwx,o=rwxt"
when: evolinux_system_chmod_tmp
when: evolinux_system_chmod_tmp | bool
- name: Setting default locales
lineinfile:
@ -13,12 +13,12 @@
line: "{{ item }}"
create: yes
state: present
with_items:
loop:
- "en_US.UTF-8 UTF-8"
- "fr_FR ISO-8859-1"
- "fr_FR.UTF-8 UTF-8"
register: default_locales
when: evolinux_system_locales
when: evolinux_system_locales | bool
- name: Reconfigure locales
command: /usr/sbin/locale-gen
@ -28,7 +28,7 @@
timezone:
name: "{{ evolinux_system_timezone | mandatory }}"
notify: restart cron
when: evolinux_system_set_timezone
when: evolinux_system_set_timezone | bool
# TODO : find a way to force the console-data configuration
# non-interactively (like tzdata ↑)
@ -41,13 +41,13 @@
dest: /etc/vim/vimrc
regexp: 'let g:skip_defaults_vim ='
line: 'let g:skip_defaults_vim = 1'
when: evolinux_system_vim_skip_defaults
when: evolinux_system_vim_skip_defaults | bool
- name: Setting vim as default editor
alternatives:
name: editor
path: /usr/bin/vim.basic
when: evolinux_system_vim_default_editor
when: evolinux_system_vim_default_editor | bool
- name: Add "umask 027" to /etc/profile.d/evolinux.sh
lineinfile:
@ -55,14 +55,14 @@
line: "umask 027"
create: yes
state: present
when: evolinux_system_profile
when: evolinux_system_profile | bool
- name: Set /etc/adduser.conf DIR_MODE to 0700
replace:
dest: /etc/adduser.conf
regexp: "^DIR_MODE=0755$"
replace: "DIR_MODE=0700"
when: evolinux_system_dirmode_adduser
when: evolinux_system_dirmode_adduser | bool
# TODO: trouver comment ne pas faire ça sur Xen Dom-U
@ -72,7 +72,7 @@
line: "tty2"
create: yes
state: present
when: evolinux_system_restrict_securetty
when: evolinux_system_restrict_securetty | bool
- name: Setting TMOUT to disconnect inactive users
lineinfile:
@ -80,15 +80,17 @@
line: "export TMOUT=36000"
create: yes
state: present
when: evolinux_system_set_timeout
when: evolinux_system_set_timeout | bool
#- name: Customizing /etc/fstab
- name: Check if cron is installed
shell: "dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'"
shell: "set -o pipefail && dpkg -l cron 2>/dev/null | grep -q -E '^(i|h)i'"
args:
executable: /bin/bash
check_mode: no
failed_when: False
changed_when: False
check_mode: no
register: is_cron_installed
- name: Set verbose logging for cron deamon
@ -97,7 +99,9 @@
line: "EXTRA_OPTS='-L 15'"
create: yes
state: present
when: is_cron_installed.rc == 0 and evolinux_system_cron_verboselog
when:
- is_cron_installed.rc == 0
- evolinux_system_cron_verboselog | bool
- name: Modify default umask for cron deamon
lineinfile:
@ -105,19 +109,23 @@
line: "umask 022"
create: yes
state: present
when: is_cron_installed.rc == 0 and evolinux_system_cron_umask
when:
- is_cron_installed.rc == 0
- evolinux_system_cron_umask | bool
- name: Randomize periodic crontabs
replace:
dest: /etc/crontab
regexp: "{{ item.regexp }}"
replace: "{{ item.replace }}"
with_items:
loop:
- { regexp: '^17((\s*\*){4})', replace: '{{ 59|random(start=1) }}\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: '^52\s*6(\s*1(\s*\*){2})', replace: '{{ 59|random(start=1) }} {{ [0,1,3,4,5,6,7]|random }}\1' }
when: is_cron_installed.rc == 0 and evolinux_system_cron_random
when:
- is_cron_installed.rc == 0
- evolinux_system_cron_random | bool
- include_role:
name: evolix/ntpd
@ -131,7 +139,7 @@
force: no
mode: "0755"
when:
- evolinux_system_alert5_init
- evolinux_system_alert5_init | bool
- ansible_distribution_release == "jessie" or ansible_distribution_release == "stretch"
- name: Enable alert5 init script (jessie/stretch)
@ -139,8 +147,8 @@
name: alert5
enabled: yes
when:
- evolinux_system_alert5_init
- evolinux_system_alert5_enable
- evolinux_system_alert5_init | bool
- evolinux_system_alert5_enable | bool
- ansible_distribution_release == "jessie" or ansible_distribution_release == "stretch"
@ -152,7 +160,7 @@
force: no
mode: "0755"
when:
- evolinux_system_alert5_init
- evolinux_system_alert5_init | bool
- ansible_distribution_major_version is version('10', '>=')
- name: Install alert5 service (buster)
@ -162,7 +170,7 @@
force: yes
mode: "0644"
when:
- evolinux_system_alert5_init
- evolinux_system_alert5_init | bool
- ansible_distribution_major_version is version('10', '>=')
- name: Enable alert5 init script (buster)
@ -171,8 +179,8 @@
daemon_reload: yes
enabled: yes
when:
- evolinux_system_alert5_init
- evolinux_system_alert5_enable
- evolinux_system_alert5_init | bool
- evolinux_system_alert5_enable | bool
- ansible_distribution_major_version is version('10', '>=')
## network interfaces
@ -189,7 +197,9 @@
dest: /etc/network/interfaces
regexp: "allow-hotplug"
replace: "auto"
when: evolinux_system_eni_auto and grep_hotplug_eni.rc == 0
when:
- evolinux_system_eni_auto | bool
- grep_hotplug_eni.rc == 0
## /sbin/deny

View File

@ -0,0 +1,4 @@
This server has been installed with Evolix Ansible roles.
https://gitea.evolix.org/evolix/ansible-roles
---

View File

@ -7,13 +7,14 @@ galaxy_info:
license: GPLv2
min_ansible_version: 2.2
min_ansible_version: "2.2"
platforms:
- name: Debian
versions:
- jessie
- stretch
- name: Debian
versions:
- jessie
- stretch
- buster
galaxy_tags: []
# List tags for your role here, one per line. A tag is

View File

@ -10,4 +10,4 @@
- name: "Content of /etc/evolinux/todo.txt"
debug:
var: evolinux_todo.stdout_lines
when: evolinux_todo.stdout != ""
when: evolinux_todo.stdout | length > 0

View File

@ -1,18 +1,28 @@
galaxy_info:
author: Evolix
company: Evolix
description: Creates evolinux users accounts.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
min_ansible_version: 2.2
min_ansible_version: "2.2"
platforms:
- name: Debian
versions:
- jessie
- stretch
- name: Debian
versions:
- jessie
- stretch
- buster
galaxy_tags: []
# List tags for your role here, one per line. A tag is
# a keyword that describes and categorizes the role.
# Users find roles by searching for tags. Be sure to
# remove the '[]' above if you add tags to this list.
#
# NOTE: A tag is limited to a single word comprised of
# alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.

View File

@ -9,22 +9,22 @@
- debug:
msg: "Warning: empty 'evolinux_users' variable, tasks will be skipped!"
when: evolinux_users == {}
when: evolinux_users | length == 0
- name: Create user accounts
include: user.yml
vars:
user: "{{ item.value }}"
with_dict: "{{ evolinux_users }}"
when: evolinux_users != {}
loop: "{{ evolinux_users | dict2items }}"
when: evolinux_users | length > 0
- name: Configure sudo
include: sudo.yml
vars:
user: "{{ item.value }}"
with_dict: "{{ evolinux_users }}"
when: evolinux_users != {}
loop: "{{ evolinux_users | dict2items }}"
when: evolinux_users | length > 0
- name: Configure SSH
include: ssh.yml
when: evolinux_users != {}
when: evolinux_users | length > 0

View File

@ -48,7 +48,7 @@
- include: ssh_allowusers.yml
vars:
user: "{{ item.value }}"
with_dict: "{{ evolinux_users }}"
loop: "{{ evolinux_users | dict2items }}"
when:
- ssh_allowusers
- not ssh_allowgroups
@ -59,6 +59,6 @@
regexp: '^PermitRootLogin (yes|without-password|prohibit-password)'
replace: "PermitRootLogin no"
notify: reload sshd
when: evolinux_root_disable_ssh
when: evolinux_root_disable_ssh | bool
- meta: flush_handlers

View File

@ -4,6 +4,8 @@
when: ansible_distribution_release == "jessie"
- include: sudo_stretch.yml
when: ansible_distribution_major_version is defined and ansible_distribution_major_version is version('9', '>=')
when:
- ansible_distribution_major_version is defined
- ansible_distribution_major_version is version('9', '>=')
- meta: flush_handlers

View File

@ -15,4 +15,4 @@
regexp: '^(User_Alias\s+ADMINS\s+=((?!{{ user.name }}).)*)$'
replace: '\1,{{ user.name }}'
validate: '/usr/sbin/visudo -cf %s'
when: not copy_sudoers_evolinux.changed
when: copy_sudoers_evolinux is not changed

View File

@ -4,11 +4,11 @@
- fail:
msg: "You must provide a value for the 'user.name ' variable."
when: user.name is not defined or user.name == ''
when: (user.name is not defined) or (user.name | length == 0)
- fail:
msg: "You must provide a value for the 'user.uid ' variable."
when: user.uid is not defined or user.uid == ''
when: (user.uid is not defined) or (user.uid | string | length == 0)
- name: "Test if '{{ user.name }}' exists"
command: 'id -u "{{ user.name }}"'
@ -102,7 +102,7 @@
state: present
when:
- evolinux_internal_group is defined
- evolinux_internal_group != ""
- evolinux_internal_group | length > 0
- ansible_distribution_major_version is version('9', '>=')
- name: "Unix user '{{ user.name }}' belongs to group '{{ evolinux_internal_group }}' (Debian 9 or later)"
@ -112,7 +112,7 @@
append: yes
when:
- evolinux_internal_group is defined
- evolinux_internal_group != ""
- evolinux_internal_group | length > 0
- ansible_distribution_major_version is version('9', '>=')
## Optional secondary groups, defined per user
@ -120,12 +120,12 @@
- name: "Secondary Unix groups are present"
group:
name: "{{ group }}"
with_items: "{{ user.groups }}"
loop: "{{ user.groups }}"
loop_control:
loop_var: group
when:
- user.groups is defined
- user.groups != []
- user.groups | length > 0
- name: "Unix user '{{ user.name }}' belongs to secondary groups"
user:
@ -134,7 +134,7 @@
append: yes
when:
- user.groups is defined
- user.groups != []
- user.groups | length > 0
# Permissions on home directory
@ -177,16 +177,20 @@
user: "{{ user.name }}"
key: "{{ user.ssh_key }}"
state: present
when: user.ssh_key is defined
when:
- user.ssh_key is defined
- user.ssh_key | length > 0
- name: "SSH public keys for '{{ user.name }}' are present"
authorized_key:
user: "{{ user.name }}"
key: "{{ ssk_key }}"
state: present
with_items: "{{ user.ssh_keys }}"
loop: "{{ user.ssh_keys }}"
loop_control:
loop_var: ssk_key
when: user.ssh_keys is defined
when:
- user.ssh_keys is defined
- user.ssh_keys | length > 0
- meta: flush_handlers

View File

@ -4,16 +4,16 @@
# Dependencies (all OS): git postgresql-client
# Dependencies (Debian): sudo
# Copyright 2007-2019 Evolix <info@evolix.fr>, Gregory Colpart <reg@evolix.fr>,
# Copyright 2007-2021 Evolix <info@evolix.fr>, Gregory Colpart <reg@evolix.fr>,
# Jérémy Lecour <jlecour@evolix.fr> and others.
VERSION="0.6.3"
VERSION="0.6.4"
show_version() {
cat <<END
evomaintenance version ${VERSION}
Copyright 2007-2019 Evolix <info@evolix.fr>,
Copyright 2007-2021 Evolix <info@evolix.fr>,
Gregory Colpart <reg@evolix.fr>,
Jérémy Lecour <jlecour@evolix.fr>
and others.
@ -178,9 +178,11 @@ is_repository_readonly() {
if [ "$(get_system)" = "OpenBSD" ]; then
partition=$(stat -f '%Sd' $1)
mount | grep ${partition} | grep -q "read-only"
else
elif command -v findmnt >/dev/null; then
mountpoint=$(stat -c '%m' $1)
findmnt ${mountpoint} --noheadings --output OPTIONS -O ro
else
grep /usr /proc/mounts | grep -E '\bro\b'
fi
}
remount_repository_readwrite() {

View File

@ -7,14 +7,14 @@ galaxy_info:
license: GPLv2
min_ansible_version: 2.2
min_ansible_version: "2.2"
platforms:
- name: Debian
versions:
- stretch
- jessie
- squeeze
- name: Debian
versions:
- jessie
- stretch
- buster
galaxy_tags: []
# List tags for your role here, one per line. A tag is

View File

@ -14,7 +14,7 @@
name:
- postgresql-client
state: present
when: evomaintenance_hook_db
when: evomaintenance_hook_db | bool
tags:
- evomaintenance
@ -42,7 +42,7 @@
mode: "{{ item.mode }}"
force: yes
backup: yes
with_items:
loop:
- { src: 'evomaintenance.sh', dest: '/usr/share/scripts/', mode: '0700' }
- { src: 'evomaintenance.tpl', dest: '/usr/share/scripts/', mode: '0600' }
tags:

View File

@ -1,66 +0,0 @@
---
- name: Dependencies are installed
openbsd_pkg:
name:
- postgresql-client
- curl
state: present
tags:
- evomaintenance
- name: /usr/share/scripts exists
file:
dest: /usr/share/scripts
mode: "0700"
owner: root
group: wheel
state: directory
tags:
- evomaintenance
- name: Evomaintenance script and template are installed
copy:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
owner: root
group: wheel
mode: "{{ item.mode }}"
force: yes
backup: yes
with_items:
- { src: 'evomaintenance.sh', dest: '/usr/share/scripts/', mode: '0700' }
- { src: 'evomaintenance.tpl', dest: '/usr/share/scripts/', mode: '0600' }
tags:
- evomaintenance
- name: Configuration is installed
template:
src: evomaintenance.j2
dest: /etc/evomaintenance.cf
owner: root
group: wheel
mode: "0600"
force: "{{ evomaintenance_force_config | bool }}"
tags:
- evomaintenance
- name: Copy mailevomaintenance
template:
src: mailevomaintenance.sh.j2
dest: /usr/share/scripts/mailevomaintenance.sh
owner: root
group: wheel
mode: "0700"
tags:
- evomaintenance
- name: Add mailevomaintenance cron
cron:
name: "mailevomaintenance"
job: "/usr/share/scripts/mailevomaintenance.sh"
minute: "50"
hour: "22"
disabled: yes
tags:
- mailevomaintenance

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