ADDED Requirements
Requirement: Ansible inventory defines relay and landing server groups
The inventory SHALL define two host groups: relay and landing, each containing the respective server's connection details (IP, SSH user, SSH key). The ansible_user SHALL be a configurable placeholder supporting both root and non-root users. The repository SHALL ship inventory/hosts.yml.example as a template; the actual inventory/hosts.yml SHALL be gitignored and created by the user.
Scenario: Inventory is valid
- WHEN the user copies
hosts.yml.example to hosts.yml and fills in their values
- THEN two groups
relay and landing are available, each with at least one host
Scenario: Non-root user with sudo
- WHEN
ansible_user is set to a non-root user (e.g., ubuntu)
- THEN Ansible connects as that user and uses
become for privilege escalation
Scenario: Root user
- WHEN
ansible_user is set to root
- THEN Ansible connects as root directly and
become is a no-op
Scenario: Missing inventory
- WHEN the user has not copied
hosts.yml.example to hosts.yml
- THEN Ansible fails with an error indicating the inventory file is missing
Requirement: Base packages are installed on all servers
The base role SHALL install essential packages: curl, wget, vim, htop, unzip, ufw, fail2ban, unattended-upgrades.
Scenario: Fresh server provisioning
- WHEN the base role runs on a fresh Ubuntu/Debian server
- THEN all listed packages are installed and available
Requirement: SSH is hardened
The base role SHALL configure SSH to disable password authentication, disable root login, and only allow key-based authentication. The SSH port SHALL be configurable per host via ssh_port, defaulting to 22.
Scenario: SSH hardening applied
- WHEN the base role completes
- THEN
/etc/ssh/sshd_config has PasswordAuthentication no, PermitRootLogin no, and PubkeyAuthentication yes
- THEN the sshd Port directive uses the host's
ssh_port value
- THEN the sshd service is restarted
Scenario: Custom SSH port per host
- WHEN a host defines
ssh_port: 2222 in inventory
- THEN sshd listens on port 2222
- THEN UFW allows port 2222 instead of 22
- THEN fail2ban monitors port 2222
Requirement: UFW firewall is configured with default deny
The base role SHALL enable UFW with a default deny incoming policy and allow SSH (port 22).
Scenario: Firewall base rules
- WHEN the base role completes
- THEN UFW is active with default deny incoming
- THEN SSH port 22 is allowed
Scenario: Proxy ports are allowed per server role
- WHEN the base role runs on a relay server
- THEN the relay proxy port is allowed through UFW
- WHEN the base role runs on a landing server
- THEN both the chained and direct proxy ports are allowed through UFW
Requirement: fail2ban protects SSH
The base role SHALL configure fail2ban to monitor SSH login attempts and ban IPs after repeated failures.
Scenario: fail2ban is active
- WHEN the base role completes
- THEN fail2ban is running with an SSH jail enabled
Requirement: Automatic security updates are enabled
The base role SHALL enable unattended-upgrades for security patches.
Scenario: Unattended upgrades configured
- WHEN the base role completes
- THEN unattended-upgrades is configured to auto-install security updates