Zum Inhalt

Security Best Practices

Overview

This guide covers security hardening for production deployments of Solar-Log Enterprise.

Authentication & Authorization

JWT Implementation (Coming Soon)

# backend/app/auth/jwt.py
from datetime import datetime, timedelta
from jose import JWTError, jwt
from passlib.context import CryptContext

SECRET_KEY = "your-secret-key-32-chars-minimum"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

def create_access_token(data: dict):
    to_encode = data.copy()
    expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    to_encode.update({"exp": expire})
    return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)

Password Hashing

def hash_password(password: str) -> str:
    return pwd_context.hash(password)

def verify_password(plain_password: str, hashed_password: str) -> bool:
    return pwd_context.verify(plain_password, hashed_password)

Network Security

Firewall Rules (UFW)

# Enable UFW
sudo ufw enable

# SSH (change port from 22 if possible)
sudo ufw allow 22/tcp

# HTTP/HTTPS only
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# Deny all other incoming
sudo ufw default deny incoming
sudo ufw default allow outgoing

# Check status
sudo ufw status verbose

Fail2Ban Configuration

# Install
sudo apt install fail2ban

# Configure
sudo nano /etc/fail2ban/jail.local
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5

[sshd]
enabled = true
port = 22
logpath = /var/log/auth.log

[nginx-limit-req]
enabled = true
filter = nginx-limit-req
logpath = /var/log/nginx/error.log

SSL/TLS Configuration

Let's Encrypt (Certbot)

# Install
sudo apt install certbot python3-certbot-nginx

# Generate certificate
sudo certbot --nginx -d solarlog.karma.organic

# Auto-renewal test
sudo certbot renew --dry-run

Nginx SSL Hardening

# /etc/nginx/sites-available/solarlog

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;

# HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

# Other security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;

Docker Security

Container Hardening

# docker-compose.yml
services:
  backend:
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE
    read_only: true
    tmpfs:
      - /tmp
      - /var/run
    user: "1000:1000"

Image Scanning

# Scan for vulnerabilities
docker scan solarlog-backend:latest
docker scan solarlog-frontend:latest

# Use Trivy
trivy image solarlog-backend:latest

Database Security

PostgreSQL Hardening

# Change default passwords
docker compose exec postgres psql -U postgres -c "ALTER USER solarlog WITH PASSWORD 'new-strong-password';"

# Restrict connections
# postgresql.conf
listen_addresses = 'localhost,172.20.0.0/16'
ssl = on
password_encryption = scram-sha-256

Backup Encryption

# Encrypt backup
pg_dump -U solarlog solarlog | gpg -e -r admin@example.com > backup.sql.gpg

# Decrypt
gpg -d backup.sql.gpg | psql -U solarlog solarlog

Secrets Management

Environment Variables

# Never commit .env files!
echo ".env" >> .gitignore
echo ".env.production" >> .gitignore

# Generate strong secrets
openssl rand -hex 32  # SECRET_KEY
openssl rand -base64 16  # DB_PASSWORD

Docker Secrets (Swarm)

# docker-compose.yml
secrets:
  db_password:
    file: ./secrets/db_password.txt
  secret_key:
    file: ./secrets/secret_key.txt

services:
  backend:
    secrets:
      - db_password
      - secret_key
    environment:
      SECRET_KEY_FILE: /run/secrets/secret_key

Rate Limiting

Nginx Rate Limiting

# Limit requests
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;

server {
    location /api {
        limit_req zone=api_limit burst=20 nodelay;
        limit_req_status 429;
    }
}

FastAPI Rate Limiting

from slowapi import Limiter
from slowapi.util import get_remote_address

limiter = Limiter(key_func=get_remote_address)
app.state.limiter = limiter

@app.get("/api/v1/inverters")
@limiter.limit("10/minute")
async def get_inverters():
    pass

Monitoring & Alerts

Security Logs

# Monitor auth logs
tail -f /var/log/auth.log | grep Failed

# Monitor nginx access
tail -f /var/log/nginx/access.log | grep "404\|403\|401"

# Docker logs
docker compose logs -f | grep ERROR

Intrusion Detection (OSSEC)

# Install OSSEC
wget https://github.com/ossec/ossec-hids/archive/3.7.0.tar.gz
tar -xvf 3.7.0.tar.gz
cd ossec-hids-3.7.0
sudo ./install.sh

API Security

CORS Configuration

# backend/app/main.py
from fastapi.middleware.cors import CORSMiddleware

app.add_middleware(
    CORSMiddleware,
    allow_origins=[
        "https://solarlog.karma.organic",
        "https://solarlog-api.karma.organic"
    ],
    allow_credentials=True,
    allow_methods=["GET", "POST", "PUT", "DELETE"],
    allow_headers=["*"],
)

API Key Authentication

from fastapi.security import APIKeyHeader

api_key_header = APIKeyHeader(name="X-API-Key")

def verify_api_key(api_key: str = Security(api_key_header)):
    if api_key != settings.api_key:
        raise HTTPException(status_code=403, detail="Invalid API Key")
    return api_key

Compliance

GDPR Considerations

  • User data encryption at rest
  • Data retention policies
  • Right to deletion
  • Privacy policy

Audit Logging

# backend/app/middleware/audit.py
import logging

audit_logger = logging.getLogger("audit")

@app.middleware("http")
async def audit_middleware(request: Request, call_next):
    audit_logger.info(f"{request.method} {request.url} - {request.client.host}")
    response = await call_next(request)
    return response

Backup Strategy

3-2-1 Rule

  • 3 copies of data
  • 2 different media types
  • 1 offsite backup
# Local backup
./scripts/backup.sh

# Sync to S3
aws s3 sync /backups s3://solarlog-backups/

# Sync to remote server
rsync -avz /backups/ user@backup-server:/backups/solarlog/

Incident Response

Response Plan

  1. Detection - Monitor logs, alerts
  2. Containment - Isolate affected services
  3. Eradication - Remove threat
  4. Recovery - Restore from backup
  5. Lessons Learned - Document and improve

Emergency Contacts

# incident-response.yml
contacts:
  - name: System Admin
    phone: +49-xxx-xxx
    email: admin@example.com

  - name: Security Team
    email: security@example.com

Regular Updates

# Update system packages
sudo apt update && sudo apt upgrade -y

# Update Docker images
docker compose pull
docker compose up -d

# Update Python dependencies
pip install --upgrade -r requirements.txt

Security Checklist

  • Strong passwords (32+ chars)
  • SSH key authentication only
  • Firewall configured (UFW)
  • Fail2Ban active
  • SSL/TLS enabled (Let's Encrypt)
  • HSTS header set
  • CORS properly configured
  • Rate limiting enabled
  • Docker containers hardened
  • Database encrypted
  • Secrets in environment variables
  • Regular backups automated
  • Monitoring & alerting setup
  • Incident response plan documented
  • Regular security updates applied

Resources