Ist es möglich, $remote_user in einem Nginx-Zugriffsprotokoll abzuschneiden?

Ist es möglich, $remote_user in einem Nginx-Zugriffsprotokoll abzuschneiden?

Wir haben einen Nginx-Server, der in einigen Kontexten vertrauliche Daten im HTTP-Benutzernamenfeld empfängt. Genauer gesagt handelt es sich um einen API-Schlüssel, den Clients wie folgt senden curl -u "$API_KEY:" ...:

Das standardmäßige Nginx-Zugriffsprotokollformat enthält $remote_user, das den gesamten Client-API-Schlüssel in das Zugriffsprotokoll schreibt und die Datei mit vertraulichen Daten verunreinigt. Ich weiß, dass ich ein anderes Protokollformat definieren kann, das die Variable $remote_user vollständig weglässt, ich kann mir jedoch Fälle vorstellen, in denen es für die Protokollkorrelation oder die Reaktion auf Vorfälle enorm hilfreich sein könnte, zumindest einen Hinweis darauf zu haben, wer der Client war. Gibt es eine Möglichkeit, Nginx so zu konfigurieren, dass eine stark gekürzte Kopie von $remote_user im Zugriffsprotokoll gespeichert wird, anstatt des vollständigen Werts vom Client? (d. h. ABCDEFGH12345678wird ABCD*oder so ähnlich.)

(Es versteht sich auch von selbst, dass ich die eigentlichen Variablen vom Typ REMOTE_USER nicht zerstören möchte, auf die sich das WSGI-Backend zur Authentifizierung verlässt.)

Dies ist nginx 1.10.3, wie in den Standard-Debian-Stretch-Repos ausgeliefert.

Antwort1

Mit der Map-Direktive können Sie eine Variable basierend auf einer anderen festlegen.

Ich habe dies nicht getestet und bin daher nicht sicher, ob Nginx mit dem {,9}Teil meiner Regex-Syntax gut zurechtkommt. Sie müssen es also möglicherweise leicht anpassen, aber so etwas sollte Ihnen eine Variable mit den ersten 9 Zeichen der Remote_User-Variable geben. Bearbeiten Sie Ihr Protokollformat, um stattdessen die Truncated_User-Variable einzuschließen.

map $remote_user $truncated_user {
    ~* ^(.{,9}).* $1;
}

Antwort2

Die Antwort von @miknik hat fast funktioniert, aber es waren ein paar Anpassungen und Experimente nötig, bis sie tatsächlich funktionierte. Die vollständige Konfiguration, die ich letztendlich verwendet habe, ist:

http {
    [...]

    map $remote_user $truncated_remote_user {
        "~^(?P<tu>.{0,6}).*" $tu;
        default              -;
    }

    log_format combined_trunc '$remote_addr - $truncated_remote_user [$time_local] '
                              '"$request" $status $body_bytes_sent "$http_referer" '
                              '"$http_user_agent"';

    [...]

    server {
        [...]

        access_log /path/to/access.log combined_trunc;

        [...]
    }
}

verwandte Informationen