Haproxy, Lua and client's IP simple application
By Лука Билановић | July 28, 2018
Ever since haproxy started supporting embedded lua applications, I wanted to write one :) Finally I got chance to write simple application just a litte more than hello world - application that will emit your IP address via HTTP. First step is to write lua script and place it somewhere on FS (preferably somewhere under /etc/haproxy):
bilke@io:~$ cat /etc/haproxy/ip.lua
core.register_service("ip", "http", function(applet)
local src = applet.sf:src()
local response = tostring(src) .. "\n"
applet:set_status(200)
applet:add_header("content-length", string.len(response))
applet:add_header("content-type", "text/plain")
applet:start_response()
applet:send(response)
end)
We are registering lua function executed as a HTTP service and named ip. Then we are using AppletHTTP’s Fetches class to get access to haproxy samples - and in our case src() sample - which is holding value of the remote IP. Then we are convering address to string, concating new line at the end and emmting it in simple HTTP plain text response with minimum of necessay headers along with HTTP/200 response code.
Haproxy configuration is quite simple. First we need to load lua script and we are doing that (as the last line) in global section of our haproxy.cfg:
global
[...]
[...]
lua-load /etc/haproxy/ip.lua
And finally we are configuring host and path (if needed other conditions too) in simple ACL in frontend section and http-request/response with our lua application if that ACL’s conditions are met:
frontend http-https-in
[...]
[...]
acl ip_application path /ip and hdr(host) -i io.bot.nu
http-request use-service lua.ip if METH_GET ip_application
Restart haproxy and test it:
bilke@longitude:~$ curl -4 io.bot.nu/ip
139.162.127.169
bilke@longitude:~$ curl -6 io.bot.nu/ip
2a01:7e81::a03c:92ff:fea8:66eb
Not only it works, but it’s blazingly fast - 40745 requests/responses per second
bilke@io:~$ wrk -c 80 -d 10 -t 4 http://localhost/ip
Running 10s test @ http://localhost/ip
4 threads and 80 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 1.93ms 292.35us 9.40ms 86.58%
Req/Sec 10.24k 339.71 10.81k 85.75%
407753 requests in 10.01s, 26.44MB read
Requests/sec: 40745.34
Transfer/sec: 2.64MB
If you need fast, simple (and not so simple) TCP/HTTP service lua+haproxy is a way to go!