From 236e1d2ad27dacb2500227e1214de0e5dd19c831 Mon Sep 17 00:00:00 2001 From: Stiftung Development Date: Tue, 9 Sep 2025 21:46:19 +0200 Subject: [PATCH] Add HTTPS/SSL security configuration - Update nginx config for HTTPS with Let's Encrypt certificates - Add HTTP to HTTPS redirect - Configure SSL security headers and HSTS - Add Django HTTPS security settings for production - Fix proxy_pass to use correct port 8081 - Enhance Content Security Policy for HTTPS --- app/core/settings.py | 12 ++++++++++++ deploy-production/nginx.conf | 35 ++++++++++++++++++++++++++++------- env-template.txt | 8 ++++++++ 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/app/core/settings.py b/app/core/settings.py index f2839e8..40f40ce 100644 --- a/app/core/settings.py +++ b/app/core/settings.py @@ -119,3 +119,15 @@ GRAMPS_API_TOKEN = os.environ.get("GRAMPS_API_TOKEN", "") GRAMPS_STIFTER_IDS = os.environ.get("GRAMPS_STIFTER_IDS", "") # comma-separated GRAMPS_USERNAME = os.environ.get("GRAMPS_USERNAME", "") GRAMPS_PASSWORD = os.environ.get("GRAMPS_PASSWORD", "") + +# HTTPS Security Settings (production) +if not DEBUG: + SECURE_SSL_REDIRECT = True + SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") + SESSION_COOKIE_SECURE = True + CSRF_COOKIE_SECURE = True + SECURE_BROWSER_XSS_FILTER = True + SECURE_CONTENT_TYPE_NOSNIFF = True + SECURE_HSTS_SECONDS = 31536000 # 1 year + SECURE_HSTS_INCLUDE_SUBDOMAINS = True + SECURE_HSTS_PRELOAD = True diff --git a/deploy-production/nginx.conf b/deploy-production/nginx.conf index 1561607..a9240a8 100644 --- a/deploy-production/nginx.conf +++ b/deploy-production/nginx.conf @@ -1,16 +1,37 @@ +# HTTP server block - redirect to HTTPS server { listen 80; - server_name 217.154.84.225 your-domain.com; + server_name vhtv-stiftung.de www.vhtv-stiftung.de; + + # Redirect all HTTP traffic to HTTPS + return 301 https://$server_name$request_uri; +} - # Security headers +# HTTPS server block +server { + listen 443 ssl http2; + server_name vhtv-stiftung.de www.vhtv-stiftung.de; + + # SSL Certificate Configuration + ssl_certificate /etc/letsencrypt/live/vhtv-stiftung.de/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/vhtv-stiftung.de/privkey.pem; + + # SSL Security Settings + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384; + ssl_prefer_server_ciphers off; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 10m; + + # HSTS (HTTP Strict Transport Security) + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + + # Enhanced Security headers add_header X-Frame-Options "SAMEORIGIN" always; add_header X-XSS-Protection "1; mode=block" always; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "no-referrer-when-downgrade" always; - add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always; - - # Rate limiting (apply the zone, don't define it here) - limit_req zone=one burst=20 nodelay; + add_header Content-Security-Policy "default-src 'self' https: data: blob: 'unsafe-inline'" always; # Static files location /static/ { @@ -27,7 +48,7 @@ server { # Django application location / { - proxy_pass http://127.0.0.1:8000; + proxy_pass http://127.0.0.1:8081; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; diff --git a/env-template.txt b/env-template.txt index e804875..987e4cd 100644 --- a/env-template.txt +++ b/env-template.txt @@ -14,6 +14,14 @@ DJANGO_ALLOWED_HOSTS=localhost,127.0.0.1 # SECRET_KEY=your-production-secret-key-here # ALLOWED_HOSTS=your-domain.com,www.your-domain.com,localhost,127.0.0.1 +# HTTPS Security Settings (enable after SSL certificate is installed) +# SECURE_SSL_REDIRECT=True +# SESSION_COOKIE_SECURE=True +# CSRF_COOKIE_SECURE=True +# SECURE_HSTS_SECONDS=31536000 +# SECURE_HSTS_INCLUDE_SUBDOMAINS=True +# SECURE_HSTS_PRELOAD=True + LANGUAGE_CODE=de TIME_ZONE=Europe/Berlin