init.lua 3.43 KB
Newer Older
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
1 2
--[[
Alpine Wall main module
3
Copyright (C) 2012-2014 Kaarle Ritvanen
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
4
See LICENSE file for license details
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
5 6 7
]]--


8
local M = {}
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
9

10 11 12 13 14 15 16
local class = require('awall.class')
local resolve = require('awall.dependency')
local IPSet = require('awall.ipset')
local IPTables = require('awall.iptables').IPTables
local optfrag = require('awall.optfrag')
M.PolicySet = require('awall.policy')
local util = require('awall.util')
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
17

18 19 20

local lfs = require('lfs')
local endswith = require('stringy').endswith
21

Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
22

23
local events
24
local procorder
25
local achains
26

27
function M.loadmodules(path)
28
   events = {}
29
   achains = {}
30 31

   local function readmetadata(mod)
32 33 34
      local export = mod.export or {}
      for name, target in pairs(export) do events[name] = target end

35 36 37 38
      for name, opts in pairs(mod.achains or {}) do
	 assert(not achains[name])
	 achains[name] = opts
      end
39

40
      return util.keys(export)
41 42
   end

43
   readmetadata(require('awall.model'))
44

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

48
   local modules = {}
49 50
   for modfile in lfs.dir((path or '/usr/share/lua/5.1')..'/awall/modules') do
      if stringy.endswith(modfile, '.lua') then
51
	 table.insert(modules, 'awall.modules.'..modfile:sub(1, -5))
52
      end
53
   end
54
   table.sort(modules)
55 56

   local imported = {}
57
   for i, name in ipairs(modules) do
58
      util.extend(imported, readmetadata(require(name)))
59
   end
60 61

   lfs.chdir(cdir)
62

63
   events['%modules'] = {before=imported}
64
   procorder = resolve(events)
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
65 66
end

67
function M.loadclass(path)
68
   assert(path:sub(1, 1) ~= '%')
69 70 71
   return events[path] and events[path].class
end

Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
72

73
M.Config = class()
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
74

75
function M.Config:init(policyconfig)
76

77
   self.objects = policyconfig:expand()
78
   self.iptables = IPTables()
79

80 81
   local acfrags = {}

82 83 84
   local function insertrules(trules)
      for i, trule in ipairs(trules) do
	 local t = self.iptables.config[trule.family][trule.table][trule.chain]
85 86 87 88 89 90 91
	 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

92
	 if trule.position == 'prepend' then
93
	    table.insert(t, 1, opts)
94
	 else
95
	    table.insert(t, opts)
96
	 end
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
97 98 99
      end
   end

100
   for i, path in ipairs(procorder) do
101
      if path:sub(1, 1) ~= '%' then
102 103 104
	 local objs = self.objects[path]
	 if objs then
	    for k, v in pairs(objs) do
105
	       objs[k] = events[path].class.morph(
106 107 108 109 110
		  v,
		  self,
		  path..' '..k..' ('..policyconfig.source[path][k]..')'
	       )
	    end
111 112 113
	 end
      end
   end
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
114

115
   for i, event in ipairs(procorder) do
116
      if event:sub(1, 1) == '%' then
117 118 119
	 local r = events[event].rules
	 if r then
	    if type(r) == 'function' then r = r(self.objects) end
120 121 122 123
	    if r then
	       assert(type(r) == 'table')
	       insertrules(r)
	    end
124 125 126
	 end
      elseif self.objects[event] then
	 for i, rule in ipairs(self.objects[event]) do
127 128
	    insertrules(rule:trules())
	 end
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
129 130
      end
   end
131

132 133 134 135
   local ofrags = {}
   for k, v in pairs(acfrags) do table.insert(ofrags, v) end
   insertrules(optfrag.combinations(achains, ofrags))

136
   self.ipset = IPSet(self.objects.ipset)
137
end
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
138

139
function M.Config:print()
140 141 142 143 144
   self.ipset:print()
   print()
   self.iptables:print()
end

145
function M.Config:dump(dir)
146 147
   self.ipset:dump(dir or '/etc/ipset.d')
   self.iptables:dump(dir or '/etc/iptables')
148
end
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
149

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

155
function M.Config:activate()
156 157 158
   self:test()
   self.iptables:activate()
end
159 160 161


return M