luci-app-ssr-plus: revert lock feature

This commit is contained in:
lean 2020-04-15 20:39:16 +08:00
parent 8a02b49078
commit 2125e805d1
36 changed files with 1548 additions and 1220 deletions

View File

@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-ssr-plus PKG_NAME:=luci-app-ssr-plus
PKG_VERSION:=176 PKG_VERSION:=176
PKG_RELEASE:=5 PKG_RELEASE:=6
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
@ -38,10 +38,10 @@ define Package/$(PKG_NAME)
SECTION:=luci SECTION:=luci
CATEGORY:=LuCI CATEGORY:=LuCI
SUBMENU:=3. Applications SUBMENU:=3. Applications
TITLE:=SS/SSR/V2Ray/Trojan/Socks5/Tun LuCI interface TITLE:=SS/SSR/V2Ray/Trojan LuCI interface
PKGARCH:=all PKGARCH:=all
DEPENDS:=+shadowsocksr-libev-alt +ipset +ip-full +iptables-mod-tproxy +dnsmasq-full +coreutils +coreutils-base64 +pdnsd-alt +wget +lua +libuci-lua \ DEPENDS:=+shadowsocksr-libev-alt +ipset +ip-full +iptables-mod-tproxy +dnsmasq-full +coreutils +coreutils-base64 +pdnsd-alt +wget +lua +libuci-lua \
+microsocks +dns2socks +shadowsocks-libev-ss-local +shadowsocksr-libev-ssr-local +shadowsocks-libev-ss-redir +simple-obfs +tcpping +resolveip \ +microsocks +dns2socks +shadowsocks-libev-ss-local +shadowsocksr-libev-ssr-local +shadowsocks-libev-ss-redir +simple-obfs +tcpping \
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_plugin:v2ray-plugin \ +PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_plugin:v2ray-plugin \
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:v2ray \ +PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:v2ray \
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan:trojan \ +PACKAGE_$(PKG_NAME)_INCLUDE_Trojan:trojan \
@ -58,17 +58,23 @@ define Build/Compile
endef endef
define Package/$(PKG_NAME)/conffiles define Package/$(PKG_NAME)/conffiles
/etc/ssr_ip
/etc/china_ssr.txt
/etc/config/shadowsocksr /etc/config/shadowsocksr
/etc/ssr/netflix.list /etc/config/white.list
/etc/ssr/netflixip.list /etc/config/black.list
/etc/config/netflix.list
/etc/dnsmasq.ssr/ad.conf
/etc/dnsmasq.ssr/gfw_list.conf
endef endef
define Package/$(PKG_NAME)/install define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/etc/ssr $(INSTALL_DIR) $(1)/etc
$(INSTALL_DATA) ./root/etc/ssr/* $(1)/etc/ssr/ $(INSTALL_DATA) ./root/etc/china_ssr.txt $(1)/etc/china_ssr.txt
$(INSTALL_DIR) $(1)/etc/config $(INSTALL_DIR) $(1)/etc/config
$(INSTALL_CONF) ./root/etc/config/shadowsocksr $(1)/etc/config/shadowsocksr $(INSTALL_CONF) ./root/etc/config/shadowsocksr $(1)/etc/config/shadowsocksr
$(INSTALL_DATA) ./root/etc/config/*.list $(1)/etc/config/
$(INSTALL_DIR) $(1)/etc/dnsmasq.oversea $(INSTALL_DIR) $(1)/etc/dnsmasq.oversea
$(INSTALL_DATA) ./root/etc/dnsmasq.oversea/* $(1)/etc/dnsmasq.oversea/ $(INSTALL_DATA) ./root/etc/dnsmasq.oversea/* $(1)/etc/dnsmasq.oversea/
@ -104,8 +110,8 @@ endef
define Package/$(PKG_NAME)/postrm define Package/$(PKG_NAME)/postrm
#!/bin/sh #!/bin/sh
rm -rf /etc/ssl/private /etc/dnsmasq.ssr /etc/dnsmasq.oversea /etc/ssr /etc/config/shadowsocksr /etc/china_ssr.txt /etc/config/black.list /etc/config/white.list \ rm -rf /etc/china_ssr.txt /etc/dnsmasq.ssr /etc/dnsmasq.oversea /etc/config/shadowsocksr /etc/config/black.list \
/etc/config/netflix.list /etc/config/netflixip.list /etc/config/gfw.list /etc/config/white.list /etc/config/netflix.list /etc/config/netflixip.list 2>/dev/null
endef endef
$(eval $(call BuildPackage,$(PKG_NAME))) $(eval $(call BuildPackage,$(PKG_NAME)))

View File

@ -1,5 +1,6 @@
-- Copyright (C) 2017 yushi studio <ywb94@qq.com> -- Copyright (C) 2017 yushi studio <ywb94@qq.com>
-- Licensed to the public under the GNU General Public License v3. -- Licensed to the public under the GNU General Public License v3.
module("luci.controller.shadowsocksr", package.seeall) module("luci.controller.shadowsocksr", package.seeall)
function index() function index()
@ -73,50 +74,105 @@ function refresh_data()
local set = luci.http.formvalue("set") local set = luci.http.formvalue("set")
local uci = luci.model.uci.cursor() local uci = luci.model.uci.cursor()
local icount = 0 local icount = 0
local retstring = 0 if set == "gfw_data" then
local function update(url, file, type, file2) refresh_cmd = "wget-ssl --no-check-certificate -O- " .. uci:get_first('shadowsocksr', 'global', 'gfwlist_url', 'https://cdn.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt') .. ' > /tmp/gfw.b64'
local Num = 1
refresh_cmd = "wget-ssl --no-check-certificate -t 3 -T 10 -O- " .. url .. " > /tmp/ssr-update." .. type
sret = luci.sys.call(refresh_cmd .. " 2>/dev/null") sret = luci.sys.call(refresh_cmd .. " 2>/dev/null")
if sret == 0 then if sret == 0 then
if type == "gfw_data" then luci.sys.call("/usr/bin/ssr-gfw")
luci.sys.call("/usr/bin/ssr-gfw " .. type) icount = luci.sys.exec("cat /tmp/gfwnew.txt | wc -l")
Num = 2 if tonumber(icount) > 1000 then
end if nixio.fs.access("/etc/dnsmasq.ssr/gfw_list.conf") then
if type == "ad_data" then oldcount = luci.sys.exec("cat /etc/dnsmasq.ssr/gfw_list.conf | wc -l")
luci.sys.call("/usr/bin/ssr-ad " .. type)
end
local new_md5 = luci.sys.exec("echo -n $([ -f '/tmp/ssr-update." .. type .. "' ] && md5sum /tmp/ssr-update." .. type .. " | awk '{print $1}')")
local old_md5 = luci.sys.exec("echo -n $([ -f '" .. file .. "' ] && md5sum " .. file .. " | awk '{print $1}')")
if new_md5 == old_md5 then
retstring = "0"
else
icount = luci.sys.exec("cat /tmp/ssr-update." .. type .. " | wc -l")
luci.sys.exec("cp -f /tmp/ssr-update." .. type .. " " .. file)
if file2 then luci.sys.exec("cp -f /tmp/ssr-update." .. type .. " " .. file2) end
retstring = tostring(tonumber(icount)/Num)
if type == "gfw_data" or type == "ad_data" then
luci.sys.exec("/usr/share/shadowsocksr/gfw2ipset.sh gfw_data")
else else
luci.sys.exec("/etc/init.d/shadowsocksr restart &") oldcount = "0"
end end
if tonumber(icount) ~= tonumber(oldcount) then
luci.sys.exec("cp -f /tmp/gfwnew.txt /etc/dnsmasq.ssr/gfw_list.conf")
luci.sys.exec("cp -f /tmp/gfwnew.txt /tmp/dnsmasq.ssr/gfw_list.conf")
luci.sys.call("/etc/init.d/dnsmasq restart")
retstring = tostring(tonumber(icount)/2)
else
retstring = "0"
end
else
retstring = "-1"
end
luci.sys.exec("rm -f /tmp/gfwnew.txt")
else
retstring = "-1"
end
end
if set == "ip_data" then
refresh_cmd = "wget-ssl --no-check-certificate -O- " .. uci:get_first('shadowsocksr', 'global', 'chnroute_url', 'https://ispip.clang.cn/all_cn.txt') .. " > /tmp/china_ssr.txt"
sret = luci.sys.call(refresh_cmd .. " 2>/dev/null")
icount = luci.sys.exec("cat /tmp/china_ssr.txt | wc -l")
if sret == 0 and tonumber(icount) > 1000 then
if nixio.fs.access("/etc/china_ssr.txt") then
oldcount = luci.sys.exec("cat /etc/china_ssr.txt | wc -l")
else
oldcount = "0"
end
if tonumber(icount) ~= tonumber(oldcount) then
luci.sys.exec("cp -f /tmp/china_ssr.txt /etc/china_ssr.txt")
luci.sys.exec("/etc/init.d/shadowsocksr restart &")
retstring = tostring(tonumber(icount))
else
retstring = "0"
end end
else else
retstring = "-1" retstring = "-1"
end end
luci.sys.exec("rm -f /tmp/ssr-update." .. type) luci.sys.exec("rm -f /tmp/china_ssr.txt")
end
if set == "gfw_data" then
update(uci:get_first("shadowsocksr", "global", "gfwlist_url", "https://cdn.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt"), "/etc/dnsmasq.ssr/gfw_list.conf", set, "/tmp/dnsmasq.ssr/gfw_list.conf")
end
if set == "ip_data" then
update(uci:get_first("shadowsocksr", "global", "chnroute_url","https://ispip.clang.cn/all_cn.txt"), "/etc/ssr/china_ssr.txt", set)
end
if set == "ad_data" then
update(uci:get_first("shadowsocksr", "global", "adblock_url","https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt"), "/etc/dnsmasq.ssr/ad.conf", set, "/tmp/dnsmasq.ssr/ad.conf")
end end
if set == "nfip_data" then if set == "nfip_data" then
update(uci:get_first("shadowsocksr", "global", "nfip_url","https://raw.githubusercontent.com/QiuSimons/Netflix_IP/master/NF_only.txt"), "/etc/ssr/netflixip.list", set) refresh_cmd = "wget-ssl --no-check-certificate -O- " .. uci:get_first('shadowsocksr', 'global', 'nfip_url','https://raw.githubusercontent.com/QiuSimons/Netflix_IP/master/NF_only.txt') .." > /tmp/netflixip.list"
sret = luci.sys.call(refresh_cmd .. " 2>/dev/null")
icount = luci.sys.exec("cat /tmp/netflixip.list | wc -l")
if sret == 0 and tonumber(icount) > 5 then
if nixio.fs.access("/etc/config/netflixip.list") then
oldcount = luci.sys.exec("cat /etc/config/netflixip.list | wc -l")
else
oldcount = "0"
end
if tonumber(icount) ~= tonumber(oldcount) then
luci.sys.exec("cp -f /tmp/netflixip.list /etc/config/netflixip.list")
luci.sys.exec("/etc/init.d/shadowsocksr restart &")
retstring = tostring(tonumber(icount))
else
retstring = "0"
end
else
retstring = "-1"
end
luci.sys.exec("rm -f /tmp/netflixip.list")
end
if set == "ad_data" then
refresh_cmd = "wget-ssl --no-check-certificate -O- " .. uci:get_first('shadowsocksr', 'global', 'adblock_url','https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt') .." > /tmp/adnew.conf"
sret = luci.sys.call(refresh_cmd .. " 2>/dev/null")
if sret == 0 then
luci.sys.call("/usr/bin/ssr-ad")
icount = luci.sys.exec("cat /tmp/ad.conf | wc -l")
if tonumber(icount) > 100 then
if nixio.fs.access("/etc/dnsmasq.ssr/ad.conf") then
oldcount = luci.sys.exec("cat /etc/dnsmasq.ssr/ad.conf | wc -l")
else
oldcount = "0"
end
if tonumber(icount) ~= tonumber(oldcount) then
luci.sys.exec("cp -f /tmp/ad.conf /etc/dnsmasq.ssr/ad.conf")
luci.sys.exec("cp -f /tmp/ad.conf /tmp/dnsmasq.ssr/ad.conf")
luci.sys.call("/etc/init.d/dnsmasq restart")
retstring = tostring(tonumber(icount))
else
retstring = "0"
end
else
retstring = "-1"
end
luci.sys.exec("rm -f /tmp/ad.conf")
else
retstring = "-1"
end
end end
luci.http.prepare_content("application/json") luci.http.prepare_content("application/json")
luci.http.write_json({ret = retstring,retcount = icount}) luci.http.write_json({ret = retstring,retcount = icount})

View File

@ -1,4 +1,3 @@
require "luci.model.uci"
local shadowsocksr = "shadowsocksr" local shadowsocksr = "shadowsocksr"
local uci = luci.model.uci.cursor() local uci = luci.model.uci.cursor()
local server_table = {} local server_table = {}

View File

@ -1,105 +1,108 @@
-- Copyright (C) 2017 yushi studio <ywb94@qq.com> github.com/ywb94 -- Copyright (C) 2017 yushi studio <ywb94@qq.com> github.com/ywb94
-- Licensed to the public under the GNU General Public License v3. -- Licensed to the public under the GNU General Public License v3.
require "luci.model.uci"
require "nixio.fs"
require "luci.sys"
require "luci.http"
local m, s, o,kcp_enable local m, s, o,kcp_enable
local shadowsocksr = "shadowsocksr" local shadowsocksr = "shadowsocksr"
local uci = luci.model.uci.cursor() local uci = luci.model.uci.cursor()
local fs = require "nixio.fs"
local sys = require "luci.sys"
local sid = arg[1] local sid = arg[1]
local uuid = luci.sys.exec("cat /proc/sys/kernel/random/uuid") local uuid = luci.sys.exec("cat /proc/sys/kernel/random/uuid")
local http = require "luci.http"
local function isKcptun(file) local function isKcptun(file)
if not nixio.fs.access(file, "rwx", "rx", "rx") then if not fs.access(file, "rwx", "rx", "rx") then
nixio.fs.chmod(file, 755) fs.chmod(file, 755)
end end
local str = luci.sys.exec(file .. " -v | awk '{printf $1}'")
local str = sys.exec(file .. " -v | awk '{printf $1}'")
return (str:lower() == "kcptun") return (str:lower() == "kcptun")
end end
local server_table = {} local server_table = {}
local encrypt_methods = { local encrypt_methods = {
"none", "none",
"table", "table",
"rc4", "rc4",
"rc4-md5-6", "rc4-md5-6",
"rc4-md5", "rc4-md5",
"aes-128-cfb", "aes-128-cfb",
"aes-192-cfb", "aes-192-cfb",
"aes-256-cfb", "aes-256-cfb",
"aes-128-ctr", "aes-128-ctr",
"aes-192-ctr", "aes-192-ctr",
"aes-256-ctr", "aes-256-ctr",
"bf-cfb", "bf-cfb",
"camellia-128-cfb", "camellia-128-cfb",
"camellia-192-cfb", "camellia-192-cfb",
"camellia-256-cfb", "camellia-256-cfb",
"cast5-cfb", "cast5-cfb",
"des-cfb", "des-cfb",
"idea-cfb", "idea-cfb",
"rc2-cfb", "rc2-cfb",
"seed-cfb", "seed-cfb",
"salsa20", "salsa20",
"chacha20", "chacha20",
"chacha20-ietf", "chacha20-ietf",
} }
local encrypt_methods_ss = { local encrypt_methods_ss = {
-- aead -- aead
"aes-128-gcm", "aes-128-gcm",
"aes-192-gcm", "aes-192-gcm",
"aes-256-gcm", "aes-256-gcm",
"chacha20-ietf-poly1305", "chacha20-ietf-poly1305",
"xchacha20-ietf-poly1305", "xchacha20-ietf-poly1305",
-- stream -- stream
"table", "table",
"rc4", "rc4",
"rc4-md5", "rc4-md5",
"aes-128-cfb", "aes-128-cfb",
"aes-192-cfb", "aes-192-cfb",
"aes-256-cfb", "aes-256-cfb",
"aes-128-ctr", "aes-128-ctr",
"aes-192-ctr", "aes-192-ctr",
"aes-256-ctr", "aes-256-ctr",
"bf-cfb", "bf-cfb",
"camellia-128-cfb", "camellia-128-cfb",
"camellia-192-cfb", "camellia-192-cfb",
"camellia-256-cfb", "camellia-256-cfb",
"salsa20", "salsa20",
"chacha20", "chacha20",
"chacha20-ietf", "chacha20-ietf",
} }
local protocol = { local protocol = {
"origin", "origin",
"verify_deflate", "verify_deflate",
"auth_sha1_v4", "auth_sha1_v4",
"auth_aes128_sha1", "auth_aes128_sha1",
"auth_aes128_md5", "auth_aes128_md5",
"auth_chain_a", "auth_chain_a",
"auth_chain_b", "auth_chain_b",
"auth_chain_c", "auth_chain_c",
"auth_chain_d", "auth_chain_d",
"auth_chain_e", "auth_chain_e",
"auth_chain_f", "auth_chain_f",
} }
obfs = { obfs = {
"plain", "plain",
"http_simple", "http_simple",
"http_post", "http_post",
"random_head", "random_head",
"tls1.2_ticket_auth", "tls1.2_ticket_auth",
} }
local securitys = { local securitys = {
"auto", "auto",
"none", "none",
"aes-128-gcm", "aes-128-gcm",
"chacha20-poly1305" "chacha20-poly1305"
} }
m = Map(shadowsocksr, translate("Edit ShadowSocksR Server")) m = Map(shadowsocksr, translate("Edit ShadowSocksR Server"))
m.redirect = luci.dispatcher.build_url("admin/services/shadowsocksr/servers") m.redirect = luci.dispatcher.build_url("admin/services/shadowsocksr/servers")
if m.uci:get(shadowsocksr, sid) ~= "servers" then if m.uci:get(shadowsocksr, sid) ~= "servers" then
@ -110,35 +113,35 @@ end
-- [[ Servers Setting ]]-- -- [[ Servers Setting ]]--
s = m:section(NamedSection, sid, "servers") s = m:section(NamedSection, sid, "servers")
s.anonymous = true s.anonymous = true
s.addremove = false s.addremove = false
o = s:option(DummyValue,"ssr_url","SS/SSR/V2RAY/TROJAN URL") o = s:option(DummyValue,"ssr_url","SS/SSR/V2RAY/TROJAN URL")
o.rawhtml = true o.rawhtml = true
o.template = "shadowsocksr/ssrurl" o.template = "shadowsocksr/ssrurl"
o.value =sid o.value =sid
o = s:option(ListValue, "type", translate("Server Node Type")) o = s:option(ListValue, "type", translate("Server Node Type"))
o:value("ssr", translate("ShadowsocksR")) o:value("ssr", translate("ShadowsocksR"))
if nixio.fs.access("/usr/bin/ss-redir") then if nixio.fs.access("/usr/bin/ss-redir") then
o:value("ss", translate("Shadowsocks New Version")) o:value("ss", translate("Shadowsocks New Version"))
end end
if nixio.fs.access("/usr/bin/v2ray/v2ray") or nixio.fs.access("/usr/bin/v2ray") then if nixio.fs.access("/usr/bin/v2ray/v2ray") or nixio.fs.access("/usr/bin/v2ray") then
o:value("v2ray", translate("V2Ray")) o:value("v2ray", translate("V2Ray"))
end end
if nixio.fs.access("/usr/sbin/trojan") then if nixio.fs.access("/usr/sbin/trojan") then
o:value("trojan", translate("Trojan")) o:value("trojan", translate("Trojan"))
end end
if nixio.fs.access("/usr/sbin/redsocks2") then if nixio.fs.access("/usr/sbin/redsocks2") then
o:value("socks5", translate("Socks5")) o:value("socks5", translate("Socks5"))
o:value("tun", translate("Network Tunnel")) o:value("tun", translate("Network Tunnel"))
end end
o.description = translate("Using incorrect encryption mothod may causes service fail to start") o.description = translate("Using incorrect encryption mothod may causes service fail to start")
o = s:option(Value, "alias", translate("Alias(optional)")) o = s:option(Value, "alias", translate("Alias(optional)"))
o = s:option(ListValue, "iface", translate("Network interface to use")) o = s:option(ListValue, "iface", translate("Network interface to use"))
for _, e in ipairs(luci.sys.net.devices()) do for _, e in ipairs(sys.net.devices()) do
if e ~= "lo" then o:value(e) end if e ~= "lo" then o:value(e) end
end end
o:depends("type", "tun") o:depends("type", "tun")
o.description = translate("Redirect traffic to this network interface") o.description = translate("Redirect traffic to this network interface")
@ -243,6 +246,7 @@ o.rmempty = true
o:depends("type", "v2ray") o:depends("type", "v2ray")
-- [[ TCP部分 ]]-- -- [[ TCP部分 ]]--
-- TCP伪装 -- TCP伪装
o = s:option(ListValue, "tcp_guise", translate("Camouflage Type")) o = s:option(ListValue, "tcp_guise", translate("Camouflage Type"))
o:depends("transport", "tcp") o:depends("transport", "tcp")
@ -261,6 +265,7 @@ o:depends("tcp_guise", "http")
o.rmempty = true o.rmempty = true
-- [[ WS部分 ]]-- -- [[ WS部分 ]]--
-- WS域名 -- WS域名
o = s:option(Value, "ws_host", translate("WebSocket Host")) o = s:option(Value, "ws_host", translate("WebSocket Host"))
o:depends("transport", "ws") o:depends("transport", "ws")
@ -272,6 +277,7 @@ o:depends("transport", "ws")
o.rmempty = true o.rmempty = true
-- [[ H2部分 ]]-- -- [[ H2部分 ]]--
-- H2域名 -- H2域名
o = s:option(Value, "h2_host", translate("HTTP/2 Host")) o = s:option(Value, "h2_host", translate("HTTP/2 Host"))
o:depends("transport", "h2") o:depends("transport", "h2")
@ -283,6 +289,7 @@ o:depends("transport", "h2")
o.rmempty = true o.rmempty = true
-- [[ QUIC部分 ]]-- -- [[ QUIC部分 ]]--
o = s:option(ListValue, "quic_security", translate("QUIC Security")) o = s:option(ListValue, "quic_security", translate("QUIC Security"))
o:depends("transport", "quic") o:depends("transport", "quic")
o.rmempty = true o.rmempty = true
@ -305,6 +312,7 @@ o:value("dtls", "DTLS 1.2")
o:value("wireguard", "WireGuard") o:value("wireguard", "WireGuard")
-- [[ mKCP部分 ]]-- -- [[ mKCP部分 ]]--
o = s:option(ListValue, "kcp_guise", translate("Camouflage Type")) o = s:option(ListValue, "kcp_guise", translate("Camouflage Type"))
o:depends("transport", "kcp") o:depends("transport", "kcp")
o:value("none", translate("None")) o:value("none", translate("None"))
@ -361,7 +369,6 @@ o.rmempty = true
o:depends("type", "v2ray") o:depends("type", "v2ray")
o:depends("type", "trojan") o:depends("type", "trojan")
o.default = "1" o.default = "1"
o.description = translate("If true, allowss insecure connection at TLS client, e.g., TLS server uses unverifiable certificates.")
-- [[ TLS ]]-- -- [[ TLS ]]--
o = s:option(Flag, "tls", translate("TLS")) o = s:option(Flag, "tls", translate("TLS"))
@ -402,31 +409,31 @@ o:depends("certificate", 1)
cert_dir = "/etc/ssl/private/" cert_dir = "/etc/ssl/private/"
local path local path
luci.http.setfilehandler( http.setfilehandler(
function(meta, chunk, eof) function(meta, chunk, eof)
if not fd then if not fd then
if (not meta) or (not meta.name) or (not meta.file) then return end if (not meta) or (not meta.name) or (not meta.file) then return end
fd = nixio.open(cert_dir .. meta.file, "w") fd = nixio.open(cert_dir .. meta.file, "w")
if not fd then if not fd then
path = translate("Create upload file error.") path = translate("Create upload file error.")
return return
end end
end end
if chunk and fd then if chunk and fd then
fd:write(chunk) fd:write(chunk)
end end
if eof and fd then if eof and fd then
fd:close() fd:close()
fd = nil fd = nil
path = '/etc/ssl/private/' .. meta.file .. '' path = '/etc/ssl/private/' .. meta.file .. ''
end end
end end
) )
if luci.http.formvalue("upload") then if luci.http.formvalue("upload") then
local f = luci.http.formvalue("ulfile") local f = luci.http.formvalue("ulfile")
if #f <= 0 then if #f <= 0 then
path = translate("No specify upload file.") path = translate("No specify upload file.")
end end
end end
o = s:option(Value, "certpath", translate("Current Certificate Path")) o = s:option(Value, "certpath", translate("Current Certificate Path"))
@ -452,36 +459,42 @@ o.default = 1234
o.rmempty = false o.rmempty = false
if nixio.fs.access("/usr/bin/kcptun-client") then if nixio.fs.access("/usr/bin/kcptun-client") then
kcp_enable = s:option(Flag, "kcp_enable", translate("KcpTun Enable"), translate("bin:/usr/bin/kcptun-client"))
kcp_enable.rmempty = true kcp_enable = s:option(Flag, "kcp_enable", translate("KcpTun Enable"), translate("bin:/usr/bin/kcptun-client"))
kcp_enable.default = "0" kcp_enable.rmempty = true
kcp_enable:depends("type", "ssr") kcp_enable.default = "0"
kcp_enable:depends("type", "ss") kcp_enable:depends("type", "ssr")
o = s:option(Value, "kcp_port", translate("KcpTun Port")) kcp_enable:depends("type", "ss")
o.datatype = "port"
o.default = 4000 o = s:option(Value, "kcp_port", translate("KcpTun Port"))
function o.validate(self, value, section) o.datatype = "port"
o.default = 4000
function o.validate(self, value, section)
local kcp_file="/usr/bin/kcptun-client" local kcp_file="/usr/bin/kcptun-client"
local enable = kcp_enable:formvalue(section) or kcp_enable.disabled local enable = kcp_enable:formvalue(section) or kcp_enable.disabled
if enable == kcp_enable.enabled then if enable == kcp_enable.enabled then
if not nixio.fs.access(kcp_file) then if not fs.access(kcp_file) then
return nil, translate("Haven't a Kcptun executable file") return nil, translate("Haven't a Kcptun executable file")
elseif not isKcptun(kcp_file) then elseif not isKcptun(kcp_file) then
return nil, translate("Not a Kcptun executable file") return nil, translate("Not a Kcptun executable file")
end
end
return value
end end
o:depends("type", "ssr") end
o:depends("type", "ss")
o = s:option(Value, "kcp_password", translate("KcpTun Password")) return value
o.password = true end
o:depends("type", "ssr") o:depends("type", "ssr")
o:depends("type", "ss") o:depends("type", "ss")
o = s:option(Value, "kcp_param", translate("KcpTun Param"))
o.default = "--nocomp" o = s:option(Value, "kcp_password", translate("KcpTun Password"))
o:depends("type", "ssr") o.password = true
o:depends("type", "ss") o:depends("type", "ssr")
o:depends("type", "ss")
o = s:option(Value, "kcp_param", translate("KcpTun Param"))
o.default = "--nocomp"
o:depends("type", "ssr")
o:depends("type", "ss")
end end
return m return m

View File

@ -1,13 +1,16 @@
-- Copyright (C) 2017 yushi studio <ywb94@qq.com> github.com/ywb94 -- Copyright (C) 2017 yushi studio <ywb94@qq.com> github.com/ywb94
-- Copyright (C) 2018 lean <coolsnowwolf@gmail.com> github.com/coolsnowwolf -- Copyright (C) 2018 lean <coolsnowwolf@gmail.com> github.com/coolsnowwolf
-- Licensed to the public under the GNU General Public License v3. -- Licensed to the public under the GNU General Public License v3.
require "luci.model.uci"
local m, s, sec, o, kcp_enable local m, s, sec, o, kcp_enable
local shadowsocksr = "shadowsocksr" local shadowsocksr = "shadowsocksr"
local uci = luci.model.uci.cursor() local uci = luci.model.uci.cursor()
local sys = require "luci.sys"
m = Map(shadowsocksr, translate("ShadowSocksR Plus+ Settings")) m = Map(shadowsocksr, translate("ShadowSocksR Plus+ Settings"))
m:section(SimpleSection).template = "shadowsocksr/status"
m:section(SimpleSection).template = "shadowsocksr/status"
local server_table = {} local server_table = {}
uci:foreach(shadowsocksr, "servers", function(s) uci:foreach(shadowsocksr, "servers", function(s)

View File

@ -1,6 +1,5 @@
require "luci.ip"
require "nixio.fs"
local m, s, o local m, s, o
local NXFS = require "nixio.fs"
m = Map("shadowsocksr", translate("IP black-and-white list")) m = Map("shadowsocksr", translate("IP black-and-white list"))
@ -28,9 +27,9 @@ o.rmempty = false
o = s:taboption("lan_ac", DynamicList, "lan_ac_ips", translate("LAN Host List")) o = s:taboption("lan_ac", DynamicList, "lan_ac_ips", translate("LAN Host List"))
o.datatype = "ipaddr" o.datatype = "ipaddr"
luci.ip.neighbors({ family = 4 }, function(entry) luci.ip.neighbors({ family = 4 }, function(entry)
if entry.reachable then if entry.reachable then
o:value(entry.dest:string()) o:value(entry.dest:string())
end end
end) end)
o:depends("lan_ac_mode", "w") o:depends("lan_ac_mode", "w")
o:depends("lan_ac_mode", "b") o:depends("lan_ac_mode", "b")
@ -38,25 +37,25 @@ o:depends("lan_ac_mode", "b")
o = s:taboption("lan_ac", DynamicList, "lan_bp_ips", translate("LAN Bypassed Host List")) o = s:taboption("lan_ac", DynamicList, "lan_bp_ips", translate("LAN Bypassed Host List"))
o.datatype = "ipaddr" o.datatype = "ipaddr"
luci.ip.neighbors({ family = 4 }, function(entry) luci.ip.neighbors({ family = 4 }, function(entry)
if entry.reachable then if entry.reachable then
o:value(entry.dest:string()) o:value(entry.dest:string())
end end
end) end)
o = s:taboption("lan_ac", DynamicList, "lan_fp_ips", translate("LAN Force Proxy Host List")) o = s:taboption("lan_ac", DynamicList, "lan_fp_ips", translate("LAN Force Proxy Host List"))
o.datatype = "ipaddr" o.datatype = "ipaddr"
luci.ip.neighbors({ family = 4 }, function(entry) luci.ip.neighbors({ family = 4 }, function(entry)
if entry.reachable then if entry.reachable then
o:value(entry.dest:string()) o:value(entry.dest:string())
end end
end) end)
o = s:taboption("lan_ac", DynamicList, "lan_gm_ips", translate("Game Mode Host List")) o = s:taboption("lan_ac", DynamicList, "lan_gm_ips", translate("Game Mode Host List"))
o.datatype = "ipaddr" o.datatype = "ipaddr"
luci.ip.neighbors({ family = 4 }, function(entry) luci.ip.neighbors({ family = 4 }, function(entry)
if entry.reachable then if entry.reachable then
o:value(entry.dest:string()) o:value(entry.dest:string())
end end
end) end)
-- Part of Self -- Part of Self
@ -67,72 +66,73 @@ end)
-- o:value("2", translatef("Forwarded Proxy")) -- o:value("2", translatef("Forwarded Proxy"))
-- o.rmempty = false -- o.rmempty = false
s:tab("esc", translate("Bypass Domain List")) s:tab("esc", translate("Bypass Domain List"))
local escconf = "/etc/ssr/white.list" local escconf = "/etc/config/white.list"
o = s:taboption("esc", TextValue, "escconf") o = s:taboption("esc", TextValue, "escconf")
o.rows = 13 o.rows = 13
o.wrap = "off" o.wrap = "off"
o.rmempty = true o.rmempty = true
o.cfgvalue = function(self, section) o.cfgvalue = function(self, section)
return nixio.fs.readfile(escconf) or "" return NXFS.readfile(escconf) or ""
end end
o.write = function(self, section, value) o.write = function(self, section, value)
nixio.fs.writefile(escconf, value:gsub("\r\n", "\n")) NXFS.writefile(escconf, value:gsub("\r\n", "\n"))
end end
o.remove = function(self, section, value) o.remove = function(self, section, value)
nixio.fs.writefile(escconf, "") NXFS.writefile(escconf, "")
end end
s:tab("block", translate("Black Domain List"))
local blockconf = "/etc/ssr/black.list" s:tab("block", translate("Black Domain List"))
local blockconf = "/etc/config/black.list"
o = s:taboption("block", TextValue, "blockconf") o = s:taboption("block", TextValue, "blockconf")
o.rows = 13 o.rows = 13
o.wrap = "off" o.wrap = "off"
o.rmempty = true o.rmempty = true
o.cfgvalue = function(self, section) o.cfgvalue = function(self, section)
return nixio.fs.readfile(blockconf) or " " return NXFS.readfile(blockconf) or " "
end end
o.write = function(self, section, value) o.write = function(self, section, value)
nixio.fs.writefile(blockconf, value:gsub("\r\n", "\n")) NXFS.writefile(blockconf, value:gsub("\r\n", "\n"))
end end
o.remove = function(self, section, value) o.remove = function(self, section, value)
nixio.fs.writefile(blockconf, "") NXFS.writefile(blockconf, "")
end end
s:tab("netflix", translate("Netflix Domain List")) s:tab("netflix", translate("Netflix Domain List"))
local netflixconf = "/etc/ssr/netflix.list" local netflixconf = "/etc/config/netflix.list"
o = s:taboption("netflix", TextValue, "netflixconf") o = s:taboption("netflix", TextValue, "netflixconf")
o.rows = 13 o.rows = 13
o.wrap = "off" o.wrap = "off"
o.rmempty = true o.rmempty = true
o.cfgvalue = function(self, section) o.cfgvalue = function(self, section)
return nixio.fs.readfile(netflixconf) or " " return NXFS.readfile(netflixconf) or " "
end end
o.write = function(self, section, value) o.write = function(self, section, value)
nixio.fs.writefile(netflixconf, value:gsub("\r\n", "\n")) NXFS.writefile(netflixconf, value:gsub("\r\n", "\n"))
end end
o.remove = function(self, section, value) o.remove = function(self, section, value)
nixio.fs.writefile(netflixconf, "") NXFS.writefile(netflixconf, "")
end end
s:tab("netflixip", translate("Netflix IP List")) s:tab("netflixip", translate("Netflix IP List"))
local netflixipconf = "/etc/ssr/netflixip.list" local netflixipconf = "/etc/config/netflixip.list"
o = s:taboption("netflixip", TextValue, "netflixipconf") o = s:taboption("netflixip", TextValue, "netflixipconf")
o.rows = 13 o.rows = 13
o.wrap = "off" o.wrap = "off"
o.rmempty = true o.rmempty = true
o.cfgvalue = function(self, section) o.cfgvalue = function(self, section)
return nixio.fs.readfile(netflixipconf) or " " return NXFS.readfile(netflixipconf) or " "
end end
o.write = function(self, section, value) o.write = function(self, section, value)
nixio.fs.writefile(netflixipconf, value:gsub("\r\n", "\n")) NXFS.writefile(netflixipconf, value:gsub("\r\n", "\n"))
end end
o.remove = function(self, section, value) o.remove = function(self, section, value)
nixio.fs.writefile(netflixipconf, "") NXFS.writefile(netflixipconf, "")
end end
return m return m

View File

@ -1,20 +1,20 @@
require "luci.util" local fs = require "nixio.fs"
require "nixio.fs"
f = SimpleForm("logview") f = SimpleForm("logview")
f.reset = false
f.submit = false
t = f:field(TextValue, "conf") t = f:field(TextValue, "conf")
t.rmempty = true t.rmempty = true
t.rows = 20 t.rows = 20
function t.cfgvalue() function t.cfgvalue()
if nixio.fs.access("/tmp/ssrplus.log") then if fs.access("/tmp/ssrplus.log") then
local logs = luci.util.execi("cat /tmp/ssrplus.log") local logs = luci.util.execi("cat /tmp/ssrplus.log")
local s = "" local s = ""
for line in logs do for line in logs do
s = line .. "\n" .. s s = line .. "\n" .. s
end end
return s return s
end end
end end
t.readonly="readonly" t.readonly="readonly"
return f
return f

View File

@ -1,44 +1,43 @@
-- Copyright (C) 2017 yushi studio <ywb94@qq.com> -- Copyright (C) 2017 yushi studio <ywb94@qq.com>
-- Licensed to the public under the GNU General Public License v3. -- Licensed to the public under the GNU General Public License v3.
require "luci.http"
require "luci.dispatcher"
local m, s, o local m, s, o
local shadowsocksr = "shadowsocksr" local shadowsocksr = "shadowsocksr"
local sid = arg[1] local sid = arg[1]
local encrypt_methods = { local encrypt_methods = {
"rc4-md5", "rc4-md5",
"rc4-md5-6", "rc4-md5-6",
"rc4", "rc4",
"table", "table",
"aes-128-cfb", "aes-128-cfb",
"aes-192-cfb", "aes-192-cfb",
"aes-256-cfb", "aes-256-cfb",
"aes-128-ctr", "aes-128-ctr",
"aes-192-ctr", "aes-192-ctr",
"aes-256-ctr", "aes-256-ctr",
"bf-cfb", "bf-cfb",
"camellia-128-cfb", "camellia-128-cfb",
"camellia-192-cfb", "camellia-192-cfb",
"camellia-256-cfb", "camellia-256-cfb",
"cast5-cfb", "cast5-cfb",
"des-cfb", "des-cfb",
"idea-cfb", "idea-cfb",
"rc2-cfb", "rc2-cfb",
"seed-cfb", "seed-cfb",
"salsa20", "salsa20",
"chacha20", "chacha20",
"chacha20-ietf", "chacha20-ietf",
} }
local protocol = { local protocol = {
"origin", "origin",
} }
obfs = { obfs = {
"plain", "plain",
"http_simple", "http_simple",
"http_post", "http_post",
} }
m = Map(shadowsocksr, translate("Edit ShadowSocksR Server")) m = Map(shadowsocksr, translate("Edit ShadowSocksR Server"))
@ -49,10 +48,13 @@ if m.uci:get(shadowsocksr, sid) ~= "server_config" then
return return
end end
-- [[ Server Setting ]]-- -- [[ Server Setting ]]--
s = m:section(NamedSection, sid, "server_config") s = m:section(NamedSection, sid, "server_config")
s.anonymous = true s.anonymous = true
s.addremove = false s.addremove = false
o = s:option(Flag, "enable", translate("Enable")) o = s:option(Flag, "enable", translate("Enable"))
o.default = 1 o.default = 1

View File

@ -1,55 +1,56 @@
-- Copyright (C) 2017 yushi studio <ywb94@qq.com> -- Copyright (C) 2017 yushi studio <ywb94@qq.com>
-- Licensed to the public under the GNU General Public License v3. -- Licensed to the public under the GNU General Public License v3.
require "luci.http"
require "luci.dispatcher"
local m, sec, o local m, sec, o
local shadowsocksr = "shadowsocksr" local shadowsocksr = "shadowsocksr"
local uci = luci.model.uci.cursor()
m = Map(shadowsocksr)
local encrypt_methods = { local encrypt_methods = {
"table", "table",
"rc4", "rc4",
"rc4-md5", "rc4-md5",
"rc4-md5-6", "rc4-md5-6",
"aes-128-cfb", "aes-128-cfb",
"aes-192-cfb", "aes-192-cfb",
"aes-256-cfb", "aes-256-cfb",
"aes-128-ctr", "aes-128-ctr",
"aes-192-ctr", "aes-192-ctr",
"aes-256-ctr", "aes-256-ctr",
"bf-cfb", "bf-cfb",
"camellia-128-cfb", "camellia-128-cfb",
"camellia-192-cfb", "camellia-192-cfb",
"camellia-256-cfb", "camellia-256-cfb",
"cast5-cfb", "cast5-cfb",
"des-cfb", "des-cfb",
"idea-cfb", "idea-cfb",
"rc2-cfb", "rc2-cfb",
"seed-cfb", "seed-cfb",
"salsa20", "salsa20",
"chacha20", "chacha20",
"chacha20-ietf", "chacha20-ietf",
} }
local protocol = { local protocol = {
"origin", "origin",
"verify_deflate", "verify_deflate",
"auth_sha1_v4", "auth_sha1_v4",
"auth_aes128_sha1", "auth_aes128_sha1",
"auth_aes128_md5", "auth_aes128_md5",
"auth_chain_a", "auth_chain_a",
} }
obfs = { obfs = {
"plain", "plain",
"http_simple", "http_simple",
"http_post", "http_post",
"random_head", "random_head",
"tls1.2_ticket_auth", "tls1.2_ticket_auth",
"tls1.2_ticket_fastauth", "tls1.2_ticket_fastauth",
} }
m = Map(shadowsocksr)
-- [[ Global Setting ]]-- -- [[ Global Setting ]]--
sec = m:section(TypedSection, "server_global", translate("Global Setting")) sec = m:section(TypedSection, "server_global", translate("Global Setting"))
sec.anonymous = true sec.anonymous = true

View File

@ -1,19 +1,23 @@
-- Licensed to the public under the GNU General Public License v3. -- Licensed to the public under the GNU General Public License v3.
require "luci.http"
require "luci.dispatcher"
require "luci.model.uci"
local m, s, o local m, s, o
local shadowsocksr = "shadowsocksr" local shadowsocksr = "shadowsocksr"
local uci = luci.model.uci.cursor() local uci = luci.model.uci.cursor()
local server_count = 0 local server_count = 0
uci:foreach("shadowsocksr", "servers", function(s) uci:foreach("shadowsocksr", "servers", function(s)
server_count = server_count + 1 server_count = server_count + 1
end) end)
m = Map(shadowsocksr, translate("Servers subscription and manage")) local fs = require "nixio.fs"
local sys = require "luci.sys"
local ucic = luci.model.uci.cursor()
m = Map(shadowsocksr, translate("Servers subscription and manage"))
-- Server Subscribe -- Server Subscribe
s = m:section(TypedSection, "server_subscribe") s = m:section(TypedSection, "server_subscribe")
s.anonymous = true s.anonymous = true
@ -21,9 +25,10 @@ o = s:option(Flag, "auto_update", translate("Auto Update"))
o.rmempty = false o.rmempty = false
o.description = translate("Auto Update Server subscription, GFW list and CHN route") o.description = translate("Auto Update Server subscription, GFW list and CHN route")
o = s:option(ListValue, "auto_update_time", translate("Update time (every day)")) o = s:option(ListValue, "auto_update_time", translate("Update time (every day)"))
for t = 0,23 do for t = 0,23 do
o:value(t, t..":00") o:value(t, t..":00")
end end
o.default=2 o.default=2
o.rmempty = false o.rmempty = false
@ -39,7 +44,7 @@ o = s:option(Button,"update_Sub",translate("Update Subscribe List"))
o.inputstyle = "reload" o.inputstyle = "reload"
o.description = translate("Update subscribe url list first") o.description = translate("Update subscribe url list first")
o.write = function() o.write = function()
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "servers")) luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "servers"))
end end
o = s:option(Flag, "switch", translate("Subscribe Default Auto-Switch")) o = s:option(Flag, "switch", translate("Subscribe Default Auto-Switch"))
@ -51,26 +56,27 @@ o = s:option(Flag, "proxy", translate("Through proxy update"))
o.rmempty = false o.rmempty = false
o.description = translate("Through proxy update list, Not Recommended ") o.description = translate("Through proxy update list, Not Recommended ")
o = s:option(Button,"subscribe", translate("Update All Subscribe Severs")) o = s:option(Button,"subscribe", translate("Update All Subscribe Severs"))
o.rawhtml = true o.rawhtml = true
o.template = "shadowsocksr/subscribe" o.template = "shadowsocksr/subscribe"
o = s:option(Button,"delete",translate("Delete All Subscribe Severs")) o = s:option(Button,"delete",translate("Delete All Subscribe Severs"))
o.inputstyle = "reset" o.inputstyle = "reset"
o.description = string.format(translate("Server Count") .. ": %d", server_count) o.description = string.format(translate("Server Count") .. ": %d", server_count)
o.write = function() o.write = function()
uci:delete_all("shadowsocksr", "servers", function(s) uci:delete_all("shadowsocksr", "servers", function(s)
if s.hashkey or s.isSubscribe then if s.hashkey or s.isSubscribe then
return true return true
else else
return false return false
end end
end) end)
uci:save("shadowsocksr") uci:save("shadowsocksr")
uci:commit("shadowsocksr") uci:commit("shadowsocksr")
luci.sys.exec("/etc/init.d/shadowsocksr restart") luci.sys.exec("/etc/init.d/shadowsocksr restart")
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "servers")) luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "servers"))
return return
end end
-- [[ Servers Manage ]]-- -- [[ Servers Manage ]]--
@ -79,12 +85,12 @@ s.anonymous = true
s.addremove = true s.addremove = true
s.template = "cbi/tblsection" s.template = "cbi/tblsection"
s.sortable = true s.sortable = true
s.extedit = luci.dispatcher.build_url("admin", "services", "shadowsocksr", "servers", "%s") s.extedit = luci.dispatcher.build_url("admin/services/shadowsocksr/servers/%s")
function s.create(...) function s.create(...)
local sid = TypedSection.create(...) local sid = TypedSection.create(...)
if sid then if sid then
luci.http.redirect(s.extedit % sid) luci.http.redirect(s.extedit % sid)
return return
end end
end end
@ -111,14 +117,15 @@ o = s:option(DummyValue, "server", translate("Ping Latency"))
o.template="shadowsocksr/ping" o.template="shadowsocksr/ping"
o.width="10%" o.width="10%"
node = s:option(Button,"apply_node",translate("Apply")) node = s:option(Button,"apply_node",translate("Apply"))
node.inputstyle = "apply" node.inputstyle = "apply"
node.write = function(self, section) node.write = function(self, section)
uci:set("shadowsocksr", '@global[0]', 'global_server', section) ucic:set("shadowsocksr", '@global[0]', 'global_server', section)
uci:save("shadowsocksr") ucic:save("shadowsocksr")
uci:commit("shadowsocksr") ucic:commit("shadowsocksr")
luci.sys.exec("/etc/init.d/shadowsocksr restart") luci.sys.exec("/etc/init.d/shadowsocksr restart")
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "client")) luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "client"))
end end
o = s:option(Flag, "switch_enable", translate("Auto Switch")) o = s:option(Flag, "switch_enable", translate("Auto Switch"))

View File

@ -1,8 +1,6 @@
-- Copyright (C) 2017 yushi studio <ywb94@qq.com> -- Copyright (C) 2017 yushi studio <ywb94@qq.com>
-- Licensed to the public under the GNU General Public License v3. -- Licensed to the public under the GNU General Public License v3.
require "nixio.fs"
require "luci.sys"
require "luci.model.uci"
local m, s, o local m, s, o
local redir_run=0 local redir_run=0
local reudp_run=0 local reudp_run=0
@ -22,69 +20,71 @@ font_off = [[</font>]]
bold_on = [[<strong>]] bold_on = [[<strong>]]
bold_off = [[</strong>]] bold_off = [[</strong>]]
local fs = require "nixio.fs"
local sys = require "luci.sys"
local kcptun_version=translate("Unknown") local kcptun_version=translate("Unknown")
local kcp_file="/usr/bin/kcptun-client" local kcp_file="/usr/bin/kcptun-client"
if not nixio.fs.access(kcp_file) then if not fs.access(kcp_file) then
kcptun_version=translate("Not exist") kcptun_version=translate("Not exist")
else else
if not nixio.fs.access(kcp_file, "rwx", "rx", "rx") then if not fs.access(kcp_file, "rwx", "rx", "rx") then
nixio.fs.chmod(kcp_file, 755) fs.chmod(kcp_file, 755)
end end
kcptun_version=luci.sys.exec(kcp_file .. " -v | awk '{printf $3}'") kcptun_version=sys.exec(kcp_file .. " -v | awk '{printf $3}'")
if not kcptun_version or kcptun_version == "" then if not kcptun_version or kcptun_version == "" then
kcptun_version = translate("Unknown") kcptun_version = translate("Unknown")
end end
end end
if nixio.fs.access("/etc/dnsmasq.ssr/gfw_list.conf") then if nixio.fs.access("/etc/dnsmasq.ssr/gfw_list.conf") then
gfw_count = tonumber(luci.sys.exec("cat /etc/dnsmasq.ssr/gfw_list.conf | wc -l"))/2 gfw_count = tonumber(sys.exec("cat /etc/dnsmasq.ssr/gfw_list.conf | wc -l"))/2
end end
if nixio.fs.access("/etc/dnsmasq.ssr/ad.conf") then if nixio.fs.access("/etc/dnsmasq.ssr/ad.conf") then
ad_count = tonumber(luci.sys.exec("cat /etc/dnsmasq.ssr/ad.conf | wc -l")) ad_count = tonumber(sys.exec("cat /etc/dnsmasq.ssr/ad.conf | wc -l"))
end end
if nixio.fs.access("/etc/ssr/china_ssr.txt") then if nixio.fs.access("/etc/china_ssr.txt") then
ip_count = tonumber(luci.sys.exec("cat /etc/ssr/china_ssr.txt | wc -l")) ip_count = tonumber(sys.exec("cat /etc/china_ssr.txt | wc -l"))
end end
if nixio.fs.access("/etc/ssr/netflixip.list") then if nixio.fs.access("/etc/config/netflixip.list") then
nfip_count = tonumber(luci.sys.exec("cat /etc/ssr/netflixip.list | wc -l")) nfip_count = tonumber(sys.exec("cat /etc/config/netflixip.list | wc -l"))
end end
local icount=luci.sys.exec("busybox ps -w | grep ssr-reudp |grep -v grep| wc -l") local icount=sys.exec("busybox ps -w | grep ssr-reudp |grep -v grep| wc -l")
if tonumber(icount)>0 then if tonumber(icount)>0 then
reudp_run=1 reudp_run=1
else else
icount=luci.sys.exec("busybox ps -w | grep ssr-retcp |grep \"\\-u\"|grep -v grep| wc -l") icount=sys.exec("busybox ps -w | grep ssr-retcp |grep \"\\-u\"|grep -v grep| wc -l")
if tonumber(icount)>0 then if tonumber(icount)>0 then
reudp_run=1 reudp_run=1
end end
end end
if luci.sys.call("busybox ps -w | grep ssr-retcp | grep -v grep >/dev/null") == 0 then if luci.sys.call("busybox ps -w | grep ssr-retcp | grep -v grep >/dev/null") == 0 then
redir_run=1 redir_run=1
end end
if luci.sys.call("busybox ps -w | grep ssr-local | grep -v ssr-socksdns |grep -v grep >/dev/null") == 0 then if luci.sys.call("busybox ps -w | grep ssr-local | grep -v ssr-socksdns |grep -v grep >/dev/null") == 0 then
sock5_run=1 sock5_run=1
end end
if luci.sys.call("pidof kcptun-client >/dev/null") == 0 then if luci.sys.call("pidof kcptun-client >/dev/null") == 0 then
kcptun_run=1 kcptun_run=1
end end
if luci.sys.call("busybox ps -w | grep ssr-server | grep -v grep >/dev/null") == 0 then if luci.sys.call("busybox ps -w | grep ssr-server | grep -v grep >/dev/null") == 0 then
server_run=1 server_run=1
end end
-- if luci.sys.call("busybox ps -w | grep ssr-tunnel |grep -v grep >/dev/null") == 0 then if luci.sys.call("busybox ps -w | grep ssr-tunnel |grep -v grep >/dev/null") == 0 then
-- tunnel_run=1 tunnel_run=1
-- end end
if luci.sys.call("pidof pdnsd >/dev/null") == 0 or (luci.sys.call("busybox ps -w | grep ssr-dns |grep -v grep >/dev/null") == 0 and luci.sys.call("pidof dns2socks >/dev/null") == 0)then if luci.sys.call("pidof pdnsd >/dev/null") == 0 or (luci.sys.call("busybox ps -w | grep ssr-dns |grep -v grep >/dev/null") == 0 and luci.sys.call("pidof dns2socks >/dev/null") == 0)then
pdnsd_run=1 pdnsd_run=1
end end
m = SimpleForm("Version") m = SimpleForm("Version")
@ -94,56 +94,56 @@ m.submit = false
s=m:field(DummyValue,"redir_run",translate("Global Client")) s=m:field(DummyValue,"redir_run",translate("Global Client"))
s.rawhtml = true s.rawhtml = true
if redir_run == 1 then if redir_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else else
s.value = translate("Not Running") s.value = translate("Not Running")
end end
s=m:field(DummyValue,"reudp_run",translate("Game Mode UDP Relay")) s=m:field(DummyValue,"reudp_run",translate("Game Mode UDP Relay"))
s.rawhtml = true s.rawhtml = true
if reudp_run == 1 then if reudp_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else else
s.value = translate("Not Running") s.value = translate("Not Running")
end end
if uci:get_first(shadowsocksr, 'global', 'pdnsd_enable', '0') ~= '0' then if uci:get_first(shadowsocksr, 'global', 'pdnsd_enable', '0') ~= '0' then
s=m:field(DummyValue,"pdnsd_run",translate("DNS Anti-pollution")) s=m:field(DummyValue,"pdnsd_run",translate("DNS Anti-pollution"))
s.rawhtml = true s.rawhtml = true
if pdnsd_run == 1 then if pdnsd_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else else
s.value = translate("Not Running") s.value = translate("Not Running")
end end
end end
s=m:field(DummyValue,"sock5_run",translate("Global SOCKS5 Proxy Server")) s=m:field(DummyValue,"sock5_run",translate("Global SOCKS5 Proxy Server"))
s.rawhtml = true s.rawhtml = true
if sock5_run == 1 then if sock5_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else else
s.value = translate("Not Running") s.value = translate("Not Running")
end end
s=m:field(DummyValue,"server_run",translate("Local Servers")) s=m:field(DummyValue,"server_run",translate("Local Servers"))
s.rawhtml = true s.rawhtml = true
if server_run == 1 then if server_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else else
s.value = translate("Not Running") s.value = translate("Not Running")
end end
if nixio.fs.access("/usr/bin/kcptun-client") then if nixio.fs.access("/usr/bin/kcptun-client") then
s=m:field(DummyValue,"kcp_version",translate("KcpTun Version")) s=m:field(DummyValue,"kcp_version",translate("KcpTun Version"))
s.rawhtml = true s.rawhtml = true
s.value =kcptun_version s.value =kcptun_version
s=m:field(DummyValue,"kcptun_run",translate("KcpTun")) s=m:field(DummyValue,"kcptun_run",translate("KcpTun"))
s.rawhtml = true s.rawhtml = true
if kcptun_run == 1 then if kcptun_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else else
s.value = translate("Not Running") s.value = translate("Not Running")
end end
end end
s=m:field(DummyValue,"google",translate("Google Connectivity")) s=m:field(DummyValue,"google",translate("Google Connectivity"))
@ -170,10 +170,10 @@ s.template = "shadowsocksr/refresh"
s.value = nfip_count .. " " .. translate("Records") s.value = nfip_count .. " " .. translate("Records")
if uci:get_first(shadowsocksr, 'global', 'adblock', '0') == '1' then if uci:get_first(shadowsocksr, 'global', 'adblock', '0') == '1' then
s=m:field(DummyValue,"ad_data",translate("Advertising Data")) s=m:field(DummyValue,"ad_data",translate("Advertising Data"))
s.rawhtml = true s.rawhtml = true
s.template = "shadowsocksr/refresh" s.template = "shadowsocksr/refresh"
s.value = ad_count .. " " .. translate("Records") s.value = ad_count .. " " .. translate("Records")
end end
s=m:field(DummyValue,"check_port",translate("Check Server Port")) s=m:field(DummyValue,"check_port",translate("Check Server Port"))

View File

@ -1,4 +1,4 @@
<%+cbi/valueheader%> <%+cbi/valueheader%>
<input class="cbi-input-file" style="width: 400px" type="file" id="ulfile" name="ulfile" /> <input class="cbi-input-file" style="width: 400px" type="file" id="ulfile" name="ulfile" />
<input type="submit" class="cbi-button cbi-input-apply" name="upload" value="<%:Upload%>" /> <input type="submit" class="cbi-button cbi-input-apply" name="upload" value="<%:Upload%>" />
<%+cbi/valuefooter%> <%+cbi/valuefooter%>

View File

@ -1,5 +1,7 @@
<%+cbi/valueheader%> <%+cbi/valueheader%>
<script type="text/javascript">//<![CDATA[ <script type="text/javascript">//<![CDATA[
function check_port(btn) function check_port(btn)
{ {
btn.disabled = true; btn.disabled = true;
@ -13,14 +15,22 @@
{ {
s.innerHTML =rv.ret; s.innerHTML =rv.ret;
} }
btn.disabled = false; btn.disabled = false;
btn.value = '<%:Check Server%>'; btn.value = '<%:Check Server%>';
} }
); );
return false; return false;
} }
//]]></script> //]]></script>
<input type="button" class="cbi-button cbi-button-apply" value="<%:Check Server%>" onclick="return check_port(this)" /> <input type="button" class="cbi-button cbi-button-apply" value="<%:Check Server%>" onclick="return check_port(this)" />
<span id="<%=self.option%>-status"><em><%=self.value%></em></span> <span id="<%=self.option%>-status"><em><%=self.value%></em></span>
<%+cbi/valuefooter%> <%+cbi/valuefooter%>

View File

@ -81,39 +81,47 @@ local dsp = require "luci.dispatcher"
return false; return false;
} }
// set tr draggable // set tr draggable
function enableDragForTable(table_selecter, store) { function enableDragForTable(table_selecter, store) {
var trs = document.querySelectorAll(table_selecter + " tr"); var trs = document.querySelectorAll(table_selecter + " tr");
if (!trs || trs.length.length < 3) { if (!trs || trs.length.length < 3) {
return; return;
} }
function ondragstart(ev) { function ondragstart(ev) {
ev.dataTransfer.setData("Text", ev.target.id); ev.dataTransfer.setData("Text", ev.target.id);
} }
function ondrop(ev) { function ondrop(ev) {
var from = ev.dataTransfer.getData("Text"); var from = ev.dataTransfer.getData("Text");
cbi_row_drop(from, this.id, store); cbi_row_drop(from, this.id, store);
} }
function ondragover(ev) { function ondragover(ev) {
ev.preventDefault(); ev.preventDefault();
ev.dataTransfer.dropEffect = "move"; ev.dataTransfer.dropEffect = "move";
} }
function moveToTop(id) { function moveToTop(id) {
var top = document.querySelectorAll(table_selecter + " tr")[2]; var top = document.querySelectorAll(table_selecter + " tr")[2];
cbi_row_drop(id, top.id, store); cbi_row_drop(id, top.id, store);
} }
function moveToBottom(id) { function moveToBottom(id) {
console.log('moveToBottom:', id); console.log('moveToBottom:', id);
var trList = document.querySelectorAll(table_selecter + " tr"); var trList = document.querySelectorAll(table_selecter + " tr");
var bottom = trList[trList.length - 1]; var bottom = trList[trList.length - 1];
cbi_row_drop(id, bottom.id, store, true); cbi_row_drop(id, bottom.id, store, true);
} }
for (let index = 2; index < trs.length; index++) { for (let index = 2; index < trs.length; index++) {
const el = trs[index]; const el = trs[index];
el.setAttribute("draggable", true); el.setAttribute("draggable", true);
el.ondragstart = ondragstart; el.ondragstart = ondragstart;
el.ondrop = ondrop; el.ondrop = ondrop;
el.ondragover = ondragover; el.ondragover = ondragover;
// reset the behaviors of the btns // reset the behaviors of the btns
var upBtns = el.querySelectorAll(".cbi-button.cbi-button-up"); var upBtns = el.querySelectorAll(".cbi-button.cbi-button-up");
if (upBtns && upBtns.length > 0) { if (upBtns && upBtns.length > 0) {
@ -123,6 +131,7 @@ local dsp = require "luci.dispatcher"
}; };
}); });
} }
var downBtns = el.querySelectorAll(".cbi-button.cbi-button-down"); var downBtns = el.querySelectorAll(".cbi-button.cbi-button-down");
if (downBtns && downBtns.length > 0) { if (downBtns && downBtns.length > 0) {
downBtns.forEach(function (_el) { downBtns.forEach(function (_el) {
@ -133,6 +142,7 @@ local dsp = require "luci.dispatcher"
} }
} }
} }
// enable // enable
enableDragForTable( enableDragForTable(
"#cbi-shadowsocksr-servers table", "#cbi-shadowsocksr-servers table",

View File

@ -80,6 +80,7 @@
} }
return false; return false;
} }
function import_ssr_url(btn, urlname, sid) { function import_ssr_url(btn, urlname, sid) {
var s = document.getElementById(urlname + '-status'); var s = document.getElementById(urlname + '-status');
if (!s) if (!s)
@ -97,6 +98,7 @@
s.innerHTML = "<font color='red'>无效格式</font>"; s.innerHTML = "<font color='red'>无效格式</font>";
return false; return false;
} }
var event = document.createEvent("HTMLEvents"); var event = document.createEvent("HTMLEvents");
event.initEvent("change", true, true); event.initEvent("change", true, true);
if (ssu[0] == "ssr") { if (ssu[0] == "ssr") {
@ -135,6 +137,7 @@
s.innerHTML = "<font color='green'>导入ShadowsocksR配置信息成功</font>"; s.innerHTML = "<font color='green'>导入ShadowsocksR配置信息成功</font>";
return false; return false;
} else if (ssu[0] == "ss") { } else if (ssu[0] == "ss") {
var url0, param = ""; var url0, param = "";
var sipIndex = ssu[1].indexOf("@"); var sipIndex = ssu[1].indexOf("@");
var ploc = ssu[1].indexOf("#"); var ploc = ssu[1].indexOf("#");
@ -144,6 +147,7 @@
} else { } else {
url0 = ssu[1]; url0 = ssu[1];
} }
if (sipIndex != -1) { if (sipIndex != -1) {
// SIP002 // SIP002
var userInfo = b64decsafe(url0.substr(0, sipIndex)); var userInfo = b64decsafe(url0.substr(0, sipIndex));
@ -159,6 +163,7 @@
plugin = pluginNameInfo.substr(pluginNameInfo.indexOf("=") + 1) plugin = pluginNameInfo.substr(pluginNameInfo.indexOf("=") + 1)
pluginOpts = pluginInfo.substr(pluginIndex + 1); pluginOpts = pluginInfo.substr(pluginIndex + 1);
} }
var userInfoSplitIndex = userInfo.indexOf(":"); var userInfoSplitIndex = userInfo.indexOf(":");
if (userInfoSplitIndex != -1) { if (userInfoSplitIndex != -1) {
method = userInfo.substr(0, userInfoSplitIndex); method = userInfo.substr(0, userInfoSplitIndex);
@ -172,6 +177,7 @@
document.getElementsByName('cbid.shadowsocksr.' + sid + '.encrypt_method_ss')[0].value = method || ""; document.getElementsByName('cbid.shadowsocksr.' + sid + '.encrypt_method_ss')[0].value = method || "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.plugin')[0].value = plugin || ""; document.getElementsByName('cbid.shadowsocksr.' + sid + '.plugin')[0].value = plugin || "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.plugin_opts')[0].value = pluginOpts || ""; document.getElementsByName('cbid.shadowsocksr.' + sid + '.plugin_opts')[0].value = pluginOpts || "";
if (param != undefined) { if (param != undefined) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = decodeURI(param); document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = decodeURI(param);
} }
@ -206,6 +212,7 @@
url0 = ssu[1] url0 = ssu[1]
} }
var sstr = url0; var sstr = url0;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = "trojan"; document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = "trojan";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event); document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event);
var team = sstr.split('@'); var team = sstr.split('@');
@ -222,6 +229,7 @@
queryParam[decodeURIComponent(params[0])] = decodeURIComponent(params[1] || ''); queryParam[decodeURIComponent(params[0])] = decodeURIComponent(params[1] || '');
} }
} }
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = serverPart[0]; document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = serverPart[0];
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = port; document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = port;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.password')[0].value = password; document.getElementsByName('cbid.shadowsocksr.' + sid + '.password')[0].value = password;
@ -229,6 +237,7 @@
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].dispatchEvent(event); document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].dispatchEvent(event);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_host')[0].value = queryParam.peer || ''; document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_host')[0].value = queryParam.peer || '';
document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].checked = queryParam.allowInsecure === '1'; document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].checked = queryParam.allowInsecure === '1';
if (param != undefined) { if (param != undefined) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = decodeURI(param); document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = decodeURI(param);
} }

View File

@ -61,21 +61,9 @@ msgstr "密码"
msgid "Encrypt Method" msgid "Encrypt Method"
msgstr "加密方式" msgstr "加密方式"
msgid "Transport"
msgstr "传输协议"
msgid "Protocol" msgid "Protocol"
msgstr "传输协议" msgstr "传输协议"
msgid "allowInsecure"
msgstr "允许不安全连接"
msgid "Concurrency"
msgstr "最大并发连接数"
msgid "If true, allowss insecure connection at TLS client, e.g., TLS server uses unverifiable certificates."
msgstr "是否允许不安全连接。当选择时,将不会检查远端主机所提供的 TLS 证书的有效性。"
msgid "Protocol param(optional)" msgid "Protocol param(optional)"
msgstr "传输协议参数(可选)" msgstr "传输协议参数(可选)"

View File

@ -1030,8 +1030,7 @@
45.65.28.0/22 45.65.28.0/22
45.112.132.0/22 45.112.132.0/22
45.112.188.0/22 45.112.188.0/22
45.112.208.0/22 45.112.208.0/21
45.112.212.0/22
45.112.216.0/22 45.112.216.0/22
45.112.220.0/22 45.112.220.0/22
45.112.228.0/22 45.112.228.0/22
@ -1472,9 +1471,6 @@
45.253.232.0/22 45.253.232.0/22
45.253.236.0/22 45.253.236.0/22
45.253.240.0/22 45.253.240.0/22
45.253.244.0/22
45.253.248.0/22
45.253.252.0/22
45.254.0.0/22 45.254.0.0/22
45.254.4.0/22 45.254.4.0/22
45.254.8.0/22 45.254.8.0/22
@ -1786,7 +1782,6 @@
61.29.128.0/18 61.29.128.0/18
61.29.192.0/19 61.29.192.0/19
61.29.224.0/20 61.29.224.0/20
61.29.240.0/20
61.45.128.0/18 61.45.128.0/18
61.45.224.0/20 61.45.224.0/20
61.47.128.0/18 61.47.128.0/18
@ -4009,13 +4004,6 @@
103.149.210.0/23 103.149.210.0/23
103.149.214.0/23 103.149.214.0/23
103.149.220.0/23 103.149.220.0/23
103.149.242.0/23
103.149.244.0/23
103.149.246.0/23
103.149.248.0/23
103.150.24.0/23
103.150.66.0/23
103.150.72.0/23
103.192.0.0/22 103.192.0.0/22
103.192.4.0/22 103.192.4.0/22
103.192.8.0/22 103.192.8.0/22
@ -5074,7 +5062,8 @@
106.4.0.0/14 106.4.0.0/14
106.8.0.0/15 106.8.0.0/15
106.11.0.0/16 106.11.0.0/16
106.12.0.0/14 106.12.0.0/15
106.14.0.0/15
106.16.0.0/12 106.16.0.0/12
106.32.0.0/12 106.32.0.0/12
106.48.0.0/15 106.48.0.0/15
@ -5412,7 +5401,10 @@
117.32.0.0/13 117.32.0.0/13
117.40.0.0/14 117.40.0.0/14
117.44.0.0/15 117.44.0.0/15
117.48.0.0/14 117.48.0.0/17
117.48.128.0/17
117.49.0.0/16
117.50.0.0/15
117.53.48.0/20 117.53.48.0/20
117.53.176.0/20 117.53.176.0/20
117.57.0.0/16 117.57.0.0/16
@ -5840,7 +5832,8 @@
124.64.0.0/15 124.64.0.0/15
124.66.0.0/17 124.66.0.0/17
124.67.0.0/16 124.67.0.0/16
124.68.0.0/14 124.68.0.0/15
124.70.0.0/15
124.72.0.0/16 124.72.0.0/16
124.73.0.0/16 124.73.0.0/16
124.74.0.0/15 124.74.0.0/15

View File

@ -6,20 +6,25 @@ config global
option dports '2' option dports '2'
option pdnsd_enable '1' option pdnsd_enable '1'
option monitor_enable '1' option monitor_enable '1'
option global_server 'nil'
option enable_switch '1' option enable_switch '1'
option switch_timeout '5' option switch_timeout '5'
option switch_time '667' option switch_time '667'
option switch_try_count '3' option switch_try_count '3'
option gfwlist_url 'https://raw.githubusercontent.com/Loukky/gfwlist-by-loukky/master/gfwlist.txt' option gfwlist_url 'https://cdn.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt'
option chnroute_url 'https://ispip.clang.cn/all_cn.txt' option chnroute_url 'https://ispip.clang.cn/all_cn.txt'
option nfip_url 'https://raw.githubusercontent.com/QiuSimons/Netflix_IP/master/NF_only.txt' option nfip_url 'https://raw.githubusercontent.com/QiuSimons/Netflix_IP/master/NF_only.txt'
option adblock_url 'https://gitee.com/privacy-protection-tools/anti-ad/raw/master/anti-ad-for-dnsmasq.conf' option adblock_url 'https://gitee.com/privacy-protection-tools/anti-ad/raw/master/anti-ad-for-dnsmasq.conf'
option netflix_server 'same'
option threads '0' option threads '0'
option global_server 'nil'
option netflix_server 'nil' config socks5_proxy
option netflix_proxy '0' option socks '0'
option local_port '1080'
option local_address '0.0.0.0'
config access_control config access_control
option wan_bp_list '/etc/china_ssr.txt'
option lan_ac_mode 'b' option lan_ac_mode 'b'
option router_proxy '1' option router_proxy '1'
list wan_fw_ips '149.154.160.0/20' list wan_fw_ips '149.154.160.0/20'
@ -28,11 +33,6 @@ config access_control
list wan_fw_ips '91.108.56.0/22' list wan_fw_ips '91.108.56.0/22'
list wan_fw_ips '109.239.140.0/24' list wan_fw_ips '109.239.140.0/24'
config socks5_proxy
option socks '0'
option local_port '1080'
option local_address '0.0.0.0'
config server_global config server_global
option enable_server '0' option enable_server '0'

File diff suppressed because it is too large Load Diff

View File

@ -13,11 +13,11 @@ uci -q batch <<-EOF >/dev/null
commit firewall commit firewall
EOF EOF
touch /etc/ssr/china_ssr.txt touch /etc/china_ssr.txt
touch /etc/ssr/white.list touch /etc/config/white.list
touch /etc/ssr/black.list touch /etc/config/black.list
touch /etc/ssr/netflix.list touch /etc/config/netflix.list
touch /etc/ssr/netflixip.list touch /etc/config/netflixip.list
touch /etc/dnsmasq.ssr/ad.conf touch /etc/dnsmasq.ssr/ad.conf
touch /etc/dnsmasq.ssr/gfw_list.conf touch /etc/dnsmasq.ssr/gfw_list.conf

View File

@ -1,9 +1,9 @@
#!/bin/sh -e #!/bin/sh -e
if [ -f /tmp/adnew.conf ]; then if [ -f /tmp/adnew.conf ]; then
if (grep -wq "address=" /tmp/adnew.conf); then if (grep -wq "address=" /tmp/adnew.conf) ; then
cp /tmp/adnew.conf /tmp/ssr-update.$1 cp /tmp/adnew.conf /tmp/ad.conf
else else
cat /tmp/adnew.conf | grep ^\|\|[^\*]*\^$ | sed -e 's:||:address\=\/:' -e 's:\^:/0\.0\.0\.0:' >/tmp/ssr-update.$1 cat /tmp/adnew.conf | grep ^\|\|[^\*]*\^$ | sed -e 's:||:address\=\/:' -e 's:\^:/0\.0\.0\.0:' > /tmp/ad.conf
fi fi
fi fi
rm -f /tmp/adnew.conf rm -f /tmp/adnew.conf

View File

@ -1,4 +1,5 @@
#!/bin/sh -e #!/bin/sh -e
generate_china_banned() { generate_china_banned() {
cat $1 | base64 -d >/tmp/gfwlist.txt cat $1 | base64 -d >/tmp/gfwlist.txt
rm -f $1 rm -f $1
@ -18,7 +19,7 @@ generate_china_banned() {
}' | sort -u }' | sort -u
} }
generate_china_banned /tmp/ssr-update.$1 >/tmp/gfw.txt generate_china_banned /tmp/gfw.b64 >/tmp/gfw.txt
rm -f /tmp/gfwlist.txt rm -f /tmp/gfwlist.txt
sed '/.*/s/.*/server=\/\.&\/127.0.0.1#5335\nipset=\/\.&\/gfwlist/' /tmp/gfw.txt >/tmp/ssr-update.$1 sed '/.*/s/.*/server=\/\.&\/127.0.0.1#5335\nipset=\/\.&\/gfwlist/' /tmp/gfw.txt >/tmp/gfwnew.txt
rm -f /tmp/gfw.txt rm -f /tmp/gfw.txt

View File

@ -6,9 +6,6 @@
# This is free software, licensed under the GNU General Public License v3. # This is free software, licensed under the GNU General Public License v3.
# See /LICENSE for more information. # See /LICENSE for more information.
# #
LOCK_FILE="/var/lock/ssr-monitor.lock"
[ -f "$LOCK_FILE" ] && exit 2
touch "$LOCK_FILE"
NAME=shadowsocksr NAME=shadowsocksr
@ -22,23 +19,6 @@ uci_get_by_type() {
echo ${ret:=$3} echo ${ret:=$3}
} }
get_host_ip() {
local host=$1
local isip=""
local ip=$host
isip=$(echo $host | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}")
if [ -z "$isip" ]; then
if [ "$host" != "${host#*:[0-9a-fA-F]}" ]; then
ip=$host
else
local ip=$(resolveip -4 -t 3 $host | awk 'NR==1{print}')
# local hostip=$(ping $host -W 1 -s 1 -c 1 | grep PING | cut -d'(' -f 2 | cut -d')' -f1)
[ -z "$ip" ] && ip=$(wget -q -O- http://119.29.29.29/d?dn=$1 | awk -F ';' '{print $1}')
fi
fi
echo ${ip:="127.0.0.1"}
}
server_process_count=$1 server_process_count=$1
redir_tcp_process=$2 redir_tcp_process=$2
redir_udp_process=$3 redir_udp_process=$3
@ -49,18 +29,25 @@ pdnsd_process=$7
if [ -z "$pdnsd_process" ]; then if [ -z "$pdnsd_process" ]; then
pdnsd_process=0 pdnsd_process=0
fi fi
i=0 i=0
GLOBAL_SERVER=$(uci_get_by_type global global_server) GLOBAL_SERVER=$(uci_get_by_type global global_server)
server=$(get_host_ip $(uci_get_by_name $GLOBAL_SERVER server)) server=$(uci_get_by_name $GLOBAL_SERVER server)
[ "$server" == "127.0.0.1" ] && hostip=$(uci_get_by_name $GLOBAL_SERVER ip)
lkcp_port=$(uci_get_by_name $GLOBAL_SERVER kcp_port) lkcp_port=$(uci_get_by_name $GLOBAL_SERVER kcp_port)
server_port=$(uci_get_by_name $GLOBAL_SERVER server_port) server_port=$(uci_get_by_name $GLOBAL_SERVER server_port)
password=$(uci_get_by_name $GLOBAL_SERVER kcp_password) password=$(uci_get_by_name $GLOBAL_SERVER kcp_password)
kcp_param=$(uci_get_by_name $GLOBAL_SERVER kcp_param) kcp_param=$(uci_get_by_name $GLOBAL_SERVER kcp_param)
[ "$password" != "" ] && password="--key "${password} [ "$password" != "" ] && password="--key "${password}
if echo "$server" | grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$" >/dev/null; then
server=${server}
else
server=$(cat /etc/ssr_ip)
fi
while [ "1" == "1" ]; do #死循环 while [ "1" == "1" ]; do #死循环
sleep 30s sleep 30
#redir tcp #redir tcp
if [ "$redir_tcp_process" -gt 0 ]; then if [ "$redir_tcp_process" -gt 0 ]; then
icount=$(busybox ps -w | grep ssr-retcp | grep -v grep | wc -l) icount=$(busybox ps -w | grep ssr-retcp | grep -v grep | wc -l)
@ -95,7 +82,6 @@ while [ "1" == "1" ]; do #死循环
logger -t "$NAME" "ssr server error.restart!" logger -t "$NAME" "ssr server error.restart!"
kill -9 $(busybox ps -w | grep ssr-server | grep -v grep | awk '{print $1}') >/dev/null 2>&1 kill -9 $(busybox ps -w | grep ssr-server | grep -v grep | awk '{print $1}') >/dev/null 2>&1
/etc/init.d/shadowsocksr restart /etc/init.d/shadowsocksr restart
exit 0
fi fi
fi fi
#kcptun #kcptun
@ -114,7 +100,6 @@ while [ "1" == "1" ]; do #死循环
logger -t "$NAME" "global socks server error.restart!" logger -t "$NAME" "global socks server error.restart!"
kill -9 $(busybox ps -w | grep ssr-local | grep -v grep | awk '{print $1}') >/dev/null 2>&1 kill -9 $(busybox ps -w | grep ssr-local | grep -v grep | awk '{print $1}') >/dev/null 2>&1
/etc/init.d/shadowsocksr restart /etc/init.d/shadowsocksr restart
exit 0
fi fi
fi fi
#pdnsd #pdnsd
@ -127,21 +112,21 @@ while [ "1" == "1" ]; do #死循环
else else
kill -9 $(ps | grep pdnsd | grep -v grep | awk '{print $1}') >/dev/null 2>&1 kill -9 $(ps | grep pdnsd | grep -v grep | awk '{print $1}') >/dev/null 2>&1
fi fi
(/usr/sbin/pdnsd -c /var/etc/pdnsd.conf &) (/usr/sbin/pdnsd -c /var/etc/pdnsd.conf -d &)
fi fi
fi fi
#dns2socks #dns2socks
if [ "$pdnsd_process" -eq 2 ]; then if [ "$pdnsd_process" -eq 2 ]; then
icount=$(busybox ps -w | grep -e ssr-dns -e dns2socks | grep -v grep | wc -l) icount=$(busybox ps -w | grep -e ssr-dns -e dns2socks | grep -v grep | wc -l)
if [ "$icount" -lt 2 ]; then #如果进程挂掉就重启它 if [ "$icount" -lt 2 ]; then #如果进程挂掉就重启它
logger -t "$NAME" "dns2socks $dnsstr tunnel error.restart!" logger -t "$NAME" "dns2socks $dnsstr tunnel error.restart!"
dnsstr=$(uci_get_by_type global tunnel_forward 8.8.4.4:53) dnsstr=$(uci_get_by_type global tunnel_forward 8.8.4.4:53)
dnsserver=$(echo "$dnsstr" | awk -F ':' '{print $1}') dnsserver=$(echo "$dnsstr" | awk -F ':' '{print $1}')
dnsport=$(echo "$dnsstr" | awk -F ':' '{print $2}') dnsport=$(echo "$dnsstr" | awk -F ':' '{print $2}')
killall -q -9 dns2socks killall -q -9 dns2socks
kill -9 $(busybox ps -w | grep ssr-dns | grep -v grep | awk '{print $1}') >/dev/null 2>&1 kill -9 $(busybox ps -w | grep ssr-dns | grep -v grep | awk '{print $1}') >/dev/null 2>&1
microsocks -i 127.0.0.1 -p 10802 ssr-dns >/dev/null 2>&1 & microsocks -i 127.0.0.1 -p 10802 ssr-dns >/dev/null 2>&1 &
dns2socks 127.0.0.1:10802 $dnsserver:$dnsport 127.0.0.1:5335 -q >/dev/null 2>&1 & dns2socks 127.0.0.1:10802 $dnsserver:$dnsport 127.0.0.1:5335 -q >/dev/null 2>&1 &
fi fi
fi fi
done done

View File

@ -33,7 +33,6 @@ Valid options are:
-F netflix mode -F netflix mode
-N netflix server IP -N netflix server IP
-M netflix proxy mode -M netflix proxy mode
-I <ip_list_file> a file content is bypassed netflix ip list
-e <extra_options> extra options for iptables -e <extra_options> extra options for iptables
-o apply the rules to the OUTPUT chain -o apply the rules to the OUTPUT chain
-O apply the global rules to the OUTPUT chain -O apply the global rules to the OUTPUT chain
@ -83,8 +82,7 @@ flush_r() {
ipset_r() { ipset_r() {
ipset -N gmlan hash:net 2>/dev/null ipset -N gmlan hash:net 2>/dev/null
for ip in $LAN_GM_IP; do ipset -! add gmlan $ip; done for ip in $LAN_GM_IP; do ipset -! add gmlan $ip; done
case "$RUNMODE" in if [ "$RUNMODE" == "router" ]; then
router)
ipset -! -R <<-EOF || return 1 ipset -! -R <<-EOF || return 1
create ss_spec_wan_ac hash:net create ss_spec_wan_ac hash:net
$(gen_iplist | sed -e "s/^/add ss_spec_wan_ac /") $(gen_iplist | sed -e "s/^/add ss_spec_wan_ac /")
@ -94,29 +92,25 @@ ipset_r() {
$IPT -I SS_SPEC_WAN_AC -p tcp ! --dport 53 -d $server -j RETURN $IPT -I SS_SPEC_WAN_AC -p tcp ! --dport 53 -d $server -j RETURN
$IPT -A SS_SPEC_WAN_AC -m set --match-set ss_spec_wan_ac dst -j RETURN $IPT -A SS_SPEC_WAN_AC -m set --match-set ss_spec_wan_ac dst -j RETURN
$IPT -A SS_SPEC_WAN_AC -j SS_SPEC_WAN_FW $IPT -A SS_SPEC_WAN_AC -j SS_SPEC_WAN_FW
;; elif [ "$RUNMODE" == "gfw" ]; then
gfw)
ipset -N gfwlist hash:net 2>/dev/null ipset -N gfwlist hash:net 2>/dev/null
$IPT -N SS_SPEC_WAN_AC $IPT -N SS_SPEC_WAN_AC
$IPT -A SS_SPEC_WAN_AC -m set --match-set gfwlist dst -j SS_SPEC_WAN_FW $IPT -A SS_SPEC_WAN_AC -m set --match-set gfwlist dst -j SS_SPEC_WAN_FW
$IPT -A SS_SPEC_WAN_AC -m set --match-set gmlan src -m set ! --match-set china dst -j SS_SPEC_WAN_FW $IPT -A SS_SPEC_WAN_AC -m set --match-set gmlan src -m set ! --match-set china dst -j SS_SPEC_WAN_FW
$IPT -A SS_SPEC_WAN_AC -m set --match-set china dst -j RETURN $IPT -A SS_SPEC_WAN_AC -m set --match-set china dst -j RETURN
$IPT -I SS_SPEC_WAN_AC -p tcp ! --dport 53 -d $server -j RETURN $IPT -I SS_SPEC_WAN_AC -p tcp ! --dport 53 -d $server -j RETURN
;; elif [ "$RUNMODE" == "oversea" ]; then
oversea)
ipset -N oversea hash:net 2>/dev/null ipset -N oversea hash:net 2>/dev/null
$IPT -N SS_SPEC_WAN_AC $IPT -N SS_SPEC_WAN_AC
ipset -N gmlan hash:net 2>/dev/null ipset -N gmlan hash:net 2>/dev/null
for ip in $LAN_GM_IP; do ipset -! add gmlan $ip; done for ip in $LAN_GM_IP; do ipset -! add gmlan $ip; done
$IPT -A SS_SPEC_WAN_AC -m set --match-set china dst -j SS_SPEC_WAN_FW $IPT -A SS_SPEC_WAN_AC -m set --match-set china dst -j SS_SPEC_WAN_FW
$IPT -I SS_SPEC_WAN_AC -p tcp ! --dport 53 -d $server -j RETURN $IPT -I SS_SPEC_WAN_AC -p tcp ! --dport 53 -d $server -j RETURN
;; elif [ "$RUNMODE" == "all" ]; then
all)
$IPT -N SS_SPEC_WAN_AC $IPT -N SS_SPEC_WAN_AC
$IPT -A SS_SPEC_WAN_AC -j SS_SPEC_WAN_FW $IPT -A SS_SPEC_WAN_AC -j SS_SPEC_WAN_FW
$IPT -I SS_SPEC_WAN_AC -p tcp ! --dport 53 -d $server -j RETURN $IPT -I SS_SPEC_WAN_AC -p tcp ! --dport 53 -d $server -j RETURN
;; fi
esac
ipset -N fplan hash:net 2>/dev/null ipset -N fplan hash:net 2>/dev/null
for ip in $LAN_FP_IP; do ipset -! add fplan $ip; done for ip in $LAN_FP_IP; do ipset -! add fplan $ip; done
$IPT -I SS_SPEC_WAN_AC -m set --match-set fplan src -j SS_SPEC_WAN_FW $IPT -I SS_SPEC_WAN_AC -m set --match-set fplan src -j SS_SPEC_WAN_FW
@ -129,25 +123,23 @@ ipset_r() {
$IPT -I SS_SPEC_WAN_AC -m set --match-set whitelist dst -j RETURN $IPT -I SS_SPEC_WAN_AC -m set --match-set whitelist dst -j RETURN
for ip in $WAN_BP_IP; do ipset -! add whitelist $ip; done for ip in $WAN_BP_IP; do ipset -! add whitelist $ip; done
for ip in $WAN_FW_IP; do ipset -! add blacklist $ip; done for ip in $WAN_FW_IP; do ipset -! add blacklist $ip; done
if [ "$NETFLIX" != "0" ]; then
ipset -N netflix hash:net 2>/dev/null if [ "$NETFLIX" == "1" ]; then
for ip in $(cat ${NETFLIX_LIST:=/dev/null} 2>/dev/null); do ipset -! add netflix $ip; done
fi
case "$NETFLIX" in
1)
$IPT -I SS_SPEC_WAN_AC -p tcp -m set --match-set netflix dst -j REDIRECT --to-ports 4321 $IPT -I SS_SPEC_WAN_AC -p tcp -m set --match-set netflix dst -j REDIRECT --to-ports 4321
if [ "$NETFLIX_PROXY" == "1" ]; then if [ "$NETFLIX_PROXY" == "1" ]; then
$IPT -I SS_SPEC_WAN_AC -p tcp -d $NETFLIX_IP -j REDIRECT --to-ports $local_port $IPT -I SS_SPEC_WAN_AC -p tcp -d $NETFLIX_IP -j REDIRECT --to-ports $local_port
else else
ipset -! add whitelist $NETFLIX_IP ipset -! add whitelist $NETFLIX_IP
fi fi
;; elif [ "$NETFLIX" == "2" ]; then
2) $IPT -I SS_SPEC_WAN_AC -p tcp -m set --match-set netflix dst -j REDIRECT --to-ports $local_port ;; $IPT -I SS_SPEC_WAN_AC -p tcp -m set --match-set netflix dst -j REDIRECT --to-ports $local_port
esac fi
return $? return $?
} }
fw_rule() { fw_rule() {
ipset -N netflix hash:net 2>/dev/null
$IPT -N SS_SPEC_WAN_FW $IPT -N SS_SPEC_WAN_FW
$IPT -A SS_SPEC_WAN_FW -d 0.0.0.0/8 -j RETURN $IPT -A SS_SPEC_WAN_FW -d 0.0.0.0/8 -j RETURN
$IPT -A SS_SPEC_WAN_FW -d 10.0.0.0/8 -j RETURN $IPT -A SS_SPEC_WAN_FW -d 10.0.0.0/8 -j RETURN
@ -224,26 +216,23 @@ tp_rule() {
$ipt -A SS_SPEC_TPROXY -p udp -m set --match-set bplan src -j RETURN $ipt -A SS_SPEC_TPROXY -p udp -m set --match-set bplan src -j RETURN
$ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -m set --match-set fplan src \ $ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -m set --match-set fplan src \
-j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01 -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
case "$RUNMODE" in if [ "$RUNMODE" == "router" ]; then
router)
$ipt -A SS_SPEC_TPROXY -p udp -m set --match-set gmlan src -m set ! --match-set china dst \ $ipt -A SS_SPEC_TPROXY -p udp -m set --match-set gmlan src -m set ! --match-set china dst \
-j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01 -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
$ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -m set ! --match-set ss_spec_wan_ac dst \ $ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -m set ! --match-set ss_spec_wan_ac dst \
-j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01 -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
;; elif [ "$RUNMODE" == "gfw" ]; then
gfw)
$ipt -A SS_SPEC_TPROXY -p udp -m set --match-set china dst -j RETURN $ipt -A SS_SPEC_TPROXY -p udp -m set --match-set china dst -j RETURN
$ipt -A SS_SPEC_TPROXY -p udp -m set --match-set gmlan src -m set ! --match-set china dst \ $ipt -A SS_SPEC_TPROXY -p udp -m set --match-set gmlan src -m set ! --match-set china dst \
-j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01 -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
$ipt -A SS_SPEC_TPROXY -p udp -m set $PROXY_PORTS --match-set gfwlist dst \ $ipt -A SS_SPEC_TPROXY -p udp -m set $PROXY_PORTS --match-set gfwlist dst \
-j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01 -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
;; elif [ "$RUNMODE" == "oversea" ]; then
oversea)
$ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -m set --match-set china dst \ $ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -m set --match-set china dst \
-j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01 -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
;; elif [ "$RUNMODE" == "all" ]; then
all) $ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01 ;; $ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
esac fi
$ipt -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p udp $EXT_ARGS $MATCH_SET \ $ipt -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p udp $EXT_ARGS $MATCH_SET \
-m comment --comment "$TAG" -j SS_SPEC_TPROXY -m comment --comment "$TAG" -j SS_SPEC_TPROXY
return $? return $?
@ -320,7 +309,7 @@ gen_include() {
return 0 return 0
} }
while getopts ":s:l:S:L:i:e:a:B:b:w:p:G:D:F:N:M:I:oOuUfgrczh" arg; do while getopts ":s:l:S:L:i:e:a:B:b:w:p:G:D:F:N:M:oOuUfgrczh" arg; do
case "$arg" in case "$arg" in
s) s)
server=$OPTARG server=$OPTARG
@ -370,9 +359,6 @@ while getopts ":s:l:S:L:i:e:a:B:b:w:p:G:D:F:N:M:I:oOuUfgrczh" arg; do
M) M)
NETFLIX_PROXY=$OPTARG NETFLIX_PROXY=$OPTARG
;; ;;
I)
NETFLIX_LIST=$OPTARG
;;
o) o)
OUTPUT=1 OUTPUT=1
;; ;;
@ -417,3 +403,4 @@ fi
flush_r && fw_rule && ipset_r && ac_rule && tp_rule && gen_include flush_r && fw_rule && ipset_r && ac_rule && tp_rule && gen_include
[ "$?" == 0 ] || loger 3 "Start failed!" [ "$?" == 0 ] || loger 3 "Start failed!"
exit $? exit $?

View File

@ -1,4 +1,4 @@
#!/bin/sh /etc/rc.common #!/bin/sh /etc/rc.common
# #
# Copyright (C) 2017 openwrt-ssr # Copyright (C) 2017 openwrt-ssr
# Copyright (C) 2017 yushi studio <ywb94@qq.com> # Copyright (C) 2017 yushi studio <ywb94@qq.com>
@ -6,9 +6,6 @@
# This is free software, licensed under the GNU General Public License v3. # This is free software, licensed under the GNU General Public License v3.
# See /LICENSE for more information. # See /LICENSE for more information.
# #
LOCK_FILE="/var/lock/ssr-switch.lock"
[ -f "$LOCK_FILE" ] && exit 2
touch "$LOCK_FILE"
cycle_time=60 cycle_time=60
switch_time=3 switch_time=3
@ -82,7 +79,7 @@ test_proxy() {
search_proxy() { search_proxy() {
let server_count=server_count+1 let server_count=server_count+1
[ "$normal_flag" == "1" -a "$server_count" -le "$server_locate" ] && return 0 [ "$normal_flag" == "1" -a "$server_count" -le "$server_locate" ] && return 0
[ "$(uci_get_by_name $1 switch_enable 0)" != "1" ] && return 1 [ "$(uci_get_by_name $1 switch_enable)" != "1" ] && return 1
[ $ENABLE_SERVER != nil ] && return 0 [ $ENABLE_SERVER != nil ] && return 0
[ "$1" == "$CURRENT_SERVER" ] && return 0 [ "$1" == "$CURRENT_SERVER" ] && return 0
local servername=$(uci_get_by_name $1 server) local servername=$(uci_get_by_name $1 server)
@ -136,7 +133,7 @@ start() {
#缺省服务器正常,切换回来 #缺省服务器正常,切换回来
CURRENT_SERVER=$DEFAULT_SERVER CURRENT_SERVER=$DEFAULT_SERVER
switch_proxy $CURRENT_SERVER switch_proxy $CURRENT_SERVER
echo "$(date "+%Y-%m-%d %H:%M:%S") switch to default "$(uci_get_by_name $CURRENT_SERVER alias)" proxy!" >>/tmp/ssrplus.log echo "$(date "+%Y-%m-%d %H:%M:%S") switch to default ["$(uci_get_by_name $CURRENT_SERVER server)"] proxy!" >>/tmp/ssrplus.log
else else
echo "$(date "+%Y-%m-%d %H:%M:%S") Main server is NOT avilable.Continue using current server." >>/tmp/ssrplus.log echo "$(date "+%Y-%m-%d %H:%M:%S") Main server is NOT avilable.Continue using current server." >>/tmp/ssrplus.log
fi fi
@ -157,7 +154,7 @@ start() {
CURRENT_SERVER=$ENABLE_SERVER CURRENT_SERVER=$ENABLE_SERVER
switch_proxy $CURRENT_SERVER switch_proxy $CURRENT_SERVER
normal_flag=1 normal_flag=1
echo "$(date "+%Y-%m-%d %H:%M:%S") Switch to "$(uci_get_by_name $CURRENT_SERVER alias)" proxy!" >>/tmp/ssrplus.log echo "$(date "+%Y-%m-%d %H:%M:%S") ShadowsocksR server switch OK" >>/tmp/ssrplus.log
else else
switch_proxy $CURRENT_SERVER switch_proxy $CURRENT_SERVER
normal_flag=1 normal_flag=1
@ -165,7 +162,7 @@ start() {
fi fi
else else
normal_flag=0 normal_flag=0
# echo "$(date "+%Y-%m-%d %H:%M:%S") ShadowsocksR No Problem." >>/tmp/ssrplus.log echo "$(date "+%Y-%m-%d %H:%M:%S") ShadowsocksR No Problem." >>/tmp/ssrplus.log
fi fi
done done
} }

View File

@ -1,9 +1,5 @@
#!/bin/sh
LOCK_FILE="/var/lock/ssr-chinaipset.lock"
[ -f "$LOCK_FILE" ] && exit 2
touch "$LOCK_FILE"
echo "create china hash:net family inet hashsize 1024 maxelem 65536" > /tmp/china.ipset echo "create china hash:net family inet hashsize 1024 maxelem 65536" > /tmp/china.ipset
awk '!/^$/&&!/^#/{printf("add china %s'" "'\n",$0)}' /etc/china_ssr.txt >> /tmp/china.ipset awk '!/^$/&&!/^#/{printf("add china %s'" "'\n",$0)}' /etc/china_ssr.txt >> /tmp/china.ipset
ipset -! flush china ipset -! flush china
ipset -! restore < /tmp/china.ipset 2>/dev/null ipset -! restore < /tmp/china.ipset 2>/dev/null
rm -f /tmp/china.ipset $LOCK_FILE rm -f /tmp/china.ipset

View File

@ -1,70 +1,72 @@
#!/bin/sh #!/bin/sh
cat <<-EOF >$1 cat <<-EOF >$1
base { base {
log_debug = off; log_debug = off;
log_info = off; log_info = off;
log = stderr; log = stderr;
daemon = on; daemon = on;
redirector = iptables; redirector = iptables;
reuseport = on; reuseport = on;
} }
EOF EOF
if [ "$2" == "socks5" ]; then if [ "$2" == "socks5" ]; then
if [ "$3" == "tcp" ]; then if [ "$3" == "tcp" ]; then
if [ "$7" == "0" ]; then if [ "$7" == "0" ]; then
cat <<-EOF >>$1 cat <<-EOF >>$1
redsocks { redsocks {
bind = "0.0.0.0:$4"; bind = "0.0.0.0:$4";
relay = "$5:$6"; relay = "$5:$6";
type = socks5; type = socks5;
autoproxy = 0; autoproxy = 0;
timeout = 10; timeout = 10;
} }
EOF EOF
else else
cat <<-EOF >>$1 cat <<-EOF >>$1
redsocks { redsocks {
bind = "0.0.0.0:$4"; bind = "0.0.0.0:$4";
relay = "$5:$6"; relay = "$5:$6";
type = socks5; type = socks5;
autoproxy = 0; autoproxy = 0;
timeout = 10; timeout = 10;
login = "$8"; login = "$8";
password = "$9"; password = "$9";
} }
EOF EOF
fi fi
else else
if [ "$7" == "0" ]; then if [ "$7" == "0" ]; then
cat <<-EOF >>$1 cat <<-EOF >>$1
redudp { redudp {
bind = "0.0.0.0:$4"; bind = "0.0.0.0:$4";
relay = "$5:$6"; relay = "$5:$6";
type = socks5; type = socks5;
udp_timeout = 10; udp_timeout = 10;
} }
EOF EOF
else else
cat <<-EOF >>$1 cat <<-EOF >>$1
redudp { redudp {
bind = "0.0.0.0:$4"; bind = "0.0.0.0:$4";
relay = "$5:$6"; relay = "$5:$6";
type = socks5; type = socks5;
udp_timeout = 10; udp_timeout = 10;
login = "$8"; login = "$8";
password = "$9"; password = "$9";
} }
EOF EOF
fi fi
fi fi
else else
cat <<-EOF >>$1 cat <<-EOF >>$1
redsocks { redsocks {
bind = "0.0.0.0:$4"; bind = "0.0.0.0:$4";
type = direct; type = direct;
interface = $3; interface = $3;
autoproxy = 0; autoproxy = 0;
timeout = 10; timeout = 10;
} }
EOF EOF
fi fi

View File

@ -3,6 +3,7 @@ local json = require "luci.jsonc"
local server_section = arg[1] local server_section = arg[1]
local proto = arg[2] local proto = arg[2]
local local_port = arg[3] local local_port = arg[3]
local server = ucursor:get_all("shadowsocksr", server_section) local server = ucursor:get_all("shadowsocksr", server_section)
local trojan = { local trojan = {

View File

@ -4,6 +4,7 @@ local server_section = arg[1]
local proto = arg[2] local proto = arg[2]
local local_port = arg[3] or "0" local local_port = arg[3] or "0"
local socks_port = arg[4] or "0" local socks_port = arg[4] or "0"
local server = ucursor:get_all("shadowsocksr", server_section) local server = ucursor:get_all("shadowsocksr", server_section)
local v2ray = { local v2ray = {

View File

@ -1,34 +1,5 @@
#!/bin/sh #!/bin/sh
NAME=shadowsocksr mkdir -p /tmp/dnsmasq.ssr
uci_get_by_type() { awk '!/^$/&&!/^#/{printf("ipset=/.%s/'"blacklist"'\n",$0)}' /etc/config/black.list > /tmp/dnsmasq.ssr/blacklist_forward.conf
local ret=$(uci get $NAME.@$1[0].$2 2>/dev/null) awk '!/^$/&&!/^#/{printf("server=/.%s/'"127.0.0.1#5335"'\n",$0)}' /etc/config/black.list >> /tmp/dnsmasq.ssr/blacklist_forward.conf
echo ${ret:=$3} awk '!/^$/&&!/^#/{printf("ipset=/.%s/'"whitelist"'\n",$0)}' /etc/config/white.list > /tmp/dnsmasq.ssr/whitelist_forward.conf
}
cp -a /etc/dnsmasq.ssr /tmp/
cp -a /etc/dnsmasq.oversea /tmp/
GLOBAL_SERVER=$(uci_get_by_type global global_server)
NETFLIX_SERVER=$(uci_get_by_type global netflix_server nil)
[ "$NETFLIX_SERVER" == "same" ] && NETFLIX_SERVER=$GLOBAL_SERVER
if [ "$NETFLIX_SERVER" != "nil" ]; then
netflix() {
for line in $(cat /etc/ssr/netflix.list); do sed -i "/$line/d" /tmp/dnsmasq.ssr/gfw_list.conf; done
awk '!/^$/&&!/^#/{printf("ipset=/.%s/'"netflix"'\n",$0)}' /etc/ssr/netflix.list >/tmp/dnsmasq.ssr/netflix_forward.conf
awk '!/^$/&&!/^#/{printf("server=/.%s/'"127.0.0.1#$1"'\n",$0)}' /etc/ssr/netflix.list >>/tmp/dnsmasq.ssr/netflix_forward.conf
}
if [ "$NETFLIX_SERVER" != "$GLOBAL_SERVER" ]; then
netflix 5555
else
netflix 5335
fi
else
rm -f /tmp/dnsmasq.ssr/netflix_forward.conf
fi
if [ "$1" == "" ]; then
awk '!/^$/&&!/^#/{printf("ipset=/.%s/'"blacklist"'\n",$0)}' /etc/ssr/black.list >/tmp/dnsmasq.ssr/blacklist_forward.conf
awk '!/^$/&&!/^#/{printf("server=/.%s/'"127.0.0.1#5335"'\n",$0)}' /etc/ssr/black.list >>/tmp/dnsmasq.ssr/blacklist_forward.conf
awk '!/^$/&&!/^#/{printf("ipset=/.%s/'"whitelist"'\n",$0)}' /etc/ssr/white.list >/tmp/dnsmasq.ssr/whitelist_forward.conf
if [ "$(uci_get_by_type global adblock 0)" == "0" ]; then
rm -f /tmp/dnsmasq.ssr/ad.conf
fi
fi
/etc/init.d/dnsmasq restart >/dev/null 2>&1

View File

@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
/usr/bin/lua /usr/share/shadowsocksr/update.lua /usr/bin/lua /usr/share/shadowsocksr/update.lua
sleep 2s
/usr/share/shadowsocksr/chinaipset.sh
sleep 2s
/usr/bin/lua /usr/share/shadowsocksr/subscribe.lua /usr/bin/lua /usr/share/shadowsocksr/subscribe.lua
sleep 10
/etc/init.d/shadowsocksr restart

View File

@ -3,33 +3,34 @@
-- This file is part of the luci-app-ssr-plus subscribe.lua -- This file is part of the luci-app-ssr-plus subscribe.lua
-- @author William Chan <root@williamchan.me> -- @author William Chan <root@williamchan.me>
------------------------------------------------ ------------------------------------------------
require "luci.model.uci" require 'nixio'
require "nixio" require 'luci.util'
require "luci.util" require 'luci.jsonc'
require "luci.sys" require 'luci.sys'
require "luci.jsonc" require 'uci'
-- these global functions are accessed all the time by the event handler -- these global functions are accessed all the time by the event handler
-- so caching them is worth the effort -- so caching them is worth the effort
local luci = luci
local tinsert = table.insert local tinsert = table.insert
local ssub, slen, schar, sbyte, sformat, sgsub = string.sub, string.len, string.char, string.byte, string.format, string.gsub local ssub, slen, schar, sbyte, sformat, sgsub = string.sub, string.len, string.char, string.byte, string.format, string.gsub
local jsonParse, jsonStringify = luci.jsonc.parse, luci.jsonc.stringify local jsonParse, jsonStringify = luci.jsonc.parse, luci.jsonc.stringify
local b64decode = nixio.bin.b64decode local b64decode = nixio.bin.b64decode
local cache = {} local cache = {}
local nodeResult = setmetatable({}, { __index = cache }) -- update result local nodeResult = setmetatable({}, { __index = cache }) -- update result
local name = 'shadowsocksr' local name = 'shadowsocksr'
local uciType = 'servers' local uciType = 'servers'
local ucic = luci.model.uci.cursor() local ucic = luci.model.uci.cursor()
local proxy = ucic:get_first(name, 'server_subscribe', 'proxy', '0') local proxy = ucic:get_first(name, 'server_subscribe', 'proxy', '0')
local switch = ucic:get_first(name, 'server_subscribe', 'switch', '1') local switch = ucic:get_first(name, 'server_subscribe', 'switch', '1')
local subscribe_url = ucic:get_first(name, 'server_subscribe', 'subscribe_url', {}) local subscribe_url = ucic:get_first(name, 'server_subscribe', 'subscribe_url', {})
local filter_words = ucic:get_first(name, 'server_subscribe', 'filter_words', '过期时间/剩余流量') local filter_words = ucic:get_first(name, 'server_subscribe', 'filter_words', 'QQ群')
local log = function(...) local log = function(...)
print(os.date("%Y-%m-%d %H:%M:%S ") .. table.concat({ ... }, " ")) print(os.date("%Y-%m-%d %H:%M:%S ") .. table.concat({ ... }, " "))
end end
-- 分割字符串 -- 分割字符串
local function split(full, sep) local function split(full, sep)
full = full:gsub("%z", "") -- 这里不是很清楚 有时候结尾带个\0 full = full:gsub("%z", "") -- 这里不是很清楚 有时候结尾带个\0
local off, result = 1, {} local off, result = 1, {}
while true do while true do
local nStart, nEnd = full:find(sep, off) local nStart, nEnd = full:find(sep, off)
@ -73,7 +74,7 @@ local function trim(text)
end end
-- md5 -- md5
local function md5(content) local function md5(content)
local stdout = luci.sys.exec('echo \"' .. urlEncode(content) .. '\" | md5sum | cut -d \" \" -f1') local stdout = luci.sys.exec('echo \"' .. urlEncode(content) .. '\" | md5sum | cut -d \" \" -f1')
-- assert(nixio.errno() == 0) -- assert(nixio.errno() == 0)
return trim(stdout) return trim(stdout)
end end
@ -118,7 +119,7 @@ local function processData(szType, content)
result.protocol_param = base64Decode(params.protoparam) result.protocol_param = base64Decode(params.protoparam)
local group = base64Decode(params.group) local group = base64Decode(params.group)
if group then if group then
result.alias = "[" .. group .. "] " result.alias = "[" .. group .. "] "
end end
result.alias = result.alias .. base64Decode(params.remarks) result.alias = result.alias .. base64Decode(params.remarks)
elseif szType == 'vmess' then elseif szType == 'vmess' then
@ -279,15 +280,15 @@ local function wget(url)
end end
local function check_filer(result) local function check_filer(result)
do do
local filter_word = split(filter_words, "/") local filter_word = split(filter_words, "/")
for i, v in pairs(filter_word) do for i, v in pairs(filter_word) do
if result.alias:find(v) then if result.alias:find(v) then
log('订阅节点关键字过滤:“' .. v ..'” ,该节点被丢弃') log('订阅节点关键字过滤:“' .. v ..'” ,该节点被丢弃')
return true return true
end end
end end
end end
end end
local execute = function() local execute = function()
@ -312,10 +313,10 @@ local execute = function()
nodes = base64Decode(raw:sub(nEnd + 1, #raw)) nodes = base64Decode(raw:sub(nEnd + 1, #raw))
nodes = jsonParse(nodes) nodes = jsonParse(nodes)
local extra = { local extra = {
airport = nodes.airport, airport = nodes.airport,
port = nodes.port, port = nodes.port,
encryption = nodes.encryption, encryption = nodes.encryption,
password = nodes.password password = nodes.password
} }
local servers = {} local servers = {}
-- SS里面包着 干脆直接这样 -- SS里面包着 干脆直接这样
@ -348,11 +349,10 @@ local execute = function()
-- log(result) -- log(result)
if result then if result then
if if
not result.server or not result.server or
not result.server_port or check_filer(result) or
check_filer(result) or result.server:match("[^0-9a-zA-Z%-%.%s]") -- 中文做地址的 也没有人拿中文域名搞就算中文域也有Puny Code SB 机场
result.server:match("[^0-9a-zA-Z%-%.%s]") -- 中文做地址的 也没有人拿中文域名搞就算中文域也有Puny Code SB 机场 then
then
log('丢弃无效节点: ' .. result.type ..' 节点, ' .. result.alias) log('丢弃无效节点: ' .. result.type ..' 节点, ' .. result.alias)
else else
log('成功解析: ' .. result.type ..' 节点, ' .. result.alias) log('成功解析: ' .. result.type ..' 节点, ' .. result.alias)
@ -385,7 +385,7 @@ local execute = function()
local dat = nodeResult[old.grouphashkey][old.hashkey] local dat = nodeResult[old.grouphashkey][old.hashkey]
ucic:tset(name, old['.name'], dat) ucic:tset(name, old['.name'], dat)
-- 标记一下 -- 标记一下
setmetatable(nodeResult[old.grouphashkey][old.hashkey], { __index = { _ignore = true } }) setmetatable(nodeResult[old.grouphashkey][old.hashkey], { __index = { _ignore = true } })
end end
else else
if not old.alias then if not old.alias then
@ -393,6 +393,7 @@ local execute = function()
end end
log('忽略手动添加的节点: ' .. old.alias) log('忽略手动添加的节点: ' .. old.alias)
end end
end) end)
for k, v in ipairs(nodeResult) do for k, v in ipairs(nodeResult) do
for kk, vv in ipairs(v) do for kk, vv in ipairs(v) do

View File

@ -3,8 +3,10 @@
-- This file is part of the luci-app-ssr-plus update.lua -- This file is part of the luci-app-ssr-plus update.lua
-- By Mattraks -- By Mattraks
------------------------------------------------ ------------------------------------------------
require "luci.sys" require 'nixio'
require "luci.model.uci" require 'luci.util'
require 'luci.jsonc'
require 'luci.sys'
local icount = 0 local icount = 0
local uci = luci.model.uci.cursor() local uci = luci.model.uci.cursor()
@ -12,41 +14,112 @@ local log = function(...)
print(os.date("%Y-%m-%d %H:%M:%S ") .. table.concat({ ... }, " ")) print(os.date("%Y-%m-%d %H:%M:%S ") .. table.concat({ ... }, " "))
end end
local function update(url, file, type, file2) log('正在更新【GFW列表】数据库')
local Num = 1 refresh_cmd = "wget-ssl --no-check-certificate -O- " .. uci:get_first('shadowsocksr', 'global', 'gfwlist_url', 'https://cdn.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt') .. " > /tmp/gfw.b64"
refresh_cmd = "wget-ssl --no-check-certificate -t 3 -T 10 -O- " .. url .. " > /tmp/ssr-update." .. type sret = luci.sys.call(refresh_cmd .. " 2>/dev/null")
sret = luci.sys.call(refresh_cmd .. " 2>/dev/null") if sret == 0 then
if sret == 0 then luci.sys.call("/usr/bin/ssr-gfw")
if type == "gfw_data" then icount = luci.sys.exec("cat /tmp/gfwnew.txt | wc -l")
luci.sys.call("/usr/bin/ssr-gfw " .. type) if tonumber(icount) > 1000 then
Num = 2 if nixio.fs.access("/etc/dnsmasq.ssr/gfw_list.conf") then
end oldcount = luci.sys.exec("cat /etc/dnsmasq.ssr/gfw_list.conf | wc -l")
if type == "ad_data" then
luci.sys.call("/usr/bin/ssr-ad " .. type)
end
local new_md5 = luci.sys.exec("echo -n $([ -f '/tmp/ssr-update." .. type .. "' ] && md5sum /tmp/ssr-update." .. type .. " | awk '{print $1}')")
local old_md5 = luci.sys.exec("echo -n $([ -f '" .. file .. "' ] && md5sum " .. file .. " | awk '{print $1}')")
if new_md5 == old_md5 then
log("你已经是最新数据,无需更新!")
else else
icount = luci.sys.exec("cat /tmp/ssr-update." .. type .. " | wc -l") oldcount = "0"
luci.sys.exec("cp -f /tmp/ssr-update." .. type .. " " .. file) end
if file2 then luci.sys.exec("cp -f /tmp/ssr-update." .. type .. " " .. file2) end if tonumber(icount) ~= tonumber(oldcount) then
log("更新成功! 新的总纪录数:" .. tostring(tonumber(icount)/Num)) luci.sys.exec("cp -f /tmp/gfwnew.txt /etc/dnsmasq.ssr/gfw_list.conf")
luci.sys.exec("cp -f /tmp/gfwnew.txt /tmp/dnsmasq.ssr/gfw_list.conf")
log('更新成功! 新的总纪录数:' .. tostring(tonumber(icount)/2))
else
log('你已经是最新数据,无需更新!')
end end
else else
log("更新失败!") log('更新失败!')
end end
luci.sys.exec("rm -f /tmp/ssr-update." .. type) luci.sys.exec("rm -f /tmp/gfwnew.txt")
else
log('更新失败!')
end end
log("正在更新【GFW列表】数据库") log('正在更新【国内IP段】数据库')
update(uci:get_first("shadowsocksr", "global", "gfwlist_url", "https://cdn.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt"), "/etc/dnsmasq.ssr/gfw_list.conf", "gfw_data", "/tmp/dnsmasq.ssr/gfw_list.conf") refresh_cmd = "wget-ssl --no-check-certificate -O- " .. uci:get_first('shadowsocksr', 'global', 'chnroute_url','https://ispip.clang.cn/all_cn.txt') .. " > /tmp/china_ssr.txt"
log("正在更新【国内IP段】数据库") sret = luci.sys.call(refresh_cmd .. " 2>/dev/null")
update(uci:get_first("shadowsocksr", "global", "chnroute_url","https://ispip.clang.cn/all_cn.txt"), "/etc/ssr/china_ssr.txt", "cnip") icount = luci.sys.exec("cat /tmp/china_ssr.txt | wc -l")
if uci:get_first("shadowsocksr", "global", "adblock","0") == "1" then if sret == 0 then
log("正在更新【广告屏蔽】数据库") icount = luci.sys.exec("cat /tmp/china_ssr.txt | wc -l")
update(uci:get_first("shadowsocksr", "global", "adblock_url","https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt"), "/etc/dnsmasq.ssr/ad.conf", "ad_data", "/tmp/dnsmasq.ssr/ad.conf") if tonumber(icount) > 1000 then
if nixio.fs.access("/etc/china_ssr.txt") then
oldcount = luci.sys.exec("cat /etc/china_ssr.txt | wc -l")
else
oldcount = "0"
end
if tonumber(icount) ~= tonumber(oldcount) then
luci.sys.exec("cp -f /tmp/china_ssr.txt /etc/china_ssr.txt")
log('更新成功! 新的总纪录数:' .. tostring(tonumber(icount)))
else
log('你已经是最新数据,无需更新!')
end
else
log('更新失败!')
end
luci.sys.exec("rm -f /tmp/china_ssr.txt")
else
log('更新失败!')
end end
-- log("正在更新【Netflix IP段】数据库")
-- update(uci:get_first("shadowsocksr", "global", "nfip_url","https://raw.githubusercontent.com/QiuSimons/Netflix_IP/master/NF_only.txt"), "/etc/ssr/netflixip.list", "nfip_data") if uci:get_first('shadowsocksr', 'global', 'adblock','0') == "1" then
log('正在更新【广告屏蔽】数据库')
refresh_cmd = "wget-ssl --no-check-certificate -O- " .. uci:get_first('shadowsocksr', 'global', 'adblock_url','https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt') .. " > /tmp/adnew.conf"
sret = luci.sys.call(refresh_cmd .. " 2>/dev/null")
if sret == 0 then
luci.sys.call("/usr/bin/ssr-ad")
icount = luci.sys.exec("cat /tmp/ad.conf | wc -l")
if tonumber(icount) > 100 then
if nixio.fs.access("/etc/dnsmasq.ssr/ad.conf") then
oldcount = luci.sys.exec("cat /etc/dnsmasq.ssr/ad.conf | wc -l")
else
oldcount = "0"
end
if tonumber(icount) ~= tonumber(oldcount) then
luci.sys.exec("cp -f /tmp/ad.conf /etc/dnsmasq.ssr/ad.conf")
luci.sys.exec("cp -f /tmp/ad.conf /tmp/dnsmasq.ssr/ad.conf")
log('更新成功! 新的总纪录数:' .. tostring(tonumber(icount)))
else
log('你已经是最新数据,无需更新!')
end
else
log('更新失败!')
end
luci.sys.exec("rm -f /tmp/ad.conf")
else
log('更新失败!')
end
end
--[[
log('正在更新【Netflix IP段】数据库')
refresh_cmd = "wget-ssl --no-check-certificate -O- " .. uci:get_first('shadowsocksr', 'global', 'nfip_url','https://raw.githubusercontent.com/QiuSimons/Netflix_IP/master/NF_only.txt') .. " > /tmp/netflixip.list"
sret = luci.sys.call(refresh_cmd .. " 2>/dev/null")
if sret == 0 then
luci.sys.call("/usr/bin/ssr-gfw")
icount = luci.sys.exec("cat /tmp/netflixip.list | wc -l")
if tonumber(icount) > 5 then
if nixio.fs.access("/etc/config/netflixip.list") then
oldcount = luci.sys.exec("cat /etc/config/netflixip.list | wc -l")
else
oldcount = "0"
end
if tonumber(icount) ~= tonumber(oldcount) then
luci.sys.exec("cp -f /tmp/netflixip.list /etc/config/netflixip.list")
log('更新成功! 新的总纪录数:' .. tostring(tonumber(icount)))
else
log('你已经是最新数据,无需更新!')
end
else
log('更新失败!')
end
luci.sys.exec("rm -f /tmp/netflixip.list")
else
log('更新失败!')
end
--]]