pacakge: drop unmaintained package
This commit is contained in:
parent
a2c7e953d7
commit
dbb01cb419
@ -17,18 +17,14 @@ v2ray-plugin source: [honwen/openwrt-v2ray-plugin](https://github.com/honwen/ope
|
||||
Package zxlhhyccc: [zxlhhyccc/MY-lede](https://github.com/zxlhhyccc/MY-lede).<br/>
|
||||
luci-theme-argon source: [jerrykuku/luci-theme-argon](https://github.com/jerrykuku/luci-theme-argon).<br/>
|
||||
openwrt-chinadns-ng source: [pexcn/openwrt-chinadns-ng](https://github.com/pexcn/openwrt-chinadns-ng).<br/>
|
||||
luci-app-ssr-plus-Jo source: [Leo-Jo-My/luci-app-ssr-plus-Jo](https://github.com/Leo-Jo-My/luci-app-ssr-plus-Jo).<br/>
|
||||
openwrt-udpspeeder source: [zhfreal/openwrt-UDPspeeder](https://github.com/zhfreal/openwrt-UDPspeeder).<br/>
|
||||
luci-app-onliner source: [rufengsuixing/luci-app-onliner](https://github.com/rufengsuixing/luci-app-onliner).<br/>
|
||||
luci-app-dockerman source: [lisaac/luci-app-dockerman](https://github.com/lisaac/luci-app-dockerman).<br/>
|
||||
luci-lib-docker source: [lisaac/luci-lib-docker](https://github.com/lisaac/luci-lib-docker).<br/>
|
||||
openwrt-iptvhelper source: [riverscn/openwrt-iptvhelper](https://github.com/riverscn/openwrt-iptvhelper).<br>
|
||||
luci-app-autoipsetadder source: [rufengsuixing/luci-app-autoipsetadder](https://github.com/rufengsuixing/luci-app-autoipsetadder).<br>
|
||||
luci-app-adguardhome source: [rufengsuixing/luci-app-adguardhome](https://github.com/rufengsuixing/luci-app-adguardhome).<br/>
|
||||
Rclone-OpenWrt source: [ElonH/Rclone-OpenWrt](https://github.com/ElonH/Rclone-OpenWrt).<br/>
|
||||
luci-app-usb3disable source: [rufengsuixing/luci-app-usb3disable](https://github.com/rufengsuixing/luci-app-usb3disable).<br/>
|
||||
luci-app-vssr source: [Leo-Jo-My/luci-app-vssr](https://github.com/Leo-Jo-My/luci-app-vssr).<br/>
|
||||
luci-app-diskman source: [lisaac/luci-app-diskman](https://github.com/lisaac/luci-app-diskman).<br/>
|
||||
qntfs-driver source: [lbbboy/qntfs-driver](https://github.com/lbbboy/qntfs-driver).<br/>
|
||||
lua-maxminddb source: [jerrykuku/lua-maxminddb](https://github.com/jerrykuku/lua-maxminddb).<br/>
|
||||
package openwrt-mwol: [Mleaf/openwrt-mwol](https://github.com/Mleaf/openwrt-mwol).<br/>
|
||||
|
||||
@ -1,181 +0,0 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-ssr-plus-Jo
|
||||
PKG_VERSION:=152
|
||||
PKG_RELEASE:=20200307-5
|
||||
PKG_CONFIG_DEPENDS:= CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Trojan \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun:kcptun \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Server \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Socks \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Socks \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ipt2socks \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_dnscrypt_proxy \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_dnsforwarder \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_haproxy \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_udpspeeder \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_udp2raw-tunnel \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_privoxy \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_simple-obfs\
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_simple-obfs-server\
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_GoQuiet-client\
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_GoQuiet-server\
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_v2ray-plugin
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/$(PKG_NAME)/config
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks
|
||||
bool "Include Shadowsocks New Version"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray
|
||||
bool "Include V2ray"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Trojan
|
||||
bool "Include Trojan"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun
|
||||
bool "Include Kcptun"
|
||||
default n
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server
|
||||
bool "Include ShadowsocksR Server"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Server
|
||||
bool "Include Shadowsocks Server"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Socks
|
||||
bool "Include ShadowsocksR Socks and Tunnel"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Socks
|
||||
bool "Include Shadowsocks Socks and Tunnel"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_ipt2socks
|
||||
bool "Include ipt2socks"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_dnscrypt_proxy
|
||||
bool "Include dnscrypt-proxy-full"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_dnsforwarder
|
||||
bool "Include dnsforwarder"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS
|
||||
bool "Include chinadns"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_haproxy
|
||||
bool "Include haproxy"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_privoxy
|
||||
bool "Include privoxy http local"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_simple-obfs
|
||||
bool "Include simple-obfsl"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_simple-obfs-server
|
||||
bool "Include simple-obfs-server"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_udpspeeder
|
||||
bool "Include udpspeeder"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_udp2raw-tunnel
|
||||
bool "Include udp2raw-tunnel"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_GoQuiet-client
|
||||
bool "Include GoQuiet-client"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_GoQuiet-server
|
||||
bool "Include GoQuiet-server"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_v2ray-plugin
|
||||
bool "Include v2ray-plugin"
|
||||
default y
|
||||
endef
|
||||
|
||||
define Package/luci-app-ssr-plus-Jo
|
||||
SECTION:=luci
|
||||
CATEGORY:=LuCI
|
||||
SUBMENU:=3. Applications
|
||||
TITLE:=SS/SSR/V2Ray LuCI interface
|
||||
PKGARCH:=all
|
||||
DEPENDS:=+shadowsocksr-libev-alt +ipset +ip-full +iptables-mod-tproxy +dnsmasq-full +coreutils +coreutils-base64 +bash +pdnsd-alt +luasocket +jshn +curl +wget +unzip \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks:shadowsocks-libev-ss-redir \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:v2ray \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan:trojan \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun:kcptun-client \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server:shadowsocksr-libev-server \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Server:shadowsocks-libev-ss-server \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Socks:shadowsocksr-libev-ssr-local \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Socks:shadowsocks-libev-ss-local \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_ipt2socks:ipt2socks \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_dnscrypt_proxy:dnscrypt-proxy-full \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_dnsforwarder:dnsforwarder \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS:openwrt_chinadns \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_haproxy:haproxy \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_privoxy:privoxy \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_udpspeeder:speederv2-tunnel \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_udp2raw-tunnel:udp2raw-tunnel \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_simple-obfs:simple-obfs \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_simple-obfs-server:simple-obfs-server \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_GoQuiet-client:gq-client \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_GoQuiet-server:gq-server \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_v2ray-plugin:v2ray-plugin
|
||||
endef
|
||||
|
||||
define Build/Prepare
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/luci-app-ssr-plus-Jo/install
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/luci
|
||||
cp -pR ./luasrc/* $(1)/usr/lib/lua/luci
|
||||
$(INSTALL_DIR) $(1)/
|
||||
cp -pR ./root/* $(1)/
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/i18n
|
||||
po2lmo ./po/zh_Hans/ssr-plus.po $(1)/usr/lib/lua/luci/i18n/ssr-plus.zh-cn.lmo
|
||||
endef
|
||||
|
||||
define Package/luci-app-ssr-plus-Jo/postinst
|
||||
#!/bin/sh
|
||||
if [ -z "$${IPKG_INSTROOT}" ]; then
|
||||
( . /etc/uci-defaults/luci-ssr-plus ) && rm -f /etc/uci-defaults/luci-ssr-plus
|
||||
rm -f /tmp/luci-indexcache
|
||||
chmod 755 /etc/init.d/shadowsocksr >/dev/null 2>&1
|
||||
/etc/init.d/shadowsocksr enable >/dev/null 2>&1
|
||||
fi
|
||||
exit 0
|
||||
endef
|
||||
|
||||
define Package/luci-app-ssr-plus-Jo/prerm
|
||||
#!/bin/sh
|
||||
if [ -z "$${IPKG_INSTROOT}" ]; then
|
||||
/etc/init.d/shadowsocksr disable
|
||||
/etc/init.d/shadowsocksr stop
|
||||
fi
|
||||
exit 0
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,luci-app-ssr-plus-Jo))
|
||||
@ -1,387 +0,0 @@
|
||||
-- Copyright (C) 2018 jerrykuku <jerrykuku@qq.com>
|
||||
-- Licensed to the public under the GNU General Public License v3.
|
||||
module("luci.controller.shadowsocksr", package.seeall)
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/shadowsocksr") then
|
||||
return
|
||||
end
|
||||
if nixio.fs.access("/usr/bin/ssr-redir") then
|
||||
entry({"admin", "vpn"}, firstchild(), "VPN", 45).dependent = false
|
||||
entry({"admin", "vpn", "shadowsocksr"},alias("admin", "vpn", "shadowsocksr", "client"), _("ShadowSocksR Plus+"),10).dependent = true
|
||||
entry({"admin", "vpn", "shadowsocksr", "client"},cbi("shadowsocksr/client"),_("SSR Client"),10).leaf = true
|
||||
entry({"admin", "vpn", "shadowsocksr", "servers"}, cbi("shadowsocksr/servers"), _("Node List"), 11).leaf = true
|
||||
entry({"admin", "vpn", "shadowsocksr", "servers"},arcombine(cbi("shadowsocksr/servers"), cbi("shadowsocksr/client-config")),_("Node List"), 11).leaf = true
|
||||
|
||||
entry({"admin", "vpn", "shadowsocksr", "subscription"},cbi("shadowsocksr/subscription"), _("Subscription"),12).leaf = true
|
||||
entry({"admin", "vpn", "shadowsocksr", "control"},cbi("shadowsocksr/control"),_("Access Control"),13).leaf = true
|
||||
entry({"admin", "vpn", "shadowsocksr", "servers-list"}, cbi("shadowsocksr/servers-list"), _("Severs Nodes"), 14).leaf = true
|
||||
entry({"admin", "vpn", "shadowsocksr", "appointlist"},form("shadowsocksr/appointlist"),_("Appointlist List"), 17).leaf = true
|
||||
entry({"admin", "vpn", "shadowsocksr", "udp2raw"},cbi("shadowsocksr/udp2raw"),_("udp2raw tunnel"),16).leaf = true
|
||||
entry({"admin", "vpn", "shadowsocksr", "advanced"},cbi("shadowsocksr/advanced"), _("Advanced Settings"),21).leaf = true
|
||||
elseif nixio.fs.access("/usr/bin/ssr-server") then
|
||||
entry({"admin", "vpn", "shadowsocksr"},alias("admin", "vpn", "shadowsocksr", "server"), _("ShadowSocksR"),10).dependent = true
|
||||
else
|
||||
return
|
||||
end
|
||||
if nixio.fs.access("/usr/bin/ssr-server") then
|
||||
entry({"admin", "vpn", "shadowsocksr", "server"},arcombine(cbi("shadowsocksr/server"), cbi("shadowsocksr/server-config")),_("SSR Server"),22).leaf = true
|
||||
end
|
||||
entry({"admin", "vpn", "shadowsocksr", "status"},form("shadowsocksr/status"),_("Status"), 23).leaf = true
|
||||
entry({"admin", "vpn", "shadowsocksr", "logview"}, cbi("shadowsocksr/logview", {hideapplybtn=true, hidesavebtn=true, hideresetbtn=true}), _("Log") ,30).leaf=true
|
||||
entry({"admin", "vpn", "shadowsocksr", "fileread"}, call("act_read"), nil).leaf=true
|
||||
entry({"admin", "vpn", "shadowsocksr", "refresh"}, call("refresh_data"))
|
||||
entry({"admin", "vpn", "shadowsocksr", "checkport"}, call("check_port"))
|
||||
entry({"admin", "vpn", "shadowsocksr", "checkports"}, call("check_ports"))
|
||||
entry({"admin", "vpn", "shadowsocksr", "run"}, call("act_status"))
|
||||
entry({"admin", "vpn", "shadowsocksr", "change"}, call("change_node"))
|
||||
entry({"admin", "vpn", "shadowsocksr", "allserver"}, call("get_servers"))
|
||||
entry({"admin", "vpn", "shadowsocksr", "subscribe"}, call("get_subscribe"))
|
||||
entry({"admin", "vpn", "shadowsocksr", "ping"}, call("act_ping")).leaf=true
|
||||
end
|
||||
function get_subscribe()
|
||||
|
||||
local cjson = require "cjson"
|
||||
local e = {}
|
||||
local uci = luci.model.uci.cursor()
|
||||
local auto_update = luci.http.formvalue("auto_update")
|
||||
local auto_update_time = luci.http.formvalue("auto_update_time")
|
||||
local proxy = luci.http.formvalue("proxy")
|
||||
local subscribe_url = luci.http.formvalue("subscribe_url")
|
||||
if subscribe_url ~= "[]" then
|
||||
local cmd1 = 'uci set shadowsocksr.@server_subscribe[0].auto_update="' ..
|
||||
auto_update .. '"'
|
||||
local cmd2 = 'uci set shadowsocksr.@server_subscribe[0].auto_update_time="' ..
|
||||
auto_update_time .. '"'
|
||||
local cmd3 = 'uci set shadowsocksr.@server_subscribe[0].proxy="' .. proxy .. '"'
|
||||
luci.sys.call('uci delete shadowsocksr.@server_subscribe[0].subscribe_url ')
|
||||
luci.sys.call(cmd1)
|
||||
luci.sys.call(cmd2)
|
||||
luci.sys.call(cmd3)
|
||||
for k, v in ipairs(cjson.decode(subscribe_url)) do
|
||||
luci.sys.call(
|
||||
'uci add_list shadowsocksr.@server_subscribe[0].subscribe_url="' .. v ..
|
||||
'"')
|
||||
end
|
||||
luci.sys.call('uci commit shadowsocksr')
|
||||
luci.sys.call(
|
||||
"nohup /usr/bin/lua /usr/share/shadowsocksr/subscribe.lua >/www/check_update.htm 2>/dev/null &")
|
||||
|
||||
e.error = 0
|
||||
else
|
||||
e.error = 1
|
||||
end
|
||||
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
|
||||
end
|
||||
-- 获取所有节点
|
||||
function get_servers()
|
||||
local uci = luci.model.uci.cursor()
|
||||
local server_table = {}
|
||||
uci:foreach("shadowsocksr", "servers", function(s)
|
||||
s["name"] = s[".name"]
|
||||
table.insert(server_table,s)
|
||||
end)
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(server_table)
|
||||
end
|
||||
|
||||
-- 切换节点
|
||||
function change_node()
|
||||
local e={}
|
||||
local uci = luci.model.uci.cursor()
|
||||
local sid = luci.http.formvalue("set")
|
||||
local name = ""
|
||||
uci:foreach("shadowsocksr", "global", function(s)
|
||||
name = s[".name"]
|
||||
end)
|
||||
e.status = false
|
||||
e.sid = sid
|
||||
if sid ~= "" then
|
||||
uci:set("shadowsocksr", name, "global_server" , sid)
|
||||
luci.sys.call("uci commit shadowsocksr && /etc/init.d/shadowsocksr restart")
|
||||
e.status = true
|
||||
end
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
-- 检测全局服务器状态
|
||||
function act_status()
|
||||
local e={}
|
||||
--全局服务器
|
||||
e.global=luci.sys.call("ps -w | grep ssr-retcp | grep -v grep >/dev/null") == 0
|
||||
|
||||
--检测chinadns状态
|
||||
if tonumber(luci.sys.exec("ps -w | grep chinadns |grep -v grep| wc -l"))>0 then
|
||||
e.chinadns= true
|
||||
elseif tonumber(luci.sys.exec("ps -w | grep dnsparsing |grep -v grep| wc -l"))>0 then
|
||||
e.chinadns= true
|
||||
elseif tonumber(luci.sys.exec("ps -w | grep dnscrypt-proxy |grep -v grep| wc -l"))>0 then
|
||||
e.chinadns= true
|
||||
elseif tonumber(luci.sys.exec("ps -w | grep pdnsd |grep -v grep| wc -l"))>0 then
|
||||
e.chinadns= true
|
||||
|
||||
elseif tonumber(luci.sys.exec("ps -w | grep dnsforwarder |grep -v grep| wc -l"))>0 then
|
||||
e.chinadns= true
|
||||
|
||||
end
|
||||
--检测SOCKS5状态
|
||||
if tonumber(luci.sys.exec("ps -w | grep ssr-local |grep -v grep| wc -l"))>0 then
|
||||
e.SOCKS5= true
|
||||
elseif tonumber(luci.sys.exec("ps -w | grep ss-local |grep -v grep| wc -l"))>0 then
|
||||
e.SOCKS5= true
|
||||
elseif tonumber(luci.sys.exec("ps -w | grep v2-ssr-local |grep -v grep| wc -l"))>0 then
|
||||
e.SOCKS5= true
|
||||
end
|
||||
|
||||
--检测UDP2RAW状态
|
||||
if tonumber(luci.sys.exec("ps -w | grep udp2raw |grep -v grep| wc -l"))>0 then
|
||||
e.udp2raw= true
|
||||
end
|
||||
--检测UDPspeeder状态
|
||||
if tonumber(luci.sys.exec("ps -w | grep udpspeeder |grep -v grep| wc -l"))>0 then
|
||||
e.udpspeeder= true
|
||||
end
|
||||
--检测服务端状态
|
||||
if tonumber(luci.sys.exec("ps -w | grep ssr-server |grep -v grep| wc -l"))>0 then
|
||||
e.server= true
|
||||
end
|
||||
if luci.sys.call("pidof ssr-server >/dev/null") == 0 then
|
||||
e.ssr_server= true
|
||||
end
|
||||
if luci.sys.call("pidof ss-server >/dev/null") == 0 then
|
||||
e.ss_server= true
|
||||
|
||||
end
|
||||
if luci.sys.call("ps -w | grep v2ray-server | grep -v grep >/dev/null") == 0 then
|
||||
e.v2_server= true
|
||||
|
||||
|
||||
end
|
||||
-- 检测游戏模式状态
|
||||
e.game = false
|
||||
if tonumber(luci.sys.exec("ps -w | grep ssr-reudp |grep -v grep| wc -l"))>0 then
|
||||
e.game= true
|
||||
else
|
||||
if tonumber(luci.sys.exec("ps -w | grep ssr-retcp |grep \"\\-u\"|grep -v grep| wc -l"))>0 then
|
||||
e.game= true
|
||||
end
|
||||
end
|
||||
-- 检测国内通道
|
||||
e.baidu = false
|
||||
sret = luci.sys.call("/usr/bin/ssr-check www.baidu.com 80 3 1")
|
||||
if sret == 0 then
|
||||
e.baidu = true
|
||||
end
|
||||
|
||||
-- 检测国外通道
|
||||
e.google = false
|
||||
sret = luci.sys.call("/usr/bin/ssr-check www.google.com 80 3 1")
|
||||
if sret == 0 then
|
||||
e.google = true
|
||||
end
|
||||
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
function act_ping()
|
||||
local e={}
|
||||
e.index=luci.http.formvalue("index")
|
||||
e.ping=luci.sys.exec("ping -c 1 -W 1 %q 2>&1 | grep -o 'time=[0-9]*.[0-9]' | awk -F '=' '{print$2}'"%luci.http.formvalue("domain"))
|
||||
luci.http.prepare_content("application/json")
|
||||
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")
|
||||
local icount = 0
|
||||
|
||||
if set == "gfw_data" then
|
||||
if nixio.fs.access("/usr/bin/wget-ssl") then
|
||||
refresh_cmd =
|
||||
"wget-ssl --no-check-certificate https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt -O /tmp/gfw.b64"
|
||||
else
|
||||
refresh_cmd = "wget -O /tmp/gfw.b64 http://iytc.net/tools/list.b64"
|
||||
end
|
||||
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/gfwnew.txt | wc -l")
|
||||
if tonumber(icount) > 1000 then
|
||||
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")
|
||||
retstring = tostring(math.ceil(tonumber(icount) / 2))
|
||||
else
|
||||
retstring = "0"
|
||||
end
|
||||
else
|
||||
retstring = "-1"
|
||||
end
|
||||
luci.sys.exec("rm -f /tmp/gfwnew.txt ")
|
||||
else
|
||||
retstring = "-1"
|
||||
end
|
||||
elseif set == "ip_data" then
|
||||
refresh_cmd =
|
||||
'wget -O- \'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest\' 2>/dev/null| awk -F\\| \'/CN\\|ipv4/ { printf("%s/%d\\n", $4, 32-log($5)/log(2)) }\' > /tmp/china_ssr.txt'
|
||||
sret = luci.sys.call(refresh_cmd)
|
||||
icount = luci.sys.exec("cat /tmp/china_ssr.txt | wc -l")
|
||||
if sret == 0 and tonumber(icount) > 1000 then
|
||||
oldcount = luci.sys.exec("cat /etc/china_ssr.txt | wc -l")
|
||||
if tonumber(icount) ~= tonumber(oldcount) then
|
||||
luci.sys.exec("cp -f /tmp/china_ssr.txt /etc/china_ssr.txt")
|
||||
retstring = tostring(tonumber(icount))
|
||||
else
|
||||
retstring = "0"
|
||||
end
|
||||
else
|
||||
retstring = "-1"
|
||||
end
|
||||
luci.sys.exec("rm -f /tmp/china_ssr.txt ")
|
||||
else
|
||||
if nixio.fs.access("/usr/bin/wget-ssl") then
|
||||
refresh_cmd =
|
||||
"wget --no-check-certificate -O - https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt | grep ^\\|\\|[^\\*]*\\^$ | sed -e 's:||:address\\=\\/:' -e 's:\\^:/127\\.0\\.0\\.1:' > /tmp/ad.conf"
|
||||
else
|
||||
refresh_cmd = "wget -O /tmp/ad.conf http://iytc.net/tools/ad.conf"
|
||||
end
|
||||
sret = luci.sys.call(refresh_cmd .. " 2>/dev/null")
|
||||
if sret == 0 then
|
||||
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")
|
||||
else
|
||||
oldcount = 0
|
||||
end
|
||||
|
||||
if tonumber(icount) ~= tonumber(oldcount) then
|
||||
luci.sys.exec("cp -f /tmp/ad.conf /etc/dnsmasq.ssr/ad.conf")
|
||||
retstring = tostring(math.ceil(tonumber(icount)))
|
||||
if oldcount == 0 then
|
||||
luci.sys.call("/etc/init.d/dnsmasq restart")
|
||||
end
|
||||
else
|
||||
retstring = "0"
|
||||
end
|
||||
else
|
||||
retstring = "-1"
|
||||
end
|
||||
luci.sys.exec("rm -f /tmp/ad.conf ")
|
||||
else
|
||||
retstring = "-1"
|
||||
end
|
||||
end
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json({ret = retstring, retcount = icount})
|
||||
end
|
||||
|
||||
|
||||
function act_ping()
|
||||
local e={}
|
||||
e.index=luci.http.formvalue("index")
|
||||
e.ping=luci.sys.exec("ping -c 1 -W 1 %q 2>&1 | grep -o 'time=[0-9]*.[0-9]' | awk -F '=' '{print$2}'"%luci.http.formvalue("domain"))
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
function check_ports()
|
||||
local set = ""
|
||||
local retstring = "<br /><br />"
|
||||
local s
|
||||
local server_name = ""
|
||||
local shadowsocksr = "shadowsocksr"
|
||||
local uci = luci.model.uci.cursor()
|
||||
local iret = 1
|
||||
|
||||
uci:foreach(
|
||||
shadowsocksr,
|
||||
"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 .. "<font color='green'>[" .. server_name .. "] OK.</font><br />"
|
||||
else
|
||||
retstring = retstring .. "<font color='red'>[" .. server_name .. "] Error.</font><br />"
|
||||
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()
|
||||
local sockets = require "socket"
|
||||
local set = luci.http.formvalue("host")
|
||||
local port = luci.http.formvalue("port")
|
||||
local retstring = ""
|
||||
local iret = 1
|
||||
iret = luci.sys.call(" ipset add ss_spec_wan_ac " .. set .. " 2>/dev/null")
|
||||
socket = nixio.socket("inet", "stream")
|
||||
socket:setopt("socket", "rcvtimeo", 3)
|
||||
socket:setopt("socket", "sndtimeo", 3)
|
||||
local t0 = sockets.gettime()
|
||||
ret = socket:connect(set, port)
|
||||
if tostring(ret) == "true" then
|
||||
socket:close()
|
||||
retstring = "1"
|
||||
else
|
||||
retstring = "0"
|
||||
end
|
||||
if iret == 0 then
|
||||
luci.sys.call(" ipset del ss_spec_wan_ac " .. set)
|
||||
end
|
||||
local t1 = sockets.gettime()
|
||||
local tt =t1 -t0
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json({ret = retstring , used = math.floor(tt*1000 + 0.5)})
|
||||
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
|
||||
|
||||
@ -1,114 +0,0 @@
|
||||
local shadowsocksr = "shadowsocksr"
|
||||
local uci = luci.model.uci.cursor()
|
||||
local server_table = {}
|
||||
|
||||
|
||||
uci:foreach(shadowsocksr, "servers", function(s)
|
||||
if s.alias then
|
||||
server_table[s[".name"]] = "[%s]:%s" %{string.upper(s.type), s.alias}
|
||||
elseif s.server and s.server_port then
|
||||
server_table[s[".name"]] = "[%s]:%s:%s" %{string.upper(s.type), s.server, s.server_port}
|
||||
end
|
||||
end)
|
||||
|
||||
local key_table = {}
|
||||
for key,_ in pairs(server_table) do
|
||||
table.insert(key_table,key)
|
||||
end
|
||||
|
||||
table.sort(key_table)
|
||||
|
||||
m = Map(shadowsocksr)
|
||||
|
||||
-- [[ global ]]--
|
||||
s = m:section(TypedSection, "global", translate("Server failsafe auto swith settings"))
|
||||
s.anonymous = true
|
||||
|
||||
o = s:option(Flag, "monitor_enable", translate("Enable Process Deamon"))
|
||||
o.rmempty = false
|
||||
o.default = "1"
|
||||
|
||||
o = s:option(Flag, "enable_switch", translate("Enable Auto Switch"))
|
||||
o.rmempty = false
|
||||
o.default = "1"
|
||||
|
||||
o = s:option(Value, "switch_time", translate("Switch check cycly(second)"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("enable_switch", "1")
|
||||
o.default = 667
|
||||
|
||||
o = s:option(Value, "switch_timeout", translate("Check timout(second)"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("enable_switch", "1")
|
||||
o.default = 5
|
||||
|
||||
o = s:option(Value, "switch_try_count", translate("Check Try Count"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("enable_switch", "1")
|
||||
o.default = 3
|
||||
|
||||
|
||||
|
||||
-- [[ SOCKS5 Proxy ]]--
|
||||
if nixio.fs.access("/usr/bin/ssr-local") then
|
||||
s = m:section(TypedSection, "socks5_proxy", translate("SOCKS5 Proxy"))
|
||||
s.anonymous = true
|
||||
|
||||
o = s:option(ListValue, "server", translate("Server"))
|
||||
o:value("nil", translate("Disable"))
|
||||
for _,key in pairs(key_table) do o:value(key,server_table[key]) end
|
||||
o.default = "nil"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "local_port", translate("Local Port"))
|
||||
o.datatype = "port"
|
||||
o.default = 1080
|
||||
o.rmempty = false
|
||||
|
||||
-- [[ HTTP Proxy ]]--
|
||||
if nixio.fs.access("/usr/sbin/privoxy") then
|
||||
o = s:option(Flag, "http_enable", translate("Enable HTTP Proxy"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "http_port", translate("HTTP Port"))
|
||||
o.datatype = "port"
|
||||
o.default = 1081
|
||||
o.rmempty = false
|
||||
|
||||
end
|
||||
end
|
||||
-- [[ adblock ]]--
|
||||
s = m:section(TypedSection, "global", translate("adblock settings"))
|
||||
s.anonymous = true
|
||||
|
||||
o = s:option(Flag, "adblock", translate("Enable adblock"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "adblock_url", translate("adblock_url"))
|
||||
o.default = "https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt"
|
||||
|
||||
-- [[ haProxy ]]--
|
||||
|
||||
s = m:section(TypedSection, "global_haproxy", translate("haProxy settings"))
|
||||
s.anonymous = true
|
||||
|
||||
o = s:option(Flag, "admin_enable", translate("Enabling the Management Console"))
|
||||
o.rmempty = false
|
||||
o.default = 1
|
||||
|
||||
o = s:option(Value, "admin_port", translate("Service Port"))
|
||||
o.datatype = "uinteger"
|
||||
o.default = 1111
|
||||
|
||||
o = s:option(Value, "admin_user", translate("User name"))
|
||||
o.default = "admin"
|
||||
|
||||
o = s:option(Value, "admin_password", translate("Password"))
|
||||
o.default = "root"
|
||||
|
||||
|
||||
|
||||
|
||||
return m
|
||||
|
||||
|
||||
@ -1,23 +0,0 @@
|
||||
local fs = require "nixio.fs"
|
||||
local conffile = "/etc/dnsmasq.ssr/appoint_list.conf"
|
||||
|
||||
f = SimpleForm("custom", translate("Appoint dns List"))
|
||||
|
||||
t = f:field(TextValue, "conf")
|
||||
t.rmempty = true
|
||||
t.rows = 13
|
||||
function t.cfgvalue()
|
||||
return fs.readfile(conffile) or ""
|
||||
end
|
||||
|
||||
function f.handle(self, state, data)
|
||||
if state == FORM_VALID then
|
||||
if data.conf then
|
||||
fs.writefile(conffile, data.conf:gsub("\r\n", "\n"))
|
||||
luci.sys.call("/etc/init.d/dnsmasq restart")
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
return f
|
||||
@ -1,49 +0,0 @@
|
||||
local shadowsocksr = "shadowsocksr"
|
||||
local uci = luci.model.uci.cursor()
|
||||
local server_table = {}
|
||||
|
||||
uci:foreach(shadowsocksr, "servers", function(s)
|
||||
if s.alias then
|
||||
server_table[s[".name"]] = "[%s]:%s" %{string.upper(s.type), s.alias}
|
||||
elseif s.server and s.server_port then
|
||||
server_table[s[".name"]] = "[%s]:%s:%s" %{string.upper(s.type), s.server, s.server_port}
|
||||
end
|
||||
end)
|
||||
|
||||
local key_table = {}
|
||||
for key,_ in pairs(server_table) do
|
||||
table.insert(key_table,key)
|
||||
end
|
||||
|
||||
table.sort(key_table)
|
||||
|
||||
m = Map(shadowsocksr)
|
||||
|
||||
|
||||
s = m:section(TypedSection, "global", translate("Server failsafe auto swith settings"))
|
||||
s.anonymous = true
|
||||
|
||||
o = s:option(Flag, "monitor_enable", translate("Enable Process Deamon"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Flag, "enable_switch", translate("Enable Auto Switch"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "switch_time", translate("Switch check cycly(second)"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("enable_switch", "1")
|
||||
o.default = 3600
|
||||
|
||||
o = s:option(Value, "switch_timeout", translate("Check timout(second)"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("enable_switch", "1")
|
||||
o.default = 5
|
||||
|
||||
o = s:option(Value, "switch_try_count", translate("Check Try Count"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("enable_switch", "1")
|
||||
o.default = 3
|
||||
|
||||
|
||||
return m
|
||||
|
||||
@ -1,461 +0,0 @@
|
||||
-- Copyright (C) 2017 yushi studio <ywb94@qq.com> github.com/ywb94
|
||||
-- Licensed to the public under the GNU General Public License v3.
|
||||
|
||||
local m, s, o,kcp_enable
|
||||
local shadowsocksr = "shadowsocksr"
|
||||
local uci = luci.model.uci.cursor()
|
||||
local ipkg = require("luci.model.ipkg")
|
||||
local fs = require "nixio.fs"
|
||||
local sys = require "luci.sys"
|
||||
local sid = arg[1]
|
||||
local uuid = luci.sys.exec("cat /proc/sys/kernel/random/uuid")
|
||||
|
||||
|
||||
local function isKcptun(file)
|
||||
if not fs.access(file, "rwx", "rx", "rx") then
|
||||
fs.chmod(file, 755)
|
||||
end
|
||||
|
||||
local str = sys.exec(file .. " -v | awk '{printf $1}'")
|
||||
return (str:lower() == "kcptun")
|
||||
end
|
||||
|
||||
|
||||
local server_table = {}
|
||||
local encrypt_methods = {
|
||||
"none",
|
||||
"table",
|
||||
"rc4",
|
||||
"rc4-md5-6",
|
||||
"rc4-md5",
|
||||
"aes-128-cfb",
|
||||
"aes-192-cfb",
|
||||
"aes-256-cfb",
|
||||
"aes-128-ctr",
|
||||
"aes-192-ctr",
|
||||
"aes-256-ctr",
|
||||
"bf-cfb",
|
||||
"camellia-128-cfb",
|
||||
"camellia-192-cfb",
|
||||
"camellia-256-cfb",
|
||||
"cast5-cfb",
|
||||
"des-cfb",
|
||||
"idea-cfb",
|
||||
"rc2-cfb",
|
||||
"seed-cfb",
|
||||
"salsa20",
|
||||
"chacha20",
|
||||
"chacha20-ietf",
|
||||
}
|
||||
|
||||
local encrypt_methods_ss = {
|
||||
-- aead
|
||||
"aes-128-gcm",
|
||||
"aes-192-gcm",
|
||||
"aes-256-gcm",
|
||||
"chacha20-ietf-poly1305",
|
||||
"xchacha20-ietf-poly1305",
|
||||
-- stream
|
||||
"table",
|
||||
"rc4",
|
||||
"rc4-md5",
|
||||
"aes-128-cfb",
|
||||
"aes-192-cfb",
|
||||
"aes-256-cfb",
|
||||
"aes-128-ctr",
|
||||
"aes-192-ctr",
|
||||
"aes-256-ctr",
|
||||
"bf-cfb",
|
||||
"camellia-128-cfb",
|
||||
"camellia-192-cfb",
|
||||
"camellia-256-cfb",
|
||||
"salsa20",
|
||||
"chacha20",
|
||||
"chacha20-ietf",
|
||||
}
|
||||
|
||||
local protocol = {
|
||||
"origin",
|
||||
"verify_deflate",
|
||||
"auth_sha1_v4",
|
||||
"auth_aes128_sha1",
|
||||
"auth_aes128_md5",
|
||||
"auth_chain_a",
|
||||
"auth_chain_b",
|
||||
"auth_chain_c",
|
||||
"auth_chain_d",
|
||||
"auth_chain_e",
|
||||
"auth_chain_f",
|
||||
}
|
||||
|
||||
local obfs = {
|
||||
"plain",
|
||||
"http_simple",
|
||||
"http_post",
|
||||
"random_head",
|
||||
"tls1.2_ticket_auth",
|
||||
}
|
||||
|
||||
local securitys = {
|
||||
"auto",
|
||||
"none",
|
||||
"aes-128-gcm",
|
||||
"chacha20-poly1305"
|
||||
}
|
||||
|
||||
|
||||
m = Map(shadowsocksr, translate("Edit ShadowSocksR Server"))
|
||||
m.redirect = luci.dispatcher.build_url("admin/vpn/shadowsocksr/servers")
|
||||
if m.uci:get(shadowsocksr, sid) ~= "servers" then
|
||||
luci.http.redirect(m.redirect)
|
||||
return
|
||||
end
|
||||
|
||||
-- [[ Servers Setting ]]--
|
||||
s = m:section(NamedSection, sid, "servers")
|
||||
s.anonymous = true
|
||||
s.addremove = false
|
||||
|
||||
o = s:option(DummyValue,"ssr_url","SS/SSR/V2RAY/TROJAN URL")
|
||||
o.rawhtml = true
|
||||
o.template = "shadowsocksr/ssrurl"
|
||||
o.value =sid
|
||||
|
||||
|
||||
o = s:option(ListValue, "type", translate("Server Node Type"))
|
||||
if nixio.fs.access("/usr/sbin/trojan") then
|
||||
o:value("trojan", translate("Trojan"))
|
||||
end
|
||||
|
||||
if nixio.fs.access("/usr/bin/v2ray/v2ray") then
|
||||
o:value("v2ray", translate("V2Ray"))
|
||||
end
|
||||
o:value("ssr", translate("ShadowsocksR"))
|
||||
if nixio.fs.access("/usr/bin/ss-redir") then
|
||||
o:value("ss", translate("Shadowsocks"))
|
||||
end
|
||||
if nixio.fs.access("/usr/bin/ipt2socks") then
|
||||
o:value("socks5", translate("Socks5"))
|
||||
end
|
||||
o.description = translate("Using incorrect encryption mothod may causes service fail to start")
|
||||
|
||||
upload_conf = s:option(FileUpload, "")
|
||||
upload_conf.template = "cbi/other_upload2"
|
||||
upload_conf:depends("use_conf_file", 1)
|
||||
|
||||
o = s:option(Value, "alias", translate("Alias(optional)"))
|
||||
|
||||
o = s:option(Value, "server", translate("Server Address"))
|
||||
o.datatype = "host"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "server_port", translate("Server Port"))
|
||||
o.datatype = "port"
|
||||
o.rmempty = false
|
||||
|
||||
-- o = s:option(Value, "timeout", translate("Connection Timeout"))
|
||||
-- o.datatype = "uinteger"
|
||||
-- o.default = 60
|
||||
-- o.rmempty = false
|
||||
|
||||
|
||||
o = s:option(Value, "weight", translate("Weight"))
|
||||
o.datatype = "uinteger"
|
||||
o.default = 10
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Flag, "auth_enable", translate("Enable Authentication"))
|
||||
o.rmempty = false
|
||||
o.default = "0"
|
||||
o:depends("type", "socks5")
|
||||
|
||||
o = s:option(Value, "username", translate("Username"))
|
||||
o.rmempty = true
|
||||
o:depends("type", "socks5")
|
||||
o = s:option(Value, "password", translate("Password"))
|
||||
o.password = true
|
||||
o.rmempty = true
|
||||
o:depends("type", "ssr")
|
||||
o:depends("type", "ss")
|
||||
o:depends("type", "trojan")
|
||||
o:depends("type", "socks5")
|
||||
|
||||
|
||||
o = s:option(ListValue, "encrypt_method", translate("Encrypt Method"))
|
||||
for _, v in ipairs(encrypt_methods) do o:value(v) end
|
||||
o.rmempty = true
|
||||
o:depends("type", "ssr")
|
||||
|
||||
o = s:option(ListValue, "encrypt_method_ss", translate("Encrypt Method"))
|
||||
for _, v in ipairs(encrypt_methods_ss) do o:value(v) end
|
||||
o.rmempty = true
|
||||
o:depends("type", "ss")
|
||||
|
||||
o = s:option(ListValue, "plugin", translate("plugin"))
|
||||
o:value("none", "None")
|
||||
if nixio.fs.access("/usr/bin/v2ray-plugin") then
|
||||
o:value("/usr/bin/v2ray-plugin", "v2ray-plugin")
|
||||
end
|
||||
if nixio.fs.access("/usr/bin/obfs-local") then
|
||||
o:value("/usr/bin/obfs-local", "obfs-local")
|
||||
end
|
||||
if nixio.fs.access("/usr/bin/goquiet-client") then
|
||||
o:value("/usr/bin/goquiet-client", "GoQuiet")
|
||||
end
|
||||
o.rmempty = false
|
||||
o.default = "none"
|
||||
o:depends("type", "ss")
|
||||
|
||||
o = s:option(Value, "plugin_opts", translate("Plugin Opts"))
|
||||
o.rmempty = true
|
||||
o:depends("plugin", "/usr/bin/v2ray-plugin")
|
||||
o:depends("plugin", "/usr/bin/obfs-local")
|
||||
o:depends("plugin", "/usr/bin/goquiet-client")
|
||||
|
||||
|
||||
o = s:option(ListValue, "protocol", translate("Protocol"))
|
||||
for _, v in ipairs(protocol) do o:value(v) end
|
||||
o.rmempty = true
|
||||
o:depends("type", "ssr")
|
||||
|
||||
o = s:option(Value, "protocol_param", translate("Protocol param(optional)"))
|
||||
o:depends("type", "ssr")
|
||||
|
||||
o = s:option(ListValue, "obfs", translate("Obfs"))
|
||||
for _, v in ipairs(obfs) do o:value(v) end
|
||||
o.rmempty = true
|
||||
o:depends("type", "ssr")
|
||||
|
||||
o = s:option(Value, "obfs_param", translate("Obfs param(optional)"))
|
||||
o:depends("type", "ssr")
|
||||
|
||||
-- AlterId
|
||||
o = s:option(Value, "alter_id", translate("AlterId"))
|
||||
o.default = 100
|
||||
o.rmempty = true
|
||||
o:depends("type", "v2ray")
|
||||
|
||||
-- VmessId
|
||||
o = s:option(Value, "vmess_id", translate("VmessId (UUID)"))
|
||||
o.rmempty = true
|
||||
o.default = uuid
|
||||
o:depends("type", "v2ray")
|
||||
|
||||
-- 加密方式
|
||||
o = s:option(ListValue, "security", translate("Encrypt Method"))
|
||||
for _, v in ipairs(securitys) do o:value(v, v:upper()) end
|
||||
o.rmempty = true
|
||||
o:depends("type", "v2ray")
|
||||
|
||||
-- 传输协议
|
||||
o = s:option(ListValue, "transport", translate("Transport"))
|
||||
o:value("tcp", "TCP")
|
||||
o:value("kcp", "mKCP")
|
||||
o:value("ws", "WebSocket")
|
||||
o:value("h2", "HTTP/2")
|
||||
o:value("quic", "QUIC")
|
||||
o.rmempty = true
|
||||
o:depends("type", "v2ray")
|
||||
|
||||
-- [[ TCP部分 ]]--
|
||||
|
||||
-- TCP伪装
|
||||
o = s:option(ListValue, "tcp_guise", translate("Camouflage Type"))
|
||||
o:depends("transport", "tcp")
|
||||
o:value("none", translate("None"))
|
||||
o:value("http", "HTTP")
|
||||
o.rmempty = true
|
||||
|
||||
-- HTTP域名
|
||||
o = s:option(DynamicList, "http_host", translate("HTTP Host"))
|
||||
o:depends("tcp_guise", "http")
|
||||
o.rmempty = true
|
||||
|
||||
-- HTTP路径
|
||||
o = s:option(DynamicList, "http_path", translate("HTTP Path"))
|
||||
o:depends("tcp_guise", "http")
|
||||
o.rmempty = true
|
||||
|
||||
|
||||
-- [[ WS部分 ]]--
|
||||
|
||||
-- WS域名
|
||||
o = s:option(Value, "ws_host", translate("WebSocket Host"))
|
||||
o:depends("transport", "ws")
|
||||
o.rmempty = true
|
||||
|
||||
-- WS路径
|
||||
o = s:option(Value, "ws_path", translate("WebSocket Path"))
|
||||
o:depends("transport", "ws")
|
||||
o.rmempty = true
|
||||
|
||||
-- [[ H2部分 ]]--
|
||||
|
||||
-- H2域名
|
||||
o = s:option(DynamicList, "h2_host", translate("HTTP/2 Host"))
|
||||
o:depends("transport", "h2")
|
||||
o.rmempty = true
|
||||
|
||||
-- H2路径
|
||||
o = s:option(Value, "h2_path", translate("HTTP/2 Path"))
|
||||
o:depends("transport", "h2")
|
||||
o.rmempty = true
|
||||
|
||||
|
||||
-- [[ QUIC部分 ]]--
|
||||
|
||||
o = s:option(ListValue, "quic_security", translate("QUIC Security"))
|
||||
o:depends("transport", "quic")
|
||||
o.rmempty = true
|
||||
o:value("none", translate("None"))
|
||||
o:value("aes-128-gcm", translate("aes-128-gcm"))
|
||||
o:value("chacha20-poly1305", translate("chacha20-poly1305"))
|
||||
|
||||
o = s:option(Value, "quic_key", translate("QUIC Key"))
|
||||
o:depends("transport", "quic")
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(ListValue, "quic_guise", translate("Header"))
|
||||
o:depends("transport", "quic")
|
||||
o.rmempty = true
|
||||
o:value("none", translate("None"))
|
||||
o:value("srtp", translate("VideoCall (SRTP)"))
|
||||
o:value("utp", translate("BitTorrent (uTP)"))
|
||||
o:value("wechat-video", translate("WechatVideo"))
|
||||
o:value("dtls", "DTLS 1.2")
|
||||
o:value("wireguard", "WireGuard")
|
||||
|
||||
-- [[ mKCP部分 ]]--
|
||||
|
||||
o = s:option(ListValue, "kcp_guise", translate("Camouflage Type"))
|
||||
o:depends("transport", "kcp")
|
||||
o:value("none", translate("None"))
|
||||
o:value("srtp", translate("VideoCall (SRTP)"))
|
||||
o:value("utp", translate("BitTorrent (uTP)"))
|
||||
o:value("wechat-video", translate("WechatVideo"))
|
||||
o:value("dtls", "DTLS 1.2")
|
||||
o:value("wireguard", "WireGuard")
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Value, "mtu", translate("MTU"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("transport", "kcp")
|
||||
o.default = 1350
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Value, "tti", translate("TTI"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("transport", "kcp")
|
||||
o.default = 50
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Value, "uplink_capacity", translate("Uplink Capacity"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("transport", "kcp")
|
||||
o.default = 50
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Value, "downlink_capacity", translate("Downlink Capacity"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("transport", "kcp")
|
||||
o.default = 20
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Value, "read_buffer_size", translate("Read Buffer Size"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("transport", "kcp")
|
||||
o.default = 2
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Value, "write_buffer_size", translate("Write Buffer Size"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("transport", "kcp")
|
||||
o.default = 2
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Flag, "congestion", translate("Congestion"))
|
||||
o:depends("transport", "kcp")
|
||||
o.rmempty = true
|
||||
|
||||
-- [[ allowInsecure ]]--
|
||||
o = s:option(Flag, "insecure", translate("allowInsecure"))
|
||||
o.rmempty = true
|
||||
o:depends("type", "v2ray")
|
||||
o:depends("type", "trojan")
|
||||
|
||||
-- [[ TLS ]]--
|
||||
o = s:option(Flag, "tls", translate("TLS"))
|
||||
o.rmempty = true
|
||||
o.default = "0"
|
||||
o:depends("type", "v2ray")
|
||||
o:depends("type", "trojan")
|
||||
|
||||
-- [[ Mux ]]--
|
||||
o = s:option(Flag, "mux", translate("Mux"))
|
||||
o.rmempty = true
|
||||
o.default = "0"
|
||||
o:depends("type", "v2ray")
|
||||
|
||||
o = s:option(Value, "concurrency", translate("Concurrency"))
|
||||
o.datatype = "uinteger"
|
||||
o.rmempty = true
|
||||
o.default = "8"
|
||||
o:depends("mux", "1")
|
||||
|
||||
o = s:option(Flag, "fast_open", translate("TCP Fast Open"))
|
||||
o.rmempty = true
|
||||
o.default = "0"
|
||||
o:depends("type", "ssr")
|
||||
o:depends("type", "ss")
|
||||
o:depends("type", "trojan")
|
||||
|
||||
o = s:option(Flag, "switch_enable", translate("Enable Auto Switch"))
|
||||
o.rmempty = false
|
||||
o.default = "1"
|
||||
|
||||
o = s:option(Value, "local_port", translate("Local Port"))
|
||||
o.datatype = "port"
|
||||
o.default = 1234
|
||||
o.rmempty = false
|
||||
|
||||
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.default = "0"
|
||||
kcp_enable:depends("type", "ssr")
|
||||
kcp_enable:depends("type", "ss")
|
||||
|
||||
o = s:option(Value, "kcp_port", translate("KcpTun Port"))
|
||||
o.datatype = "port"
|
||||
o.default = 4000
|
||||
function o.validate(self, value, section)
|
||||
local kcp_file="/usr/bin/kcptun-client"
|
||||
local enable = kcp_enable:formvalue(section) or kcp_enable.disabled
|
||||
if enable == kcp_enable.enabled then
|
||||
if not fs.access(kcp_file) then
|
||||
return nil, translate("Haven't a Kcptun executable file")
|
||||
elseif not isKcptun(kcp_file) then
|
||||
return nil, translate("Not a Kcptun executable file")
|
||||
end
|
||||
end
|
||||
|
||||
return value
|
||||
end
|
||||
o:depends("type", "ssr")
|
||||
o:depends("type", "ss")
|
||||
|
||||
o = s:option(Value, "kcp_password", translate("KcpTun Password"))
|
||||
o.password = true
|
||||
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
|
||||
|
||||
return m
|
||||
|
||||
@ -1,237 +0,0 @@
|
||||
-- Copyright (C) 2017 yushi studio <ywb94@qq.com> github.com/ywb94
|
||||
-- Copyright (C) 2018 lean <coolsnowwolf@gmail.com> github.com/coolsnowwolf
|
||||
-- Licensed to the public under the GNU General Public License v3.
|
||||
|
||||
local m, s, sec, o, kcp_enable
|
||||
local shadowsocksr = "shadowsocksr"
|
||||
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
|
||||
gfwmode=1
|
||||
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(shadowsocksr)
|
||||
|
||||
m:section(SimpleSection).template = "shadowsocksr/status"
|
||||
|
||||
local server_table = {}
|
||||
local v2ray_table = {}
|
||||
uci:foreach(shadowsocksr, "servers", function(s)
|
||||
if s.alias then
|
||||
server_table[s[".name"]] = "[%s]:%s" %{string.upper(s.type), s.alias}
|
||||
elseif s.server and s.server_port then
|
||||
server_table[s[".name"]] = "[%s]:%s:%s" %{string.upper(s.type), s.server, s.server_port}
|
||||
end
|
||||
if s.type == "v2ray" then
|
||||
if s.alias then
|
||||
v2ray_table[s[".name"]] = "[%s]:%s" %{string.upper(s.type), s.alias}
|
||||
elseif s.server and s.server_port then
|
||||
v2ray_table[s[".name"]] = "[%s]:%s:%s" %{string.upper(s.type), s.server, s.server_port}
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
local key_table = {}
|
||||
for key,_ in pairs(server_table) do
|
||||
table.insert(key_table,key)
|
||||
end
|
||||
|
||||
table.sort(key_table)
|
||||
|
||||
local key_table_v2 = {}
|
||||
for key,_ in pairs(v2ray_table) do
|
||||
table.insert(key_table_v2,key)
|
||||
end
|
||||
|
||||
table.sort(key_table_v2)
|
||||
|
||||
-- [[ Global Setting ]]--
|
||||
s = m:section(TypedSection, "global", translate("ShadowSocksR Plus+ Settings"))
|
||||
s.anonymous = true
|
||||
|
||||
o = s:option(ListValue, "global_server", translate("Main Server"))
|
||||
o:value("nil", translate("Disable"))
|
||||
if nixio.fs.access("/usr/sbin/haproxy")then
|
||||
o:value("__haproxy__", translate("Load Balancing"))
|
||||
end
|
||||
for _,key in pairs(key_table) do o:value(key,server_table[key]) end
|
||||
o.default = "nil"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(ListValue, "udp_relay_server", translate("Game Mode UDP Server"))
|
||||
o:value("", translate("Disable"))
|
||||
o:value("same", translate("Same as Global Server"))
|
||||
for _,key in pairs(key_table) do o:value(key,server_table[key]) end
|
||||
|
||||
o = s:option(Flag, "v2ray_flow", translate("Open v2ray split-flow"))
|
||||
o.rmempty = false
|
||||
o.description = translate("When open v2ray split-flow,your main server must be a v2ray server")
|
||||
|
||||
o = s:option(ListValue, "youtube_server", translate("Youtube Proxy"))
|
||||
o:value("nil", translate("Same as Global Server"))
|
||||
for _,key in pairs(key_table_v2) do o:value(key,v2ray_table[key]) end
|
||||
o:depends("v2ray_flow", "1")
|
||||
o.default = "nil"
|
||||
|
||||
|
||||
|
||||
o = s:option(ListValue, "tw_video_server", translate("TaiWan Video Proxy"))
|
||||
o:value("nil", translate("Same as Global Server"))
|
||||
for _,key in pairs(key_table_v2) do o:value(key,v2ray_table[key]) end
|
||||
o:depends("v2ray_flow", "1")
|
||||
o.default = "nil"
|
||||
|
||||
|
||||
o = s:option(ListValue, "netflix_server", translate("Netflix Proxy"))
|
||||
o:value("nil", translate("Same as Global Server"))
|
||||
for _,key in pairs(key_table_v2) do o:value(key,v2ray_table[key]) end
|
||||
o:depends("v2ray_flow", "1")
|
||||
o.default = "nil"
|
||||
|
||||
|
||||
o = s:option(ListValue, "disney_server", translate("Diseny+ Proxy"))
|
||||
o:value("nil", translate("Same as Global Server"))
|
||||
for _,key in pairs(key_table_v2) do o:value(key,v2ray_table[key]) end
|
||||
o:depends("v2ray_flow", "1")
|
||||
o.default = "nil"
|
||||
|
||||
|
||||
o = s:option(ListValue, "prime_server", translate("Prime Video Proxy"))
|
||||
o:value("nil", translate("Same as Global Server"))
|
||||
for _,key in pairs(key_table_v2) do o:value(key,v2ray_table[key]) end
|
||||
o:depends("v2ray_flow", "1")
|
||||
o.default = "nil"
|
||||
|
||||
|
||||
o = s:option(ListValue, "threads", translate("Multi Threads Option"))
|
||||
o:value("0", translate("Auto Threads"))
|
||||
o:value("1", translate("1 Thread"))
|
||||
o:value("2", translate("2 Threads"))
|
||||
o:value("4", translate("4 Threads"))
|
||||
o:value("8", translate("8 Threads"))
|
||||
o:value("16", translate("16 Threads"))
|
||||
o:value("32", translate("32 Threads"))
|
||||
o:value("64", translate("64 Threads"))
|
||||
o:value("128", translate("128 Threads"))
|
||||
o:value("256", translate("256 Threads"))
|
||||
o:value("512", translate("512 Threads"))
|
||||
o.default = "0"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(ListValue, "run_mode", translate("Running Mode"))
|
||||
o:value("gfw", translate("GFW List Mode"))
|
||||
o:value("router", translate("IP Route Mode"))
|
||||
o:value("routers", translate("Oversea IP Route Mode"))
|
||||
o:value("all", translate("Global Mode"))
|
||||
o.default = gfw
|
||||
|
||||
o = s:option(ListValue, "pdnsd_enable", translate("Resolve Dns Mode"))
|
||||
o:value("0", translate("Use Local DNS Service listen port 5335"))
|
||||
o:value("1", translate("Use Pdnsd tcp query and cache"))
|
||||
o:value("2", translate("Use Pdnsd udp query and cache"))
|
||||
if nixio.fs.access("/usr/bin/dnsforwarder") then
|
||||
o:value("3", translate("Use dnsforwarder tcp query and cache"))
|
||||
o:value("4", translate("Use dnsforwarder udp query and cache"))
|
||||
end
|
||||
if nixio.fs.access("/usr/bin/dnscrypt-proxy") then
|
||||
o:value("5", translate("Use dnscrypt-proxy query and cache"))
|
||||
end
|
||||
if nixio.fs.access("/usr/bin/chinadns") then
|
||||
o:value("6", translate("Use chinadns query and cache"))
|
||||
end
|
||||
|
||||
o.default = 1
|
||||
|
||||
o = s:option(ListValue, "chinadns_enable", translate("Chiadns Resolve Dns Mode"))
|
||||
o:value("0", translate("Use Local DNS Service"))
|
||||
o:value("1", translate("Use Pdnsd tcp query and cache"))
|
||||
o:value("2", translate("Use Pdnsd udp query and cache"))
|
||||
if nixio.fs.access("/usr/bin/dnsforwarder") then
|
||||
o:value("3", translate("Use dnsforwarder tcp query and cache"))
|
||||
o:value("4", translate("Use dnsforwarder udp query and cache"))
|
||||
end
|
||||
if nixio.fs.access("/usr/bin/dnscrypt-proxy") then
|
||||
o:value("5", translate("Use dnscrypt-proxy query and cache"))
|
||||
end
|
||||
|
||||
if nixio.fs.access("/usr/sbin/smartdns") then
|
||||
o:value("6", translate("Use smartdns query and cache"))
|
||||
end
|
||||
|
||||
if nixio.fs.access("/usr/sbin/https_dns_proxy") then
|
||||
o:value("7", translate("Use https_dns_proxy query and cache"))
|
||||
end
|
||||
o.default = 1
|
||||
o:depends("pdnsd_enable", "6")
|
||||
|
||||
o = s:option(Value, "tunnel_forward", translate("Anti-pollution DNS Server"))
|
||||
o:value("0.0.0.0:53", translate("Using System Default DNS"))
|
||||
o:value("0.0.0.0:5333", translate("Using acceleration center DNS"))
|
||||
o:value("8.8.4.4:53", translate("Google Public DNS (8.8.4.4)"))
|
||||
o:value("8.8.8.8:53", translate("Google Public DNS (8.8.8.8)"))
|
||||
o:value("208.67.222.222:53", translate("OpenDNS (208.67.222.222)"))
|
||||
o:value("208.67.220.220:53", translate("OpenDNS (208.67.220.220)"))
|
||||
o:value("209.244.0.3:53", translate("Level 3 Public DNS (209.244.0.3)"))
|
||||
o:value("209.244.0.4:53", translate("Level 3 Public DNS (209.244.0.4)"))
|
||||
o:value("4.2.2.1:53", translate("Level 3 Public DNS (4.2.2.1)"))
|
||||
o:value("4.2.2.2:53", translate("Level 3 Public DNS (4.2.2.2)"))
|
||||
o:value("4.2.2.3:53", translate("Level 3 Public DNS (4.2.2.3)"))
|
||||
o:value("4.2.2.4:53", translate("Level 3 Public DNS (4.2.2.4)"))
|
||||
o:value("1.1.1.1:53", translate("Cloudflare DNS (1.1.1.1)"))
|
||||
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:depends("pdnsd_enable", "2")
|
||||
o:depends("pdnsd_enable", "3")
|
||||
o:depends("pdnsd_enable", "4")
|
||||
o:depends("pdnsd_enable", "6")
|
||||
o.default = "8.8.4.4:53"
|
||||
|
||||
o = s:option(Flag, "bt", translate("Kill BT"))
|
||||
o.default = 0
|
||||
o.rmempty = false
|
||||
o.description = translate("Prohibit downloading tool ports through proxy")
|
||||
|
||||
o = s:option(Value, "bt_port", translate("BT Port"))
|
||||
o.default = "1236:65535"
|
||||
o.rmempty = true
|
||||
o:depends("bt", "1")
|
||||
|
||||
o = s:option(Button,"gfw_data",translate("GFW List Data"))
|
||||
o.rawhtml = true
|
||||
o.template = "shadowsocksr/refresh"
|
||||
o.value =tostring(math.ceil(gfw_count)) .. " " .. translate("Records")
|
||||
|
||||
o = s:option(Button,"ad_data",translate("Advertising Data"))
|
||||
o .rawhtml = true
|
||||
o .template = "shadowsocksr/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 = "shadowsocksr/refresh"
|
||||
o.value =ip_count .. " " .. translate("Records")
|
||||
|
||||
o = s:option(Button,"check_port",translate("Check Server Port"))
|
||||
o.template = "shadowsocksr/checkport"
|
||||
o.value =translate("No Check")
|
||||
|
||||
return m
|
||||
@ -1,104 +0,0 @@
|
||||
local m, s, o
|
||||
local NXFS = require "nixio.fs"
|
||||
|
||||
m = Map("shadowsocksr", translate("IP black-and-white list"))
|
||||
|
||||
s = m:section(TypedSection, "access_control")
|
||||
s.anonymous = true
|
||||
|
||||
-- Part of WAN
|
||||
s:tab("wan_ac", translate("WAN IP AC"))
|
||||
|
||||
o = s:taboption("wan_ac", DynamicList, "wan_bp_ips", translate("WAN White List IP"))
|
||||
o.datatype = "ip4addr"
|
||||
|
||||
o = s:taboption("wan_ac", DynamicList, "wan_fw_ips", translate("WAN Force Proxy IP"))
|
||||
o.datatype = "ip4addr"
|
||||
|
||||
-- Part of LAN
|
||||
s:tab("lan_ac", translate("LAN IP AC"))
|
||||
|
||||
o = s:taboption("lan_ac", ListValue, "lan_ac_mode", translate("LAN Access Control"))
|
||||
o:value("0", translate("Disable"))
|
||||
o:value("w", translate("Allow listed only"))
|
||||
o:value("b", translate("Allow all except listed"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("lan_ac", DynamicList, "lan_ac_ips", translate("LAN Host List"))
|
||||
o.datatype = "ipaddr"
|
||||
luci.ip.neighbors({ family = 4 }, function(entry)
|
||||
if entry.reachable then
|
||||
o:value(entry.dest:string())
|
||||
end
|
||||
end)
|
||||
o:depends("lan_ac_mode", "w")
|
||||
o:depends("lan_ac_mode", "b")
|
||||
|
||||
o = s:taboption("lan_ac", DynamicList, "lan_bp_ips", translate("LAN Bypassed Host List"))
|
||||
o.datatype = "ipaddr"
|
||||
luci.ip.neighbors({ family = 4 }, function(entry)
|
||||
if entry.reachable then
|
||||
o:value(entry.dest:string())
|
||||
end
|
||||
end)
|
||||
|
||||
o = s:taboption("lan_ac", DynamicList, "lan_fp_ips", translate("LAN Force Proxy Host List"))
|
||||
o.datatype = "ipaddr"
|
||||
luci.ip.neighbors({ family = 4 }, function(entry)
|
||||
if entry.reachable then
|
||||
o:value(entry.dest:string())
|
||||
end
|
||||
end)
|
||||
|
||||
o = s:taboption("lan_ac", DynamicList, "lan_gm_ips", translate("Game Mode Host List"))
|
||||
o.datatype = "ipaddr"
|
||||
luci.ip.neighbors({ family = 4 }, function(entry)
|
||||
if entry.reachable then
|
||||
o:value(entry.dest:string())
|
||||
end
|
||||
end)
|
||||
|
||||
-- Part of Self
|
||||
-- s:tab("self_ac", translate("Router Self AC"))
|
||||
-- o = s:taboption("self_ac",ListValue, "router_proxy", translate("Router Self Proxy"))
|
||||
-- o:value("1", translatef("Normal Proxy"))
|
||||
-- o:value("0", translatef("Bypassed Proxy"))
|
||||
-- o:value("2", translatef("Forwarded Proxy"))
|
||||
-- o.rmempty = false
|
||||
|
||||
s:tab("esc", translate("Bypass Domain List"))
|
||||
|
||||
local escconf = "/etc/config/white.list"
|
||||
o = s:taboption("esc", TextValue, "escconf")
|
||||
o.rows = 13
|
||||
o.wrap = "off"
|
||||
o.rmempty = true
|
||||
o.cfgvalue = function(self, section)
|
||||
return NXFS.readfile(escconf) or ""
|
||||
end
|
||||
o.write = function(self, section, value)
|
||||
NXFS.writefile(escconf, value:gsub("\r\n", "\n"))
|
||||
end
|
||||
o.remove = function(self, section, value)
|
||||
NXFS.writefile(escconf, "")
|
||||
end
|
||||
|
||||
|
||||
s:tab("block", translate("Black Domain List"))
|
||||
|
||||
local blockconf = "/etc/config/black.list"
|
||||
o = s:taboption("block", TextValue, "blockconf")
|
||||
o.rows = 13
|
||||
o.wrap = "off"
|
||||
o.rmempty = true
|
||||
o.cfgvalue = function(self, section)
|
||||
return NXFS.readfile(blockconf) or " "
|
||||
end
|
||||
o.write = function(self, section, value)
|
||||
NXFS.writefile(blockconf, value:gsub("\r\n", "\n"))
|
||||
end
|
||||
o.remove = function(self, section, value)
|
||||
NXFS.writefile(blockconf, "")
|
||||
end
|
||||
|
||||
return m
|
||||
@ -1,24 +0,0 @@
|
||||
local fs = require "nixio.fs"
|
||||
local conffile = "/etc/config/gfw.list"
|
||||
|
||||
f = SimpleForm("custom", translate("GFW Custom List"), translate("Please refer to the following writing"))
|
||||
|
||||
t = f:field(TextValue, "conf")
|
||||
t.rmempty = true
|
||||
t.rows = 13
|
||||
function t.cfgvalue()
|
||||
return fs.readfile(conffile) or ""
|
||||
end
|
||||
|
||||
function f.handle(self, state, data)
|
||||
if state == FORM_VALID then
|
||||
if data.conf then
|
||||
fs.writefile(conffile, data.conf:gsub("\r\n", "\n"))
|
||||
luci.sys.call("/usr/share/shadowsocksr/gfw2ipset.sh && /etc/init.d/dnsmasq restart")
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
return f
|
||||
@ -1,15 +0,0 @@
|
||||
local fs = require "nixio.fs"
|
||||
local conffile = "/tmp/ssrpro.log"
|
||||
|
||||
f = SimpleForm("logview")
|
||||
|
||||
t = f:field(TextValue, "conf")
|
||||
t.rmempty = true
|
||||
t.rows = 20
|
||||
function t.cfgvalue()
|
||||
luci.sys.exec("[ -f /tmp/ssrplus.log ] && sed '1!G;h;$!d' /tmp/ssrplus.log > /tmp/ssrpro.log")
|
||||
return fs.readfile(conffile) or ""
|
||||
end
|
||||
t.readonly="readonly"
|
||||
|
||||
return f
|
||||
@ -1,48 +0,0 @@
|
||||
-- Copyright 2008 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("shadowsocksr")
|
||||
|
||||
-- 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/ssr*" % 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 = "shadowsocksr/logsview"
|
||||
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,23 +0,0 @@
|
||||
local fs = require "nixio.fs"
|
||||
local conffile = "/etc/dnsmasq.oversea/base_list.conf"
|
||||
|
||||
f = SimpleForm("custom", translate("Oversea Custom List"))
|
||||
|
||||
t = f:field(TextValue, "conf")
|
||||
t.rmempty = true
|
||||
t.rows = 13
|
||||
function t.cfgvalue()
|
||||
return fs.readfile(conffile) or ""
|
||||
end
|
||||
|
||||
function f.handle(self, state, data)
|
||||
if state == FORM_VALID then
|
||||
if data.conf then
|
||||
fs.writefile(conffile, data.conf:gsub("\r\n", "\n"))
|
||||
luci.sys.call("/etc/init.d/dnsmasq restart")
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
return f
|
||||
@ -1,380 +0,0 @@
|
||||
-- Copyright (C) 2017 yushi studio <ywb94@qq.com>
|
||||
-- Licensed to the public under the GNU General Public License v3.
|
||||
|
||||
local m, s, o
|
||||
local shadowsocksr = "shadowsocksr"
|
||||
local uci = luci.model.uci.cursor()
|
||||
local fs = require "nixio.fs"
|
||||
local sys = require "luci.sys"
|
||||
local sid = arg[1]
|
||||
local uuid = luci.sys.exec("cat /proc/sys/kernel/random/uuid")
|
||||
local http = luci.http
|
||||
local ucursor = require "luci.model.uci".cursor()
|
||||
|
||||
local server_table = {}
|
||||
local encrypt_methods = {
|
||||
"none",
|
||||
"table",
|
||||
"rc4",
|
||||
"rc4-md5-6",
|
||||
"rc4-md5",
|
||||
"aes-128-cfb",
|
||||
"aes-192-cfb",
|
||||
"aes-256-cfb",
|
||||
"aes-128-ctr",
|
||||
"aes-192-ctr",
|
||||
"aes-256-ctr",
|
||||
"bf-cfb",
|
||||
"camellia-128-cfb",
|
||||
"camellia-192-cfb",
|
||||
"camellia-256-cfb",
|
||||
"cast5-cfb",
|
||||
"des-cfb",
|
||||
"idea-cfb",
|
||||
"rc2-cfb",
|
||||
"seed-cfb",
|
||||
"salsa20",
|
||||
"chacha20",
|
||||
"chacha20-ietf",
|
||||
}
|
||||
|
||||
local encrypt_methods_ss = {
|
||||
-- aead
|
||||
"aes-128-gcm",
|
||||
"aes-192-gcm",
|
||||
"aes-256-gcm",
|
||||
"chacha20-ietf-poly1305",
|
||||
"xchacha20-ietf-poly1305",
|
||||
-- stream
|
||||
"table",
|
||||
"rc4",
|
||||
"rc4-md5",
|
||||
"aes-128-cfb",
|
||||
"aes-192-cfb",
|
||||
"aes-256-cfb",
|
||||
"aes-128-ctr",
|
||||
"aes-192-ctr",
|
||||
"aes-256-ctr",
|
||||
"bf-cfb",
|
||||
"camellia-128-cfb",
|
||||
"camellia-192-cfb",
|
||||
"camellia-256-cfb",
|
||||
"salsa20",
|
||||
"chacha20",
|
||||
"chacha20-ietf",
|
||||
}
|
||||
|
||||
local protocol = {
|
||||
"origin",
|
||||
"verify_deflate",
|
||||
"auth_sha1_v4",
|
||||
"auth_aes128_sha1",
|
||||
"auth_aes128_md5",
|
||||
"auth_chain_a",
|
||||
"auth_chain_b",
|
||||
"auth_chain_c",
|
||||
"auth_chain_d",
|
||||
"auth_chain_e",
|
||||
"auth_chain_f",
|
||||
}
|
||||
|
||||
obfs = {
|
||||
"plain",
|
||||
"http_simple",
|
||||
"http_post",
|
||||
"random_head",
|
||||
"tls1.2_ticket_auth",
|
||||
}
|
||||
|
||||
local obfs_opts = {
|
||||
"none",
|
||||
"http",
|
||||
"tls",
|
||||
}
|
||||
|
||||
local securitys = {
|
||||
"auto",
|
||||
"none",
|
||||
"aes-128-gcm",
|
||||
"chacha20-poly1305"
|
||||
}
|
||||
|
||||
|
||||
|
||||
m = Map(shadowsocksr, translate("Edit ShadowSocksR Server"))
|
||||
|
||||
m.redirect = luci.dispatcher.build_url("admin/vpn/shadowsocksr/server")
|
||||
if m.uci:get(shadowsocksr, sid) ~= "server_config" then
|
||||
luci.http.redirect(m.redirect)
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
-- [[ Server Setting ]]--
|
||||
s = m:section(NamedSection, sid, "server_config")
|
||||
s.anonymous = true
|
||||
s.addremove = false
|
||||
|
||||
o = s:option(Flag, "enable", translate("Enable"))
|
||||
o.default = 1
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(ListValue, "type", translate("Server Node Type"))
|
||||
if nixio.fs.access("/usr/bin/ssr-server") then
|
||||
o:value("ssr", translate("ShadowsocksR"))
|
||||
end
|
||||
if nixio.fs.access("/usr/bin/ss-server") then
|
||||
o:value("ss", translate("Shadowsocks New Version"))
|
||||
end
|
||||
if nixio.fs.access("/usr/bin/v2ray/v2ray") then
|
||||
o:value("v2ray", translate("V2Ray"))
|
||||
end
|
||||
o.description = translate("Using incorrect encryption mothod may causes service fail to start")
|
||||
|
||||
|
||||
|
||||
o = s:option(Flag, "ipv4_ipv6", translate("Enabling IPv6 server"))
|
||||
o.default = 0
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "server_port", translate("Server Port"))
|
||||
o.datatype = "port"
|
||||
o.default = 8388
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "timeout", translate("Connection Timeout"))
|
||||
o.datatype = "uinteger"
|
||||
o.default = 60
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "password", translate("Password"))
|
||||
o.password = true
|
||||
o.rmempty = true
|
||||
o:depends("type", "ssr")
|
||||
o:depends("type", "ss")
|
||||
|
||||
o = s:option(ListValue, "encrypt_method", translate("Encrypt Method"))
|
||||
for _, v in ipairs(encrypt_methods) do o:value(v) end
|
||||
o.rmempty = true
|
||||
o:depends("type", "ssr")
|
||||
o:depends("type", "ss")
|
||||
|
||||
|
||||
|
||||
o = s:option(ListValue, "plugin", translate("plugin"))
|
||||
o:value("none", "None")
|
||||
if nixio.fs.access("/usr/bin/v2ray-plugin") then
|
||||
o:value("/usr/bin/v2ray-plugin", "v2ray-plugin")
|
||||
end
|
||||
if nixio.fs.access("/usr/bin/obfs-server") then
|
||||
o:value("/usr/bin/obfs-server", "obfs-server")
|
||||
end
|
||||
if nixio.fs.access("/usr/bin/gq-server") then
|
||||
o:value("/usr/bin/gq-server", "GoQuiet")
|
||||
end
|
||||
o.rmempty = false
|
||||
o.default = "none"
|
||||
o:depends("type", "ss")
|
||||
|
||||
o = s:option(Value, "plugin_opts", translate("Plugin Opts"))
|
||||
o.rmempty = true
|
||||
o:depends("plugin", "/usr/bin/v2ray-plugin")
|
||||
o:depends("plugin", "/usr/bin/obfs-server")
|
||||
o:depends("plugin", "/usr/bin/gq-server")
|
||||
|
||||
o = s:option(ListValue, "protocol", translate("Protocol"))
|
||||
for _, v in ipairs(protocol) do o:value(v) end
|
||||
o.rmempty = true
|
||||
o:depends("type", "ssr")
|
||||
|
||||
o = s:option(ListValue, "obfs", translate("Obfs"))
|
||||
for _, v in ipairs(obfs) do o:value(v) end
|
||||
o.rmempty = true
|
||||
o:depends("type", "ssr")
|
||||
|
||||
o = s:option(Value, "obfs_param", translate("Obfs param(optional)"))
|
||||
o:depends("type", "ssr")
|
||||
|
||||
|
||||
-- AlterId
|
||||
o = s:option(Value, "alter_id", translate("AlterId"))
|
||||
o.default = 100
|
||||
o.rmempty = true
|
||||
o:depends("type", "v2ray")
|
||||
|
||||
o=s:option(Value,"VMess_level",translate("User Level"))
|
||||
o.default=1
|
||||
o:depends("type", "v2ray")
|
||||
|
||||
-- VmessId
|
||||
o = s:option(Value, "vmess_id", translate("VmessId (UUID)"))
|
||||
o.rmempty = true
|
||||
o.default = uuid
|
||||
o:depends("type", "v2ray")
|
||||
|
||||
-- 加密方式
|
||||
o = s:option(ListValue, "security", translate("Encrypt Method"))
|
||||
for _, v in ipairs(securitys) do o:value(v, v:upper()) end
|
||||
o.rmempty = true
|
||||
o:depends("type", "v2ray")
|
||||
|
||||
-- 传输协议
|
||||
o = s:option(ListValue, "transport", translate("Transport"))
|
||||
o:value("tcp", "TCP")
|
||||
o:value("kcp", "mKCP")
|
||||
o:value("ws", "WebSocket")
|
||||
o:value("h2", "HTTP/2")
|
||||
o:value("quic", "QUIC")
|
||||
o.rmempty = true
|
||||
o:depends("type", "v2ray")
|
||||
|
||||
-- [[ TCP部分 ]]--
|
||||
|
||||
-- TCP伪装
|
||||
o = s:option(ListValue, "tcp_guise", translate("Camouflage Type"))
|
||||
o:depends("transport", "tcp")
|
||||
o:value("none", translate("None"))
|
||||
o:value("http", "HTTP")
|
||||
o.rmempty = true
|
||||
|
||||
-- HTTP域名
|
||||
o = s:option(DynamicList, "http_host", translate("HTTP Host"))
|
||||
o:depends("tcp_guise", "http")
|
||||
o.rmempty = true
|
||||
|
||||
-- HTTP路径
|
||||
o = s:option(DynamicList, "http_path", translate("HTTP Path"))
|
||||
o:depends("tcp_guise", "http")
|
||||
o.rmempty = true
|
||||
|
||||
-- [[ WS部分 ]]--
|
||||
|
||||
-- WS域名
|
||||
o = s:option(Value, "ws_host", translate("WebSocket Host"))
|
||||
o:depends("transport", "ws")
|
||||
o.rmempty = true
|
||||
|
||||
-- WS路径
|
||||
o = s:option(Value, "ws_path", translate("WebSocket Path"))
|
||||
o:depends("transport", "ws")
|
||||
o.rmempty = true
|
||||
|
||||
-- [[ H2部分 ]]--
|
||||
|
||||
-- H2域名
|
||||
o = s:option(DynamicList, "h2_host", translate("HTTP/2 Host"))
|
||||
o:depends("transport", "h2")
|
||||
o.rmempty = true
|
||||
|
||||
-- H2路径
|
||||
o = s:option(Value, "h2_path", translate("HTTP/2 Path"))
|
||||
o:depends("transport", "h2")
|
||||
o.rmempty = true
|
||||
|
||||
-- [[ QUIC部分 ]]--
|
||||
|
||||
o = s:option(ListValue, "quic_security", translate("QUIC Security"))
|
||||
o:depends("transport", "quic")
|
||||
o.rmempty = true
|
||||
o:value("none", translate("None"))
|
||||
o:value("aes-128-gcm", translate("aes-128-gcm"))
|
||||
o:value("chacha20-poly1305", translate("chacha20-poly1305"))
|
||||
|
||||
o = s:option(Value, "quic_key", translate("QUIC Key"))
|
||||
o:depends("transport", "quic")
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(ListValue, "quic_guise", translate("Header"))
|
||||
o:depends("transport", "quic")
|
||||
o.rmempty = true
|
||||
o:value("none", translate("None"))
|
||||
o:value("srtp", translate("VideoCall (SRTP)"))
|
||||
o:value("utp", translate("BitTorrent (uTP)"))
|
||||
o:value("wechat-video", translate("WechatVideo"))
|
||||
o:value("dtls", "DTLS 1.2")
|
||||
o:value("wireguard", "WireGuard")
|
||||
|
||||
-- [[ mKCP部分 ]]--
|
||||
|
||||
o = s:option(ListValue, "kcp_guise", translate("Camouflage Type"))
|
||||
o:depends("transport", "kcp")
|
||||
o:value("none", translate("None"))
|
||||
o:value("srtp", translate("VideoCall (SRTP)"))
|
||||
o:value("utp", translate("BitTorrent (uTP)"))
|
||||
o:value("wechat-video", translate("WechatVideo"))
|
||||
o:value("dtls", "DTLS 1.2")
|
||||
o:value("wireguard", "WireGuard")
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Value, "mtu", translate("MTU"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("transport", "kcp")
|
||||
o.default = 1350
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Value, "tti", translate("TTI"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("transport", "kcp")
|
||||
o.default = 50
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Value, "uplink_capacity", translate("Uplink Capacity"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("transport", "kcp")
|
||||
o.default = 50
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Value, "downlink_capacity", translate("Downlink Capacity"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("transport", "kcp")
|
||||
o.default = 20
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Value, "read_buffer_size", translate("Read Buffer Size"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("transport", "kcp")
|
||||
o.default = 2
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Value, "write_buffer_size", translate("Write Buffer Size"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("transport", "kcp")
|
||||
o.default = 2
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Flag, "congestion", translate("Congestion"))
|
||||
o:depends("transport", "kcp")
|
||||
o.rmempty = true
|
||||
|
||||
-- [[ allowInsecure ]]--
|
||||
o = s:option(Flag, "insecure", translate("allowInsecure"))
|
||||
o.rmempty = true
|
||||
o:depends("type", "v2ray")
|
||||
|
||||
-- [[ TLS ]]--
|
||||
o = s:option(Flag, "tls", translate("TLS"))
|
||||
o.rmempty = true
|
||||
o.default = "0"
|
||||
o:depends("type", "v2ray")
|
||||
|
||||
-- [[ Mux ]]--
|
||||
o = s:option(Flag, "mux", translate("Mux"))
|
||||
o.rmempty = true
|
||||
o.default = "0"
|
||||
o:depends("type", "v2ray")
|
||||
|
||||
o = s:option(Value, "concurrency", translate("Concurrency"))
|
||||
o.datatype = "uinteger"
|
||||
o.rmempty = true
|
||||
o.default = "8"
|
||||
o:depends("mux", "1")
|
||||
|
||||
o = s:option(Flag, "fast_open", translate("TCP Fast Open"))
|
||||
o.rmempty = true
|
||||
o:depends("type", "ssr")
|
||||
|
||||
return m
|
||||
|
||||
|
||||
@ -1,116 +0,0 @@
|
||||
-- Copyright (C) 2017 yushi studio <ywb94@qq.com>
|
||||
-- Licensed to the public under the GNU General Public License v3.
|
||||
|
||||
local m, sec, o
|
||||
local shadowsocksr = "shadowsocksr"
|
||||
local uci = luci.model.uci.cursor()
|
||||
local ipkg = require("luci.model.ipkg")
|
||||
|
||||
m = Map(shadowsocksr, translate("SS/SSR/V2RAY Server"))
|
||||
|
||||
local type = {
|
||||
"ssr",
|
||||
"ss",
|
||||
"v2ray",
|
||||
}
|
||||
|
||||
local encrypt_methods = {
|
||||
"table",
|
||||
"rc4",
|
||||
"rc4-md5",
|
||||
"rc4-md5-6",
|
||||
"aes-128-cfb",
|
||||
"aes-192-cfb",
|
||||
"aes-256-cfb",
|
||||
"aes-128-ctr",
|
||||
"aes-192-ctr",
|
||||
"aes-256-ctr",
|
||||
"aes-128-gcm",
|
||||
"aes-192-gcm",
|
||||
"aes-256-gcm",
|
||||
"bf-cfb",
|
||||
"camellia-128-cfb",
|
||||
"camellia-192-cfb",
|
||||
"camellia-256-cfb",
|
||||
"cast5-cfb",
|
||||
"des-cfb",
|
||||
"idea-cfb",
|
||||
"rc2-cfb",
|
||||
"seed-cfb",
|
||||
"salsa20",
|
||||
"chacha20",
|
||||
"chacha20-ietf",
|
||||
"chacha20-ietf-poly1305",
|
||||
"xchacha20-ietf-poly1305",
|
||||
}
|
||||
|
||||
local protocol = {
|
||||
"origin",
|
||||
"verify_deflate",
|
||||
"auth_sha1_v4",
|
||||
"auth_aes128_sha1",
|
||||
"auth_aes128_md5",
|
||||
"auth_chain_a",
|
||||
}
|
||||
|
||||
local obfs = {
|
||||
"plain",
|
||||
"http_simple",
|
||||
"http_post",
|
||||
"random_head",
|
||||
"tls1.2_ticket_auth",
|
||||
"tls1.2_ticket_fastauth",
|
||||
}
|
||||
|
||||
|
||||
m:section(SimpleSection).template = "shadowsocksr/status2"
|
||||
-- [[ Global Setting ]]--
|
||||
sec = m:section(TypedSection, "server_global", translate("Global Setting"))
|
||||
sec.anonymous = true
|
||||
|
||||
o = sec:option(Flag, "enable_server", translate("Enable Server"))
|
||||
o.rmempty = false
|
||||
|
||||
-- [[ Server Setting ]]--
|
||||
sec = m:section(TypedSection, "server_config", translate("Server Setting"))
|
||||
sec.anonymous = true
|
||||
sec.addremove = true
|
||||
sec.sortable = true
|
||||
sec.template = "cbi/tblsection"
|
||||
sec.extedit = luci.dispatcher.build_url("admin/vpn/shadowsocksr/server/%s")
|
||||
function sec.create(...)
|
||||
local sid = TypedSection.create(...)
|
||||
if sid then
|
||||
luci.http.redirect(sec.extedit % sid)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
o = sec:option(Flag, "enable", translate("Enable"))
|
||||
function o.cfgvalue(...)
|
||||
return Value.cfgvalue(...) or translate("0")
|
||||
end
|
||||
o.rmempty = false
|
||||
|
||||
o = sec:option(DummyValue, "type", translate("Server Node Type"))
|
||||
function o.cfgvalue(...)
|
||||
return Value.cfgvalue(...) or "?"
|
||||
end
|
||||
|
||||
o = sec:option(DummyValue, "server_port", translate("Server Port"))
|
||||
function o.cfgvalue(...)
|
||||
return Value.cfgvalue(...) or "?"
|
||||
end
|
||||
|
||||
o = sec:option(DummyValue, "encrypt_method", translate("Encrypt Method"))
|
||||
o.width="10%"
|
||||
|
||||
o = sec:option(DummyValue, "protocol", translate("Protocol"))
|
||||
o.width="10%"
|
||||
|
||||
o = sec:option(DummyValue, "obfs", translate("Obfs"))
|
||||
o.width="10%"
|
||||
|
||||
m:append(Template("shadowsocksr/server_list"))
|
||||
return m
|
||||
|
||||
@ -1,80 +0,0 @@
|
||||
-- Licensed to the public under the GNU General Public License v3.
|
||||
|
||||
local m, s, o
|
||||
local shadowsocksr = "shadowsocksr"
|
||||
|
||||
local uci = luci.model.uci.cursor()
|
||||
local server_count = 0
|
||||
uci:foreach("shadowsocksr", "servers", function(s)
|
||||
server_count = server_count + 1
|
||||
end)
|
||||
|
||||
local fs = require "nixio.fs"
|
||||
local sys = require "luci.sys"
|
||||
|
||||
m = Map(shadowsocksr)
|
||||
m:section(SimpleSection).template = "shadowsocksr/status"
|
||||
|
||||
|
||||
-- [[ Servers Manage ]]--
|
||||
s = m:section(TypedSection, "servers")
|
||||
s.anonymous = true
|
||||
s.addremove = true
|
||||
s.description = string.format(translate("Server Count") .. ": %d", server_count)
|
||||
s.sortable = true
|
||||
s.template = "cbi/tblsection"
|
||||
s.extedit = luci.dispatcher.build_url("admin/vpn/shadowsocksr/servers/%s")
|
||||
function s.create(...)
|
||||
local sid = TypedSection.create(...)
|
||||
if sid then
|
||||
luci.http.redirect(s.extedit % sid)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
o = s:option(DummyValue, "type", translate("Type"))
|
||||
function o.cfgvalue(...)
|
||||
return Value.cfgvalue(...) or translate("")
|
||||
end
|
||||
|
||||
o = s:option(DummyValue, "alias", translate("Alias"))
|
||||
function o.cfgvalue(...)
|
||||
return Value.cfgvalue(...) or translate("None")
|
||||
end
|
||||
|
||||
o = s:option(DummyValue, "server", translate("Server Address"))
|
||||
function o.cfgvalue(...)
|
||||
return Value.cfgvalue(...) or "?"
|
||||
end
|
||||
|
||||
o = s:option(DummyValue, "server_port", translate("Server Port"))
|
||||
function o.cfgvalue(...)
|
||||
return Value.cfgvalue(...) or "?"
|
||||
end
|
||||
|
||||
o = s:option(DummyValue, "encrypt_method", translate("Encrypt Method"))
|
||||
o.width="10%"
|
||||
|
||||
o = s:option(DummyValue, "protocol", translate("Protocol"))
|
||||
o.width="10%"
|
||||
|
||||
o = s:option(DummyValue, "obfs", translate("Obfs"))
|
||||
o.width="10%"
|
||||
o = s:option(Flag, "switch_enable", translate("Enable Auto Switch"))
|
||||
function o.cfgvalue(...)
|
||||
return Value.cfgvalue(...) or "?"
|
||||
end
|
||||
if nixio.fs.access("/usr/bin/kcptun-client") then
|
||||
|
||||
o = s:option(Flag, "kcp_enable", translate("KcpTun"))
|
||||
function o.cfgvalue(...)
|
||||
return Value.cfgvalue(...) or "?"
|
||||
end
|
||||
end
|
||||
o = s:option(DummyValue,"server",translate("Ping Latency"))
|
||||
o.template="shadowsocksr/ping"
|
||||
o.width="10%"
|
||||
|
||||
m:append(Template("shadowsocksr/server_list"))
|
||||
|
||||
return m
|
||||
@ -1,62 +0,0 @@
|
||||
-- Licensed to the public under the GNU General Public License v3.
|
||||
|
||||
local m, s, o
|
||||
local shadowsocksr = "shadowsocksr"
|
||||
|
||||
|
||||
local uci = luci.model.uci.cursor()
|
||||
local server_count = 0
|
||||
local server_table = {}
|
||||
uci:foreach("shadowsocksr", "servers", function(s)
|
||||
server_count = server_count + 1
|
||||
s["name"] = s[".name"]
|
||||
table.insert(server_table, s)
|
||||
end)
|
||||
|
||||
local name = ""
|
||||
uci:foreach("shadowsocksr", "global", function(s) name = s[".name"] end)
|
||||
|
||||
m = Map(shadowsocksr)
|
||||
|
||||
m:section(SimpleSection).template = "shadowsocksr/status"
|
||||
|
||||
-- [[ Servers List ]]--
|
||||
s = m:section(TypedSection, "servers")
|
||||
s.anonymous = true
|
||||
s.addremove = true
|
||||
s.sortable = false
|
||||
|
||||
s.des = server_count
|
||||
s.current = uci:get("shadowsocksr", name, "global_server")
|
||||
s.template = "cbi/add"
|
||||
s.extedit = luci.dispatcher.build_url("admin/vpn/shadowsocksr/servers/%s")
|
||||
function s.create(...)
|
||||
local sid = TypedSection.create(...)
|
||||
if sid then
|
||||
luci.http.redirect(s.extedit % sid)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
o = s:option(DummyValue, "type", translate("Type"))
|
||||
function o.cfgvalue(...) return Value.cfgvalue(...) or translate("") end
|
||||
|
||||
o = s:option(DummyValue, "alias", translate("Alias"))
|
||||
function o.cfgvalue(...) return Value.cfgvalue(...) or translate("None") end
|
||||
|
||||
o = s:option(DummyValue, "server", translate("Server Address"))
|
||||
function o.cfgvalue(...) return Value.cfgvalue(...) or "?" end
|
||||
|
||||
o = s:option(DummyValue, "server_port", translate("Server Port"))
|
||||
function o.cfgvalue(...) return Value.cfgvalue(...) or "?" end
|
||||
|
||||
if nixio.fs.access("/usr/bin/kcptun-client") then
|
||||
|
||||
o = s:option(DummyValue, "kcp_enable", translate("KcpTun"))
|
||||
function o.cfgvalue(...) return Value.cfgvalue(...) or "?" end
|
||||
|
||||
end
|
||||
|
||||
|
||||
return m
|
||||
|
||||
@ -1,452 +0,0 @@
|
||||
-- Copyright (C) 2017 yushi studio <ywb94@qq.com>
|
||||
-- Licensed to the public under the GNU General Public License v3.
|
||||
|
||||
local IPK_Version="20200304.151"
|
||||
local m, s, o
|
||||
local redir_run=0
|
||||
local reudp_run=0
|
||||
local sock5_run=0
|
||||
local ssock5_run=0
|
||||
local v2sock5_run=0
|
||||
local server_run=0
|
||||
local sserver_run=0
|
||||
local v2server_run=0
|
||||
local kcptun_run=0
|
||||
local tunnel_run=0
|
||||
local udp2raw_run=0
|
||||
local udpspeeder_run=0
|
||||
local gfw_count=0
|
||||
local ad_count=0
|
||||
local ip_count=0
|
||||
local gfwmode=0
|
||||
local pdnsd_run=0
|
||||
local dnsforwarder_run=0
|
||||
local dnscrypt_proxy_run=0
|
||||
local chinadns_run=0
|
||||
local haproxy_run=0
|
||||
local privoxy_run=0
|
||||
|
||||
if nixio.fs.access("/etc/dnsmasq.ssr/gfw_list.conf") then
|
||||
gfwmode=1
|
||||
end
|
||||
|
||||
local shadowsocksr = "shadowsocksr"
|
||||
|
||||
|
||||
-- html constants
|
||||
font_blue = [[<font color="green">]]
|
||||
font_off = [[</font>]]
|
||||
bold_on = [[<strong>]]
|
||||
bold_off = [[</strong>]]
|
||||
|
||||
local fs = require "nixio.fs"
|
||||
local sys = require "luci.sys"
|
||||
local kcptun_version=translate("Unknown")
|
||||
local kcp_file="/usr/bin/kcptun-client"
|
||||
if not fs.access(kcp_file) then
|
||||
kcptun_version=translate("Not exist")
|
||||
else
|
||||
if not fs.access(kcp_file, "rwx", "rx", "rx") then
|
||||
fs.chmod(kcp_file, 755)
|
||||
end
|
||||
kcptun_version=sys.exec(kcp_file .. " -v | awk '{printf $3}'")
|
||||
if not kcptun_version or kcptun_version == "" then
|
||||
kcptun_version = translate("Unknown")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
local udp2raw_version=translate("Unknown")
|
||||
local udp2raw_file="/usr/bin/udp2raw"
|
||||
if not fs.access(udp2raw_file) then
|
||||
udp2raw_version=translate("Not exist")
|
||||
else
|
||||
if not fs.access(udp2raw_file, "rwx", "rx", "rx") then
|
||||
fs.chmod(udp2raw_file, 755)
|
||||
end
|
||||
udp2raw_version=sys.exec(udp2raw_file .. " -h |grep 'git version' |awk -F ':' '{print $2}'|awk '{print $1}'")
|
||||
if not udp2raw_version or udp2raw_version == "" then
|
||||
udp2raw_version = translate("Unknown")
|
||||
end
|
||||
end
|
||||
|
||||
local udpspeeder_version=translate("Unknown")
|
||||
local udpspeeder_file="/usr/bin/udpspeeder"
|
||||
if not fs.access(udpspeeder_file) then
|
||||
udpspeeder_version=translate("Not exist")
|
||||
else
|
||||
if not fs.access(udpspeeder_file, "rwx", "rx", "rx") then
|
||||
fs.chmod(udpspeeder_file, 755)
|
||||
end
|
||||
udpspeeder_version=sys.exec(udpspeeder_file .. " -h |grep 'git version' |awk -F ':' '{print $2}'|awk '{print $1}'")
|
||||
if not udpspeeder_version or udpspeeder_version == "" then
|
||||
udpspeeder_version = translate("Unknown")
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
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")
|
||||
if tonumber(icount)>0 then
|
||||
reudp_run=1
|
||||
else
|
||||
icount=sys.exec("ps -w | grep ssr-retcp |grep \"\\-u\"|grep -v grep| wc -l")
|
||||
if tonumber(icount)>0 then
|
||||
reudp_run=1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if luci.sys.call("ps -w | grep ssr-retcp | grep -v grep >/dev/null") == 0 then
|
||||
redir_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("pidof ssr-local >/dev/null") == 0 then
|
||||
sock5_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("pidof ss-local >/dev/null") == 0 then
|
||||
ssock5_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("ps -w | grep v2-ssr-local | grep -v grep >/dev/null") == 0 then
|
||||
v2sock5_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("pidof privoxy >/dev/null") == 0 then
|
||||
privoxy_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("pidof kcptun-client >/dev/null") == 0 then
|
||||
kcptun_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("pidof ssr-server >/dev/null") == 0 then
|
||||
server_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("busybox ps -w | grep ssr-tunnel |grep -v grep >/dev/null") == 0 then
|
||||
tunnel_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("pidof ss-server >/dev/null") == 0 then
|
||||
sserver_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("ps -w | grep v2ray-server | grep -v grep >/dev/null") == 0 then
|
||||
v2server_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("ps -w | grep ssr-tunnel |grep -v grep >/dev/null") == 0 then
|
||||
tunnel_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("pidof udp2raw >/dev/null") == 0 then
|
||||
udp2raw_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("pidof udpspeeder >/dev/null") == 0 then
|
||||
udpspeeder_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("pidof chinadns >/dev/null") == 0 then
|
||||
chinadns_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("pidof pdnsd >/dev/null") == 0 then
|
||||
pdnsd_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("pidof dnsparsing >/dev/null") == 0 then
|
||||
dnsforwarder_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("pidof dnscrypt-proxy >/dev/null") == 0 then
|
||||
dnscrypt_proxy_run=1
|
||||
end
|
||||
|
||||
|
||||
if luci.sys.call("pidof haproxy >/dev/null") == 0 then
|
||||
haproxy_run=1
|
||||
end
|
||||
|
||||
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
|
||||
if redir_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
|
||||
s=m:field(DummyValue,"reudp_run",translate("Game Mode UDP Relay"))
|
||||
s.rawhtml = true
|
||||
if reudp_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
|
||||
s=m:field(DummyValue,"haproxy_run",translate("Load Balancing"))
|
||||
s.rawhtml = true
|
||||
if haproxy_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
|
||||
if nixio.fs.access("/usr/bin/chinadns") then
|
||||
s=m:field(DummyValue,"chinadns_run",translate("ChinaDNS"))
|
||||
s.rawhtml = true
|
||||
if chinadns_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
end
|
||||
|
||||
s=m:field(DummyValue,"pdnsd_run",translate("PDNSD"))
|
||||
s.rawhtml = true
|
||||
if pdnsd_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
|
||||
s=m:field(DummyValue,"dnsforwarder_run",translate("dnsforwarder"))
|
||||
s.rawhtml = true
|
||||
if dnsforwarder_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
|
||||
s=m:field(DummyValue,"dnscrypt_proxy_run",translate("dnscrypt_proxy"))
|
||||
s.rawhtml = true
|
||||
if dnscrypt_proxy_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
|
||||
if nixio.fs.access("/usr/bin/ss-local") then
|
||||
s=m:field(DummyValue,"ssock5_run",translate("SSOCKS5 Proxy"))
|
||||
s.rawhtml = true
|
||||
if ssock5_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
end
|
||||
|
||||
if nixio.fs.access("/usr/bin/ssr-local") then
|
||||
s=m:field(DummyValue,"sock5_run",translate("SSR SOCKS5 Proxy"))
|
||||
s.rawhtml = true
|
||||
if sock5_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
end
|
||||
|
||||
if nixio.fs.access("/usr/bin/v2ray/v2ray") then
|
||||
s=m:field(DummyValue,"ssock5_run",translate("V2SOCKS5 Proxy"))
|
||||
s.rawhtml = true
|
||||
if v2sock5_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
end
|
||||
|
||||
if nixio.fs.access("/usr/sbin/privoxy") then
|
||||
s=m:field(DummyValue,"privoxy_run",translate("HTTP Proxy"))
|
||||
s.rawhtml = true
|
||||
if privoxy_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
end
|
||||
|
||||
if nixio.fs.access("/usr/bin/ssr-server") then
|
||||
s=m:field(DummyValue,"server_run",translate("Global SSR Server"))
|
||||
s.rawhtml = true
|
||||
if server_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
end
|
||||
|
||||
if nixio.fs.access("/usr/bin/ss-server") then
|
||||
s=m:field(DummyValue,"sserver_run",translate("Global SS Server"))
|
||||
s.rawhtml = true
|
||||
if sserver_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
end
|
||||
|
||||
if nixio.fs.access("/usr/bin/v2ray") then
|
||||
s=m:field(DummyValue,"v2server_run",translate("Global V2RAY Server"))
|
||||
s.rawhtml = true
|
||||
if v2server_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
end
|
||||
|
||||
if nixio.fs.access("/usr/bin/kcptun-client") then
|
||||
s=m:field(DummyValue,"kcp_version",translate("KcpTun Version"))
|
||||
s.rawhtml = true
|
||||
s.value =kcptun_version
|
||||
|
||||
s=m:field(DummyValue,"kcptun_run",translate("KcpTun"))
|
||||
s.rawhtml = true
|
||||
if kcptun_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
end
|
||||
|
||||
s=m:field(DummyValue,"version",translate("IPK Version"))
|
||||
s.rawhtml = true
|
||||
s.value =IPK_Version
|
||||
|
||||
s=m:field(DummyValue,"udp2raw_version",translate("udp2raw Version"))
|
||||
s.rawhtml = true
|
||||
s.value =udp2raw_version
|
||||
s=m:field(DummyValue,"udp2raw_run",translate("udp2raw"))
|
||||
s.rawhtml = true
|
||||
if udp2raw_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
|
||||
|
||||
s=m:field(DummyValue,"udpspeeder_version",translate("UDPspeeder Version"))
|
||||
s.rawhtml = true
|
||||
s.value =udpspeeder_version
|
||||
s=m:field(DummyValue,"udpspeeder_run",translate("UDPspeeder"))
|
||||
s.rawhtml = true
|
||||
if udpspeeder_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
s=m:field(DummyValue,"feedback",translate("Feedback"))
|
||||
s.template = "shadowsocksr/feedback"
|
||||
s.value =translate("No feedback")
|
||||
|
||||
|
||||
return m
|
||||
@ -1,83 +0,0 @@
|
||||
-- Licensed to the public under the GNU General Public License v3.
|
||||
|
||||
local m, s, o
|
||||
local shadowsocksr= "shadowsocksr"
|
||||
local uci = luci.model.uci.cursor()
|
||||
local server_table = {}
|
||||
local gfwmode=0
|
||||
local gfw_count=0
|
||||
local ip_count=0
|
||||
|
||||
if nixio.fs.access("/etc/dnsmasq.ssr/gfw_list.conf") then
|
||||
gfwmode=1
|
||||
end
|
||||
|
||||
local uci = luci.model.uci.cursor()
|
||||
local server_count = 0
|
||||
uci:foreach("shadowsocksr", "servers", function(s)
|
||||
server_count = server_count + 1
|
||||
end)
|
||||
|
||||
local fs = require "nixio.fs"
|
||||
local sys = require "luci.sys"
|
||||
|
||||
if gfwmode==1 then
|
||||
gfw_count = tonumber(sys.exec("cat /etc/dnsmasq.ssr/gfw_list.conf | wc -l"))/2
|
||||
|
||||
end
|
||||
|
||||
|
||||
m = Map(shadowsocksr)
|
||||
m:section(SimpleSection).template = "shadowsocksr/status3"
|
||||
-- [[ 节点订阅 ]]--
|
||||
|
||||
s = m:section(TypedSection, "server_subscribe", translate("Subscription"))
|
||||
s.anonymous = true
|
||||
|
||||
o = s:option(Flag, "auto_update", translate("Auto Update"))
|
||||
o.rmempty = false
|
||||
o.description = translate("Auto Update Server subscription, GFW list and CHN route")
|
||||
|
||||
|
||||
o = s:option(ListValue, "auto_update_time", translate("Update time (every day)"))
|
||||
for t = 0,23 do
|
||||
o:value(t, t..":00")
|
||||
end
|
||||
o.default=2
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(DynamicList, "subscribe_url", translate("Subscribe URL"))
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Flag, "proxy", translate("Through proxy update"))
|
||||
o.rmempty = false
|
||||
o.description = translate("Through proxy update list, Not Recommended ")
|
||||
|
||||
|
||||
o = s:option(DummyValue, "", "")
|
||||
o.rawhtml = true
|
||||
o.template = "shadowsocksr/update_subscribe"
|
||||
|
||||
|
||||
|
||||
o = s:option(Button,"delete",translate("Delete All Subscribe Severs"))
|
||||
o.inputstyle = "reset"
|
||||
o.description = string.format(translate("Server Count") .. ": %d", server_count)
|
||||
o.write = function()
|
||||
uci:delete_all("shadowsocksr", "servers", function(s)
|
||||
if s["hashkey"] then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end)
|
||||
uci:save("shadowsocksr")
|
||||
luci.sys.call("uci commit shadowsocksr && /etc/init.d/shadowsocksr stop")
|
||||
|
||||
luci.http.redirect(luci.dispatcher.build_url("admin", "vpn", "shadowsocksr", "servers"))
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
|
||||
return m
|
||||
@ -1,197 +0,0 @@
|
||||
-- Copyright (C) 2017 yushi studio <ywb94@qq.com> github.com/ywb94
|
||||
-- Copyright (C) 2018 lean <coolsnowwolf@gmail.com> github.com/coolsnowwolf
|
||||
-- Licensed to the public under the GNU General Public License v3.
|
||||
|
||||
local m, s, sec, o, kcp_enable
|
||||
local shadowsocksr = "shadowsocksr"
|
||||
|
||||
|
||||
m = Map(shadowsocksr)
|
||||
|
||||
local server_table = {}
|
||||
local encrypt_methods = {
|
||||
"none",
|
||||
"table",
|
||||
"rc4",
|
||||
"rc4-md5-6",
|
||||
"rc4-md5",
|
||||
"aes-128-cfb",
|
||||
"aes-192-cfb",
|
||||
"aes-256-cfb",
|
||||
"aes-128-ctr",
|
||||
"aes-192-ctr",
|
||||
"aes-256-ctr",
|
||||
"bf-cfb",
|
||||
"camellia-128-cfb",
|
||||
"camellia-192-cfb",
|
||||
"camellia-256-cfb",
|
||||
"cast5-cfb",
|
||||
"des-cfb",
|
||||
"idea-cfb",
|
||||
"rc2-cfb",
|
||||
"seed-cfb",
|
||||
"salsa20",
|
||||
"chacha20",
|
||||
"chacha20-ietf",
|
||||
}
|
||||
|
||||
local protocol = {
|
||||
"origin",
|
||||
"verify_deflate",
|
||||
"auth_sha1_v4",
|
||||
"auth_aes128_sha1",
|
||||
"auth_aes128_md5",
|
||||
"auth_chain_a",
|
||||
"auth_chain_b",
|
||||
"auth_chain_c",
|
||||
"auth_chain_d",
|
||||
"auth_chain_e",
|
||||
"auth_chain_f",
|
||||
}
|
||||
|
||||
obfs = {
|
||||
"plain",
|
||||
"http_simple",
|
||||
"http_post",
|
||||
"random_head",
|
||||
"tls1.2_ticket_auth",
|
||||
}
|
||||
|
||||
local raw_mode = {
|
||||
"faketcp",
|
||||
"udp",
|
||||
"icmp",
|
||||
}
|
||||
|
||||
local seq_mode = {
|
||||
"0",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
}
|
||||
|
||||
local cipher_mode = {
|
||||
"none",
|
||||
"xor",
|
||||
"aes128cbc",
|
||||
}
|
||||
|
||||
local auth_mode = {
|
||||
"none",
|
||||
"simple",
|
||||
"md5",
|
||||
"crc32",
|
||||
}
|
||||
|
||||
local speeder_mode = {
|
||||
"0",
|
||||
"1",
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
-- [[ udp2raw ]]--
|
||||
if nixio.fs.access("/usr/bin/udp2raw") then
|
||||
|
||||
s = m:section(TypedSection, "udp2raw", translate(" UDP2raw "))
|
||||
s.anonymous = true
|
||||
|
||||
o = s:option(Flag, "udp2raw_enable", translate("Enable udp2raw"))
|
||||
o.default = 0
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "server", translate("Server Address"))
|
||||
o.datatype = "host"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "server_port", translate("Server Port"))
|
||||
o.datatype = "port"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "local_port", translate("Local Port"))
|
||||
o.datatype = "port"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "key", translate("Password"))
|
||||
o.password = true
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(ListValue, "raw_mode", translate("Raw Mode"))
|
||||
for _, v in ipairs(raw_mode) do o:value(v) end
|
||||
o.default = "faketcp"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(ListValue, "seq_mode", translate("Seq Mode"))
|
||||
for _, v in ipairs(seq_mode) do o:value(v) end
|
||||
o.default = "3"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(ListValue, "cipher_mode", translate("Cipher Mode"))
|
||||
for _, v in ipairs(cipher_mode) do o:value(v) end
|
||||
o.default = "xor"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(ListValue, "auth_mode", translate("Auth Mode"))
|
||||
for _, v in ipairs(auth_mode) do o:value(v) end
|
||||
o.default = "simple"
|
||||
o.rmempty = false
|
||||
|
||||
end
|
||||
|
||||
-- [[ udpspeeder ]]--
|
||||
if nixio.fs.access("/usr/bin/udpspeeder") then
|
||||
|
||||
s = m:section(TypedSection, "udpspeeder", translate("UDPspeeder"))
|
||||
s.anonymous = true
|
||||
|
||||
o = s:option(Flag, "udpspeeder_enable", translate("Enable UDPspeeder"))
|
||||
o.default = 0
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "server", translate("Server Address"))
|
||||
o.datatype = "host"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "server_port", translate("Server Port"))
|
||||
o.datatype = "port"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "local_port", translate("Local Port"))
|
||||
o.datatype = "port"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "key", translate("Password"))
|
||||
o.password = true
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(ListValue, "speeder_mode", translate("Speeder Mode"))
|
||||
for _, v in ipairs(speeder_mode) do o:value(v) end
|
||||
o.default = "0"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "fec", translate("Fec"))
|
||||
o.default = "20:10"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "mtu", translate("Mtu"))
|
||||
o.datatype = "uinteger"
|
||||
o.default = 1250
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "queue_len", translate("Queue Len"))
|
||||
o.datatype = "uinteger"
|
||||
o.default = 200
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "timeout", translate("Fec Timeout"))
|
||||
o.datatype = "uinteger"
|
||||
o.default = 8
|
||||
o.rmempty = false
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
return m
|
||||
@ -1,409 +0,0 @@
|
||||
<style>
|
||||
.cbi-section-table-row {
|
||||
position: relative;
|
||||
background: #172b4d;
|
||||
margin: 10px;
|
||||
padding: 8px 15px 10px 65px;
|
||||
box-shadow: 0 0 1rem 0 rgba(136,152,170,.75);
|
||||
border-radius: .5rem;
|
||||
border: 0;
|
||||
color: #ffffff;
|
||||
text-align: left;
|
||||
line-height: 1.7em;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
transition: all 0.3s;
|
||||
|
||||
}
|
||||
|
||||
.incon.fast ,.cbi-section-table-row.fast{
|
||||
background: #009966!important;
|
||||
}
|
||||
|
||||
.incon.nopass ,.cbi-section-table-row.nopass{
|
||||
background: #dc3545 !important;
|
||||
}
|
||||
.incon.middle ,.cbi-section-table-row.middle{
|
||||
background: #fbc658 !important;
|
||||
}
|
||||
.incon.slow ,.cbi-section-table-row.slow{
|
||||
background: #fb6340 !important;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.host_con.fast{
|
||||
color: #00ff18;
|
||||
}
|
||||
|
||||
.host_con.nopass{
|
||||
color: #f5365c;
|
||||
}
|
||||
.host_con.middle{
|
||||
color: #ffff00;
|
||||
}
|
||||
.host_con.slow{
|
||||
color: #ffa200;
|
||||
}
|
||||
|
||||
.loadings {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(255,255,255,0.7);
|
||||
border-radius: .5rem;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 30px;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.loadings.hide{
|
||||
opacity:0;
|
||||
visibility:hidden;
|
||||
pointer-events:none;
|
||||
}
|
||||
|
||||
.loadings span {
|
||||
animation: anim-rotate 2s infinite linear;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.incon {
|
||||
display: inline-block;
|
||||
margin: 0.2em 0;
|
||||
}
|
||||
.incon:nth-child(2) {
|
||||
position: absolute;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content: center;
|
||||
left: 0;
|
||||
top: -3px;
|
||||
width: 55px;
|
||||
height: 105%;
|
||||
border: 0;
|
||||
background: #00CED1;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.incon:nth-child(3) {
|
||||
padding-left: 0px;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.incon:nth-child(5) ,.incon:nth-child(6){
|
||||
display: none;
|
||||
}
|
||||
|
||||
.cbi-section-table-cell {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.ssr-button {
|
||||
background: none;
|
||||
color: #fff;
|
||||
padding: 0 0 0 0.8rem;
|
||||
}
|
||||
|
||||
.ssr-button:hover,
|
||||
.ssr-button:focus,
|
||||
.ssr-button:active {
|
||||
color: #fff;
|
||||
outline: 0;
|
||||
text-decoration: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
.cbi-section h3{
|
||||
margin-left:10px;
|
||||
margin-top:1rem;
|
||||
}
|
||||
.cbi-button-check {
|
||||
color: #fff !important;
|
||||
background-color: #008080 !important;
|
||||
border-color: #2e6da4 !important;
|
||||
font-size:14px;
|
||||
padding:0.5rem 0.8rem;
|
||||
float:right;
|
||||
margin-right:10px;
|
||||
margin-top:-0.5rem;
|
||||
}
|
||||
.cbi-section-table-cell{
|
||||
position:relative;
|
||||
}
|
||||
.host_con{
|
||||
position:absolute;
|
||||
left:0;
|
||||
width:50px;
|
||||
text-align: left;
|
||||
height:22px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.host_ok{
|
||||
color:#fff;
|
||||
background:#2dce89;
|
||||
padding: 0.1rem 0.5rem;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
.host_error{
|
||||
color:#fff;
|
||||
background:#f5365c;
|
||||
padding: 0.1rem 0.5rem;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
.cbi-button-add{
|
||||
position:fixed;
|
||||
padding: 0.3rem 0.5rem;
|
||||
z-index:1000;
|
||||
width:80px !important;
|
||||
height:80px;
|
||||
bottom:50px;
|
||||
right:60px;
|
||||
font-size:20px;
|
||||
border-radius:50%;
|
||||
display:block;
|
||||
background-color: #008080!important;
|
||||
border-color: #008080 !important;
|
||||
box-shadow: 0 0 1rem 0 rgba(136,152,170,.75);
|
||||
}
|
||||
.statused{
|
||||
position: absolute;
|
||||
z-index: 20;
|
||||
right: 0;
|
||||
top: 0;
|
||||
background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyMy4wLjEsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0i5Zu+5bGCXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgMjAwIDIwMCIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMjAwIDIwMDsiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCgkuc3Qwe2ZpbGw6IzZGOUEzNzt9DQoJLnN0MXtmaWxsOiNGRkZGRkY7fQ0KPC9zdHlsZT4NCjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0wLjIsMGwxOTkuNiwyMDBMMjAwLDAuMkwwLjIsMHoiLz4NCjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0xNjQuNSw1MS4zTDEyMyw5My44Yy0wLjksMS0yLjEsMS40LTMuNCwxLjRjLTEuMywwLTIuNS0wLjQtMy40LTEuNEw5OSw3NS42Yy0xLjgtMS45LTEuNi00LjksMC40LTYuOA0KCWMyLTEuOSw1LTEuOSw2LjgsMGwxMy41LDE0LjJsMzcuNy0zOC42YzEuOC0xLjksNC44LTEuOSw2LjgsMEMxNjYuMSw0Ni40LDE2Ni4zLDQ5LjQsMTY0LjUsNTEuM0wxNjQuNSw1MS4zeiIvPg0KPC9zdmc+DQo=');
|
||||
background-size: contain;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
transition: all 0.2s;
|
||||
pointer-events: none;
|
||||
}
|
||||
.statused.hide{
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
}
|
||||
@media screen and (max-width: 1900px) {
|
||||
.pure-u-1-5{
|
||||
width:25%;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 1600px) {
|
||||
.pure-u-1-5{
|
||||
width:33.33333333%;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 1200px) {
|
||||
.pure-u-1-5{
|
||||
width:50%;
|
||||
}
|
||||
|
||||
.status .pure-u-1-5{
|
||||
width:33.333%;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 700px) {
|
||||
|
||||
.pure-u-1-5{
|
||||
width:100%;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.status .pure-u-1-5{
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<fieldset class="cbi-section" id="cbi-apply-shadowsocksr1" style="display: none;">
|
||||
<span class="panel-title">正在应用更改</span>
|
||||
<img src="/luci-static/resources/icons/loading.gif" alt="载入中" style="vertical-align:middle">
|
||||
</fieldset>
|
||||
<!-- tblsection -->
|
||||
<fieldset class="cbi-section" id="cbi-<%=self.config%>-<%=self.sectiontype%>">
|
||||
<button class="cbi-button cbi-button-check "><%:Ping All Servers%></button><span class="panel-title"><%:Node list%> (<%:total%> <%- print(self.des)-%><%:Nodes%>)</span>
|
||||
<div class="cbi-section-node">
|
||||
<%- local count = 0 -%>
|
||||
<div class="cbi-section-table pure-g">
|
||||
|
||||
<%- local isempty = true
|
||||
for i, k in ipairs(self:cfgsections()) do
|
||||
section = k
|
||||
isempty = false
|
||||
scope = { valueheader = "cbi/cell_valueheader", valuefooter = "cbi/cell_valuefooter" }
|
||||
-%>
|
||||
|
||||
<div class="pure-u-1-5">
|
||||
<div class="cbi-section-table-row " id="cbi-<%=self.config%>-<%=section%>">
|
||||
|
||||
<div class="loadings hide"><span class="icon-loading"></span></div>
|
||||
|
||||
<div class="incon type" ></div>
|
||||
<div class="incon alias"></div>
|
||||
<div class="incon switch_enable"></div>
|
||||
<div class="statused hide"></div>
|
||||
<%- if self.extedit or self.addremove then -%>
|
||||
<div class="cbi-section-table-cell">
|
||||
<div class="host_con">
|
||||
|
||||
</div>
|
||||
|
||||
<a class="cbi-button ssr-button " type="button" value="" onclick="apply_node('<%=section%>')" alt="应用" title="<%:Apply%>"><span class="icon-edit"></span> <%:Apply%></a>
|
||||
<%- if self.extedit then -%>
|
||||
<a class="cbi-button ssr-button " type="button" value=""
|
||||
<%- if type(self.extedit) == "string" then
|
||||
%> onclick="location.href='<%=self.extedit:format(section)%>'"
|
||||
<%- elseif type(self.extedit) == "function" then
|
||||
%> onclick="location.href='<%=self:extedit(section)%>'"
|
||||
<%- end
|
||||
%> alt="<%:Edit%>" title="<%:Edit%>" ><span class="icon-edit"></span> <%:Edit%></a>
|
||||
<%- end; if self.addremove then %>
|
||||
<button class="cbi-button ssr-button" type="submit" value="" onclick="this.form.cbi_state = 'del-section'; return true" name="cbi.rts.<%=self.config%>.<%=k%>" alt="<%:Delete%>" title="<%:Delete%>" /><span class="icon-delete"></span> <%:Delete%></button>
|
||||
<%- end -%>
|
||||
</div>
|
||||
<%- end -%>
|
||||
</div>
|
||||
</div>
|
||||
<%- end -%>
|
||||
|
||||
<%- if isempty then -%>
|
||||
<div class="cbi-section-table-row">
|
||||
<div colspan="<%=count%>"><em><br /><%:This section contains no values yet%></em></div>
|
||||
</div>
|
||||
<%- end -%>
|
||||
</div>
|
||||
|
||||
<% if self.error then %>
|
||||
<div class="cbi-section-error">
|
||||
<ul><% for _, c in pairs(self.error) do for _, e in ipairs(c) do -%>
|
||||
<li><%=pcdata(e):gsub("\n","<br />")%></li>
|
||||
<%- end end %></ul>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%- if self.addremove then -%>
|
||||
<% if self.template_addremove then include(self.template_addremove) else -%>
|
||||
<div class="cbi-section-create cbi-tblsection-create">
|
||||
<% if self.anonymous then %>
|
||||
<input class="cbi-button cbi-button-add" type="submit" value="<%:Add%>" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" title="<%:Add%>" />
|
||||
<% else %>
|
||||
<% if self.invalid_cts then -%><div class="cbi-section-error"><% end %>
|
||||
<input type="text" class="cbi-section-create-name" id="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" data-type="uciname" data-optional="true" />
|
||||
<input class="cbi-button cbi-button-add" type="submit" onclick="this.form.cbi_state = 'add-section'; return true" value="<%:Add%>" title="<%:Add%>" />
|
||||
<% if self.invalid_cts then -%>
|
||||
<br /><%:Invalid%></div>
|
||||
<%- end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<%- end %>
|
||||
<%- end -%>
|
||||
</div>
|
||||
</fieldset>
|
||||
<!-- /tblsection -->
|
||||
<script type="text/javascript">
|
||||
function apply_node(node){
|
||||
$("#cbi-apply-shadowsocksr1").show();
|
||||
$.get('<%=luci.dispatcher.build_url("admin", "vpn", "shadowsocksr","change")%>',
|
||||
{
|
||||
set:node
|
||||
},
|
||||
function (data, status) {
|
||||
$("#cbi-apply-shadowsocksr1").hide();
|
||||
|
||||
if (data.status ) {
|
||||
var id = '#cbi-<%=self.config%>-'+node;
|
||||
$(".statused").addClass("hide");
|
||||
$(id).find(".statused").removeClass("hide");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
setTimeout(function() { check(); }, 500);
|
||||
function check() {
|
||||
$(".host_con").html("");
|
||||
|
||||
$(".pure-u-1-5").each(function () {
|
||||
host = $(this).find(".cbi-section-table-row ").attr("server");
|
||||
port = $(this).find(".cbi-section-table-row ").attr("server_port");
|
||||
$(".host_con").text("--ms");
|
||||
check_port(host, port, this);
|
||||
});
|
||||
}
|
||||
|
||||
$.get('<%=luci.dispatcher.build_url("admin", "vpn", "shadowsocksr","allserver")%>',
|
||||
function (data) {
|
||||
$.each(data, function (i, val) {
|
||||
var id = '#cbi-<%=self.config%>-'+val.name;
|
||||
if(val.name == "<%=self.current%>"){
|
||||
$(id).find(".statused").removeClass("hide");
|
||||
}
|
||||
$(id).find(".type").text(val.type);
|
||||
$(id).find(".alias").text(val.alias);
|
||||
var switch_text = (val.switch_enable == 1)?'<span class="icon-switch" title="自动切换"></span>':'';
|
||||
$(id).find(".switch_enable").html(switch_text);
|
||||
$(id).attr("server",val.server);
|
||||
$(id).attr("server_port",val.server_port) ;
|
||||
});
|
||||
}, "json");
|
||||
|
||||
|
||||
|
||||
|
||||
function check_port(hosts, ports, target) {
|
||||
$.get('<%=luci.dispatcher.build_url("admin", "vpn", "shadowsocksr","checkport")%>',
|
||||
{
|
||||
host: hosts,
|
||||
port: ports
|
||||
},
|
||||
function (data, status) {
|
||||
$(target).find(".loadings").addClass("hide");
|
||||
$(target).find(".incon").removeClass("fast");
|
||||
$(target).find(".incon").removeClass("middle");
|
||||
$(target).find(".incon").removeClass("slow");
|
||||
$(target).find(".incon").removeClass("nopass");
|
||||
$(target).find(".host_con").removeClass("fast");
|
||||
$(target).find(".host_con").removeClass("middle");
|
||||
$(target).find(".host_con").removeClass("slow");
|
||||
$(target).find(".host_con").removeClass("nopass");
|
||||
if (data.ret == 1) {
|
||||
if (data.used <= 80) {
|
||||
$(target).find(".incon").eq(0).addClass("fast");
|
||||
$(target).find(".host_con").addClass("fast");
|
||||
} else if (data.used > 80 && data.used <= 200) {
|
||||
$(target).find(".incon").eq(0).addClass("middle");
|
||||
$(target).find(".host_con").addClass("middle");
|
||||
} else if (data.used > 200) {
|
||||
$(target).find(".incon").eq(0).addClass("slow");
|
||||
$(target).find(".host_con").addClass("slow");
|
||||
}
|
||||
$(target).find(".host_con").text(data.used + "ms");
|
||||
} else {
|
||||
$(target).find(".incon").eq(0).addClass("nopass");
|
||||
$(target).find(".host_con").addClass("nopass");
|
||||
$(target).find(".host_con").text("Error");
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(".cbi-button-check").click(function () {
|
||||
check();
|
||||
return false;
|
||||
});
|
||||
//check();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
<%+cbi/valueheader%>
|
||||
|
||||
<label class="cbi-value-title" style="display:inline-block; width: 180px" for="ulfile"><%:Choose local file:%></label>
|
||||
<input class="cbi-input-file" style="width: 400px" type="file" id="ulfile" name="ulfile" />
|
||||
|
||||
<%+cbi/valuefooter%>
|
||||
@ -1,38 +0,0 @@
|
||||
<%+cbi/valueheader%>
|
||||
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
|
||||
function check_connect(btn,urlname)
|
||||
{
|
||||
btn.disabled = true;
|
||||
btn.value = '<%:Check...%>';
|
||||
murl=urlname;
|
||||
XHR.get('<%=luci.dispatcher.build_url("admin", "vpn", "shadowsocksr","check")%>',
|
||||
{ set:murl },
|
||||
function(x,rv)
|
||||
{
|
||||
var s = document.getElementById(urlname+'-status');
|
||||
if (s)
|
||||
{
|
||||
if (rv.ret=="0")
|
||||
s.innerHTML ="<font color='green'>"+"<%:Connect OK%>"+"</font>";
|
||||
else
|
||||
s.innerHTML ="<font color='red'>"+"<%:Connect Error%>"+"</font>";
|
||||
|
||||
|
||||
}
|
||||
|
||||
btn.disabled = false;
|
||||
btn.value = '<%:Check Connect%>';
|
||||
}
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
//]]></script>
|
||||
|
||||
|
||||
<input type="button" class="cbi-button cbi-button-apply" value="<%:Check Connect%>" onclick="return check_connect(this,'<%=self.option%>')" />
|
||||
<span id="<%=self.option%>-status"><em><%=self.value%></em></span>
|
||||
|
||||
<%+cbi/valuefooter%>
|
||||
@ -1,36 +0,0 @@
|
||||
<%+cbi/valueheader%>
|
||||
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
|
||||
function check_port(btn)
|
||||
{
|
||||
btn.disabled = true;
|
||||
btn.value = '<%:Check...%>';
|
||||
XHR.get('<%=luci.dispatcher.build_url("admin", "vpn", "shadowsocksr","checkports")%>',
|
||||
null,
|
||||
function(x,rv)
|
||||
{
|
||||
var s = document.getElementById('<%=self.option%>-status');
|
||||
if (s)
|
||||
{
|
||||
|
||||
s.innerHTML =rv.ret;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
btn.disabled = false;
|
||||
btn.value = '<%:Check Server%>';
|
||||
}
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
//]]></script>
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
<%+cbi/valuefooter%>
|
||||
@ -1,22 +0,0 @@
|
||||
|
||||
</style>
|
||||
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title">udp2raw 项目</label>
|
||||
<div class="cbi-value-field">
|
||||
<input type="button" class="cbi-button cbi-input-reload" value="点击前往" onclick="javascript:window.open('https://github.com/wangyu-/udp2raw-tunnel','target');" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title">UDPspeeder 项目</label>
|
||||
<div class="cbi-value-field">
|
||||
<input type="button" class="cbi-button cbi-input-reload" value="点击前往" onclick="javascript:window.open('https://github.com/wangyu-/UDPspeeder','target');" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</fieldset>
|
||||
</fieldset>
|
||||
@ -1,109 +0,0 @@
|
||||
<!-- ++ 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", "shadowsocksr", "fileread")%>', {lfile: document.getElementById("<%=cbid%>").value} ,
|
||||
function(x, ifc) {
|
||||
if (! ifc) {txt.value = "XHR.get(<%=luci.dispatcher.build_url("admin", "vpn", "shadowsocksr", "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,350 +0,0 @@
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="x-dns-prefetch-control" content="on">
|
||||
<link rel="dns-prefetch" href="//cdn.jsdelivr.net">
|
||||
<link rel="dns-prefetch" href="//whois.pconline.com.cn">
|
||||
<link rel="dns-prefetch" href="//ipv4.ip.sb">
|
||||
<link rel="dns-prefetch" href="//myip.ipip.net">
|
||||
<link rel="dns-prefetch" href="//api.ipify.org">
|
||||
<link rel="dns-prefetch" href="//api.ttt.sh">
|
||||
<link rel="dns-prefetch" href="//api.skk.moe">
|
||||
<link rel="dns-prefetch" href="//d.skk.moe">
|
||||
<link rel="preconnect" href="https://whois.pconline.com.cn">
|
||||
<link rel="preconnect" href="https://ip.sb">
|
||||
<link rel="preconnect" href="https://myip.ipip.net">
|
||||
<link rel="preconnect" href="https://api.ipify.org">
|
||||
<link rel="preconnect" href="https://api.ttt.sh">
|
||||
<link rel="preconnect" href="https://api.skk.moe">
|
||||
<link rel="preconnect" href="https://d.skk.moe">
|
||||
<link rel="shortcut icon" type="image/ico" href="https://cdn.jsdelivr.net/npm/skx@0.0.1">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no,minimal-ui">
|
||||
<style>
|
||||
.ip-title {
|
||||
font-weight: bold;
|
||||
color: #444;
|
||||
font-size:15px;
|
||||
display: inline-block;
|
||||
width: 25%;
|
||||
vertical-align:bottom;
|
||||
}
|
||||
|
||||
.ip-state_title {
|
||||
font-weight: bold;
|
||||
color: #444;
|
||||
font-size:15px;
|
||||
display: inline-block;
|
||||
width: 52%;
|
||||
vertical-align:bottom;
|
||||
transform:translateY(10%);
|
||||
}
|
||||
|
||||
.ip-result {
|
||||
color: #444;
|
||||
font-size:16px;
|
||||
white-space: nowrap; /*强制span不换行*/
|
||||
display: inline-block; /*将span当做块级元素对待*/
|
||||
width: 29%; /*限制宽度*/
|
||||
overflow: hidden; /*超出宽度部分隐藏*/
|
||||
text-overflow: ellipsis; /*超出部分以点号代替*/
|
||||
vertical-align:bottom;
|
||||
transform:translateY(8%);
|
||||
}
|
||||
|
||||
.ip-geo {
|
||||
color: #444;
|
||||
font-size:15px;
|
||||
white-space: nowrap; /*强制span不换行*/
|
||||
display: inline-block; /*将span当做块级元素对待*/
|
||||
width: 40%; /*限制宽度*/
|
||||
overflow: hidden; /*超出宽度部分隐藏*/
|
||||
text-overflow: ellipsis; /*超出部分以点号代替*/
|
||||
vertical-align:bottom;
|
||||
transform:translateY(2%);
|
||||
}
|
||||
|
||||
.ip-checking {
|
||||
color: #444;
|
||||
font-size:15px;
|
||||
display: inline-block;
|
||||
vertical-align:bottom;
|
||||
width: 29%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
transform:translateY(10%);
|
||||
}
|
||||
|
||||
.sk-text-success {
|
||||
color: #32b643;
|
||||
font-size:15px;
|
||||
display: inline-block;
|
||||
vertical-align:bottom;
|
||||
width: 48%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
text-align: left;
|
||||
transform:translateY(10%);
|
||||
}
|
||||
|
||||
.sk-text-error {
|
||||
color: #e85600;
|
||||
font-size:15px;
|
||||
display: inline-block;
|
||||
vertical-align:bottom;
|
||||
width: 48%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
text-align: left;
|
||||
transform:translateY(10%);
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 5px 0 6px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<fieldset class="cbi-section">
|
||||
<table>
|
||||
<tr><td width="100%">
|
||||
<body>
|
||||
<div style="display: flex;">
|
||||
<div style="width: 51%">
|
||||
<h3><font color="#2E8B57"><B>IP 地址查询</B></font></h3>
|
||||
<p>
|
||||
<span class="ip-title">IP 登录设备:</span><span class="ip-result" id="ip-webrtc"></span> <span class="ip-geo" id="ip-webrtc-cz88"></span>
|
||||
</p>
|
||||
<p>
|
||||
<span class="ip-title">IPIP 国内:</span><span class="ip-result" id="ip-ipipnet"></span> <span class="ip-geo" id="ip-ipipnet-geo"></span>
|
||||
</p>
|
||||
<p>
|
||||
<span class="ip-title">IP.PC 国内:</span><span class="ip-result" id="ip-pcol"></span> <span class="ip-geo" id="ip-pcol-ipip"></span>
|
||||
</p>
|
||||
<p>
|
||||
<span class="ip-title">IP.SB 海外:</span><span class="ip-result" id="ip-ipsb"></span> <span class="ip-geo" id="ip-ipsb-geo"></span>
|
||||
</p>
|
||||
<p>
|
||||
<span class="ip-title">IPIFY 海外:</span><span class="ip-result" id="ip-ipify"></span> <span class="ip-geo" id="ip-ipify-ipip"></span>
|
||||
</p>
|
||||
</div>
|
||||
<div style="width: 49%">
|
||||
<h3><font color="#2E8B57"><B>网站访问检查</B></font></h3>
|
||||
<p>
|
||||
<span class="ip-state_title">百度搜索:</span><span id="http-baidu"></span>
|
||||
</p>
|
||||
<p>
|
||||
<span class="ip-state_title">网易云音乐:</span><span id="http-163"></span>
|
||||
</p>
|
||||
<p>
|
||||
<span class="ip-state_title">GitHub:</span><span id="http-github"></span>
|
||||
</p>
|
||||
<p>
|
||||
<span class="ip-state_title">Facebook:</span><span id="http-facebook"></span>
|
||||
</p>
|
||||
<p>
|
||||
<span class="ip-state_title">YouTube:</span><span id="http-youtube"></span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p style="float: right; margin-top: 4px; font-size:15px; padding-right: 10px">由 <a onclick="return ip_skk()" href="javascript:void(0);">ip.skk.moe 提供支持</a></p>
|
||||
</div>
|
||||
</td></tr>
|
||||
</table>
|
||||
</fieldset>
|
||||
<script>
|
||||
function ip_skk()
|
||||
{
|
||||
url2='https://ip.skk.moe';
|
||||
window.open(url2);
|
||||
}
|
||||
const $$ = document;
|
||||
$$.getElementById('ip-webrtc').innerHTML = '查询中...';
|
||||
$$.getElementById('ip-pcol').innerHTML = '查询中...';
|
||||
$$.getElementById('ip-ipify').innerHTML = '查询中...';
|
||||
$$.getElementById('ip-ipipnet').innerHTML = '查询中...';
|
||||
$$.getElementById('ip-ipsb').innerHTML = '查询中...';
|
||||
let random = parseInt(Math.random() * 100000000);
|
||||
let IP = {
|
||||
get: (url, type) =>
|
||||
fetch(url, { method: 'GET' }).then((resp) => {
|
||||
if (type === 'text')
|
||||
return Promise.all([resp.ok, resp.status, resp.text(), resp.headers]);
|
||||
else {
|
||||
return Promise.all([resp.ok, resp.status, resp.json(), resp.headers]);
|
||||
}
|
||||
}).then(([ok, status, data, headers]) => {
|
||||
if (ok) {
|
||||
let json = {
|
||||
ok,
|
||||
status,
|
||||
data,
|
||||
headers
|
||||
}
|
||||
return json;
|
||||
} else {
|
||||
throw new Error(JSON.stringify(json.error));
|
||||
}
|
||||
}).catch(error => {
|
||||
throw error;
|
||||
}),
|
||||
parseIPIpip: (ip, elID) => {
|
||||
|
||||
IP.get(`https://api.skk.moe/network/parseIp/ipip/v3/${ip}`, 'json')
|
||||
.then(resp => {
|
||||
let x = '';
|
||||
for (let i of resp.data) {
|
||||
x += (i !== '') ? `${i} ` : '';
|
||||
}
|
||||
$$.getElementById(elID).innerHTML = x;
|
||||
//$$.getElementById(elID).innerHTML = `${resp.data.country} ${resp.data.regionName} ${resp.data.city} ${resp.data.isp}`;
|
||||
})
|
||||
},
|
||||
getWebrtcIP: () => {
|
||||
window.RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
|
||||
let pc = new RTCPeerConnection({ iceServers: [] }),
|
||||
noop = () => { };
|
||||
pc.createDataChannel('');
|
||||
pc.createOffer(pc.setLocalDescription.bind(pc), noop);
|
||||
pc.onicecandidate = (ice) => {
|
||||
if (!ice || !ice.candidate || !ice.candidate.candidate) {
|
||||
$$.getElementById('ip-webrtc').innerHTML = '没有查询到 IP';
|
||||
return;
|
||||
}
|
||||
let ip = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/.exec(ice.candidate.candidate)[1];
|
||||
$$.getElementById('ip-webrtc').innerHTML = ip;
|
||||
IP.parseIPIpip(ip, 'ip-webrtc-cz88');
|
||||
pc.onicecandidate = noop;
|
||||
};
|
||||
},
|
||||
getIpipnetIP: () => {
|
||||
IP.get(`https://myip.ipip.net/?z=${random}`, 'text')
|
||||
.then((resp) => {
|
||||
let data = resp.data.replace('当前 IP:', '').split(' 来自于:');
|
||||
$$.getElementById('ip-ipipnet').innerHTML = `${data[0]}`;
|
||||
$$.getElementById('ip-ipipnet-geo').innerHTML = `${data[1]}`;
|
||||
});
|
||||
},
|
||||
getIPApiIP: () => {
|
||||
IP.get(`https://ipapi.co/json?z=${random}`, 'json')
|
||||
.then(resp => {
|
||||
$$.getElementById('ip-ipapi').innerHTML = resp.data.ip;
|
||||
IP.parseIPIpip(resp.data.ip, 'ip-ipapi-geo');
|
||||
})
|
||||
},
|
||||
getIpifyIP: () => {
|
||||
IP.get(`https://api.ipify.org/?format=json&z=${random}`, 'json')
|
||||
.then(resp => {
|
||||
$$.getElementById('ip-ipify').innerHTML = resp.data.ip;
|
||||
return resp.data.ip;
|
||||
})
|
||||
.then(ip => {
|
||||
IP.parseIPIpip(ip, 'ip-ipify-ipip');
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
$$.getElementById('http-baidu').innerHTML = '<span class="ip-checking">检测中...</span>';
|
||||
$$.getElementById('http-163').innerHTML = '<span class="ip-checking">检测中...</span>';
|
||||
$$.getElementById('http-github').innerHTML = '<span class="ip-checking">检测中...</span>';
|
||||
$$.getElementById('http-facebook').innerHTML = '<span class="ip-checking">检测中...</span>';
|
||||
$$.getElementById('http-youtube').innerHTML = '<span class="ip-checking">检测中...</span>';
|
||||
let HTTP = {
|
||||
checker: (domain, cbElID) => {
|
||||
let img = new Image;
|
||||
let timeout = setTimeout(() => {
|
||||
img.onerror = img.onload = null;
|
||||
$$.getElementById(cbElID).innerHTML = '<span class="sk-text-error">连接超时</span>'
|
||||
}, 5000);
|
||||
|
||||
img.onerror = () => {
|
||||
clearTimeout(timeout);
|
||||
$$.getElementById(cbElID).innerHTML = '<span class="sk-text-error">无法访问</span>'
|
||||
}
|
||||
|
||||
img.onload = () => {
|
||||
clearTimeout(timeout);
|
||||
$$.getElementById(cbElID).innerHTML = '<span class="sk-text-success">连接正常</span>'
|
||||
}
|
||||
|
||||
img.src = `https://${domain}/favicon.ico?${+(new Date)}`
|
||||
},
|
||||
runcheck: () => {
|
||||
HTTP.checker('www.baidu.com', 'http-baidu');
|
||||
HTTP.checker('s1.music.126.net/style', 'http-163');
|
||||
HTTP.checker('github.com', 'http-github');
|
||||
HTTP.checker('www.facebook.com', 'http-facebook');
|
||||
HTTP.checker('www.youtube.com', 'http-youtube');
|
||||
}
|
||||
};
|
||||
|
||||
HTTP.runcheck();
|
||||
IP.getIpipnetIP();
|
||||
IP.getIpifyIP();
|
||||
IP.getWebrtcIP();
|
||||
|
||||
function getPcolIP(data){
|
||||
let pcisp = data.addr.split(' ');
|
||||
$$.getElementById('ip-pcol').innerHTML = data.ip;
|
||||
$$.getElementById('ip-pcol-ipip').innerHTML = `${data.pro} ${data.city} ${data.region} ${pcisp[1]}`;
|
||||
};
|
||||
function getIpsbIP(data){
|
||||
$$.getElementById('ip-ipsb').innerHTML = data.address;
|
||||
$$.getElementById('ip-ipsb-geo').innerHTML = `${data.country} ${data.province} ${data.city} ${data.isp.name}`
|
||||
};
|
||||
|
||||
window.onload=myip_Load();
|
||||
|
||||
function myip_Load()
|
||||
{
|
||||
var pcip = document.getElementsByTagName('HEAD').item(0);
|
||||
var pcipScript= document.createElement("script");
|
||||
pcipScript.defer = "defer";
|
||||
pcipScript.src='https://whois.pconline.com.cn/ipJson.jsp?callback=getPcolIP';
|
||||
pcip.appendChild(pcipScript);
|
||||
|
||||
var sbip = document.getElementsByTagName('HEAD').item(0);
|
||||
var sbipScript= document.createElement("script");
|
||||
sbipScript.defer = "defer";
|
||||
sbipScript.src='https://ip.sb/addrinfo?callback=getIpsbIP';
|
||||
sbip.appendChild(sbipScript);
|
||||
|
||||
const $$ = document;
|
||||
random = parseInt(Math.random() * 100000000);
|
||||
HTTP.runcheck();
|
||||
IP.getIpipnetIP();
|
||||
IP.getIpifyIP();
|
||||
IP.getWebrtcIP();
|
||||
|
||||
function getPcolIP(data){
|
||||
let pcisp = data.addr.split(' ');
|
||||
$$.getElementById('ip-pcol').innerHTML = data.ip;
|
||||
$$.getElementById('ip-pcol-ipip').innerHTML = `${data.pro} ${data.city} ${data.region} ${pcisp[1]}`;
|
||||
};
|
||||
function getIpsbIP(data){
|
||||
$$.getElementById('ip-ipsb').innerHTML = data.address;
|
||||
$$.getElementById('ip-ipsb-geo').innerHTML = `${data.country} ${data.province} ${data.city} ${data.isp.name}`
|
||||
};
|
||||
|
||||
setTimeout("myip_Load()",1000*10);
|
||||
}
|
||||
|
||||
</script>
|
||||
<script defer="defer" src="https://whois.pconline.com.cn/ipJson.jsp?callback=getPcolIP"></script>
|
||||
<script defer="defer" src="https://ip.sb/addrinfo?callback=getIpsbIP"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
@ -1,28 +0,0 @@
|
||||
<%+cbi/valueheader%>
|
||||
<span class="pingtime" hint="<%=self:cfgvalue(section)%>">-- ms</span>
|
||||
<%+cbi/valuefooter%>
|
||||
|
||||
</fieldset>
|
||||
<!-- /tblsection --><script type="text/javascript">
|
||||
//<![CDATA[
|
||||
var pings = document.getElementsByClassName('pingtime');
|
||||
for(var i = 0; i < pings.length; i++) {
|
||||
XHR.get('/cgi-bin/luci/admin/vpn/shadowsocksr/ping', {
|
||||
index: i,
|
||||
domain: pings[i].getAttribute("hint")
|
||||
},
|
||||
function(x, result) {
|
||||
pings[result.index].innerHTML = (result.ping ? "<b><font color=green>"+result.ping+"</font></b> ms" : "<b><font color=red> 检测失败 </font></b>");
|
||||
}
|
||||
);
|
||||
XHR.poll(10,'/cgi-bin/luci/admin/vpn/shadowsocksr/ping',{
|
||||
index: i,
|
||||
domain: pings[i].getAttribute("hint")
|
||||
},
|
||||
function(x, result) {
|
||||
pings[result.index].innerHTML = (result.ping ? "<b><font color=green>"+result.ping+"</font></b> ms" : "<b><font color=red> 检测失败 </font></b>");
|
||||
}
|
||||
);
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
@ -1,44 +0,0 @@
|
||||
<%+cbi/valueheader%>
|
||||
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
|
||||
function refresh_data(btn,dataname)
|
||||
{
|
||||
btn.disabled = true;
|
||||
btn.value = '<%:Refresh...%> ';
|
||||
murl=dataname;
|
||||
XHR.get('<%=luci.dispatcher.build_url("admin", "vpn", "shadowsocksr","refresh")%>',
|
||||
{ set:murl },
|
||||
function(x,rv)
|
||||
{
|
||||
var s = document.getElementById(dataname+'-status');
|
||||
if (s)
|
||||
{
|
||||
if (rv.ret=="0")
|
||||
s.innerHTML ="<font color='green'>"+"<%:No new data!%> "+"</font>";
|
||||
else if(rv.ret=="-1")
|
||||
{
|
||||
s.innerHTML ="<font color='red'>"+"<%:Refresh Error!%> "+"</font>";
|
||||
}
|
||||
else
|
||||
{
|
||||
s.innerHTML ="<font color='green'>"+"<%:Refresh OK!%> "+"<%:Total Records:%>"+rv.ret+"</font>";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
btn.disabled = false;
|
||||
btn.value = '<%:Refresh Data %>';
|
||||
}
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
//]]></script>
|
||||
|
||||
|
||||
<input type="button" class="cbi-button cbi-input-reload" value="<%:Refresh Data%> " onclick="return refresh_data(this,'<%=self.option%>')" />
|
||||
<span id="<%=self.option%>-status"><em><%=self.value%></em></span>
|
||||
|
||||
<%+cbi/valuefooter%>
|
||||
@ -1,24 +0,0 @@
|
||||
<%#
|
||||
Copyright 2018-2019 Lienol <lawlienol@gmail.com>
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
|
||||
<%
|
||||
local dsp = require "luci.dispatcher"
|
||||
-%>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
var pings = document.getElementsByClassName('pingtime');
|
||||
for(var i = 0; i < pings.length; i++) {
|
||||
XHR.get('<%=dsp.build_url("admin/vpn/shadowsocksr/ping")%>', {
|
||||
index: i,
|
||||
domain: pings[i].getAttribute("hint")
|
||||
},
|
||||
function(x, result) {
|
||||
pings[result.index].innerHTML = (result.ping ? result.ping : "--") + " ms";
|
||||
}
|
||||
);
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
@ -1,257 +0,0 @@
|
||||
<%+cbi/valueheader%>
|
||||
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
function padright(str, cnt, pad) {
|
||||
return str + Array(cnt + 1).join(pad);
|
||||
}
|
||||
function b64EncodeUnicode(str) {
|
||||
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
|
||||
return String.fromCharCode('0x' + p1);
|
||||
}));
|
||||
}
|
||||
function b64encutf8safe(str) {
|
||||
return b64EncodeUnicode(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, '');
|
||||
}
|
||||
function b64DecodeUnicode(str) {
|
||||
return decodeURIComponent(Array.prototype.map.call(atob(str), function (c) {
|
||||
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
|
||||
}).join(''));
|
||||
}
|
||||
function b64decutf8safe(str) {
|
||||
var l;
|
||||
str = str.replace(/-/g, "+").replace(/_/g, "/");
|
||||
l = str.length;
|
||||
l = (4 - l % 4) % 4;
|
||||
if (l)
|
||||
str = padright(str, l, "=");
|
||||
return b64DecodeUnicode(str);
|
||||
}
|
||||
function b64encsafe(str) {
|
||||
return btoa(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, '')
|
||||
}
|
||||
function b64decsafe(str) {
|
||||
var l;
|
||||
str = str.replace(/-/g, "+").replace(/_/g, "/");
|
||||
l = str.length;
|
||||
l = (4 - l % 4) % 4;
|
||||
if (l)
|
||||
str = padright(str, l, "=");
|
||||
return atob(str);
|
||||
}
|
||||
function dictvalue(d, key) {
|
||||
var v = d[key];
|
||||
if (typeof (v) == 'undefined' || v == '')
|
||||
return '';
|
||||
return b64decsafe(v);
|
||||
}
|
||||
function export_ssr_url(btn, urlname, sid) {
|
||||
var s = document.getElementById(urlname + '-status');
|
||||
if (!s)
|
||||
return false;
|
||||
var v_server = document.getElementById('cbid.shadowsocksr.' + sid + '.server');
|
||||
var v_port = document.getElementById('cbid.shadowsocksr.' + sid + '.server_port');
|
||||
var v_protocol = document.getElementById('cbid.shadowsocksr.' + sid + '.protocol');
|
||||
var v_method = document.getElementById('cbid.shadowsocksr.' + sid + '.encrypt_method');
|
||||
var v_obfs = document.getElementById('cbid.shadowsocksr.' + sid + '.obfs');
|
||||
var v_password = document.getElementById('cbid.shadowsocksr.' + sid + '.password');
|
||||
var v_obfs_param = document.getElementById('cbid.shadowsocksr.' + sid + '.obfs_param');
|
||||
var v_protocol_param = document.getElementById('cbid.shadowsocksr.' + sid + '.protocol_param');
|
||||
var v_alias = document.getElementById('cbid.shadowsocksr.' + sid + '.alias');
|
||||
|
||||
var ssr_str = v_server.value + ":" +
|
||||
v_port.value + ":" +
|
||||
v_protocol.value + ":" +
|
||||
v_method.value + ":" +
|
||||
v_obfs.value + ":" +
|
||||
b64encsafe(v_password.value) +
|
||||
"/?obfsparam=" + b64encsafe(v_obfs_param.value) +
|
||||
"&protoparam=" + b64encsafe(v_protocol_param.value) +
|
||||
"&remarks=" + b64encutf8safe(v_alias.value);
|
||||
var textarea = document.createElement("textarea");
|
||||
textarea.textContent = "ssr://" + b64encsafe(ssr_str);
|
||||
textarea.style.position = "fixed";
|
||||
document.body.appendChild(textarea);
|
||||
textarea.select();
|
||||
try {
|
||||
document.execCommand("copy"); // Security exception may be thrown by some browsers.
|
||||
s.innerHTML = "<font color='green'><%:Copy SSR to clipboard successfully.%></font>";
|
||||
} catch (ex) {
|
||||
s.innerHTML = "<font color='red'><%:Unable to copy SSR to clipboard.%></font>";
|
||||
} finally {
|
||||
document.body.removeChild(textarea);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
function import_ssr_url(btn, urlname, sid) {
|
||||
var s = document.getElementById(urlname + '-status');
|
||||
if (!s)
|
||||
return false;
|
||||
var ssrurl = prompt("在这里黏贴配置链接 ssr:// | ss:// | vmess:// | trojan://", "");
|
||||
if (ssrurl == null || ssrurl == "") {
|
||||
s.innerHTML = "<font color='red'>用户取消</font>";
|
||||
return false;
|
||||
}
|
||||
s.innerHTML = "";
|
||||
//var ssu = ssrurl.match(/ssr:\/\/([A-Za-z0-9_-]+)/i);
|
||||
var ssu = ssrurl.split('://');
|
||||
console.log(ssu.length);
|
||||
if ((ssu[0] != "ssr" && ssu[0] != "ss" && ssu[0] != "vmess") || ssu[1] == "") {
|
||||
s.innerHTML = "<font color='red'>无效的格式</font>";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
var event = document.createEvent("HTMLEvents");
|
||||
event.initEvent("change", true, true);
|
||||
if (ssu[0] == "ssr") {
|
||||
var sstr = b64decsafe(ssu[1]);
|
||||
var ploc = sstr.indexOf("/?");
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.type').value = "ssr";
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.type').dispatchEvent(event);
|
||||
var url0, param = "";
|
||||
if (ploc > 0) {
|
||||
url0 = sstr.substr(0, ploc);
|
||||
param = sstr.substr(ploc + 2);
|
||||
}
|
||||
var ssm = url0.match(/^(.+):([^:]+):([^:]*):([^:]+):([^:]*):([^:]+)/);
|
||||
if (!ssm || ssm.length < 7)
|
||||
return false;
|
||||
var pdict = {};
|
||||
if (param.length > 2)
|
||||
{
|
||||
var a = param.split('&');
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
var b = a[i].split('=');
|
||||
pdict[decodeURIComponent(b[0])] = decodeURIComponent(b[1] || '');
|
||||
}
|
||||
}
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.server').value = ssm[1];
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.server_port').value = ssm[2];
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.protocol').value = ssm[3];
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.encrypt_method').value = ssm[4];
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.obfs').value = ssm[5];
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.password').value = b64decsafe(ssm[6]);
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.obfs_param').value = dictvalue(pdict, 'obfsparam');
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.protocol_param').value = dictvalue(pdict, 'protoparam');
|
||||
|
||||
var rem = pdict['remarks'];
|
||||
if (typeof (rem) != 'undefined' && rem != '' && rem.length > 0)
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.alias').value = b64decutf8safe(rem);
|
||||
|
||||
s.innerHTML = "<font color='green'>导入ShadowsocksR配置信息成功</font>";
|
||||
return false;
|
||||
} else if (ssu[0] == "ss") {
|
||||
var ploc = ssu[1].indexOf("#");
|
||||
if (ploc > 0) {
|
||||
url0 = ssu[1].substr(0, ploc);
|
||||
param = ssu[1].substr(ploc + 1);
|
||||
} else {
|
||||
url0 = ssu[1]
|
||||
}
|
||||
var sstr = b64decsafe(url0);
|
||||
|
||||
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.type').value = "ss";
|
||||
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.type').dispatchEvent(event);
|
||||
var team = sstr.split('@');
|
||||
console.log(param);
|
||||
var part1 = team[0].split(':');
|
||||
var part2 = team[1].split(':');
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.server').value = part2[0];
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.server_port').value = part2[1];
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.password').value = part1[1];
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.encrypt_method_ss').value = part1[0];
|
||||
if (param != undefined) {
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.alias').value = decodeURI(param);
|
||||
}
|
||||
|
||||
s.innerHTML = "<font color='green'>导入Shadowsocks配置信息成功</font>";
|
||||
return false;
|
||||
} else if (ssu[0] == "trojan") {
|
||||
var ploc = ssu[1].indexOf("#");
|
||||
if (ploc > 0) {
|
||||
url0 = ssu[1].substr(0, ploc);
|
||||
param = ssu[1].substr(ploc + 1);
|
||||
} else {
|
||||
url0 = ssu[1]
|
||||
}
|
||||
var sstr = b64decsafe(url0);
|
||||
|
||||
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.type').value = "trojan";
|
||||
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.type').dispatchEvent(event);
|
||||
var team = sstr.split('@');
|
||||
console.log(param);
|
||||
var part1 = team[0].split(':');
|
||||
var part2 = team[1].split(':');
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.server').value = part2[0];
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.server_port').value = part2[1];
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.password').value = part1[1];
|
||||
if (param != undefined) {
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.alias').value = decodeURI(param);
|
||||
}
|
||||
|
||||
s.innerHTML = "<font color='green'>导入Trojan配置信息成功</font>";
|
||||
return false;
|
||||
} else if (ssu[0] == "vmess") {
|
||||
var sstr = b64DecodeUnicode(ssu[1]);
|
||||
var ploc = sstr.indexOf("/?");
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.type').value = "v2ray";
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.type').dispatchEvent(event);
|
||||
var url0, param = "";
|
||||
if (ploc > 0) {
|
||||
url0 = sstr.substr(0, ploc);
|
||||
param = sstr.substr(ploc + 2);
|
||||
}
|
||||
var ssm = JSON.parse(sstr);
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.alias').value = ssm.ps;
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.server').value = ssm.add;
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.server_port').value = ssm.port;
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.alter_id').value = ssm.aid;
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.vmess_id').value = ssm.id;
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.transport').value = ssm.net;
|
||||
if(ssm.tls == "tls"){
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.tls').checked = true;
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.insecure').checked = true;
|
||||
}
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.transport').dispatchEvent(event);
|
||||
|
||||
switch(ssm.net){
|
||||
case "tcp":
|
||||
break;
|
||||
|
||||
case "kcp":
|
||||
break;
|
||||
|
||||
case "ws":
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.ws_host').value = ssm.host;
|
||||
document.getElementById('cbid.shadowsocksr.' + sid + '.ws_path').value = ssm.path;
|
||||
break;
|
||||
|
||||
case "h2":
|
||||
break;
|
||||
|
||||
case "quic":
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
s.innerHTML = "<font color='green'>导入V2ray配置信息成功</font>";
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
//]]></script>
|
||||
|
||||
<input type="button" class="cbi-button cbi-button-apply" value="导入配置信息" onclick="return import_ssr_url(this, '<%=self.option%>', '<%=self.value%>')" />
|
||||
<input type="button" class="cbi-button cbi-button-apply" value="<%:Export SSR%>" onclick="return export_ssr_url(this,'<%=self.option%>','<%=self.value%>')" /><span id="<%=self.option%>-status"></span>
|
||||
<span id="<%=self.option%>-status"></span>
|
||||
|
||||
<%+cbi/valuefooter%>
|
||||
|
||||
@ -1,210 +0,0 @@
|
||||
<style>
|
||||
.pure-g{letter-spacing:-.31em;text-rendering:optimizespeed;font-family:FreeSans,Arimo,"Droid Sans",Helvetica,Arial,sans-serif;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap;-webkit-align-content:flex-start;-ms-flex-line-pack:start;align-content:flex-start}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){table .pure-g{display:block}}.opera-only :-o-prefocus,.pure-g{word-spacing:-.43em}.pure-u,.pure-u-1,.pure-u-1-1,.pure-u-1-12,.pure-u-1-2,.pure-u-1-24,.pure-u-1-3,.pure-u-1-4,.pure-u-1-5,.pure-u-1-6,.pure-u-1-8,.pure-u-10-24,.pure-u-11-12,.pure-u-11-24,.pure-u-12-24,.pure-u-13-24,.pure-u-14-24,.pure-u-15-24,.pure-u-16-24,.pure-u-17-24,.pure-u-18-24,.pure-u-19-24,.pure-u-2-24,.pure-u-2-3,.pure-u-2-5,.pure-u-20-24,.pure-u-21-24,.pure-u-22-24,.pure-u-23-24,.pure-u-24-24,.pure-u-3-24,.pure-u-3-4,.pure-u-3-5,.pure-u-3-8,.pure-u-4-24,.pure-u-4-5,.pure-u-5-12,.pure-u-5-24,.pure-u-5-5,.pure-u-5-6,.pure-u-5-8,.pure-u-6-24,.pure-u-7-12,.pure-u-7-24,.pure-u-7-8,.pure-u-8-24,.pure-u-9-24{display:inline-block;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-g [class*=pure-u]{font-family:sans-serif}.pure-u-1-24{width:4.1667%}.pure-u-1-12,.pure-u-2-24{width:8.3333%}.pure-u-1-8,.pure-u-3-24{width:12.5%}.pure-u-1-6,.pure-u-4-24{width:16.6667%}.pure-u-1-5{width:20%}.pure-u-5-24{width:20.8333%}.pure-u-1-4,.pure-u-6-24{width:25%}.pure-u-7-24{width:29.1667%}.pure-u-1-3,.pure-u-8-24{width:33.3333%}.pure-u-3-8,.pure-u-9-24{width:37.5%}.pure-u-2-5{width:40%}.pure-u-10-24,.pure-u-5-12{width:41.6667%}.pure-u-11-24{width:45.8333%}.pure-u-1-2,.pure-u-12-24{width:50%}.pure-u-13-24{width:54.1667%}.pure-u-14-24,.pure-u-7-12{width:58.3333%}.pure-u-3-5{width:60%}.pure-u-15-24,.pure-u-5-8{width:62.5%}.pure-u-16-24,.pure-u-2-3{width:66.6667%}.pure-u-17-24{width:70.8333%}.pure-u-18-24,.pure-u-3-4{width:75%}.pure-u-19-24{width:79.1667%}.pure-u-4-5{width:80%}.pure-u-20-24,.pure-u-5-6{width:83.3333%}.pure-u-21-24,.pure-u-7-8{width:87.5%}.pure-u-11-12,.pure-u-22-24{width:91.6667%}.pure-u-23-24{width:95.8333%}.pure-u-1,.pure-u-1-1,.pure-u-24-24,.pure-u-6-6{width:100%}
|
||||
.status{
|
||||
margin: 1.5rem -0.5rem 0 -0.5rem;
|
||||
}
|
||||
.block{
|
||||
margin: 0.5rem 0.5rem;
|
||||
padding: 0;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
line-height: 1;
|
||||
font-family: inherit;
|
||||
min-width: inherit;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
border: 1px solid rgba(0,0,0,.05);
|
||||
border-radius: .375rem;
|
||||
background-color: #fff ;
|
||||
box-shadow: 0 0 2rem 0 rgba(136,152,170,.15);
|
||||
}
|
||||
.img-con{
|
||||
margin: 1rem;
|
||||
|
||||
}
|
||||
.green{
|
||||
color: #2dce89;
|
||||
}
|
||||
.red{
|
||||
color: #f5365c;
|
||||
}
|
||||
.block img{
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
.pure-u-5-8{
|
||||
display:flex;
|
||||
align-items:center;
|
||||
|
||||
}
|
||||
|
||||
.block h4{
|
||||
font-size: 1.3rem;
|
||||
font-weight: bold;
|
||||
margin: 0.75rem 0;
|
||||
|
||||
line-height: 1.8em;
|
||||
}
|
||||
@media screen and (max-width: 1920px) {
|
||||
.block h4{
|
||||
font-size: 1.2rem;
|
||||
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 1690px) {
|
||||
.block h4{
|
||||
font-size: 1rem;
|
||||
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 1290px) {
|
||||
.block h4{
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
.pure-u-1-6{
|
||||
width:33.333%;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 700px) {
|
||||
|
||||
.pure-u-1-6{
|
||||
width:50%;
|
||||
}
|
||||
.img-con{
|
||||
margin: 0.5rem;
|
||||
|
||||
}
|
||||
.block h4{
|
||||
font-size: 0.81rem;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
|
||||
|
||||
<div class="pure-g status">
|
||||
<div class="pure-u-1-6">
|
||||
<div class="block pure-g" >
|
||||
<div class="pure-u-3-8">
|
||||
<div class="img-con">
|
||||
<img src="https://i.imgur.com/wzbtvXp.png" >
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-5-8">
|
||||
<h4 id="shadowsocksr_status"><%:Client%><br><span class="red"><%:Not Running%></span></h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-1-6">
|
||||
<div class="block pure-g" >
|
||||
<div class="pure-u-3-8">
|
||||
<div class="img-con">
|
||||
<img src="https://i.imgur.com/3mE04AZ.png">
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-5-8">
|
||||
<h4 id="google_status"><%:foreign websites%><br><span class="red"><%:Problem detected%></span></h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-1-6">
|
||||
<div class="block pure-g" >
|
||||
<div class="pure-u-3-8">
|
||||
<div class="img-con">
|
||||
<img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyMy4wLjEsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0i5Zu+5bGCXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMTAwIDEwMDsiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCgkuc3Qwe2ZpbGw6IzMzODhGRjt9DQoJLnN0MXtmaWxsLXJ1bGU6ZXZlbm9kZDtjbGlwLXJ1bGU6ZXZlbm9kZDtmaWxsOiNGRkZGRkY7fQ0KPC9zdHlsZT4NCjxjaXJjbGUgY2xhc3M9InN0MCIgY3g9IjUwIiBjeT0iNTAiIHI9IjUwIi8+DQo8ZyBpZD0i5pCc57SiX+eGiuaOjF82Nmljb24iPg0KCTxnIGlkPSJsb2dvIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMjEuMjEyMTIxLCA5MC45MDkwOTEpIj4NCgkJPHBhdGggaWQ9IkZpbGwtMSIgY2xhc3M9InN0MSIgZD0iTS03OS43LTU1LjRjNC41LDAsOC41LTUuNCw4LjUtMTEuOWMwLTYuNS0zLjctMTEuOS04LjUtMTEuOWMtNC41LDAtOC41LDUuNC04LjUsMTEuOQ0KCQkJQy04Ny45LTYwLjctODQuMi01NS40LTc5LjctNTUuNCIvPg0KCQk8cGF0aCBpZD0iRmlsbC0zIiBjbGFzcz0ic3QxIiBkPSJNLTU5LjktNTQuNWM2LjIsMC44LDEwLjItNS43LDExLTEwLjhjMC44LTQuOC0zLjEtMTAuOC03LjYtMTEuNmMtNC4yLTEuMS05LjksNS45LTEwLjIsMTAuNQ0KCQkJQy02Ny4yLTYxLTY2LjEtNTUuNC01OS45LTU0LjUiLz4NCgkJPHBhdGggaWQ9IkZpbGwtNSIgY2xhc3M9InN0MSIgZD0iTS05NS4zLTM4LjZjOC41LTEuNyw3LjEtMTEuNiw3LjEtMTMuOWMtMC4zLTMuNC00LjItOS4zLTkuOS04LjhjLTYuOCwwLjYtNy42LDEwLjItNy42LDEwLjINCgkJCUMtMTA2LjktNDYuNi0xMDMuOC0zNi45LTk1LjMtMzguNiIvPg0KCQk8cGF0aCBpZD0iRmlsbC03IiBjbGFzcz0ic3QxIiBkPSJNLTM1LjItNDYuM2MwLTIuNS0yLTkuNi05LjMtOS42Yy03LjQsMC04LjUsNi44LTguNSwxMS42YzAsNC41LDAuMywxMSw5LjYsMTAuOA0KCQkJQy0zNC40LTMzLjgtMzUuMi00NC0zNS4yLTQ2LjMiLz4NCgkJPHBhdGggaWQ9IkZpbGwtOSIgY2xhc3M9InN0MSIgZD0iTS04Ni41LTIxLjRjLTAuMywwLjYtMC44LDIuNS0wLjMsNGMwLjgsMy40LDQsMy43LDQsMy43aDQuMnYtMTAuOGgtNC44DQoJCQlDLTg1LjEtMjMuNi04Ni4yLTIxLjktODYuNS0yMS40Ii8+DQoJCTxwYXRoIGlkPSJGaWxsLTExIiBjbGFzcz0ic3QxIiBkPSJNLTUzLjEtOS41aC0xMi43Yy00LjgtMS4xLTUuMS00LjgtNS4xLTQuOHYtMTMuOWg1LjF2MTIuNWMwLjMsMS40LDIsMS43LDIsMS43aDUuNHYtMTMuOWg1LjQNCgkJCVYtOS41eiBNLTczLjItOS4ySC04NGMtNC44LTAuOC02LjgtNC4yLTYuOC00LjhjLTAuMy0wLjYtMS43LTMuMS0wLjgtNy42YzItNi41LDcuOS03LjEsNy45LTcuMWg1Ljd2LTcuMWg0LjgNCgkJCUMtNzMuMi0zNS44LTczLjItOS4yLTczLjItOS4yeiBNLTQ0LjYtMjUuM2MwLDAtOS42LTcuNC0xNS4zLTE1LjNjLTcuNi0xMS42LTE4LjQtNy4xLTIxLjgtMS4xYy0zLjQsNS45LTkuMSw5LjktOS45LDEwLjgNCgkJCWMtMC44LDAuOC0xMS42LDYuOC05LjEsMTcuM0MtOTguMS0zLjItODkuOS0zLjUtODkuOS0zLjVzNi4yLDAuNiwxMy4zLTEuMWM3LjEtMS43LDEzLjMsMC4zLDEzLjMsMC4zUy00Ni42LDEuMy00Mi05LjcNCgkJCUMtMzcuNS0xOS43LTQ0LjYtMjUuMy00NC42LTI1LjNMLTQ0LjYtMjUuM3oiLz4NCgk8L2c+DQo8L2c+DQo8L3N2Zz4NCg==" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-5-8">
|
||||
<h4 id="baidu_status"><%:domestic website%><br><span class="red"><%:Problem detected%></span></h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-1-6">
|
||||
<div class="block pure-g" >
|
||||
<div class="pure-u-3-8">
|
||||
<div class="img-con">
|
||||
<img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyMy4wLjEsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0i5Zu+5bGCXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMTAwIDEwMDsiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCgkuc3Qwe2ZpbGw6I0ZCQjE0MDt9DQoJLnN0MXtmaWxsOiNGRkZGRkY7fQ0KPC9zdHlsZT4NCjxjaXJjbGUgY2xhc3M9InN0MCIgY3g9IjUwIiBjeT0iNTAiIHI9IjUwIi8+DQo8cGF0aCBjbGFzcz0ic3QxIiBkPSJNODYuOCw0Ny42QzgzLjYsMzMsNzQuOCwyMi41LDY2LjUsMjNoLTAuM2MtMy4zLDAtNi41LDEuMi04LjksMy4zYy0xLjgsMi00LjQsMy4yLTcuMSwzLjINCgljLTIuNiwwLTUuMS0xLjEtNi45LTNjLTIuNS0yLjMtNS44LTMuNS05LjEtMy41aC0wLjRjLTguMi0wLjUtMTcuMSwxMC0yMC4zLDI0LjZjLTMuNSwxNS41LDAuOCwyOS44LDkuNSwzMS45DQoJYzYuMywxLjYsMTMuMy0zLjksMTcuOS0xM2gxOC43YzQuNyw5LjEsMTEuNiwxNC42LDE3LjksMTNDODYsNzcuNCw5MC4yLDYzLjEsODYuOCw0Ny42TDg2LjgsNDcuNnogTTQyLjksNDguNUgzNnY3LjJoLTUuNnYtNy4yDQoJaC02Ljl2LTUuOGg2Ljl2LTcuMkgzNnY3LjJoNi45TDQyLjksNDguNXogTTYyLjcsNDkuMmMtMiwwLjEtMy43LTEuNC0zLjgtMy40Yy0wLjEtMiwxLjQtMy43LDMuNC0zLjhjMi0wLjEsMy43LDEuNCwzLjgsMy40DQoJYzAsMC4xLDAsMC4xLDAsMC4yQzY2LjIsNDcuNSw2NC43LDQ5LjEsNjIuNyw0OS4yQzYyLjcsNDkuMiw2Mi43LDQ5LjIsNjIuNyw0OS4yeiBNNzMuNyw0OS4yYy0yLDAuMS0zLjctMS40LTMuOC0zLjQNCgljLTAuMS0yLDEuNC0zLjcsMy40LTMuOGMyLTAuMSwzLjcsMS40LDMuOCwzLjRjMCwwLjEsMCwwLjEsMCwwLjJjMC4xLDEuOS0xLjQsMy41LTMuMywzLjZINzMuN3oiLz4NCjwvc3ZnPg0K" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-5-8">
|
||||
<h4 id="game_status"><%:Game Mode%><br><span class="red"><%:Not Running%></span></h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-1-6">
|
||||
<div class="block pure-g" >
|
||||
<div class="pure-u-3-8">
|
||||
<div class="img-con">
|
||||
<img src="https://i.imgur.com/3hkGjsK.png" >
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-5-8">
|
||||
<h4 id="chinadns_status">𝐂𝐡𝐢𝐧𝐚𝐃𝐍𝐒<br><span class="red"><%:Not Running%></span></h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-1-6">
|
||||
<div class="block pure-g" >
|
||||
<div class="pure-u-3-8">
|
||||
<div class="img-con">
|
||||
<img src="https://i.imgur.com/bYz9YoR.png" >
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-5-8">
|
||||
<h4 id="SOCKS5_status">𝙎𝙊𝘾𝙆𝙎⑤<br><span class="red"><%:Not Running%></span></h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
XHR.poll(5, '<%=url([[admin]], [[vpn]], [[shadowsocksr]], [[run]])%>', null,
|
||||
function (x, data) {
|
||||
var tb = document.getElementById('shadowsocksr_status');
|
||||
var tb1 = document.getElementById('google_status');
|
||||
var tb2 = document.getElementById('baidu_status');
|
||||
var tb3 = document.getElementById('game_status');
|
||||
var tb4 = document.getElementById('chinadns_status');
|
||||
var tb5 = document.getElementById('SOCKS5_status');
|
||||
if (data && tb) {
|
||||
if (data.global) {
|
||||
tb.innerHTML = '<%:Client%><br><span class="green"><%:Running%></span>';
|
||||
} else {
|
||||
tb.innerHTML = '<%:Client%><br><span class="red"><%:Not Running%></span>';
|
||||
}
|
||||
if (data.google) {
|
||||
tb1.innerHTML = '<%:foreign websites%><br><span class="green"><%:Connect OK%></span>';
|
||||
} else {
|
||||
tb1.innerHTML = '<%:foreign websites%><br><span class="red"><%:Problem detected%></span>';
|
||||
}
|
||||
if (data.baidu) {
|
||||
tb2.innerHTML = '<%:domestic website%><br><span class="green"><%:Connect OK%></span>';
|
||||
} else {
|
||||
tb2.innerHTML = '<%:domestic website%><br><span class="red"><%:Problem detected%></span>';
|
||||
}
|
||||
if (data.game) {
|
||||
tb3.innerHTML = '<%:Game Mode%><br><span class="green"><%:Running%></span>';
|
||||
} else {
|
||||
tb3.innerHTML = '<%:Game Mode%><br><span class="red"><%:Not Running%></span>';
|
||||
}
|
||||
if (data.chinadns) {
|
||||
tb4.innerHTML = '𝐂𝐡𝐢𝐧𝐚𝐃𝐍𝐒<br><span class="green"><%:Running%></span>';
|
||||
} else {
|
||||
tb4.innerHTML = '𝐂𝐡𝐢𝐧𝐚𝐃𝐍𝐒<br><span class="red"><%:Not Running%></span>';
|
||||
}
|
||||
if (data.SOCKS5 ) {
|
||||
tb5.innerHTML = '𝙎𝙊𝘾𝙆𝙎5<br><span class="green"><%:Running%></span>';
|
||||
} else {
|
||||
tb5.innerHTML = '𝙎𝙊𝘾𝙆𝙎5<br><span class="red"><%:Not Running%></span>';
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
//]]>
|
||||
</script>
|
||||
@ -1,202 +0,0 @@
|
||||
|
||||
<fieldset id="_shadowsocksr_status_fieldset" class="cbi-section">
|
||||
<legend>
|
||||
<%:Running Status%>
|
||||
</legend>
|
||||
|
||||
<style>
|
||||
.pure-g{letter-spacing:-.31em;text-rendering:optimizespeed;font-family:FreeSans,Arimo,"Droid Sans",Helvetica,Arial,sans-serif;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap;-webkit-align-content:flex-start;-ms-flex-line-pack:start;align-content:flex-start}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){table .pure-g{display:block}}.opera-only :-o-prefocus,.pure-g{word-spacing:-.43em}.pure-u,.pure-u-1,.pure-u-1-1,.pure-u-1-12,.pure-u-1-2,.pure-u-1-24,.pure-u-1-3,.pure-u-1-4,.pure-u-1-5,.pure-u-1-6,.pure-u-1-8,.pure-u-10-24,.pure-u-11-12,.pure-u-11-24,.pure-u-12-24,.pure-u-13-24,.pure-u-14-24,.pure-u-15-24,.pure-u-16-24,.pure-u-17-24,.pure-u-18-24,.pure-u-19-24,.pure-u-2-24,.pure-u-2-3,.pure-u-2-5,.pure-u-20-24,.pure-u-21-24,.pure-u-22-24,.pure-u-23-24,.pure-u-24-24,.pure-u-3-24,.pure-u-3-4,.pure-u-3-5,.pure-u-3-8,.pure-u-4-24,.pure-u-4-5,.pure-u-5-12,.pure-u-5-24,.pure-u-5-5,.pure-u-5-6,.pure-u-5-8,.pure-u-6-24,.pure-u-7-12,.pure-u-7-24,.pure-u-7-8,.pure-u-8-24,.pure-u-9-24{display:inline-block;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-g [class*=pure-u]{font-family:sans-serif}.pure-u-1-24{width:4.1667%}.pure-u-1-12,.pure-u-2-24{width:8.3333%}.pure-u-1-8,.pure-u-3-24{width:12.5%}.pure-u-1-6,.pure-u-4-24{width:16.6667%}.pure-u-1-5{width:20%}.pure-u-5-24{width:20.8333%}.pure-u-1-4,.pure-u-6-24{width:25%}.pure-u-7-24{width:29.1667%}.pure-u-1-3,.pure-u-8-24{width:33.3333%}.pure-u-3-8,.pure-u-9-24{width:37.5%}.pure-u-2-5{width:40%}.pure-u-10-24,.pure-u-5-12{width:41.6667%}.pure-u-11-24{width:45.8333%}.pure-u-1-2,.pure-u-12-24{width:50%}.pure-u-13-24{width:54.1667%}.pure-u-14-24,.pure-u-7-12{width:58.3333%}.pure-u-3-5{width:60%}.pure-u-15-24,.pure-u-5-8{width:62.5%}.pure-u-16-24,.pure-u-2-3{width:66.6667%}.pure-u-17-24{width:70.8333%}.pure-u-18-24,.pure-u-3-4{width:75%}.pure-u-19-24{width:79.1667%}.pure-u-4-5{width:80%}.pure-u-20-24,.pure-u-5-6{width:83.3333%}.pure-u-21-24,.pure-u-7-8{width:87.5%}.pure-u-11-12,.pure-u-22-24{width:91.6667%}.pure-u-23-24{width:95.8333%}.pure-u-1,.pure-u-1-1,.pure-u-24-24,.pure-u-6-6{width:100%}
|
||||
.status{
|
||||
margin: 1.5rem -0.5rem 0 -0.5rem;
|
||||
}
|
||||
.block{
|
||||
margin: 0.5rem 0.5rem;
|
||||
padding: 0;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
line-height: 1;
|
||||
font-family: inherit;
|
||||
min-width: inherit;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
border: 1px solid rgba(0,0,0,.05);
|
||||
border-radius: .375rem;
|
||||
background-color: #fff ;
|
||||
box-shadow: 0 0 2rem 0 rgba(136,152,170,.15);
|
||||
}
|
||||
.img-con{
|
||||
margin: 1rem;
|
||||
}
|
||||
.green{
|
||||
color: #2dce89;
|
||||
}
|
||||
.red{
|
||||
color: #f5365c;
|
||||
}
|
||||
.block img{
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
.pure-u-5-8{
|
||||
display:flex;
|
||||
align-items:center;
|
||||
}
|
||||
.block h4{
|
||||
font-size: 1.3rem;
|
||||
font-weight: bold;
|
||||
margin: 0.75rem 0;
|
||||
line-height: 1.8em;
|
||||
}
|
||||
@media screen and (max-width: 1920px) {
|
||||
.block h4{
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 1690px) {
|
||||
.block h4{
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 1290px) {
|
||||
.block h4{
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
.pure-u-1-6{
|
||||
width:33.333%;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 700px) {
|
||||
.pure-u-1-6{
|
||||
width:50%;
|
||||
}
|
||||
.img-con{
|
||||
margin: 0.5rem;
|
||||
}
|
||||
.block h4{
|
||||
font-size: 0.81rem;
|
||||
}
|
||||
}
|
||||
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
|
||||
|
||||
<div class="pure-g status">
|
||||
<div class="pure-u-1-6">
|
||||
<div class="block pure-g" >
|
||||
<div class="pure-u-3-8">
|
||||
<div class="img-con">
|
||||
<img src="https://i.imgur.com/wzbtvXp.png" >
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-5-8">
|
||||
<h4 id="shadowsocksr_status"><%:Client%><br /><span class="red"><%:Not Running%></span></h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-1-6">
|
||||
<div class="block pure-g" >
|
||||
<div class="pure-u-3-8">
|
||||
<div class="img-con">
|
||||
<img src="https://i.imgur.com/3mE04AZ.png">
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-5-8">
|
||||
<h4 id="google_status"><%:foreign websites%><br /><span class="red"><%:Problem detected%></span></h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-1-6">
|
||||
<div class="block pure-g" >
|
||||
<div class="pure-u-3-8">
|
||||
<div class="img-con">
|
||||
<img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyMy4wLjEsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0i5Zu+5bGCXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMTAwIDEwMDsiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCgkuc3Qwe2ZpbGw6IzMzODhGRjt9DQoJLnN0MXtmaWxsLXJ1bGU6ZXZlbm9kZDtjbGlwLXJ1bGU6ZXZlbm9kZDtmaWxsOiNGRkZGRkY7fQ0KPC9zdHlsZT4NCjxjaXJjbGUgY2xhc3M9InN0MCIgY3g9IjUwIiBjeT0iNTAiIHI9IjUwIi8+DQo8ZyBpZD0i5pCc57SiX+eGiuaOjF82Nmljb24iPg0KCTxnIGlkPSJsb2dvIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMjEuMjEyMTIxLCA5MC45MDkwOTEpIj4NCgkJPHBhdGggaWQ9IkZpbGwtMSIgY2xhc3M9InN0MSIgZD0iTS03OS43LTU1LjRjNC41LDAsOC41LTUuNCw4LjUtMTEuOWMwLTYuNS0zLjctMTEuOS04LjUtMTEuOWMtNC41LDAtOC41LDUuNC04LjUsMTEuOQ0KCQkJQy04Ny45LTYwLjctODQuMi01NS40LTc5LjctNTUuNCIvPg0KCQk8cGF0aCBpZD0iRmlsbC0zIiBjbGFzcz0ic3QxIiBkPSJNLTU5LjktNTQuNWM2LjIsMC44LDEwLjItNS43LDExLTEwLjhjMC44LTQuOC0zLjEtMTAuOC03LjYtMTEuNmMtNC4yLTEuMS05LjksNS45LTEwLjIsMTAuNQ0KCQkJQy02Ny4yLTYxLTY2LjEtNTUuNC01OS45LTU0LjUiLz4NCgkJPHBhdGggaWQ9IkZpbGwtNSIgY2xhc3M9InN0MSIgZD0iTS05NS4zLTM4LjZjOC41LTEuNyw3LjEtMTEuNiw3LjEtMTMuOWMtMC4zLTMuNC00LjItOS4zLTkuOS04LjhjLTYuOCwwLjYtNy42LDEwLjItNy42LDEwLjINCgkJCUMtMTA2LjktNDYuNi0xMDMuOC0zNi45LTk1LjMtMzguNiIvPg0KCQk8cGF0aCBpZD0iRmlsbC03IiBjbGFzcz0ic3QxIiBkPSJNLTM1LjItNDYuM2MwLTIuNS0yLTkuNi05LjMtOS42Yy03LjQsMC04LjUsNi44LTguNSwxMS42YzAsNC41LDAuMywxMSw5LjYsMTAuOA0KCQkJQy0zNC40LTMzLjgtMzUuMi00NC0zNS4yLTQ2LjMiLz4NCgkJPHBhdGggaWQ9IkZpbGwtOSIgY2xhc3M9InN0MSIgZD0iTS04Ni41LTIxLjRjLTAuMywwLjYtMC44LDIuNS0wLjMsNGMwLjgsMy40LDQsMy43LDQsMy43aDQuMnYtMTAuOGgtNC44DQoJCQlDLTg1LjEtMjMuNi04Ni4yLTIxLjktODYuNS0yMS40Ii8+DQoJCTxwYXRoIGlkPSJGaWxsLTExIiBjbGFzcz0ic3QxIiBkPSJNLTUzLjEtOS41aC0xMi43Yy00LjgtMS4xLTUuMS00LjgtNS4xLTQuOHYtMTMuOWg1LjF2MTIuNWMwLjMsMS40LDIsMS43LDIsMS43aDUuNHYtMTMuOWg1LjQNCgkJCVYtOS41eiBNLTczLjItOS4ySC04NGMtNC44LTAuOC02LjgtNC4yLTYuOC00LjhjLTAuMy0wLjYtMS43LTMuMS0wLjgtNy42YzItNi41LDcuOS03LjEsNy45LTcuMWg1Ljd2LTcuMWg0LjgNCgkJCUMtNzMuMi0zNS44LTczLjItOS4yLTczLjItOS4yeiBNLTQ0LjYtMjUuM2MwLDAtOS42LTcuNC0xNS4zLTE1LjNjLTcuNi0xMS42LTE4LjQtNy4xLTIxLjgtMS4xYy0zLjQsNS45LTkuMSw5LjktOS45LDEwLjgNCgkJCWMtMC44LDAuOC0xMS42LDYuOC05LjEsMTcuM0MtOTguMS0zLjItODkuOS0zLjUtODkuOS0zLjVzNi4yLDAuNiwxMy4zLTEuMWM3LjEtMS43LDEzLjMsMC4zLDEzLjMsMC4zUy00Ni42LDEuMy00Mi05LjcNCgkJCUMtMzcuNS0xOS43LTQ0LjYtMjUuMy00NC42LTI1LjNMLTQ0LjYtMjUuM3oiLz4NCgk8L2c+DQo8L2c+DQo8L3N2Zz4NCg==">
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-5-8">
|
||||
<h4 id="baidu_status"><%:domestic website%><br /><span class="red"><%:Problem detected%></span></h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-1-6">
|
||||
<div class="block pure-g" >
|
||||
<div class="pure-u-3-8">
|
||||
<div class="img-con">
|
||||
<img src="https://i.imgur.com/0EJktYn.png" >
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-5-8">
|
||||
<h4 id="ss_server_status"><%:SS Servers%><br><span class="red"><%:Not Running%></span></h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-1-6">
|
||||
<div class="block pure-g" >
|
||||
<div class="pure-u-3-8">
|
||||
<div class="img-con">
|
||||
<img src="https://i.imgur.com/8Fj5nX2.png">
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-5-8">
|
||||
<h4 id="ssr_server_status"><%:SSR Servers%><br><span class="red"><%:Not Running%></span></h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-1-6">
|
||||
<div class="block pure-g" >
|
||||
<div class="pure-u-3-8">
|
||||
<div class="img-con">
|
||||
<img src="https://i.imgur.com/cWo9mwE.png" >
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-5-8">
|
||||
<h4 id="v2_server_status"><%:V2 Servers%><br><span class="red"><%:Not Running%></span></h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</style>
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
XHR.poll(5, '<%=url([[admin]], [[vpn]], [[shadowsocksr]], [[run]])%>', null,
|
||||
function (x, data) {
|
||||
var tb = document.getElementById('shadowsocksr_status');
|
||||
var tb1 = document.getElementById('google_status');
|
||||
var tb2 = document.getElementById('baidu_status');
|
||||
var tb3 = document.getElementById('ss_server_status');
|
||||
var tb4 = document.getElementById('ssr_server_status');
|
||||
var tb5 = document.getElementById('v2_server_status');
|
||||
if (data && tb) {
|
||||
if (data.global) {
|
||||
tb.innerHTML = '<%:Client%><br><span class="green"><%:Running%></span>';
|
||||
} else {
|
||||
tb.innerHTML = '<%:Client%><br><span class="red"><%:Not Running%></span>';
|
||||
}
|
||||
if (data.google) {
|
||||
tb1.innerHTML = '<%:foreign websites%><br><span class="green"><%:Connect OK%></span>';
|
||||
} else {
|
||||
tb1.innerHTML = '<%:foreign websites%><br><span class="red"><%:Problem detected%></span>';
|
||||
}
|
||||
if (data.baidu) {
|
||||
tb2.innerHTML = '<%:domestic website%><br><span class="green"><%:Connect OK%></span>';
|
||||
} else {
|
||||
tb2.innerHTML = '<%:domestic website%><br><span class="red"><%:Problem detected%></span>';
|
||||
}
|
||||
if (data.ss_server) {
|
||||
tb3.innerHTML = '<%:SS Servers%><br><span class="green"><%:Running%></span>';
|
||||
} else {
|
||||
tb3.innerHTML = '<%:SS Servers%><br><span class="red"><%:Not Running%></span>';
|
||||
}
|
||||
if (data.ssr_server) {
|
||||
tb4.innerHTML = '<%:SSR Servers%><br><span class="green"><%:Running%></span>';
|
||||
} else {
|
||||
tb4.innerHTML = '<%:SSR Servers%><br><span class="red"><%:Not Running%></span>';
|
||||
}
|
||||
if (data.v2_server ) {
|
||||
tb5.innerHTML = '<%:V2 Servers%><br><span class="green"><%:Running%></span>';
|
||||
} else {
|
||||
tb5.innerHTML = '<%:V2 Servers%><br><span class="red"><%:Not Running%></span>';
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
//]]>
|
||||
</script>
|
||||
</fieldset>
|
||||
@ -1,177 +0,0 @@
|
||||
|
||||
|
||||
<style>
|
||||
.pure-g{letter-spacing:-.31em;text-rendering:optimizespeed;font-family:FreeSans,Arimo,"Droid Sans",Helvetica,Arial,sans-serif;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap;-webkit-align-content:flex-start;-ms-flex-line-pack:start;align-content:flex-start}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){table .pure-g{display:block}}.opera-only :-o-prefocus,.pure-g{word-spacing:-.43em}.pure-u,.pure-u-1,.pure-u-1-1,.pure-u-1-12,.pure-u-1-2,.pure-u-1-24,.pure-u-1-3,.pure-u-1-4,.pure-u-1-5,.pure-u-1-6,.pure-u-1-8,.pure-u-10-24,.pure-u-11-12,.pure-u-11-24,.pure-u-12-24,.pure-u-13-24,.pure-u-14-24,.pure-u-15-24,.pure-u-16-24,.pure-u-17-24,.pure-u-18-24,.pure-u-19-24,.pure-u-2-24,.pure-u-2-3,.pure-u-2-5,.pure-u-20-24,.pure-u-21-24,.pure-u-22-24,.pure-u-23-24,.pure-u-24-24,.pure-u-3-24,.pure-u-3-4,.pure-u-3-5,.pure-u-3-8,.pure-u-4-24,.pure-u-4-5,.pure-u-5-12,.pure-u-5-24,.pure-u-5-5,.pure-u-5-6,.pure-u-5-8,.pure-u-6-24,.pure-u-7-12,.pure-u-7-24,.pure-u-7-8,.pure-u-8-24,.pure-u-9-24{display:inline-block;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-g [class*=pure-u]{font-family:sans-serif}.pure-u-1-24{width:4.1667%}.pure-u-1-12,.pure-u-2-24{width:8.3333%}.pure-u-1-8,.pure-u-3-24{width:12.5%}.pure-u-1-6,.pure-u-4-24{width:16.6667%}.pure-u-1-5{width:20%}.pure-u-5-24{width:20.8333%}.pure-u-1-4,.pure-u-6-24{width:25%}.pure-u-7-24{width:29.1667%}.pure-u-1-3,.pure-u-8-24{width:33.3333%}.pure-u-3-8,.pure-u-9-24{width:37.5%}.pure-u-2-5{width:40%}.pure-u-10-24,.pure-u-5-12{width:41.6667%}.pure-u-11-24{width:45.8333%}.pure-u-1-2,.pure-u-12-24{width:50%}.pure-u-13-24{width:54.1667%}.pure-u-14-24,.pure-u-7-12{width:58.3333%}.pure-u-3-5{width:60%}.pure-u-15-24,.pure-u-5-8{width:62.5%}.pure-u-16-24,.pure-u-2-3{width:66.6667%}.pure-u-17-24{width:70.8333%}.pure-u-18-24,.pure-u-3-4{width:75%}.pure-u-19-24{width:79.1667%}.pure-u-4-5{width:80%}.pure-u-20-24,.pure-u-5-6{width:83.3333%}.pure-u-21-24,.pure-u-7-8{width:87.5%}.pure-u-11-12,.pure-u-22-24{width:91.6667%}.pure-u-23-24{width:95.8333%}.pure-u-1,.pure-u-1-1,.pure-u-24-24,.pure-u-6-6{width:100%}
|
||||
.status{
|
||||
margin: 0rem -0.5rem -0.7rem -0.5rem;
|
||||
}
|
||||
.block{
|
||||
margin: 0.5rem 0.5rem;
|
||||
padding: 0;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
line-height: 1;
|
||||
font-family: inherit;
|
||||
min-width: inherit;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
border: 1px solid rgba(0,0,0,.05);
|
||||
border-radius: .375rem;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 0 2rem 0 rgba(136,152,170,.15);
|
||||
|
||||
}
|
||||
.img-con{
|
||||
margin: 1rem;
|
||||
|
||||
}
|
||||
.green{
|
||||
font-size:1.25rem;
|
||||
color: #2dce89;
|
||||
}
|
||||
.red{
|
||||
font-size:1.25rem;
|
||||
color: #fb6340;
|
||||
}
|
||||
|
||||
.sk-text-success{
|
||||
color: #2dce89;
|
||||
}
|
||||
.sk-text-error{
|
||||
color: #fb6340;
|
||||
}
|
||||
.gap{
|
||||
margin-right:0.5rem;
|
||||
}
|
||||
.block img{
|
||||
width: 48px;
|
||||
height: auto;
|
||||
float:right;
|
||||
}
|
||||
.pure-u-5-8{
|
||||
display:flex;
|
||||
align-items:center;
|
||||
|
||||
}
|
||||
|
||||
.block h4{
|
||||
font-size: .8125rem;
|
||||
font-weight: 600;
|
||||
margin: 1rem;
|
||||
color:#8898aa!important;
|
||||
line-height: 1.8em;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 720px) {
|
||||
.pure-u-1-6{
|
||||
width:50%;
|
||||
}
|
||||
.pure-u-1-2{
|
||||
width:100%;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
|
||||
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="pure-g status">
|
||||
<div class="pure-u-1-6">
|
||||
<div class="block pure-g">
|
||||
<div class="pure-u-3-5">
|
||||
<h4 id="shadowsocksr_status"><%:Client%><br /><span class="red"><%:Not Running%></span></h4>
|
||||
</div>
|
||||
<div class="pure-u-2-5">
|
||||
<div class="img-con">
|
||||
<img src="https://i.imgur.com/wzbtvXp.png" >
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-1-6">
|
||||
<div class="block pure-g">
|
||||
<div class="pure-u-3-5">
|
||||
|
||||
<h4 id="baidu_status"><%:domestic website%><br><span class="red"><%:Problem detected%></span></h4>
|
||||
</div>
|
||||
<div class="pure-u-2-5">
|
||||
<div class="img-con">
|
||||
<img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyMy4wLjEsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0i5Zu+5bGCXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMTAwIDEwMDsiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCgkuc3Qwe2ZpbGw6IzMzODhGRjt9DQoJLnN0MXtmaWxsLXJ1bGU6ZXZlbm9kZDtjbGlwLXJ1bGU6ZXZlbm9kZDtmaWxsOiNGRkZGRkY7fQ0KPC9zdHlsZT4NCjxjaXJjbGUgY2xhc3M9InN0MCIgY3g9IjUwIiBjeT0iNTAiIHI9IjUwIi8+DQo8ZyBpZD0i5pCc57SiX+eGiuaOjF82Nmljb24iPg0KCTxnIGlkPSJsb2dvIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMjEuMjEyMTIxLCA5MC45MDkwOTEpIj4NCgkJPHBhdGggaWQ9IkZpbGwtMSIgY2xhc3M9InN0MSIgZD0iTS03OS43LTU1LjRjNC41LDAsOC41LTUuNCw4LjUtMTEuOWMwLTYuNS0zLjctMTEuOS04LjUtMTEuOWMtNC41LDAtOC41LDUuNC04LjUsMTEuOQ0KCQkJQy04Ny45LTYwLjctODQuMi01NS40LTc5LjctNTUuNCIvPg0KCQk8cGF0aCBpZD0iRmlsbC0zIiBjbGFzcz0ic3QxIiBkPSJNLTU5LjktNTQuNWM2LjIsMC44LDEwLjItNS43LDExLTEwLjhjMC44LTQuOC0zLjEtMTAuOC03LjYtMTEuNmMtNC4yLTEuMS05LjksNS45LTEwLjIsMTAuNQ0KCQkJQy02Ny4yLTYxLTY2LjEtNTUuNC01OS45LTU0LjUiLz4NCgkJPHBhdGggaWQ9IkZpbGwtNSIgY2xhc3M9InN0MSIgZD0iTS05NS4zLTM4LjZjOC41LTEuNyw3LjEtMTEuNiw3LjEtMTMuOWMtMC4zLTMuNC00LjItOS4zLTkuOS04LjhjLTYuOCwwLjYtNy42LDEwLjItNy42LDEwLjINCgkJCUMtMTA2LjktNDYuNi0xMDMuOC0zNi45LTk1LjMtMzguNiIvPg0KCQk8cGF0aCBpZD0iRmlsbC03IiBjbGFzcz0ic3QxIiBkPSJNLTM1LjItNDYuM2MwLTIuNS0yLTkuNi05LjMtOS42Yy03LjQsMC04LjUsNi44LTguNSwxMS42YzAsNC41LDAuMywxMSw5LjYsMTAuOA0KCQkJQy0zNC40LTMzLjgtMzUuMi00NC0zNS4yLTQ2LjMiLz4NCgkJPHBhdGggaWQ9IkZpbGwtOSIgY2xhc3M9InN0MSIgZD0iTS04Ni41LTIxLjRjLTAuMywwLjYtMC44LDIuNS0wLjMsNGMwLjgsMy40LDQsMy43LDQsMy43aDQuMnYtMTAuOGgtNC44DQoJCQlDLTg1LjEtMjMuNi04Ni4yLTIxLjktODYuNS0yMS40Ii8+DQoJCTxwYXRoIGlkPSJGaWxsLTExIiBjbGFzcz0ic3QxIiBkPSJNLTUzLjEtOS41aC0xMi43Yy00LjgtMS4xLTUuMS00LjgtNS4xLTQuOHYtMTMuOWg1LjF2MTIuNWMwLjMsMS40LDIsMS43LDIsMS43aDUuNHYtMTMuOWg1LjQNCgkJCVYtOS41eiBNLTczLjItOS4ySC04NGMtNC44LTAuOC02LjgtNC4yLTYuOC00LjhjLTAuMy0wLjYtMS43LTMuMS0wLjgtNy42YzItNi41LDcuOS03LjEsNy45LTcuMWg1Ljd2LTcuMWg0LjgNCgkJCUMtNzMuMi0zNS44LTczLjItOS4yLTczLjItOS4yeiBNLTQ0LjYtMjUuM2MwLDAtOS42LTcuNC0xNS4zLTE1LjNjLTcuNi0xMS42LTE4LjQtNy4xLTIxLjgtMS4xYy0zLjQsNS45LTkuMSw5LjktOS45LDEwLjgNCgkJCWMtMC44LDAuOC0xMS42LDYuOC05LjEsMTcuM0MtOTguMS0zLjItODkuOS0zLjUtODkuOS0zLjVzNi4yLDAuNiwxMy4zLTEuMWM3LjEtMS43LDEzLjMsMC4zLDEzLjMsMC4zUy00Ni42LDEuMy00Mi05LjcNCgkJCUMtMzcuNS0xOS43LTQ0LjYtMjUuMy00NC42LTI1LjNMLTQ0LjYtMjUuM3oiLz4NCgk8L2c+DQo8L2c+DQo8L3N2Zz4NCg==" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-1-6">
|
||||
<div class="block pure-g">
|
||||
<div class="pure-u-3-5">
|
||||
<h4 id="google_status"><%:foreign websites%><br><span class="red"><%:Problem detected%></span></h4>
|
||||
</div>
|
||||
<div class="pure-u-2-5">
|
||||
<div class="img-con">
|
||||
<img src="https://i.imgur.com/3mE04AZ.png">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pure-u-1-6">
|
||||
<div class="block pure-g">
|
||||
<div class="pure-u-3-5">
|
||||
<h4 id="game_status"><%:Game Mode%><br /><span class="red"><%:Not Running%></span></h4>
|
||||
</div>
|
||||
<div class="pure-u-2-5">
|
||||
<div class="img-con">
|
||||
<img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyMy4wLjEsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0i5Zu+5bGCXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMTAwIDEwMDsiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCgkuc3Qwe2ZpbGw6I0ZCQjE0MDt9DQoJLnN0MXtmaWxsOiNGRkZGRkY7fQ0KPC9zdHlsZT4NCjxjaXJjbGUgY2xhc3M9InN0MCIgY3g9IjUwIiBjeT0iNTAiIHI9IjUwIi8+DQo8cGF0aCBjbGFzcz0ic3QxIiBkPSJNODYuOCw0Ny42QzgzLjYsMzMsNzQuOCwyMi41LDY2LjUsMjNoLTAuM2MtMy4zLDAtNi41LDEuMi04LjksMy4zYy0xLjgsMi00LjQsMy4yLTcuMSwzLjINCgljLTIuNiwwLTUuMS0xLjEtNi45LTNjLTIuNS0yLjMtNS44LTMuNS05LjEtMy41aC0wLjRjLTguMi0wLjUtMTcuMSwxMC0yMC4zLDI0LjZjLTMuNSwxNS41LDAuOCwyOS44LDkuNSwzMS45DQoJYzYuMywxLjYsMTMuMy0zLjksMTcuOS0xM2gxOC43YzQuNyw5LjEsMTEuNiwxNC42LDE3LjksMTNDODYsNzcuNCw5MC4yLDYzLjEsODYuOCw0Ny42TDg2LjgsNDcuNnogTTQyLjksNDguNUgzNnY3LjJoLTUuNnYtNy4yDQoJaC02Ljl2LTUuOGg2Ljl2LTcuMkgzNnY3LjJoNi45TDQyLjksNDguNXogTTYyLjcsNDkuMmMtMiwwLjEtMy43LTEuNC0zLjgtMy40Yy0wLjEtMiwxLjQtMy43LDMuNC0zLjhjMi0wLjEsMy43LDEuNCwzLjgsMy40DQoJYzAsMC4xLDAsMC4xLDAsMC4yQzY2LjIsNDcuNSw2NC43LDQ5LjEsNjIuNyw0OS4yQzYyLjcsNDkuMiw2Mi43LDQ5LjIsNjIuNyw0OS4yeiBNNzMuNyw0OS4yYy0yLDAuMS0zLjctMS40LTMuOC0zLjQNCgljLTAuMS0yLDEuNC0zLjcsMy40LTMuOGMyLTAuMSwzLjcsMS40LDMuOCwzLjRjMCwwLjEsMCwwLjEsMCwwLjJjMC4xLDEuOS0xLjQsMy41LTMuMywzLjZINzMuN3oiLz4NCjwvc3ZnPg0K" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-1-6">
|
||||
<div class="block pure-g">
|
||||
<div class="pure-u-3-5">
|
||||
<h4 id="chinadns_status">𝐂𝐡𝐢𝐧𝐚𝐃𝐍𝐒<br /><span class="red"><%:Not Running%></span></h4>
|
||||
</div>
|
||||
<div class="pure-u-2-5">
|
||||
<div class="img-con">
|
||||
<img src="https://i.imgur.com/3hkGjsK.png" >
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pure-u-1-6">
|
||||
<div class="block pure-g">
|
||||
<div class="pure-u-3-5">
|
||||
<h4 id="SOCKS5_status">𝙎𝙊𝘾𝙆𝙎5<br /><span class="red"><%:Not Running%></span></h4>
|
||||
</div>
|
||||
<div class="pure-u-2-5">
|
||||
<div class="img-con">
|
||||
<img src="https://i.imgur.com/bYz9YoR.png" >
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
|
||||
|
||||
//<![CDATA[
|
||||
XHR.poll(5, '<%=url([[admin]], [[vpn]], [[shadowsocksr]], [[run]])%>', null,
|
||||
function (x, data) {
|
||||
if (data) {
|
||||
document.getElementById('shadowsocksr_status').innerHTML = data.global?'<%:Client%><br><span class="green"><%:Running%></span>':'<%:Client%><br><span class="red"><%:Not Running%></span>';
|
||||
document.getElementById('baidu_status').innerHTML = data.baidu?'<%:domestic website%><br><span class="green"><%:Connect OK%></span>':'<%:domestic website%><br><span class="red"><%:Problem detected%></span>';
|
||||
document.getElementById('google_status').innerHTML = data.google?'<%:foreign websites%><br><span class="green"><%:Connect OK%></span>':'<%:foreign websites%><br><span class="red"><%:Problem detected%></span>';
|
||||
document.getElementById('game_status').innerHTML = data.game?'<%:Game Mode%><br><span class="green"><%:Running%></span>':'<%:Game Mode%><br><span class="red"><%:Not Running%></span>';
|
||||
document.getElementById('chinadns_status').innerHTML = data.chinadns?'ChinaDNS<br><span class="green"><%:Running%></span>':'ChinaDNS<br><span class="red"><%:Not Running%></span>';
|
||||
document.getElementById('SOCKS5_status').innerHTML = data.SOCKS5?'𝙎𝙊𝘾𝙆𝙎5<br><span class="green"><%:Running%></span>':'𝙎𝙊𝘾𝙆𝙎5<br><span class="red"><%:Not Running%></span>';
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
);
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
@ -1,123 +0,0 @@
|
||||
<%+cbi/valueheader%>
|
||||
<link rel="stylesheet" href="/luci-static/shadowsocksr/css/shadowsocksr.css?v=72883">
|
||||
<label class="cbi-value-title"><%= translate("Update") %></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") %>">
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
var _responseLen;
|
||||
var noChange = 0;
|
||||
var x = 5;
|
||||
|
||||
var modal = '<div class="modals-bg">' +
|
||||
'<div class="modals">' +
|
||||
'<h2><%:Subscription%></h2>'+
|
||||
'<h3 style="margin-left:0;"><%:Subscribing,Please do not refresh!%></h3>'+
|
||||
'<textarea cols="63" rows="28" wrap="on" readonly="readonly" id="log_content3" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"></textarea>'+
|
||||
'</div>'+
|
||||
'</div>';
|
||||
|
||||
|
||||
function update_subscribe() {
|
||||
$("body").append(modal);
|
||||
$(".modals-bg").show();
|
||||
|
||||
setTimeout("get_realtime_log();", 500);
|
||||
}
|
||||
|
||||
function submit_url(){
|
||||
prefix_array = $("#cbi-shadowsocksr-server_subscribe .cbi-section-node").attr("id").split("-");
|
||||
prefix_array[0] = "cbid";
|
||||
prefix = prefix_array.join(".");
|
||||
if($("[name='"+prefix+".auto_update']").is(":checked")){
|
||||
var auto_update = "1";
|
||||
}else{
|
||||
var auto_update = "0";
|
||||
}
|
||||
var auto_update_time = $("[name='"+prefix+".auto_update_time']").val();
|
||||
var subscribe_url = [];
|
||||
$("[name='"+prefix+".subscribe_url']").each(function(){
|
||||
if($(this).val() != ""){
|
||||
subscribe_url.push($(this).val());
|
||||
}
|
||||
});
|
||||
if($("[name='"+prefix+".proxy']").is(":checked")){
|
||||
var proxy = "1";
|
||||
}else{
|
||||
var proxy = "0";
|
||||
}
|
||||
|
||||
var data = {
|
||||
auto_update:auto_update,
|
||||
auto_update_time : auto_update_time,
|
||||
subscribe_url: JSON.stringify(subscribe_url),
|
||||
proxy: proxy
|
||||
}
|
||||
//console.log(data);
|
||||
$.ajax({
|
||||
type: "post",
|
||||
url: "<%=luci.dispatcher.build_url('admin', 'vpn', 'shadowsocksr','subscribe')%>",
|
||||
dataType : "json",
|
||||
data: data,
|
||||
success: function (d) {
|
||||
if(d.error == 0){
|
||||
//console.log("开始订阅");
|
||||
update_subscribe();
|
||||
}else{
|
||||
alert("请至少填写一个订阅链接");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$("#update_subscribe").click(function(){
|
||||
//console.log("提交数据");
|
||||
submit_url();
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
function refresh_page(){
|
||||
location.reload();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
function get_realtime_log() {
|
||||
$.ajax({
|
||||
url: '/check_update.htm?v='+parseInt(Math.random() * 100000000),
|
||||
dataType: 'html',
|
||||
error: function (xhr) {
|
||||
setTimeout("get_realtime_log();", 1000);
|
||||
},
|
||||
success: function (response) {
|
||||
var retArea = document.getElementById("log_content3");
|
||||
if (response.search("END SUBSCRIBE") != -1) {
|
||||
noChange++;
|
||||
}
|
||||
console.log(noChange);
|
||||
if (noChange > 10) {
|
||||
window.location.href="<%=luci.dispatcher.build_url('admin', 'vpn', 'shadowsocksr','servers')%>"
|
||||
return false;
|
||||
} else {
|
||||
setTimeout("get_realtime_log();", 250);
|
||||
}
|
||||
retArea.value = response;
|
||||
retArea.scrollTop = retArea.scrollHeight;
|
||||
_responseLen = response.length;
|
||||
},
|
||||
error: function () {
|
||||
setTimeout("get_realtime_log();", 500);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
<%+cbi/valuefooter%>
|
||||
@ -1,868 +0,0 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8\n"
|
||||
|
||||
|
||||
msgid "Enable"
|
||||
msgstr "启用"
|
||||
|
||||
msgid "Disable"
|
||||
msgstr "停用"
|
||||
|
||||
msgid "Enable Servers"
|
||||
msgstr "开启服务"
|
||||
|
||||
msgid "Enable Authentication"
|
||||
msgstr "启用 用户名/密码 认证"
|
||||
|
||||
msgid "Open v2ray split-flow"
|
||||
msgstr "开启V2ray分流"
|
||||
|
||||
msgid "When open v2ray split-flow,your main server must be a v2ray server"
|
||||
msgstr "当使用v2ray分流功能时 主服务器必须为V2ray"
|
||||
|
||||
msgid "Youtube Proxy"
|
||||
msgstr "Youtube 代理"
|
||||
|
||||
msgid "TaiWan Video Proxy"
|
||||
msgstr "台湾视频服务代理"
|
||||
|
||||
msgid "Netflix Proxy"
|
||||
msgstr "Netflix 代理"
|
||||
|
||||
msgid "Diseny+ Proxy"
|
||||
msgstr "Diseny+ 代理"
|
||||
|
||||
msgid "Prime Video Proxy"
|
||||
msgstr "Prime Video 代理"
|
||||
|
||||
msgid "adblock settings"
|
||||
msgstr "广告屏蔽设置"
|
||||
|
||||
msgid "Enable adblock"
|
||||
msgstr "开启广告屏蔽"
|
||||
|
||||
msgid "adblock_url"
|
||||
msgstr "广告屏蔽订阅"
|
||||
|
||||
msgid "Socks user"
|
||||
msgstr "用户名"
|
||||
|
||||
msgid "Socks pass"
|
||||
msgstr "密码"
|
||||
|
||||
msgid "Ping All Servers"
|
||||
msgstr "PING 所有节点"
|
||||
|
||||
msgid "Ping Latency"
|
||||
msgstr "Ping 延迟"
|
||||
|
||||
|
||||
|
||||
msgid "SSR SOCKS5 Proxy"
|
||||
msgstr "SSR SOCKS5代理"
|
||||
|
||||
msgid "Subscription"
|
||||
msgstr "订阅管理"
|
||||
|
||||
|
||||
|
||||
msgid "Subscribing,Please do not refresh!"
|
||||
msgstr "订阅,请不要刷新!"
|
||||
|
||||
msgid "Check Try Count"
|
||||
msgstr "切换检查重试次数"
|
||||
|
||||
msgid "Log"
|
||||
msgstr "日志"
|
||||
|
||||
msgid "Bypass Domain List"
|
||||
msgstr "不走代理的域名"
|
||||
|
||||
msgid "Black Domain List"
|
||||
msgstr "强制走代理的域名"
|
||||
|
||||
msgid "Node List"
|
||||
msgstr "节点列表"
|
||||
|
||||
msgid "END SUBSCRIBE"
|
||||
msgstr "结束订阅"
|
||||
|
||||
msgid "Update Setting"
|
||||
msgstr "更新设置"
|
||||
|
||||
|
||||
msgid "AlterId"
|
||||
msgstr "额外ID"
|
||||
|
||||
msgid "Save And Start Subscribe"
|
||||
msgstr "保存并开始订阅"
|
||||
|
||||
|
||||
msgid "VmessId (UUID)"
|
||||
msgstr "用户ID(UUID)"
|
||||
|
||||
msgid "Transport"
|
||||
msgstr "传输方式"
|
||||
|
||||
msgid "Configuration Url"
|
||||
msgstr "配置链接"
|
||||
|
||||
msgid "Import Configuration"
|
||||
msgstr "导入配置信息"
|
||||
|
||||
msgid "Apply"
|
||||
msgstr "应用"
|
||||
|
||||
msgid "total"
|
||||
msgstr "总计"
|
||||
|
||||
msgid "Node list"
|
||||
msgstr "节点列表"
|
||||
|
||||
|
||||
msgid "Nodes"
|
||||
msgstr "个节点"
|
||||
|
||||
msgid "Client"
|
||||
msgstr "客户端"
|
||||
|
||||
msgid "Visit foreign websites"
|
||||
msgstr "国外网站"
|
||||
|
||||
msgid "Visit domestic website"
|
||||
msgstr "国内网站"
|
||||
|
||||
msgid "Problem detected"
|
||||
msgstr "无法访问"
|
||||
|
||||
msgid "Working..."
|
||||
msgstr "连接正常"
|
||||
|
||||
|
||||
msgid "Game Mode"
|
||||
msgstr "游戏模式"
|
||||
|
||||
|
||||
msgid "V2ray SOCKS5 Proxy"
|
||||
msgstr "V2ray SOCKS5代理"
|
||||
|
||||
msgid "Edit ShadowSocksR Server"
|
||||
msgstr "编辑服务器配置"
|
||||
|
||||
msgid "ShadowSocksR is running"
|
||||
msgstr "ShadowSocksR 客户端运行中"
|
||||
|
||||
msgid "ShadowSocksR is not running"
|
||||
msgstr "ShadowSocksR 客户端未运行"
|
||||
|
||||
msgid "Global Setting"
|
||||
msgstr "全局设置"
|
||||
|
||||
msgid "Global Server"
|
||||
msgstr "全局服务器"
|
||||
|
||||
msgid "ShadowSocksR SOCK5 Proxy is running"
|
||||
msgstr "ShadowSocksR SOCK5代理运行中"
|
||||
|
||||
msgid "UDP Relay Server"
|
||||
msgstr "UDP中继服务器"
|
||||
|
||||
msgid "Same as Global Server"
|
||||
msgstr "与全局服务器相同"
|
||||
|
||||
msgid "Servers Setting"
|
||||
msgstr "服务器配置"
|
||||
|
||||
msgid "Alias(optional)"
|
||||
msgstr "别名(可选)"
|
||||
|
||||
msgid "Onetime Authentication"
|
||||
msgstr "一次验证"
|
||||
|
||||
msgid "Server Address"
|
||||
msgstr "服务器地址"
|
||||
|
||||
msgid "Server Port"
|
||||
msgstr "服务器端口"
|
||||
|
||||
msgid "Local Port"
|
||||
msgstr "本地端口"
|
||||
|
||||
msgid "Connection Timeout"
|
||||
msgstr "连接超时"
|
||||
|
||||
msgid "Password"
|
||||
msgstr "密码"
|
||||
|
||||
msgid "Encrypt Method"
|
||||
msgstr "加密方式"
|
||||
|
||||
msgid "Protocol"
|
||||
msgstr "传输协议"
|
||||
|
||||
msgid "Protocol param(optional)"
|
||||
msgstr "传输协议参数(可选)"
|
||||
|
||||
msgid "Obfs"
|
||||
msgstr "混淆插件"
|
||||
|
||||
msgid "Obfs param(optional)"
|
||||
msgstr "混淆参数(可选)"
|
||||
|
||||
msgid "Enable Tunnel(DNS)"
|
||||
msgstr "启用隧道(DNS)转发"
|
||||
|
||||
msgid "Tunnel Port"
|
||||
msgstr "隧道(DNS)本地端口"
|
||||
|
||||
msgid "Forwarding Tunnel"
|
||||
msgstr "隧道(DNS)转发地址"
|
||||
|
||||
msgid "Access Control"
|
||||
msgstr "访问控制"
|
||||
|
||||
msgid "Interfaces - WAN"
|
||||
msgstr "接口 - WAN"
|
||||
|
||||
msgid "Bypassed IP List"
|
||||
msgstr "被忽略IP列表"
|
||||
|
||||
msgid "NULL - As Global Proxy"
|
||||
msgstr "留空 - 作为全局代理"
|
||||
|
||||
msgid "Bypassed IP"
|
||||
msgstr "额外被忽略IP"
|
||||
|
||||
msgid "Forwarded IP"
|
||||
msgstr "强制走代理IP"
|
||||
|
||||
msgid "Interfaces - LAN"
|
||||
msgstr "接口 - LAN"
|
||||
|
||||
msgid "LAN Access Control"
|
||||
msgstr "内网客户端分流代理控制"
|
||||
|
||||
msgid "Allow listed only"
|
||||
msgstr "仅允许列表内主机"
|
||||
|
||||
msgid "Allow all except listed"
|
||||
msgstr "除列表外主机皆允许"
|
||||
|
||||
msgid "LAN Host List"
|
||||
msgstr "内网主机列表"
|
||||
|
||||
msgid "SSR Client"
|
||||
msgstr "客户端"
|
||||
|
||||
|
||||
msgid "ShadowSocksR Server"
|
||||
msgstr "ShadowSocksR 服务端"
|
||||
|
||||
msgid "ShadowSocksR Server is running"
|
||||
msgstr "ShadowSocksR 服务端运行中"
|
||||
|
||||
msgid "ShadowSocksR Server is not running"
|
||||
msgstr "ShadowSocksR 服务端未运行"
|
||||
|
||||
msgid "Enable Server"
|
||||
msgstr "启动服务端"
|
||||
|
||||
msgid "Server Setting"
|
||||
msgstr "服务端配置"
|
||||
|
||||
msgid "KcpTun Enable"
|
||||
msgstr "KcpTun 启用"
|
||||
|
||||
msgid "bin:/usr/bin/kcptun-client"
|
||||
msgstr "二进制文件:/usr/bin/kcptun-client"
|
||||
|
||||
msgid "KcpTun Port"
|
||||
msgstr "KcpTun 端口"
|
||||
|
||||
msgid "KcpTun Param"
|
||||
msgstr "KcpTun 参数"
|
||||
|
||||
msgid "KcpTun Password"
|
||||
msgstr "KcpTun 密码"
|
||||
|
||||
msgid "Haven't a Kcptun executable file"
|
||||
msgstr "不存在Kcptun可执行文件,请下载Kcptun可执行文件并改名放入/usr/bin/kcptun-client"
|
||||
|
||||
msgid "Not a Kcptun executable file"
|
||||
msgstr "Kcptun可执行文件格式不正确,请确认是否正确下载了路由器对应的可执行文件"
|
||||
|
||||
msgid "Enable Process Monitor"
|
||||
msgstr "启用进程监控"
|
||||
|
||||
msgid "Edit ShadowSocksR Server"
|
||||
msgstr "编辑服务器配置"
|
||||
|
||||
msgid "Alias"
|
||||
msgstr "别名"
|
||||
|
||||
msgid "SOCKS5 Proxy"
|
||||
msgstr "SOCKS5代理"
|
||||
|
||||
msgid "Server"
|
||||
msgstr "服务器"
|
||||
|
||||
msgid "TCP Fast Open"
|
||||
msgstr "TCP快速打开"
|
||||
|
||||
msgid "Status"
|
||||
msgstr "状态"
|
||||
|
||||
msgid "Unknown"
|
||||
msgstr "未知"
|
||||
|
||||
msgid "Running Status"
|
||||
msgstr "运行状态"
|
||||
|
||||
msgid "ShadowSocksR Plus+"
|
||||
msgstr "ShadowSocksR Plus+ 魔改版"
|
||||
|
||||
msgid "Global Client"
|
||||
msgstr "TCP透明代理"
|
||||
|
||||
msgid "Global SSR Server"
|
||||
msgstr "SSR服务端"
|
||||
|
||||
msgid "DNS Tunnel"
|
||||
msgstr "DNS 隧道"
|
||||
|
||||
msgid "IPK Version"
|
||||
msgstr "IPK 版本号"
|
||||
|
||||
msgid "KcpTun Version"
|
||||
msgstr "KcpTun 版本号"
|
||||
|
||||
msgid "Not exist"
|
||||
msgstr "未安装可执行文件"
|
||||
|
||||
msgid "IPK Installation Time"
|
||||
msgstr "IPK 安装时间"
|
||||
|
||||
msgid "Project"
|
||||
msgstr "项目地址"
|
||||
|
||||
msgid "Not Running"
|
||||
msgstr "未运行"
|
||||
|
||||
msgid "Running"
|
||||
msgstr "运行中"
|
||||
|
||||
msgid "Enable GFW mode"
|
||||
msgstr "启用 GFW 模式"
|
||||
|
||||
msgid "Running Mode"
|
||||
msgstr "运行模式"
|
||||
|
||||
msgid "IP Route Mode"
|
||||
msgstr "绕过中国大陆IP模式"
|
||||
|
||||
msgid "GFW List Mode"
|
||||
msgstr "GFW列表模式"
|
||||
|
||||
msgid "Global Mode"
|
||||
msgstr "全局模式"
|
||||
|
||||
msgid "Oversea Mode"
|
||||
msgstr "海外用户回国模式"
|
||||
|
||||
msgid "Router Proxy"
|
||||
msgstr "路由器访问控制"
|
||||
|
||||
msgid "Normal Proxy"
|
||||
msgstr "正常代理"
|
||||
|
||||
msgid "Bypassed Proxy"
|
||||
msgstr "不走代理"
|
||||
|
||||
msgid "Forwarded Proxy"
|
||||
msgstr "强制走代理"
|
||||
|
||||
msgid "UDP Relay"
|
||||
msgstr "UDP中继"
|
||||
|
||||
msgid "Google Connectivity"
|
||||
msgstr "【谷歌】连通性检查"
|
||||
|
||||
msgid "Baidu Connectivity"
|
||||
msgstr "【百度】连通性检查"
|
||||
|
||||
msgid "No Check"
|
||||
msgstr "未检查"
|
||||
|
||||
msgid "Check"
|
||||
msgstr "检查"
|
||||
|
||||
msgid "Connect OK"
|
||||
msgstr "连接正常"
|
||||
|
||||
msgid "Connect Error"
|
||||
msgstr "连接错误"
|
||||
|
||||
msgid "Check..."
|
||||
msgstr "正在检查.."
|
||||
|
||||
msgid "Proxy Check"
|
||||
msgstr "代理检查"
|
||||
|
||||
|
||||
msgid "GFW List Data"
|
||||
msgstr "【GFW列表】数据库"
|
||||
|
||||
msgid "China IP Data"
|
||||
msgstr "【国内IP段】数据库"
|
||||
|
||||
msgid "Records"
|
||||
msgstr "条记录"
|
||||
|
||||
msgid "Refresh Data"
|
||||
msgstr "更新数据库"
|
||||
|
||||
msgid "Refresh..."
|
||||
msgstr "正在更新,请稍候.."
|
||||
|
||||
msgid "Refresh OK!"
|
||||
msgstr "更新成功!"
|
||||
|
||||
msgid "Refresh Error!"
|
||||
msgstr "更新失败!"
|
||||
|
||||
msgid "No new data!"
|
||||
msgstr "你已经是最新数据,无需更新!"
|
||||
|
||||
msgid "Total Records:"
|
||||
msgstr "新的总纪录数:"
|
||||
|
||||
msgid "Check Server Port"
|
||||
msgstr "【服务器端口】检查"
|
||||
|
||||
msgid "Check Connect"
|
||||
msgstr "检查连通性"
|
||||
|
||||
msgid "Basic Settings"
|
||||
msgstr "服务器设置"
|
||||
|
||||
msgid "Check Server"
|
||||
msgstr "检查服务器"
|
||||
|
||||
msgid "Auto Switch"
|
||||
msgstr "自动切换"
|
||||
|
||||
msgid "Enable Auto Switch"
|
||||
msgstr "启用自动切换"
|
||||
|
||||
msgid "Switch check cycly(second)"
|
||||
msgstr "自动切换检查周期(秒)"
|
||||
|
||||
msgid "Check timout(second)"
|
||||
msgstr "切换检查超时时间(秒)"
|
||||
|
||||
msgid "Enable Process Deamon"
|
||||
msgstr "启用进程自动守护"
|
||||
|
||||
msgid "Advertising Data"
|
||||
msgstr "【广告屏蔽】数据库"
|
||||
|
||||
msgid "DNS Server IP and Port"
|
||||
msgstr "DNS服务器地址和端口"
|
||||
|
||||
msgid "Resolve Dns Mode"
|
||||
msgstr "DNS解析方式"
|
||||
|
||||
msgid "Use SSR DNS Tunnel"
|
||||
msgstr "使用SSR-DNS隧道"
|
||||
|
||||
msgid "Use Pdnsd"
|
||||
msgstr "使用Pdnsd"
|
||||
|
||||
msgid "Use Other DNS Tunnel(Need to install)"
|
||||
msgstr "使用其他DNS转发(需要自己安装)"
|
||||
|
||||
msgid "Import SSR"
|
||||
msgstr "导入ssr配置信息"
|
||||
|
||||
msgid "Export SSR"
|
||||
msgstr "导出ssr配置信息"
|
||||
|
||||
msgid "Import SSR successfully."
|
||||
msgstr "成功导入SSR。"
|
||||
|
||||
msgid "Invalid SSR format."
|
||||
msgstr "无效的SSR格式。"
|
||||
|
||||
msgid "User cancelled."
|
||||
msgstr "用户已取消。"
|
||||
|
||||
msgid "Paste ssr url here"
|
||||
msgstr "在此处粘贴ssr://网址"
|
||||
|
||||
msgid "Unable to copy SSR to clipboard."
|
||||
msgstr "无法复制SSR网址到剪贴板。"
|
||||
|
||||
msgid "Copy SSR to clipboard successfully."
|
||||
msgstr "成功复制SSR网址到剪贴板。"
|
||||
|
||||
msgid "Servers Manage"
|
||||
msgstr "服务器管理"
|
||||
|
||||
msgid "Auto Update"
|
||||
msgstr "自动更新"
|
||||
|
||||
msgid "Through proxy update"
|
||||
msgstr "通过代理更新"
|
||||
|
||||
msgid "GFW List"
|
||||
msgstr "GFW列表"
|
||||
|
||||
msgid "ShadowSocksR Plus+ Settings"
|
||||
msgstr "ShadowSocksR Plus+ 设置(支持SS/SSR/V2RAY/Trojan)"
|
||||
|
||||
msgid "Main Server"
|
||||
msgstr "主服务器"
|
||||
|
||||
msgid "Anti-pollution DNS Server"
|
||||
msgstr "访问国外域名DNS服务器"
|
||||
|
||||
msgid "Use Pdnsd tcp query and cache"
|
||||
msgstr "使用PDNSD TCP查询并缓存"
|
||||
|
||||
msgid "DNS Server IP:Port"
|
||||
msgstr "DNS服务器 IP:Port"
|
||||
|
||||
msgid "Update time (every day)"
|
||||
msgstr "更新时间 (每天)"
|
||||
|
||||
msgid "Auto Update Server subscription, GFW list and CHN route"
|
||||
msgstr "自动更新服务器订阅、GFW列表和 CHN路由表"
|
||||
|
||||
msgid "Subscribe URL"
|
||||
msgstr "SS/SSR/V2RAY订阅URL地址"
|
||||
|
||||
msgid "Update"
|
||||
msgstr "更新"
|
||||
|
||||
msgid "Server Count"
|
||||
msgstr "服务器节点数量"
|
||||
|
||||
msgid "IP black-and-white list"
|
||||
msgstr "IP黑白名单"
|
||||
|
||||
msgid "WAN IP AC"
|
||||
msgstr "WAN IP访问控制"
|
||||
|
||||
msgid "WAN White List IP"
|
||||
msgstr "不走代理的WAN IP"
|
||||
|
||||
msgid "WAN Force Proxy IP"
|
||||
msgstr "强制走代理的WAN IP"
|
||||
|
||||
msgid "LAN Bypassed Host List"
|
||||
msgstr "不走代理的局域网LAN IP"
|
||||
|
||||
msgid "LAN Force Proxy Host List"
|
||||
msgstr "全局代理的LAN IP"
|
||||
|
||||
msgid "Router Self AC"
|
||||
msgstr "路由器自身代理设置"
|
||||
|
||||
msgid "Router Self Proxy"
|
||||
msgstr "路由器自身代理方式"
|
||||
|
||||
msgid "Normal Proxy"
|
||||
msgstr "跟随全局设置"
|
||||
|
||||
msgid "Bypassed Proxy"
|
||||
msgstr "不走代理"
|
||||
|
||||
msgid "Forwarded Proxy"
|
||||
msgstr "全局代理"
|
||||
|
||||
msgid "GFW Custom List"
|
||||
msgstr "GFW 用户自定义列表"
|
||||
|
||||
msgid "Please refer to the following writing"
|
||||
msgstr "每行一个域名,无需写前面的 HTTP(S):// ,提交后即时生效"
|
||||
|
||||
msgid "Servers subscription and manage"
|
||||
msgstr "节点订阅"
|
||||
|
||||
msgid "Through proxy update list, Not Recommended"
|
||||
msgstr "通过路由器自身代理更新订阅(不推荐)"
|
||||
|
||||
msgid "LAN IP AC"
|
||||
msgstr "LAN IP访问控制"
|
||||
|
||||
msgid "Game Mode UDP Server"
|
||||
msgstr "游戏模式UDP中继服务器"
|
||||
|
||||
msgid "Game Mode UDP Relay"
|
||||
msgstr "游戏模式UDP中继"
|
||||
|
||||
msgid "Server failsafe auto swith settings"
|
||||
msgstr "服务器节点故障自动切换设置"
|
||||
|
||||
msgid "Delete all severs"
|
||||
msgstr "删除所有服务器"
|
||||
|
||||
msgid "Severs Nodes"
|
||||
msgstr "服务器节点"
|
||||
|
||||
msgid "Use Local DNS Service listen port 5335"
|
||||
msgstr "使用本机端口为5335的DNS服务"
|
||||
|
||||
msgid "Server Node Type"
|
||||
msgstr "服务器节点类型"
|
||||
|
||||
msgid "Using incorrect encryption mothod may causes service fail to start"
|
||||
msgstr "输入不正确的参数组合可能会导致服务无法启动"
|
||||
|
||||
msgid "Game Mode Host List"
|
||||
msgstr "增强游戏模式客户端LAN IP"
|
||||
|
||||
msgid "Multi Threads Option"
|
||||
msgstr "多线程并发转发"
|
||||
|
||||
msgid "Auto Threads"
|
||||
msgstr "自动(CPU线程数)"
|
||||
|
||||
msgid "1 Thread"
|
||||
msgstr "单线程"
|
||||
|
||||
msgid "2 Threads"
|
||||
msgstr "2 线程"
|
||||
|
||||
msgid "4 Threads"
|
||||
msgstr "4 线程"
|
||||
|
||||
msgid "8 Threads"
|
||||
msgstr "8 线程"
|
||||
|
||||
msgid "16 Threads"
|
||||
msgstr "16 线程"
|
||||
|
||||
msgid "32 Threads"
|
||||
msgstr "32 线程"
|
||||
|
||||
msgid "64 Threads"
|
||||
msgstr "64 线程"
|
||||
|
||||
msgid "128 Threads"
|
||||
msgstr "128 线程"
|
||||
|
||||
msgid "256 Threads"
|
||||
msgstr "256 线程"
|
||||
|
||||
msgid "512 Threads"
|
||||
msgstr "512 线程"
|
||||
|
||||
|
||||
msgid "Proxy Ports"
|
||||
msgstr "需要代理的端口"
|
||||
|
||||
msgid "All Ports"
|
||||
msgstr "所有端口(默认)"
|
||||
|
||||
msgid "Only Common Ports"
|
||||
msgstr "仅常用端口(不走P2P流量到代理)"
|
||||
|
||||
|
||||
msgid "Use dnscrypt-proxy query and cache"
|
||||
msgstr "使用dnscrypt-proxy TCP查询并缓存"
|
||||
|
||||
msgid "Use dnsforwarder tcp query and cache"
|
||||
msgstr "使用dnsforwarder TCP查询并缓存"
|
||||
|
||||
msgid "Use Pdnsd udp query and cache"
|
||||
msgstr "使用Pdnsd UDP查询并缓存"
|
||||
|
||||
|
||||
msgid "Use dnsforwarder udp query and cache"
|
||||
msgstr "使用dnsforwarder UDP查询并缓存"
|
||||
|
||||
msgid "Use chinadns query and cache"
|
||||
msgstr "使用ChinaDNS查询并缓存"
|
||||
|
||||
msgid "Chiadns Resolve Dns Mode"
|
||||
msgstr "ChinaDNS的上游服务器"
|
||||
|
||||
|
||||
msgid "Use Local DNS Service"
|
||||
msgstr "使用设定DNS解析"
|
||||
|
||||
msgid "Oversea GFW List Mode"
|
||||
msgstr "海外用户回国域名列表模式"
|
||||
|
||||
msgid "Oversea IP Route Mode"
|
||||
msgstr "海外用户回国IP路由模式"
|
||||
|
||||
msgid "Use Local DNS Service"
|
||||
msgstr "使用设定DNS解析"
|
||||
|
||||
msgid "Using System Default DNS"
|
||||
msgstr "使用系统默认DNS"
|
||||
|
||||
msgid "Using acceleration center DNS"
|
||||
msgstr "使用加速中心DNS"
|
||||
|
||||
msgid "Appoint dns List"
|
||||
msgstr "指定DNS解析列表"
|
||||
|
||||
msgid "Use https_dns_proxy query and cache"
|
||||
msgstr "使用https_dns_proxy TCP查询并缓存"
|
||||
|
||||
msgid "Use smartdns query and cache"
|
||||
msgstr "使用SmartDNS TCP查询并缓存"
|
||||
|
||||
msgid "Use Pcap_DNSProxy query and cache"
|
||||
msgstr "使用Pcap DNSProxy TCP查询并缓存"
|
||||
|
||||
msgid "Kill BT"
|
||||
msgstr "禁止 BT"
|
||||
|
||||
msgid "BT Port"
|
||||
msgstr "BT 端口"
|
||||
|
||||
msgid "Enabling IPv6 server"
|
||||
msgstr "启用ipv6服务"
|
||||
|
||||
msgid "Prohibit downloading tool ports through proxy"
|
||||
msgstr "禁止BT端口走代理"
|
||||
|
||||
|
||||
msgid "udp2raw Version"
|
||||
msgstr "udp2raw 版本"
|
||||
|
||||
msgid "udp2raw tunnel Project"
|
||||
msgstr "udp2raw 项目"
|
||||
|
||||
|
||||
msgid "UDPspeeder Version"
|
||||
msgstr "UDPspeeder 版本"
|
||||
|
||||
|
||||
msgid "UDPspeeder Project"
|
||||
msgstr "UDPspeeder 项目"
|
||||
|
||||
msgid "Appointlist List"
|
||||
msgstr "DNS列表"
|
||||
|
||||
msgid "udp2raw tunnel"
|
||||
msgstr "UDP隧道"
|
||||
|
||||
msgid "Enable udp2raw"
|
||||
msgstr "启用 udp2raw"
|
||||
|
||||
msgid "Enable UDPspeeder"
|
||||
msgstr "启用 UDPspeeder"
|
||||
|
||||
msgid "SOCKS5 Proxy"
|
||||
msgstr "SOCKS5代理"
|
||||
|
||||
msgid "SSOCKS5 Proxy"
|
||||
msgstr "SS SOCKS5代理"
|
||||
|
||||
msgid "Global SS Server"
|
||||
msgstr "SS服务端"
|
||||
|
||||
|
||||
msgid "V2SOCKS5 Proxy"
|
||||
msgstr "V2ray SOCKS5代理"
|
||||
|
||||
msgid "Global V2RAY Server"
|
||||
msgstr "V2RAY服务端"
|
||||
|
||||
msgid "haProxy settings"
|
||||
msgstr "HaProxy 设置"
|
||||
|
||||
|
||||
msgid "Enabling the Management Console"
|
||||
msgstr "启用管理控制台"
|
||||
|
||||
msgid "Service Port"
|
||||
msgstr "端口"
|
||||
|
||||
msgid "Socket Connected"
|
||||
msgstr "连接测试"
|
||||
|
||||
|
||||
msgid "Enable HTTP Proxy"
|
||||
msgstr "启用HTTP代理"
|
||||
|
||||
msgid "HTTP Port"
|
||||
msgstr "HTTP代理端口"
|
||||
|
||||
msgid "plugin"
|
||||
msgstr "插件"
|
||||
|
||||
msgid "Plugin Opts"
|
||||
msgstr "插件参数"
|
||||
|
||||
msgid "Before subscribing please click below to delete all servers in the subscription"
|
||||
msgstr "订阅前请点击下面的删除所有服务器在订阅"
|
||||
|
||||
msgid "Chnroute Setting"
|
||||
msgstr "国内IP段数据库更新设置"
|
||||
|
||||
msgid "Enable custom chnroute"
|
||||
msgstr "启用自定义更新地址"
|
||||
|
||||
msgid "Update url"
|
||||
msgstr "更新链接"
|
||||
|
||||
msgid "HTTP Proxy"
|
||||
msgstr "HTTP代理"
|
||||
|
||||
msgid "Raw Mode"
|
||||
msgstr "模式"
|
||||
|
||||
msgid "Seq Mode"
|
||||
msgstr "Seq模式"
|
||||
|
||||
msgid "Cipher Mode"
|
||||
msgstr "加密模式"
|
||||
|
||||
msgid "Auth Mode"
|
||||
msgstr "校验模式"
|
||||
|
||||
msgid "Speeder Mode"
|
||||
msgstr "Speeder模式"
|
||||
|
||||
msgid "Fec"
|
||||
msgstr "fec参数"
|
||||
|
||||
msgid "Mtu"
|
||||
msgstr "mtu参数"
|
||||
|
||||
msgid "SS Servers"
|
||||
msgstr "SS服务器"
|
||||
|
||||
|
||||
msgid "SSR Servers"
|
||||
msgstr "SSR服务器"
|
||||
|
||||
msgid "SSR Server"
|
||||
msgstr "服务端"
|
||||
|
||||
msgid "V2 Servers"
|
||||
msgstr "V2服务器"
|
||||
|
||||
msgid "SS/SSR/V2RAY Server"
|
||||
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 "文件查看器"
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,58 +0,0 @@
|
||||
1dot1dot1dot1.cloudflare-dns.com
|
||||
91smartyun.pt
|
||||
adobe.com
|
||||
amazonaws.com
|
||||
ampproject.org
|
||||
apple.news
|
||||
aws.amazon.com
|
||||
azureedge.net
|
||||
backpackers.com.tw
|
||||
bitfinex.com
|
||||
buzzfeed.com
|
||||
clockwise.ee
|
||||
cloudflare-dns.com
|
||||
cloudfront.net
|
||||
coindesk.com
|
||||
coinsquare.io
|
||||
cryptocompare.com
|
||||
dns.google
|
||||
dns9.quad9.net
|
||||
doh.opendns.com
|
||||
dropboxstatic.com
|
||||
eurecom.fr
|
||||
gdax.com
|
||||
github.com
|
||||
kknews.cc
|
||||
nutaq.com
|
||||
openairinterface.org
|
||||
skype.com
|
||||
sublimetext.com
|
||||
textnow.com
|
||||
textnow.me
|
||||
trouter.io
|
||||
uploaded.net
|
||||
whatsapp.com
|
||||
whatsapp.net
|
||||
wsj.net
|
||||
google.com
|
||||
google.com.hk
|
||||
gstatic.com
|
||||
googleusercontent.com
|
||||
googlepages.com
|
||||
googlevideo.com
|
||||
googlecode.com
|
||||
googleapis.com
|
||||
googlesource.com
|
||||
googledrive.com
|
||||
ggpht.com
|
||||
youtube.com
|
||||
youtu.be
|
||||
ytimg.com
|
||||
twitter.com
|
||||
facebook.com
|
||||
fastly.net
|
||||
akamai.net
|
||||
akamaiedge.net
|
||||
akamaihd.net
|
||||
edgesuite.net
|
||||
edgekey.net
|
||||
@ -1,54 +0,0 @@
|
||||
91smartyun.pt
|
||||
adobe.com
|
||||
amazonaws.com
|
||||
ampproject.org
|
||||
apple.news
|
||||
aws.amazon.com
|
||||
azureedge.net
|
||||
backpackers.com.tw
|
||||
bitfinex.com
|
||||
buzzfeed.com
|
||||
clockwise.ee
|
||||
cloudfront.net
|
||||
coindesk.com
|
||||
coinsquare.io
|
||||
cryptocompare.com
|
||||
dropboxstatic.com
|
||||
eurecom.fr
|
||||
gdax.com
|
||||
github.com
|
||||
kknews.cc
|
||||
nutaq.com
|
||||
openairinterface.org
|
||||
skype.com
|
||||
sublimetext.com
|
||||
textnow.com
|
||||
textnow.me
|
||||
trouter.io
|
||||
uploaded.net
|
||||
whatsapp.com
|
||||
whatsapp.net
|
||||
wsj.net
|
||||
google.com
|
||||
google.com.hk
|
||||
gstatic.com
|
||||
googleusercontent.com
|
||||
googlepages.com
|
||||
googlevideo.com
|
||||
googlecode.com
|
||||
googleapis.com
|
||||
googlesource.com
|
||||
googledrive.com
|
||||
ggpht.com
|
||||
youtube.com
|
||||
youtu.be
|
||||
ytimg.com
|
||||
twitter.com
|
||||
facebook.com
|
||||
fastly.net
|
||||
akamai.net
|
||||
akamaiedge.net
|
||||
akamaihd.net
|
||||
edgesuite.net
|
||||
edgekey.net
|
||||
|
||||
@ -1 +0,0 @@
|
||||
0xDEADBEEF
|
||||
@ -1,120 +0,0 @@
|
||||
|
||||
|
||||
config server_config
|
||||
option type 'ss'
|
||||
option ipv4_ipv6 '0'
|
||||
option server_port '8387'
|
||||
option timeout '60'
|
||||
option password 'admin'
|
||||
option encrypt_method 'aes-256-ctr'
|
||||
option enable '0'
|
||||
|
||||
config server_config
|
||||
option type 'ssr'
|
||||
option ipv4_ipv6 '0'
|
||||
option server_port '8388'
|
||||
option timeout '60'
|
||||
option password '222'
|
||||
option protocol 'origin'
|
||||
option obfs 'plain'
|
||||
option encrypt_method 'aes-192-cfb'
|
||||
option enable '0'
|
||||
|
||||
config server_config
|
||||
option type 'v2ray'
|
||||
option ipv4_ipv6 '0'
|
||||
option server_port '8389'
|
||||
option timeout '60'
|
||||
option alter_id '100'
|
||||
option VMess_level '1'
|
||||
option vmess_id '576f451f-0d21-44ed-aeaf-9b27a24d7bc9'
|
||||
option security 'auto'
|
||||
option transport 'tcp'
|
||||
option tcp_guise 'none'
|
||||
option tls '1'
|
||||
option enable '0'
|
||||
|
||||
config global
|
||||
option tunnel_address '0.0.0.0'
|
||||
option monitor_enable '1'
|
||||
option enable_switch '1'
|
||||
option switch_timeout '5'
|
||||
option switch_time '667'
|
||||
option threads '0'
|
||||
option bt '0'
|
||||
option global_server 'nil'
|
||||
option run_mode 'router'
|
||||
option pdnsd_enable '1'
|
||||
option tunnel_forward '8.8.4.4:53'
|
||||
|
||||
config socks5_proxy
|
||||
option local_port '1080'
|
||||
option local_address '0.0.0.0'
|
||||
option http_port '1081'
|
||||
option bt '0'
|
||||
option server 'nil'
|
||||
option http_enable '0'
|
||||
|
||||
config global_haproxy
|
||||
option admin_enable '1'
|
||||
option admin_port '1111'
|
||||
option admin_user 'admin'
|
||||
option admin_password 'root'
|
||||
option balancing_enable '0'
|
||||
|
||||
config access_control
|
||||
option wan_bp_list '/etc/china_ssr.txt'
|
||||
option lan_ac_mode 'b'
|
||||
option router_proxy '1'
|
||||
list wan_fw_ips '149.154.160.0/20'
|
||||
list wan_fw_ips '67.198.55.0/24'
|
||||
list wan_fw_ips '91.108.4.0/22'
|
||||
list wan_fw_ips '91.108.56.0/22'
|
||||
list wan_fw_ips '109.239.140.0/24'
|
||||
list wan_fw_ips '1.1.1.1/32'
|
||||
list wan_fw_ips '1.0.0.1/32'
|
||||
list wan_fw_ips '8.8.8.8/32'
|
||||
list wan_fw_ips '8.8.4.4/32'
|
||||
list wan_fw_ips '9.9.9.9/32'
|
||||
list wan_fw_ips '146.112.41.2/32'
|
||||
|
||||
config server_global
|
||||
option enable_server '0'
|
||||
|
||||
config server_subscribe
|
||||
option proxy '0'
|
||||
option auto_update_time '2'
|
||||
option auto_update '0'
|
||||
option v2ray_update '0'
|
||||
option edition '4.20.0'
|
||||
|
||||
config domain_white_list
|
||||
option domain_names 'youdao.com'
|
||||
|
||||
config domain_white_list
|
||||
option domain_names 'gov.cn'
|
||||
|
||||
config udp2raw
|
||||
option server '127.0.0.1'
|
||||
option local_port '400'
|
||||
option key 'passwd'
|
||||
option seq_mode '3'
|
||||
option auth_mode 'simple'
|
||||
option bt '0'
|
||||
option udp2raw_enable '1'
|
||||
option raw_mode 'udp'
|
||||
option cipher_mode 'aes128cbc'
|
||||
option server_port '600'
|
||||
|
||||
config udpspeeder
|
||||
option server '127.0.0.1'
|
||||
option server_port '400'
|
||||
option local_port '500'
|
||||
option key 'passwd'
|
||||
option speeder_mode '0'
|
||||
option fec '2:4'
|
||||
option mtu '1250'
|
||||
option queue_len '1'
|
||||
option timeout '8'
|
||||
option udpspeeder_enable '1'
|
||||
|
||||
@ -1,2 +0,0 @@
|
||||
apple.com
|
||||
microsoft.com
|
||||
@ -1,3 +0,0 @@
|
||||
server=/.3g.music.qq.com/127.0.0.1#5335
|
||||
ipset=/3g.music.qq.com/oversea
|
||||
|
||||
@ -1,192 +0,0 @@
|
||||
server=/v.youku.com/127.0.0.1#5335
|
||||
server=/api.youku.com/127.0.0.1#5335
|
||||
server=/v2.tudou.com/127.0.0.1#5335
|
||||
server=/www.tudou.com/127.0.0.1#5335
|
||||
server=/s.plcloud.music.qq.com/127.0.0.1#5335
|
||||
server=/i.y.qq.com/127.0.0.1#5335
|
||||
server=/hot.vrs.sohu.com/127.0.0.1#5335
|
||||
server=/live.tv.sohu.com/127.0.0.1#5335
|
||||
server=/pad.tv.sohu.com/127.0.0.1#5335
|
||||
server=/my.tv.sohu.com/127.0.0.1#5335
|
||||
server=/hot.vrs.letv.com/127.0.0.1#5335
|
||||
server=/data.video.qiyi.com/127.0.0.1#5335
|
||||
server=/cache.video.qiyi.com/127.0.0.1#5335
|
||||
server=/cache.vip.qiyi.com/127.0.0.1#5335
|
||||
server=/vv.video.qq.com/127.0.0.1#5335
|
||||
server=/tt.video.qq.com/127.0.0.1#5335
|
||||
server=/ice.video.qq.com/127.0.0.1#5335
|
||||
server=/tjsa.video.qq.com/127.0.0.1#5335
|
||||
server=/a10.video.qq.com/127.0.0.1#5335
|
||||
server=/xyy.video.qq.com/127.0.0.1#5335
|
||||
server=/vcq.video.qq.com/127.0.0.1#5335
|
||||
server=/vsh.video.qq.com/127.0.0.1#5335
|
||||
server=/vbj.video.qq.com/127.0.0.1#5335
|
||||
server=/bobo.video.qq.com/127.0.0.1#5335
|
||||
server=/flvs.video.qq.com/127.0.0.1#5335
|
||||
server=/bkvv.video.qq.com/127.0.0.1#5335
|
||||
server=/info.zb.qq.com/127.0.0.1#5335
|
||||
server=/geo.js.kankan.xunlei.com/127.0.0.1#5335
|
||||
server=/web-play.pptv.com/127.0.0.1#5335
|
||||
server=/web-play.pplive.cn/127.0.0.1#5335
|
||||
server=/dyn.ugc.pps.tv/127.0.0.1#5335
|
||||
server=/v.pps.tv/127.0.0.1#5335
|
||||
server=/inner.kandian.com/127.0.0.1#5335
|
||||
server=/ipservice.163.com/127.0.0.1#5335
|
||||
server=/so.open.163.com/127.0.0.1#5335
|
||||
server=/zb.s.qq.com/127.0.0.1#5335
|
||||
server=/ip.kankan.xunlei.com/127.0.0.1#5335
|
||||
server=/vxml.56.com/127.0.0.1#5335
|
||||
server=/music.sina.com.cn/127.0.0.1#5335
|
||||
server=/play.baidu.com/127.0.0.1#5335
|
||||
server=/v.iask.com/127.0.0.1#5335
|
||||
server=/tv.weibo.com/127.0.0.1#5335
|
||||
server=/wtv.v.iask.com/127.0.0.1#5335
|
||||
server=/video.sina.com.cn/127.0.0.1#5335
|
||||
server=/www.yinyuetai.com/127.0.0.1#5335
|
||||
server=/api.letv.com/127.0.0.1#5335
|
||||
server=/live.gslb.letv.com/127.0.0.1#5335
|
||||
server=/static.itv.letv.com/127.0.0.1#5335
|
||||
server=/ip.apps.cntv.cn/127.0.0.1#5335
|
||||
server=/vdn.apps.cntv.cn/127.0.0.1#5335
|
||||
server=/vdn.live.cntv.cn/127.0.0.1#5335
|
||||
server=/vip.sports.cntv.cn/127.0.0.1#5335
|
||||
server=/a.play.api.3g.youku.com/127.0.0.1#5335
|
||||
server=/i.play.api.3g.youku.com/127.0.0.1#5335
|
||||
server=/api.3g.youku.com/127.0.0.1#5335
|
||||
server=/tv.api.3g.youku.com/127.0.0.1#5335
|
||||
server=/play.api.3g.youku.com/127.0.0.1#5335
|
||||
server=/play.api.3g.tudou.com/127.0.0.1#5335
|
||||
server=/tv.api.3g.tudou.com/127.0.0.1#5335
|
||||
server=/api.3g.tudou.com/127.0.0.1#5335
|
||||
server=/api.tv.sohu.com/127.0.0.1#5335
|
||||
server=/access.tv.sohu.com/127.0.0.1#5335
|
||||
server=/iface.iqiyi.com/127.0.0.1#5335
|
||||
server=/iface2.iqiyi.com/127.0.0.1#5335
|
||||
server=/cache.m.iqiyi.com/127.0.0.1#5335
|
||||
server=/dynamic.app.m.letv.com/127.0.0.1#5335
|
||||
server=/dynamic.meizi.app.m.letv.com/127.0.0.1#5335
|
||||
server=/dynamic.search.app.m.letv.com/127.0.0.1#5335
|
||||
server=/dynamic.live.app.m.letv.com/127.0.0.1#5335
|
||||
server=/listso.m.areainfo.ppstream.com/127.0.0.1#5335
|
||||
server=/epg.api.pptv.com/127.0.0.1#5335
|
||||
server=/play.api.pptv.com/127.0.0.1#5335
|
||||
server=/m.letv.com/127.0.0.1#5335
|
||||
server=/interface.bilibili.com/127.0.0.1#5335
|
||||
server=/3g.music.qq.com/127.0.0.1#5335
|
||||
server=/mqqplayer.3g.qq.com/127.0.0.1#5335
|
||||
server=/proxy.music.qq.com/127.0.0.1#5335
|
||||
server=/proxymc.qq.com/127.0.0.1#5335
|
||||
server=/ip2.kugou.com/127.0.0.1#5335
|
||||
server=/ip.kugou.com/127.0.0.1#5335
|
||||
server=/client.api.ttpod.com/127.0.0.1#5335
|
||||
server=/mobi.kuwo.cn/127.0.0.1#5335
|
||||
server=/mobilefeedback.kugou.com/127.0.0.1#5335
|
||||
server=/tingapi.ting.baidu.com/127.0.0.1#5335
|
||||
server=/music.baidu.com/127.0.0.1#5335
|
||||
server=/serviceinfo.sdk.duomi.com/127.0.0.1#5335
|
||||
server=/music.163.com/127.0.0.1#5335
|
||||
server=/www.xiami.com/127.0.0.1#5335
|
||||
server=/spark.api.xiami.com/127.0.0.1#5335
|
||||
server=/iplocation.geo.qiyi.com/127.0.0.1#5335
|
||||
server=/sns.video.qq.com/127.0.0.1#5335
|
||||
server=/v5.pc.duomi.com/127.0.0.1#5335
|
||||
server=/tms.is.ysten.com/127.0.0.1#5335
|
||||
server=/internal.check.duokanbox.com/127.0.0.1#5335
|
||||
server=/openapi.youku.com/127.0.0.1#5335
|
||||
server=/y.qq.com/127.0.0.1#5335
|
||||
ipset=/v.youku.com/oversea
|
||||
ipset=/api.youku.com/oversea
|
||||
ipset=/v2.tudou.com/oversea
|
||||
ipset=/www.tudou.com/oversea
|
||||
ipset=/s.plcloud.music.qq.com/oversea
|
||||
ipset=/i.y.qq.com/oversea
|
||||
ipset=/hot.vrs.sohu.com/oversea
|
||||
ipset=/live.tv.sohu.com/oversea
|
||||
ipset=/pad.tv.sohu.com/oversea
|
||||
ipset=/my.tv.sohu.com/oversea
|
||||
ipset=/hot.vrs.letv.com/oversea
|
||||
ipset=/data.video.qiyi.com/oversea
|
||||
ipset=/cache.video.qiyi.com/oversea
|
||||
ipset=/cache.vip.qiyi.com/oversea
|
||||
ipset=/vv.video.qq.com/oversea
|
||||
ipset=/tt.video.qq.com/oversea
|
||||
ipset=/ice.video.qq.com/oversea
|
||||
ipset=/tjsa.video.qq.com/oversea
|
||||
ipset=/a10.video.qq.com/oversea
|
||||
ipset=/xyy.video.qq.com/oversea
|
||||
ipset=/vcq.video.qq.com/oversea
|
||||
ipset=/vsh.video.qq.com/oversea
|
||||
ipset=/vbj.video.qq.com/oversea
|
||||
ipset=/bobo.video.qq.com/oversea
|
||||
ipset=/flvs.video.qq.com/oversea
|
||||
ipset=/bkvv.video.qq.com/oversea
|
||||
ipset=/info.zb.qq.com/oversea
|
||||
ipset=/geo.js.kankan.xunlei.com/oversea
|
||||
ipset=/web-play.pptv.com/oversea
|
||||
ipset=/web-play.pplive.cn/oversea
|
||||
ipset=/dyn.ugc.pps.tv/oversea
|
||||
ipset=/v.pps.tv/oversea
|
||||
ipset=/inner.kandian.com/oversea
|
||||
ipset=/ipservice.163.com/oversea
|
||||
ipset=/so.open.163.com/oversea
|
||||
ipset=/zb.s.qq.com/oversea
|
||||
ipset=/ip.kankan.xunlei.com/oversea
|
||||
ipset=/vxml.56.com/oversea
|
||||
ipset=/music.sina.com.cn/oversea
|
||||
ipset=/play.baidu.com/oversea
|
||||
ipset=/v.iask.com/oversea
|
||||
ipset=/tv.weibo.com/oversea
|
||||
ipset=/wtv.v.iask.com/oversea
|
||||
ipset=/video.sina.com.cn/oversea
|
||||
ipset=/www.yinyuetai.com/oversea
|
||||
ipset=/api.letv.com/oversea
|
||||
ipset=/live.gslb.letv.com/oversea
|
||||
ipset=/static.itv.letv.com/oversea
|
||||
ipset=/ip.apps.cntv.cn/oversea
|
||||
ipset=/vdn.apps.cntv.cn/oversea
|
||||
ipset=/vdn.live.cntv.cn/oversea
|
||||
ipset=/vip.sports.cntv.cn/oversea
|
||||
ipset=/a.play.api.3g.youku.com/oversea
|
||||
ipset=/i.play.api.3g.youku.com/oversea
|
||||
ipset=/api.3g.youku.com/oversea
|
||||
ipset=/tv.api.3g.youku.com/oversea
|
||||
ipset=/play.api.3g.youku.com/oversea
|
||||
ipset=/play.api.3g.tudou.com/oversea
|
||||
ipset=/tv.api.3g.tudou.com/oversea
|
||||
ipset=/api.3g.tudou.com/oversea
|
||||
ipset=/api.tv.sohu.com/oversea
|
||||
ipset=/access.tv.sohu.com/oversea
|
||||
ipset=/iface.iqiyi.com/oversea
|
||||
ipset=/iface2.iqiyi.com/oversea
|
||||
ipset=/cache.m.iqiyi.com/oversea
|
||||
ipset=/dynamic.app.m.letv.com/oversea
|
||||
ipset=/dynamic.meizi.app.m.letv.com/oversea
|
||||
ipset=/dynamic.search.app.m.letv.com/oversea
|
||||
ipset=/dynamic.live.app.m.letv.com/oversea
|
||||
ipset=/listso.m.areainfo.ppstream.com/oversea
|
||||
ipset=/epg.api.pptv.com/oversea
|
||||
ipset=/play.api.pptv.com/oversea
|
||||
ipset=/m.letv.com/oversea
|
||||
ipset=/interface.bilibili.com/oversea
|
||||
ipset=/3g.music.qq.com/oversea
|
||||
ipset=/mqqplayer.3g.qq.com/oversea
|
||||
ipset=/proxy.music.qq.com/oversea
|
||||
ipset=/proxymc.qq.com/oversea
|
||||
ipset=/ip2.kugou.com/oversea
|
||||
ipset=/ip.kugou.com/oversea
|
||||
ipset=/client.api.ttpod.com/oversea
|
||||
ipset=/mobi.kuwo.cn/oversea
|
||||
ipset=/mobilefeedback.kugou.com/oversea
|
||||
ipset=/tingapi.ting.baidu.com/oversea
|
||||
ipset=/music.baidu.com/oversea
|
||||
ipset=/serviceinfo.sdk.duomi.com/oversea
|
||||
ipset=/music.163.com/oversea
|
||||
ipset=/www.xiami.com/oversea
|
||||
ipset=/spark.api.xiami.com/oversea
|
||||
ipset=/iplocation.geo.qiyi.com/oversea
|
||||
ipset=/sns.video.qq.com/oversea
|
||||
ipset=/v5.pc.duomi.com/oversea
|
||||
ipset=/tms.is.ysten.com/oversea
|
||||
ipset=/internal.check.duokanbox.com/oversea
|
||||
ipset=/openapi.youku.com/oversea
|
||||
ipset=/y.qq.com/oversea
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,143 +0,0 @@
|
||||
server=/.1test.cn/119.29.29.29#53
|
||||
server=/.360wzb.cn/119.29.29.29#53
|
||||
server=/.51cdn.com/119.29.29.29#53
|
||||
server=/.5test.cn/119.29.29.29#53
|
||||
server=/.aicdn.com/119.29.29.29#53
|
||||
server=/.alikunlun.com/119.29.29.29#53
|
||||
server=/.alikunlun.net/119.29.29.29#53
|
||||
server=/.b2r.com.cn/119.29.29.29#53
|
||||
server=/.baiduyundns.cn/119.29.29.29#53
|
||||
server=/.baiduyundns.com/119.29.29.29#53
|
||||
server=/.baiduyundns.net/119.29.29.29#53
|
||||
server=/.bcedns.cn/119.29.29.29#53
|
||||
server=/.bcedns.com/119.29.29.29#53
|
||||
server=/.bcedns.net/119.29.29.29#53
|
||||
server=/.bdydns.cn/119.29.29.29#53
|
||||
server=/.bdydns.com/119.29.29.29#53
|
||||
server=/.bdydns.net/119.29.29.29#53
|
||||
server=/.blueit.com/119.29.29.29#53
|
||||
server=/.blueit.org.cn/119.29.29.29#53
|
||||
server=/.cachecn.com/119.29.29.29#53
|
||||
server=/.cachecn.net/119.29.29.29#53
|
||||
server=/.cc-1.com/119.29.29.29#53
|
||||
server=/.cc-cps.cn/119.29.29.29#53
|
||||
server=/.cc-cps.com.cn/119.29.29.29#53
|
||||
server=/.cc-cps.com/119.29.29.29#53
|
||||
server=/.cc-cps.mobi/119.29.29.29#53
|
||||
server=/.cc-cps.net/119.29.29.29#53
|
||||
server=/.ccbench.com/119.29.29.29#53
|
||||
server=/.ccgslb.cn/119.29.29.29#53
|
||||
server=/.ccgslb.com.cn/119.29.29.29#53
|
||||
server=/.ccgslb.com/119.29.29.29#53
|
||||
server=/.ccgslb.net.cn/119.29.29.29#53
|
||||
server=/.ccgslb.net/119.29.29.29#53
|
||||
server=/.ccindex.cn/119.29.29.29#53
|
||||
server=/.ccindex.com.cn/119.29.29.29#53
|
||||
server=/.ccmplus.cn/119.29.29.29#53
|
||||
server=/.ccmplus.com.cn/119.29.29.29#53
|
||||
server=/.ccmplus.net/119.29.29.29#53
|
||||
server=/.cdn2cdn.net/119.29.29.29#53
|
||||
server=/.cdnetworks.net/119.29.29.29#53
|
||||
server=/.cdngc.net/119.29.29.29#53
|
||||
server=/.cdnsvc.cn/119.29.29.29#53
|
||||
server=/.cdnsvc.com.cn/119.29.29.29#53
|
||||
server=/.cdnsvc.com/119.29.29.29#53
|
||||
server=/.cdnsvc.net.cn/119.29.29.29#53
|
||||
server=/.cdnsvc.net/119.29.29.29#53
|
||||
server=/.cdntip.com/119.29.29.29#53
|
||||
server=/.cdnudns.com/119.29.29.29#53
|
||||
server=/.chinacache.com.cn/119.29.29.29#53
|
||||
server=/.chinacache.com/119.29.29.29#53
|
||||
server=/.chinacache.net/119.29.29.29#53
|
||||
server=/.chinacache.org/119.29.29.29#53
|
||||
server=/.chinanetcenter.com/119.29.29.29#53
|
||||
server=/.cloudcdn.cn/119.29.29.29#53
|
||||
server=/.cloudcdn.net/119.29.29.29#53
|
||||
server=/.clouddn.com/119.29.29.29#53
|
||||
server=/.cloudglb.com/119.29.29.29#53
|
||||
server=/.cloudglb.net/119.29.29.29#53
|
||||
server=/.cloudtcp.net/119.29.29.29#53
|
||||
server=/.cloudxns.com/119.29.29.29#53
|
||||
server=/.cloudxns.net/119.29.29.29#53
|
||||
server=/.dnspao.com/119.29.29.29#53
|
||||
server=/.fastcdn.com /119.29.29.29#53
|
||||
server=/.fastweb.com.cn/119.29.29.29#53
|
||||
server=/.fastwebcdn.com/119.29.29.29#53
|
||||
server=/.ffdns.net/119.29.29.29#53
|
||||
server=/.fsspace.cn/119.29.29.29#53
|
||||
server=/.fsspace.com.cn/119.29.29.29#53
|
||||
server=/.fsspace.com/119.29.29.29#53
|
||||
server=/.fwcdn.com/119.29.29.29#53
|
||||
server=/.fwcdn.net/119.29.29.29#53
|
||||
server=/.fwdns.net/119.29.29.29#53
|
||||
server=/.fwmob.com/119.29.29.29#53
|
||||
server=/.gccdn.net/119.29.29.29#53
|
||||
server=/.gslbsvc.cn/119.29.29.29#53
|
||||
server=/.gslbsvc.com.cn/119.29.29.29#53
|
||||
server=/.gslbsvc.com/119.29.29.29#53
|
||||
server=/.gslbsvc.net.cn/119.29.29.29#53
|
||||
server=/.gslbsvc.net/119.29.29.29#53
|
||||
server=/.hacdn.com/119.29.29.29#53
|
||||
server=/.hacdn.net/119.29.29.29#53
|
||||
server=/.hadns.net/119.29.29.29#53
|
||||
server=/.hdslb.com/119.29.29.29#53
|
||||
server=/.hdslb.net/119.29.29.29#53
|
||||
server=/.hd-cdn.com/119.29.29.29#53
|
||||
server=/.igslb.net/119.29.29.29#53
|
||||
server=/.kunlunaq.com/119.29.29.29#53
|
||||
server=/.kunlunar.com/119.29.29.29#53
|
||||
server=/.kunlunca.com/119.29.29.29#53
|
||||
server=/.kunluncan.com/119.29.29.29#53
|
||||
server=/.kunlunea.com/119.29.29.29#53
|
||||
server=/.kunlungem.com/119.29.29.29#53
|
||||
server=/.kunlungr.com/119.29.29.29#53
|
||||
server=/.kunlunhuf.com/119.29.29.29#53
|
||||
server=/.kunlunle.com/119.29.29.29#53
|
||||
server=/.kunlunli.com/119.29.29.29#53
|
||||
server=/.kunlunno.com/119.29.29.29#53
|
||||
server=/.kunlunpi.com/119.29.29.29#53
|
||||
server=/.kunlunra.com/119.29.29.29#53
|
||||
server=/.kunlunsa.com/119.29.29.29#53
|
||||
server=/.kunlunsc.com/119.29.29.29#53
|
||||
server=/.kunlunsl.com/119.29.29.29#53
|
||||
server=/.kunlunso.com/119.29.29.29#53
|
||||
server=/.kunlunta.com/119.29.29.29#53
|
||||
server=/.kunlunvi.com/119.29.29.29#53
|
||||
server=/.kunlunwe.com/119.29.29.29#53
|
||||
server=/.lxdns.com/119.29.29.29#53
|
||||
server=/.lxdns.net/119.29.29.29#53
|
||||
server=/.lxsvc.cn /119.29.29.29#53
|
||||
server=/.lxsvc.cn/119.29.29.29#53
|
||||
server=/.lxsvc.net/119.29.29.29#53
|
||||
server=/.myqcloud.com/119.29.29.29#53
|
||||
server=/.myxns.cn/119.29.29.29#53
|
||||
server=/.myxns.com.cn/119.29.29.29#53
|
||||
server=/.myxns.net.cn/119.29.29.29#53
|
||||
server=/.myxns.org/119.29.29.29#53
|
||||
server=/.netcenter.com.cn/119.29.29.29#53
|
||||
server=/.newdefend.cn/119.29.29.29#53
|
||||
server=/.newdefend.com.cn/119.29.29.29#53
|
||||
server=/.newdefend.com/119.29.29.29#53
|
||||
server=/.newdefend.net.cn/119.29.29.29#53
|
||||
server=/.newdefend.net/119.29.29.29#53
|
||||
server=/.newdefend.org.cn/119.29.29.29#53
|
||||
server=/.newdefend.org/119.29.29.29#53
|
||||
server=/.ourglb0.com/119.29.29.29#53
|
||||
server=/.ourwebat.com/119.29.29.29#53
|
||||
server=/.ourwebcdn.com/119.29.29.29#53
|
||||
server=/.qbox.me/119.29.29.29#53
|
||||
server=/.qcloud.com/119.29.29.29#53
|
||||
server=/.qingcdn.com/119.29.29.29#53
|
||||
server=/.qiniudn.com/119.29.29.29#53
|
||||
server=/.qiniudns.com/119.29.29.29#53
|
||||
server=/.speedupchina.com/119.29.29.29#53
|
||||
server=/.speedupchina.net/119.29.29.29#53
|
||||
server=/.sz-dns.net/119.29.29.29#53
|
||||
server=/.tcdn.qq.com/119.29.29.29#53
|
||||
server=/.tlgslb.com /119.29.29.29#53
|
||||
server=/.wangsu.com/119.29.29.29#53
|
||||
server=/.webluker.com/119.29.29.29#53
|
||||
server=/.wscdns.com/119.29.29.29#53
|
||||
server=/.wsngb.com/119.29.29.29#53
|
||||
server=/.xgslb.net/119.29.29.29#53
|
||||
server=/.yunjiasu-cdn.net/119.29.29.29#53
|
||||
@ -1,106 +0,0 @@
|
||||
ipset=/.91smartyun.pt/gfwlist
|
||||
ipset=/.adobe.com/gfwlist
|
||||
ipset=/.amazonaws.com/gfwlist
|
||||
ipset=/.ampproject.org/gfwlist
|
||||
ipset=/.apple.news/gfwlist
|
||||
ipset=/.aws.amazon.com/gfwlist
|
||||
ipset=/.azureedge.net/gfwlist
|
||||
ipset=/.backpackers.com.tw/gfwlist
|
||||
ipset=/.bitfinex.com/gfwlist
|
||||
ipset=/.buzzfeed.com/gfwlist
|
||||
ipset=/.clockwise.ee/gfwlist
|
||||
ipset=/.cloudfront.net/gfwlist
|
||||
ipset=/.coindesk.com/gfwlist
|
||||
ipset=/.coinsquare.io/gfwlist
|
||||
ipset=/.cryptocompare.com/gfwlist
|
||||
ipset=/.dropboxstatic.com/gfwlist
|
||||
ipset=/.eurecom.fr/gfwlist
|
||||
ipset=/.gdax.com/gfwlist
|
||||
ipset=/.github.com/gfwlist
|
||||
ipset=/.kknews.cc/gfwlist
|
||||
ipset=/.nutaq.com/gfwlist
|
||||
ipset=/.openairinterface.org/gfwlist
|
||||
ipset=/.skype.com/gfwlist
|
||||
ipset=/.sublimetext.com/gfwlist
|
||||
ipset=/.textnow.com/gfwlist
|
||||
ipset=/.textnow.me/gfwlist
|
||||
ipset=/.trouter.io/gfwlist
|
||||
ipset=/.uploaded.net/gfwlist
|
||||
ipset=/.whatsapp.com/gfwlist
|
||||
ipset=/.whatsapp.net/gfwlist
|
||||
ipset=/.wsj.net/gfwlist
|
||||
ipset=/.google.com/gfwlist
|
||||
ipset=/.google.com.hk/gfwlist
|
||||
ipset=/.gstatic.com/gfwlist
|
||||
ipset=/.googleusercontent.com/gfwlist
|
||||
ipset=/.googlepages.com/gfwlist
|
||||
ipset=/.googlevideo.com/gfwlist
|
||||
ipset=/.googlecode.com/gfwlist
|
||||
ipset=/.googleapis.com/gfwlist
|
||||
ipset=/.googlesource.com/gfwlist
|
||||
ipset=/.googledrive.com/gfwlist
|
||||
ipset=/.ggpht.com/gfwlist
|
||||
ipset=/.youtube.com/gfwlist
|
||||
ipset=/.youtu.be/gfwlist
|
||||
ipset=/.ytimg.com/gfwlist
|
||||
ipset=/.twitter.com/gfwlist
|
||||
ipset=/.facebook.com/gfwlist
|
||||
ipset=/.fastly.net/gfwlist
|
||||
ipset=/.akamai.net/gfwlist
|
||||
ipset=/.akamaiedge.net/gfwlist
|
||||
ipset=/.akamaihd.net/gfwlist
|
||||
ipset=/.edgesuite.net/gfwlist
|
||||
ipset=/.edgekey.net/gfwlist
|
||||
server=/.91smartyun.pt/127.0.0.1#5335
|
||||
server=/.adobe.com/127.0.0.1#5335
|
||||
server=/.amazonaws.com/127.0.0.1#5335
|
||||
server=/.ampproject.org/127.0.0.1#5335
|
||||
server=/.apple.news/127.0.0.1#5335
|
||||
server=/.aws.amazon.com/127.0.0.1#5335
|
||||
server=/.azureedge.net/127.0.0.1#5335
|
||||
server=/.backpackers.com.tw/127.0.0.1#5335
|
||||
server=/.bitfinex.com/127.0.0.1#5335
|
||||
server=/.buzzfeed.com/127.0.0.1#5335
|
||||
server=/.clockwise.ee/127.0.0.1#5335
|
||||
server=/.cloudfront.net/127.0.0.1#5335
|
||||
server=/.coindesk.com/127.0.0.1#5335
|
||||
server=/.coinsquare.io/127.0.0.1#5335
|
||||
server=/.cryptocompare.com/127.0.0.1#5335
|
||||
server=/.dropboxstatic.com/127.0.0.1#5335
|
||||
server=/.eurecom.fr/127.0.0.1#5335
|
||||
server=/.gdax.com/127.0.0.1#5335
|
||||
server=/.github.com/127.0.0.1#5335
|
||||
server=/.kknews.cc/127.0.0.1#5335
|
||||
server=/.nutaq.com/127.0.0.1#5335
|
||||
server=/.openairinterface.org/127.0.0.1#5335
|
||||
server=/.skype.com/127.0.0.1#5335
|
||||
server=/.sublimetext.com/127.0.0.1#5335
|
||||
server=/.textnow.com/127.0.0.1#5335
|
||||
server=/.textnow.me/127.0.0.1#5335
|
||||
server=/.trouter.io/127.0.0.1#5335
|
||||
server=/.uploaded.net/127.0.0.1#5335
|
||||
server=/.whatsapp.com/127.0.0.1#5335
|
||||
server=/.whatsapp.net/127.0.0.1#5335
|
||||
server=/.wsj.net/127.0.0.1#5335
|
||||
server=/.google.com/127.0.0.1#5335
|
||||
server=/.google.com.hk/127.0.0.1#5335
|
||||
server=/.gstatic.com/127.0.0.1#5335
|
||||
server=/.googleusercontent.com/127.0.0.1#5335
|
||||
server=/.googlepages.com/127.0.0.1#5335
|
||||
server=/.googlevideo.com/127.0.0.1#5335
|
||||
server=/.googlecode.com/127.0.0.1#5335
|
||||
server=/.googleapis.com/127.0.0.1#5335
|
||||
server=/.googlesource.com/127.0.0.1#5335
|
||||
server=/.googledrive.com/127.0.0.1#5335
|
||||
server=/.ggpht.com/127.0.0.1#5335
|
||||
server=/.youtube.com/127.0.0.1#5335
|
||||
server=/.youtu.be/127.0.0.1#5335
|
||||
server=/.ytimg.com/127.0.0.1#5335
|
||||
server=/.twitter.com/127.0.0.1#5335
|
||||
server=/.facebook.com/127.0.0.1#5335
|
||||
server=/.fastly.net/127.0.0.1#5335
|
||||
server=/.akamai.net/127.0.0.1#5335
|
||||
server=/.akamaiedge.net/127.0.0.1#5335
|
||||
server=/.akamaihd.net/127.0.0.1#5335
|
||||
server=/.edgesuite.net/127.0.0.1#5335
|
||||
server=/.edgekey.net/127.0.0.1#5335
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,21 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2007 OpenWrt.org
|
||||
|
||||
/etc/init.d/shadowsocksr enabled && {
|
||||
|
||||
[ "$ACTION" = "ifup" ] && {
|
||||
local_server=`uci get shadowsocksr.@global[0].global_server 2>/dev/null`
|
||||
|
||||
if [ "$local_server" = "nil" ] ;then
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") Shadowsocks/ShadowsocksR/v2ray not running!" >> /tmp/ssrplus.log
|
||||
else
|
||||
icount=`ps -w | grep ssr-retcp |grep -v grep| wc -l`
|
||||
if [ $icount = 0 ] ;then
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") Shadowsocks/ShadowsocksR/v2ray error.restart!" >> /tmp/ssrplus.log
|
||||
/etc/init.d/shadowsocksr restart
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,23 +0,0 @@
|
||||
#!/bin/sh
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@shadowsocksr[-1]
|
||||
add ucitrack shadowsocksr
|
||||
set ucitrack.@shadowsocksr[-1].init=shadowsocksr
|
||||
commit ucitrack
|
||||
delete firewall.shadowsocksr
|
||||
set firewall.shadowsocksr=include
|
||||
set firewall.shadowsocksr.type=script
|
||||
set firewall.shadowsocksr.path=/var/etc/shadowsocksr.include
|
||||
set firewall.shadowsocksr.reload=1
|
||||
commit firewall
|
||||
EOF
|
||||
|
||||
/etc/init.d/dnscrypt-proxy stop
|
||||
/etc/init.d/dnscrypt-proxy disable
|
||||
/etc/init.d/privoxy stop
|
||||
/etc/init.d/privoxy disable
|
||||
killall -q -9 v2ray-plugin
|
||||
|
||||
/usr/share/shadowsocksr/gfw2ipset.sh
|
||||
rm -f /tmp/luci-indexcache
|
||||
exit 0
|
||||
@ -1,6 +0,0 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
if [ -f /tmp/adnew.conf ]; then
|
||||
cat /tmp/adnew.conf | grep ^\|\|[^\*]*\^$ | sed -e 's:||:address\=\/:' -e 's:\^:/0\.0\.0\.0:' > /tmp/ad.conf
|
||||
fi
|
||||
|
||||
@ -1,32 +0,0 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
generate_china_banned()
|
||||
{
|
||||
|
||||
cat $1 | base64 -d > /tmp/gfwlist.txt
|
||||
rm -f $1
|
||||
|
||||
sed -i '/^@@|/d' /tmp/gfwlist.txt
|
||||
|
||||
cat /tmp/gfwlist.txt | sort -u |
|
||||
sed 's#!.\+##; s#|##g; s#@##g; s#http:\/\/##; s#https:\/\/##;' |
|
||||
sed '/\*/d; /apple\.com/d; /sina\.cn/d; /sina\.com\.cn/d; /baidu\.com/d; /byr\.cn/d; /jlike\.com/d; /weibo\.com/d; /zhongsou\.com/d; /youdao\.com/d; /sogou\.com/d; /so\.com/d; /soso\.com/d; /aliyun\.com/d; /taobao\.com/d; /jd\.com/d; /qq\.com/d' |
|
||||
sed '/^[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+$/d' |
|
||||
grep '^[0-9a-zA-Z\.-]\+$' | grep '\.' | sed 's#^\.\+##' | sort -u |
|
||||
awk '
|
||||
BEGIN { prev = "________"; } {
|
||||
cur = $0;
|
||||
if (index(cur, prev) == 1 && substr(cur, 1 + length(prev) ,1) == ".") {
|
||||
} else {
|
||||
print cur;
|
||||
prev = cur;
|
||||
}
|
||||
}' | sort -u
|
||||
|
||||
}
|
||||
|
||||
generate_china_banned /tmp/gfw.b64 > /tmp/gfw.txt
|
||||
rm -f /tmp/gfwlist.txt
|
||||
sed '/.*/s/.*/server=\/\.&\/127.0.0.1#5335\nipset=\/\.&\/gfwlist/' /tmp/gfw.txt >/tmp/gfwnew.txt
|
||||
rm -f /tmp/gfw.txt
|
||||
|
||||
@ -1,277 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (C) 2017 openwrt-ssr
|
||||
# Copyright (C) 2017 yushi studio <ywb94@qq.com>
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v3.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
|
||||
NAME=shadowsocksr
|
||||
logfile="/tmp/ssrplus.log"
|
||||
|
||||
uci_get_by_name() {
|
||||
local ret=$(uci get $NAME.$1.$2 2>/dev/null)
|
||||
echo ${ret:=$3}
|
||||
}
|
||||
|
||||
uci_get_by_type() {
|
||||
local ret=$(uci get $NAME.@$1[0].$2 2>/dev/null)
|
||||
echo ${ret:=$3}
|
||||
}
|
||||
|
||||
server_process_count=$1
|
||||
redir_tcp_process=$2
|
||||
redir_udp_process=$3
|
||||
tunnel_process=$4
|
||||
kcp_process=$5
|
||||
local_process=$6
|
||||
pdnsd_process=$7
|
||||
dnsforwarder_process=$8
|
||||
ssserver_process=$10
|
||||
ssrserver_process=$11
|
||||
v2rayserver_process=$12
|
||||
haproxy_process=$13
|
||||
privoxy_process=$14
|
||||
chinadns_process=$15
|
||||
if [ -z "$pdnsd_process" ] ;then
|
||||
pdnsd_process=0
|
||||
fi
|
||||
|
||||
i=0
|
||||
|
||||
GLOBAL_SERVER=$(uci_get_by_type global global_server)
|
||||
server=$(uci_get_by_name $GLOBAL_SERVER server)
|
||||
kcp_port=$(uci_get_by_name $GLOBAL_SERVER kcp_port)
|
||||
server_port=$(uci_get_by_name $GLOBAL_SERVER server_port)
|
||||
password=$(uci_get_by_name $GLOBAL_SERVER kcp_password)
|
||||
kcp_param=$(uci_get_by_name $GLOBAL_SERVER kcp_param)
|
||||
[ "$password" != "" ] && password="--key "${password}
|
||||
|
||||
sock5_port=$(uci_get_by_type socks5_proxy local_port 1080)
|
||||
|
||||
if [ "$(uci_get_by_type global chinadns_enable)" = "0" ] ;then
|
||||
dnsstrs="$(uci_get_by_type global tunnel_forward 8.8.4.4:53)"
|
||||
else
|
||||
dnsstrs="0.0.0.0:5337"
|
||||
fi
|
||||
|
||||
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
|
||||
sleep 30
|
||||
#redir tcp
|
||||
if [ $redir_tcp_process -gt 0 ] ;then
|
||||
icount=`ps -w | grep ssr-retcp |grep -v grep| wc -l`
|
||||
if [ $icount = 0 ] ;then
|
||||
logger -t "$NAME" "ssr redir tcp error.restart!"
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") redir tcp error.restart!" >> ${logfile}
|
||||
/etc/init.d/shadowsocksr restart
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
#redir udp
|
||||
if [ $redir_udp_process -gt 0 ] ;then
|
||||
icount=`ps -w | grep ssr-reudp|grep -v grep| wc -l`
|
||||
if [ $icount = 0 ] ;then
|
||||
logger -t "$NAME" "ssr redir udp error.restart!"
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") redir udp error.restart!" >> ${logfile}
|
||||
/etc/init.d/shadowsocksr restart
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
#tunnel
|
||||
if [ $tunnel_process -gt 0 ] ;then
|
||||
icount=`ps -w | grep ssr-tunnel |grep -v grep| wc -l`
|
||||
if [ $icount = 0 ] ;then
|
||||
logger -t "$NAME" "ssr tunnel error.restart!"
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") tunnel error.restart!" >> ${logfile}
|
||||
/etc/init.d/shadowsocksr restart
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
#server
|
||||
#ssr_server
|
||||
if [ $server_process_count -gt 0 ] ;then
|
||||
if [ $ssrserver_process -gt 0 ] ;then
|
||||
icount=`ps -w | grep ssr-server |grep -v grep| wc -l`
|
||||
if [ $icount -lt $ssrserver_process ] #如果进程挂掉就重启它
|
||||
then
|
||||
logger -t "$NAME" "ssr server error.restart!"
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") ssr server error.restart!" >> ${logfile}
|
||||
killall -q -9 ssr-server
|
||||
for i in `seq $ssrserver_process`
|
||||
do
|
||||
/usr/bin/ssr-server -c /var/etc/shadowsocksr_$i.json -u -f /var/run/ssr-server$i.pid
|
||||
done
|
||||
fi
|
||||
fi
|
||||
#ss_server
|
||||
if [ $ssserver_process -gt 0 ] ;then
|
||||
icount=`ps -w | grep ss-server |grep -v grep| wc -l`
|
||||
if [ $icount -lt $ssserver_process ] #如果进程挂掉就重启它
|
||||
then
|
||||
logger -t "$NAME" "ss server error.restart!"
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") ss server error.restart!" >> ${logfile}
|
||||
killall -q -9 ss-server
|
||||
for i in `seq $ssserver_process`
|
||||
do
|
||||
/usr/bin/ss-server -c /var/etc/shadowsocksr_$i.json -u -f /var/run/ss-server$i.pid
|
||||
done
|
||||
fi
|
||||
fi
|
||||
#v2ray_server
|
||||
if [ v2rayserver_process -gt 0 ] ;then
|
||||
icount=`ps -w | grep ss-server |grep -v grep| wc -l`
|
||||
if [ $icount -lt $v2rayserver_process ] #如果进程挂掉就重启它
|
||||
then
|
||||
logger -t "$NAME" "v2ray server error.restart!"
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") v2ray server error.restart!" >> ${logfile}
|
||||
kill -9 $(ps | grep v2ray-server | grep -v grep | awk '{print $1}') >/dev/null 2>&1
|
||||
for i in `seq $v2rayserver_process`
|
||||
do
|
||||
( /usr/bin/v2ray/v2ray -config /var/etc/v2ray-server-$i.json >/dev/null 2>&1 &)
|
||||
done
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
#kcptun
|
||||
if [ $kcp_process -gt 0 ] ;then
|
||||
icount=`ps -w | grep kcptun-client |grep -v grep| wc -l`
|
||||
if [ $icount -lt $kcp_process ] #如果进程挂掉就重启它
|
||||
then
|
||||
logger -t "$NAME" "ssr kcptun error.restart!"
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") ssr kcptun error.restart!" >> ${logfile}
|
||||
killall -q -9 kcptun-client
|
||||
|
||||
( /usr/bin/kcptun-client -r $server:$kcp_port -l :$server_port $password $kcp_param &)
|
||||
fi
|
||||
fi
|
||||
#local
|
||||
if [ $local_process -eq 1 ] ;then
|
||||
icount=`ps -w | grep ssr-local |grep -v grep| wc -l`
|
||||
if [ $icount -lt $local_process ] #如果进程挂掉就重启它
|
||||
then
|
||||
logger -t "$NAME" "ssr local error.restart!"
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") ssr local error.restart!" >> ${logfile}
|
||||
killall -q -9 ssr-local
|
||||
|
||||
( /usr/bin/ssr-local -c /var/etc/shadowsocksr_s.json -u -l $sock5_port -f /var/run/ssr-local.pid &)
|
||||
fi
|
||||
fi
|
||||
#local
|
||||
if [ $local_process -eq 2 ] ;then
|
||||
local_processs=1
|
||||
icount=`ps -w | grep ss-local |grep -v grep| wc -l`
|
||||
if [ $icount -lt $local_processs ] #如果进程挂掉就重启它
|
||||
then
|
||||
logger -t "$NAME" "ss local error.restart!"
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") ss local error.restart!" >> ${logfile}
|
||||
killall -q -9 ss-local
|
||||
|
||||
( /usr/bin/ss-local -c /var/etc/shadowsocksr_s.json -u -l $sock5_port -f /var/run/ss-local.pid &)
|
||||
fi
|
||||
fi
|
||||
#local
|
||||
if [ $local_process -eq 3 ] ;then
|
||||
local_processs=1
|
||||
icount=`ps -w | grep v2-ssr-local |grep -v grep| wc -l`
|
||||
if [ $icount -lt $local_processs ] #如果进程挂掉就重启它
|
||||
then
|
||||
logger -t "$NAME" "v2ray local error.restart!"
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") v2ray local error.restart!" >> ${logfile}
|
||||
kill -9 $(ps | grep v2-ssr-local | grep -v grep | awk '{print $1}') >/dev/null 2>&1
|
||||
|
||||
( /usr/bin/v2ray/v2ray -config /var/etc/v2-ssr-local.json >/dev/null 2>&1 &)
|
||||
fi
|
||||
fi
|
||||
#privoxy
|
||||
if [ $privoxy_process -gt 0 ] ;then
|
||||
icount=`ps -w | grep privoxy |grep -v grep| wc -l`
|
||||
if [ $icount -lt $privoxy_process ]; then
|
||||
logger -t "$NAME" "privoxy http local error.restart!"
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") privoxy http loca error.restart!" >> ${logfile}
|
||||
kill -9 $(ps | grep privoxy | grep -v grep | awk '{print $1}') >/dev/null 2>&1
|
||||
|
||||
/etc/init.d/privoxy restart
|
||||
fi
|
||||
fi
|
||||
#dnsforwarder
|
||||
if [ $dnsforwarder_process -gt 0 ] ;then
|
||||
icount=`ps -w | grep dnsparsing |grep -v grep| wc -l`
|
||||
if [ $icount -lt $dnsforwarder_process ]; then
|
||||
logger -t "$NAME" "dnsforwarder tunnel error.restart!"
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") dnsforwarder tunnel error.restart!" >> ${logfile}
|
||||
kill -9 $(ps | grep dnsparsing | grep -v grep | awk '{print $1}') >/dev/null 2>&1
|
||||
|
||||
( dnsparsing -f /var/run/dnsparsing/dnsparsing.conf -d &)
|
||||
fi
|
||||
fi
|
||||
#pdnsd
|
||||
if [ $pdnsd_process -gt 0 ] ;then
|
||||
icount=`ps -w | grep pdnsd |grep -v grep| wc -l`
|
||||
if [ $icount -lt $pdnsd_process ] #如果进程挂掉就重启它
|
||||
then
|
||||
logger -t "$NAME" "pdnsd tunnel error.restart!"
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") pdnsd tunnel error.restart!" >> ${logfile}
|
||||
if [ -f /var/run/pdnsd.pid ] ;then
|
||||
kill $(cat /var/run/pdnsd.pid) >/dev/null 2>&1
|
||||
else
|
||||
kill -9 $(ps | grep pdnsd | grep -v grep | awk '{print $1}') >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
( /usr/sbin/pdnsd -c /var/etc/pdnsd.conf -d &)
|
||||
fi
|
||||
fi
|
||||
#chiandns
|
||||
if [ $chinadns_process -gt 0 ] ;then
|
||||
icount=`ps -w | grep chinadns |grep -v grep| wc -l`
|
||||
if [ $icount -lt $chinadns_process ]; then
|
||||
logger -t "$NAME" "chinadns tunnel error.restart!"
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") chinadns tunnel error.restart!" >> ${logfile}
|
||||
kill -9 $(ps | grep chinadns | grep -v grep | awk '{print $1}') >/dev/null 2>&1
|
||||
|
||||
(nohup /usr/bin/chinadns -p 5335 -c /etc/china_ssr.txt -m -d -s $dnsstrs >/dev/null 2>&1 &)
|
||||
fi
|
||||
fi
|
||||
#haproxy
|
||||
if [ $haproxy_process -gt 0 ] ;then
|
||||
icount=`ps -w | grep haproxy |grep -v grep| wc -l`
|
||||
if [ $icount -lt $haproxy_process ] #如果进程挂掉就重启它
|
||||
then
|
||||
logger -t "$NAME" "haproxy error.restart!"
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") haproxy error.restart!" >> ${logfile}
|
||||
/etc/init.d/shadowsocksr restart
|
||||
fi
|
||||
fi
|
||||
#udp2raw
|
||||
if [ $(uci_get_by_type udp2raw udp2raw_enable) = 1 ] ;then
|
||||
ucount=`ps -w | grep udp2raw |grep -v grep| wc -l`
|
||||
if [ $ucount = 0 ] ;then
|
||||
/usr/bin/udp2raw --clear >/dev/null
|
||||
/usr/bin/udp2raw --conf-file /var/etc/udp2raw.conf >/dev/null 2>&1 &
|
||||
fi
|
||||
fi
|
||||
#udpspeeder
|
||||
if [ $(uci_get_by_type udpspeeder udpspeeder_enable) = 1 ] ;then
|
||||
scount=`ps -w | grep udpspeeder |grep -v grep| wc -l`
|
||||
if [ $scount = 0 ] ;then
|
||||
/usr/bin/udpspeeder -c -l0.0.0.0:$(uci_get_by_type udpspeeder local_port) \
|
||||
-r$(uci_get_by_type udpspeeder server):$(uci_get_by_type udpspeeder server_port) \
|
||||
-k $(uci_get_by_type udpspeeder key) \
|
||||
--mode $(uci_get_by_type udpspeeder speeder_mode) \
|
||||
--mtu $(uci_get_by_type udpspeeder mtu) \
|
||||
-f$(uci_get_by_type udpspeeder fec) \
|
||||
-q$(uci_get_by_type udpspeeder queue_len) \
|
||||
--timeout $(uci_get_by_type udpspeeder timeout) \
|
||||
>/dev/null 2>&1 &
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
@ -1,424 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (C) 2017 openwrt-ssr
|
||||
# Copyright (C) 2017 yushi studio <ywb94@qq.com>
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v3.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
TAG="_SS_SPEC_RULE_" # comment tag
|
||||
IPT="iptables -t nat" # alias of iptables
|
||||
FWI=$(uci get firewall.shadowsocksr.path 2>/dev/null) # firewall include file
|
||||
|
||||
usage() {
|
||||
cat <<-EOF
|
||||
Usage: ssr-rules [options]
|
||||
|
||||
Valid options are:
|
||||
|
||||
-s <server_ip> ip address of shadowsocksr remote server
|
||||
-l <local_port> port number of shadowsocksr local server
|
||||
-S <server_ip> ip address of shadowsocksr remote UDP server
|
||||
-L <local_port> port number of shadowsocksr local UDP server
|
||||
-i <ip_list_file> a file content is bypassed ip list
|
||||
-a <lan_ips> lan ip of access control, need a prefix to
|
||||
define access control mode
|
||||
-b <wan_ips> wan ip of will be bypassed
|
||||
-w <wan_ips> wan ip of will be forwarded
|
||||
-p <fp_lan_ips> lan ip of will be global proxy
|
||||
-G <gm_lan_ips> lan ip of will be game mode proxy
|
||||
-D <proxy_ports> proxy ports
|
||||
-k <wan_fk_ips> wan ip of will be forwarded
|
||||
-e <extra_options> extra options for iptables
|
||||
-o apply the rules to the OUTPUT chain
|
||||
-O apply the global rules to the OUTPUT chain
|
||||
-u enable udprelay mode, TPROXY is required
|
||||
-U enable udprelay mode, using different IP
|
||||
and ports for TCP and UDP
|
||||
-f flush the rules
|
||||
-g gfw list mode
|
||||
-R returns china mode
|
||||
-r return china mode
|
||||
-h show this help message and exit
|
||||
EOF
|
||||
exit $1
|
||||
}
|
||||
|
||||
loger() {
|
||||
# 1.alert 2.crit 3.err 4.warn 5.notice 6.info 7.debug
|
||||
logger -st ssr-rules[$$] -p$1 $2
|
||||
}
|
||||
|
||||
flush_r() {
|
||||
flush_iptables() {
|
||||
local ipt="iptables -t $1"
|
||||
local DAT=$(iptables-save -t $1)
|
||||
eval $(echo "$DAT" | grep "$TAG" | sed -e 's/^-A/$ipt -D/' -e 's/$/;/')
|
||||
for chain in $(echo "$DAT" | awk '/^:SS_SPEC/{print $1}'); do
|
||||
$ipt -F ${chain:1} 2>/dev/null && $ipt -X ${chain:1}
|
||||
done
|
||||
}
|
||||
|
||||
flush_iptables nat
|
||||
flush_iptables mangle
|
||||
ip rule del fwmark 0x01/0x01 table 100 2>/dev/null
|
||||
ip route del local 0.0.0.0/0 dev lo table 100 2>/dev/null
|
||||
ipset -X ss_spec_lan_ac 2>/dev/null
|
||||
ipset -X ss_spec_wan_ac 2>/dev/null
|
||||
ipset -X ssr_gen_router 2>/dev/null
|
||||
ipset -X fplan 2>/dev/null
|
||||
ipset -X gmlan 2>/dev/null
|
||||
ipset -X oversea 2>/dev/null
|
||||
ipset -X whitelist 2>/dev/null
|
||||
ipset -X blacklist 2>/dev/null
|
||||
[ -n "$FWI" ] && echo '#!/bin/sh' >$FWI
|
||||
return 0
|
||||
}
|
||||
|
||||
ipset_r() {
|
||||
ipset -N gmlan hash:net 2>/dev/null
|
||||
for ip in $LAN_GM_IP; do ipset -! add gmlan $ip ; done
|
||||
|
||||
if [ "$RUNMODE" = "router" ] ;then
|
||||
ipset -! -R <<-EOF || return 1
|
||||
create ss_spec_wan_ac hash:net
|
||||
$(gen_iplist | sed -e "s/^/add ss_spec_wan_ac /")
|
||||
$(for ip in $WAN_FW_IP; do echo "add ss_spec_wan_ac $ip nomatch"; done)
|
||||
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 -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
|
||||
|
||||
elif [ "$RUNMODE" = "gfw" ] ;then
|
||||
ipset -N gfwlist hash:net 2>/dev/null
|
||||
for ip in $WAN_FW_IP; do ipset -! add gfwlist $ip ; done
|
||||
$IPT -N SS_SPEC_WAN_AC
|
||||
$IPT -A SS_SPEC_WAN_AC -m set --match-set china dst -j RETURN
|
||||
$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 -I SS_SPEC_WAN_AC -d $server -j RETURN
|
||||
|
||||
elif [ "$RUNMODE" = "oversea" ] ;then
|
||||
ipset -N oversea hash:net 2>/dev/null
|
||||
for ip in $WAN_FK_IP; do ipset -! add oversea $ip ; done
|
||||
$IPT -N SS_SPEC_WAN_AC
|
||||
$IPT -A SS_SPEC_WAN_AC -m set --match-set oversea dst -j SS_SPEC_WAN_FW
|
||||
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 gmlan src -m set --match-set china dst -j SS_SPEC_WAN_FW
|
||||
$IPT -I SS_SPEC_WAN_AC -d $server -j RETURN
|
||||
|
||||
elif [ "$RUNMODE" = "routers" ] ;then
|
||||
ipset -! -R <<-EOF || return 1
|
||||
create ss_spec_wan_ac hash:net
|
||||
$(gen_iplist | sed -e "s/^/add ss_spec_wan_ac /")
|
||||
$(for ip in $WAN_FK_IP; do echo "add ss_spec_wan_ac $ip nomatch"; done)
|
||||
EOF
|
||||
ipset -N oversea hash:net 2>/dev/null
|
||||
$IPT -N SS_SPEC_WAN_AC
|
||||
$IPT -I SS_SPEC_WAN_AC -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
|
||||
|
||||
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
|
||||
|
||||
fi
|
||||
|
||||
ipset -N fplan hash:net 2>/dev/null
|
||||
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
|
||||
|
||||
ipset -N whitelist hash:net 2>/dev/null
|
||||
ipset -N blacklist hash:net 2>/dev/null
|
||||
$IPT -I SS_SPEC_WAN_AC -m set --match-set blacklist src -j SS_SPEC_WAN_FW
|
||||
$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_FW_IP; do ipset -! add blacklist $ip; done
|
||||
|
||||
return $?
|
||||
}
|
||||
|
||||
fw_rule() {
|
||||
$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 10.0.0.0/8 -j RETURN
|
||||
$IPT -A SS_SPEC_WAN_FW -d 127.0.0.0/8 -j RETURN
|
||||
$IPT -A SS_SPEC_WAN_FW -d 169.254.0.0/16 -j RETURN
|
||||
$IPT -A SS_SPEC_WAN_FW -d 172.16.0.0/12 -j RETURN
|
||||
$IPT -A SS_SPEC_WAN_FW -d 192.168.0.0/16 -j RETURN
|
||||
$IPT -A SS_SPEC_WAN_FW -d 224.0.0.0/4 -j RETURN
|
||||
$IPT -A SS_SPEC_WAN_FW -d 240.0.0.0/4 -j RETURN
|
||||
$IPT -A SS_SPEC_WAN_FW -p tcp $PROXY_PORTS \
|
||||
-j REDIRECT --to-ports $local_port 2>/dev/null || {
|
||||
loger 3 "Can't redirect, please check the iptables."
|
||||
exit 1
|
||||
}
|
||||
return $?
|
||||
}
|
||||
|
||||
ac_rule() {
|
||||
if [ -n "$LAN_AC_IP" ]; then
|
||||
case "${LAN_AC_IP:0:1}" in
|
||||
w|W)
|
||||
MATCH_SET="-m set --match-set ss_spec_lan_ac src"
|
||||
;;
|
||||
b|B)
|
||||
MATCH_SET="-m set ! --match-set ss_spec_lan_ac src"
|
||||
;;
|
||||
*)
|
||||
loger 3 "Bad argument \`-a $LAN_AC_IP\`."
|
||||
return 2
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
IFNAME=$(uci get -P/var/state network.lan.ifname 2>/dev/null)
|
||||
ipset -! -R <<-EOF || return 1
|
||||
create ss_spec_lan_ac hash:net
|
||||
$(for ip in ${LAN_AC_IP:1}; do echo "add ss_spec_lan_ac $ip"; done)
|
||||
EOF
|
||||
$IPT -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p tcp $EXT_ARGS $MATCH_SET \
|
||||
-m comment --comment "$TAG" -j SS_SPEC_WAN_AC
|
||||
if [ "$OUTPUT" = 1 ]; then
|
||||
$IPT -I OUTPUT 1 -p tcp $EXT_ARGS \
|
||||
-m comment --comment "$TAG" -j SS_SPEC_WAN_AC
|
||||
elif [ "$OUTPUT" = 2 ]; then
|
||||
ipset -! -R <<-EOF || return 1
|
||||
create ssr_gen_router hash:net
|
||||
$(gen_spec_iplist | sed -e "s/^/add ssr_gen_router /")
|
||||
EOF
|
||||
$IPT -N SS_SPEC_ROUTER && \
|
||||
$IPT -A SS_SPEC_ROUTER -m set --match-set ssr_gen_router dst -j RETURN && \
|
||||
$IPT -A SS_SPEC_ROUTER -j SS_SPEC_WAN_FW
|
||||
$IPT -I OUTPUT 1 -p tcp -m comment --comment "$TAG" -j SS_SPEC_ROUTER
|
||||
fi
|
||||
return $?
|
||||
}
|
||||
|
||||
tp_rule() {
|
||||
[ -n "$TPROXY" ] || return 0
|
||||
ip rule add fwmark 0x01/0x01 table 100
|
||||
ip route add local 0.0.0.0/0 dev lo table 100
|
||||
local ipt="iptables -t mangle"
|
||||
$ipt -N SS_SPEC_TPROXY
|
||||
$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 10.0.0.0/8 -j RETURN
|
||||
$ipt -A SS_SPEC_TPROXY -p udp -d 127.0.0.0/8 -j RETURN
|
||||
$ipt -A SS_SPEC_TPROXY -p udp -d 169.254.0.0/16 -j RETURN
|
||||
$ipt -A SS_SPEC_TPROXY -p udp -d 172.16.0.0/12 -j RETURN
|
||||
$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 $PROXY_PORTS -m set --match-set fplan src \
|
||||
-j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
|
||||
|
||||
if [ "$RUNMODE" = "router" ] ;then
|
||||
$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
|
||||
$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
|
||||
|
||||
elif [ "$RUNMODE" = "gfw" ] ;then
|
||||
$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 \
|
||||
-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 \
|
||||
-j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
|
||||
|
||||
elif [ "$RUNMODE" = "oversea" ] ;then
|
||||
$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
|
||||
$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
|
||||
|
||||
elif [ "$RUNMODE" = "routers" ] ;then
|
||||
$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
|
||||
|
||||
elif [ "$RUNMODE" = "all" ] ;then
|
||||
$ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
|
||||
fi
|
||||
|
||||
$ipt -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p udp $EXT_ARGS $MATCH_SET \
|
||||
-m comment --comment "$TAG" -j SS_SPEC_TPROXY
|
||||
|
||||
return $?
|
||||
}
|
||||
|
||||
get_wan_ip() {
|
||||
cat <<-EOF | grep -E "^([0-9]{1,3}\.){3}[0-9]{1,3}"
|
||||
$server
|
||||
$SERVER
|
||||
$WAN_BP_IP
|
||||
EOF
|
||||
}
|
||||
|
||||
gen_iplist() {
|
||||
cat <<-EOF
|
||||
0.0.0.0/8
|
||||
10.0.0.0/8
|
||||
100.64.0.0/10
|
||||
127.0.0.0/8
|
||||
169.254.0.0/16
|
||||
172.16.0.0/12
|
||||
192.0.0.0/24
|
||||
192.0.2.0/24
|
||||
192.88.99.0/24
|
||||
192.168.0.0/16
|
||||
198.18.0.0/15
|
||||
198.51.100.0/24
|
||||
203.0.113.0/24
|
||||
224.0.0.0/4
|
||||
240.0.0.0/4
|
||||
255.255.255.255
|
||||
$(get_wan_ip)
|
||||
$(cat ${IGNORE_LIST:=/dev/null} 2>/dev/null)
|
||||
EOF
|
||||
}
|
||||
|
||||
gen_spec_iplist() {
|
||||
cat <<-EOF
|
||||
0.0.0.0/8
|
||||
10.0.0.0/8
|
||||
100.64.0.0/10
|
||||
127.0.0.0/8
|
||||
169.254.0.0/16
|
||||
172.16.0.0/12
|
||||
192.0.0.0/24
|
||||
192.0.2.0/24
|
||||
192.88.99.0/24
|
||||
192.168.0.0/16
|
||||
198.18.0.0/15
|
||||
198.51.100.0/24
|
||||
203.0.113.0/24
|
||||
224.0.0.0/4
|
||||
240.0.0.0/4
|
||||
255.255.255.255
|
||||
$(get_wan_ip)
|
||||
EOF
|
||||
}
|
||||
|
||||
gen_include() {
|
||||
[ -n "$FWI" ] || return 0
|
||||
extract_rules() {
|
||||
echo "*$1"
|
||||
iptables-save -t $1 | grep SS_SPEC_ |\
|
||||
sed -e "s/^-A \(OUTPUT\|PREROUTING\)/-I \1 1/"
|
||||
echo 'COMMIT'
|
||||
}
|
||||
cat <<-EOF >>$FWI
|
||||
iptables-save -c | grep -v "SS_SPEC" | iptables-restore -c
|
||||
iptables-restore -n <<-EOT
|
||||
$(extract_rules nat)
|
||||
$(extract_rules mangle)
|
||||
EOT
|
||||
EOF
|
||||
return 0
|
||||
}
|
||||
|
||||
while getopts ":s:l:S:L:i:e:a:b:w:p:G:D:k:oOuUfgrRczh" arg; do
|
||||
case "$arg" in
|
||||
s)
|
||||
server=$OPTARG
|
||||
;;
|
||||
l)
|
||||
local_port=$OPTARG
|
||||
;;
|
||||
S)
|
||||
SERVER=$OPTARG
|
||||
;;
|
||||
L)
|
||||
LOCAL_PORT=$OPTARG
|
||||
;;
|
||||
i)
|
||||
IGNORE_LIST=$OPTARG
|
||||
;;
|
||||
e)
|
||||
EXT_ARGS=$OPTARG
|
||||
;;
|
||||
a)
|
||||
LAN_AC_IP=$OPTARG
|
||||
;;
|
||||
b)
|
||||
WAN_BP_IP=$(for ip in $OPTARG; do echo $ip; done)
|
||||
;;
|
||||
w)
|
||||
WAN_FW_IP=$OPTARG
|
||||
;;
|
||||
p)
|
||||
LAN_FP_IP=$OPTARG
|
||||
;;
|
||||
G)
|
||||
LAN_GM_IP=$OPTARG
|
||||
;;
|
||||
D)
|
||||
PROXY_PORTS=$OPTARG
|
||||
;;
|
||||
k)
|
||||
WAN_FK_IP=$OPTARG
|
||||
;;
|
||||
o)
|
||||
OUTPUT=1
|
||||
;;
|
||||
O)
|
||||
OUTPUT=2
|
||||
;;
|
||||
u)
|
||||
TPROXY=1
|
||||
;;
|
||||
U)
|
||||
TPROXY=2
|
||||
;;
|
||||
g)
|
||||
RUNMODE=gfw
|
||||
;;
|
||||
r)
|
||||
RUNMODE=router
|
||||
;;
|
||||
R)
|
||||
RUNMODE=routers
|
||||
;;
|
||||
c)
|
||||
RUNMODE=oversea
|
||||
;;
|
||||
z)
|
||||
RUNMODE=all
|
||||
;;
|
||||
f)
|
||||
flush_r
|
||||
exit 0
|
||||
;;
|
||||
h)
|
||||
usage 0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$server" -o -z "$local_port" ]; then
|
||||
usage 2
|
||||
fi
|
||||
|
||||
if [ "$TPROXY" = 1 ]; then
|
||||
SERVER=$server
|
||||
LOCAL_PORT=$local_port
|
||||
elif [ "$TPROXY" = 2 ]; then
|
||||
: ${SERVER:?"You must assign an ip for the udp relay server."}
|
||||
: ${LOCAL_PORT:?"You must assign a port for the udp relay server."}
|
||||
fi
|
||||
|
||||
flush_r && fw_rule && ipset_r && ac_rule && tp_rule && gen_include
|
||||
[ "$?" = 0 ] || loger 3 "Start failed!"
|
||||
exit $?
|
||||
de
|
||||
[ "$?" = 0 ] || loger 3 "Start failed!"
|
||||
exit $?
|
||||
@ -1,175 +0,0 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
#
|
||||
# Copyright (C) 2017 openwrt-ssr
|
||||
# Copyright (C) 2017 yushi studio <ywb94@qq.com>
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v3.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
cycle_time=60
|
||||
switch_time=3
|
||||
normal_flag=0
|
||||
server_locate=0
|
||||
server_count=0
|
||||
NAME=shadowsocksr
|
||||
ENABLE_SERVER=nil
|
||||
CONFIG_SWTICH_FILE=/var/etc/${NAME}_t.json
|
||||
|
||||
|
||||
[ -n "$1" ] && cycle_time=$1
|
||||
[ -n "$2" ] && switch_time=$2
|
||||
|
||||
uci_get_by_name() {
|
||||
local ret=$(uci get $NAME.$1.$2 2>/dev/null)
|
||||
echo ${ret:=$3}
|
||||
}
|
||||
|
||||
uci_get_by_type() {
|
||||
local ret=$(uci get $NAME.@$1[0].$2 2>/dev/null)
|
||||
echo ${ret:=$3}
|
||||
}
|
||||
|
||||
DEFAULT_SERVER=$(uci_get_by_type global global_server)
|
||||
CURRENT_SERVER=$DEFAULT_SERVER
|
||||
|
||||
#判断代理是否正常
|
||||
check_proxy() {
|
||||
/usr/bin/ssr-check www.google.com 80 $switch_time 1
|
||||
if [ "$?" == "0" ]; then
|
||||
return 0
|
||||
else
|
||||
/usr/bin/ssr-check www.baidu.com 80 $switch_time 1
|
||||
if [ "$?" == "0" ]; then
|
||||
#goole不通baidu通则不正常
|
||||
return 1
|
||||
else
|
||||
return 2
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
test_proxy() {
|
||||
local servername=$(uci_get_by_name $1 server)
|
||||
local serverport=$(uci_get_by_name $1 server_port)
|
||||
ret=$(ping -c 3 $servername | grep 'loss' | awk -F ',' '{ print $3 }' | awk -F "%" '{ print $1 }')
|
||||
[ -z "$ret" ] && return 1
|
||||
[ "$ret" -gt "50" ] && return 1
|
||||
ipset add ss_spec_wan_ac $servername 2>/dev/null
|
||||
ret=$?
|
||||
/usr/bin/ssr-check $servername $serverport $switch_time
|
||||
local ret2=$?
|
||||
if [ "$ret" = "0" ] ;then
|
||||
ipset del ss_spec_wan_ac $servername 2>/dev/null
|
||||
fi
|
||||
if [ "$ret2" = "0" ] ;then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
search_proxy() {
|
||||
let server_count=server_count+1
|
||||
[ "$normal_flag" = "1" -a "$server_count" -le "$server_locate" ] && return 0
|
||||
[ "$(uci_get_by_name $1 switch_enable)" != "1" ] && return 1
|
||||
[ $ENABLE_SERVER != nil ] && return 0
|
||||
[ "$1" = "$CURRENT_SERVER" ] && return 0
|
||||
local servername=$(uci_get_by_name $1 server)
|
||||
local serverport=$(uci_get_by_name $1 server_port)
|
||||
ipset add ss_spec_wan_ac $servername 2>/dev/null
|
||||
ret=$?
|
||||
/usr/bin/ssr-check $servername $serverport $switch_time
|
||||
local ret2=$?
|
||||
if [ "$ret" = "0" ] ;then
|
||||
ipset del ss_spec_wan_ac $servername 2>/dev/null
|
||||
fi
|
||||
if [ "$ret2" = "0" ] ;then
|
||||
server_locate=$server_count
|
||||
ENABLE_SERVER=$1
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
|
||||
}
|
||||
#选择可用的代理
|
||||
select_proxy() {
|
||||
|
||||
config_load $NAME
|
||||
ENABLE_SERVER=nil
|
||||
mkdir -p /var/run /var/etc
|
||||
server_count=0
|
||||
config_foreach search_proxy servers
|
||||
|
||||
}
|
||||
|
||||
#切换代理
|
||||
switch_proxy() {
|
||||
/etc/init.d/shadowsocksr restart $1
|
||||
return 0
|
||||
}
|
||||
|
||||
start() {
|
||||
#不支持kcptun启用时的切换
|
||||
[ $(uci_get_by_name $DEFAULT_SERVER kcp_enable) = "1" ] && return 1
|
||||
|
||||
while [ "1" = "1" ] #死循环
|
||||
do
|
||||
sleep $cycle_time
|
||||
|
||||
LOGTIME=$(date "+%Y-%m-%d %H:%M:%S")
|
||||
|
||||
|
||||
#判断当前代理是否为缺省服务器
|
||||
if [ "$CURRENT_SERVER" != "$DEFAULT_SERVER" ] ;then
|
||||
#echo "not default proxy"
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") Current server is not default Main server, try to switch back." >> /tmp/ssrplus.log
|
||||
|
||||
#检查缺省服务器是否正常
|
||||
if test_proxy $DEFAULT_SERVER ;then
|
||||
#echo "switch to default proxy"
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") Main server is avilable." >> /tmp/ssrplus.log
|
||||
#缺省服务器正常,切换回来
|
||||
CURRENT_SERVER=$DEFAULT_SERVER
|
||||
switch_proxy $CURRENT_SERVER
|
||||
echo "switch to default ["$(uci_get_by_name $CURRENT_SERVER server)"] proxy!" >> /tmp/ssrplus.log
|
||||
continue
|
||||
else
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") Main server is NOT avilable.Continue using current server." >> /tmp/ssrplus.log
|
||||
fi
|
||||
fi
|
||||
|
||||
#判断当前代理是否正常
|
||||
check_proxy
|
||||
current_ret=$?
|
||||
|
||||
if [ "$current_ret" = "1" ] ;then
|
||||
#当前代理错误,判断有无可用的服务器
|
||||
#echo "current error"
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") Current server error, try to switch another server." >> /tmp/ssrplus.log
|
||||
|
||||
select_proxy
|
||||
if [ "$ENABLE_SERVER" != nil ] ;then
|
||||
#有其他服务器可用,进行切换
|
||||
#echo $(uci_get_by_name $new_proxy server)
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") Another server is avilable, now switching server." >> /tmp/ssrplus.log
|
||||
CURRENT_SERVER=$ENABLE_SERVER
|
||||
switch_proxy $CURRENT_SERVER
|
||||
normal_flag=1
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") ShadowsocksR server switch OK" >> /tmp/ssrplus.log
|
||||
else
|
||||
switch_proxy $CURRENT_SERVER
|
||||
normal_flag=1
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") Try restart current server." >> /tmp/ssrplus.log
|
||||
fi
|
||||
else
|
||||
normal_flag=0
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") ShadowsocksR No Problem." >> /tmp/ssrplus.log
|
||||
fi
|
||||
|
||||
|
||||
done
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
{
|
||||
"luci-app-ssr-plus-Jo": {
|
||||
"description": "Grant UCI access for luci-app-ssr-plus-Jo",
|
||||
"read": {
|
||||
"uci": [ "shadowsocksr" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "shadowsocksr" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
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
|
||||
ipset -! flush china
|
||||
ipset -! restore < /tmp/china.ipset 2>/dev/null
|
||||
rm -f /tmp/china.ipset
|
||||
@ -1,38 +0,0 @@
|
||||
local ucursor = require "luci.model.uci".cursor()
|
||||
local json = require "luci.jsonc"
|
||||
local server_section = arg[1]
|
||||
local proto = arg[2]
|
||||
local local_port = arg[3]
|
||||
|
||||
local server = ucursor:get_all("shadowsocksr", server_section)
|
||||
|
||||
local trojan = {
|
||||
|
||||
run_type = "nat",
|
||||
local_addr = "0.0.0.0",
|
||||
local_port = tonumber(local_port),
|
||||
remote_addr = server.server,
|
||||
remote_port = tonumber(server.server_port),
|
||||
-- 传入连接
|
||||
password = {server.password},
|
||||
-- 传出连接
|
||||
ssl = {
|
||||
verify = true,
|
||||
verify_hostname = true,
|
||||
cert = (server.certificate == "1") and server.certpath or "",
|
||||
cipher = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:RSA-AES128-GCM-SHA256:RSA-AES256-GCM-SHA384:RSA-AES128-SHA:RSA-AES256-SHA:RSA-3DES-EDE-SHA",
|
||||
sni = server.tls_host,
|
||||
alpn = {"h2", "http/1.1"},
|
||||
curve = "",
|
||||
reuse_session = true,
|
||||
session_ticket = true,
|
||||
},
|
||||
tcp = {
|
||||
no_delay = true,
|
||||
keep_alive = true,
|
||||
reuse_port = true,
|
||||
fast_open = (server.fast_open == "1") and true or false,
|
||||
fast_open_qlen = 20
|
||||
}
|
||||
}
|
||||
print(json.stringify(trojan, 1))
|
||||
@ -1,176 +0,0 @@
|
||||
local ucursor = require"luci.model.uci".cursor()
|
||||
local name = "shadowsocksr"
|
||||
local json = require "luci.jsonc"
|
||||
local server_section = arg[1]
|
||||
local proto = arg[2]
|
||||
local local_port = arg[3]
|
||||
local host = arg[4]
|
||||
|
||||
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')
|
||||
|
||||
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,
|
||||
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,
|
||||
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", "nflxso.net", "nflxext.com",
|
||||
"nflximg.com", "nflximg.net", "nflxvideo.net"
|
||||
},
|
||||
|
||||
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))
|
||||
@ -1,95 +0,0 @@
|
||||
local ucursor = require "luci.model.uci".cursor()
|
||||
local json = require "luci.jsonc"
|
||||
local server_section = arg[1]
|
||||
local proto = arg[2]
|
||||
local local_port = arg[3]
|
||||
|
||||
local server = ucursor:get_all("shadowsocksr", server_section)
|
||||
|
||||
local v2ray = {
|
||||
log = {
|
||||
-- error = "/var/ssrplus.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 = "0.0.0.0",
|
||||
port = '4433',
|
||||
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
|
||||
} 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 = "" }
|
||||
}
|
||||
}
|
||||
}
|
||||
print(json.stringify(v2ray, 1))
|
||||
@ -1,107 +0,0 @@
|
||||
local ucursor = require "luci.model.uci".cursor()
|
||||
local json = require "luci.jsonc"
|
||||
local server_section = arg[1]
|
||||
local proto = arg[2]
|
||||
local local_port = arg[3]+1
|
||||
local socks_port = arg[4]
|
||||
|
||||
local server = ucursor:get_all("shadowsocksr", server_section)
|
||||
|
||||
local v2ray = {
|
||||
log = {
|
||||
-- error = "/var/ssrplus.log",
|
||||
loglevel = "warning"
|
||||
},
|
||||
-- 传入连接
|
||||
inbound = {
|
||||
port = local_port,
|
||||
protocol = "dokodemo-door",
|
||||
settings = {
|
||||
network = proto,
|
||||
followRedirect = true
|
||||
},
|
||||
sniffing = {
|
||||
enabled = true,
|
||||
destOverride = { "http", "tls" }
|
||||
}
|
||||
},
|
||||
-- 开启 socks 和 http 代理
|
||||
inboundDetour = (proto == "tcp") and {
|
||||
{
|
||||
protocol = "socks",
|
||||
port = socks_port,
|
||||
settings = {
|
||||
auth = "noauth",
|
||||
udp = true
|
||||
}
|
||||
}
|
||||
} or nil,
|
||||
-- 传出连接
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
-- 底层传输配置
|
||||
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
|
||||
} 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 = "" }
|
||||
}
|
||||
}
|
||||
}
|
||||
print(json.stringify(v2ray, 1))
|
||||
@ -1,65 +0,0 @@
|
||||
local ucursor = require "luci.model.uci".cursor()
|
||||
local json = require "luci.jsonc"
|
||||
local server_section = arg[1]
|
||||
local server = ucursor:get_all("shadowsocksr", server_section)
|
||||
|
||||
local v2ray = {
|
||||
log = {
|
||||
--error = "/var/log/v2ray.log",
|
||||
loglevel = "warning"
|
||||
},
|
||||
-- 传入连接
|
||||
inbound = {
|
||||
port = tonumber(server.server_port),
|
||||
protocol = "vmess",
|
||||
settings = {
|
||||
clients = {
|
||||
{
|
||||
id = server.vmess_id,
|
||||
alterId = tonumber(server.alter_id),
|
||||
level = tonumber(server.VMess_level)
|
||||
}
|
||||
}
|
||||
},
|
||||
-- 底层传输配置
|
||||
streamSettings = {
|
||||
network = server.transport,
|
||||
security = (server.tls == '1') and "tls" or "none",
|
||||
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,
|
||||
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
|
||||
}
|
||||
},
|
||||
-- 传出连接
|
||||
outbound = {
|
||||
protocol = "freedom"
|
||||
},
|
||||
-- 额外传出连接
|
||||
outboundDetour = {
|
||||
{
|
||||
protocol = "blackhole",
|
||||
tag = "blocked"
|
||||
}
|
||||
}
|
||||
}
|
||||
print(json.stringify(v2ray,1))
|
||||
@ -1,11 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
mkdir -p /tmp/dnsmasq.ssr
|
||||
|
||||
awk '!/^$/&&!/^#/{printf("ipset=/.%s/'"gfwlist"'\n",$0)}' /etc/config/gfw.list > /tmp/dnsmasq.ssr/custom_forward.conf
|
||||
awk '!/^$/&&!/^#/{printf("server=/.%s/'"127.0.0.1#5335"'\n",$0)}' /etc/config/gfw.list >> /tmp/dnsmasq.ssr/custom_forward.conf
|
||||
|
||||
awk '!/^$/&&!/^#/{printf("ipset=/.%s/'"blacklist"'\n",$0)}' /etc/config/black.list > /tmp/dnsmasq.ssr/blacklist_forward.conf
|
||||
awk '!/^$/&&!/^#/{printf("server=/.%s/'"127.0.0.1#5335"'\n",$0)}' /etc/config/black.list >> /tmp/dnsmasq.ssr/blacklist_forward.conf
|
||||
|
||||
awk '!/^$/&&!/^#/{printf("ipset=/.%s/'"whitelist"'\n",$0)}' /etc/config/white.list > /tmp/dnsmasq.ssr/whitelist_forward.conf
|
||||
@ -1,440 +0,0 @@
|
||||
#!/usr/bin/lua
|
||||
------------------------------------------------
|
||||
-- This file is part of the luci-app-ssr-plus subscribe.lua
|
||||
-- @author William Chan <root@williamchan.me>
|
||||
------------------------------------------------
|
||||
require 'nixio'
|
||||
require 'luci.util'
|
||||
require 'luci.jsonc'
|
||||
require 'luci.sys'
|
||||
|
||||
-- these global functions are accessed all the time by the event handler
|
||||
-- so caching them is worth the effort
|
||||
local luci = luci
|
||||
local tinsert = table.insert
|
||||
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 b64decode = nixio.bin.b64decode
|
||||
local cache = {}
|
||||
local nodeResult = setmetatable({}, { __index = cache }) -- update result
|
||||
local name = 'shadowsocksr'
|
||||
local uciType = 'servers'
|
||||
local ucic = luci.model.uci.cursor()
|
||||
local proxy = ucic:get_first(name, 'server_subscribe', 'proxy', '0')
|
||||
local switch = ucic:get_first(name, 'server_subscribe', 'switch', '1')
|
||||
local subscribe_url = ucic:get_first(name, 'server_subscribe', 'subscribe_url', {})
|
||||
|
||||
local log = function(...)
|
||||
print(os.date("%Y-%m-%d %H:%M:%S ") .. table.concat({ ... }, " "))
|
||||
end
|
||||
-- 分割字符串
|
||||
local function split(full, sep)
|
||||
full = full:gsub("%z", "") -- 这里不是很清楚 有时候结尾带个\0
|
||||
local off, result = 1, {}
|
||||
while true do
|
||||
local nStart, nEnd = full:find(sep, off)
|
||||
if not nEnd then
|
||||
local res = ssub(full, off, slen(full))
|
||||
if #res > 0 then -- 过滤掉 \0
|
||||
tinsert(result, res)
|
||||
end
|
||||
break
|
||||
else
|
||||
tinsert(result, ssub(full, off, nStart - 1))
|
||||
off = nEnd + 1
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
-- urlencode
|
||||
local function get_urlencode(c)
|
||||
return sformat("%%%02X", sbyte(c))
|
||||
end
|
||||
|
||||
local function urlEncode(szText)
|
||||
local str = szText:gsub("([^0-9a-zA-Z ])", get_urlencode)
|
||||
str = str:gsub(" ", "+")
|
||||
return str
|
||||
end
|
||||
|
||||
local function get_urldecode(h)
|
||||
return schar(tonumber(h, 16))
|
||||
end
|
||||
local function UrlDecode(szText)
|
||||
return szText:gsub("+", " "):gsub("%%(%x%x)", get_urldecode)
|
||||
end
|
||||
|
||||
-- trim
|
||||
local function trim(text)
|
||||
if not text or text == "" then
|
||||
return ""
|
||||
end
|
||||
return (sgsub(text, "^%s*(.-)%s*$", "%1"))
|
||||
end
|
||||
-- md5
|
||||
local function md5(content)
|
||||
local stdout = luci.sys.exec('echo \"' .. urlEncode(content) .. '\" | md5sum | cut -d \" \" -f1')
|
||||
-- assert(nixio.errno() == 0)
|
||||
return trim(stdout)
|
||||
end
|
||||
-- base64
|
||||
local function base64Decode(text)
|
||||
local raw = text
|
||||
if not text then return '' end
|
||||
text = text:gsub("%z", "")
|
||||
text = text:gsub("_", "/")
|
||||
text = text:gsub("-", "+")
|
||||
local mod4 = #text % 4
|
||||
text = text .. string.sub('====', mod4 + 1)
|
||||
local result = b64decode(text)
|
||||
if result then
|
||||
return result:gsub("%z", "")
|
||||
else
|
||||
return raw
|
||||
end
|
||||
end
|
||||
-- 处理数据
|
||||
local function processData(szType, content)
|
||||
local result = {
|
||||
type = szType,
|
||||
local_port = 1234,
|
||||
kcp_param = '--nocomp'
|
||||
}
|
||||
if szType == 'ssr' then
|
||||
local dat = split(content, "/%?")
|
||||
local hostInfo = split(dat[1], ':')
|
||||
result.server = hostInfo[1]
|
||||
result.server_port = hostInfo[2]
|
||||
result.protocol = hostInfo[3]
|
||||
result.encrypt_method = hostInfo[4]
|
||||
result.obfs = hostInfo[5]
|
||||
result.password = base64Decode(hostInfo[6])
|
||||
local params = {}
|
||||
for _, v in pairs(split(dat[2], '&')) do
|
||||
local t = split(v, '=')
|
||||
params[t[1]] = t[2]
|
||||
end
|
||||
result.obfs_param = base64Decode(params.obfsparam)
|
||||
result.protocol_param = base64Decode(params.protoparam)
|
||||
local group = base64Decode(params.group)
|
||||
if group then
|
||||
result.alias = "[" .. group .. "] "
|
||||
end
|
||||
result.alias = result.alias .. base64Decode(params.remarks)
|
||||
elseif szType == 'vmess' then
|
||||
local info = jsonParse(content)
|
||||
result.type = 'v2ray'
|
||||
result.server = info.add
|
||||
result.server_port = info.port
|
||||
result.transport = info.net
|
||||
result.alter_id = info.aid
|
||||
result.vmess_id = info.id
|
||||
result.alias = info.ps
|
||||
result.insecure = 1
|
||||
-- result.mux = 1
|
||||
-- result.concurrency = 8
|
||||
if info.net == 'ws' then
|
||||
result.ws_host = info.host
|
||||
result.ws_path = info.path
|
||||
end
|
||||
if info.net == 'h2' then
|
||||
result.h2_host = info.host
|
||||
result.h2_path = info.path
|
||||
end
|
||||
if info.net == 'tcp' then
|
||||
result.tcp_guise = info.type
|
||||
result.http_host = info.host
|
||||
result.http_path = info.path
|
||||
end
|
||||
if info.net == 'kcp' then
|
||||
result.kcp_guise = info.type
|
||||
result.mtu = 1350
|
||||
result.tti = 50
|
||||
result.uplink_capacity = 5
|
||||
result.downlink_capacity = 20
|
||||
result.read_buffer_size = 2
|
||||
result.write_buffer_size = 2
|
||||
end
|
||||
if info.net == 'quic' then
|
||||
result.quic_guise = info.type
|
||||
result.quic_key = info.key
|
||||
result.quic_security = info.securty
|
||||
end
|
||||
if info.security then
|
||||
result.security = info.security
|
||||
end
|
||||
if info.tls == "tls" or info.tls == "1" then
|
||||
result.tls = "1"
|
||||
result.tls_host = info.host
|
||||
else
|
||||
result.tls = "0"
|
||||
end
|
||||
elseif szType == "ss" then
|
||||
local idx_sp = 0
|
||||
local alias = ""
|
||||
if content:find("#") then
|
||||
idx_sp = content:find("#")
|
||||
alias = content:sub(idx_sp + 1, -1)
|
||||
end
|
||||
local info = content:sub(1, idx_sp - 1)
|
||||
local hostInfo = split(base64Decode(info), "@")
|
||||
local host = split(hostInfo[2], ":")
|
||||
local userinfo = base64Decode(hostInfo[1])
|
||||
local method = userinfo:sub(1, userinfo:find(":") - 1)
|
||||
local password = userinfo:sub(userinfo:find(":") + 1, #userinfo)
|
||||
result.alias = UrlDecode(alias)
|
||||
result.type = "ss"
|
||||
result.server = host[1]
|
||||
if host[2]:find("/%?") then
|
||||
local query = split(host[2], "/%?")
|
||||
result.server_port = query[1]
|
||||
local params = {}
|
||||
for _, v in pairs(split(query[2], '&')) do
|
||||
local t = split(v, '=')
|
||||
params[t[1]] = t[2]
|
||||
end
|
||||
if params.plugin then
|
||||
local plugin_info = UrlDecode(params.plugin)
|
||||
local idx_pn = plugin_info:find(";")
|
||||
if idx_pn then
|
||||
result.plugin = plugin_info:sub(1, idx_pn - 1)
|
||||
result.plugin_opts = plugin_info:sub(idx_pn + 1, #plugin_info)
|
||||
else
|
||||
result.plugin = plugin_info
|
||||
end
|
||||
end
|
||||
else
|
||||
result.server_port = host[2]
|
||||
end
|
||||
result.encrypt_method_ss = method
|
||||
result.password = password
|
||||
elseif szType == "ssd" then
|
||||
result.type = "ss"
|
||||
result.server = content.server
|
||||
result.server_port = content.port
|
||||
result.password = content.password
|
||||
result.encrypt_method_ss = content.encryption
|
||||
result.plugin = content.plugin
|
||||
result.plugin_opts = content.plugin_options
|
||||
result.alias = "[" .. content.airport .. "] " .. content.remarks
|
||||
elseif szType == "trojan" then
|
||||
local idx_sp = 0
|
||||
local alias = ""
|
||||
if content:find("#") then
|
||||
idx_sp = content:find("#")
|
||||
alias = content:sub(idx_sp + 1, -1)
|
||||
end
|
||||
local info = content:sub(1, idx_sp - 1)
|
||||
local hostInfo = split(info, "@")
|
||||
local host = split(hostInfo[2], ":")
|
||||
local userinfo = hostInfo[1]
|
||||
local password = userinfo
|
||||
result.alias = UrlDecode(alias)
|
||||
result.type = "trojan"
|
||||
result.server = host[1]
|
||||
-- 按照官方的建议 默认验证ssl证书
|
||||
result.insecure = "0"
|
||||
result.tls = "1"
|
||||
if host[2]:find("?") then
|
||||
local query = split(host[2], "?")
|
||||
result.server_port = query[1]
|
||||
local params = {}
|
||||
for _, v in pairs(split(query[2], '&')) do
|
||||
local t = split(v, '=')
|
||||
params[t[1]] = t[2]
|
||||
end
|
||||
|
||||
if params.peer then
|
||||
-- 未指定peer(sni)默认使用remote addr
|
||||
result.tls_host = params.peer
|
||||
end
|
||||
|
||||
if params.allowInsecure == "1" then
|
||||
result.insecure = "1"
|
||||
else
|
||||
result.insecure = "0"
|
||||
end
|
||||
else
|
||||
result.server_port = host[2]
|
||||
end
|
||||
result.password = password
|
||||
end
|
||||
if not result.alias then
|
||||
result.alias = result.server .. ':' .. result.server_port
|
||||
end
|
||||
|
||||
-- alias 不参与 hashkey 计算
|
||||
local alias = result.alias
|
||||
result.alias = nil
|
||||
local switch_enable = result.switch_enable
|
||||
result.switch_enable = nil
|
||||
result.hashkey = md5(jsonStringify(result))
|
||||
result.alias = alias
|
||||
result.switch_enable = switch_enable
|
||||
return result
|
||||
end
|
||||
-- wget
|
||||
local function wget(url)
|
||||
local stdout = luci.sys.exec('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 10 -O- "' .. url .. '"')
|
||||
return trim(stdout)
|
||||
end
|
||||
|
||||
local execute = function()
|
||||
-- exec
|
||||
do
|
||||
if proxy == '0' then -- 不使用代理更新的话先暂停
|
||||
log('服务正在暂停')
|
||||
luci.sys.init.stop(name)
|
||||
end
|
||||
for k, url in ipairs(subscribe_url) do
|
||||
local raw = wget(url)
|
||||
if #raw > 0 then
|
||||
local nodes, szType
|
||||
local groupHash = md5(url)
|
||||
cache[groupHash] = {}
|
||||
tinsert(nodeResult, {})
|
||||
local index = #nodeResult
|
||||
-- SSD 似乎是这种格式 ssd:// 开头的
|
||||
if raw:find('ssd://') then
|
||||
szType = 'ssd'
|
||||
local nEnd = select(2, raw:find('ssd://'))
|
||||
nodes = base64Decode(raw:sub(nEnd + 1, #raw))
|
||||
nodes = jsonParse(nodes)
|
||||
local extra = {
|
||||
airport = nodes.airport,
|
||||
port = nodes.port,
|
||||
encryption = nodes.encryption,
|
||||
password = nodes.password
|
||||
}
|
||||
local servers = {}
|
||||
-- SS里面包着 干脆直接这样
|
||||
for _, server in ipairs(nodes.servers) do
|
||||
tinsert(servers, setmetatable(server, { __index = extra }))
|
||||
end
|
||||
nodes = servers
|
||||
else
|
||||
-- ssd 外的格式
|
||||
nodes = split(base64Decode(raw):gsub(" ", "\n"), "\n")
|
||||
end
|
||||
for _, v in ipairs(nodes) do
|
||||
if v then
|
||||
local result
|
||||
if szType == 'ssd' then
|
||||
result = processData(szType, v)
|
||||
elseif not szType then
|
||||
local node = trim(v)
|
||||
local dat = split(node, "://")
|
||||
if dat and dat[1] and dat[2] then
|
||||
if dat[1] == 'ss' or dat[1] == 'trojan' then
|
||||
result = processData(dat[1], dat[2])
|
||||
else
|
||||
result = processData(dat[1], base64Decode(dat[2]))
|
||||
end
|
||||
end
|
||||
else
|
||||
log('跳过未知类型: ' .. szType)
|
||||
end
|
||||
-- log(result)
|
||||
if result then
|
||||
if result.alias:find("过期时间") or
|
||||
result.alias:find("剩余流量") or
|
||||
result.alias:find("QQ群") or
|
||||
result.alias:find("官网") or
|
||||
result.alias:find("防失联地址") or
|
||||
not result.server or
|
||||
result.server:match("[^0-9a-zA-Z%-%.%s]") -- 中文做地址的 也没有人拿中文域名搞,就算中文域也有Puny Code SB 机场
|
||||
then
|
||||
log('丢弃无效节点: ' .. result.type ..' 节点, ' .. result.alias)
|
||||
else
|
||||
log('成功解析: ' .. result.type ..' 节点, ' .. result.alias)
|
||||
result.grouphashkey = groupHash
|
||||
tinsert(nodeResult[index], result)
|
||||
cache[groupHash][result.hashkey] = nodeResult[index][#nodeResult[index]]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
log('成功解析节点数量: ' ..#nodes)
|
||||
else
|
||||
log(url .. ': 获取内容为空')
|
||||
end
|
||||
end
|
||||
end
|
||||
-- diff
|
||||
do
|
||||
if next(nodeResult) == nil then
|
||||
log("更新失败,没有可用的节点信息")
|
||||
return
|
||||
end
|
||||
local add, del = 0, 0
|
||||
ucic:foreach(name, uciType, function(old)
|
||||
if old.grouphashkey or old.hashkey then -- 没有 hash 的不参与删除
|
||||
if not nodeResult[old.grouphashkey] or not nodeResult[old.grouphashkey][old.hashkey] then
|
||||
ucic:delete(name, old['.name'])
|
||||
del = del + 1
|
||||
else
|
||||
local dat = nodeResult[old.grouphashkey][old.hashkey]
|
||||
ucic:tset(name, old['.name'], dat)
|
||||
-- 标记一下
|
||||
setmetatable(nodeResult[old.grouphashkey][old.hashkey], { __index = { _ignore = true } })
|
||||
end
|
||||
else
|
||||
if not old.alias then
|
||||
old.alias = old.server .. ':' .. old.server_port
|
||||
end
|
||||
log('忽略手动添加的节点: ' .. old.alias)
|
||||
end
|
||||
|
||||
end)
|
||||
for k, v in ipairs(nodeResult) do
|
||||
for kk, vv in ipairs(v) do
|
||||
if not vv._ignore then
|
||||
local section = ucic:add(name, uciType)
|
||||
ucic:tset(name, section, vv)
|
||||
ucic:set(name, section, "switch_enable", switch)
|
||||
add = add + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
ucic:commit(name)
|
||||
-- 如果原有服务器节点已经不见了就尝试换为第一个节点
|
||||
local globalServer = ucic:get_first(name, 'global', 'global_server', '')
|
||||
local firstServer = ucic:get_first(name, uciType)
|
||||
if firstServer then
|
||||
if not ucic:get(name, globalServer) then
|
||||
luci.sys.call("/etc/init.d/" .. name .. " stop > /dev/null 2>&1 &")
|
||||
ucic:commit(name)
|
||||
ucic:set(name, ucic:get_first(name, 'global'), 'global_server', ucic:get_first(name, uciType))
|
||||
ucic:commit(name)
|
||||
log('当前主服务器节点已被删除,正在自动更换为第一个节点。')
|
||||
luci.sys.call("/etc/init.d/" .. name .. " start > /dev/null 2>&1 &")
|
||||
else
|
||||
log('维持当前主服务器节点。')
|
||||
luci.sys.call("/etc/init.d/" .. name .." restart > /dev/null 2>&1 &")
|
||||
end
|
||||
else
|
||||
log('没有服务器节点了,停止服务')
|
||||
luci.sys.call("/etc/init.d/" .. name .. " stop > /dev/null 2>&1 &")
|
||||
end
|
||||
log('新增节点数量: ' ..add, '删除节点数量: ' .. del)
|
||||
log("END SUBSCRIBE")
|
||||
log('订阅更新成功')
|
||||
end
|
||||
end
|
||||
|
||||
if subscribe_url and #subscribe_url > 0 then
|
||||
xpcall(execute, function(e)
|
||||
log(e)
|
||||
log(debug.traceback())
|
||||
log("END SUBSCRIBE")
|
||||
log('发生错误, 正在恢复服务')
|
||||
local firstServer = ucic:get_first(name, uciType)
|
||||
if firstServer then
|
||||
luci.sys.call("/etc/init.d/" .. name .." restart > /dev/null 2>&1 &") -- 不加&的话日志会出现的更早
|
||||
log('重启服务成功')
|
||||
else
|
||||
luci.sys.call("/etc/init.d/" .. name .." stop > /dev/null 2>&1 &") -- 不加&的话日志会出现的更早
|
||||
log('停止服务成功')
|
||||
end
|
||||
end)
|
||||
end
|
||||
@ -1,260 +0,0 @@
|
||||
#!/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=shadowsocksr
|
||||
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
|
||||
@ -1,25 +0,0 @@
|
||||
#!/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/shadowsocksr/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/shadowsocksr restart
|
||||
@ -1,106 +0,0 @@
|
||||
#!/bin/sh
|
||||
logfile="/tmp/ssrplus.log"
|
||||
dir="/usr/share/v2ray/"
|
||||
v2ray_new_version=$(wget -qO- "https://github.com/v2ray/v2ray-core/tags"| grep "/v2ray/v2ray-core/releases/tag/"| head -n 1| awk -F "/tag/v" '{print $2}'| sed 's/\">//')
|
||||
echo "$v2ray_new_version" > ${dir}v2ray_new_version
|
||||
if [ $? -eq 0 ];then
|
||||
edition=$(uci get shadowsocksr.@server_subscribe[0].edition 2>/dev/null)
|
||||
if [ "$edition" = "auto_detected" ];then
|
||||
v2ray_new_version=$(cat ${dir}v2ray_new_version|sed -n '1p')
|
||||
else
|
||||
v2ray_new_version=$edition
|
||||
fi
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") v2ray自动更新启动,验证版本..." >> ${logfile}
|
||||
mem_mode=$(uci get shadowsocksr.@server_subscribe[0].mem_mode 2>/dev/null)
|
||||
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") 检测到v2ray版本为$v2ray_new_version..." >> ${logfile}
|
||||
|
||||
UpdateApp() {
|
||||
for a in $(opkg print-architecture | awk '{print $2}'); do
|
||||
case "$a" in
|
||||
all|noarch)
|
||||
;;
|
||||
aarch64_armv8-a|arm_arm1176jzf-s_vfp|arm_arm926ej-s|arm_cortex-a15_neon-vfpv4|arm_cortex-a5|arm_cortex-a53_neon-vfpv4|arm_cortex-a7_neon-vfpv4|arm_cortex-a8_vfpv3|arm_cortex-a9|arm_cortex-a9_neon|arm_cortex-a9_vfpv3|arm_fa526|arm_mpcore|arm_mpcore_vfp|arm_xscale|armeb_xscale)
|
||||
ARCH="arm"
|
||||
;;
|
||||
i386_pentium|i386_pentium4)
|
||||
ARCH="32"
|
||||
;;
|
||||
ar71xx|mips_24kc|mips_mips32|mips64_octeon)
|
||||
ARCH="mips"
|
||||
;;
|
||||
mipsel_24kc|mipsel_24kec_dsp|mipsel_74kc|mipsel_mips32|mipsel_1004kc_dsp)
|
||||
ARCH="mipsle"
|
||||
;;
|
||||
x86_64)
|
||||
ARCH="64"
|
||||
;;
|
||||
*)
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
download_binary(){
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") 开始下载v2ray二进制文件..." >> ${logfile}
|
||||
rm -rf $bin_dir/v2ray*.zip
|
||||
bin_dir="/tmp"
|
||||
UpdateApp
|
||||
cd $bin_dir
|
||||
down_url=https://github.com/v2ray/v2ray-core/releases/download/v"$v2ray_new_version"/v2ray-linux-"$ARCH".zip
|
||||
|
||||
local a=0
|
||||
while [ ! -f $bin_dir/v2ray-linux-"$ARCH"*.zip ]; do
|
||||
[ $a = 6 ] && exit
|
||||
/usr/bin/wget -T10 $down_url
|
||||
sleep 2
|
||||
let "a = a + 1"
|
||||
done
|
||||
|
||||
if [ -f $bin_dir/v2ray-linux-"$ARCH"*.zip ]; then
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") 成功下载v2ray二进制文件" >> ${logfile}
|
||||
killall -q -9 v2ray
|
||||
|
||||
if [ ! -d "/usr/bin/v2ray/" ]; then
|
||||
mkdir -p /usr/bin/v2ray
|
||||
fi
|
||||
unzip -o v2ray-linux-"$ARCH"*.zip -d $bin_dir/v2ray-v"$v2ray_new_version"-linux-"$ARCH"/
|
||||
mem_mode=$(uci get shadowsocksr.@server_subscribe[0].mem_mode 2>/dev/null)
|
||||
if [ $mem_mode -eq 1 ]; then
|
||||
if [ -f /usr/bin/v2ray/v2ray ]; then
|
||||
rm -rf /usr/bin/v2ray/*
|
||||
rm -rf $bin_dir/v2ray-v"$v2ray_new_version"-linux-"$ARCH"
|
||||
fi
|
||||
chmod +x $bin_dir/v2ray-v"$v2ray_new_version"-linux-"$ARCH"/v2*
|
||||
ln -s $bin_dir/v2ray-v"$v2ray_new_version"-linux-"$ARCH"/v2ray /usr/bin/v2ray/
|
||||
ln -s $bin_dir/v2ray-v"$v2ray_new_version"-linux-"$ARCH"/v2ctl /usr/bin/v2ray/
|
||||
ln -s $bin_dir/v2ray-v"$v2ray_new_version"-linux-"$ARCH"/geoip.dat /usr/bin/v2ray/
|
||||
ln -s $bin_dir/v2ray-v"$v2ray_new_version"-linux-"$ARCH"/geosite.dat /usr/bin/v2ray/
|
||||
else
|
||||
if [ -f /usr/bin/v2ray/v2ray ]; then
|
||||
rm -rf /usr/bin/v2ray/*
|
||||
fi
|
||||
mv $bin_dir/v2ray-v"$v2ray_new_version"-linux-"$ARCH"/v2ray /usr/bin/v2ray/
|
||||
mv $bin_dir/v2ray-v"$v2ray_new_version"-linux-"$ARCH"/v2ctl /usr/bin/v2ray/
|
||||
mv $bin_dir/v2ray-v"$v2ray_new_version"-linux-"$ARCH"/geoip.dat /usr/bin/v2ray/
|
||||
mv $bin_dir/v2ray-v"$v2ray_new_version"-linux-"$ARCH"/geosite.dat /usr/bin/v2ray/
|
||||
rm -rf $bin_dir/v2ray-v"$v2ray_new_version"-linux-"$ARCH"
|
||||
fi
|
||||
rm -rf $bin_dir/v2ray*.zip
|
||||
if [ -f "/usr/bin/v2ray/v2ray" ]; then
|
||||
chmod +x /usr/bin/v2ray/v2*
|
||||
/etc/init.d/shadowsocksr restart
|
||||
fi
|
||||
else
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") 下载v2ray二进制文件失败,请重试!" >> ${logfile}
|
||||
fi
|
||||
|
||||
|
||||
}
|
||||
|
||||
download_binary
|
||||
echo "" > ${dir}v2ray_version
|
||||
echo "$v2ray_new_version" > ${dir}v2ray_version
|
||||
rm -rf ${dir}v2ray_new_version
|
||||
fi
|
||||
@ -1,704 +0,0 @@
|
||||
@import url("flag-icon.min.css");
|
||||
|
||||
/*!
|
||||
Pure v1.0.1
|
||||
Copyright 2013 Yahoo!
|
||||
Licensed under the BSD License.
|
||||
https://github.com/pure-css/pure/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
|
||||
.pure-g {
|
||||
letter-spacing: -.31em;
|
||||
text-rendering: optimizespeed;
|
||||
font-family: FreeSans, Arimo, "Droid Sans", Helvetica, Arial, sans-serif;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-orient: horizontal;
|
||||
-webkit-box-direction: normal;
|
||||
-webkit-flex-flow: row wrap;
|
||||
-ms-flex-flow: row wrap;
|
||||
flex-flow: row wrap;
|
||||
-webkit-align-content: flex-start;
|
||||
-ms-flex-line-pack: start;
|
||||
align-content: flex-start
|
||||
}
|
||||
|
||||
@media all and (-ms-high-contrast:none),
|
||||
(-ms-high-contrast:active) {
|
||||
table .pure-g {
|
||||
display: block
|
||||
}
|
||||
}
|
||||
|
||||
.opera-only :-o-prefocus,
|
||||
.pure-g {
|
||||
word-spacing: -.43em
|
||||
}
|
||||
|
||||
.pure-u {
|
||||
display: inline-block;
|
||||
zoom: 1;
|
||||
letter-spacing: normal;
|
||||
word-spacing: normal;
|
||||
vertical-align: top;
|
||||
text-rendering: auto
|
||||
}
|
||||
|
||||
.pure-g [class*=pure-u] {
|
||||
font-family: sans-serif
|
||||
}
|
||||
|
||||
.pure-u-1,
|
||||
.pure-u-1-1,
|
||||
.pure-u-1-12,
|
||||
.pure-u-1-2,
|
||||
.pure-u-1-24,
|
||||
.pure-u-1-3,
|
||||
.pure-u-1-4,
|
||||
.pure-u-1-5,
|
||||
.pure-u-1-6,
|
||||
.pure-u-1-8,
|
||||
.pure-u-10-24,
|
||||
.pure-u-11-12,
|
||||
.pure-u-11-24,
|
||||
.pure-u-12-24,
|
||||
.pure-u-13-24,
|
||||
.pure-u-14-24,
|
||||
.pure-u-15-24,
|
||||
.pure-u-16-24,
|
||||
.pure-u-17-24,
|
||||
.pure-u-18-24,
|
||||
.pure-u-19-24,
|
||||
.pure-u-2-24,
|
||||
.pure-u-2-3,
|
||||
.pure-u-2-5,
|
||||
.pure-u-20-24,
|
||||
.pure-u-21-24,
|
||||
.pure-u-22-24,
|
||||
.pure-u-23-24,
|
||||
.pure-u-24-24,
|
||||
.pure-u-3-24,
|
||||
.pure-u-3-4,
|
||||
.pure-u-3-5,
|
||||
.pure-u-3-8,
|
||||
.pure-u-4-24,
|
||||
.pure-u-4-5,
|
||||
.pure-u-5-12,
|
||||
.pure-u-5-24,
|
||||
.pure-u-5-5,
|
||||
.pure-u-5-6,
|
||||
.pure-u-5-8,
|
||||
.pure-u-6-24,
|
||||
.pure-u-7-12,
|
||||
.pure-u-7-24,
|
||||
.pure-u-7-8,
|
||||
.pure-u-8-24,
|
||||
.pure-u-9-24 {
|
||||
display: inline-block;
|
||||
zoom: 1;
|
||||
letter-spacing: normal;
|
||||
word-spacing: normal;
|
||||
vertical-align: top;
|
||||
text-rendering: auto
|
||||
}
|
||||
|
||||
.pure-u-1-24 {
|
||||
width: 4.1667%
|
||||
}
|
||||
|
||||
.pure-u-1-12,
|
||||
.pure-u-2-24 {
|
||||
width: 8.3333%
|
||||
}
|
||||
|
||||
.pure-u-1-8,
|
||||
.pure-u-3-24 {
|
||||
width: 12.5%
|
||||
}
|
||||
|
||||
.pure-u-1-6,
|
||||
.pure-u-4-24 {
|
||||
width: 16.6667%
|
||||
}
|
||||
|
||||
.pure-u-1-5 {
|
||||
width: 20%
|
||||
}
|
||||
|
||||
.pure-u-5-24 {
|
||||
width: 20.8333%
|
||||
}
|
||||
|
||||
.pure-u-1-4,
|
||||
.pure-u-6-24 {
|
||||
width: 25%
|
||||
}
|
||||
|
||||
.pure-u-7-24 {
|
||||
width: 29.1667%
|
||||
}
|
||||
|
||||
.pure-u-1-3,
|
||||
.pure-u-8-24 {
|
||||
width: 33.3333%
|
||||
}
|
||||
|
||||
.pure-u-3-8,
|
||||
.pure-u-9-24 {
|
||||
width: 37.5%
|
||||
}
|
||||
|
||||
.pure-u-2-5 {
|
||||
width: 40%
|
||||
}
|
||||
|
||||
.pure-u-10-24,
|
||||
.pure-u-5-12 {
|
||||
width: 41.6667%
|
||||
}
|
||||
|
||||
.pure-u-11-24 {
|
||||
width: 45.8333%
|
||||
}
|
||||
|
||||
.pure-u-1-2,
|
||||
.pure-u-12-24 {
|
||||
width: 50%
|
||||
}
|
||||
|
||||
.pure-u-13-24 {
|
||||
width: 54.1667%
|
||||
}
|
||||
|
||||
.pure-u-14-24,
|
||||
.pure-u-7-12 {
|
||||
width: 58.3333%
|
||||
}
|
||||
|
||||
.pure-u-3-5 {
|
||||
width: 60%
|
||||
}
|
||||
|
||||
.pure-u-15-24,
|
||||
.pure-u-5-8 {
|
||||
width: 62.5%
|
||||
}
|
||||
|
||||
.pure-u-16-24,
|
||||
.pure-u-2-3 {
|
||||
width: 66.6667%
|
||||
}
|
||||
|
||||
.pure-u-17-24 {
|
||||
width: 70.8333%
|
||||
}
|
||||
|
||||
.pure-u-18-24,
|
||||
.pure-u-3-4 {
|
||||
width: 75%
|
||||
}
|
||||
|
||||
.pure-u-19-24 {
|
||||
width: 79.1667%
|
||||
}
|
||||
|
||||
.pure-u-4-5 {
|
||||
width: 80%
|
||||
}
|
||||
|
||||
.pure-u-20-24,
|
||||
.pure-u-5-6 {
|
||||
width: 83.3333%
|
||||
}
|
||||
|
||||
.pure-u-21-24,
|
||||
.pure-u-7-8 {
|
||||
width: 87.5%
|
||||
}
|
||||
|
||||
.pure-u-11-12,
|
||||
.pure-u-22-24 {
|
||||
width: 91.6667%
|
||||
}
|
||||
|
||||
.pure-u-23-24 {
|
||||
width: 95.8333%
|
||||
}
|
||||
|
||||
.pure-u-1,
|
||||
.pure-u-1-1,
|
||||
.pure-u-24-24,
|
||||
.pure-u-5-5 {
|
||||
width: 100%
|
||||
}
|
||||
|
||||
.status {
|
||||
margin: 1rem -0.5rem 1rem -0.5rem;
|
||||
}
|
||||
|
||||
.block {
|
||||
margin: 0.5rem 0.5rem;
|
||||
padding: 0;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
line-height: 1;
|
||||
font-family: inherit;
|
||||
min-width: inherit;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
border: 1px solid rgba(0, 0, 0, .05);
|
||||
border-radius: .500rem;
|
||||
background-color: #f4;
|
||||
box-shadow: 0 0 2rem 0 rgba(136, 152, 170, .15);
|
||||
}
|
||||
|
||||
.img-con {
|
||||
margin: 1rem;
|
||||
|
||||
}
|
||||
.pure-img{
|
||||
max-height: 100%;
|
||||
width: auto;
|
||||
}
|
||||
.green {
|
||||
font-size: 1.25rem;
|
||||
color: #2dce89;
|
||||
}
|
||||
|
||||
.red {
|
||||
font-size: 1.25rem;
|
||||
color: #fb6340;
|
||||
}
|
||||
|
||||
.sk-text-success {
|
||||
color: #2dce89;
|
||||
}
|
||||
|
||||
.sk-text-error {
|
||||
color: #fb6340;
|
||||
}
|
||||
|
||||
.gap {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.block img {
|
||||
width: 48px;
|
||||
height: auto;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.pure-u-5-8 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
}
|
||||
|
||||
.block h4 {
|
||||
font-size: .8125rem;
|
||||
font-weight: 600;
|
||||
margin: 1rem;
|
||||
color: #8898aa !important;
|
||||
line-height: 1.8em;
|
||||
}
|
||||
.p-in5{
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.cbi-section-table-row {
|
||||
position: relative;
|
||||
background: #f4;
|
||||
margin: 10px;
|
||||
padding: 8px 15px 10px 70px;
|
||||
box-shadow: 0 0 1rem 0 rgba(136,152,170,.75);
|
||||
border-radius: .5rem;
|
||||
border: 0;
|
||||
color: #fff;
|
||||
text-align: left;
|
||||
line-height: 1.7em;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
transition: all 0.3s;
|
||||
|
||||
}
|
||||
.cbi-section-table-row:hover{
|
||||
background: #fff;
|
||||
|
||||
}
|
||||
|
||||
.cbi-section-table-row.fast{
|
||||
background: #5e72e4;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.cbi-section-table-row.fast .ssr-button{
|
||||
color: #fff;
|
||||
}
|
||||
.cbi-section-table-row.fast .ssr-button:hover,
|
||||
.cbi-section-table-row.fast .ssr-button:focus,
|
||||
.cbi-section-table-row.fast .ssr-button:active {
|
||||
color: #fff;
|
||||
outline: 0;
|
||||
text-decoration: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.host_con.fast {
|
||||
color: #6f9a37;
|
||||
}
|
||||
|
||||
.host_con.nopass {
|
||||
color: #dc3545;
|
||||
}
|
||||
|
||||
.host_con.middle {
|
||||
color: #fbc658;
|
||||
}
|
||||
|
||||
.host_con.slow {
|
||||
color: #fb6340;
|
||||
}
|
||||
|
||||
.loadings {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
border-radius: .5rem;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 30px;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.loadings.hide {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.loadings span {
|
||||
animation: anim-rotate 2s infinite linear;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
|
||||
.alias{
|
||||
margin-bottom:1px;
|
||||
}
|
||||
.incon:nth-child(2) {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 61px;
|
||||
height: 100%;
|
||||
border: 0;
|
||||
border-right: #d1dfed 1px solid;
|
||||
background-position: top;
|
||||
|
||||
}
|
||||
.incon:nth-child(2) .tp{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
height: 25%;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
line-height: 15px;
|
||||
color: #fff;
|
||||
background: #525f7f;
|
||||
}
|
||||
|
||||
.incon:nth-child(3) {
|
||||
padding-left: 0px;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.incon:nth-child(5),
|
||||
.incon:nth-child(6) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.cbi-section-table-cell {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.ssr-button {
|
||||
background: none;
|
||||
color: #525f7f;
|
||||
padding: 0 0 0 6px;
|
||||
height: auto;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
.ssr-button:hover,
|
||||
.ssr-button:focus,
|
||||
.ssr-button:active {
|
||||
color: #525f7f;
|
||||
outline: 0;
|
||||
text-decoration: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.cbi-section h3 {
|
||||
margin-left: 10px;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
|
||||
.cbi-button-check {
|
||||
color: #fff !important;
|
||||
background-color: #336633 !important;
|
||||
border-color: #2e6da4 !important;
|
||||
font-size:12px;
|
||||
padding:0.5rem 0.8rem;
|
||||
float:right;
|
||||
margin-right:10px;
|
||||
margin-top:0rem;
|
||||
|
||||
}
|
||||
|
||||
.cbi-section-table-cell {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.host_con {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 50px;
|
||||
text-align: left;
|
||||
height: 22px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.host_ok {
|
||||
color: #fff;
|
||||
background: #2dce89;
|
||||
padding: 0.1rem 0.5rem;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
|
||||
.host_error {
|
||||
color: #fff;
|
||||
background: #f5365c;
|
||||
padding: 0.1rem 0.5rem;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
footer.mobile-hide{
|
||||
display: block;
|
||||
}
|
||||
.cbi-button-add{
|
||||
position:fixed;
|
||||
padding: 0.3rem 0.5rem;
|
||||
z-index:1000;
|
||||
width:70px !important;
|
||||
height:70px;
|
||||
bottom:90px;
|
||||
right:55px;
|
||||
font-size:20px;
|
||||
border-radius:50%;
|
||||
display:block;
|
||||
background-color: #336633!important;
|
||||
border-color: #CC6699 !important;
|
||||
box-shadow: 0 0 1rem 0 rgba(136,152,170,.75);
|
||||
}
|
||||
|
||||
|
||||
.mar-10 {margin-left: 50px; margin-right: 10px;}
|
||||
|
||||
.status-bar{
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
box-shadow: 0 0 2rem 0 rgba(136,152,170,.3);
|
||||
color: #525f7f;
|
||||
background: #fff;
|
||||
z-index: 5;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.status-bar .inner{
|
||||
margin: 1em;
|
||||
}
|
||||
|
||||
.status-bar .inner .flag{
|
||||
height: 3em;
|
||||
display: block;
|
||||
float: left;
|
||||
margin-right: 1em;
|
||||
}
|
||||
.status-bar .icon-con{
|
||||
height: 3em;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@media screen and (max-width: 1900px) {
|
||||
.pure-u-1-5 {
|
||||
width: 25%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1600px) {
|
||||
.pure-u-1-5 {
|
||||
width: 33.33333333%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1200px) {
|
||||
.pure-u-1-5 {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.status .pure-u-1-5 {
|
||||
width: 33.333%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 700px) {
|
||||
.pure-u-1-4 {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.pure-u-1-2 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.pure-u-1-5 {
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.status .pure-u-1-5 {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.cbi-button-add {
|
||||
position: fixed;
|
||||
padding: 0.3rem 0.5rem;
|
||||
z-index: 1000;
|
||||
width: 50px !important;
|
||||
height: 50px;
|
||||
bottom: 90px;
|
||||
right: 5px;
|
||||
font-size: 16px;
|
||||
border-radius: 50%;
|
||||
display: block;
|
||||
background-color: #fb6340!important;
|
||||
border-color: #fb6340 !important;
|
||||
box-shadow: 0 0 1rem 0 rgba(136, 152, 170, .75);
|
||||
}
|
||||
}
|
||||
|
||||
.modals-bg {
|
||||
position: fixed;
|
||||
z-index: 999;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
display: none;
|
||||
}
|
||||
|
||||
.modals {
|
||||
position: fixed;
|
||||
z-index: 100;
|
||||
width: 60%;
|
||||
height: 500px;
|
||||
background: #172b4d;
|
||||
left: 20%;
|
||||
top: 15%;
|
||||
color: #fff;
|
||||
border-radius: 10px;
|
||||
padding: 20px;
|
||||
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
/* Firefox */
|
||||
-webkit-box-sizing: border-box;
|
||||
/* Safari */
|
||||
}
|
||||
|
||||
.modals h2 {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.modals h3 {
|
||||
font-size: 14px;
|
||||
color: #f5365c !important;
|
||||
background: transparent;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#log_content3 {
|
||||
border: 0;
|
||||
width: 99%;
|
||||
height: calc(100% - 4rem);
|
||||
font-family: 'Lucida Console';
|
||||
font-size: 11px;
|
||||
background: transparent;
|
||||
color: #FFFFFF;
|
||||
outline: none;
|
||||
padding-left: 3px;
|
||||
padding-right: 22px;
|
||||
overflow: hidden
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
.modals {
|
||||
position: fixed;
|
||||
z-index: 100;
|
||||
width: 80%;
|
||||
height: 500px;
|
||||
background: #172b4d;
|
||||
left: 10%;
|
||||
top: 15%;
|
||||
color: #fff;
|
||||
border-radius: 10px;
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 700px) {
|
||||
.modals-bg {
|
||||
position: fixed;
|
||||
z-index: 100000;
|
||||
|
||||
}
|
||||
|
||||
.modals {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
.status-bar .pure-u-1-2{
|
||||
width: 50%;
|
||||
}
|
||||
.status-bar .inner .flag{
|
||||
height: 3em;
|
||||
display: block;
|
||||
float: left;
|
||||
margin-right: 1em;
|
||||
}
|
||||
.status-bar .icon-con{
|
||||
height: 2.5em;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
@ -1,201 +0,0 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-vssr
|
||||
PKG_VERSION:=1.32
|
||||
PKG_RELEASE:=4-20200331
|
||||
|
||||
PKG_CONFIG_DEPENDS:= CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Trojan \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun:kcptun \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Server \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Socks \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Socks \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ipt2socks \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_microsocks \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_dns2socks \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_dnscrypt_proxy \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_dnsforwarder \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_haproxy \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_udpspeeder \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_udp2raw-tunnel \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_privoxy \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_simple-obfs\
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_simple-obfs-server\
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_GoQuiet-client\
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_GoQuiet-server\
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_v2ray-plugin
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/$(PKG_NAME)/config
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks
|
||||
bool "Include Shadowsocks New Version"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray
|
||||
bool "Include V2ray"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Trojan
|
||||
bool "Include Trojan"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun
|
||||
bool "Include Kcptun"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server
|
||||
bool "Include ShadowsocksR Server"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Server
|
||||
bool "Include Shadowsocks Server"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Socks
|
||||
bool "Include ShadowsocksR Socks and Tunnel"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Socks
|
||||
bool "Include Shadowsocks Socks and Tunnel"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_ipt2socks
|
||||
bool "Include ipt2socks"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_microsocks
|
||||
bool "Include microsocks"
|
||||
default n
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_dns2socks
|
||||
bool "Include dns2socks"
|
||||
default n
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_dnscrypt_proxy
|
||||
bool "Include dnscrypt-proxy-full"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_dnsforwarder
|
||||
bool "Include dnsforwarder"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS
|
||||
bool "Include chinadns"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_haproxy
|
||||
bool "Include haproxy"
|
||||
default n
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_privoxy
|
||||
bool "Include privoxy http local"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_simple-obfs
|
||||
bool "Include simple-obfsl"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_simple-obfs-server
|
||||
bool "Include simple-obfs-server"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_udpspeeder
|
||||
bool "Include udpspeeder"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_udp2raw-tunnel
|
||||
bool "Include udp2raw-tunnel"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_GoQuiet-client
|
||||
bool "Include GoQuiet-client"
|
||||
default n
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_GoQuiet-server
|
||||
bool "Include GoQuiet-server"
|
||||
default n
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_v2ray-plugin
|
||||
bool "Include v2ray-plugin"
|
||||
default y
|
||||
endef
|
||||
|
||||
define Package/luci-app-vssr
|
||||
SECTION:=luci
|
||||
CATEGORY:=LuCI
|
||||
SUBMENU:=3. Applications
|
||||
TITLE:=A New SS/SSR/V2Ray/Trojan LuCI interface
|
||||
PKGARCH:=all
|
||||
DEPENDS:=+shadowsocksr-libev-alt +ipset +ip-full +iptables-mod-tproxy +dnsmasq-full +coreutils +coreutils-base64 +bash +pdnsd-alt +wget +tcpping +lua-maxminddb +lua +luasocket +jshn +lua-cjson +coreutils-nohup +curl \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks:shadowsocks-libev-ss-redir \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:v2ray \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan:trojan \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun:kcptun-client \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server:shadowsocksr-libev-server \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Server:shadowsocks-libev-ss-server \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Socks:shadowsocksr-libev-ssr-local \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Socks:shadowsocks-libev-ss-local \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_ipt2socks:ipt2socks \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_microsocks:microsocks \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_dns2socks:dns2socks \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_dnscrypt_proxy:dnscrypt-proxy-full \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_dnsforwarder:dnsforwarder \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS:openwrt_chinadns \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_haproxy:haproxy \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_privoxy:privoxy \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_udpspeeder:speederv2-tunnel \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_udp2raw-tunnel:udp2raw-tunnel \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_simple-obfs:simple-obfs \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_simple-obfs-server:simple-obfs-server \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_GoQuiet-client:gq-client \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_GoQuiet-server:gq-server \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_v2ray-plugin:v2ray-plugin
|
||||
endef
|
||||
|
||||
define Build/Prepare
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/luci-app-vssr/conffiles
|
||||
/etc/ssr_ip
|
||||
/etc/dnsmasq.vssr/gfw_list.conf
|
||||
endef
|
||||
|
||||
define Package/luci-app-vssr/install
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/luci
|
||||
cp -pR ./luasrc/* $(1)/usr/lib/lua/luci
|
||||
$(INSTALL_DIR) $(1)/
|
||||
cp -pR ./root/* $(1)/
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/i18n
|
||||
po2lmo ./po/zh_Hans/vssr.po $(1)/usr/lib/lua/luci/i18n/vssr.zh-cn.lmo
|
||||
endef
|
||||
|
||||
define Package/luci-app-vssr/postinst
|
||||
#!/bin/sh
|
||||
if [ -z "$${IPKG_INSTROOT}" ]; then
|
||||
( . /etc/uci-defaults/luci-vssr ) && rm -f /etc/uci-defaults/luci-vssr
|
||||
rm -f /tmp/luci-indexcache
|
||||
chmod 755 /etc/init.d/vssr >/dev/null 2>&1
|
||||
/etc/init.d/vssr enable >/dev/null 2>&1
|
||||
fi
|
||||
exit 0
|
||||
endef
|
||||
|
||||
define Package/luci-app-vssr/prerm
|
||||
#!/bin/sh
|
||||
if [ -z "$${IPKG_INSTROOT}" ]; then
|
||||
/etc/init.d/vssr disable
|
||||
/etc/init.d/vssr stop
|
||||
fi
|
||||
exit 0
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,luci-app-vssr))
|
||||
|
||||
|
||||
@ -1,478 +0,0 @@
|
||||
-- Copyright (C) 2018 jerrykuku <jerrykuku@qq.com>
|
||||
-- Licensed to the public under the GNU General Public License v3.
|
||||
module("luci.controller.vssr", package.seeall)
|
||||
|
||||
function index()
|
||||
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", "vssr"},alias("admin", "vpn", "vssr", "client"), _("Hello World"), 10).dependent=true
|
||||
entry({"admin", "vpn", "vssr", "client"}, cbi("vssr/client"), _("SSR Client"), 10).leaf=true
|
||||
entry({"admin", "vpn", "vssr", "servers"}, cbi("vssr/servers"), _("Node List"), 20).leaf=true
|
||||
entry({"admin", "vpn", "vssr", "servers"}, arcombine(cbi("vssr/servers"), cbi("vssr/client-config")), _("Node List"), 20).leaf =true
|
||||
entry({"admin", "vpn", "vssr", "subscription"},cbi("vssr/subscription"),_("Subscription"),30).leaf=true
|
||||
entry({"admin", "vpn", "vssr", "control"}, cbi("vssr/control"), _("Access Control"), 40).leaf=true
|
||||
entry({"admin", "vpn", "vssr", "servers-list"}, arcombine(cbi("vssr/servers-list"), cbi("vssr/client-config")), _("Severs Nodes"), 50).leaf =true
|
||||
entry({"admin", "vpn", "vssr", "appointlist"},form("vssr/appointlist"),_("Appointlist List"),60).leaf =true
|
||||
entry({"admin", "vpn", "vssr", "udp2raw"},cbi("vssr/udp2raw"),_("udp2raw tunnel"),70).leaf = true
|
||||
entry({"admin", "vpn", "vssr", "advanced"}, cbi("vssr/advanced"),_("Advanced Settings"), 80).leaf =true
|
||||
elseif nixio.fs.access("/usr/bin/ssr-server") then
|
||||
entry({"admin", "vpn", "vssr"}, alias("admin", "vpn", "vssr", "server"), _("vssr"), 10).dependent =true
|
||||
else
|
||||
return
|
||||
end
|
||||
if nixio.fs.access("/usr/bin/ssr-server") then
|
||||
entry({"admin", "vpn", "vssr", "server"},arcombine(cbi("vssr/server"), cbi("vssr/server-config")), _("SSR Server"), 85).leaf = true
|
||||
end
|
||||
entry({"admin", "vpn", "vssr", "status"},form("vssr/status"),_("Status"), 90).leaf = true
|
||||
entry({"admin", "vpn", "vssr", "logview"}, cbi("vssr/logview", {hideapplybtn=true, hidesavebtn=true, hideresetbtn=true}), _("Log") ,100).leaf=true
|
||||
entry({"admin", "vpn", "vssr", "refresh"}, call("refresh_data"))
|
||||
entry({"admin", "vpn", "vssr", "checkport"}, call("check_port"))
|
||||
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", "switch"}, call("switch"))
|
||||
entry({"admin", "vpn", "vssr", "run"}, call("act_status"))
|
||||
entry({"admin", "vpn", "vssr", "change"}, call("change_node"))
|
||||
entry({"admin", "vpn", "vssr", "allserver"}, call("get_servers"))
|
||||
entry({"admin", "vpn", "vssr", "subscribe"}, call("get_subscribe"))
|
||||
entry({"admin", "vpn", "vssr", "flag"}, call("get_flag"))
|
||||
entry({"admin", "vpn", "vssr", "ip"}, call("check_ip"))
|
||||
|
||||
end
|
||||
|
||||
-- 执行订阅
|
||||
function get_subscribe()
|
||||
local cjson = require "cjson"
|
||||
local e = {}
|
||||
local uci = luci.model.uci.cursor()
|
||||
local auto_update = luci.http.formvalue("auto_update")
|
||||
local auto_update_time = luci.http.formvalue("auto_update_time")
|
||||
local proxy = luci.http.formvalue("proxy")
|
||||
local subscribe_url = luci.http.formvalue("subscribe_url")
|
||||
if subscribe_url ~= "[]" then
|
||||
local cmd1 = 'uci set vssr.@server_subscribe[0].auto_update="' ..
|
||||
auto_update .. '"'
|
||||
local cmd2 = 'uci set vssr.@server_subscribe[0].auto_update_time="' ..
|
||||
auto_update_time .. '"'
|
||||
local cmd3 = 'uci set vssr.@server_subscribe[0].proxy="' .. proxy .. '"'
|
||||
luci.sys.call('uci delete vssr.@server_subscribe[0].subscribe_url ')
|
||||
luci.sys.call(cmd1)
|
||||
luci.sys.call(cmd2)
|
||||
luci.sys.call(cmd3)
|
||||
for k, v in ipairs(cjson.decode(subscribe_url)) do
|
||||
luci.sys.call(
|
||||
'uci add_list vssr.@server_subscribe[0].subscribe_url="' .. v .. '"')
|
||||
end
|
||||
luci.sys.call('uci commit vssr')
|
||||
luci.sys.call(
|
||||
"nohup /usr/bin/lua /usr/share/vssr/subscribe.lua >/www/check_update.htm 2>/dev/null &")
|
||||
|
||||
e.error = 0
|
||||
else
|
||||
e.error = 1
|
||||
end
|
||||
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
|
||||
end
|
||||
|
||||
-- 获取所有节点
|
||||
function get_servers()
|
||||
local uci = luci.model.uci.cursor()
|
||||
local server_table = {}
|
||||
uci:foreach("vssr", "servers", function(s)
|
||||
local e = {}
|
||||
e["name"] = s[".name"]
|
||||
local t1 = luci.sys.exec(
|
||||
"ping -c 1 -W 1 %q 2>&1 | grep -o 'time=[0-9]*.[0-9]' | awk -F '=' '{print$2}'" %
|
||||
s["server"])
|
||||
e["t1"] = t1
|
||||
table.insert(server_table, e)
|
||||
end)
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(server_table)
|
||||
end
|
||||
|
||||
-- 切换节点
|
||||
function change_node()
|
||||
local e = {}
|
||||
local uci = luci.model.uci.cursor()
|
||||
local sid = luci.http.formvalue("set")
|
||||
local name = ""
|
||||
uci:foreach("vssr", "global", function(s) name = s[".name"] end)
|
||||
e.status = false
|
||||
e.sid = sid
|
||||
if sid ~= "" then
|
||||
uci:set("vssr", name, "global_server", sid)
|
||||
uci:commit("vssr")
|
||||
luci.sys.call("/etc/init.d/vssr restart")
|
||||
e.status = true
|
||||
end
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
function switch()
|
||||
local e = {}
|
||||
local uci = luci.model.uci.cursor()
|
||||
local sid = luci.http.formvalue("node")
|
||||
local isSwitch = uci:get("vssr", sid, "switch_enable")
|
||||
if isSwitch == "1" then
|
||||
uci:set("vssr", sid, "switch_enable","0")
|
||||
e.switch = false
|
||||
else
|
||||
uci:set("vssr", sid, "switch_enable","1")
|
||||
e.switch = true
|
||||
end
|
||||
uci:commit("vssr")
|
||||
e.status = true
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
|
||||
-- 检测全局服务器状态
|
||||
function act_status()
|
||||
math.randomseed(os.time())
|
||||
local e = {}
|
||||
-- 全局服务器
|
||||
e.global=luci.sys.call("ps -w | grep ssr-retcp | grep -v grep >/dev/null") == 0
|
||||
-- 检测Socks5
|
||||
|
||||
if tonumber(luci.sys.exec("ps -w | grep ssr-local |grep -v grep| wc -l"))>0 then
|
||||
e.socks5 = true
|
||||
elseif tonumber(luci.sys.exec("ps -w | grep ss-local |grep -v grep| wc -l"))>0 then
|
||||
e.socks5 = true
|
||||
elseif tonumber(luci.sys.exec("ps -w | grep v2-ssr-local |grep -v grep| wc -l"))>0 then
|
||||
end
|
||||
--检测chinadns状态
|
||||
if tonumber(luci.sys.exec("ps -w | grep chinadns |grep -v grep| wc -l"))>0 then
|
||||
e.chinadns= true
|
||||
elseif tonumber(luci.sys.exec("ps -w | grep dnsparsing |grep -v grep| wc -l"))>0 then
|
||||
e.chinadns= true
|
||||
elseif tonumber(luci.sys.exec("ps -w | grep dnscrypt-proxy |grep -v grep| wc -l"))>0 then
|
||||
e.chinadns= true
|
||||
elseif tonumber(luci.sys.exec("ps -w | grep pdnsd |grep -v grep| wc -l"))>0 then
|
||||
e.chinadns= true
|
||||
elseif tonumber(luci.sys.exec("ps -w | grep dns2socks |grep -v grep| wc -l"))>0 then
|
||||
e.chinadns= true
|
||||
elseif tonumber(luci.sys.exec("ps -w | grep dnsforwarder |grep -v grep| wc -l"))>0 then
|
||||
e.chinadns= true
|
||||
end
|
||||
--检测服务端状态
|
||||
if tonumber(luci.sys.exec("ps -w | grep ssr-server |grep -v grep| wc -l"))>0 then
|
||||
e.server= true
|
||||
end
|
||||
if luci.sys.call("pidof ssr-server >/dev/null") == 0 then
|
||||
e.ssr_server= true
|
||||
end
|
||||
if luci.sys.call("pidof ss-server >/dev/null") == 0 then
|
||||
e.ss_server= true
|
||||
end
|
||||
if luci.sys.call("ps -w | grep v2ray-server | grep -v grep >/dev/null") == 0 then
|
||||
e.v2_server= true
|
||||
|
||||
end
|
||||
|
||||
-- 检测国内通道
|
||||
e.baidu = false
|
||||
sret = luci.sys.call("/usr/bin/ssr-check www.baidu.com 80 3 1")
|
||||
if sret == 0 then
|
||||
e.baidu = true
|
||||
end
|
||||
|
||||
-- 检测国外通道
|
||||
e.google = false
|
||||
sret = luci.sys.call("/usr/bin/ssr-check www.google.com 80 3 1")
|
||||
if sret == 0 then
|
||||
e.google = true
|
||||
end
|
||||
|
||||
|
||||
-- 检测游戏模式状态
|
||||
e.game = false
|
||||
if tonumber(luci.sys.exec("ps -w | grep ssr-reudp |grep -v grep| wc -l"))>0 then
|
||||
e.game= true
|
||||
else
|
||||
if tonumber(luci.sys.exec("ps -w | grep ssr-retcp |grep \"\\-u\"|grep -v grep| wc -l"))>0 then
|
||||
e.game= true
|
||||
end
|
||||
end
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
function act_ping()
|
||||
local e = {}
|
||||
local domain = luci.http.formvalue("domain")
|
||||
local port = luci.http.formvalue("port")
|
||||
e.index = luci.http.formvalue("index")
|
||||
local iret = luci.sys.call(" ipset add ss_spec_wan_ac " .. domain .. " 2>/dev/null")
|
||||
local socket = nixio.socket("inet", "stream")
|
||||
socket:setopt("socket", "rcvtimeo", 3)
|
||||
socket:setopt("socket", "sndtimeo", 3)
|
||||
e.socket = socket:connect(domain, port)
|
||||
socket:close()
|
||||
e.ping = luci.sys.exec("ping -c 1 -W 1 %q 2>&1 | grep -o 'time=[0-9]*.[0-9]' | awk -F '=' '{print$2}'" % domain)
|
||||
if (e.ping == "") then
|
||||
e.ping = luci.sys.exec(string.format("echo -n $(tcpping -c 1 -i 1 -p %s %s 2>&1 | grep -o 'ttl=[0-9]* time=[0-9]*.[0-9]' | awk -F '=' '{print$3}') 2>/dev/null",port, domain))
|
||||
end
|
||||
if (iret == 0) then
|
||||
luci.sys.call(" ipset del ss_spec_wan_ac " .. domain)
|
||||
end
|
||||
luci.http.prepare_content("application/json")
|
||||
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")
|
||||
local icount =0
|
||||
|
||||
if set == "gfw_data" then
|
||||
refresh_cmd="wget-ssl --no-check-certificate https://cdn.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt -O /tmp/gfw.b64"
|
||||
sret=luci.sys.call(refresh_cmd .. " 2>/dev/null")
|
||||
if sret== 0 then
|
||||
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.vssr/gfw_list.conf | wc -l")
|
||||
if tonumber(icount) ~= tonumber(oldcount) then
|
||||
luci.sys.exec("cp -f /tmp/gfwnew.txt /etc/dnsmasq.vssr/gfw_list.conf")
|
||||
luci.sys.exec("cp -f /tmp/gfwnew.txt /tmp/dnsmasq.vssr/gfw_list.conf")
|
||||
luci.sys.call("/etc/init.d/dnsmasq restart")
|
||||
retstring=tostring(math.ceil(tonumber(icount)/2))
|
||||
else
|
||||
retstring ="0"
|
||||
end
|
||||
else
|
||||
retstring ="-1"
|
||||
end
|
||||
luci.sys.exec("rm -f /tmp/gfwnew.txt ")
|
||||
else
|
||||
retstring ="-1"
|
||||
end
|
||||
elseif set == "ip_data" then
|
||||
if (luci.model.uci.cursor():get_first('vssr', 'global', 'chnroute', '0') == '1') then
|
||||
refresh_cmd="wget-ssl --no-check-certificate -O - " .. luci.model.uci.cursor():get_first('vssr', 'global', 'chnroute_url', 'https://ispip.clang.cn/all_cn.txt') .. ' > /tmp/china_ssr.txt 2>/dev/null'
|
||||
else
|
||||
refresh_cmd="wget -O- 'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest' 2>/dev/null| awk -F\\| '/CN\\|ipv4/ { printf(\"%s/%d\\n\", $4, 32-log($5)/log(2)) }' > /tmp/china_ssr.txt"
|
||||
end
|
||||
sret=luci.sys.call(refresh_cmd)
|
||||
icount = luci.sys.exec("cat /tmp/china_ssr.txt | wc -l")
|
||||
if sret== 0 and tonumber(icount)>1000 then
|
||||
oldcount=luci.sys.exec("cat /etc/china_ssr.txt | wc -l")
|
||||
if tonumber(icount) ~= tonumber(oldcount) then
|
||||
luci.sys.exec("cp -f /tmp/china_ssr.txt /etc/china_ssr.txt")
|
||||
retstring=tostring(tonumber(icount))
|
||||
else
|
||||
retstring ="0"
|
||||
end
|
||||
else
|
||||
retstring ="-1"
|
||||
end
|
||||
luci.sys.exec("rm -f /tmp/china_ssr.txt ")
|
||||
else
|
||||
if nixio.fs.access("/usr/bin/wget-ssl") then
|
||||
refresh_cmd="wget-ssl --no-check-certificate -O - ".. luci.model.uci.cursor():get_first('vssr', 'global', 'adblock_url','https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt') .." > /tmp/adnew.conf"
|
||||
end
|
||||
sret=luci.sys.call(refresh_cmd .. " 2>/dev/null")
|
||||
if sret== 0 then
|
||||
luci.sys.call("/usr/bin/vssr-ad")
|
||||
icount = luci.sys.exec("cat /tmp/ad.conf | wc -l")
|
||||
if tonumber(icount)>1000 then
|
||||
if nixio.fs.access("/etc/dnsmasq.vssr/ad.conf") then
|
||||
oldcount=luci.sys.exec("cat /etc/dnsmasq.vssr/ad.conf | wc -l")
|
||||
else
|
||||
oldcount=0
|
||||
end
|
||||
if tonumber(icount) ~= tonumber(oldcount) then
|
||||
luci.sys.exec("cp -f /tmp/ad.conf /etc/dnsmasq.vssr/ad.conf")
|
||||
luci.sys.exec("cp -f /tmp/ad.conf /tmp/dnsmasq.vssr/ad.conf")
|
||||
luci.sys.call("/etc/init.d/dnsmasq restart")
|
||||
retstring=tostring(math.ceil(tonumber(icount)))
|
||||
else
|
||||
retstring ="0"
|
||||
end
|
||||
else
|
||||
retstring ="-1"
|
||||
end
|
||||
luci.sys.exec("rm -f /tmp/ad.conf")
|
||||
else
|
||||
retstring ="-1"
|
||||
end
|
||||
end
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json({ ret=retstring ,retcount=icount})
|
||||
end
|
||||
|
||||
-- 检测所有服务器
|
||||
function check_ports()
|
||||
local set = ""
|
||||
local retstring = "<br /><br />"
|
||||
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 .. "<font color='green'>[" .. server_name .. "] OK.</font><br />"
|
||||
else
|
||||
retstring = retstring .. "<font color='red'>[" .. server_name .. "] Error.</font><br />"
|
||||
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()
|
||||
|
||||
local e = {}
|
||||
-- e.index=luci.http.formvalue("host")
|
||||
local t1 = luci.sys.exec(
|
||||
"ping -c 1 -W 1 %q 2>&1 | grep -o 'time=[0-9]*.[0-9]' | awk -F '=' '{print$2}'" %
|
||||
luci.http.formvalue("host"))
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json({ret = 1, used = t1})
|
||||
|
||||
end
|
||||
|
||||
function JudgeIPString(ipStr)
|
||||
if type(ipStr) ~= "string" then return false end
|
||||
|
||||
-- 判断长度
|
||||
local len = string.len(ipStr)
|
||||
if len < 7 or len > 15 then -- 长度不对
|
||||
return false
|
||||
end
|
||||
|
||||
-- 判断出现的非数字字符
|
||||
local point = string.find(ipStr, "%p", 1) -- 字符"."出现的位置
|
||||
local pointNum = 0 -- 字符"."出现的次数 正常ip有3个"."
|
||||
while point ~= nil do
|
||||
if string.sub(ipStr, point, point) ~= "." then -- 得到非数字符号不是字符"."
|
||||
return false
|
||||
end
|
||||
pointNum = pointNum + 1
|
||||
point = string.find(ipStr, "%p", point + 1)
|
||||
if pointNum > 3 then return false end
|
||||
end
|
||||
if pointNum ~= 3 then -- 不是正确的ip格式
|
||||
return false
|
||||
end
|
||||
|
||||
-- 判断数字对不对
|
||||
local num = {}
|
||||
for w in string.gmatch(ipStr, "%d+") do
|
||||
num[#num + 1] = w
|
||||
local kk = tonumber(w)
|
||||
if kk == nil or kk > 255 then -- 不是数字或超过ip正常取值范围了
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
if #num ~= 4 then -- 不是4段数字
|
||||
return false
|
||||
end
|
||||
|
||||
return ipStr
|
||||
end
|
||||
|
||||
-- 检测 当前节点ip 和 网站访问情况
|
||||
function check_ip()
|
||||
-- 获取当前的ip和国家
|
||||
local e = {}
|
||||
local d = {}
|
||||
local mm = require 'maxminddb'
|
||||
local db = mm.open('/usr/share/vssr/GeoLite2-Country.mmdb')
|
||||
local ip = string.gsub(luci.sys.exec("curl -s https://api.ip.sb/ip"), "\n", "")
|
||||
local res = db:lookup(ip)
|
||||
d.flag = string.lower(res:get("country", "iso_code"))
|
||||
d.country = res:get("country", "names", "zh-CN")
|
||||
e.outboard = ip
|
||||
e.outboardip = d
|
||||
|
||||
-- 检测国内通道
|
||||
e.baidu = false
|
||||
sret1 = luci.sys.call("/usr/bin/ssr-check www.baidu.com 80 3 1")
|
||||
if sret1 == 0 then e.baidu = true end
|
||||
|
||||
e.taobao = false
|
||||
sret2 = luci.sys.call("/usr/bin/ssr-check www.taobao.com 80 3 1")
|
||||
if sret2 == 0 then e.taobao = true end
|
||||
|
||||
-- 检测国外通道
|
||||
e.google = false
|
||||
sret3 = luci.sys.call("/usr/bin/ssr-check www.google.com 80 3 1")
|
||||
if sret3 == 0 then e.google = true end
|
||||
|
||||
e.youtube = false
|
||||
sret4 = luci.sys.call("/usr/bin/ssr-check www.youtube.com 80 3 1")
|
||||
if sret4 == 0 then e.youtube = true end
|
||||
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
-- 获取节点国旗 iso code
|
||||
function get_flag()
|
||||
local e = {}
|
||||
local host = luci.http.formvalue("host")
|
||||
local remark = luci.http.formvalue("remark")
|
||||
local cmd = '/usr/share/vssr/getflag.sh "' .. remark .. '" ' .. host
|
||||
e.host = host
|
||||
e.flag = luci.sys.exec(cmd)
|
||||
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
|
||||
@ -1,116 +0,0 @@
|
||||
local vssr = "vssr"
|
||||
local uci = luci.model.uci.cursor()
|
||||
local server_table = {}
|
||||
uci:foreach(vssr, "servers", function(s)
|
||||
if s.alias then
|
||||
server_table[s[".name"]] = "[%s]:%s" %{string.upper(s.type), s.alias}
|
||||
elseif s.server and s.server_port then
|
||||
server_table[s[".name"]] = "[%s]:%s:%s" %{string.upper(s.type), s.server, s.server_port}
|
||||
end
|
||||
end)
|
||||
|
||||
local key_table = {}
|
||||
for key,_ in pairs(server_table) do
|
||||
table.insert(key_table,key)
|
||||
end
|
||||
|
||||
table.sort(key_table)
|
||||
m = Map(vssr)
|
||||
|
||||
-- [[ 服务器节点故障自动切换设置 ]]--
|
||||
|
||||
s = m:section(TypedSection, "global", translate("Server failsafe auto swith settings"))
|
||||
s.anonymous = true
|
||||
|
||||
o = s:option(Flag, "monitor_enable", translate("Enable Process Deamon"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Flag, "enable_switch", translate("Enable Auto Switch"))
|
||||
o.rmempty = false
|
||||
|
||||
-- [[ adblock ]]--
|
||||
o = s:option(Flag, "adblock", translate("Enable adblock"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "adblock_url", translate("adblock_url"))
|
||||
o:value("https://gitee.com/privacy-protection-tools/anti-ad/raw/master/anti-ad-for-dnsmasq.conf", translate("anti-AD"))
|
||||
o.default = "https://gitee.com/privacy-protection-tools/anti-ad/raw/master/anti-ad-for-dnsmasq.conf"
|
||||
o:depends("adblock", "1")
|
||||
o.description = translate("Support AdGuardHome and DNSMASQ format list")
|
||||
|
||||
o = s:option(Value, "switch_time", translate("Switch check cycly(second)"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("enable_switch", "1")
|
||||
o.default = 3600
|
||||
|
||||
o = s:option(Value, "switch_timeout", translate("Check timout(second)"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("enable_switch", "1")
|
||||
o.default = 5
|
||||
|
||||
o = s:option(Value, "switch_try_count", translate("Check Try Count"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("enable_switch", "1")
|
||||
o.default = 3
|
||||
|
||||
-- [[ SOCKS5 Proxy ]]--
|
||||
if nixio.fs.access("/usr/bin/ssr-local") then
|
||||
s = m:section(TypedSection, "socks5_proxy", translate("SOCKS5 Proxy"))
|
||||
s.anonymous = true
|
||||
|
||||
o = s:option(ListValue, "server", translate("Server"))
|
||||
o:value("nil", translate("Disable"))
|
||||
for _,key in pairs(key_table) do o:value(key,server_table[key]) end
|
||||
o.default = "nil"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "local_port", translate("Local Port"))
|
||||
o.datatype = "port"
|
||||
o.default = 1080
|
||||
o.rmempty = false
|
||||
|
||||
-- [[ HTTP Proxy ]]--
|
||||
if nixio.fs.access("/usr/sbin/privoxy") then
|
||||
o = s:option(Flag, "http_enable", translate("Enable HTTP Proxy"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "http_port", translate("HTTP Port"))
|
||||
o.datatype = "port"
|
||||
o.default = 1081
|
||||
o.rmempty = false
|
||||
end
|
||||
|
||||
-- [[ chnroute ]]
|
||||
s = m:section(TypedSection, "global", translate("Chnroute Setting"))
|
||||
s.anonymous = true
|
||||
|
||||
o = s:option(Flag, "chnroute", translate("Enable custom chnroute"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "chnroute_url", translate("Update url"))
|
||||
o.default = "https://ispip.clang.cn/all_cn.txt"
|
||||
|
||||
-- [[ haProxy ]]--
|
||||
|
||||
s = m:section(TypedSection, "global_haproxy", translate("haProxy settings"))
|
||||
s.anonymous = true
|
||||
|
||||
o = s:option(Flag, "admin_enable", translate("Enabling the Management Console"))
|
||||
o.rmempty = false
|
||||
o.default = 1
|
||||
|
||||
o = s:option(Value, "admin_port", translate("Service Port"))
|
||||
o.datatype = "uinteger"
|
||||
o.default = 1111
|
||||
|
||||
o = s:option(Value, "admin_user", translate("User name"))
|
||||
o.default = "admin"
|
||||
|
||||
o = s:option(Value, "admin_password", translate("Password"))
|
||||
o.default = "root"
|
||||
|
||||
end
|
||||
return m
|
||||
|
||||
|
||||
|
||||
@ -1,23 +0,0 @@
|
||||
local fs = require "nixio.fs"
|
||||
local conffile = "/etc/dnsmasq.vssr/appoint_list.conf"
|
||||
|
||||
f = SimpleForm("custom", translate("Appoint dns List"))
|
||||
|
||||
t = f:field(TextValue, "conf")
|
||||
t.rmempty = true
|
||||
t.rows = 13
|
||||
function t.cfgvalue()
|
||||
return fs.readfile(conffile) or ""
|
||||
end
|
||||
|
||||
function f.handle(self, state, data)
|
||||
if state == FORM_VALID then
|
||||
if data.conf then
|
||||
fs.writefile(conffile, data.conf:gsub("\r\n", "\n"))
|
||||
luci.sys.call("/etc/init.d/dnsmasq restart")
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
return f
|
||||
@ -1,408 +0,0 @@
|
||||
-- Copyright (C) 2017 yushi studio <ywb94@qq.com> github.com/ywb94
|
||||
-- Licensed to the public under the GNU General Public License v3.
|
||||
local m, s, o, kcp_enable
|
||||
local vssr = "vssr"
|
||||
local uci = luci.model.uci.cursor()
|
||||
|
||||
local fs = require "nixio.fs"
|
||||
local sys = require "luci.sys"
|
||||
local sid = arg[1]
|
||||
local uuid = luci.sys.exec("cat /proc/sys/kernel/random/uuid")
|
||||
|
||||
local function isKcptun(file)
|
||||
if not fs.access(file, "rwx", "rx", "rx") then fs.chmod(file, 755) end
|
||||
|
||||
local str = sys.exec(file .. " -v | awk '{printf $1}'")
|
||||
return (str:lower() == "kcptun")
|
||||
end
|
||||
|
||||
local server_table = {}
|
||||
local encrypt_methods = {
|
||||
"none", "table", "rc4", "rc4-md5-6", "rc4-md5", "aes-128-cfb",
|
||||
"aes-192-cfb", "aes-256-cfb", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr",
|
||||
"bf-cfb", "camellia-128-cfb", "camellia-192-cfb", "camellia-256-cfb",
|
||||
"cast5-cfb", "des-cfb", "idea-cfb", "rc2-cfb", "seed-cfb", "salsa20",
|
||||
"chacha20", "chacha20-ietf"
|
||||
}
|
||||
|
||||
local encrypt_methods_ss = {
|
||||
-- aead
|
||||
"aes-128-gcm", "aes-192-gcm", "aes-256-gcm", "chacha20-ietf-poly1305",
|
||||
"xchacha20-ietf-poly1305", -- stream
|
||||
"table", "rc4", "rc4-md5", "aes-128-cfb", "aes-192-cfb", "aes-256-cfb",
|
||||
"aes-128-ctr", "aes-192-ctr", "aes-256-ctr", "bf-cfb", "camellia-128-cfb",
|
||||
"camellia-192-cfb", "camellia-256-cfb", "salsa20", "chacha20",
|
||||
"chacha20-ietf"
|
||||
}
|
||||
|
||||
local protocol = {
|
||||
"origin", "verify_deflate", "auth_sha1_v4", "auth_aes128_sha1",
|
||||
"auth_aes128_md5", "auth_chain_a", "auth_chain_b", "auth_chain_c",
|
||||
"auth_chain_d", "auth_chain_e", "auth_chain_f"
|
||||
}
|
||||
|
||||
local obfs = {
|
||||
"plain", "http_simple", "http_post", "random_head", "tls1.2_ticket_auth"
|
||||
}
|
||||
|
||||
local securitys = {"auto", "none", "aes-128-gcm", "chacha20-poly1305"}
|
||||
|
||||
m = Map(vssr, translate("Edit vssr Server"))
|
||||
m.redirect = luci.dispatcher.build_url("admin/vpn/vssr/servers")
|
||||
if m.uci:get(vssr, sid) ~= "servers" then
|
||||
luci.http.redirect(m.redirect)
|
||||
return
|
||||
end
|
||||
|
||||
-- [[ Servers Setting ]]--
|
||||
s = m:section(NamedSection, sid, "servers")
|
||||
s.anonymous = true
|
||||
s.addremove = false
|
||||
|
||||
o = s:option(DummyValue, "ssr_url", translate("Configuration Url"))
|
||||
o.rawhtml = true
|
||||
o.template = "vssr/ssrurl"
|
||||
o.value = sid
|
||||
|
||||
o = s:option(ListValue, "type", translate("Server Node Type"))
|
||||
if nixio.fs.access("/usr/sbin/trojan") then
|
||||
o:value("trojan", translate("Trojan"))
|
||||
end
|
||||
|
||||
if nixio.fs.access("/usr/bin/v2ray/v2ray") then
|
||||
o:value("v2ray", translate("V2Ray"))
|
||||
end
|
||||
o:value("ssr", translate("ShadowsocksR"))
|
||||
if nixio.fs.access("/usr/bin/ss-redir") then
|
||||
o:value("ss", translate("Shadowsocks"))
|
||||
end
|
||||
|
||||
if nixio.fs.access("/usr/bin/ipt2socks") then
|
||||
o:value("socks5", translate("Socks5"))
|
||||
end
|
||||
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, "flag", translate("Country"))
|
||||
o.description = translate(
|
||||
"请自己指定。格式:cn us hk 等")
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Value, "server", translate("Server Address"))
|
||||
o.datatype = "host"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "server_port", translate("Server Port"))
|
||||
o.datatype = "port"
|
||||
o.rmempty = false
|
||||
|
||||
-- o = s:option(Value, "timeout", translate("Connection Timeout"))
|
||||
-- o.datatype = "uinteger"
|
||||
-- o.default = 60
|
||||
-- o.rmempty = false
|
||||
|
||||
o = s:option(Flag, "auth_enable", translate("Enable Authentication"))
|
||||
o.rmempty = false
|
||||
o.default = "0"
|
||||
o:depends("type", "socks5")
|
||||
|
||||
o = s:option(Value, "username", translate("Username"))
|
||||
o.rmempty = true
|
||||
o:depends("type", "socks5")
|
||||
|
||||
|
||||
o = s:option(Value, "password", translate("Password"))
|
||||
o.password = true
|
||||
o.rmempty = true
|
||||
o:depends("type", "ssr")
|
||||
o:depends("type", "ss")
|
||||
o:depends("type", "trojan")
|
||||
o:depends("type", "socks5")
|
||||
|
||||
|
||||
o = s:option(ListValue, "encrypt_method", translate("Encrypt Method"))
|
||||
for _, v in ipairs(encrypt_methods) do o:value(v) end
|
||||
o.rmempty = true
|
||||
o:depends("type", "ssr")
|
||||
|
||||
o = s:option(ListValue, "encrypt_method_ss", translate("Encrypt Method"))
|
||||
for _, v in ipairs(encrypt_methods_ss) do o:value(v) end
|
||||
o.rmempty = true
|
||||
o:depends("type", "ss")
|
||||
|
||||
-- Shadowsocks Plugin
|
||||
|
||||
o = s:option(ListValue, "plugin", translate("plugin"))
|
||||
o:value("none", "None")
|
||||
if nixio.fs.access("/usr/bin/v2ray-plugin") then
|
||||
o:value("/usr/bin/v2ray-plugin", "v2ray-plugin")
|
||||
end
|
||||
if nixio.fs.access("/usr/bin/obfs-local") then
|
||||
o:value("/usr/bin/obfs-local", "obfs-local")
|
||||
end
|
||||
if nixio.fs.access("/usr/bin/goquiet-client") then
|
||||
o:value("/usr/bin/goquiet-client", "GoQuiet")
|
||||
end
|
||||
o.rmempty = false
|
||||
o.default = "none"
|
||||
o:depends("type", "ss")
|
||||
|
||||
o = s:option(Value, "plugin_opts", translate("Plugin Opts"))
|
||||
o.rmempty = true
|
||||
o:depends("plugin", "/usr/bin/v2ray-plugin")
|
||||
o:depends("plugin", "/usr/bin/obfs-local")
|
||||
o:depends("plugin", "/usr/bin/goquiet-client")
|
||||
|
||||
o = s:option(ListValue, "protocol", translate("Protocol"))
|
||||
for _, v in ipairs(protocol) do o:value(v) end
|
||||
o.rmempty = true
|
||||
o:depends("type", "ssr")
|
||||
|
||||
o = s:option(Value, "protocol_param", translate("Protocol param(optional)"))
|
||||
o:depends("type", "ssr")
|
||||
|
||||
o = s:option(ListValue, "obfs", translate("Obfs"))
|
||||
for _, v in ipairs(obfs) do o:value(v) end
|
||||
o.rmempty = true
|
||||
o:depends("type", "ssr")
|
||||
|
||||
o = s:option(Value, "obfs_param", translate("Obfs param(optional)"))
|
||||
o:depends("type", "ssr")
|
||||
|
||||
-- AlterId
|
||||
o = s:option(Value, "alter_id", translate("AlterId"))
|
||||
o.datatype = "port"
|
||||
o.default = 16
|
||||
o.rmempty = true
|
||||
o:depends("type", "v2ray")
|
||||
|
||||
-- VmessId
|
||||
o = s:option(Value, "vmess_id", translate("VmessId (UUID)"))
|
||||
o.rmempty = true
|
||||
o.default = uuid
|
||||
o:depends("type", "v2ray")
|
||||
|
||||
-- 加密方式
|
||||
o = s:option(ListValue, "security", translate("Encrypt Method"))
|
||||
for _, v in ipairs(securitys) do o:value(v, v:upper()) end
|
||||
o.rmempty = true
|
||||
o:depends("type", "v2ray")
|
||||
|
||||
-- 传输协议
|
||||
o = s:option(ListValue, "transport", translate("Transport"))
|
||||
o:value("tcp", "TCP")
|
||||
o:value("kcp", "mKCP")
|
||||
o:value("ws", "WebSocket")
|
||||
o:value("h2", "HTTP/2")
|
||||
o:value("quic", "QUIC")
|
||||
o.rmempty = true
|
||||
o:depends("type", "v2ray")
|
||||
|
||||
-- [[ TCP部分 ]]--
|
||||
|
||||
-- TCP伪装
|
||||
o = s:option(ListValue, "tcp_guise", translate("Camouflage Type"))
|
||||
o:depends("transport", "tcp")
|
||||
o:value("none", translate("None"))
|
||||
o:value("http", "HTTP")
|
||||
o.rmempty = true
|
||||
|
||||
-- HTTP域名
|
||||
o = s:option(DynamicList, "http_host", translate("HTTP Host"))
|
||||
o:depends("tcp_guise", "http")
|
||||
o.rmempty = true
|
||||
|
||||
-- HTTP路径
|
||||
o = s:option(DynamicList, "http_path", translate("HTTP Path"))
|
||||
o:depends("tcp_guise", "http")
|
||||
o.rmempty = true
|
||||
|
||||
-- [[ WS部分 ]]--
|
||||
|
||||
-- WS域名
|
||||
o = s:option(Value, "ws_host", translate("WebSocket Host"))
|
||||
o:depends("transport", "ws")
|
||||
o.rmempty = true
|
||||
|
||||
-- WS路径
|
||||
o = s:option(Value, "ws_path", translate("WebSocket Path"))
|
||||
o:depends("transport", "ws")
|
||||
o.rmempty = true
|
||||
|
||||
-- [[ H2部分 ]]--
|
||||
|
||||
-- H2域名
|
||||
o = s:option(DynamicList, "h2_host", translate("HTTP/2 Host"))
|
||||
o:depends("transport", "h2")
|
||||
o.rmempty = true
|
||||
|
||||
-- H2路径
|
||||
o = s:option(Value, "h2_path", translate("HTTP/2 Path"))
|
||||
o:depends("transport", "h2")
|
||||
o.rmempty = true
|
||||
|
||||
-- [[ QUIC部分 ]]--
|
||||
|
||||
o = s:option(ListValue, "quic_security", translate("QUIC Security"))
|
||||
o:depends("transport", "quic")
|
||||
o.rmempty = true
|
||||
o:value("none", translate("None"))
|
||||
o:value("aes-128-gcm", translate("aes-128-gcm"))
|
||||
o:value("chacha20-poly1305", translate("chacha20-poly1305"))
|
||||
|
||||
o = s:option(Value, "quic_key", translate("QUIC Key"))
|
||||
o:depends("transport", "quic")
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(ListValue, "quic_guise", translate("Header"))
|
||||
o:depends("transport", "quic")
|
||||
o.rmempty = true
|
||||
o:value("none", translate("None"))
|
||||
o:value("srtp", translate("VideoCall (SRTP)"))
|
||||
o:value("utp", translate("BitTorrent (uTP)"))
|
||||
o:value("wechat-video", translate("WechatVideo"))
|
||||
o:value("dtls", "DTLS 1.2")
|
||||
o:value("wireguard", "WireGuard")
|
||||
|
||||
-- [[ mKCP部分 ]]--
|
||||
|
||||
o = s:option(ListValue, "kcp_guise", translate("Camouflage Type"))
|
||||
o:depends("transport", "kcp")
|
||||
o:value("none", translate("None"))
|
||||
o:value("srtp", translate("VideoCall (SRTP)"))
|
||||
o:value("utp", translate("BitTorrent (uTP)"))
|
||||
o:value("wechat-video", translate("WechatVideo"))
|
||||
o:value("dtls", "DTLS 1.2")
|
||||
o:value("wireguard", "WireGuard")
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Value, "mtu", translate("MTU"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("transport", "kcp")
|
||||
o.default = 1350
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Value, "tti", translate("TTI"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("transport", "kcp")
|
||||
o.default = 50
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Value, "uplink_capacity", translate("Uplink Capacity"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("transport", "kcp")
|
||||
o.default = 5
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Value, "downlink_capacity", translate("Downlink Capacity"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("transport", "kcp")
|
||||
o.default = 20
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Value, "read_buffer_size", translate("Read Buffer Size"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("transport", "kcp")
|
||||
o.default = 2
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Value, "write_buffer_size", translate("Write Buffer Size"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("transport", "kcp")
|
||||
o.default = 2
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Flag, "congestion", translate("Congestion"))
|
||||
o:depends("transport", "kcp")
|
||||
o.rmempty = true
|
||||
|
||||
-- [[ allowInsecure ]]--
|
||||
o = s:option(Flag, "insecure", translate("allowInsecure"))
|
||||
o.rmempty = true
|
||||
o:depends("type", "v2ray")
|
||||
o:depends("type", "trojan")
|
||||
|
||||
-- [[ TLS ]]--
|
||||
o = s:option(Flag, "tls", translate("TLS"))
|
||||
o.rmempty = true
|
||||
o.default = "0"
|
||||
o:depends("type", "v2ray")
|
||||
o:depends("type", "trojan")
|
||||
|
||||
o = s:option(Value, "tls_host", translate("TLS Host"))
|
||||
--o:depends("type", "trojan")
|
||||
o:depends("tls", "1")
|
||||
o.rmempty = true
|
||||
|
||||
|
||||
-- [[ Mux ]]--
|
||||
o = s:option(Flag, "mux", translate("Mux"))
|
||||
o.rmempty = true
|
||||
o.default = "0"
|
||||
o:depends("type", "v2ray")
|
||||
o:depends("v2ray_plugin", "1")
|
||||
|
||||
o = s:option(Value, "concurrency", translate("Concurrency"))
|
||||
o.datatype = "uinteger"
|
||||
o.rmempty = true
|
||||
o.default = "8"
|
||||
o:depends("mux", "1")
|
||||
o = s:option(Flag, "fast_open", translate("TCP Fast Open"))
|
||||
o.rmempty = true
|
||||
o.default = "0"
|
||||
o:depends("type", "ssr")
|
||||
o:depends("type", "ss")
|
||||
o:depends("type", "trojan")
|
||||
|
||||
o = s:option(Flag, "switch_enable", translate("Enable Auto Switch"))
|
||||
o.rmempty = false
|
||||
o.default = "1"
|
||||
|
||||
o = s:option(Value, "local_port", translate("Local Port"))
|
||||
o.datatype = "port"
|
||||
o.default = 1234
|
||||
o.rmempty = false
|
||||
|
||||
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.default = "0"
|
||||
kcp_enable:depends("type", "ssr")
|
||||
kcp_enable:depends("type", "ss")
|
||||
|
||||
o = s:option(Value, "kcp_port", translate("KcpTun Port"))
|
||||
o.datatype = "port"
|
||||
o.default = 4000
|
||||
function o.validate(self, value, section)
|
||||
local kcp_file = "/usr/bin/kcptun-client"
|
||||
local enable = kcp_enable:formvalue(section) or kcp_enable.disabled
|
||||
if enable == kcp_enable.enabled then
|
||||
if not fs.access(kcp_file) then
|
||||
return nil, translate("Haven't a Kcptun executable file")
|
||||
elseif not isKcptun(kcp_file) then
|
||||
return nil, translate("Not a Kcptun executable file")
|
||||
end
|
||||
end
|
||||
|
||||
return value
|
||||
end
|
||||
o:depends("type", "ssr")
|
||||
o:depends("type", "ss")
|
||||
|
||||
o = s:option(Value, "kcp_password", translate("KcpTun Password"))
|
||||
o.password = true
|
||||
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
|
||||
|
||||
return m
|
||||
@ -1,229 +0,0 @@
|
||||
-- Copyright (C) 2017 yushi studio <ywb94@qq.com> github.com/ywb94
|
||||
-- Copyright (C) 2018 lean <coolsnowwolf@gmail.com> github.com/coolsnowwolf
|
||||
-- Licensed to the public under the GNU General Public License v3.
|
||||
|
||||
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.vssr/gfw_list.conf") then
|
||||
gfwmode=1
|
||||
end
|
||||
|
||||
local uci = luci.model.uci.cursor()
|
||||
|
||||
local sys = require "luci.sys"
|
||||
|
||||
if gfwmode==1 then
|
||||
gfw_count = tonumber(sys.exec("cat /etc/dnsmasq.vssr/gfw_list.conf | wc -l"))/2
|
||||
if nixio.fs.access("/etc/dnsmasq.vssr/ad.conf") then
|
||||
ad_count=tonumber(sys.exec("cat /etc/dnsmasq.vssr/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)
|
||||
|
||||
m:section(SimpleSection).template = "vssr/status"
|
||||
|
||||
local server_table = {}
|
||||
local v2ray_table = {}
|
||||
uci:foreach(vssr, "servers", function(s)
|
||||
if s.alias then
|
||||
server_table[s[".name"]] = "[%s]:%s" %{string.upper(s.type), s.alias}
|
||||
elseif s.server and s.server_port then
|
||||
server_table[s[".name"]] = "[%s]:%s:%s" %{string.upper(s.type), s.server, s.server_port}
|
||||
end
|
||||
if s.type == "v2ray" then
|
||||
if s.alias then
|
||||
v2ray_table[s[".name"]] = "[%s]:%s" %{string.upper(s.type), s.alias}
|
||||
elseif s.server and s.server_port then
|
||||
v2ray_table[s[".name"]] = "[%s]:%s:%s" %{string.upper(s.type), s.server, s.server_port}
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
local key_table = {}
|
||||
for key,_ in pairs(server_table) do
|
||||
table.insert(key_table,key)
|
||||
end
|
||||
|
||||
table.sort(key_table)
|
||||
|
||||
local key_table_v2 = {}
|
||||
for key,_ in pairs(v2ray_table) do
|
||||
table.insert(key_table_v2,key)
|
||||
end
|
||||
|
||||
table.sort(key_table_v2)
|
||||
|
||||
-- [[ Global Setting ]]--
|
||||
s = m:section(TypedSection, "global", translate("Basic Settings"))
|
||||
s.anonymous = true
|
||||
|
||||
|
||||
|
||||
o = s:option(ListValue, "global_server", translate("Main Server"))
|
||||
o:value("nil", translate("Disable"))
|
||||
if nixio.fs.access("/usr/sbin/haproxy")then
|
||||
o:value("__haproxy__", translate("Load Balancing"))
|
||||
end
|
||||
for _,key in pairs(key_table) do o:value(key,server_table[key]) end
|
||||
o.default = "nil"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(ListValue, "udp_relay_server", translate("Game Mode UDP Server"))
|
||||
o:value("", translate("Disable"))
|
||||
o:value("same", translate("Same as Global Server"))
|
||||
for _,key in pairs(key_table) do o:value(key,server_table[key]) end
|
||||
|
||||
o = s:option(Flag, "v2ray_flow", translate("Open v2ray split-flow") .."</font>")
|
||||
o.rmempty = false
|
||||
o.description = ("<font color='red'>" ..translate("When open v2ray split-flow,your main server must be a v2ray server").."</font>")
|
||||
|
||||
o = s:option(ListValue, "youtube_server", translate("Youtube Proxy"))
|
||||
o:value("nil", translate("Same as Global Server"))
|
||||
for _,key in pairs(key_table_v2) do o:value(key,v2ray_table[key]) end
|
||||
o:depends("v2ray_flow", "1")
|
||||
o.default = "nil"
|
||||
|
||||
o = s:option(ListValue, "tw_video_server", translate("TaiWan Video Proxy"))
|
||||
o:value("nil", translate("Same as Global Server"))
|
||||
for _,key in pairs(key_table_v2) do o:value(key,v2ray_table[key]) end
|
||||
o:depends("v2ray_flow", "1")
|
||||
o.default = "nil"
|
||||
|
||||
o = s:option(ListValue, "netflix_server", translate("Netflix Proxy"))
|
||||
o:value("nil", translate("Same as Global Server"))
|
||||
for _,key in pairs(key_table_v2) do o:value(key,v2ray_table[key]) end
|
||||
o:depends("v2ray_flow", "1")
|
||||
o.default = "nil"
|
||||
|
||||
o = s:option(ListValue, "disney_server", translate("Diseny+ Proxy"))
|
||||
o:value("nil", translate("Same as Global Server"))
|
||||
for _,key in pairs(key_table_v2) do o:value(key,v2ray_table[key]) end
|
||||
o:depends("v2ray_flow", "1")
|
||||
o.default = "nil"
|
||||
|
||||
o = s:option(ListValue, "prime_server", translate("Prime Video Proxy"))
|
||||
o:value("nil", translate("Same as Global Server"))
|
||||
for _,key in pairs(key_table_v2) do o:value(key,v2ray_table[key]) end
|
||||
o:depends("v2ray_flow", "1")
|
||||
o.default = "nil"
|
||||
|
||||
o = s:option(ListValue, "threads", translate("Multi Threads Option"))
|
||||
o:value("0", translate("Auto Threads"))
|
||||
o:value("1", translate("1 Thread"))
|
||||
o:value("2", translate("2 Threads"))
|
||||
o:value("4", translate("4 Threads"))
|
||||
o:value("8", translate("8 Threads"))
|
||||
o:value("16", translate("16 Threads"))
|
||||
o:value("32", translate("32 Threads"))
|
||||
o:value("64", translate("64 Threads"))
|
||||
o:value("128", translate("128 Threads"))
|
||||
o.default = "0"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(ListValue, "run_mode", translate("Running Mode"))
|
||||
o:value("gfw", translate("GFW List Mode"))
|
||||
o:value("router", translate("IP Route Mode"))
|
||||
o:value("routers", translate("Oversea IP Route Mode"))
|
||||
o:value("oversea", translate("Oversea GFW List Mode"))
|
||||
o:value("all", translate("Global Mode"))
|
||||
o.default = gfw
|
||||
|
||||
o = s:option(ListValue, "dports", translate("Proxy Ports"))
|
||||
o:value("1", translate("All Ports"))
|
||||
o:value("2", translate("Only Common Ports"))
|
||||
o.default = 1
|
||||
|
||||
o = s:option(ListValue, "pdnsd_enable", translate("Resolve Dns Mode"))
|
||||
o:value("0", translate("Use Local DNS Service listen port 5335"))
|
||||
o:value("1", translate("Use Pdnsd tcp query and cache"))
|
||||
if nixio.fs.access("/usr/bin/dnsforwarder") then
|
||||
o:value("3", translate("Use dnsforwarder tcp query and cache"))
|
||||
end
|
||||
if nixio.fs.access("/usr/bin/dnscrypt-proxy") then
|
||||
o:value("5", translate("Use dnscrypt-proxy query and cache"))
|
||||
end
|
||||
if nixio.fs.access("/usr/bin/chinadns") then
|
||||
o:value("6", translate("Use chinadns query and cache"))
|
||||
end
|
||||
if nixio.fs.access("/usr/bin/dns2socks") then
|
||||
o:value("7", translate("Use DNS2SOCKS query and cache"))
|
||||
end
|
||||
o.default = 1
|
||||
|
||||
o = s:option(ListValue, "chinadns_enable", translate("Chiadns Resolve Dns Mode"))
|
||||
o:value("0", translate("Use Local DNS Service"))
|
||||
o:value("1", translate("Use Pdnsd tcp query and cache"))
|
||||
if nixio.fs.access("/usr/bin/dnsforwarder") then
|
||||
o:value("3", translate("Use dnsforwarder tcp query and cache"))
|
||||
end
|
||||
if nixio.fs.access("/usr/bin/dnscrypt-proxy") then
|
||||
o:value("5", translate("Use dnscrypt-proxy query and cache"))
|
||||
end
|
||||
|
||||
if nixio.fs.access("/usr/sbin/smartdns") then
|
||||
o:value("6", translate("Use smartdns query and cache"))
|
||||
end
|
||||
|
||||
if nixio.fs.access("/usr/sbin/https_dns_proxy") then
|
||||
o:value("7", translate("Use https_dns_proxy query and cache"))
|
||||
end
|
||||
o.default = 1
|
||||
o:depends("pdnsd_enable", "6")
|
||||
|
||||
o = s:option(Value, "tunnel_forward", translate("Anti-pollution DNS Server"))
|
||||
o:value("0.0.0.0:53", translate("Using System Default DNS"))
|
||||
o:value("0.0.0.0:5333", translate("Using acceleration center DNS"))
|
||||
o:value("8.8.4.4:53", translate("Google Public DNS (8.8.4.4)"))
|
||||
o:value("8.8.8.8:53", translate("Google Public DNS (8.8.8.8)"))
|
||||
o:value("208.67.222.222:53", translate("OpenDNS (208.67.222.222)"))
|
||||
o:value("208.67.220.220:53", translate("OpenDNS (208.67.220.220)"))
|
||||
o:value("209.244.0.3:53", translate("Level 3 Public DNS (209.244.0.3)"))
|
||||
o:value("209.244.0.4:53", translate("Level 3 Public DNS (209.244.0.4)"))
|
||||
o:value("4.2.2.1:53", translate("Level 3 Public DNS (4.2.2.1)"))
|
||||
o:value("4.2.2.2:53", translate("Level 3 Public DNS (4.2.2.2)"))
|
||||
o:value("4.2.2.3:53", translate("Level 3 Public DNS (4.2.2.3)"))
|
||||
o:value("4.2.2.4:53", translate("Level 3 Public DNS (4.2.2.4)"))
|
||||
o:value("1.1.1.1:53", translate("Cloudflare DNS (1.1.1.1)"))
|
||||
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:depends("pdnsd_enable", "2")
|
||||
o:depends("pdnsd_enable", "3")
|
||||
o:depends("pdnsd_enable", "4")
|
||||
o:depends("pdnsd_enable", "5")
|
||||
o:depends("pdnsd_enable", "6")
|
||||
o:depends("pdnsd_enable", "7")
|
||||
o.default = "8.8.4.4:53"
|
||||
|
||||
|
||||
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
|
||||
@ -1,109 +0,0 @@
|
||||
local m, s, o
|
||||
local NXFS = require "nixio.fs"
|
||||
|
||||
m = Map("vssr", translate("IP black-and-white list"))
|
||||
|
||||
s = m:section(TypedSection, "access_control")
|
||||
s.anonymous = true
|
||||
|
||||
-- Part of WAN
|
||||
s:tab("wan_ac", translate("WAN IP AC"))
|
||||
|
||||
o = s:taboption("wan_ac", DynamicList, "wan_bp_ips", translate("WAN White List IP"))
|
||||
o.datatype = "ip4addr"
|
||||
|
||||
o = s:taboption("wan_ac", DynamicList, "wan_fw_ips", translate("WAN Force Proxy IP"))
|
||||
o.datatype = "ip4addr"
|
||||
|
||||
-- Part of LAN
|
||||
s:tab("lan_ac", translate("LAN IP AC"))
|
||||
|
||||
o = s:taboption("lan_ac", ListValue, "lan_ac_mode", translate("LAN Access Control"))
|
||||
o:value("0", translate("Disable"))
|
||||
o:value("w", translate("Allow listed only"))
|
||||
o:value("b", translate("Allow all except listed"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("lan_ac", DynamicList, "lan_ac_ips", translate("LAN Host List"))
|
||||
o.datatype = "ipaddr"
|
||||
luci.ip.neighbors({ family = 4 }, function(entry)
|
||||
if entry.reachable then
|
||||
o:value(entry.dest:string())
|
||||
end
|
||||
end)
|
||||
o:depends("lan_ac_mode", "w")
|
||||
o:depends("lan_ac_mode", "b")
|
||||
|
||||
o = s:taboption("lan_ac", DynamicList, "lan_bp_ips", translate("LAN Bypassed Host List"))
|
||||
o.datatype = "ipaddr"
|
||||
luci.ip.neighbors({ family = 4 }, function(entry)
|
||||
if entry.reachable then
|
||||
o:value(entry.dest:string())
|
||||
end
|
||||
end)
|
||||
|
||||
o = s:taboption("lan_ac", DynamicList, "lan_fp_ips", translate("LAN Force Proxy Host List"))
|
||||
o.datatype = "ipaddr"
|
||||
luci.ip.neighbors({ family = 4 }, function(entry)
|
||||
if entry.reachable then
|
||||
o:value(entry.dest:string())
|
||||
end
|
||||
end)
|
||||
|
||||
o = s:taboption("lan_ac", DynamicList, "lan_gm_ips", translate("Game Mode Host List"))
|
||||
o.datatype = "ipaddr"
|
||||
luci.ip.neighbors({ family = 4 }, function(entry)
|
||||
if entry.reachable then
|
||||
o:value(entry.dest:string())
|
||||
end
|
||||
end)
|
||||
|
||||
-- Part of Self
|
||||
-- s:tab("self_ac", translate("Router Self AC"))
|
||||
-- o = s:taboption("self_ac",ListValue, "router_proxy", translate("Router Self Proxy"))
|
||||
-- o:value("1", translatef("Normal Proxy"))
|
||||
-- o:value("0", translatef("Bypassed Proxy"))
|
||||
-- o:value("2", translatef("Forwarded Proxy"))
|
||||
-- o.rmempty = false
|
||||
|
||||
s:tab("esc", translate("Bypass Domain List"), "<font color='red'>" ..
|
||||
translate("Join the white list of domain names will not go agent.") ..
|
||||
"</font>")
|
||||
|
||||
local escconf = "/etc/config/white.list"
|
||||
o = s:taboption("esc", TextValue, "escconf")
|
||||
o.rows = 13
|
||||
o.wrap = "off"
|
||||
o.rmempty = true
|
||||
o.cfgvalue = function(self, section)
|
||||
return NXFS.readfile(escconf) or ""
|
||||
end
|
||||
o.write = function(self, section, value)
|
||||
NXFS.writefile(escconf, value:gsub("\r\n", "\n"))
|
||||
end
|
||||
o.remove = function(self, section, value)
|
||||
NXFS.writefile(escconf, "")
|
||||
end
|
||||
|
||||
|
||||
s:tab("block", translate("Black Domain List"),
|
||||
"<font color='red'>" .. translate(
|
||||
"These had been joined websites will use proxy.Please input the domain names of websites,every line can input only one website domain.For example,google.com.") ..
|
||||
"</font>")
|
||||
|
||||
local blockconf = "/etc/config/black.list"
|
||||
o = s:taboption("block", TextValue, "blockconf")
|
||||
o.rows = 13
|
||||
o.wrap = "off"
|
||||
o.rmempty = true
|
||||
o.cfgvalue = function(self, section)
|
||||
return NXFS.readfile(blockconf) or " "
|
||||
end
|
||||
o.write = function(self, section, value)
|
||||
NXFS.writefile(blockconf, value:gsub("\r\n", "\n"))
|
||||
end
|
||||
o.remove = function(self, section, value)
|
||||
NXFS.writefile(blockconf, "")
|
||||
end
|
||||
|
||||
return m
|
||||
@ -1,23 +0,0 @@
|
||||
local fs = require "nixio.fs"
|
||||
local conffile = "/etc/config/gfw.list"
|
||||
|
||||
f = SimpleForm("custom", translate("GFW Custom List"), translate("Please refer to the following writing"))
|
||||
|
||||
t = f:field(TextValue, "conf")
|
||||
t.rmempty = true
|
||||
t.rows = 13
|
||||
function t.cfgvalue()
|
||||
return fs.readfile(conffile) or ""
|
||||
end
|
||||
|
||||
function f.handle(self, state, data)
|
||||
if state == FORM_VALID then
|
||||
if data.conf then
|
||||
fs.writefile(conffile, data.conf:gsub("\r\n", "\n"))
|
||||
luci.sys.call("/usr/share/vssr/gfw2ipset.sh && /etc/init.d/dnsmasq restart")
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
return f
|
||||
@ -1,15 +0,0 @@
|
||||
local fs = require "nixio.fs"
|
||||
local conffile = "/tmp/ssrpro.log"
|
||||
|
||||
f = SimpleForm("logview")
|
||||
|
||||
t = f:field(TextValue, "conf")
|
||||
t.rmempty = true
|
||||
t.rows = 20
|
||||
function t.cfgvalue()
|
||||
luci.sys.exec("[ -f /tmp/vssr.log ] && sed '1!G;h;$!d' /tmp/vssr.log > /tmp/ssrpro.log")
|
||||
return fs.readfile(conffile) or ""
|
||||
end
|
||||
t.readonly="readonly"
|
||||
|
||||
return f
|
||||
@ -1,48 +0,0 @@
|
||||
-- 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,378 +0,0 @@
|
||||
-- Copyright (C) 2017 yushi studio <ywb94@qq.com>
|
||||
-- Licensed to the public under the GNU General Public License v3.
|
||||
|
||||
local m, s, o
|
||||
local vssr = "vssr"
|
||||
local uci = luci.model.uci.cursor()
|
||||
local fs = require "nixio.fs"
|
||||
local sys = require "luci.sys"
|
||||
local sid = arg[1]
|
||||
local uuid = luci.sys.exec("cat /proc/sys/kernel/random/uuid")
|
||||
local http = luci.http
|
||||
local ucursor = require "luci.model.uci".cursor()
|
||||
|
||||
local server_table = {}
|
||||
local encrypt_methods = {
|
||||
"none",
|
||||
"table",
|
||||
"rc4",
|
||||
"rc4-md5-6",
|
||||
"rc4-md5",
|
||||
"aes-128-cfb",
|
||||
"aes-192-cfb",
|
||||
"aes-256-cfb",
|
||||
"aes-128-ctr",
|
||||
"aes-192-ctr",
|
||||
"aes-256-ctr",
|
||||
"bf-cfb",
|
||||
"camellia-128-cfb",
|
||||
"camellia-192-cfb",
|
||||
"camellia-256-cfb",
|
||||
"cast5-cfb",
|
||||
"des-cfb",
|
||||
"idea-cfb",
|
||||
"rc2-cfb",
|
||||
"seed-cfb",
|
||||
"salsa20",
|
||||
"chacha20",
|
||||
"chacha20-ietf",
|
||||
}
|
||||
|
||||
local encrypt_methods_ss = {
|
||||
-- aead
|
||||
"aes-128-gcm",
|
||||
"aes-192-gcm",
|
||||
"aes-256-gcm",
|
||||
"chacha20-ietf-poly1305",
|
||||
"xchacha20-ietf-poly1305",
|
||||
-- stream
|
||||
"table",
|
||||
"rc4",
|
||||
"rc4-md5",
|
||||
"aes-128-cfb",
|
||||
"aes-192-cfb",
|
||||
"aes-256-cfb",
|
||||
"aes-128-ctr",
|
||||
"aes-192-ctr",
|
||||
"aes-256-ctr",
|
||||
"bf-cfb",
|
||||
"camellia-128-cfb",
|
||||
"camellia-192-cfb",
|
||||
"camellia-256-cfb",
|
||||
"salsa20",
|
||||
"chacha20",
|
||||
"chacha20-ietf",
|
||||
}
|
||||
|
||||
local protocol = {
|
||||
"origin",
|
||||
"verify_deflate",
|
||||
"auth_sha1_v4",
|
||||
"auth_aes128_sha1",
|
||||
"auth_aes128_md5",
|
||||
"auth_chain_a",
|
||||
"auth_chain_b",
|
||||
"auth_chain_c",
|
||||
"auth_chain_d",
|
||||
"auth_chain_e",
|
||||
"auth_chain_f",
|
||||
}
|
||||
|
||||
obfs = {
|
||||
"plain",
|
||||
"http_simple",
|
||||
"http_post",
|
||||
"random_head",
|
||||
"tls1.2_ticket_auth",
|
||||
}
|
||||
|
||||
local obfs_opts = {
|
||||
"none",
|
||||
"http",
|
||||
"tls",
|
||||
}
|
||||
|
||||
local securitys = {
|
||||
"auto",
|
||||
"none",
|
||||
"aes-128-gcm",
|
||||
"chacha20-poly1305"
|
||||
}
|
||||
|
||||
|
||||
|
||||
m = Map(vssr, translate("Edit vssr Server"))
|
||||
|
||||
m.redirect = luci.dispatcher.build_url("admin/vpn/vssr/server")
|
||||
if m.uci:get(vssr, sid) ~= "server_config" then
|
||||
luci.http.redirect(m.redirect)
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
-- [[ Server Setting ]]--
|
||||
s = m:section(NamedSection, sid, "server_config")
|
||||
s.anonymous = true
|
||||
s.addremove = false
|
||||
|
||||
o = s:option(Flag, "enable", translate("Enable"))
|
||||
o.default = 1
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(ListValue, "type", translate("Server Node Type"))
|
||||
if nixio.fs.access("/usr/bin/ssr-server") then
|
||||
o:value("ssr", translate("ShadowsocksR"))
|
||||
end
|
||||
if nixio.fs.access("/usr/bin/ss-server") then
|
||||
o:value("ss", translate("Shadowsocks New Version"))
|
||||
end
|
||||
if nixio.fs.access("/usr/bin/v2ray/v2ray") then
|
||||
o:value("v2ray", translate("V2Ray"))
|
||||
end
|
||||
o.description = translate("Using incorrect encryption mothod may causes service fail to start")
|
||||
|
||||
|
||||
|
||||
o = s:option(Flag, "ipv4_ipv6", translate("Enabling IPv6 server"))
|
||||
o.default = 0
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "server_port", translate("Server Port"))
|
||||
o.datatype = "port"
|
||||
o.default = 8388
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "timeout", translate("Connection Timeout"))
|
||||
o.datatype = "uinteger"
|
||||
o.default = 60
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "password", translate("Password"))
|
||||
o.password = true
|
||||
o.rmempty = true
|
||||
o:depends("type", "ssr")
|
||||
o:depends("type", "ss")
|
||||
|
||||
o = s:option(ListValue, "encrypt_method", translate("Encrypt Method"))
|
||||
for _, v in ipairs(encrypt_methods) do o:value(v) end
|
||||
o.rmempty = true
|
||||
o:depends("type", "ssr")
|
||||
o:depends("type", "ss")
|
||||
|
||||
|
||||
|
||||
o = s:option(ListValue, "plugin", translate("plugin"))
|
||||
o:value("none", "None")
|
||||
if nixio.fs.access("/usr/bin/v2ray-plugin") then
|
||||
o:value("/usr/bin/v2ray-plugin", "v2ray-plugin")
|
||||
end
|
||||
if nixio.fs.access("/usr/bin/obfs-server") then
|
||||
o:value("/usr/bin/obfs-server", "obfs-server")
|
||||
end
|
||||
if nixio.fs.access("/usr/bin/gq-server") then
|
||||
o:value("/usr/bin/gq-server", "GoQuiet")
|
||||
end
|
||||
o.rmempty = false
|
||||
o.default = "none"
|
||||
o:depends("type", "ss")
|
||||
|
||||
o = s:option(Value, "plugin_opts", translate("Plugin Opts"))
|
||||
o.rmempty = true
|
||||
o:depends("plugin", "/usr/bin/v2ray-plugin")
|
||||
o:depends("plugin", "/usr/bin/obfs-server")
|
||||
o:depends("plugin", "/usr/bin/gq-server")
|
||||
|
||||
o = s:option(ListValue, "protocol", translate("Protocol"))
|
||||
for _, v in ipairs(protocol) do o:value(v) end
|
||||
o.rmempty = true
|
||||
o:depends("type", "ssr")
|
||||
|
||||
o = s:option(ListValue, "obfs", translate("Obfs"))
|
||||
for _, v in ipairs(obfs) do o:value(v) end
|
||||
o.rmempty = true
|
||||
o:depends("type", "ssr")
|
||||
|
||||
o = s:option(Value, "obfs_param", translate("Obfs param(optional)"))
|
||||
o:depends("type", "ssr")
|
||||
|
||||
|
||||
-- AlterId
|
||||
o = s:option(Value, "alter_id", translate("AlterId"))
|
||||
o.default = 100
|
||||
o.rmempty = true
|
||||
o:depends("type", "v2ray")
|
||||
|
||||
o=s:option(Value,"VMess_level",translate("User Level"))
|
||||
o.default=1
|
||||
o:depends("type", "v2ray")
|
||||
|
||||
-- VmessId
|
||||
o = s:option(Value, "vmess_id", translate("VmessId (UUID)"))
|
||||
o.rmempty = true
|
||||
o.default = uuid
|
||||
o:depends("type", "v2ray")
|
||||
|
||||
-- 加密方式
|
||||
o = s:option(ListValue, "security", translate("Encrypt Method"))
|
||||
for _, v in ipairs(securitys) do o:value(v, v:upper()) end
|
||||
o.rmempty = true
|
||||
o:depends("type", "v2ray")
|
||||
|
||||
-- 传输协议
|
||||
o = s:option(ListValue, "transport", translate("Transport"))
|
||||
o:value("tcp", "TCP")
|
||||
o:value("kcp", "mKCP")
|
||||
o:value("ws", "WebSocket")
|
||||
o:value("h2", "HTTP/2")
|
||||
o:value("quic", "QUIC")
|
||||
o.rmempty = true
|
||||
o:depends("type", "v2ray")
|
||||
|
||||
-- [[ TCP部分 ]]--
|
||||
|
||||
-- TCP伪装
|
||||
o = s:option(ListValue, "tcp_guise", translate("Camouflage Type"))
|
||||
o:depends("transport", "tcp")
|
||||
o:value("none", translate("None"))
|
||||
o:value("http", "HTTP")
|
||||
o.rmempty = true
|
||||
|
||||
-- HTTP域名
|
||||
o = s:option(DynamicList, "http_host", translate("HTTP Host"))
|
||||
o:depends("tcp_guise", "http")
|
||||
o.rmempty = true
|
||||
|
||||
-- HTTP路径
|
||||
o = s:option(DynamicList, "http_path", translate("HTTP Path"))
|
||||
o:depends("tcp_guise", "http")
|
||||
o.rmempty = true
|
||||
|
||||
-- [[ WS部分 ]]--
|
||||
|
||||
-- WS域名
|
||||
o = s:option(Value, "ws_host", translate("WebSocket Host"))
|
||||
o:depends("transport", "ws")
|
||||
o.rmempty = true
|
||||
|
||||
-- WS路径
|
||||
o = s:option(Value, "ws_path", translate("WebSocket Path"))
|
||||
o:depends("transport", "ws")
|
||||
o.rmempty = true
|
||||
|
||||
-- [[ H2部分 ]]--
|
||||
|
||||
-- H2域名
|
||||
o = s:option(DynamicList, "h2_host", translate("HTTP/2 Host"))
|
||||
o:depends("transport", "h2")
|
||||
o.rmempty = true
|
||||
|
||||
-- H2路径
|
||||
o = s:option(Value, "h2_path", translate("HTTP/2 Path"))
|
||||
o:depends("transport", "h2")
|
||||
o.rmempty = true
|
||||
|
||||
-- [[ QUIC部分 ]]--
|
||||
|
||||
o = s:option(ListValue, "quic_security", translate("QUIC Security"))
|
||||
o:depends("transport", "quic")
|
||||
o.rmempty = true
|
||||
o:value("none", translate("None"))
|
||||
o:value("aes-128-gcm", translate("aes-128-gcm"))
|
||||
o:value("chacha20-poly1305", translate("chacha20-poly1305"))
|
||||
|
||||
o = s:option(Value, "quic_key", translate("QUIC Key"))
|
||||
o:depends("transport", "quic")
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(ListValue, "quic_guise", translate("Header"))
|
||||
o:depends("transport", "quic")
|
||||
o.rmempty = true
|
||||
o:value("none", translate("None"))
|
||||
o:value("srtp", translate("VideoCall (SRTP)"))
|
||||
o:value("utp", translate("BitTorrent (uTP)"))
|
||||
o:value("wechat-video", translate("WechatVideo"))
|
||||
o:value("dtls", "DTLS 1.2")
|
||||
o:value("wireguard", "WireGuard")
|
||||
|
||||
-- [[ mKCP部分 ]]--
|
||||
|
||||
o = s:option(ListValue, "kcp_guise", translate("Camouflage Type"))
|
||||
o:depends("transport", "kcp")
|
||||
o:value("none", translate("None"))
|
||||
o:value("srtp", translate("VideoCall (SRTP)"))
|
||||
o:value("utp", translate("BitTorrent (uTP)"))
|
||||
o:value("wechat-video", translate("WechatVideo"))
|
||||
o:value("dtls", "DTLS 1.2")
|
||||
o:value("wireguard", "WireGuard")
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Value, "mtu", translate("MTU"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("transport", "kcp")
|
||||
o.default = 1350
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Value, "tti", translate("TTI"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("transport", "kcp")
|
||||
o.default = 50
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Value, "uplink_capacity", translate("Uplink Capacity"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("transport", "kcp")
|
||||
o.default = 50
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Value, "downlink_capacity", translate("Downlink Capacity"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("transport", "kcp")
|
||||
o.default = 20
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Value, "read_buffer_size", translate("Read Buffer Size"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("transport", "kcp")
|
||||
o.default = 2
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Value, "write_buffer_size", translate("Write Buffer Size"))
|
||||
o.datatype = "uinteger"
|
||||
o:depends("transport", "kcp")
|
||||
o.default = 2
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(Flag, "congestion", translate("Congestion"))
|
||||
o:depends("transport", "kcp")
|
||||
o.rmempty = true
|
||||
|
||||
-- [[ allowInsecure ]]--
|
||||
o = s:option(Flag, "insecure", translate("allowInsecure"))
|
||||
o.rmempty = true
|
||||
o:depends("type", "v2ray")
|
||||
|
||||
-- [[ TLS ]]--
|
||||
o = s:option(Flag, "tls", translate("TLS"))
|
||||
o.rmempty = true
|
||||
o.default = "0"
|
||||
o:depends("type", "v2ray")
|
||||
|
||||
-- [[ Mux ]]--
|
||||
o = s:option(Flag, "mux", translate("Mux"))
|
||||
o.rmempty = true
|
||||
o.default = "0"
|
||||
o:depends("type", "v2ray")
|
||||
|
||||
o = s:option(Value, "concurrency", translate("Concurrency"))
|
||||
o.datatype = "uinteger"
|
||||
o.rmempty = true
|
||||
o.default = "8"
|
||||
o:depends("mux", "1")
|
||||
|
||||
o = s:option(Flag, "fast_open", translate("TCP Fast Open"))
|
||||
o.rmempty = true
|
||||
o:depends("type", "ssr")
|
||||
|
||||
return m
|
||||
@ -1,119 +0,0 @@
|
||||
-- Copyright (C) 2017 yushi studio <ywb94@qq.com>
|
||||
-- Licensed to the public under the GNU General Public License v3.
|
||||
|
||||
local m, sec, o
|
||||
local vssr = "vssr"
|
||||
local uci = luci.model.uci.cursor()
|
||||
local ipkg = require("luci.model.ipkg")
|
||||
|
||||
m = Map(vssr, translate("SS/SSR/V2RAY Server"))
|
||||
m:section(SimpleSection).template = "vssr/status3"
|
||||
local type = {
|
||||
"ssr",
|
||||
"ss",
|
||||
"v2ray",
|
||||
}
|
||||
|
||||
local encrypt_methods = {
|
||||
"table",
|
||||
"rc4",
|
||||
"rc4-md5",
|
||||
"rc4-md5-6",
|
||||
"aes-128-cfb",
|
||||
"aes-192-cfb",
|
||||
"aes-256-cfb",
|
||||
"aes-128-ctr",
|
||||
"aes-192-ctr",
|
||||
"aes-256-ctr",
|
||||
"aes-128-gcm",
|
||||
"aes-192-gcm",
|
||||
"aes-256-gcm",
|
||||
"bf-cfb",
|
||||
"camellia-128-cfb",
|
||||
"camellia-192-cfb",
|
||||
"camellia-256-cfb",
|
||||
"cast5-cfb",
|
||||
"des-cfb",
|
||||
"idea-cfb",
|
||||
"rc2-cfb",
|
||||
"seed-cfb",
|
||||
"salsa20",
|
||||
"chacha20",
|
||||
"chacha20-ietf",
|
||||
"chacha20-ietf-poly1305",
|
||||
"xchacha20-ietf-poly1305",
|
||||
}
|
||||
|
||||
local protocol = {
|
||||
"origin",
|
||||
"verify_deflate",
|
||||
"auth_sha1_v4",
|
||||
"auth_aes128_sha1",
|
||||
"auth_aes128_md5",
|
||||
"auth_chain_a",
|
||||
}
|
||||
|
||||
local obfs = {
|
||||
"plain",
|
||||
"http_simple",
|
||||
"http_post",
|
||||
"random_head",
|
||||
"tls1.2_ticket_auth",
|
||||
"tls1.2_ticket_fastauth",
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- [[ Global Setting ]]--
|
||||
sec = m:section(TypedSection, "server_global", translate("Global Setting"))
|
||||
sec.anonymous = true
|
||||
|
||||
o = sec:option(Flag, "enable_server", translate("Enable Server"))
|
||||
o.rmempty = false
|
||||
|
||||
-- [[ Server Setting ]]--
|
||||
sec = m:section(TypedSection, "server_config", translate("Server Setting"))
|
||||
sec.anonymous = true
|
||||
sec.addremove = true
|
||||
sec.sortable = true
|
||||
sec.template = "cbi/tblsection"
|
||||
sec.extedit = luci.dispatcher.build_url("admin/vpn/vssr/server/%s")
|
||||
function sec.create(...)
|
||||
local sid = TypedSection.create(...)
|
||||
if sid then
|
||||
luci.http.redirect(sec.extedit % sid)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
o = sec:option(Flag, "enable", translate("Enable"))
|
||||
function o.cfgvalue(...)
|
||||
return Value.cfgvalue(...) or translate("0")
|
||||
end
|
||||
o.rmempty = false
|
||||
|
||||
|
||||
|
||||
o = sec:option(DummyValue, "type", translate("Server Node Type"))
|
||||
function o.cfgvalue(...)
|
||||
return Value.cfgvalue(...) or "?"
|
||||
end
|
||||
|
||||
o = sec:option(DummyValue, "server_port", translate("Server Port"))
|
||||
function o.cfgvalue(...)
|
||||
return Value.cfgvalue(...) or "?"
|
||||
end
|
||||
|
||||
o = sec:option(DummyValue,"vmess_id",translate("ID"))
|
||||
o.width="10%"
|
||||
|
||||
o = sec:option(DummyValue, "encrypt_method", translate("Encrypt Method"))
|
||||
o.width="10%"
|
||||
|
||||
o = sec:option(DummyValue, "protocol", translate("Protocol"))
|
||||
o.width="10%"
|
||||
|
||||
o = sec:option(DummyValue, "obfs", translate("Obfs"))
|
||||
o.width="10%"
|
||||
m:append(Template("vssr/server_list"))
|
||||
return m
|
||||
@ -1,76 +0,0 @@
|
||||
-- Licensed to the public under the GNU General Public License v3.
|
||||
local d = require "luci.dispatcher"
|
||||
local fs = require "nixio.fs"
|
||||
local sys = require "luci.sys"
|
||||
local uci = require "luci.model.uci".cursor()
|
||||
local m, s, o
|
||||
local vssr = "vssr"
|
||||
|
||||
|
||||
local uci = luci.model.uci.cursor()
|
||||
local server_count = 0
|
||||
uci:foreach("vssr", "servers", function(s)
|
||||
server_count = server_count + 1
|
||||
end)
|
||||
|
||||
|
||||
|
||||
m = Map(vssr, translate("Node List"))
|
||||
m:section(SimpleSection).template = "vssr/status1"
|
||||
|
||||
|
||||
-- [[ Servers Manage ]]--
|
||||
s = m:section(TypedSection, "servers")
|
||||
s.anonymous = true
|
||||
s.addremove = true
|
||||
s.description = string.format(translate("Server Count") .. ": %d", server_count)
|
||||
s.sortable = true
|
||||
s.template = "cbi/tblsection"
|
||||
s.extedit = luci.dispatcher.build_url("admin/vpn/vssr/servers/%s")
|
||||
function s.create(...)
|
||||
local sid = TypedSection.create(...)
|
||||
if sid then
|
||||
luci.http.redirect(s.extedit % sid)
|
||||
return
|
||||
end
|
||||
end
|
||||
o = s:option(DummyValue, "alias", translate("Alias"))
|
||||
o.width="10%"
|
||||
o = s:option(DummyValue, "type", translate("Type"))
|
||||
o.width="15%"
|
||||
|
||||
o = s:option(DummyValue, "server", translate("Server Address"))
|
||||
o.width="10%"
|
||||
|
||||
o = s:option(DummyValue, "server_port", translate("Server Port"))
|
||||
o.width="10%"
|
||||
|
||||
o = s:option(DummyValue, "encrypt_method", translate("Encrypt Method"))
|
||||
o.width="10%"
|
||||
|
||||
o = s:option(DummyValue, "protocol", translate("Protocol"))
|
||||
o.width="10%"
|
||||
o = s:option(DummyValue, "obfs", translate("Obfs"))
|
||||
o.width="10%"
|
||||
|
||||
o = s:option(Flag, "switch_enable", translate("Enable Auto Switch"))
|
||||
o.width="10%"
|
||||
|
||||
if nixio.fs.access("/usr/bin/kcptun-client") then
|
||||
|
||||
o = s:option(Flag, "kcp_enable", translate("KcpTun"))
|
||||
o.width="10%"
|
||||
end
|
||||
|
||||
o = s:option(DummyValue, "server_port", translate("Socket Connected"))
|
||||
o.template="vssr/socket"
|
||||
o.width="10%"
|
||||
|
||||
o = s:option(DummyValue,"server",translate("Ping Latency"))
|
||||
o.template="vssr/ping"
|
||||
o.width="10%"
|
||||
|
||||
m:append(Template("vssr/server_list"))
|
||||
|
||||
|
||||
return m
|
||||
@ -1,62 +0,0 @@
|
||||
-- Licensed to the public under the GNU General Public License v3.
|
||||
local m, s, o
|
||||
local vssr = "vssr"
|
||||
local cjson = require("cjson")
|
||||
|
||||
local uci = luci.model.uci.cursor()
|
||||
local server_count = 0
|
||||
local server_table = {}
|
||||
uci:foreach("vssr", "servers", function(s)
|
||||
server_count = server_count + 1
|
||||
s["name"] = s[".name"]
|
||||
table.insert(server_table, s)
|
||||
end)
|
||||
|
||||
local name = ""
|
||||
uci:foreach("vssr", "global", function(s) name = s[".name"] end)
|
||||
|
||||
m = Map(vssr)
|
||||
|
||||
m:section(SimpleSection).template = "vssr/status"
|
||||
|
||||
-- [[ Servers List ]]--
|
||||
s = m:section(TypedSection, "servers")
|
||||
s.anonymous = true
|
||||
s.addremove = true
|
||||
s.sortable = false
|
||||
|
||||
s.des = server_count
|
||||
s.current = uci:get("vssr", name, "global_server")
|
||||
s.servers = cjson.encode(server_table)
|
||||
s.template = "vssr/tblsection"
|
||||
s.extedit = luci.dispatcher.build_url("admin/vpn/vssr/servers/%s")
|
||||
function s.create(...)
|
||||
local sid = TypedSection.create(...)
|
||||
if sid then
|
||||
luci.http.redirect(s.extedit % sid)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
o = s:option(DummyValue, "type", translate("Type"))
|
||||
function o.cfgvalue(...) return Value.cfgvalue(...) or translate("") end
|
||||
|
||||
o = s:option(DummyValue, "alias", translate("Alias"))
|
||||
function o.cfgvalue(...) return Value.cfgvalue(...) or translate("None") end
|
||||
|
||||
o = s:option(DummyValue, "server", translate("Server Address"))
|
||||
function o.cfgvalue(...) return Value.cfgvalue(...) or "?" end
|
||||
|
||||
o = s:option(DummyValue, "server_port", translate("Server Port"))
|
||||
function o.cfgvalue(...) return Value.cfgvalue(...) or "?" end
|
||||
|
||||
if nixio.fs.access("/usr/bin/kcptun-client") then
|
||||
|
||||
o = s:option(DummyValue, "kcp_enable", translate("KcpTun"))
|
||||
function o.cfgvalue(...) return Value.cfgvalue(...) or "?" end
|
||||
|
||||
end
|
||||
m:section(SimpleSection).template = "vssr/status2"
|
||||
|
||||
return m
|
||||
|
||||
@ -1,466 +0,0 @@
|
||||
-- Copyright (C) 2017 yushi studio <ywb94@qq.com>
|
||||
-- Licensed to the public under the GNU General Public License v3.
|
||||
|
||||
local IPK_Version="20200328.1.31"
|
||||
local m, s, o
|
||||
local redir_run=0
|
||||
local reudp_run=0
|
||||
local sock5_run=0
|
||||
local ssock5_run=0
|
||||
local v2sock5_run=0
|
||||
local server_run=0
|
||||
local sserver_run=0
|
||||
local v2server_run=0
|
||||
local kcptun_run=0
|
||||
local tunnel_run=0
|
||||
local udp2raw_run=0
|
||||
local udpspeeder_run=0
|
||||
local gfw_count=0
|
||||
local ad_count=0
|
||||
local ip_count=0
|
||||
local gfwmode=0
|
||||
local pdnsd_run=0
|
||||
local dnsforwarder_run=0
|
||||
local dnscrypt_proxy_run=0
|
||||
local chinadns_run=0
|
||||
local dns2socks_run=0
|
||||
local haproxy_run=0
|
||||
local privoxy_run=0
|
||||
|
||||
if nixio.fs.access("/etc/dnsmasq.vssr/gfw_list.conf") then
|
||||
gfwmode=1
|
||||
end
|
||||
|
||||
local vssr= "vssr"
|
||||
|
||||
|
||||
-- html constants
|
||||
font_blue = [[<font color="green">]]
|
||||
font_off = [[</font>]]
|
||||
bold_on = [[<strong>]]
|
||||
bold_off = [[</strong>]]
|
||||
|
||||
local fs = require "nixio.fs"
|
||||
local sys = require "luci.sys"
|
||||
local kcptun_version=translate("Unknown")
|
||||
local kcp_file="/usr/bin/kcptun-client"
|
||||
if not fs.access(kcp_file) then
|
||||
kcptun_version=translate("Not exist")
|
||||
else
|
||||
if not fs.access(kcp_file, "rwx", "rx", "rx") then
|
||||
fs.chmod(kcp_file, 755)
|
||||
end
|
||||
kcptun_version=sys.exec(kcp_file .. " -v | awk '{printf $3}'")
|
||||
if not kcptun_version or kcptun_version == "" then
|
||||
kcptun_version = translate("Unknown")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
local udp2raw_version=translate("Unknown")
|
||||
local udp2raw_file="/usr/bin/udp2raw"
|
||||
if not fs.access(udp2raw_file) then
|
||||
udp2raw_version=translate("Not exist")
|
||||
else
|
||||
if not fs.access(udp2raw_file, "rwx", "rx", "rx") then
|
||||
fs.chmod(udp2raw_file, 755)
|
||||
end
|
||||
udp2raw_version=sys.exec(udp2raw_file .. " -h |grep 'git version' |awk -F ':' '{print $2}'|awk '{print $1}'")
|
||||
if not udp2raw_version or udp2raw_version == "" then
|
||||
udp2raw_version = translate("Unknown")
|
||||
end
|
||||
end
|
||||
|
||||
local udpspeeder_version=translate("Unknown")
|
||||
local udpspeeder_file="/usr/bin/udpspeeder"
|
||||
if not fs.access(udpspeeder_file) then
|
||||
udpspeeder_version=translate("Not exist")
|
||||
else
|
||||
if not fs.access(udpspeeder_file, "rwx", "rx", "rx") then
|
||||
fs.chmod(udpspeeder_file, 755)
|
||||
end
|
||||
udpspeeder_version=sys.exec(udpspeeder_file .. " -h |grep 'git version' |awk -F ':' '{print $2}'|awk '{print $1}'")
|
||||
if not udpspeeder_version or udpspeeder_version == "" then
|
||||
udpspeeder_version = translate("Unknown")
|
||||
end
|
||||
end
|
||||
|
||||
if gfwmode==1 then
|
||||
gfw_count = tonumber(sys.exec("cat /etc/dnsmasq.vssr/gfw_list.conf | wc -l"))/2
|
||||
if nixio.fs.access("/etc/dnsmasq.vssr/ad.conf") then
|
||||
ad_count=tonumber(sys.exec("cat /etc/dnsmasq.vssr/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
|
||||
|
||||
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")
|
||||
if tonumber(icount)>0 then
|
||||
reudp_run=1
|
||||
else
|
||||
icount=sys.exec("ps -w | grep ssr-retcp |grep \"\\-u\"|grep -v grep| wc -l")
|
||||
if tonumber(icount)>0 then
|
||||
reudp_run=1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if luci.sys.call("ps -w | grep ssr-retcp | grep -v grep >/dev/null") == 0 then
|
||||
redir_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("pidof ssr-local >/dev/null") == 0 then
|
||||
sock5_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("pidof ss-local >/dev/null") == 0 then
|
||||
ssock5_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("ps -w | grep v2-ssr-local | grep -v grep >/dev/null") == 0 then
|
||||
v2sock5_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("pidof privoxy >/dev/null") == 0 then
|
||||
privoxy_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("pidof kcptun-client >/dev/null") == 0 then
|
||||
kcptun_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("pidof ssr-server >/dev/null") == 0 then
|
||||
server_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("busybox ps -w | grep ssr-tunnel |grep -v grep >/dev/null") == 0 then
|
||||
tunnel_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("pidof ss-server >/dev/null") == 0 then
|
||||
sserver_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("ps -w | grep v2ray-server | grep -v grep >/dev/null") == 0 then
|
||||
v2server_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("ps -w | grep ssr-tunnel |grep -v grep >/dev/null") == 0 then
|
||||
tunnel_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("pidof udp2raw >/dev/null") == 0 then
|
||||
udp2raw_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("pidof udpspeeder >/dev/null") == 0 then
|
||||
udpspeeder_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("pidof chinadns >/dev/null") == 0 then
|
||||
chinadns_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("pidof pdnsd >/dev/null") == 0 then
|
||||
pdnsd_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("pidof dnsparsing >/dev/null") == 0 then
|
||||
dnsforwarder_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("pidof dnscrypt-proxy >/dev/null") == 0 then
|
||||
dnscrypt_proxy_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("pidof dns2socks >/dev/null") == 0 then
|
||||
dns2socks_run=1
|
||||
end
|
||||
|
||||
if luci.sys.call("pidof haproxy >/dev/null") == 0 then
|
||||
haproxy_run=1
|
||||
end
|
||||
|
||||
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 usage (%)"))
|
||||
t:option(DummyValue, "%MEM", translate("Memory usage (%)"))
|
||||
|
||||
s=m:field(DummyValue,"redir_run",translate("Global Client"))
|
||||
s.rawhtml = true
|
||||
if redir_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
|
||||
s=m:field(DummyValue,"reudp_run",translate("Game Mode UDP Relay"))
|
||||
s.rawhtml = true
|
||||
if reudp_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
|
||||
s=m:field(DummyValue,"haproxy_run",translate("Load Balancing"))
|
||||
s.rawhtml = true
|
||||
if haproxy_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
|
||||
if nixio.fs.access("/usr/bin/chinadns") then
|
||||
s=m:field(DummyValue,"chinadns_run",translate("ChinaDNS"))
|
||||
s.rawhtml = true
|
||||
if chinadns_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
end
|
||||
|
||||
s=m:field(DummyValue,"pdnsd_run",translate("PDNSD"))
|
||||
s.rawhtml = true
|
||||
if pdnsd_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
|
||||
if nixio.fs.access("/usr/bin/dns2socks") then
|
||||
s=m:field(DummyValue,"dns2socks_run",translate("DNS2SOCKS"))
|
||||
s.rawhtml = true
|
||||
if dns2socks_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
end
|
||||
|
||||
s=m:field(DummyValue,"dnsforwarder_run",translate("dnsforwarder"))
|
||||
s.rawhtml = true
|
||||
if dnsforwarder_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
|
||||
s=m:field(DummyValue,"dnscrypt_proxy_run",translate("dnscrypt_proxy"))
|
||||
s.rawhtml = true
|
||||
if dnscrypt_proxy_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
|
||||
if nixio.fs.access("/usr/bin/ss-local") then
|
||||
s=m:field(DummyValue,"ssock5_run",translate("SSOCKS5 Proxy"))
|
||||
s.rawhtml = true
|
||||
if ssock5_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
end
|
||||
|
||||
if nixio.fs.access("/usr/bin/ssr-local") then
|
||||
s=m:field(DummyValue,"sock5_run",translate("SSR SOCKS5 Proxy"))
|
||||
s.rawhtml = true
|
||||
if sock5_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if nixio.fs.access("/usr/bin/v2ray/v2ray") then
|
||||
s=m:field(DummyValue,"ssock5_run",translate("V2SOCKS5 Proxy"))
|
||||
s.rawhtml = true
|
||||
if v2sock5_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
end
|
||||
|
||||
if nixio.fs.access("/usr/sbin/privoxy") then
|
||||
s=m:field(DummyValue,"privoxy_run",translate("HTTP Proxy"))
|
||||
s.rawhtml = true
|
||||
if privoxy_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
end
|
||||
|
||||
if nixio.fs.access("/usr/bin/ssr-server") then
|
||||
s=m:field(DummyValue,"server_run",translate("Global SSR Server"))
|
||||
s.rawhtml = true
|
||||
if server_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
end
|
||||
|
||||
if nixio.fs.access("/usr/bin/ss-server") then
|
||||
s=m:field(DummyValue,"sserver_run",translate("Global SS Server"))
|
||||
s.rawhtml = true
|
||||
if sserver_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
end
|
||||
|
||||
if nixio.fs.access("/usr/bin/v2ray") then
|
||||
s=m:field(DummyValue,"v2server_run",translate("Global V2RAY Server"))
|
||||
s.rawhtml = true
|
||||
if v2server_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
end
|
||||
|
||||
if nixio.fs.access("/usr/bin/kcptun-client") then
|
||||
s=m:field(DummyValue,"kcp_version",translate("KcpTun Version"))
|
||||
s.rawhtml = true
|
||||
s.value =kcptun_version
|
||||
|
||||
s=m:field(DummyValue,"kcptun_run",translate("KcpTun"))
|
||||
s.rawhtml = true
|
||||
if kcptun_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
end
|
||||
|
||||
s=m:field(DummyValue,"version",translate("IPK Version"))
|
||||
s.rawhtml = true
|
||||
s.value =IPK_Version
|
||||
|
||||
s=m:field(DummyValue,"udp2raw_version",translate("udp2raw Version"))
|
||||
s.rawhtml = true
|
||||
s.value =udp2raw_version
|
||||
s=m:field(DummyValue,"udp2raw_run",translate("udp2raw"))
|
||||
s.rawhtml = true
|
||||
if udp2raw_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
|
||||
|
||||
s=m:field(DummyValue,"udpspeeder_version",translate("UDPspeeder Version"))
|
||||
s.rawhtml = true
|
||||
s.value =udpspeeder_version
|
||||
s=m:field(DummyValue,"udpspeeder_run",translate("UDPspeeder"))
|
||||
s.rawhtml = true
|
||||
if udpspeeder_run == 1 then
|
||||
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
|
||||
else
|
||||
s.value = translate("Not Running")
|
||||
end
|
||||
s=m:field(DummyValue,"feedback",translate("Feedback"))
|
||||
s.template = "vssr/feedback"
|
||||
s.value =translate("No feedback")
|
||||
|
||||
|
||||
return m
|
||||
@ -1,91 +0,0 @@
|
||||
-- Licensed to the public under the GNU General Public License v3.
|
||||
|
||||
local m, s, o
|
||||
local vssr = "vssr"
|
||||
local uci = luci.model.uci.cursor()
|
||||
local server_table = {}
|
||||
local gfwmode=0
|
||||
local gfw_count=0
|
||||
local ip_count=0
|
||||
|
||||
if nixio.fs.access("/etc/dnsmasq.vssr/gfw_list.conf") then
|
||||
gfwmode=1
|
||||
end
|
||||
|
||||
local uci = luci.model.uci.cursor()
|
||||
local server_count = 0
|
||||
uci:foreach("vssr", "servers", function(s)
|
||||
server_count = server_count + 1
|
||||
end)
|
||||
|
||||
local fs = require "nixio.fs"
|
||||
local sys = require "luci.sys"
|
||||
|
||||
if gfwmode==1 then
|
||||
gfw_count = tonumber(sys.exec("cat /etc/dnsmasq.vssr/gfw_list.conf | wc -l"))/2
|
||||
|
||||
end
|
||||
|
||||
|
||||
m = Map(vssr)
|
||||
m:section(SimpleSection).template = "vssr/status"
|
||||
-- [[ 节点订阅 ]]--
|
||||
|
||||
s = m:section(TypedSection, "server_subscribe", translate("Subscription"))
|
||||
s.anonymous = true
|
||||
|
||||
o = s:option(Flag, "auto_update", translate("Auto Update"))
|
||||
o.rmempty = false
|
||||
o.description = translate("Auto Update Server subscription, GFW list and CHN route")
|
||||
|
||||
|
||||
o = s:option(ListValue, "auto_update_time", translate("Update time (every day)"))
|
||||
for t = 0,23 do
|
||||
o:value(t, t..":00")
|
||||
end
|
||||
o.default=2
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(DynamicList, "subscribe_url", translate("Subscribe URL"))
|
||||
o.rmempty = true
|
||||
|
||||
|
||||
o = s:option(Flag, "proxy", translate("Through proxy update"))
|
||||
o.rmempty = false
|
||||
o.description = translate("Through proxy update list, Not Recommended ")
|
||||
|
||||
o = s:option(Flag, "switch", translate("Subscribe Default Auto-Switch"))
|
||||
o.rmempty = false
|
||||
o.description = translate("Subscribe new add server default Auto-Switch on")
|
||||
o.default="0"
|
||||
|
||||
o = s:option(DummyValue, "", "")
|
||||
o.rawhtml = true
|
||||
o.template = "vssr/update_subscribe"
|
||||
|
||||
o = s:option(Button,"delete",translate("Delete All Subscribe Severs"))
|
||||
o.inputstyle = "reset"
|
||||
o.description = string.format(translate("Server Count") .. ": %d", server_count)
|
||||
o.write = function()
|
||||
uci:delete_all("vssr", "servers", function(s)
|
||||
if s["hashkey"] then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end)
|
||||
uci:save("vssr")
|
||||
luci.sys.call("uci commit vssr && /etc/init.d/vssr stop")
|
||||
luci.http.redirect(luci.dispatcher.build_url("admin", "vpn", "vssr", "servers"))
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
m:section(SimpleSection).template = "vssr/status2"
|
||||
|
||||
return m
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1,197 +0,0 @@
|
||||
-- Copyright (C) 2017 yushi studio <ywb94@qq.com> github.com/ywb94
|
||||
-- Copyright (C) 2018 lean <coolsnowwolf@gmail.com> github.com/coolsnowwolf
|
||||
-- Licensed to the public under the GNU General Public License v3.
|
||||
|
||||
local m, s, sec, o, kcp_enable
|
||||
local vssr = "vssr"
|
||||
|
||||
|
||||
m = Map(vssr)
|
||||
|
||||
local server_table = {}
|
||||
local encrypt_methods = {
|
||||
"none",
|
||||
"table",
|
||||
"rc4",
|
||||
"rc4-md5-6",
|
||||
"rc4-md5",
|
||||
"aes-128-cfb",
|
||||
"aes-192-cfb",
|
||||
"aes-256-cfb",
|
||||
"aes-128-ctr",
|
||||
"aes-192-ctr",
|
||||
"aes-256-ctr",
|
||||
"bf-cfb",
|
||||
"camellia-128-cfb",
|
||||
"camellia-192-cfb",
|
||||
"camellia-256-cfb",
|
||||
"cast5-cfb",
|
||||
"des-cfb",
|
||||
"idea-cfb",
|
||||
"rc2-cfb",
|
||||
"seed-cfb",
|
||||
"salsa20",
|
||||
"chacha20",
|
||||
"chacha20-ietf",
|
||||
}
|
||||
|
||||
local protocol = {
|
||||
"origin",
|
||||
"verify_deflate",
|
||||
"auth_sha1_v4",
|
||||
"auth_aes128_sha1",
|
||||
"auth_aes128_md5",
|
||||
"auth_chain_a",
|
||||
"auth_chain_b",
|
||||
"auth_chain_c",
|
||||
"auth_chain_d",
|
||||
"auth_chain_e",
|
||||
"auth_chain_f",
|
||||
}
|
||||
|
||||
obfs = {
|
||||
"plain",
|
||||
"http_simple",
|
||||
"http_post",
|
||||
"random_head",
|
||||
"tls1.2_ticket_auth",
|
||||
}
|
||||
|
||||
local raw_mode = {
|
||||
"faketcp",
|
||||
"udp",
|
||||
"icmp",
|
||||
}
|
||||
|
||||
local seq_mode = {
|
||||
"0",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
}
|
||||
|
||||
local cipher_mode = {
|
||||
"none",
|
||||
"xor",
|
||||
"aes128cbc",
|
||||
}
|
||||
|
||||
local auth_mode = {
|
||||
"none",
|
||||
"simple",
|
||||
"md5",
|
||||
"crc32",
|
||||
}
|
||||
|
||||
local speeder_mode = {
|
||||
"0",
|
||||
"1",
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
-- [[ udp2raw ]]--
|
||||
if nixio.fs.access("/usr/bin/udp2raw") then
|
||||
|
||||
s = m:section(TypedSection, "udp2raw", translate(" UDP2raw "))
|
||||
s.anonymous = true
|
||||
|
||||
o = s:option(Flag, "udp2raw_enable", translate("Enable udp2raw"))
|
||||
o.default = 0
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "server", translate("Server Address"))
|
||||
o.datatype = "host"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "server_port", translate("Server Port"))
|
||||
o.datatype = "port"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "local_port", translate("Local Port"))
|
||||
o.datatype = "port"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "key", translate("Password"))
|
||||
o.password = true
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(ListValue, "raw_mode", translate("Raw Mode"))
|
||||
for _, v in ipairs(raw_mode) do o:value(v) end
|
||||
o.default = "faketcp"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(ListValue, "seq_mode", translate("Seq Mode"))
|
||||
for _, v in ipairs(seq_mode) do o:value(v) end
|
||||
o.default = "3"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(ListValue, "cipher_mode", translate("Cipher Mode"))
|
||||
for _, v in ipairs(cipher_mode) do o:value(v) end
|
||||
o.default = "xor"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(ListValue, "auth_mode", translate("Auth Mode"))
|
||||
for _, v in ipairs(auth_mode) do o:value(v) end
|
||||
o.default = "simple"
|
||||
o.rmempty = false
|
||||
|
||||
end
|
||||
|
||||
-- [[ udpspeeder ]]--
|
||||
if nixio.fs.access("/usr/bin/udpspeeder") then
|
||||
|
||||
s = m:section(TypedSection, "udpspeeder", translate("UDPspeeder"))
|
||||
s.anonymous = true
|
||||
|
||||
o = s:option(Flag, "udpspeeder_enable", translate("Enable UDPspeeder"))
|
||||
o.default = 0
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "server", translate("Server Address"))
|
||||
o.datatype = "host"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "server_port", translate("Server Port"))
|
||||
o.datatype = "port"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "local_port", translate("Local Port"))
|
||||
o.datatype = "port"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "key", translate("Password"))
|
||||
o.password = true
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(ListValue, "speeder_mode", translate("Speeder Mode"))
|
||||
for _, v in ipairs(speeder_mode) do o:value(v) end
|
||||
o.default = "0"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "fec", translate("Fec"))
|
||||
o.default = "20:10"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "mtu", translate("Mtu"))
|
||||
o.datatype = "uinteger"
|
||||
o.default = 1250
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "queue_len", translate("Queue Len"))
|
||||
o.datatype = "uinteger"
|
||||
o.default = 200
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "timeout", translate("Fec Timeout"))
|
||||
o.datatype = "uinteger"
|
||||
o.default = 8
|
||||
o.rmempty = false
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
return m
|
||||
@ -1 +0,0 @@
|
||||
</div>
|
||||
@ -1 +0,0 @@
|
||||
<div id="cbi-<%=self.config.."-"..section.."-"..self.option%>" data-index="<%=self.index%>" class="incon<%=subcount%>" data-depends="<%=pcdata(self:deplist2json(section))%>">
|
||||
@ -1,38 +0,0 @@
|
||||
<%+cbi/valueheader%>
|
||||
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
|
||||
function check_connect(btn,urlname)
|
||||
{
|
||||
btn.disabled = true;
|
||||
btn.value = '<%:Check...%>';
|
||||
murl=urlname;
|
||||
XHR.get('<%=luci.dispatcher.build_url("admin", "vpn", "vssr","check")%>',
|
||||
{ set:murl },
|
||||
function(x,rv)
|
||||
{
|
||||
var s = document.getElementById(urlname+'-status');
|
||||
if (s)
|
||||
{
|
||||
if (rv.ret=="0")
|
||||
s.innerHTML ="<font color='green'>"+"<%:Connect OK%>"+"</font>";
|
||||
else
|
||||
s.innerHTML ="<font color='red'>"+"<%:Connect Error%>"+"</font>";
|
||||
|
||||
|
||||
}
|
||||
|
||||
btn.disabled = false;
|
||||
btn.value = '<%:Check Connect%>';
|
||||
}
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
//]]></script>
|
||||
|
||||
|
||||
<input type="button" class="cbi-button cbi-button-apply" value="<%:Check Connect%>" onclick="return check_connect(this,'<%=self.option%>')" />
|
||||
<span id="<%=self.option%>-status"><em><%=self.value%></em></span>
|
||||
|
||||
<%+cbi/valuefooter%>
|
||||
@ -1,36 +0,0 @@
|
||||
<%+cbi/valueheader%>
|
||||
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
|
||||
function check_port(btn)
|
||||
{
|
||||
btn.disabled = true;
|
||||
btn.value = '<%:Check...%>';
|
||||
XHR.get('<%=luci.dispatcher.build_url("admin", "vpn", "vssr","checkports")%>',
|
||||
null,
|
||||
function(x,rv)
|
||||
{
|
||||
var s = document.getElementById('<%=self.option%>-status');
|
||||
if (s)
|
||||
{
|
||||
|
||||
s.innerHTML =rv.ret;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
btn.disabled = false;
|
||||
btn.value = '<%:Check Server%>';
|
||||
}
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
//]]></script>
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
<%+cbi/valuefooter%>
|
||||
@ -1,21 +0,0 @@
|
||||
|
||||
</style>
|
||||
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title">udp2raw 项目</label>
|
||||
<div class="cbi-value-field">
|
||||
<input type="button" class="cbi-button cbi-input-reload" value="点击前往" onclick="javascript:window.open('https://github.com/wangyu-/udp2raw-tunnel','target');" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title">UDPspeeder 项目</label>
|
||||
<div class="cbi-value-field">
|
||||
<input type="button" class="cbi-button cbi-input-reload" value="点击前往" onclick="javascript:window.open('https://github.com/wangyu-/UDPspeeder','target');" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</fieldset>
|
||||
</fieldset>
|
||||
@ -1,109 +0,0 @@
|
||||
<!-- ++ 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,3 +0,0 @@
|
||||
<%+cbi/valueheader%>
|
||||
<span class="pingtime" hint="<%=self:cfgvalue(section)%>">-- ms</span>
|
||||
<%+cbi/valuefooter%>
|
||||
@ -1,44 +0,0 @@
|
||||
<%+cbi/valueheader%>
|
||||
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
|
||||
function refresh_data(btn,dataname)
|
||||
{
|
||||
btn.disabled = true;
|
||||
btn.value = '<%:Refresh...%> ';
|
||||
murl=dataname;
|
||||
XHR.get('<%=luci.dispatcher.build_url("admin", "vpn", "vssr","refresh")%>',
|
||||
{ set:murl },
|
||||
function(x,rv)
|
||||
{
|
||||
var s = document.getElementById(dataname+'-status');
|
||||
if (s)
|
||||
{
|
||||
if (rv.ret=="0")
|
||||
s.innerHTML ="<font color='green'>"+"<%:No new data!%> "+"</font>";
|
||||
else if(rv.ret=="-1")
|
||||
{
|
||||
s.innerHTML ="<font color='red'>"+"<%:Refresh Error!%> "+"</font>";
|
||||
}
|
||||
else
|
||||
{
|
||||
s.innerHTML ="<font color='green'>"+"<%:Refresh OK!%> "+"<%:Total Records:%>"+rv.ret+"</font>";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
btn.disabled = false;
|
||||
btn.value = '<%:Refresh Data %>';
|
||||
}
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
//]]></script>
|
||||
|
||||
|
||||
<input type="button" class="cbi-button cbi-input-reload" value="<%:Refresh Data%> " onclick="return refresh_data(this,'<%=self.option%>')" />
|
||||
<span id="<%=self.option%>-status"><em><%=self.value%></em></span>
|
||||
|
||||
<%+cbi/valuefooter%>
|
||||
@ -1,53 +0,0 @@
|
||||
<%#
|
||||
Copyright 2018-2019 Lienol <lawlienol@gmail.com>
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
<%
|
||||
local dsp = require "luci.dispatcher"
|
||||
-%>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
const doms = document.getElementsByClassName('pingtime');
|
||||
const ports = document.getElementsByClassName("socket-connected")
|
||||
const xhr = (index) => {
|
||||
return new Promise((res) => {
|
||||
const dom = doms[index];
|
||||
const port = ports[index];
|
||||
if (!dom) res()
|
||||
port.innerHTML = '<font color="#0072c3">connecting...</font>';
|
||||
|
||||
XHR.get('<%=dsp.build_url("admin/vpn/vssr/ping")%>', {
|
||||
index,
|
||||
domain: dom.getAttribute("hint"),
|
||||
port: port.getAttribute("hint")
|
||||
},
|
||||
(x, result) => {
|
||||
let col = '#ff0000';
|
||||
if (result.ping) {
|
||||
if (result.ping < 300) col = '#ff3300';
|
||||
if (result.ping < 200) col = '#ff7700';
|
||||
if (result.ping < 100) col = '#249400';
|
||||
}
|
||||
dom.innerHTML = `<font color="${col}">${(result.ping ? result.ping : "--") + " ms"}</font>`
|
||||
if (result.socket) {
|
||||
port.innerHTML = '<font color="#249400">ok</font>';
|
||||
} else {
|
||||
port.innerHTML = '<font color="#ff0000">fail</font>';
|
||||
}
|
||||
res();
|
||||
});
|
||||
})
|
||||
}
|
||||
let task = -1;
|
||||
const thread = () => {
|
||||
task = task + 1
|
||||
if (doms[task]) {
|
||||
xhr(task).then(thread);
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < 10; i++) {
|
||||
thread()
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
@ -1,3 +0,0 @@
|
||||
<%+cbi/valueheader%>
|
||||
<span class="socket-connected" hint="<%=self:cfgvalue(section)%>">wait</span>
|
||||
<%+cbi/valuefooter%>
|
||||
@ -1,299 +0,0 @@
|
||||
<%+cbi/valueheader%>
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
function padright(str, cnt, pad) {
|
||||
return str + Array(cnt + 1).join(pad);
|
||||
}
|
||||
function b64EncodeUnicode(str) {
|
||||
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
|
||||
return String.fromCharCode('0x' + p1);
|
||||
}));
|
||||
}
|
||||
function b64encutf8safe(str) {
|
||||
return b64EncodeUnicode(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, '');
|
||||
}
|
||||
function b64DecodeUnicode(str) {
|
||||
return decodeURIComponent(Array.prototype.map.call(atob(str), function (c) {
|
||||
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
|
||||
}).join(''));
|
||||
}
|
||||
function b64decutf8safe(str) {
|
||||
var l;
|
||||
str = str.replace(/-/g, "+").replace(/_/g, "/");
|
||||
l = str.length;
|
||||
l = (4 - l % 4) % 4;
|
||||
if (l)
|
||||
str = padright(str, l, "=");
|
||||
return b64DecodeUnicode(str);
|
||||
}
|
||||
function b64encsafe(str) {
|
||||
return btoa(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, '')
|
||||
}
|
||||
function b64decsafe(str) {
|
||||
var l;
|
||||
str = str.replace(/-/g, "+").replace(/_/g, "/");
|
||||
l = str.length;
|
||||
l = (4 - l % 4) % 4;
|
||||
if (l)
|
||||
str = padright(str, l, "=");
|
||||
return atob(str);
|
||||
}
|
||||
function dictvalue(d, key) {
|
||||
var v = d[key];
|
||||
if (typeof (v) == 'undefined' || v == '')
|
||||
return '';
|
||||
return b64decsafe(v);
|
||||
}
|
||||
function export_ssr_url(btn, urlname, sid) {
|
||||
var s = document.getElementById(urlname + '-status');
|
||||
if (!s)
|
||||
return false;
|
||||
var v_server = document.getElementById('cbid.vssr.' + sid + '.server');
|
||||
var v_port = document.getElementById('cbid.vssr.' + sid + '.server_port');
|
||||
var v_protocol = document.getElementById('cbid.vssr.' + sid + '.protocol');
|
||||
var v_method = document.getElementById('cbid.vssr.' + sid + '.encrypt_method');
|
||||
var v_obfs = document.getElementById('cbid.vssr.' + sid + '.obfs');
|
||||
var v_password = document.getElementById('cbid.vssr.' + sid + '.password');
|
||||
var v_obfs_param = document.getElementById('cbid.vssr.' + sid + '.obfs_param');
|
||||
var v_protocol_param = document.getElementById('cbid.vssr.' + sid + '.protocol_param');
|
||||
var v_alias = document.getElementById('cbid.vssr.' + sid + '.alias');
|
||||
var ssr_str = v_server.value + ":" +
|
||||
v_port.value + ":" +
|
||||
v_protocol.value + ":" +
|
||||
v_method.value + ":" +
|
||||
v_obfs.value + ":" +
|
||||
b64encsafe(v_password.value) +
|
||||
"/?obfsparam=" + b64encsafe(v_obfs_param.value) +
|
||||
"&protoparam=" + b64encsafe(v_protocol_param.value) +
|
||||
"&remarks=" + b64encutf8safe(v_alias.value);
|
||||
var textarea = document.createElement("textarea");
|
||||
textarea.textContent = "ssr://" + b64encsafe(ssr_str);
|
||||
textarea.style.position = "fixed";
|
||||
document.body.appendChild(textarea);
|
||||
textarea.select();
|
||||
try {
|
||||
document.execCommand("copy"); // Security exception may be thrown by some browsers.
|
||||
s.innerHTML = "<font color='green'><%:Copy SSR to clipboard successfully.%></font>";
|
||||
} catch (ex) {
|
||||
s.innerHTML = "<font color='red'><%:Unable to copy SSR to clipboard.%></font>";
|
||||
} finally {
|
||||
document.body.removeChild(textarea);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function import_ssr_url(btn, urlname, sid) {
|
||||
var s = document.getElementById(urlname + '-status');
|
||||
if (!s)
|
||||
return false;
|
||||
var ssrurl = prompt("在这里黏贴配置链接 ssr:// | ss:// | vmess:// | trojan://", "");
|
||||
if (ssrurl == null || ssrurl == "") {
|
||||
s.innerHTML = "<font color='red'>用户取消</font>";
|
||||
return false;
|
||||
}
|
||||
s.innerHTML = "";
|
||||
//var ssu = ssrurl.match(/ssr:\/\/([A-Za-z0-9_-]+)/i);
|
||||
var ssu = ssrurl.split('://');
|
||||
console.log(ssu.length);
|
||||
if ((ssu[0] != "ssr" && ssu[0] != "ss" && ssu[0] != "vmess" && ssu[0] != "trojan") || ssu[1] == "") {
|
||||
s.innerHTML = "<font color='red'>无效格式</font>";
|
||||
return false;
|
||||
}
|
||||
|
||||
var event = document.createEvent("HTMLEvents");
|
||||
event.initEvent("change", true, true);
|
||||
if (ssu[0] == "ssr") {
|
||||
var sstr = b64decsafe(ssu[1]);
|
||||
var ploc = sstr.indexOf("/?");
|
||||
document.getElementById('cbid.vssr.' + sid + '.type').value = "ssr";
|
||||
document.getElementById('cbid.vssr.' + sid + '.type').dispatchEvent(event);
|
||||
var url0, param = "";
|
||||
if (ploc > 0) {
|
||||
url0 = sstr.substr(0, ploc);
|
||||
param = sstr.substr(ploc + 2);
|
||||
}
|
||||
var ssm = url0.match(/^(.+):([^:]+):([^:]*):([^:]+):([^:]*):([^:]+)/);
|
||||
if (!ssm || ssm.length < 7)
|
||||
return false;
|
||||
var pdict = {};
|
||||
if (param.length > 2)
|
||||
{
|
||||
var a = param.split('&');
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
var b = a[i].split('=');
|
||||
pdict[decodeURIComponent(b[0])] = decodeURIComponent(b[1] || '');
|
||||
}
|
||||
}
|
||||
document.getElementById('cbid.vssr.' + sid + '.server').value = ssm[1];
|
||||
document.getElementById('cbid.vssr.' + sid + '.server_port').value = ssm[2];
|
||||
document.getElementById('cbid.vssr.' + sid + '.protocol').value = ssm[3];
|
||||
document.getElementById('cbid.vssr.' + sid + '.encrypt_method').value = ssm[4];
|
||||
document.getElementById('cbid.vssr.' + sid + '.obfs').value = ssm[5];
|
||||
document.getElementById('cbid.vssr.' + sid + '.password').value = b64decsafe(ssm[6]);
|
||||
document.getElementById('cbid.vssr.' + sid + '.obfs_param').value = dictvalue(pdict, 'obfsparam');
|
||||
document.getElementById('cbid.vssr.' + sid + '.protocol_param').value = dictvalue(pdict, 'protoparam');
|
||||
var rem = pdict['remarks'];
|
||||
if (typeof (rem) != 'undefined' && rem != '' && rem.length > 0)
|
||||
document.getElementById('cbid.vssr.' + sid + '.alias').value = b64decutf8safe(rem);
|
||||
s.innerHTML = "<font color='green'>导入ShadowsocksR配置信息成功</font>";
|
||||
return false;
|
||||
} else if (ssu[0] == "ss") {
|
||||
|
||||
var url0, param = "";
|
||||
var sipIndex = ssu[1].indexOf("@");
|
||||
var ploc = ssu[1].indexOf("#");
|
||||
if (ploc > 0) {
|
||||
url0 = ssu[1].substr(0, ploc);
|
||||
param = ssu[1].substr(ploc + 1);
|
||||
} else {
|
||||
url0 = ssu[1];
|
||||
}
|
||||
|
||||
if (sipIndex != -1) {
|
||||
// SIP002
|
||||
var userInfo = b64decsafe(url0.substr(0, sipIndex));
|
||||
var temp = url0.substr(sipIndex + 1).split("/?");
|
||||
var serverInfo = temp[0].split(":");
|
||||
var server = serverInfo[0];
|
||||
var port = serverInfo[1];
|
||||
var method, password, plugin, pluginOpts;
|
||||
if (temp[1]) {
|
||||
var pluginInfo = decodeURIComponent(temp[1]);
|
||||
var pluginIndex = pluginInfo.indexOf(";");
|
||||
var pluginNameInfo = pluginInfo.substr(0, pluginIndex);
|
||||
plugin = pluginNameInfo.substr(pluginNameInfo.indexOf("=") + 1)
|
||||
pluginOpts = pluginInfo.substr(pluginIndex + 1);
|
||||
}
|
||||
|
||||
var userInfoSplitIndex = userInfo.indexOf(":");
|
||||
if (userInfoSplitIndex != -1) {
|
||||
method = userInfo.substr(0, userInfoSplitIndex);
|
||||
password = userInfo.substr(userInfoSplitIndex + 1);
|
||||
}
|
||||
document.getElementById('cbid.vssr.' + sid + '.type').value = "ss";
|
||||
document.getElementById('cbid.vssr.' + sid + '.type').dispatchEvent(event);
|
||||
document.getElementById('cbid.vssr.' + sid + '.server').value = server;
|
||||
document.getElementById('cbid.vssr.' + sid + '.server_port').value = port;
|
||||
document.getElementById('cbid.vssr.' + sid + '.password').value = password || "";
|
||||
document.getElementById('cbid.vssr.' + sid + '.encrypt_method_ss').value = method || "";
|
||||
document.getElementById('cbid.vssr.' + sid + '.plugin').value = plugin || "";
|
||||
document.getElementById('cbid.vssr.' + sid + '.plugin_opts').value = pluginOpts || "";
|
||||
|
||||
if (param != undefined) {
|
||||
document.getElementById('cbid.vssr.' + sid + '.alias').value = decodeURI(param);
|
||||
}
|
||||
s.innerHTML = "<font color='green'>导入Shadowsocks配置信息成功</font>";
|
||||
} else {
|
||||
var sstr = b64decsafe(url0);
|
||||
document.getElementById('cbid.vssr.' + sid + '.type').value = "ss";
|
||||
document.getElementById('cbid.vssr.' + sid + '.type').dispatchEvent(event);
|
||||
var team = sstr.split('@');
|
||||
console.log(param);
|
||||
var part1 = team[0].split(':');
|
||||
var part2 = team[1].split(':');
|
||||
document.getElementById('cbid.vssr.' + sid + '.server').value = part2[0];
|
||||
document.getElementById('cbid.vssr.' + sid + '.server_port').value = part2[1];
|
||||
document.getElementById('cbid.vssr.' + sid + '.password').value = part1[1];
|
||||
document.getElementById('cbid.vssr.' + sid + '.encrypt_method_ss').value = part1[0];
|
||||
document.getElementById('cbid.vssr.' + sid + '.plugin').value = "";
|
||||
document.getElementById('cbid.vssr.' + sid + '.plugin_opts').value = "";
|
||||
if (param != undefined) {
|
||||
document.getElementById('cbid.vssr.' + sid + '.alias').value = decodeURI(param);
|
||||
}
|
||||
s.innerHTML = "<font color='green'>导入Shadowsocks配置信息成功</font>";
|
||||
}
|
||||
return false;
|
||||
} else if (ssu[0] == "trojan") {
|
||||
var url0, param = "";
|
||||
var ploc = ssu[1].indexOf("#");
|
||||
if (ploc > 0) {
|
||||
url0 = ssu[1].substr(0, ploc);
|
||||
param = ssu[1].substr(ploc + 1);
|
||||
} else {
|
||||
url0 = ssu[1]
|
||||
}
|
||||
var sstr = url0;
|
||||
|
||||
document.getElementById('cbid.vssr.' + sid + '.type').value = "trojan";
|
||||
document.getElementById('cbid.vssr.' + sid + '.type').dispatchEvent(event);
|
||||
var team = sstr.split('@');
|
||||
var password = team[0]
|
||||
var serverPart = team[1].split(':');
|
||||
var others = serverPart[1].split('?');
|
||||
var port = others[0]
|
||||
var queryParam = {}
|
||||
if(others.length > 1) {
|
||||
var queryParams = others[1]
|
||||
var queryArray = queryParams.split('&')
|
||||
for (i = 0; i < queryArray.length; i++) {
|
||||
var params = queryArray[i].split('=');
|
||||
queryParam[decodeURIComponent(params[0])] = decodeURIComponent(params[1] || '');
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById('cbid.vssr.' + sid + '.server').value = serverPart[0];
|
||||
document.getElementById('cbid.vssr.' + sid + '.server_port').value = port;
|
||||
document.getElementById('cbid.vssr.' + sid + '.password').value = password;
|
||||
document.getElementById('cbid.vssr.' + sid + '.tls').checked = true;
|
||||
document.getElementById('cbid.vssr.' + sid + '.tls').dispatchEvent(event);
|
||||
document.getElementById('cbid.vssr.' + sid + '.tls_host').value = queryParam.peer || '';
|
||||
document.getElementById('cbid.vssr.' + sid + '.insecure').checked = queryParam.allowInsecure === '1';
|
||||
|
||||
if (param != undefined) {
|
||||
document.getElementById('cbid.vssr.' + sid + '.alias').value = decodeURI(param);
|
||||
}
|
||||
s.innerHTML = "<font color='green'>导入Trojan配置信息成功</font>";
|
||||
return false;
|
||||
} else if (ssu[0] == "vmess") {
|
||||
var sstr = b64DecodeUnicode(ssu[1]);
|
||||
var ploc = sstr.indexOf("/?");
|
||||
document.getElementById('cbid.vssr.' + sid + '.type').value = "v2ray";
|
||||
document.getElementById('cbid.vssr.' + sid + '.type').dispatchEvent(event);
|
||||
var url0, param = "";
|
||||
if (ploc > 0) {
|
||||
url0 = sstr.substr(0, ploc);
|
||||
param = sstr.substr(ploc + 2);
|
||||
}
|
||||
var ssm = JSON.parse(sstr);
|
||||
document.getElementById('cbid.vssr.' + sid + '.alias').value = ssm.ps;
|
||||
document.getElementById('cbid.vssr.' + sid + '.server').value = ssm.add;
|
||||
document.getElementById('cbid.vssr.' + sid + '.server_port').value = ssm.port;
|
||||
document.getElementById('cbid.vssr.' + sid + '.alter_id').value = ssm.aid;
|
||||
document.getElementById('cbid.vssr.' + sid + '.vmess_id').value = ssm.id;
|
||||
document.getElementById('cbid.vssr.' + sid + '.transport').value = ssm.net;
|
||||
document.getElementById('cbid.vssr.' + sid + '.transport').dispatchEvent(event);
|
||||
if (ssm.net == "tcp") {
|
||||
document.getElementById('cbid.vssr.' + sid + '.http_host').value = ssm.host;
|
||||
document.getElementById('cbid.vssr.' + sid + '.http_path').value = ssm.path;
|
||||
}
|
||||
if (ssm.net == "ws") {
|
||||
document.getElementById('cbid.vssr.' + sid + '.ws_host').value = ssm.host;
|
||||
document.getElementById('cbid.vssr.' + sid + '.ws_path').value = ssm.path;
|
||||
}
|
||||
if (ssm.net == "h2") {
|
||||
document.getElementById('cbid.vssr.' + sid + '.h2_host').value = ssm.host;
|
||||
document.getElementById('cbid.vssr.' + sid + '.h2_path').value = ssm.path;
|
||||
}
|
||||
if (ssm.net == "quic") {
|
||||
document.getElementById('cbid.vssr.' + sid + '.quic_security').value = ssm.securty;
|
||||
document.getElementById('cbid.vssr.' + sid + '.quic_key').value = ssm.key;
|
||||
}
|
||||
if (ssm.net == "kcp") {
|
||||
document.getElementById('cbid.vssr.' + sid + '.kcp_guise').value = ssm.type;
|
||||
}
|
||||
if (ssm.tls == "tls") {
|
||||
document.getElementById('cbid.vssr.' + sid + '.tls').checked = true;
|
||||
document.getElementById('cbid.vssr.' + sid + '.tls').dispatchEvent(event);
|
||||
document.getElementById('cbid.vssr.' + sid + '.tls_host').value = ssm.host;
|
||||
}
|
||||
document.getElementById('cbid.vssr.' + sid + '.mux').checked = true;
|
||||
document.getElementById('cbid.vssr.' + sid + '.mux').dispatchEvent(event);
|
||||
s.innerHTML = "<font color='green'>导入V2ray配置信息成功</font>";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//]]></script>
|
||||
<input type="button" class="cbi-button cbi-button-apply" value="导入配置信息" onclick="return import_ssr_url(this, '<%=self.option%>', '<%=self.value%>')" />
|
||||
<input type="button" class="cbi-button cbi-button-apply" value="<%:Export SSR%>" onclick="return export_ssr_url(this,'<%=self.option%>','<%=self.value%>')" /><span id="<%=self.option%>-status"></span>
|
||||
|
||||
<span id="<%=self.option%>-status"></span>
|
||||
<%+cbi/valuefooter%>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user