From 5e54313b2b24003c4b6b75f2b8d7b3b6df5e0f2c Mon Sep 17 00:00:00 2001 From: Andrea Dell'Amico Date: Mon, 23 Feb 2026 17:39:13 +0100 Subject: [PATCH] Big refactor that adds some tasks, and also move some existing tasks into the os-bootstrap role. --- .ansible-lint | 9 + README.md | 424 ++++++++++++++++- defaults/main.yml | 431 ++++++++++++------ files/99-disable-network-config.cfg | 1 + files/fail2ban-journal-sepol.te | 25 + files/letsencrypt_ca_files/isrg-root-x2.pem | 14 - files/letsencrypt_ca_files/isrgrootx1.pem | 31 -- .../letsencrypt_ca_files/lets-encrypt-e1.pem | 17 - .../letsencrypt_ca_files/lets-encrypt-e2.pem | 17 - .../letsencrypt_ca_files/lets-encrypt-r3.pem | 30 -- .../letsencrypt_ca_files/lets-encrypt-r4.pem | 30 -- handlers/main.yml | 31 +- meta/main.yml | 42 +- molecule/default/converge.yml | 52 +++ molecule/default/molecule.yml | 58 +++ molecule/default/verify.yml | 61 +++ tasks/additional_disks.yml | 45 -- tasks/ansible-python3-pkgs.yml | 22 - tasks/autofs.yml | 50 +- tasks/certificate_from_private_ca.yml | 75 --- tasks/cloud_init.yml | 37 ++ tasks/custom_bashrc.yml | 24 +- tasks/dell_utilities.yml | 43 ++ tasks/dell_utilities_deb.yml | 10 + tasks/dell_utilities_el.yml | 11 + tasks/etchosts-customizations.yml | 57 --- tasks/fail2ban.yml | 13 + tasks/fail2ban_deb.yml | 88 ++++ tasks/fail2ban_el.yml | 69 +++ tasks/ganesha-nfs.yml | 96 ++-- tasks/grub_cmdline_parameters.yml | 18 - tasks/hostname.yml | 24 - tasks/http_client_proxy.yml | 18 - tasks/locale.yml | 36 -- tasks/main.yml | 64 ++- tasks/motd.yml | 8 + tasks/motd_deb.yml | 37 ++ tasks/motd_el.yml | 10 + tasks/network-interfaces.yml | 53 --- tasks/nfs-kernel-server.yml | 79 ++-- tasks/pki_dir.yml | 20 - tasks/self_signed_certificate.yml | 46 -- tasks/sshd_config.yml | 13 + tasks/swap_device.yml | 22 - tasks/sysctl.yml | 53 --- tasks/timezone.yml | 21 - tasks/tmpreaper.yml | 56 ++- tasks/trusted_ca.yml | 120 ----- tasks/tuned_el.yml | 31 ++ templates/10-caching-proxy.sh.j2 | 5 - templates/10-java-caching-proxy.sh.j2 | 1 - templates/apache-ddos-filter.conf.j2 | 8 + templates/apache-ddos-jail.conf.j2 | 9 + templates/etc-timezone.j2 | 1 - templates/fail2ban.local.j2 | 3 + templates/grub_cmdline.cfg.j2 | 1 - templates/jail-d-customization.local.j2 | 28 ++ templates/jail.local.j2 | 254 +++++++++++ templates/motd.j2 | 2 + templates/netplan-70-ansible.yaml.j2 | 14 - templates/nginx-ddos-filter.conf.j2 | 8 + templates/nginx-ddos-jail.conf.j2 | 9 + templates/sshd_config.j2 | 216 +++++++++ templates/update_motd.j2 | 5 + tests/test.yml | 14 +- 65 files changed, 2081 insertions(+), 1139 deletions(-) create mode 100644 .ansible-lint create mode 100644 files/99-disable-network-config.cfg create mode 100644 files/fail2ban-journal-sepol.te delete mode 100644 files/letsencrypt_ca_files/isrg-root-x2.pem delete mode 100644 files/letsencrypt_ca_files/isrgrootx1.pem delete mode 100644 files/letsencrypt_ca_files/lets-encrypt-e1.pem delete mode 100644 files/letsencrypt_ca_files/lets-encrypt-e2.pem delete mode 100644 files/letsencrypt_ca_files/lets-encrypt-r3.pem delete mode 100644 files/letsencrypt_ca_files/lets-encrypt-r4.pem create mode 100644 molecule/default/converge.yml create mode 100644 molecule/default/molecule.yml create mode 100644 molecule/default/verify.yml delete mode 100644 tasks/additional_disks.yml delete mode 100644 tasks/ansible-python3-pkgs.yml delete mode 100644 tasks/certificate_from_private_ca.yml create mode 100644 tasks/cloud_init.yml create mode 100644 tasks/dell_utilities.yml create mode 100644 tasks/dell_utilities_deb.yml create mode 100644 tasks/dell_utilities_el.yml delete mode 100644 tasks/etchosts-customizations.yml create mode 100644 tasks/fail2ban.yml create mode 100644 tasks/fail2ban_deb.yml create mode 100644 tasks/fail2ban_el.yml delete mode 100644 tasks/grub_cmdline_parameters.yml delete mode 100644 tasks/hostname.yml delete mode 100644 tasks/http_client_proxy.yml delete mode 100644 tasks/locale.yml create mode 100644 tasks/motd.yml create mode 100644 tasks/motd_deb.yml create mode 100644 tasks/motd_el.yml delete mode 100644 tasks/network-interfaces.yml delete mode 100644 tasks/pki_dir.yml delete mode 100644 tasks/self_signed_certificate.yml create mode 100644 tasks/sshd_config.yml delete mode 100644 tasks/swap_device.yml delete mode 100644 tasks/sysctl.yml delete mode 100644 tasks/timezone.yml delete mode 100644 tasks/trusted_ca.yml create mode 100644 tasks/tuned_el.yml delete mode 100644 templates/10-caching-proxy.sh.j2 delete mode 100644 templates/10-java-caching-proxy.sh.j2 create mode 100644 templates/apache-ddos-filter.conf.j2 create mode 100644 templates/apache-ddos-jail.conf.j2 delete mode 100644 templates/etc-timezone.j2 create mode 100644 templates/fail2ban.local.j2 delete mode 100644 templates/grub_cmdline.cfg.j2 create mode 100644 templates/jail-d-customization.local.j2 create mode 100644 templates/jail.local.j2 create mode 100644 templates/motd.j2 delete mode 100644 templates/netplan-70-ansible.yaml.j2 create mode 100644 templates/nginx-ddos-filter.conf.j2 create mode 100644 templates/nginx-ddos-jail.conf.j2 create mode 100644 templates/sshd_config.j2 create mode 100644 templates/update_motd.j2 diff --git a/.ansible-lint b/.ansible-lint new file mode 100644 index 0000000..2da727a --- /dev/null +++ b/.ansible-lint @@ -0,0 +1,9 @@ +--- +enable_list: + - name[prefix] +skip_list: + - key-order +warn_list: + - experimental + - no-changed-when + - no-free-form diff --git a/README.md b/README.md index fc2e781..a3e5303 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,423 @@ -basic-system-setup -========= +# basic-system-setup -This role runs a set of tasks that perform some basic systems configurations +An Ansible role that configures Linux servers at the service layer: SSH hardening, intrusion prevention (Fail2ban), Message of the Day, cloud-init management, NFS serving, autofs, tmpreaper, and Dell server utilities. -Role Variables --------------- +Early-stage OS bootstrap tasks (locale, timezone, hostname, packages, sysctl, PKI, etc.) are handled by the [os-bootstrap](https://gitea-s2i2s.isti.cnr.it/ISTI-ansible-roles/ansible-role-os-bootstrap) dependency, which always runs first. -```yaml -See the `defaults/main.yml` file +## Requirements + +- Ansible >= 2.9 +- The `os-bootstrap` dependency role (declared in `meta/main.yml`, resolved automatically) + +### Ansible Collections Required + +```bash +ansible-galaxy collection install ansible.posix +ansible-galaxy collection install community.general ``` -License -------- +## Supported Platforms + +- Ubuntu 20.04 (Focal), 22.04 (Jammy), 24.04 (Noble) +- Debian 11 (Bullseye), 12 (Bookworm) +- RHEL / CentOS Stream / Rocky Linux / AlmaLinux 8, 9, 10 + +## Task Descriptions + +| Task File | Description | Condition | +| --------- | ----------- | --------- | +| `cloud_init.yml` | Disables cloud-init network config; optionally removes the package | always | +| `sshd_config.yml` | Deploys a hardened `/etc/ssh/sshd_config` from template | `sshd_install_config` | +| `motd.yml` | Configures the Message of the Day | `motd_setup` | +| `fail2ban.yml` | Installs and configures Fail2ban with SSH, DDoS, and recidive jails | `fail2ban_enabled` | +| `dell_utilities.yml` | Installs Dell DSU, srvadmin, and syscfg on bare-metal Dell servers | Dell hardware + bare metal | +| `tuned_el.yml` | Applies a tuned profile on EL/RedHat | RedHat family only | +| `autofs.yml` | Manages autofs configuration and NFS/CIFS mount maps | `autofs_client_mountpoint` | +| `tmpreaper.yml` | Installs and configures tmpreaper for `/tmp` cleanup | always | +| `ganesha-nfs.yml` | Installs and configures NFS Ganesha user-space NFS server | `nfs_server_ganesha_enabled` | +| `nfs-kernel-server.yml` | Installs and configures the kernel NFS server | `nfs_server_enabled` and not Ganesha | +| `custom_bashrc.yml` | Deploys custom `.bashrc` and shell history settings | always | + +## Role Variables + +### Cloud-init + +```yaml +cloud_init_disable_netconfig: false # write 99-disable-network-config.cfg +cloud_init_remove_pkg: true # remove cloud-init after first boot +``` + +### SSHD Configuration + +```yaml +sshd_install_config: true +sshd_port: 22 +sshd_config_dir: /etc/ssh +sshd_config_file: sshd_config + +# Authentication +sshd_password_authentication: "no" +sshd_permit_empty_passwords: "no" +sshd_permit_root_login: prohibit-password # "no", "yes", "prohibit-password" +sshd_pubkey_authentication: "yes" +sshd_strict_mode: "yes" +sshd_max_auth_tries: 6 +sshd_max_sessions: 10 +sshd_login_grace_time: 120 + +# PAM +sshd_use_pam: "yes" +sshd_pam_service_name: "" # OpenSSH 9.8+ only + +# Keyboard-interactive (OTP/s-key only) +sshd_kbd_interactive_authentication: "no" + +# Tunneling / forwarding +sshd_permit_tunnel: "no" +sshd_x11_forwarding: "no" +sshd_agent_forwarding: "yes" +sshd_tcp_forwarding: "no" +sshd_permit_user_environment: "no" +sshd_gateway_ports: "no" + +# GSSAPI +sshd_gssapi_authentication: "no" +sshd_gssapi_cleanup_credentials: "yes" + +# Logging +sshd_syslog_facility: AUTH +sshd_log_level: INFO + +# Connection keepalive / rate limiting +sshd_tcp_keep_alive: "yes" +sshd_client_alive_interval: 0 +sshd_client_alive_count_max: 3 +sshd_max_startups: 10:30:100 # start:rate:full + +# Display +sshd_print_motd: "no" +sshd_print_last_log: "yes" +sshd_banner_path: none # e.g. /etc/issue.net + +# Host keys (override only for custom paths) +sshd_host_keys: + - /etc/ssh/ssh_host_rsa_key + - /etc/ssh/ssh_host_ecdsa_key + - /etc/ssh/ssh_host_ed25519_key + +# Ciphers / MACs / KEX — leave empty to use distribution defaults +sshd_ciphers: "" +sshd_macs: "" +sshd_kex_algorithms: "" +sshd_host_key_algorithms: "" + +# Version-specific options (included only when the distribution's OpenSSH supports them) +sshd_include_config_d: true # Include sshd_config.d/*.conf (OpenSSH 8.2+) +sshd_per_source_max_startups: "" # Max connections per source IP (OpenSSH 8.5+) +sshd_per_source_net_block_size: "" # CIDR grouping for source IPs (OpenSSH 8.5+) +sshd_required_rsa_size: "" # Min RSA key size in bits (OpenSSH 9.1+) +sshd_channel_timeout: "" # e.g. "session:*=30m" (OpenSSH 9.2+) +sshd_unused_connection_timeout: "" # Close idle connections (OpenSSH 9.2+) +sshd_per_source_penalties: "" # Penalty-based rate limiting (OpenSSH 9.8+) +sshd_per_source_penalty_exempt_list: "" + +# SFTP +sshd_enable_sftp_subsystem: true +sshd_enable_sftp_jail: false +sshd_sftp_chroot_match_group: filetransfer +sshd_sftp_chroot_directory: "%h" +sshd_sftp_force_command: internal-sftp + +# Additional Match blocks +sshd_match_blocks: [] +# Example: +# sshd_match_blocks: +# - criteria: "User admin" +# options: +# - PasswordAuthentication: "yes" +# - AllowTcpForwarding: "yes" +``` + +OpenSSH version reference: + +| Distribution | OpenSSH version | +| ------------ | --------------- | +| Ubuntu 20.04 (Focal) | 8.2 | +| Ubuntu 22.04 (Jammy) | 8.9 | +| Ubuntu 24.04 (Noble) | 9.6 | +| Debian 11 (Bullseye) | 8.4 | +| Debian 12 (Bookworm) | 9.2 | +| EL 8 | 8.0 | +| EL 9 | 8.7 | +| EL 10 | 9.8 | + +### Fail2ban — Debian/Ubuntu + +```yaml +fail2ban_enabled: true +f2b_ban_time: 86400 # seconds; 86400 = 1 day +f2b_findtime: 600 +f2b_maxretry: 5 +f2b_ddos_findtime: 120 +f2b_ddos_maxretry: 200 +f2b_default_backend: auto +f2b_usedns: warn +f2b_dest_email: sysadmin@{{ domain_name }} +f2b_sender_email: sysadmin@{{ domain_name }} +f2b_default_banaction: iptables-multiport +f2b_default_action: action_ # ban only, no email +f2b_default_iptableschain: INPUT + +# Jail toggles +f2b_ssh_enabled: true +f2b_ssh_ddos_enabled: true +f2b_apache_ddos_enabled: false +f2b_apache_auth_enabled: false +f2b_apache_noscript_enabled: false +f2b_apache_overflow_enabled: false +f2b_php_url_fopen: false +f2b_nginx_auth_enabled: false +f2b_nginx_ddos_enabled: false +f2b_vsftpd_enabled: false +f2b_vsftpd_logpath: /var/log/vsftpd.log +f2b_recidive_enabled: true +f2b_recidive_findtime: 604800 # 1 week +f2b_recidive_ban_time: 14515200 # 24 weeks +``` + +### Fail2ban — EL/RedHat + +```yaml +fail2ban_logtarget: SYSLOG +fail2ban_bantime: 600000 +fail2ban_findtime: 4800 +fail2ban_maxretry: 2 +fail2ban_sshd_enabled: true +fail2ban_sshd_ddos_enabled: true +fail2ban_nginx_auth_enabled: false +fail2ban_apache_auth_enabled: false +fail2ban_php_url_fopen_enabled: false +fail2ban_vsftpd_enabled: false +``` + +### MOTD + +```yaml +motd_setup: true +motd_additional_text: "\nThis host runs services\n" + +# Debian/Ubuntu packages installed for dynamic MOTD +deb_motd_packages: + - update-notifier-common + - landscape-common +``` + +### Autofs + +```yaml +autofs_client_mountpoint: false # set to true to manage autofs +autofs_maps: [] +# - map_name: 'data' +# mountpoint_prefix: '/' +# path: 'data' +# nfs_server: 'nfs.example.com' +# remote_export: '/export' +# is_home: false +# force_ownership: false +# owner_uid: 1000 +# owner_gid: 1000 +# permissions: "0750" +``` + +### Tmpreaper + +```yaml +tmpreaper_install: false +tmpreaper_time: 7d +tmpreaper_dirs: /tmp/. +tmpreaper_use_ctime: true +tmpreaper_protect_extra: "" +tmpreaper_extra_dirs: "" +tmpreaper_delay: "256" +tmpreaper_additional_options: "" +``` + +### NFS Kernel Server + +```yaml +nfs_server_enabled: false +nfs_server_exports: [] +# - name: export_filename +# id: 1 +# path: /export +# options: 'rw,sync,fsid=1,root_squash,no_wdelay' +# clients: +# - host1 +# - hostN +``` + +### NFS Ganesha Server + +```yaml +nfs_server_ganesha_enabled: false # mirrors nfs_server_enabled by default +nfs_server_ganesha_server_protocols: "4" +nfs_server_ganesha_path_pseudo: false +nfs_server_ganesha_mdcache: false +nfs_server_ganesha_mdcache_hwmark: 100000 +nfs_server_ganesha_exports: [] +# - name: export_filename +# id: 1 +# path: /export +# pseudo: /nfs_export +# access_type: 'RW' # optional, default RW +# protocols: '4' # optional +# squash: 'root_squash' # optional +# disable_acl: 'false' # optional +# sectype: 'sys' # optional +# nfs_commit: 'false' # optional +# delegations: 'none' # optional +# fsal: 'VFS' +# clients: +# - host1 +``` + +### Tuned (EL/RedHat only) + +```yaml +centos_tuned_enabled: true +centos_tuned_profile: "{{ centos_guest_tuned_profile }}" +centos_guest_tuned_profile: virtual-guest +centos_host_tuned_profile: virtual-host +``` + +### Dell Server Utilities + +Runs automatically on bare-metal Dell servers (`'Dell' in ansible_system_vendor` and `ansible_virtualization_role == 'host'`). No variables to set for basic operation. + +```yaml +dell_utilities_installer_url: http://linux.dell.com/repo/hardware/dsu/bootstrap.cgi +dell_utilities_base_dir: /opt/dell_dsu +dell_utilities_packages: + - dell-system-update + - srvadmin-all + - syscfg +dell_utilities_raid_packages: + - raidcfg +``` + +### Custom Bash Configuration + +```yaml +bash_customize_skel_bashrc: false # deploy custom /etc/skel/.bashrc +bash_customize_root_bashrc: false # deploy custom /root/.bashrc +bash_customize_root_history_settings: false # deploy extended history settings for root +bash_custom_history_directory: /var/log/users_root_history +``` + +## Dependencies + +This role declares the following dependencies in `meta/main.yml`. They are resolved automatically when the role is installed. + +| Role | Required | Condition | Purpose | +| ---- | -------- | --------- | ------- | +| **os-bootstrap** | yes | always | Early-stage OS setup (locale, timezone, hostname, packages, sysctl, PKI, etc.) | +| rsyslog | yes | always | Centralized logging | +| linux-firewall | yes | always | Firewall management | +| ntp | yes | always | Time synchronization | +| letsencrypt-acme-sh-client | no | `letsencrypt_acme_install: true` | TLS certificate provisioning | +| zabbix-agent | no | `zabbix_agent_install: true` | Monitoring agent | +| prometheus-node-exporter | no | `prometheus_enabled: true` | Metrics exporter | + +## Example Playbook + +### Minimal + +```yaml +--- +- hosts: servers + become: true + roles: + - role: basic-system-setup +``` + +### SSH hardening + Fail2ban with nginx protection + +```yaml +--- +- hosts: webservers + become: true + roles: + - role: basic-system-setup + vars: + sshd_permit_root_login: "no" + sshd_password_authentication: "no" + fail2ban_enabled: true + f2b_nginx_ddos_enabled: true + f2b_nginx_auth_enabled: true + motd_additional_text: "\nWeb Server - Production\n" +``` + +### NFS kernel server + +```yaml +--- +- hosts: nfs_servers + become: true + roles: + - role: basic-system-setup + vars: + nfs_server_enabled: true + nfs_server_ganesha_enabled: false + nfs_server_exports: + - name: data_export + id: 1 + path: /srv/nfs/data + options: 'rw,sync,no_subtree_check,root_squash' + clients: + - 10.0.0.0/8 +``` + +### Autofs NFS mounts + +```yaml +--- +- hosts: clients + become: true + roles: + - role: basic-system-setup + vars: + autofs_client_mountpoint: true + autofs_maps: + - map_name: data + mountpoint_prefix: / + path: data + nfs_server: nfs.example.com + remote_export: /export/data + is_home: false +``` + +## Testing + +```bash +source ~/ansible/ansible6/bin/activate +ansible-lint +``` + +Molecule tests are available under `molecule/default/` and target Ubuntu 22.04 (Jammy) and Rocky Linux 9. + +```bash +molecule test # full cycle +molecule converge # apply only +molecule verify # idempotency / verification +molecule destroy # teardown +``` + +## License EUPL-1.2 -Author Information ------------------- +## Author Information Andrea Dell'Amico + +ISTI-CNR, Pisa, Italy diff --git a/defaults/main.yml b/defaults/main.yml index eb334ef..3a044be 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1,42 +1,4 @@ --- -# timezone -timezone: 'Europe/Rome' -default_locale_lang: "en_US.UTF-8" -default_deb_locale_messages: "C.UTF-8" -default_el_locale_messages: "en_US.UTF-8" -locales_list: - - {name: '{{ default_locale_lang }}'} - - {name: 'en_US.UTF-8'} - - {name: 'en_US'} - - {name: 'it_IT.UTF-8'} - - {name: 'it_IT'} - -domain_name: '{{ ansible_domain }}' - -configure_grub_cmdline_parameters: false -grub_cmdline_additional_parameters: "" -sysctl_custom_file: /etc/sysctl.d/90-custom-values.conf -sysctl_opts_reload: yes -sysctl_custom_file_state: present -explicitly_set_hostname: true -custom_etc_hosts_entries: "" -custom_etc_hosts_entries_adjunct: "" - -# Only name and value are mandatory. The others have defaults -sysctl_custom_options: [] -# - name: 'net.nf_conntrack_max' -# value: '32768' -# sysctlfile: '{{ sysctl_custom_file }}' -# sysctl_reload: '{{ sysctl_opts_reload }}' -# sysctlfile_state: '{{ sysctl_custom_file_state }}' - -ubuntu_configure_additional_interfaces: false -ubuntu_configure_additional_int_dhcp_overrides: true -ubuntu_configure_additional_ints_list: [] -disable_ipv6: false -ipv6_sysctl_value: 1 -ipv6_sysctl_file: /etc/sysctl.d/10-ipv6-disable.conf - # Bash prompt and shell history settings # bash_customize_skel_bashrc: false @@ -48,35 +10,21 @@ bash_root_bashrc_file: /root/.bashrc bash_customize_root_history_settings: false bash_custom_history_directory: /var/log/users_root_history bash_custom_history_settings_file: files/root_bashrc_history.sh -# -# Define the following variables to manage additional disks and mount points, even static nfs ones -additional_disks: false -disks_and_mountpoints_list: [] -# - { mountpoint: '/data', device: 'xvda3', fstype: 'xfs', opts: 'noatime', state: 'mounted', create_filesystem: True } - -swap_device: false -swap_device_name: /dev/vdxxxxx - -ansible_python3_debs: - - python3-lxml - -ansible_python3_el: - - python3-lxml idmap_verbosity: 0 idmap_conf_options: - - { section: 'General', option: 'Domain', value: '{{ domain_name }}', state: 'present' } - - { section: 'General', option: 'Verbosity', value: '{{ idmap_verbosity }}', state: 'present' } + - { section: General, option: Domain, value: "{{ domain_name }}", state: present } + - { section: General, option: Verbosity, value: "{{ idmap_verbosity }}", state: present } # autofs mount points autofs_client_mountpoint: false autofs_conf_options: - - { section: 'autofs', option: 'master_map_name', value: '/etc/auto.master', state: 'present' } - - { section: 'autofs', option: 'timeout', value: '300', state: 'present' } - - { section: 'autofs', option: 'negative_timeout', value: '60', state: 'present' } - - { section: 'autofs', option: 'mount_nfs_default_protocol', value: '4', state: 'present' } - - { section: 'autofs', option: 'logging', value: 'none', state: 'present' } - - { section: 'amd', option: 'dismount_interval', value: '300', state: 'present' } + - { section: autofs, option: master_map_name, value: /etc/auto.master, state: present } + - { section: autofs, option: timeout, value: "300", state: present } + - { section: autofs, option: negative_timeout, value: "60", state: present } + - { section: autofs, option: mount_nfs_default_protocol, value: "4", state: present } + - { section: autofs, option: logging, value: none, state: present } + - { section: amd, option: dismount_interval, value: "300", state: present } autofs_packages_deb: - autofs @@ -86,19 +34,19 @@ autofs_packages_el: # path: without the initial / autofs_maps: [] - # - map_name: 'data' - # mountpoint_prefix: '/' - # path: 'data' - # nfs_server: 'nfs.example.com' - # remote_export: '/export' - # is_home: false - # force_ownership: false - # owner_uid: 1000 - # owner_gid: 1000 - # permissions: "0750" +# - map_name: 'data' +# mountpoint_prefix: '/' +# path: 'data' +# nfs_server: 'nfs.example.com' +# remote_export: '/export' +# is_home: false +# force_ownership: false +# owner_uid: 1000 +# owner_gid: 1000 +# permissions: "0750" nfs_server_enabled: false -nfs_server_ganesha_enabled: '{{ nfs_server_enabled }}' +nfs_server_ganesha_enabled: "{{ nfs_server_enabled }}" nfs_server_kernel_el_pkgs: - nfs-utils @@ -135,14 +83,14 @@ nfs_server_ganesha_el_pkgs: - librados2 nfs_server_ganesha_deb_pkgs: - - 'nfs-ganesha' - - 'nfs-ganesha-vfs' - - 'nfs-ganesha-xfs' + - nfs-ganesha + - nfs-ganesha-vfs + - nfs-ganesha-xfs -#Protocols = 3,4,9P; -nfs_server_ganesha_server_protocols: '4' -nfs_server_ganesha_path_pseudo: False -nfs_server_ganesha_mdcache: False +# Protocols = 3,4,9P; +nfs_server_ganesha_server_protocols: "4" +nfs_server_ganesha_path_pseudo: false +nfs_server_ganesha_mdcache: false nfs_server_ganesha_mdcache_hwmark: 100000 nfs_server_ganesha_exports: [] # name, id, path, pseudo_path, access_type (RW, RO), protocols (global), squash (true,false), disable_actl (true,false), sectype, fsal (VFS, XFS), clients @@ -166,81 +114,266 @@ nfs_server_ganesha_exports: [] # tmpreaper tmpreaper_install: false tmpreaper_use_ctime: true -tmpreaper_protect_extra: '' -tmpreaper_dirs: '/tmp/.' -tmpreaper_extra_dirs: '' -tmpreaper_delay: '256' -tmpreaper_additional_options: '' -tmpreaper_time: '7d' +tmpreaper_protect_extra: "" +tmpreaper_dirs: /tmp/. +tmpreaper_extra_dirs: "" +tmpreaper_delay: "256" +tmpreaper_additional_options: "" +tmpreaper_time: 7d # -enable_env_proxy: False -env_proxy_http_host: 'localhost' -env_proxy_http_port: '3128' -env_proxy_http_protocol: 'http' -env_proxy_https_protocol: '{{ env_proxy_http_protocol }}' -env_proxy_http_url: '{{ env_proxy_http_protocol }}://{{ env_proxy_http_host }}:{{ env_proxy_http_port }}' -env_proxy_https_url: '{{ env_proxy_http_url }}' -env_proxy_protocols: - - 'http_proxy' - - 'https_proxy' - - 'ftp_proxy' - - 'HTTP_PROXY' - - 'HTTPS_PROXY' - - 'FTP_PROXY' -env_proxy_use_authentication: False -env_proxy_username: '' -env_proxy_password: '' -no_proxy_targets: - - '::1' - - '127.0.0.1' - - 'localhost' +# SSHD Configuration +# +# OpenSSH versions by distribution: +# Ubuntu 20.04 (Focal): 8.2 | Ubuntu 22.04 (Jammy): 8.9 | Ubuntu 24.04 (Noble): 9.6 +# Debian 11 (Bullseye): 8.4 | Debian 12 (Bookworm): 9.2 +# EL 8: 8.0 | EL 9: 8.7 | EL 10: 9.8 +# +sshd_install_config: true +sshd_port: 22 +sshd_config_dir: /etc/ssh +sshd_config_file: sshd_config -# A generic PKI directory where the local certificates will be stored -pki_dir: /etc/pki -pki_subdirs: - - certs - - keys -pki_install_a_custom_ca: false -self_signed_cert: "{{ pki_dir }}/selfsigned/cert" -self_signed_fullchain: "{{ pki_dir }}/selfsigned/fullchain" -self_signed_key: "{{ pki_dir }}/selfsigned/privkey" -self_signed_subject: "/CN={{ ansible_fqdn }} self signed" +# Basic authentication settings +sshd_password_authentication: "no" +sshd_permit_empty_passwords: "no" +# "no", "yes", "prohibit-password", or "without-password" (legacy alias for prohibit-password) +sshd_permit_root_login: prohibit-password +sshd_strict_mode: "yes" +sshd_pubkey_authentication: "yes" +sshd_max_auth_tries: 6 +sshd_max_sessions: 10 -mkcert_create_certificate: false -mkcert_cert_name: "{{ ansible_fqdn }}.pem" -mkcert_cert_dest_path: "{{ pki_dir }}/certs" -mkcert_cert_file_path: "{{ mkcert_cert_dest_path }}/{{ mkcert_cert_name }}" -mkcert_key_name: "{{ ansible_fqdn }}-key.pem" -mkcert_key_dest_path: "{{ pki_dir }}/keys" -mkcert_key_file_path: "{{ mkcert_key_dest_path }}/{{ mkcert_key_name }}" -mkcert_dsn_and_ip_list: "{{ ansible_fqdn }} {% for ip in ansible_all_ipv4_addresses %}{{ ip }} {% endfor %}" -mkcert_ca_host: localhost +# Login timing +sshd_login_grace_time: 120 -trusted_ca_el_anchors_path: '/etc/pki/ca-trust/source/anchors' -trusted_ca_deb_path: '/usr/local/share/ca-certificates' -# it shoudn't be needed -trusted_ca_letsencrypt_install: false -trusted_ca_letsencrypt_ca_certificates_url: https://letsencrypt.org/certs -trusted_ca_letsencrypt_ca_files: - - { ca_src: 'isrgrootx1.pem', ca: 'isrgrootx1.crt', name: 'isrg-root-x1' } - - { ca_src: 'isrg-root-x2.pem', ca: 'isrg-root-x2.crt', name: 'isrg-root-x2-not-cross' } - - { ca_src: '2024/e5.pem', ca: 'lets-encrypt-e5.crt', name: 'lets-encrypt-e5' } - - { ca_src: '2024/e6.pem', ca: 'lets-encrypt-e6.crt', name: 'lets-encrypt-e6' } - - { ca_src: '2024/r10.pem', ca: 'lets-encrypt-r10.crt', name: 'lets-encrypt-r10-not-cross' } - - { ca_src: '2024/r11.pem', ca: 'lets-encrypt-r11.crt', name: 'lets-encrypt-r11-not-cross' } - - { ca_src: '2024/e7.pem', ca: 'lets-encrypt-e7.crt', name: 'lets-encrypt-e7' } - - { ca_src: '2024/e7-cross.pem', ca: 'lets-encrypt-e7-cross.crt', name: 'lets-encrypt-e7-cross' } - - { ca_src: '2024/e8.pem', ca: 'lets-encrypt-e8.crt', name: 'lets-encrypt-e8' } - - { ca_src: '2024/e8-cross.pem', ca: 'lets-encrypt-e8-cross.crt', name: 'lets-encrypt-e8-cross' } - - { ca_src: '2024/r12.pem', ca: 'lets-encrypt-r12.crt', name: 'lets-encrypt-r12-not-cross' } - - { ca_src: '2024/r13.pem', ca: 'lets-encrypt-r13.crt', name: 'lets-encrypt-r13-not-cross' } +# PAM settings +# If set to no, the locked users cannot log in. adduser creates users without password as locked +sshd_use_pam: "yes" +# PAM service name (OpenSSH 9.8+, Portable OpenSSH only) +# Allows selecting PAM service name at runtime. Defaults to "sshd" if not set. +sshd_pam_service_name: "" -expired_ca_letsencrypt_ca_files: - - isrg-root-x2-cross-signed.pem - - lets-encrypt-r3-cross-signed.pem - - lets-encrypt-x3-cross-signed.pem - - letsencryptauthorityx3.pem +# Keyboard-interactive authentication (formerly ChallengeResponseAuthentication) +# Use "yes" only if you are using s/key, OTP, or similar +# Note: ChallengeResponseAuthentication was renamed to KbdInteractiveAuthentication in OpenSSH 8.7 +sshd_kbd_interactive_authentication: "no" -trusted_ca_additional_ca_files: [] -# - { ca_url: 'https://example.com/foo-ca.pem', ca: 'foo-ca.pem', name: 'foo-ca' } +# Tunneling and forwarding +sshd_permit_tunnel: "no" +sshd_x11_forwarding: "no" +sshd_x11_display_offset: 10 +sshd_agent_forwarding: "yes" +sshd_tcp_forwarding: "no" +sshd_permit_user_environment: "no" +sshd_gateway_ports: "no" + +# GSSAPI options +sshd_gssapi_authentication: "no" +sshd_gssapi_cleanup_credentials: "yes" + +# Logging +sshd_syslog_facility: AUTH +sshd_log_level: INFO + +# Connection settings +sshd_tcp_keep_alive: "yes" +sshd_client_alive_interval: 0 +sshd_client_alive_count_max: 3 +# MaxStartups: start:rate:full - connections refused above 'full', rate% dropped between start and full +sshd_max_startups: 10:30:100 + +# Display settings +sshd_print_motd: "no" +sshd_print_last_log: "yes" +# Usually /etc/issue.net, or "none" to disable +sshd_banner_path: none + +# Environment +sshd_acceptenv: LANG LC_* + +# Host-based authentication (generally disabled for security) +sshd_hostbased_authentication: "no" +sshd_ignore_rhosts: "yes" +sshd_ignore_user_known_hosts: "no" + +# DNS (set to "no" for faster connections when DNS is slow) +sshd_use_dns: "no" + +# +# Version-specific options (OpenSSH 8.2+) +# These are only included when supported by the distribution's OpenSSH version +# + +# Include additional configuration files (OpenSSH 8.2+) +# Set to true to include /etc/ssh/sshd_config.d/*.conf +sshd_include_config_d: true + +# Per-source rate limiting (OpenSSH 8.5+) +# Maximum unauthenticated connections per source IP +sshd_per_source_max_startups: "" +# CIDR block size for grouping source IPs (IPv4, e.g., 24 for /24) +sshd_per_source_net_block_size: "" + +# +# Version-specific options (OpenSSH 9.x+) +# + +# Minimum RSA key size in bits (OpenSSH 9.1+) +# Recommended: 2048 or 3072 for better security +sshd_required_rsa_size: "" + +# Channel timeout (OpenSSH 9.2+) +# Close channels after inactivity, e.g., "session:*=30m" or "x11-connection=5m" +sshd_channel_timeout: "" + +# Unused connection timeout (OpenSSH 9.2+) +# Close connections with no open channels after this time +sshd_unused_connection_timeout: "" + +# Penalty-based rate limiting (OpenSSH 9.8+) +# Configures penalty thresholds and durations for connection rate limiting +# Format: "crash:N refuseconnection:N noauth:N grace-exceeded:N max:M min:S" +sshd_per_source_penalties: "" +# List of addresses/networks exempt from penalties, e.g., "192.168.1.0/24,10.0.0.0/8" +sshd_per_source_penalty_exempt_list: "" + +# +# Host keys - automatically configured based on distribution +# Override these only if you have custom key paths +# +sshd_host_keys: + - /etc/ssh/ssh_host_rsa_key + - /etc/ssh/ssh_host_ecdsa_key + - /etc/ssh/ssh_host_ed25519_key + +# +# Ciphers, MACs, and Key Exchange algorithms +# Leave empty to use distribution defaults (recommended) +# Only set these if you need to restrict to specific algorithms +# +sshd_ciphers: "" +sshd_macs: "" +sshd_kex_algorithms: "" +sshd_host_key_algorithms: "" + +# +# SFTP configuration +# +sshd_enable_sftp_subsystem: true +sshd_enable_sftp_jail: false +sshd_sftp_chroot_match_group: filetransfer +sshd_sftp_chroot_directory: "%h" +sshd_sftp_force_command: internal-sftp + +# +# Additional Match blocks (advanced) +# List of match blocks, each with: criteria, and options (list of key: value) +# +sshd_match_blocks: [] +# Example: +# sshd_match_blocks: +# - criteria: "User admin" +# options: +# - PasswordAuthentication: "yes" +# - AllowTcpForwarding: "yes" +# - criteria: "Address 10.0.0.0/8" +# options: +# - PermitRootLogin: "yes" + +# +# Fail2ban Configuration (Debian/Ubuntu) +# +fail2ban_enabled: true +# ban time in seconds. 86400 == 1 day +f2b_ban_time: 86400 +f2b_findtime: 600 +f2b_maxretry: 5 +f2b_ddos_findtime: 120 +f2b_ddos_maxretry: 200 +f2b_default_backend: auto +f2b_usedns: warn +f2b_dest_email: sysadmin@{{ domain_name }} +f2b_sender_email: sysadmin@{{ domain_name }} +f2b_default_banaction: iptables-multiport +# Default action: ban. Not send email +f2b_default_action: action_ +f2b_default_iptableschain: INPUT +f2b_ssh_enabled: true +f2b_ssh_ddos_enabled: true +f2b_apache_ddos_enabled: false +f2b_apache_auth_enabled: false +f2b_apache_noscript_enabled: false +f2b_apache_overflow_enabled: false +f2b_php_url_fopen: false +f2b_nginx_auth_enabled: false +f2b_nginx_ddos_enabled: false +f2b_vsftpd_enabled: false +f2b_vsftpd_logpath: /var/log/vsftpd.log +f2b_recidive_enabled: true +# 604800: one week +f2b_recidive_findtime: 604800 +# 14515200: 24 weeks +f2b_recidive_ban_time: 14515200 + +f2b_packages_deb: + - fail2ban + - iptables + +# +# Fail2ban Configuration (EL/RedHat) +# +fail2ban_logtarget: SYSLOG +fail2ban_bantime: 600000 +fail2ban_findtime: 4800 +fail2ban_maxretry: 2 +fail2ban_sshd_enabled: true +fail2ban_sshd_ddos_enabled: true +fail2ban_nginx_auth_enabled: false +fail2ban_apache_auth_enabled: false +fail2ban_php_url_fopen_enabled: false +fail2ban_vsftpd_enabled: false + +f2b_packages_el: + - fail2ban + - fail2ban-server + - fail2ban-systemd + - fail2ban-firewalld + - fail2ban-sendmail + +# +# MOTD Configuration +# +motd_setup: true +motd_additional_text: "\nThis host runs services\n" + +deb_motd_packages: + - update-notifier-common + - landscape-common + +# +# Cloud-init Configuration +# +cloud_init_disable_netconfig: false +cloud_init_remove_pkg: true + +# +# Dell Server Utilities +# +dell_utilities_installer_url: http://linux.dell.com/repo/hardware/dsu/bootstrap.cgi +dell_utilities_base_dir: /opt/dell_dsu +dell_utilities_packages: + - dell-system-update + - srvadmin-all + - syscfg + +dell_utilities_raid_packages: + - raidcfg + +# +# Tuned Setup (EL) +# +centos_tuned_enabled: true +centos_host_tuned_profile: virtual-host +centos_guest_tuned_profile: virtual-guest +centos_tuned_profile: "{{ centos_guest_tuned_profile }}" diff --git a/files/99-disable-network-config.cfg b/files/99-disable-network-config.cfg new file mode 100644 index 0000000..f144451 --- /dev/null +++ b/files/99-disable-network-config.cfg @@ -0,0 +1 @@ +network: {config: disabled} diff --git a/files/fail2ban-journal-sepol.te b/files/fail2ban-journal-sepol.te new file mode 100644 index 0000000..b71ae3d --- /dev/null +++ b/files/fail2ban-journal-sepol.te @@ -0,0 +1,25 @@ + +module fail2ban-journal-sepol 1.0; + +require { + type fail2ban_client_exec_t; + type logrotate_t; + type fail2ban_t; + type var_run_t; + type syslogd_t; + type syslogd_var_run_t; + class dir read; + class file { ioctl read execute execute_no_trans open getattr }; +} + +#============= fail2ban_t ============== + +allow fail2ban_t var_run_t:file { read getattr open }; +allow fail2ban_t syslogd_var_run_t:dir read; +allow fail2ban_t syslogd_var_run_t:file { read getattr open }; + +#============= syslogd_t ============== +allow syslogd_t var_run_t:file { read getattr open }; + +#============= logrotate_t ============== +allow logrotate_t fail2ban_client_exec_t:file { ioctl read execute execute_no_trans open }; diff --git a/files/letsencrypt_ca_files/isrg-root-x2.pem b/files/letsencrypt_ca_files/isrg-root-x2.pem deleted file mode 100644 index 7d903ed..0000000 --- a/files/letsencrypt_ca_files/isrg-root-x2.pem +++ /dev/null @@ -1,14 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw -CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg -R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00 -MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT -ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw -EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW -+1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9 -ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T -AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI -zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW -tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1 -/q4AaOeMSQ+2b1tbFfLn ------END CERTIFICATE----- diff --git a/files/letsencrypt_ca_files/isrgrootx1.pem b/files/letsencrypt_ca_files/isrgrootx1.pem deleted file mode 100644 index b85c803..0000000 --- a/files/letsencrypt_ca_files/isrgrootx1.pem +++ /dev/null @@ -1,31 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw -TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh -cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 -WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu -ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY -MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc -h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ -0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U -A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW -T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH -B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC -B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv -KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn -OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn -jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw -qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI -rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq -hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL -ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ -3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK -NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 -ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur -TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC -jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc -oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq -4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA -mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d -emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= ------END CERTIFICATE----- diff --git a/files/letsencrypt_ca_files/lets-encrypt-e1.pem b/files/letsencrypt_ca_files/lets-encrypt-e1.pem deleted file mode 100644 index 2a19d41..0000000 --- a/files/letsencrypt_ca_files/lets-encrypt-e1.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICxjCCAk2gAwIBAgIRALO93/inhFu86QOgQTWzSkUwCgYIKoZIzj0EAwMwTzEL -MAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2VhcmNo -IEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDIwHhcNMjAwOTA0MDAwMDAwWhcN -MjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3MgRW5j -cnlwdDELMAkGA1UEAxMCRTEwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQkXC2iKv0c -S6Zdl3MnMayyoGli72XoprDwrEuf/xwLcA/TmC9N/A8AmzfwdAVXMpcuBe8qQyWj -+240JxP2T35p0wKZXuskR5LBJJvmsSGPwSSB/GjMH2m6WPUZIvd0xhajggEIMIIB -BDAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMB -MBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFFrz7Sv8NsI3eblSMOpUb89V -yy6sMB8GA1UdIwQYMBaAFHxClq7eS0g7+pL4nozPbYupcjeVMDIGCCsGAQUFBwEB -BCYwJDAiBggrBgEFBQcwAoYWaHR0cDovL3gyLmkubGVuY3Iub3JnLzAnBgNVHR8E -IDAeMBygGqAYhhZodHRwOi8veDIuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYG -Z4EMAQIBMA0GCysGAQQBgt8TAQEBMAoGCCqGSM49BAMDA2cAMGQCMHt01VITjWH+ -Dbo/AwCd89eYhNlXLr3pD5xcSAQh8suzYHKOl9YST8pE9kLJ03uGqQIwWrGxtO3q -YJkgsTgDyj2gJrjubi1K9sZmHzOa25JK1fUpE8ZwYii6I4zPPS/Lgul/ ------END CERTIFICATE----- diff --git a/files/letsencrypt_ca_files/lets-encrypt-e2.pem b/files/letsencrypt_ca_files/lets-encrypt-e2.pem deleted file mode 100644 index 0fd9f40..0000000 --- a/files/letsencrypt_ca_files/lets-encrypt-e2.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICxjCCAkygAwIBAgIQTtI99q9+x/mwxHJv+VEqdzAKBggqhkjOPQQDAzBPMQsw -CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg -R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw0y -NTA5MTUxNjAwMDBaMDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNy -eXB0MQswCQYDVQQDEwJFMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABCOaLO3lixmN -YVWex+ZVYOiTLgi0SgNWtU4hufk50VU4Zp/LbBVDxCsnsI7vuf4xp4Cu+ETNggGE -yBqJ3j8iUwe5Yt/qfSrRf1/D5R58duaJ+IvLRXeASRqEL+VkDXrW3qOCAQgwggEE -MA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEw -EgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUbZkq9U0C6+MRwWC6km+NPS7x -6kQwHwYDVR0jBBgwFoAUfEKWrt5LSDv6kviejM9ti6lyN5UwMgYIKwYBBQUHAQEE -JjAkMCIGCCsGAQUFBzAChhZodHRwOi8veDIuaS5sZW5jci5vcmcvMCcGA1UdHwQg -MB4wHKAaoBiGFmh0dHA6Ly94Mi5jLmxlbmNyLm9yZy8wIgYDVR0gBBswGTAIBgZn -gQwBAgEwDQYLKwYBBAGC3xMBAQEwCgYIKoZIzj0EAwMDaAAwZQIxAPJCN9qpyDmZ -tX8K3m8UYQvK51BrXclM6WfrdeZlUBKyhTXUmFAtJw4X6A0x9mQFPAIwJa/No+KQ -UAM1u34E36neL/Zba7ombkIOchSgx1iVxzqtFWGddgoG+tppRPWhuhhn ------END CERTIFICATE----- diff --git a/files/letsencrypt_ca_files/lets-encrypt-r3.pem b/files/letsencrypt_ca_files/lets-encrypt-r3.pem deleted file mode 100644 index 43b222a..0000000 --- a/files/letsencrypt_ca_files/lets-encrypt-r3.pem +++ /dev/null @@ -1,30 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw -TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh -cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw -WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg -RW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cP -R5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdx -sxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8Zutm -NHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxg -Z3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG -/kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC -AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB -Af8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaA -FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw -AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw -Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB -gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6W -PTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wl -ikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQz -CkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BIm -lJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4 -avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2 -yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1O -yK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90Ids -hCExroL1+7mryIkXPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+ -HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6Zv -MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX -nLRbwHOoq7hHwg== ------END CERTIFICATE----- diff --git a/files/letsencrypt_ca_files/lets-encrypt-r4.pem b/files/letsencrypt_ca_files/lets-encrypt-r4.pem deleted file mode 100644 index 578b3bd..0000000 --- a/files/letsencrypt_ca_files/lets-encrypt-r4.pem +++ /dev/null @@ -1,30 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFFjCCAv6gAwIBAgIRAIp5IlCr5SxSbO7Pf8lC3WIwDQYJKoZIhvcNAQELBQAw -TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh -cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw -WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg -RW5jcnlwdDELMAkGA1UEAxMCUjQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQCzKNx3KdPnkb7ztwoAx/vyVQslImNTNq/pCCDfDa8oPs3Gq1e2naQlGaXS -Mm1Jpgi5xy+hm5PFIEBrhDEgoo4wYCVg79kaiT8faXGy2uo/c0HEkG9m/X2eWNh3 -z81ZdUTJoQp7nz8bDjpmb7Z1z4vLr53AcMX/0oIKr13N4uichZSk5gA16H5OOYHH -IYlgd+odlvKLg3tHxG0ywFJ+Ix5FtXHuo+8XwgOpk4nd9Z/buvHa4H6Xh3GBHhqC -VuQ+fBiiCOUWX6j6qOBIUU0YFKAMo+W2yrO1VRJrcsdafzuM+efZ0Y4STTMzAyrx -E+FCPMIuWWAubeAHRzNl39Jnyk2FAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC -AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB -Af8CAQAwHQYDVR0OBBYEFDadPuCxQPYnLHy/jZ0xivZUpkYmMB8GA1UdIwQYMBaA -FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw -AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw -Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB -gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCJbu5CalWO+H+Az0lmIG14DXmlYHQE -k26umjuCyioWs2icOlZznPTcZvbfq02YPHGTCu3ctggVDULJ+fwOxKekzIqeyLNk -p8dyFwSAr23DYBIVeXDpxHhShvv0MLJzqqDFBTHYe1X5X2Y7oogy+UDJxV2N24/g -Z8lxG4Vr2/VEfUOrw4Tosl5Z+1uzOdvTyBcxD/E5rGgTLczmulctHy3IMTmdTFr0 -FnU0/HMQoquWQuODhFqzMqNcsdbjANUBwOEQrKI8Sy6+b84kHP7PtO+S4Ik8R2k7 -ZeMlE1JmxBi/PZU860YlwT8/qOYToCHVyDjhv8qutbf2QnUl3SV86th2I1QQE14s -0y7CdAHcHkw3sAEeYGkwCA74MO+VFtnYbf9B2JBOhyyWb5087rGzitu5MTAW41X9 -DwTeXEg+a24tAeht+Y1MionHUwa4j7FB/trN3Fnb/r90+4P66ZETVIEcjseUSMHO -w6yqv10/H/dw/8r2EDUincBBX3o9DL3SadqragkKy96HtMiLcqMMGAPm0gti1b6f -bnvOdr0mrIVIKX5nzOeGZORaYLoSD4C8qvFT7U+Um6DMo36cVDNsPmkF575/s3C2 -CxGiCPQqVxPgfNSh+2CPd2Xv04lNeuw6gG89DlOhHuoFKRlmPnom+gwqhz3ZXMfz -TfmvjrBokzCICA== ------END CERTIFICATE----- diff --git a/handlers/main.yml b/handlers/main.yml index 705bddb..1077af3 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -1,9 +1,32 @@ --- -- name: Netplan Apply - ansible.builtin.command: - cmd: netplan apply - - name: Restart autofs ansible.builtin.service: name: autofs state: restarted + +- name: Reload the ssh service + ansible.builtin.service: + name: "{{ 'ssh' if ansible_distribution_file_variety == 'Debian' else 'sshd' }}" + state: reloaded + +- name: Restart fail2ban + ansible.builtin.service: + name: fail2ban + state: restarted + +- name: Reload fail2ban + ansible.builtin.service: + name: fail2ban + state: reloaded + +- name: Enable and start fail2ban + ansible.builtin.service: + name: fail2ban + state: started + enabled: true + +- name: Enable and start firewalld + ansible.builtin.service: + name: firewalld + state: started + enabled: true diff --git a/meta/main.yml b/meta/main.yml index c635cc1..98e62e7 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -1,6 +1,7 @@ +--- galaxy_info: author: Andrea Dell'Amico - description: Perform some low level system configuration + description: Consolidated role for basic system setup including SSH, fail2ban, MOTD, cloud-init, and distribution-specific configuration company: ISTI-CNR namespace: adellam role_name: basic_system_setup @@ -12,15 +13,48 @@ galaxy_info: platforms: - name: Ubuntu versions: - - bionic - focal - jammy + - noble + - name: Debian + versions: + - bullseye + - bookworm - name: EL versions: - - "7" - "8" - "9" + - "10" galaxy_tags: - os-setup - + - bootstrap + - ssh + - fail2ban + - selinux + +dependencies: + - src: git+https://gitea-s2i2s.isti.cnr.it/ISTI-ansible-roles/ansible-role-os-bootstrap.git + version: master + name: os-bootstrap + - src: git+https://gitea-s2i2s.isti.cnr.it/ISTI-ansible-roles/ansible-role-rsyslog.git + version: master + name: rsyslog + - src: git+https://gitea-s2i2s.isti.cnr.it/ISTI-ansible-roles/ansible-role-linux-firewall.git + version: master + name: linux-firewall + - src: git+https://code-repo.d4science.org/InfraScience/ansible-role-ntp.git + version: master + name: ntp + - src: git+https://gitea-s2i2s.isti.cnr.it/ISTI-ansible-roles/ansible-role-letsencrypt-acme-sh-client.git + version: master + name: letsencrypt-acme-sh-client + when: letsencrypt_acme_install is defined and letsencrypt_acme_install + - src: git+https://gitea-s2i2s.isti.cnr.it/ISTI-ansible-roles/ansible-role-zabbix-agent.git + version: master + name: zabbix-agent + when: zabbix_agent_install is defined and zabbix_agent_install + - src: git+https://gitea-s2i2s.isti.cnr.it/ISTI-ansible-roles/ansible-role-prometheus-node-exporter.git + version: master + name: prometheus-node-exporter + when: prometheus_enabled is defined and prometheus_enabled diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml new file mode 100644 index 0000000..94d315e --- /dev/null +++ b/molecule/default/converge.yml @@ -0,0 +1,52 @@ +--- +- name: Converge + hosts: all + become: true + vars: + # Core settings + timezone: Europe/Rome + explicitly_set_hostname: true + + # SSHD settings + sshd_install_config: true + sshd_permit_root_login: without-password + sshd_password_authentication: "no" + + # Fail2ban settings - disabled for testing (requires systemd) + fail2ban_enabled: false + + # MOTD settings + motd_setup: true + motd_additional_text: "\nTest host managed by Ansible\n" + + # Cloud-init settings + cloud_init_disable_netconfig: false + cloud_init_remove_pkg: false + + # Skip dependencies for testing + centos_install_epel: true + + # Disable services that may not work in containers + disable_some_not_needed_services: false + disable_apport_service: false + + # Package cleanup + cleanup_base_packages: false + cleanup_exim_email_server: false + ubuntu_remove_lxd: false + + pre_tasks: + - name: Update apt cache on Debian + ansible.builtin.apt: + update_cache: true + cache_valid_time: 3600 + when: ansible_os_family == 'Debian' + + - name: Install EPEL on EL + ansible.builtin.dnf: + name: epel-release + state: present + when: ansible_os_family == 'RedHat' + + roles: + - role: basic-system-setup diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml new file mode 100644 index 0000000..e741050 --- /dev/null +++ b/molecule/default/molecule.yml @@ -0,0 +1,58 @@ +--- +dependency: + name: galaxy + options: + ignore-errors: true +driver: + name: docker +platforms: + - name: ubuntu-jammy + image: geerlingguy/docker-ubuntu2204-ansible + pre_build_image: true + privileged: true + command: /lib/systemd/systemd + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + tmpfs: + - /run + - /tmp + - name: rocky-9 + image: geerlingguy/docker-rockylinux9-ansible + pre_build_image: true + privileged: true + command: /lib/systemd/systemd + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + tmpfs: + - /run + - /tmp +# EL 10 - uncomment when stable images are available +# - name: almalinux-10 +# image: almalinux:10 +# pre_build_image: false +# privileged: true +# command: /lib/systemd/systemd +# volumes: +# - /sys/fs/cgroup:/sys/fs/cgroup:rw +# cgroupns_mode: host +# tmpfs: +# - /run +# - /tmp +provisioner: + name: ansible + config_options: + defaults: + interpreter_python: auto_silent + inventory: + host_vars: + ubuntu-jammy: + ansible_python_interpreter: /usr/bin/python3 + rocky-9: + ansible_python_interpreter: /usr/bin/python3 +verifier: + name: ansible +lint: | + set -e + ansible-lint diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml new file mode 100644 index 0000000..b0b4a3e --- /dev/null +++ b/molecule/default/verify.yml @@ -0,0 +1,61 @@ +--- +- name: Verify + hosts: all + become: true + gather_facts: true + tasks: + - name: Verify timezone is set correctly + ansible.builtin.command: timedatectl show --property=Timezone --value + register: timezone_result + changed_when: false + failed_when: "'Europe/Rome' not in timezone_result.stdout" + + - name: Verify SSH config exists + ansible.builtin.stat: + path: /etc/ssh/sshd_config + register: sshd_config + failed_when: not sshd_config.stat.exists + + - name: Verify SSH config contains expected settings + ansible.builtin.command: grep -E "^PermitRootLogin\s+without-password" /etc/ssh/sshd_config + register: sshd_root_login + changed_when: false + failed_when: sshd_root_login.rc != 0 + + - name: Verify MOTD file exists on Debian + ansible.builtin.stat: + path: /etc/static-motd + register: motd_file + when: ansible_os_family == 'Debian' + failed_when: not motd_file.stat.exists + + - name: Verify MOTD file exists on EL + ansible.builtin.stat: + path: /etc/motd + register: motd_file_el + when: ansible_os_family == 'RedHat' + failed_when: not motd_file_el.stat.exists + + - name: Verify common packages are installed on Debian + ansible.builtin.command: dpkg -l htop + register: htop_deb + changed_when: false + failed_when: htop_deb.rc != 0 + when: ansible_os_family == 'Debian' + + - name: Verify common packages are installed on EL + ansible.builtin.command: rpm -q htop + register: htop_el + changed_when: false + failed_when: htop_el.rc != 0 + when: ansible_os_family == 'RedHat' + + - name: Verify PKI directory exists + ansible.builtin.stat: + path: /etc/pki + register: pki_dir + failed_when: not pki_dir.stat.exists + + - name: Print verification summary + ansible.builtin.debug: + msg: All verification tests passed successfully! diff --git a/tasks/additional_disks.yml b/tasks/additional_disks.yml deleted file mode 100644 index e2373da..0000000 --- a/tasks/additional_disks.yml +++ /dev/null @@ -1,45 +0,0 @@ ---- -- block: - - name: Install the NFS client utilities when we are going to mount a NFS file system - ansible.builtin.apt: - pkg: nfs-common - state: present - update_cache: true - cache_valid_time: 1800 - loop: '{{ disks_and_mountpoints_list }}' - when: item.fstype == 'nfs' - - - name: Install the NFS 4 acl tools if we are going to mount a NFS file system - ansible.builtin.apt: - pkg: nfs4-acl-tools - state: present - update_cache: true - cache_valid_time: 1800 - loop: '{{ disks_and_mountpoints_list }}' - when: item.fstype == 'nfs' - - when: ansible_distribution_file_variety == "Debian" - tags: [ 'data_disk', 'mountpoint' ] - -- block: - - name: Create a file system on the new disks - ansible.builtin.filesystem: - dev: "{{ item.root_device | default('/dev/') }}{{ item.device }}" - fstype: '{{ item.fstype }}' - force: false - loop: '{{ disks_and_mountpoints_list }}' - when: - - additional_disks - - item.create_filesystem - - item.fstype != 'nfs' - - - name: Manage the additional file systems - mount: - name: '{{ item.mountpoint }}' - src: "{% if item.uuid is not defined %}{{ item.root_device | default('/dev/') }}{{ item.device }}{% else %}UUID={{ item.uuid }}{% endif %}" - fstype: '{{ item.fstype }}' - opts: '{{ item.opts }}' - state: '{{ item.state }}' - loop: '{{ disks_and_mountpoints_list }}' - - tags: [ 'data_disk', 'mountpoint' ] diff --git a/tasks/ansible-python3-pkgs.yml b/tasks/ansible-python3-pkgs.yml deleted file mode 100644 index 2c9fa86..0000000 --- a/tasks/ansible-python3-pkgs.yml +++ /dev/null @@ -1,22 +0,0 @@ ---- -- name: Install some python3 packages on deb distributsions - block: - - name: Install some python3 packages on Ubuntu/Debian - apt: - pkg: '{{ ansible_python3_debs }}' - state: present - cache_valid_time: 1800 - - when: ansible_distribution_file_variety == "Debian" - tags: ['python', 'python3'] - -- name: Install some python3 packages on EL - block: - - name: Install some python3 packages on EL - yum: - pkg: '{{ ansible_python3_el }}' - state: present - - when: ansible_distribution_file_variety == "RedHat" - tags: ['python', 'python3'] - diff --git a/tasks/autofs.yml b/tasks/autofs.yml index 4e94cfd..bcb5caa 100644 --- a/tasks/autofs.yml +++ b/tasks/autofs.yml @@ -1,7 +1,7 @@ --- - name: autofs | Install and configure autofs on Ubuntu/Debian when: ansible_distribution_file_variety == "Debian" - tags: ['nfs', 'autofs'] + tags: [nfs, autofs] block: - name: autofs | Install the autofs packages on Ubuntu/Debian ansible.builtin.apt: @@ -11,7 +11,7 @@ - name: autofs | Install and configure autofs on EL when: ansible_distribution_file_variety == "RedHat" - tags: ['nfs', 'autofs'] + tags: [nfs, autofs] block: - name: autofs | Install the autofs packages on EL ansible.builtin.yum: @@ -19,7 +19,7 @@ state: present - name: autofs | Stop autofs if it is a 'hard' reconfiguration - tags: ['nfs', 'autofs', 'autofs_conf'] + tags: [nfs, autofs, autofs_conf] block: - name: autofs | Stop autofs ansible.builtin.service: @@ -28,7 +28,7 @@ when: autofs_hard_reconfig is defined and autofs_hard_reconfig - name: autofs | Configure autofs and its maps - tags: ['nfs', 'autofs', 'autofs_conf'] + tags: [nfs, autofs, autofs_conf] block: - name: autofs | Create the mount points ansible.builtin.file: @@ -37,33 +37,33 @@ owner: root group: root mode: "0755" - loop: '{{ autofs_maps }}' + loop: "{{ autofs_maps }}" - name: autofs | Setup idmap.conf community.general.ini_file: path: /etc/idmapd.conf - section: '{{ item.section }}' - option: '{{ item.option }}' - value: '{{ item.value }}' - state: '{{ item.state }}' - owner: 'root' - group: 'root' - mode: '0644' + section: "{{ item.section }}" + option: "{{ item.option }}" + value: "{{ item.value }}" + state: "{{ item.state }}" + owner: root + group: root + mode: "0644" create: false - loop: '{{ idmap_conf_options }}' + loop: "{{ idmap_conf_options }}" - name: autofs | Setup autofs.conf community.general.ini_file: path: /etc/autofs.conf - section: '{{ item.section }}' - option: '{{ item.option }}' - value: '{{ item.value }}' - state: '{{ item.state }}' - owner: 'root' - group: 'root' - mode: '0644' + section: "{{ item.section }}" + option: "{{ item.option }}" + value: "{{ item.value }}" + state: "{{ item.state }}" + owner: root + group: root + mode: "0644" create: false - loop: '{{ autofs_conf_options }}' + loop: "{{ autofs_conf_options }}" - name: autofs | Install the autofs master configuration ansible.builtin.template: @@ -77,11 +77,11 @@ - name: autofs | Install the autofs map files ansible.builtin.template: src: auto.data.j2 - dest: "/etc/auto.{{ item.map_name }}" + dest: /etc/auto.{{ item.map_name }} owner: root group: root mode: "0644" - loop: '{{ autofs_maps }}' + loop: "{{ autofs_maps }}" notify: Restart autofs - name: autofs | Ensure that autofs is enabled and running @@ -92,7 +92,7 @@ - name: autofs | Force a restart of autofs after a configuration change ansible.builtin.meta: flush_handlers - tags: ['nfs', 'autofs', 'autofs_conf'] + tags: [nfs, autofs, autofs_conf] - name: autofs | Force the ownership of the mount point ansible.builtin.file: @@ -103,4 +103,4 @@ mode: "{{ item.permissions }}" loop: "{{ autofs_maps }}" when: item.force_ownership is defined and item.force_ownership - tags: ['nfs', 'autofs', 'autofs_conf'] + tags: [nfs, autofs, autofs_conf] diff --git a/tasks/certificate_from_private_ca.yml b/tasks/certificate_from_private_ca.yml deleted file mode 100644 index 7201ad0..0000000 --- a/tasks/certificate_from_private_ca.yml +++ /dev/null @@ -1,75 +0,0 @@ ---- -- name: certificate_from_private_ca | Create the certificate using the private CA - tags: [pki, tls, tls_certificate] - block: - - name: certificate_from_private_ca | Set the common group between mkcert-ca and ansible - ansible.builtin.set_fact: - ansible_common_remote_group: ansible - - - name: certificate_from_private_ca | Remove the already existing certificates from the CA archive (delegate to the CA server) - ansible.builtin.file: - path: "/srv/mkcert-ca/{{ item }}" - state: absent - loop: - - "{{ mkcert_cert_name }}" - - "{{ mkcert_key_name }}" - - "client-{{ mkcert_cert_name }}" - - "client-{{ mkcert_key_name }}" - delegate_to: "{{ mkcert_ca_host }}" - - - name: certificate_from_private_ca | Create the certificate (delegate to the CA server) - ansible.builtin.command: - cmd: mkcert -cert-file /srv/mkcert-ca/{{ mkcert_cert_name }} -key-file /srv/mkcert-ca/{{ mkcert_key_name }} {{ mkcert_dsn_and_ip_list }} - args: - chdir: /srv/mkcert-ca - creates: "/srv/mkcert-ca/{{ mkcert_cert_name }}" - environment: - CAROOT: /srv/mkcert-ca/.local/share/mkcert - delegate_to: "{{ mkcert_ca_host }}" - - - name: certificate_from_private_ca | Create a certificate able to do client authentication (delegate to the CA server) - ansible.builtin.command: - cmd: mkcert -client -cert-file /srv/mkcert-ca/client-{{ mkcert_cert_name }} -key-file /srv/mkcert-ca/client-{{ mkcert_key_name }} {{ mkcert_dsn_and_ip_list }} # yamllint disable-line rule:line-length - args: - chdir: /srv/mkcert-ca - creates: "/srv/mkcert-ca/client-{{ mkcert_cert_name }}" - environment: - CAROOT: /srv/mkcert-ca/.local/share/mkcert - delegate_to: "{{ mkcert_ca_host }}" - -- name: certificate_from_private_ca | Manage the certificate installation - tags: [pki, tls, tls_certificate] - block: - - name: certificate_from_private_ca | Get the certificate and its key from the CA server - ansible.builtin.fetch: - src: "/srv/mkcert-ca/{{ item }}" - dest: "files/" - flat: true - loop: - - "{{ mkcert_cert_name }}" - - "{{ mkcert_key_name }}" - - "client-{{ mkcert_cert_name }}" - - "client-{{ mkcert_key_name }}" - delegate_to: "{{ mkcert_ca_host }}" - - - name: certificate_from_private_ca | Copy the certificate to the destination server - ansible.builtin.copy: - src: "files/{{ item }}" - dest: "{{ mkcert_cert_dest_path }}" - owner: root - group: root - mode: "0444" - loop: - - "{{ mkcert_cert_name }}" - - "client-{{ mkcert_cert_name }}" - - - name: certificate_from_private_ca | Copy the certificate to the destination server - ansible.builtin.copy: - src: "files/{{ item }}" - dest: "{{ mkcert_key_dest_path }}" - owner: root - group: root - mode: "0440" - loop: - - "{{ mkcert_key_name }}" - - "client-{{ mkcert_key_name }}" diff --git a/tasks/cloud_init.yml b/tasks/cloud_init.yml new file mode 100644 index 0000000..0c5dc32 --- /dev/null +++ b/tasks/cloud_init.yml @@ -0,0 +1,37 @@ +--- +- name: cloud_init | Disable cloud-init network configuration + ansible.builtin.copy: + src: 99-disable-network-config.cfg + dest: /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg + owner: root + group: root + mode: "0644" + when: cloud_init_disable_netconfig + tags: + - ovirt_cloud_init_net + - ovirt + - cloud_init + +- name: cloud_init | Remove the cloud-init package on Debian based systems + ansible.builtin.apt: + pkg: cloud-init + state: absent + when: + - cloud_init_remove_pkg + - ansible_distribution_file_variety == 'Debian' + tags: + - ovirt_cloud_init + - ovirt + - cloud_init + +- name: cloud_init | Remove the cloud-init package on EL/CentOS + ansible.builtin.dnf: + pkg: cloud-init + state: absent + when: + - cloud_init_remove_pkg + - ansible_distribution_file_variety == 'RedHat' + tags: + - ovirt_cloud_init + - ovirt + - cloud_init diff --git a/tasks/custom_bashrc.yml b/tasks/custom_bashrc.yml index 2c51faa..1798ea2 100644 --- a/tasks/custom_bashrc.yml +++ b/tasks/custom_bashrc.yml @@ -8,8 +8,8 @@ - name: custom_bashrc | Manage the skel bashrc customizations ansible.builtin.blockinfile: path: "{{ bash_etc_skel_file }}" - marker_begin: 'bashrc_customizations_start' - marker_end: 'bashrc_customizations_end' + marker_begin: bashrc_customizations_start + marker_end: bashrc_customizations_end marker: "# {mark} Customization to bashrc installed via ansible" block: "{{ item }}" state: present @@ -25,8 +25,8 @@ - name: custom_bashrc | Remove the skel bashrc customizations ansible.builtin.blockinfile: path: "{{ bash_etc_skel_file }}" - marker_begin: 'bashrc_customizations_start' - marker_end: 'bashrc_customizations_end' + marker_begin: bashrc_customizations_start + marker_end: bashrc_customizations_end marker: "# {mark} Customization to bashrc installed via ansible" block: "{{ item }}" state: absent @@ -42,8 +42,8 @@ - name: custom_bashrc | Manage the root user bashrc customization ansible.builtin.blockinfile: path: "{{ bash_root_bashrc_file }}" - marker_begin: 'bashrc_customizations_start' - marker_end: 'bashrc_customizations_end' + marker_begin: bashrc_customizations_start + marker_end: bashrc_customizations_end marker: "# {mark} Customization to bashrc installed via ansible" block: "{{ item }}" state: present @@ -59,8 +59,8 @@ - name: custom_bashrc | Remove the root user bashrc customization ansible.builtin.blockinfile: path: "{{ bash_root_bashrc_file }}" - marker_begin: 'bashrc_customizations_start' - marker_end: 'bashrc_customizations_end' + marker_begin: bashrc_customizations_start + marker_end: bashrc_customizations_end marker: "# {mark} Customization to bashrc installed via ansible" block: "{{ item }}" state: absent @@ -83,8 +83,8 @@ - name: custom_bashrc | Manage the root user bashrc history settings ansible.builtin.blockinfile: path: "{{ bash_root_bashrc_file }}" - marker_begin: 'history_customizations_start' - marker_end: 'history_customizations_end' + marker_begin: history_customizations_start + marker_end: history_customizations_end marker: "# {mark} Customization to the bash prompt installed via ansible" block: "{{ item }}" state: present @@ -100,8 +100,8 @@ - name: custom_bashrc | Remove the root user bashrc history settings ansible.builtin.blockinfile: path: "{{ bash_root_bashrc_file }}" - marker_begin: 'history_customizations_start' - marker_end: 'history_customizations_end' + marker_begin: history_customizations_start + marker_end: history_customizations_end marker: "# {mark} Customization to the bash prompt installed via ansible" block: "{{ item }}" state: absent diff --git a/tasks/dell_utilities.yml b/tasks/dell_utilities.yml new file mode 100644 index 0000000..f50dab3 --- /dev/null +++ b/tasks/dell_utilities.yml @@ -0,0 +1,43 @@ +--- +- name: dell_utilities | Create the Dell utilities directory + ansible.builtin.file: + dest: "{{ dell_utilities_base_dir }}" + state: directory + mode: "0755" + when: + - "'Dell' in ansible_system_vendor" + - ansible_virtualization_role == "host" + tags: + - dell_utilities + - dell_dsu + +- name: dell_utilities | Download the Dell utility installer + ansible.builtin.get_url: + url: "{{ dell_utilities_installer_url }}" + dest: "{{ dell_utilities_base_dir }}/dsu_installer" + mode: "0700" + when: + - "'Dell' in ansible_system_vendor" + - ansible_virtualization_role == "host" + tags: + - dell_utilities + - dell_dsu + +- name: dell_utilities | Run the installer + ansible.builtin.command: "{{ dell_utilities_base_dir }}/dsu_installer" + args: + creates: /etc/yum.repos.d/dell-system-update.repo + when: + - "'Dell' in ansible_system_vendor" + - ansible_virtualization_role == "host" + tags: + - dell_utilities + - dell_dsu + +- name: dell_utilities | Configure for EL/RedHat + ansible.builtin.import_tasks: dell_utilities_el.yml + when: ansible_distribution_file_variety == "RedHat" + +- name: dell_utilities | Configure for Debian + ansible.builtin.import_tasks: dell_utilities_deb.yml + when: ansible_distribution_file_variety == "Debian" diff --git a/tasks/dell_utilities_deb.yml b/tasks/dell_utilities_deb.yml new file mode 100644 index 0000000..53d0e75 --- /dev/null +++ b/tasks/dell_utilities_deb.yml @@ -0,0 +1,10 @@ +--- +- name: dell_utilities_deb | Dell utilities status + ansible.builtin.debug: + msg: No Dell utilities available for Debian or Ubuntu servers yet + when: + - "'Dell' in ansible_system_vendor" + - ansible_virtualization_role == "host" + tags: + - dell_utilities + - dell_dsu diff --git a/tasks/dell_utilities_el.yml b/tasks/dell_utilities_el.yml new file mode 100644 index 0000000..23beb7b --- /dev/null +++ b/tasks/dell_utilities_el.yml @@ -0,0 +1,11 @@ +--- +- name: dell_utilities_el | Install the EL/CentOS Dell utilities + ansible.builtin.dnf: + pkg: "{{ dell_utilities_packages }}" + state: present + when: + - "'Dell' in ansible_system_vendor" + - ansible_virtualization_role == "host" + tags: + - dell_utilities + - dell_dsu diff --git a/tasks/etchosts-customizations.yml b/tasks/etchosts-customizations.yml deleted file mode 100644 index a5cc30d..0000000 --- a/tasks/etchosts-customizations.yml +++ /dev/null @@ -1,57 +0,0 @@ ---- -- name: etchosts-customizations | Add entries to /etc/hosts - when: custom_etc_hosts_entries | length > 0 - tags: - - etchosts - block: - - name: etchosts-customizations | Add custom entries to /etc/hosts - ansible.builtin.blockinfile: - path: /etc/hosts - marker_begin: 'ansible_etchosts_customizations_start' - marker_end: 'ansible_etchosts_customizations_end' - marker: "# {mark} hosts entries managed by ansible" - block: "{{ custom_etc_hosts_entries }}" - state: present - -- name: etchosts-customizations | Remove entries from /etc/hosts - when: custom_etc_hosts_entries | length == 0 - tags: - - etchosts - block: - - name: etchosts-customizations | Remove custom entries from /etc/hosts - ansible.builtin.blockinfile: - path: /etc/hosts - marker_begin: 'ansible_etchosts_customizations_start' - marker_end: 'ansible_etchosts_customizations_end' - marker: "# {mark} hosts entries managed by ansible" - block: "{{ custom_etc_hosts_entries }}" - state: absent - -- name: etchosts-customizations | Additional custom entries to /etc/hosts - when: custom_etc_hosts_entries_adjunct | length > 0 - tags: - - etchosts - block: - - name: etchosts-customizations | Additional custom entries to /etc/hosts - ansible.builtin.blockinfile: - path: /etc/hosts - marker_begin: 'ansible_etchosts_adjunct_start' - marker_end: 'ansible_etchosts_adjunct_end' - marker: "# {mark} additional hosts entries managed by ansible" - block: "{{ custom_etc_hosts_entries_adjunct }}" - state: present - -- name: etchosts-customizations | Remove entries from /etc/hosts - when: custom_etc_hosts_entries_adjunct | length == 0 - tags: - - etchosts - block: - - name: etchosts-customizations | Remove the additional custom entries from /etc/hosts - ansible.builtin.blockinfile: - path: /etc/hosts - marker_begin: 'ansible_etchosts_adjunct_start' - marker_end: 'ansible_etchosts_adjunct_end' - marker: "# {mark} additional hosts entries managed by ansible" - block: "{{ custom_etc_hosts_entries_adjunct }}" - state: absent - diff --git a/tasks/fail2ban.yml b/tasks/fail2ban.yml new file mode 100644 index 0000000..c3b4103 --- /dev/null +++ b/tasks/fail2ban.yml @@ -0,0 +1,13 @@ +--- +- name: fail2ban | Configure fail2ban on Debian/Ubuntu + ansible.builtin.import_tasks: fail2ban_deb.yml + when: + - ansible_distribution_file_variety == "Debian" + - fail2ban_enabled + +- name: fail2ban | Configure fail2ban on EL/RedHat + ansible.builtin.import_tasks: fail2ban_el.yml + when: + - ansible_distribution_file_variety == "RedHat" + - fail2ban_enabled + - centos_install_epel diff --git a/tasks/fail2ban_deb.yml b/tasks/fail2ban_deb.yml new file mode 100644 index 0000000..54feaa4 --- /dev/null +++ b/tasks/fail2ban_deb.yml @@ -0,0 +1,88 @@ +--- +- name: fail2ban_deb | Install fail2ban packages + ansible.builtin.apt: + pkg: "{{ f2b_packages_deb }}" + state: present + cache_valid_time: 1800 + tags: + - fail2ban + +- name: fail2ban_deb | Ensure that fail2ban is enabled and running + ansible.builtin.service: + name: fail2ban + state: started + enabled: true + tags: + - fail2ban + +- name: fail2ban_deb | Install the fail2ban custom jail file + ansible.builtin.template: + src: jail.local.j2 + dest: /etc/fail2ban/jail.local + owner: root + group: root + mode: "0444" + notify: Restart fail2ban + tags: + - fail2ban + +- name: fail2ban_deb | Install the fail2ban apache ddos filter + ansible.builtin.template: + src: apache-ddos-filter.conf.j2 + dest: /etc/fail2ban/filter.d/apache-ddos-filter.conf + owner: root + group: root + mode: "0444" + when: f2b_apache_ddos_enabled + notify: Restart fail2ban + tags: + - fail2ban + - f2b_apache_ddos + +- name: fail2ban_deb | Install the fail2ban apache ddos rule + ansible.builtin.template: + src: apache-ddos-jail.conf.j2 + dest: /etc/fail2ban/jail.d/apache-ddos-jail.conf + owner: root + group: root + mode: "0444" + when: f2b_apache_ddos_enabled + notify: Restart fail2ban + tags: + - fail2ban + - f2b_apache_ddos + +- name: fail2ban_deb | Install the fail2ban nginx ddos filter + ansible.builtin.template: + src: nginx-ddos-filter.conf.j2 + dest: /etc/fail2ban/filter.d/nginx-ddos-filter.conf + owner: root + group: root + mode: "0444" + when: f2b_nginx_ddos_enabled + notify: Restart fail2ban + tags: + - fail2ban + - f2b_nginx_ddos + +- name: fail2ban_deb | Install the fail2ban nginx ddos rule + ansible.builtin.template: + src: nginx-ddos-jail.conf.j2 + dest: /etc/fail2ban/jail.d/nginx-ddos-jail.conf + owner: root + group: root + mode: "0444" + when: f2b_nginx_ddos_enabled + notify: Restart fail2ban + tags: + - fail2ban + - f2b_nginx_ddos + +- name: fail2ban_deb | Uninstall fail2ban when not enabled + ansible.builtin.apt: + pkg: fail2ban + state: absent + when: not fail2ban_enabled + tags: + - fail2ban + - uninstall_fail2ban diff --git a/tasks/fail2ban_el.yml b/tasks/fail2ban_el.yml new file mode 100644 index 0000000..4b0ac11 --- /dev/null +++ b/tasks/fail2ban_el.yml @@ -0,0 +1,69 @@ +--- +- name: fail2ban_el | Install fail2ban packages + ansible.builtin.dnf: + name: "{{ f2b_packages_el }}" + state: present + notify: + - Enable and start fail2ban + - Enable and start firewalld + tags: + - fail2ban + - centos + - rhel + +- name: fail2ban_el | Install fail2ban local config + ansible.builtin.template: + src: fail2ban.local.j2 + dest: /etc/fail2ban/fail2ban.local + owner: root + group: root + mode: "0444" + notify: Reload fail2ban + tags: + - fail2ban + +- name: fail2ban_el | Install fail2ban jail custom configuration + ansible.builtin.template: + src: jail-d-customization.local.j2 + dest: /etc/fail2ban/jail.d/customization.local + owner: root + group: root + mode: "0444" + notify: Reload fail2ban + tags: + - fail2ban + +- name: fail2ban_el | Install the selinux policy file for fail2ban + ansible.builtin.copy: + src: fail2ban-journal-sepol.te + dest: /usr/local/etc/fail2ban-journal-sepol.te + owner: root + group: root + mode: "0644" + register: fail2ban_selinux_policy + tags: + - fail2ban + - selinux + +- name: fail2ban_el | Activate the selinux policy for fail2ban + ansible.builtin.shell: > + checkmodule -M -m -o /usr/local/etc/fail2ban-journal-sepol.mod /usr/local/etc/fail2ban-journal-sepol.te && + semodule_package -o /usr/local/etc/fail2ban-journal-sepol.pp -m /usr/local/etc/fail2ban-journal-sepol.mod && + semodule -i /usr/local/etc/fail2ban-journal-sepol.pp + args: + creates: /usr/local/etc/fail2ban-journal-sepol.pp + when: fail2ban_selinux_policy is changed # noqa: no-handler + tags: + - fail2ban + - selinux + +- name: fail2ban_el | Ensure that fail2ban and firewalld are started and enabled + ansible.builtin.service: + name: "{{ item }}" + state: started + enabled: true + loop: + - fail2ban + - firewalld + tags: + - fail2ban diff --git a/tasks/ganesha-nfs.yml b/tasks/ganesha-nfs.yml index f65ec09..408851a 100644 --- a/tasks/ganesha-nfs.yml +++ b/tasks/ganesha-nfs.yml @@ -1,98 +1,104 @@ --- -- name: Create the export directory trees +- name: ganesha-nfs | Create the export directory trees block: - - name: Create the directory of the NFS exports + - name: ganesha-nfs | Create the directory of the NFS exports ansible.builtin.file: - dest: '{{ item.path }}' + dest: "{{ item.path }}" state: directory owner: root group: root - mode: 0755 - loop: '{{ nfs_server_ganesha_exports }}' + mode: "0755" + loop: "{{ nfs_server_ganesha_exports }}" - tags: ['san', 'nfs', 'storage', 'ganesha', 'ganesha_export'] + tags: [san, nfs, storage, ganesha, ganesha_export] -- name: Repositories and packages on EL +- name: ganesha-nfs | Repositories and packages on EL block: - - name: Install storage SIG repositories + - name: ganesha-nfs | Install storage SIG repositories ansible.builtin.yum: - name: '{{ nfs_server_ganesha_el_repos }}' + name: "{{ nfs_server_ganesha_el_repos }}" state: present - - name: Install the SAN NFS packages + - name: ganesha-nfs | Install the SAN NFS packages ansible.builtin.yum: - name: '{{ nfs_server_ganesha_el_pkgs }}' + name: "{{ nfs_server_ganesha_el_pkgs }}" state: present - - name: Install the files needed to produce a SELinux policy for ganesha + - name: ganesha-nfs | Install the files needed to produce a SELinux policy for ganesha ansible.builtin.copy: - src: '{{ item }}' - dest: '/usr/local/lib/{{ item }}' + src: "{{ item }}" + dest: /usr/local/lib/{{ item }} owner: root group: root - mode: 0600 + mode: "0600" loop: - ganesha_selinux.pp - ganesha_selinux.te register: ganesha_selinux_policy - - name: Generate the SELinux policy module + - name: ganesha-nfs | Generate the SELinux policy module ansible.builtin.shell: semodule -i /usr/local/lib/ganesha_selinux.pp && touch /usr/local/lib/.ganesha_selinux - when: ganesha_selinux_policy is changed + when: ganesha_selinux_policy is changed # noqa: no-handler + changed_when: true when: ansible_distribution_file_variety == "RedHat" - tags: ['san', 'nfs', 'storage', 'ganesha', 'ganesha_pkg'] + tags: [san, nfs, storage, ganesha, ganesha_pkg] -- name: Repositories and packages on Ubuntu/Debian +- name: ganesha-nfs | Repositories and packages on Ubuntu/Debian block: - - name: Install the nfs ganesha packages on deb systems - apt: - pkg: '{{ nfs_server_ganesha_deb_pkgs }}' + - name: ganesha-nfs | Install the nfs ganesha packages on deb systems + ansible.builtin.apt: + pkg: "{{ nfs_server_ganesha_deb_pkgs }}" state: present cache_valid_time: 1800 - - name: Ensure that the kernel NFS server package is not installed - apt: + - name: ganesha-nfs | Ensure that the kernel NFS server package is not installed + ansible.builtin.apt: pkg: nfs-kernel-server state: absent when: ansible_distribution_file_variety == "Debian" - tags: ['san', 'nfs', 'storage', 'ganesha', 'ganesha_pkg'] + tags: [san, nfs, storage, ganesha, ganesha_pkg] -- name: Install and configure ganesha exports using the VFS backend +- name: ganesha-nfs | Install and configure ganesha exports using the VFS backend block: - - name: Install the ganesha configuration files - template: - src: '{{ item }}.j2' - dest: '/etc/ganesha/{{ item }}' + - name: ganesha-nfs | Install the ganesha configuration files + ansible.builtin.template: + src: "{{ item }}.j2" + dest: /etc/ganesha/{{ item }} owner: root group: root - mode: 0644 - loop: '{{ nfs_ganesha_conf_files }}' + mode: "0644" + loop: "{{ nfs_ganesha_conf_files }}" register: ganesha_conf_files - - name: Install the ganesha export files - template: + - name: ganesha-nfs | Install the ganesha export files + ansible.builtin.template: src: ganesha-export.conf.j2 - dest: '/etc/ganesha/{{ item.name }}.conf' + dest: /etc/ganesha/{{ item.name }}.conf owner: root group: root - mode: 0644 - loop: '{{ nfs_server_ganesha_exports }}' + mode: "0644" + loop: "{{ nfs_server_ganesha_exports }}" register: ganesha_conf_files - - name: Ensure that the Kernel NFS service is stopped on EL - service: + - name: ganesha-nfs | Ensure that the Kernel NFS service is stopped on EL + ansible.builtin.service: name: nfs-server state: stopped enabled: false when: ansible_distribution_file_variety == "RedHat" - - name: Ensure that ganesha is started and enabled - service: name=nfs-ganesha state=started enabled=yes + - name: ganesha-nfs | Ensure that ganesha is started and enabled + ansible.builtin.service: + name: nfs-ganesha + state: started + enabled: true - - name: Reload ganesha after a reconfiguration - service: name=nfs-ganesha state=reloaded - when: ganesha_conf_files is changed + - name: ganesha-nfs | Reload ganesha after a reconfiguration + ansible.builtin.service: + name: nfs-ganesha + state: reloaded + when: ganesha_conf_files is changed # noqa: no-handler - tags: ['san', 'nfs', 'storage', 'ganesha', 'ganesha_conf'] + tags: [san, nfs, storage, ganesha, ganesha_conf] diff --git a/tasks/grub_cmdline_parameters.yml b/tasks/grub_cmdline_parameters.yml deleted file mode 100644 index 66c6f22..0000000 --- a/tasks/grub_cmdline_parameters.yml +++ /dev/null @@ -1,18 +0,0 @@ -- name: grub_cmdline_parameters | Manage additional grub command line options - tags: - - grub - - kernel - block: - - name: grub_cmdline_parameters | Install the grub command line configuration - ansible.builtin.template: - src: grub_cmdline.cfg.j2 - dest: /etc/default/grub.d/99-grub-ansible-cmdline.cfg - owner: root - group: root - mode: "0644" - when: configure_grub_cmdline_parameters - - name: grub_cmdline_parameters | Remove the custom grub command line configuration - ansible.builtin.file: - dest: /etc/default/grub.d/99-grub-ansible-cmdline.cfg - state: absent - when: not configure_grub_cmdline_parameters diff --git a/tasks/hostname.yml b/tasks/hostname.yml deleted file mode 100644 index 4242d7d..0000000 --- a/tasks/hostname.yml +++ /dev/null @@ -1,24 +0,0 @@ ---- -- name: hostname | Add entries to /etc/hosts - when: explicitly_set_hostname - tags: [ 'systemsetup', 'hostname' ] - block: - - name: hostname | Set the hostname when different from the inventory one. - ansible.builtin.hostname: - name: "{{ hostname }}" - when: hostname is defined - - - name: hostname | Set the hostname as defined in the inventory - ansible.builtin.hostname: - name: "{{ inventory_hostname }}" - when: hostname is not defined - - - name: hostname | Add the hostname into the /etc/hosts file - ansible.builtin.blockinfile: - path: /etc/hosts - marker_begin: 'ansible_hostname_start' - marker_end: 'ansible_hostname_end' - marker: "# {mark} hostname entry managed by ansible" - block: "{{ ansible_default_ipv4.address }} {{ hostname }} {{ ansible_hostname }}" - state: present - diff --git a/tasks/http_client_proxy.yml b/tasks/http_client_proxy.yml deleted file mode 100644 index f4338a6..0000000 --- a/tasks/http_client_proxy.yml +++ /dev/null @@ -1,18 +0,0 @@ ---- -- name: Proxy in the global shell environment - block: - - name: Install the proxy environment files - template: src={{ item }}.j2 dest=/etc/profile.d/{{ item }} owner=root group=root mode=0444 - with_items: - - 10-caching-proxy.sh - - 10-java-caching-proxy.sh - when: enable_env_proxy - - - name: Remove the proxy environment file if not required - file: dest=/etc/profile.d/{{ item }} state=absent - with_items: - - 10-caching-proxy.sh - - 10-java-caching-proxy.sh - when: not enable_env_proxy - - tags: [ 'systemsetup', 'proxyenv' ] diff --git a/tasks/locale.yml b/tasks/locale.yml deleted file mode 100644 index b5ca258..0000000 --- a/tasks/locale.yml +++ /dev/null @@ -1,36 +0,0 @@ ---- -- name: Generate locales and set the default locale on Debian and Ubuntu distributions - block: - - name: Add/remove a list of locales - locale_gen: name={{ item.name }} state={{ item.state | default('present') }} - with_items: '{{ locales_list }}' - - - name: Set the default locale on Trusty - shell: update-locale LANG={{ default_locale_lang }} - when: ansible_distribution_release == "trusty" - - when: ansible_distribution_file_variety == "Debian" - tags: [ 'systemsetup', 'locale' ] - -- name: Set the locale on distributions that run systemd - block: - - name: Check if localectl exists - stat: path=/usr/bin/localectl - register: localectl_executable - - - name: Set the default locale - command: localectl set-locale 'LANG={{ default_locale_lang }}' 'LC_MESSAGES={{ default_deb_locale_messages }}' - when: - - localectl_executable.stat.exists | bool - - ansible_distribution_file_variety == "Debian" - - - name: Set the default locale - command: localectl set-locale "{{ item }}" - with_items: - - 'LANG={{ default_locale_lang }}' - - 'LC_MESSAGES={{ default_el_locale_messages }}' - when: - - localectl_executable.stat.exists | bool - - ansible_distribution_file_variety == "RedHat" - - tags: [ 'systemsetup', 'locale' ] diff --git a/tasks/main.yml b/tasks/main.yml index 5dad0c4..9761117 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,52 +1,46 @@ --- -- name: Python3 requirements for ansible - ansible.builtin.import_tasks: ansible-python3-pkgs.yml -- name: Set the hostname - ansible.builtin.import_tasks: hostname.yml -- name: Set the locale - ansible.builtin.import_tasks: locale.yml -- name: Set the timezone - ansible.builtin.import_tasks: timezone.yml -- name: Manage customizations to the /etc/hosts file - ansible.builtin.import_tasks: etchosts-customizations.yml -- name: Sysctl kernel parameters - ansible.builtin.import_tasks: sysctl.yml -- name: Grub command line parameters - ansible.builtin.import_tasks: grub_cmdline_parameters.yml -- name: Additional network interfaces - ansible.builtin.import_tasks: network-interfaces.yml -- name: Create a directory that will contain the local generated certificates - ansible.builtin.import_tasks: pki_dir.yml -- name: Self signed certificates waiting for the letsencrypt ones - ansible.builtin.import_tasks: self_signed_certificate.yml - when: letsencrypt_acme_install is defined and letsencrypt_acme_install -- name: Certificate from privte CA (mkcert) - ansible.builtin.import_tasks: certificate_from_private_ca.yml +- name: Cloud-init configuration + ansible.builtin.import_tasks: cloud_init.yml + +- name: SSH daemon configuration + ansible.builtin.import_tasks: sshd_config.yml + when: sshd_install_config + +- name: Message of the Day (MOTD) configuration + ansible.builtin.import_tasks: motd.yml + when: motd_setup + +- name: Fail2ban configuration + ansible.builtin.import_tasks: fail2ban.yml + when: fail2ban_enabled + +- name: Dell server utilities + ansible.builtin.import_tasks: dell_utilities.yml when: - - (letsencrypt_acme_install is not defined) or (not letsencrypt_acme_install) - - mkcert_create_certificate -- name: HTTP client proxy - ansible.builtin.import_tasks: http_client_proxy.yml -- name: Manage additional disk volumes - ansible.builtin.import_tasks: additional_disks.yml - when: additional_disks -- name: Manage a swap device - ansible.builtin.import_tasks: swap_device.yml - when: swap_device + - "'Dell' in ansible_system_vendor | default('')" + - ansible_virtualization_role is defined + - ansible_virtualization_role == "host" + +- name: Tuned service for EL/RedHat + ansible.builtin.import_tasks: tuned_el.yml + when: ansible_distribution_file_variety == "RedHat" + - name: Manage the autofs configuration ansible.builtin.import_tasks: autofs.yml when: autofs_client_mountpoint + - name: Manage tmpreaper ansible.builtin.import_tasks: tmpreaper.yml -- name: Manage the trusted CAs - ansible.builtin.import_tasks: trusted_ca.yml + - name: Ganesha NFS ansible.builtin.import_tasks: ganesha-nfs.yml when: nfs_server_ganesha_enabled + - name: Linux Kernel NFS server ansible.builtin.import_tasks: nfs-kernel-server.yml when: - nfs_server_enabled - not nfs_server_ganesha_enabled + - name: Custom bashrc settings ansible.builtin.import_tasks: custom_bashrc.yml diff --git a/tasks/motd.yml b/tasks/motd.yml new file mode 100644 index 0000000..41bee03 --- /dev/null +++ b/tasks/motd.yml @@ -0,0 +1,8 @@ +--- +- name: motd | Configure MOTD on Debian/Ubuntu + ansible.builtin.import_tasks: motd_deb.yml + when: ansible_distribution_file_variety == "Debian" + +- name: motd | Configure MOTD on EL/RedHat + ansible.builtin.import_tasks: motd_el.yml + when: ansible_distribution_file_variety == "RedHat" diff --git a/tasks/motd_deb.yml b/tasks/motd_deb.yml new file mode 100644 index 0000000..2b90d84 --- /dev/null +++ b/tasks/motd_deb.yml @@ -0,0 +1,37 @@ +--- +- name: motd_deb | Install the packages that manage the dynamic motd file + ansible.builtin.apt: + pkg: "{{ deb_motd_packages }}" + state: present + update_cache: true + cache_valid_time: 3600 + tags: + - motd + +- name: motd_deb | Install our motd template file + ansible.builtin.template: + src: motd.j2 + dest: /etc/static-motd + owner: root + group: root + mode: "0644" + tags: + - motd + +- name: motd_deb | Install the dynamic merge script of the motd file + ansible.builtin.template: + src: update_motd.j2 + dest: /etc/update-motd.d/05-motd-message + owner: root + group: root + mode: "0755" + tags: + - motd + +- name: motd_deb | Initialise the motd prompt + ansible.builtin.shell: run-parts --lsbsysinit /etc/update-motd.d > /run/motd.dynamic && touch /etc/.custom_motd + args: + creates: /etc/.custom_motd + failed_when: false + tags: + - motd diff --git a/tasks/motd_el.yml b/tasks/motd_el.yml new file mode 100644 index 0000000..3b3e23e --- /dev/null +++ b/tasks/motd_el.yml @@ -0,0 +1,10 @@ +--- +- name: motd_el | Install our motd template file on EL/CentOS based distributions + ansible.builtin.template: + src: motd.j2 + dest: /etc/motd + owner: root + group: root + mode: "0644" + tags: + - motd diff --git a/tasks/network-interfaces.yml b/tasks/network-interfaces.yml deleted file mode 100644 index b7887d6..0000000 --- a/tasks/network-interfaces.yml +++ /dev/null @@ -1,53 +0,0 @@ ---- -- name: network-interfaces | Manage additional network interfaces, Ubuntu style - tags: - - network_interface - - networking - when: - - ansible_distribution == 'Ubuntu' - - ubuntu_configure_additional_interfaces - block: - - name: network-interfaces | Check if netplan is in use - ansible.builtin.stat: - path: /etc/netplan - register: netplan_in_use - - name: network-interfaces | Check if additional interfaces have been defined - ansible.builtin.set_fact: - net_ints: '{% for i in ansible_interfaces %}{% if i != ansible_lo.device and i != ansible_default_ipv4.interface %}"{{ i }}"{% if not loop.last %},{% endif %}{% endif %}{% endfor %}' - when: netplan_in_use.stat.isdir - - name: network-interfaces | Create a dictionary of additional interfaces - ansible.builtin.set_fact: - new_ints: '[{% for i in ansible_interfaces %}{% if i != ansible_lo.device and i != ansible_default_ipv4.interface %}"{{ i }}"{% if not loop.last %},{% endif %}{% endif %}{% endfor %}]' - when: net_ints is defined and net_ints | length != 0 - - name: network-interfaces | Print the loopback interface name - ansible.builtin.debug: - msg: "Loopback interface: {{ ansible_lo.device }}" - - name: network-interfaces | Print the name of the default interface - ansible.builtin.debug: - msg: "Loopback interface: {{ ansible_default_ipv4.interface }}" - - name: network-interfaces | List of interfaces other than the default one - ansible.builtin.debug: - msg: "Interfaces list: {{ new_ints }}" - - name: network-interfaces | Override the interfaces list - ansible.builtin.set_fact: - new_ints: "{{ ubuntu_configure_additional_ints_list }}" - when: ubuntu_configure_additional_ints_list | length != 0 - - name: network-interfaces | List of interfaces that we are going to configure - ansible.builtin.debug: - msg: "Interfaces list: {{ new_ints }}" - when: ubuntu_configure_additional_ints_list | length != 0 - - name: network-interfaces | Install the network interface file - ansible.builtin.template: - src: netplan-70-ansible.yaml.j2 - dest: /etc/netplan/70-ansible.yaml - owner: root - group: root - mode: "0644" - when: new_ints | length != 0 - notify: Netplan Apply - -- name: network-interfaces | Force the Netplan Apply command execution - ansible.builtin.meta: flush_handlers - tags: - - network_interface - - networking diff --git a/tasks/nfs-kernel-server.yml b/tasks/nfs-kernel-server.yml index 9515acd..20d9f48 100644 --- a/tasks/nfs-kernel-server.yml +++ b/tasks/nfs-kernel-server.yml @@ -1,84 +1,85 @@ --- -- name: Create the export directory trees +- name: nfs-kernel-server | Create the export directory trees block: - - name: Create the directory of the NFS exports + - name: nfs-kernel-server | Create the directory of the NFS exports ansible.builtin.file: - dest: '{{ item.path }}' + dest: "{{ item.path }}" state: directory owner: root group: root - mode: 0755 - loop: '{{ nfs_server_exports }}' + mode: "0755" + loop: "{{ nfs_server_exports }}" - tags: ['san', 'nfs', 'storage', 'kernel_nfs'] + tags: [san, nfs, storage, kernel_nfs] -- name: Repositories and packages on EL +- name: nfs-kernel-server | Repositories and packages on EL block: - - name: Install the NFS packages on EL - yum: - name: '{{ nfs_server_kernel_el_pkgs }}' + - name: nfs-kernel-server | Install the NFS packages on EL + ansible.builtin.yum: + name: "{{ nfs_server_kernel_el_pkgs }}" state: present - - name: Ensure that the Ganesha NFS server is not installed - yum: + - name: nfs-kernel-server | Ensure that the Ganesha NFS server is not installed + ansible.builtin.yum: name: nfs-ganesha state: absent when: ansible_distribution_file_variety == "RedHat" - tags: ['san', 'nfs', 'storage', 'kernel_nfs'] + tags: [san, nfs, storage, kernel_nfs] -- name: Repositories and packages on Ubuntu/Debian +- name: nfs-kernel-server | Repositories and packages on Ubuntu/Debian block: - - name: Install the nfs packages on deb systems - apt: - pkg: '{{ nfs_server_kernel_deb_pkgs }}' + - name: nfs-kernel-server | Install the nfs packages on deb systems + ansible.builtin.apt: + pkg: "{{ nfs_server_kernel_deb_pkgs }}" state: present cache_valid_time: 1800 - - name: Ensure that the ganesha server package is not installed - apt: + - name: nfs-kernel-server | Ensure that the ganesha server package is not installed + ansible.builtin.apt: pkg: nfs-ganesha state: absent when: ansible_distribution_file_variety == "Debian" - tags: ['san', 'nfs', 'storage', 'kernel_nfs'] + tags: [san, nfs, storage, kernel_nfs] -- name: Manage the NFS exports +- name: nfs-kernel-server | Manage the NFS exports block: - - name: Create the NFS exports folder - file: - dest: '/etc/exports.d' + - name: nfs-kernel-server | Create the NFS exports folder + ansible.builtin.file: + dest: /etc/exports.d owner: root group: root state: directory - mode: 0755 + mode: "0755" - - name: Install the NFS export files - template: - src: 'kernel-nfs-exports.j2' - dest: '/etc/exports.d/{{ item.name }}.exports' + - name: nfs-kernel-server | Install the NFS export files + ansible.builtin.template: + src: kernel-nfs-exports.j2 + dest: /etc/exports.d/{{ item.name }}.exports owner: root group: root - mode: 0644 - loop: '{{ nfs_server_exports }}' + mode: "0644" + loop: "{{ nfs_server_exports }}" register: update_exportfs - - name: Ensure that the Kernel NFS service is started and enabled on EL - service: + - name: nfs-kernel-server | Ensure that the Kernel NFS service is started and enabled on EL + ansible.builtin.service: name: nfs-server state: started enabled: true when: ansible_distribution_file_variety == "RedHat" - - name: Ensure that the Kernel NFS service is started and enabled on deb systems - service: + - name: nfs-kernel-server | Ensure that the Kernel NFS service is started and enabled on deb systems + ansible.builtin.service: name: nfs-kernel-server state: started enabled: true when: ansible_distribution_file_variety == "Debian" - - name: Refresh the exports - shell: exportfs -r - when: update_exportfs is changed + - name: nfs-kernel-server | Refresh the exports + ansible.builtin.shell: exportfs -r + when: update_exportfs is changed # noqa: no-handler + changed_when: false - tags: ['san', 'nfs', 'storage', 'kernel_nfs', 'kernel_nfs_conf'] + tags: [san, nfs, storage, kernel_nfs, kernel_nfs_conf] diff --git a/tasks/pki_dir.yml b/tasks/pki_dir.yml deleted file mode 100644 index 4118a8b..0000000 --- a/tasks/pki_dir.yml +++ /dev/null @@ -1,20 +0,0 @@ ---- -- name: Manage the PKI directory - tags: [pki, ssl, ca, letsencrypt, tls, tls_certificate] - block: - - name: Ensure that the PKI directory exists - ansible.builtin.file: - path: "{{ pki_dir }}" - state: directory - owner: root - group: root - mode: 0755 - - - name: Ensure that the PKI subdirectories exist - ansible.builtin.file: - path: "{{ pki_dir }}/{{ item }}" - state: directory - owner: root - group: root - mode: 0755 - loop: "{{ pki_subdirs }}" diff --git a/tasks/self_signed_certificate.yml b/tasks/self_signed_certificate.yml deleted file mode 100644 index 51d2fe7..0000000 --- a/tasks/self_signed_certificate.yml +++ /dev/null @@ -1,46 +0,0 @@ ---- -- name: Letsencrypt is going to manage the certificates. Check if a certificate already exists - tags: ['pki', 'ssl', 'letsencrypt'] - block: - - name: Check if a certificate already exists. If so, skip all the related tasks - ansible.builtin.stat: - path: "{{ letsencrypt_acme_sh_certificates_install_path }}" - register: true_cert - -- name: Manage self signed certificates, if letsencrypt is going to be installed - when: - - true_cert is defined - - true_cert.stat is defined - - true_cert.stat.islnk is not defined - tags: ['pki', 'ssl', 'letsencrypt'] - block: - - name: Create the path to the self signed certificates - ansible.builtin.file: - path: "{{ item }}" - state: directory - owner: root - group: root - mode: 0755 - loop: - - "{{ letsencrypt_acme_sh_certificates_install_base_path }}" - - "{{ pki_dir }}/selfsigned" - - - name: Generate the self signed certificate and private key - ansible.builtin.command: openssl req -x509 -newkey rsa:2048 -keyout {{ self_signed_key }} -out {{ self_signed_cert }} -days 365 -nodes -subj '{{ self_signed_subject }}' - args: - creates: '{{ self_signed_cert }}' - - - name: Copy the cert file into fullchain - ansible.builtin.copy: - src: "{{ self_signed_cert }}" - dest: "{{ self_signed_fullchain }}" - remote_src: true - owner: root - group: root - mode: 0644 - - - name: Create the symbolic link for the certificates into the letsencrypt live directory - ansible.builtin.file: - src: "{{ pki_dir }}/selfsigned" - dest: "{{ letsencrypt_acme_sh_certificates_install_path }}" - state: link diff --git a/tasks/sshd_config.yml b/tasks/sshd_config.yml new file mode 100644 index 0000000..812dbab --- /dev/null +++ b/tasks/sshd_config.yml @@ -0,0 +1,13 @@ +--- +- name: sshd_config | Install the sshd configuration file + ansible.builtin.template: + src: sshd_config.j2 + dest: "{{ sshd_config_dir }}/{{ sshd_config_file }}" + owner: root + group: root + mode: "0644" + notify: Reload the ssh service + when: sshd_install_config + tags: + - ssh + - sshd_config diff --git a/tasks/swap_device.yml b/tasks/swap_device.yml deleted file mode 100644 index 872854b..0000000 --- a/tasks/swap_device.yml +++ /dev/null @@ -1,22 +0,0 @@ ---- -- name: swap_device | Configure and enable a swap device - when: swap_device - tags: - - swap - - swap_device - block: - - name: swap_device | Initialize the swap device - ansible.builtin.shell: mkswap {{ swap_device_name }} && touch /root/.mkswap_executed - args: - creates: /root/.mkswap_executed - register: mkswap_command_execution - - name: swap_device | Enable the swap device - ansible.builtin.shell: swapon {{ swap_device_name }} && touch /root/.swapon_executed - args: - creates: /root/.swapon_executed - - - name: swap_device | Add the swap device to the fstab file - ansible.builtin.lineinfile: - path: /etc/fstab - regexp: "^{{ swap_device_name }}" - line: "{{ swap_device_name }} swap swap defaults 0 0" diff --git a/tasks/sysctl.yml b/tasks/sysctl.yml deleted file mode 100644 index 762aefb..0000000 --- a/tasks/sysctl.yml +++ /dev/null @@ -1,53 +0,0 @@ ---- -- block: - - name: Ensure that the /etc/sysctl.d directory exists - file: - path: /etc/sysctl.d - state: directory - owner: root - group: root - - tags: ['sysctl', 'kernel', 'sysctl_ipv6', 'ipv6'] - -- block: - - name: Set the custom sysctl values - sysctl: - name: '{{ item.name }}' - value: '{{ item.value }}' - sysctl_file: "{{ item.sysctlfile | default ('/etc/sysctl.d/90-custom-values.conf') }}" - reload: "{{ item.sysctl_reload | default(true) }}" - state: "{{ item.sysctlfile_state | default('present') }}" - loop: '{{ sysctl_custom_options }}' - - tags: ['sysctl', 'kernel'] - -- block: - - name: Disable the in kernel ipv6 support - sysctl: - name: '{{ item }}' - value: 1 - sysctl_file: '{{ ipv6_sysctl_file }}' - reload: true - state: present - loop: - - net.ipv6.conf.all.disable_ipv6 - - net.ipv6.conf.default.disable_ipv6 - - net.ipv6.conf.lo.disable_ipv6 - - net.ipv6.conf.{{ ansible_default_ipv4.interface }}.disable_ipv6 - when: disable_ipv6 - - - name: enable the in kernel ipv6 support - sysctl: - name: '{{ item }}' - value: 0 - sysctl_file: '{{ ipv6_sysctl_file }}' - reload: true - state: present - loop: - - net.ipv6.conf.all.disable_ipv6 - - net.ipv6.conf.default.disable_ipv6 - - net.ipv6.conf.lo.disable_ipv6 - - net.ipv6.conf.{{ ansible_default_ipv4.interface }}.disable_ipv6 - when: not disable_ipv6 - - tags: ['sysctl', 'kernel', 'sysctl_ipv6', 'ipv6'] diff --git a/tasks/timezone.yml b/tasks/timezone.yml deleted file mode 100644 index 8b05dec..0000000 --- a/tasks/timezone.yml +++ /dev/null @@ -1,21 +0,0 @@ ---- -- name: Manage the timezone in Ubuntu Trusty and older - block: - - name: Write the timezone file - template: src=etc-timezone.j2 dest=/etc/timezone owner=root group=root mode=0644 - register: set_timezone - - - name: Reconfigure the system tzdata - command: dpkg-reconfigure --frontend noninteractive tzdata - when: set_timezone is changed - - when: ansible_distribution_release == "trusty" - tags: [ 'systemsetup', 'timezone' ] - -- name: Manage the timezone in Ubuntu Bionic or CentOS - block: - - name: Set the timezone - command: timedatectl set-timezone {{ timezone }} - - when: ansible_facts['distribution_version'] is version_compare('16.04', '>=') or ansible_distribution_file_variety == "RedHat" - tags: [ 'systemsetup', 'timezone' ] diff --git a/tasks/tmpreaper.yml b/tasks/tmpreaper.yml index 9f3b0bf..f5e808e 100644 --- a/tasks/tmpreaper.yml +++ b/tasks/tmpreaper.yml @@ -1,38 +1,50 @@ --- -- name: Install tmpreaper on Debian/Ubuntu +- name: tmpreaper | Install tmpreaper on Debian/Ubuntu when: - tmpreaper_install - ansible_distribution_file_variety == "Debian" tags: tmpreaper block: - - name: Install tmpreaper - ansible.builtin.apt: pkg=tmpreaper state=latest cache_valid_time=1800 + - name: tmpreaper | Install tmpreaper + ansible.builtin.apt: + pkg: tmpreaper + state: present + cache_valid_time: 1800 - - name: Change the date check criteria from ctime to mtime - ansible.builtin.lineinfile: - path: /etc/cron.daily/tmpreaper - regexp: '^ --[c|m]time \\' - line: ' --mtime \' - when: not tmpreaper_use_ctime + - name: tmpreaper | Change the date check criteria from ctime to mtime + ansible.builtin.lineinfile: + path: /etc/cron.daily/tmpreaper + regexp: ^ --[c|m]time \\ + line: " --mtime \\" + when: not tmpreaper_use_ctime - - name: Change the date check criteria from mtime to ctime - ansible.builtin.lineinfile: - path: /etc/cron.daily/tmpreaper - regexp: '^ --[c|m]time \\' - line: ' --ctime \' - when: tmpreaper_use_ctime + - name: tmpreaper | Change the date check criteria from mtime to ctime + ansible.builtin.lineinfile: + path: /etc/cron.daily/tmpreaper + regexp: ^ --[c|m]time \\ + line: " --ctime \\" + when: tmpreaper_use_ctime - - name: Install the tmpreaper configuration - ansible.builtin.template: src=tmpreaper.conf.j2 dest=/etc/tmpreaper.conf owner=root group=root mode=0444 + - name: tmpreaper | Install the tmpreaper configuration + ansible.builtin.template: + src: tmpreaper.conf.j2 + dest: /etc/tmpreaper.conf + owner: root + group: root + mode: "0444" -- name: Remove tmpreaper on Debian/Ubuntu +- name: tmpreaper | Remove tmpreaper on Debian/Ubuntu when: - not tmpreaper_install - ansible_distribution_file_variety == "Debian" tags: tmpreaper block: - - name: Remove the tmpreaper package - ansible.builtin.apt: pkg=tmpreaper state=absent + - name: tmpreaper | Remove the tmpreaper package + ansible.builtin.apt: + pkg: tmpreaper + state: absent - - name: Remove the tmpreaper configuration - ansible.builtin.file: dest=/etc/tmpreaper.conf state=absent + - name: tmpreaper | Remove the tmpreaper configuration + ansible.builtin.file: + dest: /etc/tmpreaper.conf + state: absent diff --git a/tasks/trusted_ca.yml b/tasks/trusted_ca.yml deleted file mode 100644 index 95defe8..0000000 --- a/tasks/trusted_ca.yml +++ /dev/null @@ -1,120 +0,0 @@ ---- -- name: Manage optional CA files on EL - tags: ['pki', 'trusted_ca', 'letsencrypt_ca'] - block: - - name: Get the CA files that we want to trust on EL - get_url: url={{ item.ca_url }} dest=/etc/pki/ca-trust/source/anchors/{{ item.ca }} owner=root group=root mode='0444' - with_items: '{{ trusted_ca_additional_ca_files }}' - register: ca_files_installation - - - name: Trust the CA files on EL - command: /bin/update-ca-trust extract - when: ca_files_installation is changed - - when: ansible_distribution_file_variety == "RedHat" - -- name: Manage the Letsencrypt CA files on EL - when: - - trusted_ca_letsencrypt_install - - ansible_distribution_file_variety == "RedHat" - tags: ['pki', 'trusted_ca', 'letsencrypt_ca'] - block: - - name: Download the letsencrypt CA files on EL - get_url: - url: '{{ trusted_ca_letsencrypt_ca_certificates_url }}/{{ item.ca_src }}' - dest: '/etc/pki/ca-trust/source/anchors/{{ item.ca }}' - owner: root - group: root - mode: 0444 - loop: '{{ trusted_ca_letsencrypt_ca_files }}' - register: letsencrypt_ca_files_installation - - - name: Rebuild the trust CA files on EL - command: /bin/update-ca-trust extract - when: letsencrypt_ca_files_installation is changed - - - name: Ensure that the expired CA files are not present - file: - dest: '/etc/pki/ca-trust/source/anchors/{{ item }}' - state: absent - loop: '{{ expired_ca_letsencrypt_ca_files }}' - register: letsencrypt_ca_files_removal - - - name: Rebuild the trust CA files on EL - command: /bin/update-ca-trust extract - when: letsencrypt_ca_files_removal is changed - - -- name: Manage optional CA files on deb - when: ansible_distribution_file_variety == "Debian" - tags: ['pki', 'trusted_ca', 'letsencrypt_ca'] - block: - - name: Ensure that ca-certificates is installed and up to date - apt: - pkg: ca-certificates - state: latest - cache_valid_time: 1800 - - - name: Get the CA files that we want to trust on deb - get_url: url={{ item.ca_url }} dest={{ trusted_ca_deb_path }}/{{ item.ca }} owner=root group=root mode='0444' - with_items: '{{ trusted_ca_additional_ca_files }}' - register: ca_files_installation - - - name: Trust the CA files on deb - command: /usr/sbin/update-ca-certificates - when: ca_files_installation is changed - -- name: Distrust the DST Root CA X3 in Ubuntu Trusty - when: - - ansible_distribution_file_variety == "Debian" - - ansible_distribution_version is version_compare('14.04', '==') - tags: ['pki', 'obsolete_ca'] - block: - - name: Comment the mozilla/DST_Root_CA_X3.crt entry - lineinfile: - path: /etc/ca-certificates.conf - regexp: '^mozilla/DST_Root_CA_X3.crt' - line: '!mozilla/DST_Root_CA_X3.crt' - register: dst_x3_distrust - - - name: Trust the CA files on deb - command: /usr/sbin/update-ca-certificates - when: dst_x3_distrust is changed - -- name: Manage the Letsencrypt CA files on deb - when: - - trusted_ca_letsencrypt_install - - ansible_distribution_file_variety == "Debian" - tags: ['pki', 'trusted_ca', 'letsencrypt_ca'] - block: - - name: Download the letsencrypt CA files on deb - get_url: - url: '{{ trusted_ca_letsencrypt_ca_certificates_url }}/{{ item.ca_src }}' - dest: '{{ trusted_ca_deb_path }}/{{ item.ca }}' - owner: root - group: root - mode: 0444 - loop: '{{ trusted_ca_letsencrypt_ca_files }}' - register: letsencrypt_ca_files_installation - - - name: Trust the CA files on deb - command: /usr/sbin/update-ca-certificates - when: letsencrypt_ca_files_installation is changed - - - name: Ensure that the expired CA files are not present - file: - dest: '/etc/ssl/certs/{{ item }}' - state: absent - loop: '{{ expired_ca_letsencrypt_ca_files }}' - register: letsencrypt_ca_files_removal - - - name: Ensure that the expired CA files are not present - file: - dest: '{{ trusted_ca_deb_path }}/{{ item }}' - state: absent - loop: '{{ expired_ca_letsencrypt_ca_files }}' - register: letsencrypt_ca_files_removal - - - name: Trust the CA files on deb - command: /usr/sbin/update-ca-certificates - when: letsencrypt_ca_files_removal is changed diff --git a/tasks/tuned_el.yml b/tasks/tuned_el.yml new file mode 100644 index 0000000..4551bbe --- /dev/null +++ b/tasks/tuned_el.yml @@ -0,0 +1,31 @@ +--- +- name: tuned_el | Enable the tuned service when we want it active + ansible.builtin.service: + name: tuned + state: started + enabled: true + when: centos_tuned_enabled + tags: + - centos + - bootstrap + - tuned + +- name: tuned_el | Disable the tuned service if we do not want it + ansible.builtin.service: + name: tuned + state: stopped + enabled: false + when: not centos_tuned_enabled + tags: + - centos + - bootstrap + - tuned + +- name: tuned_el | Activate the tuned profile we chose + ansible.builtin.command: tuned-adm profile {{ centos_tuned_profile }} + when: centos_tuned_enabled + changed_when: false + tags: + - centos + - bootstrap + - tuned diff --git a/templates/10-caching-proxy.sh.j2 b/templates/10-caching-proxy.sh.j2 deleted file mode 100644 index 6e60897..0000000 --- a/templates/10-caching-proxy.sh.j2 +++ /dev/null @@ -1,5 +0,0 @@ -{% for proto in env_proxy_protocols %} -export {{ proto }}="{{ env_proxy_http_url }}" -{% endfor %} -export no_proxy="{% for target in no_proxy_targets %}{{ target }}{% if not loop.last %},{% endif %}{% endfor %}" -export NO_PROXY="{% for target in no_proxy_targets %}{{ target }}{% if not loop.last %},{% endif %}{% endfor %}" diff --git a/templates/10-java-caching-proxy.sh.j2 b/templates/10-java-caching-proxy.sh.j2 deleted file mode 100644 index 733c7ff..0000000 --- a/templates/10-java-caching-proxy.sh.j2 +++ /dev/null @@ -1 +0,0 @@ -export JAVA_OPTS="-DproxySet=true -Dhttp.proxyHost={{ env_proxy_http_host }} -Dhttp.proxyPort={{ env_proxy_http_port }} -Dhttps.proxyHost={{ env_proxy_http_host }} -Dhttps.proxyPort={{ env_proxy_http_port }}" diff --git a/templates/apache-ddos-filter.conf.j2 b/templates/apache-ddos-filter.conf.j2 new file mode 100644 index 0000000..d2948a3 --- /dev/null +++ b/templates/apache-ddos-filter.conf.j2 @@ -0,0 +1,8 @@ +# {{ ansible_managed }} +[Definition] + +# regex derived from the apache-bot one + +failregex = ^ -.*"(GET|POST).* + +ignoreregex = diff --git a/templates/apache-ddos-jail.conf.j2 b/templates/apache-ddos-jail.conf.j2 new file mode 100644 index 0000000..c311666 --- /dev/null +++ b/templates/apache-ddos-jail.conf.j2 @@ -0,0 +1,9 @@ +# {{ ansible_managed }} +[http-get-dos] +enabled = {{ f2b_apache_ddos_enabled }} +port = http,https +filter = apache-ddos-filter +logpath = /var/log/apache*/*access*log +maxretry = {{ f2b_ddos_maxretry }} +findtime = {{ f2b_ddos_findtime }} +bantime = {{ f2b_ban_time }} diff --git a/templates/etc-timezone.j2 b/templates/etc-timezone.j2 deleted file mode 100644 index 0b6d009..0000000 --- a/templates/etc-timezone.j2 +++ /dev/null @@ -1 +0,0 @@ -{{ timezone }} diff --git a/templates/fail2ban.local.j2 b/templates/fail2ban.local.j2 new file mode 100644 index 0000000..0c1ddac --- /dev/null +++ b/templates/fail2ban.local.j2 @@ -0,0 +1,3 @@ +# {{ ansible_managed }} +[Definition] +logtarget = {{ fail2ban_logtarget }} diff --git a/templates/grub_cmdline.cfg.j2 b/templates/grub_cmdline.cfg.j2 deleted file mode 100644 index b35ee6e..0000000 --- a/templates/grub_cmdline.cfg.j2 +++ /dev/null @@ -1 +0,0 @@ -GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT {{ grub_cmdline_additional_parameters }}" diff --git a/templates/jail-d-customization.local.j2 b/templates/jail-d-customization.local.j2 new file mode 100644 index 0000000..c453813 --- /dev/null +++ b/templates/jail-d-customization.local.j2 @@ -0,0 +1,28 @@ +# {{ ansible_managed }} +[DEFAULT] + +# "bantime" is the number of seconds that a host is banned. +bantime = {{ fail2ban_bantime }} +# A host is banned if it has generated "maxretry" during the last "findtime" +# seconds. +findtime = {{ fail2ban_findtime }} +# "maxretry" is the number of failures before a host get banned. +maxretry = {{ fail2ban_maxretry }} + +[sshd] +enabled={{ fail2ban_sshd_enabled }} + +[sshd-ddos] +enabled={{ fail2ban_sshd_ddos_enabled }} + +[nginx-http-auth] +enabled={{ fail2ban_nginx_auth_enabled }} + +[apache-auth] +enabled={{ fail2ban_apache_auth_enabled }} + +[php-url-fopen] +enabled={{ fail2ban_php_url_fopen_enabled }} + +[vsftpd] +enabled={{ fail2ban_vsftpd_enabled }} diff --git a/templates/jail.local.j2 b/templates/jail.local.j2 new file mode 100644 index 0000000..60a2b2f --- /dev/null +++ b/templates/jail.local.j2 @@ -0,0 +1,254 @@ +# {{ ansible_managed }} +# Fail2Ban configuration file. +# +# This file was composed for Debian systems from the original one +# provided now under /usr/share/doc/fail2ban/examples/jail.conf +# for additional examples. +# +# Comments: use '#' for comment lines and ';' for inline comments +# +# To avoid merges during upgrades DO NOT MODIFY THIS FILE +# and rather provide your changes in /etc/fail2ban/jail.local +# + +# The DEFAULT allows a global definition of the options. They can be overridden +# in each jail afterwards. + +[DEFAULT] + +# "ignoreip" can be an IP address, a CIDR mask or a DNS host. Fail2ban will not +# ban a host which matches an address in this list. Several addresses can be +# defined using space separator. +ignoreip = 127.0.0.1/8 {% if cm_ip is defined %}{{ cm_ip }}{% endif %} {% if monitoring_ip is defined %}{{ monitoring_ip }}{% endif %} + +# "bantime" is the number of seconds that a host is banned. +bantime = {{ f2b_ban_time }} + +# A host is banned if it has generated "maxretry" during the last "findtime" +# seconds. +findtime = {{ f2b_findtime }} +maxretry = {{ f2b_maxretry }} + +# "backend" specifies the backend used to get files modification. +# Available options are "pyinotify", "gamin", "polling" and "auto". +# This option can be overridden in each jail as well. +# +# pyinotify: requires pyinotify (a file alteration monitor) to be installed. +# If pyinotify is not installed, Fail2ban will use auto. +# gamin: requires Gamin (a file alteration monitor) to be installed. +# If Gamin is not installed, Fail2ban will use auto. +# polling: uses a polling algorithm which does not require external libraries. +# auto: will try to use the following backends, in order: +# pyinotify, gamin, polling. +backend = {{ f2b_default_backend }} + +# "usedns" specifies if jails should trust hostnames in logs, +# warn when reverse DNS lookups are performed, or ignore all hostnames in logs +# +# yes: if a hostname is encountered, a reverse DNS lookup will be performed. +# warn: if a hostname is encountered, a reverse DNS lookup will be performed, +# but it will be logged as a warning. +# no: if a hostname is encountered, will not be used for banning, +# but it will be logged as info. +usedns = {{ f2b_usedns }} + +# +# Destination email address used solely for the interpolations in +# jail.{conf,local} configuration files. +destemail = {{ f2b_dest_email }} + +# +# Name of the sender for mta actions +sendername = {{ f2b_sender_email }} + +# +# ACTIONS +# + +# Default banning action (e.g. iptables, iptables-new, +# iptables-multiport, shorewall, etc) It is used to define +# action_* variables. Can be overridden globally or per +# section within jail.local file +banaction = {{ f2b_default_banaction }} + +# email action. Since 0.8.1 upstream fail2ban uses sendmail +# MTA for the mailing. Change mta configuration parameter to mail +# if you want to revert to conventional 'mail'. +mta = sendmail + +# Default protocol +protocol = tcp + +# Specify chain where jumps would need to be added in iptables-* actions +chain = {{ f2b_default_iptableschain }} + +# +# Action shortcuts. To be used to define action parameter + +# The simplest action to take: ban only +action_ = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"] + +# ban & send an e-mail with whois report to the destemail. +action_mw = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"] + %(mta)s-whois[name=%(__name__)s, dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s", sendername="%(sendername)s"] + +# ban & send an e-mail with whois report and relevant log lines +# to the destemail. +action_mwl = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"] + %(mta)s-whois-lines[name=%(__name__)s, dest="%(destemail)s", logpath=%(logpath)s, chain="%(chain)s", sendername="%(sendername)s"] + +# Choose default action. To change, just override value of 'action' with the +# interpolation to the chosen action shortcut (e.g. action_mw, action_mwl, etc) in jail.local +# globally (section [DEFAULT]) or per specific section +action = %({{ f2b_default_action }})s + +# +# JAILS +# + +# Next jails corresponds to the standard configuration in Fail2ban 0.6 which +# was shipped in Debian. Enable any defined here jail by including +# +# [SECTION_NAME] +# enabled = true + +# +# in /etc/fail2ban/jail.local. +# +# Optionally you may override any other parameter (e.g. banaction, +# action, port, logpath, etc) in that section within jail.local + +[ssh] + +enabled = {{ f2b_ssh_enabled }} +port = ssh +filter = sshd +logpath = /var/log/auth.log +maxretry = {{ f2b_maxretry }} + +[dropbear] + +enabled = false +port = ssh +filter = dropbear +logpath = /var/log/auth.log +maxretry = 6 + +# Generic filter for pam. Has to be used with action which bans all ports +# such as iptables-allports, shorewall +[pam-generic] + +enabled = false +# pam-generic filter can be customized to monitor specific subset of 'tty's +filter = pam-generic +# port actually must be irrelevant but lets leave it all for some possible uses +port = all +banaction = iptables-allports +logpath = /var/log/auth.log +maxretry = 6 + +[xinetd-fail] + +enabled = false +filter = xinetd-fail +port = all +banaction = iptables-multiport-log +logpath = /var/log/daemon.log +maxretry = 2 + + +[ssh-ddos] + +enabled = {{ f2b_ssh_ddos_enabled }} +port = ssh +filter = sshd-ddos +logpath = /var/log/auth.log +maxretry = {{ f2b_maxretry }} + + +# +# HTTP servers +# + +# default action is now multiport, so apache-multiport jail was left +# for compatibility with previous (<0.7.6-2) releases +[apache-multiport] + +enabled = {{ f2b_apache_auth_enabled }} +port = http,https +filter = apache-auth +logpath = /var/log/apache*/*error.log +maxretry = 6 + +[apache-noscript] + +enabled = {{ f2b_apache_noscript_enabled }} +port = http,https +filter = apache-noscript +logpath = /var/log/apache*/*error.log +maxretry = 6 + +[apache-overflows] + +enabled = {{ f2b_apache_overflow_enabled }} +port = http,https +filter = apache-overflows +logpath = /var/log/apache*/*error.log +maxretry = 2 + +# Ban attackers that try to use PHP's URL-fopen() functionality +# through GET/POST variables. - Experimental, with more than a year +# of usage in production environments. + +[php-url-fopen] + +enabled = {{ f2b_php_url_fopen }} +port = http,https +filter = php-url-fopen +logpath = /var/www/*/logs/access_log + +# A simple PHP-fastcgi jail which works with lighttpd. +# If you run a lighttpd server, then you probably will +# find these kinds of messages in your error_log: +# ALERT – tried to register forbidden variable 'GLOBALS' +# through GET variables (attacker '1.2.3.4', file '/var/www/default/htdocs/index.php') + +[nginx-http-auth] + +enabled = {{ f2b_nginx_auth_enabled }} +filter = nginx-http-auth +port = http,https +logpath = /var/log/nginx/error.log + +# +# FTP servers +# + +[vsftpd] + +enabled = {{ f2b_vsftpd_enabled }} +port = ftp,ftp-data,ftps,ftps-data +filter = vsftpd +logpath = {{ f2b_vsftpd_logpath }} +# or overwrite it in jails.local to be +# logpath = /var/log/auth.log +# if you want to rely on PAM failed login attempts +# vsftpd's failregex should match both of those formats +maxretry = 6 + + +# Jail for more extended banning of persistent abusers +# !!! WARNING !!! +# Make sure that your loglevel specified in fail2ban.conf/.local +# is not at DEBUG level -- which might then cause fail2ban to fall into +# an infinite loop constantly feeding itself with non-informative lines +[recidive] + +enabled = {{ f2b_recidive_enabled }} +filter = recidive +logpath = /var/log/fail2ban.log +action = iptables-allports[name=recidive] + sendmail-whois-lines[name=recidive, logpath=/var/log/fail2ban.log] +bantime = {{ f2b_recidive_ban_time }} +findtime = {{ f2b_recidive_findtime }} +maxretry = 5 diff --git a/templates/motd.j2 b/templates/motd.j2 new file mode 100644 index 0000000..b4fd8e8 --- /dev/null +++ b/templates/motd.j2 @@ -0,0 +1,2 @@ + +{{ motd_additional_text }} diff --git a/templates/netplan-70-ansible.yaml.j2 b/templates/netplan-70-ansible.yaml.j2 deleted file mode 100644 index 6603860..0000000 --- a/templates/netplan-70-ansible.yaml.j2 +++ /dev/null @@ -1,14 +0,0 @@ -network: - version: 2 - ethernets: -{% for int in new_ints %} - {{ int }}: - dhcp4: true -{% if ubuntu_configure_additional_int_dhcp_overrides | default(true) %} - dhcp4-overrides: - use-dns: false - use-routes: false - use-mtu: true -{% endif %} -{% endfor %} - diff --git a/templates/nginx-ddos-filter.conf.j2 b/templates/nginx-ddos-filter.conf.j2 new file mode 100644 index 0000000..d2948a3 --- /dev/null +++ b/templates/nginx-ddos-filter.conf.j2 @@ -0,0 +1,8 @@ +# {{ ansible_managed }} +[Definition] + +# regex derived from the apache-bot one + +failregex = ^ -.*"(GET|POST).* + +ignoreregex = diff --git a/templates/nginx-ddos-jail.conf.j2 b/templates/nginx-ddos-jail.conf.j2 new file mode 100644 index 0000000..d1da525 --- /dev/null +++ b/templates/nginx-ddos-jail.conf.j2 @@ -0,0 +1,9 @@ +# {{ ansible_managed }} +[nginx-get-dos] +enabled = {{ f2b_nginx_ddos_enabled }} +port = http,https +filter = nginx-ddos-filter +logpath = /var/log/nginx/*access.log +maxretry = {{ f2b_ddos_maxretry }} +findtime = {{ f2b_ddos_findtime }} +bantime = {{ f2b_ban_time }} diff --git a/templates/sshd_config.j2 b/templates/sshd_config.j2 new file mode 100644 index 0000000..2d16330 --- /dev/null +++ b/templates/sshd_config.j2 @@ -0,0 +1,216 @@ +# {{ ansible_managed }} +# +# OpenSSH Server Configuration +# +# OpenSSH versions by distribution: +# Ubuntu 20.04 (Focal): 8.2 | Ubuntu 22.04 (Jammy): 8.9 | Ubuntu 24.04 (Noble): 9.6 +# Debian 11 (Bullseye): 8.4 | Debian 12 (Bookworm): 9.2 | Debian 13 (Trixie): 9.9 +# EL 8: 8.0 | EL 9: 8.7 | EL 10: 9.8 +# +# Version-specific features enabled by this template: +# 8.2+: Include directive +# 8.5+: PerSourceMaxStartups, PerSourceNetBlockSize +# 8.7+: KbdInteractiveAuthentication (replaces ChallengeResponseAuthentication) +# 9.1+: RequiredRSASize +# 9.2+: ChannelTimeout, UnusedConnectionTimeout +# 9.8+: PerSourcePenalties, PerSourcePenaltyExemptList, PAMServiceName +# +# Deprecated options handled: +# ChallengeResponseAuthentication: deprecated in 8.7, uses KbdInteractiveAuthentication instead +# + +{% set openssh_version_map = { + 'focal': 8.2, + 'jammy': 8.9, + 'noble': 9.6, + 'bullseye': 8.4, + 'bookworm': 9.2, + 'trixie': 9.9, +} %} +{% if ansible_distribution_file_variety == 'Debian' %} +{% set openssh_version = openssh_version_map.get(ansible_distribution_release, 8.0) %} +{% elif ansible_distribution_file_variety == 'RedHat' %} +{% if ansible_distribution_major_version | int >= 10 %} +{% set openssh_version = 9.8 %} +{% elif ansible_distribution_major_version | int >= 9 %} +{% set openssh_version = 8.7 %} +{% else %} +{% set openssh_version = 8.0 %} +{% endif %} +{% else %} +{% set openssh_version = 8.0 %} +{% endif %} + +# --- Include directive (OpenSSH 8.2+) --- +{% if openssh_version >= 8.2 and sshd_include_config_d %} +Include /etc/ssh/sshd_config.d/*.conf + +{% endif %} +# --- Network --- +Port {{ sshd_port }} +AddressFamily any +#ListenAddress 0.0.0.0 +#ListenAddress :: + +# --- Host Keys --- +{% for key in sshd_host_keys %} +HostKey {{ key }} +{% endfor %} + +# --- Ciphers, MACs, and Key Exchange --- +{% if sshd_ciphers %} +Ciphers {{ sshd_ciphers }} +{% endif %} +{% if sshd_macs %} +MACs {{ sshd_macs }} +{% endif %} +{% if sshd_kex_algorithms %} +KexAlgorithms {{ sshd_kex_algorithms }} +{% endif %} +{% if sshd_host_key_algorithms %} +HostKeyAlgorithms {{ sshd_host_key_algorithms }} +{% endif %} + +# --- Minimum RSA key size (OpenSSH 9.1+) --- +{% if openssh_version >= 9.1 and sshd_required_rsa_size %} +RequiredRSASize {{ sshd_required_rsa_size }} +{% endif %} + +# --- Logging --- +SyslogFacility {{ sshd_syslog_facility }} +LogLevel {{ sshd_log_level }} + +# --- Authentication --- +LoginGraceTime {{ sshd_login_grace_time }} +PermitRootLogin {{ sshd_permit_root_login }} +StrictModes {{ sshd_strict_mode }} +MaxAuthTries {{ sshd_max_auth_tries }} +MaxSessions {{ sshd_max_sessions }} + +PubkeyAuthentication {{ sshd_pubkey_authentication }} +#AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2 + +# Host-based authentication +HostbasedAuthentication {{ sshd_hostbased_authentication }} +IgnoreRhosts {{ sshd_ignore_rhosts }} +{% if sshd_ignore_user_known_hosts == "yes" %} +IgnoreUserKnownHosts yes +{% endif %} + +# Password and empty password settings +PermitEmptyPasswords {{ sshd_permit_empty_passwords }} +PasswordAuthentication {{ sshd_password_authentication }} + +# Keyboard-interactive authentication +# Note: ChallengeResponseAuthentication was renamed to KbdInteractiveAuthentication in OpenSSH 8.7 +# and deprecated in OpenSSH 9.x. We use the appropriate directive based on version. +{% if openssh_version >= 8.7 %} +KbdInteractiveAuthentication {{ sshd_kbd_interactive_authentication }} +{% else %} +ChallengeResponseAuthentication {{ sshd_kbd_interactive_authentication }} +{% endif %} + +# GSSAPI options +GSSAPIAuthentication {{ sshd_gssapi_authentication }} +{% if sshd_gssapi_authentication == "yes" %} +GSSAPICleanupCredentials {{ sshd_gssapi_cleanup_credentials }} +{% endif %} + +# PAM +UsePAM {{ sshd_use_pam }} +{% if openssh_version >= 9.8 and sshd_pam_service_name %} +PAMServiceName {{ sshd_pam_service_name }} +{% endif %} + +# --- Forwarding --- +AllowAgentForwarding {{ sshd_agent_forwarding }} +AllowTcpForwarding {{ sshd_tcp_forwarding }} +GatewayPorts {{ sshd_gateway_ports }} +X11Forwarding {{ sshd_x11_forwarding }} +{% if sshd_x11_forwarding == "yes" %} +X11DisplayOffset {{ sshd_x11_display_offset }} +X11UseLocalhost yes +{% endif %} +PermitTunnel {{ sshd_permit_tunnel }} +PermitUserEnvironment {{ sshd_permit_user_environment }} + +# --- Connection Settings --- +TCPKeepAlive {{ sshd_tcp_keep_alive }} +{% if sshd_client_alive_interval | int > 0 %} +ClientAliveInterval {{ sshd_client_alive_interval }} +ClientAliveCountMax {{ sshd_client_alive_count_max }} +{% endif %} +MaxStartups {{ sshd_max_startups }} + +# --- Per-source rate limiting (OpenSSH 8.5+) --- +{% if openssh_version >= 8.5 %} +{% if sshd_per_source_max_startups %} +PerSourceMaxStartups {{ sshd_per_source_max_startups }} +{% endif %} +{% if sshd_per_source_net_block_size %} +PerSourceNetBlockSize {{ sshd_per_source_net_block_size }} +{% endif %} +{% endif %} + +# --- Penalty-based rate limiting (OpenSSH 9.8+) --- +# Supported on: EL 10+, Ubuntu 25.04+, Debian Trixie+ +{% if openssh_version >= 9.8 %} +{% if sshd_per_source_penalties %} +PerSourcePenalties {{ sshd_per_source_penalties }} +{% endif %} +{% if sshd_per_source_penalty_exempt_list %} +PerSourcePenaltyExemptList {{ sshd_per_source_penalty_exempt_list }} +{% endif %} +{% endif %} + +# --- Timeouts (OpenSSH 9.2+) --- +{% if openssh_version >= 9.2 %} +{% if sshd_channel_timeout %} +ChannelTimeout {{ sshd_channel_timeout }} +{% endif %} +{% if sshd_unused_connection_timeout %} +UnusedConnectionTimeout {{ sshd_unused_connection_timeout }} +{% endif %} +{% endif %} + +# --- Display --- +PrintMotd {{ sshd_print_motd }} +PrintLastLog {{ sshd_print_last_log }} +Banner {{ sshd_banner_path }} + +# --- DNS --- +UseDNS {{ sshd_use_dns }} + +# --- Environment --- +AcceptEnv {{ sshd_acceptenv }} + +# --- Subsystems --- +{% if sshd_enable_sftp_subsystem %} +{% if ansible_distribution_file_variety == 'RedHat' %} +Subsystem sftp /usr/libexec/openssh/sftp-server +{% else %} +Subsystem sftp /usr/lib/openssh/sftp-server +{% endif %} +{% endif %} + +# --- Match Blocks --- +{% if sshd_enable_sftp_subsystem and sshd_enable_sftp_jail %} +# SFTP Chroot Jail +Match Group {{ sshd_sftp_chroot_match_group }} + ChrootDirectory {{ sshd_sftp_chroot_directory }} + ForceCommand {{ sshd_sftp_force_command }} + PermitTunnel no + AllowAgentForwarding no + AllowTcpForwarding no + X11Forwarding no + +{% endif %} +{% for match in sshd_match_blocks %} +Match {{ match.criteria }} +{% for option in match.options %} +{% for key, value in option.items() %} + {{ key }} {{ value }} +{% endfor %} +{% endfor %} + +{% endfor %} diff --git a/templates/update_motd.j2 b/templates/update_motd.j2 new file mode 100644 index 0000000..95bff2d --- /dev/null +++ b/templates/update_motd.j2 @@ -0,0 +1,5 @@ +#!/bin/sh + +cat /etc/static-motd + +exit 0 diff --git a/tests/test.yml b/tests/test.yml index 4ba2a88..8e4ac64 100644 --- a/tests/test.yml +++ b/tests/test.yml @@ -1,5 +1,15 @@ --- -- hosts: localhost +- name: Test basic-system-setup role + hosts: localhost remote_user: root + become: true + vars: + # Minimal test configuration + fail2ban_enabled: false + cloud_init_remove_pkg: false + cleanup_base_packages: false + cleanup_exim_email_server: false + ubuntu_remove_lxd: false + disable_some_not_needed_services: false roles: - - ansible-role-template \ No newline at end of file + - basic-system-setup