Big file upload and lua script

Hello,

I have configured haproxy (2.4.3 as docker container) to validate the token via lua script against Keycloak server. Otherwise it has been working ok, but now I detected problem with files larger than the tune.bufsize configuration.

I’m using this library to connect the Keycloak server: GitHub - haproxytech/haproxy-lua-http: Simple Lua HTTP helper && client for use with HAPro. The script seems to run fine and token is validated.

The error returned is 500 Internal Server Error and the request is never forwarded to the api-server. If the multipart file is smaller or bufsize is increased, everything works without any problems.

Is this a bug or am I missing some option here?

global
    lua-load /usr/local/etc/haproxy/authorize.lua
    maxconn 50000
    log stdout local0
    user haproxy
    group haproxy
    nbthread 4
    cpu-map auto:1/1-4 0-3
    ssl-default-bind-ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
    ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
defaults
    timeout connect 10s
    timeout client 30s
    timeout server 30s
    timeout tunnel 1h
    log global
    mode http
    option httplog
    maxconn 3000s
    option http-keep-alive
resolvers mydns
    parse-resolv-conf
frontend localhost

    bind *:8443 ssl crt /usr/local/etc/certs/cert.pem

    http-request redirect scheme https unless { ssl_fc }
    http-request set-header X-Forwarded-Proto https
   
    # ACL for target
    acl is_api path_beg /api/
    http-request set-var(req.token) hdr(authorization)

    http-request lua.authorize keycloak keycloak1 testrealm if is_api

    # ACL for token
    acl is_valid_organization var(req.token_ok) -m bool
    acl is_authenticated var(req.is_authenticated) -m bool

    # Deny if not authenticated for api
    http-request deny if !is_authenticated

    use_backend api if is_api
backend api
    option forwardfor
    server server1 apiserver:8080 check resolvers mydns
backend keycloak
    option forwardfor
    server keycloak1 keycloak:8080 check resolvers mydns

local http = require('http')

local function main(txn, backend, server, realm)

    -- extract authorization and host headers
    local token = txn.get_var(txn, "req.token")
    local host_header = txn.sf:req_fhdr("host")
    if token == nil then 
        core.log(6, "No authorization token found")
        do return end
    end
    core.Info(token)
    
    -- Create url for keycloak token validation
    local url =
        "http://" .. core.backends[backend].servers[server]:get_addr() ..
            "/auth/realms/" .. realm .. "/protocol/openid-connect/userinfo"
    -- Validate the token, authorization header is copied from client. host-header also needs to be copied and x-forwarded-proto set to https
    -- for token issuer matching
    local res, err = http.get {
        url = url,
        headers = {
            authorization = token,
            host = host_header,
            ["x-forwarded-proto"] = "https"
        }
    }
    if res then
        core.Info(tostring(res.content))
        if res.status_code == 200 then
            txn:set_var("req.is_authenticated", true)
            core.Info("Token validated. Checking access rights.")
            local json = res:json();
            local path = txn.sf:path() .. "/"
            if json.organization ~= nil then
                local pattern = "^/.*/" .. json.organization .. "/"
                core.Info(pattern)
                core.Info(string.match(path, pattern))
                if string.match(path, pattern) ~= nil
                then
                    txn:set_var("req.token_ok", true)
                end
            end
        else
            core.Info("Token not valid!")
            txn:set_var("req.is_authenticated", false)
        end
    end

end

core.register_action("authorize", {"http-req"}, main, 3)

1 Like