Merge pull request #1323 from yousong/shadowsocks-libev
luci-app-shadowsocks-libev: support for option dst_forward_recentrst
This commit is contained in:
commit
d86244ab39
4 changed files with 158 additions and 91 deletions
|
@ -9,23 +9,28 @@ m = Map("shadowsocks-libev",
|
|||
translate("Redir Rules"),
|
||||
translate("On this page you can configure how traffics are to be \
|
||||
forwarded to ss-redir instances. \
|
||||
If enabled, packets will first have their source ip addresses checked \
|
||||
against <em>Src ip bypass</em>, <em>Src ip forward</em>, \
|
||||
<em>Src ip checkdst</em> and if none matches <em>Src default</em> \
|
||||
If enabled, packets will first have their src ip addresses checked \
|
||||
against <em>Src ip/net bypass</em>, <em>Src ip/net forward</em>, \
|
||||
<em>Src ip/net checkdst</em> and if none matches <em>Src default</em> \
|
||||
will give the default action to be taken. \
|
||||
If the prior check results in action <em>checkdst</em>, packets will continue \
|
||||
to have their destination addresses checked."))
|
||||
to have their dst addresses checked."))
|
||||
|
||||
local sdata = m:get('ss_rules')
|
||||
if not sdata then
|
||||
m:set('ss_rules', nil, 'ss_rules')
|
||||
m:set('ss_rules', 'disabled', true)
|
||||
m:set('ss_rules', 'disabled', "1")
|
||||
end
|
||||
|
||||
function src_dst_option(s, ...)
|
||||
local o = s:taboption(...)
|
||||
o.datatype = "or(ip4addr,cidr4)"
|
||||
end
|
||||
|
||||
s = m:section(NamedSection, "ss_rules", "ss_rules")
|
||||
s:tab("general", translate("General Settings"))
|
||||
s:tab("srcip", translate("Source Settings"))
|
||||
s:tab("dstip", translate("Destination Settings"))
|
||||
s:tab("src", translate("Source Settings"))
|
||||
s:tab("dst", translate("Destination Settings"))
|
||||
|
||||
s:taboption('general', Flag, "disabled", translate("Disable"))
|
||||
ss.option_install_package(s, 'general')
|
||||
|
@ -49,38 +54,56 @@ s:taboption('general', Value, "ipt_args",
|
|||
translate("Extra arguments"),
|
||||
translate("Passes additional arguments to iptables. Use with care!"))
|
||||
|
||||
s:taboption('srcip', DynamicList, "src_ips_bypass",
|
||||
translate("Src ip bypass"),
|
||||
translate("Bypass redir action for packets with source addresses in this list"))
|
||||
s:taboption('srcip', DynamicList, "src_ips_forward",
|
||||
translate("Src ip forward"),
|
||||
translate("Go through redir action for packets with source addresses in this list"))
|
||||
s:taboption('srcip', DynamicList, "src_ips_checkdst",
|
||||
translate("Src ip checkdst"),
|
||||
translate("Continue to have dst address checked for packets with source addresses in this list"))
|
||||
o = s:taboption('srcip', ListValue, "src_default",
|
||||
src_dst_option(s, 'src', DynamicList, "src_ips_bypass",
|
||||
translate("Src ip/net bypass"),
|
||||
translate("Bypass ss-redir for packets with src address in this list"))
|
||||
src_dst_option(s, 'src', DynamicList, "src_ips_forward",
|
||||
translate("Src ip/net forward"),
|
||||
translate("Forward through ss-redir for packets with src address in this list"))
|
||||
src_dst_option(s, 'src', DynamicList, "src_ips_checkdst",
|
||||
translate("Src ip/net checkdst"),
|
||||
translate("Continue to have dst address checked for packets with src address in this list"))
|
||||
o = s:taboption('src', ListValue, "src_default",
|
||||
translate("Src default"),
|
||||
translate("Default action for packets whose source addresses do not match any of the source ip list"))
|
||||
translate("Default action for packets whose src address do not match any of the src ip/net list"))
|
||||
ss.values_actions(o)
|
||||
|
||||
s:taboption('dstip', DynamicList, "dst_ips_bypass",
|
||||
translate("Dst ip bypass"),
|
||||
translate("Bypass redir action for packets with destination addresses in this list"))
|
||||
s:taboption('dstip', DynamicList, "dst_ips_forward",
|
||||
translate("Dst ip forward"),
|
||||
translate("Go through redir action for packets with destination addresses in this list"))
|
||||
src_dst_option(s, 'dst', DynamicList, "dst_ips_bypass",
|
||||
translate("Dst ip/net bypass"),
|
||||
translate("Bypass ss-redir for packets with dst address in this list"))
|
||||
src_dst_option(s, 'dst', DynamicList, "dst_ips_forward",
|
||||
translate("Dst ip/net forward"),
|
||||
translate("Forward through ss-redir for packets with dst address in this list"))
|
||||
|
||||
o = s:taboption('dstip', FileBrowser, "dst_ips_bypass_file",
|
||||
translate("Dst ip bypass file"),
|
||||
translate("File containing ip addresses for the purposes as with <em>Dst ip bypass</em>"))
|
||||
o = s:taboption('dst', FileBrowser, "dst_ips_bypass_file",
|
||||
translate("Dst ip/net bypass file"),
|
||||
translate("File containing ip/net for the purposes as with <em>Dst ip/net bypass</em>"))
|
||||
o.datatype = "file"
|
||||
s:taboption('dstip', FileBrowser, "dst_ips_forward_file",
|
||||
translate("Dst ip forward file"),
|
||||
translate("File containing ip addresses for the purposes as with <em>Dst ip forward</em>"))
|
||||
s:taboption('dst', FileBrowser, "dst_ips_forward_file",
|
||||
translate("Dst ip/net forward file"),
|
||||
translate("File containing ip/net for the purposes as with <em>Dst ip/net forward</em>"))
|
||||
o.datatype = "file"
|
||||
o = s:taboption('dstip', ListValue, "dst_default",
|
||||
o = s:taboption('dst', ListValue, "dst_default",
|
||||
translate("Dst default"),
|
||||
translate("Default action for packets whose destination addresses do not match any of the destination ip list"))
|
||||
translate("Default action for packets whose dst address do not match any of the dst ip list"))
|
||||
ss.values_actions(o)
|
||||
|
||||
local installed = os.execute("iptables -m recent -h &>/dev/null") == 0
|
||||
if installed then
|
||||
o = s:taboption('dst', Flag, "dst_forward_recentrst")
|
||||
else
|
||||
m:set('ss_rules', 'dst_forward_recentrst', "0")
|
||||
o = s:taboption("dst", Button, "_install")
|
||||
o.inputtitle = translate("Install package iptables-mod-conntrack-extra")
|
||||
o.inputstyle = "apply"
|
||||
o.write = function()
|
||||
return luci.http.redirect(
|
||||
luci.dispatcher.build_url("admin/system/packages") ..
|
||||
"?submit=1&install=iptables-mod-conntrack-extra"
|
||||
)
|
||||
end
|
||||
end
|
||||
o.title = translate("Forward recentrst")
|
||||
o.description = translate("Forward those packets whose dst have recently sent to us multiple tcp-rst")
|
||||
|
||||
return m
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
local _up = getfenv(3)
|
||||
local ut = require("luci.util")
|
||||
local sys = require("luci.sys")
|
||||
local ds = require("luci.dispatcher")
|
||||
local nw = require("luci.model.network")
|
||||
nw.init()
|
||||
|
@ -23,13 +24,16 @@ end
|
|||
|
||||
function values_redir(o, xmode)
|
||||
o.map.uci.foreach("shadowsocks-libev", "ss_redir", function(sdata)
|
||||
local disabled = ucival_to_bool(sdata["disabled"])
|
||||
local sname = sdata[".name"]
|
||||
local mode = sdata["mode"] or "tcp_only"
|
||||
if mode and mode:find(xmode) then
|
||||
if not disabled and mode:find(xmode) then
|
||||
local desc = "%s - %s" % {sname, mode}
|
||||
o:value(sname, desc)
|
||||
end
|
||||
end)
|
||||
o:value("", "<unset>")
|
||||
o.default = ""
|
||||
end
|
||||
|
||||
function values_serverlist(o)
|
||||
|
@ -53,10 +57,8 @@ function values_ipaddr(o)
|
|||
end
|
||||
|
||||
function values_ifnames(o)
|
||||
for _, v in ipairs(nw:get_interfaces()) do
|
||||
if v.dev then
|
||||
o:value(v.dev.name)
|
||||
end
|
||||
for _, v in ipairs(sys.net.devices()) do
|
||||
o:value(v)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -118,6 +118,70 @@ var cbi_validators = {
|
|||
return false;
|
||||
},
|
||||
|
||||
'ip4prefix': function()
|
||||
{
|
||||
return !isNaN(this) && this >= 0 && this <= 32;
|
||||
},
|
||||
|
||||
'ip6prefix': function()
|
||||
{
|
||||
return !isNaN(this) && this >= 0 && this <= 128;
|
||||
},
|
||||
|
||||
'cidr': function()
|
||||
{
|
||||
return cbi_validators.cidr4.apply(this) ||
|
||||
cbi_validators.cidr6.apply(this);
|
||||
},
|
||||
|
||||
'cidr4': function()
|
||||
{
|
||||
if (this.match(/^(\S+)\/(\S+)$/))
|
||||
{
|
||||
ip = RegExp.$1;
|
||||
mask = RegExp.$2;
|
||||
return cbi_validators.ip4addr.apply(ip) &&
|
||||
cbi_validators.ip4prefix.apply(mask);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
'cidr6': function()
|
||||
{
|
||||
if (this.match(/^(\S+)\/(\S+)$/))
|
||||
{
|
||||
ip = RegExp.$1;
|
||||
mask = RegExp.$2;
|
||||
return cbi_validators.ip6addr.apply(ip) &&
|
||||
cbi_validators.ip6prefix.apply(mask);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
'ipnet4': function()
|
||||
{
|
||||
if (this.match(/^(\S+)\/(\S+)$/))
|
||||
{
|
||||
ip = RegExp.$1;
|
||||
net = RegExp.$2;
|
||||
return cbi_validators.ip4addr.apply(ip) &&
|
||||
cbi_validators.ip4addr.apply(net);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
'ipnet6': function()
|
||||
{
|
||||
if (this.match(/^(\S+)\/(\S+)$/))
|
||||
{
|
||||
ip = RegExp.$1;
|
||||
net = RegExp.$2;
|
||||
return cbi_validators.ip6addr.apply(ip) &&
|
||||
cbi_validators.ip6addr.apply(net);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
'ipmask': function()
|
||||
{
|
||||
return cbi_validators.ipmask4.apply(this) ||
|
||||
|
@ -126,40 +190,16 @@ var cbi_validators = {
|
|||
|
||||
'ipmask4': function()
|
||||
{
|
||||
var ip = this, mask = 32;
|
||||
|
||||
if (ip.match(/^(\S+)\/(\S+)$/))
|
||||
{
|
||||
ip = RegExp.$1;
|
||||
mask = RegExp.$2;
|
||||
}
|
||||
|
||||
if (!isNaN(mask) && (mask < 0 || mask > 32))
|
||||
return false;
|
||||
|
||||
if (isNaN(mask) && !cbi_validators.ip4addr.apply(mask))
|
||||
return false;
|
||||
|
||||
return cbi_validators.ip4addr.apply(ip);
|
||||
return cbi_validators.cidr4.apply(this) ||
|
||||
cbi_validators.ipnet4.apply(this) ||
|
||||
cbi_validators.ip4addr.apply(this);
|
||||
},
|
||||
|
||||
'ipmask6': function()
|
||||
{
|
||||
var ip = this, mask = 128;
|
||||
|
||||
if (ip.match(/^(\S+)\/(\S+)$/))
|
||||
{
|
||||
ip = RegExp.$1;
|
||||
mask = RegExp.$2;
|
||||
}
|
||||
|
||||
if (!isNaN(mask) && (mask < 0 || mask > 128))
|
||||
return false;
|
||||
|
||||
if (isNaN(mask) && !cbi_validators.ip6addr.apply(mask))
|
||||
return false;
|
||||
|
||||
return cbi_validators.ip6addr.apply(ip);
|
||||
return cbi_validators.cidr6.apply(this) ||
|
||||
cbi_validators.ipnet6.apply(this) ||
|
||||
cbi_validators.ip6addr.apply(this);
|
||||
},
|
||||
|
||||
'port': function()
|
||||
|
|
|
@ -132,38 +132,40 @@ function ip6prefix(val)
|
|||
return ( val and val >= 0 and val <= 128 )
|
||||
end
|
||||
|
||||
function cidr4(val)
|
||||
local ip, mask = val:match("^([^/]+)/([^/]+)$")
|
||||
|
||||
return ip4addr(ip) and ip4prefix(mask)
|
||||
end
|
||||
|
||||
function cidr6(val)
|
||||
local ip, mask = val:match("^([^/]+)/([^/]+)$")
|
||||
|
||||
return ip6addr(ip) and ip6prefix(mask)
|
||||
end
|
||||
|
||||
function ipnet4(val)
|
||||
local ip, mask = val:match("^([^/]+)/([^/]+)$")
|
||||
|
||||
return ip4addr(ip) and ip4addr(mask)
|
||||
end
|
||||
|
||||
function ipnet6(val)
|
||||
local ip, mask = val:match("^([^/]+)/([^/]+)$")
|
||||
|
||||
return ip6addr(ip) and ip6addr(mask)
|
||||
end
|
||||
|
||||
function ipmask(val)
|
||||
return ipmask4(val) or ipmask6(val)
|
||||
end
|
||||
|
||||
function ipmask4(val)
|
||||
local ip, mask = val:match("^([^/]+)/([^/]+)$")
|
||||
local bits = tonumber(mask)
|
||||
|
||||
if bits and (bits < 0 or bits > 32) then
|
||||
return false
|
||||
end
|
||||
|
||||
if not bits and mask and not ip4addr(mask) then
|
||||
return false
|
||||
end
|
||||
|
||||
return ip4addr(ip or val)
|
||||
return cidr4(val) or ipnet4(val) or ip4addr(val)
|
||||
end
|
||||
|
||||
function ipmask6(val)
|
||||
local ip, mask = val:match("^([^/]+)/([^/]+)$")
|
||||
local bits = tonumber(mask)
|
||||
|
||||
if bits and (bits < 0 or bits > 128) then
|
||||
return false
|
||||
end
|
||||
|
||||
if not bits and mask and not ip6addr(mask) then
|
||||
return false
|
||||
end
|
||||
|
||||
return ip6addr(ip or val)
|
||||
return cidr6(val) or ipnet6(val) or ip6addr(val)
|
||||
end
|
||||
|
||||
function ip6hostid(val)
|
||||
|
|
Loading…
Reference in a new issue