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

module(..., package.seeall)

require 'json'
10
require 'lfs'
11
require 'stringy'
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
12

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


20
local modules = {package.loaded['awall.model']}
21 22

function loadmodules(path)
23 24 25
   local cdir = lfs.currentdir()
   if path then lfs.chdir(path) end

26 27 28 29 30 31
   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)
	 table.insert(modules, package.loaded[name])
      end
32
   end
33 34

   lfs.chdir(cdir)
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
35 36 37
end


38
Config = awall.object.class(awall.object.Object)
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
39

40
function Config:init(confdirs)
41 42

   self.input = {}
43
   self.iptables = awall.iptables.IPTables.new()
44

45
   for i, dir in ipairs(confdirs or {'/usr/share/awall', '/etc/awall'}) do
46 47 48 49 50
      local fnames = {}
      for fname in lfs.dir(dir) do table.insert(fnames, fname) end
      table.sort(fnames)

      for i, fname in ipairs(fnames) do
51 52 53 54 55 56
	 if string.sub(fname, 1, 1) ~= '.' then
	    local data = ''
	    for line in io.lines(dir..'/'..fname) do data = data..line end
	    data = json.decode(data)
	    
	    for cls, objs in pairs(data) do
57 58
	       if not self.input[cls] then self.input[cls] = objs
	       elseif objs[1] then util.extend(self.input[cls], objs)
59
	       else
60
		  for k, v in pairs(objs) do self.input[cls][k] = v end
61 62 63 64 65
	       end
	    end
	 end
      end
   end
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
66

Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
67 68 69 70 71 72 73 74 75 76

   function expandvars(obj)
      for k, v in pairs(obj) do
	 if type(v) == 'table' then
	    expandvars(v)

	 else
	    local visited = {}
	    local val = v

77 78 79 80
	    local pattern = '%$(%a[%w_]*)'

	    while type(val) == 'string' and string.find(val, pattern) do
	       local si, ei, name = string.find(val, pattern)
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
81 82 83 84 85
		  
	       if util.contains(visited, name) then
		  error('Circular variable definition: '..name)
	       end
	       table.insert(visited, name)
86 87 88 89 90 91 92 93 94 95

	       local var = self.input.variable[name]
	       if not var then error('Invalid variable reference: '..name) end

	       if si == 1 and ei == string.len(val) then val = var
	       elseif util.contains({'number', 'string'}, type(var)) then
		  val = string.sub(val, 1, si - 1)..var..string.sub(val, ei + 1, -1)
	       else
		  error('Attempted to concatenate complex variable: '..name)
	       end
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
96 97 98 99 100 101 102
	    end

	    obj[k] = val
	 end
      end
   end

103
   expandvars(self.input)
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
104 105


Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
106
   function insertrule(trule)
107
      local t = self.iptables.config[trule.family][trule.table][trule.chain]
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
108 109 110 111 112 113 114 115 116 117 118
      if trule.position == 'prepend' then
	 table.insert(t, 1, trule.opts)
      else
	 table.insert(t, trule.opts)
      end
   end

   local locations = {}

   for i, mod in ipairs(modules) do
      for path, cls in pairs(mod.classmap) do
119 120 121 122
	 if self.input[path] then	    
	    awall.util.map(self.input[path],
			   function(obj) return cls.morph(obj, self) end)
	    table.insert(locations, self.input[path])
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
123 124 125 126 127 128 129 130 131 132 133 134
	 end
      end

      for i, rule in ipairs(mod.defrules) do insertrule(rule) end
   end


   for i, location in ipairs(locations) do
      for i, rule in ipairs(location) do
	 for i, trule in ipairs(rule:trules()) do insertrule(trule) end
      end
   end
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
135

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

139 140 141
function Config:dump(iptdir, ipsfile)
   self.ipset:dump(ipsfile or '/etc/ipset.d/awall')
   self.iptables:dump(iptdir or '/etc/iptables')
142
end
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
143

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

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