0aa618d2907ffff073647614e1668a3b18c7a710
[project/luci.git] / applications / luci-firewall / luasrc / model / cbi / luci_fw / zone.lua
1 --[[
2 LuCI - Lua Configuration Interface
3
4 Copyright 2008 Steven Barth <steven@midlink.org>
5
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
9
10         http://www.apache.org/licenses/LICENSE-2.0
11
12 $Id$
13 ]]--
14
15 local nw = require "luci.model.network"
16 local fw = require "luci.model.firewall"
17 local utl = require "luci.util"
18 local dsp = require "luci.dispatcher"
19
20 local has_v2 = nixio.fs.access("/lib/firewall/fw.sh")
21 local out, inp
22
23 require("luci.tools.webadmin")
24 m = Map("firewall", translate("Firewall - Zone Settings"))
25
26 fw.init(m.uci)
27 nw.init(m.uci)
28
29
30 local zone = fw:get_zone(arg[1])
31 if not zone then
32         luci.http.redirect(dsp.build_url("admin", "network", "firewall"))
33         return
34 end
35
36
37 s = m:section(NamedSection, zone.sid, "zone",
38         translatef("Zone %q", zone:name()),
39         translatef("This section defines common properties of %q. " ..
40                 "The <em>input</em> and <em>output</em> options set the default "..
41                 "policies for traffic entering and leaving this zone while the " ..
42                 "<em>forward</em> option describes the policy for forwarded traffic " ..
43                 "between different networks within the zone. " ..
44                 "<em>Covered networks</em> specifies which available networks are " ..
45                 "member of this zone.", zone:name()))
46
47 s.anonymous = true
48 s.addremove = false
49
50 m.on_commit = function(map)
51         local zone = fw:get_zone(arg[1])
52         if zone then
53                 s.section  = zone.sid
54                 s2.section = zone.sid
55         end
56 end
57
58
59 s:tab("general", translate("General Settings"))
60 s:tab("advanced", translate("Advanced Settings"))
61
62
63 name = s:taboption("general", Value, "name", translate("Name"))
64 name.optional = false
65 name.forcewrite = true
66 name.datatype = "uciname"
67
68 function name.write(self, section, value)
69         if zone:name() ~= value then
70                 fw:rename_zone(zone:name(), value)
71                 out.exclude = value
72                 inp.exclude = value
73         end
74
75         m.redirect = luci.dispatcher.build_url(
76                 "admin", "network", "firewall", "zones", value
77         )
78 end
79
80 p = {}
81 p[1] = s:taboption("general", ListValue, "input", translate("Input"))
82 p[2] = s:taboption("general", ListValue, "output", translate("Output"))
83 p[3] = s:taboption("general", ListValue, "forward", translate("Forward"))
84
85 for i, v in ipairs(p) do
86         v:value("REJECT", translate("reject"))
87         v:value("DROP", translate("drop"))
88         v:value("ACCEPT", translate("accept"))
89 end
90
91 s:taboption("general", Flag, "masq", translate("Masquerading"))
92 s:taboption("general", Flag, "mtu_fix", translate("MSS clamping"))
93
94 net = s:taboption("general", Value, "network", translate("Covered networks"))
95 net.template = "cbi/network_netlist"
96 net.widget = "checkbox"
97 net.cast = "string"
98
99 function net.formvalue(self, section)
100         return Value.formvalue(self, section) or "-"
101 end
102
103 function net.cfgvalue(self, section)
104         return Value.cfgvalue(self, section) or name:cfgvalue(section)
105 end
106
107 function net.write(self, section, value)
108         zone:clear_networks()
109
110         local n
111         for n in utl.imatch(value) do
112                 zone:add_network(n)
113         end
114 end
115
116
117 if has_v2 then
118         family = s:taboption("advanced", ListValue, "family",
119                 translate("Restrict to address family"))
120
121         family.rmempty = true
122         family:value("", translate("IPv4 and IPv6"))
123         family:value("ipv4", translate("IPv4 only"))
124         family:value("ipv6", translate("IPv6 only"))
125 end
126
127 msrc = s:taboption("advanced", DynamicList, "masq_src",
128         translate("Restrict Masquerading to given source subnets"))
129
130 msrc.optional = true
131 msrc.datatype = "ip4addr"
132 msrc.placeholder = "0.0.0.0/0"
133 msrc:depends("family", "")
134 msrc:depends("family", "ipv4")
135
136 mdest = s:taboption("advanced", DynamicList, "masq_dest",
137         translate("Restrict Masquerading to given destination subnets"))
138
139 mdest.optional = true
140 mdest.datatype = "ip4addr"
141 mdest.placeholder = "0.0.0.0/0"
142 mdest:depends("family", "")
143 mdest:depends("family", "ipv4")
144
145 s:taboption("advanced", Flag, "conntrack",
146         translate("Force connection tracking"))
147
148 if has_v2 then
149         log = s:taboption("advanced", Flag, "log",
150                 translate("Enable logging on this zone"))
151
152         log.rmempty = true
153         log.enabled = "1"
154
155         lim = s:taboption("advanced", Value, "log_limit",
156                 translate("Limit log messages"))
157
158         lim.placeholder = "10/minute"
159         lim:depends("log", "1")
160 end
161
162
163 s2 = m:section(NamedSection, zone.sid, "fwd_out",
164         translate("Inter-Zone Forwarding"),
165         translatef("The options below control the forwarding policies between " ..
166                 "this zone (%s) and other zones. <em>Destination zones</em> cover " ..
167                 "forwarded traffic <strong>originating from %q</strong>. " ..
168                 "<em>Source zones</em> match forwarded traffic from other zones " ..
169                 "<strong>targeted at %q</strong>. The forwarding rule is " ..
170                 "<em>unidirectional</em>, e.g. a forward from lan to wan does " ..
171                 "<em>not</em> imply a permission to forward from wan to lan as well.",
172                 zone:name(), zone:name(), zone:name()
173
174         ))
175
176 out = s2:option(Value, "out",
177         translate("Allow forward to <em>destination zones</em>:"))
178
179 out.nocreate = true
180 out.widget = "checkbox"
181 out.exclude = zone:name()
182 out.template = "cbi/firewall_zonelist"
183
184 inp = s2:option(Value, "in",
185         translate("Allow forward from <em>source zones</em>:"))
186
187 inp.nocreate = true
188 inp.widget = "checkbox"
189 inp.exclude = zone:name()
190 inp.template = "cbi/firewall_zonelist"
191
192 function out.cfgvalue(self, section)
193         local v = { }
194         local f
195         for _, f in ipairs(zone:get_forwardings_by("src")) do
196                 v[#v+1] = f:dest()
197         end
198         return table.concat(v, " ")
199 end
200
201 function inp.cfgvalue(self, section)
202         local v = { }
203         local f
204         for _, f in ipairs(zone:get_forwardings_by("dest")) do
205                 v[#v+1] = f:src()
206         end
207         return v
208 end
209
210 function out.formvalue(self, section)
211         return Value.formvalue(self, section) or "-"
212 end
213
214 function inp.formvalue(self, section)
215         return Value.formvalue(self, section) or "-"
216 end
217
218 function out.write(self, section, value)
219         zone:del_forwardings_by("src")
220
221         local f
222         for f in utl.imatch(value) do
223                 zone:add_forwarding_to(f)
224         end
225 end
226
227 function inp.write(self, section, value)
228         zone:del_forwardings_by("dest")
229
230         local f
231         for f in utl.imatch(value) do
232                 zone:add_forwarding_from(f)
233         end
234 end
235
236 return m