Files
TimeTracker/setup-https-mkcert.sh
Dries Peeters 94e8e49439 feat: Add HTTPS support with mkcert and automatic SSL configuration
Add comprehensive HTTPS support with two deployment options:
- mkcert for local development with trusted certificates
- Automatic SSL with Let's Encrypt for production

HTTPS Implementation:
- Add docker-compose.https-mkcert.yml for local HTTPS development
- Add docker-compose.https-auto.yml for automatic SSL certificates
- Create Dockerfile.mkcert for certificate generation
- Add setup scripts (setup-https-mkcert.sh/bat)
- Add startup scripts (start-https.sh/bat)
- Add certificate generation script (generate-mkcert-certs.sh)

CSRF and IP Access Fixes:
- Fix CSRF token validation for IP-based access
- Add CSRF troubleshooting documentation
- Update configuration to handle various access patterns

Documentation:
- Add HTTPS_MKCERT_GUIDE.md with setup instructions
- Add README_HTTPS.md with general HTTPS documentation
- Add README_HTTPS_AUTO.md for automatic SSL setup
- Add AUTOMATIC_HTTPS_SUMMARY.md
- Add CSRF_IP_ACCESS_FIX.md and CSRF_IP_FIX_SUMMARY.md
- Add docs/CSRF_IP_ACCESS_GUIDE.md
- Update main README.md with HTTPS information

Configuration:
- Update .gitignore for SSL certificates and nginx configs
- Update env.example with new HTTPS-related variables
- Update docker-compose.yml with SSL configuration options

This enables secure HTTPS access in both development and production
environments while maintaining compatibility with existing deployments.
2025-10-13 18:32:45 +02:00

153 lines
4.0 KiB
Bash

#!/bin/bash
# Setup HTTPS for TimeTracker using mkcert
# Works with localhost and IP addresses - NO certificate warnings!
set -e
echo "=========================================="
echo "TimeTracker HTTPS Setup with mkcert"
echo "=========================================="
echo ""
# Check if mkcert is installed
if ! command -v mkcert &> /dev/null; then
echo "❌ mkcert is not installed!"
echo ""
echo "Install mkcert:"
echo " macOS: brew install mkcert"
echo " Linux: https://github.com/FiloSottile/mkcert#linux"
echo " Windows: choco install mkcert OR scoop install mkcert"
echo ""
exit 1
fi
echo "✅ mkcert found"
echo ""
# Install local CA
echo "Installing local Certificate Authority..."
mkcert -install
echo "✅ Local CA installed"
echo ""
# Detect local IP
if [[ "$OSTYPE" == "darwin"* ]]; then
LOCAL_IP=$(ipconfig getifaddr en0 || ipconfig getifaddr en1 || echo "192.168.1.100")
elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
LOCAL_IP=$(hostname -I | awk '{print $1}' || echo "192.168.1.100")
else
LOCAL_IP="192.168.1.100"
fi
echo "Detected local IP: $LOCAL_IP"
echo ""
# Create directories
mkdir -p nginx/ssl nginx/conf.d
# Generate certificates
echo "Generating certificates..."
mkcert -key-file nginx/ssl/key.pem -cert-file nginx/ssl/cert.pem \
localhost 127.0.0.1 ::1 $LOCAL_IP *.local
echo "✅ Certificates generated"
echo ""
# Create nginx config
cat > nginx/conf.d/https.conf << 'NGINX_EOF'
server {
listen 80;
server_name _;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name _;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
location / {
proxy_pass http://app:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
NGINX_EOF
echo "✅ nginx config created"
echo ""
# Create docker-compose override
cat > docker-compose.https.yml << 'COMPOSE_EOF'
services:
nginx:
image: nginx:alpine
container_name: timetracker-nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d:ro
- ./nginx/ssl:/etc/nginx/ssl:ro
depends_on:
- app
restart: unless-stopped
app:
ports: []
environment:
- WTF_CSRF_SSL_STRICT=true
- SESSION_COOKIE_SECURE=true
- CSRF_COOKIE_SECURE=true
COMPOSE_EOF
echo "✅ docker-compose.https.yml created"
echo ""
# Update .env if exists
if [ -f .env ]; then
cp .env .env.backup
sed -i.bak 's/^WTF_CSRF_SSL_STRICT=.*/WTF_CSRF_SSL_STRICT=true/' .env 2>/dev/null || echo "WTF_CSRF_SSL_STRICT=true" >> .env
sed -i.bak 's/^SESSION_COOKIE_SECURE=.*/SESSION_COOKIE_SECURE=true/' .env 2>/dev/null || echo "SESSION_COOKIE_SECURE=true" >> .env
sed -i.bak 's/^CSRF_COOKIE_SECURE=.*/CSRF_COOKIE_SECURE=true/' .env 2>/dev/null || echo "CSRF_COOKIE_SECURE=true" >> .env
rm -f .env.bak
echo "✅ .env updated"
else
echo "⚠️ No .env file - create from env.example"
fi
echo ""
echo "=========================================="
echo "✅ HTTPS Setup Complete!"
echo "=========================================="
echo ""
echo "Start with HTTPS:"
echo " docker-compose -f docker-compose.yml -f docker-compose.https.yml up -d"
echo ""
echo "Access at:"
echo " https://localhost"
echo " https://$LOCAL_IP"
echo ""
echo "For other devices:"
echo " 1. Find CA: mkcert -CAROOT"
echo " 2. Copy rootCA.pem to device"
echo " 3. Import as trusted certificate"
echo ""