Ingress Nginx
๐ Documentation ๐ Hub ๐ฌ Discourse
A lua Remediation Component for Ingress Nginx Controller.
How does it work ?โ
This component leverages OpenResty lua's API, used the ingress nginx controller as a plugin.
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.
Installationโ
The Ingress nginx controller should be installed using the official helm chart
Using Helmโ
First you need to create new ingress-nginx chart values file (crowdsec-ingress-values.yaml) to upgrade the ingress controller with the crowdsec plugin.
Lua support has been removed from mainline ingress nginx in version 1.12. As CrowdSec remediation relies on lua, you need to use our controller image as shown in the following values.yaml.
controller:
image:
PullPolicy: IfNotPresent
image: crowdsecurity/controller
# Crowdsec Remediation with Ingress Nginx requires to use our controller image
tag: v1.13.2
# If you update the tag, the digest needs to be updated as well
digest: sha256:4575be24781cad35f8e58437db6a3f492df2a3167fed2b6759a6ff0dc3488d56
registry: docker.io
extraVolumes:
- name: crowdsec-bouncer-plugin
emptyDir: {}
extraInitContainers:
- name: init-clone-crowdsec-bouncer
image: crowdsecurity/lua-bouncer-plugin
imagePullPolicy: IfNotPresent
env:
- name: API_URL
value: "http://crowdsec-service.crowdsec.svc.cluster.local:8080" # crowdsec lapi service-name
- name: API_KEY
value: "<API KEY>" # generated with `cscli bouncers add <bouncer_name>
- name: BOUNCER_CONFIG
value: "/crowdsec/crowdsec-bouncer.conf"
- name: CAPTCHA_PROVIDER
value: "recaptcha" # valid providers are recaptcha, hcaptcha, turnstile
- name: SECRET_KEY
value: "<your-captcha-secret-key>" # If you want captcha support otherwise remove this ENV VAR
- name: SITE_KEY
value: "<your-captcha-site-key>" # If you want captcha support otherwise remove this ENV VAR
- name: BAN_TEMPLATE_PATH
value: "/etc/nginx/lua/plugins/crowdsec/templates/ban.html"
- name: CAPTCHA_TEMPLATE_PATH
value: "/etc/nginx/lua/plugins/crowdsec/templates/captcha.html"
## Appsec configuration, optional.
## Remove this section if not using appsec
- name: APPSEC_URL
value: "http://crowdsec-appsec-service.crowdsec.svc.cluster.local:7422" # if using our helm chart with "crowdsec" release name, and running the appsec in the "crowdsec" namespace
- name: APPSEC_FAILURE_ACTION
value: "passthrough" # What to do if the appsec is down, optional
- name: APPSEC_CONNECT_TIMEOUT # connection timeout to the appsec, in ms, optionial
value: "100"
- name: APPSEC_SEND_TIMEOUT # write timeout to the appsec, in ms, optional
value: "100"
- name: APPSEC_PROCESS_TIMEOUT # max processing duration of the request, in ms, optional
value: "1000"
- name: ALWAYS_SEND_TO_APPSEC
value: "false" # always send requests to the appsec, even if there's a decision against the IP, optional
command:
[
"sh",
"-c",
"sh /docker_start.sh; mkdir -p /lua_plugins/crowdsec/; cp -R /crowdsec/* /lua_plugins/crowdsec/",
]
volumeMounts:
- name: crowdsec-bouncer-plugin
mountPath: /lua_plugins
extraVolumeMounts:
- name: crowdsec-bouncer-plugin
mountPath: /etc/nginx/lua/plugins/crowdsec
subPath: crowdsec
config:
plugins: "crowdsec"
lua-shared-dicts: "crowdsec_cache: 50m"
server-snippet: |
lua_ssl_trusted_certificate "/etc/ssl/certs/ca-certificates.crt"; # If you want captcha support otherwise remove this line
resolver local=on ipv6=off;
You already have a deployed ingress nginx
This values.yaml upgrade your ingress deployment to add crowdsec lua lib as a
plugin and run with the crowdsec maintained nginx ingress controller with lua
support. It uses this docker
image to copy the
crowdsec lua library. You can upgrade the ingress-nginx using this crowdsec-ingress-values.yaml
helm -n ingress-nginx upgrade -f ingress-nginx-values.yaml -f crowdsec-ingress-values.yaml ingress-nginx/ingress-nginx
You don't have a deployed ingress nginx
This values.yaml install your ingress deployment to add crowdsec lua lib as a
plugin and run with the crowdsec maintained nginx ingress controller with lua
support. It uses this docker
image to copy the
crowdsec lua library. You can install the ingress-nginx using this crowdsec-ingress-values.yaml
helm -n ingress-nginx install -f crowdsec-ingress-values.yaml ingress-nginx ingress-nginx/ingress-nginx
And then check if the ingress controller is running well.
kubectl -n ingress-nginx get pods
In stream mode, the component will launch an internal timer to pull the local API at the first request made to the ingress controller.
Ingress controller Configurationโ
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 :
controller:
config:
lua-shared-dicts: "crowdsec_cache: 50m"
โ ๏ธ Do not rename the crowdsec_cache shared dict, else the component 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)
Referencesโ
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.
USE_TLS_AUTHโ
boolean
USE_TLS_AUTH=false # default
Enable mutual TLS (mTLS) authentication for secure communication with CrowdSec Local API. When enabled, the bouncer will use client certificates for authentication instead of API keys.
TLS_CLIENT_CERTโ
string (path to file)
TLS_CLIENT_CERT=<path_to_cert>
Path to the client certificate file for mTLS authentication. This option is only used when USE_TLS_AUTH is set to true.
TLS_CLIENT_KEYโ
string (path to file)
TLS_CLIENT_KEY=<path_to_key>
Path to the client certificate's private key file for mTLS authentication. This option is only used when USE_TLS_AUTH is set to true.
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 component mode:
- stream: The component will pull new/old decisions from the local API every X seconds (
UPDATE_FREQUENCYparameter). - 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_EXPIRATIONparameter).
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
livemode.
CACHE_EXPIRATION=120
The cache expiration, in second, for IPs that the component store in cache in live mode.
UPDATE_FREQUENCYโ
int
This option is only for the
streammode.
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
banremediation.
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
banremediation.
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 /etc/nginx/lua/plugins/crowdsec/templates/ban.html.
RET_CODEโ
int
This option is only for the
banremediation.
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
captcharemediation.
CAPTCHA_PROVIDER=recaptcha
For backwards compatibility reasons recaptcha is the default if no value is set.
SECRET_KEYโ
string
This option is only for the
captcharemediation.
SECRET_KEY=<captcha_secret_key>
The captcha secret key.
SITE_KEYโ
string
This option is only for the
captcharemediation.
SITE_KEY=<captcha_site_key>
The captcha site key.
CAPTCHA_TEMPLATE_PATHโ
string (path to file)
This option is only for the
captcharemediation.
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 /etc/nginx/lua/plugins/crowdsec/templates/captcha.html.
CAPTCHA_EXPIRATIONโ
int
This option is only for the
captcharemediation.
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
APPSEC_URL=http://<ip>:<port>
If set, enable appsec mode and forward the request to this endpoint for analysis.
Use http://crowdsec-appsec-service.crowdsec.svc.cluster.local:7422 if using our helm chart with crowdsec release name, and running the appsec in the crowdsec namespace.
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.