Today we'll learn how to build the cheapest and smallest - but efficient - layer 7 firewall. Then you don't need anymore to buy very expensive appliances for URL filtering (F5 BigIP, Netscaler,..) and you don't have to spend hours to make Apache mod_security work. This security can be added to the Tomcat Security Manager if you are running a reverse-proxy, and provides in-depth security as advised by many including official government services such as ANSSI (Agence nationale de la sécurité des systèmes d’information).
With Apache 2.4 we get the opportunity to try LUA through the experimental mod_lua module. This module provides LUA scripting as well as being very compatible with Apache. It's a good way to interfere with HTTP requests/responses because it can go into full request inspection (mod_rewrite cannot), and without breaking the others modules. So you still can write proxy configs or anything else, which is very usable. Now, let's start saving money :
LoadModule lua_module modules/mod_lua.so
<LuaQuickHandler firewall>
require "apache2"
function firewall(r)
-- contains all the forbidden words raising a 403
forbiddenWords = { 'INSERT',
'SELECT',
'UPDATE',
'DELETE',
'DISTINCT',
'HAVING',
'TRUNCATE',
'REPLACE',
'handler',
'like',
'procedure',
'limit',
'order by',
'group by',
'script',
'document',
'java.io.',
'%.%.'
}
-- contains the result
foundForbidden = false
-- is debug enabled ?
isDebug = true
local f = io.open("/tmp/debug-lua.log", "a")
if f then
if r.method == 'GET' then
for i, v in ipairs(forbiddenWords) do
if string.find( string.lower(url_decode(r.the_request)), string.lower(v) ) then
foundForbidden = true
end
if isDebug then
f:write( string.lower(url_decode(r.the_request)).." , "..string.lower(v).." , " .. tostring(foundForbidden) .." \n")
end
end
elseif r.method == 'POST' then
for k, w in pairs( r:parsebody() ) do
for i, v in ipairs(forbiddenWords) do
if string.find( url_decode(string.lower(w)), string.lower(v) ) then
foundForbidden = true
end
if isDebug then
f:write( string.lower(url_decode(string.lower(w))).." , "..string.lower(v).." , " .. tostring(foundForbidden) .." \n")
end
end
end
end
f:close()
end
if foundForbidden then
return 403
else
return apache2.DECLINED
end
end
-- url decoding as anywhere in the web
function url_decode(str)
str = string.gsub (str, "+", " ")
str = string.gsub (str, "%%(%x%x)",
function(h) return string.char(tonumber(h,16)) end)
str = string.gsub (str, "\r\n", "\n")
return str
end
</LuaQuickHandler>
Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer