Nginx / OpenResty
Deploy Centinel Analytica protection on your Nginx or OpenResty server using a Lua module.
Overview
This quickstart outlines the installation workflow for the Centinel nginx module. The module runs in OpenResty or nginx with lua-nginx-module and validates requests against the Centinel API. Allow 2-3 minutes for installation.
Prerequisites
- Centinel secret key (from your dashboard)
- OpenResty 1.19+ or nginx with lua-nginx-module
- Root/sudo access to install files and edit nginx config
Method 1: Quick Install Script
Run this single command to install the Centinel module:
curl -sSL https://docs.centinelanalytica.com/downloads/install-nginx.sh | bashThe script will:
- Detect your OpenResty or nginx installation
- Download the Centinel module and dependencies
- Generate the nginx configuration snippet
After the script completes, follow the printed instructions to:
- Add the configuration to your
nginx.conf - Set your
CENTINEL_SECRET_KEYenvironment variable - Reload nginx
Method 2: Manual Installation
Download the Centinel Lua module to your OpenResty/nginx Lua path:
# For OpenResty (default path)
curl -o /usr/local/openresty/site/lualib/centinel-nginx.lua \
https://docs.centinelanalytica.com/downloads/centinel-nginx.lua
# Install lua-resty-http dependency (if not already installed)
opm get ledgetech/lua-resty-httpIf opm is not available, install lua-resty-http manually:
mkdir -p /usr/local/openresty/site/lualib/resty
curl -o /usr/local/openresty/site/lualib/resty/http.lua \
https://raw.githubusercontent.com/ledgetech/lua-resty-http/master/lib/resty/http.lua
curl -o /usr/local/openresty/site/lualib/resty/http_headers.lua \
https://raw.githubusercontent.com/ledgetech/lua-resty-http/master/lib/resty/http_headers.lua
curl -o /usr/local/openresty/site/lualib/resty/http_connect.lua \
https://raw.githubusercontent.com/ledgetech/lua-resty-http/master/lib/resty/http_connect.luaAdd the following to your nginx.conf inside the http {} block:
http {
# SSL certificates for outbound HTTPS (required)
lua_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
lua_ssl_verify_depth 3;
# DNS resolver (required)
resolver 8.8.8.8 valid=30s ipv6=off;
# Shared memory for circuit breaker (required)
lua_shared_dict centinel_cache 10m;
# Lua module path (adjust if needed)
lua_package_path '/usr/local/openresty/site/lualib/?.lua;;';
# Initialize Centinel at startup
init_by_lua_block {
centinel = require("centinel-nginx")
centinel.init({
secret_key = os.getenv("CENTINEL_SECRET_KEY")
})
}
# ... your existing configuration ...
}Then add the protection handler to locations you want to protect:
server {
listen 80;
location / {
# Centinel bot protection
access_by_lua_block {
centinel.access_handler()
}
# Your existing proxy_pass or other directives
proxy_pass http://backend;
}
}Set the CENTINEL_SECRET_KEY environment variable before starting nginx:
export CENTINEL_SECRET_KEY="sk_live_your_key_here"For systemd services, add to your unit file:
[Service]
Environment="CENTINEL_SECRET_KEY=sk_live_your_key_here"Test and reload the configuration:
nginx -t && nginx -s reload- Visit your website to confirm normal traffic flow.
- Check nginx error logs for
[Centinel]entries:tail -f /var/log/nginx/error.log | grep Centinel - Enable debug mode for detailed logging (see Advanced Configuration).
Advanced Configuration
Customize Protected Paths
By default, all paths are protected except static assets. Customize this in centinel.init():
init_by_lua_block {
centinel = require("centinel-nginx")
centinel.init({
secret_key = os.getenv("CENTINEL_SECRET_KEY"),
-- Only protect specific paths (empty = protect all)
protected_paths = {
"^/api/",
"^/admin",
"^/checkout"
},
-- Add paths to skip (in addition to defaults)
unprotected_paths = {
"%.css$", "%.js$", "%.png$", "%.jpg$",
"^/health$",
"^/metrics$"
}
})
}Default excluded patterns: Static assets like .css, .js, .png, .jpg, .gif, .svg, .woff, .woff2, .mp4, .mp3, .zip, and more.
Timeout Settings
Adjust API timeouts for your environment:
centinel.init({
secret_key = os.getenv("CENTINEL_SECRET_KEY"),
-- API request timeout (default: 100ms)
timeout_ms = 200,
-- Connection timeout (default: 100ms)
connect_timeout_ms = 150,
-- Allow requests if API is unavailable (default: true)
fail_open = true
})Circuit Breaker
The module implements exponential backoff when the API fails:
| Failure | Backoff Duration |
|---|---|
| 1st | 1 second |
| 2nd | 2 seconds |
| 3rd | 4 seconds |
| 4th | 8 seconds |
| Max | 5 minutes |
During backoff, all requests are allowed (fail-open). The backoff resets on successful API response.
Enable Debug Logging
For troubleshooting, enable debug mode:
centinel.init({
secret_key = os.getenv("CENTINEL_SECRET_KEY"),
debug = true
})Or via environment variable:
export CENTINEL_DEBUG=trueDebug logs include:
- Validation requests and responses
- Path protection decisions
- Backoff/circuit breaker state
View logs with:
tail -f /var/log/nginx/error.log | grep CentinelDocker Installation
For containerized deployments:
FROM openresty/openresty:alpine
# Install CA certificates
RUN apk add --no-cache ca-certificates
# Install lua-resty-http
RUN mkdir -p /usr/local/openresty/site/lualib/resty && \
wget -q -O /usr/local/openresty/site/lualib/resty/http.lua \
https://raw.githubusercontent.com/ledgetech/lua-resty-http/master/lib/resty/http.lua && \
wget -q -O /usr/local/openresty/site/lualib/resty/http_headers.lua \
https://raw.githubusercontent.com/ledgetech/lua-resty-http/master/lib/resty/http_headers.lua && \
wget -q -O /usr/local/openresty/site/lualib/resty/http_connect.lua \
https://raw.githubusercontent.com/ledgetech/lua-resty-http/master/lib/resty/http_connect.lua
# Install Centinel module
RUN wget -q -O /usr/local/openresty/site/lualib/centinel-nginx.lua \
https://docs.centinelanalytica.com/downloads/centinel-nginx.lua
COPY nginx.conf /usr/local/openresty/nginx/conf/nginx.conf
EXPOSE 80
CMD ["/usr/local/openresty/bin/openresty", "-g", "daemon off;"]Run with:
docker run -e CENTINEL_SECRET_KEY="sk_live_xxx" -p 80:80 your-imageConfiguration Reference
| Variable | Type | Required | Default | Description |
|---|---|---|---|---|
secret_key | string | Yes | – | Your Centinel API key from the dashboard. |
validator_url | string | No | https://validator.centinelanalytica.com/validate | Validator API endpoint. |
timeout_ms | number | No | 100 | API request timeout in milliseconds. |
connect_timeout_ms | number | No | 100 | Connection timeout in milliseconds. |
fail_open | boolean | No | true | Allow requests when API is unavailable. |
ssl_verify | boolean | No | true | Verify SSL certificates for API calls. |
debug | boolean | No | false | Enable debug logging. |
log_enabled | boolean | No | true | Enable all logging. |
protected_paths | table | No | {} | Lua patterns for paths to protect. Empty table protects all paths. |
unprotected_paths | table | No | [static assets] | Lua patterns for paths to skip (static assets by default). |
Troubleshooting
SSL certificate errors
SSL certificate problem: unable to get local issuer certificateEnsure lua_ssl_trusted_certificate points to your CA bundle:
- Debian/Ubuntu/Alpine:
/etc/ssl/certs/ca-certificates.crt - CentOS/RHEL:
/etc/pki/tls/certs/ca-bundle.crt - macOS:
/etc/ssl/cert.pem
Module not found
module 'centinel-nginx' not foundCheck that lua_package_path matches where you installed the module:
lua_package_path '/usr/local/openresty/site/lualib/?.lua;;';lua-resty-http not found
module 'resty.http' not foundInstall via opm or manually download:
opm get ledgetech/lua-resty-httpShared dict not configured
Shared dict 'centinel_cache' not configuredAdd to your http {} block:
lua_shared_dict centinel_cache 10m;DNS resolution failures
no resolver defined to resolveAdd a resolver to your http {} block:
resolver 8.8.8.8 valid=30s ipv6=off;Changelog
- 1.0.0 - Initial release with OpenResty support, circuit breaker, and path filtering.