HAproxy + Lua:如果Lua脚本验证失败,则返回请求 [英] HAproxy+Lua: Return requests if validation fails from Lua script

查看:99
本文介绍了HAproxy + Lua:如果Lua脚本验证失败,则返回请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在尝试使用HAProxy + Lua构建传入请求验证平台.我们的用例是创建一个LUA脚本,该脚本本质上将根据验证结果对Validation API进行套接字调用从验证API,我们希望将请求重定向到后端API,如果验证失败,我们希望返回直接来自LUA脚本的请求.例如,对于200响应,我们希望将请求重定向到后端api,对于404,我们希望返回请求.从文档中,我了解到有许多可用的默认功能与Lua-Haproxy集成.

We are trying to build an incoming request validation platform using HAProxy+Lua. Our use-case is to create a LUA scripts that will essentially make a socket call to a Validation API, and based on the response from Validation API we want to redirect the request to a backend API, and if the validation fails we would want to return the request right from the LUA script. For example, for 200 response we would want to redirect the request to backend api, and for 404 we would want to return the request. From the documentation, I understand that there are various default functions available with Lua-Haproxy integration.

core.register_action() --> I'm using this. Take TXN as input
core.register_converters() --> Essentially used for string manipulations.
core.register_fetches() --> Takes TXN as input and returns string; Mainly used for representing dynamic backend profiles in haproxy config
core.register_init() --> Used for initialization
core.register_service() --> You have to return the response mandatorily while using this function, which doesn't satisfy our requirements
core.register_task() -->  For using normal functions. No mandatory input class. TXN is required to fetch header details from request

我已经尝试了上面列表中的所有功能,我知道core.register_service基本上是从Lua脚本.但是,有问题的是,我们必须从LUA脚本发送响应,并且它不会将请求重定向到BACKEND.当前,我正在使用core.register_action中断请求,但是无法使用此函数返回请求.这是我的代码是什么样的:

I have tried all of the functions from above list, I understand that core.register_service is basically to return a response from the Lua script. However, what is problematic is, we must send the response from the LUA script and it will not redirect the request to BACKEND. Currently, I am using core.register_action to interrupt the requests, but I'm not able to return the request using this function. Here's what my code looks like:

local http_socket = require("socket.http")
local pretty_print = require("pl.pretty")

function add_http_request_header(txn, name, value)
    local headerName = name
    local headerValue = value
    txn.http:req_add_header(headerName, headerValue)
end

function call_validation_api()
    local request, code, header = http_socket.request {
                                   method = "GET",                    -- Validation API Method                           
                                   url = "http://www.google.com/"     -- Validation API URL
                                   }

   -- Using core.log; Print in some cases is a blocking operation http://www.arpalert.org/haproxy-lua.html#h203
   core.Info( "Validation API Response Code: " .. code )
   pretty_print.dump( header )
   return code
end

function failure_response(txn)
    local response = "Validation Failed"
    core.Info(response)
    txn.res:send(response)
--    txn:close()
end

core.register_action("validation_action", { "http-req", "http-res" }, function(txn)
   local validation_api_code = call_validation_api()
   if validation_api_code == 200 then
      core.Info("Validation Successful")
      add_http_request_header(txn, "test-header", "abcdefg")
      pretty_print.dump( txn.http:req_get_headers() )
   else
      failure_response(txn) --->>> **HERE I WANT TO RETURN THE RESPONSE**
   end
end)

以下是配置文件条目:

frontend  http-in
    bind :8000
    mode http
    http-request    lua.validation_action

    #Capturing header of the incoming request
    capture request header test-header len 64

    #use_backend %[lua.fetch_req_params]
    default_backend app

backend         app
    balance     roundrobin
    server      app1    127.0.0.1:9999  check

在实现此功能方面,任何帮助都将不胜感激.另外,我知道从Lua脚本进行的SOCKET调用是阻塞调用,这与HAProxy的keep-alive连接的默认性质相反.如果您已经使用过,请随时建议其他实用程序来实现此功能.

Any help is much appreciated in achieving this functionality. Also, I understand that SOCKET call from Lua script is a blocking call, which is opposite to HAProxy's default nature of keep-alive connection. Please feel free to suggest any other utility to achieve this functionality, if you have already used it.

推荐答案

好,我已经找到了这个问题的答案:我创建了2个用于成功和失败请求的后端,并根据响应返回了2个不同的字符串.在"failure_backend"中,我调用了另一个服务,该服务本质上是core.register_service,可以返回响应.我正在粘贴配置文件和lua脚本的代码

Ok I have figured out the answer to this question: I created 2 backends for success and failure of requests, and based on the response I am returning 2 different strings. In "failure_backend", I have called a different service, which essentially is a core.register_service and can return the response. I'm pasting code for both the configuration file and lua script

HAProxy conf文件:

HAProxy conf file:

#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    # to have these messages end up in /var/log/haproxy.log you will
    # need to:
    #
    # 1) configure syslog to accept network log events.  This is done
    #    by adding the '-r' option to the SYSLOGD_OPTIONS in
    #    /etc/sysconfig/syslog
    #
    # 2) configure local2 events to go to the /var/log/haproxy.log
    #   file. A line like the following can be added to
    #   /etc/sysconfig/syslog
    #
    #    local2.*                       /var/log/haproxy.log
    #
    log         127.0.0.1 local2
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon
    #lua file load
    lua-load    /home/aman/coding/haproxy/http_header.lua

    # turn on stats unix socket
    stats       socket      /var/lib/haproxy/stats

#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
    mode        http
    log         global
    option      httplog
    option      dontlognull
    retries     3
    timeout     http-request    90s
    timeout     queue           1m
    timeout     connect         10s
    timeout     client          1m
    timeout     server          1m
    timeout     http-keep-alive 10s
    timeout     check           10s
    maxconn     3000

#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend            http-in
    bind            :8000
    mode            http
    use_backend     %[lua.validation_fetch]
    default_backend failure_backend

#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend         success_backend
    balance     roundrobin
    server      app1    172.23.12.94:9999  check

backend             failure_backend
    http-request    use-service     lua.failure_service

# For displaying HAProxy statistics.
frontend            stats
    bind            :8888
    default_backend stats

backend     stats
    stats   enable
    stats   hide-version
    stats   realm Haproxy Statistics
    stats   uri /haproxy/stats
    stats   auth aman:rjil@123

Lua脚本:

local http_socket = require("socket.http")
local pretty_print = require("pl.pretty")

function add_http_request_header(txn, name, value)
    local headerName = name
    local headerValue = value
    txn.http:req_add_header(headerName, headerValue)
end

function call_validation_api()
    local request, code, header = http_socket.request {
                                   method = "GET",                          -- Validation API Method                           
                                   url = "http://www.google.com/"     -- Validation API URL
                                   }

   -- Using core.log; Print in some cases is a blocking operation http://www.arpalert.org/haproxy-lua.html#h203
   core.Info( "Validation API Response Code: " .. code )
   pretty_print.dump( header )
   return code
end

function failure_response(txn)
    local response = "Validation Failed"
    core.Info(response)
    return "failure_backend"
end

-- Decides back-end based on Success and Failure received from validation API
core.register_fetches("validation_fetch", function(txn)
   local validation_api_code = call_validation_api()
   if validation_api_code == 200 then
      core.Info("Validation Successful")
      add_http_request_header(txn, "test_header", "abcdefg")
      pretty_print.dump( txn.http:req_get_headers() )
      return "success_backend"
   else
      failure_response(txn)
   end
end)

-- Failure service
core.register_service("failure_service", "http", function(applet)
      local response = "Validation Failed"
      core.Info(response)
      applet:set_status(400)
      applet:add_header("content-length", string.len(response))
      applet:add_header("content-type", "text/plain")
      applet:start_response()
      applet:send(response)
end)

这篇关于HAproxy + Lua:如果Lua脚本验证失败,则返回请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆