Skip to content

Commit

Permalink
Add live test (#78)
Browse files Browse the repository at this point in the history
* add some tests for live mode
  • Loading branch information
sabban committed Oct 2, 2024
1 parent f182e80 commit 06e584d
Show file tree
Hide file tree
Showing 10 changed files with 373 additions and 2 deletions.
43 changes: 43 additions & 0 deletions .github/workflows/nginx.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: lua ca bouncer nginx test

on:
push:
branches:
- main
- releases/**
pull_request:
branches:
- main
- releases/**


jobs:
tests:
runs-on: ubuntu-latest
name: "Nginx test suite"
container:
image: debian:latest

steps:
- name: Check out repository
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: false
- name: "install nginx & nginx perl test suite"
run: |
cat /etc/os-release
apt-get update
apt-get install -y make gcc nginx libnginx-mod-http-lua perl ca-certificates luarocks
luarocks install lua-cjson 2.1.0.10-1
luarocks install lua-resty-http 0.17.1-0
cpan Test::Nginx
cpan Test::Nginx::Socket
echo "Installation done"
- name: "Run tests"
run: |
export PERL5LIB=/root/.cpan/build/Test-Nginx-0.30-3/blib/lib
for i in t/*.t; do
prove $i ;
done
2 changes: 1 addition & 1 deletion lib/plugins/crowdsec/ban.lua
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,4 @@ function M.apply(...)
return
end

return M
return M
2 changes: 1 addition & 1 deletion lib/plugins/crowdsec/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ function M.read_file(path)
io.input(file)
local content = io.read("*a")
io.close(file)
return content
return content:sub(1,-2)
end

function M.file_exist(path)
Expand Down
42 changes: 42 additions & 0 deletions t/01lua_config.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use Test::Nginx::Socket 'no_plan';

run_tests();

__DATA__
=== TEST 1: Load lua configuration
--- main_config
load_module /usr/share/nginx/modules/ndk_http_module.so;
load_module /usr/share/nginx/modules/ngx_http_lua_module.so;
--- http
init_by_lua_block {
cs = require "crowdsec"
local ok, err = cs.init("/etc/crowdsec/bouncers/crowdsec-nginx-bouncer.conf", "crowdsec-nginx-bouncer/v1.0.8")
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"
if ngx.var.unix == "1" then
ngx.log(ngx.DEBUG, "[Crowdsec] Unix socket request ignoring...")
else
cs.Allow(ngx.var.remote_addr)
end
}
--- config
location = /t {
content_by_lua_block {
ngx.say("hello, world")
}
}
--- request
GET /t
--- response_body
hello, world
--- error_code: 200
73 changes: 73 additions & 0 deletions t/02live.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use Test::Nginx::Socket 'no_plan';

run_tests();

__DATA__

=== TEST 2: Live mode block test

--- main_config
load_module /usr/share/nginx/modules/ndk_http_module.so;
load_module /usr/share/nginx/modules/ngx_http_lua_module.so;

--- http_config

lua_package_path './lib/?.lua;;';
lua_shared_dict crowdsec_cache 50m;
lua_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;


init_by_lua_block
{
cs = require "crowdsec"
local ok, err = cs.init("./t/conf_t/02_live_crowdsec_nginx_bouncer.conf", "crowdsec-nginx-bouncer/v1.0.8")
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)
if ngx.var.unix == "1" then
ngx.log(ngx.DEBUG, "[Crowdsec] Unix socket request ignoring...")
else
cs.Allow(ngx.var.remote_addr)
end
}

server {
listen 8081;

location = /v1/decisions {
content_by_lua_block {
local args, err = ngx.req.get_uri_args()
if args.ip == "1.1.1.1" then
ngx.say('[{"duration":"1h00m00s","id":4091593,"origin":"CAPI","scenario":"crowdsecurity/vpatch-CVE-2024-4577","scope":"Ip","type":"ban","value":"1.1.1.1"}]')
else
ngx.say('[{}]')
end
}
}
}


--- config


location = /t {
set_real_ip_from 127.0.0.1;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
content_by_lua_block {
ngx.say(ngx.var.remote_addr)
}
}
--- more_headers
X-Forwarded-For: 1.1.1.1
--- request
GET /t
--- error_code: 403
77 changes: 77 additions & 0 deletions t/03live_and_ban.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use Test::Nginx::Socket 'no_plan';

run_tests();

__DATA__

=== TEST 3: Test body response on block

--- main_config
load_module /usr/share/nginx/modules/ndk_http_module.so;
load_module /usr/share/nginx/modules/ngx_http_lua_module.so;

--- http_config

lua_package_path './lib/?.lua;;';
lua_shared_dict crowdsec_cache 50m;
lua_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;


init_by_lua_block
{
cs = require "crowdsec"
local ok, err = cs.init("./t/conf_t/03_live_and_ban_crowdsec_nginx_bouncer.conf", "crowdsec-nginx-bouncer/v1.0.8")
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)
if ngx.var.unix == "1" then
ngx.log(ngx.DEBUG, "[Crowdsec] Unix socket request ignoring...")
else
cs.Allow(ngx.var.remote_addr)
end
}

server {
listen 8081;

location = /v1/decisions {
content_by_lua_block {
local args, err = ngx.req.get_uri_args()
if args.ip == "1.1.1.1" then
ngx.say('[{"duration":"1h00m00s","id":4091593,"origin":"CAPI","scenario":"crowdsecurity/vpatch-CVE-2024-4577","scope":"Ip","type":"ban","value":"1.1.1.1"}]')
else
ngx.print('null')
end
}
}
}


--- config


location = /t {
set_real_ip_from 127.0.0.1;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
content_by_lua_block {
ngx.say("Hello, world")
}
}
--- more_headers
X-Forwarded-For: 1.1.1.1
--- request
GET /t
--- response_body

Nope

--- error_code: 403
77 changes: 77 additions & 0 deletions t/04live_and_not_ban.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use Test::Nginx::Socket 'no_plan';

run_tests();

__DATA__

=== TEST 4: Test body response on a not blocked request

--- main_config
load_module /usr/share/nginx/modules/ndk_http_module.so;
load_module /usr/share/nginx/modules/ngx_http_lua_module.so;

--- http_config

lua_package_path './lib/?.lua;;';
lua_shared_dict crowdsec_cache 50m;
lua_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;


init_by_lua_block
{
cs = require "crowdsec"
local ok, err = cs.init("./t/conf_t/03_live_and_ban_crowdsec_nginx_bouncer.conf", "crowdsec-nginx-bouncer/v1.0.8")
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)
if ngx.var.unix == "1" then
ngx.log(ngx.DEBUG, "[Crowdsec] Unix socket request ignoring...")
else
cs.Allow(ngx.var.remote_addr)
end
}

server {
listen 8081;

location = /v1/decisions {
content_by_lua_block {
local args, err = ngx.req.get_uri_args()
if args.ip == "1.1.1.1" then
ngx.say('[{"duration":"1h00m00s","id":4091593,"origin":"CAPI","scenario":"crowdsecurity/vpatch-CVE-2024-4577","scope":"Ip","type":"ban","value":"1.1.1.1"}]')
else
ngx.print('null')
end
}
}
}


--- config


location = /t {
set_real_ip_from 127.0.0.1;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
content_by_lua_block {
ngx.say("Hello, world")
}
}
--- more_headers
X-Forwarded-For: 1.1.1.2
--- request
GET /t
--- response_body

Hello, world

--- error_code: 200
29 changes: 29 additions & 0 deletions t/conf_t/02_live_crowdsec_nginx_bouncer.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
APPSEC_URL=http://127.0.0.1:7422
ENABLED=true
API_URL=http://127.0.0.1:8081
API_KEY=LFrdL+aiecMTSxpGE9vLkx5sGMwdIpgVovpVMfXp3J0
CACHE_EXPIRATION=1
# bounce for all type of remediation that the bouncer can receive from the local API
BOUNCING_ON_TYPE=all
FALLBACK_REMEDIATION=ban
REQUEST_TIMEOUT=3000
UPDATE_FREQUENCY=10
# live or stream
MODE=live
# exclude the bouncing on those location
EXCLUDE_LOCATION=/v1/decisions
#those apply for "ban" action
# /!\ REDIRECT_LOCATION and RET_CODE can't be used together. REDIRECT_LOCATION take priority over RET_CODE
BAN_TEMPLATE_PATH=./ban
REDIRECT_LOCATION=
RET_CODE=
#those apply for "captcha" action
#valid providers are recaptcha, hcaptcha, turnstile
CAPTCHA_PROVIDER=
# Captcha Secret Key
SECRET_KEY=
# Captcha Site key
SITE_KEY=
CAPTCHA_TEMPLATE_PATH=/var/lib/crowdsec/lua/templates/captcha.html
CAPTCHA_EXPIRATION=3600
#METRICS_PERIOD=60
29 changes: 29 additions & 0 deletions t/conf_t/03_live_and_ban_crowdsec_nginx_bouncer.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
APPSEC_URL=http://127.0.0.1:7422
ENABLED=true
API_URL=http://127.0.0.1:8081
API_KEY=LFrdL+aiecMTSxpGE9vLkx5sGMwdIpgVovpVMfXp3J0
CACHE_EXPIRATION=1
# bounce for all type of remediation that the bouncer can receive from the local API
BOUNCING_ON_TYPE=all
FALLBACK_REMEDIATION=ban
REQUEST_TIMEOUT=3000
UPDATE_FREQUENCY=10
# live or stream
MODE=live
# exclude the bouncing on those location
EXCLUDE_LOCATION=/v1/decisions
#those apply for "ban" action
# /!\ REDIRECT_LOCATION and RET_CODE can't be used together. REDIRECT_LOCATION take priority over RET_CODE
BAN_TEMPLATE_PATH=./t/conf_t/ban
REDIRECT_LOCATION=
RET_CODE=
#those apply for "captcha" action
#valid providers are recaptcha, hcaptcha, turnstile
CAPTCHA_PROVIDER=
# Captcha Secret Key
SECRET_KEY=
# Captcha Site key
SITE_KEY=
CAPTCHA_TEMPLATE_PATH=/var/lib/crowdsec/lua/templates/captcha.html
CAPTCHA_EXPIRATION=3600
#METRICS_PERIOD=60
1 change: 1 addition & 0 deletions t/conf_t/ban
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Nope

0 comments on commit 06e584d

Please sign in to comment.