update 2022-05-22 23:42:54

This commit is contained in:
github-actions[bot] 2022-05-22 23:42:54 +08:00
parent 78023e2056
commit 3c562ad20f
8 changed files with 462 additions and 411 deletions

View File

@ -9,7 +9,7 @@ function index()
local page = entry({'admin', 'services', 'vssr'}, alias('admin', 'services', 'vssr', 'client'), _('Hello World'), 0) -- 首页 local page = entry({'admin', 'services', 'vssr'}, alias('admin', 'services', 'vssr', 'client'), _('Hello World'), 0) -- 首页
page.dependent = true page.dependent = true
page.acl_depends = { "luci-app-vssr" } page.acl_depends = {'luci-app-vssr'}
entry({'admin', 'services', 'vssr', 'client'}, cbi('vssr/client'), _('SSR Client'), 10).leaf = true -- 基本设置 entry({'admin', 'services', 'vssr', 'client'}, cbi('vssr/client'), _('SSR Client'), 10).leaf = true -- 基本设置
entry({'admin', 'services', 'vssr', 'servers'}, cbi('vssr/servers'), _('Severs Nodes'), 11).leaf = true -- 服务器节点 entry({'admin', 'services', 'vssr', 'servers'}, cbi('vssr/servers'), _('Severs Nodes'), 11).leaf = true -- 服务器节点
@ -254,7 +254,7 @@ function refresh_data()
retstring = '-1' retstring = '-1'
end end
elseif set == 'ip_data' then elseif set == 'ip_data' then
local ip_data_url = uci:get("vssr","@socks5_proxy[0]","ip_data_url") local ip_data_url = uci:get('vssr', '@socks5_proxy[0]', 'ip_data_url')
refresh_cmd = "wget-ssl -O- '" .. ip_data_url .. "' > /tmp/china_ssr.txt 2>/dev/null" refresh_cmd = "wget-ssl -O- '" .. ip_data_url .. "' > /tmp/china_ssr.txt 2>/dev/null"
sret = luci.sys.call(refresh_cmd) sret = luci.sys.call(refresh_cmd)
icount = luci.sys.exec('cat /tmp/china_ssr.txt | wc -l') icount = luci.sys.exec('cat /tmp/china_ssr.txt | wc -l')

View File

@ -1,11 +1,4 @@
--[[
Author: your name
Date: 2019-11-11 09:33:07
LastEditTime: 2021-01-14 18:50:06
LastEditors: Please set LastEditors
Description: In User Settings Edit
FilePath: \luci-app-vssr\luasrc\model\cbi\vssr\socks5.lua
--]]
local vssr = 'vssr' local vssr = 'vssr'
local uci = luci.model.uci.cursor() local uci = luci.model.uci.cursor()
local server_table = {} local server_table = {}

View File

@ -21,6 +21,8 @@ CONFIG_UDP_FILE=/var/etc/${NAME}_u.json
CONFIG_SOCK5_FILE=/var/etc/${NAME}_s.json CONFIG_SOCK5_FILE=/var/etc/${NAME}_s.json
CRON_FILE=/etc/crontabs/root CRON_FILE=/etc/crontabs/root
LOCK_FILE=/var/lock/vssr.lock
#定义可执行文件路径 #定义可执行文件路径
VSSR_RULES_BIN=/usr/bin/vssr-rules VSSR_RULES_BIN=/usr/bin/vssr-rules
@ -39,6 +41,30 @@ switch_server=$1
MAXFD=32768 MAXFD=32768
threads=1 threads=1
set_lock() {
exec 1000>"$LOCK_FILE"
flock -xn 1000
}
unset_lock() {
flock -u 1000
rm -rf "$LOCK_FILE"
}
unlock() {
failcount=1
while [ "$failcount" -le 10 ]; do
if [ -f "$LOCK_FILE" ]; then
echo "$(date "+%Y-%m-%d %H:%M:%S") wait for file unlock: $failcount count" >> /tmp/vssr.log
let "failcount++"
sleep 1s
[ "$failcount" -ge 10 ] && unset_lock
else
break
fi
done
}
#读取 uci 数据 #读取 uci 数据
uci_get_by_name() { uci_get_by_name() {
@ -374,8 +400,6 @@ start_redir() {
local stype=$(uci_get_by_name $GLOBAL_SERVER type) local stype=$(uci_get_by_name $GLOBAL_SERVER type)
sscmd=$(find_bin $stype) sscmd=$(find_bin $stype)
if [ "$(uci_get_by_type global threads 0)" = "0" ]; then if [ "$(uci_get_by_type global threads 0)" = "0" ]; then
threads=$(cat /proc/cpuinfo | grep 'processor' | wc -l) threads=$(cat /proc/cpuinfo | grep 'processor' | wc -l)
else else
@ -576,6 +600,7 @@ rules() {
} }
start() { start() {
set_lock
if [ -z "$switch_server" ]; then if [ -z "$switch_server" ]; then
GLOBAL_SERVER=$(uci_get_by_type global global_server) GLOBAL_SERVER=$(uci_get_by_type global global_server)
else else
@ -635,6 +660,8 @@ EOF
fi fi
fi fi
unset_lock
ENABLE_SERVER=$(uci_get_by_type global global_server) ENABLE_SERVER=$(uci_get_by_type global global_server)
[ "$ENABLE_SERVER" = "nil" ] && return 1 [ "$ENABLE_SERVER" = "nil" ] && return 1
} }
@ -644,6 +671,9 @@ boot() {
} }
stop() { stop() {
unlock
set_lock
echo "stop" echo "stop"
/usr/bin/vssr-rules -f /usr/bin/vssr-rules -f
srulecount=$(iptables -L | grep SSR-SERVER-RULE | wc -l) srulecount=$(iptables -L | grep SSR-SERVER-RULE | wc -l)
@ -665,4 +695,6 @@ stop() {
/etc/init.d/dnsmasq restart >/dev/null 2>&1 /etc/init.d/dnsmasq restart >/dev/null 2>&1
fi fi
del_cron del_cron
unset_lock
} }

View File

@ -185,8 +185,6 @@ tp_rule() {
ip route add local 0.0.0.0/0 dev lo table 100 ip route add local 0.0.0.0/0 dev lo table 100
local ipt="iptables -t mangle" local ipt="iptables -t mangle"
$ipt -N SS_SPEC_TPROXY $ipt -N SS_SPEC_TPROXY
$ipt -A SS_SPEC_TPROXY -p udp --dport 443 -j RETURN
$ipt -A SS_SPEC_TPROXY -p udp --dport 80 -j RETURN
$ipt -A SS_SPEC_TPROXY -p udp --dport 53 -j RETURN $ipt -A SS_SPEC_TPROXY -p udp --dport 53 -j RETURN
$ipt -A SS_SPEC_TPROXY -p udp -d 0.0.0.0/8 -j RETURN $ipt -A SS_SPEC_TPROXY -p udp -d 0.0.0.0/8 -j RETURN
$ipt -A SS_SPEC_TPROXY -p udp -d 10.0.0.0/8 -j RETURN $ipt -A SS_SPEC_TPROXY -p udp -d 10.0.0.0/8 -j RETURN

View File

@ -1,9 +1,11 @@
#!/usr/bin/lua #!/usr/bin/lua
------------------------------------------------ ------------------------------------------------
-- This file is converter ip to country iso code -- This file is converter ip to country iso code
-- @author Jerryk <jerrykuku@qq.com> -- @author Jerryk <jerrykuku@qq.com>
------------------------------------------------ ------------------------------------------------
local _M = {} local _M = {}
-- Get country iso code with remark or host -- Get country iso code with remark or host
@ -17,7 +19,30 @@ function _M.get_flag(remark, host)
local search_table = json.decode(json_string) local search_table = json.decode(json_string)
local iso_code = nil local iso_code = nil
local delete_table = {'%b[]', 'networks', 'test', 'game', 'gaming', 'tls', 'iepl', 'aead', 'hgc', 'hkbn', 'netflix', 'disney', 'hulu', 'hinet','sb','az','aws','cn','ss','ssr','trojan','all'} local delete_table = {
'%b[]',
'networks',
'test',
'game',
'gaming',
'tls',
'iepl',
'aead',
'hgc',
'hkbn',
'netflix',
'disney',
'hulu',
'hinet',
'sb',
'az',
'aws',
'cn',
'ss',
'ssr',
'trojan',
'all'
}
if (remark ~= nil) then if (remark ~= nil) then
-- 过滤 -- 过滤
remark = string.lower(remark) remark = string.lower(remark)

View File

@ -12,10 +12,10 @@ function read_conf(file)
if not nixio.fs.access(file) then if not nixio.fs.access(file) then
return nil return nil
end end
local rfile = io.open(file, "r") local rfile = io.open(file, 'r')
local ltable = {} local ltable = {}
for line in rfile:lines() do for line in rfile:lines() do
local re = string.gsub(line, "\r", "") local re = string.gsub(line, '\r', '')
table.insert(ltable, re) table.insert(ltable, re)
end end
local rtable = next(ltable) ~= nil and ltable or nil local rtable = next(ltable) ~= nil and ltable or nil
@ -24,27 +24,26 @@ end
local v2ray_flow = ucursor:get_first(name, 'global', 'v2ray_flow', '0') local v2ray_flow = ucursor:get_first(name, 'global', 'v2ray_flow', '0')
local custom_domain = read_conf("/etc/vssr/custom_domain.list") local custom_domain = read_conf('/etc/vssr/custom_domain.list')
local custom_ip = read_conf("/etc/vssr/custom_ip.list") local custom_ip = read_conf('/etc/vssr/custom_ip.list')
local youtube_domain = read_conf("/etc/vssr/youtube_domain.list") local youtube_domain = read_conf('/etc/vssr/youtube_domain.list')
local youtube_ip = read_conf("/etc/vssr/youtube_ip.list") local youtube_ip = read_conf('/etc/vssr/youtube_ip.list')
local tw_video_domain = read_conf("/etc/vssr/tw_video_domain.list") local tw_video_domain = read_conf('/etc/vssr/tw_video_domain.list')
local tw_video_ip = read_conf("/etc/vssr/tw_video_ip.list") local tw_video_ip = read_conf('/etc/vssr/tw_video_ip.list')
local netflix_domain = read_conf("/etc/vssr/netflix_domain.list") local netflix_domain = read_conf('/etc/vssr/netflix_domain.list')
local netflix_ip = read_conf("/etc/vssr/netflix_ip.list") local netflix_ip = read_conf('/etc/vssr/netflix_ip.list')
local disney_domain = read_conf("/etc/vssr/disney_domain.list") local disney_domain = read_conf('/etc/vssr/disney_domain.list')
local disney_ip = read_conf("/etc/vssr/disney_ip.list") local disney_ip = read_conf('/etc/vssr/disney_ip.list')
local prime_domain = read_conf("/etc/vssr/prime_domain.list") local prime_domain = read_conf('/etc/vssr/prime_domain.list')
local prime_ip = read_conf("/etc/vssr/prime_ip.list") local prime_ip = read_conf('/etc/vssr/prime_ip.list')
local tvb_domain = read_conf("/etc/vssr/tvb_domain.list")
local tvb_ip = read_conf("/etc/vssr/tvb_ip.list")
local tvb_domain = read_conf('/etc/vssr/tvb_domain.list')
local tvb_ip = read_conf('/etc/vssr/tvb_ip.list')
local flow_table = { local flow_table = {
yotube = { yotube = {
@ -125,7 +124,7 @@ function gen_outbound(server_node, tags, local_ports)
bound = nil bound = nil
else else
local server = ucursor:get_all(name, server_node) local server = ucursor:get_all(name, server_node)
local node_type = server.type == "vless" and "vless" or "vmess" local node_type = server.type == 'vless' and 'vless' or 'vmess'
if server.type ~= 'v2ray' and server.type ~= 'vless' then if server.type ~= 'v2ray' and server.type ~= 'vless' then
bound = { bound = {
@ -133,7 +132,7 @@ function gen_outbound(server_node, tags, local_ports)
protocol = 'socks', protocol = 'socks',
settings = { settings = {
servers = { servers = {
{ address = '127.0.0.1', port = tonumber(local_ports) } {address = '127.0.0.1', port = tonumber(local_ports)}
} }
} }
} }
@ -149,10 +148,10 @@ function gen_outbound(server_node, tags, local_ports)
users = { users = {
{ {
id = server.vmess_id, id = server.vmess_id,
alterId = server.type == "v2ray" and tonumber(server.alter_id) or nil, alterId = server.type == 'v2ray' and tonumber(server.alter_id) or nil,
security = server.type == "v2ray" and server.security or nil, security = server.type == 'v2ray' and server.security or nil,
flow = (server.xtls == '1') and (server.vless_flow and server.vless_flow or "xtls-rprx-origin") or nil, flow = (server.xtls == '1') and (server.vless_flow and server.vless_flow or 'xtls-rprx-origin') or nil,
encryption = server.type == "vless" and server.vless_encryption or nil encryption = server.type == 'vless' and server.vless_encryption or nil
} }
} }
} }
@ -161,9 +160,9 @@ function gen_outbound(server_node, tags, local_ports)
-- 底层传输配置 -- 底层传输配置
streamSettings = { streamSettings = {
network = server.transport, network = server.transport,
security = (server.tls == '1') and ((server.xtls == '1') and "xtls" or "tls") or "none", security = (server.tls == '1') and ((server.xtls == '1') and 'xtls' or 'tls') or 'none',
tlsSettings = (server.tls == '1' and server.xtls ~= '1') and { allowInsecure = (server.insecure ~= "0") and true or false, serverName = server.tls_host, } or nil, tlsSettings = (server.tls == '1' and server.xtls ~= '1') and {allowInsecure = (server.insecure ~= '0') and true or false, serverName = server.tls_host} or nil,
xtlsSettings = (server.xtls == '1') and { allowInsecure = (server.insecure ~= "0") and true or false, serverName = server.tls_host, } or nil, xtlsSettings = (server.xtls == '1') and {allowInsecure = (server.insecure ~= '0') and true or false, serverName = server.tls_host} or nil,
kcpSettings = (server.transport == 'kcp') and kcpSettings = (server.transport == 'kcp') and
{ {
mtu = tonumber(server.mtu), mtu = tonumber(server.mtu),
@ -173,21 +172,21 @@ function gen_outbound(server_node, tags, local_ports)
congestion = (server.congestion == '1') and true or false, congestion = (server.congestion == '1') and true or false,
readBufferSize = tonumber(server.read_buffer_size), readBufferSize = tonumber(server.read_buffer_size),
writeBufferSize = tonumber(server.write_buffer_size), writeBufferSize = tonumber(server.write_buffer_size),
header = { type = server.kcp_guise } header = {type = server.kcp_guise}
} or } or
nil, nil,
wsSettings = (server.transport == 'ws') and (server.ws_path ~= nil or server.ws_host ~= nil) and wsSettings = (server.transport == 'ws') and (server.ws_path ~= nil or server.ws_host ~= nil) and
{ {
path = server.ws_path, path = server.ws_path,
headers = (server.ws_host ~= nil) and { Host = server.ws_host } or nil headers = (server.ws_host ~= nil) and {Host = server.ws_host} or nil
} or } or
nil, nil,
httpSettings = (server.transport == 'h2') and { path = server.h2_path, host = server.h2_host } or nil, httpSettings = (server.transport == 'h2') and {path = server.h2_path, host = server.h2_host} or nil,
quicSettings = (server.transport == 'quic') and quicSettings = (server.transport == 'quic') and
{ {
security = server.quic_security, security = server.quic_security,
key = server.quic_key, key = server.quic_key,
header = { type = server.quic_guise } header = {type = server.quic_guise}
} or } or
nil nil
}, },
@ -202,7 +201,6 @@ function gen_outbound(server_node, tags, local_ports)
end end
if v2ray_flow == '1' then if v2ray_flow == '1' then
table.insert(outbounds_table, gen_outbound(server_section, 'global', 2080)) table.insert(outbounds_table, gen_outbound(server_section, 'global', 2080))
for _, v in pairs(flow_table) do for _, v in pairs(flow_table) do
if (v.rules.domain ~= nil or v.rules.ip ~= nil) then if (v.rules.domain ~= nil or v.rules.ip ~= nil) then
@ -243,15 +241,15 @@ local v2ray = {
{ {
port = tonumber(local_port), port = tonumber(local_port),
protocol = 'dokodemo-door', protocol = 'dokodemo-door',
settings = { network = proto, followRedirect = true }, settings = {network = proto, followRedirect = true},
sniffing = { enabled = true, destOverride = { 'http', 'tls' } }, sniffing = {enabled = true, destOverride = {'http', 'tls'}},
streamSettings = { streamSettings = {
sockopt = { tproxy = (proto == 'tcp') and 'redirect' or 'tproxy' } sockopt = {tproxy = (proto == 'tcp') and 'redirect' or 'tproxy'}
} }
} }
}, },
-- 传出连接 -- 传出连接
outbounds = outbounds_table, outbounds = outbounds_table,
routing = { domainStrategy = 'IPIfNonMatch', rules = rules_table } routing = {domainStrategy = 'IPIfNonMatch', rules = rules_table}
} }
print(json.stringify(v2ray, 1)) print(json.stringify(v2ray, 1))

View File

@ -4,6 +4,8 @@
-- 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 'nixio' require 'nixio'
require 'luci.util' require 'luci.util'
require 'luci.jsonc' require 'luci.jsonc'
@ -13,9 +15,7 @@ require 'luci.sys'
-- so caching them is worth the effort -- so caching them is worth the effort
local luci = luci local luci = luci
local tinsert = table.insert local tinsert = table.insert
local ssub, slen, schar, sbyte, sformat, sgsub = string.sub, string.len, local ssub, slen, schar, sbyte, sformat, sgsub = string.sub, string.len, string.char, string.byte, string.format, string.gsub
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 = {}
@ -25,31 +25,26 @@ 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 = '0' local switch = '0'
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',
'过期时间/剩余流量')
function print_r(t) function print_r(t)
local print_r_cache = {} local print_r_cache = {}
local function sub_print_r(t, indent) local function sub_print_r(t, indent)
if (print_r_cache[tostring(t)]) then if (print_r_cache[tostring(t)]) then
print(indent .. "*" .. tostring(t)) print(indent .. '*' .. tostring(t))
else else
print_r_cache[tostring(t)] = true print_r_cache[tostring(t)] = true
if (type(t) == "table") then if (type(t) == 'table') then
for pos, val in pairs(t) do for pos, val in pairs(t) do
if (type(val) == "table") then if (type(val) == 'table') then
print(indent .. "[" .. pos .. "] => " .. tostring(t) .. print(indent .. '[' .. pos .. '] => ' .. tostring(t) .. ' {')
" {") sub_print_r(val, indent .. string.rep(' ', string.len(pos) + 8))
sub_print_r(val, indent .. print(indent .. string.rep(' ', string.len(pos) + 6) .. '}')
string.rep(" ", string.len(pos) + 8)) elseif (type(val) == 'string') then
print(indent .. string.rep(" ", string.len(pos) + 6) .. print(indent .. '[' .. pos .. '] => "' .. val .. '"')
"}")
elseif (type(val) == "string") then
print(indent .. "[" .. pos .. '] => "' .. val .. '"')
else else
print(indent .. "[" .. pos .. "] => " .. tostring(val)) print(indent .. '[' .. pos .. '] => ' .. tostring(val))
end end
end end
else else
@ -57,12 +52,13 @@ function print_r(t)
end end
end end
end end
if (type(t) == "table") then
print(tostring(t) .. " {") if (type(t) == 'table') then
sub_print_r(t, " ") print(tostring(t) .. ' {')
print("}") sub_print_r(t, ' ')
print('}')
else else
sub_print_r(t, " ") sub_print_r(t, ' ')
end end
print() print()
end end
@ -95,7 +91,7 @@ end
local function clone(object) local function clone(object)
local lookup_table = {} local lookup_table = {}
local function copyObj(object) local function copyObj(object)
if type(object) ~= "table" then if type(object) ~= 'table' then
return object return object
elseif lookup_table[object] then elseif lookup_table[object] then
return lookup_table[object] return lookup_table[object]
@ -108,6 +104,7 @@ local function clone(object)
end end
return setmetatable(new_table, getmetatable(object)) return setmetatable(new_table, getmetatable(object))
end end
return copyObj(object) return copyObj(object)
end end
@ -119,7 +116,6 @@ local function table_unique(list)
if v1.alias ~= v2.alias and v1.hashkey == v2.hashkey then if v1.alias ~= v2.alias and v1.hashkey == v2.hashkey then
table.remove(temp1, k1) table.remove(temp1, k1)
table.remove(temp2, k1) table.remove(temp2, k1)
end end
end end
end end
@ -127,7 +123,9 @@ local function table_unique(list)
end end
-- urlencode -- urlencode
local function get_urlencode(c) return sformat('%%%02X', sbyte(c)) end local function get_urlencode(c)
return sformat('%%%02X', sbyte(c))
end
local function urlEncode(szText) local function urlEncode(szText)
local str = szText:gsub('([^0-9a-zA-Z ])', get_urlencode) local str = szText:gsub('([^0-9a-zA-Z ])', get_urlencode)
@ -135,27 +133,35 @@ local function urlEncode(szText)
return str return str
end end
local function get_urldecode(h) return schar(tonumber(h, 16)) end local function get_urldecode(h)
return schar(tonumber(h, 16))
end
local function UrlDecode(szText) local function UrlDecode(szText)
return szText:gsub('+', ' '):gsub('%%(%x%x)', get_urldecode) return szText:gsub('+', ' '):gsub('%%(%x%x)', get_urldecode)
end end
-- trim -- trim
local function trim(text) local function trim(text)
if not text or text == '' then return '' end if not text or text == '' then
return ''
end
return (sgsub(text, '^%s*(.-)%s*$', '%1')) return (sgsub(text, '^%s*(.-)%s*$', '%1'))
end end
-- md5 -- md5
local function md5(content) local function md5(content)
local stdout = luci.sys.exec('echo "' .. urlEncode(content) .. local stdout = luci.sys.exec('echo "' .. urlEncode(content) .. '" | md5sum | cut -d " " -f1')
'" | md5sum | cut -d " " -f1')
-- assert(nixio.errno() == 0) -- assert(nixio.errno() == 0)
return trim(stdout) return trim(stdout)
end end
-- base64 -- base64
local function base64Decode(text) local function base64Decode(text)
local raw = text local raw = text
if not text then return '' end if not text then
return ''
end
text = text:gsub('%z', '') text = text:gsub('%z', '')
text = text:gsub('_', '/') text = text:gsub('_', '/')
text = text:gsub('-', '+') text = text:gsub('-', '+')
@ -168,6 +174,7 @@ local function base64Decode(text)
return raw return raw
end end
end end
-- 处理数据 -- 处理数据
local function processData(szType, content, groupName) local function processData(szType, content, groupName)
local result = { local result = {
@ -198,7 +205,9 @@ local function processData(szType, content, groupName)
result.obfs_param = base64Decode(params.obfsparam) result.obfs_param = base64Decode(params.obfsparam)
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 result.alias = '[' .. group .. '] ' end if group then
result.alias = '[' .. group .. '] '
end
result.alias = result.alias .. base64Decode(params.remarks) result.alias = result.alias .. base64Decode(params.remarks)
elseif szType == 'vmess' then elseif szType == 'vmess' then
local info = jsonParse(content) local info = jsonParse(content)
@ -238,7 +247,9 @@ local function processData(szType, content, groupName)
result.quic_key = info.key result.quic_key = info.key
result.quic_security = info.securty result.quic_security = info.securty
end end
if info.security then result.security = info.security end if info.security then
result.security = info.security
end
if info.tls == 'tls' or info.tls == '1' then if info.tls == 'tls' or info.tls == '1' then
result.tls = '1' result.tls = '1'
result.tls_host = info.host result.tls_host = info.host
@ -274,14 +285,13 @@ local function processData(szType, content, groupName)
local idx_pn = plugin_info:find(';') local idx_pn = plugin_info:find(';')
if idx_pn then if idx_pn then
result.plugin = plugin_info:sub(1, idx_pn - 1) result.plugin = plugin_info:sub(1, idx_pn - 1)
result.plugin_opts = result.plugin_opts = plugin_info:sub(idx_pn + 1, #plugin_info)
plugin_info:sub(idx_pn + 1, #plugin_info)
else else
result.plugin = plugin_info result.plugin = plugin_info
end end
-- 部分机场下发的插件名为 simple-obfs这里应该改为 obfs-local -- 部分机场下发的插件名为 simple-obfs这里应该改为 obfs-local
if result.plugin == "simple-obfs" then if result.plugin == 'simple-obfs' then
result.plugin = "obfs-local" result.plugin = 'obfs-local'
end end
end end
else else
@ -325,8 +335,8 @@ local function processData(szType, content, groupName)
result.server_port = content.port result.server_port = content.port
result.password = content.password result.password = content.password
result.encrypt_method_ss = content.encryption result.encrypt_method_ss = content.encryption
if content.plugin == "simple-obfs" then if content.plugin == 'simple-obfs' then
result.plugin = "obfs-local" result.plugin = 'obfs-local'
else else
result.plugin = content.plugin result.plugin = content.plugin
end end
@ -338,7 +348,7 @@ local function processData(szType, content, groupName)
if result.server and result.server_port then if result.server and result.server_port then
result.alias = result.server .. ':' .. result.server_port result.alias = result.server .. ':' .. result.server_port
else else
result.alias = "NULL" result.alias = 'NULL'
end end
end end
-- alias 不参与 hashkey 计算 -- alias 不参与 hashkey 计算
@ -354,21 +364,22 @@ local function processData(szType, content, groupName)
return result return result
end end
-- wget -- wget
local function wget(url) local function wget(url)
local stdout = luci.sys.exec( local stdout =
'wget-ssl -q --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36" --no-check-certificate -t 3 -T 10 -O- "' .. luci.sys.exec(
url .. '"') 'wget-ssl -q --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36" --no-check-certificate -t 3 -T 10 -O- "' .. url .. '"'
)
return trim(stdout) return trim(stdout)
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
@ -383,10 +394,9 @@ local execute = function()
luci.sys.init.stop(name) luci.sys.init.stop(name)
end end
for k, url in ipairs(subscribe_url) do for k, url in ipairs(subscribe_url) do
local groupName = "" local groupName = ''
urlTable = split(url, ",") urlTable = split(url, ',')
groupName = groupName = table.getn(urlTable) > 1 and '[' .. urlTable[1] .. '] ' or ''
table.getn(urlTable) > 1 and '[' .. urlTable[1] .. '] ' or ""
url = table.getn(urlTable) > 1 and urlTable[2] or url url = table.getn(urlTable) > 1 and urlTable[2] or url
local raw = wget(url) local raw = wget(url)
if #raw > 0 then if #raw > 0 then
@ -427,12 +437,9 @@ local execute = function()
local dat = split(node, '://') local dat = split(node, '://')
if dat and dat[1] and dat[2] then if dat and dat[1] and dat[2] then
if dat[1] == 'ss' then if dat[1] == 'ss' then
result = result = processData(dat[1], dat[2], groupName)
processData(dat[1], dat[2], groupName)
else else
result = processData(dat[1], result = processData(dat[1], base64Decode(dat[2]), groupName)
base64Decode(dat[2]),
groupName)
end end
end end
else else
@ -440,19 +447,13 @@ local execute = function()
end end
-- log(result) -- log(result)
if result then if result then
if not result.server or not result.server_port or if not result.server or not result.server_port or result.alias == 'NULL' or check_filer(result) or result.server:match('[^0-9a-zA-Z%-%.%s]') then -- 中文做地址的 也没有人拿中文域名搞就算中文域也有Puny Code SB 机场
result.alias == "NULL" or check_filer(result) or log('丢弃无效节点: ' .. result.type .. ' 节点, ' .. result.alias)
result.server:match("[^0-9a-zA-Z%-%.%s]") -- 中文做地址的 也没有人拿中文域名搞就算中文域也有Puny Code SB 机场
then
log('丢弃无效节点: ' .. result.type ..
' 节点, ' .. result.alias)
else else
log('成功解析: ' .. result.type .. log('成功解析: ' .. result.type .. ' 节点, ' .. result.alias)
' 节点, ' .. result.alias)
result.grouphashkey = groupHash result.grouphashkey = groupHash
tinsert(nodeResult[index], result) tinsert(nodeResult[index], result)
cache[groupHash][result.hashkey] = cache[groupHash][result.hashkey] = nodeResult[index][#nodeResult[index]]
nodeResult[index][#nodeResult[index]]
end end
end end
end end
@ -466,7 +467,7 @@ local execute = function()
-- diff -- diff
do do
if next(nodeResult) == nil then if next(nodeResult) == nil then
log("更新失败,没有可用的节点信息") log('更新失败,没有可用的节点信息')
if proxy == '0' then if proxy == '0' then
luci.sys.init.start(name) luci.sys.init.start(name)
log('订阅失败, 恢复服务') log('订阅失败, 恢复服务')
@ -474,18 +475,19 @@ local execute = function()
return return
end end
local add, del = 0, 0 local add, del = 0, 0
ucic:foreach(name, uciType, function(old) ucic:foreach(
name,
uciType,
function(old)
if old.grouphashkey or old.hashkey then -- 没有 hash 的不参与删除 if old.grouphashkey or old.hashkey then -- 没有 hash 的不参与删除
if not nodeResult[old.grouphashkey] or if not nodeResult[old.grouphashkey] or not nodeResult[old.grouphashkey][old.hashkey] then
not nodeResult[old.grouphashkey][old.hashkey] then
ucic:delete(name, old['.name']) ucic:delete(name, old['.name'])
del = del + 1 del = del + 1
else else
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], setmetatable(nodeResult[old.grouphashkey][old.hashkey], {__index = {_ignore = true}})
{__index = {_ignore = true}})
end end
else else
if not old.alias then if not old.alias then
@ -499,7 +501,8 @@ local execute = function()
log('忽略手动添加的节点: ' .. old.alias) log('忽略手动添加的节点: ' .. old.alias)
end end
end end
end) end
)
for k, v in ipairs(nodeResult) do for k, v in ipairs(nodeResult) do
-- 如果订阅节点中有相同的节点信息 需要先去重。 -- 如果订阅节点中有相同的节点信息 需要先去重。
@ -519,36 +522,36 @@ local execute = function()
local firstServer = ucic:get_first(name, uciType) local firstServer = ucic:get_first(name, uciType)
if not ucic:get(name, globalServer) then if not ucic:get(name, globalServer) then
if firstServer then if firstServer then
ucic:set(name, ucic:get_first(name, 'global'), 'global_server', ucic:set(name, ucic:get_first(name, 'global'), 'global_server', firstServer)
firstServer)
ucic:commit(name) ucic:commit(name)
log('当前主服务器已更新,正在自动更换。') log('当前主服务器已更新,正在自动更换。')
end end
end end
if firstServer then if firstServer then
luci.sys.call('/etc/init.d/' .. name .. luci.sys.call('/etc/init.d/' .. name .. ' restart > /dev/null 2>&1') -- 不加&的话日志会出现的更早
' restart > /dev/null 2>&1 &') -- 不加&的话日志会出现的更早
else else
luci.sys.call('/etc/init.d/' .. name .. ' stop > /dev/null 2>&1 &') -- 不加&的话日志会出现的更早 luci.sys.call('/etc/init.d/' .. name .. ' stop > /dev/null 2>&1') -- 不加&的话日志会出现的更早
end end
log('新增节点数量: ' .. add, '删除节点数量: ' .. del) log('新增节点数量: ' .. add, '删除节点数量: ' .. del)
log('更新成功服务正在启动') log('更新成功服务启动成功')
log('END SUBSCRIBE') log('END SUBSCRIBE')
end end
end end
if subscribe_url and #subscribe_url > 0 then if subscribe_url and #subscribe_url > 0 then
xpcall(execute, function(e) xpcall(
execute,
function(e)
log(e) log(e)
-- log(debug.traceback()) log(debug.traceback())
log('发生错误, 正在恢复服务') log('发生错误, 正在恢复服务')
log('END SUBSCRIBE') log('END SUBSCRIBE')
local firstServer = ucic:get_first(name, uciType) local firstServer = ucic:get_first(name, uciType)
if firstServer then if firstServer then
luci.sys.call('/etc/init.d/' .. name .. luci.sys.call('/etc/init.d/' .. name .. ' restart > /dev/null 2>&1') -- 不加&的话日志会出现的更早
' restart > /dev/null 2>&1 &') -- 不加&的话日志会出现的更早
else else
luci.sys.call('/etc/init.d/' .. name .. ' stop > /dev/null 2>&1 &') -- 不加&的话日志会出现的更早 luci.sys.call('/etc/init.d/' .. name .. ' stop > /dev/null 2>&1') -- 不加&的话日志会出现的更早
end end
end) end
)
end end

View File

@ -1,9 +1,11 @@
#!/usr/bin/lua #!/usr/bin/lua
------------------------------------------------ ------------------------------------------------
-- 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 'nixio' require 'nixio'
require 'luci.util' require 'luci.util'
require 'luci.jsonc' require 'luci.jsonc'
@ -39,8 +41,8 @@ else
end end
log('正在更新【国内IP段】数据库') log('正在更新【国内IP段】数据库')
local ip_data_url = ucic:get("vssr","@socks5_proxy[0]","ip_data_url") local ip_data_url = ucic:get('vssr', '@socks5_proxy[0]', 'ip_data_url')
refresh_cmd ="wget-ssl -O- '".. ip_data_url .."' > /tmp/china_ssr.txt 2>/dev/null" refresh_cmd = "wget-ssl -O- '" .. ip_data_url .. "' > /tmp/china_ssr.txt 2>/dev/null"
sret = luci.sys.call(refresh_cmd) sret = luci.sys.call(refresh_cmd)
icount = luci.sys.exec('cat /tmp/china_ssr.txt | wc -l') icount = luci.sys.exec('cat /tmp/china_ssr.txt | wc -l')
if sret == 0 then if sret == 0 then