init.lua 3.33 KB
Newer Older
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
1 2 3 4 5 6 7 8
--[[
Alpine Wall main module
Copyright (C) 2012 Kaarle Ritvanen
Licensed under the terms of GPL2
]]--

module(..., package.seeall)

9
require 'lfs'
10
require 'stringy'
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
11

12
require 'awall.ipset'
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
13
require 'awall.iptables'
14
require 'awall.model'
15
require 'awall.object'
16
require 'awall.optfrag'
17
require 'awall.policy'
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
18 19
require 'awall.util'

20 21
local optfrag = awall.optfrag

Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
22

23 24
local procorder
local defrules
25 26

function loadmodules(path)
27 28 29
   classmap = {}
   procorder = {}
   defrules = {}
30
   achains = {}
31 32

   local function readmetadata(mod)
33
      for i, clsdef in ipairs(mod.classes or {}) do
34 35 36 37
	 local path, cls = unpack(clsdef)
	 classmap[path] = cls
	 table.insert(procorder, path)
      end
38
      for phase, rules in pairs(mod.defrules or {}) do
39
	 if not defrules[phase] then defrules[phase] = {} end
40
	 table.insert(defrules[phase], rules)
41
      end
42 43 44 45
      for name, opts in pairs(mod.achains or {}) do
	 assert(not achains[name])
	 achains[name] = opts
      end
46 47 48 49
   end

   readmetadata(model)

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

53 54 55 56
   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)
57
	 readmetadata(package.loaded[name])
58
      end
59
   end
60 61

   lfs.chdir(cdir)
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
62 63 64
end


65 66 67
PolicySet = policy.PolicySet


68
Config = object.class(object.Object)
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
69

70
function Config:init(policyconfig)
71

72
   self.objects = policyconfig:expand()
73
   self.iptables = iptables.IPTables.new()
74

75
   local function morph(path, cls)
76
      local objs = self.objects[path]
77 78 79 80 81 82 83 84 85
      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

86 87
   local acfrags = {}

88 89 90
   local function insertrules(trules)
      for i, trule in ipairs(trules) do
	 local t = self.iptables.config[trule.family][trule.table][trule.chain]
91 92 93 94 95 96 97
	 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

98
	 if trule.position == 'prepend' then
99
	    table.insert(t, 1, opts)
100
	 else
101
	    table.insert(t, opts)
102
	 end
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
103 104 105
      end
   end

106
   local function insertdefrules(phase)
107 108
      for i, rulegroup in ipairs(defrules[phase] or {}) do
	 if type(rulegroup) == 'function' then
109
	    insertrules(rulegroup(self.objects))
110 111
	 else insertrules(rulegroup) end
      end
112
   end
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
113

114
   for i, path in ipairs(procorder) do morph(path, classmap[path]) end
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
115

116
   insertdefrules('pre')
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
117

118
   for i, path in ipairs(procorder) do
119 120
      if self.objects[path] then
	 for i, rule in ipairs(self.objects[path]) do
121 122
	    insertrules(rule:trules())
	 end
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
123
      end
124
      insertdefrules('post-'..path)
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
125
   end
126

127 128 129 130
   local ofrags = {}
   for k, v in pairs(acfrags) do table.insert(ofrags, v) end
   insertrules(optfrag.combinations(achains, ofrags))

131
   morph('ipset', awall.model.ConfigObject)
132
   self.ipset = ipset.IPSet.new(self.objects.ipset)
133
end
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
134

135 136 137 138 139 140
function Config:print()
   self.ipset:print()
   print()
   self.iptables:print()
end

141 142 143
function Config:dump(dir)
   self.ipset:dump(dir or '/etc/ipset.d')
   self.iptables:dump(dir or '/etc/iptables')
144
end
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
145

146 147 148
function Config:test()
   self.ipset:create()
   self.iptables:test()
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
149
end
150 151 152 153 154

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