Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement: ability to set the content type on served ban template. #68

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions config_example.conf
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ EXCLUDE_LOCATION=
#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=/var/lib/crowdsec/lua/templates/ban.html
# Content type for the ban template, can be html, text, gif, jpeg, svg, png or tiff. Default: html
BAN_CONTENT_TYPE=html
REDIRECT_LOCATION=
RET_CODE=
#those apply for "captcha" action
Expand Down
5 changes: 2 additions & 3 deletions lib/crowdsec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,7 @@ function csmod.init(configFile, userAgent)
ngx.log(ngx.ERR, "Lua shared dict (crowdsec cache) is full, please increase dict size in config")
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["BAN_CONTENT_TYPE"])
if err ~= nil then
ngx.log(ngx.ERR, "error loading ban plugins: " .. err)
end
Expand Down Expand Up @@ -758,4 +757,4 @@ end
function csmod.close()
end

return csmod
return csmod
22 changes: 18 additions & 4 deletions lib/plugins/crowdsec/ban.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ local M = {_TYPE='module', _NAME='ban.funcs', _VERSION='1.0-0'}

M.template_str = ""
M.redirect_location = ""
M.content_type = "text/html"
M.ret_code = ngx.HTTP_FORBIDDEN


function M.new(template_path, redirect_location, ret_code)
function M.new(template_path, redirect_location, ret_code, content_type)
M.redirect_location = redirect_location

ret_code_ok = false
Expand All @@ -33,6 +34,20 @@ function M.new(template_path, redirect_location, ret_code)
end
end

content_type_ok = false
if content_type ~= nil and content_type ~= "" then
for k, v in pairs(utils.CONTENT_TYPE) do
if k == content_type then
M.content_type = utils.CONTENT_TYPE[content_type]
content_type_ok = true
break
end
end
if content_type_ok == false then
ngx.log(ngx.ERR, "RET_CONTENT_TYPE '" .. content_type .. "' is not supported, using default content_type " .. M.content_type)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for such a long wait time, should this be BAN_CONTENT_TYPE instead of RET_CONTENT_TYPE? so they know which property in configuration is wrong?

end
end

if template_file_ok == false and (M.redirect_location == nil or M.redirect_location == "") then
ngx.log(ngx.ERR, "BAN_TEMPLATE_PATH and REDIRECT_LOCATION variable are empty, will return HTTP " .. M.ret_code .. " for ban decisions")
end
Expand Down Expand Up @@ -61,17 +76,16 @@ function M.apply(...)
return
end
if M.template_str ~= "" then
ngx.header.content_type = "text/html"
ngx.header.content_type = M.content_type
ngx.header.cache_control = "no-cache"
ngx.status = status
ngx.say(M.template_str)
ngx.exit(status)
return
end

ngx.exit(status)

return
end

return M
return M
7 changes: 4 additions & 3 deletions lib/plugins/crowdsec/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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', 'APPSEC_URL', 'APPSEC_FAILURE_ACTION', 'ALWAYS_SEND_TO_APPSEC', 'SSL_VERIFY'}
local valid_params = {'ENABLED','API_URL', 'API_KEY', 'BOUNCING_ON_TYPE', 'MODE', 'SECRET_KEY', 'SITE_KEY', 'BAN_TEMPLATE_PATH', 'BAN_CONTENT_TYPE' ,'CAPTCHA_TEMPLATE_PATH', 'REDIRECT_LOCATION', 'RET_CODE', 'EXCLUDE_LOCATION', 'FALLBACK_REMEDIATION', 'CAPTCHA_PROVIDER', 'APPSEC_URL', 'APPSEC_FAILURE_ACTION', 'ALWAYS_SEND_TO_APPSEC', 'SSL_VERIFY'}
local valid_int_params = {'CACHE_EXPIRATION', 'CACHE_SIZE', 'REQUEST_TIMEOUT', 'UPDATE_FREQUENCY', 'CAPTCHA_EXPIRATION', 'APPSEC_CONNECT_TIMEOUT', 'APPSEC_SEND_TIMEOUT', 'APPSEC_PROCESS_TIMEOUT', 'STREAM_REQUEST_TIMEOUT'}
local valid_bouncing_on_type_values = {'ban', 'captcha', 'all'}
local valid_truefalse_values = {'false', 'true'}
Expand All @@ -55,6 +55,7 @@ function config.loadConfig(file)
['REDIRECT_LOCATION'] = "",
['EXCLUDE_LOCATION'] = {},
['RET_CODE'] = 0,
['BAN_CONTENT_TYPE'] = "html",
['CAPTCHA_PROVIDER'] = "recaptcha",
['APPSEC_URL'] = "",
['APPSEC_CONNECT_TIMEOUT'] = 100,
Expand Down Expand Up @@ -116,7 +117,7 @@ function config.loadConfig(file)
value = "ban"
end
end

conf[key] = value

elseif has_value(valid_int_params, key) then
Expand All @@ -133,4 +134,4 @@ function config.loadConfig(file)
end
return conf, nil
end
return config
return config
20 changes: 14 additions & 6 deletions lib/plugins/crowdsec/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,21 @@ M.HTTP_CODE["301"] = ngx.HTTP_MOVED_PERMANENTLY
M.HTTP_CODE["302"] = ngx.HTTP_MOVED_TEMPORARILY
M.HTTP_CODE["400"] = ngx.HTTP_BAD_REQUEST
M.HTTP_CODE["401"] = ngx.HTTP_UNAUTHORIZED
M.HTTP_CODE["401"] = ngx.HTTP_UNAUTHORIZED
M.HTTP_CODE["403"] = ngx.HTTP_FORBIDDEN
M.HTTP_CODE["404"] = ngx.HTTP_NOT_FOUND
M.HTTP_CODE["405"] = ngx.HTTP_NOT_ALLOWED
M.HTTP_CODE["406"] = ngx.HTTP_NOT_ACCEPTABLE
M.HTTP_CODE["500"] = ngx.HTTP_INTERNAL_SERVER_ERROR

M.CONTENT_TYPE = {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm very sorry for the very late review. Is there any reason not to allow users to set content-type directly? I'm afraid the mapping is more error-prone than anything.

M.CONTENT_TYPE["gif"] = "image/gif"
M.CONTENT_TYPE["html"] = "text/html"
M.CONTENT_TYPE["jpeg"] = "image/jpeg"
M.CONTENT_TYPE["png"] = "image/png"
M.CONTENT_TYPE["svg"] = "image/svg+xml"
M.CONTENT_TYPE["text"] = "text/plain"
M.CONTENT_TYPE["tiff"] = "image/tiff"

function M.read_file(path)
local file = io.open(path, "r") -- r read mode and b binary mode
if not file then return nil end
Expand All @@ -30,18 +38,18 @@ function M.file_exist(path)
return nil
end
local f = io.open(path, "r")
if f ~= nil then
if f ~= nil then
io.close(f)
return true
else
return true
else
return false
end
end

function M.starts_with(str, start)
return str:sub(1, #start) == start
end

function M.ends_with(str, ending)
return ending == "" or str:sub(-#ending) == ending
end
Expand All @@ -54,4 +62,4 @@ function M.table_len(table)
return count
end

return M
return M