Commit d44d633a authored by Kaarle Ritvanen's avatar Kaarle Ritvanen

do not create helper chains for unused actions

only the minimum set of targets is required of the kernel
parent c9aec673
...@@ -13,9 +13,12 @@ require 'awall.ipset' ...@@ -13,9 +13,12 @@ require 'awall.ipset'
require 'awall.iptables' require 'awall.iptables'
require 'awall.model' require 'awall.model'
require 'awall.object' require 'awall.object'
require 'awall.optfrag'
require 'awall.policy' require 'awall.policy'
require 'awall.util' require 'awall.util'
local optfrag = awall.optfrag
local procorder local procorder
local defrules local defrules
...@@ -24,6 +27,7 @@ function loadmodules(path) ...@@ -24,6 +27,7 @@ function loadmodules(path)
classmap = {} classmap = {}
procorder = {} procorder = {}
defrules = {} defrules = {}
achains = {}
local function readmetadata(mod) local function readmetadata(mod)
for i, clsdef in ipairs(mod.classes or {}) do for i, clsdef in ipairs(mod.classes or {}) do
...@@ -35,6 +39,10 @@ function loadmodules(path) ...@@ -35,6 +39,10 @@ function loadmodules(path)
if not defrules[phase] then defrules[phase] = {} end if not defrules[phase] then defrules[phase] = {} end
table.insert(defrules[phase], rules) table.insert(defrules[phase], rules)
end end
for name, opts in pairs(mod.achains or {}) do
assert(not achains[name])
achains[name] = opts
end
end end
readmetadata(model) readmetadata(model)
...@@ -75,13 +83,22 @@ function Config:init(policyconfig) ...@@ -75,13 +83,22 @@ function Config:init(policyconfig)
end end
end end
local acfrags = {}
local function insertrules(trules) local function insertrules(trules)
for i, trule in ipairs(trules) do for i, trule in ipairs(trules) do
local t = self.iptables.config[trule.family][trule.table][trule.chain] local t = self.iptables.config[trule.family][trule.table][trule.chain]
local opts = (trule.opts and trule.opts..' ' or '')..'-j '..trule.target
local acfrag = {family=trule.family,
table=trule.table,
chain=trule.target}
acfrags[optfrag.location(acfrag)] = acfrag
if trule.position == 'prepend' then if trule.position == 'prepend' then
table.insert(t, 1, trule.opts) table.insert(t, 1, opts)
else else
table.insert(t, trule.opts) table.insert(t, opts)
end end
end end
end end
...@@ -107,6 +124,10 @@ function Config:init(policyconfig) ...@@ -107,6 +124,10 @@ function Config:init(policyconfig)
insertdefrules('post-'..path) insertdefrules('post-'..path)
end end
local ofrags = {}
for k, v in pairs(acfrags) do table.insert(ofrags, v) end
insertrules(optfrag.combinations(achains, ofrags))
morph('ipset', awall.model.ConfigObject) morph('ipset', awall.model.ConfigObject)
self.ipset = ipset.IPSet.new(self.objects.ipset) self.ipset = ipset.IPSet.new(self.objects.ipset)
end end
......
...@@ -48,8 +48,8 @@ function ConfigObject:info() ...@@ -48,8 +48,8 @@ function ConfigObject:info()
local res = {} local res = {}
for i, trule in ipairs(self:trules()) do for i, trule in ipairs(self:trules()) do
table.insert(res, table.insert(res,
{' '..trule.family..'/'..trule.table..'/'..trule.chain, {' '..awall.optfrag.location(trule),
trule.opts}) (trule.opts and trule.opts..' ' or '')..'-j '..trule.target})
end end
return res return res
end end
...@@ -294,10 +294,6 @@ function Rule:trules() ...@@ -294,10 +294,6 @@ function Rule:trules()
end) end)
end end
local function appendtarget(ofrag, target)
ofrag.opts = (ofrag.opts and ofrag.opts..' ' or '')..'-j '..target
end
local res = self:zoneoptfrags() local res = self:zoneoptfrags()
if self.ipset then if self.ipset then
...@@ -358,12 +354,12 @@ function Rule:trules() ...@@ -358,12 +354,12 @@ function Rule:trules()
tag(res, 'position', self:position()) tag(res, 'position', self:position())
for i, ofrag in ipairs(res) do appendtarget(ofrag, target) end res = combinations(res, {{target=target}})
if addrchain then if addrchain then
for i, ofrag in ipairs(addrofrags) do for i, ofrag in ipairs(addrofrags) do
ofrag.chain = target ofrag.chain = target
appendtarget(ofrag, self:target()) ofrag.target = self:target()
table.insert(res, ofrag) table.insert(res, ofrag)
end end
end end
......
...@@ -14,6 +14,7 @@ require 'awall.optfrag' ...@@ -14,6 +14,7 @@ require 'awall.optfrag'
require 'awall.util' require 'awall.util'
local model = awall.model local model = awall.model
local combinations = awall.optfrag.combinations
local Filter = model.class(model.Rule) local Filter = model.class(model.Rule)
...@@ -25,7 +26,7 @@ function Filter:destoptfrags() ...@@ -25,7 +26,7 @@ function Filter:destoptfrags()
local ofrags = model.Rule.destoptfrags(self) local ofrags = model.Rule.destoptfrags(self)
if not self.dnat then return ofrags end if not self.dnat then return ofrags end
ofrags = awall.optfrag.combinations(ofrags, {{family='inet6'}}) ofrags = combinations(ofrags, {{family='inet6'}})
local natof = self:create(model.Zone, {addr=self.dnat}):optfrags('out') local natof = self:create(model.Zone, {addr=self.dnat}):optfrags('out')
assert(#natof == 1) assert(#natof == 1)
table.insert(ofrags, natof[1]) table.insert(ofrags, natof[1])
...@@ -115,9 +116,11 @@ function Filter:extraoptfrags() ...@@ -115,9 +116,11 @@ function Filter:extraoptfrags()
end end
local optbase = '-m recent --name '..self:target() local optbase = '-m recent --name '..self:target()
table.insert(res, {chain=self:target(), table.insert(res, {chain=self:target(),
opts=optbase..' --update --hitcount '..self[limit].count..' --seconds '..self[limit].interval..' -j logdrop'}) opts=optbase..' --update --hitcount '..self[limit].count..' --seconds '..self[limit].interval,
target='logdrop'})
table.insert(res, {chain=self:target(), table.insert(res, {chain=self:target(),
opts=optbase..' --set -j ACCEPT'}) opts=optbase..' --set',
target='ACCEPT'})
end end
return res return res
end end
...@@ -132,47 +135,37 @@ function Policy:servoptfrags() return nil end ...@@ -132,47 +135,37 @@ function Policy:servoptfrags() return nil end
classes = {{'filter', Filter}, classes = {{'filter', Filter},
{'policy', Policy}} {'policy', Policy}}
defrules = {pre={}, ['post-filter']={}}
local limitedlog = '-m limit --limit 1/second -j LOG' defrules = {}
for i, family in ipairs({'inet', 'inet6'}) do local dar = combinations({{chain='FORWARD'}, {chain='INPUT'}, {chain='OUTPUT'}},
for i, target in ipairs({'drop', 'reject'}) do {{opts='-m state --state RELATED,ESTABLISHED'}})
for i, opts in ipairs({limitedlog, '-j '..string.upper(target)}) do for i, chain in ipairs({'INPUT', 'OUTPUT'}) do
table.insert(defrules.pre, table.insert(dar,
{family=family, {chain=chain,
table='filter', opts='-'..string.lower(string.sub(chain, 1, 1))..' lo'})
chain='log'..target, end
opts=opts}) defrules.pre = combinations(combinations(dar,
end {{table='filter', target='ACCEPT'}}),
end {{family='inet'}, {family='inet6'}})
for i, opts in ipairs({limitedlog, '-p tcp -j TARPIT', '-j DROP'}) do defrules['post-filter'] = combinations({{family='inet6',
table.insert(defrules.pre, table='filter',
{family=family, table='filter', chain='tarpit', opts=opts}) opts='-p icmpv6',
end target='ACCEPT'}},
{{chain='INPUT'}, {chain='OUTPUT'}})
for i, chain in ipairs({'FORWARD', 'INPUT', 'OUTPUT'}) do
table.insert(defrules.pre,
{family=family,
table='filter',
chain=chain,
opts='-m state --state RELATED,ESTABLISHED -j ACCEPT'})
end
for i, chain in ipairs({'INPUT', 'OUTPUT'}) do achains = {}
table.insert(defrules.pre,
{family=family,
table='filter',
chain=chain,
opts='-'..string.lower(string.sub(chain, 1, 1))..' lo -j ACCEPT'})
end
end
for i, chain in ipairs({'INPUT', 'OUTPUT'}) do local limitedlog = {opts='-m limit --limit 1/second', target='LOG'}
table.insert(defrules['post-filter'], for i, target in ipairs({'drop', 'reject'}) do
{family='inet6', util.extend(achains,
table='filter', combinations({{chain='log'..target}},
chain=chain, {limitedlog, {target=string.upper(target)}}))
opts='-p icmpv6 -j ACCEPT'})
end end
util.extend(achains,
combinations({{chain='tarpit'}},
{limitedlog,
{opts='-p tcp', target='TARPIT'},
{target='DROP'}}))
...@@ -34,8 +34,8 @@ function RouteTrackRule:servoptfrags() ...@@ -34,8 +34,8 @@ function RouteTrackRule:servoptfrags()
end end
function RouteTrackRule:extraoptfrags() function RouteTrackRule:extraoptfrags()
return {{chain=self:target(), opts='-j '..MarkRule.target(self)}, return {{chain=self:target(), target=MarkRule.target(self)},
{chain=self:target(), opts='-j CONNMARK --save-mark'}} {chain=self:target(), target='CONNMARK --save-mark'}}
end end
...@@ -53,7 +53,8 @@ function defrules.pre(config) ...@@ -53,7 +53,8 @@ function defrules.pre(config)
{family=family, {family=family,
table='mangle', table='mangle',
chain=chain, chain=chain,
opts='-m connmark ! --mark 0 -j CONNMARK --restore-mark'}) opts='-m connmark ! --mark 0',
target='CONNMARK --restore-mark'})
end end
end end
end end
......
...@@ -10,7 +10,9 @@ module(..., package.seeall) ...@@ -10,7 +10,9 @@ module(..., package.seeall)
-- TODO configuration of the ipset via JSON config -- TODO configuration of the ipset via JSON config
defrules = {['post-snat']={{family='inet', table='nat', defrules = {['post-snat']={{family='inet', table='nat',
chain='POSTROUTING', chain='POSTROUTING',
opts='-m set --match-set awall-masquerade src -j awall-masquerade'}, opts='-m set --match-set awall-masquerade src',
target='awall-masquerade'},
{family='inet', table='nat', {family='inet', table='nat',
chain='awall-masquerade', chain='awall-masquerade',
opts='-m set ! --match-set awall-masquerade dst -j MASQUERADE'}}} opts='-m set ! --match-set awall-masquerade dst',
target='MASQUERADE'}}}
...@@ -46,3 +46,5 @@ function combinations(of1, of2) ...@@ -46,3 +46,5 @@ function combinations(of1, of2)
return res return res
end end
function location(of) return of.family..'/'..of.table..'/'..of.chain end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment