awall-cli 2.76 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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
require 'awall.policy'

for i, action in ipairs({'disable', 'enable'}) do
   for i, policy in ipairs(params[string.sub(action, 1, 1)]) do
      policyset = policyset or awall.policy.PolicySet.new(params.i, params.I)
      policyset[action](policyset, policy, confdir, import)
   end
end
if policyset then os.exit() end

if mode == 'l' then
   for name, status in awall.policy.PolicySet.new(params.i,
						  params.I):list() do
      print(name, status)
   end
   os.exit()
end


Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
68
require 'awall'
69
require 'awall.iptables'
70
awall.loadmodules(basedir)
71

72
config = awall.Config.new(params.i, params.I)
73 74


75
if mode == 'a' then
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 124 125

   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