Erscheinungsbild
Apache und .htaccess
Bei deployment.target: 'mittwald-static' entstehen beim Bauen zwei Dateien: dist/.htaccess und dist/_astro/.htaccess. Beide sind erzeugt und werden beim nächsten Build überschrieben — was darin stehen soll, gehört nach deployment.apache (ADR 0012).
Was in der Datei steht
| Abschnitt | Inhalt |
|---|---|
| Grundlagen | AddDefaultCharset utf-8, kein Verzeichnislisting, ErrorDocument 404 |
| Verborgene Dateien | Alles mit führendem Punkt ist gesperrt |
| Weiterleitungen | HTTPS, kanonische Domain, Projektweiterleitungen |
| Sicherheits-Header | nosniff, Referrer-Policy, X-Frame-Options, Permissions-Policy, CSP, HSTS |
| Zwischenspeicherung | HTML wird gegengeprüft, Dateien mit festem Namen eine Stunde |
| Kompression | mod_deflate für Text-Inhaltstypen |
Die zweite Datei regelt nur das Assets-Verzeichnis: Dort trägt jede Datei den Hash ihres Inhalts im Namen, deshalb gilt max-age=31536000, immutable.
Konfigurieren
ts
deployment: {
target: 'mittwald-static',
apache: {
canonicalHost: 'www.kunde.de',
forceHttps: true,
redirects: [
{ from: '/alte-seite', to: '/neue-seite', status: 301 },
{ from: '/aktion', to: 'https://shop.kunde.de/aktion', status: 302 },
],
csp: {
mode: 'report-only',
additionalSources: {
'frame-src': ['https://www.youtube-nocookie.com'],
},
},
hsts: {
maxAge: 31536000,
includeSubDomains: true,
preload: false,
},
},
},Fehlt die Sektion, gelten die Vorgaben: HTTPS-Weiterleitung an, CSP im Beobachtungsmodus, kein HSTS, keine kanonische Domain, keine Weiterleitungen.
canonicalHost
Jede andere Schreibweise wird einmalig auf diesen Host weitergeleitet. Damit gibt es zu jeder Seite genau eine Adresse — kunde.de und www.kunde.de sind für eine Suchmaschine sonst zwei Websites.
Der Hostname wird für den regulären Ausdruck maskiert; ohne das wäre der Punkt ein Platzhalter für jedes Zeichen, und wwwXkunde.de gälte als kanonisch.
forceHttps
Aus nur, wenn eine vorgeschaltete Stelle das schon übernimmt. Zwei HTTPS-Weiterleitungen hintereinander sind der häufigste Grund für eine Weiterleitungsschleife.
Die erzeugte Regel prüft %{HTTPS} und X-Forwarded-Proto. Hinter einem Proxy, der TLS beendet, steht %{HTTPS} auf off, obwohl der Besucher längst über HTTPS kommt — eine Regel, die nur darauf schaut, leitet endlos im Kreis.
redirects
from ist ein absoluter Pfad, to ein Pfad oder eine absolute URL. Der abschließende Schrägstrich ist freigestellt: /alt und /alt/ sind dieselbe Adresse. Das Muster ist an beiden Enden verankert, /alternativ wird also nicht mitgezogen.
301 ist dauerhaft und wird von Browsern gecacht — bei einem Versehen lange. 302 für alles, was wieder zurückgenommen werden soll.
hsts
Standardmäßig aus. Der Header ist eine Zusage an den Browser, diese Domain für die angegebene Dauer ausschließlich über HTTPS zu laden — und die nimmt er nicht zurück, wenn der Header verschwindet.
preload verlangt includeSubDomains und mindestens ein Jahr; die Konfigurationsprüfung setzt das durch. Ein Eintrag in der Preload-Liste ist praktisch nicht rückholbar und gilt für alle Subdomains, auch die, die es noch nicht gibt. Für eine Kundenwebsite mit einem internen intranet.kunde.de ohne Zertifikat ist das ein Ausfall.
Ein sinnvoller Einstieg ist eine kurze Frist ohne Subdomains, etwa maxAge: 300, und eine Erhöhung, wenn nichts auffällt.
csp
Siehe Content Security Policy. Kurz: Vorgabe ist report-only, additionalSources ergänzt Quellen für Einbettungen, und 'unsafe-inline' ist bei script-src ausgeschlossen.
Wenn AllowOverride aus ist
Dann liest Apache die Datei nicht, und zwar ohne Fehlermeldung. Die Website funktioniert — ohne Sicherheits-Header, ohne Weiterleitungen, ohne Cache-Regeln. Bei Mittwald ist AllowOverride für statische Deployments üblicherweise aktiv.
Prüfen:
sh
curl -sI https://www.kunde.de | grep -i -E 'x-content-type|referrer|content-security'Kommt keine Zeile zurück, greift die Datei nicht. Dann gehören dieselben Regeln in die Serverkonfiguration; die erzeugte Datei ist die Vorlage dafür.
Für nginx
Der Starter erzeugt keine nginx-Konfiguration. Die drei Dinge, die dort mindestens nötig sind:
nginx
# Handler-Verzeichnis sperren, nur den Endpunkt freigeben
location ^~ /api/forms/ { return 404; }
location = /api/forms/submit.php { include fastcgi_params; fastcgi_pass php; }
# Gehashte Assets unbegrenzt zwischenspeichern
location ^~ /_astro/ { add_header Cache-Control "public, max-age=31536000, immutable"; }
# HTML gegenprüfen lassen
location ~* \.html$ { add_header Cache-Control "no-cache"; }Die Sicherheits-Header und die Content Security Policy lassen sich aus dist/.htaccess übernehmen — der Wert des CSP-Headers ist derselbe, nur die Syntax des Servers ist eine andere. Er ändert sich mit jedem Build, in dem sich ein Inline-Skript ändert; von Hand kopiert ist er nach der nächsten Änderung falsch.
Das Handler-Verzeichnis
Der PHP-Handler bringt seine eigene .htaccess mit (ADR 0010). Beide bestehen nebeneinander: Die des Handler-Verzeichnisses sperrt es ab und gibt nur submit.php frei, die erzeugte im Wurzelverzeichnis liefert die Sicherheits-Header, die auch für dessen Antworten gelten.
basicAuth
Passwortschutz der gesamten Auslieferung über HTTP Basic Auth — für eine Vorschau vor dem echten Launch (ADR 0020).
ts
deployment: {
target: 'mittwald-static',
apache: {
basicAuth: {
realm: 'Kunde — Vorschau',
documentRoot: '/home/www/p123456/html/kunde.de',
},
},
},documentRoot ist der absolute Dokumentenstamm auf dem Zielsystem — derselbe Wert wie DEPLOY_PATH der Deployment-Umgebung. Kein Geheimnis, aber AuthUserFile verlangt einen Dateisystempfad; ein relativer wäre gegen Apaches ServerRoot aufgelöst, nicht gegen den Dokumentenstamm der Domain.
Benutzername und Passwort stehen nicht in project.config.ts — sie kommen aus den Umgebungsvariablen KT_BASIC_AUTH_USER und KT_BASIC_AUTH_PASSWORD. In der GitHub-Umgebung sind sie zwei weitere Secrets neben DEPLOY_SSH_KEY (siehe Mittwald). Fehlen sie bei einem production-Build, bricht er ab — eine Ausgabe, die den Schutz zusagt und nicht hat, wäre die gefährlichere Richtung. Außerhalb von production (lokal, in der CI der Pull Requests) entsteht die Ausgabe ohne den Block und mit einer Warnung im Build-Log.
Zum Entfernen genügt es, basicAuth aus der Konfiguration zu streichen — die .htpasswd verschwindet beim nächsten Build von selbst, weil sie nur zusammen mit dem Auth-Block entsteht. pnpm starter:init fragt bei Mittwald-Projekten danach.