├── .gitignore ├── roles ├── common │ ├── templates │ │ ├── var_lib_fail2ban_emptylog.log.j2 │ │ ├── etc_sudoers.d_use-pty.j2 │ │ ├── var_log_firewalld-info.log.j2 │ │ ├── etc_ansible_facts.d_fail2ban.fact.j2 │ │ ├── etc_profile.d_tmout.sh.j2 │ │ ├── etc_ansible_facts.d_ssh.fact.j2 │ │ ├── etc_ssh_revoked_keys.j2 │ │ ├── etc_systemd_system_apt-daily-upgrade.timer.d_override.conf.j2 │ │ ├── etc_cron.allow.j2 │ │ ├── etc_ansible_facts.d_firewalld.fact.j2 │ │ ├── etc_default_rcS.j2 │ │ ├── etc_ansible_facts.d_msmtp.fact.j2 │ │ ├── etc_resolv.conf.j2 │ │ ├── etc_apt_apt.conf.d_99-autoremove.j2 │ │ ├── etc_modprobe.d_blacklist.conf.j2 │ │ ├── etc_fail2ban_jail.d_sshd.conf.j2 │ │ ├── etc_apt_apt.conf.d_99no-overwrite-conffiles.j2 │ │ ├── etc_apt_apt.conf.d_99norecommends.j2 │ │ ├── etc_apt_listbugs_ignore_bugs.j2 │ │ ├── etc_logrotate.d_wtmp.j2 │ │ ├── etc_fail2ban_jail.d_pam-generic.conf.j2 │ │ ├── etc_ansible_facts.d_common.fact.j2 │ │ ├── etc_sudoers.d_nopasswd.j2 │ │ ├── etc_apt_apt.conf.d_10apt-listbugs.j2 │ │ ├── etc_fail2ban_fail2ban.local.j2 │ │ ├── etc_systemd_system_firehol.service.j2 │ │ ├── etc_default_cron.j2 │ │ ├── etc_fail2ban_jail.local.j2 │ │ ├── etc_msmtprc.j2 │ │ └── etc_systemd_logind.conf.j2 │ ├── tasks │ │ ├── utils-reboot.yml │ │ ├── utils-shutdown.yml │ │ ├── dns.yml │ │ ├── ca-certificates.yml │ │ ├── hostname.yml │ │ ├── utils-fail2ban-get-banned.yml │ │ ├── utils-apt-upgrade.yml │ │ ├── datetime.yml │ │ ├── fact.yml │ │ ├── hosts.yml │ │ ├── remove-firehol.yml │ │ ├── utils-firewalld-info.yml │ │ ├── utils-apt-unattended-upgrade.yml │ │ ├── sysctl.yml │ │ ├── packages.yml │ │ ├── cron.yml │ │ ├── utils-debian11to12.yml │ │ ├── mail.yml │ │ ├── fail2ban.yml │ │ └── apt.yml │ ├── handlers │ │ └── main.yml │ └── meta │ │ └── main.yml ├── openldap │ ├── vars │ │ ├── Debian-buster.yml │ │ └── Debian-bullseye.yml │ ├── templates │ │ ├── etc_ansible_facts.d_openldap.fact.j2 │ │ ├── usr_local_bin_openldap-dump.sh.j2 │ │ ├── var_lib_ldap-account-manager_config_profiles_lam_default.group.j2 │ │ ├── etc_rsnapshot.d_openldap.conf.j2 │ │ ├── etc_ansible_facts.d_ldap_account_manager.fact.j2 │ │ ├── etc_ansible_facts.d_self_service_password.fact.j2 │ │ ├── etc_netdata_health.d_systemdunits.conf.d_openldap.conf.j2 │ │ ├── etc_netdata_go.d_httpcheck.conf.d_openldap.conf.j2 │ │ ├── var_lib_ldap-account-manager_config_profiles_lam_default.user.j2 │ │ ├── etc_php_PHPVERSION_fpm_pool.d_ldap-account-manager.conf.j2 │ │ ├── etc_php_PHPVERSION_fpm_pool.d_self-service-password.conf.j2 │ │ ├── etc_apache2_sites-available_ldap-account-manager.conf.j2 │ │ ├── etc_apache2_sites-available_self-service-password.conf.j2 │ │ ├── etc_ldap-account-manager_config.cfg.j2 │ │ ├── etc_default_slapd.j2 │ │ └── var_www_self-service-password_conf_config.inc.local.php.j2 │ ├── files │ │ ├── var_www_self-service-password_images_logo.png │ │ ├── var_www_self-service-password_images_background.png │ │ └── var_www_self-service-password_css_self-service-password.css │ ├── handlers │ │ └── main.yml │ ├── tasks │ │ ├── fact.yml │ │ ├── backups.yml │ │ ├── netdata.yml │ │ ├── ldap-account-manager-ssl-selfsigned.yml │ │ ├── self-service-password-ssl-selfsigned.yml │ │ ├── main.yml │ │ ├── openldap.yml │ │ └── ssl-selfsigned.yml │ └── meta │ │ └── main.yml ├── apache │ ├── vars │ │ ├── Debian-bookworm.yml │ │ ├── Debian-bullseye.yml │ │ └── Debian-buster.yml │ ├── templates │ │ ├── etc_ansible_facts.d_apache.fact.j2 │ │ ├── etc_php_PHPVERSION_cli_conf.d_20-apcu.ini.j2 │ │ ├── etc_php_PHPVERSION_apache2_conf.d_30-hide-header.ini.j2 │ │ ├── etc_apache2_conf-available_logging.conf.j2 │ │ ├── etc_rsyslog.d_php-fpm.conf.j2 │ │ ├── etc_netdata_health.d_systemdunits.conf.d_apache.conf.j2 │ │ ├── etc_apache2_conf-available_mod-md.conf.j2 │ │ ├── etc_systemd_system_apache2.service.d_override.conf.j2 │ │ ├── etc_apt_preferences.d_99-apache2-buster-backports.j2 │ │ ├── etc_apache2_ports.conf.j2 │ │ ├── etc_rsyslog.d_apache.conf.j2 │ │ ├── etc_netdata_go.d_httpcheck.conf.d_apache-reverseproxies.conf.j2 │ │ ├── etc_fail2ban_jail.d_apache.conf.j2 │ │ ├── etc_fail2ban_filter.d_apache-default-vhost.conf.j2 │ │ └── etc_apache2_conf-available_ssl-common.conf.j2 │ ├── handlers │ │ └── main.yml │ ├── tasks │ │ ├── mail.yml │ │ ├── firewalld.yml │ │ ├── rsyslog.yml │ │ ├── netdata.yml │ │ ├── fact.yml │ │ ├── fail2ban.yml │ │ ├── apache-mod-evasive.yml │ │ ├── checks.yml │ │ └── main.yml │ ├── meta │ │ └── main.yml │ └── files │ │ └── usr_local_bin_apache-mod-md-reload ├── monitoring_netdata │ ├── templates │ │ ├── etc_netdata_.opt-out-from-anonymous-statistics.j2 │ │ ├── etc_systemd_system_netdata.service.d_override.conf.j2 │ │ ├── etc_netdata_go.d_phpfpm.conf.d_000-phpfpm.conf.j2 │ │ ├── var_lib_debsecan_whitelist.j2 │ │ ├── var_lib_netdata_cloud.d_cloud.conf.j2 │ │ ├── etc_ansible_facts.d_netdata.fact.j2 │ │ ├── etc_netdata_python.d_apache.conf.j2 │ │ ├── etc_rsyslog.d_netdata.conf.j2 │ │ ├── etc_apt_sources.list.d_netdata-packagecloud.list.j2 │ │ ├── etc_netdata_go.d_httpcheck.conf.d_httpcheck.conf.j2 │ │ ├── etc_netdata_go.d_x509check.conf.d_x509check.conf.j2 │ │ ├── etc_firewalld_services_netdata.xml.j2 │ │ ├── etc_netdata_go.d_filecheck.conf.d_000-filecheck.conf.j2 │ │ ├── etc_netdata_go.d_httpcheck.conf.d_000-httpcheck.conf.j2 │ │ ├── etc_netdata_go.d_x509check.conf.d_000-x509check.conf.j2 │ │ ├── etc_cron.d_needrestart-autorestart.j2 │ │ ├── etc_systemd_system.conf.d_accounting.conf.j2 │ │ ├── etc_apt_preferences.d_99-netdata-packagecloud.j2 │ │ ├── etc_netdata_go.d_portcheck.conf.d_portcheck.conf.j2 │ │ ├── etc_netdata_go.d_portcheck.conf.d_000-portcheck.conf.j2 │ │ ├── etc_needrestart_conf.d_autorestart.conf.j2 │ │ ├── etc_netdata_health.d_processes.conf.j2 │ │ ├── etc_netdata_health.d_processes.conf.d_000-processes.conf.j2 │ │ ├── etc_default_smartmontools.j2 │ │ ├── etc_netdata_stream.conf.j2 │ │ ├── etc_cron.d_netdata-downtime.j2 │ │ ├── opt_netdata-logcount_logcount.sql.j2 │ │ ├── etc_default_debsecan.j2 │ │ ├── etc_netdata_health.d_dockerd.conf.j2 │ │ ├── etc_netdata_health.d_logcount.conf.j2 │ │ ├── etc_netdata_health.d_filecheck.conf.d_000-filecheck.conf.j2 │ │ ├── etc_netdata_fping.conf.j2 │ │ ├── etc_netdata_health.d_ping.conf.j2 │ │ ├── etc_netdata_go.d.conf.j2 │ │ └── etc_netdata_netdata.conf.j2 │ ├── vars │ │ ├── Debian-bookworm.yml │ │ ├── Debian-bullseye.yml │ │ ├── Debian-buster.yml │ │ └── Ubuntu-bionic.yml │ ├── files │ │ ├── usr_share_keyrings_netdata.gpg │ │ └── usr_local_bin_needrestart-autorestart │ ├── handlers │ │ └── main.yml │ ├── tasks │ │ ├── rsyslog.yml │ │ ├── utils-netdata-test-notifications.yml │ │ ├── fact.yml │ │ ├── utils-autorestart.yml │ │ ├── firewalld.yml │ │ ├── netdata-module-apt.yml │ │ ├── netdata-module-debsecan.yml │ │ └── netdata-module-needrestart.yml │ └── meta │ │ └── main.yml ├── docker │ ├── templates │ │ ├── etc_ansible_facts.d_docker.fact.j2 │ │ └── etc_docker_daemon.json.j2 │ ├── handlers │ │ └── main.yml │ ├── tasks │ │ ├── main.yml │ │ └── fact.yml │ ├── meta │ │ └── main.yml │ ├── README.md │ └── defaults │ │ └── main.yml ├── gitlab_runner │ ├── meta │ │ ├── .galaxy_install_info │ │ └── main.yml │ ├── tasks │ │ ├── main.yml │ │ └── checks.yml │ ├── templates │ │ ├── etc_apt_preferences.d_pin-gitlab-runner.pref.j2 │ │ └── etc_gitlab-runner_config.toml.j2 │ ├── handlers │ │ └── main.yml │ ├── defaults │ │ └── main.yml │ └── README.md ├── monitoring_rsyslog │ ├── templates │ │ ├── etc_ansible_facts.d_rsyslog.fact.j2 │ │ ├── etc_rsyslog.d_000-imfile.conf.j2 │ │ ├── etc_rsyslog.d_000-singlefile.conf.j2 │ │ ├── etc_rsyslog.d_000-custom.conf.j2 │ │ ├── etc_rsyslog.d_fail2ban.conf.j2 │ │ ├── etc_rsyslog.d_000-discard.conf.j2 │ │ ├── etc_firewalld_services_syslog-tcp-ssl.xml.j2 │ │ ├── etc_rsyslog.d_apt.conf.j2 │ │ ├── etc_logrotate.d_rsyslog.j2 │ │ └── etc_systemd_journald.conf.j2 │ ├── handlers │ │ └── main.yml │ ├── tasks │ │ ├── fact.yml │ │ ├── firewalld.yml │ │ ├── main.yml │ │ ├── rsyslog.yml │ │ ├── rsyslog-ssl.yml │ │ ├── checks.yml │ │ └── rsyslog-ssl-server.yml │ ├── meta │ │ └── main.yml │ ├── README.md │ └── defaults │ │ └── main.yml ├── gitlab │ ├── handlers │ │ └── main.yml │ ├── tasks │ │ ├── main.yml │ │ ├── ssl-selfsigned.yml │ │ └── checks.yml │ └── meta │ │ └── main.yml ├── proxmox │ ├── templates │ │ ├── etc_fail2ban_jail.d_proxmox.conf.j2 │ │ ├── etc_fail2ban_filter.d_proxmox.conf.j2 │ │ └── etc_apt_sources.list.d_proxmox.list.j2 │ ├── tasks │ │ ├── main.yml │ │ ├── fail2ban.yml │ │ └── proxmox.yml │ ├── meta │ │ └── main.yml │ └── README.md ├── handlers │ └── README.md ├── docker_nginx │ ├── templates │ │ ├── etc_systemd_system_certbot.timer.j2 │ │ ├── etc_letsencrypt_cli.ini.j2 │ │ └── etc_docker_services-config │ │ │ └── nginx │ │ │ └── docker-compose.yml.j2 │ ├── handlers │ │ └── main.yml │ ├── tasks │ │ ├── checks.yml │ │ ├── ssl-letsencrypt.yml │ │ ├── main.yml │ │ ├── remove.yml │ │ └── docker-nginx.yml │ ├── meta │ │ └── main.yml │ └── defaults │ │ └── main.yml ├── adminer │ ├── tasks │ │ ├── checks.yml │ │ ├── adminer.yml │ │ ├── main.yml │ │ ├── php-fpm.yml │ │ ├── apache.yml │ │ └── ssl-selfsigned.yml │ ├── meta │ │ └── main.yml │ ├── README.md │ ├── templates │ │ ├── etc_apache2_sites-available_adminer.conf.j2 │ │ └── etc_php_7.3_fpm_pool.d_adminer.conf.j2 │ └── defaults │ │ └── main.yml ├── monitoring_utils │ ├── templates │ │ ├── etc_default_debsums.j2 │ │ ├── usr_local_bin_bonnie++-wrapper.j2 │ │ └── etc_lynis_custom.prf.j2 │ ├── tasks │ │ ├── checks.yml │ │ ├── utils-duc.yml │ │ ├── monitoring-utils.yml │ │ ├── main.yml │ │ ├── utils-bonnie.yml │ │ └── lynis.yml │ └── meta │ │ └── main.yml ├── mailcatcher │ ├── handlers │ │ └── main.yml │ ├── meta │ │ └── main.yml │ ├── tasks │ │ ├── main.yml │ │ ├── checks.yml │ │ ├── ssl-selfsigned.yml │ │ ├── mailcatcher.yml │ │ └── apache.yml │ ├── defaults │ │ └── main.yml │ ├── templates │ │ ├── etc_systemd_system_mailcatcher.service.j2 │ │ └── etc_apache2_sites-available_mailcatcher.conf.j2 │ └── README.md └── monitoring │ ├── meta │ └── main.yml │ └── README.md ├── tests ├── inventory.yml ├── playbook.yml └── host_vars │ └── localhost.yml ├── .gitlab-ci.yml ├── galaxy.yml └── Makefile /.gitignore: -------------------------------------------------------------------------------- 1 | .venv/ 2 | .vscode/ 3 | *.swp 4 | -------------------------------------------------------------------------------- /roles/common/templates/var_lib_fail2ban_emptylog.log.j2: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /roles/openldap/vars/Debian-buster.yml: -------------------------------------------------------------------------------- 1 | php_fpm_version: 7.3 2 | -------------------------------------------------------------------------------- /roles/common/templates/etc_sudoers.d_use-pty.j2: -------------------------------------------------------------------------------- 1 | Defaults use_pty 2 | -------------------------------------------------------------------------------- /roles/openldap/vars/Debian-bullseye.yml: -------------------------------------------------------------------------------- 1 | php_fpm_version: 7.4 2 | -------------------------------------------------------------------------------- /roles/apache/vars/Debian-bookworm.yml: -------------------------------------------------------------------------------- 1 | apache_php_fpm_version: "8.2" 2 | -------------------------------------------------------------------------------- /roles/apache/vars/Debian-bullseye.yml: -------------------------------------------------------------------------------- 1 | apache_php_fpm_version: "7.4" 2 | -------------------------------------------------------------------------------- /roles/apache/vars/Debian-buster.yml: -------------------------------------------------------------------------------- 1 | apache_php_fpm_version: "7.3" 2 | -------------------------------------------------------------------------------- /roles/common/tasks/utils-reboot.yml: -------------------------------------------------------------------------------- 1 | - name: reboot the host 2 | reboot: 3 | -------------------------------------------------------------------------------- /roles/common/templates/var_log_firewalld-info.log.j2: -------------------------------------------------------------------------------- 1 | {{ common_firewalld_info }} 2 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_netdata_.opt-out-from-anonymous-statistics.j2: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/vars/Debian-bookworm.yml: -------------------------------------------------------------------------------- 1 | python3_ipaddr_package: python3 2 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/vars/Debian-bullseye.yml: -------------------------------------------------------------------------------- 1 | python3_ipaddr_package: python3-ipaddr 2 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/vars/Debian-buster.yml: -------------------------------------------------------------------------------- 1 | python3_ipaddr_package: python-ipaddress 2 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/vars/Ubuntu-bionic.yml: -------------------------------------------------------------------------------- 1 | python3_ipaddr_package: python-ipaddress 2 | -------------------------------------------------------------------------------- /roles/apache/templates/etc_ansible_facts.d_apache.fact.j2: -------------------------------------------------------------------------------- 1 | { 2 | "ansible_managed": true 3 | } 4 | -------------------------------------------------------------------------------- /roles/common/tasks/utils-shutdown.yml: -------------------------------------------------------------------------------- 1 | - name: shutdown the host 2 | community.general.shutdown: 3 | -------------------------------------------------------------------------------- /roles/common/templates/etc_ansible_facts.d_fail2ban.fact.j2: -------------------------------------------------------------------------------- 1 | { 2 | "ansible_managed": true 3 | } 4 | -------------------------------------------------------------------------------- /roles/common/templates/etc_profile.d_tmout.sh.j2: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | export TMOUT={{ bash_timeout }} 3 | -------------------------------------------------------------------------------- /roles/docker/templates/etc_ansible_facts.d_docker.fact.j2: -------------------------------------------------------------------------------- 1 | { 2 | "ansible_managed": true 3 | } 4 | -------------------------------------------------------------------------------- /roles/gitlab_runner/meta/.galaxy_install_info: -------------------------------------------------------------------------------- 1 | install_date: Mon Jun 8 08:21:58 2020 2 | version: 1.0.2 3 | -------------------------------------------------------------------------------- /roles/openldap/templates/etc_ansible_facts.d_openldap.fact.j2: -------------------------------------------------------------------------------- 1 | { 2 | "ansible_managed": true 3 | } 4 | -------------------------------------------------------------------------------- /roles/apache/templates/etc_php_PHPVERSION_cli_conf.d_20-apcu.ini.j2: -------------------------------------------------------------------------------- 1 | extension=apcu.so 2 | apc.enable_cli=1 3 | -------------------------------------------------------------------------------- /roles/common/templates/etc_ansible_facts.d_ssh.fact.j2: -------------------------------------------------------------------------------- 1 | { 2 | "ansible_managed": {{ setup_ssh|to_json }} 3 | } 4 | -------------------------------------------------------------------------------- /roles/common/templates/etc_ssh_revoked_keys.j2: -------------------------------------------------------------------------------- 1 | {% for key in ssh_server_revoked_keys %} 2 | {{key}} 3 | {% endfor %} -------------------------------------------------------------------------------- /roles/common/templates/etc_systemd_system_apt-daily-upgrade.timer.d_override.conf.j2: -------------------------------------------------------------------------------- 1 | [Timer] 2 | RandomizedDelaySec=10m -------------------------------------------------------------------------------- /roles/monitoring_rsyslog/templates/etc_ansible_facts.d_rsyslog.fact.j2: -------------------------------------------------------------------------------- 1 | { 2 | "ansible_managed": true 3 | } 4 | -------------------------------------------------------------------------------- /roles/common/templates/etc_cron.allow.j2: -------------------------------------------------------------------------------- 1 | {% for user in linux_users_crontab_allow %} 2 | {{ user }} 3 | {% endfor %} 4 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_systemd_system_netdata.service.d_override.conf.j2: -------------------------------------------------------------------------------- 1 | [Service] 2 | LogNamespace= 3 | -------------------------------------------------------------------------------- /roles/apache/templates/etc_php_PHPVERSION_apache2_conf.d_30-hide-header.ini.j2: -------------------------------------------------------------------------------- 1 | ;hide PHP HTTP headers 2 | expose_php = Off 3 | -------------------------------------------------------------------------------- /roles/common/templates/etc_ansible_facts.d_firewalld.fact.j2: -------------------------------------------------------------------------------- 1 | { 2 | "ansible_managed": {{ setup_firewall|to_json }} 3 | } 4 | -------------------------------------------------------------------------------- /roles/gitlab/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: reconfigure gitlab 4 | become: yes 5 | command: gitlab-ctl reconfigure -------------------------------------------------------------------------------- /roles/common/templates/etc_default_rcS.j2: -------------------------------------------------------------------------------- 1 | # automatically repair filesystems with inconsistencies during boot 2 | FSCKFIX=yes 3 | -------------------------------------------------------------------------------- /roles/monitoring_rsyslog/templates/etc_rsyslog.d_000-imfile.conf.j2: -------------------------------------------------------------------------------- 1 | # load the imfile text file input module 2 | module(load="imfile") -------------------------------------------------------------------------------- /roles/openldap/templates/usr_local_bin_openldap-dump.sh.j2: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | sudo slapcat -l /var/backups/openldap/slapd-backup.ldif 3 | -------------------------------------------------------------------------------- /roles/common/templates/etc_ansible_facts.d_msmtp.fact.j2: -------------------------------------------------------------------------------- 1 | { 2 | "ansible_managed": {{ 'true' if setup_msmtp else 'false' }} 3 | } 4 | -------------------------------------------------------------------------------- /roles/common/templates/etc_resolv.conf.j2: -------------------------------------------------------------------------------- 1 | {% for nameserver in dns_nameservers %} 2 | nameserver {{ nameserver }} 3 | {% endfor %} 4 | -------------------------------------------------------------------------------- /roles/monitoring_rsyslog/templates/etc_rsyslog.d_000-singlefile.conf.j2: -------------------------------------------------------------------------------- 1 | # Log everything to /var/log/syslog 2 | *.* -/var/log/syslog -------------------------------------------------------------------------------- /roles/monitoring_rsyslog/templates/etc_rsyslog.d_000-custom.conf.j2: -------------------------------------------------------------------------------- 1 | {% for item in rsyslog_custom_config %} 2 | {{ item }} 3 | {% endfor %} 4 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_netdata_go.d_phpfpm.conf.d_000-phpfpm.conf.j2: -------------------------------------------------------------------------------- 1 | # netdata go.d.plugin configuration for phpfpm 2 | jobs: 3 | -------------------------------------------------------------------------------- /roles/proxmox/templates/etc_fail2ban_jail.d_proxmox.conf.j2: -------------------------------------------------------------------------------- 1 | [proxmox] 2 | enabled = true 3 | filter = proxmox 4 | logpath = /var/log/daemon.log 5 | -------------------------------------------------------------------------------- /roles/common/templates/etc_apt_apt.conf.d_99-autoremove.j2: -------------------------------------------------------------------------------- 1 | // Automatically remove unused dependency packages 2 | APT::Get::AutomaticRemove "true"; 3 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/var_lib_debsecan_whitelist.j2: -------------------------------------------------------------------------------- 1 | VERSION 0 2 | {% for item in debsecan_whitelist %} 3 | {{ item }}, 4 | {% endfor %} 5 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/var_lib_netdata_cloud.d_cloud.conf.j2: -------------------------------------------------------------------------------- 1 | [global] 2 | {%if not netdata_cloud_enabled %} enabled = no{% endif %} 3 | -------------------------------------------------------------------------------- /roles/common/templates/etc_modprobe.d_blacklist.conf.j2: -------------------------------------------------------------------------------- 1 | {% for module in kernel_modules_blacklist %} 2 | install {{ module }} /bin/true 3 | {% endfor %} 4 | -------------------------------------------------------------------------------- /tests/inventory.yml: -------------------------------------------------------------------------------- 1 | tests: 2 | hosts: 3 | localhost: 4 | ansible_connection: local 5 | ansible_python_interpreter: "{{ansible_playbook_python}}" -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_ansible_facts.d_netdata.fact.j2: -------------------------------------------------------------------------------- 1 | { 2 | "ansible_managed": true, 3 | "public_port": "{{ netdata_public_port }}" 4 | } 5 | -------------------------------------------------------------------------------- /roles/common/templates/etc_fail2ban_jail.d_sshd.conf.j2: -------------------------------------------------------------------------------- 1 | [sshd] 2 | # openssh server login failures 3 | # other options defined in /etc/fail2ban/jail.conf 4 | enabled = true 5 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_netdata_python.d_apache.conf.j2: -------------------------------------------------------------------------------- 1 | # only update apache status charts every 10 seconds to decrease access log spam 2 | update_every: 10 3 | -------------------------------------------------------------------------------- /roles/common/tasks/dns.yml: -------------------------------------------------------------------------------- 1 | - name: set DNS resolver settings in /etc/resolv.conf 2 | template: 3 | src: "etc_resolv.conf.j2" 4 | dest: "/etc/resolv.conf" 5 | mode: "0644" 6 | -------------------------------------------------------------------------------- /roles/common/templates/etc_apt_apt.conf.d_99no-overwrite-conffiles.j2: -------------------------------------------------------------------------------- 1 | // Never replace changed conffiles modified by the user on upgrades 2 | Dpkg::Options { 3 | "--force-confold"; 4 | } -------------------------------------------------------------------------------- /roles/common/templates/etc_apt_apt.conf.d_99norecommends.j2: -------------------------------------------------------------------------------- 1 | // Don't auto-install 'recommended' packages 2 | // https://wiki.debian.org/AptPreferences 3 | Apt::Install-Recommends "false"; -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_rsyslog.d_netdata.conf.j2: -------------------------------------------------------------------------------- 1 | # rsyslog configuration for netdata logs 2 | # all netdata logs are collected through systemd-journald/ForwardToSyslog 3 | -------------------------------------------------------------------------------- /roles/openldap/templates/var_lib_ldap-account-manager_config_profiles_lam_default.group.j2: -------------------------------------------------------------------------------- 1 | profname: default 2 | ldap_suffix: ou=groups,{{ openldap_base_dn }} 3 | ldap_rdn: cn 4 | 5 | -------------------------------------------------------------------------------- /roles/monitoring_rsyslog/handlers/main.yml: -------------------------------------------------------------------------------- 1 | - name: restart systemd-journald 2 | become: yes 3 | systemd: 4 | name: systemd-journald 5 | state: restarted 6 | enabled: yes 7 | -------------------------------------------------------------------------------- /roles/common/templates/etc_apt_listbugs_ignore_bugs.j2: -------------------------------------------------------------------------------- 1 | # List of packages or bug numbers to be ignored. 2 | {% for bugnumber in apt_listbugs_ignore_list %} 3 | {{ bugnumber }} 4 | {% endfor %} 5 | -------------------------------------------------------------------------------- /roles/gitlab_runner/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - include: checks.yml 2 | tags: 3 | - gitlab_runner 4 | - checks 5 | 6 | - include: gitlab-runner.yml 7 | become: yes 8 | tags: gitlab_runner 9 | -------------------------------------------------------------------------------- /roles/proxmox/templates/etc_fail2ban_filter.d_proxmox.conf.j2: -------------------------------------------------------------------------------- 1 | [Definition] 2 | failregex = pvedaemon\[[0-9]*\]: authentication failure; rhost=::ffff: user=.* msg=.* 3 | ignoreregex = 4 | 5 | -------------------------------------------------------------------------------- /roles/apache/templates/etc_apache2_conf-available_logging.conf.j2: -------------------------------------------------------------------------------- 1 | # Log to single access log file, prepend virtualhost name to log messages 2 | CustomLog ${APACHE_LOG_DIR}/access.log vhost_combined 3 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/files/usr_share_keyrings_netdata.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libre-logic/ansible-collection-librelogic/HEAD/roles/monitoring_netdata/files/usr_share_keyrings_netdata.gpg -------------------------------------------------------------------------------- /roles/openldap/templates/etc_rsnapshot.d_openldap.conf.j2: -------------------------------------------------------------------------------- 1 | # rsnapshot configuration for openldap backups 2 | backup_exec /usr/local/bin/openldap-dump.sh 3 | backup /var/backups/openldap/ localhost/ 4 | -------------------------------------------------------------------------------- /roles/openldap/files/var_www_self-service-password_images_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libre-logic/ansible-collection-librelogic/HEAD/roles/openldap/files/var_www_self-service-password_images_logo.png -------------------------------------------------------------------------------- /roles/monitoring_netdata/handlers/main.yml: -------------------------------------------------------------------------------- 1 | - name: restart smartd 2 | become: yes 3 | service: 4 | name: smartd 5 | state: restarted 6 | enabled: yes 7 | ignore_errors: "{{ ansible_check_mode }}" 8 | -------------------------------------------------------------------------------- /roles/common/templates/etc_logrotate.d_wtmp.j2: -------------------------------------------------------------------------------- 1 | # no packages own wtmp -- we'll rotate it here 2 | /var/log/wtmp { 3 | missingok 4 | monthly 5 | create 0660 root utmp 6 | minsize 1M 7 | rotate 1 8 | } 9 | -------------------------------------------------------------------------------- /roles/docker/handlers/main.yml: -------------------------------------------------------------------------------- 1 | - name: restart docker 2 | become: yes 3 | service: 4 | name: docker 5 | state: restarted 6 | when: docker_enable_service|bool 7 | ignore_errors: "{{ ansible_check_mode }}" 8 | -------------------------------------------------------------------------------- /roles/handlers/README.md: -------------------------------------------------------------------------------- 1 | # librelogic.handlers 2 | 3 | This role only provides handlers used by multiple roles in the [librelogic.librelogic](https://github.com/librelogic/ansible-collection-librelogic/) collection. 4 | -------------------------------------------------------------------------------- /roles/openldap/files/var_www_self-service-password_images_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libre-logic/ansible-collection-librelogic/HEAD/roles/openldap/files/var_www_self-service-password_images_background.png -------------------------------------------------------------------------------- /roles/docker_nginx/templates/etc_systemd_system_certbot.timer.j2: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Run certbot daily 3 | 4 | [Timer] 5 | OnCalendar=*-*-* 04:30:00 6 | Persistent=true 7 | 8 | [Install] 9 | WantedBy=timers.target 10 | -------------------------------------------------------------------------------- /roles/gitlab_runner/templates/etc_apt_preferences.d_pin-gitlab-runner.pref.j2: -------------------------------------------------------------------------------- 1 | Explanation: Prefer GitLab provided packages over the Debian native ones 2 | Package: gitlab-runner 3 | Pin: origin packages.gitlab.com 4 | Pin-Priority: 1001 5 | -------------------------------------------------------------------------------- /roles/openldap/handlers/main.yml: -------------------------------------------------------------------------------- 1 | - name: restart slapd 2 | become: yes 3 | service: 4 | name: slapd 5 | state: restarted 6 | enabled: yes 7 | when: not ansible_check_mode 8 | ignore_errors: "{{ ansible_check_mode }}" 9 | -------------------------------------------------------------------------------- /roles/apache/handlers/main.yml: -------------------------------------------------------------------------------- 1 | - name: restart php-fpm (apache) 2 | service: 3 | name: php{{ apache_php_fpm_version }}-fpm 4 | state: restarted 5 | enabled: yes 6 | become: yes 7 | ignore_errors: "{{ ansible_check_mode }}" 8 | -------------------------------------------------------------------------------- /roles/monitoring_rsyslog/templates/etc_rsyslog.d_fail2ban.conf.j2: -------------------------------------------------------------------------------- 1 | # rsyslog configuration for fail2ban logs 2 | 3 | input(type="imfile" 4 | File="/var/log/fail2ban.log" 5 | Tag="fail2ban:" 6 | Facility="auth" 7 | PersistStateInterval="0") -------------------------------------------------------------------------------- /roles/openldap/templates/etc_ansible_facts.d_ldap_account_manager.fact.j2: -------------------------------------------------------------------------------- 1 | { 2 | "ansible_managed": true, 3 | "installed": { 4 | "version": "{{ ldap_account_manager_version }}" 5 | }, 6 | "fqdn": "{{ ldap_account_manager_fqdn }}" 7 | } 8 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_apt_sources.list.d_netdata-packagecloud.list.j2: -------------------------------------------------------------------------------- 1 | deb [signed-by=/usr/share/keyrings/netdata.gpg] https://packagecloud.io/netdata/netdata/{{ ansible_facts.distribution | lower }}/ {{ ansible_facts.distribution_release }} main 2 | -------------------------------------------------------------------------------- /roles/openldap/templates/etc_ansible_facts.d_self_service_password.fact.j2: -------------------------------------------------------------------------------- 1 | { 2 | "ansible_managed": true, 3 | "installed": { 4 | "version": "{{ self_service_password_version }}" 5 | }, 6 | "fqdn": "{{ self_service_password_fqdn }}" 7 | } 8 | -------------------------------------------------------------------------------- /roles/common/tasks/ca-certificates.yml: -------------------------------------------------------------------------------- 1 | - name: copy CA certificates 2 | copy: 3 | src: "{{ item }}" 4 | dest: "/usr/local/share/ca-certificates/" 5 | mode: 0644 6 | notify: update ca certificates store 7 | with_fileglob: 8 | - "certificates/*.crt" 9 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_netdata_go.d_httpcheck.conf.d_httpcheck.conf.j2: -------------------------------------------------------------------------------- 1 | # netdata go.d.plugin configuration for httpcheck 2 | {% if netdata_http_checks %} 3 | jobs: 4 | {{ netdata_http_checks|to_nice_yaml(indent=2) | indent(2, first=True) }} 5 | {% endif %} 6 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_netdata_go.d_x509check.conf.d_x509check.conf.j2: -------------------------------------------------------------------------------- 1 | # netdata go.d.plugin configuration for x509check 2 | {% if netdata_x509_checks %} 3 | jobs: 4 | {{ netdata_x509_checks|to_nice_yaml(indent=2) | indent(2, first=True) }} 5 | {% endif %} 6 | -------------------------------------------------------------------------------- /roles/adminer/tasks/checks.yml: -------------------------------------------------------------------------------- 1 | - name: check that mandatory variables are correctly defined 2 | assert: 3 | that: 4 | - adminer_fqdn is not search("CHANGEME") 5 | - adminer_user is not search("CHANGEME") 6 | - adminer_password is not search("CHANGEME") 7 | -------------------------------------------------------------------------------- /roles/apache/templates/etc_rsyslog.d_php-fpm.conf.j2: -------------------------------------------------------------------------------- 1 | # rsyslog configuration for php-fpm logs 2 | 3 | input(type="imfile" 4 | File="/var/log/php{{ apache_php_fpm_version }}-fpm.log" 5 | Tag="php-fpm:" 6 | Facility="daemon" 7 | PersistStateInterval="0") 8 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_firewalld_services_netdata.xml.j2: -------------------------------------------------------------------------------- 1 | 2 | 3 | Netdata 4 | Netdata monitoring dashboard/API 5 | 6 | 7 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_netdata_go.d_filecheck.conf.d_000-filecheck.conf.j2: -------------------------------------------------------------------------------- 1 | # netdata go.d.plugin configuration for filecheck 2 | jobs: 3 | {% if netdata_file_checks %} 4 | {{ netdata_file_checks|to_nice_yaml(indent=2) | indent(2, first=True) }} 5 | {% endif %} 6 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_netdata_go.d_httpcheck.conf.d_000-httpcheck.conf.j2: -------------------------------------------------------------------------------- 1 | # netdata go.d.plugin configuration for httpcheck 2 | jobs: 3 | {% if netdata_http_checks %} 4 | {{ netdata_http_checks|to_nice_yaml(indent=2) | indent(2, first=True) }} 5 | {% endif %} 6 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_netdata_go.d_x509check.conf.d_000-x509check.conf.j2: -------------------------------------------------------------------------------- 1 | # netdata go.d.plugin configuration for x509check 2 | jobs: 3 | {% if netdata_x509_checks %} 4 | {{ netdata_x509_checks|to_nice_yaml(indent=2) | indent(2, first=True) }} 5 | {% endif %} 6 | -------------------------------------------------------------------------------- /roles/common/templates/etc_fail2ban_jail.d_pam-generic.conf.j2: -------------------------------------------------------------------------------- 1 | # Fail2ban PAM jails 2 | 3 | [pam-generic] 4 | # PAM authentication failures 5 | enabled = true 6 | bantime = -1 7 | filter = pam-generic 8 | logpath = %(syslog_authpriv)s 9 | backend = %(syslog_backend)s 10 | -------------------------------------------------------------------------------- /roles/apache/tasks/mail.yml: -------------------------------------------------------------------------------- 1 | - name: forward all www-data cron jobs mail to root 2 | lineinfile: 3 | path: /etc/aliases 4 | state: present 5 | create: yes 6 | regexp: "^www-data" 7 | line: "www-data: root" 8 | owner: root 9 | group: root 10 | mode: "0644" 11 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/tasks/rsyslog.yml: -------------------------------------------------------------------------------- 1 | - name: configure rsyslog to aggregate netdata logs to syslog 2 | template: 3 | src: etc_rsyslog.d_netdata.conf.j2 4 | dest: /etc/rsyslog.d/netdata.conf 5 | owner: root 6 | group: root 7 | mode: "0644" 8 | notify: restart rsyslog 9 | -------------------------------------------------------------------------------- /roles/gitlab_runner/handlers/main.yml: -------------------------------------------------------------------------------- 1 | - name: update apt cache 2 | become: yes 3 | apt: 4 | update_cache: yes 5 | 6 | - name: restart gitlab-runner 7 | become: yes 8 | service: 9 | name: gitlab-runner 10 | state: restarted 11 | ignore_errors: "{{ ansible_check_mode }}" 12 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/tasks/utils-netdata-test-notifications.yml: -------------------------------------------------------------------------------- 1 | - name: send test netdata notification 2 | become: yes 3 | become_user: netdata 4 | command: /usr/libexec/netdata/plugins.d/alarm-notify.sh test 5 | environment: 6 | NETDATA_ALARM_NOTIFY_DEBUG: "1" 7 | changed_when: True 8 | -------------------------------------------------------------------------------- /roles/apache/templates/etc_netdata_health.d_systemdunits.conf.d_apache.conf.j2: -------------------------------------------------------------------------------- 1 | alarm: systemd_service_apache2 2 | on: systemdunits_service_units.service_unit_state 3 | calc: $apache2 4 | every: 10s 5 | crit: ($this = 5) 6 | units: state 7 | info: apache web server service status 8 | to: sysadmin 9 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_cron.d_needrestart-autorestart.j2: -------------------------------------------------------------------------------- 1 | {% if needrestart_autorestart_cron %} 2 | {{ needrestart_autorestart_cron }} root /usr/local/bin/needrestart-autorestart 2>&1 | logger -t needrestart-autorestart 3 | {% else %} 4 | # automatic reboot is disabled on this host 5 | {% endif %} 6 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_systemd_system.conf.d_accounting.conf.j2: -------------------------------------------------------------------------------- 1 | # This enables systemd cgroups accounting 2 | # Provides a 'systemd services' chart in Netdata 3 | [Manager] 4 | DefaultCPUAccounting=yes 5 | DefaultBlockIOAccounting=yes 6 | DefaultMemoryAccounting=yes 7 | DefaultTasksAccounting=yes 8 | -------------------------------------------------------------------------------- /roles/openldap/templates/etc_netdata_health.d_systemdunits.conf.d_openldap.conf.j2: -------------------------------------------------------------------------------- 1 | alarm: systemd_service_slapd 2 | on: systemdunits_service_units.service_unit_state 3 | calc: $slapd 4 | every: 10s 5 | crit: ($this = 5) 6 | units: state 7 | info: openldap server service status 8 | to: sysadmin 9 | -------------------------------------------------------------------------------- /roles/gitlab/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - include: checks.yml 2 | tags: 3 | - gitlab 4 | - checks 5 | 6 | - include: ssl-selfsigned.yml 7 | become: yes 8 | tags: 9 | - gitlab 10 | - ssl 11 | when: not gitlab_letsencrypt_enable 12 | 13 | - include: gitlab.yml 14 | become: yes 15 | tags: gitlab 16 | -------------------------------------------------------------------------------- /roles/proxmox/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - include: proxmox.yml 2 | become: yes 3 | tags: proxmox 4 | 5 | - include: fail2ban.yml 6 | become: yes 7 | tags: 8 | - proxmox 9 | - fail2ban 10 | when: 11 | - ansible_local.fail2ban.ansible_managed is defined 12 | - ansible_local.fail2ban.ansible_managed|bool 13 | -------------------------------------------------------------------------------- /roles/common/templates/etc_ansible_facts.d_common.fact.j2: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -o errexit 3 | set -o nounset 4 | 5 | echo '{ 6 | "ansible_managed": true,' 7 | 8 | if grep -sqo rdrand /proc/cpuinfo; then 9 | echo ' "cpu_rdrand" : true' 10 | else 11 | echo ' "cpu_rdrand" : false' 12 | fi 13 | 14 | echo '}' 15 | -------------------------------------------------------------------------------- /roles/apache/tasks/firewalld.yml: -------------------------------------------------------------------------------- 1 | - name: setup apache firewalld rules 2 | firewalld: 3 | zone: "{{ item[0].zone }}" 4 | service: "{{ item[1] }}" 5 | state: "{{ item[0].state }}" 6 | permanent: yes 7 | immediate: yes 8 | with_nested: 9 | - "{{ apache_firewalld_zones }}" 10 | - ['http', 'https'] 11 | -------------------------------------------------------------------------------- /roles/monitoring_utils/templates/etc_default_debsums.j2: -------------------------------------------------------------------------------- 1 | # Defaults for debsums cron jobs 2 | # sourced by /etc/cron.d/debsums 3 | 4 | # 5 | # This is a POSIX shell fragment 6 | # 7 | 8 | # Set this to never to disable the checksum verification or 9 | # one of "daily", "weekly", "monthly" to enable it 10 | CRON_CHECK={{ debsums_cron_check }} 11 | -------------------------------------------------------------------------------- /roles/apache/tasks/rsyslog.yml: -------------------------------------------------------------------------------- 1 | - name: configure rsyslog to aggregate apache/php-fpm logs to syslog 2 | template: 3 | src: etc_rsyslog.d_{{ item }}.conf.j2 4 | dest: /etc/rsyslog.d/{{ item }}.conf 5 | owner: root 6 | group: root 7 | mode: "0644" 8 | notify: restart rsyslog 9 | with_items: 10 | - apache 11 | - php-fpm 12 | -------------------------------------------------------------------------------- /roles/apache/templates/etc_apache2_conf-available_mod-md.conf.j2: -------------------------------------------------------------------------------- 1 | # common configuration for mod_md 2 | MDCertificateAgreement accepted 3 | MDContactEmail {{ apache_letsencrypt_email }} 4 | MDPrivateKeys RSA 4096 5 | MDMessageCmd /usr/local/bin/apache-mod-md-reload request 6 | MDRequireHttps {{ 'permanent' if apache_letsencrypt_enable_hsts else 'temporary' }} 7 | -------------------------------------------------------------------------------- /roles/docker_nginx/handlers/main.yml: -------------------------------------------------------------------------------- 1 | - name: restart nginx docker service 2 | become: yes 3 | command: docker service update --force nginx-reverseproxy_nginx-reverseproxy 4 | changed_when: True 5 | ignore_errors: "{{ ansible_check_mode }}" 6 | 7 | - name: reload systemd unit files 8 | become: yes 9 | systemd: 10 | daemon_reload: yes 11 | -------------------------------------------------------------------------------- /roles/mailcatcher/handlers/main.yml: -------------------------------------------------------------------------------- 1 | - name: restart mailcatcher 2 | service: 3 | name: mailcatcher 4 | state: restarted 5 | enabled: yes 6 | become: yes 7 | when: mailcatcher_enable_service 8 | ignore_errors: "{{ ansible_check_mode|bool }}" 9 | 10 | - name: reload systemd unit files 11 | become: yes 12 | systemd: daemon_reload=yes 13 | -------------------------------------------------------------------------------- /roles/docker/templates/etc_docker_daemon.json.j2: -------------------------------------------------------------------------------- 1 | { 2 | {% if docker_log_driver == 'syslog' %} 3 | "log-driver": "syslog", 4 | "log-opts": { 5 | "tag": "docker.{{ '{{' }}.Name{{ '}}' }}" 6 | }, 7 | {% endif %} 8 | "metrics-addr" : "127.0.0.1:9323", 9 | "experimental" : true, 10 | "iptables" : {{ 'true' if docker_iptables else 'false' }} 11 | } 12 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_apt_preferences.d_99-netdata-packagecloud.j2: -------------------------------------------------------------------------------- 1 | # Only allow installation of netdata related packages from packagecloud repository 2 | # Prevent installation for packages not named netdata* 3 | Package: * 4 | Origin: packagecloud 5 | Pin-Priority: -1 6 | 7 | Package: netdata* 8 | Origin: packagecloud 9 | Pin-Priority: 500 10 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | image: debian:buster 2 | 3 | stages: 4 | - test 5 | 6 | cache: 7 | paths: 8 | - "$CI_PROJECT_DIR/pip-cache" 9 | - "$CI_PROJECT_DIR/.venv" 10 | 11 | before_script: 12 | - apt update && apt -y install make bash python3-venv python3-pip 13 | 14 | test: 15 | stage: test 16 | script: 17 | - make tests 18 | interruptible: true 19 | -------------------------------------------------------------------------------- /tests/playbook.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | roles: 3 | - common 4 | - docker 5 | - docker_nginx 6 | - monitoring 7 | - monitoring_rsyslog 8 | - monitoring_netdata 9 | - monitoring_utils 10 | - openldap 11 | - gitlab 12 | - proxmox 13 | - mailcatcher 14 | - apache 15 | - php_fpm 16 | - adminer 17 | - gitlab_runner 18 | -------------------------------------------------------------------------------- /roles/apache/templates/etc_systemd_system_apache2.service.d_override.conf.j2: -------------------------------------------------------------------------------- 1 | [Service] 2 | PrivateDevices=true 3 | ProtectControlGroups=true 4 | ProtectHome=true 5 | ProtectKernelTunables=true 6 | RestrictSUIDSGID=true 7 | ProtectClock=true 8 | 9 | # unapplicable 10 | #ProtectSystem=strict # causes segfault with strict or full 11 | #PrivateUsers=true # causes segfault 12 | 13 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_netdata_go.d_portcheck.conf.d_portcheck.conf.j2: -------------------------------------------------------------------------------- 1 | # netdata go.d.plugin configuration for portcheck 2 | {% if netdata_port_checks %} 3 | jobs: 4 | {% for job in netdata_port_checks %} 5 | - name: {{ job.name }} 6 | host: {{ job.host }} 7 | ports: {{ job.ports }} 8 | update_every: {{ job.interval }} 9 | {% endfor %} 10 | {% endif %} 11 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_netdata_go.d_portcheck.conf.d_000-portcheck.conf.j2: -------------------------------------------------------------------------------- 1 | # netdata go.d.plugin configuration for portcheck 2 | jobs: 3 | {% if netdata_port_checks %} 4 | {% for job in netdata_port_checks %} 5 | - name: {{ job.name }} 6 | host: {{ job.host }} 7 | ports: {{ job.ports }} 8 | update_every: {{ job.interval }} 9 | {% endfor %} 10 | {% endif %} 11 | -------------------------------------------------------------------------------- /roles/monitoring_rsyslog/templates/etc_rsyslog.d_000-discard.conf.j2: -------------------------------------------------------------------------------- 1 | # Discard these messages, never log them 2 | :msg, contains, "failed to read Temperature" stop 3 | if $programname == 'apache' and re_match($msg, '.* 127.0.0.1 - - .* "GET /server-status\\?auto HTTP/1.1" 200') then stop 4 | if $programname == 'CRON' and re_match($msg, 'cron:session): session (opened|closed) for user .*') then stop 5 | -------------------------------------------------------------------------------- /roles/apache/tasks/netdata.yml: -------------------------------------------------------------------------------- 1 | - name: install netdata checks for apache 2 | template: 3 | src: etc_netdata_go.d_httpcheck.conf.d_apache-reverseproxies.conf.j2 4 | dest: /etc/netdata/go.d/httpcheck.conf.d/apache-reverseproxies.conf 5 | owner: root 6 | group: netdata 7 | mode: "0640" 8 | notify: assemble netdata configuration 9 | ignore_errors: "{{ ansible_check_mode }}" 10 | -------------------------------------------------------------------------------- /roles/docker/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: import docker configuration tasks 2 | ansible.builtin.import_tasks: docker.yml 3 | become: yes 4 | tags: docker 5 | 6 | - name: import facct configuration tasks 7 | ansible.builtin.import_tasks: fact.yml 8 | become: yes 9 | tags: docker 10 | 11 | - name: apply configuration (flush handlers) 12 | ansible.builtin.meta: flush_handlers 13 | tags: docker 14 | -------------------------------------------------------------------------------- /roles/apache/templates/etc_apt_preferences.d_99-apache2-buster-backports.j2: -------------------------------------------------------------------------------- 1 | # Prefer apache2 packages from buster-backports 2 | # Required to for ACMEv2 support for mod_md 3 | # ACMEv1 protocol is discontinued by Let's Encrypt 4 | 5 | Package: apache2* 6 | Pin: release n=buster-backports 7 | Pin-Priority: 600 8 | 9 | Package: libapache2-mod* 10 | Pin: release n=buster-backports 11 | Pin-Priority: 600 12 | 13 | -------------------------------------------------------------------------------- /roles/docker_nginx/tasks/checks.yml: -------------------------------------------------------------------------------- 1 | - name: check that mandatory variables are correctly defined 2 | assert: 3 | that: 4 | - docker_nginx_remove == docker_nginx_remove|bool 5 | 6 | - name: check that mandatory variables are correctly defined (when nginx installation is enabled) 7 | assert: 8 | that: 9 | - nginx_letsencrypt_email is not search("CHANGEME") 10 | when: not docker_nginx_remove -------------------------------------------------------------------------------- /roles/adminer/meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | license: "GPL-3.0" 3 | author: "Libre Logic " 4 | description: "Database management in a single PHP file" 5 | min_ansible_version: 2.12 6 | platforms: 7 | - name: Debian 8 | versions: 9 | - 10 10 | - name: Ubuntu 11 | versions: 12 | - 18.04 13 | 14 | dependencies: 15 | - librelogic.librelogic.apache 16 | -------------------------------------------------------------------------------- /roles/docker/tasks/fact.yml: -------------------------------------------------------------------------------- 1 | - name: create ansible facts.d directory 2 | file: 3 | path: /etc/ansible/facts.d 4 | state: directory 5 | mode: 0755 6 | 7 | - name: create docker fact file 8 | template: 9 | src: etc_ansible_facts.d_docker.fact.j2 10 | dest: /etc/ansible/facts.d/docker.fact 11 | mode: 0644 12 | notify: update ansible facts 13 | ignore_errors: "{{ ansible_check_mode }}" 14 | -------------------------------------------------------------------------------- /roles/apache/tasks/fact.yml: -------------------------------------------------------------------------------- 1 | - name: create ansible facts.d directory 2 | file: 3 | path: /etc/ansible/facts.d 4 | state: directory 5 | mode: "0755" 6 | 7 | - name: create apache fact file 8 | template: 9 | src: etc_ansible_facts.d_apache.fact.j2 10 | dest: /etc/ansible/facts.d/apache.fact 11 | mode: "0644" 12 | notify: update ansible facts 13 | ignore_errors: "{{ ansible_check_mode }}" 14 | -------------------------------------------------------------------------------- /roles/apache/templates/etc_apache2_ports.conf.j2: -------------------------------------------------------------------------------- 1 | # If you just change the port or add more ports here, you will likely also 2 | # have to change the VirtualHost statement in 3 | # /etc/apache2/sites-enabled/000-default.conf 4 | 5 | {% if apache_listen_http %} 6 | Listen 80 7 | {% endif %} 8 | 9 | 10 | Listen 443 11 | 12 | 13 | 14 | Listen 443 15 | 16 | -------------------------------------------------------------------------------- /roles/openldap/tasks/fact.yml: -------------------------------------------------------------------------------- 1 | - name: create ansible facts.d directory 2 | file: 3 | path: /etc/ansible/facts.d 4 | state: directory 5 | mode: 0755 6 | 7 | - name: create openldap fact file 8 | template: 9 | src: etc_ansible_facts.d_openldap.fact.j2 10 | dest: /etc/ansible/facts.d/openldap.fact 11 | mode: 0644 12 | notify: update ansible facts 13 | ignore_errors: "{{ ansible_check_mode }}" 14 | -------------------------------------------------------------------------------- /roles/mailcatcher/meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | license: "GPL-3.0" 3 | author: "Libre Logic " 4 | description: "Simple SMTP server/mail interceptor and web interface" 5 | min_ansible_version: 2.12 6 | platforms: 7 | - name: Debian 8 | versions: 9 | - buster 10 | - name: Ubuntu 11 | versions: 12 | - 18.04 13 | 14 | dependencies: 15 | - librelogic.librelogic.apache 16 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/tasks/fact.yml: -------------------------------------------------------------------------------- 1 | - name: create ansible facts.d directory 2 | file: 3 | path: /etc/ansible/facts.d 4 | state: directory 5 | mode: "0755" 6 | 7 | - name: create netdata fact file 8 | template: 9 | src: etc_ansible_facts.d_netdata.fact.j2 10 | dest: /etc/ansible/facts.d/netdata.fact 11 | mode: "0644" 12 | notify: update ansible facts 13 | ignore_errors: "{{ ansible_check_mode }}" 14 | -------------------------------------------------------------------------------- /roles/monitoring_rsyslog/tasks/fact.yml: -------------------------------------------------------------------------------- 1 | - name: create ansible facts.d directory 2 | file: 3 | path: /etc/ansible/facts.d 4 | state: directory 5 | mode: "0755" 6 | 7 | - name: create rsyslog fact file 8 | template: 9 | src: etc_ansible_facts.d_rsyslog.fact.j2 10 | dest: /etc/ansible/facts.d/rsyslog.fact 11 | mode: "0644" 12 | notify: update ansible facts 13 | ignore_errors: "{{ ansible_check_mode }}" 14 | -------------------------------------------------------------------------------- /roles/common/tasks/hostname.yml: -------------------------------------------------------------------------------- 1 | ##### HOSTNAME #### 2 | 3 | - name: set hostname 4 | hostname: 5 | name: "{{ inventory_hostname }}" 6 | 7 | - name: update /etc/hosts with new hostname 8 | lineinfile: 9 | dest: '/etc/hosts' 10 | line: '{{ item }} {{ inventory_hostname }}' # noqa no-tabs 11 | regexp: '^{{ item }}' 12 | owner: root 13 | group: root 14 | mode: "0644" 15 | with_items: 16 | - '127.0.1.1' 17 | -------------------------------------------------------------------------------- /roles/gitlab_runner/tasks/checks.yml: -------------------------------------------------------------------------------- 1 | - name: check that all variables are correctly defined 2 | assert: 3 | that: 4 | - gitlab_runner_output_limit == gitlab_runner_output_limit|int 5 | - gitlab_runner_maximum_timeout == gitlab_runner_maximum_timeout|int 6 | - gitlab_runner_api_token is not search('CHANGEME') 7 | - gitlab_runner_registration_token is not search('CHANGEME') 8 | - gitlab_runner_gitlab_url is not search('CHANGEME') 9 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_needrestart_conf.d_autorestart.conf.j2: -------------------------------------------------------------------------------- 1 | # Restart mode: (l)ist only, (i)nteractive or (a)utomatically. 2 | # 3 | # ATTENTION: If needrestart is configured to run in interactive mode but is run 4 | # non-interactive (i.e. unattended-upgrades) it will fallback to list only mode. 5 | # 6 | {% if needrestart_autorestart_services %} 7 | $nrconf{restart} = 'a'; 8 | {% else %} 9 | $nrconf{restart} = 'l'; 10 | {% endif %} 11 | -------------------------------------------------------------------------------- /roles/monitoring_utils/templates/usr_local_bin_bonnie++-wrapper.j2: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -o errexit 3 | set -o nounset 4 | benchmark_dirs="{{ bonnie_benchmark_paths | join(' ') }}" 5 | 6 | rm -f /var/log/bonnie++.csv /var/log/bonnie++.html 7 | for dir in $benchmark_dirs; do 8 | /usr/sbin/bonnie++ -q -u root -d "$dir" -m "$HOSTNAME-$dir" -s 1024 -r 512 >> /var/log/bonnie++.csv 9 | done 10 | 11 | (bon_csv2html /var/log/bonnie++.txt || true) > /var/log/bonnie++.html 12 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_netdata_health.d_processes.conf.j2: -------------------------------------------------------------------------------- 1 | {% for job in netdata_process_checks %} 2 | {% if job.min_count > 0 %} 3 | alarm: {{ job.name }}_processes 4 | on: apps.processes 5 | calc: ${{ job.name }} 6 | every: {{ job.interval }}s 7 | crit: ($this < {{ job.min_count }}) OR ($this = nan) 8 | units: processes 9 | info: {{ job.name }} running processes 10 | to: sysadmin 11 | class: Errors 12 | {% endif %} 13 | {% endfor %} 14 | 15 | -------------------------------------------------------------------------------- /roles/apache/templates/etc_rsyslog.d_apache.conf.j2: -------------------------------------------------------------------------------- 1 | # rsyslog configuration for apache logs 2 | 3 | input(type="imfile" 4 | File="/var/log/apache2/error.log" 5 | Tag="apache:" 6 | Facility="daemon" 7 | PersistStateInterval="0") 8 | 9 | {% if apache_access_log_to_syslog %} 10 | input(type="imfile" 11 | File="/var/log/apache2/access.log" 12 | Tag="apache-access:" 13 | Facility="daemon" 14 | PersistStateInterval="0") 15 | {% endif %} 16 | -------------------------------------------------------------------------------- /roles/docker_nginx/meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | role_name: docker_nginx 3 | author: "Libre Logic " 4 | description: "Nginx reverseproxy (ready-to-use docker container)" 5 | license: "GPL-3.0" 6 | min_ansible_version: 2.8 7 | platforms: 8 | - name: Debian 9 | versions: 10 | - stretch 11 | galaxy_tags: 12 | - web 13 | - server 14 | - reverseproxy 15 | - ssl 16 | 17 | dependencies: ['librelogic.librelogic.docker'] -------------------------------------------------------------------------------- /roles/monitoring_rsyslog/templates/etc_firewalld_services_syslog-tcp-ssl.xml.j2: -------------------------------------------------------------------------------- 1 | 2 | 3 | syslog-tcp-ssl 4 | Syslog is a client/server protocol: a logging application transmits a text message to the syslog receiver. The receiver is commonly called syslogd, syslog daemon or syslog server. Syslog-tls uses TLS encryption to protect the messages during transport. 5 | 6 | 7 | -------------------------------------------------------------------------------- /roles/proxmox/meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | role_name: proxmox 3 | author: Libre Logic 4 | description: Proxmox VE configuration 5 | license: GPL-3.0 6 | min_ansible_version: 2.12 7 | platforms: 8 | - name: Debian 9 | versions: 10 | - 10 11 | galaxy_tags: 12 | - proxmox 13 | - virtualization 14 | - hypervisor 15 | - kvm 16 | - lxc 17 | - vm 18 | 19 | dependencies: [] 20 | # - librelogic.librelogic.common # optional, unattended upgrades 21 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_netdata_health.d_processes.conf.d_000-processes.conf.j2: -------------------------------------------------------------------------------- 1 | {% for job in netdata_process_checks %} 2 | {% if job.min_count > 0 %} 3 | alarm: {{ job.name }}_processes 4 | on: apps.processes 5 | calc: ${{ job.name }} 6 | every: {{ job.interval }}s 7 | crit: ($this < {{ job.min_count }}) OR ($this = nan) 8 | units: processes 9 | info: {{ job.name }} running processes 10 | to: sysadmin 11 | class: Errors 12 | {% endif %} 13 | 14 | {% endfor %} 15 | 16 | -------------------------------------------------------------------------------- /roles/common/templates/etc_sudoers.d_nopasswd.j2: -------------------------------------------------------------------------------- 1 | {% if ansible_user_allow_sudo_rsync_nopasswd %} 2 | Defaults:{{ ansible_user }} !requiretty 3 | {{ ansible_user }} ALL=(ALL) NOPASSWD: /usr/bin/rsync 4 | {% endif %} 5 | 6 | {% for user in linux_users %} 7 | {% if user.sudo_nopasswd_commands is defined %} 8 | Defaults:{{ user.name }} !requiretty 9 | {% for command in user.sudo_nopasswd_commands %} 10 | {{ user.name }} ALL=(ALL) NOPASSWD: {{ command }} 11 | {% endfor %} 12 | {% endif %} 13 | {% endfor %} 14 | -------------------------------------------------------------------------------- /roles/gitlab_runner/meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | author: 'Libre Logic ' 3 | description: 'gitlab-runner CI/CD runner' 4 | company: 'Libre Logic' 5 | license: 'GPL-3.0' 6 | min_ansible_version: '2.10' 7 | platforms: 8 | - name: Debian 9 | versions: 10 | - '10' 11 | galaxy_tags: 12 | - continuous 13 | - integration 14 | - delivery 15 | - ci 16 | - cd 17 | - automation 18 | 19 | dependencies: 20 | - librelogic.librelogic.docker 21 | -------------------------------------------------------------------------------- /roles/apache/templates/etc_netdata_go.d_httpcheck.conf.d_apache-reverseproxies.conf.j2: -------------------------------------------------------------------------------- 1 | {% for item in apache_reverseproxies %} 2 | {% if item.monitor_http is not defined or item.monitor_http %} 3 | - name: {{ item.servername }} 4 | timeout: 5 5 | tls_skip_verify: {{ 'true' if (item.https_mode is not defined or item.https_mode == 'selfsigned') else 'false' }} 6 | update_every: 10 7 | url: https://127.0.0.1 8 | headers: 9 | Host: "{{ item.servername }}" 10 | 11 | {% endif %} 12 | {% endfor %} 13 | -------------------------------------------------------------------------------- /roles/common/tasks/utils-fail2ban-get-banned.yml: -------------------------------------------------------------------------------- 1 | - name: get list of fail2ban banned IPs 2 | become: yes 3 | shell: 4 | cmd: /usr/bin/fail2ban-client banned > /root/fail2ban-banned.txt 5 | changed_when: yes 6 | 7 | - name: download list of fail2ban banned IPs to data/fail2ban-banned-*.txt 8 | become: yes 9 | fetch: 10 | src: /root/fail2ban-banned.txt 11 | dest: "{{ playbook_dir }}/data/fail2ban-banned-{{ inventory_hostname }}.txt" 12 | flat: yes 13 | ignore_errors: "{{ ansible_check_mode }}" 14 | -------------------------------------------------------------------------------- /roles/apache/templates/etc_fail2ban_jail.d_apache.conf.j2: -------------------------------------------------------------------------------- 1 | [apache-auth] 2 | # apache basic auth login failures 3 | # other options defined in /etc/fail2ban/jail.conf 4 | enabled = true 5 | logpath = %(apache_error_log)s 6 | /var/lib/fail2ban/emptylog.log 7 | port = http,https 8 | 9 | [apache-default-vhost] 10 | # requests to the default virtualhost 11 | enabled = true 12 | filter = apache-default-vhost 13 | port = http,https 14 | logpath = %(apache_access_log)s 15 | /var/lib/fail2ban/emptylog.log 16 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_default_smartmontools.j2: -------------------------------------------------------------------------------- 1 | # Defaults for smartmontools initscript (/etc/init.d/smartmontools) 2 | # This is a POSIX shell fragment 3 | 4 | # List of devices you want to explicitly enable S.M.A.R.T. for 5 | # Not needed (and not recommended) if the device is monitored by smartd 6 | #enable_smart="/dev/hda /dev/hdb" 7 | 8 | # uncomment to pass additional options to smartd on startup 9 | # dump smartd attrs info every 600 seconds 10 | smartd_opts="--attributelog=/var/log/smartd/ --interval=600" 11 | -------------------------------------------------------------------------------- /roles/common/templates/etc_apt_apt.conf.d_10apt-listbugs.j2: -------------------------------------------------------------------------------- 1 | // Before installing packages, check whether they have release-critical bugs. 2 | // If you don't like it, comment it out. 3 | DPkg::Pre-Install-Pkgs {"/usr/bin/apt-listbugs apt --force-no-pin --{{ apt_listbugs_action }}";}; 4 | DPkg::Tools::Options::/usr/bin/apt-listbugs ""; 5 | DPkg::Tools::Options::/usr/bin/apt-listbugs::Version "3"; 6 | DPkg::Tools::Options::/usr/bin/apt-listbugs::InfoFD "20"; 7 | AptListbugs::Severities "critical,grave,serious"; 8 | // AptListbugs::IgnoreRegexp "FTBFS"; 9 | -------------------------------------------------------------------------------- /roles/docker_nginx/templates/etc_letsencrypt_cli.ini.j2: -------------------------------------------------------------------------------- 1 | # Because we are using logrotate for greater flexibility, disable the 2 | # internal certbot logrotation. 3 | max-log-backups = 0 4 | 5 | # Because we are using the standalone authenticator, stop the nginx service before attempting to renew a certificate 6 | # Else renewal will fail with "Problem binding to port 80: Could not bind to IPv4 or IPv6" 7 | pre-hook = docker service scale nginx-reverseproxy_nginx-reverseproxy=0 8 | post-hook = docker service scale nginx-reverseproxy_nginx-reverseproxy=1 9 | -------------------------------------------------------------------------------- /roles/common/tasks/utils-apt-upgrade.yml: -------------------------------------------------------------------------------- 1 | - name: run apt upgrade now 2 | apt: 3 | upgrade: safe 4 | 5 | - name: list and display upgradable packages 6 | block: 7 | - name: list upgradable packages 8 | command: 9 | cmd: apt list --upgradable 10 | register: apt_upgradable 11 | changed_when: no 12 | check_mode: no # run even in check mode so that following tasks don't fail, doesn't change anything 13 | - name: display upgradable packages 14 | debug: 15 | msg: "{{ apt_upgradable.stdout }}" 16 | -------------------------------------------------------------------------------- /roles/common/tasks/datetime.yml: -------------------------------------------------------------------------------- 1 | ##### DATE/TIME ##### 2 | 3 | - name: set timezone 4 | community.general.timezone: 5 | name: "{{ timezone }}" 6 | when: timezone is defined 7 | 8 | - name: install systemd-timesyncd time synchronization service 9 | apt: 10 | state: present 11 | package: systemd-timesyncd 12 | 13 | - name: start systemd-timesyncd time synchronization service 14 | service: 15 | name: systemd-timesyncd 16 | state: started 17 | enabled: yes 18 | ignore_errors: "{{ ansible_check_mode }}" 19 | tags: services 20 | -------------------------------------------------------------------------------- /roles/common/handlers/main.yml: -------------------------------------------------------------------------------- 1 | - name: update pam configuration 2 | become: yes 3 | command: 'pam-auth-update --package' 4 | changed_when: yes 5 | 6 | - name: restart systemd-logind 7 | become: yes 8 | service: 9 | name: systemd-logind 10 | state: restarted 11 | enabled: yes 12 | 13 | - name: restart ssh 14 | become: yes 15 | service: 16 | name: ssh 17 | state: restarted 18 | enabled: yes 19 | 20 | - name: restart crond 21 | become: yes 22 | service: 23 | name: cron 24 | state: restarted 25 | enabled: yes 26 | -------------------------------------------------------------------------------- /roles/apache/tasks/fail2ban.yml: -------------------------------------------------------------------------------- 1 | - name: copy apache fail2ban jail config 2 | template: 3 | src: etc_fail2ban_jail.d_apache.conf.j2 4 | dest: /etc/fail2ban/jail.d/apache.conf 5 | owner: root 6 | group: root 7 | mode: "0644" 8 | notify: reload fail2ban 9 | 10 | - name: copy fail2ban apache-default-vhost filter 11 | template: 12 | src: etc_fail2ban_filter.d_apache-default-vhost.conf.j2 13 | dest: /etc/fail2ban/filter.d/apache-default-vhost.conf 14 | owner: root 15 | group: root 16 | mode: "0644" 17 | notify: reload fail2ban 18 | -------------------------------------------------------------------------------- /roles/monitoring_utils/tasks/checks.yml: -------------------------------------------------------------------------------- 1 | - name: check that mandatory variables are correctly defined 2 | assert: 3 | quiet: yes 4 | that: "{{ item }}" 5 | fail_msg: "One or more variables are not correctly defined. Check role documentation: https://gitlab.com/nodiscc/xsrv/-/tree/master/roles/monitoring_utils" 6 | loop: 7 | - lynis_report_regex is string 8 | - lynis_skip_tests|type_debug == "list" 9 | - debsums_cron_check in ['daily', 'weekly', 'monthly'] 10 | - duc_index_path is string 11 | - bonnie_benchmark_paths | type_debug == "list" 12 | -------------------------------------------------------------------------------- /roles/proxmox/tasks/fail2ban.yml: -------------------------------------------------------------------------------- 1 | - name: copy fail2ban jail configuration for proxmox 2 | template: 3 | src: etc_fail2ban_jail.d_proxmox.conf.j2 4 | dest: /etc/fail2ban/jail.d/proxmox.conf 5 | owner: root 6 | group: root 7 | mode: 0644 8 | notify: reload fail2ban 9 | 10 | - name: copy fail2ban filter for proxmox authentication failures 11 | template: 12 | src: etc_fail2ban_filter.d_proxmox.conf.j2 13 | dest: /etc/fail2ban/filter.d/proxmox.conf 14 | owner: root 15 | group: root 16 | mode: 0644 17 | notify: reload fail2ban 18 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_netdata_stream.conf.j2: -------------------------------------------------------------------------------- 1 | [stream] 2 | enabled = {{ 'yes' if netdata_streaming_send_enabled else 'no' }} 3 | {% if netdata_streaming_send_enabled %} 4 | destination = {{ netdata_streaming_destination }} 5 | api key = {{ netdata_streaming_api_key }} 6 | ssl skip certificate verification = yes 7 | {% endif %} 8 | 9 | {% if netdata_streaming_receive_enabled %} 10 | [{{ netdata_streaming_api_key }}] 11 | enabled = yes 12 | health enabled by default = {{ 'yes' if netdata_streaming_receive_alarms else 'no' }} 13 | {% endif %} 14 | -------------------------------------------------------------------------------- /roles/common/tasks/fact.yml: -------------------------------------------------------------------------------- 1 | - name: create ansible facts.d directory 2 | file: 3 | path: /etc/ansible/facts.d 4 | state: directory 5 | mode: "0755" 6 | 7 | - name: create common fact file 8 | template: 9 | src: etc_ansible_facts.d_common.fact.j2 10 | dest: /etc/ansible/facts.d/common.fact 11 | mode: "0755" 12 | notify: update ansible facts 13 | ignore_errors: "{{ ansible_check_mode }}" 14 | 15 | # update ansible facts immediately to detect CPU TRNG support 16 | - name: apply configuration (flush handlers) 17 | meta: flush_handlers 18 | tags: common 19 | -------------------------------------------------------------------------------- /roles/monitoring_rsyslog/meta/main.yml: -------------------------------------------------------------------------------- 1 | # @tag rsyslog - setup system log processing 2 | 3 | galaxy_info: 4 | role_name: monitoring_rsyslog 5 | author: "nodiscc " 6 | description: "log aggregation, processing and forwarding system" 7 | license: GPL-3.0 8 | min_ansible_version: "2.12" 9 | platforms: 10 | - name: Debian 11 | versions: 12 | - "11" 13 | - "12" 14 | galaxy_tags: 15 | - system 16 | - monitoring 17 | - syslog 18 | - rsyslog 19 | - logging 20 | dependencies: 21 | - librelogic.librelogic.handlers 22 | -------------------------------------------------------------------------------- /roles/openldap/templates/etc_netdata_go.d_httpcheck.conf.d_openldap.conf.j2: -------------------------------------------------------------------------------- 1 | {% if openldap_setup_lam %} 2 | - name: ldap-account-manager 3 | timeout: 1 4 | tls_skip_verify: true 5 | update_every: 10 6 | url: https://127.0.0.1 7 | headers: 8 | Host: "{{ ldap_account_manager_fqdn }}" 9 | {% endif %} 10 | {% if openldap_setup_ssp %} 11 | - name: self-service-password 12 | timeout: 1 13 | tls_skip_verify: true 14 | update_every: 10 15 | url: https://127.0.0.1 16 | headers: 17 | Host: "{{ self_service_password_fqdn }}" 18 | {% endif %} 19 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_cron.d_netdata-downtime.j2: -------------------------------------------------------------------------------- 1 | {% for downtime in netdata_notification_downtimes %} 2 | {{ downtime.start }} netdata SHELL=/bin/bash netdata_api_key=$(cat /var/lib/netdata/netdata.api.key) && curl --silent --insecure "https://127.0.0.1:19999/api/v1/manage/health?cmd=SILENCE ALL" -H "X-Auth-Token: $netdata_api_key" >/dev/null 3 | {{ downtime.end }} netdata SHELL=/bin/bash netdata_api_key=$(cat /var/lib/netdata/netdata.api.key) && curl --silent --insecure "https://127.0.0.1:19999/api/v1/manage/health?cmd=RESET" -H "X-Auth-Token: $netdata_api_key" >/dev/null 4 | {% endfor %} 5 | -------------------------------------------------------------------------------- /roles/common/templates/etc_fail2ban_fail2ban.local.j2: -------------------------------------------------------------------------------- 1 | # Fail2Ban local configuration file 2 | # These settings override fail2Ban's default settings in /etc/fail2ban/fail2ban.conf 3 | # See man jail.conf 4 | 5 | [DEFAULT] 6 | # Options: dbpurgeage 7 | # Notes.: Sets age at which bans should be purged from the database 8 | # Values: [ SECONDS ] Default: 86400 (24hours) 9 | # 1 year 10 | dbpurgeage = 31536000 11 | 12 | # Option: allowipv6 13 | # Notes.: Allows IPv6 interface: 14 | # Default: auto 15 | # Values: [ auto yes (on, true, 1) no (off, false, 0) ] Default: auto 16 | allowipv6 = auto 17 | -------------------------------------------------------------------------------- /roles/mailcatcher/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: import variable checks tasks 2 | ansible.builtin.import_tasks: checks.yml 3 | tags: 4 | - mailcatcher 5 | - checks 6 | 7 | - name: import Mailcatcher configuration tasks 8 | ansible.builtin.import_tasks: mailcatcher.yml 9 | become: yes 10 | tags: mailcatcher 11 | 12 | - name: import self-signed certificates configuration tasks 13 | ansible.builtin.import_tasks: ssl-selfsigned.yml 14 | become: yes 15 | tags: mailcatcher 16 | 17 | - name: import apache configuration tasks 18 | ansible.builtin.import_tasks: apache.yml 19 | become: yes 20 | tags: mailcatcher 21 | -------------------------------------------------------------------------------- /roles/adminer/tasks/adminer.yml: -------------------------------------------------------------------------------- 1 | - name: install adminer php requirements 2 | apt: 3 | package: php-pgsql 4 | state: present 5 | 6 | - name: create adminer virtualhost directory 7 | file: 8 | state: directory 9 | path: /var/www/{{ adminer_fqdn }} 10 | owner: root 11 | group: www-data 12 | mode: 0750 13 | 14 | - name: download adminer 15 | get_url: 16 | url: https://github.com/vrana/adminer/releases/download/v4.8.1/adminer-4.8.1.php 17 | dest: /var/www/{{ adminer_fqdn }}/index.php 18 | owner: root 19 | group: www-data 20 | mode: 0644 21 | ignore_errors: "{{ ansible_check_mode }}" 22 | -------------------------------------------------------------------------------- /roles/common/tasks/hosts.yml: -------------------------------------------------------------------------------- 1 | - name: add /etc/hosts entries # noqa no-tabs 2 | lineinfile: 3 | path: /etc/hosts 4 | line: "{{ item.ip_address }} {{ item.hostname }}" 5 | regexp: "^{{ item.ip_address }} .*$" 6 | state: present 7 | with_items: "{{ hosts_file_entries }}" 8 | when: (item.state is not defined) or (item.state == 'present') 9 | 10 | - name: remove /etc/hosts entries # noqa no-tabs 11 | lineinfile: 12 | path: /etc/hosts 13 | regexp: "^{{ item.ip_address }} .*$" 14 | state: absent 15 | with_items: "{{ hosts_file_entries }}" 16 | when: (item.state is defined) and (item.state == 'absent') 17 | -------------------------------------------------------------------------------- /roles/proxmox/templates/etc_apt_sources.list.d_proxmox.list.j2: -------------------------------------------------------------------------------- 1 | deb https://deb.debian.org/debian/ {{ ansible_facts.distribution_release }} contrib 2 | deb https://deb.debian.org/debian/ {{ ansible_facts.distribution_release }}-updates contrib 3 | {% if ansible_facts.distribution_release == 'bullseye' %} 4 | deb http://security.debian.org/debian-security {{ ansible_facts.distribution_release }}-security contrib 5 | {% else %} 6 | deb http://security.debian.org/debian-security {{ ansible_facts.distribution_release }}/updates contrib 7 | {% endif %} 8 | deb http://download.proxmox.com/debian/pve {{ ansible_facts.distribution_release }} pve-no-subscription 9 | -------------------------------------------------------------------------------- /roles/mailcatcher/defaults/main.yml: -------------------------------------------------------------------------------- 1 | ##### MAILCATCHER ##### 2 | # mailtacher bin path 3 | mailcatcher_bin_path: "/var/lib/mailcatcher/.local/share/gem/ruby/2.7.0/bin/mailcatcher" 4 | # FQDN for the gitlab webserver virtualhost 5 | mailcatcher_fqdn: "mailcatcher.CHANGEME.org" 6 | # username/password for mailcatcher HTTP Basic Auth 7 | mailcatcher_user: "CHANGEME" 8 | mailcatcher_password: "CHANGEME" 9 | # yes/no: enable/disable mailcatcher service, enable/disable it at boot 10 | mailcatcher_enable_service: yes 11 | # listen addresses for the SMTP and HTTP services 12 | mailcatcher_smtp_listen_ip: "0.0.0.0" 13 | mailcatcher_http_listen_ip: "0.0.0.0" 14 | -------------------------------------------------------------------------------- /roles/adminer/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: import variable checks tasks 2 | import_tasks: checks.yml 3 | tags: 4 | - adminer 5 | - checks 6 | 7 | - name: import Adminer configuration tasks 8 | import_tasks: adminer.yml 9 | become: yes 10 | tags: adminer 11 | 12 | - name: import php-fpm configuration tasks 13 | import_tasks: php-fpm.yml 14 | become: yes 15 | tags: adminer 16 | 17 | - name: import self-signed certificates configuration tasks 18 | import_tasks: ssl-selfsigned.yml 19 | become: yes 20 | tags: adminer 21 | 22 | - name: import apache configuration tasks 23 | import_tasks: apache.yml 24 | become: yes 25 | tags: adminer 26 | -------------------------------------------------------------------------------- /roles/common/tasks/remove-firehol.yml: -------------------------------------------------------------------------------- 1 | - name: remove firehol management tools (supersessed with librelogic.librelogic.firewalld) 2 | apt: 3 | package: 4 | - firehol 5 | - firehol-tools 6 | state: absent 7 | purge: yes 8 | autoremove: yes 9 | 10 | - name: remove configurations 11 | file: 12 | path: "{{ item }}" 13 | state: absent 14 | loop: 15 | - "/etc/firehol" 16 | - "/etc/systemd/system/firehol.service" 17 | - "/etc/default/firehol" 18 | notify: reload systemd unit files 19 | 20 | # Apply firewall rules as soon as possible 21 | - name: force all notified handlers to run now 22 | meta: flush_handlers 23 | -------------------------------------------------------------------------------- /roles/monitoring_utils/templates/etc_lynis_custom.prf.j2: -------------------------------------------------------------------------------- 1 | # Profile name, will be used as title/description 2 | profile-name=Custom Audit Template 3 | 4 | # Skip a test (one per line) 5 | {% if lynis_skip_tests %} 6 | {% for test in lynis_skip_tests %} 7 | skip-test={{ test }} 8 | {% endfor %} 9 | {% endif %} 10 | {{ "skip-test=ACCT-9626" if (ansible_local.netdata.ansible_managed is defined) and (ansible_local.netdata.ansible_managed) }} 11 | # Skip a particular option within a test (when applicable) 12 | #skip-test=SSH-7408:loglevel 13 | #skip-test=SSH-7408:permitrootlogin 14 | 15 | # Skip Lynis upgrade availability test (default: no) 16 | skip-upgrade-test=yes 17 | -------------------------------------------------------------------------------- /roles/common/templates/etc_systemd_system_firehol.service.j2: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Firehol stateful packet filtering firewall for humans 3 | Documentation=man:firehol(1) man:firehol.conf(5) 4 | 5 | DefaultDependencies=no 6 | 7 | Before=network-pre.target 8 | Wants=network-pre.target 9 | 10 | Wants=systemd-modules-load.service local-fs.target 11 | After=systemd-modules-load.service local-fs.target 12 | 13 | Conflicts=shutdown.target 14 | Before=shutdown.target 15 | 16 | [Service] 17 | Type=oneshot 18 | RemainAfterExit=yes 19 | ExecStart=/usr/sbin/firehol start 20 | ExecReload=/usr/sbin/firehol start 21 | ExecStop= 22 | 23 | [Install] 24 | WantedBy=multi-user.target 25 | -------------------------------------------------------------------------------- /roles/mailcatcher/tasks/checks.yml: -------------------------------------------------------------------------------- 1 | ##### CHECKS FOR MAILCATCHER ROLE ##### 2 | 3 | - name: check that mandatory variables are correctly defined 4 | assert: 5 | that: 6 | - mailcatcher_fqdn is not search("CHANGEME") 7 | - mailcatcher_user is not search("CHANGEME") 8 | - mailcatcher_password is not search("CHANGEME") 9 | - mailcatcher_enable_service == mailcatcher_enable_service|bool 10 | # - mailcatcher_smtp_listen_ip|ansible.netcommon.ipaddr # disabled, adds a dependency on python3-netaddr on the controller 11 | # - mailcatcher_http_listen_ip|ansible.netcommon.ipaddr # disabled, adds a dependency on python3-netaddr on the controller 12 | -------------------------------------------------------------------------------- /roles/monitoring_utils/tasks/utils-duc.yml: -------------------------------------------------------------------------------- 1 | - name: install duc 2 | apt: 3 | package: duc 4 | state: present 5 | 6 | - name: index filesystem with duc 7 | command: 8 | cmd: "duc index --check-hard-links --database=/root/.duc.db '{{ duc_index_path }}'" 9 | changed_when: yes 10 | 11 | - name: download duc database to data/duc-*.db 12 | fetch: 13 | src: /root/.duc.db 14 | dest: "{{ playbook_dir }}/data/duc-{{ inventory_hostname }}.db" 15 | flat: yes 16 | 17 | - name: show duc completion message 18 | debug: 19 | msg: "you can now open the database with duc gui --database={{ playbook_dir }}/data/duc-{{ inventory_hostname }}.db {{ duc_index_path }}" 20 | -------------------------------------------------------------------------------- /galaxy.yml: -------------------------------------------------------------------------------- 1 | namespace: librelogic 2 | name: librelogic 3 | version: 0.1.0 4 | readme: README.md 5 | authors: 6 | - Libre Logic 7 | description: "Install and manage self-hosted network services, applications and IT infrastructure" 8 | license: "GPL-3.0" 9 | tags: [] 10 | dependencies: {} 11 | repository: "https://github.com/libre-logic/ansible-collection-librelogic" 12 | documentation: "https://github.com/libre-logic/ansible-collection-librelogic" 13 | homepage: "https://www.libre-logic.fr" 14 | issues: "https://github.com/libre-logic/ansible-collection-librelogic/issues" 15 | build_ignore: 16 | - .venv 17 | - tests/ 18 | - Makefile 19 | - .gitlab-ci.yml 20 | -------------------------------------------------------------------------------- /roles/mailcatcher/templates/etc_systemd_system_mailcatcher.service.j2: -------------------------------------------------------------------------------- 1 | # Systemd unit file for mailcatcher 2 | # https://github.com/sj26/mailcatcher#command-line-options 3 | [Unit] 4 | Description=mailcatcher - catches any e-mail sent to it to display in a web interface 5 | After=syslog.target 6 | After=network.target 7 | 8 | [Service] 9 | RestartSec=5s 10 | Type=simple 11 | User=mailcatcher 12 | Group=mailcatcher 13 | WorkingDirectory=~ 14 | ExecStart={{ mailcatcher_bin_path }} --smtp-ip {{ mailcatcher_smtp_listen_ip }} --smtp-port 1025 --http-ip {{ mailcatcher_http_listen_ip }} --http-port=8025 --foreground --verbose 15 | Restart=always 16 | 17 | [Install] 18 | WantedBy=multi-user.target 19 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/opt_netdata-logcount_logcount.sql.j2: -------------------------------------------------------------------------------- 1 | # 2 | # @synopsis: level-count 3 | # @description: Print out the number of log messages from the past 1 minute and broken down by log level 4 | # @reference: https://github.com/tstack/lnav/issues/721 5 | # 6 | 7 | ;WITH level_counts AS 8 | (SELECT log_level, count(*) AS total 9 | FROM all_logs 10 | WHERE log_time >= datetime(datetime(CURRENT_TIMESTAMP, 'localtime'), '-{{ netdata_logcount_update_interval }} minutes') 11 | GROUP BY log_level) 12 | SELECT 'total' AS log_level, sum(total) AS total FROM level_counts 13 | UNION 14 | SELECT * FROM level_counts 15 | :write-csv-to /var/cache/logcount 16 | -------------------------------------------------------------------------------- /roles/gitlab/meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | author: 'Libre Logic ' 3 | description: 'Gitlab software forge and DevOps platform' 4 | company: 'Libre Logic' 5 | license: 'GPL-3.0' 6 | min_ansible_version: 2.12 7 | platforms: 8 | - name: Debian 9 | versions: 10 | - 10 11 | - 11 12 | galaxy_tags: 13 | - git 14 | - forge 15 | - continuous 16 | - integration 17 | - delivery 18 | - issues 19 | - project 20 | - management 21 | - wiki 22 | 23 | dependencies: [] 24 | # - librelogic.librelogic.common # optional (firewall, fail2ban, base setup) 25 | # - librelogic.librelogic.monitoring # optional (log aggregation) 26 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/files/usr_local_bin_needrestart-autorestart: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Parse needrestart output and reboot automatically if needed. 3 | # Must be run as root or user with permissions to reboot. 4 | set -o errexit 5 | set -o pipefail 6 | set -o nounset 7 | 8 | needrestart_ksta=$(/usr/sbin/needrestart -b -k | grep '^NEEDRESTART-KSTA' | awk -F' ' '{print $2}') 9 | 10 | if [[ "$needrestart_ksta" == "3" ]]; then 11 | echo "NEEDRESTART-KSTA: 3, reboot required, rebooting" 12 | /usr/sbin/reboot 13 | elif [[ "$needrestart_ksta" == "2" ]]; then 14 | echo "NEEDRESTART-KSTA: 2, reboot required, rebooting" 15 | /usr/sbin/reboot 16 | else 17 | echo "No reboot required." 18 | fi 19 | -------------------------------------------------------------------------------- /roles/apache/meta/main.yml: -------------------------------------------------------------------------------- 1 | # @tag apache - setup the apache web server 2 | # @tag ssl - setup SSL certificates and configuration 3 | # @tag apache-reverseproxy - setup apache custom reverseproxies 4 | 5 | galaxy_info: 6 | role_name: apache 7 | author: "nodiscc " 8 | description: "web server/reverse proxy + PHP-FPM interpreter" 9 | license: "GPL-3.0" 10 | min_ansible_version: "2.12" 11 | platforms: 12 | - name: Debian 13 | versions: 14 | - "11" 15 | - "12" 16 | galaxy_tags: 17 | - web 18 | - apache 19 | - php 20 | - server 21 | - webserver 22 | - reverseproxy 23 | - lamp 24 | dependencies: 25 | - librelogic.librelogic.handlers 26 | -------------------------------------------------------------------------------- /roles/adminer/tasks/php-fpm.yml: -------------------------------------------------------------------------------- 1 | - name: detect php-fpm version 2 | set_fact: 3 | php_fpm_version: "{{ item.value }}" 4 | when: "ansible_distribution == 'Debian' and ansible_distribution_release == item.release_name" 5 | loop: 6 | - { value: "7.3", release_name: 'buster' } 7 | - { value: "7.4", release_name: 'bullseye' } 8 | - { value: "7.5", release_name: 'bookworm' } 9 | 10 | - name: copy php-fpm configuration 11 | template: 12 | src: etc_php_7.3_fpm_pool.d_adminer.conf.j2 13 | dest: /etc/php/{{ php_fpm_version }}/fpm/pool.d/adminer.conf 14 | mode: 0644 15 | notify: restart php-fpm 16 | 17 | - name: ensure php-fpm configuration is applied (flush handlers) 18 | meta: flush_handlers 19 | -------------------------------------------------------------------------------- /roles/common/tasks/utils-firewalld-info.yml: -------------------------------------------------------------------------------- 1 | - name: get firewalld status info 2 | ansible.posix.firewalld_info: 3 | register: common_firewalld_info 4 | 5 | - name: write firewalld status info to file 6 | template: 7 | src: var_log_firewalld-info.log.j2 8 | dest: /var/log/firewalld-info.log 9 | owner: root 10 | group: root 11 | mode: "0640" 12 | ignore_errors: "{{ ansible_check_mode }}" 13 | diff: no 14 | 15 | - name: download firewalld status info to data/firewalld-info-*.log 16 | fetch: 17 | src: /var/log/firewalld-info.log 18 | dest: "{{ playbook_dir }}/data/firewalld-info-{{ inventory_hostname }}.log" 19 | flat: yes 20 | ignore_errors: "{{ ansible_check_mode }}" 21 | diff: no 22 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_default_debsecan.j2: -------------------------------------------------------------------------------- 1 | # Configuration file for debsecan. Contents of this file should 2 | # adhere to the KEY=VALUE shell syntax. This file may be edited by 3 | # debsecan's scripts, but your modifications are preserved. 4 | 5 | # If true, enable daily reports, sent by email. 6 | REPORT={{ 'true' if debsecan_enable_reports else 'false' }} 7 | 8 | # For better reporting, specify the correct suite here, using the code 9 | # name (that is, "sid" instead of "unstable"). 10 | SUITE={{ ansible_facts.distribution_release }} 11 | 12 | # Mail address to which reports are sent. 13 | MAILTO=root 14 | 15 | # The URL from which vulnerability data is downloaded. Empty for the 16 | # built-in default. 17 | SOURCE= 18 | -------------------------------------------------------------------------------- /roles/docker/meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | role_name: docker 3 | author: "geerlingguy, nodiscc , Libre Logic " 4 | description: "Open source application containerization technology" 5 | license: MIT 6 | min_ansible_version: 2.9 7 | platforms: 8 | - name: Debian 9 | versions: 10 | - 9 11 | - 10 12 | - name: Ubuntu 13 | versions: 14 | - 18.04 15 | galaxy_tags: 16 | - web 17 | - system 18 | - containers 19 | - docker 20 | - orchestration 21 | - compose 22 | - server 23 | dependencies: 24 | - librelogic.librelogic.handlers 25 | # - librelogic.librelogic.common # optional 26 | # - librelogic.librelogic.monitoring # optional 27 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_netdata_health.d_dockerd.conf.j2: -------------------------------------------------------------------------------- 1 | {% if 'librelogic.librelogic.docker' in role_names %} 2 | template: docker_unhealthy_containers 3 | on: docker.unhealthy_containers 4 | units: unhealthy containers 5 | every: 10s 6 | lookup: average -10s 7 | crit: $this > 0 8 | info: number of unhealthy containers 9 | to: sysadmin 10 | 11 | alarm: docker_running_containers 12 | on: dockerd_local.running_containers 13 | units: running containers 14 | every: 10s 15 | lookup: average -10s 16 | crit: ($this < {{ netdata_min_running_docker_containers }}) OR ($this > {{ netdata_max_running_docker_containers }}) 17 | info: number of running containers 18 | to: sysadmin 19 | {% endif %} 20 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/tasks/utils-autorestart.yml: -------------------------------------------------------------------------------- 1 | - name: check if host must be rebooted 2 | command: needrestart -b -k 3 | register: monitoring_netdata_needrestart_kernel 4 | changed_when: no 5 | check_mode: no # run even in check mode as it doesn't change anything 6 | ignore_errors: "{{ ansible_check_mode }}" 7 | 8 | - name: reboot host if an updated kernel must be loaded 9 | reboot: 10 | when: "'NEEDRESTART-KSTA: 3' in monitoring_netdata_needrestart_kernel.stdout_lines" 11 | 12 | - name: restart services if required after an upgrade 13 | command: needrestart -r a 14 | become: yes 15 | register: monitoring_netdata_needrestart_services 16 | changed_when: "'No services need to be restarted.' not in monitoring_netdata_needrestart_services.stdout_lines" 17 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/tasks/firewalld.yml: -------------------------------------------------------------------------------- 1 | - name: copy netdata firewalld service definition 2 | template: 3 | src: etc_firewalld_services_netdata.xml.j2 4 | dest: /etc/firewalld/services/netdata.xml 5 | owner: root 6 | group: adm 7 | mode: "0640" 8 | notify: reload firewalld 9 | ignore_errors: "{{ ansible_check_mode }}" 10 | 11 | # reload firewalld service definitions 12 | - name: apply configuration (flush handlers) 13 | meta: flush_handlers 14 | 15 | - name: setup firewalld rules for netdata 16 | ansible.posix.firewalld: 17 | zone: "{{ item.zone }}" 18 | service: netdata 19 | state: "{{ item.state }}" 20 | permanent: yes 21 | immediate: yes 22 | with_items: "{{ netdata_firewalld_zones }}" 23 | ignore_errors: "{{ ansible_check_mode }}" 24 | -------------------------------------------------------------------------------- /roles/openldap/tasks/backups.yml: -------------------------------------------------------------------------------- 1 | - name: create directory for openldap backups 2 | file: 3 | path: /var/backups/openldap/ 4 | state: directory 5 | owner: root 6 | group: openldap 7 | mode: 0750 8 | 9 | - name: copy slapd database backup script 10 | template: 11 | src: usr_local_bin_openldap-dump.sh.j2 12 | dest: /usr/local/bin/openldap-dump.sh 13 | mode: 0755 14 | owner: root 15 | group: root 16 | 17 | - name: copy rsnapshot configuration for openldap backups 18 | template: 19 | src: etc_rsnapshot.d_openldap.conf.j2 20 | dest: /etc/rsnapshot.d/openldap.conf 21 | mode: 0600 22 | notify: check rsnapshot configuration 23 | when: 24 | - ansible_local.backup.ansible_managed is defined 25 | - ansible_local.backup.ansible_managed|bool 26 | -------------------------------------------------------------------------------- /roles/openldap/meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | role_name: openldap 3 | author: "nodiscc , Libre Logic " 4 | description: "LDAP directory server and web management tools" 5 | license: "GPL-3.0" 6 | min_ansible_version: 2.7 7 | platforms: 8 | - name: Debian 9 | versions: 10 | - 10 11 | - 11 12 | galaxy_tags: 13 | - ldap 14 | - directory 15 | - authentication 16 | dependencies: [] 17 | #- 'librelogic.librelogic.common' # optional, base system setup/hardening/firewall/bruteforce protection 18 | #- 'librelogic.librelogic.apache' # optional, if ldap-account-manager/self-service-password setup is enabled 19 | #- 'librelogic.librelogic.php_fpm' # optional, if ldap-account-manager/self-service-password setup is enabled 20 | -------------------------------------------------------------------------------- /roles/monitoring_rsyslog/tasks/firewalld.yml: -------------------------------------------------------------------------------- 1 | - name: copy syslog-tcp-ssl firewalld service definition 2 | template: 3 | src: etc_firewalld_services_syslog-tcp-ssl.xml.j2 4 | dest: /etc/firewalld/services/syslog-tcp-ssl.xml 5 | owner: root 6 | group: adm 7 | mode: "0640" 8 | notify: reload firewalld 9 | ignore_errors: "{{ ansible_check_mode }}" 10 | 11 | # reload firewalld service definitions 12 | - name: apply configuration (flush handlers) 13 | meta: flush_handlers 14 | 15 | - name: setup firewalld rules for rsyslog 16 | ansible.posix.firewalld: 17 | zone: "{{ item.zone }}" 18 | service: syslog-tcp-ssl 19 | state: "{{ item.state if rsyslog_enable_receive else 'disabled' }}" 20 | permanent: yes 21 | immediate: yes 22 | with_items: "{{ rsyslog_firewalld_zones }}" 23 | -------------------------------------------------------------------------------- /roles/openldap/tasks/netdata.yml: -------------------------------------------------------------------------------- 1 | - name: install netdata http/systemd checks for openldap 2 | template: 3 | src: "{{ item.src }}" 4 | dest: "{{ item.dest }}" 5 | owner: root 6 | group: netdata 7 | mode: 0640 8 | notify: assemble netdata configuration 9 | ignore_errors: "{{ ansible_check_mode }}" 10 | with_items: 11 | - src: etc_netdata_go.d_httpcheck.conf.d_openldap.conf.j2 12 | dest: /etc/netdata/go.d/httpcheck.conf.d/openldap.conf 13 | - src: etc_netdata_health.d_systemdunits.conf.d_openldap.conf.j2 14 | dest: /etc/netdata/health.d/systemdunits.conf.d/openldap.conf 15 | 16 | - name: remove files from old versions of the role 17 | file: 18 | state: absent 19 | path: "/etc/netdata/health.d/processes.conf.d/openldap.conf" 20 | notify: assemble netdata configuration 21 | -------------------------------------------------------------------------------- /roles/monitoring_utils/meta/main.yml: -------------------------------------------------------------------------------- 1 | # @tag lynis - setup lynis security audit tool 2 | # @tag monitoring_utils - setup command-line/additional monitoring utilities 3 | # @tag utils-duc - (manual) run duc disk usage analyzer and download the report on the controller 4 | # @tag utils-bonnie - (manual) run duc disk benchmarking tool and download the report on the controller 5 | 6 | galaxy_info: 7 | role_name: monitoring_utils 8 | author: "nodiscc " 9 | description: "monitoring and audit utilities" 10 | license: GPL-3.0 11 | min_ansible_version: "2.12" 12 | platforms: 13 | - name: Debian 14 | versions: 15 | - "11" 16 | - "12" 17 | galaxy_tags: 18 | - system 19 | - monitoring 20 | - audit 21 | - security 22 | dependencies: 23 | - librelogic.librelogic.handlers 24 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_netdata_health.d_logcount.conf.j2: -------------------------------------------------------------------------------- 1 | alarm: logcount_error 2 | on: logcount.messages 3 | calc: $error 4 | every: 10s 5 | warn: $this > {{ netdata_logcount_error_threshold_warn }} 6 | crit: $this > {{ netdata_logcount_error_threshold_crit }} 7 | units: error messages 8 | info: error messages in logs over last {{ netdata_logcount_update_interval }} minutes 9 | to: {{ netdata_logcount_notification_to }} 10 | class: Errors 11 | 12 | alarm: logcount_warning 13 | on: logcount.messages 14 | calc: $warning 15 | every: 10s 16 | warn: $this > {{ netdata_logcount_warning_threshold_warn }} 17 | units: warning messages 18 | info: warning messages in logs over last {{ netdata_logcount_update_interval }} minutes 19 | to: {{ netdata_logcount_notification_to }} 20 | class: Errors 21 | -------------------------------------------------------------------------------- /roles/common/tasks/utils-apt-unattended-upgrade.yml: -------------------------------------------------------------------------------- 1 | - name: run unattended-upgrades now 2 | command: 3 | cmd: /usr/bin/unattended-upgrade --verbose 4 | register: unattended_upgrade 5 | changed_when: '"No packages found that can be upgraded unattended and no pending auto-removals" not in unattended_upgrade.stdout' 6 | environment: 7 | LANG: C 8 | LC_ALL: C 9 | LANGUAGE: C 10 | 11 | - name: list and display upgradable packages 12 | block: 13 | - name: list upgradable packages 14 | command: 15 | cmd: apt list --upgradable 16 | register: apt_upgradable 17 | changed_when: no 18 | check_mode: no # run even in check mode so that following tasks don't fail, doesn't change anything 19 | - name: display upgradable packages 20 | debug: 21 | msg: "{{ apt_upgradable.stdout }}" 22 | -------------------------------------------------------------------------------- /roles/proxmox/tasks/proxmox.yml: -------------------------------------------------------------------------------- 1 | - name: remove files from old versions of the role 2 | file: 3 | state: absent 4 | path: "{{ item }}" 5 | with_items: 6 | - "/etc/apt/sources.list.d/debian-contrib.list" 7 | - "/etc/apt/sources.list.d/debian-updates-contrib.list" 8 | - "/etc/apt/sources.list.d/debian-security-contrib.list" 9 | 10 | - name: copy APT sources lists for proxmox (contrib, pve-no-subscription) 11 | template: 12 | src: etc_apt_sources.list.d_proxmox.list.j2 13 | dest: /etc/apt/sources.list.d/proxmox.list 14 | owner: root 15 | group: root 16 | mode: 0644 17 | 18 | - name: hide OS name in postfix banner 19 | lineinfile: 20 | path: /etc/postfix/main.cf 21 | regexp: '^smtpd_banner' 22 | line: 'smtpd_banner = $myhostname ESMTP' 23 | mode: 0644 24 | owner: root 25 | group: root 26 | -------------------------------------------------------------------------------- /roles/monitoring/meta/main.yml: -------------------------------------------------------------------------------- 1 | # @tag monitoring - setup monitoring/alerting/logging system/utilities 2 | 3 | galaxy_info: 4 | role_name: monitoring 5 | author: "nodiscc " 6 | description: "monitoring, alerting, audit and logging system" 7 | license: GPL-3.0 8 | min_ansible_version: "2.12" 9 | platforms: 10 | - name: Debian 11 | versions: 12 | - "11" 13 | - "12" 14 | galaxy_tags: 15 | - system 16 | - performance 17 | - monitoring 18 | - alerting 19 | - health 20 | - graphs 21 | - charts 22 | - syslog 23 | - rsyslog 24 | - logging 25 | - audit 26 | - security 27 | dependencies: 28 | - librelogic.librelogic.handlers 29 | - librelogic.librelogic.monitoring_rsyslog 30 | - librelogic.librelogic.monitoring_netdata 31 | - librelogic.librelogic.monitoring_utils 32 | -------------------------------------------------------------------------------- /roles/monitoring_rsyslog/templates/etc_rsyslog.d_apt.conf.j2: -------------------------------------------------------------------------------- 1 | # rsyslog configuration for APT package manager related logs 2 | 3 | input(type="imfile" 4 | File="/var/log/apt/history.log" 5 | readMode="0" 6 | Tag="apt:" 7 | Facility="local0" 8 | PersistStateInterval="0") 9 | 10 | input(type="imfile" 11 | File="/var/log/apt/term.log" 12 | readMode="2" 13 | Tag="apt:" 14 | Facility="local0" 15 | PersistStateInterval="0") 16 | 17 | # dpkg log - verbose, disabled 18 | #input(type="imfile" 19 | # File="/var/log/dpkg.log" 20 | # Tag="dpkg:" 21 | # Facility="local0" 22 | # PersistStateInterval="0") 23 | 24 | input(type="imfile" 25 | File="/var/log/unattended-upgrades/unattended-upgrades.log" 26 | readMode="0" 27 | Tag="unattended-upgrades:" 28 | Facility="local0" 29 | PersistStateInterval="0") 30 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_netdata_health.d_filecheck.conf.d_000-filecheck.conf.j2: -------------------------------------------------------------------------------- 1 | # examples: 2 | # alarm: filecheck_file1_exists 3 | # on: filecheck_file1.file_existence 4 | # calc: ${/path/to/file1} 5 | # every: 5m 6 | # crit: $this = 0 7 | # info: existence of /path/to/file1 8 | # class: Errors 9 | # to: sysadmin 10 | 11 | # alarm: filecheck_file1_max_age 12 | # on: filecheck_file1.file_mtime_ago 13 | # calc: ${/path/to/file1} 14 | # every: 5m 15 | # units: seconds 16 | # warn: $this > 88200 # 24h 17 | # crit: $this > 90000 # 25h 18 | # info: time since last modification of /path/to/file1 19 | # class: Errors 20 | # to: sysadmin 21 | 22 | # alarm: filecheck_dir2_numfiles 23 | # on: filecheck_dir2_dir_num_of_files 24 | # calc: ${/path/to/dir2} 25 | # every: 5m 26 | # warn: $this > 0 27 | # info: number of files in /path/to/dir2/ 28 | # class: Errors 29 | # to: sysadmin 30 | -------------------------------------------------------------------------------- /roles/monitoring_utils/tasks/monitoring-utils.yml: -------------------------------------------------------------------------------- 1 | - name: install interactive/command-line monitoring tools 2 | apt: 3 | state: present 4 | package: 5 | - ncdu # ncurses disk usage viewer 6 | - nethogs # network bandwidth usage monitor 7 | - htop # system monitor/process manager 8 | - lsof # list open files 9 | - strace # trace system calls 10 | - lnav # enhanced log file viewer 11 | - iputils-ping # tools to test the reachability of network hosts 12 | # - spectre-meltdown-checker # spectre & meltdown CPU vulnerability checker 13 | # - iotop # simple top-like I/O monitor 14 | # - iftop # displays bandwidth usage information on a network interface 15 | # - inxi # full featured system information script 16 | # - arpscan # count machines on LAN 17 | # - logwatch # log analyser with nice output written in Perl (requires libdate-manip-perl) 18 | -------------------------------------------------------------------------------- /roles/docker/README.md: -------------------------------------------------------------------------------- 1 | # librelogic.docker 2 | 3 | An Ansible Role that installs [Docker](https://www.docker.com) on Linux. 4 | 5 | ## Requirements/Dependencies/example playbook 6 | 7 | See [`meta/main.yml`](meta/main.yml) 8 | 9 | ```yaml 10 | # playbook.yml 11 | - hosts: my.CHANGEME.org 12 | roles: 13 | - librelogic.librelogic.common # (optional) basic setup, hardening, firewall 14 | - librelogic.librelogic.monitoring # (optional) system/container monitoring and health checks 15 | - librelogic.librelogic.docker 16 | 17 | # required variables: 18 | # none 19 | ``` 20 | 21 | See [`defaults/main.yml`](defaults/main.yml) for all configuration variables. 22 | 23 | ## License 24 | 25 | [MIT](https://opensource.org/licenses/MIT) 26 | 27 | 28 | ## References 29 | 30 | - https://github.com/libre-logic/ansible-collection/ 31 | - https://github.com/nodiscc/xsrv/tree/master/roles/docker 32 | - https://github.com/geerlingguy/ansible-role-docker 33 | -------------------------------------------------------------------------------- /roles/openldap/templates/var_lib_ldap-account-manager_config_profiles_lam_default.user.j2: -------------------------------------------------------------------------------- 1 | profname: default 2 | ldap_suffix: ou=users,{{ openldap_base_dn }} 3 | ldap_rdn: cn 4 | inetOrgPerson_initials: 5 | inetOrgPerson_description: 6 | inetOrgPerson_street: 7 | inetOrgPerson_postOfficeBox: 8 | inetOrgPerson_postalCode: 9 | inetOrgPerson_l: 10 | inetOrgPerson_st: 11 | inetOrgPerson_postalAddress: 12 | inetOrgPerson_registeredAddress: 13 | inetOrgPerson_physicalDeliveryOfficeName: 14 | inetOrgPerson_roomNumber: 15 | inetOrgPerson_telephoneNumber: 16 | inetOrgPerson_facsimileTelephoneNumber: 17 | inetOrgPerson_mail: 18 | inetOrgPerson_labeledURI: 19 | inetOrgPerson_departmentNumber: 20 | inetOrgPerson_ou: 21 | inetOrgPerson_o: 22 | inetOrgPerson_title: 23 | inetOrgPerson_employeeType: 24 | inetOrgPerson_businessCategory: 25 | posixAccount_primaryGroup: users 26 | posixAccount_homeDirectory: /home/$user 27 | posixAccount_loginShell: /bin/bash 28 | -------------------------------------------------------------------------------- /roles/monitoring_utils/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: import monitoring-utils configuration tasks 2 | import_tasks: monitoring-utils.yml 3 | become: yes 4 | tags: 5 | - monitoring 6 | - monitoring_utils 7 | 8 | - name: import lynis configuration tasks 9 | import_tasks: lynis.yml 10 | become: yes 11 | tags: 12 | - monitoring 13 | - monitoring_utils 14 | - lynis 15 | 16 | - name: apply configuration (flush handlers) 17 | meta: flush_handlers 18 | tags: 19 | - monitoring 20 | - monitoring_utils 21 | - lynis 22 | 23 | ##### UTILITIES ##### 24 | # These tasks are tagged 'never' and will never run unless one of their tags is explicitly passed on the command line 25 | - name: import duc disk usage analysis tasks 26 | import_tasks: utils-duc.yml 27 | become: yes 28 | tags: 29 | - never 30 | - utils-duc 31 | 32 | - name: import bonnie++ disk benchmarking tasks 33 | import_tasks: utils-bonnie.yml 34 | become: yes 35 | tags: 36 | - never 37 | - utils-bonnie 38 | -------------------------------------------------------------------------------- /roles/gitlab_runner/templates/etc_gitlab-runner_config.toml.j2: -------------------------------------------------------------------------------- 1 | concurrent = {{ gitlab_runner_concurrent }} 2 | log_level = "{{ gitlab_runner_log_level }}" 3 | log_format = "text" 4 | check_interval = 3 5 | 6 | [session_server] 7 | session_timeout = 1800 8 | 9 | [[runners]] 10 | output_limit = {{ gitlab_runner_output_limit }} 11 | name = "{{ inventory_hostname }}" 12 | url = "{{ gitlab_runner_gitlab_url }}" 13 | token = "{{ gitlab_runner_register.runner.token | default(gitlab_runner_token[0]) }}" 14 | executor = "{{ gitlab_runner_executor }}" 15 | [runners.docker] 16 | tls_verify = false 17 | image = "docker.io/docker:stable" 18 | allowed_pull_policies = ["always", "if-not-present", "never"] 19 | privileged = false 20 | disable_entrypoint_overwrite = false 21 | oom_kill_disable = false 22 | disable_cache = false 23 | volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"] 24 | shm_size = 0 25 | [runners.cache] 26 | [runners.cache.s3] 27 | [runners.cache.gcs] 28 | -------------------------------------------------------------------------------- /roles/common/tasks/sysctl.yml: -------------------------------------------------------------------------------- 1 | - name: copy sysctl configuration 2 | template: 3 | src: 'etc_sysctl.d_custom.conf.j2' 4 | dest: '/etc/sysctl.d/custom.conf' 5 | owner: root 6 | group: root 7 | mode: "0600" 8 | notify: apply sysctl configuration 9 | 10 | - name: setup kernel modules blacklist 11 | template: 12 | src: etc_modprobe.d_blacklist.conf.j2 13 | dest: /etc/modprobe.d/blacklist.conf 14 | mode: "0644" 15 | owner: root 16 | group: root 17 | 18 | - name: configure system to attempt to repair failed filesystems on boot 19 | template: 20 | src: etc_default_rcS.j2 21 | dest: /etc/default/rcS 22 | owner: root 23 | group: root 24 | mode: "0644" 25 | 26 | - name: mount /proc 27 | mount: 28 | name: /proc 29 | src: none 30 | fstype: proc 31 | opts: "rw,nosuid,nodev,noexec,relatime,hidepid={{ '2' if kernel_proc_hidepid else '0' }}" 32 | state: mounted 33 | 34 | # apply sysctl configuration 35 | - name: apply configuration (flush handlers) 36 | meta: flush_handlers 37 | -------------------------------------------------------------------------------- /roles/gitlab_runner/defaults/main.yml: -------------------------------------------------------------------------------- 1 | ##### GITLAB RUNNER ##### 2 | 3 | # URL of the gitlab instance to register the runner on 4 | gitlab_runner_gitlab_url: "https://gitlab.CHANGEME.com" 5 | # Runner registration token on the gitlab instance (admin/runners) 6 | gitlab_runner_registration_token: "CHANGEME" 7 | # Personal access token with API scope on the gitlab instance 8 | gitlab_runner_api_token: "CHANGEME" 9 | # Runner configuration, see https://docs.gitlab.com/runner/configuration/advanced-configuration.html 10 | gitlab_runner_description: "gitlab-runner on {{ inventory_hostname }} - {{ gitlab_runner_executor }} executor" 11 | gitlab_runner_access_level: "not_protected" 12 | gitlab_runner_executor: "docker" 13 | gitlab_runner_concurrent: '{{ ansible_processor_vcpus }}' 14 | gitlab_runner_log_level: "info" 15 | # yes/no: enable the gitlab-runner service 16 | gitlab_runner_enable_service: yes 17 | # maximum build log size in kilobytes 18 | gitlab_runner_output_limit: 20000 19 | # maximum run time for CI jobs, in seconds 20 | gitlab_runner_maximum_timeout: 3600 21 | -------------------------------------------------------------------------------- /roles/apache/templates/etc_fail2ban_filter.d_apache-default-vhost.conf.j2: -------------------------------------------------------------------------------- 1 | # Fail2Ban apache-default-vhost filter 2 | # 3 | # This fail2ban filter matches all requests to the default apache virtualhost 4 | # Apache logs are expected to be in a custom format of form "%t %v:%p h:% 13 | # The timestamp is surrounded with square brackets. 14 | # Fail2Ban remove the timestamp (see https://fail2ban.readthedocs.io/en/latest/filters.html) => square brackets are left emtpy. 15 | # Then we match the host "default" and the port. 16 | # And finally : 17 | # - either the address from the X-Forwarded-For HTT Header (if any); 18 | # - either the address from the remote server. 19 | # This aims to avoid the ban of front-end reverse proxy. 20 | failregex = ^\[\] default:(80|443) (.*ff:[^-]|h:) 21 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/tasks/netdata-module-apt.yml: -------------------------------------------------------------------------------- 1 | ### NETDATA-APT ### 2 | 3 | - name: clone netdata-apt module 4 | git: 5 | dest: "/root/netdata-apt" 6 | repo: "https://gitlab.com/nodiscc/netdata-apt" 7 | version: "1.1.2" 8 | accept_hostkey: yes 9 | force: yes # discard modified files 10 | ignore_errors: "{{ ansible_check_mode }}" 11 | no_log: yes 12 | 13 | - name: install netdata-apt module/script/configuration 14 | copy: 15 | remote_src: yes 16 | src: "{{ item.src }}" 17 | dest: "{{ item.dest }}" 18 | owner: root 19 | group: netdata 20 | mode: "0640" 21 | with_items: 22 | - { src: "/root/netdata-apt/usr_libexec_netdata_python.d_apt.chart.py", dest: "/usr/libexec/netdata/python.d/apt.chart.py", mode: "0755" } 23 | - { src: "/root/netdata-apt/etc_netdata_python.d_apt.conf", dest: "/etc/netdata/python.d/apt.conf" } 24 | - { src: "/root/netdata-apt/etc_netdata_health.d_apt.conf", dest: "/etc/netdata/health.d/apt.conf" } 25 | notify: restart netdata 26 | ignore_errors: "{{ ansible_check_mode }}" 27 | -------------------------------------------------------------------------------- /roles/docker_nginx/tasks/ssl-letsencrypt.yml: -------------------------------------------------------------------------------- 1 | ##### LET'S ENCRYPT CERTIFICATES ##### 2 | 3 | - name: check if certificate already exists 4 | become: yes 5 | stat: 6 | path: "/etc/letsencrypt/live/{{ item }}/cert.pem" 7 | register: letsencrypt_cert 8 | tags: docker_nginx 9 | 10 | - name: stop nginx to allow certbot standalone server to bind to port 80 11 | become: yes 12 | command: docker service scale nginx-reverseproxy_nginx-reverseproxy=0 13 | when: not letsencrypt_cert.stat.exists 14 | failed_when: false # ignore errors since the service will not exist yet on first run 15 | tags: docker_nginx 16 | 17 | - name: wait 5 seconds to allow the nginx docker service to terminate 18 | wait_for: 19 | timeout: 5 20 | when: not letsencrypt_cert.stat.exists 21 | tags: docker_nginx 22 | 23 | - name: generate initial certificate 24 | become: yes 25 | command: > 26 | certbot certonly --standalone --noninteractive --agree-tos 27 | --email "{{ nginx_letsencrypt_email }}" 28 | -d "{{ item }}" 29 | when: not letsencrypt_cert.stat.exists 30 | tags: docker_nginx 31 | -------------------------------------------------------------------------------- /roles/mailcatcher/templates/etc_apache2_sites-available_mailcatcher.conf.j2: -------------------------------------------------------------------------------- 1 | 2 | ServerName {{ mailcatcher_fqdn }} 3 | ServerAdmin webmaster@{{ mailcatcher_fqdn }} 4 | # Redirect all HTTP requests to HTTPS 5 | RewriteEngine On 6 | RewriteCond %{HTTPS} off 7 | RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} 8 | 9 | 10 | 11 | ServerName {{ mailcatcher_fqdn }} 12 | ServerAdmin webmaster@{{ mailcatcher_fqdn }} 13 | SSLEngine on 14 | SSLCertificateFile /etc/ssl/certs/{{ mailcatcher_fqdn }}.crt 15 | SSLCertificateKeyFile /etc/ssl/private/{{ mailcatcher_fqdn }}.key 16 | 17 | ProxyAddHeaders On 18 | ProxyPreserveHost On 19 | ProxyRequests off 20 | 21 | 22 | AuthType Basic 23 | AuthName "Authorization required" 24 | AuthBasicProvider file 25 | AuthUserFile /etc/apache2/mailcatcher.htpasswd 26 | Require valid-user 27 | 28 | ProxyPass http://127.0.0.1:8025/ 29 | ProxyPassReverse http://127.0.0.1:8025/ 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /roles/common/templates/etc_default_cron.j2: -------------------------------------------------------------------------------- 1 | # Cron configuration options 2 | 3 | # Whether to read the system's default environment files (if present) 4 | # If set to "yes", cron will set a proper mail charset from the 5 | # locale information. If set to something other than 'yes', the default 6 | # charset 'C' (canonical name: ANSI_X3.4-1968) will be used. 7 | # 8 | # This has no effect on tasks running under cron; their environment can 9 | # only be changed via PAM or from within the crontab; see crontab(5). 10 | READ_ENV="yes" 11 | 12 | # Extra options for cron, see cron(8) 13 | # 14 | # For example, to enable LSB name support in /etc/cron.d/, use 15 | # EXTRA_OPTS='-l' 16 | # 17 | # Or, to log standard messages, plus jobs with exit status != 0: 18 | # EXTRA_OPTS='-L 5' 19 | # 20 | # For quick reference, the currently available log levels are: 21 | # 0 no logging (errors are logged regardless) 22 | # 1 log start of jobs 23 | # 2 log end of jobs 24 | # 4 log jobs with exit status != 0 25 | # 8 log the process identifier of child process (in all logs) 26 | # 27 | EXTRA_OPTS="-n -L {{ cron_log_level }}" 28 | 29 | -------------------------------------------------------------------------------- /roles/monitoring_utils/tasks/utils-bonnie.yml: -------------------------------------------------------------------------------- 1 | - name: install bonnie++ 2 | apt: 3 | state: present 4 | package: bonnie++ 5 | 6 | - name: install bonnie++ wrapper script 7 | template: 8 | src: usr_local_bin_bonnie++-wrapper.j2 9 | dest: /usr/local/bin/bonnie++-wrapper 10 | owner: root 11 | group: root 12 | mode: "0755" 13 | 14 | - name: run bonnie++ 15 | command: 16 | cmd: /usr/local/bin/bonnie++-wrapper 17 | changed_when: yes # always returns changed, not meant to be idempotent 18 | 19 | - name: download bonnie++ reports to data/bonnie++-*.csv,html 20 | fetch: 21 | src: "{{ item.src }}" 22 | dest: "{{ item.dest }}" 23 | flat: yes 24 | loop: 25 | - src: /var/log/bonnie++.html 26 | dest: "{{ playbook_dir }}/data/bonnie++-{{ inventory_hostname }}.html" 27 | - src: /var/log/bonnie++.csv 28 | dest: "{{ playbook_dir }}/data/bonnie++-{{ inventory_hostname }}.csv" 29 | 30 | - name: show bonnie++ completion message 31 | debug: 32 | msg: "The CSV and HTML reports have been downloaded to {{ playbook_dir }}/data/bonnie++-{{ inventory_hostname }}.{csv,html}" 33 | -------------------------------------------------------------------------------- /roles/docker_nginx/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: show deprecation message 2 | tags: docker_nginx 3 | debug: 4 | msg: "**DEPRECATED** This role is deprecated in favor of the apache role. If you are still using this role, please adapt your nginx configuration for apache, then set `docker_nginx_remove: yes` before applying the apache role (this will remove the nginx Docker service/configuration and allow apache to bind port 80/443)." 5 | 6 | - include: checks.yml 7 | tags: 8 | - docker_nginx 9 | - checks 10 | 11 | - name: uninstall other web servers 12 | become: yes 13 | apt: 14 | state: absent 15 | package: 16 | - apache2 17 | - nginx 18 | when: not docker_nginx_remove|bool 19 | tags: docker_nginx 20 | 21 | - include: docker-nginx.yml 22 | become: yes 23 | when: not docker_nginx_remove|bool 24 | tags: docker_nginx 25 | 26 | - include: ssl-letsencrypt.yml 27 | with_items: "{{ nginx_letsencrypt_certificates }}" 28 | when: not docker_nginx_remove|bool 29 | tags: docker_nginx 30 | 31 | - include: remove.yml 32 | become: yes 33 | when: docker_nginx_remove|bool 34 | tags: docker_nginx 35 | -------------------------------------------------------------------------------- /roles/monitoring_rsyslog/templates/etc_logrotate.d_rsyslog.j2: -------------------------------------------------------------------------------- 1 | /var/log/syslog 2 | { 3 | rotate {{ rsyslog_retention_days }} 4 | daily 5 | missingok 6 | notifempty 7 | delaycompress 8 | compress 9 | postrotate 10 | /usr/lib/rsyslog/rsyslog-rotate 11 | endscript 12 | } 13 | 14 | /var/log/mail.info 15 | /var/log/mail.warn 16 | /var/log/mail.err 17 | /var/log/mail.log 18 | /var/log/daemon.log 19 | /var/log/kern.log 20 | /var/log/auth.log 21 | /var/log/user.log 22 | /var/log/lpr.log 23 | /var/log/cron.log 24 | /var/log/debug 25 | /var/log/messages 26 | { 27 | rotate 4 28 | weekly 29 | missingok 30 | notifempty 31 | compress 32 | delaycompress 33 | sharedscripts 34 | postrotate 35 | /usr/lib/rsyslog/rsyslog-rotate 36 | endscript 37 | } 38 | {% if rsyslog_enable_receive %} 39 | {{ rsyslog_remote_logs_path }}/*.log 40 | { 41 | rotate {{ rsyslog_retention_days }} 42 | daily 43 | dateext 44 | missingok 45 | notifempty 46 | delaycompress 47 | compress 48 | postrotate 49 | /usr/lib/rsyslog/rsyslog-rotate 50 | endscript 51 | } 52 | {% endif %} 53 | -------------------------------------------------------------------------------- /roles/adminer/tasks/apache.yml: -------------------------------------------------------------------------------- 1 | - name: install requirements for ansible htpasswd module 2 | apt: 3 | package: 4 | - python3-passlib 5 | - python3-bcrypt 6 | state: present 7 | 8 | - name: create apache HTTP basic auth password file 9 | htpasswd: 10 | path: /etc/apache2/adminer.htpasswd 11 | name: "{{ adminer_user }}" 12 | password: '{{ adminer_password }}' 13 | owner: root 14 | group: www-data 15 | mode: 0640 16 | notify: reload apache 17 | ignore_errors: "{{ ansible_check_mode }}" 18 | 19 | - name: copy apache2 virtualhost configuration 20 | template: 21 | src: etc_apache2_sites-available_adminer.conf.j2 22 | dest: /etc/apache2/sites-available/adminer.conf 23 | mode: 0644 24 | notify: reload apache 25 | ignore_errors: "{{ ansible_check_mode }}" 26 | 27 | - name: enable apache2 virtualhost 28 | command: a2ensite adminer 29 | args: 30 | creates: "/etc/apache2/sites-enabled/adminer.conf" 31 | notify: restart apache 32 | ignore_errors: "{{ ansible_check_mode }}" 33 | 34 | - name: ensure apache configuration is applied (flush handlers) 35 | meta: flush_handlers 36 | -------------------------------------------------------------------------------- /roles/apache/templates/etc_apache2_conf-available_ssl-common.conf.j2: -------------------------------------------------------------------------------- 1 | # Common SSL/TLS configuration 2 | SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 -TLSv1.2 3 | SSLCipherSuite ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS 4 | SSLHonorCipherOrder on 5 | SSLCompression off 6 | # Always ensure Cookies have "Secure" set (JAH 2012/1) 7 | # Header edit Set-Cookie (?i)^(.*)(;\s*secure)??((\s*;)?(.*)) "$1; Secure$3$4" 8 | # Disable SSL session tickets, may compromise Perfect Forward Secrecy 9 | SSLSessionTickets off 10 | # enable HTTP/2 11 | Protocols h2 http/1.1 -------------------------------------------------------------------------------- /roles/openldap/files/var_www_self-service-password_css_self-service-password.css: -------------------------------------------------------------------------------- 1 | /* CSS for LDAP Tool Box Self Service Password */ 2 | 3 | html, body { 4 | background: #eee; 5 | padding-top: 20px; 6 | font-size: 12pt; 7 | } 8 | 9 | .panel, .alert, .navbar-wrapper { 10 | box-shadow:0 3px 6px rgba(0,0,0,.25); 11 | } 12 | 13 | .panel { 14 | background-color:#fff; 15 | background-color:rgba(255,255,255,0.8); 16 | } 17 | 18 | img.logo { 19 | margin-bottom: 20px; 20 | } 21 | 22 | .title h1 { 23 | font-size: 20pt; 24 | } 25 | 26 | .result p { 27 | font-size: 14pt; 28 | } 29 | 30 | .result i.fa { 31 | font-size: 18pt; 32 | margin-right: 10px; 33 | } 34 | 35 | .help i.fa { 36 | font-size: 14pt; 37 | margin-right: 5px; 38 | } 39 | 40 | textarea { 41 | resize: vertical; 42 | } 43 | 44 | /** OVERRIDES/DARK THEME **/ 45 | 46 | .container-fluid { 47 | background-color: #1c1f20; 48 | } 49 | 50 | .panel { 51 | background-color: #1c1f20; 52 | background-image: none; 53 | border: 0px solid transparent; 54 | } 55 | 56 | .navbar { 57 | border: 0; 58 | } 59 | 60 | .alert { 61 | background-image: none; 62 | } 63 | 64 | .alert-info { 65 | background-color: #f2f2f2; 66 | } 67 | -------------------------------------------------------------------------------- /roles/monitoring/README.md: -------------------------------------------------------------------------------- 1 | # xsrv.monitoring 2 | 3 | This role will install a monitoring, alerting and logging system on a Linux machine. It is an alias for the following roles: 4 | - [librelogic.librelogic.monitoring_rsyslog](../monitoring_rsyslog) 5 | - [librelogic.librelogic.monitoring_netdata](../monitoring_netdata) 6 | - [librelogic.librelogic.monitoring_utils](../monitoring_utils) 7 | 8 | ## Requirements/dependencies/example playbook 9 | 10 | See [meta/main.yml](meta/main.yml) 11 | 12 | ```yaml 13 | - hosts: my.CHANGEME.org 14 | roles: 15 | - librelogic.librelogic.common # (optional) basic setup, hardening, firewall 16 | - librelogic.librelogic.monitoring 17 | # or enable only specific roles: 18 | # - librelogic.librelogic.monitoring_rsyslog 19 | # - librelogic.librelogic.monitoring_netdata 20 | # - librelogic.librelogic.monitoring_lynis 21 | ``` 22 | 23 | 24 | ## Tags 25 | 26 | 27 | ``` 28 | monitoring - setup monitoring/alerting/logging system/utilities 29 | ``` 30 | 31 | 32 | 33 | ## License 34 | 35 | [GNU GPLv3](../../LICENSE) 36 | 37 | 38 | ## References 39 | 40 | - https://stdout.root.sx/links/?searchtags=monitoring 41 | -------------------------------------------------------------------------------- /roles/adminer/README.md: -------------------------------------------------------------------------------- 1 | # librelogic.librelogic.adminer 2 | 3 | This role will install and configure [adminer](https://www.adminer.org/) 4 | 5 | > Adminer (formerly phpMinAdmin) is a full-featured database management tool written in PHP. Conversely to phpMyAdmin, it consist of a single file ready to deploy to the target server. Adminer is available for MySQL, MariaDB, PostgreSQL, SQLite, MS SQL, Oracle, Elasticsearch, MongoDB and others via plugin. 6 | 7 | 8 | ## Requirements/Dependencies/Example playbook 9 | 10 | See [meta/main.yml](meta/main.yml) 11 | 12 | ```yaml 13 | - hosts: my.CHANGEME.org 14 | roles: 15 | - librelogic.librelogic.common # optional 16 | - librelogic.librelogic.apache 17 | - librelogic.librelogic.php_fpm 18 | - librelogic.librelogic.adminer 19 | 20 | # host_vars/my.CHANGEME.org/my.CHANGEME.org.yml 21 | adminer_fqdn: adminer.CHANGEME.org 22 | 23 | # ansible-vault edit host_vars/my.CHANGEME.org/my.CHANGEME.org.vault.yml 24 | adminer_user: "CHANGEME" 25 | adminer_password: "CHANGEME" 26 | ``` 27 | 28 | ## License 29 | 30 | [GNU GPLv3](https://www.gnu.org/licenses/gpl-3.0.txt) 31 | 32 | ## References 33 | 34 | - https://github.com/libre-logic/ansible-collection-librelogic/ 35 | -------------------------------------------------------------------------------- /roles/adminer/tasks/ssl-selfsigned.yml: -------------------------------------------------------------------------------- 1 | ##### SSL/TLS CERTIFICATES - SELF-SIGNED ##### 2 | 3 | - name: install requirements for SSL/TLS certificates generation 4 | apt: 5 | state: present 6 | package: 7 | - python3-openssl 8 | - ssl-cert 9 | 10 | - name: generate openssl private key 11 | openssl_privatekey: 12 | path: "/etc/ssl/private/{{ adminer_fqdn }}.key" 13 | notify: restart apache 14 | ignore_errors: "{{ ansible_check_mode }}" 15 | 16 | - name: generate openssl certificate signing request 17 | openssl_csr: 18 | path: "/etc/ssl/private/{{ adminer_fqdn }}.csr" 19 | privatekey_path: "/etc/ssl/private/{{ adminer_fqdn }}.key" 20 | common_name: "{{ adminer_fqdn }}" 21 | key_usage: "digitalSignature,keyEncipherment" 22 | basicConstraints: "CA:TRUE" 23 | ignore_errors: "{{ ansible_check_mode }}" 24 | 25 | - name: generate self-signed openssl certificate 26 | openssl_certificate: 27 | path: "/etc/ssl/certs/{{ adminer_fqdn }}.crt" 28 | privatekey_path: "/etc/ssl/private/{{ adminer_fqdn }}.key" 29 | csr_path: "/etc/ssl/private/{{ adminer_fqdn }}.csr" 30 | provider: selfsigned 31 | notify: restart apache 32 | ignore_errors: "{{ ansible_check_mode }}" 33 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/meta/main.yml: -------------------------------------------------------------------------------- 1 | # @tag netdata - setup netdata monitoring system 2 | # @tag netdata-config - copy netdata configuration files 3 | # @tag netdata-modules - setup custom netdata modules 4 | # @tag netdata-needrestart - setup netdata needrestart module 5 | # @tag netdata-logcount - setup netdata logcount module 6 | # @tag netdata-debsecan - setup netdata debsecan module 7 | # @tag netdata-apt - setup netdata apt module 8 | # @tag utils-autorestart - (manual) reboot hosts if a Linux kernel upgrade is pending 9 | # @tag utils-netdata-test-notifications - send test netdata notification 10 | # @tag netdata-downtime - configure netdata downtime/silence schedules 11 | 12 | galaxy_info: 13 | role_name: monitoring_netdata 14 | author: "nodiscc " 15 | description: "lightweight, real-time monitoring and alerting system" 16 | license: GPL-3.0 17 | min_ansible_version: "2.12" 18 | platforms: 19 | - name: Debian 20 | versions: 21 | - "11" 22 | - "12" 23 | galaxy_tags: 24 | - system 25 | - performance 26 | - monitoring 27 | - alerting 28 | - health 29 | - graphs 30 | - charts 31 | dependencies: 32 | - librelogic.librelogic.handlers 33 | -------------------------------------------------------------------------------- /roles/monitoring_utils/tasks/lynis.yml: -------------------------------------------------------------------------------- 1 | ##### LYNIS SECURITY AUDIT ##### 2 | 3 | - name: install lynis and related utilities 4 | apt: 5 | package: 6 | - lynis 7 | - debsums 8 | state: present 9 | 10 | - name: copy custom lynis scan profile 11 | template: 12 | src: etc_lynis_custom.prf.j2 13 | dest: /etc/lynis/custom.prf 14 | owner: root 15 | group: root 16 | mode: "0640" 17 | 18 | - name: setup lynis daily cron job 19 | cron: 20 | cron_file: lynis 21 | hour: "21" 22 | minute: "0" 23 | day: "*" 24 | name: "daily lynis audit" 25 | job: > 26 | /usr/sbin/lynis audit system --profile /etc/lynis/custom.prf --warnings-only --cronjob --report-file /var/log/lynis-report.txt >/dev/null && 27 | grep -i -E '{{ lynis_report_regex }}' /var/log/lynis-report.txt 28 | user: root 29 | 30 | - name: disable lynis systemd timer 31 | systemd: 32 | name: lynis.timer 33 | state: stopped 34 | enabled: no 35 | ignore_errors: "{{ ansible_check_mode }}" 36 | 37 | - name: copy debsums cron job configuration 38 | template: 39 | src: etc_default_debsums.j2 40 | dest: /etc/default/debsums 41 | owner: root 42 | group: root 43 | mode: "0644" 44 | -------------------------------------------------------------------------------- /roles/common/templates/etc_fail2ban_jail.local.j2: -------------------------------------------------------------------------------- 1 | # Default Fail2ban configuration values 2 | 3 | [DEFAULT] 4 | # list of IPs that should never be banned 5 | ignoreip = 127.0.0.1 {{ ' '.join(fail2ban_ignoreip) }} 6 | # time interval (in seconds or time abbreviation format) before the current time where failures will count towards a ban 7 | findtime = {{ fail2ban_default_findtime }} 8 | # number of failures that have to occur in the last findtime seconds to ban the IP 9 | maxretry = {{ fail2ban_default_maxretry }} 10 | # effective ban duration (in seconds or time abbreviation format) 11 | bantime = {{ fail2ban_default_bantime }} 12 | # destination email address used for banactions 'action_m*' which trigger sending an email 13 | destemail = root 14 | # default banning action 15 | banaction = {{ 'firewallcmd-ipset[actiontype=,blocktype=DROP,maxelem=1000000]' if (ansible_local.firewalld.ansible_managed is defined and ansible_local.firewalld.ansible_managed) else 'iptables-ipset[type=multiport]' }} 16 | banaction_allports = {{ 'firewallcmd-ipset[actiontype=,blocktype=DROP,maxelem=1000000]' if (ansible_local.firewalld.ansible_managed is defined and ansible_local.firewalld.ansible_managed) else 'iptables-ipset[type=allports' }} 17 | -------------------------------------------------------------------------------- /roles/mailcatcher/tasks/ssl-selfsigned.yml: -------------------------------------------------------------------------------- 1 | ##### SSL/TLS CERTIFICATES - SELF-SIGNED ##### 2 | 3 | - name: install requirements for SSL/TLS certificates generation 4 | apt: 5 | state: present 6 | package: 7 | - python3-openssl 8 | - ssl-cert 9 | 10 | - name: generate openssl private key 11 | openssl_privatekey: 12 | path: "/etc/ssl/private/{{ mailcatcher_fqdn }}.key" 13 | notify: restart apache 14 | ignore_errors: "{{ ansible_check_mode }}" 15 | 16 | - name: generate openssl certificate signing request 17 | openssl_csr: 18 | path: "/etc/ssl/private/{{ mailcatcher_fqdn }}.csr" 19 | privatekey_path: "/etc/ssl/private/{{ mailcatcher_fqdn }}.key" 20 | common_name: "{{ mailcatcher_fqdn }}" 21 | key_usage: "digitalSignature,keyEncipherment" 22 | basicConstraints: "CA:TRUE" 23 | ignore_errors: "{{ ansible_check_mode }}" 24 | 25 | - name: generate self-signed openssl certificate 26 | openssl_certificate: 27 | path: "/etc/ssl/certs/{{ mailcatcher_fqdn }}.crt" 28 | privatekey_path: "/etc/ssl/private/{{ mailcatcher_fqdn }}.key" 29 | csr_path: "/etc/ssl/private/{{ mailcatcher_fqdn }}.csr" 30 | provider: selfsigned 31 | notify: restart apache 32 | ignore_errors: "{{ ansible_check_mode }}" 33 | -------------------------------------------------------------------------------- /roles/docker_nginx/templates/etc_docker_services-config/nginx/docker-compose.yml.j2: -------------------------------------------------------------------------------- 1 | version: '3.8' 2 | 3 | networks: 4 | nginx: 5 | external: true 6 | 7 | services: 8 | nginx-reverseproxy: 9 | image: nginx:alpine 10 | volumes: 11 | - /etc/docker/services-config/nginx/nginx.conf:/etc/nginx/nginx.conf:ro 12 | - /etc/docker/services-config/nginx/conf.d/:/etc/nginx/conf.d/:ro 13 | - /etc/docker/services-config/nginx/static:/usr/share/nginx/static:ro 14 | - /etc/docker/services-config/nginx/ssl/selfsigned/:/etc/nginx/ssl/selfsigned/:ro 15 | - /etc/letsencrypt/:/etc/nginx/ssl/letsencrypt/:ro 16 | ports: 17 | - target: 80 18 | published: 80 19 | protocol: tcp 20 | mode: host 21 | - target: 443 22 | published: 443 23 | protocol: tcp 24 | mode: host 25 | networks: 26 | {% if nginx_docker_aliases %} 27 | nginx: 28 | aliases: 29 | {% for alias in nginx_docker_aliases %} 30 | - {{ alias }} 31 | {% endfor %} 32 | {% else %} 33 | - nginx 34 | {% endif %} 35 | {% if nginx_docker_label_constraint is defined %} 36 | deploy: 37 | placement: 38 | constraints: [ node.labels.{{ nginx_docker_label_constraint }} == true ] 39 | {% endif %} 40 | -------------------------------------------------------------------------------- /roles/openldap/tasks/ldap-account-manager-ssl-selfsigned.yml: -------------------------------------------------------------------------------- 1 | - name: install requirements for SSL/TLS certificates generation 2 | apt: 3 | state: present 4 | package: 5 | - python3-openssl 6 | - ssl-cert 7 | 8 | - name: generate openssl private key 9 | openssl_privatekey: 10 | path: "/etc/ssl/private/{{ ldap_account_manager_fqdn }}.key" 11 | notify: restart apache 12 | ignore_errors: "{{ ansible_check_mode }}" 13 | 14 | - name: generate openssl certificate signing request 15 | openssl_csr: 16 | path: "/etc/ssl/private/{{ ldap_account_manager_fqdn }}.csr" 17 | privatekey_path: "/etc/ssl/private/{{ ldap_account_manager_fqdn }}.key" 18 | common_name: "{{ ldap_account_manager_fqdn }}" 19 | key_usage: "digitalSignature,keyEncipherment" 20 | basicConstraints: "CA:TRUE" 21 | ignore_errors: "{{ ansible_check_mode }}" 22 | 23 | - name: generate self-signed openssl certificate 24 | openssl_certificate: 25 | path: "/etc/ssl/certs/{{ ldap_account_manager_fqdn }}.crt" 26 | privatekey_path: "/etc/ssl/private/{{ ldap_account_manager_fqdn }}.key" 27 | csr_path: "/etc/ssl/private/{{ ldap_account_manager_fqdn }}.csr" 28 | provider: selfsigned 29 | notify: restart apache 30 | ignore_errors: "{{ ansible_check_mode }}" 31 | -------------------------------------------------------------------------------- /roles/mailcatcher/tasks/mailcatcher.yml: -------------------------------------------------------------------------------- 1 | - name: create mailcatcher user 2 | user: 3 | name: mailcatcher 4 | comment: "Mailcatcher service" 5 | home: '/var/lib/mailcatcher' 6 | 7 | - name: install requirements for mailcatcher gem builds 8 | package: 9 | name: 10 | - ruby-dev 11 | - ruby-sqlite3 12 | - make 13 | - g++ 14 | - acl 15 | state: present 16 | 17 | - name: install mailcatcher ruby gem 18 | become_user: mailcatcher 19 | gem: 20 | name: mailcatcher 21 | version: 0.8.0 22 | state: present 23 | user_install: yes 24 | ignore_errors: "{{ ansible_check_mode|bool }}" 25 | 26 | - name: install mailcatcher systemd service 27 | template: 28 | src: etc_systemd_system_mailcatcher.service.j2 29 | dest: /etc/systemd/system/mailcatcher.service 30 | owner: root 31 | group: root 32 | mode: 0644 33 | notify: 34 | - reload systemd unit files 35 | - restart mailcatcher 36 | 37 | - name: enable/disable start/stop mailcatcher service 38 | systemd: 39 | name: mailcatcher 40 | enabled: "{{ mailcatcher_enable_service }}" 41 | state: "{{ 'started' if mailcatcher_enable_service else 'stopped' }}" 42 | daemon_reload: yes 43 | ignore_errors: "{{ ansible_check_mode|bool }}" 44 | -------------------------------------------------------------------------------- /roles/openldap/tasks/self-service-password-ssl-selfsigned.yml: -------------------------------------------------------------------------------- 1 | - name: install requirements for SSL/TLS certificates generation 2 | apt: 3 | state: present 4 | package: 5 | - python3-openssl 6 | - ssl-cert 7 | 8 | - name: generate openssl private key 9 | openssl_privatekey: 10 | path: "/etc/ssl/private/{{ self_service_password_fqdn }}.key" 11 | notify: restart apache 12 | ignore_errors: "{{ ansible_check_mode }}" 13 | 14 | - name: generate openssl certificate signing request 15 | openssl_csr: 16 | path: "/etc/ssl/private/{{ self_service_password_fqdn }}.csr" 17 | privatekey_path: "/etc/ssl/private/{{ self_service_password_fqdn }}.key" 18 | common_name: "{{ self_service_password_fqdn }}" 19 | key_usage: "digitalSignature,keyEncipherment" 20 | basicConstraints: "CA:TRUE" 21 | ignore_errors: "{{ ansible_check_mode }}" 22 | 23 | - name: generate self-signed openssl certificate 24 | openssl_certificate: 25 | path: "/etc/ssl/certs/{{ self_service_password_fqdn }}.crt" 26 | privatekey_path: "/etc/ssl/private/{{ self_service_password_fqdn }}.key" 27 | csr_path: "/etc/ssl/private/{{ self_service_password_fqdn }}.csr" 28 | provider: selfsigned 29 | notify: restart apache 30 | ignore_errors: "{{ ansible_check_mode }}" 31 | -------------------------------------------------------------------------------- /roles/openldap/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - include: checks.yml 2 | tags: 3 | - openldap 4 | - checks 5 | 6 | - include: openldap.yml 7 | become: yes 8 | tags: openldap 9 | 10 | - include: populate.yml 11 | become: yes 12 | tags: openldap 13 | 14 | - include: backups.yml 15 | become: yes 16 | tags: 17 | - openldap 18 | - backup 19 | 20 | - include: ssl-selfsigned.yml 21 | become: yes 22 | tags: 23 | - ssl 24 | - openldap 25 | - openldap-ssl 26 | 27 | - include: ldap-account-manager.yml 28 | become: yes 29 | tags: 30 | - openldap 31 | - ldap-account-manager 32 | when: openldap_setup_lam|bool 33 | 34 | - include: self-service-password.yml 35 | become: yes 36 | tags: 37 | - openldap 38 | - self-service-password 39 | when: openldap_setup_ssp|bool 40 | 41 | - include: netdata.yml 42 | become: yes 43 | tags: 44 | - openldap 45 | - monitoring 46 | - netdata 47 | - ldap-account-manager 48 | - self-service-password 49 | when: 50 | - ansible_local.netdata.ansible_managed is defined 51 | - ansible_local.netdata.ansible_managed|bool 52 | 53 | - include: fact.yml 54 | become: yes 55 | tags: openldap 56 | 57 | - name: apply configuration (flush handlers) 58 | meta: flush_handlers 59 | tags: openldap 60 | -------------------------------------------------------------------------------- /roles/common/tasks/packages.yml: -------------------------------------------------------------------------------- 1 | - name: remove unwanted packages 2 | apt: 3 | state: absent 4 | package: "{{ packages_remove }}" 5 | 6 | - name: install ansible modules requirements 7 | apt: 8 | state: present 9 | package: 10 | - aptitude # apt module 11 | - curl # http modules 12 | - git # git module 13 | - initramfs-tools 14 | - unzip # unarchive module 15 | - zip # unarchive module 16 | 17 | - name: install additional packages 18 | apt: 19 | state: present 20 | package: "{{ packages_install }}" 21 | 22 | ##### HARDWARE-SPECIFIC ##### 23 | 24 | - name: install haveged random number generator if the host is a KVM/VMware VM 25 | apt: 26 | state: present 27 | package: haveged 28 | when: "('kvm' in ansible_facts.virtualization_tech_guest) or ('VMware' in ansible_facts.virtualization_tech_guest)" 29 | 30 | - name: install hardware random number generator support packages if the CPU supports it 31 | apt: 32 | state: present 33 | package: rng-tools5 34 | when: ansible_local.common.cpu_rdrand 35 | ignore_errors: "{{ ansible_check_mode }}" 36 | 37 | - name: install qemu guest agent if the host is a KVM VM 38 | apt: 39 | state: present 40 | package: haveged 41 | when: "'kvm' in ansible_facts.virtualization_tech_guest" 42 | -------------------------------------------------------------------------------- /roles/gitlab/tasks/ssl-selfsigned.yml: -------------------------------------------------------------------------------- 1 | - name: install requirements for SSL/TLS certificates generation 2 | apt: 3 | state: present 4 | package: 5 | - python3-openssl 6 | - ssl-cert 7 | 8 | - name: create directory for self-signed certificates 9 | file: 10 | state: directory 11 | path: "{{ item }}" 12 | owner: root 13 | group: root 14 | mode: 0755 15 | with_items: 16 | - /etc/gitlab 17 | - /etc/gitlab/ssl 18 | 19 | - name: generate openssl private key for gitlab registry 20 | openssl_privatekey: 21 | path: "/etc/gitlab/ssl/{{ gitlab_registry_fqdn }}.key" 22 | 23 | - name: generate openssl certificate signing request for gitlab registry 24 | openssl_csr: 25 | path: "/etc/gitlab/ssl/{{ gitlab_registry_fqdn }}.csr" 26 | privatekey_path: "/etc/gitlab/ssl/{{ gitlab_registry_fqdn }}.key" 27 | common_name: "{{ gitlab_registry_fqdn }}" 28 | key_usage: "digitalSignature,keyEncipherment" 29 | basicConstraints: "CA:TRUE" 30 | 31 | - name: generate self-signed openssl certificate for gitlab registry 32 | openssl_certificate: 33 | path: "/etc/gitlab/ssl/{{ gitlab_registry_fqdn }}.crt" 34 | privatekey_path: "/etc/gitlab/ssl/{{ gitlab_registry_fqdn }}.key" 35 | csr_path: "/etc/gitlab/ssl/{{ gitlab_registry_fqdn }}.csr" 36 | provider: selfsigned 37 | -------------------------------------------------------------------------------- /roles/apache/tasks/apache-mod-evasive.yml: -------------------------------------------------------------------------------- 1 | ##### APACHE MOD_EVASIVE ##### 2 | 3 | - name: copy mod_evasive configuration 4 | template: 5 | src: etc_apache2_conf-available_mod-evasive.conf.j2 6 | dest: /etc/apache2/conf-available/mod-evasive.conf 7 | mode: 0644 8 | when: apache_enable_mod_evasive|bool 9 | ignore_errors: "{{ ansible_check_mode }}" 10 | 11 | - name: enable apache mod_evasive 12 | command: a2enmod evasive 13 | args: 14 | creates: /etc/apache2/mods-enabled/evasive.load 15 | when: apache_enable_mod_evasive|bool 16 | notify: restart apache 17 | 18 | - name: enable apache mod_evasive configuration 19 | command: a2enconf mod-evasive 20 | args: 21 | creates: /etc/apache2/conf-enabled/mod-evasive.conf 22 | when: apache_enable_mod_evasive|bool 23 | notify: reload apache 24 | ignore_errors: "{{ ansible_check_mode }}" 25 | 26 | - name: disable apache mod_evasive 27 | command: a2dismod evasive 28 | args: 29 | removes: /etc/apache2/mods-enabled/evasive.load 30 | when: not apache_enable_mod_evasive|bool 31 | notify: restart apache 32 | 33 | - name: disable apache mod_evasive configuration 34 | command: a2disconf mod-evasive|bool 35 | args: 36 | removes: /etc/apache2/conf-enabled/mod-evasive.conf 37 | when: not apache_enable_mod_evasive|bool 38 | notify: reload apache 39 | -------------------------------------------------------------------------------- /roles/docker_nginx/defaults/main.yml: -------------------------------------------------------------------------------- 1 | ##### NGINX REVERSEPROXY ##### 2 | 3 | # e-mail address for registration on letsencrypt.org 4 | nginx_letsencrypt_email: "CHANGEME@example.org" 5 | 6 | # list of domain names for which to generate Let's Encrypt certificates 7 | # private keys will be available to nginx in /etc/nginx/ssl/letsencrypt/live/$DOMAIN/privkey.pem 8 | # certificates will be available to nginx in /etc/nginx/ssl/letsencrypt/live/$DOMAIN/cert.pem 9 | # full certificate chains will be available to nginx in /etc/nginx/ssl/letsencrypt/live/$DOMAIN/fullchain.pem 10 | nginx_letsencrypt_certificates: [] 11 | 12 | # (optional) Docker swarm node label required to run the service 13 | # nginx_docker_label_constraint: nginx 14 | 15 | # enforce X-Frame-Options: SAMEORIGIN HTTP header (security) 16 | # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options 17 | nginx_enforce_xframe_sameorigin: yes 18 | 19 | # a list of network aliases to attach to the nginx service 20 | # can be used to work around services inside the swarm calling the host's FQDN when no NAT loopback is enabled 21 | nginx_docker_aliases: [] 22 | # Example: 23 | # nginx_docker_aliases: 24 | # - "chat.example.com" 25 | # - "webservice.example.com" 26 | 27 | # set to yes to completely remove components installed by this role 28 | docker_nginx_remove: no 29 | -------------------------------------------------------------------------------- /roles/common/templates/etc_msmtprc.j2: -------------------------------------------------------------------------------- 1 | # msmtp system wide configuration file 2 | # This allows msmtp to be used like /usr/sbin/sendmail. 3 | 4 | # msmtp supports multiple accounts 5 | # This configures the default account 6 | account default 7 | 8 | # TCP port to use 9 | # Usually 25 (SMTP), 465 (SMTPS) or 587 (submission) 10 | port {{ msmtp_port }} 11 | 12 | # The SMTP smarthost. 13 | host {{ msmtp_host }} 14 | 15 | {% if msmtp_from == 'auto' %} 16 | auto_from on 17 | {% else %} 18 | from {{ msmtp_from }} 19 | {% endif %} 20 | 21 | {% if msmtp_auth_enabled %} 22 | # Enable authentication 23 | auth on 24 | # Set SMTP username/password 25 | user {{ msmtp_username }} 26 | password {{ msmtp_password }} 27 | {% endif %} 28 | 29 | # Use TLS. 30 | {% if msmtp_tls_enabled %} 31 | tls on 32 | {% if msmtp_tls_certcheck %} 33 | tls_certcheck on 34 | {% if msmtp_smtp_host_tls_fingerprint is defined %}tls_fingerprint {{ msmtp_smtp_host_tls_fingerprint }} 35 | {% else %}tls_trust_file /etc/ssl/certs/ca-certificates.crt 36 | {% endif %} 37 | {% else %} 38 | tls_certcheck off 39 | {% endif %} 40 | tls_starttls {{ 'on' if msmtp_starttls else 'off' }} 41 | {% endif %} 42 | 43 | 44 | # Syslog logging with facility LOG_MAIL instead of the default LOG_USER. 45 | syslog LOG_MAIL 46 | 47 | # Replace local recipients with addresses in the aliases file 48 | aliases /etc/aliases 49 | -------------------------------------------------------------------------------- /roles/adminer/templates/etc_apache2_sites-available_adminer.conf.j2: -------------------------------------------------------------------------------- 1 | 2 | DocumentRoot /var/www/{{ adminer_fqdn }} 3 | ServerName {{ adminer_fqdn }} 4 | ServerAdmin webmaster@{{ adminer_fqdn }} 5 | {% if adminer_https_mode == 'selfsigned' %} 6 | # Redirect all HTTP requests to HTTPS 7 | RewriteEngine On 8 | RewriteCond %{HTTPS} off 9 | RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} 10 | {% endif %} 11 | 12 | 13 | {% if adminer_https_mode == 'letsencrypt' %} 14 | MDomain {{ adminer_fqdn }} 15 | {% endif %} 16 | 17 | 18 | DocumentRoot /var/www/{{ adminer_fqdn }} 19 | ServerName {{ adminer_fqdn }} 20 | ServerAdmin webmaster@{{ adminer_fqdn }} 21 | SSLEngine on 22 | {% if adminer_https_mode == 'selfsigned' %} 23 | SSLCertificateFile /etc/ssl/certs/{{ adminer_fqdn }}.crt 24 | SSLCertificateKeyFile /etc/ssl/private/{{ adminer_fqdn }}.key 25 | {% endif %} 26 | 27 | 28 | AuthType Basic 29 | AuthName "Authorization required" 30 | AuthBasicProvider file 31 | AuthUserFile /etc/apache2/adminer.htpasswd 32 | Require valid-user 33 | 34 | 35 | 36 | SetHandler "proxy:unix:/run/php/php{{ php_fpm_version }}-fpm-adminer.sock|fcgi://localhost" 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /roles/gitlab_runner/README.md: -------------------------------------------------------------------------------- 1 | # librelogic.librelogic.gitlab_runner 2 | 3 | Ansible role to deploy and configure [Gitlab Runner](https://docs.gitlab.com/runner/), a continuous integration runner for the Gitlab software forge. 4 | 5 | ## Requirements/dependencies/example playbook 6 | 7 | See [meta/main.yml](defaults/main.yml) 8 | 9 | ```yaml 10 | - hosts: runner.CHANGEME.org 11 | roles: 12 | - librelogic.librelogic.common 13 | - librelogic.librelogic.docker 14 | - gitlab_runner 15 | 16 | # host_vars/runner.CHANGEME.org/runner.CHANGEME.org.yml 17 | gitlab_runner_gitlab_url: "https://gitlab.CHANGEME.com" 18 | 19 | # host_vars/runner.CHANGEME.org/runner.CHANGEME.org.vault.yml 20 | gitlab_runner_registration_token: "CHANGEME" 21 | gitlab_runner_api_token: "CHANGEME" 22 | ``` 23 | 24 | See [defaults/main.yml](defaults/main.yml) for all configuration variables 25 | 26 | 27 | ## License 28 | 29 | GPL-3.0 30 | 31 | ## References/Documentation 32 | 33 | - https://github.com/libre-logic/ansible-collection/ 34 | - https://docs.gitlab.com/runner/install/linux-repository.html 35 | - https://docs.gitlab.com/runner/register/index.html 36 | - https://docs.ansible.com/ansible/latest/modules/gitlab_runner_module.html 37 | - https://docs.gitlab.com/runner/configuration/index.html 38 | - https://docs.gitlab.com/ee/ci/runners/ 39 | - https://docs.gitlab.com/runner/configuration/ 40 | -------------------------------------------------------------------------------- /roles/openldap/templates/etc_php_PHPVERSION_fpm_pool.d_ldap-account-manager.conf.j2: -------------------------------------------------------------------------------- 1 | [ldap-account-manager] 2 | user = www-data 3 | group = www-data 4 | listen = /run/php/php{{ php_fpm_version }}-fpm-ldap-account-manager.sock 5 | listen.owner = www-data 6 | listen.group = www-data 7 | listen.allowed_clients = 127.0.0.1 8 | 9 | ;;; PROCESS MANAGEMENT ;;; 10 | pm = dynamic 11 | pm.max_children = 5 12 | pm.start_servers = 2 13 | pm.min_spare_servers = 1 14 | pm.max_spare_servers = 3 15 | pm.process_idle_timeout = 20s 16 | ;pm.max_requests = 500 17 | 18 | ;;; MONITORING ;;; 19 | ;pm.status_path = /status 20 | ;ping.path = /ping 21 | ;ping.response = pong 22 | 23 | ;;; LOGGING/DEBUGGING ;;; 24 | ;access.log = log/$pool.access.log 25 | ;slowlog = log/$pool.log.slow 26 | ;request_slowlog_timeout = 0 27 | ;request_slowlog_trace_depth = 20 28 | ;catch_workers_output = no 29 | ;php_flag[display_errors] = off 30 | 31 | ;;; LIMITS 32 | php_admin_value[max_execution_time] = {{ ldap_account_manager_php_max_execution_time }} 33 | php_admin_value[max_input_time] = {{ ldap_account_manager_php_max_input_time }} 34 | php_admin_value[memory_limit] = {{ ldap_account_manager_php_memory_limit }} 35 | php_admin_value[post_max_size] = {{ ldap_account_manager_php_post_max_size }} 36 | php_admin_value[upload_max_filesize] = {{ ldap_account_manager_php_upload_max_filesize }} 37 | ;rlimit_files = 1024 38 | ;chroot = 39 | ;chdir = / 40 | -------------------------------------------------------------------------------- /roles/openldap/templates/etc_php_PHPVERSION_fpm_pool.d_self-service-password.conf.j2: -------------------------------------------------------------------------------- 1 | [self-service-password] 2 | user = www-data 3 | group = www-data 4 | listen = /run/php/php{{ php_fpm_version }}-fpm-self-service-password.sock 5 | listen.owner = www-data 6 | listen.group = www-data 7 | listen.allowed_clients = 127.0.0.1 8 | 9 | ;;; PROCESS MANAGEMENT ;;; 10 | pm = dynamic 11 | pm.max_children = 5 12 | pm.start_servers = 2 13 | pm.min_spare_servers = 1 14 | pm.max_spare_servers = 3 15 | pm.process_idle_timeout = 20s 16 | ;pm.max_requests = 500 17 | 18 | ;;; MONITORING ;;; 19 | ;pm.status_path = /status 20 | ;ping.path = /ping 21 | ;ping.response = pong 22 | 23 | ;;; LOGGING/DEBUGGING ;;; 24 | ;access.log = log/$pool.access.log 25 | ;slowlog = log/$pool.log.slow 26 | ;request_slowlog_timeout = 0 27 | ;request_slowlog_trace_depth = 20 28 | ;catch_workers_output = no 29 | ;php_flag[display_errors] = off 30 | 31 | ;;; LIMITS 32 | php_admin_value[max_execution_time] = {{ self_service_password_php_max_execution_time }} 33 | php_admin_value[max_input_time] = {{ self_service_password_php_max_input_time }} 34 | php_admin_value[memory_limit] = {{ self_service_password_php_memory_limit }} 35 | php_admin_value[post_max_size] = {{ self_service_password_php_post_max_size }} 36 | php_admin_value[upload_max_filesize] = {{ self_service_password_php_upload_max_filesize }} 37 | ;rlimit_files = 1024 38 | ;chroot = 39 | ;chdir = / 40 | -------------------------------------------------------------------------------- /roles/monitoring_rsyslog/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: import variable checks tasks 2 | import_tasks: checks.yml 3 | tags: 4 | - monitoring 5 | - rsyslog 6 | - checks 7 | 8 | - name: import rsyslog server/CA certificates configuration tasks 9 | import_tasks: rsyslog-ssl-server.yml 10 | become: yes 11 | tags: 12 | - monitoring 13 | - rsyslog 14 | - ssl 15 | when: rsyslog_enable_receive | bool 16 | 17 | - name: import rsyslog client certificates configuration tasks 18 | import_tasks: rsyslog-ssl-client.yml 19 | become: yes 20 | tags: 21 | - monitoring 22 | - rsyslog 23 | - ssl 24 | when: rsyslog_enable_forwarding | bool 25 | 26 | - name: import rsyslog configuration tasks 27 | import_tasks: rsyslog.yml 28 | become: yes 29 | tags: 30 | - monitoring 31 | - rsyslog 32 | 33 | - name: import firewalld configuration tasks 34 | import_tasks: firewalld.yml 35 | become: yes 36 | tags: 37 | - monitoring 38 | - rsyslog 39 | - firewall 40 | when: 41 | - ansible_local.firewalld.ansible_managed is defined 42 | - ansible_local.firewalld.ansible_managed | bool 43 | 44 | - name: import ansible facts configuration tasks 45 | import_tasks: fact.yml 46 | become: yes 47 | tags: 48 | - monitoring 49 | - rsyslog 50 | 51 | - name: apply configuration (flush handlers) 52 | meta: flush_handlers 53 | tags: 54 | - monitoring 55 | - rsyslog 56 | -------------------------------------------------------------------------------- /roles/apache/files/usr_local_bin_apache-mod-md-reload: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # gracefully restart (reload) apache2 when a required by mod_md after certificate generation/renewal 3 | # https://httpd.apache.org/docs/2.4/mod/mod_md.html#mdmessagecmd 4 | # - mod_md must be configured with 'MDMessageCmd /usr/local/bin/apache-mod-md-reload request' 5 | # - a cron job run as root must check periodically the presence of the file using '/usr/local/bin/apache-mod-md-reload check-reload' 6 | set -o errexit 7 | set -o nounset 8 | 9 | command="$1" 10 | 11 | if [[ "$command" == "request" ]]; then 12 | reason="$2" 13 | mdomain="$3" 14 | case "$reason" in 15 | "renewing") echo "$mdomain: starting certificate renewal" ;; 16 | "renewed") echo "$mdomain: certificate renewed" ;; 17 | "installed") touch /var/lib/apache2/md/mod-md-reload-required && echo "$mdomain: certificate installed, reload requested" ;; 18 | "expiring") echo "$mdomain: certificate will expire soon" ;; 19 | "errored") echo "$mdomain: errors were encountered during certificate renewal" ;; 20 | *) echo "$mdomain: $reason" 21 | esac 22 | elif [[ "$1" == "check-reload" ]]; then 23 | if [[ -f /var/lib/apache2/md/mod-md-reload-required ]]; then 24 | echo "mod_md requested reload, gracefully restarting apache2" 25 | systemctl reload apache2 26 | rm /var/lib/apache2/md/mod-md-reload-required 27 | fi 28 | fi 29 | -------------------------------------------------------------------------------- /roles/common/tasks/cron.yml: -------------------------------------------------------------------------------- 1 | - name: configure cron daemon 2 | template: 3 | src: etc_default_cron.j2 4 | dest: /etc/default/cron 5 | mode: "0644" 6 | owner: root 7 | group: root 8 | notify: restart crond 9 | 10 | - name: only allow select users to use crontab 11 | template: 12 | src: etc_cron.allow.j2 13 | dest: /etc/cron.allow 14 | mode: "0644" 15 | owner: root 16 | group: root 17 | 18 | # Granting write access to this directory for non-privileged users could provide 19 | # them the means for gaining unauthorized elevated privileges. 20 | # Granting read access to this directory could give an unprivileged user insight 21 | # in how to gain elevated privileges or circumvent auditing controls. 22 | # CIS 5.1.2 - CIS 5.1.7 23 | # From https://github.com/dev-sec/ansible-collection-hardening/blob/master/roles/os_hardening/tasks/cron.yml - Apache License, Version 2.0 24 | - name: find cron files and directories 25 | find: 26 | paths: 27 | - /etc 28 | patterns: 29 | - cron.hourly 30 | - cron.daily 31 | - cron.weekly 32 | - cron.monthly 33 | - cron.d 34 | - crontab 35 | file_type: any 36 | register: common_cron_directories 37 | - name: ensure only root can access cron files and directories 38 | ansible.builtin.file: 39 | path: "{{ item.path }}" 40 | owner: root 41 | group: root 42 | mode: og-rwx 43 | with_items: "{{ common_cron_directories.files }}" 44 | -------------------------------------------------------------------------------- /roles/mailcatcher/README.md: -------------------------------------------------------------------------------- 1 | # librelogic.librelogic.mailcatcher 2 | 3 | This role will install and configure [mailcatcher](https://github.com/sj26/mailcatcher) 4 | 5 | > MailCatcher runs a super simple SMTP server which catches any message sent to it to display in a web interface. Run mailcatcher, set your favourite app to deliver to smtp://127.0.0.1:1025 instead of your default SMTP server, then check out http://127.0.0.1:1080 to see the mail that's arrived so far. 6 | 7 | 8 | ## Requirements/Dependencies/Example playbook 9 | 10 | See [meta/main.yml](meta/main.yml) 11 | 12 | ```yaml 13 | - hosts: my.CHANGEME.org 14 | roles: 15 | - librelogic.librelogic.common # optional 16 | - librelogic.librelogic.apache 17 | - librelogic.librelogic.mailcatcher 18 | 19 | # host_vars/my.CHANGEME.org/my.CHANGEME.org.yml 20 | mailcatcher_fqdn: mailcatcher.CHANGEME.org 21 | 22 | # ansible-vault edit host_vars/my.CHANGEME.org/my.CHANGEME.org.vault.yml 23 | mailcatcher_user: "CHANGEME" 24 | mailcatcher_password: "CHANGEME" 25 | 26 | # mailcatcher bin path can be override 27 | mailcatcher_bin_path: "/var/lib/mailcatcher/.local/share/gem/ruby/2.7.0/bin/mailcatcher" 28 | ``` 29 | 30 | ## License 31 | 32 | [GNU GPLv3](https://www.gnu.org/licenses/gpl-3.0.txt) 33 | 34 | ## References 35 | 36 | - https://github.com/libre-logic/ansible-collection-librelogic/ 37 | - https://github.com/sj26/mailcatcher#how 38 | - https://docs.ansible.com/ansible/latest/collections/community/general/gem_module.html 39 | -------------------------------------------------------------------------------- /roles/proxmox/README.md: -------------------------------------------------------------------------------- 1 | # librelogic.librelogic.proxmox 2 | 3 | This role will perform basic setup steps for a [Proxmox](https://www.proxmox.com/en/proxmox-ve) hypervisor: 4 | - setup `pve-no-subscription` APT repositories 5 | 6 | > [Proxmox Virtual Environment](https://en.wikipedia.org/wiki/Proxmox_Virtual_Environment) (Proxmox VE or PVE) is an open-source software server for virtualization management. It is a Debian-based Linux distribution with a modified Ubuntu LTS kernel and allows deployment and management of virtual machines and containers. Proxmox VE includes a web console and command-line tools. 7 | 8 | If the `librelogic.xsrv.common` role is deployed: 9 | - protect the login form from brutefore using `fail2ban` 10 | 11 | ## Requirements/eependencies/example playbook 12 | 13 | See [meta/main.yml](meta/main.yml) 14 | 15 | ```yaml 16 | # playbook.yml 17 | - hosts: my.CHANGEME.org 18 | roles: 19 | - librelogic.librelogic.common # (optional) hardening/bruteforce protection/automatic security upgrades 20 | - librelogic.librelogic.monitoring # (optional) server monitoring and log aggregation 21 | - librelogic.librelogic.proxmox 22 | ``` 23 | 24 | See [defaults/main.yml](defaults/main.yml) for all configuration variables 25 | 26 | 27 | ## License 28 | 29 | [GNU GPLv3](https://www.gnu.org/licenses/gpl-3.0.txt) 30 | 31 | ## References 32 | 33 | - https://github.com/libre-logic/ansible-collection-librelogic/ 34 | - https://github.com/libre-logic/ansible-collection-librelogic/tree/master/roles/proxmox 35 | 36 | -------------------------------------------------------------------------------- /roles/openldap/templates/etc_apache2_sites-available_ldap-account-manager.conf.j2: -------------------------------------------------------------------------------- 1 | 2 | DocumentRoot {{ ldap_account_manager_install_dir }} 3 | ServerName {{ ldap_account_manager_fqdn }} 4 | ServerAdmin webmaster@{{ ldap_account_manager_fqdn }} 5 | {% if ldap_account_manager_https_mode == 'selfsigned' %} 6 | # Redirect all HTTP requests to HTTPS 7 | RewriteEngine On 8 | RewriteCond %{HTTPS} off 9 | RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} 10 | {% endif %} 11 | 12 | 13 | {% if ldap_account_manager_https_mode == 'letsencrypt' %} 14 | MDomain {{ ldap_account_manager_fqdn }} 15 | {% endif %} 16 | 17 | 18 | DocumentRoot {{ ldap_account_manager_install_dir }} 19 | ServerName {{ ldap_account_manager_fqdn }} 20 | ServerAdmin webmaster@{{ ldap_account_manager_fqdn }} 21 | SSLEngine on 22 | {% if ldap_account_manager_https_mode == 'selfsigned' %} 23 | SSLCertificateFile /etc/ssl/certs/{{ ldap_account_manager_fqdn }}.crt 24 | SSLCertificateKeyFile /etc/ssl/private/{{ ldap_account_manager_fqdn }}.key 25 | {% endif %} 26 | 27 | 28 | SetHandler "proxy:unix:/run/php/php{{ php_fpm_version }}-fpm-ldap-account-manager.sock|fcgi://localhost" 29 | 30 | 31 | 32 | Require all denied 33 | 34 | 35 | 36 | Require all denied 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /roles/monitoring_rsyslog/templates/etc_systemd_journald.conf.j2: -------------------------------------------------------------------------------- 1 | # This file is part of systemd. 2 | # 3 | # systemd is free software; you can redistribute it and/or modify it under the 4 | # terms of the GNU Lesser General Public License as published by the Free 5 | # Software Foundation; either version 2.1 of the License, or (at your option) 6 | # any later version. 7 | # 8 | # Entries in this file show the compile time defaults. Local configuration 9 | # should be created by either modifying this file, or by creating "drop-ins" in 10 | # the journald.conf.d/ subdirectory. The latter is generally recommended. 11 | # Defaults can be restored by simply deleting this file and all drop-ins. 12 | # 13 | # Use 'systemd-analyze cat-config systemd/journald.conf' to display the full config. 14 | # 15 | # See journald.conf(5) for details. 16 | 17 | [Journal] 18 | Storage=volatile 19 | #Compress=yes 20 | #Seal=yes 21 | #SplitMode=uid 22 | #SyncIntervalSec=5m 23 | #RateLimitIntervalSec=30s 24 | #RateLimitBurst=10000 25 | #SystemMaxUse= 26 | #SystemKeepFree= 27 | #SystemMaxFileSize= 28 | #SystemMaxFiles=100 29 | #RuntimeMaxUse= 30 | #RuntimeKeepFree= 31 | #RuntimeMaxFileSize= 32 | #RuntimeMaxFiles=100 33 | #MaxRetentionSec= 34 | #MaxFileSec=1month 35 | ForwardToSyslog=yes 36 | #ForwardToKMsg=no 37 | #ForwardToConsole=no 38 | #ForwardToWall=yes 39 | #TTYPath=/dev/console 40 | #MaxLevelStore=debug 41 | #MaxLevelSyslog=debug 42 | #MaxLevelKMsg=notice 43 | #MaxLevelConsole=info 44 | #MaxLevelWall=emerg 45 | #LineMax=48K 46 | #ReadKMsg=yes 47 | #Audit=no 48 | -------------------------------------------------------------------------------- /roles/mailcatcher/tasks/apache.yml: -------------------------------------------------------------------------------- 1 | ##### APACHE ##### 2 | 3 | - name: install requirements for ansible htpasswd module 4 | apt: 5 | package: 6 | - python3-passlib 7 | - python3-bcrypt 8 | state: present 9 | 10 | - name: create apache HTTP basic auth password file 11 | htpasswd: 12 | path: /etc/apache2/mailcatcher.htpasswd 13 | name: "{{ mailcatcher_user }}" 14 | password: '{{ mailcatcher_password }}' 15 | owner: root 16 | group: www-data 17 | mode: 0640 18 | notify: reload apache 19 | ignore_errors: "{{ ansible_check_mode }}" 20 | 21 | - name: enable required apache modules 22 | command: a2enmod {{ item }} 23 | with_items: 24 | - headers 25 | - proxy 26 | - proxy_http 27 | args: 28 | creates: "/etc/apache2/mods-enabled/{{ item }}.load" 29 | notify: restart apache 30 | ignore_errors: "{{ ansible_check_mode }}" 31 | 32 | - name: copy mailcatcher apache virtualhost configuration 33 | template: 34 | src: "etc_apache2_sites-available_mailcatcher.conf.j2" 35 | dest: "/etc/apache2/sites-available/mailcatcher.conf" 36 | owner: root 37 | group: root 38 | mode: 0644 39 | notify: reload apache 40 | ignore_errors: "{{ ansible_check_mode }}" 41 | 42 | - name: enable mailcatcher apache virtualhost configuration 43 | command: a2ensite mailcatcher 44 | args: 45 | creates: "/etc/apache2/sites-enabled/mailcatcher.conf" 46 | notify: reload apache 47 | 48 | - name: ensure apache configuration is applied (flush handlers) 49 | meta: flush_handlers 50 | -------------------------------------------------------------------------------- /roles/adminer/defaults/main.yml: -------------------------------------------------------------------------------- 1 | ##### ADMINER ##### 2 | # FQDN for the gitlab webserver virtualhost 3 | adminer_fqdn: "adminer.CHANGEME.org" 4 | # username/password for adminer HTTP Basic Auth 5 | adminer_user: "CHANGEME" 6 | adminer_password: "CHANGEME" 7 | # mode for SSL/TLS certificates for the adminer webserver virtualhost (letsencrypt/selfsigned) 8 | # letsencrypt: acquire a certificate from letsencrypt.org 9 | # selfsigned: generate a self-signed certificate (will generate warning in browsers and clients) 10 | adminer_https_mode: selfsigned 11 | # adminer php-fpm pool settings (performance/resource usage) 12 | # php-fpm: Maximum amount of memory a script may consume (K, M, G) 13 | adminer_php_memory_limit: '128M' 14 | # php_fpm: Maximum execution time of each script (seconds) 15 | adminer_php_max_execution_time: 60 16 | # php-fpm: Maximum amount of time each script may spend parsing request data (seconds) 17 | adminer_php_max_input_time: 60 18 | # php-fpm: Maximum size of POST data that PHP will accept (K, M, G) 19 | adminer_php_post_max_size: '10M' 20 | # php-fpm: Maximum allowed size for uploaded files (K, M, G) 21 | adminer_php_upload_max_filesize: '10M' 22 | # php-fpm: maximum number of child processes 23 | adminer_php_pm_max_children: 10 24 | # php-fpm: number of child processes created on startup. 25 | adminer_php_pm_start_servers: 1 26 | # php-fpm: desired minimum number of idle server processes 27 | adminer_php_pm_min_spare_servers: 1 28 | # php-fpm: desired maximum number of idle server processes 29 | adminer_php_pm_max_max_spare_servers: 2 30 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_netdata_fping.conf.j2: -------------------------------------------------------------------------------- 1 | # no need for shebang - this file is sourced from fping.plugin 2 | 3 | # fping.plugin requires a recent version of fping. 4 | # 5 | # You can get it on your system, by running: 6 | # 7 | # /usr/libexec/netdata/plugins.d/fping.plugin install 8 | 9 | # ----------------------------------------------------------------------------- 10 | # configuration options 11 | 12 | # The fping binary to use. We need one that can output netdata friendly info 13 | # (supporting: -N). If you have multiple versions, put here the full filename 14 | # of the right one 15 | 16 | #fping="/usr/local/bin/fping" 17 | 18 | 19 | # a space separated list of hosts to fping 20 | # we suggest to put names here and the IPs of these names in /etc/hosts 21 | 22 | hosts="{{ ' '.join(netdata_fping_hosts) }}" 23 | 24 | 25 | # The update frequency of the chart - the default is inherited from netdata 26 | 27 | update_every={{ netdata_fping_update_every }} 28 | 29 | 30 | # The time in milliseconds (1 sec = 1000 ms) to ping the hosts 31 | # by default 5 pings per host per iteration 32 | # fping will not allow this to be below 20ms 33 | 34 | ping_every="{{ netdata_fping_ping_every }}" 35 | 36 | # other fping options - defaults: 37 | # -R = send packets with random data 38 | # -b 56 = the number of bytes per packet 39 | # -i 1 = 1 ms when sending packets to others hosts (switching hosts) 40 | # -r 0 = never retry packets 41 | # -t 5000 = per packet timeout at 5000 ms 42 | 43 | #fping_opts="-R -b 56 -i 1 -r 0 -t 5000" 44 | -------------------------------------------------------------------------------- /roles/openldap/tasks/openldap.yml: -------------------------------------------------------------------------------- 1 | ##### OPENLDAP DIRECTORY SERVER ##### 2 | 3 | - name: install ansible modules requirements 4 | apt: 5 | state: present 6 | package: 7 | - debconf-utils 8 | - python3-ldap 9 | check_mode: no 10 | 11 | ### DEBCONF ### 12 | 13 | # preconfigure the LDAP base DN in debconf - else it will be automatically derived from the machine's hostname 14 | - name: pre-configure openldap server 15 | debconf: 16 | name: slapd 17 | question: "{{ item.question }}" 18 | vtype: string 19 | value: "{{ item.value }}" 20 | with_items: 21 | - { question: "slapd/domain", value: "{{ openldap_domain }}" } 22 | - { question: "shared/organization", value: "{{ openldap_organization }}" } 23 | 24 | ### PACKAGES ### 25 | 26 | - name: install openLDAP server 27 | apt: 28 | state: present 29 | update_cache: yes 30 | cache_valid_time: 900 31 | package: 32 | - slapd 33 | - ldap-utils 34 | - openssl 35 | - ldapscripts 36 | - python3-pyldap 37 | 38 | ### CONFIGURATION ### 39 | 40 | - name: create LDAP database directory 41 | file: 42 | path: "/var/lib/ldap/{{ openldap_domain }}/" 43 | state: directory 44 | owner: openldap 45 | group: openldap 46 | mode: 0750 47 | 48 | - name: copy slapd configuration 49 | template: 50 | src: etc_default_slapd.j2 51 | dest: /etc/default/slapd 52 | owner: root 53 | group: root 54 | mode: 0644 55 | notify: restart slapd 56 | 57 | - name: apply configuration (flush handlers) 58 | meta: flush_handlers 59 | -------------------------------------------------------------------------------- /roles/monitoring_rsyslog/tasks/rsyslog.yml: -------------------------------------------------------------------------------- 1 | - name: install rsyslog 2 | apt: 3 | state: present 4 | package: 5 | - rsyslog 6 | - rsyslog-gnutls # TLS forwarding support 7 | 8 | - name: set retention/rotation policy for rsyslog logs 9 | template: 10 | src: etc_logrotate.d_rsyslog.j2 11 | dest: /etc/logrotate.d/rsyslog 12 | mode: "0644" 13 | 14 | - name: configure rsyslog 15 | template: 16 | src: etc_rsyslog.d_{{ item }}.conf.j2 17 | dest: /etc/rsyslog.d/{{ item }}.conf 18 | owner: root 19 | group: root 20 | mode: "0644" 21 | notify: restart rsyslog 22 | with_items: 23 | - 000-custom # custom configuration 24 | - 000-singlefile # log all messages to /var/log/syslog 25 | - 000-imfile # load the imfile (text file input) module used by other roles 26 | - 000-forwarding # message forwarding over TCP/TLS, if enabled 27 | - fail2ban # fail2ban logs aggregation 28 | - apt # apt logs aggregation 29 | 30 | - name: configure systemd-journald 31 | template: 32 | src: etc_systemd_journald.conf.j2 33 | dest: /etc/systemd/journald.conf 34 | owner: root 35 | group: root 36 | mode: "0644" 37 | notify: restart systemd-journald 38 | 39 | # rsyslog is configured to send all messages to /var/log/syslog in singlefile.conf 40 | # if a '*.*' filter is present in main rsyslog.conf, messages will be logged twice 41 | - name: configure rsyslog to avoid duplicate messages 42 | lineinfile: 43 | path: /etc/rsyslog.conf 44 | state: absent 45 | regexp: '^\*\.\*' 46 | notify: restart rsyslog 47 | -------------------------------------------------------------------------------- /roles/docker/defaults/main.yml: -------------------------------------------------------------------------------- 1 | ##### DOCKER CONTAINER ENGINE ##### 2 | # Docker release channel (stable/edge) 3 | docker_apt_release_channel: stable 4 | docker_apt_arch: amd64 5 | # A list of users who will be added to the docker group 6 | docker_users: [] 7 | # yes/no: start/stop docker service, enable/disable it on boot 8 | docker_enable_service: yes 9 | # the log driver for the docker daemon (none/local/json-file/syslog/journaled/gelf/fluentd/awslogs/splunk/etwlogs/gcplogs/logentries) 10 | docker_log_driver: "syslog" 11 | # docker swarm settings (accepts all parameters from https://docs.ansible.com/ansible/latest/collections/community/general/docker_swarm_module.html) 12 | docker_swarm: 13 | state: "present" 14 | # enable nightly prune of unused networks/images/stopped containers/build cache (yes/no) 15 | docker_prune_nightly: yes 16 | # allow docker to configure iptables rules automatically (yes/no) 17 | docker_iptables: no 18 | # Expected minimum/maximum number of running docker containers (if the host has the monitoring_netdata role) 19 | # a list of additional hostname:IP mappings to include /etc/hosts inside containers 20 | # extra_hosts: {{ docker_extra_hosts }} must be declared at the service level in docker stacks compose sections 21 | docker_extra_hosts: [] 22 | # Example: 23 | #docker_extra_hosts: 24 | # - "somehost:162.242.195.82" 25 | # - "otherhost:50.31.209.229" 26 | 27 | # Docker Swarm labels to apply on host (dict): 28 | docker_swarm_node_labels: {} 29 | # Exemple: 30 | # docker_swarm_node_labels: 31 | # has_volume_x: "true" 32 | # has_volume_y: "true" 33 | # has_service_z: "true" 34 | -------------------------------------------------------------------------------- /roles/monitoring_rsyslog/tasks/rsyslog-ssl.yml: -------------------------------------------------------------------------------- 1 | - name: install requirements for SSL/TLS certificates generation 2 | apt: 3 | state: present 4 | package: 5 | - python3-openssl 6 | - ssl-cert 7 | 8 | - name: create directory for rsyslog certs/keys/CSRs 9 | file: 10 | state: directory 11 | path: /etc/ssl/rsyslog 12 | owner: root 13 | group: root 14 | mode: 0755 15 | 16 | # generate a private key and CSR on the syslog client machine 17 | - name: generate syslog client openssl private key 18 | openssl_privatekey: 19 | path: "/etc/ssl/rsyslog/rsyslog.key" 20 | owner: root 21 | group: root 22 | mode: 0600 23 | notify: restart rsyslog 24 | 25 | - name: generate syslog client openssl certificate signing request (CSR) 26 | openssl_csr: 27 | path: "/etc/ssl/rsyslog/rsyslog.csr" 28 | privatekey_path: "/etc/ssl/rsyslog/rsyslog.key" 29 | common_name: "{{ inventory_hostname }}" 30 | owner: root 31 | group: root 32 | mode: 0600 33 | 34 | - name: generate self-signed openssl client certificate 35 | openssl_certificate: 36 | path: "/etc/ssl/rsyslog/rsyslog.crt" 37 | privatekey_path: "/etc/ssl/rsyslog/rsyslog.key" 38 | csr_path: "/etc/ssl/rsyslog/rsyslog.csr" 39 | provider: selfsigned 40 | owner: root 41 | group: root 42 | mode: 0600 43 | force: no 44 | notify: restart rsyslog 45 | 46 | - name: upload syslog server CA certificate 47 | copy: 48 | src: "{{ rsyslog_ssl_ca_cert_file }}" 49 | dest: "/etc/ssl/rsyslog/{{ rsyslog_ssl_ca_cert_file | basename }}" 50 | owner: root 51 | group: root 52 | mode: 0644 53 | -------------------------------------------------------------------------------- /roles/docker_nginx/tasks/remove.yml: -------------------------------------------------------------------------------- 1 | - name: remove docker_nginx/letsencrypt configuration 2 | become: yes 3 | file: 4 | state: absent 5 | path: "{{ item }}" 6 | with_items: 7 | - /etc/docker/services-config/nginx/ 8 | - /etc/systemd/system/certbot.timer 9 | notify: reload systemd unit files 10 | 11 | # don't remove certbot automatically as it may still be used by other roles 12 | # - name: remove certbot 13 | # become: yes 14 | # package: 15 | # state: absent 16 | # name: certbot 17 | # autoremove: yes 18 | 19 | - name: remove nginx-reverseproxy docker stack 20 | become: yes 21 | docker_stack: 22 | name: nginx-reverseproxy 23 | state: absent 24 | 25 | - name: remove nginx docker network and handle errors (downtime, services proxied through nginx will become unreachable) 26 | block: 27 | - name: remove nginx docker network 28 | become: yes 29 | docker_network: 30 | name: nginx 31 | state: absent 32 | force: yes 33 | rescue: 34 | - name: rescue - list all docker stacks 35 | community.docker.docker_stack_info: 36 | register: docker_stacks 37 | - name: rescue - show docker stacks 38 | debug: 39 | var: docker_stacks.results 40 | - name: rescue - delete all docker stacks 41 | become: yes 42 | docker_stack: 43 | state: absent 44 | name: "{{ item.Name }}" 45 | loop: "{{ docker_stacks.results }}" 46 | - name: rescue - remove nginx docker network 47 | become: yes 48 | retries: 5 49 | delay: 1 50 | docker_network: 51 | name: nginx 52 | state: absent 53 | force: yes 54 | -------------------------------------------------------------------------------- /roles/adminer/templates/etc_php_7.3_fpm_pool.d_adminer.conf.j2: -------------------------------------------------------------------------------- 1 | [adminer] 2 | user = www-data 3 | group = www-data 4 | listen = /run/php/php{{ php_fpm_version }}-fpm-adminer.sock 5 | listen.owner = www-data 6 | listen.group = www-data 7 | listen.allowed_clients = 127.0.0.1 8 | 9 | ;;; PROCESS MANAGEMENT ;;; 10 | pm = dynamic 11 | pm.max_children = {{ adminer_php_pm_max_children }} 12 | pm.start_servers = {{ adminer_php_pm_start_servers }} 13 | pm.min_spare_servers = {{ adminer_php_pm_min_spare_servers }} 14 | pm.max_spare_servers = {{ adminer_php_pm_max_max_spare_servers }} 15 | pm.process_idle_timeout = 20s 16 | ;pm.max_requests = 500 17 | 18 | ;;; MONITORING ;;; 19 | ;pm.status_path = /status 20 | ;ping.path = /ping 21 | ;ping.response = pong 22 | 23 | ;;; LOGGING/DEBUGGING ;;; 24 | ;access.log = log/$pool.access.log 25 | ;slowlog = log/$pool.log.slow 26 | ;request_slowlog_timeout = 0 27 | ;request_slowlog_trace_depth = 20 28 | ;catch_workers_output = no 29 | ;php_flag[display_errors] = off 30 | 31 | ;;; LIMITS 32 | php_admin_value[max_execution_time] = {{ adminer_php_max_execution_time }} 33 | php_admin_value[max_input_time] = {{ adminer_php_max_input_time }} 34 | php_admin_value[memory_limit] = {{ adminer_php_memory_limit }} 35 | php_admin_value[post_max_size] = {{ adminer_php_post_max_size }} 36 | php_admin_value[upload_max_filesize] = {{ adminer_php_upload_max_filesize }} 37 | ;rlimit_files = 1024 38 | ;chroot = 39 | ;chdir = / 40 | 41 | ;; adminer comes with its own adminer/.htaccess file 42 | ;; php-fpm can’t read PHP settings in .htaccess 43 | php_admin_value[mbstring.func_overload] = 0 44 | php_admin_value[default_charset] = 'UTF-8' 45 | php_admin_value[output_buffering] = 0 46 | -------------------------------------------------------------------------------- /roles/common/templates/etc_systemd_logind.conf.j2: -------------------------------------------------------------------------------- 1 | # This file is part of systemd. 2 | # 3 | # systemd is free software; you can redistribute it and/or modify it 4 | # under the terms of the GNU Lesser General Public License as published by 5 | # the Free Software Foundation; either version 2.1 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # Entries in this file show the compile time defaults. 9 | # You can change settings by editing this file. 10 | # Defaults can be restored by simply deleting this file. 11 | # 12 | # See logind.conf(5) for details. 13 | 14 | [Login] 15 | #NAutoVTs=6 16 | #ReserveVT=6 17 | #KillUserProcesses=no 18 | #KillOnlyUsers= 19 | #KillExcludeUsers=root 20 | #InhibitDelayMaxSec=5 21 | #UserStopDelaySec=10 22 | #HandlePowerKey=poweroff 23 | #HandleSuspendKey=suspend 24 | #HandleHibernateKey=hibernate 25 | #HandleLidSwitch=suspend 26 | #HandleLidSwitchExternalPower=suspend 27 | #HandleLidSwitchDocked=ignore 28 | #HandleRebootKey=reboot 29 | #PowerKeyIgnoreInhibited=no 30 | #SuspendKeyIgnoreInhibited=no 31 | #HibernateKeyIgnoreInhibited=no 32 | #LidSwitchIgnoreInhibited=yes 33 | #RebootKeyIgnoreInhibited=no 34 | #HoldoffTimeoutSec=30s 35 | #IdleAction=ignore 36 | #IdleActionSec=30min 37 | #RuntimeDirectorySize=10% 38 | #RuntimeDirectoryInodes=400k 39 | #RemoveIPC=yes 40 | #InhibitorsMax=8192 41 | #SessionsMax=8192 42 | KillUserProcesses={{ 'yes' if systemd_logind_kill_user_processes else 'no' }} 43 | KillExcludeUsers={{ systemd_logind_kill_exclude_users|join(' ') }} 44 | {% if not systemd_logind_lock_after_idle_min == 0 %} 45 | IdleAction=lock 46 | IdleActionSec={{ systemd_logind_lock_after_idle_min }}min 47 | {% endif %} 48 | RemoveIPC=yes 49 | -------------------------------------------------------------------------------- /roles/openldap/templates/etc_apache2_sites-available_self-service-password.conf.j2: -------------------------------------------------------------------------------- 1 | 2 | DocumentRoot {{ self_service_password_install_dir }} 3 | ServerName {{ self_service_password_fqdn }} 4 | ServerAdmin webmaster@{{ self_service_password_fqdn }} 5 | {% if self_service_password_https_mode == 'selfsigned' %} 6 | # Redirect all HTTP requests to HTTPS 7 | RewriteEngine On 8 | RewriteCond %{HTTPS} off 9 | RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} 10 | {% endif %} 11 | 12 | 13 | {% if self_service_password_https_mode == 'letsencrypt' %} 14 | MDomain {{ self_service_password_fqdn }} 15 | {% endif %} 16 | 17 | 18 | DocumentRoot {{ self_service_password_install_dir }} 19 | ServerName {{ self_service_password_fqdn }} 20 | ServerAdmin webmaster@{{ self_service_password_fqdn }} 21 | SSLEngine on 22 | {% if self_service_password_https_mode == 'selfsigned' %} 23 | SSLCertificateFile /etc/ssl/certs/{{ self_service_password_fqdn }}.crt 24 | SSLCertificateKeyFile /etc/ssl/private/{{ self_service_password_fqdn }}.key 25 | {% endif %} 26 | 27 | DirectoryIndex index.php 28 | AddDefaultCharset UTF-8 29 | 30 | 31 | AllowOverride None 32 | Require ip 127.0.0.1 {{ self_service_password_allowed_hosts }} 33 | 34 | 35 | 36 | SetHandler "proxy:unix:/run/php/php{{ php_fpm_version }}-fpm-self-service-password.sock|fcgi://localhost" 37 | 38 | 39 | 40 | AllowOverride None 41 | Require all denied 42 | 43 | 44 | -------------------------------------------------------------------------------- /roles/apache/tasks/checks.yml: -------------------------------------------------------------------------------- 1 | - name: check that mandatory variables are correctly defined 2 | assert: 3 | quiet: yes 4 | that: "{{ item }}" 5 | fail_msg: "One or more variables are not correctly defined. Check role documentation: https://gitlab.com/nodiscc/xsrv/-/tree/master/roles/apache" 6 | loop: 7 | - apache_enable_service == apache_enable_service | bool 8 | - apache_letsencrypt_email is not search("CHANGEME") 9 | - apache_listen_http == apache_listen_http | bool 10 | - apache_allow_robots == apache_allow_robots | bool 11 | - php_fpm_enable_default_pool == php_fpm_enable_default_pool | bool 12 | - apache_access_log_to_syslog == apache_access_log_to_syslog | bool 13 | - apache_firewalld_zones | type_debug == "list" 14 | - apache_reverseproxies | type_debug == "list" 15 | - apache_letsencrypt_enable_hsts == apache_letsencrypt_enable_hsts | bool 16 | 17 | - name: check that variables are correctly defined (apache_reverseproxies) 18 | assert: 19 | quiet: yes 20 | fail_msg: "One or more variables are not correctly defined. Check role documentation: https://gitlab.com/nodiscc/xsrv/-/tree/master/roles/apache" 21 | that: 22 | - item.servername is string 23 | - item.upstream is string 24 | - (item.https_mode is not defined) or (item.https_mode in ['selfsigned', 'letsencrypt']) 25 | - (item.redirect_https is not defined) or (item.redirect_https == item.redirect_https | bool) 26 | - (item.extra_directives is not defined) or (item.extra_directives | type_debug == "list") 27 | - (item.monitor_http is not defined) or (item.monitor_http == item.monitor_http | bool) 28 | loop: "{{ apache_reverseproxies }}" 29 | tags: apache-reverseproxy 30 | -------------------------------------------------------------------------------- /roles/monitoring_rsyslog/README.md: -------------------------------------------------------------------------------- 1 | # xsrv.monitoring_rsyslog 2 | 3 | This role will setup [rsyslog](https://en.wikipedia.org/wiki/Rsyslog): 4 | - aggregation of common log files (APT/unattended-upgrades/fail2ban) to a single `/var/log/syslog` file 5 | - retention policy (`logrotate`) 6 | - `systemd-journald` storage settings 7 | - (optional) log filtering/discarding of unwanted messages 8 | - (optional) log forwarding over TCP/SSL/TLS 9 | 10 | [![](https://screenshots.debian.net/shrine/screenshot/10371/simage/large-24897d7d91b1b5fc33cca4accd70781b.png)](https://screenshots.debian.net/package/lnav) 11 | 12 | 13 | ## Requirements/dependencies/example playbook 14 | 15 | See [meta/main.yml](meta/main.yml) 16 | 17 | ```yaml 18 | - hosts: my.CHANGEME.org 19 | roles: 20 | - librelogic.librelogic.common # (optional) basic setup, hardening, firewall 21 | - librelogic.librelogic.monitoring_rsyslog 22 | # - librelogic.librelogic.monitoring # (optional) full monitoring suite including monitoring_rsyslog 23 | ``` 24 | 25 | See [defaults/main.yml](defaults/main.yml) for all configuration variables 26 | 27 | If `rsyslog_enable_receive: yes`, the host must be reachable by syslog clients on port `514/tcp`. 28 | If `rsyslog_enable_receive: yes`, the host must be deployed **before** syslog clients in the playbook execution order (the syslog server's CA certificate must already exist in order to sign client certificates) 29 | 30 | ## Tags 31 | 32 | 33 | ``` 34 | rsyslog - setup system log processing 35 | ``` 36 | 37 | 38 | 39 | ## License 40 | 41 | [GNU GPLv3](../../LICENSE) 42 | 43 | 44 | ## References 45 | 46 | - https://stdout.root.sx/links/?searchtags=monitoring 47 | - https://stdout.root.sx/links/?searchtags=logs 48 | -------------------------------------------------------------------------------- /roles/common/tasks/utils-debian11to12.yml: -------------------------------------------------------------------------------- 1 | - name: check if host is already running the target distribution 2 | debug: 3 | msg: "Host is already running Debian 12. Nothing to do." 4 | when: ansible_facts.distribution_release == "bookworm" 5 | 6 | - name: upgrade Debian 11 to 12 7 | when: ansible_facts.distribution_release == "bullseye" 8 | block: 9 | - name: update apt cache 10 | apt: 11 | update_cache: yes 12 | - name: upgrade all packages to latest versions (safe-upgrade) # noqa no-changed-when command-instead-of-module 13 | command: 14 | cmd: apt-get -y upgrade 15 | environment: 16 | DEBIAN_FRONTEND: noninteractive 17 | - name: list APT sources configuration files 18 | find: 19 | path: /etc/apt/sources.list.d/ 20 | patterns: '*.list' 21 | register: common_apt_sources_files 22 | - name: replace bullseye with bookworm in APT sources list 23 | replace: 24 | path: "{{ item }}" 25 | regexp: "bullseye" 26 | replace: "bookworm" 27 | with_items: "{{ common_apt_sources_files.files | map(attribute='path') | list + ['/etc/apt/sources.list'] }}" 28 | - name: update apt cache 29 | apt: 30 | update_cache: yes 31 | - name: upgrade all packages to latest versions (dist-upgrade) # noqa no-changed-when command-instead-of-module 32 | command: 33 | cmd: apt-get -y dist-upgrade 34 | environment: 35 | DEBIAN_FRONTEND: noninteractive 36 | - name: reboot host 37 | reboot: 38 | reboot_timeout: 6000 39 | - name: show upgrade completion message 40 | debug: 41 | msg: "Upgrade to Debian 12 complete. Please run the playbook against this host to apply up-to-date configuration for Debian 12." 42 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_netdata_health.d_ping.conf.j2: -------------------------------------------------------------------------------- 1 | # you can disable an alarm notification by setting the 'to' line to: silent 2 | 3 | template: ping_host_reachable 4 | families: * 5 | on: ping.host_packet_loss 6 | class: Errors 7 | type: Other 8 | component: Network 9 | lookup: average -30s unaligned of loss 10 | calc: $this != nan AND $this < 100 11 | units: up/down 12 | every: 10s 13 | crit: $this == 0 14 | delay: down 30m multiplier 1.5 max 2h 15 | info: network host ${label:host} reachability status 16 | to: {{ 'sysadmin' if not netdata_fping_alarms_silent else 'silent' }} 17 | 18 | template: ping_packet_loss 19 | families: * 20 | on: ping.host_packet_loss 21 | class: Errors 22 | type: Other 23 | component: Network 24 | lookup: average -10m unaligned of loss 25 | green: 5 26 | red: 10 27 | units: % 28 | every: 10s 29 | warn: $this > $green 30 | crit: $this > $red 31 | delay: down 30m multiplier 1.5 max 2h 32 | info: packet loss percentage to the network host ${label:host} over the last 10 minutes 33 | to: {{ 'sysadmin' if not netdata_fping_alarms_silent else 'silent' }} 34 | 35 | template: ping_host_latency 36 | families: * 37 | on: ping.host_rtt 38 | class: Latency 39 | type: Other 40 | component: Network 41 | lookup: average -10s unaligned of avg 42 | units: ms 43 | every: 10s 44 | green: 500 45 | red: 1000 46 | warn: $this > $green OR $max > $red 47 | crit: $this > $red 48 | delay: down 30m multiplier 1.5 max 2h 49 | info: average latency to the network host ${label:host} over the last 10 seconds 50 | to: {{ 'sysadmin' if not netdata_fping_alarms_silent else 'silent' }} 51 | -------------------------------------------------------------------------------- /tests/host_vars/localhost.yml: -------------------------------------------------------------------------------- 1 | nginx_letsencrypt_email: 'test.email@mail.com' 2 | openldap_fqdn: 'openldap.fqdn' 3 | openldap_domain: 'openldap.domain' 4 | openldap_organization: 'openldap-organization' 5 | openldap_base_dn: 'openldap.base.dn' 6 | openldap_bind_username: 'openldap-bind-username' 7 | openldap_bind_password: 'openldap-bind-password' 8 | openldap_admin_password: 'openldap-admin-password' 9 | 10 | ldap_account_manager_fqdn: 'ldap.account.manager.fqdn' 11 | ldap_account_manager_install_dir: 'ldap/account/manager/install/dir' 12 | 13 | self_service_password_fqdn: 'self.service.password.fqdn' 14 | self_service_password_install_dir: 'self/service/password/install/dir' 15 | 16 | gitlab_fqdn: 'gitlab.fqdn' 17 | gitlab_initial_root_password: 'gitlab-initial-root-password' 18 | gitlab_initial_shared_runners_registration_token: 'gitlab-initial-shared-runners-registration-token' 19 | gitlab_registry_fqdn: 'gitlab.registry.fqdn' 20 | gitlab_ldap_server: 'gitlab.ldap.server' 21 | gitlab_ldap_bind_dn: 'gitlab.ldap.bind.dn' 22 | gitlab_ldap_bind_password: 'gitlab-ldap-bind-password' 23 | gitlab_ldap_search_base: 'gitlab-ldap-search-base' 24 | gitlab_smtp_server: 'gitlab-smtp' 25 | gitlab_smtp_user: 'gitlab-smtp' 26 | gitlab_smtp_password: 'gitlab-smtp' 27 | gitlab_smtp_domain: 'gitlab-smtp' 28 | 29 | apache_letsencrypt_email: 'apache.letsencrypt.email@mail.com' 30 | 31 | mailcatcher_fqdn: 'mailcatcher.fqdn' 32 | mailcatcher_user: 'mailcatcher-user' 33 | mailcatcher_password: 'mailcatcher-password' 34 | 35 | adminer_fqdn: 'adminer.fqdn' 36 | adminer_user: 'adminer-user' 37 | adminer_password: 'adminer-password' 38 | 39 | gitlab_runner_api_token: 'gitlab-ronner-api-token' 40 | gitlab_runner_registration_token: 'gitlab-ronner-registration-token' 41 | gitlab_runner_gitlab_url: 'gitlab-ronner-gitlab-url' -------------------------------------------------------------------------------- /roles/openldap/templates/etc_ldap-account-manager_config.cfg.j2: -------------------------------------------------------------------------------- 1 | # password to add/delete/rename configuration profiles (default: lam) 2 | # Configuration via web interface is locked by default, changes will be overwritten by ansible 3 | # Uncomment this to temporarily allow access to configuration interface with the password 'lam' 4 | # don't forget to comment it back afterwards! 5 | # password: {SSHA}D6AaX93kPmck9wAxNlq3GF93S7A= R7gkjQ== 6 | 7 | # default profile, without ".conf" 8 | default: lam 9 | 10 | # log level 11 | logLevel: 5 12 | 13 | # log destination 14 | logDestination: SYSLOG 15 | 16 | 17 | # session timeout in minutes 18 | sessionTimeout: {{ ldap_account_manager_session_timeout }} 19 | 20 | # list of hosts which may access LAM 21 | allowedHosts: {{ ldap_account_manager_allowed_hosts }} 22 | 23 | # list of hosts which may access LAM Pro self service 24 | allowedHostsSelfService: 25 | 26 | # encrypt session data 27 | encryptSession: true 28 | 29 | # Password: minimum password length 30 | passwordMinLength: 9 31 | 32 | # Password: minimum uppercase characters 33 | passwordMinUpper: 0 34 | 35 | # Password: minimum lowercase characters 36 | passwordMinLower: 0 37 | 38 | # Password: minimum numeric characters 39 | passwordMinNumeric: 0 40 | 41 | # Password: minimum symbolic characters 42 | passwordMinSymbol: 0 43 | 44 | # Password: minimum character classes (0-4) 45 | passwordMinClasses: 3 46 | 47 | # Password: checked rules 48 | checkedRulesCount: -1 49 | 50 | # Password: must not contain part of user name 51 | passwordMustNotContain3Chars: false 52 | 53 | # Password: must not contain user name 54 | passwordMustNotContainUser: false 55 | 56 | # Email format (default/unix) 57 | mailEOL: default 58 | 59 | # PHP error reporting (default/system) 60 | errorReporting: default 61 | 62 | # License 63 | license: 64 | -------------------------------------------------------------------------------- /roles/common/tasks/mail.yml: -------------------------------------------------------------------------------- 1 | ##### SYSTEM MAIL ##### 2 | 3 | - name: forward all root mail to {{ mail_root_alias }} 4 | lineinfile: 5 | path: /etc/aliases 6 | state: present 7 | create: yes 8 | regexp: "^root" 9 | line: "root: {{ mail_root_alias }}" 10 | owner: root 11 | group: root 12 | mode: "0644" 13 | when: not setup_msmtp | bool 14 | 15 | ##### OUTGOING MAIL/SMARTHOST ##### 16 | 17 | - name: install msmtp SMTP client/MTA 18 | apt: 19 | package: 20 | - msmtp 21 | - msmtp-mta 22 | state: present 23 | when: setup_msmtp | bool 24 | 25 | - name: copy msmtp configuration 26 | template: 27 | src: "etc_msmtprc.j2" 28 | dest: "/etc/msmtprc" 29 | mode: "0640" 30 | owner: root 31 | group: "msmtp" 32 | when: setup_msmtp | bool 33 | 34 | - name: forward all root mail to msmtp_admin_email 35 | lineinfile: 36 | path: /etc/aliases 37 | state: present 38 | create: yes 39 | regexp: "{{ item.regex }}" 40 | line: "{{ item.line }}" 41 | owner: root 42 | group: root 43 | mode: "0644" 44 | with_items: 45 | - regex: "^root" 46 | line: "root: default" 47 | - regex: "^default" 48 | line: "default: {{ msmtp_admin_email }}" 49 | when: setup_msmtp | bool 50 | 51 | ##### FACTS ##### 52 | 53 | - name: create ansible facts.d directory 54 | file: 55 | path: /etc/ansible/facts.d 56 | state: directory 57 | mode: "0755" 58 | ignore_errors: "{{ ansible_check_mode }}" 59 | 60 | - name: create msmtp fact file 61 | template: 62 | src: etc_ansible_facts.d_msmtp.fact.j2 63 | dest: /etc/ansible/facts.d/msmtp.fact 64 | mode: "0644" 65 | notify: update ansible facts 66 | ignore_errors: "{{ ansible_check_mode }}" 67 | 68 | # ensure ansible facts are up to date before continuing 69 | - name: apply configuration (flush handlers) 70 | meta: flush_handlers 71 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_netdata_go.d.conf.j2: -------------------------------------------------------------------------------- 1 | # netdata go.d.plugin configuration 2 | # 3 | # This file is in YAML format. 4 | 5 | # Enable/disable the whole go.d.plugin. 6 | enabled: yes 7 | 8 | # Enable/disable default value for all modules. 9 | default_run: yes 10 | 11 | # Maximum number of used CPUs. Zero means no limit. 12 | max_procs: 0 13 | 14 | # Enable/disable specific g.d.plugin module 15 | # If you want to change any value, you need to uncomment out it first. 16 | # IMPORTANT: Do not remove all spaces, just remove # symbol. There should be a space before module name. 17 | modules: 18 | # activemq: yes 19 | # apache: yes 20 | # bind: yes 21 | # cockroachdb: yes 22 | # consul: yes 23 | # coredns: yes 24 | # couchbase: yes 25 | # couchdb: yes 26 | # dnsdist: yes 27 | # dnsmasq: yes 28 | # dnsmasq_dhcp: yes 29 | # dns_query: yes 30 | # docker_engine: yes 31 | # dockerhub: yes 32 | # elasticsearch: yes 33 | # example: no 34 | # filecheck: yes 35 | # fluentd: yes 36 | # freeradius: yes 37 | # haproxy: yes 38 | # hdfs: yes 39 | # httpcheck: yes 40 | # isc_dhcpd: yes 41 | # k8s_kubelet: yes 42 | # k8s_kubeproxy: yes 43 | # lighttpd: yes 44 | # lighttpd2: yes 45 | # logstash: yes 46 | # mongodb: yes 47 | # mysql: yes 48 | # nginx: yes 49 | # nginxvts: yes 50 | # openvpn: yes 51 | # phpdaemon: yes 52 | # phpfpm: yes 53 | # pihole: yes 54 | # pika: yes 55 | # portcheck: yes 56 | # powerdns: yes 57 | # powerdns_recursor: yes 58 | # prometheus: yes 59 | # pulsar: yes 60 | # rabbitmq: yes 61 | # redis: yes 62 | # scaleio: yes 63 | # solr: yes 64 | # springboot2: yes 65 | # squidlog: yes 66 | # supervisord: yes 67 | systemdunits: yes 68 | # tengine: yes 69 | # traefik: yes 70 | # unbound: yes 71 | # vernemq: yes 72 | # vcsa: yes 73 | # vsphere: yes 74 | # web_log: yes 75 | # whoisquery: yes 76 | # wmi: yes 77 | # x509check: yes 78 | # zookeeper: yes 79 | -------------------------------------------------------------------------------- /roles/monitoring_rsyslog/tasks/checks.yml: -------------------------------------------------------------------------------- 1 | - name: check that mandatory variables are correctly defined 2 | assert: 3 | quiet: yes 4 | that: "{{ item }}" 5 | fail_msg: "One or more variables are not correctly defined. Check role documentation: https://gitlab.com/nodiscc/xsrv/-/tree/master/roles/monitoring_rsyslog" 6 | loop: 7 | - rsyslog_retention_days == rsyslog_retention_days | int 8 | - rsyslog_enable_forwarding == rsyslog_enable_forwarding | bool 9 | - rsyslog_custom_config | type_debug == "list" 10 | - rsyslog_enable_receive == rsyslog_enable_receive | bool 11 | - rsyslog_remote_logs_path is string 12 | - rsyslog_firewalld_zones | type_debug == "list" 13 | 14 | - name: check that mandatory variables are correctly defined (syslog forwarding) 15 | assert: 16 | quiet: yes 17 | that: "{{ item }}" 18 | fail_msg: "One or more variables are not correctly defined. Check role documentation: https://gitlab.com/nodiscc/xsrv/-/tree/master/roles/monitoring_rsyslog" 19 | when: rsyslog_enable_forwarding 20 | loop: 21 | - rsyslog_forward_to_hostname is not search('CHANGEME') 22 | - rsyslog_forward_to_inventory_hostname is not search('CHANGEME') 23 | - rsyslog_forward_to_port == rsyslog_forward_to_port | int 24 | - rsyslog_cert_not_after | ansible.builtin.to_datetime("%Y%m%d%H%M%SZ") 25 | - rsyslog_cert_not_before | ansible.builtin.to_datetime("%Y%m%d%H%M%SZ") 26 | 27 | - name: check that mandatory variables are correctly defined (syslog receiving) 28 | assert: 29 | quiet: yes 30 | that: "{{ item }}" 31 | fail_msg: "One or more variables are not correctly defined. Check role documentation: https://gitlab.com/nodiscc/xsrv/-/tree/master/roles/monitoring_rsyslog" 32 | when: rsyslog_enable_receive 33 | loop: 34 | - rsyslog_fqdn is not search('CHANGEME') 35 | - rsyslog_cert_not_after | ansible.builtin.to_datetime("%Y%m%d%H%M%SZ") 36 | - rsyslog_cert_not_before | ansible.builtin.to_datetime("%Y%m%d%H%M%SZ") 37 | -------------------------------------------------------------------------------- /roles/openldap/templates/etc_default_slapd.j2: -------------------------------------------------------------------------------- 1 | # Default location of the slapd.conf file or slapd.d cn=config directory. If 2 | # empty, use the compiled-in default (/etc/ldap/slapd.d with a fallback to 3 | # /etc/ldap/slapd.conf). 4 | SLAPD_CONF= 5 | 6 | # System account to run the slapd server under. If empty the server 7 | # will run as root. 8 | SLAPD_USER="openldap" 9 | 10 | # System group to run the slapd server under. If empty the server will 11 | # run in the primary group of its user. 12 | SLAPD_GROUP="openldap" 13 | 14 | # Path to the pid file of the slapd server. If not set the init.d script 15 | # will try to figure it out from $SLAPD_CONF (/etc/ldap/slapd.d by 16 | # default) 17 | SLAPD_PIDFILE= 18 | 19 | # slapd normally serves ldap only on all TCP-ports 389. slapd can also 20 | # service requests on TCP-port 636 (ldaps) and requests via unix 21 | # sockets. 22 | # Example usage: 23 | # SLAPD_SERVICES="ldap://127.0.0.1:389/ ldaps:/// ldapi:///" 24 | SLAPD_SERVICES="ldap:/// ldaps:/// ldapi:///" 25 | 26 | # If SLAPD_NO_START is set, the init script will not start or restart 27 | # slapd (but stop will still work). Uncomment this if you are 28 | # starting slapd via some other means or if you don't want slapd normally 29 | # started at boot. 30 | #SLAPD_NO_START=1 31 | 32 | # If SLAPD_SENTINEL_FILE is set to path to a file and that file exists, 33 | # the init script will not start or restart slapd (but stop will still 34 | # work). Use this for temporarily disabling startup of slapd (when doing 35 | # maintenance, for example, or through a configuration management system) 36 | # when you don't want to edit a configuration file. 37 | SLAPD_SENTINEL_FILE=/etc/ldap/noslapd 38 | 39 | # For Kerberos authentication (via SASL), slapd by default uses the system 40 | # keytab file (/etc/krb5.keytab). To use a different keytab file, 41 | # uncomment this line and change the path. 42 | #export KRB5_KTNAME=/etc/krb5.keytab 43 | 44 | # Additional options to pass to slapd 45 | SLAPD_OPTIONS="" 46 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/templates/etc_netdata_netdata.conf.j2: -------------------------------------------------------------------------------- 1 | # netdata configuration 2 | # You can download the running configuration of your netdata instance, using: 3 | # curl http://localhost:19999/netdata.conf 4 | 5 | [db] 6 | update every = {{ netdata_update_every }} 7 | mode = dbengine 8 | storage tiers = 3 9 | page cache size MB = {{ netdata_dbengine_page_cache_size }} 10 | # tier 0, per-second data 11 | dbengine multihost disk space MB = {{ netdata_dbengine_disk_space }} 12 | # tier 1, per-minute data 13 | dbengine tier 1 multihost disk space MB = 400 14 | dbengine tier 1 update every iterations = 60 15 | # tier 2, per-hour data 16 | dbengine tier 2 multihost disk space MB = 200 17 | dbengine tier 2 update every iterations = 60 18 | 19 | [logs] 20 | logs to trigger flood protection = 1000 21 | logs flood protection period = 60 22 | level = info 23 | daemon = journal 24 | collector = journal 25 | access = /var/log/netdata/access.log 26 | health = journal 27 | 28 | {% if not netdata_enable_health_notifications %} 29 | [health] 30 | script to execute on alarm = /bin/true 31 | {% endif %} 32 | 33 | [web] 34 | default port = 19999 35 | allow connections from = {{ netdata_allow_connections_from }} localhost 36 | allow netdata.conf from = {{ netdata_allow_connections_from }} localhost 37 | ssl key = /etc/ssl/netdata/netdata-key.pem 38 | ssl certificate = /etc/ssl/netdata/netdata-cert.pem 39 | web files owner = root 40 | web files group = netdata 41 | accept a streaming request every seconds = 0 42 | 43 | [registry] 44 | enabled = yes 45 | registry to announce = https://{{ inventory_hostname }}:{{ netdata_public_port | default('19999') }} 46 | 47 | {% if netdata_streaming_send_enabled %} 48 | [ml] 49 | enabled = no 50 | {% endif %} 51 | 52 | [plugins] 53 | {% for plugin in netdata_disabled_plugins %} 54 | {{ plugin }} = no 55 | {% endfor %} 56 | 57 | [plugin:proc:diskspace] 58 | exclude space metrics on paths = /proc/* /sys/* /var/run/user/* /run/user/* /snap/* /var/lib/docker/* /dev /dev/shm 59 | -------------------------------------------------------------------------------- /roles/monitoring_rsyslog/defaults/main.yml: -------------------------------------------------------------------------------- 1 | ##### RSYSLOG LOG PROCESSING SYSTEM ##### 2 | # number of daily /var/log/syslog archives to retain 3 | rsyslog_retention_days: 186 4 | # enable forwarding of syslog logs to a syslog server over TLS/TCP (no/yes) 5 | rsyslog_enable_forwarding: no 6 | # if forwarding is enabled, hostname/port to forward logs to 7 | rsyslog_forward_to_hostname: "logs.CHANGEME.org" 8 | rsyslog_forward_to_port: 5140 9 | # if forwarding is enabled, inventory hostname of the host to forward logs to 10 | rsyslog_forward_to_inventory_hostname: "my.CHANGEME.org" 11 | # enable receiving logs from other hosts over TLS/TCP port 514 (no/yes) 12 | # log collectors must be deployed before clients in the playbook execution order 13 | rsyslog_enable_receive: no 14 | # if rsyslog_enable_receive is enabled, DNS name of this syslog server/collector 15 | rsyslog_fqdn: "logs.CHANGEME.org" 16 | # if rsyslog_enable_receive is enabled, path to the directory to write remote hosts logs to 17 | rsyslog_remote_logs_path: /var/log/rsyslog/hosts 18 | # when rsyslog_enable_forwarding or rsyslog_enable_receive is enabled, start and end validity dates for TLS certificates (YYYYMMDDHHMMSSZ) 19 | rsyslog_cert_not_before: "20240219000000Z" 20 | rsyslog_cert_not_after: "20340219000000Z" 21 | # custom rsyslog configuration directives, applied before forwarding/single-file aggregation (list) 22 | # Example: 23 | # rsyslog_custom_config: 24 | # - ':msg, contains, "failed to read Temperature" stop' # discard messages containing this string 25 | # - 'if $programname == "apache" and re_match($msg, ".* 127.0.0.1 - - .* \"GET /server-status\\?auto HTTP/1.1\" 200") then stop' # discard messages matching this program name and regular expression 26 | # - 'if $programname == "CRON" and re_match($msg, "cron:session): session (opened|closed) for user .*") then stop' 27 | rsyslog_custom_config: [] 28 | # firewall zones from which to allow incoming logs (zone, state), if rsyslog_enable_receive: yes and librelogic.librelogic.common/firewalld role is deployed 29 | # 'zone:' is one of firewalld zones, set 'state:' to 'disabled' to remove the rule (the default is state: enabled) 30 | rsyslog_firewalld_zones: 31 | - zone: internal 32 | state: enabled 33 | - zone: public 34 | state: enabled 35 | -------------------------------------------------------------------------------- /roles/docker_nginx/tasks/docker-nginx.yml: -------------------------------------------------------------------------------- 1 | ##### NGINX REVERSEPROXY CONFIGURATION ##### 2 | 3 | - name: create configuration directories 4 | file: 5 | path: "{{ item }}" 6 | state: directory 7 | mode: 0755 8 | with_items: 9 | - "/etc/docker/services-config/nginx/" 10 | - "/etc/docker/services-config/nginx/conf.d" 11 | - "/etc/docker/services-config/nginx/ssl/selfsigned" 12 | - "/etc/docker/services-config/nginx/static" 13 | ignore_errors: "{{ ansible_check_mode }}" 14 | 15 | - name: copy nginx configuration 16 | template: 17 | src: "etc_docker_services-config/nginx/nginx.conf.j2" 18 | dest: "/etc/docker/services-config/nginx/nginx.conf" 19 | mode: 0644 20 | 21 | ##### SSL/TLS CERTIFICATES ##### 22 | 23 | - name: install requirements for certificates generation 24 | apt: 25 | state: present 26 | package: 27 | - certbot 28 | - python3-openssl 29 | 30 | - name: create base directory for letsencrypt certificates 31 | file: 32 | state: directory 33 | path: /etc/letsencrypt/live 34 | owner: root 35 | group: root 36 | mode: 0700 37 | 38 | - name: copy certbot configuration 39 | template: 40 | src: etc_letsencrypt_cli.ini.j2 41 | dest: /etc/letsencrypt/cli.ini 42 | owner: root 43 | group: root 44 | mode: 0644 45 | 46 | - name: copy certbot systemd timer configuration 47 | template: 48 | src: etc_systemd_system_certbot.timer.j2 49 | dest: /etc/systemd/system/certbot.timer 50 | owner: root 51 | group: root 52 | mode: 0644 53 | 54 | 55 | ##### DOCKER STACK ##### 56 | 57 | - name: copy configuration file for nginx-reverseproxy docker stack 58 | template: 59 | src: "etc_docker_services-config/nginx/docker-compose.yml.j2" 60 | dest: "/etc/docker/services-config/nginx/docker-compose.yml" 61 | mode: 0644 62 | 63 | - name: create nginx docker network 64 | docker_network: 65 | name: nginx 66 | driver: overlay 67 | scope: swarm 68 | attachable: yes 69 | ignore_errors: "{{ ansible_check_mode }}" 70 | 71 | - name: create nginx-reverseproxy docker stack 72 | docker_stack: 73 | state: present 74 | name: nginx-reverseproxy 75 | compose: 76 | - '/etc/docker/services-config/nginx/docker-compose.yml' 77 | ignore_errors: "{{ ansible_check_mode }}" 78 | 79 | - name: run all notified handlers 80 | meta: flush_handlers 81 | -------------------------------------------------------------------------------- /roles/common/meta/main.yml: -------------------------------------------------------------------------------- 1 | # @tag common - setup base system 2 | # @tag apt - setup APT package management 3 | # @tag checks - check that variables are correctly defined 4 | # @tag datetime - setup date/time configuration 5 | # @tag dns - setup DNS resolution 6 | # @tag fail2ban - setup fail2ban intrusion prevention system 7 | # @tag firewall - setup firewall 8 | # @tag hostname - setup hostname 9 | # @tag hosts - setup /etc/hosts entries 10 | # @tag packages - additional package installation/removal 11 | # @tag sysctl - setup sysctl kernel configuration 12 | # @tag users - setup users and groups 13 | # @tag ssh - setup SSH server 14 | # @tag ssh-authorized-keys - setup ssh authorized keys 15 | # @tag mail - setup outgoing system mail 16 | # @tag msmtp - setup outgoing system mail 17 | # @tag services - start/stop/enable/disable services 18 | # @tag utils-apt-unattended-upgrade - (manual) run unattended-upgrade now 19 | # @tag utils-apt-upgrade - (manual) run apt upgrade now 20 | # @tag utils-debian10to11 - (manual) upgrade debian 10 hosts to debian 11 21 | # @tag utils-debian11to12 - (manual) upgrade debian 11 hosts to debian 12 22 | # @tag utils-fail2ban-get-banned - (manual) download the list of banned IPs 23 | # @tag utils-firewalld-info - (manual) get firewall status informations 24 | # @tag utils-shutdown - (manual) shut down the host 25 | # @tag utils-reboot - (manual) reboot the host 26 | # @tag cron - configure cron task scheduler 27 | # @tag apt-listbugs - configure apt-listbugs bug prevention tool 28 | 29 | galaxy_info: 30 | role_name: common 31 | author: "Libre Logic " 32 | description: "Base setup for Debian-based servers" 33 | license: GPL-3.0 34 | min_ansible_version: "2.12" 35 | platforms: 36 | - name: Debian 37 | versions: 38 | - "11" 39 | - "12" 40 | galaxy_tags: 41 | - hostname 42 | - kernel 43 | - networking 44 | - swap 45 | - memory 46 | - sysctl 47 | - apt 48 | - debian 49 | - upgrades 50 | - pam 51 | - limits 52 | - ntp 53 | - time 54 | - date 55 | - ssh 56 | - firewall 57 | - fail2ban 58 | - hardening 59 | - security 60 | - utilities 61 | - users 62 | - sudo 63 | - cis 64 | - debian 65 | - disa 66 | - stig 67 | - systemd 68 | dependencies: 69 | - librelogic.librelogic.handlers 70 | 71 | -------------------------------------------------------------------------------- /roles/common/tasks/fail2ban.yml: -------------------------------------------------------------------------------- 1 | - name: install fail2ban 2 | apt: 3 | state: present 4 | package: 5 | - fail2ban 6 | - ipset 7 | 8 | - name: create fail2ban configuration directories 9 | file: 10 | path: "{{ item }}" 11 | state: directory 12 | owner: root 13 | group: root 14 | mode: "0755" 15 | with_items: 16 | - "/etc/fail2ban" 17 | - "/etc/fail2ban/jail.d" 18 | - "/etc/fail2ban/filter.d" 19 | 20 | - name: copy fail2ban global configuration 21 | template: 22 | src: "{{ item.src }}" 23 | dest: "{{ item.dest }}" 24 | owner: root 25 | group: root 26 | mode: "0644" 27 | with_items: 28 | - { src: 'etc_fail2ban_jail.local.j2', dest: '/etc/fail2ban/jail.local' } 29 | - { src: 'etc_fail2ban_action.d_firewallcmd-ipset.conf.j2', dest: '/etc/fail2ban/action.d/firewallcmd-ipset.conf' } 30 | - { src: 'etc_fail2ban_fail2ban.local.j2', dest: '/etc/fail2ban/fail2ban.local' } 31 | - { src: 'var_lib_fail2ban_emptylog.log.j2', dest: '/var/lib/fail2ban/emptylog.log' } 32 | notify: restart fail2ban 33 | 34 | - name: copy fail2ban sshd jail configuration 35 | template: 36 | src: etc_fail2ban_jail.d_sshd.conf.j2 37 | dest: /etc/fail2ban/jail.d/sshd.conf 38 | owner: root 39 | group: root 40 | mode: "0644" 41 | notify: reload fail2ban 42 | 43 | - name: migration/1.17.0 - remove files from old versions of the role 44 | file: 45 | path: /etc/fail2ban/jail.d/pam-generic.conf 46 | state: absent 47 | notify: reload fail2ban 48 | 49 | ##### FACTS ##### 50 | 51 | - name: create ansible facts.d directory 52 | file: 53 | path: /etc/ansible/facts.d 54 | state: directory 55 | owner: root 56 | group: root 57 | mode: "0755" 58 | ignore_errors: "{{ ansible_check_mode }}" 59 | 60 | - name: create fail2ban fact file 61 | template: 62 | src: etc_ansible_facts.d_fail2ban.fact.j2 63 | dest: /etc/ansible/facts.d/fail2ban.fact 64 | owner: root 65 | group: root 66 | mode: "0644" 67 | notify: update ansible facts 68 | ignore_errors: "{{ ansible_check_mode }}" 69 | 70 | - name: apply configuration (flush handlers) 71 | meta: flush_handlers 72 | 73 | ##### SERVICES ##### 74 | 75 | - name: start and enable fail2ban 76 | service: 77 | name: fail2ban 78 | state: started 79 | enabled: yes 80 | ignore_errors: "{{ ansible_check_mode }}" 81 | tags: services 82 | -------------------------------------------------------------------------------- /roles/gitlab/tasks/checks.yml: -------------------------------------------------------------------------------- 1 | - name: check that mandatory variables are correctly defined 2 | assert: 3 | that: 4 | - gitlab_fqdn is not search("CHANGEME") 5 | - gitlab_initial_root_password is not search("CHANGEME") 6 | - gitlab_initial_shared_runners_registration_token is not search("CHANGEME") 7 | - gitlab_registry_fqdn is not search("CHANGEME") 8 | - gitlab_ldap_enabled in ['true', 'false'] 9 | - gitlab_smtp_enabled in ['true', 'false'] 10 | - gitlab_letsencrypt_enable == gitlab_letsencrypt_enable|bool 11 | - gitlab_nginx_enable in ['true', 'false'] 12 | - gitlab_nginx_listen_https == gitlab_nginx_listen_https|bool 13 | success_msg: "Role variables are correctly defined." 14 | fail_msg: "One or more variables are not correctly defined. Check role documentation." 15 | 16 | - name: check that mandatory variables are correctly defined (LDAP) 17 | assert: 18 | that: 19 | - gitlab_ldap_server is not search("CHANGEME") 20 | - gitlab_ldap_bind_dn is not search("CHANGEME") 21 | - gitlab_ldap_bind_password is not search("CHANGEME") 22 | - gitlab_ldap_search_base is not search("CHANGEME") 23 | - gitlab_ldap_verify_certificates == gitlab_ldap_verify_certificates|bool 24 | - gitlab_ldap_encryption in ['start_tls', 'simple_tls', 'plain'] 25 | success_msg: "Role variables are correctly defined." 26 | fail_msg: "Gitlab LDAP authentication enabled but one or more variables are not correctly defined." 27 | when: gitlab_ldap_enabled == 'true' 28 | 29 | - name: check that mandatory variables are correctly defined (SMTP) 30 | assert: 31 | that: 32 | - gitlab_smtp_server is not search("CHANGEME") 33 | - gitlab_smtp_port == gitlab_smtp_port|int 34 | - gitlab_smtp_user is not search("CHANGEME") 35 | - gitlab_smtp_password is not search("CHANGEME") 36 | - gitlab_smtp_domain is not search("CHANGEME") 37 | - gitlab_smtp_authentication in ['plain', 'login'] 38 | - gitlab_smtp_enable_starttls_auto in ['true', 'false'] 39 | - gitlab_smtp_tls in ['true', 'false'] 40 | - gitlab_smtp_openssl_verify_mode in ['peer', 'none', 'client_once', 'fail_if_no_peer_cert'] 41 | success_msg: "Role variables are correctly defined." 42 | fail_msg: "Gitlab internal SMTP mailer enabled but one or more variables are not correctly defined." 43 | when: gitlab_smtp_enabled == 'true' 44 | -------------------------------------------------------------------------------- /roles/openldap/tasks/ssl-selfsigned.yml: -------------------------------------------------------------------------------- 1 | - name: install requirements for SSL/TLS certificates generation 2 | apt: 3 | state: present 4 | package: 5 | - python3-openssl 6 | - ssl-cert 7 | 8 | - name: create directory for openldap SSL certs/keys 9 | file: 10 | path: /etc/ssl/openldap 11 | state: directory 12 | owner: root 13 | group: openldap 14 | mode: 0750 15 | 16 | - name: generate openssl private key 17 | openssl_privatekey: 18 | path: "/etc/ssl/openldap/{{ openldap_fqdn }}.key" 19 | owner: root 20 | group: openldap 21 | mode: 0640 22 | notify: restart slapd 23 | ignore_errors: "{{ ansible_check_mode }}" 24 | 25 | - name: generate openssl certificate signing request 26 | openssl_csr: 27 | path: "/etc/ssl/openldap/{{ openldap_fqdn }}.csr" 28 | privatekey_path: "/etc/ssl/openldap/{{ openldap_fqdn }}.key" 29 | common_name: "{{ openldap_fqdn }}" 30 | key_usage: "digitalSignature,keyEncipherment" 31 | basicConstraints: "CA:TRUE" 32 | ignore_errors: "{{ ansible_check_mode }}" 33 | 34 | - name: generate self-signed openssl certificate 35 | openssl_certificate: 36 | path: "/etc/ssl/openldap/{{ openldap_fqdn }}.crt" 37 | privatekey_path: "/etc/ssl/openldap/{{ openldap_fqdn }}.key" 38 | csr_path: "/etc/ssl/openldap/{{ openldap_fqdn }}.csr" 39 | provider: selfsigned 40 | owner: root 41 | group: openldap 42 | mode: 0640 43 | notify: restart slapd 44 | ignore_errors: "{{ ansible_check_mode }}" 45 | 46 | - name: configure slapd to use self-signed server certificates 47 | ldap_attrs: 48 | dn: "cn=config" 49 | attributes: "{{ item }}" 50 | state: 'exact' 51 | with_items: 52 | - { olcTLSCACertificateFile: '/etc/ssl/openldap/{{ openldap_fqdn }}.crt' } 53 | - { olcTLSCertificateFile: '/etc/ssl/openldap/{{ openldap_fqdn }}.crt' } 54 | - { olcTLSCertificateKeyFile: '/etc/ssl/openldap/{{ openldap_fqdn }}.key' } 55 | ignore_errors: "{{ ansible_check_mode }}" 56 | 57 | - name: create local certificates directory on the controller 58 | become: no 59 | delegate_to: localhost 60 | file: 61 | path: "{{ playbook_dir }}/certificates/" 62 | state: directory 63 | mode: 0755 64 | 65 | - name: download self-signed certificate to the controller 66 | fetch: 67 | src: "/etc/ssl/openldap/{{ openldap_fqdn }}.crt" 68 | dest: "{{ playbook_dir }}/certificates/{{ openldap_fqdn }}.openldap.crt" 69 | flat: yes 70 | -------------------------------------------------------------------------------- /roles/monitoring_rsyslog/tasks/rsyslog-ssl-server.yml: -------------------------------------------------------------------------------- 1 | ##### REQUIREMENTS ### 2 | 3 | - name: install requirements for SSL/TLS certificates generation 4 | apt: 5 | state: present 6 | package: 7 | - python3-openssl 8 | - ssl-cert 9 | 10 | - name: create directory for syslog certificates/keys/CSRs 11 | file: 12 | state: directory 13 | path: /etc/ssl/syslog 14 | owner: root 15 | group: root 16 | mode: "0755" 17 | 18 | ##### SERVER CERTIFICATE GENERATION ##### 19 | 20 | - name: generate syslog server/CA private key 21 | community.crypto.openssl_privatekey: 22 | path: /etc/ssl/syslog/server.key 23 | owner: root 24 | group: root 25 | mode: "0640" 26 | notify: restart rsyslog 27 | ignore_errors: "{{ ansible_check_mode }}" 28 | 29 | - name: generate CSR for the syslog server/CA certificate 30 | community.crypto.openssl_csr: 31 | path: /etc/ssl/syslog/server.csr 32 | privatekey_path: /etc/ssl/syslog/server.key 33 | common_name: "{{ rsyslog_fqdn }}" 34 | basicConstraints: "CA:TRUE" 35 | # key_usage: "keyCertSign" 36 | # use_common_name_for_san: false 37 | # basic_constraints_critical: true 38 | # key_usage_critical: true 39 | owner: root 40 | group: root 41 | mode: "0640" 42 | ignore_errors: "{{ ansible_check_mode }}" 43 | 44 | - name: generate self-signed syslog server/CA certificate 45 | community.crypto.x509_certificate: 46 | path: /etc/ssl/syslog/server.crt 47 | privatekey_path: /etc/ssl/syslog/server.key 48 | csr_path: /etc/ssl/syslog/server.csr 49 | provider: selfsigned 50 | selfsigned_not_after: "{{ rsyslog_cert_not_after }}" 51 | selfsigned_not_before: "{{ rsyslog_cert_not_before }}" 52 | owner: root 53 | group: root 54 | mode: "0640" 55 | notify: restart rsyslog 56 | ignore_errors: "{{ ansible_check_mode }}" 57 | 58 | # the certificate will be uploaded to syslog clients (hosts with rsyslog_enable_forwarding: yes) 59 | - name: create local certificates directory on the controller 60 | become: no 61 | delegate_to: localhost 62 | file: 63 | path: "{{ playbook_dir }}/data/certificates/" 64 | state: directory 65 | mode: "0755" 66 | - name: download syslog CA certificate to the controller 67 | fetch: 68 | src: /etc/ssl/syslog/server.crt 69 | dest: "{{ playbook_dir }}/data/certificates/syslog-{{ rsyslog_fqdn }}.crt" 70 | flat: yes 71 | ignore_errors: "{{ ansible_check_mode }}" 72 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SHELL=/bin/bash 2 | 3 | all: tests 4 | 5 | venv: 6 | python3 -m venv .venv 7 | 8 | install_ansible: venv 9 | source .venv/bin/activate && \ 10 | pip3 install wheel && \ 11 | pip3 install ansible==6.4.0 ansible-lint==6.7.0 cryptography==43.0.3 cffi==1.14.6 12 | 13 | tests: install_ansible clean 14 | ln -s common roles/librelogic.librelogic.common 15 | ln -s monitoring roles/librelogic.librelogic.monitoring 16 | ln -s monitoring_rsyslog roles/librelogic.librelogic.monitoring_rsyslog 17 | ln -s monitoring_netdata roles/librelogic.librelogic.monitoring_netdata 18 | ln -s monitoring_utils roles/librelogic.librelogic.monitoring_utils 19 | ln -s docker roles/librelogic.librelogic.docker 20 | ln -s docker_nginx roles/librelogic.librelogic.docker_nginx 21 | ln -s gitlab roles/librelogic.librelogic.gitlab 22 | ln -s proxmox roles/librelogic.librelogic.proxmox 23 | ln -s mailcatcher roles/librelogic.librelogic.mailcatcher 24 | ln -s apache roles/librelogic.librelogic.apache 25 | ln -s php_fpm roles/librelogic.librelogic.php_fpm 26 | ln -s adminer roles/librelogic.librelogic.adminer 27 | ln -s gitlab_runner roles/librelogic.librelogic.gitlab_runner 28 | ln -s handlers roles/librelogic.librelogic.handlers 29 | source .venv/bin/activate && \ 30 | cp tests/playbook.yml playbook.yml && \ 31 | cp tests/inventory.yml inventory.yml && \ 32 | cp -r tests/host_vars host_vars && \ 33 | ansible-playbook playbook.yml --syntax-check && \ 34 | ansible-lint -x role-name,ignore-errors,no-tabs playbook.yml && \ 35 | ansible-playbook -i inventory.yml --check playbook.yml --tags="checks" 36 | make clean 37 | 38 | clean: 39 | rm -f playbook.yml 40 | rm -f inventory.yml 41 | rm -rf host_vars 42 | rm -rf roles/librelogic.librelogic.common 43 | rm -rf roles/librelogic.librelogic.monitoring 44 | rm -rf roles/librelogic.librelogic.monitoring_rsyslog 45 | rm -rf roles/librelogic.librelogic.monitoring_netdata 46 | rm -rf roles/librelogic.librelogic.monitoring_utils 47 | rm -rf roles/librelogic.librelogic.docker 48 | rm -rf roles/librelogic.librelogic.docker_nginx 49 | rm -rf roles/librelogic.librelogic.gitlab 50 | rm -rf roles/librelogic.librelogic.proxmox 51 | rm -rf roles/librelogic.librelogic.mailcatcher 52 | rm -rf roles/librelogic.librelogic.apache 53 | rm -rf roles/librelogic.librelogic.php_fpm 54 | rm -rf roles/librelogic.librelogic.adminer 55 | rm -rf roles/librelogic.librelogic.gitlab_runner 56 | rm -rf roles/librelogic.librelogic.handlers 57 | -------------------------------------------------------------------------------- /roles/apache/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: import variable checks tasks 2 | ansible.builtin.import_tasks: checks.yml 3 | tags: 4 | - apache 5 | - checks 6 | 7 | - name: load distribution-specific variables 8 | include_vars: 9 | file: "{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_release }}.yml" 10 | tags: 11 | - apache 12 | - monitoring 13 | - rsyslog 14 | 15 | - name: import self-signed certificates configuration tasks 16 | ansible.builtin.import_tasks: ssl-selfsigned.yml 17 | become: yes 18 | tags: 19 | - apache 20 | - ssl 21 | - apache-reverseproxy 22 | 23 | - name: import apache configuration tasks 24 | ansible.builtin.import_tasks: apache.yml 25 | become: yes 26 | tags: 27 | - apache 28 | 29 | - name: import system mail configuration tasks 30 | ansible.builtin.import_tasks: mail.yml 31 | become: yes 32 | tags: 33 | - apache 34 | - mail 35 | 36 | - name: import fail2ban configuration tasks 37 | ansible.builtin.import_tasks: fail2ban.yml 38 | become: yes 39 | tags: 40 | - apache 41 | - fail2ban 42 | when: 43 | - ansible_local.fail2ban.ansible_managed is defined 44 | - ansible_local.fail2ban.ansible_managed | bool 45 | 46 | - name: import rsyslog configuration tasks 47 | ansible.builtin.import_tasks: rsyslog.yml 48 | become: yes 49 | tags: 50 | - apache 51 | - monitoring 52 | - rsyslog 53 | when: 54 | - ansible_local.rsyslog.ansible_managed is defined 55 | - ansible_local.rsyslog.ansible_managed | bool 56 | 57 | - name: import netdata configuration tasks 58 | ansible.builtin.import_tasks: netdata.yml 59 | become: yes 60 | tags: 61 | - apache 62 | - monitoring 63 | - netdata 64 | when: 65 | - ansible_local.netdata.ansible_managed is defined 66 | - ansible_local.netdata.ansible_managed | bool 67 | 68 | - name: import ansible facts configuration tasks 69 | ansible.builtin.import_tasks: fact.yml 70 | become: yes 71 | tags: apache 72 | 73 | - name: import firewalld configuration tasks 74 | ansible.builtin.import_tasks: firewalld.yml 75 | become: yes 76 | tags: 77 | - apache 78 | - firewall 79 | when: 80 | - ansible_local.firewalld.ansible_managed is defined 81 | - ansible_local.firewalld.ansible_managed | bool 82 | 83 | - name: apply configuration (flush handlers) 84 | ansible.builtin.meta: flush_handlers 85 | tags: 86 | - apache 87 | - monitoring 88 | - fail2ban 89 | -------------------------------------------------------------------------------- /roles/openldap/templates/var_www_self-service-password_conf_config.inc.local.php.j2: -------------------------------------------------------------------------------- 1 | &1 | logger -t apt-purge 36 | disabled: "{{ False if apt_purge_nightly else True }}" 37 | 38 | # update apt cache 39 | - name: apply configuration (flush handlers) 40 | meta: flush_handlers 41 | 42 | - name: install aptitude and unattended-upgrades 43 | apt: 44 | state: present 45 | package: 46 | - aptitude 47 | - unattended-upgrades 48 | - apt-listchanges 49 | 50 | ##### APT-LISTBUGS ##### 51 | 52 | - name: install apt-listbugs 53 | apt: 54 | state: present 55 | package: apt-listbugs 56 | when: apt_listbugs | bool 57 | tags: apt-listbugs 58 | 59 | - name: configure apt-listbugs 60 | template: 61 | src: "{{ item.src }}" 62 | dest: "{{ item.dest }}" 63 | owner: root 64 | group: root 65 | mode: "0644" 66 | with_items: 67 | - src: etc_apt_listbugs_ignore_bugs.j2 68 | dest: /etc/apt/listbugs/ignore_bugs 69 | - src: etc_apt_apt.conf.d_10apt-listbugs.j2 70 | dest: /etc/apt/apt.conf.d/10apt-listbugs 71 | when: apt_listbugs | bool 72 | tags: apt-listbugs 73 | 74 | - name: remove automatic APT pinnings added by apt-listbugs 75 | file: 76 | path: /etc/apt/preferences.d/apt-listbugs 77 | state: absent 78 | when: apt_listbugs | bool 79 | tags: apt-listbugs 80 | -------------------------------------------------------------------------------- /roles/monitoring_netdata/tasks/netdata-module-needrestart.yml: -------------------------------------------------------------------------------- 1 | ### NETDATA-NEEDRESTART ### 2 | 3 | - name: install needrestart 4 | apt: 5 | state: present 6 | package: needrestart 7 | 8 | - name: copy needrestart configuration 9 | template: 10 | src: 'etc_needrestart_conf.d_autorestart.conf.j2' 11 | dest: '/etc/needrestart/conf.d/autorestart.conf' 12 | mode: "0600" 13 | 14 | - name: clone netdata-needrestart module 15 | git: 16 | dest: "/root/netdata-needrestart" 17 | repo: "https://gitlab.com/nodiscc/netdata-needrestart" 18 | version: "1.0.3" 19 | accept_hostkey: yes 20 | force: yes # discard modified files 21 | ignore_errors: "{{ ansible_check_mode }}" 22 | 23 | - name: generate initial needrestart report 24 | command: needrestart -b > /var/log/needrestart.log 25 | args: 26 | creates: "/var/log/needrestart.log" 27 | 28 | - name: configure cron to refresh needrestart report 29 | cron: 30 | cron_file: "needrestart" 31 | month: "*" 32 | day: "*" 33 | hour: "*" # every hour 34 | minute: "0" 35 | job: /usr/sbin/needrestart -b > /var/log/needrestart.log 2>&1 36 | name: "needrestart" 37 | user: root 38 | 39 | - name: configure dpkg to refresh the file after each run 40 | copy: 41 | remote_src: yes 42 | src: "/root/netdata-needrestart/etc_apt_apt.conf.d_99needrestart" 43 | dest: "/etc/apt/apt.conf.d/99needrestart" 44 | mode: "0644" 45 | ignore_errors: "{{ ansible_check_mode }}" 46 | 47 | - name: install netdata-needrestart module/configuration/alarms 48 | copy: 49 | remote_src: yes 50 | src: "{{ item.src }}" 51 | dest: "{{ item.dest }}" 52 | owner: root 53 | group: netdata 54 | mode: "0640" 55 | with_items: 56 | - { src: '/root/netdata-needrestart/needrestart.chart.py', dest: '/usr/libexec/netdata/python.d/needrestart.chart.py' } 57 | - { src: '/root/netdata-needrestart/needrestart.conf', dest: '/etc/netdata/python.d/needrestart.conf' } 58 | - { src: '/root/netdata-needrestart/health.d_needrestart.conf', dest: '/etc/netdata/health.d/needrestart.conf' } 59 | notify: restart netdata 60 | ignore_errors: "{{ ansible_check_mode }}" 61 | 62 | - name: copy needrestart automatic reboot script 63 | copy: 64 | src: usr_local_bin_needrestart-autorestart 65 | dest: /usr/local/bin/needrestart-autorestart 66 | owner: root 67 | group: root 68 | mode: "0755" 69 | 70 | - name: setup needrestart cron job 71 | template: 72 | src: etc_cron.d_needrestart-autorestart.j2 73 | dest: /etc/cron.d/needrestart-autorestart 74 | owner: root 75 | group: root 76 | mode: "0644" 77 | --------------------------------------------------------------------------------