Files
stechuhr3/apache2.conf

276 lines
11 KiB
ApacheConf

# Apache 2 VirtualHost-Konfiguration für TimeClock v3
# Datei speichern unter: /etc/apache2/sites-available/stechuhr3.tsschulz.de.conf
#
# Installation:
# sudo cp apache2.conf /etc/apache2/sites-available/stechuhr3.tsschulz.de.conf
# sudo a2enmod proxy proxy_http ssl rewrite headers deflate expires
# sudo a2ensite stechuhr3.tsschulz.de
# sudo apache2ctl configtest
# sudo systemctl reload apache2
# HTTP VirtualHost - Redirect zu HTTPS
<VirtualHost *:80>
ServerName stechuhr3.tsschulz.de
ServerAdmin admin@tsschulz.de
# Let's Encrypt ACME Challenge
DocumentRoot /var/www/certbot
<Directory /var/www/certbot>
Require all granted
</Directory>
# Alle anderen Requests zu HTTPS umleiten
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
ErrorLog ${APACHE_LOG_DIR}/stechuhr3-error.log
CustomLog ${APACHE_LOG_DIR}/stechuhr3-access.log combined
</VirtualHost>
# HTTPS VirtualHost - Hauptkonfiguration
<VirtualHost *:443>
ServerName stechuhr3.tsschulz.de
ServerAdmin admin@tsschulz.de
# =================================================================
# SSL-Konfiguration (wird von Certbot automatisch verwaltet)
# =================================================================
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/stechuhr3.tsschulz.de/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/stechuhr3.tsschulz.de/privkey.pem
# SSL-Protokolle und Cipher Suites
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder off
SSLSessionTickets off
# OCSP Stapling
SSLUseStapling on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
# =================================================================
# Frontend (Vue.js SPA)
# =================================================================
DocumentRoot /var/www/timeclock/frontend/dist
<Directory /var/www/timeclock/frontend/dist>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
# SPA Fallback - alle Requests zu index.html
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/api
RewriteRule . /index.html [L]
</IfModule>
</Directory>
# =================================================================
# Gzip Compression
# =================================================================
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript
AddOutputFilterByType DEFLATE application/javascript application/x-javascript application/json
AddOutputFilterByType DEFLATE application/xml application/xml+rss application/rss+xml
AddOutputFilterByType DEFLATE application/atom+xml
AddOutputFilterByType DEFLATE image/svg+xml
AddOutputFilterByType DEFLATE font/ttf font/woff font/woff2
</IfModule>
# =================================================================
# Security Headers
# =================================================================
<IfModule mod_headers.c>
# X-Frame-Options: Schutz vor Clickjacking
Header always set X-Frame-Options "SAMEORIGIN"
# X-Content-Type-Options: Verhindert MIME-Type Sniffing
Header always set X-Content-Type-Options "nosniff"
# X-XSS-Protection: XSS-Schutz für ältere Browser
Header always set X-XSS-Protection "1; mode=block"
# Referrer-Policy: Kontrolliert Referrer-Informationen
Header always set Referrer-Policy "strict-origin-when-cross-origin"
# Permissions-Policy: Kontrolliert Browser-Features
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"
# Content-Security-Policy (angepasst für Vue.js)
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https://stechuhr3.tsschulz.de;"
# Strict-Transport-Security (HSTS)
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
</IfModule>
# =================================================================
# API Reverse Proxy zum Backend
# =================================================================
<IfModule mod_proxy.c>
ProxyPreserveHost On
ProxyRequests Off
# Timeouts
ProxyTimeout 60
# API Proxy
ProxyPass /api http://localhost:3010/api retry=0
ProxyPassReverse /api http://localhost:3010/api
<Location /api>
# Proxy Headers
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
RequestHeader set X-Real-IP %{REMOTE_ADDR}s
# CORS Headers (falls benötigt, aber Backend sollte das handhaben)
# Header set Access-Control-Allow-Origin "https://stechuhr3.tsschulz.de"
# Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
# Header set Access-Control-Allow-Headers "Content-Type, Authorization"
# Header set Access-Control-Allow-Credentials "true"
</Location>
</IfModule>
# =================================================================
# Statische Assets mit langem Cache
# =================================================================
<IfModule mod_expires.c>
ExpiresActive On
# JavaScript und CSS
ExpiresByType text/css "access plus 1 year"
ExpiresByType text/javascript "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType application/x-javascript "access plus 1 year"
# Bilder
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
ExpiresByType image/x-icon "access plus 1 year"
# Fonts
ExpiresByType font/ttf "access plus 1 year"
ExpiresByType font/woff "access plus 1 year"
ExpiresByType font/woff2 "access plus 1 year"
ExpiresByType application/font-woff "access plus 1 year"
ExpiresByType application/font-woff2 "access plus 1 year"
# HTML (kein Cache)
ExpiresByType text/html "access plus 0 seconds"
</IfModule>
# Cache-Control Headers für Assets
<FilesMatch "\.(js|css|png|jpg|jpeg|gif|ico|svg|webp|woff|woff2|ttf|eot)$">
<IfModule mod_headers.c>
Header set Cache-Control "public, max-age=31536000, immutable"
</IfModule>
</FilesMatch>
# Kein Cache für HTML
<FilesMatch "\.(html|htm)$">
<IfModule mod_headers.c>
Header set Cache-Control "no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "0"
</IfModule>
</FilesMatch>
# =================================================================
# Spezielle Dateien
# =================================================================
# robots.txt und sitemap.xml
<FilesMatch "(robots\.txt|sitemap\.xml)$">
<IfModule mod_headers.c>
Header set Cache-Control "public, max-age=86400"
</IfModule>
</FilesMatch>
# =================================================================
# Sicherheit: Verstecke sensible Dateien
# =================================================================
# Blockiere Zugriff auf versteckte Dateien (.git, .env, etc.)
<DirectoryMatch "^\.|\/\.">
Require all denied
</DirectoryMatch>
<FilesMatch "^\.">
Require all denied
</FilesMatch>
# Blockiere Zugriff auf Backup-Dateien
<FilesMatch "~$">
Require all denied
</FilesMatch>
# Blockiere .env Dateien
<FilesMatch "\.env">
Require all denied
</FilesMatch>
# =================================================================
# Limits
# =================================================================
# Client Body Size Limit (z.B. für File-Uploads)
LimitRequestBody 10485760
# Timeouts
TimeOut 300
# =================================================================
# Logging
# =================================================================
ErrorLog ${APACHE_LOG_DIR}/stechuhr3-error.log
CustomLog ${APACHE_LOG_DIR}/stechuhr3-access.log combined
# Optional: Log-Level für detailliertere Logs
# LogLevel info ssl:warn proxy:debug
</VirtualHost>
# =================================================================
# Globale SSL-Konfiguration (optional, in /etc/apache2/mods-available/ssl.conf)
# =================================================================
# <IfModule mod_ssl.c>
# # OCSP Stapling Cache
# SSLStaplingCache shmcb:/var/run/ocsp(128000)
#
# # SSL Session Cache
# SSLSessionCache shmcb:/var/run/ssl_scache(512000)
# SSLSessionCacheTimeout 300
# </IfModule>
# =================================================================
# OPTIONAL: Rate Limiting mit mod_evasive
# =================================================================
# Installieren mit: sudo apt install libapache2-mod-evasive
# Dann konfigurieren in: /etc/apache2/mods-available/evasive.conf
#
# <IfModule mod_evasive20.c>
# DOSHashTableSize 3097
# DOSPageCount 5
# DOSSiteCount 100
# DOSPageInterval 1
# DOSSiteInterval 1
# DOSBlockingPeriod 10
# DOSEmailNotify admin@tsschulz.de
# DOSLogDir /var/log/apache2/mod_evasive
# </IfModule>
# =================================================================
# OPTIONAL: Zusätzliche Security mit mod_security
# =================================================================
# Installieren mit: sudo apt install libapache2-mod-security2
# Konfiguration in: /etc/modsecurity/modsecurity.conf