Nginx Location-Matching-Regeln mit Beispielen erklärt
Sie haben wahrscheinlich schon einmal eine Nginx-Konfiguration angepasst, neu geladen und sich gefragt, warum Ihr location-Block einfach nicht angewendet wird. Vielleicht trifft eine Anfrage nach einer statischen Datei auf Ihren PHP-Handler, oder eine API-Route wird von einem Catch-All verschluckt. Der Übeltäter ist oft der Location-Matching-Algorithmus von Nginx – er ist nicht so einfach, wie er aussieht.
In diesem Leitfaden erklären wir, wie Nginx einen Location-Block auswählt, mit echten Beispielen, die Sie testen können. Am Ende wissen Sie genau, welcher Block gewinnt und warum.
Wie Nginx Location-Matching funktioniert
Wenn eine Anfrage eingeht, vergleicht Nginx die URI mit allen definierten location-Blöcken. Der Abgleich folgt einer bestimmten Reihenfolge:
- Exakter Treffer (
=) – höchste Priorität. Wenn gefunden, stoppt Nginx und verwendet ihn. - Längster Präfix-Treffer – Nginx merkt sich den längsten übereinstimmenden Präfix-Location.
- Regulärer Ausdruck (
~oder~*) – wird in der Reihenfolge des Auftretens geprüft. Der erste passende Regex gewinnt und überschreibt den Präfix-Treffer (es sei denn,^~wird verwendet). - Präfix-Treffer mit
^~– wenn der längste übereinstimmende Präfix^~hat, überspringt Nginx die Regex-Prüfung und verwendet ihn. - Wenn kein Regex übereinstimmt, wird der längste Präfix-Treffer verwendet.
Das ist der Kernalgorithmus. Sehen wir ihn in Aktion.
Location-Modifikatoren: Eine kurze Übersicht
| Modifikator | Syntax | Match-Typ | Priorität |
|---|---|---|---|
= | location = /path | Exakt | Höchste |
^~ | location ^~ /path | Präfix (kein Regex) | Hoch |
~ | location ~ \.php$ | Regex (Groß-/Kleinschreibung beachten) | Mittel |
~* | location ~* \.(jpg|png)$ | Regex (Groß-/Kleinschreibung ignorieren) | Mittel |
| keiner | location /path | Präfix | Niedrigste |
Praxisbeispiel 1: Statische Dateien vs. PHP
Betrachten Sie dieses gängige Setup:
server {
listen 80;
server_name example.com;
location / {
root /var/www/html;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
}
Eine Anfrage für /index.php stimmt mit dem Regex \.php$ überein, also geht sie an PHP-FPM. Eine Anfrage für /logo.png stimmt nicht mit dem Regex überein, also fällt sie auf das Präfix / zurück und liefert die statische Datei aus. Einfach, oder?
Aber was, wenn Sie /uploads/photo.php als statische Datei ausliefern möchten (vielleicht ist es tatsächlich ein Bild)? Sie können einen exakten Treffer hinzufügen:
location = /uploads/photo.php {
root /var/www/html;
}
Jetzt hat dieser exakte Treffer Vorrang vor dem Regex.
Praxisbeispiel 2: API-Routing mit Präfix und Regex
Angenommen, Sie haben eine API unter /api/ und möchten alle Anfragen an ein Backend proxyen, außer einem Health-Check, der eine statische Antwort zurückgibt.
location = /api/health {
return 200 "OK";
}
location /api/ {
proxy_pass http://backend;
}
location ~ ^/api/v[0-9]+/special {
proxy_pass http://special-backend;
}
Verfolgen wir /api/health: exakter Treffer gewinnt, gibt 200 zurück. Für /api/users: kein exakter Treffer, kein Regex (stimmt nicht mit special überein), also wird der längste Präfix /api/ verwendet. Für /api/v1/special: Regex stimmt überein, also überschreibt er den Präfix und geht an special-backend.
Dies zeigt, wie Regex einen Präfix-Treffer überschreiben kann. Wenn Sie wollten, dass der Präfix immer gewinnt, würden Sie stattdessen ^~ verwenden.
Praxisbeispiel 3: Die Macht von ^~
Stellen Sie sich vor, Sie haben ein Verzeichnis /static/ mit Dateien, die niemals von PHP verarbeitet werden sollen, selbst wenn sie mit .php enden. Die Verwendung von ^~ stellt sicher, dass Nginx keine Regex-Locations prüft.
location ^~ /static/ {
root /var/www/html;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
Eine Anfrage für /static/script.php stimmt mit dem Präfix ^~ /static/ überein. Wegen ^~ überspringt Nginx die Regex-Prüfung und liefert die Datei direkt aus. Ohne ^~ würde der Regex übereinstimmen und PHP-FPM würde sie ausführen – ein potenzielles Sicherheitsrisiko.
Häufige Fallstricke und wie man sie vermeidet
- Regex-Reihenfolge ist wichtig: Nginx prüft Regex-Locations in der Reihenfolge, in der sie in der Konfiguration erscheinen. Setzen Sie spezifischere Muster an den Anfang.
- Fehlende abschließende Schrägstriche:
location /apiundlocation /api/sind unterschiedlich. Ersteres stimmt mit/apiund/apixüberein, letzteres mit/api/und/api/users. Seien Sie präzise. - Überlappende Präfixe: Der längste Präfix gewinnt, also hat
location /api/v1Vorrang vorlocation /apifür/api/v1/users. ^~für statische Assets vergessen: Verwenden Sie es, um zu verhindern, dass Regex Anfragen für statische Dateien kapert.- Groß-/Kleinschreibung:
~beachtet die Groß-/Kleinschreibung,~*nicht. Verwenden Sie~*für Dateiendungen.
Debugging des Location-Matchings
Wenn Sie sich nicht sicher sind, welche Location verwendet wird, aktivieren Sie die Debug-Protokollierung in Nginx. Fügen Sie error_log /var/log/nginx/error.log debug; in Ihrem Server-Block hinzu, laden Sie neu und prüfen Sie das Log. Sie werden Zeilen wie test location: "/api/users" und using configuration "/api/" sehen.
Alternativ können Sie vorübergehend return 200 "matched: /api/"; in jeder Location verwenden, um zu sehen, welche antwortet.
FAQ
Wie ist die Prioritätsreihenfolge der Nginx-Location-Modifikatoren?
Exakter Treffer (=) ist am höchsten, dann längster Präfix mit ^~, dann Regex (~ oder ~*) in Reihenfolge, dann der längste Präfix-Treffer ohne ^~.
Kann eine Regex-Location eine Präfix-Location überschreiben?
Ja, es sei denn, die Präfix-Location verwendet ^~. Regex-Locations werden nach dem längsten Präfix-Treffer geprüft, und wenn ein Regex übereinstimmt, hat er Vorrang vor einem regulären Präfix.
Wie stimme ich eine Location nur für eine bestimmte Datei ab?
Verwenden Sie einen exakten Treffer mit =, z. B. location = /favicon.ico. Dies stellt sicher, dass nur diese exakte URI übereinstimmt.
Meistern Sie Ihre Nginx-Konfiguration
Das Verständnis des Location-Matchings ist der Schlüssel für ein zuverlässiges Nginx-Setup. Testen Sie Ihre Konfigurationen mit nginx -t und verwenden Sie Debug-Logs, wenn Sie Zweifel haben. Wenn Sie mit Nginx-Logs arbeiten und Verkehrsmuster analysieren müssen, probieren Sie unseren Nginx Log Analyzer, um Ihre Logs schnell zu parsen und zu visualisieren.