HAProxy is able to use LUA scripts to handle requests.
To test this functionality, I will add a LUA script that will check the status of a TCP echo server and return a HTML status (200 for OK)
It was really simple and straight-forward.
I used the really good (as usual) blog post from the HAProxy blog team:
https://www.haproxy.com/fr/blog/5-ways-to-extend-haproxy-with-lua/
Declare in the global block the Lua scripts:
global
lua-load /etc/haproxy/checktcp.lua
Identify the kind of script you need (there are 5): check the blog post to find the one you need.
For my use-case, I need the service kind.
This one is really interesting for me as it allows to generates HTML page.
Write the rules in the frontends/backends: it depends of what kind of script you wrote.
For my use-case, the script will handle requests in the backend:
frontend fe_main
bind *:80
default_backend checktcp
backed checktcp
mode http
http-request use-service lua.checktcp
Of course, you cadd all kind of ACL and rules.
Write the script.
Probably the most difficult part.
But you have access to all Lua libraries found on your system and the inner API from HAProxy (http://www.arpalert.org/haproxy-api.html).
Mine is really simple: - it connects to the TCP server and send a message: ‘check’ - it removes the first line of the response (I used a custom TCP echo server that adds a header with some information like IPs) - it check the next line to see if it sees the word ‘check’ - if so, it creates a HTML page with an ‘OK’ text and return the code 200 - otherwise, it creates a HTML page with a ‘KO’ text and return the code 503
local function checktcp(applet)
local addr = '127.0.0.1'
local port = 8080
local code = 503
local response = "KO\r\n"
-- Use core.tcp to get an instance of the Socket class
local socket = core.tcp()
socket:settimeout(1)
-- Connect to the service and send the request
if socket:connect(addr, port) then
if socket:send("check\n") then
-- Skip response headers
socket:receive('*l')
-- Get the content
local content = socket:receive('*l')
if content and content == "check" then
code = 200
response = "OK\r\n"
end
end
socket:close()
end
applet:set_status(code)
applet:add_header("content-length", string.len(response))
applet:add_header("content-type", "text/html")
applet:start_response()
applet:send(response)
end
core.register_service("checktcp", "http", checktcp)
And that’s all: just restart HAProxy now.