diff --git a/config_example.conf b/config_example.conf index e99e4b28..ac17baa5 100644 --- a/config_example.conf +++ b/config_example.conf @@ -25,3 +25,7 @@ SECRET_KEY= SITE_KEY= CAPTCHA_TEMPLATE_PATH=/var/lib/crowdsec/lua/templates/captcha.html CAPTCHA_EXPIRATION=3600 +## Contact us button on ban page +CONTACT_US_URL= +#mailto:// or https:// +## Keep in mind if you use a mailto link it will be visible to all via html, so you can expect some spam \ No newline at end of file diff --git a/lib/crowdsec.lua b/lib/crowdsec.lua index bc8c81d3..0c00ab4e 100644 --- a/lib/crowdsec.lua +++ b/lib/crowdsec.lua @@ -57,7 +57,7 @@ function csmod.init(configFile, userAgent) end - local err = ban.new(runtime.conf["BAN_TEMPLATE_PATH"], runtime.conf["REDIRECT_LOCATION"], runtime.conf["RET_CODE"]) + local err = ban.new(runtime.conf["BAN_TEMPLATE_PATH"], runtime.conf["REDIRECT_LOCATION"], runtime.conf["RET_CODE"], runtime.conf["CONTACT_US_URL"]) if err ~= nil then ngx.log(ngx.ERR, "error loading ban plugins: " .. err) end @@ -231,7 +231,9 @@ local function stream_query(premature) error("Failed to create the timer: " .. (err or "unknown")) end set_refreshing(false) - error("request failed: ".. err) + if err ~= nil then + error("request failed: ".. err) + end end local succ, err, forcible = runtime.cache:set("last_refresh", ngx.time()) @@ -374,7 +376,7 @@ end function csmod.SetupStream() -- if it stream mode and startup start timer ngx.log(ngx.DEBUG, "timer started: " .. tostring(runtime.timer_started) .. " in worker " .. tostring(ngx.worker.id())) - if runtime.timer_started == false and runtime.conf["MODE"] == "stream" then + if runtime.timer_started == false then local ok, err ok, err = ngx.timer.at(runtime.conf["UPDATE_FREQUENCY"], stream_query) if not ok then @@ -390,7 +392,9 @@ function csmod.allowIp(ip) return true, nil, "Configuration is bad, cannot run properly" end - csmod.SetupStream() + if runtime.conf["MODE"] == "stream" then + csmod.SetupStream() + end local key = item_to_string(ip, "ip") local key_parts = {} diff --git a/lib/plugins/crowdsec/ban.lua b/lib/plugins/crowdsec/ban.lua index 19f10294..5f8da208 100644 --- a/lib/plugins/crowdsec/ban.lua +++ b/lib/plugins/crowdsec/ban.lua @@ -1,4 +1,5 @@ local utils = require "plugins.crowdsec.utils" +local template = require "plugins.crowdsec.template" local M = {_TYPE='module', _NAME='ban.funcs', _VERSION='1.0-0'} @@ -8,7 +9,7 @@ M.redirect_location = "" M.ret_code = ngx.HTTP_FORBIDDEN -function M.new(template_path, redirect_location, ret_code) +function M.new(template_path, redirect_location, ret_code, contact_us_url) M.redirect_location = redirect_location ret_code_ok = false @@ -27,7 +28,11 @@ function M.new(template_path, redirect_location, ret_code) template_file_ok = false if (template_path ~= nil and template_path ~= "" and utils.file_exist(template_path) == true) then - M.template_str = utils.read_file(template_path) + local template_data = {} + template_data["contact_us_url"] = contact_us_url + local ban_template = utils.read_file(template_path) + local view = template.compile(ban_template, template_data) + M.template_str = view if M.template_str ~= nil then template_file_ok = true end diff --git a/lib/plugins/crowdsec/config.lua b/lib/plugins/crowdsec/config.lua index 256c8b41..289916f6 100644 --- a/lib/plugins/crowdsec/config.lua +++ b/lib/plugins/crowdsec/config.lua @@ -39,7 +39,7 @@ function config.loadConfig(file) return nil, "File ".. file .." doesn't exist" end local conf = {} - local valid_params = {'ENABLED','API_URL', 'API_KEY', 'BOUNCING_ON_TYPE', 'MODE', 'SECRET_KEY', 'SITE_KEY', 'BAN_TEMPLATE_PATH' ,'CAPTCHA_TEMPLATE_PATH', 'REDIRECT_LOCATION', 'RET_CODE', 'EXCLUDE_LOCATION', 'FALLBACK_REMEDIATION', 'CAPTCHA_PROVIDER'} + local valid_params = {'ENABLED','API_URL', 'API_KEY', 'BOUNCING_ON_TYPE', 'MODE', 'SECRET_KEY', 'SITE_KEY', 'BAN_TEMPLATE_PATH' ,'CAPTCHA_TEMPLATE_PATH', 'REDIRECT_LOCATION', 'RET_CODE', 'EXCLUDE_LOCATION', 'FALLBACK_REMEDIATION', 'CAPTCHA_PROVIDER', 'CONTACT_US_URL'} local valid_int_params = {'CACHE_EXPIRATION', 'CACHE_SIZE', 'REQUEST_TIMEOUT', 'UPDATE_FREQUENCY', 'CAPTCHA_EXPIRATION'} local valid_bouncing_on_type_values = {'ban', 'captcha', 'all'} local valid_truefalse_values = {'false', 'true'} @@ -53,7 +53,8 @@ function config.loadConfig(file) ['REDIRECT_LOCATION'] = "", ['EXCLUDE_LOCATION'] = {}, ['RET_CODE'] = 0, - ['CAPTCHA_PROVIDER'] = "recaptcha" + ['CAPTCHA_PROVIDER'] = "recaptcha", + ['CONTACT_US_URL'] = "", } for line in io.lines(file) do local isOk = false diff --git a/lib/plugins/crowdsec/template.lua b/lib/plugins/crowdsec/template.lua index 535abb28..37261684 100644 --- a/lib/plugins/crowdsec/template.lua +++ b/lib/plugins/crowdsec/template.lua @@ -1,3 +1,5 @@ +local utils = require "plugins.crowdsec.utils" + local template = {} function template.compile(template_str, args) @@ -7,7 +9,79 @@ function template.compile(template_str, args) template_str = template_str:gsub(var, v) end - return template_str + return findIfStatements(template_str, args) +end + +-- This function finds if statements in the template and removes the lines that are not needed +-- BEAWARE nested if statements are not currently supported +function findIfStatements(inputString, args) + -- Split the input string into lines + local lines = {} + for line in inputString:gmatch("[^\r\n]+") do + table.insert(lines, line) + end + local finalLines = {} + toAdd = true + for _, line in ipairs(lines) do + local trimLine = utils.trim(line) + if utils.starts_with(trimLine, "{{ if") then + local elements = utils.split(trimLine, " ") + local comparee = "" + local comparer = "" + local agaisnt = "" + for _, el in ipairs(elements) do + if el == "{{" or el == "if" or el == "}}" or el == "then" then + goto con + end + if comparee ~= "" and comparer ~= "" and against ~= "" then + break + end + if comparee == "" then + for k, v in pairs(args) do + if el == k then + comparee = v + goto con + end + end + end + if comparer == "" then + if el == "==" or el == "!=" then + comparer = el + goto con + end + end + if comparee ~= "" and comparer ~= "" then + agaisnt = el + end + ::con:: + end + if comparer == "==" then + if comparee ~= agaisnt then + toAdd = false + end + end + if comparer == "!=" then + if comparee == agaisnt then + toAdd = false + end + end + goto continue + end + if utils.starts_with(trimLine, "{{ else") then + toAdd = not toAdd + goto continue + end + if utils.starts_with(trimLine, "{{ end") then + toAdd = true + goto continue + end + if toAdd then + table.insert(finalLines, line) + end + ::continue:: + end + + return table.concat(finalLines, "\n") end return template \ No newline at end of file diff --git a/lib/plugins/crowdsec/utils.lua b/lib/plugins/crowdsec/utils.lua index 9d732373..3636a4b5 100644 --- a/lib/plugins/crowdsec/utils.lua +++ b/lib/plugins/crowdsec/utils.lua @@ -53,4 +53,19 @@ function M.table_len(table) return count end +function M.trim(s) + return s:gsub("^%s+", ""):gsub("%s+$", "") +end + +function M.split(str, delimiter) + local result = {} + local pattern = string.format("([^%s]+)", delimiter) + + str:gsub(pattern, function(item) + table.insert(result, item) + end) + + return result +end + return M \ No newline at end of file diff --git a/templates/ban.html b/templates/ban.html index 7c13af1a..12494f46 100644 --- a/templates/ban.html +++ b/templates/ban.html @@ -4,7 +4,7 @@ CrowdSec Ban - + @@ -17,6 +17,11 @@

CrowdSec Access Forbidden

You are unable to visit the website.

+ {{ if contact_us_url != "" then }} + + Contact Us + + {{ end }}

diff --git a/templates/captcha.html b/templates/captcha.html index b01f5e11..40da8f2a 100644 --- a/templates/captcha.html +++ b/templates/captcha.html @@ -4,7 +4,7 @@ CrowdSec Captcha - +