f0e7b8665d56b3342e3a30480f24ac2752a0ed0a
[project/luci.git] / applications / luci-firewall / luasrc / model / cbi / luci_fw / zones.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 ds = require "luci.dispatcher"
18
19 local has_v2 = nixio.fs.access("/lib/firewall/fw.sh")
20
21 require("luci.tools.webadmin")
22 m = Map("firewall", translate("Firewall"), translate("The firewall creates zones over your network interfaces to control network traffic flow."))
23
24 fw.init(m.uci)
25 nw.init(m.uci)
26
27 s = m:section(TypedSection, "defaults")
28 s.anonymous = true
29 s.addremove = false
30
31 s:tab("general", translate("General Settings"))
32 s:tab("custom", translate("Custom Rules"))
33
34
35 s:taboption("general", Flag, "syn_flood", translate("Enable SYN-flood protection"))
36
37 local di = s:taboption("general", Flag, "drop_invalid", translate("Drop invalid packets"))
38 di.rmempty = false
39 function di.cfgvalue(...)
40         return AbstractValue.cfgvalue(...) or "1"
41 end
42
43 p = {}
44 p[1] = s:taboption("general", ListValue, "input", translate("Input"))
45 p[2] = s:taboption("general", ListValue, "output", translate("Output"))
46 p[3] = s:taboption("general", ListValue, "forward", translate("Forward"))
47
48 for i, v in ipairs(p) do
49         v:value("REJECT", translate("reject"))
50         v:value("DROP", translate("drop"))
51         v:value("ACCEPT", translate("accept"))
52 end
53
54 custom = s:taboption("custom", Value, "_custom",
55         translate("Custom Rules (/etc/firewall.user)"))
56
57 custom.template = "cbi/tvalue"
58 custom.rows = 20
59
60 function custom.cfgvalue(self, section)
61         return nixio.fs.readfile("/etc/firewall.user")
62 end
63
64 function custom.write(self, section, value)
65         nixio.fs.writefile("/etc/firewall.user", value)
66 end
67
68
69 s = m:section(TypedSection, "zone", translate("Zones"))
70 s.template = "cbi/tblsection"
71 s.anonymous = true
72 s.addremove = true
73 s.extedit   = ds.build_url("admin", "network", "firewall", "zones", "%s")
74
75 function s.create(self)
76         local z = fw:new_zone()
77         if z then
78                 luci.http.redirect(
79                         ds.build_url("admin", "network", "firewall", "zones", z.sid)
80                 )
81         end
82 end
83
84 info = s:option(DummyValue, "_info", translate("Zone ⇒ Forwardings"))
85 info.template = "cbi/firewall_zoneforwards"
86 function info.cfgvalue(self, section)
87         return self.map:get(section, "name")
88 end
89
90 p = {}
91 p[1] = s:option(ListValue, "input", translate("Input"))
92 p[2] = s:option(ListValue, "output", translate("Output"))
93 p[3] = s:option(ListValue, "forward", translate("Forward"))
94
95 for i, v in ipairs(p) do
96         v:value("REJECT", translate("reject"))
97         v:value("DROP", translate("drop"))
98         v:value("ACCEPT", translate("accept"))
99 end
100
101 s:option(Flag, "masq", translate("Masquerading"))
102 s:option(Flag, "mtu_fix", translate("MSS clamping"))
103
104
105 local created = nil
106
107 --
108 -- Redirects
109 --
110
111 s = m:section(TypedSection, "redirect", translate("Redirections"))
112 s.template  = "cbi/tblsection"
113 s.addremove = true
114 s.anonymous = true
115 s.extedit   = ds.build_url("admin", "network", "firewall", "redirect", "%s")
116
117 function s.create(self, section)
118         created = TypedSection.create(self, section)
119 end
120
121 function s.parse(self, ...)
122         TypedSection.parse(self, ...)
123         if created then
124                 m.uci:save("firewall")
125                 luci.http.redirect(ds.build_url(
126                         "admin", "network", "firewall", "redirect", created
127                 ))
128         end
129 end
130
131 name = s:option(DummyValue, "_name", translate("Name"))
132 function name.cfgvalue(self, s)
133         return self.map:get(s, "_name") or "-"
134 end
135
136 proto = s:option(DummyValue, "proto", translate("Protocol"))
137 function proto.cfgvalue(self, s)
138         local p = self.map:get(s, "proto")
139         if not p or p == "tcpudp" then
140                 return "TCP+UDP"
141         else
142                 return p:upper()
143         end
144 end
145
146 src = s:option(DummyValue, "src", translate("Source"))
147 function src.cfgvalue(self, s)
148         local rv = "%s:%s:%s" % {
149                 self.map:get(s, "src") or "*",
150                 self.map:get(s, "src_ip") or "0.0.0.0/0",
151                 self.map:get(s, "src_port") or "*"
152         }
153
154         local mac = self.map:get(s, "src_mac")
155         if mac then
156                 rv = rv .. ", MAC " .. mac
157         end
158
159         return rv
160 end
161
162 via = s:option(DummyValue, "via", translate("Via"))
163 function via.cfgvalue(self, s)
164         return "%s:%s:%s" % {
165                 translate("Device"),
166                 self.map:get(s, "src_dip") or "0.0.0.0/0",
167                 self.map:get(s, "src_dport") or "*"
168         }
169 end
170
171 dest = s:option(DummyValue, "dest", translate("Destination"))
172 function dest.cfgvalue(self, s)
173         return "%s:%s:%s" % {
174                 self.map:get(s, "dest") or "*",
175                 self.map:get(s, "dest_ip") or "0.0.0.0/0",
176                 self.map:get(s, "dest_port") or "*"
177         }
178 end
179
180 target = s:option(DummyValue, "target", translate("Action"))
181 function target.cfgvalue(self, s)
182         return self.map:get(s, "target") or "DNAT"
183 end
184
185
186 --
187 -- Rules
188 --
189
190 s = m:section(TypedSection, "rule", translate("Rules"))
191 s.addremove = true
192 s.anonymous = true
193 s.template = "cbi/tblsection"
194 s.extedit   = ds.build_url("admin", "network", "firewall", "rule", "%s")
195 s.defaults.target = "ACCEPT"
196
197 function s.create(self, section)
198         local created = TypedSection.create(self, section)
199         m.uci:save("firewall")
200         luci.http.redirect(ds.build_url(
201                 "admin", "network", "firewall", "rule", created
202         ))
203         return
204 end
205
206 name = s:option(DummyValue, "_name", translate("Name"))
207 function name.cfgvalue(self, s)
208         return self.map:get(s, "_name") or "-"
209 end
210
211 if has_v2 then
212         family = s:option(DummyValue, "family", translate("Family"))
213         function family.cfgvalue(self, s)
214                 local f = self.map:get(s, "family")
215                 if f and f:match("4") then
216                         return translate("IPv4 only")
217                 elseif f and f:match("6") then
218                         return translate("IPv6 only")
219                 else
220                         return translate("IPv4 and IPv6")
221                 end
222         end
223 end
224
225 proto = s:option(DummyValue, "proto", translate("Protocol"))
226 function proto.cfgvalue(self, s)
227         local p = self.map:get(s, "proto")
228         local t = self.map:get(s, "icmp_type")
229         if p == "icmp" and t then
230                 return "ICMP (%s)" % t
231         elseif p == "tcpudp" or not p then
232                 return "TCP+UDP"
233         else
234                 return p:upper()
235         end
236 end
237
238 src = s:option(DummyValue, "src", translate("Source"))
239 function src.cfgvalue(self, s)
240         local rv = "%s:%s:%s" % {
241                 self.map:get(s, "src") or "*",
242                 self.map:get(s, "src_ip") or "0.0.0.0/0",
243                 self.map:get(s, "src_port") or "*"
244         }
245
246         local mac = self.map:get(s, "src_mac")
247         if mac then
248                 rv = rv .. ", MAC " .. mac
249         end
250
251         return rv
252 end
253
254 dest = s:option(DummyValue, "dest", translate("Destination"))
255 function dest.cfgvalue(self, s)
256         return "%s:%s:%s" % {
257                 self.map:get(s, "dest") or translate("Device"),
258                 self.map:get(s, "dest_ip") or "0.0.0.0/0",
259                 self.map:get(s, "dest_port") or "*"
260         }
261 end
262
263
264 s:option(DummyValue, "target", translate("Action"))
265
266 return m