aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--awall/model.lua43
-rw-r--r--awall/modules/filter.lua42
2 files changed, 58 insertions, 27 deletions
diff --git a/awall/model.lua b/awall/model.lua
index c49daa5..fcc1ee8 100644
--- a/awall/model.lua
+++ b/awall/model.lua
@@ -29,6 +29,9 @@ local maplist = util.maplist
local startswith = require('stringy').startswith
+local RECENT_MAX_COUNT = 20
+
+
local function join(a, b)
local comps = {}
local function add(s) if s and s > '' then table.insert(comps, s) end end
@@ -67,6 +70,7 @@ function M.ConfigObject:create(cls, params, label, index)
end
end
+ if type(params) ~= 'table' then params = {params} end
params.label = join(self.label, label)
local obj = cls.morph(params, self.context, self.location)
@@ -572,6 +576,45 @@ end
function M.Rule:extraoptfrags() return {} end
+M.Limit = M.class(M.ConfigObject)
+
+function M.Limit:init(...)
+ M.Limit.super(self):init(...)
+
+ if not self.count then
+ if not self[1] then
+ self:error('Packet count not defined for limit')
+ end
+ self.count = self[1]
+ end
+
+ if not self.interval then self.interval = 1 end
+end
+
+function M.Limit:rate() return math.ceil(self.count / self.interval) end
+
+function M.Limit:recentopts()
+ local count = self.count
+ local interval = self.interval
+
+ if count > RECENT_MAX_COUNT then
+ count = self:rate()
+ interval = 1
+ end
+
+ if count <= RECENT_MAX_COUNT then
+ return '--update --hitcount '..count..' --seconds '..interval
+ end
+end
+
+function M.Limit:limitopts(name)
+ local rate = self:rate()
+ return '-m hashlimit --hashlimit-upto '..rate..
+ '/second --hashlimit-burst '..rate..
+ ' --hashlimit-mode srcip --hashlimit-name '..(name or self:uniqueid())
+end
+
+
M.export = {zone={class=M.Zone}, ipset={class=IPSet, before='%modules'}}
return M
diff --git a/awall/modules/filter.lua b/awall/modules/filter.lua
index 1c78dda..dd12132 100644
--- a/awall/modules/filter.lua
+++ b/awall/modules/filter.lua
@@ -19,8 +19,6 @@ local contains = util.contains
local extend = util.extend
local listpairs = util.listpairs
-local RECENT_MAX_COUNT = 20
-
local TranslatingRule = class(Rule)
@@ -240,48 +238,38 @@ function Filter:extraoptfrags()
local limitchain = self:uniqueid('limit')
local limitlog = self[limit].log
- local count = self[limit].count
- local interval = self[limit].interval or 1
-
- if count > RECENT_MAX_COUNT then
- count = math.ceil(count / interval)
- interval = 1
- end
+ local limitobj = self:create(model.Limit, self[limit], 'limit')
local ofrags = {}
local logch, limitofs
local accept = self:position() == 'append'
- if count > RECENT_MAX_COUNT then
- if accept then
- ofrags, logch = self:logchain(self.log, 'accept', 'ACCEPT')
- else logch = 'RETURN' end
-
- limitofs = {
- {
- opts='-m hashlimit --hashlimit-upto '..count..'/second --hashlimit-burst '..count..' --hashlimit-mode srcip --hashlimit-name '..limitchain,
- target=logch
- },
- {target='DROP'}
- }
- if limitlog then table.insert(limitofs, 2, limitlog:optfrag()) end
+ local recentopts = limitobj:recentopts()
- else
+ if recentopts then
ofrags, logch = self:logchain(limitlog, 'drop', 'DROP')
limitofs = combinations(
{{opts='-m recent --name '..limitchain}},
{
- {
- opts='--update --hitcount '..count..' --seconds '..interval,
- target=logch
- },
+ {opts=recentopts, target=logch},
{opts='--set', target=accept and 'ACCEPT' or nil}
}
)
if accept and self.log then
table.insert(limitofs, 2, self.log:optfrag())
end
+
+ else
+ if accept then
+ ofrags, logch = self:logchain(self.log, 'accept', 'ACCEPT')
+ else logch = 'RETURN' end
+
+ limitofs = {
+ {opts=limitobj:limitopts(limitchain), target=logch},
+ {target='DROP'}
+ }
+ if limitlog then table.insert(limitofs, 2, limitlog:optfrag()) end
end
extend(ofrags, combinations({{chain=limitchain}}, limitofs))