Skip to main content

KALNET Security Guide

Overview

This document describes the security architecture and best practices for KALNET deployment. Security is implemented in layers:
  1. Network Security - Firewall rules, network isolation
  2. Container Security - Docker hardening, resource limits
  3. Authentication - Service access controls
  4. Secrets Management - Credential handling
  5. TLS/Encryption - Data in transit protection

Quick Start

# 1. Initialize security settings
./security/init-security.sh --check   # Audit current state
./security/init-security.sh --fix     # Auto-fix issues

# 2. Configure secrets
cp .secrets.example .secrets
chmod 600 .secrets
# Edit .secrets with your values

# 3. Apply firewall rules
./security/firewall-rules.sh --apply

Security Architecture

Figure 1 — KALNET Security Architecture. Internet traffic passes through the firewall (UFW/nftables), which restricts access to ports 80 and 443. Traefik terminates TLS, enforces rate limits, and adds security headers before forwarding to the Docker network. Each container runs with hardened settings: no-new-privileges, read-only mounts, and resource limits.
Trace IDRequirementRationaleTest Case
KALNET-SEC-001All public-facing traffic shall pass through Traefik with TLS termination and security headersCentralises security policy and prevents direct container access from the internetTC-KALNET-SEC-001
KALNET-SEC-002All containers shall run with no-new-privileges and resource limitsMitigates container-escape and denial-of-service risksTC-KALNET-SEC-002
KALNET-SEC-003Samba ports (139, 445) shall be restricted to LAN traffic onlyPrevents SMB exposure to the internetTC-KALNET-SEC-003

1. Network Security

Firewall Configuration

KALNET uses UFW (Uncomplicated Firewall) for network access control:
# View current rules
./security/firewall-rules.sh

# Apply KALNET rules
./security/firewall-rules.sh --apply

Port Matrix

PortProtocolAccessServiceNotes
22TCPLANSSHRemote management
80TCPPublicHTTPRedirects to HTTPS
443TCPPublicHTTPSMain entry point
139TCPLANSambaNetBIOS
445TCPLANSambaSMB direct
8080TCPLANTraefikDashboard
9090TCPLANMetricsPrometheus endpoint

Docker/UFW Compatibility

Docker manipulates iptables directly, which can bypass UFW rules. Apply the Docker UFW fix:
./security/firewall-rules.sh --docker
This adds DOCKER-USER chain rules to ensure UFW policies are respected.

Network Isolation

Services communicate via an isolated Docker bridge network:
networks:
  kalnet:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/16
Best Practices:
  • Services only expose ports to Traefik, not the host
  • Samba is an exception (SMB can’t be HTTP-proxied)
  • Inter-service communication uses container names

2. Container Security

Security Options

All containers should include these security options:
services:
  example:
    security_opt:
      - no-new-privileges:true    # Prevent privilege escalation
    cap_drop:
      - ALL                        # Drop all capabilities
    cap_add:
      - CHOWN                      # Add only what's needed
      - SETUID
      - SETGID
    read_only: true                # Read-only root filesystem
    tmpfs:
      - /tmp                       # Writable temp directories
      - /run

Resource Limits

Prevent resource exhaustion with deploy limits:
deploy:
  resources:
    limits:
      cpus: '1.0'
      memory: 512M
    reservations:
      cpus: '0.25'
      memory: 128M

Non-Root Users

Containers should run as non-root users:
environment:
  - PUID=1000
  - PGID=1000
user: "1000:1000"

Image Security

  • Use specific image tags, not latest
  • Prefer minimal base images (Alpine)
  • Regularly update images: docker-compose pull && docker-compose up -d
  • Scan images: docker scan <image>

3. Authentication

Current State (TASKSET 2)

Individual service authentication:
  • Jellyfin: Built-in user accounts
  • n8n: Basic auth via environment variables
  • Traefik Dashboard: IP whitelist (LAN only)
  • Samba: Unix user authentication

Future State (TASKSET 4+)

Centralized SSO with Authelia:
  • Single sign-on for all web services
  • 2FA/MFA support
  • LDAP integration for user management

Traefik Basic Auth

For services without built-in auth, use Traefik middleware:
# In traefik/dynamic.yml
http:
  middlewares:
    basic-auth:
      basicAuth:
        users:
          # Generate with: htpasswd -nb user password
          - "admin:$apr1$xyz..."

4. Secrets Management

File-Based Secrets

Secrets are stored in .secrets file:
# Setup
cp .secrets.example .secrets
chmod 600 .secrets

# Use
source .secrets
docker-compose -f docker-compose.prod.yml up -d

Docker Secrets (Alternative)

For swarm mode or enhanced security:
secrets:
  db_password:
    file: ./secrets/db_password.txt

services:
  database:
    secrets:
      - db_password

Secret Rotation

  1. Generate new secret
  2. Update .secrets file
  3. Restart affected service
  4. Verify functionality
  5. Remove old secret from any backups

What NOT to Do

  • Store secrets in .env (may be logged)
  • Commit secrets to git
  • Use default passwords
  • Share secrets between services

5. TLS/Encryption

Certificate Management

Traefik handles TLS with Let’s Encrypt:
# traefik/traefik.yml
certificatesResolvers:
  letsencrypt:
    acme:
      email: "${ACME_EMAIL}"
      storage: /etc/traefik/acme/acme.json
      httpChallenge:
        entryPoint: web

Self-Signed Certificates (Development)

For local development without public DNS:
# Generate self-signed cert
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout traefik/certs/kalnet.key \
  -out traefik/certs/kalnet.crt \
  -subj "/CN=*.localhost"

chmod 600 traefik/certs/kalnet.key

TLS Best Practices

  • Minimum TLS 1.2 (configured in Traefik)
  • Strong cipher suites
  • HSTS headers enabled
  • Certificate pinning for mobile apps

6. Security Hardening Checklist

Initial Setup

  • Run ./security/init-security.sh --fix
  • Configure .secrets file
  • Apply firewall rules
  • Generate/obtain TLS certificates
  • Set strong passwords for all services

Ongoing

  • Weekly: docker-compose pull to update images
  • Monthly: Review access logs
  • Quarterly: Rotate secrets
  • As needed: Security patches

Audit

# Full security audit
./security/init-security.sh --check

# Check for exposed ports
ss -tlnp | grep -E ':(80|443|445|8080|9090)'

# Check container security
docker inspect --format='{{.HostConfig.SecurityOpt}}' kalnet-jellyfin

# Check for outdated images
docker images --format "{{.Repository}}:{{.Tag}} {{.CreatedSince}}"

7. Incident Response

If Compromised

  1. Isolate: docker-compose down
  2. Preserve: Copy logs before wiping
  3. Investigate: Check access logs, container logs
  4. Remediate: Identify entry point, patch vulnerability
  5. Recover: Restore from clean backup
  6. Rotate: All secrets, certificates, passwords

Log Locations

# Container logs
docker logs kalnet-traefik
docker logs kalnet-jellyfin

# Host firewall logs
sudo journalctl -u ufw

# Access logs
/srv/kalnet/logs/traefik/access.log

Emergency Contacts

Configure in .secrets:
ALERT_EMAIL=admin@example.com
ALERT_PHONE=+1234567890

8. Compliance Notes

Home Use

For personal/home use, this security configuration provides:
  • Protection from casual attacks
  • Network isolation between services
  • Basic access logging
  • Encrypted external access

NOT Suitable For

  • Healthcare (HIPAA)
  • Payment processing (PCI-DSS)
  • Enterprise production
  • Multi-tenant environments
  • firewall-rules.sh - Firewall configuration script
  • init-security.sh - Security initialization script
  • .secrets.example - Secrets template
  • ../traefik/dynamic.yml - Security middleware configuration