awall-cli 2.85 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'

Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
14 15
short_opts = 'o:V'
long_opts = {['output-dir']='o', verify='V'}
16

Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
17 18 19 20 21 22
function fail()
   io.stderr:write('Syntax error\n')
   os.exit()
end

params = {}
23

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

Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
34 35 36 37 38 39
if not arg[1] then fail() end

if not stringy.startswith(arg[1], '-') then
   mode = arg[1]
   table.remove(arg, 1)
end
40

Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
41 42 43
opts, opind = alt_getopt.get_opts(arg, short_opts, long_opts)
for switch, value in pairs(opts) do
   if switch == 'V' then verify = true
44 45 46
   elseif switch == 'o' then
      iptdir = value
      ipsfile = value..'/ipset'
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
47
   else table.insert(params[switch], value) end
48
end
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
49

Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
50 51 52 53 54 55 56 57 58 59 60 61
if not mode then
   mode = arg[opind]
   opind = opind + 1
end


require 'awall.util'

if not awall.util.contains({'translate', 'activate', 'fallback',
			    'enable', 'disable', 'list'},
			   mode) then fail() end

62

63 64 65
require 'awall'

policyset = awall.PolicySet.new(params.i, params.I)
66

Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
67 68 69
if mode == 'list' then
   for name, status in policyset:list() do print(name, status) end
   os.exit()
70 71
end

Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
72 73 74 75 76 77
if awall.util.contains({'disable', 'enable'}, mode) then
   if opind > #arg then fail() end
   repeat
      policyset[mode](policyset, arg[opind])
      opind = opind + 1
   until opind > #arg
78 79 80 81
   os.exit()
end


82
require 'awall.iptables'
83
awall.loadmodules(basedir)
84

85
config = awall.Config.new(policyset)
86

Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
87 88 89 90 91
if mode == 'translate' then
   if verify then config:test() end
   config:dump(iptdir, ipsfile)      
   
elseif mode == 'activate' then
92 93 94 95 96 97 98 99 100 101 102 103 104

   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'
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
105
   pid, stdio, stdout = lpc.run(arg[0], 'fallback')
106 107 108 109 110 111 112
   stdio:close()
   stdout:close()
   
   config:activate()

   io.stderr:write('New firewall configuration activated\n')
   io.stderr:write('Press RETURN to commit changes permanently: ')
113
   interrupted = not io.read()
114 115 116 117 118 119 120 121 122 123 124 125

   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


Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
126
elseif mode == 'fallback' then
127 128 129 130 131 132 133 134 135 136 137

   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()

Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
138
else assert(false) end