This commit is contained in:
alteredCoder 2022-01-25 17:22:01 +01:00
parent b1cd4212bb
commit bda45e88c7
2 changed files with 75 additions and 7 deletions

View file

@ -1,4 +1,23 @@
local cs = require "crowdsec"
captcha_status = ngx.shared.crowdsec_cache:get("captcha_"..ngx.var.remote_addr)
if captcha_status == "to_verify" then
ngx.req.read_body()
local recaptcha_res = ngx.req.get_post_args()["g-recaptcha-response"] or 0
if recaptcha_res ~= 0 then
valid, err = cs.validateCaptcha(recaptcha_res, ngx.var.remote_addr)
if valid == true then
ngx.shared.crowdsec_cache:set("captcha_"..ngx.var.remote_addr, "validated")
headers = ngx.resp.get_headers()["Origin"]
ngx.log(ngx.ERR, "ORIG: " .. headers)
return
else
ngx.log(ngx.ALERT, "Invalid captcha from " .. ngx.var.remote_addr)
end
end
end
local ok, remediation, err = cs.allowIp(ngx.var.remote_addr)
if err ~= nil then
ngx.log(ngx.ERR, "[Crowdsec] bouncer error: " .. err)
@ -8,4 +27,12 @@ if not ok then
if remediation == "ban" then
ngx.exit(ngx.HTTP_FORBIDDEN)
end
if remediation == "captcha" then
captcha_status = ngx.shared.crowdsec_cache:get("captcha_"..ngx.var.remote_addr)
if captcha_status ~= "validated" then
ngx.header.content_type = "text/html"
ngx.say(cs.GetCaptchaTemplate())
ngx.shared.crowdsec_cache:set("captcha_"..ngx.var.remote_addr, "to_verify")
end
end
end

View file

@ -15,6 +15,7 @@ runtime.remediations["1"] = "ban"
runtime.remediations["2"] = "captcha"
local recaptcha_verify_url = "https://www.google.com/recaptcha/api/siteverify"
local csmod = {}
@ -42,10 +43,8 @@ function csmod.init(configFile, userAgent)
local view = template.new(captcha_template)
view.recaptcha_site_key = runtime.conf["SITE_KEY"]
runtime.captcha_template_path = tostring(view)
ngx.log(ngx.ERR, runtime.captcha_template_path)
runtime.captcha_template = tostring(view)
runtime.recaptcha_secret_key = runtime.conf["SECRET_KEY"]
-- if stream mode, add callback to stream_query and start timer
if runtime.conf["MODE"] == "stream" then
@ -56,7 +55,44 @@ function csmod.init(configFile, userAgent)
return true, nil
end
function http_request(link)
function csmod.validateCaptcha(g_captcha_res, remote_ip)
body = {
secret = runtime.recaptcha_secret_key,
response = g_captcha_res,
remoteip = remote_ip
}
res, err = post_http_request(recaptcha_verify_url, table_to_encoded_url(body))
if err ~= nil then
return true, err
end
result = cjson.decode(res.body)
return result.success, nil
end
function table_to_encoded_url(args)
local params = {}
for k, v in pairs(args) do table.insert(params, k .. '=' .. v) end
return table.concat(params, "&")
end
function post_http_request(link, body)
local httpc = http.new()
httpc:set_timeout(runtime.conf['REQUEST_TIMEOUT'])
local res, err = httpc:request_uri(link, {
method = "POST",
body = body,
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
},
})
return res, err
end
function get_http_request(link)
local httpc = http.new()
httpc:set_timeout(runtime.conf['REQUEST_TIMEOUT'])
local res, err = httpc:request_uri(link, {
@ -138,7 +174,7 @@ function stream_query()
local is_startup = runtime.cache:get("startup")
ngx.log(ngx.DEBUG, "Stream Query from worker : " .. tostring(ngx.worker.id()) .. " with startup "..tostring(is_startup))
local link = runtime.conf["API_URL"] .. "/v1/decisions/stream?startup=" .. tostring(is_startup)
local res, err = http_request(link)
local res, err = get_http_request(link)
if not res then
if ngx.timer.every == nil then
local ok, err = ngx.timer.at(runtime.conf["UPDATE_FREQUENCY"], stream_query)
@ -213,7 +249,7 @@ end
function live_query(ip)
local link = runtime.conf["API_URL"] .. "/v1/decisions?ip=" .. ip
local res, err = http_request(link)
local res, err = get_http_request(link)
if not res then
return true, nil, "request failed: ".. err
end
@ -251,6 +287,11 @@ function live_query(ip)
end
function csmod.GetCaptchaTemplate()
return runtime.captcha_template
end
function csmod.allowIp(ip)
if runtime.conf == nil then
return true, nil, "Configuration is bad, cannot run properly"