OpenResty Bouncer
๐ Documentation๐ Hub๐ฌ Discourse
A lua bouncer for OpenResty.
#
How does it work ?This bouncer leverages OpenResty lua's API, namely access_by_lua_block
to check e IP address against the local API.
Supported features:
- Live mode (query the local API for each request)
- 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)
- reCAPTCHA v2 remediation (can return a captcha)
- Works with IPv4/IPv6
- Support IP ranges (can apply a remediation on an IP range)
At the back, this bouncer uses crowdsec lua lib.
warning
If you need to upgrade the bouncer from v0.X to v1.X, please follow this migration process
#
InstallationBefore installation
openresty bouncer depends on openresty, openresty-opm, gettext-base. it has been tested only on debian/ubuntu based distributions. You can install openresty and openresty-opm from openresty linux packages.
Install the following packages:
sudo apt install openresty openresty-opm gettext-base
#
Using packages- Debian/Ubuntu
- RHEL/Centos/Fedora
sudo apt install crowdsec-openresty-bouncer
sudo yum install crowdsec-openresty-bouncer
info
In stream mode, the bouncer will launch an internal timer to pull the local API at the first request made to the server.
After installation
The openresty linux packages doesn't include any conf.d/
directory for custom configurations.
You need to add include /usr/local/openresty/nginx/conf/conf.d/crowdsec_openresty.conf;
in nginx config file /usr/local/openresty/nginx/conf/nginx.conf
in the http section.
#
Manual installationDownload the latest release here
tar xvzf crowdsec-openresty-bouncer.tgzcd crowdsec-openresty-bouncer-v*/sudo ./install.sh
If you are on a mono-machine setup, the crowdsec-openresty-bouncer
install script will register directly to the local crowdsec, so you're good to go !
โ ๏ธ the installation script will take care of dependencies for Debian/Ubuntu
non-debian based dependencies
- openresty-opm : OpenResty Package Manager
- pintsized/lua-resty-http : lua lib managed by openresty-opm
#
Configuration#
Bouncer configurationAPI_URL=<CROWDSEC_LAPI_URL>API_KEY=<CROWDSEC_LAPI_KEY># bounce for all type of remediation that the bouncer can receive from the local APIBOUNCING_ON_TYPE=all# when the bouncer receive an unknown remediation, fallback to this remediationFALLBACK_REMEDIATION=banMODE=streamREQUEST_TIMEOUT=1000# exclude the bouncing on those locationEXCLUDE_LOCATION=# Cache expiration in live mode, in secondCACHE_EXPIRATION=1# Update frequency in stream mode, in secondUPDATE_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_PATHBAN_TEMPLATE_PATH=/var/lib/crowdsec/lua/templates/ban.htmlREDIRECT_LOCATION=RET_CODE=#those apply for "captcha" action# reCAPTCHA Secret KeySECRET_KEY=# reCAPTCHA Site keySITE_KEY=CAPTCHA_TEMPLATE_PATH=/var/lib/crowdsec/lua/templates/captcha.htmlCAPTCHA_EXPIRATION=3600
#
OpenResty ConfigurationThe bouncer OpenResty configuration is located in /usr/local/openresty/nginx/conf/conf.d/crowdsec_openresty.conf
:
lua_package_path '$prefix/../lualib/plugins/crowdsec/?.lua;;';lua_shared_dict crowdsec_cache 50m;resolver local=on ipv6=off;lua_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;init_by_lua_block { cs = require "crowdsec" local ok, err = cs.init("/etc/crowdsec/bouncers/crowdsec-openresty-bouncer.conf", "crowdsec-openresty-bouncer/v0.0.7") if ok == nil then ngx.log(ngx.ERR, "[Crowdsec] " .. err) error() end ngx.log(ngx.ALERT, "[Crowdsec] Initialisation done")}
access_by_lua_block { local cs = require "crowdsec" cs.Allow(ngx.var.remote_addr) }
The bouncer uses lua_shared_dict to share cache between all workers.
If you want to increase the cache size you need to change this value lua_shared_dict crowdsec_cache 50m;
.
โ ๏ธ Do not rename the crowdsec_cache
shared dict, else the bouncer will not work anymore.
#
When using captcha remediationTo make HTTP request in the bouncer, we need to set a resolver
in the configuration. We choose local=on
directive since we query google.com
for the captcha verification, but you can replace it with a valid one.
To make secure HTTP request in the bouncer, we need to specify a trusted certificate (lua_ssl_trusted_certificate
).
You can also change this with a valid one :
- /etc/ssl/certs/ca-certificates.crt (Debian/Ubuntu/Gentoo) - /etc/pki/tls/certs/ca-bundle.crt (Fedora/RHEL 6) - /etc/ssl/ca-bundle.pem (OpenSUSE) - /etc/pki/tls/cacert.pem (OpenELEC) - /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem (CentOS/RHEL 7) - /etc/ssl/cert.pem (OpenBSD, Alpine)
#
Setup captchaCurrently, only reCAPTCHA v2 is supported.
If you want to use reCAPTCHA with your OpenResty Bouncer, you must provide a reCAPTCHA Site key and Secret key in your bouncer configuration (recaptcha documentation).
Edit etc/crowdsec/bouncers/crowdsec-openresty-bouncer.conf
and configure the following options:
SECRET_KEY=SITE_KEY=CAPTCHA_TEMPLATE_PATH=/var/lib/crowdsec/lua/templates/captcha.htmlCAPTCHA_EXPIRATION=3600
Restart OpenResty.
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 instantlyIn stream mode, the bouncer 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.
#
Resolver and certificatesIn order to query google.com
for the reCAPTCHA verification, we need to set a resolver and a SSL certificate in our OpenResty configuration.
If you already have a resolver set in nginx configuration, you don't need to add another one.
Here is a config example, but you can change values:
resolver local=on ipv6=off;lua_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
And restart OpenResty.
#
Migrate from v0 to v1The best way to migrate from the crowdsec-openresty-bouncer v0.* to v1 is to reinstall the bouncer. Indeed, many new configurations options are now available and some has been removed.
- Backup your CrowdSec Local API key from your configuration file (
/etc/crowdsec/bouncers/crowdsec-openresty-bouncer.conf
) - Remove the old bouncer:
sudo apt-get remove --purge crowdsec-openresty-bouncer
- Install the new bouncer:
sudo apt-get updatesudo apt-get install crowdsec-openresty-bouncer
- Configure the bouncer in
/etc/crowdsec/bouncers/crowdsec-openresty-bouncer.conf
#
ReferencesAPI_KEY
#
API_KEY=<API_KEY>
CrowdSec Local API key.
Generated with sudo cscli bouncers add
command.
API_URL
#
API_URL=http://<ip>:<port>
CrowdSec local API URL.
BOUNCING_ON_TYPE
#
BOUNCING_ON_TYPE=all|ban|captcha
Type of remediation we want to bounce.
If you choose ban
only and receive a decision with captcha
as remediation, the bouncer will skip the decision.
FALLBACK_REMEDIATION
#
FALLBACK_REMEDIATION=ban
The fallback remediation is applied if the bouncer receives a decision with an unknown remediation.
MODE
#
MODE=stream|live
The default mode is live
.
The bouncer mode:
- stream: The bouncer will pull new/old decisions from the local API every X seconds (
UPDATE_FREQUENCY
parameter).
Note: The timer that pull the local API will be triggered after the first request.
- live: The bouncer will query the local API for each requests (if IP is not in cache) and will store the IP in cache for X seconds (
CACHE_EXPIRATION
parameter).
REQUEST_TIMEOUT
#
REQUEST_TIMEOUT=1000
Timeout in milliseconds for the HTTP requests done by the bouncer to query CrowdSec local API or www.google.com (for the reCAPTCHA verification).
EXCLUDE_LOCATION
#
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=/
.
CACHE_EXPIRATION
#
This option is only for the
live
mode.
CACHE_EXPIRATION=1
The cache expiration, in second, for IPs that the bouncer store in cache in live
mode.
UPDATE_FREQUENCY
#
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
#
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 bouncer will return the page defined in the BAN_TEMPLATE_PATH
with the RET_CODE
(403 by default).
BAN_TEMPLATE_PATH
#
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
#
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
#
This option is only for the
captcha
remediation.
SECRET_KEY=<recaptcha_secret_key>
The reCAPTCHA v2 secret key.
SITE_KEY
#
This option is only for the
captcha
remediation.
SITE_KEY=<recaptcha_site_key>
The reCAPTCHA v2 site key.
CAPTCHA_TEMPLATE_PATH
#
This option is only for the
captcha
remediation.
CAPTCHA_TEMPLATE_PATH=<path_to_html_template>
The path to a captcha HTML template.
The bouncer will try to replace {{recaptcha_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
#
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.