diff options
author | Kaarle Ritvanen <kaarle.ritvanen@datakunkku.fi> | 2012-12-16 19:10:38 +0200 |
---|---|---|
committer | Kaarle Ritvanen <kaarle.ritvanen@datakunkku.fi> | 2012-12-16 19:10:38 +0200 |
commit | e4361842fcdec369fbd4466f2528b2815f504ff9 (patch) | |
tree | 4694ca56f9e9a4869763d8fe1f31a81f6f62ac0b /acf/modules/awall.lua | |
download | acf2-e4361842fcdec369fbd4466f2528b2815f504ff9.tar.bz2 acf2-e4361842fcdec369fbd4466f2528b2815f504ff9.tar.xz |
initial version
Diffstat (limited to 'acf/modules/awall.lua')
-rw-r--r-- | acf/modules/awall.lua | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/acf/modules/awall.lua b/acf/modules/awall.lua new file mode 100644 index 0000000..8d25638 --- /dev/null +++ b/acf/modules/awall.lua @@ -0,0 +1,138 @@ +--[[ +Copyright (c) 2012 Kaarle Ritvanen +See LICENSE file for license details +--]] + +module(..., package.seeall) + +local M = require('acf.model') + +local object = require('acf.object') +local class = object.class +local super = object.super + + +IPv4Addr = class(M.String) +function IPv4Addr:validate(txn, path, value) + local function test(...) + if #arg ~= 4 then return true end + for _, octet in ipairs(arg) do + if tonumber(octet) > 255 then return true end + end + end + if test(string.match(value, '(%d+)%.(%d+)%.(%d+)%.(%d+)')) then + error('Invalid IP address: '..value) + end +end + +Port = class(M.Integer) +function Port:validate(txn, path, value) + super(self, Port):validate(txn, path, value) + if value < 0 or value > 65535 then error('Invalid port: '..value) end +end + +Range = class(M.String) +function Range:validate(txn, path, value) + local comps = stringy.split(value, '-') + if #comps > 2 then error('Invalid range: '..value) end + for _, v in ipairs(comps) do + local num = tonumber(v) + if not num then error('Invalid range: ' ..value) end + M.to_field(self.type):validate(txn, path, num) + end +end + +PortRange = class(Range) +function PortRange:init() super(self, PortRange):init{type=Port} end + +Direction = class(M.String) +function Direction:init() + super(self, Direction):init{choice={'in', 'out'}} +end + + +-- TODO reference types? + +IPSet = M.new() +-- TODO choices +IPSet.type = M.String{required=true} +IPSet.family = M.String{required=true, choice={'inet', 'inet6'}} + +Service = M.new() +Service.proto = M.String{required=true} +Service.port = M.Collection{type=PortRange} +Service['icmp-type'] = M.String + +-- TODO fw zone + +Zone = M.new() +Zone.iface = M.PrimitiveList{type=M.String} +Zone.addr = M.PrimitiveList{type=M.String} +Zone['route-back'] = M.Boolean{default=false} + +LogClass = M.new() +LogClass.mode = M.String{default='log', choice={'log', 'nflog', 'ulog'}} +LogClass.limit = M.Integer +LogClass.prefix = M.String + +IPSetReference = M.new() +IPSetReference.name = M.Reference{scope='../../ipset', required=true} +IPSetReference.args = M.Collection{type=Direction, required=true} + +Rule = M.new() +Rule['in'] = M.Collection{type=M.Reference{scope='../../zone'}} +Rule.out = M.Collection{type=M.Reference{scope='../../zone'}} +Rule.src = M.Collection{type=M.String} +Rule.dest = M.Collection{type=M.String} +Rule.ipset = IPSetReference +Rule.ipsec = Direction +Rule.service = M.Collection{type=M.Reference{scope='../../service'}} +Rule.action = M.String{choice={'accept'}} + + +-- TODO no service field +PolicyRule = M.new(Rule) +PolicyRule.log = M.Reference{scope='../log'} +PolicyRule.action = M.String{required=true, + choice={'accept', 'drop', 'reject', 'tarpit'}} + +Limit = M.new() +Limit.count = M.Integer +Limit.interval = M.Integer +Limit.log = M.Reference{scope='../../log'} + +FilterRule = M.new(PolicyRule) +FilterRule['conn-limit'] = Limit +FilterRule['flow-limit'] = Limit +FilterRule.dnat = IPv4Addr +FilterRule['no-track'] = M.Boolean{default=false} + +NATRule = M.new(Rule) +NATRule['to-addr'] = Range{type=IPv4Addr} +NATRule['to-port'] = PortRange + +MarkRule = M.new(Rule) +MarkRule.mark = M.Integer{required=true} + +ClampMSSRule = M.new(Rule) +ClampMSSRule.mss = M.Integer + + +AWall = M.new() +-- TODO differentiate lists? +AWall.service = M.Collection{type=M.Collection{type=Service}} +AWall.zone = M.Collection{type=Zone} +AWall.log = M.Collection{type=LogClass} +AWall.policy = M.Collection{type=PolicyRule} +AWall.filter = M.Collection{type=FilterRule} +AWall.dnat = M.Collection{type=NATRule} +AWall.snat = M.Collection{type=NATRule} +AWall.mark = M.Collection{type=MarkRule} +AWall['route-track'] = M.Collection{type=MarkRule} +AWall['clamp-mss'] = M.Collection{type=ClampMSSRule} +AWall['no-track'] = M.Collection{type=Rule} +AWall.ipset = M.Collection{type=IPSet} + +M.register('awall', + '/json'..require('lfs').currentdir()..'/config/awall.json', + AWall) |