diff --git a/package/ctcgfw/luci-app-vssr-coexist/luasrc/controller/vssr.lua b/package/ctcgfw/luci-app-vssr-coexist/luasrc/controller/vssr.lua
index 12e970c7b5..95fdd3ff55 100644
--- a/package/ctcgfw/luci-app-vssr-coexist/luasrc/controller/vssr.lua
+++ b/package/ctcgfw/luci-app-vssr-coexist/luasrc/controller/vssr.lua
@@ -3,10 +3,12 @@
module("luci.controller.vssr", package.seeall)
function index()
- if not nixio.fs.access("/etc/config/vssr") then return end
+ if not nixio.fs.access("/etc/config/vssr") then
+ return
+end
if nixio.fs.access("/usr/bin/ssr-redir") then
- entry({"admin", "vpn"}, firstchild(), "VPN", 45).dependent = false
+ entry({"admin", "vpn"}, firstchild(), "VPN", 45).dependent = false
entry({"admin", "vpn", "vssr"},
alias("admin", "vpn", "vssr", "client"), _("vssr"), 10).dependent =
true -- 首页
@@ -20,6 +22,7 @@ function index()
entry({"admin", "vpn", "vssr", "subscription"},cbi("vssr/subscription"), _("Subscription"),12).leaf = true
entry({"admin", "vpn", "vssr", "control"}, cbi("vssr/control"),
_("Access Control"), 13).leaf = true -- 访问控制
+
entry({"admin", "vpn", "vssr", "advanced"}, cbi("vssr/advanced"),
_("Advanced Settings"), 14).leaf = true -- 高级设置
elseif nixio.fs.access("/usr/bin/ssr-server") then
@@ -41,6 +44,7 @@ entry({"admin", "vpn", "vssr", "status"},form("vssr/status"),_("Status"), 23).le
entry({"admin", "vpn", "vssr", "refresh"}, call("refresh_data")) -- 更新白名单和GFWLIST
entry({"admin", "vpn", "vssr", "checkport"}, call("check_port")) -- 检测单个端口并返回Ping
+ entry({"admin", "vpn", "vssr", "checkports"}, call("check_ports"))
entry({"admin", "vpn", "vssr", "run"}, call("act_status")) -- 检测全局服务器状态
entry({"admin", "vpn", "vssr", "change"}, call("change_node")) -- 切换节点
entry({"admin", "vpn", "vssr", "allserver"}, call("get_servers")) -- 获取所有节点Json
@@ -88,6 +92,7 @@ function get_subscribe()
end
+
-- 获取所有节点
function get_servers()
local uci = luci.model.uci.cursor()
@@ -191,6 +196,19 @@ function act_status()
luci.http.write_json(e)
end
+function check_status()
+ local set ="/usr/bin/ssr-check www." .. luci.http.formvalue("set") .. ".com 80 3 1"
+ sret=luci.sys.call(set)
+ if sret== 0 then
+ retstring ="0"
+ else
+ retstring ="1"
+ end
+
+ luci.http.prepare_content("application/json")
+ luci.http.write_json({ ret=retstring })
+end
+
-- 刷新检测文件
function refresh_data()
local set = luci.http.formvalue("set")
@@ -208,11 +226,9 @@ function refresh_data()
luci.sys.call("/usr/bin/vssr-gfw")
icount = luci.sys.exec("cat /tmp/gfwnew.txt | wc -l")
if tonumber(icount) > 1000 then
- oldcount = luci.sys.exec(
- "cat /etc/dnsmasq.ssr/gfw_list.conf | wc -l")
+ oldcount = luci.sys.exec("cat /etc/dnsmasq.ssr/gfw_list.conf | wc -l")
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 /etc/dnsmasq.ssr/gfw_list.conf")
retstring = tostring(math.ceil(tonumber(icount) / 2))
else
retstring = "0"
@@ -253,8 +269,7 @@ function refresh_data()
icount = luci.sys.exec("cat /tmp/ad.conf | wc -l")
if tonumber(icount) > 1000 then
if nixio.fs.access("/etc/dnsmasq.ssr/ad.conf") then
- oldcount = luci.sys.exec(
- "cat /etc/dnsmasq.ssr/ad.conf | wc -l")
+ oldcount = luci.sys.exec("cat /etc/dnsmasq.ssr/ad.conf | wc -l")
else
oldcount = 0
end
@@ -280,6 +295,48 @@ function refresh_data()
luci.http.write_json({ret = retstring, retcount = icount})
end
+
+-- 检测所有服务器
+function check_ports()
+ local set = ""
+ local retstring = "
"
+ local s
+ local server_name = ""
+ local vssr = "vssr"
+ local uci = luci.model.uci.cursor()
+ local iret = 1
+
+ uci:foreach(
+ vssr,
+ "servers",
+ function(s)
+ if s.alias then
+ server_name = s.alias
+ elseif s.server and s.server_port then
+ server_name = "%s:%s" % {s.server, s.server_port}
+ end
+ iret = luci.sys.call(" ipset add ss_spec_wan_ac " .. s.server .. " 2>/dev/null")
+ socket = nixio.socket("inet", "stream")
+ socket:setopt("socket", "rcvtimeo", 3)
+ socket:setopt("socket", "sndtimeo", 3)
+ ret = socket:connect(s.server, s.server_port)
+ if tostring(ret) == "true" then
+ socket:close()
+ retstring = retstring .. "[" .. server_name .. "] OK.
"
+ else
+ retstring = retstring .. "[" .. server_name .. "] Error.
"
+ end
+ if iret == 0 then
+ luci.sys.call(" ipset del ss_spec_wan_ac " .. s.server)
+ end
+ end
+ )
+
+ luci.http.prepare_content("application/json")
+ luci.http.write_json({ret = retstring})
+end
+
+
-- 检测单个节点状态并返回连接速度
function check_port()
diff --git a/package/ctcgfw/luci-app-vssr-coexist/luasrc/model/cbi/vssr/advanced.lua b/package/ctcgfw/luci-app-vssr-coexist/luasrc/model/cbi/vssr/advanced.lua
index 4e59c5abad..bef3f0df48 100644
--- a/package/ctcgfw/luci-app-vssr-coexist/luasrc/model/cbi/vssr/advanced.lua
+++ b/package/ctcgfw/luci-app-vssr-coexist/luasrc/model/cbi/vssr/advanced.lua
@@ -92,20 +92,7 @@ s.anonymous = true
o = s:option(Flag, "adblock", translate("Enable adblock"))
o.rmempty = false
--- [[ 更新设置 ]]--
-s = m:section(TypedSection,"socks5_proxy",translate("Update Setting"))
-s.anonymous = true
-
-o = s:option(Button,"gfw_data",translate("GFW List Data"))
-o.rawhtml = true
-o.template = "vssr/refresh"
-o.value =tostring(math.ceil(gfw_count)) .. " " .. translate("Records")
-
-o = s:option(Button,"ip_data",translate("China IP Data"))
-o.rawhtml = true
-o.template = "vssr/refresh"
-o.value =ip_count .. " " .. translate("Records")
diff --git a/package/ctcgfw/luci-app-vssr-coexist/luasrc/model/cbi/vssr/client.lua b/package/ctcgfw/luci-app-vssr-coexist/luasrc/model/cbi/vssr/client.lua
index adb92c3ba5..a72ce8c95d 100644
--- a/package/ctcgfw/luci-app-vssr-coexist/luasrc/model/cbi/vssr/client.lua
+++ b/package/ctcgfw/luci-app-vssr-coexist/luasrc/model/cbi/vssr/client.lua
@@ -5,7 +5,9 @@
local m, s, sec, o, kcp_enable
local vssr = "vssr"
-
+local gfw_count=0
+local ad_count=0
+local ip_count=0
local gfwmode=0
if nixio.fs.access("/etc/dnsmasq.ssr/gfw_list.conf") then
@@ -14,7 +16,18 @@ end
local uci = luci.model.uci.cursor()
+local sys = require "luci.sys"
+if gfwmode==1 then
+ gfw_count = tonumber(sys.exec("cat /etc/dnsmasq.ssr/gfw_list.conf | wc -l"))/2
+ if nixio.fs.access("/etc/dnsmasq.ssr/ad.conf") then
+ ad_count=tonumber(sys.exec("cat /etc/dnsmasq.ssr/ad.conf | wc -l"))
+ end
+end
+
+if nixio.fs.access("/etc/china_ssr.txt") then
+ ip_count = sys.exec("cat /etc/china_ssr.txt | wc -l")
+end
m = Map(vssr)
@@ -147,5 +160,24 @@ o:value("114.114.114.114:53", translate("Oversea Mode DNS-1 (114.114.114.114)"))
o:value("114.114.115.115:53", translate("Oversea Mode DNS-2 (114.114.115.115)"))
o:depends("pdnsd_enable", "1")
+o = s:option(Button,"gfw_data",translate("GFW List Data"))
+o.rawhtml = true
+o.template = "vssr/refresh"
+o.value =tostring(math.ceil(gfw_count)) .. " " .. translate("Records")
+
+o = s:option(Button,"ad_data",translate("Advertising Data"))
+o .rawhtml = true
+o .template = "vssr/refresh"
+o .value =tostring(math.ceil(ad_count)) .. " " .. translate("Records")
+
+o = s:option(Button,"ip_data",translate("China IP Data"))
+o.rawhtml = true
+o.template = "vssr/refresh"
+o.value =ip_count .. " " .. translate("Records")
+
+o = s:option(Button,"check_port",translate("Check Server Port"))
+o.template = "vssr/checkport"
+o.value =translate("No Check")
+
m:section(SimpleSection).template = "vssr/status2"
return m
diff --git a/package/ctcgfw/luci-app-vssr-coexist/root/etc/uci-defaults/luci-vssr b/package/ctcgfw/luci-app-vssr-coexist/root/etc/uci-defaults/luci-vssr
old mode 100644
new mode 100755
diff --git a/package/ctcgfw/luci-app-vssr-coexist/root/usr/share/vssr/genv2config.lua b/package/ctcgfw/luci-app-vssr-coexist/root/usr/share/vssr/genv2config.lua
index b01ee0daec..3b6a3587ca 100755
--- a/package/ctcgfw/luci-app-vssr-coexist/root/usr/share/vssr/genv2config.lua
+++ b/package/ctcgfw/luci-app-vssr-coexist/root/usr/share/vssr/genv2config.lua
@@ -1,95 +1,180 @@
-local ucursor = require "luci.model.uci".cursor()
+local ucursor = require"luci.model.uci".cursor()
+local name = "vssr"
local json = require "luci.jsonc"
local server_section = arg[1]
-local proto = arg[2]
+local proto = arg[2]
local local_port = arg[3]
+local host = arg[4]
-local server = ucursor:get_all("vssr", server_section)
+local v2ray_flow = ucursor:get_first(name, 'global', 'v2ray_flow', '0')
+local youtube_server = ucursor:get_first(name, 'global', 'youtube_server')
+local tw_video_server = ucursor:get_first(name, 'global', 'tw_video_server')
+local netflix_server = ucursor:get_first(name, 'global', 'netflix_server')
+local disney_server = ucursor:get_first(name, 'global', 'disney_server')
+local prime_server = ucursor:get_first(name, 'global', 'prime_server')
-local v2ray = {
- log = {
- -- error = "/var/vssr.log",
- loglevel = "warning"
- },
- -- 传入连接
- inbound = {
- port = local_port,
- protocol = "dokodemo-door",
- settings = {
- network = proto,
- followRedirect = true
- },
- sniffing = {
- enabled = true,
- destOverride = { "http", "tls" }
- }
- },
- -- 传出连接
- outbound = {
- protocol = "vmess",
- settings = {
- vnext = {
- {
- address = server.server,
- port = tonumber(server.server_port),
- users = {
- {
- id = server.vmess_id,
- alterId = tonumber(server.alter_id),
- security = server.security
+function gen_outbound(server_node, tags)
+ local bound = {}
+ if server_node == "nil" then
+ bound = nil
+ else
+ local server = ucursor:get_all(name, server_node)
+ bound = {
+ tag = tags,
+ protocol = "vmess",
+ settings = {
+ vnext = {
+ {
+ address = server.server,
+ port = tonumber(server.server_port),
+ users = {
+ {
+ id = server.vmess_id,
+ alterId = tonumber(server.alter_id),
+ security = server.security
+ }
}
}
}
- }
- },
- -- 底层传输配置
- streamSettings = {
- network = server.transport,
- security = (server.tls == '1') and "tls" or "none",
- tlsSettings = {allowInsecure = (server.insecure == "1") and true or false,},
- kcpSettings = (server.transport == "kcp") and {
- mtu = tonumber(server.mtu),
- tti = tonumber(server.tti),
- uplinkCapacity = tonumber(server.uplink_capacity),
- downlinkCapacity = tonumber(server.downlink_capacity),
- congestion = (server.congestion == "1") and true or false,
- readBufferSize = tonumber(server.read_buffer_size),
- writeBufferSize = tonumber(server.write_buffer_size),
- header = {
- type = server.kcp_guise
- }
- } or nil,
- wsSettings = (server.transport == "ws") and {
- path = server.ws_path,
- headers = (server.ws_host ~= nil) and {
- Host = server.ws_host
+ },
+ -- 底层传输配置
+ streamSettings = {
+ network = server.transport,
+ security = (server.tls == '1') and "tls" or "none",
+ tlsSettings = {
+ allowInsecure = (server.insecure == "1") and true or false,
+ serverName = server.ws_host
+ },
+ kcpSettings = (server.transport == "kcp") and {
+ mtu = tonumber(server.mtu),
+ tti = tonumber(server.tti),
+ uplinkCapacity = tonumber(server.uplink_capacity),
+ downlinkCapacity = tonumber(server.downlink_capacity),
+ congestion = (server.congestion == "1") and true or false,
+ readBufferSize = tonumber(server.read_buffer_size),
+ writeBufferSize = tonumber(server.write_buffer_size),
+ header = {type = server.kcp_guise}
} or nil,
- } or nil,
- httpSettings = (server.transport == "h2") and {
- path = server.h2_path,
- host = server.h2_host,
- } or nil,
- quicSettings = (server.transport == "quic") and {
- security = server.quic_security,
- key = server.quic_key,
- header = {
- type = server.quic_guise
- }
- } or nil
- },
- mux = {
- enabled = (server.mux == "1") and true or false,
- concurrency = tonumber(server.concurrency)
- }
- },
-
- -- 额外传出连接
- outboundDetour = {
- {
- protocol = "freedom",
- tag = "direct",
- settings = { keep = "" }
+ wsSettings = (server.transport == "ws") and
+ (server.ws_path ~= nil or server.ws_host ~= nil) and {
+ path = server.ws_path,
+ headers = (server.ws_host ~= nil) and
+ {Host = server.ws_host} or nil
+ } or nil,
+ httpSettings = (server.transport == "h2") and
+ {path = server.h2_path, host = server.h2_host} or nil,
+ quicSettings = (server.transport == "quic") and {
+ security = server.quic_security,
+ key = server.quic_key,
+ header = {type = server.quic_guise}
+ } or nil
+ },
+ mux = {
+ enabled = (server.mux == "1") and true or false,
+ concurrency = tonumber(server.concurrency)
+ }
}
- }
+ end
+ return bound
+end
+
+local outbounds_table = {}
+
+table.insert(outbounds_table, gen_outbound(server_section, "main"))
+if v2ray_flow == "1" then
+ table.insert(outbounds_table, gen_outbound(youtube_server, "youtube"))
+ table.insert(outbounds_table, gen_outbound(tw_video_server, "twvideo"))
+ table.insert(outbounds_table, gen_outbound(netflix_server, "netflix"))
+ table.insert(outbounds_table, gen_outbound(disney_server, "disney"))
+ table.insert(outbounds_table, gen_outbound(prime_server, "prime"))
+end
+
+-- rules gen
+
+local youtube_rule = {
+ type = "field",
+ domain = {"youtube", "googlevideo.com", "gvt2.com", "youtu.be"},
+ outboundTag = "youtube"
+}
+
+local tw_video_rule = {
+ type = "field",
+ domain = {
+ "vidol.tv", "hinet.net", "books.com", "litv.tv", "pstatic.net",
+ "app-measurement.com", "kktv.com.tw", "gamer.com.tw"
+ },
+ outboundTag = "twvideo"
+}
+
+local netflix_rule = {
+ type = "field",
+ domain = {
+ "netflix.com", "netflix.net", "nflxso.net", "nflxext.com",
+ "nflximg.com", "nflximg.net", "nflxvideo.net"
+ },
+ ip = {
+ "23.246.0.0/12", "37.77.0.0/12", "45.57.0.0/12", "64.120.128.0/17",
+ "66.197.128.0/17", "108.175.0.0/12", "185.2.0.0/12", "185.9.188.0/22",
+ "192.173.64.0/18", "198.38.0.0/12", "198.45.0.0/12"
+ },
+ outboundTag = "netflix"
+}
+
+local disney_rule = {
+ type = "field",
+ domain = {
+ "cdn.registerdisney.go.com", "disneyplus.com", "disney-plus.net",
+ "dssott.com", "bamgrid.com", "execute-api.us-east-1.amazonaws.com"
+ },
+ outboundTag = "disney"
+}
+
+local prime_rule = {
+ type = "field",
+ domain = {"aiv-cdn.net", "amazonaws.com", "amazonvideo.com", "llnwd.net"},
+ outboundTag = "prime"
+}
+
+local rules_table = {}
+
+if (youtube_server ~= "nil" and v2ray_flow == "1") then
+ table.insert(rules_table, youtube_rule)
+end
+
+if (tw_video_server ~= "nil" and v2ray_flow == "1") then
+ table.insert(rules_table, tw_video_rule)
+end
+
+if (netflix_server ~= "nil" and v2ray_flow == "1") then
+ table.insert(rules_table, netflix_rule)
+end
+
+if (disney_server ~= "nil" and v2ray_flow == "1") then
+ table.insert(rules_table, disney_rule)
+end
+
+if (prime_server ~= "nil" and v2ray_flow == "1") then
+ table.insert(rules_table, prime_rule)
+end
+
+local v2ray = {
+ log = {
+ -- error = "/var/ssrplus.log",
+ loglevel = "warning"
+ },
+ -- 传入连接
+ inbounds = {
+ {
+ port = local_port,
+ protocol = "dokodemo-door",
+ settings = {network = proto, followRedirect = true},
+ sniffing = {enabled = true, destOverride = {"http", "tls"}}
+ }
+
+ },
+ -- 传出连接
+ outbounds = outbounds_table,
+ routing = {domainStrategy = "IPIfNonMatch", rules = rules_table}
+
}
print(json.stringify(v2ray, 1))