ansible-role-basic-system-s.../README.md

12 KiB
Raw Blame History

basic-system-setup

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.

Early-stage OS bootstrap tasks (locale, timezone, hostname, packages, sysctl, PKI, etc.) are handled by the os-bootstrap dependency, which always runs first.

Requirements

  • Ansible >= 2.9
  • The os-bootstrap dependency role (declared in meta/main.yml, resolved automatically)

Ansible Collections Required

ansible-galaxy collection install ansible.posix
ansible-galaxy collection install community.general

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

cloud_init_disable_netconfig: false   # write 99-disable-network-config.cfg
cloud_init_remove_pkg: true           # remove cloud-init after first boot

SSHD Configuration

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

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

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

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

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

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

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

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)

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.

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

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

---
- hosts: servers
  become: true
  roles:
    - role: basic-system-setup

SSH hardening + Fail2ban with nginx protection

---
- 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

---
- 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

---
- 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

source ~/ansible/ansible6/bin/activate
ansible-lint

Molecule tests are available under molecule/default/ and target Ubuntu 22.04 (Jammy) and Rocky Linux 9.

molecule test           # full cycle
molecule converge       # apply only
molecule verify         # idempotency / verification
molecule destroy        # teardown

License

EUPL-1.2

Author Information

Andrea DellAmico andrea.dellamico@isti.cnr.it

ISTI-CNR, Pisa, Italy