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:
Jo-Philipp Wich 2019-11-03 20:34:57 +01:00
parent a43b1c6468
commit 9e57fbb2c3
5 changed files with 39 additions and 322 deletions

View file

@ -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
});

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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" ]
}
}