summaryrefslogtreecommitdiffstats
path: root/awall/init.lua
blob: 9787c5398aa04b09408c869cb46056a39900edf6 (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
--[[
Alpine Wall main module
Copyright (C) 2012 Kaarle Ritvanen
Licensed under the terms of GPL2
]]--

module(..., package.seeall)

require 'lfs'
require 'stringy'

require 'awall.ipset'
require 'awall.iptables'
require 'awall.model'
require 'awall.object'
require 'awall.policy'
require 'awall.util'


local procorder
local defrules

function loadmodules(path)
   classmap = {}
   procorder = {}
   defrules = {}

   local function readmetadata(mod)
      for i, clsdef in ipairs(mod.classes) do
	 local path, cls = unpack(clsdef)
	 classmap[path] = cls
	 table.insert(procorder, path)
      end
      for phase, rules in pairs(mod.defrules) do
	 if not defrules[phase] then defrules[phase] = {} end
	 table.insert(defrules[phase], rules)
      end
   end

   readmetadata(model)

   local cdir = lfs.currentdir()
   if path then lfs.chdir(path) end

   for modfile in lfs.dir((path or '/usr/share/lua/5.1')..'/awall/modules') do
      if stringy.endswith(modfile, '.lua') then
	 local name = 'awall.modules.'..string.sub(modfile, 1, -5)
	 require(name)
	 readmetadata(package.loaded[name])
      end
   end

   lfs.chdir(cdir)
end


PolicySet = policy.PolicySet


Config = object.class(object.Object)

function Config:init(policyconfig)

   self.input = policyconfig:expand()
   self.iptables = iptables.IPTables.new()

   local function morph(path, cls)
      local objs = self.input[path]
      if objs then
	 for k, v in pairs(objs) do
	    objs[k] = cls.morph(v,
				self,
				path..' '..k..' ('..policyconfig.source[path][k]..')')
	 end
      end
   end

   local function insertrules(trules)
      for i, trule in ipairs(trules) do
	 local t = self.iptables.config[trule.family][trule.table][trule.chain]
	 if trule.position == 'prepend' then
	    table.insert(t, 1, trule.opts)
	 else
	    table.insert(t, trule.opts)
	 end
      end
   end

   local function insertdefrules(phase)
      for i, rulegroup in ipairs(defrules[phase] or {}) do
	 if type(rulegroup) == 'function' then
	    insertrules(rulegroup(self.input))
	 else insertrules(rulegroup) end
      end
   end

   for i, path in ipairs(procorder) do morph(path, classmap[path]) end

   insertdefrules('pre')

   for i, path in ipairs(procorder) do
      if self.input[path] then
	 for i, rule in ipairs(self.input[path]) do
	    insertrules(rule:trules())
	 end
      end
      insertdefrules('post-'..path)
   end

   morph('ipset', awall.model.ConfigObject)
   self.ipset = ipset.IPSet.new(self.input.ipset)
end

function Config:dump(iptdir, ipsfile)
   self.ipset:dump(ipsfile or '/etc/ipset.d/awall')
   self.iptables:dump(iptdir or '/etc/iptables')
end

function Config:test()
   self.ipset:create()
   self.iptables:test()
end

function Config:activate()
   self:test()
   self.iptables:activate()
end