init.lua 3.06 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 23 24 25 26 27 28

function loadmodules(path)
   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
29
   end
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
30 31 32
end


33
Config = awall.object.class(awall.object.Object)
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
34

35
function Config:init(confdirs)
36 37 38

   self.input = {}
   self.iptables = awall.iptables.new()
39

40
   for i, dir in ipairs(confdirs or {'/usr/share/awall', '/etc/awall'}) do
41 42 43 44 45
      local fnames = {}
      for fname in lfs.dir(dir) do table.insert(fnames, fname) end
      table.sort(fnames)

      for i, fname in ipairs(fnames) do
46 47 48 49 50 51
	 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
52 53
	       if not self.input[cls] then self.input[cls] = objs
	       elseif objs[1] then util.extend(self.input[cls], objs)
54
	       else
55
		  for k, v in pairs(objs) do self.input[cls][k] = v end
56 57 58 59 60
	       end
	    end
	 end
      end
   end
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
61

Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79

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

	 else
	    local visited = {}
	    local val = v

	    while type(val) == 'string' and string.sub(val, 1, 1) == '$' do
	       local name = string.sub(val, 2, -1)
		  
	       if util.contains(visited, name) then
		  error('Circular variable definition: '..name)
	       end
	       table.insert(visited, name)
		  
80
	       val = self.input.variable[name]
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
81 82 83 84 85 86 87 88
	       if not val then error('Invalid variable reference: '..name) end
	    end

	    obj[k] = val
	 end
      end
   end

89
   expandvars(self.input)
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
90 91


Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
92
   function insertrule(trule)
93
      local t = self.iptables.config[trule.family][trule.table][trule.chain]
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
94 95 96 97 98 99 100 101 102 103 104
      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
105 106 107 108
	 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
109 110 111 112 113 114 115 116 117 118 119 120
	 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
121

122
   self.ipset = awall.ipset.IPSet.new(self.input.ipset)
123
end
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
124

125 126 127
function Config:dump(iptdir, ipsfile)
   self.ipset:dump(ipsfile or '/etc/ipset.d/awall')
   self.iptables:dump(iptdir or '/etc/iptables')
128
end
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
129

130 131 132
function Config:test()
   self.ipset:create()
   self.iptables:test()
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
133
end