Commit 9fdf8d72 authored by Kaarle Ritvanen's avatar Kaarle Ritvanen

constrain 'netbios-ns' service to IPv4 only

parent 4313b0b6
...@@ -223,12 +223,7 @@ function Rule:servoptfrags() ...@@ -223,12 +223,7 @@ function Rule:servoptfrags()
if not self.service then return end if not self.service then return end
local function containskey(tbl, key) local fports = {inet={}, inet6={}}
for k, v in pairs(tbl) do if k == key then return true end end
return false
end
local ports = {}
local res = {} local res = {}
for i, serv in ipairs(self.service) do for i, serv in ipairs(self.service) do
...@@ -236,15 +231,24 @@ function Rule:servoptfrags() ...@@ -236,15 +231,24 @@ function Rule:servoptfrags()
if not sdef.proto then self:error('Protocol not defined') end if not sdef.proto then self:error('Protocol not defined') end
if util.contains({6, 'tcp', 17, 'udp'}, sdef.proto) then if util.contains({6, 'tcp', 17, 'udp'}, sdef.proto) then
local new = not containskey(ports, sdef.proto) for family, ports in pairs(fports) do
if new then ports[sdef.proto] = {} end if not sdef.family or family == sdef.family then
if new or ports[sdef.proto][1] then local new = not ports[sdef.proto]
if sdef.port then if new then ports[sdef.proto] = {} end
util.extend(ports[sdef.proto],
util.maplist(sdef.port, if new or ports[sdef.proto][1] then
function(p) return string.gsub(p, '-', ':') end)) if sdef.port then
else ports[sdef.proto] = {} end util.extend(
ports[sdef.proto],
util.maplist(
sdef.port,
function(p) return string.gsub(p, '-', ':') end
)
)
else ports[sdef.proto] = {} end
end
end
end end
else else
...@@ -263,47 +267,62 @@ function Rule:servoptfrags() ...@@ -263,47 +267,62 @@ function Rule:servoptfrags()
elseif sdef.type then elseif sdef.type then
self:error('Type specification not valid with '..sdef.proto) self:error('Type specification not valid with '..sdef.proto)
end end
if sdef.type then opts = opts..' --'..oname..' '..sdef.type end
if sdef.family then
if not family then family = sdef.family
elseif family ~= sdef.family then
self:error(
'Protocol '..sdef.proto..' is incompatible with '..sdef.family
)
end
end
if sdef.type then opts = opts..' --'..oname..' '..sdef.type end
table.insert(res, {family=family, opts=opts}) table.insert(res, {family=family, opts=opts})
end end
end end
end end
local popt = ' --'..(self.reverse and 's' or 'd')..'port' local popt = ' --'..(self.reverse and 's' or 'd')..'port'
for proto, plist in pairs(ports) do for family, pports in pairs(fports) do
local propt = '-p '..proto local ofrags = {}
if plist[1] then for proto, ports in pairs(pports) do
local len = #plist local propt = '-p '..proto
repeat
local opts if ports[1] then
local len = #ports
if len == 1 then repeat
opts = propt..popt..' '..plist[1] local opts
len = 0
if len == 1 then
else opts = propt..popt..' '..ports[1]
opts = propt..' -m multiport'..popt..'s ' len = 0
local pc = 0
repeat else
local sep = pc == 0 and '' or ',' opts = propt..' -m multiport'..popt..'s '
local port = plist[1] local pc = 0
repeat
pc = pc + (string.find(port, ':') and 2 or 1) local sep = pc == 0 and '' or ','
if pc > 15 then break end local port = ports[1]
opts = opts..sep..port pc = pc + (string.find(port, ':') and 2 or 1)
if pc > 15 then break end
table.remove(plist, 1)
len = len - 1 opts = opts..sep..port
until len == 0
end table.remove(ports, 1)
len = len - 1
table.insert(res, {opts=opts}) until len == 0
until len == 0 end
table.insert(ofrags, {opts=opts})
until len == 0
else table.insert(ofrags, {opts=propt}) end
end
else table.insert(res, {opts=propt}) end util.extend(res, combinations(ofrags, {{family=family}}))
end end
return res return res
......
...@@ -27,6 +27,7 @@ function RelatedRule:servoptfrags() ...@@ -27,6 +27,7 @@ function RelatedRule:servoptfrags()
local helper = sdef['ct-helper'] local helper = sdef['ct-helper']
if helper then if helper then
helpers[helper] = { helpers[helper] = {
family=sdef.family,
opts='-m conntrack --ctstate RELATED -m helper --helper '..helper opts='-m conntrack --ctstate RELATED -m helper --helper '..helper
} }
end end
...@@ -259,51 +260,59 @@ local fchains = {{chain='FORWARD'}, {chain='INPUT'}, {chain='OUTPUT'}} ...@@ -259,51 +260,59 @@ local fchains = {{chain='FORWARD'}, {chain='INPUT'}, {chain='OUTPUT'}}
function stateful(config) function stateful(config)
local res = {} local res = {}
local families = {{family='inet'}, {family='inet6'}} for i, family in ipairs{'inet', 'inet6'} do
local er = combinations( local er = combinations(
fchains, fchains,
{{opts='-m conntrack --ctstate ESTABLISHED'}} {{opts='-m conntrack --ctstate ESTABLISHED'}}
)
for i, chain in ipairs({'INPUT', 'OUTPUT'}) do
table.insert(
er,
{
chain=chain,
opts='-'..string.lower(string.sub(chain, 1, 1))..' lo'
}
) )
end for i, chain in ipairs({'INPUT', 'OUTPUT'}) do
extend(res, combinations(families, er, {{table='filter', target='ACCEPT'}})) table.insert(
er,
-- TODO avoid creating unnecessary CT rules by inspecting the {
-- filter rules' target families and chains chain=chain,
local visited = {} opts='-'..string.lower(string.sub(chain, 1, 1))..' lo'
local ofrags = {} }
for i, rule in listpairs(config.filter) do )
for i, serv in listpairs(rule.service) do end
if not visited[serv] then extend(
for i, sdef in listpairs(serv) do res,
if sdef['ct-helper'] then combinations(er, {{family=family, table='filter', target='ACCEPT'}})
local of = model.Rule.morph({service={sdef}}):servoptfrags() )
assert(#of == 1)
of[1].target = 'CT --helper '..sdef['ct-helper'] -- TODO avoid creating unnecessary CT rules by inspecting the
table.insert(ofrags, of[1]) -- filter rules' target families and chains
local visited = {}
local ofrags = {}
for i, rule in listpairs(config.filter) do
for i, serv in listpairs(rule.service) do
if not visited[serv] then
for i, sdef in listpairs(serv) do
if sdef['ct-helper'] then
local of = combinations(
model.Rule.morph{service={sdef}}:servoptfrags(),
{{family=family}}
)
if of[1] then
assert(#of == 1)
of[1].target = 'CT --helper '..sdef['ct-helper']
table.insert(ofrags, of[1])
end
end
end end
visited[serv] = true
end end
visited[serv] = true
end end
end end
end extend(
extend( res,
res, combinations(
combinations( {{table='raw'}},
families, {{chain='PREROUTING'}, {chain='OUTPUT'}},
{{table='raw'}}, ofrags
{{chain='PREROUTING'}, {chain='OUTPUT'}}, )
ofrags
) )
) end
return res return res
end end
......
...@@ -66,8 +66,13 @@ ...@@ -66,8 +66,13 @@
{ "proto": "udp", "port": 138 } { "proto": "udp", "port": 138 }
], ],
"netbios-ns": [ "netbios-ns": [
{ "proto": "tcp", "port": 137 }, { "family": "inet", "proto": "tcp", "port": 137 },
{ "proto": "udp", "port": 137, "ct-helper": "netbios-ns" } {
"family": "inet",
"proto": "udp",
"port": 137,
"ct-helper": "netbios-ns"
}
], ],
"netbios-ssn": [ "netbios-ssn": [
{ "proto": "tcp", "port": 139 }, { "proto": "tcp", "port": 139 },
......
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