Security

Security architecture, authentication, authorization, and compliance

Security Architecture

The homelab implements a comprehensive security strategy based on defense-in-depth principles, zero-trust networking, and industry best practices.

Security Layers

Security Architecture
  1. Perimeter Security: Router-level firewall and intrusion detection
  2. Network Security: Segmentation, VLANs, and traffic filtering
  3. Host Security: VM-level firewalls and hardening
  4. Application Security: Authentication, authorization, and encryption
  5. Data Security: Encryption at rest and in transit

Authentication & Authorization

Single Sign-On (SSO)

Authelia Configuration:

  • Location: auth.home.dodwell.us
  • Backend: LDAP (OpenLDAP)
  • 2FA Methods: TOTP, WebAuthn
  • Session Management: Redis-backed sessions

Supported Applications:

  • Grafana (OIDC integration)
  • Harbor Registry (OIDC integration)
  • ArgoCD (OIDC integration)
  • Gitea (OIDC integration)

LDAP Directory

OpenLDAP Configuration:

# Base DN
dc=home,dc=dodwell,dc=us

# Organizational Units
ou=users,dc=home,dc=dodwell,dc=us
ou=groups,dc=home,dc=dodwell,dc=us

# Service Account
cn=authelia-service,ou=users,dc=home,dc=dodwell,dc=us

User Attributes:

  • uid: Username
  • mail: Email address
  • cn: Display name
  • memberOf: Group memberships

Access Control Policies

Authelia Rules:

access_control:
  default_policy: 'deny'
  rules:
    # Bypass authentication for auth service
    - domain: "auth.home.dodwell.us"
      policy: bypass
    
    # Single factor for monitoring
    - domain: ["grafana.home.dodwell.us", "prometheus.home.dodwell.us"]
      policy: one_factor
    
    # Two factor for critical services
    - domain: ["proxmox.home.dodwell.us", "argocd.home.dodwell.us", "vault.home.dodwell.us"]
      policy: two_factor

Certificate Management

Let’s Encrypt Integration

cert-manager Configuration:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: admin@dodwell.us
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
    - dns01:
        cloudflare:
          email: admin@dodwell.us
          apiTokenSecretRef:
            name: cloudflare-api-token
            key: api-token

Certificate Lifecycle:

  1. Issuance: Automatic via DNS-01 challenge
  2. Renewal: 30 days before expiration
  3. Distribution: Kubernetes TLS secrets
  4. Monitoring: Prometheus metrics and alerts

TLS Configuration

Minimum TLS Standards:

  • TLS Version: 1.2 minimum, 1.3 preferred
  • Cipher Suites: ECDHE-RSA-AES256-GCM-SHA384, ECDHE-RSA-AES128-GCM-SHA256
  • HSTS: Enabled with 1-year max-age
  • OCSP Stapling: Enabled

nginx-ingress TLS Configuration:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/ssl-protocols: "TLSv1.2 TLSv1.3"
    nginx.ingress.kubernetes.io/ssl-ciphers: "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256"

Secret Management

HashiCorp Vault

Vault Configuration:

  • Storage Backend: File system (PV-backed)
  • Seal Type: Shamir’s Secret Sharing
  • Auth Methods: Token, Kubernetes, LDAP
  • Secret Engines: KV v2, PKI, Transit

Vault Policies:

# Developer policy
path "secret/data/dev/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

# Production read-only
path "secret/data/prod/*" {
  capabilities = ["read", "list"]
}

SOPS Integration

SOPS Configuration:

# .sops.yaml
creation_rules:
  - path_regex: .*\.sops\.yaml$
    key_groups:
    - age:
      - age1abc123...

Encrypted Secret Example:

apiVersion: v1
kind: Secret
metadata:
  name: database-credentials
data:
  username: ENC[AES256_GCM,data:abc123...]
  password: ENC[AES256_GCM,data:def456...]

Network Security

Firewall Configuration

MikroTik Firewall Rules:

# Input chain - router protection
/ip firewall filter
add chain=input action=accept connection-state=established,related,untracked
add chain=input action=drop connection-state=invalid
add chain=input action=accept protocol=icmp
add chain=input action=accept dst-address=127.0.0.1
add chain=input action=drop in-interface-list=!LAN

# Forward chain - traffic filtering
add chain=forward action=accept connection-state=established,related,untracked
add chain=forward action=drop connection-state=invalid
add chain=forward action=drop connection-nat-state=!dstnat connection-state=new in-interface-list=WAN

Network Segmentation

VLAN Configuration:

  • Management: 10.0.0.0/24 (isolated)
  • Production: 192.168.1.0/24 (main)
  • IoT/Cameras: 192.168.20.0/24 (restricted)
  • Guest: 192.168.100.0/24 (internet-only)

Inter-VLAN Rules:

# Allow cameras to Home Assistant
/ip firewall filter add chain=forward action=accept src-address=192.168.20.0/24 dst-address=192.168.1.2 dst-port=8123 protocol=tcp

# Allow NTP for cameras
/ip firewall filter add chain=forward action=accept src-address=192.168.20.0/24 dst-port=123 protocol=udp

# Block cameras from main network
/ip firewall filter add chain=forward action=drop src-address=192.168.20.0/24 dst-address=192.168.1.0/24

Intrusion Detection

Monitoring Strategies:

  • Log Analysis: Centralized logging with Loki
  • Anomaly Detection: Prometheus metrics and alerts
  • Traffic Analysis: Flow-based monitoring
  • Behavioral Analysis: User activity patterns

Kubernetes Security

Pod Security Standards

Pod Security Policy:

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: restricted
spec:
  privileged: false
  allowPrivilegeEscalation: false
  requiredDropCapabilities:
    - ALL
  volumes:
    - 'configMap'
    - 'emptyDir'
    - 'projected'
    - 'secret'
    - 'downwardAPI'
    - 'persistentVolumeClaim'
  runAsUser:
    rule: 'MustRunAsNonRoot'
  seLinux:
    rule: 'RunAsAny'
  fsGroup:
    rule: 'RunAsAny'

Network Policies

Default Deny Policy:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

Service-Specific Policy:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: grafana-policy
spec:
  podSelector:
    matchLabels:
      app: grafana
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: ingress-nginx
    ports:
    - protocol: TCP
      port: 3000
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          name: prometheus
    ports:
    - protocol: TCP
      port: 9090

RBAC Configuration

Service Account Example:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: monitoring-sa
  namespace: monitoring
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: monitoring-reader
rules:
- apiGroups: [""]
  resources: ["nodes", "pods", "services", "endpoints"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["metrics.k8s.io"]
  resources: ["nodes", "pods"]
  verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: monitoring-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: monitoring-reader
subjects:
- kind: ServiceAccount
  name: monitoring-sa
  namespace: monitoring

Data Protection

Encryption at Rest

Storage Encryption:

  • TrueNAS: ZFS native encryption
  • Kubernetes: Encrypted etcd
  • Vault: Auto-unseal with encrypted storage

Database Encryption:

# PostgreSQL with encryption
apiVersion: v1
kind: ConfigMap
metadata:
  name: postgres-config
data:
  postgresql.conf: |
    ssl = on
    ssl_cert_file = '/etc/ssl/certs/server.crt'
    ssl_key_file = '/etc/ssl/private/server.key'
    ssl_ca_file = '/etc/ssl/certs/ca.crt'

Backup Security

Backup Encryption:

  • Encryption Key: AES-256 (stored in Vault)
  • Backup Integrity: SHA-256 checksums
  • Access Control: Separate backup user accounts

Backup Procedures:

  1. Application Quiesce: Consistent state capture
  2. Encryption: Client-side encryption before transmission
  3. Verification: Integrity checks on restore
  4. Retention: Encrypted long-term storage

Compliance & Auditing

Security Monitoring

Prometheus Metrics:

# Security-related metrics
- name: authentication_failures
  expr: increase(authelia_authentication_failures_total[5m])
  
- name: certificate_expiry
  expr: (cert_exporter_not_after - time()) / 86400
  
- name: failed_login_attempts
  expr: rate(nginx_ingress_controller_requests{status=~"401|403"}[5m])

Grafana Dashboards:

  • Authentication success/failure rates
  • Certificate expiration timeline
  • Network traffic anomalies
  • Security event correlation

Incident Response

Security Incident Playbook:

  1. Detection: Automated alerts and manual reporting
  2. Containment: Immediate isolation procedures
  3. Investigation: Log analysis and forensics
  4. Recovery: Service restoration procedures
  5. Lessons Learned: Post-incident review

Emergency Procedures:

# Disable user account
kubectl patch user $USERNAME -p '{"spec":{"disabled":true}}'

# Revoke certificates
kubectl delete secret tls-secret-name

# Block IP address
# Add to MikroTik firewall
/ip firewall address-list add list=blocked_ips address=X.X.X.X

Security Hardening

Host Hardening

Ubuntu Security Configuration:

# Automatic security updates
apt-get install unattended-upgrades
dpkg-reconfigure -plow unattended-upgrades

# Fail2ban for intrusion prevention
apt-get install fail2ban
systemctl enable fail2ban

# SSH hardening
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config

Container Security

Container Image Security:

  • Base Images: Minimal distributions (Alpine, distroless)
  • Vulnerability Scanning: Harbor with Trivy
  • Image Signing: Cosign integration
  • Runtime Security: Falco monitoring

Security Scanning:

# Trivy vulnerability scan
trivy image nginx:latest

# Container runtime security
kubectl apply -f falco-rules.yaml

Vulnerability Scanning & Assessment

OpenVAS (Greenbone Community Edition)

  • Purpose: Network vulnerability scanning and assessment
  • Access: openvas.home.dodwell.us
  • Schedule: Weekly scans every Sunday at 2 AM
  • Scope: 192.168.1.0/24 network (excluding critical infrastructure)
  • Login: admin / admin

Scanning Targets:

  • K3s cluster nodes (192.168.1.210-214)
  • HAProxy load balancer (192.168.1.200)
  • DNS servers and network services
  • All web application ingresses

Trivy Operator

  • Purpose: Kubernetes cluster and container security scanning
  • Integration: Native Kubernetes operator in trivy-system namespace
  • Schedule: Daily scans at 3 AM
  • Scope: All cluster workloads, configurations, and compliance

Scan Types:

  • Container image vulnerability scanning
  • Kubernetes configuration audit
  • Compliance reporting (NSA, CIS, PCI-DSS)
  • Runtime security monitoring

Security Reports Dashboard

Weekly Security Reports

Security scans generate automated reports that include:

  • Executive Summary: Critical findings and risk assessment
  • Action Items: Prioritized todo list for remediation
  • Compliance Status: Standards adherence (NSA, CIS, PCI-DSS)
  • Trend Analysis: Security posture improvements over time

Report Locations

Report TypeLocationFrequency
OpenVAS Network Scan/reports/openvas-weekly-YYYYMMDD.pdfWeekly
Trivy Cluster Scan/reports/trivy-cluster-YYYYMMDD.jsonDaily
Security Summary/reports/security-summary-YYYYMMDD.mdWeekly

Current Security Status

Security Metrics Dashboard:

Priority Security Actions

High Priority:

  • Review critical vulnerabilities from latest OpenVAS scan
  • Update container images with high-severity CVEs
  • Validate SSL certificate expiration dates
  • Audit RBAC permissions in Kubernetes

Medium Priority:

  • Review Authelia access logs for anomalies
  • Update system packages on all nodes
  • Verify backup encryption integrity
  • Test incident response procedures

Low Priority:

  • Review and update security documentation
  • Optimize security scanning schedules
  • Enhance monitoring alert thresholds
  • Conduct security awareness training

Security Tools Access

ToolURLPurposeAuth Method
OpenVASopenvas.home.dodwell.usNetwork vulnerability scanningAuthelia + local
Trivy ReportsK8s clusterContainer/K8s security scanningkubectl access
Grafana Securitygrafana.home.dodwell.usSecurity metrics and dashboardsAuthelia OIDC
Autheliaauth.home.dodwell.usAuthentication and access controlLDAP
Harbor Securityharbor.home.dodwell.usContainer image scanningAuthelia OIDC

Emergency Security Procedures

Critical Vulnerability Response

  1. Assess Impact: Determine affected systems and severity
  2. Containment: Isolate vulnerable systems if necessary
  3. Patch/Mitigate: Apply security updates or workarounds
  4. Verify Fix: Re-scan to confirm vulnerability resolution
  5. Document: Update security documentation and lessons learned

Security Incident Response

  1. Identify: Detect and analyze the security incident
  2. Contain: Isolate affected systems and prevent spread
  3. Eradicate: Remove the threat and close attack vectors
  4. Recover: Restore normal operations safely
  5. Lessons: Conduct post-incident review and improvements

Emergency Contacts

  • Security Lead: Available 24/7 for critical incidents
  • Infrastructure Team: On-call rotation for system issues
  • External Support: Security vendor contacts for escalation

Security Documentation References