awall-cli 2.67 KB
Newer Older
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
1 2 3 4 5 6 7 8
#!/usr/bin/lua

--[[
Alpine Wall
Copyright (C) 2012 Kaarle Ritvanen
Licensed under the terms of GPL2
]]--

9
require 'alt_getopt'
10
require 'lfs'
11
require 'signal'
12 13
require 'stringy'

14
short_opts = 'ad:e:Flo:V'
15
long_opts = {activate='a',
16 17 18
	     disable='d',
	     enable='e',
	     list='l',
19
	     ['output-dir']='o',
20
	     verify='V'}
21

22 23
params = {d = {}, e = {}}

24 25
if stringy.endswith(arg[0], '/awall-cli') then
   basedir = string.sub(arg[0], 1, -11)
26 27
   params.i = {basedir..'/json'}
   params.I = {}
28

29
   short_opts = short_opts..'i:I:'
30
   long_opts['input-dir'] = 'i'
31
   long_opts['import-path'] = 'I'
32 33
end

34 35
require 'awall.util'

36
for switch, value in pairs(alt_getopt.get_opts(arg, short_opts, long_opts)) do
37 38
   if awall.util.contains({'a', 'l'}, switch) then mode = switch
   elseif awall.util.contains({'d', 'e', 'i', 'I'}, switch) then
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
39
      table.insert(params[switch], value)
40
   elseif switch == 'F' then fallback = true
41 42 43
   elseif switch == 'o' then
      iptdir = value
      ipsfile = value..'/ipset'
44
   elseif switch == 'V' then verify = true
45
   else assert(false) end
46
end
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
47

48

49 50 51
require 'awall'

policyset = awall.PolicySet.new(params.i, params.I)
52 53 54 55

for i, action in ipairs({'disable', 'enable'}) do
   for i, policy in ipairs(params[string.sub(action, 1, 1)]) do
      policyset[action](policyset, policy, confdir, import)
56
      exit = true
57 58
   end
end
59
if exit then os.exit() end
60 61

if mode == 'l' then
62
   for name, status in policyset:list() do print(name, status) end
63 64 65 66
   os.exit()
end


67
require 'awall.iptables'
68
awall.loadmodules(basedir)
69

70
config = awall.Config.new(policyset)
71 72


73
if mode == 'a' then
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

   awall.iptables.backup()

   signal.signal('SIGCHLD',
		 function() if pid and lpc.wait(pid, 1) then os.exit(2) end end)
   for i, sig in ipairs({'INT', 'TERM'}) do
      signal.signal('SIG'..sig, function()
				   interrupted = true
				   io.stdin:close()
				end)
   end

   require 'lpc'
   pid, stdio, stdout = lpc.run(arg[0], '-F')
   stdio:close()
   stdout:close()
   
   config:activate()

   io.stderr:write('New firewall configuration activated\n')
   io.stderr:write('Press RETURN to commit changes permanently: ')
   io.read()

   signal.signal('SIGCHLD', 'default')
   signal.kill(pid, 'SIGTERM')
   lpc.wait(pid)

   if interrupted then
      io.stderr:write('\nActivation canceled, reverting to the old configuration\n')
      awall.iptables.revert()

   else config:dump() end


elseif fallback then

   for i, sig in ipairs({'HUP', 'PIPE'}) do
      signal.signal('SIG'..sig, function() end)
   end

   require 'lsleep'
   lsleep.sleep(10)

   io.stderr:write('\nTimeout, reverting to the old configuration\n')
   awall.iptables.revert()

else
   if verify then config:test() end
   config:dump(iptdir, ipsfile)
end