是否可以在 nginx 访问日志中截断 $remote_user?

是否可以在 nginx 访问日志中截断 $remote_user?

我们有一个 nginx 服务器,在某些情况下,它会接收 HTTP 用户名字段中的敏感数据。更具体地说,它是客户端发送的 API 密钥,例如curl -u "$API_KEY:" ...

默认的 nginx access_log 格式包括 $remote_user,它将整个客户端 API 密钥写入访问日志并用敏感数据污染文件。我知道我可以定义一个完全省略 $remote_user 变量的不同 log_format,但是我可以看到至少有一个关于客户端是谁的提示对于日志关联或事件响应非常有帮助。有没有办法配置 nginx 以将严重截断的 $remote_user 副本存储在访问日志中,而不是来自客户端的完整值?(即ABCDEFGH12345678成为ABCD*或类似的东西。)

(不用说,我不想破坏 WSGI 后端依赖于身份验证的实际 REMOTE_USER 类型变量。)

这是 nginx 1.10.3,在默认的 Debian Stretch 存储库中发布。

答案1

您可以使用 map 指令根据另一个变量来设置一个变量。

我还没有测试过这个,所以不确定 Nginx 是否能很好地处理{,9}我的正则表达式语法部分,所以您可能需要稍微调整一下,但是这样的事情应该会给您一个包含 remote_user 变量的前 9 个字符的变量,编辑您的日志格式以包含 truncated_user 变量。

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

答案2

@miknik 的答案几乎奏效了,但需要进行一些调整和实验才能真正让它发挥作用。我最终使用的完整配置是:

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;

        [...]
    }
}

相关内容