【问题标题】:Replace request body in NGINX proxy for POST将 NGINX 代理中的请求正文替换为 POST
【发布时间】:2015-09-16 16:40:47
【问题描述】:

我正在尝试使用 NGINX 代理一个需要在中间做一些魔术的请求。本质上,我有一个只能发送未经身份验证的 GET 请求的客户端,我需要接收此请求,使用存储在 NGINX 配置中的静态凭据进行 POST 登录到服务器,并用 html 重定向替换响应正文。这将适用于我的场景,因为 POST 响应将包含一个 Set-Cookie 标头,其中的会话 id 表示经过身份验证的会话。我知道我可以使用 proxy_method 强制 NGINX 通过 POST 进行出站呼叫,并且我可以使用 sub_filter 将 POST 响应替换为 html 重定向。我的问题是如何设置将在 POST 请求中发送的请求正文?

有什么想法吗?

伊恩

【问题讨论】:

    标签: nginx proxy


    【解决方案1】:

    Ubuntu 16.04 和 Ubuntu 18.04 的工作示例

    安装

    # sudo apt purge nginx-*  # maybe necessary, backup your /etc/nginx/… configs before!
    sudo add-apt-repository ppa:nginx/stable
    sudo apt-cache show nginx-extras | grep -E '(xenial|bionic)'
    sudo apt install nginx-extras  # Lua support (nginx-extras is > nginx-full)
    

    配置

    /etc/nginx/sites-available/test.conf

    server
    {
        listen 80;
        server_name test.example.com;
    
        location /
        {
            if ($request_method = POST)
            {
                access_by_lua_block
                {
                    ngx.req.read_body()
                    local req = ngx.req.get_body_data()
                    local newreq, n, err = ngx.re.gsub(req, "REPLACE", "REPLACED")
                    ngx.req.set_body_data(newreq)
                }
            }
    
            include proxy_params;
            proxy_pass http://target.local:80/;
        }
    }
    

    激活

    cd /etc/nginx/sites-enabled
    sudo ln -s ../sites-available/test.conf test.conf
    sudo nginx -t
    sudo service nginx reload  # or newer: sudo systemctl reload nginx
    

    如果没有sites-availablesites-enabled 文件夹,只需将test.conf 放入您的conf.d 文件夹即可。

    【讨论】:

    • 成功了!对于 docker 容器,它必须使用 "--with-luajit \" 编译
    【解决方案2】:

    不久前我花了很多时间研究这个问题,最好的解决方案似乎是使用 Lua。这有点痛苦。我不得不用 Lua 编译 NGINX。我用OpenResty。我的用例需要屏蔽通过我的 NGINX 反向代理发布的敏感数据。但是,它与您的绝对不同,因为您使用 proxy_method 进行额外的 POST,所以我不是 100% 它会解决您的问题。但是,我认为值得一试。如果有帮助,这是我的配置中的一个小代码 sn-p。如果您需要,很高兴详细说明。

    location /login {
        set $request_body_mask "";
    
            # mask client_secret in posts
            access_by_lua '
                local req = ngx.req.get_body_data()
            ngx.var.request_body_mask = ngx.re.gsub(req, "(client_secret=).{8}", "$1********")
        ';
    
        # mask client_secret in gets
        set_by_lua $request_mask '
            local req = ngx.var.request_uri
            return ngx.re.gsub(req, "(client_secret=).{8}", "$1********")
        ';
    

    【讨论】:

    • 谢谢,很有帮助。这也差不多是我得出的结论。我可能会选择编写一个模块来代替。
    • 我是否需要更改日志格式的任何内容。截至目前,我正在使用 $request_body。但是在应用上面的代码之后它没有记录任何东西
    • 好几年没看过这段代码了。这就是我所拥有的: # 添加到使用 lua log_format bodylog '$remote_addr $http_client_ip_address - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent " "$http_x_forwarded_for" ' '"$http_source_environment" "SUUID=$http_Session_UUID" ' '$request_time $upstream_response_time $pipe ' '"$resp_body"';
    猜你喜欢
    • 2019-02-22
    • 1970-01-01
    • 1970-01-01
    • 2020-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-25
    • 1970-01-01
    相关资源
    最近更新 更多