mirror of
https://github.com/hanwckf/immortalwrt-mt798x.git
synced 2025-01-10 19:12:33 +08:00
luci-app-vssr: sync with upstream source
This commit is contained in:
parent
1fb7b958aa
commit
8782ce26c8
@ -1,8 +1,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-vssr
|
||||
PKG_VERSION:=1.16
|
||||
PKG_RELEASE:=20200301-4
|
||||
PKG_VERSION:=1.17
|
||||
PKG_RELEASE:=20200304-4
|
||||
|
||||
PKG_CONFIG_DEPENDS:= CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray \
|
||||
|
@ -47,13 +47,15 @@ end
|
||||
_("SSR Server"), 20).leaf = true
|
||||
end
|
||||
entry({"admin", "vpn", "vssr", "status"},form("vssr/status"),_("Status"), 23).leaf = true
|
||||
entry({"admin", "vpn", "vssr", "log"}, cbi("vssr/log"), _("Log"), 30).leaf =
|
||||
true
|
||||
|
||||
entry({"admin", "vpn", "vssr", "logview"}, cbi("vssr/logview", {hideapplybtn=true, hidesavebtn=true, hideresetbtn=true}), _("Log") ,80).leaf=true
|
||||
|
||||
|
||||
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", "ping"}, call("act_ping")).leaf=true
|
||||
entry({"admin", "vpn", "vssr", "fileread"}, call("act_read"), nil).leaf=true
|
||||
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
|
||||
@ -534,3 +536,16 @@ function get_flag()
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
function act_read(lfile)
|
||||
local NXFS = require "nixio.fs"
|
||||
local HTTP = require "luci.http"
|
||||
local lfile = HTTP.formvalue("lfile")
|
||||
local ldata={}
|
||||
ldata[#ldata+1] = NXFS.readfile(lfile) or "_nofile_"
|
||||
if ldata[1] == "" then
|
||||
ldata[1] = "_nodata_"
|
||||
end
|
||||
HTTP.prepare_content("application/json")
|
||||
HTTP.write_json(ldata)
|
||||
end
|
||||
|
@ -0,0 +1,48 @@
|
||||
-- Copyright 2009 Steven Barth <steven@midlink.org>
|
||||
-- Licensed to the public under the Apache License 2.0.
|
||||
|
||||
local NXFS = require "nixio.fs"
|
||||
local DISP = require "luci.dispatcher"
|
||||
local HTTP = require "luci.http"
|
||||
local UCI = luci.model.uci.cursor()
|
||||
|
||||
m = Map("vssr")
|
||||
|
||||
-- log directory
|
||||
log_dir = UCI:get_first(m.config, "global", "log_dir") or "/tmp"
|
||||
run_dir = UCI:get_first(m.config, "global", "run_dir") or "/var/etc"
|
||||
local logfile_list = {}
|
||||
|
||||
for path in (NXFS.glob("%s/vssr*" % log_dir) or function() end) do
|
||||
logfile_list[#logfile_list+1] = path
|
||||
end
|
||||
for path in (NXFS.glob("%s/*.*" % run_dir) or function() end) do
|
||||
logfile_list[#logfile_list+1] = path
|
||||
end
|
||||
|
||||
ns = m:section(TypedSection, "_dummy", translate("File Viewer"))
|
||||
ns.addremove = false
|
||||
ns.anonymous = true
|
||||
function ns.cfgsections()
|
||||
return{"_exrules"}
|
||||
end
|
||||
|
||||
lv = ns:option(DynamicList, "logfiles")
|
||||
lv.template = "vssr/logview"
|
||||
lv.inputtitle = translate("Read / Reread log file")
|
||||
lv.rows = 25
|
||||
lv.default = ""
|
||||
for _, lfile in ipairs(logfile_list) do lv:value(lfile, lfile) end
|
||||
function lv.cfgvalue(self, section)
|
||||
if logfile_list[1] then
|
||||
local lfile=logfile_list[1]
|
||||
if NXFS.access(lfile) then
|
||||
return lfile .. "\n" .. translate("Please press [Read] button")
|
||||
end
|
||||
return lfile .. "\n" .. translate("File not found or empty")
|
||||
else
|
||||
return log_dir .. "\/\n" .. translate("No files found")
|
||||
end
|
||||
end
|
||||
|
||||
return m
|
@ -1,7 +1,7 @@
|
||||
-- Copyright (C) 2017 yushi studio <ywb94@qq.com>
|
||||
-- Licensed to the public under the GNU General Public License v3.
|
||||
|
||||
local IPK_Version="20200301.1.16"
|
||||
local IPK_Version="20200304.1.17"
|
||||
local m, s, o
|
||||
local redir_run=0
|
||||
local reudp_run=0
|
||||
@ -96,7 +96,88 @@ if nixio.fs.access("/etc/china_ssr.txt") then
|
||||
ip_count = sys.exec("cat /etc/china_ssr.txt | wc -l")
|
||||
end
|
||||
|
||||
function processlist()
|
||||
local data = {}
|
||||
local netf = {}
|
||||
local k
|
||||
local ps = luci.util.execi("/bin/busybox top -bn1 | egrep -v dnsmasq")
|
||||
local nets = luci.util.execi("netstat -netupl | egrep -v dnsmasq | awk '{print $1,$4,_,$6,$7}'")
|
||||
|
||||
if not ps or not nets then
|
||||
return
|
||||
end
|
||||
|
||||
for line in nets do
|
||||
-- tcp 0 0 127.0.0.1:1234 0.0.0.0:* LISTEN 5103/v2ray
|
||||
-- udp 0 0 127.0.0.1:1234 0.0.0.0:* 5147/v2ray
|
||||
-- local proto, ip, port, nid = line:match("([^%s]+) +.* +([^ ]*):(%d+) +.* +(%d+)\/.*")
|
||||
local proto, ip, port, nid = line:match("([^%s]+) (.*):(%d+)[^%d]+(%d+)\/.*")
|
||||
local idx = tonumber(nid)
|
||||
if idx and ip then
|
||||
local newstr = "://" .. ip .. ":" .. port
|
||||
local isnew = (netf[idx] and netf[idx]['listen']) and netf[idx]['listen']:match(proto .. newstr) or false
|
||||
netf[idx] = {
|
||||
['listen'] = ((netf[idx] and netf[idx]['listen']) and (not isnew) and (netf[idx]['listen'] .. "\n" .. proto) or proto) .. newstr,
|
||||
}
|
||||
end
|
||||
end
|
||||
-- 5103 1 root S 661m 543% 0% /usr/bin/v2ray/v2ray -config /var/etc/shadowsocksr.json
|
||||
for line in ps do
|
||||
local pid, ppid, user, stat, vsz, mem, cpu, cmd = line:match(
|
||||
"^ *(%d+) +(%d+) +(%S.-%S) +([RSDZTW][W ][<N ]) +(%d+.?) +(%d+%%) +(%d+%%) +(.+)"
|
||||
)
|
||||
if cmd then
|
||||
local idx = tonumber(pid)
|
||||
local bin, param, cfg = cmd:match("^.*\/([^ ]*) *([^ ]*) *\/var\/etc\/([^ ]*).*")
|
||||
if idx and cfg then
|
||||
local listen = "NONE"
|
||||
if netf[idx] and netf[idx]['listen'] then
|
||||
listen = netf[idx]['listen']
|
||||
end
|
||||
data[idx] = {
|
||||
['PID'] = pid,
|
||||
['COMMAND'] = bin,
|
||||
['LISTEN'] = listen,
|
||||
['CONFIG'] = cfg,
|
||||
['%MEM'] = mem,
|
||||
['%CPU'] = cpu,
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return data
|
||||
end
|
||||
|
||||
function printstat(status, form, name)
|
||||
local tabs = {
|
||||
["Global Client"] = "shadowsocksr.json",
|
||||
["Game Mode UDP Relay"] = "shadowsocksr_u.json",
|
||||
["PDNSD"] = "pdnsd.conf",
|
||||
["DNS Forward"] = "shadowsocksr_d.json",
|
||||
["SOCKS5 Proxy"] = "shadowsocksr_s.json",
|
||||
["Global SSR Server"] = "shadowsocksr_0.json",
|
||||
|
||||
}
|
||||
local stat = translate("Unknown")
|
||||
local sname = stat
|
||||
if tabs[name] and status then
|
||||
stat = translate("Not Running")
|
||||
for idx, cfg in pairs(status) do
|
||||
if status[idx]['CONFIG'] and status[idx]['CONFIG'] == tabs[name] then
|
||||
stat = font_blue .. bold_on .. translate("Running") .. bold_off .. " > " .. status[idx]['COMMAND'] .. " -c " .. status[idx]['CONFIG'] .. font_off
|
||||
sname = translate(status[idx]['COMMAND'])
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
local section = form:field(DummyValue,name,translate(name) .. ": " .. sname)
|
||||
section.rawhtml = true
|
||||
section.value = stat
|
||||
return section
|
||||
end
|
||||
|
||||
procs=processlist()
|
||||
|
||||
|
||||
local icount=sys.exec("ps -w | grep ssr-reudp |grep -v grep| wc -l")
|
||||
@ -187,7 +268,12 @@ m = SimpleForm("Version")
|
||||
m.reset = false
|
||||
m.submit = false
|
||||
|
||||
|
||||
t = m:section(Table, procs, translate("Running Details: ") .. "(/var/etc)")
|
||||
t:option(DummyValue, "PID", translate("PID"))
|
||||
t:option(DummyValue, "COMMAND", translate("CMD"))
|
||||
t:option(DummyValue, "LISTEN", translate("LISTEN"))
|
||||
t:option(DummyValue, "%CPU", translate("CPU"))
|
||||
t:option(DummyValue, "%MEM", translate("MEM"))
|
||||
|
||||
s=m:field(DummyValue,"redir_run",translate("Global Client"))
|
||||
s.rawhtml = true
|
||||
|
@ -46,8 +46,7 @@ end
|
||||
o.default=2
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(DynamicList, "subscribe_url", translate("Subscribe URL"),
|
||||
translate("Before subscribing please click below to delete all servers in the subscription"))
|
||||
o = s:option(DynamicList, "subscribe_url", translate("Subscribe URL"))
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Flag, "proxy", translate("Through proxy update"))
|
||||
@ -59,6 +58,12 @@ o = s:option(DummyValue, "", "")
|
||||
o.rawhtml = true
|
||||
o.template = "vssr/update_subscribe"
|
||||
|
||||
o = s:option(Button,"update",translate("Update All Subscribe Severs"),translate("No special needs, please click here to subscribe to update"))
|
||||
o.inputstyle = "reload"
|
||||
o.write = function()
|
||||
luci.sys.call("bash /usr/share/vssr/subscribe.sh >>/tmp/vssr.log 2>&1")
|
||||
luci.http.redirect(luci.dispatcher.build_url("admin", "vpn", "vssr", "servers"))
|
||||
end
|
||||
|
||||
|
||||
o = s:option(Button,"delete",translate("Delete All Subscribe Severs"))
|
||||
|
109
package/ctcgfw/luci-app-vssr/luasrc/view/vssr/logview.htm
Normal file
109
package/ctcgfw/luci-app-vssr/luasrc/view/vssr/logview.htm
Normal file
@ -0,0 +1,109 @@
|
||||
<!-- ++ BEGIN ++ Auto Repeater ++ logsview.htm ++ -->
|
||||
<%-
|
||||
local values = self:formvalue(section)
|
||||
if not values then
|
||||
values = self:cfgvalue(section) or {self.default}
|
||||
end
|
||||
|
||||
local function serialize_json(x, cb)
|
||||
local rv, push = nil, cb
|
||||
if not push then
|
||||
rv = { }
|
||||
push = function(tok) rv[#rv+1] = tok end
|
||||
end
|
||||
|
||||
if x == nil then
|
||||
push("null")
|
||||
elseif type(x) == "table" then
|
||||
push("[")
|
||||
for k = 1, #x do
|
||||
if k > 1 then
|
||||
push(",")
|
||||
end
|
||||
serialize_json(x[k], push)
|
||||
end
|
||||
push("]")
|
||||
else
|
||||
push('"%s"' % tostring(x):gsub('["%z\1-\31\\]',
|
||||
function(c) return '\\u%04x' % c:byte(1) end))
|
||||
end
|
||||
|
||||
if not cb then
|
||||
return table.concat(rv, "")
|
||||
end
|
||||
end
|
||||
-%>
|
||||
<%+cbi/valueheader%>
|
||||
<select class="cbi-input-select" onchange="onclick_logview(this, false)"
|
||||
<%=
|
||||
attr("name", cbid) .. attr("id", cbid) .. attr("value", self.default) .. ifattr(self.size, "size")
|
||||
%>
|
||||
></select>
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
(function() {
|
||||
//var values = <%=serialize_json(values)%>;
|
||||
var keylist = <%=serialize_json(self.keylist)%>;
|
||||
var vallist = <%=serialize_json(self.vallist)%>;
|
||||
var parent = document.getElementById("<%=cbid%>");
|
||||
for (var j = 0; j < keylist.length; j++) {
|
||||
var opt = document.createElement("option");
|
||||
opt.value = keylist[j];
|
||||
if (j == 0) {
|
||||
opt.selected = "selected";
|
||||
}
|
||||
opt.appendChild(document.createTextNode(vallist[j]));
|
||||
parent.appendChild(opt);
|
||||
}
|
||||
}());
|
||||
//]]></script>
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
function onclick_logview(id, bottom) {
|
||||
// get elements
|
||||
var txt = document.getElementById("<%=cbid%>.txt"); // TextArea
|
||||
if ( !txt ) { return; } // security check
|
||||
txt.value= "Reading: " + document.getElementById("<%=cbid%>").value
|
||||
XHR.get('<%=luci.dispatcher.build_url("admin", "vpn", "vssr", "fileread")%>', {lfile: document.getElementById("<%=cbid%>").value} ,
|
||||
function(x, ifc) {
|
||||
if (! ifc) {txt.value = "XHR.get(<%=luci.dispatcher.build_url("admin", "vpn", "vssr", "fileread")%>) Failed!"; return;}
|
||||
txt.value = ifc[0];
|
||||
if (bottom)
|
||||
txt.scrollTop = txt.scrollHeight;
|
||||
else
|
||||
txt.scrollTop = 0;
|
||||
txt.scrollLeft = 0;
|
||||
}
|
||||
);
|
||||
}
|
||||
//]]></script>
|
||||
|
||||
<%
|
||||
-- one button on top, one at the buttom
|
||||
%>
|
||||
<br /><br />
|
||||
<input class="cbi-button cbi-input-button" style="align: center; width: 100%" type="button" onclick='onclick_logview(this, false)'
|
||||
<%=
|
||||
attr("name", section) .. attr("id", cbid .. ".btn1") .. attr("value", self.inputtitle)
|
||||
%> />
|
||||
|
||||
<br /><br />
|
||||
|
||||
<%
|
||||
-- set a readable style taken from openwrt theme for textarea#syslog
|
||||
-- in openwrt theme there are problems with a width of 100 so we check for theme and set to lower value
|
||||
%>
|
||||
<textarea style="width: <%if media == "/luci-static/openwrt.org" then%>98.7%<%else%>100%<%end%> ; min-height: 200px; border: 3px solid #cccccc; padding: 5px; font-family: monospace; resize: none;" wrap="off" readonly="readonly"
|
||||
<%=
|
||||
attr("name", cbid .. ".txt") .. attr("id", cbid .. ".txt") .. ifattr(self.rows, "rows")
|
||||
%> >
|
||||
<%-=pcdata(self:cfgvalue(section))-%>
|
||||
</textarea>
|
||||
<br /><br />
|
||||
|
||||
<%
|
||||
-- one button on top, one at the buttom
|
||||
%>
|
||||
<input class="cbi-button cbi-input-button" style="align: center; width: 100%" type="button" onclick='onclick_logview(this, true)'
|
||||
<%= attr("name", section) .. attr("id", cbid .. ".btn2") .. attr("value", self.inputtitle) %> />
|
||||
<br /><br />
|
||||
<%+cbi/valuefooter%>
|
||||
<!-- ++ END ++ Auto Repeater ++ logsview.htm ++ -->
|
@ -1,6 +1,6 @@
|
||||
<%+cbi/valueheader%>
|
||||
<link rel="stylesheet" href="/luci-static/vssr/css/vssr.css?v=72883">
|
||||
<label class="cbi-value-title"><%= translate("Update") %></label>
|
||||
<label class="cbi-value-title"><%= translate("Before subscribing please click below to delete all servers in the subscription") %></label>
|
||||
<div class="cbi-value-field">
|
||||
<input class="cbi-button cbi-button-reload" id="update_subscribe" type="button"
|
||||
size="0" value="<%= translate("Save And Start Subscribe") %>">
|
||||
|
@ -800,7 +800,7 @@ msgid "Plugin Opts"
|
||||
msgstr "插件参数"
|
||||
|
||||
msgid "Before subscribing please click below to delete all servers in the subscription"
|
||||
msgstr "订阅前请点击下面的删除所有服务器在订阅"
|
||||
msgstr "使用此订阅前请删除所有服务器在订阅"
|
||||
|
||||
msgid "Chnroute Setting"
|
||||
msgstr "国内IP段数据库更新设置"
|
||||
@ -854,4 +854,15 @@ msgstr "SS/SSR/V2RAY 服务端"
|
||||
msgid "Delete All Subscribe Severs"
|
||||
msgstr "删除所有订阅服务器节点"
|
||||
|
||||
msgid "Update All Subscribe Severs"
|
||||
msgstr "更新所有订阅服务器节点"
|
||||
|
||||
msgid "No special needs, please click here to subscribe to update"
|
||||
msgstr "没有特殊需要,请点击这里订阅更新"
|
||||
|
||||
msgid "Running Details:"
|
||||
msgstr "进程详情:"
|
||||
|
||||
msgid "File Viewer"
|
||||
msgstr "文件查看器"
|
||||
|
||||
|
@ -54,8 +54,11 @@ uci_get_by_type() {
|
||||
add_cron() {
|
||||
sed -i '/vssr.log/d' $CRON_FILE
|
||||
echo '0 1 * * 0 echo "" > /tmp/vssr.log' >>$CRON_FILE
|
||||
[ $(uci_get_by_type server_subscribe auto_update 0) -eq 1 ] && echo "0 $(uci_get_by_type server_subscribe auto_update_time) * * * /usr/bin/lua /usr/share/vssr/subscribe.lua" >> $CRON_FILE
|
||||
# [ $(uci_get_by_type server_subscribe auto_update 0) -eq 1 ] && echo "0 $(uci_get_by_type server_subscribe auto_update_time) * * * /usr/bin/lua /usr/share/vssr/subscribe.lua" >> $CRON_FILE
|
||||
[ $(uci_get_by_type server_subscribe auto_update 0) -eq 1 ] && echo "0 $(uci_get_by_type server_subscribe auto_update_time) * * * /usr/bin/lua /usr/share/vssr/update.lua" >> $CRON_FILE
|
||||
[ -n "$(grep -w "/usr/share/vssr/subscribe.sh" $CRON_FILE)" ] && sed -i '/\/usr\/share\/vssr\/subscribe.sh/d' $CRON_FILE
|
||||
[ $(uci_get_by_type server_subscribe auto_update 0) -eq 1 ] && echo "0 $(uci_get_by_type server_subscribe auto_update_time) * * * /usr/share/vssr/subscribe.sh" >> $CRON_FILE
|
||||
[ -z "$(grep -w "/usr/share/vssr/update.sh" $CRON_FILE)" ] && echo "0 5 * * 0 /usr/share/vssr/update.sh" >> $CRON_FILE
|
||||
crontab $CRON_FILE
|
||||
}
|
||||
|
||||
@ -614,6 +617,7 @@ start_redir() {
|
||||
sscmd="/usr/bin/v2ray/v2ray"
|
||||
elif [ "$stype" == "trojan" ] ;then
|
||||
sscmd="/usr/sbin/trojan"
|
||||
|
||||
fi
|
||||
local utype=$(uci_get_by_name $UDP_RELAY_SERVER type)
|
||||
if [ "$utype" == "ss" ] ;then
|
||||
@ -624,6 +628,7 @@ start_redir() {
|
||||
ucmd="/usr/bin/v2ray/v2ray"
|
||||
elif [ "$utype" == "trojan" ] ;then
|
||||
ucmd="/usr/sbin/trojan"
|
||||
|
||||
fi
|
||||
if [ "$(uci_get_by_type global threads 0)" = "0" ] ;then
|
||||
threads=$(cat /proc/cpuinfo | grep 'processor' | wc -l)
|
||||
@ -642,14 +647,16 @@ start_redir() {
|
||||
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") Shadowsocks/ShadowsocksR $threads 线程 已启动!" >> /tmp/vssr.log
|
||||
elif [ "$stype" == "v2ray" ] ;then
|
||||
for i in $(seq 1 $threads); do
|
||||
$sscmd -config /var/etc/v2-ssr-retcp.json >/dev/null 2>&1 &
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") $($sscmd -version | head -1) 已启动!" >> /tmp/vssr.log
|
||||
done
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") $($sscmd -version | head -1) $threads 线程 已启动!" >> /tmp/vssr.log
|
||||
|
||||
elif [ "$stype" == "trojan" ] ;then
|
||||
for i in $(seq 1 $threads); do
|
||||
$sscmd --config /var/etc/trojan-ssr-retcp.json >/dev/null 2>&1 &
|
||||
done
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") $($sscmd --version 2>&1 | head -1) 已启动!" >> /tmp/vssr.log
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") $($sscmd --version 2>&1 | head -1) $threads 线程 已启动!" >> /tmp/vssr.log
|
||||
|
||||
fi
|
||||
|
||||
@ -896,6 +903,7 @@ start_server() {
|
||||
gen_serv_include
|
||||
return 0
|
||||
}
|
||||
|
||||
start_local() {
|
||||
local local_server=$(uci_get_by_type socks5_proxy server)
|
||||
local http_enable=$(uci_get_by_type socks5_proxy http_enable)
|
||||
@ -1051,7 +1059,7 @@ stop() {
|
||||
killall -q -9 vssr-monitor
|
||||
killall -q -9 ss-redir
|
||||
killall -q -9 ssr-redir
|
||||
killall -q -9 trojan
|
||||
killall -q -9 trojan
|
||||
killall -q -9 v2ray
|
||||
killall -q -9 ssr-server
|
||||
killall -q -9 ss-server
|
||||
@ -1066,8 +1074,8 @@ stop() {
|
||||
killall -q -9 obfs-local
|
||||
killall -q -9 obfs-server
|
||||
killall -q -9 chinadns
|
||||
killall -q -9 udp2raw
|
||||
killall -q -9 udpspeeder
|
||||
killall -q -9 udp2raw
|
||||
killall -q -9 udpspeeder
|
||||
/usr/bin/udp2raw --clear >/dev/null
|
||||
if [ -f /var/run/pdnsd.pid ] ;then
|
||||
kill $(cat /var/run/pdnsd.pid) >/dev/null 2>&1
|
||||
|
@ -84,7 +84,7 @@ ipset_r() {
|
||||
EOF
|
||||
ipset -N gfwlist hash:net 2>/dev/null
|
||||
$IPT -N SS_SPEC_WAN_AC
|
||||
$IPT -I SS_SPEC_WAN_AC -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 -j SS_SPEC_WAN_FW
|
||||
|
||||
@ -94,7 +94,7 @@ EOF
|
||||
$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 china dst -j RETURN
|
||||
$IPT -I SS_SPEC_WAN_AC -d $server -j RETURN
|
||||
$IPT -I SS_SPEC_WAN_AC -p tcp ! --dport 53 -d $server -j RETURN
|
||||
|
||||
elif [ "$RUNMODE" = "oversea" ] ;then
|
||||
ipset -N oversea hash:net 2>/dev/null
|
||||
@ -102,12 +102,12 @@ EOF
|
||||
ipset -N gmlan hash:net 2>/dev/null
|
||||
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 -I SS_SPEC_WAN_AC -d $server -j RETURN
|
||||
$IPT -I SS_SPEC_WAN_AC -p tcp ! --dport 53 -d $server -j RETURN
|
||||
|
||||
elif [ "$RUNMODE" = "all" ] ;then
|
||||
$IPT -N SS_SPEC_WAN_AC
|
||||
$IPT -A SS_SPEC_WAN_AC -j SS_SPEC_WAN_FW
|
||||
$IPT -I SS_SPEC_WAN_AC -d $server -j RETURN
|
||||
$IPT -I SS_SPEC_WAN_AC -p tcp ! --dport 53 -d $server -j RETURN
|
||||
|
||||
fi
|
||||
|
||||
@ -199,7 +199,7 @@ tp_rule() {
|
||||
$ipt -A SS_SPEC_TPROXY -p udp -d 192.168.0.0/16 -j RETURN
|
||||
$ipt -A SS_SPEC_TPROXY -p udp -d 224.0.0.0/4 -j RETURN
|
||||
$ipt -A SS_SPEC_TPROXY -p udp -d 240.0.0.0/4 -j RETURN
|
||||
$ipt -A SS_SPEC_TPROXY -p udp -d $SERVER -j RETURN
|
||||
$ipt -A SS_SPEC_TPROXY -p udp ! --dport 53 -d $server -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 \
|
||||
-j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
|
||||
|
260
package/ctcgfw/luci-app-vssr/root/usr/share/vssr/subscribe.sh
Normal file
260
package/ctcgfw/luci-app-vssr/root/usr/share/vssr/subscribe.sh
Normal file
@ -0,0 +1,260 @@
|
||||
#!/bin/bash
|
||||
# Copyright (C) 2017 XiaoShan https://www.mivm.cn
|
||||
|
||||
. /usr/share/libubox/jshn.sh
|
||||
|
||||
urlsafe_b64decode() {
|
||||
local d="====" data=$(echo $1 | sed 's/_/\//g; s/-/+/g')
|
||||
local mod4=$((${#data}%4))
|
||||
[ $mod4 -gt 0 ] && data=${data}${d:mod4}
|
||||
echo $data | base64 -d
|
||||
}
|
||||
|
||||
urldecode() { : "${*//+/ }"; echo -e "${_//%/\\x}"; }
|
||||
|
||||
echo_date(){
|
||||
echo $(TZ=UTC-8 date -R +%Y-%m-%d\ %X):$1
|
||||
}
|
||||
|
||||
Server_Update() {
|
||||
local uci_set="uci -q set $name.$1."
|
||||
${uci_set}grouphashkey="$ssr_grouphashkey"
|
||||
${uci_set}hashkey="$ssr_hashkey"
|
||||
${uci_set}alias="[$ssr_group] $ssr_remarks"
|
||||
${uci_set}auth_enable="0"
|
||||
${uci_set}switch_enable="1"
|
||||
${uci_set}type="$ssr_type"
|
||||
${uci_set}server="$ssr_host"
|
||||
${uci_set}server_port="$ssr_port"
|
||||
${uci_set}local_port="1234"
|
||||
uci -q get $name.@servers[$1].timeout >/dev/null || ${uci_set}timeout="60"
|
||||
${uci_set}password="$ssr_passwd"
|
||||
${uci_set}encrypt_method="$ssr_method"
|
||||
${uci_set}protocol="$ssr_protocol"
|
||||
${uci_set}protocol_param="$ssr_protoparam"
|
||||
${uci_set}obfs="$ssr_obfs"
|
||||
${uci_set}obfs_param="$ssr_obfsparam"
|
||||
${uci_set}fast_open="0"
|
||||
${uci_set}kcp_enable="0"
|
||||
${uci_set}kcp_port="0"
|
||||
${uci_set}kcp_param="--nocomp"
|
||||
|
||||
if [ "$ssr_type" = "v2ray" ]; then
|
||||
#v2ray
|
||||
${uci_set}alter_id="$ssr_alter_id"
|
||||
${uci_set}vmess_id="$ssr_vmess_id"
|
||||
${uci_set}transport="$ssr_transport"
|
||||
${uci_set}tcp_guise="$ssr_tcp_guise"
|
||||
${uci_set}ws_host="$ssr_ws_host"
|
||||
${uci_set}ws_path="$ssr_ws_path"
|
||||
${uci_set}h2_host="$ssr_h2_host"
|
||||
${uci_set}h2_path="$ssr_h2_path"
|
||||
${uci_set}tls="$ssr_tls"
|
||||
${uci_set}security=$ssr_security
|
||||
${uci_set}alias="$ssr_remarks"
|
||||
fi
|
||||
|
||||
if [ "$ssr_type" = "ss" ]; then
|
||||
${uci_set}encrypt_method_ss="$ss_method"
|
||||
${uci_set}alias="$ssr_remarks"
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
name=vssr
|
||||
subscribe_url=($(uci get $name.@server_subscribe[0].subscribe_url)) #订阅服务器地址
|
||||
[ ${#subscribe_url[@]} -eq 0 ] && exit 1
|
||||
[ $(uci -q get $name.@server_subscribe[0].proxy || echo 0) -eq 0 ] && /etc/init.d/$name stop >/dev/null 2>&1
|
||||
log_name=${name}_subscribe
|
||||
for ((o=0;o<${#subscribe_url[@]};o++))
|
||||
do
|
||||
echo_date "从 ${subscribe_url[o]} 获取订阅"
|
||||
echo_date "开始更新在线订阅列表..."
|
||||
echo_date "尝试下载订阅链接到本地临时文件,请稍等..."
|
||||
subscribe_data=$(wget-ssl --no-check-certificate -t 3 -T 30 -O- ${subscribe_url[o]})
|
||||
curl_code=$?
|
||||
# 计算group的hashkey
|
||||
ssr_grouphashkey=$(echo "${subscribe_url[o]}" | md5sum | cut -d ' ' -f1)
|
||||
if [ ! $curl_code -eq 0 ];then
|
||||
echo_date "下载订阅失败,自动重试中..."
|
||||
subscribe_data=$(wget-ssl --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" --no-check-certificate -t 3 -T 30 -O- ${subscribe_url[o]})
|
||||
curl_code=$?
|
||||
fi
|
||||
if [ $curl_code -eq 0 ];then
|
||||
echo_date "下载订阅成功,开始解析节点信息..."
|
||||
ssr_url=($(echo $subscribe_data | base64 -d | sed 's/\r//g')) # 解码数据并删除 \r 换行符
|
||||
subscribe_max=$(echo ${ssr_url[0]} | grep -i MAX= | awk -F = '{print $2}')
|
||||
subscribe_max_x=()
|
||||
if [ -n "$subscribe_max" ]; then
|
||||
while [ ${#subscribe_max_x[@]} -ne $subscribe_max ]
|
||||
do
|
||||
if [ ${#ssr_url[@]} -ge 10 ]; then
|
||||
if [ $((${RANDOM:0:2}%2)) -eq 0 ]; then
|
||||
temp_x=${RANDOM:0:1}
|
||||
else
|
||||
temp_x=${RANDOM:0:2}
|
||||
fi
|
||||
else
|
||||
temp_x=${RANDOM:0:1}
|
||||
fi
|
||||
[ $temp_x -lt ${#ssr_url[@]} -a -z "$(echo "${subscribe_max_x[*]}" | grep -w $temp_x)" ] && subscribe_max_x[${#subscribe_max_x[@]}]="$temp_x"
|
||||
done
|
||||
else
|
||||
subscribe_max=${#ssr_url[@]}
|
||||
fi
|
||||
echo_date "共计$subscribe_max个节点"
|
||||
|
||||
ssr_group=$(urlsafe_b64decode $(urlsafe_b64decode ${ssr_url[$((${#ssr_url[@]} - 1))]//ssr:\/\//} | sed 's/&/\n/g' | grep group= | awk -F = '{print $2}'))
|
||||
if [ -z "$ssr_group" ]; then
|
||||
ssr_group="default"
|
||||
fi
|
||||
if [ -n "$ssr_group" ]; then
|
||||
subscribe_i=0
|
||||
subscribe_n=0
|
||||
subscribe_o=0
|
||||
subscribe_x=""
|
||||
temp_host_o=()
|
||||
curr_ssr=$(uci show $name | grep @servers | grep -c server=)
|
||||
for ((x=0;x<$curr_ssr;x++)) # 循环已有服务器信息,匹配当前订阅群组
|
||||
do
|
||||
temp_alias=$(uci -q get $name.@servers[$x].grouphashkey | grep "$ssr_grouphashkey")
|
||||
[ -n "$temp_alias" ] && temp_host_o[${#temp_host_o[@]}]=$(uci get $name.@servers[$x].hashkey)
|
||||
done
|
||||
|
||||
for ((x=0;x<$subscribe_max;x++)) # 循环链接
|
||||
do
|
||||
[ ${#subscribe_max_x[@]} -eq 0 ] && temp_x=$x || temp_x=${subscribe_max_x[x]}
|
||||
result=$(echo ${ssr_url[temp_x]} | grep "ss")
|
||||
subscribe_url_type=$(echo "$ssr_url" | awk -F ':' '{print $1}')
|
||||
|
||||
if [ "$subscribe_url_type" = "ss" ]; then
|
||||
temp_info=${ssr_url[temp_x]//ss:\/\//} # 解码 SS 链接
|
||||
# 计算hashkey
|
||||
ssr_hashkey=$(echo "$temp_info" | md5sum | cut -d ' ' -f1)
|
||||
|
||||
info=$(urlsafe_b64decode $(echo "$temp_info" | awk -F '@' '{print $1}'))
|
||||
temp_info_array=(${info//:/ })
|
||||
ssr_type="ss"
|
||||
ss_method=${temp_info_array[0]}
|
||||
ssr_passwd=${temp_info_array[1]}
|
||||
info=$(echo "$temp_info" | awk -F '@' '{print $2}' | awk -F '#' '{print $1}')
|
||||
temp_info_array=(${info//:/ })
|
||||
ssr_host=${temp_info_array[0]}
|
||||
ssr_port=${temp_info_array[1]}
|
||||
ssr_remarks=$(urldecode $(echo "$temp_info" | awk -F '#' '{print $2}'))
|
||||
fi
|
||||
|
||||
if [ "$subscribe_url_type" = "ssr" ]; then
|
||||
temp_info=$(urlsafe_b64decode ${ssr_url[temp_x]//ssr:\/\//}) # 解码 SSR 链接
|
||||
# 计算hashkey
|
||||
ssr_hashkey=$(echo "$temp_info" | md5sum | cut -d ' ' -f1)
|
||||
|
||||
info=${temp_info///?*/}
|
||||
temp_info_array=(${info//:/ })
|
||||
ssr_type="ssr"
|
||||
ssr_host=${temp_info_array[0]}
|
||||
ssr_port=${temp_info_array[1]}
|
||||
ssr_protocol=${temp_info_array[2]}
|
||||
ssr_method=${temp_info_array[3]}
|
||||
ssr_obfs=${temp_info_array[4]}
|
||||
ssr_passwd=$(urlsafe_b64decode ${temp_info_array[5]})
|
||||
info=${temp_info:$((${#info} + 2))}
|
||||
info=(${info//&/ })
|
||||
ssr_protoparam=""
|
||||
ssr_obfsparam=""
|
||||
ssr_remarks="$temp_x"
|
||||
for ((i=0;i<${#info[@]};i++)) # 循环扩展信息
|
||||
do
|
||||
temp_info=($(echo ${info[i]} | sed 's/=/ /g'))
|
||||
case "${temp_info[0]}" in
|
||||
protoparam)
|
||||
ssr_protoparam=$(urlsafe_b64decode ${temp_info[1]});;
|
||||
obfsparam)
|
||||
ssr_obfsparam=$(urlsafe_b64decode ${temp_info[1]});;
|
||||
remarks)
|
||||
ssr_remarks=$(urlsafe_b64decode ${temp_info[1]});;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
if [ "$subscribe_url_type" = "vmess" ]; then
|
||||
temp_info=$(urlsafe_b64decode ${ssr_url[temp_x]//vmess:\/\//}) # 解码 Vmess 链接
|
||||
# 计算hashkey
|
||||
ssr_hashkey=$(echo "$temp_info" | md5sum | cut -d ' ' -f1)
|
||||
|
||||
ssr_type="v2ray"
|
||||
json_load "$temp_info"
|
||||
json_get_var ssr_host add
|
||||
json_get_var ssr_port port
|
||||
json_get_var ssr_alter_id aid
|
||||
json_get_var ssr_vmess_id id
|
||||
json_get_var ssr_security security
|
||||
if [ "$ssr_security" == "" ]; then
|
||||
ssr_security="auto"
|
||||
fi
|
||||
json_get_var ssr_transport net
|
||||
json_get_var ssr_remarks ps
|
||||
ssr_tcp_guise="none"
|
||||
json_get_var ssr_ws_host host
|
||||
json_get_var ssr_ws_path path
|
||||
json_get_var ssr_h2_host host
|
||||
json_get_var ssr_h2_path path
|
||||
json_get_var ssr_tls tls
|
||||
if [ "$ssr_tls" == "tls" -o "$ssr_tls" == "1" ]; then
|
||||
ssr_tls="1"
|
||||
else
|
||||
ssr_tls="0"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "ssr_remarks" ]; then # 没有备注的话则生成一个
|
||||
ssr_remarks="$ssr_host:$ssr_port";
|
||||
fi
|
||||
|
||||
uci_name_tmp=$(uci show $name | grep -w "$ssr_hashkey" | awk -F . '{print $2}')
|
||||
if [ -z "$uci_name_tmp" ]; then # 判断当前服务器信息是否存在
|
||||
uci_name_tmp=$(uci add $name servers)
|
||||
subscribe_n=$(($subscribe_n + 1))
|
||||
fi
|
||||
Server_Update $uci_name_tmp
|
||||
subscribe_x=$subscribe_x$ssr_hashkey" "
|
||||
ssrtype=$(echo $ssr_type | tr '[a-z]' '[A-Z]')
|
||||
echo_date "$ssrtype节点:【$ssr_remarks】"
|
||||
|
||||
# SSR
|
||||
# echo "服务器地址: $ssr_host"
|
||||
# echo "服务器端口 $ssr_port"
|
||||
# echo "密码: $ssr_passwd"
|
||||
# echo "SS加密: $ss_method"
|
||||
# echo "加密: $ssr_method"
|
||||
# echo "协议: $ssr_protocol"
|
||||
# echo "协议参数: $ssr_protoparam"
|
||||
# echo "混淆: $ssr_obfs"
|
||||
# echo "混淆参数: $ssr_obfsparam"
|
||||
# echo "备注: $ssr_remarks"
|
||||
|
||||
done
|
||||
for ((x=0;x<${#temp_host_o[@]};x++)) # 新旧服务器信息匹配,如果旧服务器信息不存在于新服务器信息则删除
|
||||
do
|
||||
if [ -z "$(echo "$subscribe_x" | grep -w ${temp_host_o[x]})" ]; then
|
||||
uci_name_tmp=$(uci show $name | grep ${temp_host_o[x]} | awk -F . '{print $2}')
|
||||
uci delete $name.$uci_name_tmp
|
||||
subscribe_o=$(($subscribe_o + 1))
|
||||
fi
|
||||
done
|
||||
echo_date "本次更新订阅来源 【$ssr_group】 服务器数量: ${#ssr_url[@]} 新增服务器: $subscribe_n 删除服务器: $subscribe_o"
|
||||
echo_date "在线订阅列表更新完成!请等待网页自动刷新!"
|
||||
subscribe_log="$ssr_group 服务器订阅更新成功 服务器数量: ${#ssr_url[@]} 新增服务器: $subscribe_n 删除服务器: $subscribe_o"
|
||||
logger -st $log_name[$$] -p6 "$subscribe_log"
|
||||
uci commit $name
|
||||
else
|
||||
echo_date "${subscribe_url[$o]} 订阅数据解析失败 无法获取 Group"
|
||||
logger -st $log_name[$$] -p3 "${subscribe_url[$o]} 订阅数据解析失败 无法获取 Group"
|
||||
fi
|
||||
else
|
||||
echo_date "${subscribe_url[$o]} 订阅数据获取失败 错误代码: $curl_code"
|
||||
logger -st $log_name[$$] -p3 "${subscribe_url[$o]} 订阅数据获取失败 错误代码: $curl_code"
|
||||
fi
|
||||
done
|
||||
echo "END SUBSCRIBE"
|
||||
/etc/init.d/$name restart >/dev/null 2>&1
|
25
package/ctcgfw/luci-app-vssr/root/usr/share/vssr/update.sh
Normal file
25
package/ctcgfw/luci-app-vssr/root/usr/share/vssr/update.sh
Normal file
@ -0,0 +1,25 @@
|
||||
#!/bin/sh
|
||||
chnroute_data=$(wget -O- -t 3 -T 3 http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest)
|
||||
[ $? -eq 0 ] && {
|
||||
echo "$chnroute_data" | grep ipv4 | grep CN | awk -F\| '{ printf("%s/%d\n", $4, 32-log($5)/log(2)) }' > /tmp/china_ssr.txt
|
||||
}
|
||||
|
||||
if [ -s "/tmp/china_ssr.txt" ];then
|
||||
if ( ! cmp -s /tmp/china_ssr.txt /etc/china_ssr.txt );then
|
||||
mv /tmp/china_ssr.txt /etc/china_ssr.txt
|
||||
fi
|
||||
fi
|
||||
|
||||
/usr/share/vssr/chinaipset.sh
|
||||
|
||||
wget-ssl --no-check-certificate https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt -O /tmp/gfw.b64
|
||||
/usr/bin/ssr-gfw
|
||||
|
||||
if [ -s "/tmp/gfwnew.txt" ];then
|
||||
if ( ! cmp -s /tmp/gfwnew.txt /etc/dnsmasq.ssr/gfw_list.conf );then
|
||||
mv /tmp/gfwnew.txt /etc/dnsmasq.ssr/gfw_list.conf
|
||||
echo "copy"
|
||||
fi
|
||||
fi
|
||||
|
||||
/etc/init.d/vssr restart
|
Loading…
x
Reference in New Issue
Block a user