summaryrefslogtreecommitdiffstats
path: root/acf/modules/awall.lua
blob: fa120c618dc034ff534c35ac2e8a4bdbd9f28bc6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
--[[
Copyright (c) 2012-2013 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
      M.error.raise(path, 'Invalid IP address')
   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 M.error.raise(path, 'Invalid port') end
end

PortRange = class(M.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.Set{type=M.String}
Zone.addr = M.Set{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'] = M.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)

M.permission.defaults('/awall')