# 🔐 Security Guide ## Overview This guide covers security best practices for the homelab, including authentication, network security, secrets management, and incident response. --- ## 🏰 Security Architecture ``` ┌─────────────────────────────────────────────────────────────────────────────┐ │ SECURITY LAYERS │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ EXTERNAL │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ Cloudflare WAF + DDoS Protection + Bot Management │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ GATEWAY ▼ │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ Nginx Proxy Manager (SSL Termination + Rate Limiting) │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ AUTHENTICATION ▼ │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ Authentik SSO (OAuth2/OIDC + MFA + User Management) │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ NETWORK ▼ │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ Tailscale (Zero-Trust Mesh VPN) + Wireguard (Site-to-Site) │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ APPLICATION ▼ │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ Vaultwarden (Secrets) + Container Isolation + Least Privilege │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ ``` --- ## 🔑 Authentication & Access Control ### Authentik SSO All services use centralized authentication through Authentik: ```yaml # Services integrated with Authentik SSO: - Grafana (OAuth2) - Portainer (OAuth2) - Proxmox (LDAP) - Mattermost (OAuth2) - Seafile (OAuth2) - Paperless-NGX (OAuth2) - Various internal apps (Forward Auth) ``` ### Multi-Factor Authentication (MFA) | Service | MFA Type | Status | |---------|----------|--------| | Authentik | TOTP + WebAuthn | ✅ Required | | Vaultwarden | TOTP + FIDO2 | ✅ Required | | Synology DSM | TOTP | ✅ Required | | Proxmox | TOTP | ✅ Required | | Tailscale | Google SSO | ✅ Required | ### Access Levels ```yaml # Role-Based Access Control roles: admin: description: Full access to all systems access: - All Portainer environments - Authentik admin - DSM admin - Proxmox root operator: description: Day-to-day operations access: - Container management - Service restarts - Log viewing viewer: description: Read-only monitoring access: - Grafana dashboards - Uptime Kuma status - Read-only Portainer family: description: Consumer access only access: - Plex/Jellyfin streaming - Photo viewing - Limited file access ``` --- ## 🌐 Network Security ### Firewall Rules ```bash # Synology Firewall - Recommended rules # Control Panel > Security > Firewall # Allow Tailscale Allow: 100.64.0.0/10 (Tailscale CGNAT) # Allow local network Allow: 192.168.0.0/16 (RFC1918) Allow: 10.0.0.0/8 (RFC1918) # Block everything else by default Deny: All # Specific port rules Allow: TCP 443 from Cloudflare IPs only Allow: TCP 80 from Cloudflare IPs only (redirect to 443) ``` ### Cloudflare Configuration ```yaml # Cloudflare Security Settings ssl_mode: full_strict # End-to-end encryption min_tls_version: "1.2" always_use_https: true # WAF Rules waf_enabled: true bot_management: enabled ddos_protection: automatic # Rate Limiting rate_limit: requests_per_minute: 100 action: challenge # Access Rules ip_access_rules: - action: block filter: known_bots - action: challenge filter: threat_score > 10 ``` ### Port Exposure ```yaml # Only these ports exposed to internet (via Cloudflare) exposed_ports: - 443/tcp # HTTPS (Nginx Proxy Manager) # Everything else via Tailscale/VPN only internal_only: - 22/tcp # SSH - 8080/tcp # Portainer - 9090/tcp # Prometheus - 3000/tcp # Grafana - All Docker services ``` --- ## 🔒 Secrets Management ### Vaultwarden Central password manager for all credentials: ```yaml # Vaultwarden Security Settings vaultwarden: admin_token: # Argon2 hashed signups_allowed: false invitations_allowed: true # Password policy password_hints_allowed: false password_iterations: 600000 # PBKDF2 iterations # 2FA enforcement require_device_email: true # Session security login_ratelimit_seconds: 60 login_ratelimit_max_burst: 10 ``` ### Environment Variables ```bash # Never store secrets in docker-compose.yml # Use Docker secrets or environment files # Bad ❌ environment: - DB_PASSWORD="REDACTED_PASSWORD" # Good ✅ - Using .env file environment: - DB_PASSWORD="REDACTED_PASSWORD" # Better ✅ - Using Docker secrets secrets: - db_password ``` ### Secret Rotation ```yaml # Secret rotation schedule rotation_schedule: api_tokens: 90 days oauth_secrets: 180 days database_passwords: 365 days ssl_certificates: auto (Let's Encrypt) ssh_keys: on compromise only ``` --- ## 🐳 Container Security ### Docker Security Practices ```yaml # docker-compose.yml security settings services: myservice: # Run as non-root user: "1000:1000" # Read-only root filesystem read_only: true # Disable privilege escalation security_opt: - no-new-privileges:true # Limit capabilities cap_drop: - ALL cap_add: - NET_BIND_SERVICE # Only if needed # Resource limits deploy: resources: limits: cpus: '1.0' memory: 512M ``` ### Container Scanning ```bash # Scan images for vulnerabilities docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \ aquasec/trivy image myimage:latest # Scan all running containers for img in $(docker ps --format '{{.Image}}' | sort -u); do echo "Scanning: $img" docker run --rm aquasec/trivy image "$img" --severity HIGH,CRITICAL done ``` ### Image Security ```yaml # Only use trusted image sources trusted_registries: - docker.io/library/ # Official images - ghcr.io/ # GitHub Container Registry - lscr.io/linuxserver/ # LinuxServer.io # Always pin versions # Bad ❌ image: nginx:latest # Good ✅ image: nginx:1.25.3-alpine ``` --- ## 🛡️ Backup Security ### Encrypted Backups ```bash # Hyper Backup encryption settings encryption: enabled: true type: client-side # Encrypt before transfer algorithm: AES-256-CBC key_storage: local # Never store key on backup destination # Verify encryption # Check that backup files are not readable without key file backup.hbk # Should show: "data" not "text" or recognizable format ``` ### Backup Access Control ```yaml # Separate credentials for backup systems backup_credentials: hyper_backup: read_only: true # Cannot delete backups separate_user: backup_user syncthing: ignore_delete: true # Prevent sync of deletions offsite: encryption_key: stored_offline access: write_only # Cannot read existing backups ``` --- ## 📊 Security Monitoring ### Log Aggregation ```yaml # Critical logs to monitor security_logs: - /var/log/auth.log # Authentication attempts - /var/log/nginx/access.log # Web access - Authentik audit logs # SSO events - Docker container logs # Application events ``` ### Alerting Rules ```yaml # prometheus/rules/security.yml groups: - name: security rules: - alert: REDACTED_APP_PASSWORD expr: increase(authentik_login_failures_total[1h]) > 10 labels: severity: warning annotations: summary: "High number of failed login attempts" - alert: SSHBruteForce expr: increase(sshd_auth_failures_total[5m]) > 5 labels: severity: critical annotations: summary: "Possible SSH brute force attack" - alert: UnauthorizedContainerStart expr: changes(container_start_time_seconds[1h]) > 0 labels: severity: info annotations: summary: "New container started" ``` ### Security Dashboard Key metrics to display in Grafana: - Failed authentication attempts - Active user sessions - SSL certificate expiry - Firewall blocked connections - Container privilege changes - Unusual network traffic patterns --- ## 🚨 Incident Response ### Response Procedure ``` 1. DETECT └─► Alerts from monitoring └─► User reports └─► Anomaly detection 2. CONTAIN └─► Isolate affected systems └─► Block malicious IPs └─► Disable compromised accounts 3. INVESTIGATE └─► Review logs └─► Identify attack vector └─► Assess data exposure 4. REMEDIATE └─► Patch vulnerabilities └─► Rotate credentials └─► Restore from backup if needed 5. RECOVER └─► Restore services └─► Verify integrity └─► Monitor for recurrence 6. DOCUMENT └─► Incident report └─► Update procedures └─► Implement improvements ``` ### Emergency Contacts ```yaml # Store securely in Vaultwarden emergency_contacts: - ISP support - Domain registrar - Cloudflare support - Family members with access ``` ### Quick Lockdown Commands ```bash # Block all external access immediately # On Synology: sudo iptables -I INPUT -j DROP sudo iptables -I INPUT -s 100.64.0.0/10 -j ACCEPT # Keep Tailscale # Stop all non-essential containers docker stop $(docker ps -q --filter "name!=essential-service") # Force logout all Authentik sessions docker exec authentik-server ak invalidate_sessions --all ``` --- ## 📋 Security Checklist ### Weekly - [ ] Review failed login attempts - [ ] Check for container updates - [ ] Verify backup integrity - [ ] Review Cloudflare analytics ### Monthly - [ ] Rotate API tokens - [ ] Review user access - [ ] Run vulnerability scans - [ ] Test backup restoration - [ ] Update SSL certificates (if manual) ### Quarterly - [ ] Full security audit - [ ] Review firewall rules - [ ] Update incident response plan - [ ] Test disaster recovery - [ ] Review third-party integrations --- ## 🔗 Related Documentation - [Authentik SSO Setup](../infrastructure/authentik-sso.md) - [Cloudflare Configuration](../infrastructure/cloudflare-dns.md) - [Backup Strategies](backup-strategies.md) - [Disaster Recovery](../troubleshooting/disaster-recovery.md) - [Tailscale Setup](../infrastructure/tailscale-setup-guide.md)