Zum Inhalt

sorted-args: Normalisierung von HTTP-Querystring-Parametern für NGINX

Erfordert den Pro-Plan (oder höher) des GetPageSpeed NGINX Extras-Abonnements.

Installation

Sie können dieses Modul in jeder RHEL-basierten Distribution installieren, einschließlich, aber nicht beschränkt auf:

  • RedHat Enterprise Linux 7, 8, 9 und 10
  • CentOS 7, 8, 9
  • AlmaLinux 8, 9
  • Rocky Linux 8, 9
  • Amazon Linux 2 und Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-sorted-args
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-sorted-args

Aktivieren Sie das Modul, indem Sie Folgendes an den Anfang von /etc/nginx/nginx.conf hinzufügen:

load_module modules/ngx_http_sorted_args_module.so;

Dieses Dokument beschreibt nginx-module-sorted-args v3.0.1, veröffentlicht am 03. Mai 2026.


Ein leistungsstarkes Nginx-Modul, das HTTP-Anforderungs-Querystring-Parameter durch alphanumerische Sortierung normalisiert. Dieses Modul bietet eine konsistente, kanonische Darstellung von Query-Strings, unabhängig von der ursprünglichen Parameterreihenfolge, was es ideal für die Generierung von Cache-Schlüsseln, die Duplizierung von Anforderungen und die Normalisierung von URLs macht.

Übersicht

Verschiedene URLs mit denselben Query-Parametern in unterschiedlicher Reihenfolge erzeugen denselben normalisierten Querystring:

  • /index.php?b=2&a=1&c=3
  • /index.php?b=2&c=3&a=1
  • /index.php?c=3&a=1&b=2
  • /index.php?c=3&b=2&a=1

Alle oben genannten erzeugen denselben normalisierten Querystring: a=1&b=2&c=3

Diese Normalisierung ist über die Variable $sorted_args zugänglich, die in Cache-Schlüsseln, Protokollierung und anderen NGINX-Kontexten verwendet werden kann.

Funktionen

  • Natürliche Sortierung der Query-Parameter nach Schlüssel, dann nach Wert (z.B. item2 < item10)
  • Entfernen leerer Werte — Parameter wie ?a= werden automatisch entfernt
  • Blocklistenmodus (sorted_args_ignore_list), um bestimmte Parameter aus der sortierten Ausgabe auszuschließen
  • Whitelistmodus (sorted_args_allow_list), um nur bestimmte Parameter beizubehalten und alle anderen zu verwerfen
  • Wildcard-Muster — verwenden Sie utm_*, um alle UTM-Parameter zu erfassen, *_id für Suffixe
  • Duplikatserkennung (sorted_args_dedupe) — nur die erste oder letzte Vorkommen von doppelten Schlüsseln beibehalten
  • Optionale $args-Überschreibung, um den ursprünglichen Querystring automatisch durch sortierte Argumente zu ersetzen
  • Standortbezogene Konfiguration mit Vererbung aus Server- und Hauptkontexten
  • Effiziente Implementierung unter Verwendung der nativen Warteschlangen-Sortierung von NGINX
  • Groß-/Kleinschreibung ignorierende Parameterbenennung für Filterung
  • Duplikaterkennung in Filterlisten

Konfiguration

Variablen

$sorted_args

Gibt die Querystring-Parameter zurück, die alphanumerisch nach Parametername und dann nach Wert sortiert sind. Parameter werden mit & verbunden und behalten ihre ursprüngliche URL-Codierung.

Beispiel:

Anfrage: /page?zebra=1&apple=2&banana=3
$sorted_args: apple=2&banana=3&zebra=1

Verhalten: - Ein leerer Querystring gibt einen leeren String zurück - Parameter ohne Werte (z.B. ?param) werden als param einbezogen - Parameter mit leeren Werten (z.B. ?param=) werden automatisch entfernt - Mehrere Werte für denselben Parameter werden einzeln sortiert - Natürliche Sortierung: p=1, p=2, p=10 sortieren korrekt (nicht p=1, p=10, p=2) - Groß-/Kleinschreibung ignorierende Sortierung für Parameternamen

Direktiven

sorted_args_ignore_list

Syntax: sorted_args_ignore_list pattern [pattern ...];

Standard: keine

Kontext: http, server, location, if

Beschreibung:

Gibt ein oder mehrere Muster an, die aus der Variable $sorted_args ausgeschlossen werden sollen (Blocklistenmodus). Dies ist nützlich, um Cache-busting-Parameter (wie Zeitstempel, Versionsnummern oder Tracking-IDs) aus Cache-Schlüsseln zu entfernen, während andere Parameter beibehalten werden.

Musterarten: - name — exakte Übereinstimmung (groß-/kleinschreibung ignorierend) - name* — Präfixübereinstimmung (übereinstimmt mit name, name_foo, name123 usw.) - *name — Suffixübereinstimmung (übereinstimmt mit foo_name, bar_name usw.) - *name* — Enthält-Übereinstimmung (übereinstimmt mit jedem Parameter, der name enthält)

Doppelte Muster in der Liste werden automatisch entfernt.

Beispiel:

location /api {
    # Exakte Namen und alle utm_* Tracking-Parameter filtern
    sorted_args_ignore_list timestamp version _ utm_* fb_*;

    proxy_cache_key "$uri$sorted_args";
    proxy_pass http://backend;
}

In diesem Beispiel erzeugen Anfragen wie /api?user=123&timestamp=1234567890&utm_source=google&utm_medium=cpc $sorted_args als user=123, wobei timestamp und alle UTM-Parameter herausgefiltert werden.

sorted_args_allow_list

Syntax: sorted_args_allow_list pattern [pattern ...];

Standard: keine

Kontext: http, server, location, if

Beschreibung:

Gibt ein oder mehrere Muster an, die in der Variable $sorted_args behalten werden sollen (Whitelistmodus). Alle Parameter, die keinem Muster entsprechen, werden ausgeschlossen. Dies ist nützlich, wenn Sie genau steuern möchten, welche Query-Parameter für das Caching zulässig sind.

Musterarten: - name — exakte Übereinstimmung (groß-/kleinschreibung ignorierend) - name* — Präfixübereinstimmung (übereinstimmt mit name, name_foo, name123 usw.) - *name — Suffixübereinstimmung (übereinstimmt mit foo_name, bar_name usw.) - *name* — Enthält-Übereinstimmung (übereinstimmt mit jedem Parameter, der name enthält)

Wenn sowohl sorted_args_allow_list als auch sorted_args_ignore_list konfiguriert sind, wird die Whitelist zuerst angewendet (nur erlaubte Parameter werden beibehalten), dann wird die Ignorierliste angewendet, um verbleibende unerwünschte Parameter herauszufiltern.

Beispiel:

location /api {
    # Nur Paginierungs- und Sortierungsparameter zulassen
    sorted_args_allow_list page* sort* limit;

    proxy_cache_key "$uri$sorted_args";
    proxy_pass http://backend;
}

In diesem Beispiel wird eine Anfrage wie /api?page=1&page_size=10&sort=asc&timestamp=123 $sorted_args als limit=10&page=1&page_size=10&sort=asc erzeugen. Der timestamp-Parameter wird verworfen, da er keinem Muster entspricht.

sorted_args_overwrite

Syntax: sorted_args_overwrite on | off;

Standard: off

Kontext: http, server, location, if

Beschreibung:

Wenn aktiviert, überschreibt diese Direktive automatisch die eingebaute Variable $args mit den sortierten (und optional gefilterten) Query-Argumenten. Dies ist nützlich, wenn Sie möchten, dass alle nachgelagerten Prozesse (Proxying, Protokollierung, Weiterleitungen) den normalisierten Querystring verwenden, ohne explizit auf $sorted_args zu verweisen.

Die Überschreibung erfolgt während der Rewrite-Phase, sodass alle nachfolgenden Phasen die sortierten Argumente in $args sehen.

Beispiel:

location /api {
    sorted_args_overwrite on;
    sorted_args_ignore_list timestamp version;

    # $args ist jetzt automatisch sortiert und gefiltert
    proxy_pass http://backend$uri?$args;
}

In diesem Beispiel wird eine Anfrage an /api?z=1&a=2&timestamp=123 als /api?a=2&z=1 proxied — sortiert und mit timestamp herausgefiltert.

sorted_args_dedupe

Syntax: sorted_args_dedupe first | last | off;

Standard: off

Kontext: http, server, location, if

Beschreibung:

Steuert, wie doppelte Parameter-Schlüssel behandelt werden. Wenn mehrere Parameter denselben Schlüssel haben (z.B. ?a=1&a=2&a=3), bestimmt diese Direktive, welchen Wert man beibehalten möchte.

  • first — nur das erste Vorkommen jedes Schlüssels beibehalten
  • last — nur das letzte Vorkommen jedes Schlüssels beibehalten
  • off — alle Vorkommen beibehalten (Standardverhalten)

Dies ist nützlich, um URLs zu normalisieren, bei denen derselbe Parameter möglicherweise mehrfach angegeben wird, um konsistente Cache-Schlüssel sicherzustellen.

Beispiel:

location /search {
    sorted_args_dedupe first;

    proxy_cache_key "$uri$sorted_args";
    proxy_pass http://backend;
}

In diesem Beispiel wird eine Anfrage wie /search?q=foo&q=bar&q=baz $sorted_args als q=foo erzeugen, wobei nur der erste Wert beibehalten wird. Mit sorted_args_dedupe last würde es q=baz erzeugen.

Anwendungsbeispiele

Grundlegende Cache-Schlüssel-Normalisierung

Normalisieren Sie Cache-Schlüssel unabhängig von der Parameterreihenfolge:

http {
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m;

    server {
        listen 80;

        location / {
            proxy_cache my_cache;
            proxy_cache_key "$scheme$host$uri$sorted_args";
            proxy_pass http://backend;
        }
    }
}

Automatische Argumentüberschreibung

Automatisch $args mit sortierten Parametern für alle nachgelagerten Prozesse umschreiben:

server {
    listen 80;

    location /api {
        sorted_args_overwrite on;
        sorted_args_ignore_list timestamp _;

        # Alle diese verwenden jetzt automatisch sortierte, gefilterte Argumente
        proxy_pass http://backend;
        # Entspricht: proxy_pass http://backend$uri?$sorted_args;
    }
}

Herausfiltern von Cache-Busting-Parametern

Entfernen Sie Zeitstempel- und Tracking-Parameter aus Cache-Schlüsseln:

location /static {
    sorted_args_ignore_list _ t timestamp v version;

    proxy_cache zone;
    proxy_cache_key "$uri$sorted_args";
    proxy_pass http://cdn;
}

Whitelistmodus (Nur bestimmte Parameter zulassen)

Wenn Query-Parameter zu schwerem serverseitigem Processing führen können, verwenden Sie eine Whitelist, um streng zu steuern, welche Parameter für das Caching zulässig sind:

location /search {
    # Nur diese Parameter beeinflussen den Cache-Schlüssel; alle anderen werden verworfen
    sorted_args_allow_list q page limit category;

    proxy_cache zone;
    proxy_cache_key "$uri$sorted_args";
    proxy_pass http://search_backend;
}

In diesem Beispiel werden Anfragen wie /search?q=nginx&page=1&debug=true&nocache=1 unter Verwendung von nur category=&limit=&page=1&q=nginx zwischengespeichert, wodurch effektiv alle Cache-busting- oder Debugging-Parameter ignoriert werden.

Kombination von Whitelist und Blockliste

Sie können beide Direktiven zusammen verwenden, um eine feinkörnige Kontrolle zu erhalten. Die Whitelist wird zuerst angewendet, dann die Blockliste:

location /api {
    # Zuerst nur diese Parameter beibehalten
    sorted_args_allow_list user_id action page limit timestamp;

    # Dann den Zeitstempel aus dem erlaubten Set entfernen
    sorted_args_ignore_list timestamp;

    proxy_cache zone;
    proxy_cache_key "$uri$sorted_args";
    proxy_pass http://api_backend;
}

Protokollierung normalisierter Querystrings

Fügen Sie sortierte Querystrings in den Zugriffsprotokollen ein:

http {
    log_format detailed '$remote_addr - $remote_user [$time_local] '
                        '"$request" $status $body_bytes_sent '
                        '"$http_referer" "$http_user_agent" '
                        'args="$args" sorted_args="$sorted_args"';

    server {
        access_log /var/log/nginx/access.log detailed;
        # ...
    }
}

Standortbezogene Filterung

Verschiedene Standorte können unterschiedliche Filterlisten haben:

server {
    # Standard: Filtert gängige Tracking-Parameter
    sorted_args_ignore_list _ utm_source utm_medium utm_campaign;

    location /api {
        # API: auch Version und Zeitstempel filtern
        sorted_args_ignore_list _ utm_source utm_medium utm_campaign version t;
        proxy_pass http://api_backend;
    }

    location /content {
        # Inhalt: nur Tracking filtern
        proxy_pass http://content_backend;
    }
}

Vollständiges Beispiel

pid         logs/nginx.pid;
error_log   logs/error.log warn;

worker_processes  auto;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" "$http_user_agent" '
                    'args="$args" sorted_args="$sorted_args"';

    access_log  logs/access.log  main;

    proxy_cache_path /tmp/cache
                     levels=1:2
                     keys_zone=zone:10m
                     inactive=10d
                     max_size=100m;

    server {
        listen       8080;
        server_name  localhost;

        # Filtert Tracking- und Cache-Busting-Parameter
        location /filtered {
            sorted_args_ignore_list v _ time timestamp;

            proxy_set_header Host "backend";
            proxy_pass http://localhost:8081;

            proxy_cache zone;
            proxy_cache_key "$uri$sorted_args";
            proxy_cache_valid 200 1m;
        }

        # Verwenden Sie sortierte Argumente ohne Filterung
        location / {
            proxy_pass http://localhost:8081;

            proxy_cache zone;
            proxy_cache_key "$uri$sorted_args";
            proxy_cache_valid 200 10m;
        }
    }

    # Backend-Server zum Testen
    server {
        listen       8081;

        location / {
            return 200 "args: $args\nsorted_args: $sorted_args\n";
        }
    }
}

Wie es funktioniert

  1. Parameterextraktion: Das Modul analysiert den Querystring aus r->args, indem es an & und = splittet.
  2. Warteschlangenaufbau: Jeder Parameter wird in einer Warteschlangenstruktur mit seinem Schlüssel, Wert und vollständigem Schlüssel-Wert-Paar gespeichert.
  3. Sortierung: Parameter werden mit einer natürlichen Vergleichsfunktion sortiert:
  4. Primäre Sortierung: Parametername (groß-/kleinschreibung ignorierend, natürliche Reihenfolge)
  5. Sekundäre Sortierung: vollständiger Parameterstring (key=value, natürliche Reihenfolge)
  6. Natürliche Reihenfolge bedeutet, dass eingebettete Zahlen numerisch verglichen werden: item2 < item10
  7. Entfernen leerer Werte: Parameter mit = aber ohne Wert (wie ?a=) werden entfernt.
  8. Whitelist-Filterung: Wenn sorted_args_allow_list konfiguriert ist, werden nur Parameter, die den Mustern entsprechen, beibehalten.
  9. Blocklisten-Filterung: Parameter, die den Mustern in sorted_args_ignore_list entsprechen, werden ausgeschlossen.
  10. Duplikaterkennung: Wenn sorted_args_dedupe aktiviert ist, wird nur das erste oder letzte Vorkommen jedes Schlüssels beibehalten.
  11. Rekonstruktion: Die sortierten, gefilterten Parameter werden mit & verbunden, um den finalen String zu bilden.

Testen

Dieses Projekt verwendet Test::Nginx für seine Test-Suite, die in Docker für reproduzierbare Builds ausgeführt wird.

Voraussetzungen

  • Docker

Tests ausführen

Führen Sie die gesamte Test-Suite aus:

make tests

Führen Sie eine bestimmte Testdatei aus:

make tests T=t/sorted_args.t

Deaktivieren Sie den HUP-Modus zur Fehlersuche (langsamer, aber isolierter):

make tests HUP=0

Verwenden Sie eine andere NGINX-Version:

make tests NGINX_VERSION=release-1.26.2

Öffnen Sie eine interaktive Shell im Testcontainer zur Fehlersuche:

make shell

Testabdeckung

Die Test-Suite überprüft: - ✅ Grundlegende Sortierfunktionalität - ✅ Natürliche/numerische Sortierung (z.B. p=1, p=2, p=10 in der richtigen Reihenfolge) - ✅ Array-ähnliche Parameter (z.B. c[]=1&c[]=2) - ✅ Blocklistenfilterung (sorted_args_ignore_list) - ✅ Whitelistfilterung (sorted_args_allow_list) - ✅ Kombinierte Verwendung von Whitelist und Blockliste - ✅ Wildcard-Muster: Präfix (utm_*), Suffix (*_id), enthält (*token*) - ✅ Duplikaterkennung: sorted_args_dedupe first und last - ✅ Umgang mit leerem Querystring - ✅ Entfernen leerer Werte (?a=&b=2b=2) - ✅ Verwendung von Cache-Schlüsseln - ✅ Standortbezogene Konfigurationsvererbung - ✅ Direktive sorted_args_overwrite - ✅ Groß-/Kleinschreibung ignorierende Parameterübereinstimmung (sowohl Whitelist als auch Blockliste) - ✅ Parameter ohne Werte vs. leere Werte - ✅ Umgang mit doppelten Parametern - ✅ Erhaltung spezieller Zeichen - ✅ Fehlerhafte Query-Strings (aufeinanderfolgende kaufmännische Und-Zeichen) - ✅ Parameter mit mehreren Gleichheitszeichen - ✅ E2E: $args wird vor der Auswertung des Cache-Schlüssels geändert (REWRITE-Phasenzeitpunkt) - ✅ E2E: Umgestellte Parameter erzeugen identische Cache-Schlüssel - ✅ E2E: Rewrite-Direktiven sehen überschriebenes $args

Leistungsüberlegungen

  • Der sortierte Querystring wird einmal pro Anfrage berechnet und im Anfragekontext zwischengespeichert.
  • Die Sortierung verwendet den effizienten warteschlangenbasierten Algorithmus von NGINX.
  • Die Filterung verwendet eine groß-/kleinschreibung ignorierende Zeichenfolgenvergleich.
  • Die Speicherzuweisung erfolgt aus dem Anfragepool, sodass keine explizite Bereinigung erforderlich ist.

Einschränkungen

  • Parameterwerte werden nicht decodiert/codiert; die ursprüngliche Codierung bleibt erhalten.
  • Die Filterung ist für Parameternamen groß-/kleinschreibung ignorierend, bewahrt jedoch die ursprüngliche Groß-/Kleinschreibung in der Ausgabe.
  • Parameter mit leeren Werten (z.B. ?a=) werden immer entfernt; verwenden Sie ?a (ohne Gleichheitszeichen) für Flags.