OpenResty
📚 Documentation 💠 Hub 💬 Discourse
A lua Remediation Component for OpenResty.
How does it work ?
This component 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)
- Captcha remediation (can return a captcha)
- Works with IPv4/IPv6
- Support IP ranges (can apply a remediation on an IP range)
At the back, this component uses crowdsec lua lib.
If you need to upgrade the component from v0.X to v1.X, please follow this migration process
Installation
openresty component 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
In stream mode, the component will launch an internal timer to pull the local API at the first request made to the server.
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 installation
Download the latest release here
tar xvzf crowdsec-openresty-bouncer.tgz
cd 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
Component configuration
API_URL=<CROWDSEC_LAPI_URL>
API_KEY=<CROWDSEC_LAPI_KEY>
# bounce for all type of remediation that the remediation can receive from the local API
BOUNCING_ON_TYPE=all
# when the remediation receive an unknown remediation, fallback to this remediation
FALLBACK_REMEDIATION=ban
MODE=stream
REQUEST_TIMEOUT=1000
# exclude the bouncing on those location
EXCLUDE_LOCATION=
# Cache expiration in live mode, in second
CACHE_EXPIRATION=1
# 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/templates/ban.html
REDIRECT_LOCATION=
RET_CODE=
#those apply for "captcha" action
#valid providers are recaptcha, hcaptcha, turnstile
CAPTCHA_PROVIDER=
# default is recaptcha to ensure backwards compatibility
# Captcha Secret Key
SECRET_KEY=
# Captcha Site key
SITE_KEY=
CAPTCHA_TEMPLATE_PATH=/var/lib/crowdsec/lua/templates/captcha.html
CAPTCHA_EXPIRATION=3600
## Application Security Component Configuration
APPSEC_URL=
#### default ###
APPSEC_FAILURE_ACTION=passthrough
APPSEC_CONNECT_TIMEOUT=100
APPSEC_SEND_TIMEOUT=100
APPSEC_PROCESS_TIMEOUT=1000
ALWAYS_SEND_TO_APPSEC=false
SSL_VERIFY=true
################
OpenResty Configuration
The component 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 component 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 remediation
To make HTTP request in the component, 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 component, 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)
Application Security Component Configuration
To setup the Application Security Component you first need to install it in your CrowdSec Security Engine.
On the Remediation Component side, you just need to configure the following option in the Remediation Component file:
# Mandatory
APPSEC_URL=http://127.0.0.1:7422
# URL of the AppSec Component
# Optional
APPSEC_FAILURE_ACTION=passthrough # default
APPSEC_CONNECT_TIMEOUT=100 # default
APPSEC_SEND_TIMEOUT=100 # default
APPSEC_PROCESS_TIMEOUT=1000 # default
ALWAYS_SEND_TO_APPSEC=false # default
SSL_VERIFY=true # default
Setup captcha
Currently, we have support for 3 providers: recaptcha, hcaptcha or turnstile
If you want to use captcha with your OpenResty, 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 also provide a Captcha provider.
Edit etc/crowdsec/bouncers/crowdsec-openresty-bouncer.conf
and configure the following options:
CAPTCHA_PROVDER=
SECRET_KEY=
SITE_KEY=
CAPTCHA_TEMPLATE_PATH=/var/lib/crowdsec/lua/templates/captcha.html
CAPTCHA_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 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.
Resolver and certificates
In order to resolve the captcha provider you need to set a resolver and a SSL certificate in your nginx 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 v1
The 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 component:
sudo apt-get remove --purge crowdsec-openresty-bouncer
- Install the new component:
sudo apt-get update
sudo apt-get install crowdsec-openresty-bouncer
- Configure the component in
/etc/crowdsec/bouncers/crowdsec-openresty-bouncer.conf
Configuration Reference
API_KEY
string
API_KEY=<API_KEY>
CrowdSec Local API key.
Generated with sudo cscli bouncers add
command.
API_URL
string
API_URL=http://<ip>:<port>
CrowdSec local API URL.
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.
MODE
stream | live
MODE=stream
The default mode is live
.
The component mode:
- stream: The component will pull new/old decisions from the local API every X seconds (
UPDATE_FREQUENCY
parameter). - live: The component 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).
The timer that pull the local API will be triggered after the first request.
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 (comma separated)
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
int
This option is only for the
live
mode.
CACHE_EXPIRATION=1
The cache expiration, in second, for IPs that the remediation store in cache in live
mode.
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.
CAPTCHA_PROVIDER
recaptcha | hcaptcha | turnstile
This option is only for the
captcha
remediation.
CAPTCHA_PROVIDER=<recaptcha
For backwards compatability reasons recaptcha
is the default if no value is set.
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.
APPSEC_URL
string
URL of the Application Security Component
APPSEC_URL=http://127.0.0.1:7422
APPSEC_FAILURE_ACTION
passthrough | deny
APPSEC_FAILURE_ACTION=passthrough # default
Behavior when the AppSec Component return a 500. Can let the request passthrough or deny it.
ALWAYS_SEND_TO_APPSEC
boolean
ALWAYS_SEND_TO_APPSEC=false # default
Send the request to the AppSec Component even if there is a decision for the IP.
SSL_VERIFY
boolean
SSL_VERIFY=false # default
Verify the AppSec Component SSL certificate validity.
APPSEC_CONNECT_TIMEOUT
int (milliseconds)
APPSEC_CONNECT_TIMEOUT=100 # default
The timeout of the connection between the Remediation Component and AppSec Component.
APPSEC_SEND_TIMEOUT
int (milliseconds)
APPSEC_SEND_TIMEOUT=100 # default
The timeout to send data from the Remediation Component to the AppSec Component.
APPSEC_PROCESS_TIMEOUT
int (milliseconds)
APPSEC_PROCESS_TIMEOUT=500 # default
The timeout to process the request from the Remediation Component to the AppSec Component.