HAProxy - Lua (Built-in HTTP Client)
Supported versions
This DataDome module is supported with HAProxy 2.6.8+ and 2.7.1+ as it requires a built-in HTTP client to call DataDome's Protection API.
Installation
If you already have HAProxy binary with Lua support, you can skip this section.
You can check HAProxy version by running
$ haproxy -v
HAProxy version 2.6.8-1ppa1~jammy 2023/01/24 - https://haproxy.org/
Status: long-term supported branch - will stop receiving fixes around Q2 2027.
Known bugs: http://www.haproxy.org/bugs/bugs-2.6.8.html
Running on: Linux 5.15.0-1028-aws #32-Ubuntu SMP Mon Jan 9 12:28:07 UTC 2023 x86_64
You can validate Lua Version using
$ haproxy -vv
HAProxy version 2.6.8-1ppa1~jammy 2023/01/24 - https://haproxy.org/
Status: long-term supported branch - will stop receiving fixes around Q2 2027.
[...]
Built with Lua version : Lua 5.3.6
[...]
Configuration
You need to follow the steps below:
- Download the latest DataDome module from this link here and extract it in your HAProxy configuration directory.
The archive includes the following files:
- datadome.lua: a Lua script that handles the transformation of the HTTP request
- core/helper.lua: Lua scripts to manipulate strings and HTTP Requests
- haproxy.cfg: Example file of a working configuration
- Edit the HAProxy configuration file and set
DATADOME_SERVERSIDE_API_KEY
with your own API server key provided by DataDome. You can find this key inside our dashboard. - Update your HAProxy configuration file by replacing
<PATH>
with the actual path where you placed the file, and setting the different blocks needed: - Add the
txn.placeholderX
variable in the frontend to protect - Add the request/response hook as in the example below
global
[...]
lua-load <PATH>/datadome.lua
set-var proc.Datadome_key str("DATADOME_SERVERSIDE_API_KEY") # Set your serverside key here
[...]
# Example of frontend which will be protected
frontend http
[...]
# Insert these lines on each frontend you want to protect
http-request set-var(txn.placeholder1) var(txn.dd.x_datadome_request_headers)
http-request set-var(txn.placeholder2) var(txn.dd.x_datadome_headers)
http-request set-var(txn.placeholder3) var(txn.dd.x_datadome_response)
http-request set-var(txn.placeholder4) var(txn.dd.body)
http-request set-var(txn.placeholder5) var(txn.dd.error)
# Here check uri is not in exclusion path
acl excluded_files path_reg -i .\.(avi|flv|mka|mkv|mov|mp4|mpeg|mpg|mp3|flac|ogg|ogm|opus|wav|webm|webp|bmp|gif|ico|jpeg|jpg|png|svg|svgz|swf|eot|otf|ttf|woff|woff2|css|less|jsf|js|map)$
http-request lua.Datadome_request_hook if !excluded_files
http-response lua.Datadome_response_hook
# Insert this line before all default_backend / use_backend directives
use_backend failure_backend if { var(txn.dd.status) -m str blocked }
default_backend [...]
# Backend to server the "blocked page"
backend failure_backend
mode http
http-request use-service lua.failure_service
Settings
Settings | Description | Default Value | Required | File |
---|---|---|---|---|
DataDome_Key (*haproxy.cfg) | Your DataDome server-side key - Available inside our dashboard | Yes | haproxy.cfg | |
Endpoint | URL of the closest endpoint. More info here | api.datadome.co | Optional | datadome.lua |
Timeout | API request timeout for reused connections in ms | 150ms | Optional | datadome.lua |
FAQ
How can I have DataDome response status in the log?
- For each request protected by DataDome, the txn.dd.x_datadome_response contains the value of the HTTP response API
- If there is an issue in the call to Datadome, the variable txn.dd.error contains the error code and details.
- the main errors are as follow:
- 400 - Bad Request (Invalid DataDome Key ?)
- 504 - API Server times out
- 503 - Invalid response from API Server
How can I get Bot Name, RuleType and Bot/Human flags in my application?
It is possible to specify a Log-Format to log the returned Datadome Headers
Some headers returned by the API are:
- X-DataDome-botname
- X-DataDome-ruletype
- X-DataDome-isbot
- X-DataDome-requestid
- ...
and can be logged using the methodlua.ddHeaders
as follow
log-format "X-DataDome-botname: %{+Q}[lua.ddHeaders(X-DataDome-botname)] | X-DataDome-family: %{+Q}[lua.ddHeaders(X-DataDome-ruletype)] | X-DataDome-isbot: %{+Q}[lua.ddHeaders(X-DataDome-isbot)] | %{+Q}[lua.ddHeaders(X-DataDome-requestid)]"
You can find more information here.
How can I exclude files from DataDome protection?
In the Haproxy configuration, option to call DataDome is managed by an HAProxy ACL.
Default ACL is as follow
acl excluded_files path_reg -i .\.(avi|flv|mka|mkv|mov|mp4|mpeg|mpg|mp3|flac|ogg|ogm|opus|wav|webm|webp|bmp|gif|ico|jpeg|jpg|png|svg|svgz|swf|eot|otf|ttf|woff|woff2|css|less|jsf|js|map)$
It can be completed by custom rules / other ACLs
Updated about 2 months ago