luci-base, luci-app-firewall: port custom rules to client side view
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
This commit is contained in:
parent
a43b1c6468
commit
9e57fbb2c3
5 changed files with 39 additions and 322 deletions
|
@ -0,0 +1,31 @@
|
|||
'use strict';
|
||||
'require fs';
|
||||
|
||||
return L.view.extend({
|
||||
load: function() {
|
||||
return L.resolveDefault(fs.read('/etc/firewall.user'), '');
|
||||
},
|
||||
|
||||
handleSave: function(ev) {
|
||||
var value = (document.querySelector('textarea').value || '').trim().replace(/\r\n/g, '\n') + '\n';
|
||||
|
||||
return fs.write('/etc/firewall.user', value).then(function(rc) {
|
||||
document.querySelector('textarea').value = value;
|
||||
L.ui.addNotification(null, E('p', _('Contents have been saved.')), 'info');
|
||||
fs.exec('/etc/init.d/firewall', ['restart']);
|
||||
}).catch(function(e) {
|
||||
L.ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
},
|
||||
|
||||
render: function(fwuser) {
|
||||
return E([
|
||||
E('h2', _('Firewall - Custom Rules')),
|
||||
E('p', {}, _('Custom rules allow you to execute arbitrary iptables commands which are not otherwise covered by the firewall framework. The commands are executed after each firewall restart, right after the default ruleset has been loaded.')),
|
||||
E('p', {}, E('textarea', { 'style': 'width:100%', 'rows': 10 }, [ fwuser != null ? fwuser : '' ]))
|
||||
]);
|
||||
},
|
||||
|
||||
handleSaveApply: null,
|
||||
handleReset: null
|
||||
});
|
|
@ -15,6 +15,5 @@ function index()
|
|||
view("firewall/rules"), _("Traffic Rules"), 30)
|
||||
|
||||
entry({"admin", "network", "firewall", "custom"},
|
||||
form("firewall/custom"),
|
||||
_("Custom Rules"), 40).leaf = true
|
||||
view("firewall/custom"), _("Custom Rules"), 40).leaf = true
|
||||
end
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
-- Copyright 2011 Jo-Philipp Wich <jow@openwrt.org>
|
||||
-- Licensed to the public under the Apache License 2.0.
|
||||
|
||||
local fs = require "nixio.fs"
|
||||
|
||||
local f = SimpleForm("firewall",
|
||||
translate("Firewall - Custom Rules"),
|
||||
translate("Custom rules allow you to execute arbitrary iptables commands \
|
||||
which are not otherwise covered by the firewall framework. \
|
||||
The commands are executed after each firewall restart, right after \
|
||||
the default ruleset has been loaded."))
|
||||
|
||||
local o = f:field(Value, "_custom")
|
||||
|
||||
o.template = "cbi/tvalue"
|
||||
o.rows = 20
|
||||
|
||||
function o.cfgvalue(self, section)
|
||||
return fs.readfile("/etc/firewall.user")
|
||||
end
|
||||
|
||||
function o.write(self, section, value)
|
||||
value = value:gsub("\r\n?", "\n")
|
||||
fs.writefile("/etc/firewall.user", value)
|
||||
require("luci.sys").call("/etc/init.d/firewall restart >/dev/null 2<&1")
|
||||
require("nixio").syslog('info', 'Restarting firewall on custom /etc/firewall.user change')
|
||||
end
|
||||
|
||||
f.submit = translate("Restart Firewall")
|
||||
|
||||
return f
|
|
@ -1,289 +0,0 @@
|
|||
-- Copyright 2011-2012 Jo-Philipp Wich <jow@openwrt.org>
|
||||
-- Licensed to the public under the Apache License 2.0.
|
||||
|
||||
module("luci.tools.firewall", package.seeall)
|
||||
|
||||
local ut = require "luci.util"
|
||||
local ip = require "luci.ip"
|
||||
local nx = require "nixio"
|
||||
|
||||
local translate, translatef = luci.i18n.translate, luci.i18n.translatef
|
||||
|
||||
local function _(...)
|
||||
return tostring(translate(...))
|
||||
end
|
||||
|
||||
function fmt_neg(x)
|
||||
if type(x) == "string" then
|
||||
local v, neg = x:gsub("^ *! *", "")
|
||||
if neg > 0 then
|
||||
return v, "%s " % _("not")
|
||||
else
|
||||
return x, ""
|
||||
end
|
||||
end
|
||||
return x, ""
|
||||
end
|
||||
|
||||
function fmt_mac(x)
|
||||
if x and #x > 0 then
|
||||
local m, n
|
||||
local l = { _("MAC"), " " }
|
||||
for m in ut.imatch(x) do
|
||||
m, n = fmt_neg(m)
|
||||
l[#l+1] = "<var>%s%s</var>" %{ n, m }
|
||||
l[#l+1] = ", "
|
||||
end
|
||||
if #l > 1 then
|
||||
l[#l] = nil
|
||||
if #l > 3 then
|
||||
l[1] = _("MACs")
|
||||
end
|
||||
return table.concat(l, "")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function fmt_port(x, d)
|
||||
if x and #x > 0 then
|
||||
local p, n
|
||||
local l = { _("port"), " " }
|
||||
for p in ut.imatch(x) do
|
||||
p, n = fmt_neg(p)
|
||||
local a, b = p:match("(%d+)%D+(%d+)")
|
||||
if a and b then
|
||||
l[1] = _("ports")
|
||||
l[#l+1] = "<var>%s%d-%d</var>" %{ n, a, b }
|
||||
else
|
||||
l[#l+1] = "<var>%s%d</var>" %{ n, p }
|
||||
end
|
||||
l[#l+1] = ", "
|
||||
end
|
||||
if #l > 1 then
|
||||
l[#l] = nil
|
||||
if #l > 3 then
|
||||
l[1] = _("ports")
|
||||
end
|
||||
return table.concat(l, "")
|
||||
end
|
||||
end
|
||||
return d and "<var>%s</var>" % d
|
||||
end
|
||||
|
||||
function fmt_ip(x, d)
|
||||
if x and #x > 0 then
|
||||
local l = { _("IP"), " " }
|
||||
local v, a, n
|
||||
for v in ut.imatch(x) do
|
||||
v, n = fmt_neg(v)
|
||||
a, m = v:match("(%S+)/(%d+%.%S+)")
|
||||
a = a or v
|
||||
a = a:match(":") and ip.IPv6(a, m) or ip.IPv4(a, m)
|
||||
if a and (a:is6() and a:prefix() < 128 or a:prefix() < 32) then
|
||||
l[1] = _("IP range")
|
||||
l[#l+1] = "<var title='%s - %s'>%s%s</var>" %{
|
||||
a:minhost():string(),
|
||||
a:maxhost():string(),
|
||||
n, a:string()
|
||||
}
|
||||
else
|
||||
l[#l+1] = "<var>%s%s</var>" %{
|
||||
n,
|
||||
a and a:string() or v
|
||||
}
|
||||
end
|
||||
l[#l+1] = ", "
|
||||
end
|
||||
if #l > 1 then
|
||||
l[#l] = nil
|
||||
if #l > 3 then
|
||||
l[1] = _("IPs")
|
||||
end
|
||||
return table.concat(l, "")
|
||||
end
|
||||
end
|
||||
return d and "<var>%s</var>" % d
|
||||
end
|
||||
|
||||
function fmt_zone(x, d)
|
||||
if x == "*" then
|
||||
return "<var>%s</var>" % _("any zone")
|
||||
elseif x and #x > 0 then
|
||||
return "<var>%s</var>" % x
|
||||
elseif d then
|
||||
return "<var>%s</var>" % d
|
||||
end
|
||||
end
|
||||
|
||||
function fmt_icmp_type(x)
|
||||
if x and #x > 0 then
|
||||
local t, v, n
|
||||
local l = { _("type"), " " }
|
||||
for v in ut.imatch(x) do
|
||||
v, n = fmt_neg(v)
|
||||
l[#l+1] = "<var>%s%s</var>" %{ n, v }
|
||||
l[#l+1] = ", "
|
||||
end
|
||||
if #l > 1 then
|
||||
l[#l] = nil
|
||||
if #l > 3 then
|
||||
l[1] = _("types")
|
||||
end
|
||||
return table.concat(l, "")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function fmt_proto(x, icmp_types)
|
||||
if x and #x > 0 then
|
||||
local v, n
|
||||
local l = { }
|
||||
local t = fmt_icmp_type(icmp_types)
|
||||
for v in ut.imatch(x) do
|
||||
v, n = fmt_neg(v)
|
||||
if v == "tcpudp" then
|
||||
l[#l+1] = "TCP"
|
||||
l[#l+1] = ", "
|
||||
l[#l+1] = "UDP"
|
||||
l[#l+1] = ", "
|
||||
elseif v ~= "all" then
|
||||
local p = nx.getproto(v)
|
||||
if p then
|
||||
-- ICMP
|
||||
if (p.proto == 1 or p.proto == 58) and t then
|
||||
l[#l+1] = translatef(
|
||||
"%s%s with %s",
|
||||
n, p.aliases[1] or p.name, t
|
||||
)
|
||||
else
|
||||
l[#l+1] = "%s%s" %{
|
||||
n,
|
||||
p.aliases[1] or p.name
|
||||
}
|
||||
end
|
||||
l[#l+1] = ", "
|
||||
end
|
||||
end
|
||||
end
|
||||
if #l > 0 then
|
||||
l[#l] = nil
|
||||
return table.concat(l, "")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function fmt_limit(limit, burst)
|
||||
burst = tonumber(burst)
|
||||
if limit and #limit > 0 then
|
||||
local l, u = limit:match("(%d+)/(%w+)")
|
||||
l = tonumber(l or limit)
|
||||
u = u or "second"
|
||||
if l then
|
||||
if u:match("^s") then
|
||||
u = _("second")
|
||||
elseif u:match("^m") then
|
||||
u = _("minute")
|
||||
elseif u:match("^h") then
|
||||
u = _("hour")
|
||||
elseif u:match("^d") then
|
||||
u = _("day")
|
||||
end
|
||||
if burst and burst > 0 then
|
||||
return translatef("<var>%d</var> pkts. per <var>%s</var>, \
|
||||
burst <var>%d</var> pkts.", l, u, burst)
|
||||
else
|
||||
return translatef("<var>%d</var> pkts. per <var>%s</var>", l, u)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function fmt_target(x, src, dest)
|
||||
if not src or #src == 0 then
|
||||
if x == "ACCEPT" then
|
||||
return _("Accept output")
|
||||
elseif x == "REJECT" then
|
||||
return _("Refuse output")
|
||||
elseif x == "NOTRACK" then
|
||||
return _("Do not track output")
|
||||
else --if x == "DROP" then
|
||||
return _("Discard output")
|
||||
end
|
||||
elseif dest and #dest > 0 then
|
||||
if x == "ACCEPT" then
|
||||
return _("Accept forward")
|
||||
elseif x == "REJECT" then
|
||||
return _("Refuse forward")
|
||||
elseif x == "NOTRACK" then
|
||||
return _("Do not track forward")
|
||||
else --if x == "DROP" then
|
||||
return _("Discard forward")
|
||||
end
|
||||
else
|
||||
if x == "ACCEPT" then
|
||||
return _("Accept input")
|
||||
elseif x == "REJECT" then
|
||||
return _("Refuse input")
|
||||
elseif x == "NOTRACK" then
|
||||
return _("Do not track input")
|
||||
else --if x == "DROP" then
|
||||
return _("Discard input")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function opt_enabled(s, t, ...)
|
||||
if t == luci.cbi.Button then
|
||||
local o = s:option(t, "__enabled")
|
||||
function o.render(self, section)
|
||||
if self.map:get(section, "enabled") ~= "0" then
|
||||
self.title = _("Rule is enabled")
|
||||
self.inputtitle = _("Disable")
|
||||
self.inputstyle = "reset"
|
||||
else
|
||||
self.title = _("Rule is disabled")
|
||||
self.inputtitle = _("Enable")
|
||||
self.inputstyle = "apply"
|
||||
end
|
||||
t.render(self, section)
|
||||
end
|
||||
function o.write(self, section, value)
|
||||
if self.map:get(section, "enabled") ~= "0" then
|
||||
self.map:set(section, "enabled", "0")
|
||||
else
|
||||
self.map:del(section, "enabled")
|
||||
end
|
||||
end
|
||||
return o
|
||||
else
|
||||
local o = s:option(t, "enabled", ...)
|
||||
o.default = "1"
|
||||
return o
|
||||
end
|
||||
end
|
||||
|
||||
function opt_name(s, t, ...)
|
||||
local o = s:option(t, "name", ...)
|
||||
|
||||
function o.cfgvalue(self, section)
|
||||
return self.map:get(section, "name") or
|
||||
self.map:get(section, "_name") or "-"
|
||||
end
|
||||
|
||||
function o.write(self, section, value)
|
||||
if value ~= "-" then
|
||||
self.map:set(section, "name", value)
|
||||
self.map:del(section, "_name")
|
||||
else
|
||||
self:remove(section)
|
||||
end
|
||||
end
|
||||
|
||||
function o.remove(self, section)
|
||||
self.map:del(section, "name")
|
||||
self.map:del(section, "_name")
|
||||
end
|
||||
|
||||
return o
|
||||
end
|
|
@ -88,12 +88,19 @@
|
|||
"luci-app-firewall": {
|
||||
"description": "Grant access to firewall procedures",
|
||||
"read": {
|
||||
"file": {
|
||||
"/etc/firewall.user": [ "read" ]
|
||||
},
|
||||
"ubus": {
|
||||
"luci": [ "getConntrackHelpers" ]
|
||||
},
|
||||
"uci": [ "firewall" ]
|
||||
},
|
||||
"write": {
|
||||
"file": {
|
||||
"/etc/firewall.user": [ "write" ],
|
||||
"/etc/init.d/firewall": [ "exec" ]
|
||||
},
|
||||
"uci": [ "firewall" ]
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue