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