Skip to content

Security & Penetration Testing Guide

This document covers the homelab's attack surfaces, threat vectors, security controls, and pentesting methodology. Use this for security audits, hardening verification, and educational reference.


Architecture Security Overview

                          INTERNET
                    ┌─────────────────────┐
                    │   Cloudflare DNS    │
                    │   (DDoS protection) │
                    └─────────┬───────────┘
                    ┌─────────────────────┐
                    │   Hetzner VPS       │
                    │   5.161.45.147      │
                    │   ─────────────     │
                    │   Caddy (TLS)       │
                    │   WireGuard Client  │
                    └─────────┬───────────┘
                              │ WireGuard Tunnel
                              │ (encrypted)
                    ┌─────────────────────┐
                    │   OPNsense Firewall │
                    │   10.22.95.1        │
                    └─────────┬───────────┘
                    ┌─────────────────────┐
                    │   K8s Cluster       │
                    │   10.89.97.0/24     │
                    │   ─────────────     │
                    │   nginx-ingress     │
                    │   Authentik SSO     │
                    │   Application Pods  │
                    └─────────────────────┘

Attack Surface Inventory

External Attack Surface (Internet-Facing)

Component Exposed Port Purpose Protection
VPS Caddy 443 (HTTPS) Reverse proxy TLS 1.3, rate limiting
VPS Caddy 80 (HTTP) Redirect to HTTPS Auto-redirect
VPS WireGuard 51820 (UDP) VPN tunnel Key-based auth
VPS SSH 22 Admin access Key-only, fail2ban

Services Exposed via VPS (*.bogocat.com)

Service URL Auth Type Risk Level
Authentik auth.bogocat.com Native (MFA required) HIGH (SSO = keys to kingdom)
Home Portal portal.bogocat.com Authentik OAuth Medium
Money Tracker money.bogocat.com Authentik OAuth Medium
Trip Planner travel.bogocat.com Authentik OAuth Medium
Immich photos.bogocat.com Authentik OIDC (native) Medium
Jellyfin jellyfin.bogocat.com LDAP + OAuth (SSO plugin) Medium
Radarr radarr.bogocat.com Authentik Forward Auth Low
Sonarr sonarr.bogocat.com Authentik Forward Auth Low
(other arr services) *.bogocat.com Authentik Forward Auth Low

Auth Type Legend: - Authentik OAuth: App uses NextAuth with Authentik provider (MFA enforced) - Authentik OIDC: App has native OIDC support, configured with Authentik (MFA enforced) - Authentik Forward Auth: nginx-ingress checks auth before proxying (MFA enforced) - LDAP + OAuth: Dual auth paths - LDAP for devices (no MFA), OAuth for browsers (MFA)

Internal Attack Surface (Requires VPN/Physical Access)

Component IP/Port Notes
Proxmox Host 10.89.97.11:8006 Web UI + SSH
K8s API 10.89.97.201:6443 kubectl access
PostgreSQL (Supabase) 10.89.97.219:5432 Database
LDAP Outpost 10.89.97.218:389 Authentik LDAP

Threat Model

Threat Actors

Actor Capability Motivation Likelihood
Script Kiddie Automated scans, known exploits Curiosity, botnets HIGH
Credential Stuffing Bot Breached password lists Account takeover HIGH
Targeted Attacker Custom exploits, persistence Data theft LOW
Insider (Friend) Valid credentials Curiosity, accident LOW

Attack Vectors

1. Authentication Attacks

Vector Description Current Mitigation
Password Spraying Try common passwords across accounts Rate limiting (5 attempts = lockout)
Credential Stuffing Use breached credentials Unique passwords + MFA
MFA Bypass Phishing for TOTP codes WebAuthn (phishing-resistant)
Session Hijacking Steal session cookies HTTPS-only, secure cookies
OAuth Token Theft Intercept authorization codes Short-lived tokens, PKCE

2. Network Attacks

Vector Description Current Mitigation
DDoS Flood VPS with traffic Cloudflare, VPS isolation
WireGuard Key Theft Compromise VPN access Key rotation, limited peers
Man-in-the-Middle Intercept traffic TLS everywhere, WireGuard
DNS Hijacking Redirect *.bogocat.com Cloudflare DNS security

3. Application Attacks

Vector Description Current Mitigation
XSS Inject malicious scripts CSP headers, input sanitization
SQL Injection Database manipulation Parameterized queries, RLS
SSRF Server-side request forgery Internal network isolation
Path Traversal Access unauthorized files Containerization, read-only FS

4. Infrastructure Attacks

Vector Description Current Mitigation
Container Escape Break out of K8s pod SecurityContext, no privileged
Supply Chain Compromised dependencies Image scanning, pinned versions
Secrets Exposure Leaked credentials SealedSecrets, gitignored .env

Authentication Flow Security

Current Authentication Chain

User Request → Caddy (VPS) → nginx-ingress (K8s) → Authentik → Application
                  │                   │              │
                  │                   │              └─ MFA Validation
                  │                   └─ Forward Auth Check
                  └─ TLS Termination

MFA Configuration

Current Setup:

default-authentication-flow:
  Order 10: identification-stage (username/email)
  Order 20: password-stage
  Order 30: mfa-validation (TOTP + WebAuthn)
           └─ Not configured action: Configure (FORCES MFA SETUP)

Key Security Properties: - MFA is required for all users - Users cannot skip MFA setup on first login - WebAuthn (passkeys) preferred over TOTP - 5 failed attempts = temporary account lockout

User Onboarding Security Gap

Scenario: Admin creates new user account

Timeline:
┌─────────────────────────────────────────────────────────────────┐
│ T+0    Admin creates user, sets initial password                │
│ T+?    Admin sends password to user (email, chat, etc.)         │
│ T+??   User logs in for first time                              │
│        └─> FORCED to configure MFA before accessing any app     │
│ T+??? User is now protected by MFA                              │
└─────────────────────────────────────────────────────────────────┘

Risk Window: Between T+0 and T+?? (user's first login)

Risk Likelihood Impact Mitigation
Password intercepted in transit Low High Use secure channel (Signal, in-person)
Admin account compromised Low Critical Admin uses MFA, separate admin account
Brute force before user logs in Very Low Medium Rate limiting, strong initial password

Best Practices for User Onboarding: 1. Generate strong random initial password (20+ chars) 2. Send via secure channel (Signal, in-person, NOT email) 3. Set password expiry (force change on first login) 4. Monitor for unusual login attempts 5. User must configure MFA before accessing any application


Penetration Testing Methodology

Phase 1: Reconnaissance

# DNS enumeration
dig +short bogocat.com
dig +short ANY bogocat.com
nslookup -type=any bogocat.com

# Subdomain discovery (passive)
curl -s "https://crt.sh/?q=%.bogocat.com&output=json" | jq -r '.[].name_value' | sort -u

# Port scanning (from authorized location)
nmap -sV -sC -p- 5.161.45.147

# SSL/TLS analysis
testssl.sh auth.bogocat.com

Phase 2: Authentication Testing

# Test for default credentials
curl -X POST https://auth.bogocat.com/api/v3/core/users/ \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"admin"}'

# Test rate limiting
for i in {1..10}; do
  curl -s -o /dev/null -w "%{http_code}\n" \
    -X POST https://auth.bogocat.com/api/v3/flows/executor/default-authentication-flow/ \
    -d "uid_field=test&password=wrong$i"
done

# Test MFA bypass (should fail)
# Attempt to access protected resource without completing MFA flow
curl -v https://portal.bogocat.com/ -H "Cookie: authentik_session=..."

# Test API endpoint protection
curl -s -o /dev/null -w "%{http_code}" \
  -H "Host: radarr.bogocat.com" \
  https://radarr.bogocat.com/api/v3/system/status
# Expected: 302 (redirect to auth)

Phase 3: Forward Auth Testing

# Test that forward auth is enforced
for service in sonarr radarr lidarr prowlarr; do
  echo -n "$service: "
  curl -s -o /dev/null -w "%{http_code}" "https://$service.bogocat.com/"
done
# Expected: All return 302 (redirect to Authentik)

# Test header injection (should be blocked)
curl -v https://sonarr.bogocat.com/ \
  -H "X-Authentik-Username: admin" \
  -H "X-Authentik-Groups: admins"
# Expected: 302 (headers ignored, still requires auth)

Phase 4: Application Testing

# Test for information disclosure
curl -s https://portal.bogocat.com/ | grep -i "version\|powered by\|server"

# Test error handling (no stack traces)
curl -s "https://portal.bogocat.com/api/nonexistent" | head -20

# Test CORS configuration
curl -v -X OPTIONS https://portal.bogocat.com/api/ \
  -H "Origin: https://evil.com" \
  -H "Access-Control-Request-Method: POST"

Phase 5: Infrastructure Testing

# From VPS (if compromised, what's reachable?)
ssh root@5.161.45.147

# Test WireGuard tunnel isolation
ping 10.89.97.220  # K8s ingress - should work
ping 10.89.97.11   # Proxmox host - should work (evaluate if needed)

# Test what ports are accessible through tunnel
for port in 22 5432 6443 8006; do
  nc -zv 10.89.97.11 $port 2>&1 | grep -q succeeded && echo "Port $port OPEN"
done

Security Controls Checklist

Authentication & Authorization

  • [x] MFA required for all users
  • [x] MFA forced on first login (not optional)
  • [x] WebAuthn (phishing-resistant) available
  • [x] Rate limiting on login attempts
  • [x] Session timeout configured
  • [x] Forward auth on all arr-stack services
  • [ ] Password policy enforcement (min length, complexity)
  • [ ] Account lockout notification to admin

Network Security

  • [x] TLS on all external endpoints
  • [x] WireGuard for VPS-to-homelab tunnel
  • [x] No direct port forwarding from home IP
  • [x] Firewall rules on OPNsense
  • [ ] Network segmentation (arr-stack isolated from apps)
  • [ ] VPN access logging/alerting

Application Security

  • [x] HTTPS-only (HTTP redirects)
  • [x] Secure cookie flags (HttpOnly, Secure, SameSite)
  • [x] Containerized workloads
  • [ ] Security headers (CSP, X-Frame-Options, etc.)
  • [ ] Regular dependency updates
  • [ ] Container image scanning

Secrets Management

  • [x] SealedSecrets for K8s
  • [x] .env files gitignored
  • [x] Secrets not logged
  • [ ] Secret rotation schedule
  • [ ] Vault/external secrets manager

Monitoring & Alerting

  • [x] Authentik event logs
  • [ ] Failed login alerting
  • [ ] Suspicious activity detection
  • [ ] Uptime monitoring
  • [ ] Log aggregation (Loki/ELK)

Incident Response

If VPS is Compromised

  1. Contain: Disable WireGuard tunnel immediately

    # From OPNsense or Proxmox
    # Disable the WireGuard peer for VPS
    

  2. Assess: Check what was accessed

    # VPS access logs
    ssh root@5.161.45.147 "cat /var/log/auth.log | tail -100"
    ssh root@5.161.45.147 "journalctl -u caddy --since '1 hour ago'"
    

  3. Recover:

  4. Rebuild VPS from scratch (assume compromised)
  5. Rotate WireGuard keys
  6. Review Authentik sessions/tokens
  7. Change any secrets that were accessible

If Authentik is Compromised

  1. Contain: Take Authentik offline

    kubectl scale deployment -n authentik authentik-server --replicas=0
    

  2. Assess:

  3. Check Authentik event logs
  4. Review user sessions
  5. Check for new users/applications/providers

  6. Recover:

  7. Invalidate all sessions
  8. Force password reset for all users
  9. Review and re-enroll MFA devices
  10. Audit application access

If User Credentials Leaked

  1. Contain: Disable user account

    Authentik UI → Directory → Users → Deactivate
    

  2. Assess: Check user's recent activity in Authentik logs

  3. Recover:

  4. Reset password
  5. Remove all MFA devices
  6. Re-enroll user with new credentials

Regular Security Tasks

Weekly

  • [ ] Review Authentik event logs for anomalies
  • [ ] Check for failed login attempts

Monthly

  • [ ] Update container images
  • [ ] Review user accounts (remove unused)
  • [ ] Test backup restoration

Quarterly

  • [ ] Full penetration test (this checklist)
  • [ ] Review and update this document
  • [ ] Rotate long-lived secrets
  • [ ] Review firewall rules

Tools Reference

Tool Purpose Installation
nmap Port scanning apt install nmap
testssl.sh TLS analysis git clone https://github.com/drwetter/testssl.sh
nikto Web vulnerability scanner apt install nikto
nuclei Template-based scanner go install github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
ffuf Web fuzzer go install github.com/ffuf/ffuf/v2@latest
burpsuite HTTP proxy/scanner Download from PortSwigger