Skip to content

Security Hardening Guide

Critical Security Issues

1. World-Readable .env Files (HIGH PRIORITY)

Current Issue: Several .env files have permissions 644 (world-readable), exposing sensitive credentials.

# Files with incorrect permissions:
-rw-r--r-- 1 root root /srv/dockerdata/supabase/.env
-rw-r--r-- 1 root root /srv/dockerdata/supabase/supabase.env

Immediate Fix Required:

# Fix all .env file permissions
find /srv/dockerdata -name "*.env" -type f -exec chmod 640 {} \;
find /srv/dockerdata -name "*.env" -type f -exec chown root:docker {} \;

# Verify fixes
find /srv/dockerdata -name "*.env" -type f -exec ls -la {} \;

2. Implement Security Audit Script

# Create security audit script
cat > /srv/dockerdata/_scripts/security-audit.sh << 'EOF'
#!/bin/bash
set -euo pipefail

REPORT_FILE="/var/log/security-audit-$(date +%Y%m%d).log"
ERRORS=0

echo "=== Docker Security Audit Report ===" | tee "$REPORT_FILE"
echo "Date: $(date)" | tee -a "$REPORT_FILE"
echo "" | tee -a "$REPORT_FILE"

# Check .env file permissions
echo "## Checking .env file permissions..." | tee -a "$REPORT_FILE"
while IFS= read -r -d '' file; do
    perms=$(stat -c %a "$file")
    owner=$(stat -c %U:%G "$file")
    if [[ $perms -gt 640 ]]; then
        echo "❌ CRITICAL: $file has permissions $perms (should be 640 or less)" | tee -a "$REPORT_FILE"
        ((ERRORS++))
    else
        echo "✓ $file: $perms $owner" | tee -a "$REPORT_FILE"
    fi
done < <(find /srv/dockerdata -name "*.env" -type f -print0)

# Check for exposed ports
echo -e "\n## Checking for exposed ports..." | tee -a "$REPORT_FILE"
docker ps --format "table {{.Names}}\t{{.Ports}}" | grep -E "0\.0\.0\.0:" | while read line; do
    if ! echo "$line" | grep -q "traefik"; then
        echo "⚠️  WARNING: $line" | tee -a "$REPORT_FILE"
    fi
done

# Check for containers running as root
echo -e "\n## Checking for containers running as root..." | tee -a "$REPORT_FILE"
docker ps -q | while read container; do
    user=$(docker inspect "$container" --format '{{.Config.User}}')
    name=$(docker inspect "$container" --format '{{.Name}}' | sed 's/^\/\+//')
    if [[ -z "$user" || "$user" == "root" ]]; then
        echo "⚠️  WARNING: Container '$name' running as root" | tee -a "$REPORT_FILE"
    fi
done

# Check for unused Docker resources
echo -e "\n## Checking for unused Docker resources..." | tee -a "$REPORT_FILE"
dangling_images=$(docker images -f "dangling=true" -q | wc -l)
dangling_volumes=$(docker volume ls -f "dangling=true" -q | wc -l)
echo "Dangling images: $dangling_images" | tee -a "$REPORT_FILE"
echo "Dangling volumes: $dangling_volumes" | tee -a "$REPORT_FILE"

# Check SSL certificates
echo -e "\n## Checking SSL certificates..." | tee -a "$REPORT_FILE"
if [[ -f /srv/dockerdata/traefik/letsencrypt/acme.json ]]; then
    perms=$(stat -c %a /srv/dockerdata/traefik/letsencrypt/acme.json)
    if [[ $perms != "600" ]]; then
        echo "❌ CRITICAL: acme.json has permissions $perms (should be 600)" | tee -a "$REPORT_FILE"
        ((ERRORS++))
    else
        echo "✓ acme.json permissions correct (600)" | tee -a "$REPORT_FILE"
    fi
fi

# Check for default passwords
echo -e "\n## Checking for common default passwords..." | tee -a "$REPORT_FILE"
grep -r "password\|secret\|changeme\|admin\|test\|demo" /srv/dockerdata/*.env 2>/dev/null | \
    grep -v "POSTGRES_PASSWORD\|JWT_SECRET\|ANON_KEY\|SERVICE_ROLE_KEY" | \
    while read line; do
        echo "⚠️  Potential default password: $line" | tee -a "$REPORT_FILE"
    done

# Summary
echo -e "\n## Summary" | tee -a "$REPORT_FILE"
if [[ $ERRORS -eq 0 ]]; then
    echo "✓ No critical security issues found" | tee -a "$REPORT_FILE"
else
    echo "❌ Found $ERRORS critical security issues!" | tee -a "$REPORT_FILE"
    exit 1
fi
EOF

chmod +x /srv/dockerdata/_scripts/security-audit.sh

# Run initial audit
/srv/dockerdata/_scripts/security-audit.sh

Git Repository Security

Dual Repository Architecture

We maintain a secure dual-repository system that balances operational needs with public security:

  1. Gitea (Primary Repository)
  2. Self-hosted on our infrastructure
  3. Contains full Git history including sensitive files (.env, certificates, etc.)
  4. Provides complete version control for configuration management
  5. Accessible only through VPN or authenticated access
  6. Used by internal team for development and operations

  7. GitHub (Public Mirror)

  8. Automatically synced from Gitea with comprehensive filtering
  9. All sensitive files removed from entire Git history using git-filter-repo
  10. Secure for public access and open-source collaboration
  11. Force pushes are expected and normal due to history rewriting
  12. Read-only mirror - development happens on Gitea

Secret Detection and Filtering

The sync process uses industry-standard secret detection patterns from: - Gitleaks: Comprehensive regex-based secret scanning - TruffleHog: Entropy analysis and verified secret detection - detect-secrets: Baseline-based secret prevention - Custom patterns: Infrastructure-specific secret formats

Security Verification Process

Before any code reaches GitHub: 1. Complete Git history is cloned from Gitea 2. git-filter-repo removes all sensitive files from every commit 3. Comprehensive secret scanning verifies the cleaned repository 4. Only after passing all checks is the code pushed to GitHub

This ensures that secrets never exist in the public repository, not even in historical commits.

Secrets Management

1. Docker Secrets Setup

# Initialize Docker Swarm (if not already)
docker swarm init

# Create secrets from environment variables
cat > /srv/dockerdata/_scripts/create-secrets.sh << 'EOF'
#!/bin/bash
set -euo pipefail

# Function to create secret if it doesn't exist
create_secret() {
    local name=$1
    local value=$2

    if ! docker secret ls | grep -q "^$name "; then
        echo "$value" | docker secret create "$name" -
        echo "✓ Created secret: $name"
    else
        echo "- Secret already exists: $name"
    fi
}

# Load current environment variables
source /srv/dockerdata/supabase/supabase.env

# Create Docker secrets
create_secret "postgres_password" "$POSTGRES_PASSWORD"
create_secret "jwt_secret" "$JWT_SECRET"
create_secret "anon_key" "$ANON_KEY"
create_secret "service_role_key" "$SERVICE_ROLE_KEY"
create_secret "supabase_admin_password" "$DASHBOARD_PASSWORD"

# Traefik secrets
if [[ -f /srv/dockerdata/traefik/.env ]]; then
    source /srv/dockerdata/traefik/.env
    create_secret "cf_api_email" "$CF_API_EMAIL"
    create_secret "cf_dns_api_token" "$CF_DNS_API_TOKEN"
fi

echo -e "\n✓ Secrets created. List all secrets:"
docker secret ls
EOF

chmod +x /srv/dockerdata/_scripts/create-secrets.sh

2. Migrate to Docker Secrets

# Example: Update Supabase to use secrets
version: '3.8'

services:
  db:
    image: supabase/postgres:15.8.1.122
    secrets:
      - postgres_password
    environment:
      POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password

secrets:
  postgres_password:
    external: true

3. HashiCorp Vault Integration (Advanced)

# Deploy Vault for production secrets management
cat > /srv/dockerdata/vault/docker-compose.yml << 'EOF'
version: '3.8'

services:
  vault:
    image: hashicorp/vault:latest
    container_name: vault
    restart: unless-stopped
    cap_add:
      - IPC_LOCK
    environment:
      VAULT_DEV_ROOT_TOKEN_ID: myroot
      VAULT_DEV_LISTEN_ADDRESS: 0.0.0.0:8200
    volumes:
      - vault_data:/vault/data
      - ./config:/vault/config
    networks:
      - secure
    command: server

volumes:
  vault_data:

networks:
  secure:
    driver: bridge
    internal: true
EOF

Network Security

1. Implement Network Segmentation

# Create isolated networks
docker network create --internal internal_db
docker network create --internal internal_cache
docker network create dmz

# Update docker-compose files to use appropriate networks
# Example for Supabase:
cat > /srv/dockerdata/supabase/network-update.yml << 'EOF'
services:
  db:
    networks:
      - internal_db
    # Remove from traefik_proxy

  supabase-auth:
    networks:
      - internal_db
      - dmz

  supabase-rest:
    networks:
      - internal_db
      - dmz
      - traefik_proxy

networks:
  internal_db:
    external: true
  dmz:
    external: true
  traefik_proxy:
    external: true
EOF

2. Implement Firewall Rules

# Install UFW if not present
sudo apt-get update && sudo apt-get install -y ufw

# Configure UFW
cat > /srv/dockerdata/_scripts/setup-firewall.sh << 'EOF'
#!/bin/bash
set -euo pipefail

# Default policies
ufw default deny incoming
ufw default allow outgoing

# Allow SSH (adjust port as needed)
ufw allow 22/tcp comment "SSH"

# Allow HTTP/HTTPS
ufw allow 80/tcp comment "HTTP"
ufw allow 443/tcp comment "HTTPS"

# Docker management (localhost only)
ufw allow from 127.0.0.1 to any port 2375 comment "Docker API"
ufw allow from 127.0.0.1 to any port 2376 comment "Docker TLS"

# Internal services (do not expose)
# PostgreSQL - internal only
ufw deny 5432/tcp comment "Block PostgreSQL"

# Monitoring (internal only)
ufw allow from 10.0.0.0/8 to any port 9090 comment "Prometheus"
ufw allow from 10.0.0.0/8 to any port 3000 comment "Grafana"

# Enable firewall
ufw --force enable

# Show status
ufw status verbose
EOF

chmod +x /srv/dockerdata/_scripts/setup-firewall.sh

3. Network Policies

# Example: Restrict database access
version: '3.8'

services:
  db:
    networks:
      backend:
        aliases:
          - postgres
    deploy:
      endpoint_mode: dnsrr

  app:
    networks:
      - frontend
      - backend
    depends_on:
      - db

networks:
  frontend:
    external: true
  backend:
    driver: bridge
    internal: true
    driver_opts:
      com.docker.network.bridge.enable_icc: "false"

SSL/TLS Configuration

1. Strengthen TLS Configuration

# Update Traefik static configuration
cat >> /srv/dockerdata/traefik/traefik.yml << 'EOF'

# TLS Options
tls:
  options:
    default:
      minVersion: VersionTLS12
      cipherSuites:
        - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
      curvePreferences:
        - secp521r1
        - secp384r1
      sniStrict: true

    strict:
      minVersion: VersionTLS13
EOF

2. Certificate Monitoring

# Certificate expiry monitoring script
cat > /srv/dockerdata/_scripts/check-certificates.sh << 'EOF'
#!/bin/bash
set -euo pipefail

DAYS_WARNING=30
ALERT_EMAIL="[email protected]"

check_cert() {
    local domain=$1
    local port=${2:-443}

    expiry=$(echo | openssl s_client -servername "$domain" -connect "$domain:$port" 2>/dev/null | \
             openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)

    if [[ -n "$expiry" ]]; then
        expiry_epoch=$(date -d "$expiry" +%s)
        current_epoch=$(date +%s)
        days_left=$(( (expiry_epoch - current_epoch) / 86400 ))

        if [[ $days_left -lt $DAYS_WARNING ]]; then
            echo "⚠️  WARNING: $domain certificate expires in $days_left days"
            # Send alert
            echo "Certificate for $domain expires in $days_left days" | \
                mail -s "Certificate Expiry Warning" "$ALERT_EMAIL"
        else
            echo "✓ $domain: $days_left days until expiry"
        fi
    else
        echo "❌ ERROR: Could not check certificate for $domain"
    fi
}

# Check all domains
check_cert "supabase.rbnk.uk"
check_cert "grafana.rbnk.uk"
check_cert "traefik.rbnk.uk"
EOF

chmod +x /srv/dockerdata/_scripts/check-certificates.sh

# Add to cron
echo "0 9 * * * /srv/dockerdata/_scripts/check-certificates.sh" | crontab -

Container Security

1. Security Scanning

# Install Trivy for vulnerability scanning
cat > /srv/dockerdata/_scripts/scan-images.sh << 'EOF'
#!/bin/bash
set -euo pipefail

# Install Trivy if not present
if ! command -v trivy &> /dev/null; then
    wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -
    echo "deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | \
        sudo tee /etc/apt/sources.list.d/trivy.list
    sudo apt-get update && sudo apt-get install -y trivy
fi

REPORT_DIR="/var/log/security-scans"
mkdir -p "$REPORT_DIR"

echo "=== Scanning Docker Images for Vulnerabilities ==="

# Scan all running containers
docker ps --format "{{.Image}}" | sort -u | while read image; do
    echo "Scanning: $image"
    report_file="$REPORT_DIR/$(echo $image | tr '/:' '_')-$(date +%Y%m%d).json"

    trivy image --format json --output "$report_file" "$image" || true

    # Check for critical vulnerabilities
    critical=$(jq '[.Results[].Vulnerabilities[]? | select(.Severity=="CRITICAL")] | length' "$report_file")
    high=$(jq '[.Results[].Vulnerabilities[]? | select(.Severity=="HIGH")] | length' "$report_file")

    if [[ $critical -gt 0 ]]; then
        echo "❌ CRITICAL: Found $critical critical vulnerabilities in $image"
    elif [[ $high -gt 0 ]]; then
        echo "⚠️  WARNING: Found $high high severity vulnerabilities in $image"
    else
        echo "✓ No critical/high vulnerabilities found"
    fi
done

# Generate summary report
echo -e "\n=== Vulnerability Summary ===" > "$REPORT_DIR/summary-$(date +%Y%m%d).txt"
for report in "$REPORT_DIR"/*.json; do
    [[ -f "$report" ]] || continue
    image=$(basename "$report" .json | tr '_' '/')
    critical=$(jq '[.Results[].Vulnerabilities[]? | select(.Severity=="CRITICAL")] | length' "$report")
    high=$(jq '[.Results[].Vulnerabilities[]? | select(.Severity=="HIGH")] | length' "$report")
    echo "$image - Critical: $critical, High: $high" >> "$REPORT_DIR/summary-$(date +%Y%m%d).txt"
done

cat "$REPORT_DIR/summary-$(date +%Y%m%d).txt"
EOF

chmod +x /srv/dockerdata/_scripts/scan-images.sh

2. Runtime Security

# Add security options to containers
version: '3.8'

services:
  app:
    image: myapp:latest
    security_opt:
      - no-new-privileges:true
      - apparmor:docker-default
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE
    read_only: true
    tmpfs:
      - /tmp
      - /var/run
    user: "1000:1000"

3. Docker Daemon Hardening

# Update Docker daemon configuration
cat > /etc/docker/daemon.json << 'EOF'
{
  "icc": false,
  "userland-proxy": false,
  "no-new-privileges": true,
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  },
  "live-restore": true,
  "userland-proxy": false,
  "experimental": false,
  "features": {
    "buildkit": true
  },
  "metrics-addr": "127.0.0.1:9323"
}
EOF

# Restart Docker
sudo systemctl restart docker

API Key and Authentication Management

LiteLLM Virtual Keys Implementation

Our LiteLLM deployment uses Virtual Keys for enhanced security and cost tracking. This system provides:

  • Individual Budget Limits: Each service has its own budget ($5-$20/month)
  • Real-time Cost Tracking: Monitor usage and costs per service
  • Security Isolation: Services cannot access each other's usage data
  • Automated Alerting: Get notified when approaching budget limits

For complete implementation details, setup procedures, and management commands, see: LiteLLM Virtual Keys Implementation

Access Control

1. Implement RBAC

# Create user groups
sudo groupadd docker-readonly
sudo groupadd docker-admin

# Create restricted sudo rules
cat > /etc/sudoers.d/docker-access << 'EOF'
# Docker read-only access
%docker-readonly ALL=(ALL) NOPASSWD: /usr/bin/docker ps*, /usr/bin/docker logs*, /usr/bin/docker inspect*

# Docker admin access
%docker-admin ALL=(ALL) NOPASSWD: /usr/bin/docker *

# Deny direct database access
%docker-readonly ALL=(ALL) !/usr/bin/docker exec * psql *
%docker-readonly ALL=(ALL) !/usr/bin/docker exec * mysql *
EOF

2. Authentication Middleware

# Add to Traefik dynamic configuration
cat > /srv/dockerdata/traefik/dynamic/auth.yml << 'EOF'
http:
  middlewares:
    auth:
      basicAuth:
        users:
          - "admin:$2y$10$..."  # htpasswd -nB admin
        realm: "Restricted Area"

    oauth:
      forwardAuth:
        address: "http://oauth-proxy:4181"
        trustForwardHeader: true
        authResponseHeaders:
          - "X-Forwarded-User"

    rate-limit:
      rateLimit:
        average: 100
        burst: 200
        period: 1m

    security-headers:
      headers:
        sslRedirect: true
        stsSeconds: 31536000
        stsIncludeSubdomains: true
        stsPreload: true
        forceSTSHeader: true
        contentTypeNosniff: true
        browserXssFilter: true
        referrerPolicy: "same-origin"
        featurePolicy: "geolocation 'none'; microphone 'none'; camera 'none'"
        customResponseHeaders:
          X-Robots-Tag: "noindex,nofollow,nosnippet,noarchive,notranslate,noimageindex"
EOF

Security Monitoring

1. Audit Logging

# Enable Docker audit logging
cat > /srv/dockerdata/_scripts/enable-audit-logging.sh << 'EOF'
#!/bin/bash
set -euo pipefail

# Install auditd if not present
sudo apt-get update && sudo apt-get install -y auditd

# Add Docker audit rules
cat >> /etc/audit/rules.d/docker.rules << 'AUDIT'
# Docker daemon
-w /usr/bin/dockerd -k docker
-w /usr/bin/docker -k docker
-w /var/lib/docker -k docker
-w /etc/docker -k docker

# Container runtime
-w /usr/bin/docker-containerd -k docker
-w /usr/bin/docker-runc -k docker

# Docker service
-w /lib/systemd/system/docker.service -k docker
-w /lib/systemd/system/docker.socket -k docker

# Docker config files
-w /etc/default/docker -k docker
-w /etc/docker/daemon.json -k docker
AUDIT

# Restart auditd
sudo service auditd restart

# Verify rules loaded
sudo auditctl -l | grep docker
EOF

chmod +x /srv/dockerdata/_scripts/enable-audit-logging.sh

2. Intrusion Detection

# Deploy Falco for runtime security
version: '3.8'

services:
  falco:
    image: falcosecurity/falco:latest
    container_name: falco
    privileged: true
    volumes:
      - /var/run/docker.sock:/host/var/run/docker.sock
      - /dev:/host/dev
      - /proc:/host/proc:ro
      - /boot:/host/boot:ro
      - /lib/modules:/host/lib/modules:ro
      - ./falco/rules:/etc/falco/rules.d
    environment:
      - SKIP_DRIVER_LOADER=false

Security Checklist

Daily Tasks

  • [ ] Review security audit logs
  • [ ] Check for failed authentication attempts
  • [ ] Monitor resource usage for anomalies
  • [ ] Verify all services are running expected versions

Weekly Tasks

  • [ ] Run vulnerability scans on all images
  • [ ] Review and update access controls
  • [ ] Check certificate expiration dates
  • [ ] Audit user access and permissions
  • [ ] Review firewall rules

Monthly Tasks

  • [ ] Full security audit using audit script
  • [ ] Update all container images
  • [ ] Review and rotate secrets
  • [ ] Test backup restoration
  • [ ] Security training/awareness

Quarterly Tasks

  • [ ] Penetration testing
  • [ ] Review security policies
  • [ ] Update incident response plan
  • [ ] Compliance audit

Incident Response

1. Incident Response Plan

# Create incident response script
cat > /srv/dockerdata/_scripts/incident-response.sh << 'EOF'
#!/bin/bash
set -euo pipefail

INCIDENT_ID=$(date +%Y%m%d%H%M%S)
INCIDENT_DIR="/var/log/incidents/$INCIDENT_ID"

mkdir -p "$INCIDENT_DIR"

echo "=== Incident Response Started: $INCIDENT_ID ==="

# Collect system state
docker ps -a > "$INCIDENT_DIR/docker-ps.txt"
docker images > "$INCIDENT_DIR/docker-images.txt"
netstat -tulpn > "$INCIDENT_DIR/netstat.txt"
ps auxf > "$INCIDENT_DIR/processes.txt"

# Collect logs
docker logs --since 24h traefik > "$INCIDENT_DIR/traefik.log" 2>&1
journalctl --since "24 hours ago" > "$INCIDENT_DIR/system.log"

# Network connections
ss -tupn > "$INCIDENT_DIR/connections.txt"

# Check for suspicious files
find /srv/dockerdata -type f -mtime -1 -ls > "$INCIDENT_DIR/recent-files.txt"

echo "Incident data collected in: $INCIDENT_DIR"
EOF

chmod +x /srv/dockerdata/_scripts/incident-response.sh

2. Automated Response

# Automatic containment script
cat > /srv/dockerdata/_scripts/contain-threat.sh << 'EOF'
#!/bin/bash
set -euo pipefail

CONTAINER=$1

if [[ -z "$CONTAINER" ]]; then
    echo "Usage: $0 <container_name>"
    exit 1
fi

echo "⚠️  Containing potential threat in container: $CONTAINER"

# Disconnect from networks
docker network disconnect traefik_proxy "$CONTAINER" || true

# Stop container
docker stop "$CONTAINER"

# Create forensic copy
docker commit "$CONTAINER" "forensic/$CONTAINER:$(date +%Y%m%d%H%M%S)"

# Collect logs
docker logs "$CONTAINER" > "/var/log/incidents/$CONTAINER-$(date +%Y%m%d%H%M%S).log"

echo "✓ Container contained and evidence preserved"
EOF

chmod +x /srv/dockerdata/_scripts/contain-threat.sh

Compliance and Reporting

Generate Security Report

cat > /srv/dockerdata/_scripts/security-report.sh << 'EOF'
#!/bin/bash
set -euo pipefail

REPORT_FILE="/var/log/security-report-$(date +%Y%m).html"

cat > "$REPORT_FILE" << 'HTML'
<!DOCTYPE html>
<html>
<head>
    <title>Security Report</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 20px; }
        .pass { color: green; }
        .fail { color: red; }
        .warn { color: orange; }
        table { border-collapse: collapse; width: 100%; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #f2f2f2; }
    </style>
</head>
<body>
    <h1>Monthly Security Report</h1>
    <p>Generated: $(date)</p>
HTML

# Add audit results
echo "<h2>Security Audit Results</h2>" >> "$REPORT_FILE"
/srv/dockerdata/_scripts/security-audit.sh >> "$REPORT_FILE" 2>&1

# Add vulnerability scan results
echo "<h2>Vulnerability Scan Summary</h2>" >> "$REPORT_FILE"
if [[ -f /var/log/security-scans/summary-*.txt ]]; then
    echo "<pre>" >> "$REPORT_FILE"
    cat /var/log/security-scans/summary-*.txt >> "$REPORT_FILE"
    echo "</pre>" >> "$REPORT_FILE"
fi

echo "</body></html>" >> "$REPORT_FILE"

echo "Security report generated: $REPORT_FILE"
EOF

chmod +x /srv/dockerdata/_scripts/security-report.sh

Quick Security Fixes

# Run this script to apply immediate security fixes
cat > /srv/dockerdata/_scripts/quick-security-fix.sh << 'EOF'
#!/bin/bash
set -euo pipefail

echo "=== Applying Quick Security Fixes ==="

# 1. Fix file permissions
echo "Fixing .env file permissions..."
find /srv/dockerdata -name "*.env" -type f -exec chmod 640 {} \;
find /srv/dockerdata -name "*.env" -type f -exec chown root:docker {} \;

# 2. Fix certificate permissions
if [[ -f /srv/dockerdata/traefik/letsencrypt/acme.json ]]; then
    chmod 600 /srv/dockerdata/traefik/letsencrypt/acme.json
fi

# 3. Remove unnecessary packages from containers
docker image prune -f

# 4. Update all containers to latest versions
echo "Pulling latest images..."
for compose in /srv/dockerdata/*/docker-compose.yml; do
    dir=$(dirname "$compose")
    cd "$dir"
    docker compose pull
done

echo "✓ Quick security fixes applied"
echo "⚠️  Remember to restart services to apply updates"
EOF

chmod +x /srv/dockerdata/_scripts/quick-security-fix.sh

# Run it immediately
/srv/dockerdata/_scripts/quick-security-fix.sh