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
Using Helm
First you need to create new ingress-nginx chart values file (crowdsec-ingress-bouncer.yaml
) to upgrade the ingress controller with the crowdsec plugin.
controller:
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;
This values upgrade your ingress deployment to add crowdsec lua lib as a plugin and run with the ingress controller. It used this docker image to copy the crowdsec lua library.
Once you have this patch we can upgrade the ingress-nginx chart.
helm -n ingress-nginx upgrade -f ingress-nginx-values.yaml -f crowdsec-ingress-bouncer.yaml ingress-nginx ingress-nginx
And then check if the ingress controller is running well.
kubectl -n ingress-nginx get pods
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.
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_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).
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=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
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 /etc/nginx/lua/plugins/crowdsec/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
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 /etc/nginx/lua/plugins/crowdsec/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
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.