- 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
99 lines
3.7 KiB
Markdown
99 lines
3.7 KiB
Markdown
# 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)
|
|
|
|
```yaml
|
|
# 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).
|
|
|
|
<!-- ponytail: No SELinux/AppArmor yet. Ceiling: DAC-only can't contain a compromised
|
|
service from lateral movement on the same host. Upgrade: AppArmor profiles for
|
|
Caddy, WordPress, Gitea when client compliance requires it. -->
|