sns-network-solutions/infra/sns-networking/hardening-baseline.md
Samuel James b1a35783bb Consolidate 7 divisions to 3: Networking, Digital, Support
- Merge Infrastructure + Secure + Systems → SNS Networking (Business #1)
- Merge Web + Software + Cloud → SNS Digital (planned)
- SNS Support unchanged (planned)
- Add infra/ folder with 16 FOSS-first buildable designs
- Update all agent knowledge, division briefs, legal structure
- Restructure businesses/ from 7 to 3 operating folders
2026-07-18 13:08:23 -05:00

3.7 KiB

Host Hardening Baseline — SNS Networking

Entity: SNS Networking · Status: Buildable now (Ansible playbook)

What it is

The minimum security posture applied to every Linux host — on-prem VM, LXC, or cloud VPS — before it does anything else. This is the Ansible "base" role that runs first on every new machine.

Stack

Component Software FOSS Role
Firewall UFW (iptables frontend) Yes Default-deny inbound, explicit allow
Brute-force protection Fail2ban Yes SSH + web login jail
SSH hardening OpenSSH (config only) Yes Key-only, no root, no password
Auto-updates unattended-upgrades (Debian) Yes Security patches only
Audit logging auditd Yes File access, privilege escalation events
Rootkit detection rkhunter Yes Weekly scan, email on findings

The Playbook (what it does)

# roles/base-hardening/tasks/main.yml (conceptual)
- name: SSH hardening
  # PermitRootLogin no
  # PasswordAuthentication no
  # PubkeyAuthentication yes
  # MaxAuthTries 3
  # AllowUsers sam

- name: UFW default deny
  # Default incoming: deny
  # Default outgoing: allow
  # Allow: SSH (22/tcp) from Tailscale/WireGuard subnet only

- name: Fail2ban SSH jail
  # maxretry: 3
  # bantime: 3600
  # findtime: 600

- name: Unattended upgrades (security only)
  # Automatic-Reboot: false (manual kernel reboots)

- name: Auditd rules
  # Watch /etc/passwd, /etc/shadow, /etc/sudoers
  # Log all sudo usage
  # Log failed file access attempts

- name: Disable unused services
  # Stop & mask: cups, avahi-daemon, bluetooth (if present)

- name: Sysctl hardening
  # net.ipv4.conf.all.rp_filter = 1
  # net.ipv4.icmp_echo_ignore_broadcasts = 1
  # net.ipv4.conf.all.accept_redirects = 0
  # net.ipv4.conf.all.send_redirects = 0
  # kernel.randomize_va_space = 2

Per-Host Firewall Rules

Host type Inbound allowed Notes
All hosts SSH from 10.10.0.0/24 (WireGuard) Management only over VPN
Web-facing (Caddy) 80, 443 from 0.0.0.0/0 Public web traffic
Bastion (Linode) 22, 51820/udp from 0.0.0.0/0 SSH + WireGuard
Internal services App port from service VLAN only No direct internet access
Proxmox host 8006 from Tailscale only Web UI never on public IP

Build Steps

  1. Write Ansible role roles/base-hardening/ with the above tasks.
  2. Add to site.yml as the first role for all host groups.
  3. Run against all existing hosts: ansible-playbook site.yml --tags hardening
  4. Verify: ssh root@host should fail. ssh sam@host with key should work.
  5. Verify: nmap -sS host from outside WireGuard should show only allowed ports.

Security Posture

  • Default deny. Nothing gets in unless explicitly allowed.
  • No passwords anywhere. SSH key-only. Service accounts use tokens or certs.
  • Audit trail. Every sudo, every sensitive file access logged.
  • Automatic patching. Security updates apply daily without manual intervention. Kernel updates require manual reboot (scheduled maintenance window).

Upgrade Path

  • CIS Benchmark compliance: Run cis-cat scanner and close gaps for client environments that require formal compliance.
  • OSSEC/Wazuh: When you need centralized security event management across 10+ hosts.
  • SELinux/AppArmor: Enforce MAC policies on high-value services (currently not enabled — adds complexity without proportional gain at this scale).