Skip to content

Allow unix socket and http appsec sources #54

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

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
67 changes: 54 additions & 13 deletions lib/crowdsec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,34 @@ function csmod.init(configFile, userAgent)
if runtime.conf["APPSEC_URL"] ~= "" then
local u = url.parse(runtime.conf["APPSEC_URL"])
runtime.conf["APPSEC_ENABLED"] = true
runtime.conf["APPSEC_HOST"] = u.host
if u.scheme ~= nil then
runtime.conf["APPSEC_SCHEME"] = u.scheme
ngx.log(ngx.DEBUG, "APPSEC scheme is '" .. u.scheme .. "'")
end
if u.url ~= nil then
runtime.conf["APPSEC_PARSED"] = u.url
ngx.log(ngx.DEBUG, "APPSEC url is '" .. u.url .. "'")
end
if u.host ~= nil then
runtime.conf["APPSEC_HOST"] = u.host
ngx.log(ngx.DEBUG, "APPSEC host is '" .. runtime.conf["APPSEC_HOST"] .. "'")
end
if u.path ~= nil then
runtime.conf["APPSEC_PATH"] = u.path
ngx.log(ngx.DEBUG, "APPSEC path is '" .. u.path .. "'")
end
if u.port ~= nil then
runtime.conf["APPSEC_HOST"] = runtime.conf["APPSEC_HOST"] .. ":" .. u.port
ngx.log(ngx.DEBUG, "APPSEC port is '" .. u.port .. "'")
runtime.conf["APPSEC_PORT"] = u.port
end

if runtime.conf["APPSEC_SCHEME"] == "unix" then
-- if the scheme is unix, then reset all fields to nil
runtime.conf["APPSEC_SCHEME"] = nil
runtime.conf["APPSEC_PORT"] = nil
runtime.conf["APPSEC_HOST"] = nil
runtime.conf["APPSEC_PATH"] = nil
end
ngx.log(ngx.ERR, "APPSEC is enabled on '" .. runtime.conf["APPSEC_HOST"] .. "'")
end


Expand Down Expand Up @@ -455,12 +478,18 @@ function csmod.AppSecCheck(ip)
headers[APPSEC_API_KEY_HEADER] = runtime.conf["API_KEY"]

-- set CrowdSec APPSEC Host
headers["host"] = runtime.conf["APPSEC_HOST"]
headers["Host"] = runtime.conf["APPSEC_HOST"] or "localhost"
-- Set localhost if no host is set (Unix socket)
if runtime.conf["APPSEC_PORT"] ~= nil then
headers["Host"] = headers["Host"] .. ":" .. runtime.conf["APPSEC_PORT"]
end
-- Append port if set (Cannot set on runtime configuration since we need it for connection)

local ok, remediation, status_code = true, "allow", 200
if runtime.conf["APPSEC_FAILURE_ACTION"] == DENY then
ok = false
remediation = runtime.conf["FALLBACK_REMEDIATION"]
-- Should we change status code based on "FALLBACK_REMEDIATION"
end

local method = "GET"
Expand All @@ -477,15 +506,26 @@ function csmod.AppSecCheck(ip)
headers["content-length"] = nil
end

local res, err = httpc:request_uri(runtime.conf["APPSEC_URL"], {
local httpok, err, ssl_session = httpc:connect({
scheme = runtime.conf["APPSEC_SCHEME"],
port = runtime.conf["APPSEC_PORT"],
host = runtime.conf["APPSEC_HOST"] or runtime.conf["APPSEC_URL"],
ssl_verify = runtime.conf["SSL_VERIFY"],
})

if not httpok then
ngx.log(ngx.ERR, "connection failed: ", err)
return
end

local res, err = httpc:request({
path = runtime.conf["APPSEC_PATH"] or "/",
method = method,
headers = headers,
body = body,
ssl_verify = runtime.conf["SSL_VERIFY"],
})
httpc:close()

if err ~= nil then
if err ~= nil or not res then
ngx.log(ngx.ERR, "Fallback because of err: " .. err)
return ok, remediation, status_code, err
end
Expand All @@ -495,8 +535,9 @@ function csmod.AppSecCheck(ip)
remediation = "allow"
elseif res.status == 403 then
ok = false
ngx.log(ngx.DEBUG, "Appsec body response: " .. res.body)
local response = cjson.decode(res.body)
local body = res:read_body()
ngx.log(ngx.DEBUG, "Appsec body response: " .. body)
local response = cjson.decode(body)
remediation = response.action
if response.http_status ~= nil then
ngx.log(ngx.DEBUG, "Got status code from APPSEC: " .. response.http_status)
Expand All @@ -507,11 +548,11 @@ function csmod.AppSecCheck(ip)
elseif res.status == 401 then
ngx.log(ngx.ERR, "Unauthenticated request to APPSEC")
else
ngx.log(ngx.ERR, "Bad request to APPSEC (" .. res.status .. "): " .. res.body)
ngx.log(ngx.ERR, "Bad request to APPSEC (" .. res.status .. "): " .. res:read_body())
end


httpc:close()
return ok, remediation, status_code, err

end

--- return if the IP is allowed or not
Expand Down