Skip to main content

HAProxy

CrowdSec

📚 Documentation 💠 Hub 💬 Discourse

A lua Remediation Component for haproxy.

warning

This component is compatible with HAProxy version 2.5 and higher.

How does it work ?

This component leverages haproxy lua's API to check e IP address against the local API.

Supported features:

  • Stream mode (pull the local API for new/old decisions every X seconds)
  • Ban remediation (can ban an IP address by redirecting him or returning a custom HTML page)
  • Captcha remediation (can return a captcha)
  • Works with IPv4/IPv6
  • Support IP ranges (can apply a remediation on an IP range)

Installation

Using packages

First, setup crowdsec repositories.

sudo apt install crowdsec-haproxy-bouncer
info

In stream mode, the component will launch an internal timer to pull the local API at the first request made to the server.

Manual installation

warning

It has been tested only on Debian/Ubuntu based distributions.

Download the latest release here

tar xvzf crowdsec-haproxy-bouncer.tgz
cd crowdsec-haproxy-bouncer-v*/
./install.sh

If you are on a mono-machine setup, the crowdsec-haproxy-bouncer install script will register directly to the local crowdsec, so you're good to go !

Upgrade

From package

sudo apt-get update
sudo apt-get install crowdsec-haproxy-bouncer

Manual Upgrade

If you already have crowdsec-haproxy-bouncer installed, please download the latest release and run the following commands:

tar xzvf crowdsec-haproxy-bouncer.tgz
cd crowdsec-haproxy-bouncer-v*/
sudo ./upgrade.sh
sudo systemctl restart haproxy

Configuration

Component configuration

/etc/crowdsec/bouncers/crowdsec-haproxy-bouncer.conf
API_KEY=<CROWDSEC_LAPI_KEY>
MAP_PATH= # path to community_blocklist.map
# bounce for all type of remediation that the component can receive from the local API
BOUNCING_ON_TYPE=all
# when the bouncer receive an unknown remediation, fallback to this remediation
FALLBACK_REMEDIATION=ban
MODE=stream
REQUEST_TIMEOUT=1000
# exclude the bouncing on those location
EXCLUDE_LOCATION=
# Update frequency in stream mode, in second
UPDATE_FREQUENCY=10
#those apply for "ban" action
# /!\ REDIRECT_LOCATION and BAN_TEMPLATE_PATH/RET_CODE can't be used together. REDIRECT_LOCATION take priority over RET_CODE AND BAN_TEMPLATE_PATH
BAN_TEMPLATE_PATH=/var/lib/crowdsec/lua/haproxy/templates/ban.html
REDIRECT_LOCATION=
RET_CODE=
#those apply for "captcha" action
# Captcha Secret Key
SECRET_KEY=
# Captcha Site key
SITE_KEY=
CAPTCHA_TEMPLATE_PATH=/var/lib/crowdsec/lua/haproxy/templates/captcha.html
CAPTCHA_EXPIRATION=3600

HAProxy Configuration

HAProxy must be amended with following configuration :

/!\ Be careful to the actual lua scripts location after install (/usr/lib or /usr/lib64 or /usr/local ...)

/etc/haproxy/haproxy.cfg
global
...
# Crowdsec bouncer >>>
lua-prepend-path /usr/lib/crowdsec/lua/haproxy/?.lua
lua-load /usr/lib/crowdsec/lua/haproxy/crowdsec.lua # path to crowdsec.lua
setenv CROWDSEC_CONFIG /etc/crowdsec/bouncers/crowdsec-haproxy-bouncer.conf # path to crowdsec bouncer configuration file
# Crowdsec bouncer <<<
...
frontend myApp
...
# Crowdsec bouncer >>>
stick-table type ip size 10k expire 30m # declare a stick table to cache captcha verifications
http-request lua.crowdsec_allow # action to identify crowdsec remediation
http-request track-sc0 src if { var(req.remediation) -m str "captcha-allow" } # cache captcha allow decision
http-request redirect location %[var(req.redirect_uri)] if { var(req.remediation) -m str "captcha-allow" } # redirect to initial url
http-request use-service lua.reply_captcha if { var(req.remediation) -m str "captcha" } # serve captcha template if remediation is captcha
http-request use-service lua.reply_ban if { var(req.remediation) -m str "ban" } # serve ban template if remediation is ban
# Crowdsec bouncer <<<
...
# Crowdsec bouncer >>>
# define a backend for the captcha provider to allow DNS resolution
backend captcha_verifier
server captcha_verifier www.recaptcha.net:443 check
#server hcaptcha_verifier hcaptcha.com:443 check
#server turnstile_verifier challenges.cloudflare.com:443 check
# this is a little bit magic the server name is used to inform which captcha service you are using

# define a backend for crowdsec to allow DNS resolution
# replace 127.0.0.1:8080 by the listen URI of the crowdsec local API
backend crowdsec
server crowdsec 127.0.0.1:8080 check
# Crowdsec bouncer <<<

Common haproxy issues

If you are facing errors where haproxy 503's when trying to reach out for captcha verification backend, you can try:

/etc/haproxy/haproxy.cfg
global
#Beware that this is disabling http client ssl verification and is only a temp workaround
httpclient.ssl.verify none
httpclient.resolvers.id my_resolver

#8.8.8.8 is just an example
resolvers my_resolver
nameserver ns1 8.8.8.8:53

Crowdsec backend

You must declare a backend for Crowdsec so we're able to resolve it's address during the refresh task. the backend and the server both must be named crowdsec.

The decisions are stored in a Map file, the location of the map file is configured with MAP_PATH parameter.

When using captcha remediation

Using captcha, You must declare a backend for the captcha provider so we're able to resolve it's address during captcha verification.

Validated ips are cached in a Stick table to avoid too many requests to captcha verification endpoint.

Setup captcha

Currently, we have support for 3 providers: recaptcha, hcaptcha or turnstile

If you want to use captcha with your HAProxy component, you must provide a Site key and Secret key in your component configuration.

If you wish to use any other provider than recaptcha you MUST adapt the server name in the backend:

  • recaptcha

(captcha_verifier documentation).

backend captcha_verifier
mode http
server captcha_verifier www.google.com:443 check
  • hcaptcha

(hcaptcha_verifier documentation)

backend captcha_verifier
mode http
server hcaptcha_verifier hcaptcha.com:443
  • turnstile

(turnstile_verifier documentation).

backend captcha_verifier
mode http
server turnstile_verifier challenges.cloudflare.com:443

Edit etc/crowdsec/bouncers/crowdsec-haproxy-bouncer.conf and configure the following options:

SECRET_KEY=
SITE_KEY=
CAPTCHA_TEMPLATE_PATH=/var/lib/crowdsec/lua/templates/captcha.html
CAPTCHA_EXPIRATION=3600

Restart HAProxy.

You can add a decisions with a type captcha to check if it works correctly:

sudo cscli decisions add -i <IP_TO_TEST> -t captcha

FAQ

Why aren't decisions applied instantly

In stream mode, the component will launch an internal timer to pull the local API at the first request. So the cache won't be refreshed until the first request hits the service.

SSL and certificates

In order to query captcha provider for verification, you need SSL certificates. Make sure you have root certificates installed on your system. You can also install ca-certificates.

References

API_KEY

string

API_KEY=<API_KEY>

CrowdSec Local API key.

Generated with sudo cscli bouncers add command.

BOUNCING_ON_TYPE

all | ban | captcha

BOUNCING_ON_TYPE=all

Type of remediation we want to bounce. If you choose ban only and receive a decision with captcha as remediation, the component will skip the decision.

FALLBACK_REMEDIATION

ban | captcha

FALLBACK_REMEDIATION=ban

The fallback remediation is applied if the component receives a decision with an unknown remediation.

REQUEST_TIMEOUT

int

REQUEST_TIMEOUT=1000

Timeout in milliseconds for the HTTP requests done by the component to query CrowdSec local API or captcha provider (for the captcha verification).

EXCLUDE_LOCATION

string (Seperate by comma)

EXCLUDE_LOCATION=/<path1>,/<path2>

The locations to exclude while bouncing. It is a list of location, separated by commas.

⚠️ It is not recommended to put EXCLUDE_LOCATION=/.

UPDATE_FREQUENCY

int

This option is only for the stream mode.

UPDATE_FREQUENCY=10

The frequency of update, in second, to pull new/old IPs from the CrowdSec local API.

REDIRECT_LOCATION

string

This option is only for the ban remediation.

REDIRECT_LOCATION=/<path>

The location to redirect the user when there is a ban.

If it is not set, the component will return the page defined in the BAN_TEMPLATE_PATH with the RET_CODE (403 by default).

BAN_TEMPLATE_PATH

string (path to file)

This option is only for the ban remediation.

BAN_TEMPLATE_PATH=<path_to_html_template>

The path to a HTML page to return to IPs that trigger ban remediation.

By default, the HTML template is located in /var/lib/crowdsec/lua/templates/ban.html.

RET_CODE

int

This option is only for the ban remediation.

RET_CODE=403

The HTTP code to return for IPs that trigger a ban remediation. If nothing specified, it will return a 403.

SECRET_KEY

string

This option is only for the captcha remediation.

SECRET_KEY=<captcha_secret_key>

The captcha secret key.

SITE_KEY

string

This option is only for the captcha remediation.

SITE_KEY=<captcha_site_key>

The captcha site key.

CAPTCHA_TEMPLATE_PATH

string (path to file)

This option is only for the captcha remediation.

CAPTCHA_TEMPLATE_PATH=<path_to_html_template>

The path to a captcha HTML template.

The component will try to replace {{captcha_site_key}} in the template with SITE_KEY parameter.

By default, the HTML template is located in /var/lib/crowdsec/lua/templates/captcha.html.

CAPTCHA_EXPIRATION

int

This option is only for the captcha remediation.

CAPTCHA_EXPIRATION=3600

The time for which the captcha will be validated. After this duration, if the decision is still present in CrowdSec local API, the IPs address will get a captcha again.