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
[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
- Detection - Monitor logs, alerts
- Containment - Isolate affected services
- Eradication - Remove threat
- Recovery - Restore from backup
- 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