424 lines
12 KiB
Markdown
424 lines
12 KiB
Markdown
# 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](https://gitea-s2i2s.isti.cnr.it/ISTI-ansible-roles/ansible-role-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
|
|
|
|
```bash
|
|
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
|
|
|
|
```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
|
|
|
|
Andrea Dell'Amico <andrea.dellamico@isti.cnr.it>
|
|
|
|
ISTI-CNR, Pisa, Italy
|