spec.md 3.7 KB

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. The group_vars/all.yml SHALL set ansible_python_interpreter: auto to enable interpreter auto-discovery on all hosts.

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

Scenario: Python interpreter auto-discovery

  • WHEN Ansible connects to any managed host
  • THEN it uses auto-discovery to locate the Python interpreter instead of assuming /usr/bin/python3

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