luci-app-passwall: sync with upstream source
This commit is contained in:
parent
c653aaa165
commit
c5644ccb0b
@ -6,9 +6,9 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-passwall
|
||||
PKG_VERSION:=3.6
|
||||
PKG_RELEASE:=40
|
||||
PKG_DATE:=20200411
|
||||
PKG_VERSION:=3.9
|
||||
PKG_RELEASE:=4
|
||||
PKG_DATE:=20200705
|
||||
|
||||
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
|
||||
@ -22,20 +22,16 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_ipt2socks
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks
|
||||
bool "Include Shadowsocks Redir (ss-redir)"
|
||||
bool "Include Shadowsocks"
|
||||
default n
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR
|
||||
bool "Include ShadowsocksR Redir (ssr-redir)"
|
||||
bool "Include ShadowsocksR"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_socks
|
||||
bool "Include Shadowsocks Socks (ss-local)"
|
||||
default n
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_socks
|
||||
bool "Include ShadowsocksR Socks (ssr-local)"
|
||||
default n
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server
|
||||
bool "Include ShadowsocksR Server"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray
|
||||
bool "Include V2ray"
|
||||
@ -86,12 +82,13 @@ define Package/$(PKG_NAME)
|
||||
TITLE:=LuCI support for PassWall
|
||||
PKGARCH:=all
|
||||
DEPENDS:=+libmbedtls +iptables-mod-tproxy +ip +ipset +coreutils +coreutils-base64 +coreutils-nohup +luci-lib-jsonc \
|
||||
+wget +resolveip +unzip +dnsmasq-full +tcping +libuci-lua \
|
||||
+curl +ca-certificates +resolveip +unzip +dnsmasq-full +tcping +libuci-lua \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_ipt2socks:ipt2socks \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks:shadowsocks-libev-ss-redir \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks:shadowsocks-libev-ss-local \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR:shadowsocksr-libev-alt \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_socks:shadowsocks-libev-ss-local \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_socks:shadowsocksr-libev-ssr-local \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR:shadowsocksr-libev-ssr-local \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server:shadowsocksr-libev-server \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:v2ray \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan:trojan \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan:ipt2socks \
|
||||
@ -116,6 +113,7 @@ endef
|
||||
|
||||
define Package/$(PKG_NAME)/conffiles
|
||||
/etc/config/passwall
|
||||
/etc/config/passwall_server
|
||||
/usr/share/passwall/rules/blacklist_host
|
||||
/usr/share/passwall/rules/blacklist_ip
|
||||
/usr/share/passwall/rules/whitelist_host
|
||||
@ -125,16 +123,21 @@ endef
|
||||
define Package/$(PKG_NAME)/install
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_CONF) ./root/etc/config/passwall $(1)/etc/config/passwall
|
||||
$(INSTALL_CONF) ./root/etc/config/passwall_show $(1)/etc/config/passwall_show
|
||||
$(INSTALL_CONF) ./root/etc/config/passwall_server $(1)/etc/config/passwall_server
|
||||
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) ./root/etc/init.d/passwall $(1)/etc/init.d/passwall
|
||||
$(INSTALL_BIN) ./root/etc/init.d/passwall_server $(1)/etc/init.d/passwall_server
|
||||
|
||||
$(INSTALL_DIR) $(1)/etc/uci-defaults
|
||||
$(INSTALL_CONF) ./root/etc/uci-defaults/* $(1)/etc/uci-defaults
|
||||
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) ./root/etc/init.d/passwall $(1)/etc/init.d/passwall
|
||||
|
||||
$(INSTALL_DIR) $(1)/usr/share/passwall
|
||||
cp -pR ./root/usr/share/passwall/* $(1)/usr/share/passwall
|
||||
$(INSTALL_CONF) ./root/etc/config/passwall $(1)/usr/share/passwall/config.default
|
||||
|
||||
$(INSTALL_DIR) $(1)/usr/share/rpcd/acl.d
|
||||
cp -pR ./root/usr/share/rpcd/acl.d/* $(1)/usr/share/rpcd/acl.d
|
||||
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/luci
|
||||
cp -pR ./luasrc/* $(1)/usr/lib/lua/luci/
|
||||
@ -146,6 +149,8 @@ endef
|
||||
define Package/$(PKG_NAME)/postinst
|
||||
#!/bin/sh
|
||||
chmod a+x $${IPKG_INSTROOT}/usr/share/passwall/* >/dev/null 2>&1
|
||||
chmod a+x $${IPKG_INSTROOT}/usr/lib/lua/luci/model/cbi/passwall/server/api/app.lua >/dev/null 2>&1
|
||||
touch $${IPKG_INSTROOT}/etc/config/passwall_show >/dev/null 2>&1
|
||||
exit 0
|
||||
endef
|
||||
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
-- Copyright 2018-2020 Lienol <lawlienol@gmail.com>
|
||||
module("luci.controller.passwall", package.seeall)
|
||||
local appname = "passwall"
|
||||
local ucic = luci.model.uci.cursor()
|
||||
local http = require "luci.http"
|
||||
local passwall = require "luci.model.cbi.passwall.api.passwall"
|
||||
local kcptun = require "luci.model.cbi.passwall.api.kcptun"
|
||||
local brook = require "luci.model.cbi.passwall.api.brook"
|
||||
local v2ray = require "luci.model.cbi.passwall.api.v2ray"
|
||||
@ -10,75 +10,53 @@ local v2ray = require "luci.model.cbi.passwall.api.v2ray"
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/passwall") then return end
|
||||
entry({"admin", "vpn"}, firstchild(), "VPN", 45).dependent = false
|
||||
entry({"admin", "vpn", "passwall", "reset_config"}, call("reset_config")).leaf =
|
||||
true
|
||||
entry({"admin", "vpn", "passwall", "reset_config"}, call("reset_config")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "show"}, call("show_menu")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "hide"}, call("hide_menu")).leaf = true
|
||||
if nixio.fs.access("/etc/config/passwall") and
|
||||
nixio.fs.access("/etc/config/passwall_show") then
|
||||
entry({"admin", "vpn", "passwall"},
|
||||
alias("admin", "vpn", "passwall", "settings"), _("Pass Wall"), 1).dependent =
|
||||
true
|
||||
entry({"admin", "vpn", "passwall"}, alias("admin", "vpn", "passwall", "settings"), _("Pass Wall"), 1).dependent = true
|
||||
end
|
||||
entry({"admin", "vpn", "passwall", "settings"}, cbi("passwall/global"),
|
||||
_("Basic Settings"), 1).dependent = true
|
||||
entry({"admin", "vpn", "passwall", "node_list"}, cbi("passwall/node_list"),
|
||||
_("Node List"), 2).dependent = true
|
||||
entry({"admin", "vpn", "passwall", "auto_switch"},
|
||||
cbi("passwall/auto_switch"), _("Auto Switch"), 3).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "other"},
|
||||
cbi("passwall/other", {autoapply = true}), _("Other Settings"), 93).leaf =
|
||||
true
|
||||
entry({"admin", "vpn", "passwall", "settings"}, cbi("passwall/global"), _("Basic Settings"), 1).dependent = true
|
||||
entry({"admin", "vpn", "passwall", "node_list"}, cbi("passwall/node_list"), _("Node List"), 2).dependent = true
|
||||
entry({"admin", "vpn", "passwall", "auto_switch"}, cbi("passwall/auto_switch"), _("Auto Switch"), 3).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "other"}, cbi("passwall/other", {autoapply = true}), _("Other Settings"), 93).leaf = true
|
||||
if nixio.fs.access("/usr/sbin/haproxy") then
|
||||
entry({"admin", "vpn", "passwall", "haproxy"},
|
||||
cbi("passwall/haproxy"), _("Load Balancing"), 94).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "haproxy"}, cbi("passwall/haproxy"), _("Load Balancing"), 94).leaf = true
|
||||
end
|
||||
entry({"admin", "vpn", "passwall", "node_subscribe"},
|
||||
cbi("passwall/node_subscribe"), _("Node Subscribe"), 95).dependent =
|
||||
true
|
||||
entry({"admin", "vpn", "passwall", "rule"}, cbi("passwall/rule"),
|
||||
_("Rule Update"), 96).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "acl"}, cbi("passwall/acl"),
|
||||
_("Access control"), 97).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "log"}, form("passwall/log"),
|
||||
_("Watch Logs"), 99).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "node_config"},
|
||||
cbi("passwall/node_config")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "node_subscribe"}, cbi("passwall/node_subscribe"), _("Node Subscribe"), 95).dependent = true
|
||||
entry({"admin", "vpn", "passwall", "rule"}, cbi("passwall/rule"), _("Rule Update"), 96).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "node_config"}, cbi("passwall/node_config")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "shunt_rules"}, cbi("passwall/shunt_rules")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "acl"}, cbi("passwall/acl"), _("Access control"), 97).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "log"}, form("passwall/log"), _("Watch Logs"), 999).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "server"}, cbi("passwall/server/index"), _("Server-Side"), 99).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "server_user"}, cbi("passwall/server/user")).leaf = true
|
||||
|
||||
entry({"admin", "vpn", "passwall", "link_add_node"}, call("link_add_node")).leaf =
|
||||
true
|
||||
entry({"admin", "vpn", "passwall", "server_user_status"}, call("server_user_status")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "server_get_log"}, call("server_get_log")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "server_clear_log"}, call("server_clear_log")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "link_add_node"}, call("link_add_node")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "get_log"}, call("get_log")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "clear_log"}, call("clear_log")).leaf =
|
||||
true
|
||||
entry({"admin", "vpn", "passwall", "clear_log"}, call("clear_log")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "status"}, call("status")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "connect_status"}, call("connect_status")).leaf =
|
||||
true
|
||||
entry({"admin", "vpn", "passwall", "check_port"}, call("check_port")).leaf =
|
||||
true
|
||||
entry({"admin", "vpn", "passwall", "ping_node"}, call("ping_node")).leaf =
|
||||
true
|
||||
entry({"admin", "vpn", "passwall", "set_node"}, call("set_node")).leaf =
|
||||
true
|
||||
entry({"admin", "vpn", "passwall", "copy_node"}, call("copy_node")).leaf =
|
||||
true
|
||||
entry({"admin", "vpn", "passwall", "update_rules"}, call("update_rules")).leaf =
|
||||
true
|
||||
entry({"admin", "vpn", "passwall", "luci_check"}, call("luci_check")).leaf =
|
||||
true
|
||||
entry({"admin", "vpn", "passwall", "luci_update"}, call("luci_update")).leaf =
|
||||
true
|
||||
entry({"admin", "vpn", "passwall", "kcptun_check"}, call("kcptun_check")).leaf =
|
||||
true
|
||||
entry({"admin", "vpn", "passwall", "kcptun_update"}, call("kcptun_update")).leaf =
|
||||
true
|
||||
entry({"admin", "vpn", "passwall", "brook_check"}, call("brook_check")).leaf =
|
||||
true
|
||||
entry({"admin", "vpn", "passwall", "brook_update"}, call("brook_update")).leaf =
|
||||
true
|
||||
entry({"admin", "vpn", "passwall", "v2ray_check"}, call("v2ray_check")).leaf =
|
||||
true
|
||||
entry({"admin", "vpn", "passwall", "v2ray_update"}, call("v2ray_update")).leaf =
|
||||
true
|
||||
entry({"admin", "vpn", "passwall", "socks_status"}, call("socks_status")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "connect_status"}, call("connect_status")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "check_port"}, call("check_port")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "ping_node"}, call("ping_node")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "set_node"}, call("set_node")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "copy_node"}, call("copy_node")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "clear_all_nodes"}, call("clear_all_nodes")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "delete_select_nodes"}, call("delete_select_nodes")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "update_rules"}, call("update_rules")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "luci_check"}, call("luci_check")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "luci_update"}, call("luci_update")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "kcptun_check"}, call("kcptun_check")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "kcptun_update"}, call("kcptun_update")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "brook_check"}, call("brook_check")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "brook_update"}, call("brook_update")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "v2ray_check"}, call("v2ray_check")).leaf = true
|
||||
entry({"admin", "vpn", "passwall", "v2ray_update"}, call("v2ray_update")).leaf = true
|
||||
end
|
||||
|
||||
local function http_write_json(content)
|
||||
@ -87,8 +65,7 @@ local function http_write_json(content)
|
||||
end
|
||||
|
||||
function reset_config()
|
||||
luci.sys.call(
|
||||
'[ -f "/usr/share/passwall/config.default" ] && cp -f /usr/share/passwall/config.default /etc/config/passwall && /etc/init.d/passwall reload')
|
||||
luci.sys.call('[ -f "/usr/share/passwall/config.default" ] && cp -f /usr/share/passwall/config.default /etc/config/passwall && /etc/init.d/passwall reload')
|
||||
luci.http.redirect(luci.dispatcher.build_url("admin", "vpn", "passwall"))
|
||||
end
|
||||
|
||||
@ -104,83 +81,63 @@ end
|
||||
|
||||
function link_add_node()
|
||||
local link = luci.http.formvalue("link")
|
||||
luci.sys.call('rm -f /tmp/links.conf && echo "' .. link ..
|
||||
'" >> /tmp/links.conf')
|
||||
luci.sys.call('rm -f /tmp/links.conf && echo "' .. link .. '" >> /tmp/links.conf')
|
||||
luci.sys.call("lua /usr/share/passwall/subscribe.lua add log")
|
||||
end
|
||||
|
||||
function get_log()
|
||||
-- luci.sys.exec("[ -f /var/log/passwall.log ] && sed '1!G;h;$!d' /var/log/passwall.log > /var/log/passwall_show.log")
|
||||
luci.http.write(luci.sys.exec(
|
||||
"[ -f '/var/log/passwall.log' ] && cat /var/log/passwall.log"))
|
||||
luci.http.write(luci.sys.exec("[ -f '/var/log/passwall.log' ] && cat /var/log/passwall.log"))
|
||||
end
|
||||
|
||||
function clear_log() luci.sys.call("echo '' > /var/log/passwall.log") end
|
||||
function clear_log()
|
||||
luci.sys.call("echo '' > /var/log/passwall.log")
|
||||
end
|
||||
|
||||
function status()
|
||||
-- local dns_mode = luci.sys.exec("echo -n $(uci -q get " .. appname .. ".@global[0].dns_mode)")
|
||||
-- local dns_mode = ucic:get(appname, "@global[0]", "dns_mode")
|
||||
local e = {}
|
||||
e.dns_mode_status = luci.sys.call("netstat -apn | grep 7913 >/dev/null") ==
|
||||
0
|
||||
e.haproxy_status = luci.sys.call(string.format(
|
||||
"ps -w | grep -v grep | grep '%s/bin/' | grep haproxy >/dev/null",
|
||||
appname)) == 0
|
||||
local tcp_node_num = luci.sys.exec(
|
||||
"echo -n $(uci -q get %s.@global_other[0].tcp_node_num)" %
|
||||
appname)
|
||||
e.dns_mode_status = luci.sys.call("netstat -apn | grep 7913 >/dev/null") == 0
|
||||
e.haproxy_status = luci.sys.call(string.format("ps -w | grep -v grep | grep '%s/bin/' | grep haproxy >/dev/null", appname)) == 0
|
||||
local tcp_node_num = ucic:get(appname, "@global_other[0]", "tcp_node_num") or 1
|
||||
for i = 1, tcp_node_num, 1 do
|
||||
e["kcptun_tcp_node%s_status" % i] =
|
||||
luci.sys.call(string.format(
|
||||
"ps -w | grep -v grep | grep '%s/bin/' | grep 'kcptun_tcp_%s' >/dev/null",
|
||||
appname, i)) == 0
|
||||
e["tcp_node%s_status" % i] = luci.sys.call(
|
||||
string.format(
|
||||
"ps -w | grep -v grep | grep -v kcptun | grep '%s/bin/' | grep -i -E 'TCP_%s' >/dev/null",
|
||||
appname, i)) == 0
|
||||
e["kcptun_tcp_node%s_status" % i] = luci.sys.call(string.format("ps -w | grep -v grep | grep '%s/bin/kcptun' | grep -i 'tcp_%s' >/dev/null", appname, i)) == 0
|
||||
e["tcp_node%s_status" % i] = luci.sys.call(string.format("ps -w | grep -v -E 'grep|kcptun' | grep '%s/bin/' | grep -i 'TCP_%s' >/dev/null", appname, i)) == 0
|
||||
end
|
||||
|
||||
local udp_node_num = luci.sys.exec(
|
||||
"echo -n $(uci -q get %s.@global_other[0].udp_node_num)" %
|
||||
appname)
|
||||
local udp_node_num = ucic:get(appname, "@global_other[0]", "udp_node_num") or 1
|
||||
for i = 1, udp_node_num, 1 do
|
||||
e["udp_node%s_status" % i] = luci.sys.call(
|
||||
string.format(
|
||||
"ps -w | grep -v grep | grep '%s/bin/' | grep -i -E 'UDP_%s' >/dev/null",
|
||||
appname, i)) == 0
|
||||
end
|
||||
|
||||
local socks_node_num = luci.sys.exec(
|
||||
"echo -n $(uci -q get %s.@global_other[0].socks_node_num)" %
|
||||
appname)
|
||||
for i = 1, socks_node_num, 1 do
|
||||
e["kcptun_socks_node%s_status" % i] =
|
||||
luci.sys.call(string.format(
|
||||
"ps -w | grep -v grep | grep '%s/bin/' | grep 'kcptun_socks_%s' >/dev/null",
|
||||
appname, i)) == 0
|
||||
e["socks_node%s_status" % i] = luci.sys.call(
|
||||
string.format(
|
||||
"ps -w | grep -v grep | grep -v kcptun | grep '%s/bin/' | grep -i 'SOCKS_%s' >/dev/null",
|
||||
appname, i, i)) == 0
|
||||
if (ucic:get(appname, "@global[0]", "udp_node" .. i) or "nil") == "tcp" then
|
||||
e["udp_node%s_status" % i] = e["tcp_node%s_status" % i]
|
||||
else
|
||||
e["udp_node%s_status" % i] = luci.sys.call(string.format("ps -w | grep -v grep | grep '%s/bin/' | grep -i 'UDP_%s' >/dev/null", appname, i)) == 0
|
||||
end
|
||||
end
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
function connect_status()
|
||||
local os = require "os"
|
||||
function socks_status()
|
||||
local e = {}
|
||||
local start_time = os.time()
|
||||
if luci.http.formvalue("type") == "google" then
|
||||
e.status = luci.sys.call(
|
||||
"echo $(/usr/share/passwall/test.sh test_url 'www.google.com/generate_204') | grep 200 >/dev/null") ==
|
||||
0
|
||||
else
|
||||
e.status = luci.sys.call(
|
||||
"echo $(/usr/share/passwall/test.sh test_url 'www.baidu.com') | grep 200 >/dev/null") ==
|
||||
0
|
||||
local index = luci.http.formvalue("index")
|
||||
local id = luci.http.formvalue("id")
|
||||
e.index = index
|
||||
e.status = luci.sys.call(string.format("ps -w | grep -v grep | grep '%s/bin/' | grep 'SOCKS_%s' > /dev/null", appname, id)) == 0
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
function connect_status()
|
||||
local e = {}
|
||||
e.use_time = ""
|
||||
local url = luci.http.formvalue("url")
|
||||
local result = luci.sys.exec('curl --connect-timeout 5 -o /dev/null -I -skL -w "%{http_code}:%{time_total}" ' .. url)
|
||||
local code = tonumber(luci.sys.exec("echo -n '" .. result .. "' | awk -F ':' '{print $1}'") or "0")
|
||||
if code ~= 0 then
|
||||
local use_time = luci.sys.exec("echo -n '" .. result .. "' | awk -F ':' '{print $2}'")
|
||||
e.use_time = string.format("%.2f", use_time * 1000)
|
||||
e.ping_type = "curl"
|
||||
end
|
||||
local use_time = os.difftime(os.time(), start_time)
|
||||
e.use_time = use_time
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
@ -191,12 +148,11 @@ function ping_node()
|
||||
local port = luci.http.formvalue("port")
|
||||
local e = {}
|
||||
e.index = index
|
||||
if luci.sys.exec("echo -n $(uci -q get %s.@global_other[0].use_tcping)" % appname) == "1" and luci.sys.exec("echo -n $(command -v tcping)") ~= "" then
|
||||
e.ping = luci.sys.exec(string.format("echo -n $(tcping -q -c 1 -i 1 -p %s %s 2>&1 | grep -o 'time=[0-9]*' | awk -F '=' '{print$2}') 2>/dev/null", port, address))
|
||||
luci.sys.call(string.format("ps -w | grep 'tcping -q -c 1 -i 1 -p %s %s' | grep -v grep | awk '{print $1}' | xargs kill -9 2>/dev/null", port, address))
|
||||
if (ucic:get(appname, "@global_other[0]", "use_tcping") or 1) == "1" and luci.sys.exec("echo -n $(command -v tcping)") ~= "" then
|
||||
e.ping = luci.sys.exec(string.format("echo -n $(tcping -q -c 1 -i 1 -t 1 -p %s %s 2>&1 | grep -o 'time=[0-9]*' | awk -F '=' '{print $2}') 2>/dev/null", port, address))
|
||||
end
|
||||
if e.ping == nil or tonumber(e.ping) == 0 then
|
||||
e.ping = luci.sys.exec("echo -n $(ping -c 1 -W 1 %q 2>&1 | grep -o 'time=[0-9]*' | awk -F '=' '{print$2}') 2>/dev/null" % address)
|
||||
e.ping = luci.sys.exec("echo -n $(ping -c 1 -W 1 %q 2>&1 | grep -o 'time=[0-9]*' | awk -F '=' '{print $2}') 2>/dev/null" % address)
|
||||
end
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
@ -206,11 +162,10 @@ function set_node()
|
||||
local protocol = luci.http.formvalue("protocol")
|
||||
local number = luci.http.formvalue("number")
|
||||
local section = luci.http.formvalue("section")
|
||||
luci.sys.call("uci set passwall.@global[0]." .. protocol .. "_node" ..
|
||||
number .. "=" .. section ..
|
||||
" && uci commit passwall && /etc/init.d/passwall restart > /dev/null 2>&1 &")
|
||||
luci.http.redirect(luci.dispatcher.build_url("admin", "vpn", "passwall",
|
||||
"log"))
|
||||
ucic:set(appname, "@global[0]", protocol .. "_node" .. number, section)
|
||||
ucic:commit(appname)
|
||||
luci.sys.call("/etc/init.d/passwall restart > /dev/null 2>&1 &")
|
||||
luci.http.redirect(luci.dispatcher.build_url("admin", "vpn", "passwall", "log"))
|
||||
end
|
||||
|
||||
function copy_node()
|
||||
@ -220,17 +175,44 @@ function copy_node()
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
function clear_all_nodes()
|
||||
ucic:foreach(appname, "nodes", function(node)
|
||||
ucic:delete(appname, node['.name'])
|
||||
end)
|
||||
|
||||
local function clear(type)
|
||||
local node_num = ucic:get(appname, "@global_other[0]", type .. "_node_num") or 1
|
||||
for i = 1, node_num, 1 do
|
||||
local node = ucic:get(appname, "@global[0]", type .. "_node" .. i)
|
||||
if node then
|
||||
ucic:set(appname, '@global[0]', type .. "_node" .. i, "nil")
|
||||
end
|
||||
end
|
||||
end
|
||||
clear("tcp")
|
||||
clear("udp")
|
||||
|
||||
ucic:commit(appname)
|
||||
luci.sys.call("/etc/init.d/" .. appname .. " restart")
|
||||
end
|
||||
|
||||
function delete_select_nodes()
|
||||
local ids = luci.http.formvalue("ids")
|
||||
string.gsub(ids, '[^' .. "," .. ']+', function(w)
|
||||
ucic:delete(appname, w)
|
||||
end)
|
||||
ucic:commit(appname)
|
||||
luci.sys.call("/etc/init.d/" .. appname .. " restart")
|
||||
end
|
||||
|
||||
function check_port()
|
||||
local s
|
||||
local node_name = ""
|
||||
local uci = luci.model.uci.cursor()
|
||||
|
||||
local retstring = "<br />"
|
||||
-- retstring = retstring .. "<font color='red'>暂时不支持UDP检测</font><br />"
|
||||
|
||||
retstring = retstring ..
|
||||
"<font color='green'>检测端口可用性</font><br />"
|
||||
uci:foreach("passwall", "nodes", function(s)
|
||||
retstring = retstring .. "<font color='green'>检测端口可用性</font><br />"
|
||||
ucic:foreach("passwall", "nodes", function(s)
|
||||
local ret = ""
|
||||
local tcp_socket
|
||||
if (s.use_kcp and s.use_kcp == "1" and s.kcp_port) or
|
||||
@ -246,13 +228,9 @@ function check_port()
|
||||
tcp_socket:setopt("socket", "sndtimeo", 3)
|
||||
ret = tcp_socket:connect(s.address, s.port)
|
||||
if tostring(ret) == "true" then
|
||||
retstring =
|
||||
retstring .. "<font color='green'>" .. node_name ..
|
||||
" OK.</font><br />"
|
||||
retstring = retstring .. "<font color='green'>" .. node_name .. " OK.</font><br />"
|
||||
else
|
||||
retstring =
|
||||
retstring .. "<font color='red'>" .. node_name ..
|
||||
" Error.</font><br />"
|
||||
retstring = retstring .. "<font color='red'>" .. node_name .. " Error.</font><br />"
|
||||
end
|
||||
ret = ""
|
||||
end
|
||||
@ -265,19 +243,22 @@ end
|
||||
|
||||
function update_rules()
|
||||
local update = luci.http.formvalue("update")
|
||||
luci.sys.call("lua /usr/share/passwall/rule_update.lua log '" .. update ..
|
||||
"' > /dev/null 2>&1 &")
|
||||
luci.sys.call("lua /usr/share/passwall/rule_update.lua log '" .. update .. "' > /dev/null 2>&1 &")
|
||||
end
|
||||
|
||||
function luci_check()
|
||||
local json = passwall.to_check("")
|
||||
http_write_json(json)
|
||||
function server_user_status()
|
||||
local e = {}
|
||||
e.index = luci.http.formvalue("index")
|
||||
e.status = luci.sys.call(string.format("ps -w | grep -v 'grep' | grep '%s/bin/' | grep -i '%s' >/dev/null", appname .. "_server", luci.http.formvalue("id"))) == 0
|
||||
http_write_json(e)
|
||||
end
|
||||
|
||||
function luci_update()
|
||||
local json = passwall.update_luci(http.formvalue("url"),
|
||||
http.formvalue("save"))
|
||||
http_write_json(json)
|
||||
function server_get_log()
|
||||
luci.http.write(luci.sys.exec("[ -f '/var/log/passwall_server.log' ] && cat /var/log/passwall_server.log"))
|
||||
end
|
||||
|
||||
function server_clear_log()
|
||||
luci.sys.call("echo '' > /var/log/passwall_server.log")
|
||||
end
|
||||
|
||||
function kcptun_check()
|
||||
|
||||
@ -1,11 +1,8 @@
|
||||
local sys = require "luci.sys"
|
||||
local webadmin = require "luci.tools.webadmin"
|
||||
local uci = require"luci.model.uci".cursor()
|
||||
local fs = require "nixio.fs"
|
||||
local api = require "luci.model.cbi.passwall.api.api"
|
||||
local appname = "passwall"
|
||||
|
||||
m = Map("passwall")
|
||||
m = Map(appname)
|
||||
|
||||
-- [[ Rule List Settings ]]--
|
||||
s = m:section(TypedSection, "global_rules")
|
||||
@ -15,7 +12,7 @@ s.anonymous = true
|
||||
s:tab("w_hosts", translate("Whitelist Hosts"), "<font color='red'>" ..
|
||||
translate("Join the white list of domain names will not go agent.") ..
|
||||
"</font>")
|
||||
local w_host_file = "/usr/share/passwall/rules/whitelist_host"
|
||||
local w_host_file = string.format("/usr/share/%s/rules/whitelist_host", appname)
|
||||
o = s:taboption("w_hosts", TextValue, "whitelist_host")
|
||||
o.rows = 8
|
||||
o.wrap = "off"
|
||||
@ -30,7 +27,7 @@ o.remove = function(self, section, value) fs.writefile(w_host_file, "") end
|
||||
s:tab("w_ip", translate("Whitelist IP"), "<font color='red'>" .. translate(
|
||||
"These had been joined ip addresses will not use proxy.Please input the ip address or ip address segment,every line can input only one ip address.For example,192.168.0.0/24 or 223.5.5.5.") ..
|
||||
"</font>")
|
||||
local w_ip_file = "/usr/share/passwall/rules/whitelist_ip"
|
||||
local w_ip_file = string.format("/usr/share/%s/rules/whitelist_ip", appname)
|
||||
o = s:taboption("w_ip", TextValue, "whitelist_ip")
|
||||
o.rows = 8
|
||||
o.wrap = "off"
|
||||
@ -46,7 +43,7 @@ s:tab("b_hosts", translate("Blacklist Hosts"),
|
||||
"<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 b_host_file = "/usr/share/passwall/rules/blacklist_host"
|
||||
local b_host_file = string.format("/usr/share/%s/rules/blacklist_host", appname)
|
||||
o = s:taboption("b_hosts", TextValue, "blacklist_host")
|
||||
o.rows = 8
|
||||
o.wrap = "off"
|
||||
@ -61,7 +58,7 @@ o.remove = function(self, section, value) fs.writefile(b_host_file, "") end
|
||||
s:tab("b_ip", translate("Blacklist IP"), "<font color='red'>" .. translate(
|
||||
"These had been joined ip addresses will use proxy.Please input the ip address or ip address segment,every line can input only one ip address.For example,35.24.0.0/24 or 8.8.4.4.") ..
|
||||
"</font>")
|
||||
local b_ip_file = "/usr/share/passwall/rules/blacklist_ip"
|
||||
local b_ip_file = string.format("/usr/share/%s/rules/blacklist_ip", appname)
|
||||
o = s:taboption("b_ip", TextValue, "blacklist_ip")
|
||||
o.rows = 8
|
||||
o.wrap = "off"
|
||||
@ -111,14 +108,14 @@ o.rmempty = true
|
||||
sys.net.mac_hints(function(e, t) o:value(e, "%s (%s)" % {e, t}) end)
|
||||
|
||||
---- TCP Node
|
||||
local tcp_node_num = api.uci_get_type("global_other", "tcp_node_num", 1)
|
||||
local tcp_node_num = m:get("@global_other[0]", "tcp_node_num") or 1
|
||||
if tonumber(tcp_node_num) > 1 then
|
||||
o = s:option(ListValue, "tcp_node", translate("TCP Node"))
|
||||
for i = 1, tcp_node_num, 1 do o:value(i, "TCP_" .. i) end
|
||||
end
|
||||
|
||||
---- UDP Node
|
||||
local udp_node_num = api.uci_get_type("global_other", "udp_node_num", 1)
|
||||
local udp_node_num = m:get("@global_other[0]", "udp_node_num") or 1
|
||||
if tonumber(udp_node_num) > 1 then
|
||||
o = s:option(ListValue, "udp_node", translate("UDP Node"))
|
||||
for i = 1, udp_node_num, 1 do o:value(i, "UDP_" .. i) end
|
||||
|
||||
@ -6,16 +6,21 @@ local util = require "luci.util"
|
||||
local i18n = require "luci.i18n"
|
||||
|
||||
appname = "passwall"
|
||||
curl = "/usr/bin/curl"
|
||||
curl_args = {"-skL", "--connect-timeout 3", "--retry 3", "-m 60"}
|
||||
wget = "/usr/bin/wget"
|
||||
wget_args = {"--no-check-certificate", "--quiet", "--timeout=100", "--tries=3"}
|
||||
command_timeout = 300
|
||||
LEDE_BOARD = nil
|
||||
DISTRIB_TARGET = nil
|
||||
|
||||
function gen_uuid()
|
||||
local uuid = string.gsub(sys.exec("echo -n $(cat /proc/sys/kernel/random/uuid)"), "-", "")
|
||||
return uuid
|
||||
end
|
||||
|
||||
function uci_get_type(type, config, default)
|
||||
local value = uci:get_first(appname, type, config, default) or sys.exec(
|
||||
"echo -n `uci -q get " .. appname .. ".@" .. type ..
|
||||
"[0]." .. config .. "`")
|
||||
local value = uci:get_first(appname, type, config, default) or sys.exec("echo -n `uci -q get " .. appname .. ".@" .. type .."[0]." .. config .. "`")
|
||||
if (value == nil or value == "") and (default and default ~= "") then
|
||||
value = default
|
||||
end
|
||||
@ -23,15 +28,46 @@ function uci_get_type(type, config, default)
|
||||
end
|
||||
|
||||
function uci_get_type_id(id, config, default)
|
||||
local value = uci:get(appname, id, config, default) or
|
||||
sys.exec("echo -n `uci -q get " .. appname .. "." .. id ..
|
||||
"." .. config .. "`")
|
||||
local value = uci:get(appname, id, config, default) or sys.exec("echo -n `uci -q get " .. appname .. "." .. id .. "." .. config .. "`")
|
||||
if (value == nil or value == "") and (default and default ~= "") then
|
||||
value = default
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
function get_v2ray_path()
|
||||
local path = uci_get_type("global_app", "v2ray_file")
|
||||
return path .. "/v2ray"
|
||||
end
|
||||
|
||||
function get_v2ray_version()
|
||||
local path = get_v2ray_path()
|
||||
local version = sys.exec("[ -f '" .. path .. "' ] && " .. path .. " -version | awk '{print $2}' | sed -n 1P")
|
||||
return version
|
||||
end
|
||||
|
||||
function get_kcptun_path()
|
||||
local path = uci_get_type("global_app", "kcptun_client_file")
|
||||
return path
|
||||
end
|
||||
|
||||
function get_kcptun_version()
|
||||
local path = get_kcptun_path()
|
||||
local version = sys.exec("[ -f '" .. path .. "' ] && " .. path .. " -v | awk '{print $3}'")
|
||||
return version
|
||||
end
|
||||
|
||||
function get_brook_path()
|
||||
local path = uci_get_type("global_app", "brook_file")
|
||||
return path
|
||||
end
|
||||
|
||||
function get_brook_version()
|
||||
local path = get_brook_path()
|
||||
local version = sys.exec("[ -f '" .. path .. "' ] && " .. path .. " -v | awk '{print $3}'")
|
||||
return version
|
||||
end
|
||||
|
||||
function _unpack(t, i)
|
||||
i = i or 1
|
||||
if t[i] ~= nil then return t[i], _unpack(t, i + 1) end
|
||||
@ -169,16 +205,7 @@ end
|
||||
function get_api_json(url)
|
||||
local jsonc = require "luci.jsonc"
|
||||
|
||||
local output = {}
|
||||
-- exec(wget, { "-O-", url, _unpack(wget_args) },
|
||||
-- function(chunk) output[#output + 1] = chunk end)
|
||||
-- local json_content = util.trim(table.concat(output))
|
||||
|
||||
local json_content = luci.sys.exec(wget ..
|
||||
" --no-check-certificate --timeout=10 -t 1 -O- " ..
|
||||
url)
|
||||
|
||||
local json_content = luci.sys.exec(curl .. " " .. _unpack(curl_args) .. " " .. url)
|
||||
if json_content == "" then return {} end
|
||||
|
||||
return jsonc.parse(json_content) or {}
|
||||
end
|
||||
|
||||
@ -103,8 +103,7 @@ function to_download(url)
|
||||
|
||||
local tmp_file = util.trim(util.exec("mktemp -u -t brook_download.XXXXXX"))
|
||||
|
||||
local result = api.exec(api.wget, {"-O", tmp_file, url, api._unpack(api.wget_args)},
|
||||
nil, api.command_timeout) == 0
|
||||
local result = api.exec(api.curl, {api._unpack(api.curl_args), "-o", tmp_file, url}, nil, api.command_timeout) == 0
|
||||
|
||||
if not result then
|
||||
api.exec("/bin/rm", {"-f", tmp_file})
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
local ucursor = require "luci.model.uci".cursor()
|
||||
local jsonc = require "luci.jsonc"
|
||||
local node_section = arg[1]
|
||||
local local_port = arg[2]
|
||||
local server_host = arg[3]
|
||||
local server_port = arg[4]
|
||||
local node = ucursor:get_all("passwall", node_section)
|
||||
|
||||
local config = {
|
||||
server = server_host or node.address,
|
||||
server_port = server_port or tonumber(node.port),
|
||||
local_address = "0.0.0.0",
|
||||
local_port = tonumber(local_port),
|
||||
password = node.password,
|
||||
timeout = tonumber(node.timeout),
|
||||
fast_open = (node.tcp_fast_open and node.tcp_fast_open == "true") and true or false,
|
||||
reuse_port = true
|
||||
}
|
||||
|
||||
if node.type == "SS" then
|
||||
config.method = node.ss_encrypt_method
|
||||
if node.ss_plugin and node.ss_plugin ~= "none" then
|
||||
config.plugin = node.ss_plugin
|
||||
config.plugin_opts = node.ss_plugin_opts or nil
|
||||
end
|
||||
elseif node.type == "SSR" then
|
||||
config.method = node.ssr_encrypt_method
|
||||
config.protocol = node.protocol
|
||||
config.protocol_param = node.protocol_param
|
||||
config.obfs = node.obfs
|
||||
config.obfs_param = node.obfs_param
|
||||
end
|
||||
|
||||
print(jsonc.stringify(config, 1))
|
||||
@ -1,24 +1,51 @@
|
||||
local ucursor = require"luci.model.uci".cursor()
|
||||
local sys = require "luci.sys"
|
||||
local json = require "luci.jsonc"
|
||||
local appname = "passwall"
|
||||
local node_section = arg[1]
|
||||
local proto = arg[2]
|
||||
local redir_port = arg[3]
|
||||
local socks_proxy_port = arg[4]
|
||||
local node = ucursor:get_all("passwall", node_section)
|
||||
local node = ucursor:get_all(appname, node_section)
|
||||
local inbounds = {}
|
||||
local outbounds = {}
|
||||
local network = proto
|
||||
local routing = nil
|
||||
|
||||
local function gen_outbound(node)
|
||||
local function gen_outbound(node, tag)
|
||||
local result = nil
|
||||
if node then
|
||||
local node_id = node[".name"]
|
||||
if tag == nil then
|
||||
tag = node_id
|
||||
end
|
||||
if node.type ~= "V2ray" then
|
||||
if node.type == "Socks" then
|
||||
node.v2ray_protocol = "socks"
|
||||
node.v2ray_transport = "tcp"
|
||||
else
|
||||
local node_type = (proto and proto ~= "nil") and proto or "socks"
|
||||
local new_port = sys.exec(string.format("echo -n $(/usr/share/%s/app.sh get_new_port auto tcp)", appname))
|
||||
node.port = new_port
|
||||
sys.call(string.format("/usr/share/%s/app.sh run_socks %s %s %s %s %s",
|
||||
appname,
|
||||
node_id,
|
||||
"127.0.0.1",
|
||||
new_port,
|
||||
string.format("/var/etc/%s/v2_%s_%s.json", appname, node_type, node_id),
|
||||
"4")
|
||||
)
|
||||
node.v2ray_protocol = "socks"
|
||||
node.v2ray_transport = "tcp"
|
||||
node.address = "127.0.0.1"
|
||||
end
|
||||
end
|
||||
result = {
|
||||
tag = node[".name"],
|
||||
tag = tag,
|
||||
protocol = node.v2ray_protocol or "vmess",
|
||||
mux = {
|
||||
enabled = (node.v2ray_mux == "1") and true or false,
|
||||
concurrency = (node.v2ray_mux_concurrency) and
|
||||
tonumber(node.v2ray_mux_concurrency) or 8
|
||||
concurrency = (node.v2ray_mux_concurrency) and tonumber(node.v2ray_mux_concurrency) or 8
|
||||
},
|
||||
-- 底层传输配置
|
||||
streamSettings = (node.v2ray_protocol == "vmess") and {
|
||||
@ -26,10 +53,10 @@ local function gen_outbound(node)
|
||||
security = node.v2ray_stream_security,
|
||||
tlsSettings = (node.v2ray_stream_security == "tls") and {
|
||||
serverName = node.tls_serverName,
|
||||
allowInsecure = (node.tls_allowInsecure == "1") and true or
|
||||
false
|
||||
allowInsecure = (node.tls_allowInsecure == "1") and true or false
|
||||
} or nil,
|
||||
tcpSettings = (node.v2ray_transport == "tcp") and {
|
||||
tcpSettings = (node.v2ray_transport == "tcp" and
|
||||
node.v2ray_protocol ~= "socks") and {
|
||||
header = {
|
||||
type = node.v2ray_tcp_guise,
|
||||
request = {
|
||||
@ -45,8 +72,7 @@ local function gen_outbound(node)
|
||||
tti = tonumber(node.v2ray_mkcp_tti),
|
||||
uplinkCapacity = tonumber(node.v2ray_mkcp_uplinkCapacity),
|
||||
downlinkCapacity = tonumber(node.v2ray_mkcp_downlinkCapacity),
|
||||
congestion = (node.v2ray_mkcp_congestion == "1") and true or
|
||||
false,
|
||||
congestion = (node.v2ray_mkcp_congestion == "1") and true or false,
|
||||
readBufferSize = tonumber(node.v2ray_mkcp_readBufferSize),
|
||||
writeBufferSize = tonumber(node.v2ray_mkcp_writeBufferSize),
|
||||
header = {type = node.v2ray_mkcp_guise}
|
||||
@ -82,19 +108,12 @@ local function gen_outbound(node)
|
||||
}
|
||||
}
|
||||
} or nil,
|
||||
servers = (node.v2ray_protocol == "http" or node.v2ray_protocol == "socks" or node.v2ray_protocol == "shadowsocks") and {
|
||||
servers = (node.v2ray_protocol == "socks") and {
|
||||
{
|
||||
address = node.address,
|
||||
port = tonumber(node.port),
|
||||
method = node.v2ray_ss_encrypt_method,
|
||||
password = node.password or "",
|
||||
ota = (node.v2ray_ss_ota == '1') and true or false,
|
||||
users = (node.username and node.password) and {
|
||||
{
|
||||
user = node.username or "",
|
||||
pass = node.password or ""
|
||||
}
|
||||
} or nil
|
||||
users = (node.username and node.password) and
|
||||
{{user = node.username, pass = node.password}} or nil
|
||||
}
|
||||
} or nil
|
||||
}
|
||||
@ -139,12 +158,83 @@ if redir_port ~= "nil" then
|
||||
end
|
||||
end
|
||||
|
||||
local outbound = gen_outbound(node)
|
||||
if outbound then table.insert(outbounds, outbound) end
|
||||
if node.v2ray_protocol == "_shunt" then
|
||||
local rules = {}
|
||||
|
||||
ucursor:foreach(appname, "shunt_rules", function(e)
|
||||
local _node_id = node[e[".name"]] or nil
|
||||
if _node_id and _node_id ~= "nil" then
|
||||
local _node = ucursor:get_all(appname, _node_id)
|
||||
local _outbound = gen_outbound(_node, e[".name"])
|
||||
if _outbound then
|
||||
table.insert(outbounds, _outbound)
|
||||
if e.domain_list then
|
||||
local _domain = {}
|
||||
string.gsub(e.domain_list, '[^' .. "\r\n" .. ']+', function(w)
|
||||
table.insert(_domain, w)
|
||||
end)
|
||||
table.insert(rules, {
|
||||
type = "field",
|
||||
outboundTag = e[".name"],
|
||||
domain = _domain
|
||||
})
|
||||
end
|
||||
if e.ip_list then
|
||||
local _ip = {}
|
||||
string.gsub(e.ip_list, '[^' .. "\r\n" .. ']+', function(w)
|
||||
table.insert(_ip, w)
|
||||
end)
|
||||
table.insert(rules, {
|
||||
type = "field",
|
||||
outboundTag = e[".name"],
|
||||
ip = _ip
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
local default_node_id = node.default_node or nil
|
||||
if default_node_id and default_node_id ~= "nil" then
|
||||
local default_node = ucursor:get_all(appname, default_node_id)
|
||||
local default_outbound = gen_outbound(default_node, "default")
|
||||
if default_outbound then
|
||||
table.insert(outbounds, default_outbound)
|
||||
local rule = {
|
||||
type = "field",
|
||||
outboundTag = "default",
|
||||
network = network
|
||||
}
|
||||
table.insert(rules, rule)
|
||||
end
|
||||
end
|
||||
|
||||
routing = {domainStrategy = "IPOnDemand", rules = rules}
|
||||
|
||||
elseif node.v2ray_protocol == "_balancing" then
|
||||
if node.v2ray_balancing_node then
|
||||
local nodes = node.v2ray_balancing_node
|
||||
local length = #nodes
|
||||
for i = 1, length do
|
||||
local node = ucursor:get_all(appname, nodes[i])
|
||||
local outbound = gen_outbound(node)
|
||||
if outbound then table.insert(outbounds, outbound) end
|
||||
end
|
||||
routing = {
|
||||
domainStrategy = "IPOnDemand",
|
||||
balancers = {{tag = "balancer", selector = nodes}},
|
||||
rules = {
|
||||
{type = "field", network = "tcp,udp", balancerTag = "balancer"}
|
||||
}
|
||||
}
|
||||
end
|
||||
else
|
||||
local outbound = gen_outbound(node)
|
||||
if outbound then table.insert(outbounds, outbound) end
|
||||
end
|
||||
|
||||
-- 额外传出连接
|
||||
table.insert(outbounds,
|
||||
{protocol = "freedom", tag = "direct", settings = {keep = ""}})
|
||||
table.insert(outbounds, {protocol = "freedom", tag = "direct", settings = {keep = ""}})
|
||||
|
||||
local v2ray = {
|
||||
log = {
|
||||
|
||||
@ -1,193 +0,0 @@
|
||||
local ucursor = require"luci.model.uci".cursor()
|
||||
local sys = require "luci.sys"
|
||||
local json = require "luci.jsonc"
|
||||
local node_section = arg[1]
|
||||
local proto = arg[2]
|
||||
local redir_port = arg[3]
|
||||
local socks_proxy_port = arg[4]
|
||||
local node = ucursor:get_all("passwall", node_section)
|
||||
local inbounds = {}
|
||||
local outbounds = {}
|
||||
local network = proto
|
||||
local routing = nil
|
||||
|
||||
local function gen_outbound(node)
|
||||
local result = nil
|
||||
if node then
|
||||
local node_id = node[".name"]
|
||||
if node.type ~= "V2ray" then
|
||||
if node.type == "Socks5" then
|
||||
node.v2ray_protocol = "socks"
|
||||
node.v2ray_transport = "tcp"
|
||||
else
|
||||
local node_type = (proto and proto ~= "nil") and proto or
|
||||
"socks"
|
||||
local new_port = sys.exec(
|
||||
"echo -n $(/usr/share/passwall/app.sh get_new_port auto tcp)")
|
||||
node.port = new_port
|
||||
sys.call(string.format(
|
||||
"/usr/share/passwall/app.sh gen_start_config %s %s %s %s %s %s",
|
||||
node_id, new_port, "SOCKS",
|
||||
"/var/etc/passwall/v2_balancing_" .. node_type .. "_" ..
|
||||
node_id .. ".json", "4", "127.0.0.1"))
|
||||
node.v2ray_protocol = "socks"
|
||||
node.v2ray_transport = "tcp"
|
||||
node.address = "127.0.0.1"
|
||||
end
|
||||
end
|
||||
result = {
|
||||
tag = node_id,
|
||||
protocol = node.v2ray_protocol or "vmess",
|
||||
mux = {
|
||||
enabled = (node.v2ray_mux == "1") and true or false,
|
||||
concurrency = (node.v2ray_mux_concurrency) and
|
||||
tonumber(node.v2ray_mux_concurrency) or 8
|
||||
},
|
||||
-- 底层传输配置
|
||||
streamSettings = (node.v2ray_protocol == "vmess") and {
|
||||
network = node.v2ray_transport,
|
||||
security = node.v2ray_stream_security,
|
||||
tlsSettings = (node.v2ray_stream_security == "tls") and {
|
||||
serverName = node.tls_serverName,
|
||||
allowInsecure = (node.tls_allowInsecure == "1") and true or
|
||||
false
|
||||
} or nil,
|
||||
tcpSettings = (node.v2ray_transport == "tcp" and
|
||||
node.v2ray_protocol ~= "socks") and {
|
||||
header = {
|
||||
type = node.v2ray_tcp_guise,
|
||||
request = {
|
||||
path = node.v2ray_tcp_guise_http_path or {"/"},
|
||||
headers = {
|
||||
Host = node.v2ray_tcp_guise_http_host or {}
|
||||
}
|
||||
} or {}
|
||||
}
|
||||
} or nil,
|
||||
kcpSettings = (node.v2ray_transport == "mkcp") and {
|
||||
mtu = tonumber(node.v2ray_mkcp_mtu),
|
||||
tti = tonumber(node.v2ray_mkcp_tti),
|
||||
uplinkCapacity = tonumber(node.v2ray_mkcp_uplinkCapacity),
|
||||
downlinkCapacity = tonumber(node.v2ray_mkcp_downlinkCapacity),
|
||||
congestion = (node.v2ray_mkcp_congestion == "1") and true or
|
||||
false,
|
||||
readBufferSize = tonumber(node.v2ray_mkcp_readBufferSize),
|
||||
writeBufferSize = tonumber(node.v2ray_mkcp_writeBufferSize),
|
||||
header = {type = node.v2ray_mkcp_guise}
|
||||
} or nil,
|
||||
wsSettings = (node.v2ray_transport == "ws") and {
|
||||
path = node.v2ray_ws_path or "",
|
||||
headers = (node.v2ray_ws_host ~= nil) and
|
||||
{Host = node.v2ray_ws_host} or nil
|
||||
} or nil,
|
||||
httpSettings = (node.v2ray_transport == "h2") and
|
||||
{path = node.v2ray_h2_path, host = node.v2ray_h2_host} or
|
||||
nil,
|
||||
dsSettings = (node.v2ray_transport == "ds") and
|
||||
{path = node.v2ray_ds_path} or nil,
|
||||
quicSettings = (node.v2ray_transport == "quic") and {
|
||||
security = node.v2ray_quic_security,
|
||||
key = node.v2ray_quic_key,
|
||||
header = {type = node.v2ray_quic_guise}
|
||||
} or nil
|
||||
} or nil,
|
||||
settings = {
|
||||
vnext = (node.v2ray_protocol == "vmess") and {
|
||||
{
|
||||
address = node.address,
|
||||
port = tonumber(node.port),
|
||||
users = {
|
||||
{
|
||||
id = node.v2ray_VMess_id,
|
||||
alterId = tonumber(node.v2ray_VMess_alterId),
|
||||
level = tonumber(node.v2ray_VMess_level),
|
||||
security = node.v2ray_security
|
||||
}
|
||||
}
|
||||
}
|
||||
} or nil,
|
||||
servers = (node.v2ray_protocol == "socks") and {
|
||||
{
|
||||
address = node.address,
|
||||
port = tonumber(node.port),
|
||||
users = (node.username and node.password) and
|
||||
{{user = node.username, pass = node.password}} or
|
||||
nil
|
||||
}
|
||||
} or nil
|
||||
}
|
||||
}
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
if socks_proxy_port ~= "nil" then
|
||||
table.insert(inbounds, {
|
||||
listen = "0.0.0.0",
|
||||
port = socks_proxy_port,
|
||||
protocol = "socks",
|
||||
settings = {auth = "noauth", udp = true, ip = "127.0.0.1"}
|
||||
})
|
||||
network = "tcp,udp"
|
||||
end
|
||||
|
||||
if redir_port ~= "nil" then
|
||||
table.insert(inbounds, {
|
||||
port = redir_port,
|
||||
protocol = "dokodemo-door",
|
||||
settings = {network = proto, followRedirect = true},
|
||||
sniffing = {enabled = true, destOverride = {"http", "tls"}}
|
||||
})
|
||||
if proto == "tcp" and node.v2ray_tcp_socks == "1" then
|
||||
table.insert(inbounds, {
|
||||
listen = "0.0.0.0",
|
||||
port = tonumber(node.v2ray_tcp_socks_port),
|
||||
protocol = "socks",
|
||||
settings = {
|
||||
auth = node.v2ray_tcp_socks_auth,
|
||||
accounts = (node.v2ray_tcp_socks_auth == "password") and {
|
||||
{
|
||||
user = node.v2ray_tcp_socks_auth_username,
|
||||
pass = node.v2ray_tcp_socks_auth_password
|
||||
}
|
||||
} or nil,
|
||||
udp = true
|
||||
}
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
if node.v2ray_balancing_node then
|
||||
local nodes = node.v2ray_balancing_node
|
||||
local length = #nodes
|
||||
for i = 1, length do
|
||||
local node = ucursor:get_all("passwall", nodes[i])
|
||||
local outbound = gen_outbound(node)
|
||||
if outbound then table.insert(outbounds, outbound) end
|
||||
end
|
||||
routing = {
|
||||
domainStrategy = "IPOnDemand",
|
||||
balancers = {{tag = "balancer", selector = nodes}},
|
||||
rules = {
|
||||
{type = "field", network = "tcp,udp", balancerTag = "balancer"}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
-- 额外传出连接
|
||||
table.insert(outbounds,
|
||||
{protocol = "freedom", tag = "direct", settings = {keep = ""}})
|
||||
|
||||
local v2ray = {
|
||||
log = {
|
||||
-- error = "/var/log/v2ray.log",
|
||||
loglevel = "warning"
|
||||
},
|
||||
-- 传入连接
|
||||
inbounds = inbounds,
|
||||
-- 传出连接
|
||||
outbounds = outbounds,
|
||||
-- 路由
|
||||
routing = routing
|
||||
}
|
||||
print(json.stringify(v2ray, 1))
|
||||
@ -1,222 +0,0 @@
|
||||
local ucursor = require"luci.model.uci".cursor()
|
||||
local sys = require "luci.sys"
|
||||
local json = require "luci.jsonc"
|
||||
local node_section = arg[1]
|
||||
local proto = arg[2]
|
||||
local redir_port = arg[3]
|
||||
local socks_proxy_port = arg[4]
|
||||
local node = ucursor:get_all("passwall", node_section)
|
||||
local inbounds = {}
|
||||
local outbounds = {}
|
||||
local network = proto
|
||||
local routing = nil
|
||||
|
||||
local function gen_outbound(node, tag)
|
||||
local result = nil
|
||||
if node then
|
||||
local node_id = node[".name"]
|
||||
if node.type ~= "V2ray" then
|
||||
if node.type == "Socks5" then
|
||||
node.v2ray_protocol = "socks"
|
||||
node.v2ray_transport = "tcp"
|
||||
else
|
||||
local node_type = (proto and proto ~= "nil") and proto or "socks"
|
||||
local new_port = sys.exec("echo -n $(/usr/share/passwall/app.sh get_new_port auto tcp)")
|
||||
node.port = new_port
|
||||
sys.call(string.format("/usr/share/passwall/app.sh gen_start_config %s %s %s %s %s %s",
|
||||
node_id, new_port, "SOCKS",
|
||||
"/var/etc/passwall/v2_shunt_" .. node_type .. "_" .. node_id .. ".json", "4", "127.0.0.1"))
|
||||
node.v2ray_protocol = "socks"
|
||||
node.v2ray_transport = "tcp"
|
||||
node.address = "127.0.0.1"
|
||||
end
|
||||
end
|
||||
result = {
|
||||
tag = tag,
|
||||
protocol = node.v2ray_protocol or "vmess",
|
||||
mux = {
|
||||
enabled = (node.v2ray_mux == "1") and true or false,
|
||||
concurrency = (node.v2ray_mux_concurrency) and tonumber(node.v2ray_mux_concurrency) or 8
|
||||
},
|
||||
-- 底层传输配置
|
||||
streamSettings = (node.v2ray_protocol == "vmess") and {
|
||||
network = node.v2ray_transport,
|
||||
security = node.v2ray_stream_security,
|
||||
tlsSettings = (node.v2ray_stream_security == "tls") and {
|
||||
serverName = node.tls_serverName,
|
||||
allowInsecure = (node.tls_allowInsecure == "1") and true or false
|
||||
} or nil,
|
||||
tcpSettings = (node.v2ray_transport == "tcp" and
|
||||
node.v2ray_protocol ~= "socks") and {
|
||||
header = {
|
||||
type = node.v2ray_tcp_guise,
|
||||
request = {
|
||||
path = node.v2ray_tcp_guise_http_path or {"/"},
|
||||
headers = {
|
||||
Host = node.v2ray_tcp_guise_http_host or {}
|
||||
}
|
||||
} or {}
|
||||
}
|
||||
} or nil,
|
||||
kcpSettings = (node.v2ray_transport == "mkcp") and {
|
||||
mtu = tonumber(node.v2ray_mkcp_mtu),
|
||||
tti = tonumber(node.v2ray_mkcp_tti),
|
||||
uplinkCapacity = tonumber(node.v2ray_mkcp_uplinkCapacity),
|
||||
downlinkCapacity = tonumber(node.v2ray_mkcp_downlinkCapacity),
|
||||
congestion = (node.v2ray_mkcp_congestion == "1") and true or false,
|
||||
readBufferSize = tonumber(node.v2ray_mkcp_readBufferSize),
|
||||
writeBufferSize = tonumber(node.v2ray_mkcp_writeBufferSize),
|
||||
header = {type = node.v2ray_mkcp_guise}
|
||||
} or nil,
|
||||
wsSettings = (node.v2ray_transport == "ws") and {
|
||||
path = node.v2ray_ws_path or "",
|
||||
headers = (node.v2ray_ws_host ~= nil) and
|
||||
{Host = node.v2ray_ws_host} or nil
|
||||
} or nil,
|
||||
httpSettings = (node.v2ray_transport == "h2") and
|
||||
{path = node.v2ray_h2_path, host = node.v2ray_h2_host} or
|
||||
nil,
|
||||
dsSettings = (node.v2ray_transport == "ds") and
|
||||
{path = node.v2ray_ds_path} or nil,
|
||||
quicSettings = (node.v2ray_transport == "quic") and {
|
||||
security = node.v2ray_quic_security,
|
||||
key = node.v2ray_quic_key,
|
||||
header = {type = node.v2ray_quic_guise}
|
||||
} or nil
|
||||
} or nil,
|
||||
settings = {
|
||||
vnext = (node.v2ray_protocol == "vmess") and {
|
||||
{
|
||||
address = node.address,
|
||||
port = tonumber(node.port),
|
||||
users = {
|
||||
{
|
||||
id = node.v2ray_VMess_id,
|
||||
alterId = tonumber(node.v2ray_VMess_alterId),
|
||||
level = tonumber(node.v2ray_VMess_level),
|
||||
security = node.v2ray_security
|
||||
}
|
||||
}
|
||||
}
|
||||
} or nil,
|
||||
servers = (node.v2ray_protocol == "socks") and {
|
||||
{
|
||||
address = node.address,
|
||||
port = tonumber(node.port),
|
||||
users = (node.username and node.password) and
|
||||
{{user = node.username, pass = node.password}} or nil
|
||||
}
|
||||
} or nil
|
||||
}
|
||||
}
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
if socks_proxy_port ~= "nil" then
|
||||
table.insert(inbounds, {
|
||||
listen = "0.0.0.0",
|
||||
port = socks_proxy_port,
|
||||
protocol = "socks",
|
||||
settings = {auth = "noauth", udp = true, ip = "127.0.0.1"}
|
||||
})
|
||||
network = "tcp,udp"
|
||||
end
|
||||
|
||||
if redir_port ~= "nil" then
|
||||
table.insert(inbounds, {
|
||||
port = redir_port,
|
||||
protocol = "dokodemo-door",
|
||||
settings = {network = proto, followRedirect = true},
|
||||
sniffing = {enabled = true, destOverride = {"http", "tls"}}
|
||||
})
|
||||
if proto == "tcp" and node.v2ray_tcp_socks == "1" then
|
||||
table.insert(inbounds, {
|
||||
listen = "0.0.0.0",
|
||||
port = tonumber(node.v2ray_tcp_socks_port),
|
||||
protocol = "socks",
|
||||
settings = {
|
||||
auth = node.v2ray_tcp_socks_auth,
|
||||
accounts = (node.v2ray_tcp_socks_auth == "password") and {
|
||||
{
|
||||
user = node.v2ray_tcp_socks_auth_username,
|
||||
pass = node.v2ray_tcp_socks_auth_password
|
||||
}
|
||||
} or nil,
|
||||
udp = true
|
||||
}
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
local rules = {}
|
||||
|
||||
local youtube_node_id = node.youtube_node or nil
|
||||
if youtube_node_id and youtube_node_id ~= "nil" then
|
||||
local youtube_node = ucursor:get_all("passwall", youtube_node_id)
|
||||
local youtube_outbound = gen_outbound(youtube_node, "youtube")
|
||||
if youtube_outbound then
|
||||
table.insert(outbounds, youtube_outbound)
|
||||
local rule = {
|
||||
type = "field",
|
||||
domain = {
|
||||
"youtube", "youtube.com", "youtu.be", "googlevideo.com",
|
||||
"ytimg.com", "gvt2.com"
|
||||
},
|
||||
outboundTag = "youtube"
|
||||
}
|
||||
table.insert(rules, rule)
|
||||
end
|
||||
end
|
||||
|
||||
local netflix_node_id = node.netflix_node or nil
|
||||
if netflix_node_id and netflix_node_id ~= "nil" then
|
||||
local netflix_node = ucursor:get_all("passwall", netflix_node_id)
|
||||
local netflix_outbound = gen_outbound(netflix_node, "netflix")
|
||||
if netflix_outbound then
|
||||
table.insert(outbounds, netflix_outbound)
|
||||
local rule = {
|
||||
type = "field",
|
||||
domain = {
|
||||
"netflix", "netflix.com", "nflxso.net", "nflxext.com",
|
||||
"nflximg.com", "nflximg.net", "nflxvideo.net", "fast.com"
|
||||
},
|
||||
outboundTag = "netflix"
|
||||
}
|
||||
table.insert(rules, rule)
|
||||
end
|
||||
end
|
||||
|
||||
local default_node_id = node.default_node or nil
|
||||
if default_node_id and default_node_id ~= "nil" then
|
||||
local default_node = ucursor:get_all("passwall", default_node_id)
|
||||
local default_outbound = gen_outbound(default_node, "default")
|
||||
if default_outbound then
|
||||
table.insert(outbounds, default_outbound)
|
||||
local rule = {
|
||||
type = "field",
|
||||
outboundTag = "default",
|
||||
network = network
|
||||
}
|
||||
table.insert(rules, rule)
|
||||
end
|
||||
end
|
||||
|
||||
routing = {domainStrategy = "IPOnDemand", rules = rules}
|
||||
|
||||
-- 额外传出连接
|
||||
table.insert(outbounds, {protocol = "freedom", tag = "direct", settings = {keep = ""}})
|
||||
|
||||
local v2ray = {
|
||||
log = {
|
||||
-- error = "/var/log/v2ray.log",
|
||||
loglevel = "warning"
|
||||
},
|
||||
-- 传入连接
|
||||
inbounds = inbounds,
|
||||
-- 传出连接
|
||||
outbounds = outbounds,
|
||||
-- 路由
|
||||
routing = routing
|
||||
}
|
||||
print(json.stringify(v2ray, 1))
|
||||
@ -99,9 +99,7 @@ function to_download(url)
|
||||
|
||||
local tmp_file = util.trim(util.exec("mktemp -u -t kcptun_download.XXXXXX"))
|
||||
|
||||
local result = api.exec(api.wget,
|
||||
{"-O", tmp_file, url, api._unpack(api.wget_args)},
|
||||
nil, api.command_timeout) == 0
|
||||
local result = api.exec(api.curl, {api._unpack(api.curl_args), "-o", tmp_file, url}, nil, api.command_timeout) == 0
|
||||
|
||||
if not result then
|
||||
api.exec("/bin/rm", {"-f", tmp_file})
|
||||
|
||||
@ -1,110 +0,0 @@
|
||||
module("luci.model.cbi.passwall.api.passwall", package.seeall)
|
||||
local fs = require "nixio.fs"
|
||||
local sys = require "luci.sys"
|
||||
local util = require "luci.util"
|
||||
local i18n = require "luci.i18n"
|
||||
local api = require "luci.model.cbi.passwall.api.api"
|
||||
|
||||
local luci_api =
|
||||
"https://api.github.com/repos/lienol/openwrt-package/releases/latest"
|
||||
|
||||
function get_luci_version()
|
||||
local ipkg = require "luci.model.ipkg"
|
||||
local package_name = "luci-app-passwall"
|
||||
local package_info = ipkg.info(package_name) or {}
|
||||
if next(package_info) ~= nil then
|
||||
return package_info[package_name]["Version"]
|
||||
end
|
||||
return ""
|
||||
end
|
||||
|
||||
function to_check()
|
||||
local json = api.get_api_json(luci_api)
|
||||
|
||||
if json.tag_name == nil then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("Get remote version info failed.")
|
||||
}
|
||||
end
|
||||
|
||||
local remote_version = json.tag_name:match("[^v]+")
|
||||
|
||||
local needs_update = api.compare_versions(get_luci_version(client_file),
|
||||
"<", remote_version)
|
||||
local html_url, download_url
|
||||
|
||||
if needs_update then
|
||||
html_url = json.html_url
|
||||
for _, v in ipairs(json.assets) do
|
||||
local n = v.name
|
||||
if n then
|
||||
if n:match("luci%-app%-passwall") then
|
||||
download_url = v.browser_download_url
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if needs_update and not download_url then
|
||||
return {
|
||||
code = 1,
|
||||
now_version = get_luci_version(),
|
||||
version = remote_version,
|
||||
html_url = html_url,
|
||||
error = i18n.translate(
|
||||
"New version found, but failed to get new version download url.")
|
||||
}
|
||||
end
|
||||
|
||||
return {
|
||||
code = 0,
|
||||
update = needs_update,
|
||||
now_version = get_luci_version(),
|
||||
version = remote_version,
|
||||
url = {html = html_url, download = download_url}
|
||||
}
|
||||
end
|
||||
|
||||
function update_luci(url, save)
|
||||
if not url or url == "" then
|
||||
return {code = 1, error = i18n.translate("Download url is required.")}
|
||||
end
|
||||
|
||||
sys.call("/bin/rm -f /tmp/luci_passwall.*.ipk")
|
||||
|
||||
local tmp_file =
|
||||
util.trim(util.exec("mktemp -u -t luci_passwall.XXXXXX")) .. ".ipk"
|
||||
|
||||
local result = api.exec(api.wget,
|
||||
{"-O", tmp_file, url, api._unpack(api.wget_args)},
|
||||
nil, api.command_timeout) == 0
|
||||
|
||||
if not result then
|
||||
api.exec("/bin/rm", {"-f", tmp_file})
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("File download failed or timed out: %s", url)
|
||||
}
|
||||
end
|
||||
|
||||
api.exec("/bin/opkg", {"remove", "luci-app-passwall"})
|
||||
|
||||
local opkg_args = {"--force-downgrade", "--force-reinstall"}
|
||||
|
||||
if save ~= "true" then opkg_args[#opkg_args + 1] = "--force-maintainer" end
|
||||
|
||||
result =
|
||||
api.exec("/bin/opkg", {"install", tmp_file, api._unpack(opkg_args)}) ==
|
||||
0
|
||||
|
||||
if not result then
|
||||
api.exec("/bin/rm", {"-f", tmp_file})
|
||||
return {code = 1, error = i18n.translate("Package update failed.")}
|
||||
end
|
||||
|
||||
api.exec("/bin/rm", {"-f", tmp_file})
|
||||
api.exec("/bin/rm", {"-rf", "/tmp/luci-indexcache", "/tmp/luci-modulecache"})
|
||||
|
||||
return {code = 0}
|
||||
end
|
||||
@ -95,9 +95,7 @@ function to_download(url)
|
||||
|
||||
local tmp_file = util.trim(util.exec("mktemp -u -t v2ray_download.XXXXXX"))
|
||||
|
||||
local result = api.exec(api.wget,
|
||||
{"-O", tmp_file, url, api._unpack(api.wget_args)},
|
||||
nil, api.command_timeout) == 0
|
||||
local result = api.exec(api.curl, {api._unpack(api.curl_args), "-o", tmp_file, url}, nil, api.command_timeout) == 0
|
||||
|
||||
if not result then
|
||||
api.exec("/bin/rm", {"-f", tmp_file})
|
||||
|
||||
@ -1,20 +1,22 @@
|
||||
local uci = require"luci.model.uci".cursor()
|
||||
local api = require "luci.model.cbi.passwall.api.api"
|
||||
local appname = "passwall"
|
||||
|
||||
local n = {}
|
||||
local nodes_table = {}
|
||||
uci:foreach(appname, "nodes", function(e)
|
||||
if e.type and e.remarks and e.address and e.port then
|
||||
if (e.type == "V2ray_balancing" or e.type == "V2ray_shunt") or (e.address:match("[\u4e00-\u9fa5]") and e.address:find("%.") and e.address:sub(#e.address) ~= ".") then
|
||||
n[e[".name"]] = "%s:[%s] %s:%s" % {e.type, e.remarks, e.address, e.port}
|
||||
if e.type and e.remarks then
|
||||
local remarks = ""
|
||||
if e.type == "V2ray" and (e.v2ray_protocol == "_balancing" or e.v2ray_protocol == "_shunt") then
|
||||
remarks = "%s:[%s] " % {translatef(e.type .. e.v2ray_protocol), e.remarks}
|
||||
else
|
||||
remarks = "%s:[%s] %s:%s" % {e.type, e.remarks, e.address, e.port}
|
||||
end
|
||||
nodes_table[#nodes_table + 1] = {
|
||||
id = e[".name"],
|
||||
remarks = remarks
|
||||
}
|
||||
end
|
||||
end)
|
||||
|
||||
local key_table = {}
|
||||
for key, _ in pairs(n) do table.insert(key_table, key) end
|
||||
table.sort(key_table)
|
||||
|
||||
m = Map(appname)
|
||||
|
||||
-- [[ Auto Switch Settings ]]--
|
||||
@ -32,15 +34,14 @@ o = s:option(Value, "testing_time", translate("How often is a diagnosis made"),
|
||||
o.default = "3"
|
||||
|
||||
---- TCP Node
|
||||
-- local tcp_node_num = tonumber(api.uci_get_type("global_other", "tcp_node_num", 1))
|
||||
-- local tcp_node_num = tonumber(m:get("@global_other[0]", "tcp_node_num") or 1)
|
||||
-- 暂时只支持TCP1
|
||||
local tcp_node_num = 1
|
||||
for i = 1, tcp_node_num, 1 do
|
||||
o = s:option(DynamicList, "tcp_node" .. i,
|
||||
"TCP " .. i .. " " .. translate("List of backup nodes"),
|
||||
translate(
|
||||
"List of backup nodes, the first of which must be the primary node and the others the standby node."))
|
||||
for _, key in pairs(key_table) do o:value(key, n[key]) end
|
||||
o = s:option(DynamicList, "tcp_node" .. i, "TCP " .. i .. " " .. translate("List of backup nodes"), translate("List of backup nodes, the first of which must be the primary node and the others the standby node."))
|
||||
for k, v in pairs(nodes_table) do
|
||||
o:value(v.id, v.remarks)
|
||||
end
|
||||
end
|
||||
|
||||
return m
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
local o = require "luci.dispatcher"
|
||||
local fs = require "nixio.fs"
|
||||
local sys = require "luci.sys"
|
||||
local ipkg = require("luci.model.ipkg")
|
||||
local uci = require"luci.model.uci".cursor()
|
||||
local api = require "luci.model.cbi.passwall.api.api"
|
||||
local appname = "passwall"
|
||||
|
||||
local function is_installed(e) return ipkg.installed(e) end
|
||||
@ -14,36 +12,32 @@ local function is_finded(e)
|
||||
false
|
||||
end
|
||||
|
||||
local n = {}
|
||||
local nodes_table = {}
|
||||
uci:foreach(appname, "nodes", function(e)
|
||||
local type = e.type
|
||||
if type == nil then type = "" end
|
||||
local address = e.address
|
||||
if address == nil then address = "" end
|
||||
-- if (type == "V2ray_balancing" or type == "V2ray_shunt") or (address:match("[\u4e00-\u9fa5]") and address:find("%.") and address:sub(#address) ~= ".") then
|
||||
if type and address and e.remarks then
|
||||
if e.use_kcp and e.use_kcp == "1" then
|
||||
n[e[".name"]] = "%s+%s:[%s] %s" %
|
||||
{translate(type), "Kcptun", e.remarks, address}
|
||||
if e.type and e.remarks then
|
||||
local remarks = ""
|
||||
if e.type == "V2ray" and (e.v2ray_protocol == "_balancing" or e.v2ray_protocol == "_shunt") then
|
||||
remarks = "%s:[%s] " % {translatef(e.type .. e.v2ray_protocol), e.remarks}
|
||||
else
|
||||
n[e[".name"]] = "%s:[%s] %s" %
|
||||
{translate(type), e.remarks, address}
|
||||
if e.use_kcp and e.use_kcp == "1" then
|
||||
remarks = "%s+%s:[%s] %s" % {e.type, "Kcptun", e.remarks, address}
|
||||
else
|
||||
remarks = "%s:[%s] %s:%s" % {e.type, e.remarks, e.address, e.port}
|
||||
end
|
||||
end
|
||||
nodes_table[#nodes_table + 1] = {
|
||||
id = e[".name"],
|
||||
remarks = remarks
|
||||
}
|
||||
end
|
||||
-- end
|
||||
end)
|
||||
|
||||
local key_table = {}
|
||||
for key, _ in pairs(n) do table.insert(key_table, key) end
|
||||
table.sort(key_table)
|
||||
|
||||
m = Map(appname)
|
||||
local status_use_big_icon = api.uci_get_type("global_other",
|
||||
"status_use_big_icon", 1)
|
||||
local status_use_big_icon = m:get("@global_other[0]", "status_use_big_icon") or 1
|
||||
if status_use_big_icon and tonumber(status_use_big_icon) == 1 then
|
||||
m:append(Template("passwall/global/status"))
|
||||
m:append(Template(appname .. "/global/status"))
|
||||
else
|
||||
m:append(Template("passwall/global/status2"))
|
||||
m:append(Template(appname .. "/global/status2"))
|
||||
end
|
||||
|
||||
-- [[ Global Settings ]]--
|
||||
@ -57,8 +51,7 @@ o = s:option(Flag, "enabled", translate("Main switch"))
|
||||
o.rmempty = false
|
||||
|
||||
---- TCP Node
|
||||
local tcp_node_num = tonumber(
|
||||
api.uci_get_type("global_other", "tcp_node_num", 1))
|
||||
local tcp_node_num = tonumber(m:get("@global_other[0]", "tcp_node_num") or 1)
|
||||
for i = 1, tcp_node_num, 1 do
|
||||
if i == 1 then
|
||||
o = s:option(ListValue, "tcp_node" .. i, translate("TCP Node"))
|
||||
@ -68,41 +61,24 @@ for i = 1, tcp_node_num, 1 do
|
||||
translate("TCP Node") .. " " .. i)
|
||||
end
|
||||
o:value("nil", translate("Close"))
|
||||
for _, key in pairs(key_table) do o:value(key, n[key]) end
|
||||
for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) end
|
||||
end
|
||||
|
||||
---- UDP Node
|
||||
local udp_node_num = tonumber(
|
||||
api.uci_get_type("global_other", "udp_node_num", 1))
|
||||
local udp_node_num = tonumber(m:get("@global_other[0]", "udp_node_num") or 1)
|
||||
for i = 1, udp_node_num, 1 do
|
||||
if i == 1 then
|
||||
o = s:option(ListValue, "udp_node" .. i, translate("UDP Node"))
|
||||
-- o.description = translate("For Game Mode or DNS resolution and more.") .. translate("The selected server will not use Kcptun.")
|
||||
o:value("nil", translate("Close"))
|
||||
o:value("tcp", translate("Same as the tcp node"))
|
||||
o:value("tcp_", translate("Same as the tcp node") .. "(" .. translate("New process") .. ")")
|
||||
else
|
||||
o = s:option(ListValue, "udp_node" .. i,
|
||||
translate("UDP Node") .. " " .. i)
|
||||
o:value("nil", translate("Close"))
|
||||
end
|
||||
for _, key in pairs(key_table) do o:value(key, n[key]) end
|
||||
end
|
||||
|
||||
---- Socks Node
|
||||
local socks_node_num = tonumber(api.uci_get_type("global_other",
|
||||
"socks_node_num", 1))
|
||||
for i = 1, socks_node_num, 1 do
|
||||
if i == 1 then
|
||||
o = s:option(ListValue, "socks_node" .. i, translate("Socks Node"))
|
||||
-- o.description = translate("The client can use the router's Socks proxy.")
|
||||
o:value("nil", translate("Close"))
|
||||
o:value("tcp", translate("Same as the tcp node"))
|
||||
else
|
||||
o = s:option(ListValue, "socks_node" .. i,
|
||||
translate("Socks Node") .. " " .. i)
|
||||
o:value("nil", translate("Close"))
|
||||
end
|
||||
for _, key in pairs(key_table) do o:value(key, n[key]) end
|
||||
for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) end
|
||||
end
|
||||
|
||||
o = s:option(Value, "up_china_dns", translate("China DNS Server") .. "(UDP)")
|
||||
@ -125,19 +101,20 @@ o = s:option(ListValue, "dns_mode", translate("DNS Mode"))
|
||||
-- o.description = translate("if has problem, please try another mode.<br />if you use no patterns are used, DNS of wan will be used by default as upstream of dnsmasq.")
|
||||
o.rmempty = false
|
||||
o:reset_values()
|
||||
if is_finded("chinadns-ng") then o:value("chinadns-ng", "ChinaDNS-NG") end
|
||||
if is_finded("chinadns-ng") then
|
||||
o:value("chinadns-ng", "ChinaDNS-NG")
|
||||
end
|
||||
if is_installed("pdnsd") or is_installed("pdnsd-alt") or is_finded("pdnsd") then
|
||||
o:value("pdnsd", "pdnsd")
|
||||
end
|
||||
if is_finded("dns2socks") then
|
||||
o:value("dns2socks",
|
||||
"dns2socks + " .. translate("Use Socks Node Resolve DNS"))
|
||||
o:value("dns2socks", "dns2socks")
|
||||
end
|
||||
o:value("local_7913", translate("Use local port 7913 as DNS"))
|
||||
o:value("nonuse", translate("No patterns are used"))
|
||||
|
||||
---- Upstream trust DNS Server for ChinaDNS-NG
|
||||
o = s:option(Value, "up_trust_chinadns_ng_dns",
|
||||
o = s:option(ListValue, "up_trust_chinadns_ng_dns",
|
||||
translate("Upstream trust DNS Server for ChinaDNS-NG") .. "(UDP)")
|
||||
-- o.description = translate("You can use other resolving DNS services as trusted DNS, Example: dns2socks, dns-forwarder... 127.0.0.1#5353<br />Only use two at most, english comma separation, If you do not fill in the # and the following port, you are using port 53.")
|
||||
o.default = "pdnsd"
|
||||
@ -145,41 +122,46 @@ if is_installed("pdnsd") or is_installed("pdnsd-alt") or is_finded("pdnsd") then
|
||||
o:value("pdnsd", "pdnsd + " .. translate("Use TCP Node Resolve DNS"))
|
||||
end
|
||||
if is_finded("dns2socks") then
|
||||
o:value("dns2socks",
|
||||
"dns2socks + " .. translate("Use Socks Node Resolve DNS"))
|
||||
o:value("dns2socks", "dns2socks")
|
||||
end
|
||||
o:value("8.8.4.4,8.8.8.8", "8.8.4.4, 8.8.8.8 (Google DNS)")
|
||||
o:value("208.67.222.222,208.67.220.220",
|
||||
"208.67.222.222, 208.67.220.220 (Open DNS)")
|
||||
o:value("udp", translate("Use UDP Node Resolve DNS"))
|
||||
o:depends("dns_mode", "chinadns-ng")
|
||||
|
||||
---- Use TCP Node Resolve DNS
|
||||
--[[ if is_installed("pdnsd") or is_installed("pdnsd-alt") or is_finded("pdnsd") then
|
||||
o = s:option(Flag, "use_tcp_node_resolve_dns",
|
||||
translate("Use TCP Node Resolve DNS"))
|
||||
-- o.description = translate("If checked, DNS is resolved using the TCP node.")
|
||||
o = s:option(Flag, "use_tcp_node_resolve_dns", translate("Use TCP Node Resolve DNS"))
|
||||
o.description = translate("If checked, DNS is resolved using the TCP node.")
|
||||
o.default = 1
|
||||
o:depends("dns_mode", "pdnsd")
|
||||
end
|
||||
--]]
|
||||
|
||||
o = s:option(Value, "dns2socks_forward", translate("DNS Address"))
|
||||
o = s:option(Value, "socks_server", translate("Socks Server"))
|
||||
o.default = "127.0.0.1:1080"
|
||||
o:depends({dns_mode = "dns2socks"})
|
||||
o:depends({dns_mode = "chinadns-ng", up_trust_chinadns_ng_dns = "dns2socks"})
|
||||
|
||||
o = s:option(Flag, "fair_mode", translate("Fair Mode"))
|
||||
o.default = "1"
|
||||
o:depends({dns_mode = "chinadns-ng"})
|
||||
|
||||
---- DNS Forward
|
||||
o = s:option(Value, "dns_forward", translate("DNS Address"))
|
||||
o.default = "8.8.4.4"
|
||||
o:value("8.8.4.4", "8.8.4.4 (Google DNS)")
|
||||
o:value("8.8.8.8", "8.8.8.8 (Google DNS)")
|
||||
o:value("208.67.222.222", "208.67.222.222 (Open DNS)")
|
||||
o:value("208.67.220.220", "208.67.220.220 (Open DNS)")
|
||||
o:depends("dns_mode", "dns2socks")
|
||||
o:depends("up_trust_chinadns_ng_dns", "dns2socks")
|
||||
o:depends({dns_mode = "chinadns-ng"})
|
||||
o:depends({dns_mode = "dns2socks"})
|
||||
o:depends({dns_mode = "pdnsd"})
|
||||
|
||||
---- DNS Forward
|
||||
o = s:option(Value, "dns_forward", translate("DNS Address"))
|
||||
o.default = "8.8.4.4, 8.8.8.8"
|
||||
o:value("8.8.4.4, 8.8.8.8", "8.8.4.4, 8.8.8.8 (Google DNS)")
|
||||
o:value("208.67.222.222", "208.67.222.222 (Open DNS)")
|
||||
o:value("208.67.220.220", "208.67.220.220 (Open DNS)")
|
||||
o:depends("dns_mode", "pdnsd")
|
||||
o:depends("up_trust_chinadns_ng_dns", "pdnsd")
|
||||
o = s:option(Flag, "dns_cache", translate("DNS Cache"))
|
||||
o.default = "1"
|
||||
o:depends({dns_mode = "chinadns-ng", up_trust_chinadns_ng_dns = "pdnsd"})
|
||||
o:depends({dns_mode = "chinadns-ng", up_trust_chinadns_ng_dns = "dns2socks"})
|
||||
o:depends({dns_mode = "dns2socks"})
|
||||
o:depends({dns_mode = "pdnsd"})
|
||||
|
||||
---- TCP Default Proxy Mode
|
||||
o = s:option(ListValue, "tcp_proxy_mode",
|
||||
@ -227,12 +209,12 @@ o.default = "default"
|
||||
o.rmempty = false
|
||||
|
||||
---- Tips
|
||||
s:append(Template("passwall/global/tips"))
|
||||
s:append(Template(appname .. "/global/tips"))
|
||||
|
||||
--[[
|
||||
local apply = luci.http.formvalue("cbi.apply")
|
||||
if apply then
|
||||
os.execute("/etc/init.d/passwall restart")
|
||||
os.execute("/etc/init.d/" .. appname .." restart")
|
||||
end
|
||||
--]]
|
||||
|
||||
|
||||
@ -1,30 +1,28 @@
|
||||
local e = require "nixio.fs"
|
||||
local e = require "luci.sys"
|
||||
local net = require"luci.model.network".init()
|
||||
local uci = require"luci.model.uci".cursor()
|
||||
local net = require "luci.model.network".init()
|
||||
local uci = require "luci.model.uci".cursor()
|
||||
local appname = "passwall"
|
||||
|
||||
local n = {}
|
||||
local nodes_table = {}
|
||||
uci:foreach(appname, "nodes", function(e)
|
||||
if e.type and e.remarks and e.port and e.address and e.address ~= "127.0.0.1" then
|
||||
if e.address:match("[\u4e00-\u9fa5]") and e.address:find("%.") and e.address:sub(#e.address) ~= "." then
|
||||
e.remark = "%s:[%s] %s:%s" % {translate(e.type), e.remarks, e.address, e.port}
|
||||
n[e[".name"]] = e
|
||||
nodes_table[#nodes_table + 1] = {
|
||||
id = e[".name"],
|
||||
remarks = "%s:[%s] %s:%s" % {translate(e.type), e.remarks, e.address, e.port},
|
||||
obj = e
|
||||
}
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
local key_table = {}
|
||||
for key, _ in pairs(n) do table.insert(key_table, key) end
|
||||
table.sort(key_table)
|
||||
|
||||
m = Map(appname)
|
||||
|
||||
-- [[ Haproxy Settings ]]--
|
||||
s = m:section(TypedSection, "global_haproxy", translate("Load Balancing"))
|
||||
s.anonymous = true
|
||||
|
||||
s:append(Template("passwall/haproxy/status"))
|
||||
s:append(Template(appname .. "/haproxy/status"))
|
||||
|
||||
---- Balancing Enable
|
||||
o = s:option(Flag, "balancing_enable", translate("Enable Load Balancing"))
|
||||
@ -63,9 +61,7 @@ o.rmempty = false
|
||||
|
||||
---- Node Address
|
||||
o = s:option(Value, "lbss", translate("Node Address"))
|
||||
for _, key in pairs(key_table) do
|
||||
o:value(n[key].address .. ":" .. n[key].port, n[key].remark)
|
||||
end
|
||||
for k, v in pairs(nodes_table) do o:value(v.obj.address .. ":" .. v.obj.port, v.remarks) end
|
||||
o.rmempty = false
|
||||
|
||||
---- Node Port
|
||||
|
||||
@ -55,7 +55,7 @@ local v2ray_header_type_list = {
|
||||
}
|
||||
|
||||
m = Map(appname, translate("Node Config"))
|
||||
m.redirect = d.build_url("admin", "vpn", "passwall")
|
||||
m.redirect = d.build_url("admin", "vpn", appname)
|
||||
|
||||
s = m:section(NamedSection, arg[1], "nodes", "")
|
||||
s.addremove = false
|
||||
@ -68,14 +68,16 @@ remarks.rmempty = false
|
||||
type = s:option(ListValue, "type", translate("Type"))
|
||||
if ((is_installed("redsocks2") or is_finded("redsocks2")) or
|
||||
(is_installed("ipt2socks") or is_finded("ipt2socks"))) then
|
||||
type:value("Socks5", translate("Socks5"))
|
||||
type:value("Socks", translate("Socks"))
|
||||
end
|
||||
if is_finded("ss-redir") then
|
||||
type:value("SS", translate("Shadowsocks"))
|
||||
end
|
||||
if is_finded("ssr-redir") then
|
||||
type:value("SSR", translate("ShadowsocksR"))
|
||||
end
|
||||
if is_finded("ss-redir") then type:value("SS", translate("Shadowsocks")) end
|
||||
if is_finded("ssr-redir") then type:value("SSR", translate("ShadowsocksR")) end
|
||||
if is_installed("v2ray") or is_finded("v2ray") then
|
||||
type:value("V2ray", translate("V2ray"))
|
||||
type:value("V2ray_balancing", translate("V2ray Balancing"))
|
||||
type:value("V2ray_shunt", translate("V2ray Shunt"))
|
||||
end
|
||||
if is_installed("brook") or is_finded("brook") then
|
||||
type:value("Brook", translate("Brook"))
|
||||
@ -84,14 +86,50 @@ if is_installed("trojan") or is_finded("trojan") then
|
||||
type:value("Trojan", translate("Trojan"))
|
||||
end
|
||||
|
||||
v2ray_protocol = s:option(ListValue, "v2ray_protocol",
|
||||
translate("V2ray Protocol"))
|
||||
v2ray_protocol = s:option(ListValue, "v2ray_protocol", translate("Protocol"))
|
||||
v2ray_protocol:value("vmess", translate("Vmess"))
|
||||
v2ray_protocol:value("http", translate("HTTP"))
|
||||
v2ray_protocol:value("socks", translate("Socks"))
|
||||
v2ray_protocol:value("shadowsocks", translate("Shadowsocks"))
|
||||
v2ray_protocol:value("_balancing", translate("Balancing"))
|
||||
v2ray_protocol:value("_shunt", translate("Shunt"))
|
||||
v2ray_protocol:depends("type", "V2ray")
|
||||
|
||||
local nodes_table = {}
|
||||
uci:foreach(appname, "nodes", function(e)
|
||||
if e.type and e.remarks and e.port then
|
||||
if e.address:match("[\u4e00-\u9fa5]") and e.address:find("%.") and e.address:sub(#e.address) ~= "." then
|
||||
nodes_table[#nodes_table + 1] = {
|
||||
id = e[".name"],
|
||||
remarks = "%s:[%s] %s:%s" % {e.type, e.remarks, e.address, e.port}
|
||||
}
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- 负载均衡列表
|
||||
v2ray_balancing_node = s:option(DynamicList, "v2ray_balancing_node", translate("Load balancing node list"), translate("Load balancing node list, <a target='_blank' href='https://toutyrater.github.io/routing/balance2.html'>document</a>"))
|
||||
for k, v in pairs(nodes_table) do v2ray_balancing_node:value(v.id, v.remarks) end
|
||||
v2ray_balancing_node:depends("v2ray_protocol", "_balancing")
|
||||
|
||||
-- 分流
|
||||
uci:foreach(appname, "shunt_rules", function(e)
|
||||
o = s:option(ListValue, e[".name"], translate(e.remarks))
|
||||
o:value("nil", translate("Close"))
|
||||
for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) end
|
||||
o:depends("v2ray_protocol", "_shunt")
|
||||
|
||||
o = s:option(Flag, e[".name"] .. "_proxy", translate(e.remarks) .. translate("Preproxy"), translate("Use the default node for the transit."))
|
||||
o.default = 0
|
||||
o:depends("v2ray_protocol", "_shunt")
|
||||
end)
|
||||
|
||||
default_node = s:option(ListValue, "default_node", translate("Default") .. " " .. translate("Node"))
|
||||
default_node:value("nil", translate("Close"))
|
||||
for k, v in pairs(nodes_table) do default_node:value(v.id, v.remarks) end
|
||||
default_node:depends("v2ray_protocol", "_shunt")
|
||||
|
||||
-- Brook协议
|
||||
brook_protocol = s:option(ListValue, "brook_protocol",
|
||||
translate("Brook Protocol"))
|
||||
brook_protocol:value("client", translate("Brook"))
|
||||
@ -101,70 +139,28 @@ brook_protocol:depends("type", "Brook")
|
||||
brook_tls = s:option(Flag, "brook_tls", translate("Use TLS"))
|
||||
brook_tls:depends("brook_protocol", "wsclient")
|
||||
|
||||
local n = {}
|
||||
uci:foreach(appname, "nodes", function(e)
|
||||
if e.type and e.remarks and e.port then
|
||||
if e.address:match("[\u4e00-\u9fa5]") and e.address:find("%.") and e.address:sub(#e.address) ~= "." then
|
||||
n[e[".name"]] = "%s:[%s] %s:%s" % {e.type, e.remarks, e.address, e.port}
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
local key_table = {}
|
||||
for key, _ in pairs(n) do table.insert(key_table, key) end
|
||||
table.sort(key_table)
|
||||
|
||||
v2ray_balancing_node = s:option(DynamicList, "v2ray_balancing_node",
|
||||
translate("Load balancing node list"),
|
||||
translate(
|
||||
"Load balancing node list, <a target='_blank' href='https://toutyrater.github.io/routing/balance2.html'>document</a>"))
|
||||
for _, key in pairs(key_table) do v2ray_balancing_node:value(key, n[key]) end
|
||||
v2ray_balancing_node:depends("type", "V2ray_balancing")
|
||||
|
||||
youtube_node = s:option(ListValue, "youtube_node",
|
||||
"Youtube " .. translate("Node"))
|
||||
youtube_node:value("nil", translate("Close"))
|
||||
for _, key in pairs(key_table) do youtube_node:value(key, n[key]) end
|
||||
youtube_node:depends("type", "V2ray_shunt")
|
||||
|
||||
youtube_proxy = s:option(Flag, "youtube_proxy", "Youtube " .. translate("Node") .. translate("Preproxy"),
|
||||
"Youtube " .. translate("Node") .. translate("Use the default node for the transit."))
|
||||
youtube_proxy.default = 0
|
||||
youtube_proxy:depends("type", "V2ray_shunt")
|
||||
|
||||
netflix_node = s:option(ListValue, "netflix_node",
|
||||
"Netflix " .. translate("Node"))
|
||||
netflix_node:value("nil", translate("Close"))
|
||||
for _, key in pairs(key_table) do netflix_node:value(key, n[key]) end
|
||||
netflix_node:depends("type", "V2ray_shunt")
|
||||
|
||||
netflix_proxy = s:option(Flag, "netflix_proxy", "Netflix " .. translate("Node") .. translate("Preproxy"),
|
||||
"Netflix " .. translate("Node") .. translate("Use the default node for the transit."))
|
||||
netflix_proxy.default = 0
|
||||
netflix_proxy:depends("type", "V2ray_shunt")
|
||||
|
||||
default_node = s:option(ListValue, "default_node",
|
||||
translate("Default") .. " " .. translate("Node"))
|
||||
default_node:value("nil", translate("Close"))
|
||||
for _, key in pairs(key_table) do default_node:value(key, n[key]) end
|
||||
default_node:depends("type", "V2ray_shunt")
|
||||
|
||||
address = s:option(Value, "address", translate("Address (Support Domain Name)"))
|
||||
address.rmempty = false
|
||||
address:depends("type", "Socks5")
|
||||
address:depends("type", "Socks")
|
||||
address:depends("type", "SS")
|
||||
address:depends("type", "SSR")
|
||||
address:depends("type", "V2ray")
|
||||
address:depends({ type = "V2ray", v2ray_protocol = "vmess" })
|
||||
address:depends({ type = "V2ray", v2ray_protocol = "http" })
|
||||
address:depends({ type = "V2ray", v2ray_protocol = "socks" })
|
||||
address:depends({ type = "V2ray", v2ray_protocol = "shadowsocks" })
|
||||
address:depends("type", "Brook")
|
||||
address:depends("type", "Trojan")
|
||||
|
||||
--[[
|
||||
use_ipv6 = s:option(Flag, "use_ipv6", translate("Use IPv6"))
|
||||
use_ipv6.default = 0
|
||||
use_ipv6:depends("type", "Socks5")
|
||||
use_ipv6:depends("type", "Socks")
|
||||
use_ipv6:depends("type", "SS")
|
||||
use_ipv6:depends("type", "SSR")
|
||||
use_ipv6:depends("type", "V2ray")
|
||||
use_ipv6:depends({ type = "V2ray", v2ray_protocol = "vmess" })
|
||||
use_ipv6:depends({ type = "V2ray", v2ray_protocol = "http" })
|
||||
use_ipv6:depends({ type = "V2ray", v2ray_protocol = "socks" })
|
||||
use_ipv6:depends({ type = "V2ray", v2ray_protocol = "shadowsocks" })
|
||||
use_ipv6:depends("type", "Brook")
|
||||
use_ipv6:depends("type", "Trojan")
|
||||
--]]
|
||||
@ -172,21 +168,24 @@ use_ipv6:depends("type", "Trojan")
|
||||
port = s:option(Value, "port", translate("Port"))
|
||||
port.datatype = "port"
|
||||
port.rmempty = false
|
||||
port:depends("type", "Socks5")
|
||||
port:depends("type", "Socks")
|
||||
port:depends("type", "SS")
|
||||
port:depends("type", "SSR")
|
||||
port:depends("type", "V2ray")
|
||||
port:depends({ type = "V2ray", v2ray_protocol = "vmess" })
|
||||
port:depends({ type = "V2ray", v2ray_protocol = "http" })
|
||||
port:depends({ type = "V2ray", v2ray_protocol = "socks" })
|
||||
port:depends({ type = "V2ray", v2ray_protocol = "shadowsocks" })
|
||||
port:depends("type", "Brook")
|
||||
port:depends("type", "Trojan")
|
||||
|
||||
username = s:option(Value, "username", translate("Username"))
|
||||
username:depends("type", "Socks5")
|
||||
username:depends("type", "Socks")
|
||||
username:depends("v2ray_protocol", "http")
|
||||
username:depends("v2ray_protocol", "socks")
|
||||
|
||||
password = s:option(Value, "password", translate("Password"))
|
||||
password.password = true
|
||||
password:depends("type", "Socks5")
|
||||
password:depends("type", "Socks")
|
||||
password:depends("type", "SS")
|
||||
password:depends("type", "SSR")
|
||||
password:depends("type", "Brook")
|
||||
@ -429,10 +428,12 @@ v2ray_quic_guise = s:option(ListValue, "v2ray_quic_guise",
|
||||
for a, t in ipairs(v2ray_header_type_list) do v2ray_quic_guise:value(t) end
|
||||
v2ray_quic_guise:depends("v2ray_transport", "quic")
|
||||
|
||||
-- [[ 其它 ]]--
|
||||
|
||||
-- [[ Mux ]]--
|
||||
v2ray_mux = s:option(Flag, "v2ray_mux", translate("Mux"))
|
||||
v2ray_mux:depends("type", "V2ray")
|
||||
v2ray_mux:depends({ type = "V2ray", v2ray_protocol = "vmess" })
|
||||
v2ray_mux:depends({ type = "V2ray", v2ray_protocol = "http" })
|
||||
v2ray_mux:depends({ type = "V2ray", v2ray_protocol = "socks" })
|
||||
v2ray_mux:depends({ type = "V2ray", v2ray_protocol = "shadowsocks" })
|
||||
|
||||
v2ray_mux_concurrency = s:option(Value, "v2ray_mux_concurrency",
|
||||
translate("Mux Concurrency"))
|
||||
@ -448,7 +449,7 @@ v2ray_tcp_socks.default = 0
|
||||
v2ray_tcp_socks:depends("type", "V2ray")
|
||||
|
||||
v2ray_tcp_socks_port = s:option(Value, "v2ray_tcp_socks_port",
|
||||
"Socks5 " .. translate("Port"),
|
||||
"Socks " .. translate("Port"),
|
||||
translate("Do not conflict with other ports"))
|
||||
v2ray_tcp_socks_port.datatype = "port"
|
||||
v2ray_tcp_socks_port.default = 1080
|
||||
@ -463,11 +464,11 @@ v2ray_tcp_socks_auth:value("password", translate("User Password"))
|
||||
v2ray_tcp_socks_auth:depends("v2ray_tcp_socks", "1")
|
||||
|
||||
v2ray_tcp_socks_auth_username = s:option(Value, "v2ray_tcp_socks_auth_username",
|
||||
"Socks5 " .. translate("Username"))
|
||||
"Socks " .. translate("Username"))
|
||||
v2ray_tcp_socks_auth_username:depends("v2ray_tcp_socks_auth", "password")
|
||||
|
||||
v2ray_tcp_socks_auth_password = s:option(Value, "v2ray_tcp_socks_auth_password",
|
||||
"Socks5 " .. translate("Password"))
|
||||
"Socks " .. translate("Password"))
|
||||
v2ray_tcp_socks_auth_password:depends("v2ray_tcp_socks_auth", "password")
|
||||
--]]
|
||||
|
||||
@ -481,54 +482,4 @@ trojan_cert_path = s:option(Value, "trojan_cert_path",
|
||||
trojan_cert_path.default = ""
|
||||
trojan_cert_path:depends("trojan_verify_cert", "1")
|
||||
|
||||
-- v2ray_insecure = s:option(Flag, "v2ray_insecure", translate("allowInsecure"))
|
||||
-- v2ray_insecure:depends("type", "V2ray")
|
||||
|
||||
function rmempty_restore()
|
||||
address.rmempty = true
|
||||
port.rmempty = true
|
||||
password.rmempty = true
|
||||
timeout.rmempty = true
|
||||
tcp_fast_open.rmempty = true
|
||||
-- v2ray_protocol.rmempty = true
|
||||
v2ray_VMess_id.rmempty = true
|
||||
v2ray_VMess_alterId.rmempty = true
|
||||
end
|
||||
|
||||
type.validate = function(self, value)
|
||||
rmempty_restore()
|
||||
if value == "SS" then
|
||||
address.rmempty = false
|
||||
port.rmempty = false
|
||||
password.rmempty = false
|
||||
timeout.rmempty = false
|
||||
tcp_fast_open.rmempty = false
|
||||
elseif value == "SSR" then
|
||||
address.rmempty = false
|
||||
port.rmempty = false
|
||||
password.rmempty = false
|
||||
timeout.rmempty = false
|
||||
tcp_fast_open.rmempty = false
|
||||
elseif value == "V2ray" then
|
||||
address.rmempty = false
|
||||
port.rmempty = false
|
||||
-- v2ray_protocol.rmempty = false
|
||||
-- v2ray_VMess_id.rmempty = false
|
||||
-- v2ray_VMess_alterId.rmempty = false
|
||||
elseif value == "V2ray_balancing" then
|
||||
elseif value == "Brook" then
|
||||
address.rmempty = false
|
||||
port.rmempty = false
|
||||
password.rmempty = false
|
||||
elseif value == "Trojan" then
|
||||
address.rmempty = false
|
||||
port.rmempty = false
|
||||
password.rmempty = false
|
||||
tcp_fast_open.rmempty = false
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
v2ray_transport.validate = function(self, value) return value end
|
||||
|
||||
return m
|
||||
|
||||
@ -1,8 +1,5 @@
|
||||
local d = require "luci.dispatcher"
|
||||
local fs = require "nixio.fs"
|
||||
local sys = require "luci.sys"
|
||||
local uci = require"luci.model.uci".cursor()
|
||||
local api = require "luci.model.cbi.passwall.api.api"
|
||||
local _api = require "luci.model.cbi.passwall.api.api"
|
||||
local appname = "passwall"
|
||||
|
||||
m = Map(appname)
|
||||
@ -34,48 +31,56 @@ o = s:option(Flag, "show_group", translate("Show Group"))
|
||||
o.default = 1
|
||||
|
||||
-- [[ Add the node via the link ]]--
|
||||
s:append(Template("passwall/node_list/link_add_node"))
|
||||
s:append(Template(appname .. "/node_list/link_add_node"))
|
||||
|
||||
-- [[ Node List ]]--
|
||||
s = m:section(TypedSection, "nodes")
|
||||
-- s.description = translate("Support for more than 10,000 ping nodes and luci does not crash and not slow.")
|
||||
s.anonymous = true
|
||||
s.addremove = true
|
||||
s.template = "cbi/tblsection"
|
||||
s.extedit = d.build_url("admin", "vpn", "passwall", "node_config", "%s")
|
||||
s.extedit = d.build_url("admin", "vpn", appname, "node_config", "%s")
|
||||
function s.create(e, t)
|
||||
local e = TypedSection.create(e, t)
|
||||
luci.http
|
||||
.redirect(d.build_url("admin", "vpn", "passwall", "node_config", e))
|
||||
local uuid = _api.gen_uuid()
|
||||
t = uuid
|
||||
TypedSection.create(e, t)
|
||||
luci.http.redirect(e.extedit:format(t))
|
||||
end
|
||||
|
||||
function s.remove(t, a)
|
||||
function s.remove(e, t)
|
||||
s.map.proceed = true
|
||||
s.map:del(a)
|
||||
luci.http.redirect(d.build_url("admin", "vpn", "passwall", "node_list"))
|
||||
s.map:del(t)
|
||||
luci.http.redirect(d.build_url("admin", "vpn", appname, "node_list"))
|
||||
end
|
||||
|
||||
if api.uci_get_type("global_other", "show_group", "1") == "1" then
|
||||
if m:get("@global_other[0]", "show_group") == "1" then
|
||||
show_group = s:option(DummyValue, "group", translate("Group"))
|
||||
show_group.cfgvalue = function(t, n)
|
||||
local group = api.uci_get_type_id(n, "group") or "无"
|
||||
local group = m:get(n, "group") or "无"
|
||||
return group ~= "" and group or "无"
|
||||
end
|
||||
end
|
||||
|
||||
s.sortable = true
|
||||
-- 简洁模式
|
||||
if api.uci_get_type("global_other", "compact_display_nodes", "0") == "1" then
|
||||
if m:get("@global_other[0]", "compact_display_nodes") == "1" then
|
||||
if show_group then show_group.width = "25%" end
|
||||
o = s:option(DummyValue, "remarks", translate("Remarks"))
|
||||
o.cfgvalue = function(t, n)
|
||||
local str = ""
|
||||
local is_sub = api.uci_get_type_id(n, "is_sub") or ""
|
||||
local group = api.uci_get_type_id(n, "group") or ""
|
||||
local remarks = api.uci_get_type_id(n, "remarks") or ""
|
||||
local type = api.uci_get_type_id(n, "type") or ""
|
||||
local address = api.uci_get_type_id(n, "address") or ""
|
||||
local port = api.uci_get_type_id(n, "port") or ""
|
||||
local is_sub = m:get(n, "is_sub") or ""
|
||||
local group = m:get(n, "group") or ""
|
||||
local remarks = m:get(n, "remarks") or ""
|
||||
local type = m:get(n, "type") or ""
|
||||
if type == "V2ray" then
|
||||
local protocol = m:get(n, "v2ray_protocol")
|
||||
if protocol == "_balancing" then
|
||||
type = type .. " 负载均衡"
|
||||
elseif protocol == "_shunt" then
|
||||
type = type .. " 分流"
|
||||
end
|
||||
end
|
||||
local address = m:get(n, "address") or ""
|
||||
local port = m:get(n, "port") or ""
|
||||
str = str .. translate(type) .. ":" .. remarks
|
||||
if address ~= "" and port ~= "" then
|
||||
local s = " (" .. address .. ":" .. port .. ")"
|
||||
@ -85,7 +90,7 @@ if api.uci_get_type("global_other", "compact_display_nodes", "0") == "1" then
|
||||
end
|
||||
else
|
||||
---- Add Mode
|
||||
if api.uci_get_type("global_other", "show_add_mode", "1") == "1" then
|
||||
if m:get("@global_other[0]", "show_add_mode") == "1" then
|
||||
o = s:option(DummyValue, "add_mode", translate("Add Mode"))
|
||||
o.cfgvalue = function(t, n)
|
||||
local v = Value.cfgvalue(t, n)
|
||||
@ -101,8 +106,20 @@ else
|
||||
---- Type
|
||||
o = s:option(DummyValue, "type", translate("Type"))
|
||||
o.cfgvalue = function(t, n)
|
||||
local result = ""
|
||||
local v = Value.cfgvalue(t, n)
|
||||
if v then return translate(v) end
|
||||
if v then
|
||||
result = translate(v)
|
||||
if v == "V2ray" then
|
||||
local protocol = m:get(n, "v2ray_protocol")
|
||||
if protocol == "_balancing" then
|
||||
result = result .. " 负载均衡"
|
||||
elseif protocol == "_shunt" then
|
||||
result = result .. " 分流"
|
||||
end
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
---- Remarks
|
||||
@ -119,32 +136,27 @@ else
|
||||
o.cfgvalue = function(t, n)
|
||||
return Value.cfgvalue(t, n) or "---"
|
||||
end
|
||||
|
||||
---- Encrypt Method
|
||||
--[[ o = s:option(DummyValue, "encrypt_method", translate("Encrypt Method"))
|
||||
o.width = "15%"
|
||||
o.cfgvalue = function(t, n)
|
||||
local str = "无"
|
||||
local type = api.uci_get_type_id(n, "type") or ""
|
||||
if type == "SSR" then
|
||||
return api.uci_get_type_id(n, "ssr_encrypt_method")
|
||||
elseif type == "SS" then
|
||||
return api.uci_get_type_id(n, "ss_encrypt_method")
|
||||
elseif type == "V2ray" then
|
||||
return api.uci_get_type_id(n, "v2ray_security")
|
||||
end
|
||||
return str
|
||||
end--]]
|
||||
end
|
||||
|
||||
---- Ping
|
||||
o = s:option(DummyValue, "ping", translate("Latency"))
|
||||
if api.uci_get_type("global_other", "auto_ping", "0") == "0" then
|
||||
o.template = "passwall/node_list/ping"
|
||||
if m:get("@global_other[0]", "auto_ping") == "0" then
|
||||
o.template = appname .. "/node_list/ping"
|
||||
else
|
||||
o.template = "passwall/node_list/auto_ping"
|
||||
o.template = appname .. "/node_list/auto_ping"
|
||||
end
|
||||
--[[
|
||||
o.cfgvalue = function(t, n)
|
||||
local type = m:get(n, "type") or ""
|
||||
if type == "V2ray" then
|
||||
local protocol = m:get(n, "v2ray_protocol","")
|
||||
if protocol == "_balancing" or protocol == "_shunt" then
|
||||
return "---"
|
||||
end
|
||||
end
|
||||
end
|
||||
--]]
|
||||
|
||||
m:append(Template("passwall/node_list/node_list"))
|
||||
m:append(Template(appname .. "/node_list/node_list"))
|
||||
|
||||
return m
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
local e = require "nixio.fs"
|
||||
local e = require "luci.sys"
|
||||
local appname = "passwall"
|
||||
|
||||
m = Map("passwall")
|
||||
m = Map(appname)
|
||||
|
||||
-- [[ Subscribe Settings ]]--
|
||||
s = m:section(TypedSection, "global_subscribe", "")
|
||||
@ -36,20 +35,16 @@ o:depends("auto_update_subscribe", 1)
|
||||
o = s:option(Button, "_update", translate("Manual subscription"))
|
||||
o.inputstyle = "apply"
|
||||
function o.write(e, e)
|
||||
luci.sys.call(
|
||||
"lua /usr/share/passwall/subscribe.lua start log > /dev/null 2>&1 &")
|
||||
luci.http.redirect(luci.dispatcher.build_url("admin", "vpn", "passwall",
|
||||
"log"))
|
||||
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start log > /dev/null 2>&1 &")
|
||||
luci.http.redirect(luci.dispatcher.build_url("admin", "vpn", appname, "log"))
|
||||
end
|
||||
|
||||
---- Subscribe Delete All
|
||||
o = s:option(Button, "_stop", translate("Delete All Subscribe Node"))
|
||||
o.inputstyle = "remove"
|
||||
function o.write(e, e)
|
||||
luci.sys.call(
|
||||
"lua /usr/share/passwall/subscribe.lua truncate log > /dev/null 2>&1 &")
|
||||
luci.http.redirect(luci.dispatcher.build_url("admin", "vpn", "passwall",
|
||||
"log"))
|
||||
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua truncate log > /dev/null 2>&1 &")
|
||||
luci.http.redirect(luci.dispatcher.build_url("admin", "vpn", appname, "log"))
|
||||
end
|
||||
|
||||
filter_enabled = s:option(Flag, "filter_enabled", translate("Filter keyword switch"), translate("When checked, below options can only be take effect."))
|
||||
@ -62,6 +57,10 @@ o = s:option(Flag, "filter_keyword_discarded", translate("Filter keyword discard
|
||||
o.default = "1"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Flag, "allowInsecure", translate("allowInsecure"), translate("Whether unsafe connections are allowed. When checked, V2Ray does not check the validity of the TLS certificate provided by the remote host by default."))
|
||||
o.default = "1"
|
||||
o.rmempty = false
|
||||
|
||||
s = m:section(TypedSection, "subscribe_list", "",
|
||||
"<font color='red'>" .. translate(
|
||||
"Please input the subscription url first, save and submit before updating. If you subscribe to update, it is recommended to delete all subscriptions and then re-subscribe.") ..
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
local api = require "luci.model.cbi.passwall.api.api"
|
||||
local _api = require "luci.model.cbi.passwall.api.api"
|
||||
local uci = require"luci.model.uci".cursor()
|
||||
local appname = "passwall"
|
||||
|
||||
m = Map("passwall")
|
||||
m = Map(appname)
|
||||
|
||||
-- [[ Delay Settings ]]--
|
||||
s = m:section(TypedSection, "global_delay", translate("Delay Settings"))
|
||||
@ -73,8 +75,8 @@ o.default = "22,25,53,143,465,587,993,995,80,443"
|
||||
o:value("1:65535", translate("All"))
|
||||
o:value("22,25,53,143,465,587,993,995,80,443", translate("Common Use"))
|
||||
o:value("80,443", translate("Only Web"))
|
||||
o:value("80:", "80 " .. translate("or more"))
|
||||
o:value(":443", "443 " .. translate("or less"))
|
||||
o:value("80:65535", "80 " .. translate("or more"))
|
||||
o:value("1:443", "443 " .. translate("or less"))
|
||||
|
||||
---- UDP Redir Ports
|
||||
o = s:option(Value, "udp_redir_ports", translate("UDP Redir Ports"))
|
||||
@ -92,15 +94,6 @@ o:value("2", "2 " .. translate("Process"))
|
||||
o:value("3", "3 " .. translate("Process"))
|
||||
o:value("4", "4 " .. translate("Process"))
|
||||
|
||||
---- Socks Proxy Port
|
||||
local socks_node_num = tonumber(api.uci_get_type("global_other",
|
||||
"socks_node_num", 1))
|
||||
for i = 1, socks_node_num, 1 do
|
||||
o = s:option(Value, "socks_proxy_port" .. i, translate("Socks Proxy Port"))
|
||||
o.datatype = "port"
|
||||
o.default = "108" .. i
|
||||
end
|
||||
|
||||
--[[
|
||||
---- Proxy IPv6
|
||||
o = s:option(Flag, "proxy_ipv6", translate("Proxy IPv6"),
|
||||
@ -152,14 +145,6 @@ o:value("1")
|
||||
o:value("2")
|
||||
o:value("3")
|
||||
|
||||
---- Socks Node Number Option
|
||||
o = s:option(ListValue, "socks_node_num", "Socks" .. translate("Node Number"))
|
||||
o.default = "1"
|
||||
o.rmempty = false
|
||||
o:value("1")
|
||||
o:value("2")
|
||||
o:value("3")
|
||||
|
||||
---- 状态使用大图标
|
||||
o = s:option(Flag, "status_use_big_icon", translate("Status Use Big Icon"))
|
||||
o.default = "1"
|
||||
@ -176,4 +161,54 @@ o = s:option(Flag, "status_show_ip111", translate("Status Show IP111"))
|
||||
o.default = "0"
|
||||
o.rmempty = false
|
||||
|
||||
local nodes_table = {}
|
||||
uci:foreach(appname, "nodes", function(e)
|
||||
if e.type and e.remarks then
|
||||
local remarks = ""
|
||||
if e.type == "V2ray" and (e.v2ray_protocol == "_balancing" or e.v2ray_protocol == "_shunt") then
|
||||
remarks = "%s:[%s] " % {translatef(e.type .. e.v2ray_protocol), e.remarks}
|
||||
else
|
||||
if e.use_kcp and e.use_kcp == "1" then
|
||||
remarks = "%s+%s:[%s] %s" % {e.type, "Kcptun", e.remarks, address}
|
||||
else
|
||||
remarks = "%s:[%s] %s:%s" % {e.type, e.remarks, e.address, e.port}
|
||||
end
|
||||
end
|
||||
nodes_table[#nodes_table + 1] = {
|
||||
id = e[".name"],
|
||||
remarks = remarks
|
||||
}
|
||||
end
|
||||
end)
|
||||
|
||||
-- [[ Node List ]]--
|
||||
s = m:section(TypedSection, "socks", translate("Socks Config"))
|
||||
s.anonymous = true
|
||||
s.addremove = true
|
||||
s.template = "cbi/tblsection"
|
||||
function s.create(e, t)
|
||||
TypedSection.create(e, _api.gen_uuid())
|
||||
end
|
||||
|
||||
o = s:option(DummyValue, "status", translate("Status"))
|
||||
o.template = appname .. "/other/socks_status"
|
||||
|
||||
---- Enable
|
||||
o = s:option(Flag, "enabled", translate("Enable"))
|
||||
o.default = 1
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(ListValue, "node", translate("Socks Node"))
|
||||
local tcp_node_num = tonumber(m:get("@global_other[0]", "tcp_node_num") or 1)
|
||||
for i = 1, tcp_node_num, 1 do
|
||||
o:value("tcp" .. i, translatef("Same as the tcp %s node", i))
|
||||
end
|
||||
for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) end
|
||||
|
||||
o = s:option(Value, "port", translate("Listen Port"))
|
||||
o.datatype = "port"
|
||||
o.rmempty = false
|
||||
|
||||
m:append(Template(appname .. "/other/footer"))
|
||||
|
||||
return m
|
||||
|
||||
@ -1,17 +1,36 @@
|
||||
local e = require "nixio.fs"
|
||||
local e = require "luci.sys"
|
||||
local d = require "luci.dispatcher"
|
||||
local appname = "passwall"
|
||||
|
||||
m = Map("passwall")
|
||||
m = Map(appname)
|
||||
-- [[ Rule Settings ]]--
|
||||
s = m:section(TypedSection, "global_rules", translate("Rule status"))
|
||||
s.anonymous = true
|
||||
s:append(Template("passwall/rule/rule_version"))
|
||||
s:append(Template(appname .. "/rule/rule_version"))
|
||||
|
||||
--[[
|
||||
o = s:option(Flag, "adblock", translate("Enable adblock"))
|
||||
o.rmempty = false
|
||||
]]--
|
||||
|
||||
---- Enable custom url
|
||||
o = s:option(Flag, "enable_custom_url", translate("Enable custom url"))
|
||||
o.default = 0
|
||||
o.rmempty = false
|
||||
|
||||
---- gfwlist URL
|
||||
o = s:option(Value, "gfwlist_url", translate("gfwlist Update url"))
|
||||
o:value("https://cdn.jsdelivr.net/gh/Loukky/gfwlist-by-loukky/gfwlist.txt", translate("Loukky/gfwlist-by-loukky"))
|
||||
o:value("https://cdn.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt", translate("gfwlist/gfwlist"))
|
||||
o.default = "https://cdn.jsdelivr.net/gh/Loukky/gfwlist-by-loukky/gfwlist.txt"
|
||||
o:depends("enable_custom_url", 1)
|
||||
|
||||
----chnroute URL
|
||||
o = s:option(Value, "chnroute_url", translate("Chnroute Update url"))
|
||||
o:value("https://ispip.clang.cn/all_cn.txt", translate("Clang.CN"))
|
||||
o:value("https://ispip.clang.cn/all_cn_cidr.txt", translate("Clang.CN.CIDR"))
|
||||
o.default = "https://ispip.clang.cn/all_cn.txt"
|
||||
o:depends("enable_custom_url", 1)
|
||||
|
||||
---- Auto Update
|
||||
o = s:option(Flag, "auto_update", translate("Enable auto update rules"))
|
||||
o.default = 0
|
||||
@ -31,16 +50,27 @@ for e = 0, 23 do o:value(e, e .. translate("oclock")) end
|
||||
o.default = 0
|
||||
o:depends("auto_update", 1)
|
||||
|
||||
s = m:section(TypedSection, "shunt_rules", "V2ray" .. translate("Shunt") .. translate("Rule"))
|
||||
s.template = "cbi/tblsection"
|
||||
s.anonymous = false
|
||||
s.addremove = true
|
||||
s.extedit = d.build_url("admin", "vpn", appname, "shunt_rules", "%s")
|
||||
function s.create(e, t)
|
||||
TypedSection.create(e, t)
|
||||
luci.http.redirect(e.extedit:format(t))
|
||||
end
|
||||
|
||||
o = s:option(DummyValue, "remarks", translate("Remarks"))
|
||||
|
||||
-- [[ App Settings ]]--
|
||||
s = m:section(TypedSection, "global_app", translate("App Update"),
|
||||
"<font color='red'>" ..
|
||||
translate("Please confirm that your firmware supports FPU.") ..
|
||||
"</font>")
|
||||
s.anonymous = true
|
||||
s:append(Template("passwall/rule/passwall_version"))
|
||||
s:append(Template("passwall/rule/v2ray_version"))
|
||||
s:append(Template("passwall/rule/kcptun_version"))
|
||||
s:append(Template("passwall/rule/brook_version"))
|
||||
s:append(Template(appname .. "/rule/v2ray_version"))
|
||||
s:append(Template(appname .. "/rule/kcptun_version"))
|
||||
s:append(Template(appname .. "/rule/brook_version"))
|
||||
|
||||
---- V2ray Path
|
||||
o = s:option(Value, "v2ray_file", translate("V2ray Path"), translate(
|
||||
@ -57,7 +87,7 @@ o.rmempty = false
|
||||
|
||||
--[[
|
||||
o = s:option(Button, "_check_kcptun", translate("Manually update"), translate("Make sure there is enough space to install Kcptun"))
|
||||
o.template = "passwall/kcptun"
|
||||
o.template = appname .. "/kcptun"
|
||||
o.inputstyle = "apply"
|
||||
o.btnclick = "onBtnClick_kcptun(this);"
|
||||
o.id = "_kcptun-check_btn"]] --
|
||||
|
||||
@ -0,0 +1,130 @@
|
||||
#!/usr/bin/lua
|
||||
|
||||
local action = arg[1]
|
||||
local sys = require 'luci.sys'
|
||||
local jsonc = require "luci.jsonc"
|
||||
local ucic = require"luci.model.uci".cursor()
|
||||
local _api = require "luci.model.cbi.passwall.api.api"
|
||||
|
||||
local CONFIG = "passwall_server"
|
||||
local CONFIG_PATH = "/var/etc/" .. CONFIG
|
||||
local LOG_APP_FILE = "/var/log/" .. CONFIG .. ".log"
|
||||
local TMP_BIN_PATH = CONFIG_PATH .. "/bin"
|
||||
|
||||
local function log(...)
|
||||
local f, err = io.open(LOG_APP_FILE, "a")
|
||||
if f and err == nil then
|
||||
local str = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ")
|
||||
f:write(str .. "\n")
|
||||
f:close()
|
||||
end
|
||||
end
|
||||
|
||||
local function cmd(cmd)
|
||||
sys.call(cmd)
|
||||
end
|
||||
|
||||
local function ln_start(s, d, command)
|
||||
d = TMP_BIN_PATH .. "/" .. d
|
||||
cmd(string.format('[ ! -f "%s" ] && ln -s %s %s 2>/dev/null', d, s, d))
|
||||
return string.format("%s >/dev/null 2>&1 &", d .. " " ..command)
|
||||
end
|
||||
|
||||
local function gen_include()
|
||||
cmd(string.format("echo '#!/bin/sh' > /var/etc/%s.include", CONFIG))
|
||||
local function extract_rules(a)
|
||||
local result = "*" .. a
|
||||
result = result .. "\n" .. sys.exec('iptables-save -t ' .. a .. ' | grep "PSW-SERVER" | sed -e "s/^-A \\(INPUT\\)/-I \\1 1/"')
|
||||
result = result .. "COMMIT"
|
||||
return result
|
||||
end
|
||||
local f, err = io.open("/var/etc/" .. CONFIG .. ".include", "a")
|
||||
if f and err == nil then
|
||||
f:write('iptables-save -c | grep -v "PSW-SERVER" | iptables-restore -c' .. "\n")
|
||||
f:write('iptables-restore -n <<-EOT' .. "\n")
|
||||
f:write(extract_rules("filter") .. "\n")
|
||||
f:write("EOT" .. "\n")
|
||||
f:close()
|
||||
end
|
||||
end
|
||||
|
||||
local function start()
|
||||
local enabled = tonumber(ucic:get(CONFIG, "@global[0]", "enable") or 0)
|
||||
if enabled == nil or enabled == 0 then
|
||||
return
|
||||
end
|
||||
cmd(string.format("mkdir -p %s %s", CONFIG_PATH, TMP_BIN_PATH))
|
||||
cmd(string.format("touch %s", LOG_APP_FILE))
|
||||
cmd("iptables -N PSW-SERVER")
|
||||
cmd("iptables -I INPUT -j PSW-SERVER")
|
||||
ucic:foreach(CONFIG, "user", function(user)
|
||||
local id = user[".name"]
|
||||
local enable = user.enable
|
||||
if enable and tonumber(enable) == 1 then
|
||||
local remarks = user.remarks
|
||||
local port = tonumber(user.port)
|
||||
local bin
|
||||
local config = {}
|
||||
local config_file = CONFIG_PATH .. "/" .. id .. ".json"
|
||||
local udp_forward = 1
|
||||
local type = user.type or ""
|
||||
if type == "SSR" then
|
||||
config = require("luci.model.cbi.passwall.server.api.ssr").gen_config(user)
|
||||
local udp_param = ""
|
||||
udp_forward = tonumber(user.udp_forward) or 1
|
||||
if udp_forward == 1 then
|
||||
udp_param = "-u"
|
||||
end
|
||||
bin = ln_start("/usr/bin/ssr-server", "ssr-server", "-c " .. config_file .. " " .. udp_param)
|
||||
elseif type == "V2ray" then
|
||||
config = require("luci.model.cbi.passwall.server.api.v2ray").gen_config(user)
|
||||
bin = ln_start(_api.get_v2ray_path(), "v2ray", "-config=" .. config_file)
|
||||
elseif type == "Trojan" then
|
||||
config = require("luci.model.cbi.passwall.server.api.trojan").gen_config(user)
|
||||
bin = ln_start("/usr/sbin/trojan", "trojan", "-c " .. config_file)
|
||||
elseif type == "Brook" then
|
||||
local brook_protocol = user.brook_protocol
|
||||
local brook_password = user.password
|
||||
bin = ln_start(_api.get_brook_path(), "brook_" .. id, string.format("%s -l :%s -p %s", brook_protocol, port, brook_password))
|
||||
end
|
||||
|
||||
if next(config) then
|
||||
local f, err = io.open(config_file, "w")
|
||||
if f and err == nil then
|
||||
f:write(jsonc.stringify(config, 1))
|
||||
f:close()
|
||||
end
|
||||
log(string.format("%s %s 生成配置文件并运行 - %s", remarks, port, config_file))
|
||||
end
|
||||
|
||||
if bin then
|
||||
cmd(bin)
|
||||
end
|
||||
|
||||
local bind_local = user.bind_local or 0
|
||||
if bind_local and tonumber(bind_local) ~= 1 then
|
||||
cmd(string.format('iptables -A PSW-SERVER -p tcp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks))
|
||||
if udp_forward == 1 then
|
||||
cmd(string.format('iptables -A PSW-SERVER -p udp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks))
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
gen_include()
|
||||
end
|
||||
|
||||
local function stop()
|
||||
cmd(string.format("ps -w | grep -v 'grep' | grep '%s/' | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 &", CONFIG_PATH))
|
||||
cmd("iptables -D INPUT -j PSW-SERVER 2>/dev/null")
|
||||
cmd("iptables -F PSW-SERVER 2>/dev/null")
|
||||
cmd("iptables -X PSW-SERVER 2>/dev/null")
|
||||
cmd(string.format("rm -rf %s %s /var/etc/%s.include", CONFIG_PATH, LOG_APP_FILE, CONFIG))
|
||||
end
|
||||
|
||||
if action then
|
||||
if action == "start" then
|
||||
start()
|
||||
elseif action == "stop" then
|
||||
stop()
|
||||
end
|
||||
end
|
||||
@ -0,0 +1,15 @@
|
||||
module("luci.model.cbi.passwall.server.api.ssr", package.seeall)
|
||||
function gen_config(user)
|
||||
local config = {}
|
||||
config.server = {"[::0]", "0.0.0.0"}
|
||||
config.server_port = tonumber(user.port)
|
||||
config.password = user.password
|
||||
config.timeout = tonumber(user.timeout)
|
||||
config.fast_open = (user.tcp_fast_open and user.tcp_fast_open == "true") and true or false
|
||||
config.method = user.ssr_encrypt_method
|
||||
config.protocol = user.protocol
|
||||
config.protocol_param = user.protocol_param
|
||||
config.obfs = user.obfs
|
||||
config.obfs_param = user.obfs_param
|
||||
return config
|
||||
end
|
||||
@ -0,0 +1,36 @@
|
||||
module("luci.model.cbi.passwall.server.api.trojan", package.seeall)
|
||||
function gen_config(user)
|
||||
local config = {
|
||||
run_type = "server",
|
||||
local_addr = "0.0.0.0",
|
||||
local_port = tonumber(user.port),
|
||||
remote_addr = (user.remote_enable == "1" and user.remote_address) and user.remote_address or nil,
|
||||
remote_port = (user.remote_enable == "1" and user.remote_port) and user.remote_port or nil,
|
||||
password = user.password,
|
||||
log_level = 1,
|
||||
ssl = {
|
||||
cert = user.tls_certificateFile,
|
||||
key = user.tls_keyFile,
|
||||
key_password = "",
|
||||
cipher = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:AES128-SHA:AES256-SHA:DES-CBC3-SHA",
|
||||
cipher_tls13 = "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384",
|
||||
prefer_server_cipher = true,
|
||||
alpn = {"http/1.1"},
|
||||
reuse_session = true,
|
||||
session_ticket = false,
|
||||
session_timeout = 600,
|
||||
plain_http_response = "",
|
||||
curves = "",
|
||||
dhparam = ""
|
||||
},
|
||||
tcp = {
|
||||
prefer_ipv4 = false,
|
||||
no_delay = true,
|
||||
keep_alive = true,
|
||||
reuse_port = false,
|
||||
fast_open = (user.fast_open == "true") and true or false,
|
||||
fast_open_qlen = 20
|
||||
}
|
||||
}
|
||||
return config
|
||||
end
|
||||
@ -0,0 +1,235 @@
|
||||
module("luci.model.cbi.passwall.server.api.v2ray", package.seeall)
|
||||
local ucic = require"luci.model.uci".cursor()
|
||||
|
||||
function gen_config(user)
|
||||
local settings = nil
|
||||
local routing = nil
|
||||
local outbounds = {
|
||||
{protocol = "freedom"}, {protocol = "blackhole", tag = "blocked"}
|
||||
}
|
||||
|
||||
if user.v2ray_protocol == "vmess" then
|
||||
if user.vmess_id then
|
||||
local clients = {}
|
||||
for i = 1, #user.vmess_id do
|
||||
clients[i] = {
|
||||
id = user.vmess_id[i],
|
||||
level = tonumber(user.vmess_level),
|
||||
alterId = tonumber(user.vmess_alterId)
|
||||
}
|
||||
end
|
||||
settings = {clients = clients}
|
||||
end
|
||||
elseif user.v2ray_protocol == "socks" then
|
||||
settings = {
|
||||
auth = (user.username == nil and user.password == nil) and "noauth" or "password",
|
||||
accounts = {
|
||||
{
|
||||
user = (user.username == nil) and "" or user.username,
|
||||
pass = (user.password == nil) and "" or user.password
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif user.v2ray_protocol == "http" then
|
||||
settings = {
|
||||
allowTransparent = false,
|
||||
accounts = {
|
||||
{
|
||||
user = (user.username == nil) and "" or user.username,
|
||||
pass = (user.password == nil) and "" or user.password
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif user.v2ray_protocol == "shadowsocks" then
|
||||
settings = {
|
||||
method = user.v2ray_ss_encrypt_method,
|
||||
password = user.password,
|
||||
level = tonumber(user.vmess_level) or 1,
|
||||
network = user.v2ray_ss_network or "TCP,UDP",
|
||||
ota = (user.v2ray_ss_ota == '1') and true or false
|
||||
}
|
||||
end
|
||||
|
||||
if user.accept_lan == nil or user.accept_lan == "0" then
|
||||
routing = {
|
||||
domainStrategy = "IPOnDemand",
|
||||
rules = {
|
||||
{
|
||||
type = "field",
|
||||
ip = {"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"},
|
||||
outboundTag = "blocked"
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
if user.transit_node and user.transit_node ~= "nil" then
|
||||
local node = ucic:get_all("passwall", user.transit_node)
|
||||
if node and node ~= "nil" and node.type and node.type == "V2ray" then
|
||||
local transit_node = {
|
||||
tag = "transit",
|
||||
protocol = node.v2ray_protocol or "vmess",
|
||||
mux = {
|
||||
enabled = (node.v2ray_mux == "1") and true or false,
|
||||
concurrency = (node.v2ray_mux_concurrency) and
|
||||
tonumber(node.v2ray_mux_concurrency) or 8
|
||||
},
|
||||
-- 底层传输配置
|
||||
streamSettings = (node.v2ray_protocol == "vmess") and {
|
||||
network = node.v2ray_transport,
|
||||
security = node.v2ray_stream_security,
|
||||
tlsSettings = (node.v2ray_stream_security == "tls") and {
|
||||
serverName = node.tls_serverName,
|
||||
allowInsecure = (node.tls_allowInsecure == "1") and true or
|
||||
false
|
||||
} or nil,
|
||||
tcpSettings = (node.v2ray_transport == "tcp") and {
|
||||
header = {
|
||||
type = node.v2ray_tcp_guise,
|
||||
request = {
|
||||
path = node.v2ray_tcp_guise_http_path or {"/"},
|
||||
headers = {
|
||||
Host = node.v2ray_tcp_guise_http_host or {}
|
||||
}
|
||||
} or {}
|
||||
}
|
||||
} or nil,
|
||||
kcpSettings = (node.v2ray_transport == "mkcp") and {
|
||||
mtu = tonumber(node.v2ray_mkcp_mtu),
|
||||
tti = tonumber(node.v2ray_mkcp_tti),
|
||||
uplinkCapacity = tonumber(node.v2ray_mkcp_uplinkCapacity),
|
||||
downlinkCapacity = tonumber(
|
||||
node.v2ray_mkcp_downlinkCapacity),
|
||||
congestion = (node.v2ray_mkcp_congestion == "1") and
|
||||
true or false,
|
||||
readBufferSize = tonumber(node.v2ray_mkcp_readBufferSize),
|
||||
writeBufferSize = tonumber(
|
||||
node.v2ray_mkcp_writeBufferSize),
|
||||
header = {type = node.v2ray_mkcp_guise}
|
||||
} or nil,
|
||||
wsSettings = (node.v2ray_transport == "ws") and {
|
||||
path = node.v2ray_ws_path or "",
|
||||
headers = (node.v2ray_ws_host ~= nil) and
|
||||
{Host = node.v2ray_ws_host} or nil
|
||||
} or nil,
|
||||
httpSettings = (node.v2ray_transport == "h2") and
|
||||
{path = node.v2ray_h2_path, host = node.v2ray_h2_host} or
|
||||
nil,
|
||||
dsSettings = (node.v2ray_transport == "ds") and
|
||||
{path = node.v2ray_ds_path} or nil,
|
||||
quicSettings = (node.v2ray_transport == "quic") and {
|
||||
security = node.v2ray_quic_security,
|
||||
key = node.v2ray_quic_key,
|
||||
header = {type = node.v2ray_quic_guise}
|
||||
} or nil
|
||||
} or nil,
|
||||
settings = {
|
||||
vnext = (node.v2ray_protocol == "vmess") and {
|
||||
{
|
||||
address = node.address,
|
||||
port = tonumber(node.port),
|
||||
users = {
|
||||
{
|
||||
id = node.v2ray_VMess_id,
|
||||
alterId = tonumber(node.v2ray_VMess_alterId),
|
||||
level = tonumber(node.v2ray_VMess_level),
|
||||
security = node.v2ray_security
|
||||
}
|
||||
}
|
||||
}
|
||||
} or nil,
|
||||
servers = (node.v2ray_protocol == "http" or
|
||||
node.v2ray_protocol == "socks" or node.v2ray_protocol == "shadowsocks") and {
|
||||
{
|
||||
address = node.address,
|
||||
port = tonumber(node.port),
|
||||
method = node.v2ray_ss_encrypt_method,
|
||||
password = node.password or "",
|
||||
ota = (node.v2ray_ss_ota == '1') and true or false,
|
||||
users = (node.username and node.password) and
|
||||
{
|
||||
{
|
||||
user = node.username or "",
|
||||
pass = node.password or ""
|
||||
}
|
||||
} or nil
|
||||
}
|
||||
} or nil
|
||||
}
|
||||
}
|
||||
table.insert(outbounds, 1, transit_node)
|
||||
end
|
||||
end
|
||||
|
||||
local config = {
|
||||
log = {
|
||||
-- error = "/var/log/v2ray.log",
|
||||
loglevel = "warning"
|
||||
},
|
||||
-- 传入连接
|
||||
inbounds = {
|
||||
{
|
||||
listen = (user.bind_local == "1") and "127.0.0.1" or nil,
|
||||
port = tonumber(user.port),
|
||||
protocol = user.v2ray_protocol,
|
||||
-- 底层传输配置
|
||||
settings = settings,
|
||||
streamSettings = (user.v2ray_protocol == "vmess") and {
|
||||
network = user.v2ray_transport,
|
||||
security = (user.tls_enable == '1') and "tls" or "none",
|
||||
tlsSettings = (user.tls_enable == '1') and {
|
||||
-- serverName = (user.tls_serverName),
|
||||
allowInsecure = false,
|
||||
disableSystemRoot = false,
|
||||
certificates = {
|
||||
{
|
||||
certificateFile = user.tls_certificateFile,
|
||||
keyFile = user.tls_keyFile
|
||||
}
|
||||
}
|
||||
} or nil,
|
||||
tcpSettings = (user.v2ray_transport == "tcp") and {
|
||||
header = {
|
||||
type = user.v2ray_tcp_guise,
|
||||
request = {
|
||||
path = user.v2ray_tcp_guise_http_path or {"/"},
|
||||
headers = {
|
||||
Host = user.v2ray_tcp_guise_http_host or {}
|
||||
}
|
||||
} or {}
|
||||
}
|
||||
} or nil,
|
||||
kcpSettings = (user.v2ray_transport == "mkcp") and {
|
||||
mtu = tonumber(user.v2ray_mkcp_mtu),
|
||||
tti = tonumber(user.v2ray_mkcp_tti),
|
||||
uplinkCapacity = tonumber(user.v2ray_mkcp_uplinkCapacity),
|
||||
downlinkCapacity = tonumber(user.v2ray_mkcp_downlinkCapacity),
|
||||
congestion = (user.v2ray_mkcp_congestion == "1") and true or false,
|
||||
readBufferSize = tonumber(user.v2ray_mkcp_readBufferSize),
|
||||
writeBufferSize = tonumber(user.v2ray_mkcp_writeBufferSize),
|
||||
header = {type = user.v2ray_mkcp_guise}
|
||||
} or nil,
|
||||
wsSettings = (user.v2ray_transport == "ws") and
|
||||
{
|
||||
headers = (user.v2ray_ws_host) and {Host = user.v2ray_ws_host} or
|
||||
nil,
|
||||
path = user.v2ray_ws_path
|
||||
} or nil,
|
||||
httpSettings = (user.v2ray_transport == "h2") and
|
||||
{path = user.v2ray_h2_path, host = user.v2ray_h2_host} or nil,
|
||||
dsSettings = (user.v2ray_transport == "ds") and
|
||||
{path = user.v2ray_ds_path} or nil,
|
||||
quicSettings = (user.v2ray_transport == "quic") and {
|
||||
security = user.v2ray_quic_security,
|
||||
key = user.v2ray_quic_key,
|
||||
header = {type = user.v2ray_quic_guise}
|
||||
} or nil
|
||||
} or nil
|
||||
}
|
||||
},
|
||||
-- 传出连接
|
||||
outbounds = outbounds,
|
||||
routing = routing
|
||||
}
|
||||
return config
|
||||
end
|
||||
@ -0,0 +1,51 @@
|
||||
local d = require "luci.dispatcher"
|
||||
local _api = require "luci.model.cbi.passwall.api.api"
|
||||
local e = luci.model.uci.cursor()
|
||||
|
||||
m = Map("passwall_server", translate("Server-Side"))
|
||||
|
||||
t = m:section(NamedSection, "global", "global")
|
||||
t.anonymous = true
|
||||
t.addremove = false
|
||||
|
||||
e = t:option(Flag, "enable", translate("Enable"))
|
||||
e.rmempty = false
|
||||
|
||||
t = m:section(TypedSection, "user", translate("Users Manager"))
|
||||
t.anonymous = true
|
||||
t.addremove = true
|
||||
t.template = "cbi/tblsection"
|
||||
t.extedit = d.build_url("admin", "vpn", "passwall", "server_user", "%s")
|
||||
function t.create(e, t)
|
||||
local uuid = _api.gen_uuid()
|
||||
t = uuid
|
||||
TypedSection.create(e, t)
|
||||
luci.http.redirect(e.extedit:format(t))
|
||||
end
|
||||
function t.remove(e, t)
|
||||
e.map.proceed = true
|
||||
e.map:del(t)
|
||||
luci.http.redirect(d.build_url("admin", "vpn", "passwall", "server"))
|
||||
end
|
||||
|
||||
e = t:option(Flag, "enable", translate("Enable"))
|
||||
e.width = "5%"
|
||||
e.rmempty = false
|
||||
|
||||
e = t:option(DummyValue, "status", translate("Status"))
|
||||
e.template = "passwall/server/users_status"
|
||||
e.value = translate("Collecting data...")
|
||||
|
||||
e = t:option(DummyValue, "remarks", translate("Remarks"))
|
||||
e.width = "15%"
|
||||
|
||||
---- Type
|
||||
e = t:option(DummyValue, "type", translate("Type"))
|
||||
|
||||
e = t:option(DummyValue, "port", translate("Port"))
|
||||
|
||||
m:append(Template("passwall/server/log"))
|
||||
|
||||
m:append(Template("passwall/server/users_list_status"))
|
||||
return m
|
||||
|
||||
@ -0,0 +1,322 @@
|
||||
local d = require "luci.dispatcher"
|
||||
local ipkg = require("luci.model.ipkg")
|
||||
local uci = require"luci.model.uci".cursor()
|
||||
local api = require "luci.model.cbi.passwall.api.api"
|
||||
|
||||
local function is_finded(e)
|
||||
local function get_customed_path(e)
|
||||
return api.uci_get_type("global_app", e .. "_file")
|
||||
end
|
||||
return luci.sys.exec("find /usr/*bin %s -iname %s -type f" % {get_customed_path(e), e}) ~= "" and true or false
|
||||
end
|
||||
|
||||
local function is_installed(e) return ipkg.installed(e) end
|
||||
|
||||
local ssr_encrypt_method_list = {
|
||||
"none", "table", "rc2-cfb", "rc4", "rc4-md5", "rc4-md5-6", "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", "seed-cfb", "salsa20", "chacha20",
|
||||
"chacha20-ietf"
|
||||
}
|
||||
|
||||
local ssr_protocol_list = {
|
||||
"origin", "verify_simple", "verify_deflate", "verify_sha1", "auth_simple",
|
||||
"auth_sha1", "auth_sha1_v2", "auth_sha1_v4", "auth_aes128_md5",
|
||||
"auth_aes128_sha1", "auth_chain_a", "auth_chain_b", "auth_chain_c",
|
||||
"auth_chain_d", "auth_chain_e", "auth_chain_f"
|
||||
}
|
||||
local ssr_obfs_list = {
|
||||
"plain", "http_simple", "http_post", "random_head", "tls_simple",
|
||||
"tls1.0_session_auth", "tls1.2_ticket_auth"
|
||||
}
|
||||
|
||||
local v2ray_ss_encrypt_method_list = {
|
||||
"aes-128-cfb", "aes-256-cfb", "aes-128-gcm", "aes-256-gcm", "chacha20", "chacha20-ietf", "chacha20-poly1305", "chacha20-ietf-poly1305"
|
||||
}
|
||||
|
||||
local v2ray_header_type_list = {
|
||||
"none", "srtp", "utp", "wechat-video", "dtls", "wireguard"
|
||||
}
|
||||
|
||||
map = Map("passwall_server", translate("Server Config"))
|
||||
map.redirect = d.build_url("admin", "vpn", "passwall", "server")
|
||||
|
||||
s = map:section(NamedSection, arg[1], "user", "")
|
||||
s.addremove = false
|
||||
s.dynamic = false
|
||||
|
||||
enable = s:option(Flag, "enable", translate("Enable"))
|
||||
enable.default = "1"
|
||||
enable.rmempty = false
|
||||
|
||||
remarks = s:option(Value, "remarks", translate("Remarks"))
|
||||
remarks.default = translate("Remarks")
|
||||
remarks.rmempty = false
|
||||
|
||||
type = s:option(ListValue, "type", translate("Type"))
|
||||
if is_finded("ssr-server") then
|
||||
type:value("SSR", translate("ShadowsocksR"))
|
||||
end
|
||||
if is_installed("v2ray") or is_finded("v2ray") then
|
||||
type:value("V2ray", translate("V2ray"))
|
||||
end
|
||||
if is_installed("brook") or is_finded("brook") then
|
||||
type:value("Brook", translate("Brook"))
|
||||
end
|
||||
if is_installed("trojan") or is_finded("trojan") then
|
||||
type:value("Trojan", translate("Trojan"))
|
||||
end
|
||||
|
||||
v2ray_protocol = s:option(ListValue, "v2ray_protocol", translate("Protocol"))
|
||||
v2ray_protocol:value("vmess", translate("Vmess"))
|
||||
v2ray_protocol:value("http", translate("HTTP"))
|
||||
v2ray_protocol:value("socks", translate("Socks"))
|
||||
v2ray_protocol:value("shadowsocks", translate("Shadowsocks"))
|
||||
v2ray_protocol:depends("type", "V2ray")
|
||||
|
||||
-- Brook协议
|
||||
brook_protocol = s:option(ListValue, "brook_protocol",
|
||||
translate("Brook Protocol"))
|
||||
brook_protocol:value("server", translate("Brook"))
|
||||
brook_protocol:value("wsserver", translate("WebSocket"))
|
||||
brook_protocol:depends("type", "Brook")
|
||||
|
||||
brook_tls = s:option(Flag, "brook_tls", translate("Use TLS"))
|
||||
brook_tls:depends("brook_protocol", "wsserver")
|
||||
|
||||
port = s:option(Value, "port", translate("Port"))
|
||||
port.datatype = "port"
|
||||
port.rmempty = false
|
||||
port:depends("type", "SSR")
|
||||
port:depends({ type = "V2ray", v2ray_protocol = "vmess" })
|
||||
port:depends({ type = "V2ray", v2ray_protocol = "http" })
|
||||
port:depends({ type = "V2ray", v2ray_protocol = "socks" })
|
||||
port:depends({ type = "V2ray", v2ray_protocol = "shadowsocks" })
|
||||
port:depends("type", "Brook")
|
||||
port:depends("type", "Trojan")
|
||||
|
||||
username = s:option(Value, "username", translate("Username"))
|
||||
username:depends("v2ray_protocol", "http")
|
||||
username:depends("v2ray_protocol", "socks")
|
||||
|
||||
password = s:option(Value, "password", translate("Password"))
|
||||
password.password = true
|
||||
password:depends("type", "SSR")
|
||||
password:depends("type", "Brook")
|
||||
password:depends("type", "Trojan")
|
||||
password:depends({ type = "V2ray", v2ray_protocol = "http" })
|
||||
password:depends({ type = "V2ray", v2ray_protocol = "socks" })
|
||||
password:depends({ type = "V2ray", v2ray_protocol = "shadowsocks" })
|
||||
|
||||
ssr_encrypt_method = s:option(ListValue, "ssr_encrypt_method", translate("Encrypt Method"))
|
||||
for a, t in ipairs(ssr_encrypt_method_list) do ssr_encrypt_method:value(t) end
|
||||
ssr_encrypt_method:depends("type", "SSR")
|
||||
|
||||
v2ray_ss_encrypt_method = s:option(ListValue, "v2ray_ss_encrypt_method", translate("Encrypt Method"))
|
||||
for a, t in ipairs(v2ray_ss_encrypt_method_list) do v2ray_ss_encrypt_method:value(t) end
|
||||
v2ray_ss_encrypt_method:depends("v2ray_protocol", "shadowsocks")
|
||||
|
||||
v2ray_ss_network = s:option(ListValue, "v2ray_ss_network", translate("Transport"))
|
||||
v2ray_ss_network.default = "tcp,udp"
|
||||
v2ray_ss_network:value("tcp", "TCP")
|
||||
v2ray_ss_network:value("udp", "UDP")
|
||||
v2ray_ss_network:value("tcp,udp", "TCP,UDP")
|
||||
v2ray_ss_network:depends("v2ray_protocol", "shadowsocks")
|
||||
|
||||
v2ray_ss_ota = s:option(Flag, "v2ray_ss_ota", translate("OTA"), translate("When OTA is enabled, V2Ray will reject connections that are not OTA enabled. This option is invalid when using AEAD encryption."))
|
||||
v2ray_ss_ota.default = "0"
|
||||
v2ray_ss_ota:depends("v2ray_protocol", "shadowsocks")
|
||||
|
||||
protocol = s:option(ListValue, "protocol", translate("Protocol"))
|
||||
for a, t in ipairs(ssr_protocol_list) do protocol:value(t) end
|
||||
protocol:depends("type", "SSR")
|
||||
|
||||
protocol_param = s:option(Value, "protocol_param", translate("Protocol_param"))
|
||||
protocol_param:depends("type", "SSR")
|
||||
|
||||
obfs = s:option(ListValue, "obfs", translate("Obfs"))
|
||||
for a, t in ipairs(ssr_obfs_list) do obfs:value(t) end
|
||||
obfs:depends("type", "SSR")
|
||||
|
||||
obfs_param = s:option(Value, "obfs_param", translate("Obfs_param"))
|
||||
obfs_param:depends("type", "SSR")
|
||||
|
||||
timeout = s:option(Value, "timeout", translate("Connection Timeout"))
|
||||
timeout.datatype = "uinteger"
|
||||
timeout.default = 300
|
||||
timeout:depends("type", "SSR")
|
||||
|
||||
tcp_fast_open = s:option(ListValue, "tcp_fast_open", translate("TCP Fast Open"), translate("Need node support required"))
|
||||
tcp_fast_open:value("false")
|
||||
tcp_fast_open:value("true")
|
||||
tcp_fast_open:depends("type", "SSR")
|
||||
tcp_fast_open:depends("type", "Trojan")
|
||||
|
||||
udp_forward = s:option(Flag, "udp_forward", translate("UDP Forward"))
|
||||
udp_forward.default = "1"
|
||||
udp_forward.rmempty = false
|
||||
udp_forward:depends("type", "SSR")
|
||||
|
||||
vmess_id = s:option(DynamicList, "vmess_id", translate("ID"))
|
||||
for i = 1, 3 do
|
||||
local uuid = luci.sys.exec("echo -n $(cat /proc/sys/kernel/random/uuid)")
|
||||
vmess_id:value(uuid)
|
||||
end
|
||||
vmess_id:depends({ type = "V2ray", v2ray_protocol = "vmess" })
|
||||
|
||||
vmess_alterId = s:option(Value, "vmess_alterId", translate("Alter ID"))
|
||||
vmess_alterId.default = 16
|
||||
vmess_alterId:depends({ type = "V2ray", v2ray_protocol = "vmess" })
|
||||
|
||||
vmess_level = s:option(Value, "vmess_level", translate("User Level"))
|
||||
vmess_level.default = 1
|
||||
vmess_level:depends({ type = "V2ray", v2ray_protocol = "vmess" })
|
||||
vmess_level:depends({ type = "V2ray", v2ray_protocol = "shadowsocks" })
|
||||
|
||||
v2ray_transport = s:option(ListValue, "v2ray_transport", translate("Transport"))
|
||||
v2ray_transport:value("tcp", "TCP")
|
||||
v2ray_transport:value("mkcp", "mKCP")
|
||||
v2ray_transport:value("ws", "WebSocket")
|
||||
v2ray_transport:value("h2", "HTTP/2")
|
||||
v2ray_transport:value("ds", "DomainSocket")
|
||||
v2ray_transport:value("quic", "QUIC")
|
||||
v2ray_transport:depends("v2ray_protocol", "vmess")
|
||||
|
||||
-- [[ TCP部分 ]]--
|
||||
|
||||
-- TCP伪装
|
||||
v2ray_tcp_guise = s:option(ListValue, "v2ray_tcp_guise", translate("Camouflage Type"))
|
||||
v2ray_tcp_guise:value("none", "none")
|
||||
v2ray_tcp_guise:value("http", "http")
|
||||
v2ray_tcp_guise:depends("v2ray_transport", "tcp")
|
||||
|
||||
-- HTTP域名
|
||||
v2ray_tcp_guise_http_host = s:option(DynamicList, "v2ray_tcp_guise_http_host", translate("HTTP Host"))
|
||||
v2ray_tcp_guise_http_host:depends("v2ray_tcp_guise", "http")
|
||||
|
||||
-- HTTP路径
|
||||
v2ray_tcp_guise_http_path = s:option(DynamicList, "v2ray_tcp_guise_http_path", translate("HTTP Path"))
|
||||
v2ray_tcp_guise_http_path:depends("v2ray_tcp_guise", "http")
|
||||
|
||||
-- [[ mKCP部分 ]]--
|
||||
|
||||
v2ray_mkcp_guise = s:option(ListValue, "v2ray_mkcp_guise", translate("Camouflage Type"), translate('<br />none: default, no masquerade, data sent is packets with no characteristics.<br />srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).<br />utp: packets disguised as uTP will be recognized as bittorrent downloaded data.<br />wechat-video: packets disguised as WeChat video calls.<br />dtls: disguised as DTLS 1.2 packet.<br />wireguard: disguised as a WireGuard packet. (not really WireGuard protocol)'))
|
||||
for a, t in ipairs(v2ray_header_type_list) do v2ray_mkcp_guise:value(t) end
|
||||
v2ray_mkcp_guise:depends("v2ray_transport", "mkcp")
|
||||
|
||||
v2ray_mkcp_mtu = s:option(Value, "v2ray_mkcp_mtu", translate("KCP MTU"))
|
||||
v2ray_mkcp_mtu:depends("v2ray_transport", "mkcp")
|
||||
|
||||
v2ray_mkcp_tti = s:option(Value, "v2ray_mkcp_tti", translate("KCP TTI"))
|
||||
v2ray_mkcp_tti:depends("v2ray_transport", "mkcp")
|
||||
|
||||
v2ray_mkcp_uplinkCapacity = s:option(Value, "v2ray_mkcp_uplinkCapacity", translate("KCP uplinkCapacity"))
|
||||
v2ray_mkcp_uplinkCapacity:depends("v2ray_transport", "mkcp")
|
||||
|
||||
v2ray_mkcp_downlinkCapacity = s:option(Value, "v2ray_mkcp_downlinkCapacity", translate("KCP downlinkCapacity"))
|
||||
v2ray_mkcp_downlinkCapacity:depends("v2ray_transport", "mkcp")
|
||||
|
||||
v2ray_mkcp_congestion = s:option(Flag, "v2ray_mkcp_congestion", translate("KCP Congestion"))
|
||||
v2ray_mkcp_congestion:depends("v2ray_transport", "mkcp")
|
||||
|
||||
v2ray_mkcp_readBufferSize = s:option(Value, "v2ray_mkcp_readBufferSize", translate("KCP readBufferSize"))
|
||||
v2ray_mkcp_readBufferSize:depends("v2ray_transport", "mkcp")
|
||||
|
||||
v2ray_mkcp_writeBufferSize = s:option(Value, "v2ray_mkcp_writeBufferSize", translate("KCP writeBufferSize"))
|
||||
v2ray_mkcp_writeBufferSize:depends("v2ray_transport", "mkcp")
|
||||
|
||||
-- [[ WebSocket部分 ]]--
|
||||
|
||||
v2ray_ws_host = s:option(Value, "v2ray_ws_host", translate("WebSocket Host"))
|
||||
v2ray_ws_host:depends("v2ray_transport", "ws")
|
||||
v2ray_ws_host:depends("v2ray_ss_transport", "ws")
|
||||
|
||||
v2ray_ws_path = s:option(Value, "v2ray_ws_path", translate("WebSocket Path"))
|
||||
v2ray_ws_path:depends("v2ray_transport", "ws")
|
||||
v2ray_ws_path:depends("v2ray_ss_transport", "ws")
|
||||
|
||||
-- [[ HTTP/2部分 ]]--
|
||||
|
||||
v2ray_h2_host = s:option(DynamicList, "v2ray_h2_host", translate("HTTP/2 Host"))
|
||||
v2ray_h2_host:depends("v2ray_transport", "h2")
|
||||
v2ray_h2_host:depends("v2ray_ss_transport", "h2")
|
||||
|
||||
v2ray_h2_path = s:option(Value, "v2ray_h2_path", translate("HTTP/2 Path"))
|
||||
v2ray_h2_path:depends("v2ray_transport", "h2")
|
||||
v2ray_h2_path:depends("v2ray_ss_transport", "h2")
|
||||
|
||||
-- [[ DomainSocket部分 ]]--
|
||||
|
||||
v2ray_ds_path = s:option(Value, "v2ray_ds_path", "Path", translate("A legal file path. This file must not exist before running V2Ray."))
|
||||
v2ray_ds_path:depends("v2ray_transport", "ds")
|
||||
|
||||
-- [[ QUIC部分 ]]--
|
||||
v2ray_quic_security = s:option(ListValue, "v2ray_quic_security", translate("Encrypt Method"))
|
||||
v2ray_quic_security:value("none")
|
||||
v2ray_quic_security:value("aes-128-gcm")
|
||||
v2ray_quic_security:value("chacha20-poly1305")
|
||||
v2ray_quic_security:depends("v2ray_transport", "quic")
|
||||
|
||||
v2ray_quic_key = s:option(Value, "v2ray_quic_key", translate("Encrypt Method") .. translate("Key"))
|
||||
v2ray_quic_key:depends("v2ray_transport", "quic")
|
||||
|
||||
v2ray_quic_guise = s:option(ListValue, "v2ray_quic_guise", translate("Camouflage Type"))
|
||||
for a, t in ipairs(v2ray_header_type_list) do v2ray_quic_guise:value(t) end
|
||||
v2ray_quic_guise:depends("v2ray_transport", "quic")
|
||||
|
||||
remote_enable = s:option(Flag, "remote_enable", translate("Enable Remote"),translate("You can forward to Nginx/Caddy/V2ray WebSocket and more."))
|
||||
remote_enable.default = "1"
|
||||
remote_enable.rmempty = false
|
||||
remote_enable:depends("type", "Trojan")
|
||||
|
||||
remote_address = s:option(Value, "remote_address", translate("Remote Address"))
|
||||
remote_address.default = "127.0.0.1"
|
||||
remote_address:depends("remote_enable", 1)
|
||||
|
||||
remote_port = s:option(Value, "remote_port", translate("Remote Port"))
|
||||
remote_port.datatype = "port"
|
||||
remote_port.default = "80"
|
||||
remote_port:depends("remote_enable", 1)
|
||||
|
||||
-- [[ TLS部分 ]] --
|
||||
tls_enable = s:option(Flag, "tls_enable", "TLS/SSL")
|
||||
tls_enable:depends({ type = "V2ray", v2ray_protocol = "vmess", v2ray_transport = "ws" })
|
||||
tls_enable:depends({ type = "V2ray", v2ray_protocol = "vmess", v2ray_transport = "h2" })
|
||||
tls_enable.default = "0"
|
||||
tls_enable.rmempty = false
|
||||
|
||||
tls_certificateFile = s:option(Value, "tls_certificateFile", translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem")
|
||||
tls_certificateFile:depends("tls_enable", 1)
|
||||
tls_certificateFile:depends("type", "Trojan")
|
||||
|
||||
tls_keyFile = s:option(Value, "tls_keyFile", translate("Private key absolute path"), translate("as:") .. "/etc/ssl/private.key")
|
||||
tls_keyFile:depends("tls_enable", 1)
|
||||
tls_keyFile:depends("type", "Trojan")
|
||||
|
||||
local nodes_table = {}
|
||||
uci:foreach("passwall", "nodes", function(e)
|
||||
if e.type and e.type == "V2ray" and e.remarks and e.address and e.port then
|
||||
nodes_table[#nodes_table + 1] = {
|
||||
id = e[".name"],
|
||||
remarks = "%s:[%s] %s:%s" % {e.type, e.remarks, e.address, e.port}
|
||||
}
|
||||
end
|
||||
end)
|
||||
|
||||
transit_node = s:option(ListValue, "transit_node", translate("transit node"))
|
||||
transit_node:value("nil", translate("Close"))
|
||||
for k, v in pairs(nodes_table) do transit_node:value(v.id, v.remarks) end
|
||||
transit_node.default = "nil"
|
||||
transit_node:depends("type", "V2ray")
|
||||
|
||||
bind_local = s:option(Flag, "bind_local", translate("Bind Local"), translate("When selected, it can only be accessed locally,It is recommended to turn on when using reverse proxies."))
|
||||
bind_local.default = "0"
|
||||
bind_local:depends("type", "V2ray")
|
||||
|
||||
accept_lan = s:option(Flag, "accept_lan", translate("Accept LAN Access"), translate("When selected, it can accessed lan , this will not be safe!"))
|
||||
accept_lan.default = "0"
|
||||
accept_lan.rmempty = false
|
||||
accept_lan:depends("type", "V2ray")
|
||||
|
||||
return map
|
||||
@ -0,0 +1,21 @@
|
||||
local d = require "luci.dispatcher"
|
||||
local appname = "passwall"
|
||||
|
||||
m = Map(appname, "V2ray" .. translate("Shunt") .. translate("Rule"))
|
||||
m.redirect = d.build_url("admin", "vpn", appname)
|
||||
|
||||
s = m:section(NamedSection, arg[1], "shunt_rules", "")
|
||||
s.addremove = false
|
||||
s.dynamic = false
|
||||
|
||||
remarks = s:option(Value, "remarks", translate("Remarks"))
|
||||
remarks.default = arg[1]
|
||||
remarks.rmempty = false
|
||||
|
||||
domain_list = s:option(TextValue, "domain_list", translate("Domain"))
|
||||
domain_list.rows = 15
|
||||
|
||||
ip_list = s:option(TextValue, "ip_list", "IP")
|
||||
ip_list.rows = 15
|
||||
|
||||
return m
|
||||
File diff suppressed because one or more lines are too long
@ -13,7 +13,6 @@ end
|
||||
|
||||
local tcp_node_num = api.uci_get_type("global_other", "tcp_node_num", 1)
|
||||
local udp_node_num = api.uci_get_type("global_other", "udp_node_num", 1)
|
||||
local socks_node_num = api.uci_get_type("global_other", "socks_node_num", 1)
|
||||
|
||||
local status_show_check_port = api.uci_get_type("global_other", "status_show_check_port", 0)
|
||||
local status_show_ip111 = api.uci_get_type("global_other", "status_show_ip111", 0)
|
||||
@ -82,15 +81,6 @@ local status_show_ip111 = api.uci_get_type("global_other", "status_show_ip111",
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title">Socks
|
||||
<%:Status%>
|
||||
</label>
|
||||
<div class="cbi-value-field" id="_socks_node_status">
|
||||
<%:Collecting data...%>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% if ipkg.installed("kcptun") or is_finded("kcptun*") then %>
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title">Kcptun
|
||||
@ -127,7 +117,7 @@ local status_show_ip111 = api.uci_get_type("global_other", "status_show_ip111",
|
||||
<%:Baidu Connection%>
|
||||
</label>
|
||||
<div class="cbi-value-field">
|
||||
<input type="button" class="cbi-button cbi-input-apply" value="<%:Check%>" onclick="return check_connect(this,'baidu')" />
|
||||
<input type="button" class="cbi-button cbi-input-apply" value="<%:Check%>" onclick="return check_connect(this, 'baidu', 'www.baidu.com')" />
|
||||
<font id="_baidu_status"></font>
|
||||
</div>
|
||||
</div>
|
||||
@ -136,10 +126,19 @@ local status_show_ip111 = api.uci_get_type("global_other", "status_show_ip111",
|
||||
<%:Google Connection%>
|
||||
</label>
|
||||
<div class="cbi-value-field">
|
||||
<input type="button" class="cbi-button cbi-input-apply" value="<%:Check%>" onclick="return check_connect(this,'google')" />
|
||||
<input type="button" class="cbi-button cbi-input-apply" value="<%:Check%>" onclick="return check_connect(this, 'google', 'www.google.com/generate_204')" />
|
||||
<font id="_google_status"></font>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title">
|
||||
<%:GitHub Connection%>
|
||||
</label>
|
||||
<div class="cbi-value-field">
|
||||
<input type="button" class="cbi-button cbi-input-apply" value="<%:Check%>" onclick="return check_connect(this, 'github', 'https://github.com')" />
|
||||
<font id="_github_status"></font>
|
||||
</div>
|
||||
</div>
|
||||
<% if tonumber(status_show_check_port) == 1 then %>
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title">
|
||||
@ -172,7 +171,7 @@ local status_show_ip111 = api.uci_get_type("global_other", "status_show_ip111",
|
||||
var google_status = document.getElementById('_google_status');
|
||||
XHR.poll(3, '<%=dsp.build_url("admin/vpn/passwall/status")%>', null,
|
||||
function(x, json) {
|
||||
if(x && x.status == 200) {
|
||||
if (x && x.status == 200) {
|
||||
var tcp_node_status = document.getElementById('_tcp_node_status');
|
||||
if (tcp_node_status) {
|
||||
var tcp_node_num = <%=tcp_node_num%>;
|
||||
@ -236,73 +235,43 @@ local status_show_ip111 = api.uci_get_type("global_other", "status_show_ip111",
|
||||
udp_node_status.innerHTML = text;
|
||||
}
|
||||
}
|
||||
|
||||
var socks_node_status = document.getElementById('_socks_node_status');
|
||||
if (socks_node_status) {
|
||||
var socks_node_num = <%=socks_node_num%>;
|
||||
if (socks_node_num >= 1) {
|
||||
var text = '';
|
||||
if (socks_node_num == 1) {
|
||||
if (json["socks_node1_status"])
|
||||
text += '<font color="green"><%:RUNNING%> ✓</font>';
|
||||
else
|
||||
text += '<font color="red"><%:NOT RUNNING%> X</font>';
|
||||
} else {
|
||||
for(var i = 0; i < socks_node_num; i++) {
|
||||
var k = i + 1;
|
||||
if (json["socks_node" + k + "_status"])
|
||||
text += '<font color="green" size="3"> ✓</font>';
|
||||
else
|
||||
text += '<font color="red" size="3"> X</font>';
|
||||
}
|
||||
}
|
||||
socks_node_status.innerHTML = text;
|
||||
}
|
||||
}
|
||||
if(haproxy_status)
|
||||
if (haproxy_status)
|
||||
haproxy_status.innerHTML = json.haproxy_status ? '<font color="green"><%:RUNNING%> ✓</font>' : '<font color="red"><%:NOT RUNNING%> X</font>';
|
||||
if(dns_mode_status)
|
||||
if (dns_mode_status)
|
||||
dns_mode_status.innerHTML = json.dns_mode_status ? '<font color="green"><%:RUNNING%> ✓</font>' : '<font color="red"><%:NOT RUNNING%> X</font>';
|
||||
}
|
||||
});
|
||||
|
||||
function check_connect(btn, type) {
|
||||
function check_connect(btn, type, url) {
|
||||
btn.disabled = true;
|
||||
btn.value = '<%:Check...%>';
|
||||
var sendDate = (new Date()).getTime();
|
||||
XHR.get('<%=dsp.build_url("admin/vpn/passwall/connect_status")%>', {
|
||||
type: type
|
||||
type: type,
|
||||
url: url
|
||||
},
|
||||
function(x, rv) {
|
||||
var s = document.getElementById('_' + type + '_status');
|
||||
if(s) {
|
||||
if(rv.status) {
|
||||
if (s) {
|
||||
if (rv.ping_type && rv.ping_type == "curl") {
|
||||
var use_time = rv.use_time;
|
||||
var speed = "";
|
||||
var color="red";
|
||||
if (use_time < 1) {
|
||||
if (use_time < 1000) {
|
||||
color = "green";
|
||||
speed = "<%:Very Fast%>";
|
||||
} else if (use_time < 2) {
|
||||
color = "green";
|
||||
speed = "<%:Fast%>";
|
||||
} else if (use_time < 3) {
|
||||
} else if (use_time < 2000) {
|
||||
color = "#b9b90b";
|
||||
speed = "<%:General%>";
|
||||
} else if (use_time < 4) {
|
||||
} else {
|
||||
color = "red";
|
||||
speed = "<%:Slow%>";
|
||||
} else if (use_time >= 4) {
|
||||
color = "red";
|
||||
speed = "<%:Very Slow%>";
|
||||
}
|
||||
//s.setAttribute("color", color);
|
||||
btn.setAttribute("style","background-color: " + color + " !important; border-color: " + color + " !important;");
|
||||
btn.value = speed;
|
||||
}
|
||||
else {
|
||||
btn.setAttribute("style","color: " + color + " !important");
|
||||
btn.value = use_time + " ms";;
|
||||
} else if (rv.status) {
|
||||
btn.setAttribute("style","color: green !important");
|
||||
btn.value = "<%:Working...%>";
|
||||
} else {
|
||||
//s.setAttribute("color", "red");
|
||||
btn.setAttribute("style","background-color:red !important; border-color: red !important;");
|
||||
btn.setAttribute("style","color: red !important");
|
||||
btn.value = '<%:Problem detected!%> X';
|
||||
}
|
||||
}
|
||||
@ -319,7 +288,7 @@ local status_show_ip111 = api.uci_get_type("global_other", "status_show_ip111",
|
||||
XHR.get('<%=dsp.build_url("admin/vpn/passwall/check_port")%>', null,
|
||||
function(x, rv) {
|
||||
var s = document.getElementById('_node_status');
|
||||
if(s) {
|
||||
if (s) {
|
||||
s.innerHTML = rv.ret;
|
||||
var clear_btn = document.getElementById('clear_check_port_btn');
|
||||
clear_btn.style.display = "inline-block";
|
||||
|
||||
@ -62,16 +62,24 @@ local dsp = require "luci.dispatcher"
|
||||
document.getElementById("nodes_link").focus();
|
||||
}
|
||||
}
|
||||
|
||||
function clear_all_nodes() {
|
||||
if (confirm('<%:Are you sure to clear all nodes?%>') == true){
|
||||
XHR.get('<%=dsp.build_url("admin/vpn/passwall/clear_all_nodes")%>', null,
|
||||
function(x, data) {
|
||||
if(x && x.status == 200) {
|
||||
window.location.href = '<%=dsp.build_url("admin/vpn/passwall/node_list")%>';
|
||||
}
|
||||
else {
|
||||
alert("<%:Error%>");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title"><%:Add Node%></label>
|
||||
<div class="cbi-value-field">
|
||||
<input class="cbi-button cbi-button-add" type="button" onclick="open_add_link_div()" value="<%:Add the node via the link%>" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="add_link_div">
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title"><%:SS/SSR/V2ray/Trojan Link%></label>
|
||||
@ -87,3 +95,13 @@ local dsp = require "luci.dispatcher"
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title"><%:Operation%></label>
|
||||
<div class="cbi-value-field">
|
||||
<input class="cbi-button cbi-button-add" type="button" onclick="open_add_link_div()" value="<%:Add the node via the link%>" />
|
||||
<input class="cbi-button cbi-button-remove" type="button" onclick="clear_all_nodes()" value="<%:Clear all nodes%>" />
|
||||
<input class="cbi-button cbi-button-remove" type="button" onclick="delete_select_nodes()" value="<%:Delete select nodes%>" />
|
||||
<input class="cbi-button" type="button" onclick="select_all(this)" value="<%:Select all%>" />
|
||||
</div>
|
||||
</div>
|
||||
@ -5,7 +5,6 @@
|
||||
|
||||
local tcp_node_num = api.uci_get_type("global_other", "tcp_node_num", 1)
|
||||
local udp_node_num = api.uci_get_type("global_other", "udp_node_num", 1)
|
||||
local socks_node_num = api.uci_get_type("global_other", "socks_node_num", 1)
|
||||
local compact_display_nodes = api.uci_get_type("global_other", "compact_display_nodes", 1)
|
||||
-%>
|
||||
|
||||
@ -20,32 +19,39 @@ table td, .table .td {
|
||||
word-break: keep-all;
|
||||
}
|
||||
|
||||
#set_node_div{
|
||||
#set_node_div {
|
||||
display: none;
|
||||
width: 30rem;
|
||||
position: fixed;
|
||||
left:50%;
|
||||
top:50%;
|
||||
transform: translate(-50%, -50%);
|
||||
padding-top: 30px;
|
||||
z-index: 99;
|
||||
text-align: center;
|
||||
background: white;
|
||||
box-shadow: darkgrey 10px 10px 30px 5px;
|
||||
}
|
||||
|
||||
._select {
|
||||
background: #dad8d8;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
var ajax = {
|
||||
post: function(url, data, fn_success, fn_timeout) {
|
||||
post: function(url, data, fn_success, timeout, fn_timeout) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
var code = ajax.encode(data);
|
||||
xhr.open("POST", url, true);
|
||||
xhr.timeout = 1000;
|
||||
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
||||
xhr.ontimeout = function() {
|
||||
fn_timeout(xhr);
|
||||
|
||||
if (timeout && timeout > 1000) {
|
||||
xhr.timeout = timeout;
|
||||
}
|
||||
if (fn_timeout) {
|
||||
xhr.ontimeout = function() {
|
||||
fn_timeout(xhr);
|
||||
}
|
||||
}
|
||||
xhr.onreadystatechange = function() {
|
||||
if(xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 304)) {
|
||||
@ -96,30 +102,131 @@ table td, .table .td {
|
||||
document.getElementById("set_node_name").innerHTML = "";
|
||||
}
|
||||
|
||||
function _cbi_row_top(id) {
|
||||
var dom = document.getElementById("cbi-passwall-" + id);
|
||||
if (dom) {
|
||||
var trs = document.getElementById("cbi-passwall-nodes").getElementsByClassName("cbi-section-table-row");
|
||||
if (trs && trs.length > 0) {
|
||||
for (var i = 0; i < trs.length; i++) {
|
||||
var up = dom.getElementsByClassName("cbi-button-up");
|
||||
if (up) {
|
||||
cbi_row_swap(up[0], true, 'cbi.sts.passwall.nodes');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function select_node_div(btn, id) {
|
||||
btn.value = "<%:DeSelect%>";
|
||||
btn.setAttribute("onclick", "deselect_node_div(this, '" + id + "')");
|
||||
var dom = document.getElementById("cbi-passwall-" + id);
|
||||
if (dom) {
|
||||
dom.classList.add("_select");
|
||||
dom.setAttribute("nodes_id", id);
|
||||
}
|
||||
}
|
||||
|
||||
function deselect_node_div(btn, id) {
|
||||
btn.value = "<%:Select%>";
|
||||
btn.setAttribute("onclick", "select_node_div(this, '" + id + "')");
|
||||
var dom = document.getElementById("cbi-passwall-" + id);
|
||||
if (dom) {
|
||||
dom.classList.remove("_select");
|
||||
dom.removeAttribute("nodes_id");
|
||||
}
|
||||
}
|
||||
|
||||
function select_all(btn) {
|
||||
var doms = document.getElementById("cbi-passwall-nodes").getElementsByClassName("cbi-section-table-row");
|
||||
if (doms && doms.length > 0) {
|
||||
for (var i = 0 ; i < doms.length; i++) {
|
||||
var id = doms[i].id.replace("cbi-passwall-", "");
|
||||
var btn2 = document.getElementById("select_" + id);
|
||||
select_node_div(btn2, id);
|
||||
}
|
||||
btn.value = "<%:DeSelect all%>";
|
||||
btn.setAttribute("onclick", "deselect_all(this)");
|
||||
}
|
||||
}
|
||||
|
||||
function deselect_all(btn) {
|
||||
var doms = document.getElementById("cbi-passwall-nodes").getElementsByClassName("cbi-section-table-row");
|
||||
if (doms && doms.length > 0) {
|
||||
for (var i = 0 ; i < doms.length; i++) {
|
||||
var id = doms[i].id.replace("cbi-passwall-", "");
|
||||
var btn2 = document.getElementById("select_" + id);
|
||||
deselect_node_div(btn2, id);
|
||||
}
|
||||
btn.value = "<%:Select all%>";
|
||||
btn.setAttribute("onclick", "select_all(this)");
|
||||
}
|
||||
}
|
||||
|
||||
function delete_select_nodes() {
|
||||
var doms = document.getElementsByClassName("_select");
|
||||
if (doms && doms.length > 0) {
|
||||
var ids = [];
|
||||
for (var i = 0 ; i < doms.length; i++) {
|
||||
if (doms[i].getAttribute("nodes_id")) {
|
||||
ids.push(doms[i].getAttribute("nodes_id"))
|
||||
}
|
||||
}
|
||||
if (confirm('<%:Are you sure to delete select nodes?%>') == true){
|
||||
XHR.get('<%=dsp.build_url("admin/vpn/passwall/delete_select_nodes")%>', {
|
||||
ids: ids.join()
|
||||
},
|
||||
function(x, data) {
|
||||
if(x && x.status == 200) {
|
||||
window.location.href = '<%=dsp.build_url("admin/vpn/passwall/node_list")%>';
|
||||
}
|
||||
else {
|
||||
alert("<%:Error%>");
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
alert("<%:You no select nodes !%>");
|
||||
}
|
||||
}
|
||||
|
||||
function set_node(protocol,number) {
|
||||
if (confirm('<%:Are you sure set to%> ' + protocol.toUpperCase() + "_" + number + '<%:the server?%>')==true){
|
||||
window.location.href = '<%=dsp.build_url("admin/vpn/passwall/set_node")%>?protocol=' + protocol + '&number=' + number + '§ion=' + section;
|
||||
}
|
||||
}
|
||||
|
||||
function ping_node(cbi_id,dom) {
|
||||
function get_address_full(id) {
|
||||
<% if compact_display_nodes and tonumber(compact_display_nodes) == 1 then %>
|
||||
var remarks = document.getElementById("cbid.passwall." + cbi_id + ".remarks").value;
|
||||
var address = null;
|
||||
var port = null;
|
||||
if (remarks.lastIndexOf("(") != -1 && remarks.lastIndexOf(")") != -1) {
|
||||
var address_full = remarks.substring(remarks.lastIndexOf("(") + 1, remarks.lastIndexOf(")"));
|
||||
address = address_full.substring(0, address_full.lastIndexOf(":"));
|
||||
port = address_full.substring(address_full.lastIndexOf(":") + 1);
|
||||
var remarks = document.getElementById("cbid.passwall." + id + ".remarks").value;
|
||||
var result = remarks.match("\\((.+?)\\)");
|
||||
if (result != null) {
|
||||
var full = result[1];
|
||||
var address = full.substring(0, full.lastIndexOf(":"));
|
||||
var port = full.substring(full.lastIndexOf(":") + 1);
|
||||
}
|
||||
<% else %>
|
||||
var address = document.getElementById("cbid.passwall." + cbi_id + ".address").value;
|
||||
var port = document.getElementById("cbid.passwall." + cbi_id + ".port").value;
|
||||
try {
|
||||
var address = document.getElementById("cbid.passwall." + id + ".address").value;
|
||||
var port = document.getElementById("cbid.passwall." + id + ".port").value;
|
||||
}
|
||||
catch(err){}
|
||||
<% end %>
|
||||
if ((address != null && address != "") && (port != null && port != "")) {
|
||||
//判断是否含有汉字
|
||||
var reg = new RegExp("[\\u4E00-\\u9FFF]+","g");
|
||||
if ((address != null && address != "") && (port != null && port != "") && reg.test(address) == false && (address.indexOf(".") != -1 && address.charAt(address.address - 1) != ".")) {
|
||||
return { address: address, port: port };
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function ping_node(cbi_id, dom) {
|
||||
var full = get_address_full(cbi_id);
|
||||
if (full != null) {
|
||||
XHR.get('<%=dsp.build_url("admin/vpn/passwall/ping_node")%>', {
|
||||
address: address,
|
||||
port: port
|
||||
address: full.address,
|
||||
port: full.port
|
||||
},
|
||||
function(x, result) {
|
||||
if(x && x.status == 200) {
|
||||
@ -141,102 +248,143 @@ table td, .table .td {
|
||||
}
|
||||
|
||||
/* 自动Ping */
|
||||
var nodes = [];
|
||||
const auto_ping_value = document.getElementsByClassName('auto_ping_value');
|
||||
var index = 0;
|
||||
function auto_ping() {
|
||||
if (index >= auto_ping_value.length) {
|
||||
return;
|
||||
}
|
||||
var has_ping = auto_ping_value[index].getAttribute("has_ping");
|
||||
if (has_ping == null) {
|
||||
var cbi_id = auto_ping_value[index].getAttribute("cbiid");
|
||||
<% if compact_display_nodes and tonumber(compact_display_nodes) == 1 then %>
|
||||
var remarks = document.getElementById("cbid.passwall." + cbi_id + ".remarks").value;
|
||||
var address = null;
|
||||
var port = null;
|
||||
if (remarks.lastIndexOf("(") != -1 && remarks.lastIndexOf(")") != -1) {
|
||||
var address_full = remarks.substring(remarks.lastIndexOf("(") + 1, remarks.lastIndexOf(")"));
|
||||
address = address_full.substring(0, address_full.lastIndexOf(":"));
|
||||
port = address_full.substring(address_full.lastIndexOf(":") + 1);
|
||||
for (var i = 0; i < auto_ping_value.length; i++) {
|
||||
var cbi_id = auto_ping_value[i].getAttribute("cbiid");
|
||||
var full = get_address_full(cbi_id);
|
||||
if (full != null) {
|
||||
var flag = false;
|
||||
//当有多个相同地址和端口时合在一起
|
||||
for (var j = 0; j < nodes.length; j++) {
|
||||
if (nodes[j].address == full.address && nodes[j].port == full.port) {
|
||||
nodes[j].indexs = nodes[j].indexs + "," + i;
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
<% else %>
|
||||
var address = document.getElementById("cbid.passwall." + cbi_id + ".address").value;
|
||||
var port = document.getElementById("cbid.passwall." + cbi_id + ".port").value;
|
||||
<% end %>
|
||||
//判断是否含有汉字
|
||||
var reg = new RegExp("[\\u4E00-\\u9FFF]+","g");
|
||||
if ((address != null && address != "") && (port != null && port != "") && reg.test(address) == false && (address.indexOf(".") != -1 && address.charAt(address.address - 1) != ".")) {
|
||||
ajax.post('<%=dsp.build_url("admin/vpn/passwall/ping_node")%>', {
|
||||
index: index,
|
||||
address: address,
|
||||
port: port
|
||||
},
|
||||
function(x, result) {
|
||||
if(x && x.status == 200) {
|
||||
for(var i = 0; i < auto_ping_value.length; i++) {
|
||||
var obj = auto_ping_value[i];
|
||||
var obj_cbi_id = obj.getAttribute("cbiid");
|
||||
<% if compact_display_nodes and tonumber(compact_display_nodes) == 1 then %>
|
||||
var obj_remarks = document.getElementById("cbid.passwall." + obj_cbi_id + ".remarks").value;
|
||||
var obj_address = null;
|
||||
var obj_port = null;
|
||||
if (obj_remarks.lastIndexOf("(") != -1 && obj_remarks.lastIndexOf(")") != -1) {
|
||||
var obj_address_full = obj_remarks.substring(obj_remarks.lastIndexOf("(") + 1, obj_remarks.lastIndexOf(")"));
|
||||
obj_address = obj_address_full.substring(0, obj_address_full.lastIndexOf(":"));
|
||||
obj_port = obj_address_full.substring(obj_address_full.lastIndexOf(":") + 1);
|
||||
}
|
||||
<% else %>
|
||||
var obj_address = document.getElementById("cbid.passwall." + obj_cbi_id + ".address").value;
|
||||
var obj_port = document.getElementById("cbid.passwall." + obj_cbi_id + ".port").value;
|
||||
<% end %>
|
||||
|
||||
if (address == obj_address && port == obj_port) {
|
||||
auto_ping_value[i].setAttribute("has_ping", "1");
|
||||
if (result.ping == null || result.ping.trim() == "") {
|
||||
auto_ping_value[i].innerHTML = "<font style='color:red'><%:Timeout%></font>";
|
||||
} else {
|
||||
var ping = parseInt(result.ping);
|
||||
if (ping < 100)
|
||||
auto_ping_value[i].innerHTML = "<font style='color:green'>" + result.ping + " ms" + "</font>";
|
||||
else if (ping < 200)
|
||||
auto_ping_value[i].innerHTML = "<font style='color:#fb9a05'>" + result.ping + " ms" + "</font>";
|
||||
else if (ping >= 200)
|
||||
auto_ping_value[i].innerHTML = "<font style='color:red'>" + result.ping + " ms" + "</font>";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
index++;
|
||||
auto_ping();
|
||||
},
|
||||
function(x) {
|
||||
auto_ping_value[index].innerHTML = "<font style='color:red'><%:Timeout%></font>";
|
||||
index++;
|
||||
auto_ping();
|
||||
},
|
||||
);
|
||||
} else {
|
||||
index++;
|
||||
auto_ping();
|
||||
}
|
||||
}
|
||||
else {
|
||||
index++;
|
||||
auto_ping();
|
||||
if (flag)
|
||||
continue;
|
||||
nodes.push({
|
||||
indexs: i + "",
|
||||
address: full.address,
|
||||
port: full.port
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
auto_ping();
|
||||
const _xhr = (index) => {
|
||||
return new Promise((res) => {
|
||||
const dom = nodes[index];
|
||||
if (!dom) res()
|
||||
ajax.post('<%=dsp.build_url("admin/vpn/passwall/ping_node")%>', {
|
||||
index: dom.indexs,
|
||||
address: dom.address,
|
||||
port: dom.port
|
||||
},
|
||||
function(x, result) {
|
||||
if (x && x.status == 200) {
|
||||
var strs = dom.indexs.split(",");
|
||||
for (var i = 0; i < strs.length; i++) {
|
||||
if (result.ping == null || result.ping.trim() == "") {
|
||||
auto_ping_value[strs[i]].innerHTML = "<font style='color:red'><%:Timeout%></font>";
|
||||
} else {
|
||||
var ping = parseInt(result.ping);
|
||||
if (ping < 100)
|
||||
auto_ping_value[strs[i]].innerHTML = "<font style='color:green'>" + result.ping + " ms" + "</font>";
|
||||
else if (ping < 200)
|
||||
auto_ping_value[strs[i]].innerHTML = "<font style='color:#fb9a05'>" + result.ping + " ms" + "</font>";
|
||||
else if (ping >= 200)
|
||||
auto_ping_value[strs[i]].innerHTML = "<font style='color:red'>" + result.ping + " ms" + "</font>";
|
||||
}
|
||||
}
|
||||
}
|
||||
res();
|
||||
},
|
||||
5000,
|
||||
function(x) {
|
||||
var strs = dom.indexs.split(",");
|
||||
for (var i = 0; i < strs.length; i++) {
|
||||
auto_ping_value[strs[i]].innerHTML = "<font style='color:red'><%:Timeout%></font>";
|
||||
}
|
||||
res();
|
||||
}
|
||||
);
|
||||
})
|
||||
}
|
||||
|
||||
//添加"应用"按钮到"修改"按钮前
|
||||
var edit_btn = document.getElementsByClassName("cbi-button cbi-button-edit");
|
||||
let task = -1;
|
||||
const thread = () => {
|
||||
task = task + 1
|
||||
if (nodes[task]) {
|
||||
_xhr(task).then(thread);
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < 20; i++) {
|
||||
thread()
|
||||
}
|
||||
|
||||
/* 递归单请求方法
|
||||
var index = 0;
|
||||
function auto_ping() {
|
||||
if (index >= nodes.length) {
|
||||
return;
|
||||
}
|
||||
var indexs = nodes[index].indexs;
|
||||
var address = nodes[index].address;
|
||||
var port = nodes[index].port;
|
||||
ajax.post('<%=dsp.build_url("admin/vpn/passwall/ping_node")%>', {
|
||||
index: indexs,
|
||||
address: address,
|
||||
port: port
|
||||
},
|
||||
function(x, result) {
|
||||
if (x && x.status == 200) {
|
||||
var strs = indexs.split(",");
|
||||
for (var i = 0; i < strs.length; i++) {
|
||||
if (result.ping == null || result.ping.trim() == "") {
|
||||
auto_ping_value[strs[i]].innerHTML = "<font style='color:red'><%:Timeout%></font>";
|
||||
} else {
|
||||
var ping = parseInt(result.ping);
|
||||
if (ping < 100)
|
||||
auto_ping_value[strs[i]].innerHTML = "<font style='color:green'>" + result.ping + " ms" + "</font>";
|
||||
else if (ping < 200)
|
||||
auto_ping_value[strs[i]].innerHTML = "<font style='color:#fb9a05'>" + result.ping + " ms" + "</font>";
|
||||
else if (ping >= 200)
|
||||
auto_ping_value[strs[i]].innerHTML = "<font style='color:red'>" + result.ping + " ms" + "</font>";
|
||||
}
|
||||
}
|
||||
}
|
||||
index++;
|
||||
return auto_ping();
|
||||
},
|
||||
function(x) {
|
||||
var strs = indexs.split(",");
|
||||
for (var i = 0; i < strs.length; i++) {
|
||||
auto_ping_value[strs[i]].innerHTML = "<font style='color:red'><%:Timeout%></font>";
|
||||
}
|
||||
index++;
|
||||
return auto_ping();
|
||||
},
|
||||
);
|
||||
}
|
||||
auto_ping();
|
||||
*/
|
||||
|
||||
var edit_btn = document.getElementById("cbi-passwall-nodes").getElementsByClassName("cbi-button cbi-button-edit");
|
||||
for(var i = 0; i < edit_btn.length; i++) {
|
||||
try {
|
||||
var onclick_str = edit_btn[i].getAttribute("onclick");
|
||||
var id = onclick_str.substring(onclick_str.lastIndexOf('/') + 1, onclick_str.length - 1);
|
||||
var td = edit_btn[i].parentNode;
|
||||
var apply = '<input class="cbi-button cbi-button-add" type="button" value="<%:Use%>" onclick="open_set_node_div(\'' + id + '\')" alt="<%:Use%>" title="<%:Use%>" />';
|
||||
td.innerHTML = apply + " " + td.innerHTML;
|
||||
var new_div = "";
|
||||
//添加"置顶"按钮到"修改"按钮前
|
||||
new_div += '<input class="cbi-button" type="button" value="<%:To Top%>" onclick="_cbi_row_top(\'' + id + '\')"/> ';
|
||||
//添加"选择"按钮到"修改"按钮前
|
||||
new_div += '<input class="cbi-button cbi-button-add" type="button" value="<%:Select%>" id="select_' + id + '" onclick="select_node_div(this, \'' + id + '\')"/> ';
|
||||
//添加"应用"按钮到"修改"按钮前
|
||||
new_div += '<input class="cbi-button cbi-button-apply" type="button" value="<%:Use%>" id="apply_' + id + '" onclick="open_set_node_div(\'' + id + '\')"/> ';
|
||||
td.innerHTML = new_div + td.innerHTML;
|
||||
}
|
||||
catch(err) {
|
||||
console.error(err);
|
||||
@ -246,26 +394,22 @@ table td, .table .td {
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
<div id="set_node_div">
|
||||
<div class="cbi-value"><%:You choose node is:%><span id="set_node_name"></span></div>
|
||||
<div class="cbi-value">
|
||||
<% if tcp_node_num and tonumber(tcp_node_num) >= 1 then %>
|
||||
<% for i = 1, tcp_node_num, 1 do %>
|
||||
<input class="cbi-button cbi-button-edit" type="button" onclick="set_node('tcp',<%=i%>)" value="TCP_<%=i%>" />
|
||||
<div style="display: -webkit-flex; display: flex; -webkit-align-items: center; align-items: center; -webkit-justify-content: center; justify-content: center;">
|
||||
<div id="set_node_div">
|
||||
<div class="cbi-value"><%:You choose node is:%><span id="set_node_name"></span></div>
|
||||
<div class="cbi-value">
|
||||
<% if tcp_node_num and tonumber(tcp_node_num) >= 1 then %>
|
||||
<% for i = 1, tcp_node_num, 1 do %>
|
||||
<input class="cbi-button cbi-button-edit" type="button" onclick="set_node('tcp',<%=i%>)" value="TCP_<%=i%>" />
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% if udp_node_num and tonumber(udp_node_num) >= 1 then %>
|
||||
<% for i = 1, udp_node_num, 1 do %>
|
||||
<input class="cbi-button cbi-button-edit" type="button" onclick="set_node('udp',<%=i%>)" value="UDP_<%=i%>" />
|
||||
|
||||
<% if udp_node_num and tonumber(udp_node_num) >= 1 then %>
|
||||
<% for i = 1, udp_node_num, 1 do %>
|
||||
<input class="cbi-button cbi-button-edit" type="button" onclick="set_node('udp',<%=i%>)" value="UDP_<%=i%>" />
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% if socks_node_num and tonumber(socks_node_num) >= 1 then %>
|
||||
<% for i = 1, socks_node_num, 1 do %>
|
||||
<input class="cbi-button cbi-button-edit" type="button" onclick="set_node('socks',<%=i%>)" value="Socks_<%=i%>" />
|
||||
<% end %>
|
||||
<% end %>
|
||||
<input class="cbi-button cbi-button-remove" type="button" onclick="close_set_node_div()" value="<%:Close%>" />
|
||||
<input class="cbi-button cbi-button-remove" type="button" onclick="close_set_node_div()" value="<%:Close%>" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -0,0 +1,22 @@
|
||||
<%
|
||||
local dsp = require "luci.dispatcher"
|
||||
-%>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
var _status = document.getElementsByClassName('_status');
|
||||
for (var i = 0; i < _status.length; i++) {
|
||||
var id = _status[i].getAttribute("socks_id");
|
||||
XHR.get('<%=dsp.build_url("admin/vpn/passwall/socks_status")%>', {
|
||||
index: i,
|
||||
id: id
|
||||
},
|
||||
function(x, result) {
|
||||
_status[result.index].setAttribute("style","font-weight:bold;");
|
||||
_status[result.index].setAttribute("color",result.status ? "green":"red");
|
||||
_status[result.index].innerHTML = (result.status ? '✓' : 'X');
|
||||
}
|
||||
);
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
@ -0,0 +1,3 @@
|
||||
<%+cbi/valueheader%>
|
||||
<font class="_status" socks_id="<%=section%>"></font>
|
||||
<%+cbi/valuefooter%>
|
||||
@ -2,8 +2,7 @@
|
||||
local api = require "luci.model.cbi.passwall.api.api"
|
||||
local dsp = require "luci.dispatcher"
|
||||
|
||||
local brook_path = api.uci_get_type("global_app", "brook_file")
|
||||
local brook_version = luci.sys.exec("[ -f '" .. brook_path .. "' ] && " .. brook_path .. " -v | awk '{print $3}'")
|
||||
local brook_version = api.get_brook_version()
|
||||
-%>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
@ -2,8 +2,7 @@
|
||||
local api = require "luci.model.cbi.passwall.api.api"
|
||||
local dsp = require "luci.dispatcher"
|
||||
|
||||
local kcptun_path = api.uci_get_type("global_app", "kcptun_client_file")
|
||||
local kcptun_version = luci.sys.exec("[ -f '" .. kcptun_path .. "' ] && " .. kcptun_path .. " -v | awk '{print $3}'")
|
||||
local kcptun_version = api.get_kcptun_version()
|
||||
-%>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
@ -1,156 +0,0 @@
|
||||
<%
|
||||
local api = require "luci.model.cbi.passwall.api.api"
|
||||
local dsp = require "luci.dispatcher"
|
||||
|
||||
function get_luci_version()
|
||||
local ipkg = require "luci.model.ipkg"
|
||||
local package_name = "luci-app-passwall"
|
||||
local package_info = ipkg.info(package_name) or {}
|
||||
if next(package_info) ~= nil then
|
||||
return package_info[package_name]["Version"]
|
||||
end
|
||||
return ""
|
||||
end
|
||||
|
||||
local passwall_version = get_luci_version()
|
||||
-%>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
var passwallInfo;
|
||||
var tokenStr = '<%=token%>';
|
||||
var noUpdateText = '<%:It is the latest version%>';
|
||||
var updateSuccessText = '<%:Update successful%>';
|
||||
var clickToUpdateText = '<%:Click to update%>';
|
||||
var inProgressText = '<%:Updating...%>';
|
||||
var unexpectedErrorText = '<%:Unexpected error%>';
|
||||
var updateInProgressNotice = '<%:Updating, are you sure to close?%>';
|
||||
var downloadingText = '<%:Downloading...%>';
|
||||
var decompressioningText = '<%:Unpacking...%>';
|
||||
var movingText = '<%:Moving...%>';
|
||||
|
||||
window.onload = function() {
|
||||
var passwallCheckBtn = document.getElementById('_passwall-check_btn');
|
||||
var passwallDetailElm = document.getElementById('_passwall-check_btn-detail');
|
||||
};
|
||||
|
||||
function addPageNotice_luci() {
|
||||
window.onbeforeunload = function(e) {
|
||||
e.returnValue = updateInProgressNotice;
|
||||
return updateInProgressNotice;
|
||||
};
|
||||
}
|
||||
|
||||
function removePageNotice_luci() {
|
||||
window.onbeforeunload = undefined;
|
||||
}
|
||||
|
||||
function onUpdateSuccess_luci(btn) {
|
||||
alert(updateSuccessText);
|
||||
|
||||
if(btn) {
|
||||
btn.value = updateSuccessText;
|
||||
btn.placeholder = updateSuccessText;
|
||||
btn.disabled = true;
|
||||
}
|
||||
|
||||
window.setTimeout(function() {
|
||||
window.location.reload();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function onRequestError_luci(btn, errorMessage) {
|
||||
btn.disabled = false;
|
||||
btn.value = btn.placeholder;
|
||||
|
||||
if(errorMessage) {
|
||||
alert(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
function onBtnClick_luci(btn) {
|
||||
if(passwallInfo === undefined) {
|
||||
checkUpdate_luci(btn);
|
||||
} else {
|
||||
doUpdate_luci(btn);
|
||||
}
|
||||
}
|
||||
|
||||
function checkUpdate_luci(btn) {
|
||||
btn.disabled = true;
|
||||
btn.value = inProgressText;
|
||||
|
||||
addPageNotice_luci();
|
||||
|
||||
var ckeckDetailElm = document.getElementById(btn.id + '-detail');
|
||||
|
||||
XHR.get('<%=dsp.build_url("admin/vpn/passwall/luci_check")%>', {
|
||||
token: tokenStr,
|
||||
arch: ''
|
||||
}, function(x,json) {
|
||||
removePageNotice_luci();
|
||||
|
||||
if(json.code) {
|
||||
passwallInfo = undefined;
|
||||
onRequestError_luci(btn, json.error);
|
||||
} else {
|
||||
if(json.update) {
|
||||
passwallInfo = json;
|
||||
btn.disabled = false;
|
||||
btn.value = clickToUpdateText;
|
||||
btn.placeholder = clickToUpdateText;
|
||||
|
||||
if(ckeckDetailElm) {
|
||||
var urlNode = '';
|
||||
if(json.version) {
|
||||
urlNode = '<em style="color:red;">最新版本号:' + json.version + '</em>';
|
||||
if(json.url && json.url.html) {
|
||||
urlNode = '<a href="' + json.url.html + '" target="_blank">' + urlNode + '</a>';
|
||||
}
|
||||
}
|
||||
ckeckDetailElm.innerHTML = urlNode;
|
||||
}
|
||||
} else {
|
||||
btn.disabled = true;
|
||||
btn.value = noUpdateText;
|
||||
}
|
||||
}
|
||||
},300);
|
||||
}
|
||||
|
||||
function doUpdate_luci(btn) {
|
||||
btn.disabled = true;
|
||||
btn.value = downloadingText;
|
||||
|
||||
addPageNotice_luci();
|
||||
|
||||
var updateUrl = '<%=dsp.build_url("admin/vpn/passwall/luci_update")%>';
|
||||
// Download file
|
||||
XHR.get(updateUrl, {
|
||||
token: tokenStr,
|
||||
url: passwallInfo ? passwallInfo.url.download : '',
|
||||
save: true
|
||||
}, function(x,json) {
|
||||
removePageNotice_luci();
|
||||
if(json.code) {
|
||||
onRequestError_luci(btn, json.error);
|
||||
} else {
|
||||
onUpdateSuccess_luci(btn);
|
||||
}
|
||||
},300)
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title">PassWall
|
||||
<%:Version%>
|
||||
</label>
|
||||
<div class="cbi-value-field">
|
||||
<div class="cbi-value-description">
|
||||
<span>【 <%=passwall_version%>】</span>
|
||||
<input class="cbi-button cbi-input-apply" type="button" id="_passwall-check_btn" onclick="onBtnClick_luci(this);" value="<%:Manually update%>" />
|
||||
<span id="_passwall-check_btn-detail"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -2,8 +2,7 @@
|
||||
local api = require "luci.model.cbi.passwall.api.api"
|
||||
local dsp = require "luci.dispatcher"
|
||||
|
||||
local V2ray_path = api.uci_get_type("global_app", "v2ray_file")
|
||||
local V2ray_version = luci.sys.exec("[ -f '" .. V2ray_path .. "/v2ray' ] && " .. V2ray_path .. "/v2ray -version | awk '{print $2}' | sed -n 1P")
|
||||
local v2ray_version = api.get_v2ray_version()
|
||||
-%>
|
||||
|
||||
<script type="text/javascript">
|
||||
@ -167,7 +166,7 @@ local V2ray_version = luci.sys.exec("[ -f '" .. V2ray_path .. "/v2ray' ] && " ..
|
||||
</label>
|
||||
<div class="cbi-value-field">
|
||||
<div class="cbi-value-description">
|
||||
<span>【 <%=V2ray_version%>】</span>
|
||||
<span>【 <%=v2ray_version%>】</span>
|
||||
<input class="cbi-button cbi-input-apply" type="button" id="_v2ray-check_btn" onclick="onBtnClick_v2ray(this);" value="<%:Manually update%>" />
|
||||
<span id="_v2ray-check_btn-detail"></span>
|
||||
</div>
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
function clear_log(btn) {
|
||||
XHR.get('<%=url([[admin]], [[vpn]], [[passwall]], [[server_clear_log]])%>', null,
|
||||
function(x, data) {
|
||||
if(x && x.status == 200) {
|
||||
var log_textarea = document.getElementById('log_textarea');
|
||||
log_textarea.innerHTML = "";
|
||||
log_textarea.scrollTop = log_textarea.scrollHeight;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
XHR.poll(3, '<%=url([[admin]], [[vpn]], [[passwall]], [[server_get_log]])%>', null,
|
||||
function(x, data) {
|
||||
if(x && x.status == 200) {
|
||||
var log_textarea = document.getElementById('log_textarea');
|
||||
log_textarea.innerHTML = x.responseText;
|
||||
log_textarea.scrollTop = log_textarea.scrollHeight;
|
||||
}
|
||||
}
|
||||
);
|
||||
//]]>
|
||||
</script>
|
||||
<fieldset class="cbi-section" id="_log_fieldset">
|
||||
<legend>
|
||||
<%:Logs%>
|
||||
</legend>
|
||||
<input class="cbi-button cbi-input-remove" type="button" onclick="clear_log()" value="<%:Clear logs%>">
|
||||
<textarea id="log_textarea" class="cbi-input-textarea" style="width: 100%;margin-top: 10px;" data-update="change" rows="20" wrap="off" readonly="readonly"></textarea>
|
||||
</fieldset>
|
||||
@ -0,0 +1,23 @@
|
||||
<%
|
||||
local dsp = require "luci.dispatcher"
|
||||
-%>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
var _users_status = document.getElementsByClassName('_users_status');
|
||||
for(var i = 0; i < _users_status.length; i++) {
|
||||
var id = _users_status[i].parentElement.parentElement.parentElement.id;
|
||||
id = id.substr(id.lastIndexOf("-") + 1);
|
||||
XHR.poll(1,'<%=url([[admin]], [[vpn]], [[passwall]], [[server_user_status]])%>', {
|
||||
index: i,
|
||||
id: id
|
||||
},
|
||||
function(x, result) {
|
||||
_users_status[result.index].setAttribute("style","font-weight:bold;");
|
||||
_users_status[result.index].setAttribute("color",result.status ? "green":"red");
|
||||
_users_status[result.index].innerHTML = (result.status ? '✓' : 'X');
|
||||
}
|
||||
);
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
@ -0,0 +1,3 @@
|
||||
<%+cbi/valueheader%>
|
||||
<font class="_users_status" hint="<%=self:cfgvalue(section)%>">--</font>
|
||||
<%+cbi/valuefooter%>
|
||||
@ -94,6 +94,9 @@ msgstr "百度连接"
|
||||
msgid "Google Connection"
|
||||
msgstr "谷歌连接"
|
||||
|
||||
msgid "GitHub Connection"
|
||||
msgstr "GitHub连接"
|
||||
|
||||
msgid "Node Check"
|
||||
msgstr "节点检测"
|
||||
|
||||
@ -103,9 +106,6 @@ msgstr "检测中..."
|
||||
msgid "Clear"
|
||||
msgstr "清除"
|
||||
|
||||
msgid "If you can use it, very stable. If not, GG !!!"
|
||||
msgstr "如果你会用,稳得一批。否则,GG!!!"
|
||||
|
||||
msgid "Main switch"
|
||||
msgstr "总开关"
|
||||
|
||||
@ -115,12 +115,21 @@ msgstr "TCP节点"
|
||||
msgid "UDP Node"
|
||||
msgstr "UDP节点"
|
||||
|
||||
msgid "Socks Config"
|
||||
msgstr "Socks配置"
|
||||
|
||||
msgid "Socks Node"
|
||||
msgstr "Socks节点"
|
||||
|
||||
msgid "Same as the tcp node"
|
||||
msgstr "与TCP节点相同"
|
||||
|
||||
msgid "Same as the tcp %s node"
|
||||
msgstr "与TCP%s节点相同"
|
||||
|
||||
msgid "New process"
|
||||
msgstr "另开进程"
|
||||
|
||||
msgid "For used to surf the Internet."
|
||||
msgstr "用于科学上网。"
|
||||
|
||||
@ -148,12 +157,24 @@ msgstr "如果有问题,请尝试其他模式。<br />如果您没有使用任
|
||||
msgid "Use TCP Node Resolve DNS"
|
||||
msgstr "使用TCP节点解析DNS"
|
||||
|
||||
msgid "Use UDP Node Resolve DNS"
|
||||
msgstr "使用UDP节点解析DNS"
|
||||
|
||||
msgid "If checked, DNS is resolved using the TCP node."
|
||||
msgstr "如果勾选,则使用TCP节点解析DNS解决污染。"
|
||||
|
||||
msgid "Socks Server"
|
||||
msgstr "Socks服务器"
|
||||
|
||||
msgid "Fair Mode"
|
||||
msgstr "公平模式"
|
||||
|
||||
msgid "DNS Address"
|
||||
msgstr "DNS地址"
|
||||
|
||||
msgid "DNS Cache"
|
||||
msgstr "DNS缓存"
|
||||
|
||||
msgid "China DNS Server"
|
||||
msgstr "国内DNS服务器"
|
||||
|
||||
@ -256,6 +277,9 @@ msgstr "路由器自身"
|
||||
msgid "Danger"
|
||||
msgstr "危险"
|
||||
|
||||
msgid "Operation"
|
||||
msgstr "操作"
|
||||
|
||||
msgid "Add Node"
|
||||
msgstr "添加节点"
|
||||
|
||||
@ -268,6 +292,39 @@ msgstr "SS/SSR/V2ray/Trojan链接"
|
||||
msgid "Please enter the correct link, ss:// ssr:// vmess:// trojan://"
|
||||
msgstr "请输入正确的链接,ss:// ssr:// vmess:// trojan://"
|
||||
|
||||
msgid "Clear all nodes"
|
||||
msgstr "清空所有节点"
|
||||
|
||||
msgid "Are you sure to clear all nodes?"
|
||||
msgstr "你确定要清空所有节点吗?"
|
||||
|
||||
msgid "Error"
|
||||
msgstr "错误"
|
||||
|
||||
msgid "Delete select nodes"
|
||||
msgstr "删除选择的节点"
|
||||
|
||||
msgid "To Top"
|
||||
msgstr "置顶"
|
||||
|
||||
msgid "Select"
|
||||
msgstr "选择"
|
||||
|
||||
msgid "DeSelect"
|
||||
msgstr "反选"
|
||||
|
||||
msgid "Select all"
|
||||
msgstr "全选"
|
||||
|
||||
msgid "DeSelect all"
|
||||
msgstr "全不选"
|
||||
|
||||
msgid "Are you sure to delete select nodes?"
|
||||
msgstr "你确定要删除选择的节点吗?"
|
||||
|
||||
msgid "You no select nodes !"
|
||||
msgstr "你没有选择任何节点!"
|
||||
|
||||
msgid "Are you sure set to"
|
||||
msgstr "你确定要设为"
|
||||
|
||||
@ -289,14 +346,14 @@ msgstr "添加方式"
|
||||
msgid "Type"
|
||||
msgstr "类型"
|
||||
|
||||
msgid "V2ray Balancing"
|
||||
msgstr "V2ray 负载均衡"
|
||||
msgid "Balancing"
|
||||
msgstr "负载均衡"
|
||||
|
||||
msgid "V2ray_balancing"
|
||||
msgstr "V2ray 负载均衡"
|
||||
|
||||
msgid "V2ray Shunt"
|
||||
msgstr "V2ray 分流"
|
||||
msgid "Shunt"
|
||||
msgstr "分流"
|
||||
|
||||
msgid "V2ray_shunt"
|
||||
msgstr "V2ray 分流"
|
||||
@ -358,9 +415,6 @@ msgstr "选中后保存应用后即使用tcping替换ping检测节点"
|
||||
msgid "Concise display nodes"
|
||||
msgstr "简洁显示节点"
|
||||
|
||||
msgid "Support for more than 10,000 ping nodes and luci does not crash and not slow."
|
||||
msgstr "支持超过10000个节点,而LuCI却不会卡死,更不会崩溃。"
|
||||
|
||||
msgid "Apply"
|
||||
msgstr "应用"
|
||||
|
||||
@ -526,6 +580,15 @@ msgstr "备用"
|
||||
msgid "Manually update"
|
||||
msgstr "手动更新"
|
||||
|
||||
msgid "Enable custom url"
|
||||
msgstr "启用自定义规则地址"
|
||||
|
||||
msgid "gfwlist Update url"
|
||||
msgstr "GFWList更新URL"
|
||||
|
||||
msgid "Chnroute Update url"
|
||||
msgstr "国内IP段(Chnroute)更新URL"
|
||||
|
||||
msgid "Rule status"
|
||||
msgstr "规则版本"
|
||||
|
||||
@ -646,6 +709,9 @@ msgstr "关键字丢弃"
|
||||
msgid "When checked, the keywords in the list are discarded. Otherwise, it is not discarded."
|
||||
msgstr "当勾选时,将丢弃包含列表里的关键字的节点。否则,将保留列表的关键字的节点(反过来)。"
|
||||
|
||||
msgid "Whether unsafe connections are allowed. When checked, V2Ray does not check the validity of the TLS certificate provided by the remote host by default."
|
||||
msgstr "是否允许不安全连接。当勾选时,缺省情况下客户端不会检查远端主机所提供的 TLS 证书的有效性。"
|
||||
|
||||
msgid "Add"
|
||||
msgstr "添加"
|
||||
|
||||
@ -841,6 +907,60 @@ msgstr "隐藏菜单方法,地址栏输入例:"
|
||||
msgid "After the hidden to the display, input example in the address bar:"
|
||||
msgstr "当你隐藏后想再次显示,地址栏输入例:"
|
||||
|
||||
msgid "When OTA is enabled, V2Ray will reject connections that are not OTA enabled. This option is invalid when using AEAD encryption."
|
||||
msgstr "开启 OTA 后,V2Ray 会拒绝未启用 OTA 的连接。当使用 AEAD 加密时,该选项无效。"
|
||||
|
||||
msgid "transit node"
|
||||
msgstr "中转到此节点"
|
||||
|
||||
msgid "Bind Local"
|
||||
msgstr "本机监听"
|
||||
|
||||
msgid "When selected, it can only be accessed locally,It is recommended to turn on when using reverse proxies."
|
||||
msgstr "当勾选时,只能由本机访问此端口,当开启反向代理时建议勾选此项。"
|
||||
|
||||
msgid "Accept LAN Access"
|
||||
msgstr "接受局域网访问"
|
||||
|
||||
msgid "When selected, it can accessed lan , this will not be safe!"
|
||||
msgstr "当勾选时,可以直接访问局域网,这将不安全!(非特殊情况不建议开启)"
|
||||
|
||||
msgid "Enable Remote"
|
||||
msgstr "启用转发"
|
||||
|
||||
msgid "You can forward to Nginx/Caddy/V2ray WebSocket and more."
|
||||
msgstr "您可以转发到Nginx/Caddy/V2ray WebSocket等。"
|
||||
|
||||
msgid "Remote Address"
|
||||
msgstr "远程地址"
|
||||
|
||||
msgid "Remote Port"
|
||||
msgstr "远程端口"
|
||||
|
||||
msgid "as:"
|
||||
msgstr "如:"
|
||||
|
||||
msgid "Public key absolute path"
|
||||
msgstr "公钥文件绝对路径"
|
||||
|
||||
msgid "Private key absolute path"
|
||||
msgstr "私钥文件绝对路径"
|
||||
|
||||
msgid "Server-Side"
|
||||
msgstr "服务器端"
|
||||
|
||||
msgid "Server Config"
|
||||
msgstr "服务器配置"
|
||||
|
||||
msgid "Users Manager"
|
||||
msgstr "用户管理"
|
||||
|
||||
msgid "Logs"
|
||||
msgstr "日志"
|
||||
|
||||
msgid "UDP Forward"
|
||||
msgstr "UDP转发"
|
||||
|
||||
msgid "Can't determine ARCH, or ARCH not supported."
|
||||
msgstr "无法确认ARCH架构,或是不支持。"
|
||||
|
||||
|
||||
@ -3,7 +3,6 @@ config global
|
||||
option enabled '0'
|
||||
option tcp_node1 'nil'
|
||||
option udp_node1 'nil'
|
||||
option socks_node1 'nil'
|
||||
option dns_mode 'pdnsd'
|
||||
option up_china_dns 'default'
|
||||
option dns_forward '8.8.4.4'
|
||||
@ -27,9 +26,6 @@ config global_forwarding
|
||||
option udp_no_redir_ports '80,443'
|
||||
option tcp_redir_ports '22,25,53,143,465,587,993,995,80,443'
|
||||
option udp_redir_ports '1:65535'
|
||||
option socks_proxy_port1 '1081'
|
||||
option socks_proxy_port2 '1082'
|
||||
option socks_proxy_port3 '1083'
|
||||
option proxy_ipv6 '0'
|
||||
|
||||
config global_other
|
||||
@ -37,7 +33,6 @@ config global_other
|
||||
option auto_ping '1'
|
||||
option tcp_node_num '1'
|
||||
option udp_node_num '1'
|
||||
option socks_node_num '1'
|
||||
option status_use_big_icon '1'
|
||||
option status_show_check_port '0'
|
||||
option status_show_ip111 '0'
|
||||
@ -50,10 +45,13 @@ config global_rules
|
||||
option chnlist_update '1'
|
||||
option chnroute_update '1'
|
||||
option gfwlist_update '1'
|
||||
option gfwlist_version '2020-03-10'
|
||||
option chnroute_version '2020-03-10'
|
||||
option chnlist_version '2020-03-10'
|
||||
|
||||
option gfwlist_version '2020-04-14'
|
||||
option chnroute_version '2020-05-22'
|
||||
option chnlist_version '2020-05-22'
|
||||
option enable_custom_url '0'
|
||||
option gfwlist_url 'https://cdn.jsdelivr.net/gh/Loukky/gfwlist-by-loukky/gfwlist.txt'
|
||||
option chnroute_url 'https://ispip.clang.cn/all_cn.txt'
|
||||
|
||||
config global_app
|
||||
option v2ray_file '/usr/bin/v2ray/'
|
||||
option kcptun_client_file '/usr/bin/kcptun-client'
|
||||
@ -64,6 +62,7 @@ config global_subscribe
|
||||
option auto_update_subscribe '0'
|
||||
option filter_enabled '1'
|
||||
option filter_keyword_discarded '1'
|
||||
option allowInsecure '1'
|
||||
list filter_keyword '过期时间'
|
||||
list filter_keyword '剩余流量'
|
||||
list filter_keyword 'QQ群'
|
||||
@ -72,3 +71,28 @@ config global_subscribe
|
||||
config auto_switch
|
||||
option testing_time '1'
|
||||
option enable '0'
|
||||
|
||||
config shunt_rules 'youtube'
|
||||
option remarks 'youtube'
|
||||
option domain_list 'youtube
|
||||
youtube.com
|
||||
youtu.be
|
||||
googlevideo.com
|
||||
ytimg.com
|
||||
gvt2.com'
|
||||
|
||||
config shunt_rules 'netflix'
|
||||
option remarks '奈飞'
|
||||
option domain_list 'netflix
|
||||
netflix.com
|
||||
nflxso.net
|
||||
nflxext.com
|
||||
nflximg.com
|
||||
nflximg.net
|
||||
nflxvideo.net
|
||||
fast.com'
|
||||
|
||||
config shunt_rules 'TVB'
|
||||
option remarks 'TVB'
|
||||
option domain_list 'tvb.com
|
||||
mytvsuper.com'
|
||||
|
||||
@ -0,0 +1,4 @@
|
||||
|
||||
config global 'global'
|
||||
option enable '0'
|
||||
|
||||
16
package/lienol/luci-app-passwall/root/etc/init.d/passwall_server
Executable file
16
package/lienol/luci-app-passwall/root/etc/init.d/passwall_server
Executable file
@ -0,0 +1,16 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=99
|
||||
|
||||
start() {
|
||||
/usr/lib/lua/luci/model/cbi/passwall/server/api/app.lua start
|
||||
}
|
||||
|
||||
stop() {
|
||||
/usr/lib/lua/luci/model/cbi/passwall/server/api/app.lua stop
|
||||
}
|
||||
|
||||
restart() {
|
||||
stop
|
||||
start
|
||||
}
|
||||
@ -11,9 +11,19 @@ uci -q batch <<-EOF >/dev/null
|
||||
set firewall.passwall.path=/var/etc/passwall.include
|
||||
set firewall.passwall.reload=1
|
||||
commit firewall
|
||||
delete ucitrack.@passwall_server[-1]
|
||||
add ucitrack passwall_server
|
||||
set ucitrack.@passwall_server[-1].init=passwall_server
|
||||
commit ucitrack
|
||||
delete firewall.passwall_server
|
||||
set firewall.passwall_server=include
|
||||
set firewall.passwall_server.type=script
|
||||
set firewall.passwall_server.path=/var/etc/passwall_server.include
|
||||
set firewall.passwall_server.reload=1
|
||||
commit firewall
|
||||
set uhttpd.main.max_requests=50
|
||||
commit uhttpd
|
||||
EOF
|
||||
|
||||
killall -q -9 kcptun haproxy shadowsocks-libev shadowsocksr-libev
|
||||
/etc/init.d/haproxy disable && /etc/init.d/haproxy stop
|
||||
rm -rf /tmp/luci-*cache
|
||||
exit 0
|
||||
|
||||
@ -17,10 +17,9 @@ DNSMASQ_PATH=/etc/dnsmasq.d
|
||||
RESOLVFILE=/tmp/resolv.conf.d/resolv.conf.auto
|
||||
DNS_PORT=7913
|
||||
LUA_API_PATH=/usr/lib/lua/luci/model/cbi/$CONFIG/api
|
||||
API_GEN_TROJAN=$LUA_API_PATH/gen_trojan.lua
|
||||
API_GEN_SS=$LUA_API_PATH/gen_shadowsocks.lua
|
||||
API_GEN_V2RAY=$LUA_API_PATH/gen_v2ray.lua
|
||||
API_GEN_V2RAY_BALANCING=$LUA_API_PATH/gen_v2ray_balancing.lua
|
||||
API_GEN_V2RAY_SHUNT=$LUA_API_PATH/gen_v2ray_shunt.lua
|
||||
API_GEN_TROJAN=$LUA_API_PATH/gen_trojan.lua
|
||||
|
||||
echolog() {
|
||||
local d="$(date "+%Y-%m-%d %H:%M:%S")"
|
||||
@ -104,7 +103,7 @@ check_port_exists() {
|
||||
|
||||
get_new_port() {
|
||||
port=$1
|
||||
[ "$port" == "auto" ] && port=$SOCKS_REDIR_PORT3
|
||||
[ "$port" == "auto" ] && port=2082
|
||||
protocol=$2
|
||||
result=$(check_port_exists $port $protocol)
|
||||
if [ "$result" = 1 ]; then
|
||||
@ -156,19 +155,11 @@ UDP_REDIR_PORT1=$(config_t_get global_forwarding udp_redir_port 1051)
|
||||
UDP_REDIR_PORT2=$(expr $UDP_REDIR_PORT1 + 1)
|
||||
UDP_REDIR_PORT3=$(expr $UDP_REDIR_PORT2 + 1)
|
||||
|
||||
SOCKS_NODE_NUM=$(config_t_get global_other socks_node_num 1)
|
||||
for i in $(seq 1 $SOCKS_NODE_NUM); do
|
||||
eval SOCKS_NODE$i=$(config_t_get global socks_node$i nil)
|
||||
done
|
||||
SOCKS_REDIR_PORT1=$(config_t_get global_forwarding socks_proxy_port1 1081)
|
||||
SOCKS_REDIR_PORT2=$(config_t_get global_forwarding socks_proxy_port2 1082)
|
||||
SOCKS_REDIR_PORT3=$(config_t_get global_forwarding socks_proxy_port3 1083)
|
||||
|
||||
[ "$UDP_NODE1" == "tcp" ] && UDP_NODE1=$TCP_NODE1
|
||||
[ "$SOCKS_NODE1" == "tcp" ] && SOCKS_NODE1=$TCP_NODE1
|
||||
[ "$UDP_NODE1" == "tcp_" ] && UDP_NODE1=$TCP_NODE1
|
||||
[ "$UDP_NODE1" == "tcp" ] && UDP_REDIR_PORT1=$TCP_REDIR_PORT1
|
||||
|
||||
# Dynamic variables (Used to record)
|
||||
# TCP_NODE1_IP="" UDP_NODE1_IP="" SOCKS_NODE1_IP="" TCP_NODE1_PORT="" UDP_NODE1_PORT="" SOCKS_NODE1_PORT="" TCP_NODE1_TYPE="" UDP_NODE1_TYPE="" SOCKS_NODE1_TYPE=""
|
||||
# TCP_NODE1_IP="" UDP_NODE1_IP="" TCP_NODE1_PORT="" UDP_NODE1_PORT="" TCP_NODE1_TYPE="" UDP_NODE1_TYPE=""
|
||||
|
||||
TCP_REDIR_PORTS=$(config_t_get global_forwarding tcp_redir_ports '80,443')
|
||||
UDP_REDIR_PORTS=$(config_t_get global_forwarding udp_redir_ports '1:65535')
|
||||
@ -183,14 +174,26 @@ LOCALHOST_UDP_PROXY_MODE=$(config_t_get global localhost_udp_proxy_mode default)
|
||||
[ "$LOCALHOST_UDP_PROXY_MODE" == "default" ] && LOCALHOST_UDP_PROXY_MODE=$UDP_PROXY_MODE
|
||||
|
||||
load_config() {
|
||||
local auto_switch_list=$(config_t_get auto_switch tcp_node1 nil)
|
||||
[ -n "$auto_switch_list" -a "$auto_switch_list" != "nil" ] && {
|
||||
for tmp in $auto_switch_list; do
|
||||
tmp_id=$(config_n_get $tmp address nil)
|
||||
[ "$tmp_id" == "nil" ] && {
|
||||
uci -q del_list $CONFIG.@auto_switch[0].tcp_node1=$tmp
|
||||
uci commit $CONFIG
|
||||
}
|
||||
done
|
||||
}
|
||||
|
||||
[ "$ENABLED" != 1 ] && return 1
|
||||
[ "$TCP_NODE1" == "nil" -a "$UDP_NODE1" == "nil" -a "$SOCKS_NODE1" == "nil" ] && {
|
||||
[ "$TCP_NODE1" == "nil" -a "$UDP_NODE1" == "nil" ] && {
|
||||
echolog "没有选择节点!"
|
||||
return 1
|
||||
}
|
||||
|
||||
DNS_MODE=$(config_t_get global dns_mode pdnsd)
|
||||
DNS_FORWARD=$(config_t_get global dns_forward 8.8.4.4)
|
||||
DNS_CACHE=$(config_t_get global dns_cache 1)
|
||||
use_tcp_node_resolve_dns=0
|
||||
use_udp_node_resolve_dns=0
|
||||
process=1
|
||||
@ -224,191 +227,126 @@ load_config() {
|
||||
return 0
|
||||
}
|
||||
|
||||
gen_ss_ssr_config_file() {
|
||||
local type local_port kcptun node configfile
|
||||
type=$1
|
||||
local_port=$2
|
||||
kcptun=$3
|
||||
node=$4
|
||||
configfile=$5
|
||||
local port encrypt_method
|
||||
port=$(config_n_get $node port)
|
||||
encrypt_method=$(config_n_get $node ss_encrypt_method)
|
||||
[ "$type" == "ssr" ] && encrypt_method=$(config_n_get $node ssr_encrypt_method)
|
||||
[ "$kcptun" == "1" ] && {
|
||||
server_host=127.0.0.1
|
||||
port=$KCPTUN_REDIR_PORT
|
||||
}
|
||||
cat <<-EOF >$configfile
|
||||
{
|
||||
"server": "$server_host",
|
||||
"server_port": $port,
|
||||
"local_address": "0.0.0.0",
|
||||
"local_port": $local_port,
|
||||
"password": "$(config_n_get $node password)",
|
||||
"timeout": $(config_n_get $node timeout),
|
||||
"method": "$encrypt_method",
|
||||
"fast_open": $(config_n_get $node tcp_fast_open false),
|
||||
"reuse_port": true,
|
||||
EOF
|
||||
[ "$1" == "ssr" ] && {
|
||||
cat <<-EOF >>$configfile
|
||||
"protocol": "$(config_n_get $node protocol)",
|
||||
"protocol_param": "$(config_n_get $node protocol_param)",
|
||||
"obfs": "$(config_n_get $node obfs)",
|
||||
"obfs_param": "$(config_n_get $node obfs_param)"
|
||||
EOF
|
||||
}
|
||||
echo -e "}" >>$configfile
|
||||
}
|
||||
|
||||
gen_start_config() {
|
||||
local node local_port redir_type config_file bind server_host port type
|
||||
node=$1
|
||||
local_port=$2
|
||||
redir_type=$3
|
||||
config_file=$4
|
||||
bind="0.0.0.0"
|
||||
[ -n "$6" ] && bind="$6"
|
||||
type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
|
||||
remarks=$(config_n_get $node remarks)
|
||||
server_host=$(config_n_get $node address)
|
||||
port=$(config_n_get $node port)
|
||||
run_socks() {
|
||||
local node=$1
|
||||
local bind=$2
|
||||
local local_port=$3
|
||||
local config_file=$4
|
||||
local type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
|
||||
local remarks=$(config_n_get $node remarks)
|
||||
local server_host=$(config_n_get $node address)
|
||||
local port=$(config_n_get $node port)
|
||||
[ -n "$server_host" -a -n "$port" ] && {
|
||||
# 判断节点服务器地址是否URL并去掉~
|
||||
server_host=$(echo $server_host | sed 's/^\(https:\/\/\|http:\/\/\)//g' | awk -F '/' '{print $1}')
|
||||
local server_host=$(echo $server_host | sed 's/^\(https:\/\/\|http:\/\/\)//g' | awk -F '/' '{print $1}')
|
||||
# 判断节点服务器地址是否包含汉字~
|
||||
local tmp=$(echo -n $server_host | awk '{print gensub(/[!-~]/,"","g",$0)}')
|
||||
[ -n "$tmp" ] && {
|
||||
echolog "${redir_type}_${5}节点,非法的服务器地址,无法启动!"
|
||||
echolog "$remarks,非法的服务器地址,无法启动!"
|
||||
return 1
|
||||
}
|
||||
[ "$bind" == "0.0.0.0" ] && echolog "${redir_type}_${5}节点:$remarks,节点:${server_host}:${port},监听端口:$local_port"
|
||||
[ "$bind" != "127.0.0.1" ] && echolog "Socks节点:$remarks,地址:${server_host}:${port},监听端口:$local_port"
|
||||
}
|
||||
|
||||
if [ "$redir_type" == "SOCKS" ]; then
|
||||
eval SOCKS_NODE${5}_PORT=$port
|
||||
if [ "$type" == "socks5" ]; then
|
||||
echolog "Socks节点不能使用Socks代理节点!"
|
||||
elif [ "$type" == "v2ray" ]; then
|
||||
lua $API_GEN_V2RAY $node nil nil $local_port >$config_file
|
||||
ln_start_bin $(config_t_get global_app v2ray_file $(find_bin v2ray))/v2ray v2ray_socks_$5 "-config=$config_file"
|
||||
elif [ "$type" == "v2ray_balancing" ]; then
|
||||
lua $API_GEN_V2RAY_BALANCING $node nil nil $local_port >$config_file
|
||||
ln_start_bin $(config_t_get global_app v2ray_file $(find_bin v2ray))/v2ray v2ray_socks_$5 "-config=$config_file"
|
||||
elif [ "$type" == "v2ray_shunt" ]; then
|
||||
lua $API_GEN_V2RAY_SHUNT $node nil nil $local_port >$config_file
|
||||
ln_start_bin $(config_t_get global_app v2ray_file $(find_bin v2ray))/v2ray v2ray_socks_$5 "-config=$config_file"
|
||||
elif [ "$type" == "trojan" ]; then
|
||||
lua $API_GEN_TROJAN $node client $bind $local_port >$config_file
|
||||
ln_start_bin $(find_bin trojan) trojan_socks_$5 "-c $config_file"
|
||||
elif [ "$type" == "brook" ]; then
|
||||
local protocol=$(config_n_get $node brook_protocol client)
|
||||
local brook_tls=$(config_n_get $node brook_tls 0)
|
||||
[ "$protocol" == "wsclient" ] && {
|
||||
[ "$brook_tls" == "1" ] && server_host="wss://${server_host}" || server_host="ws://${server_host}"
|
||||
}
|
||||
ln_start_bin $(config_t_get global_app brook_file $(find_bin brook)) brook_socks_$5 "$protocol -l $bind:$local_port -i $$bind -s $server_host:$port -p $(config_n_get $node password)"
|
||||
elif [ "$type" == "ssr" ]; then
|
||||
gen_ss_ssr_config_file ssr $local_port 0 $node $config_file
|
||||
ln_start_bin $(find_bin ssr-local) ssr-local_socks_$5 "-c $config_file -b $bind -u"
|
||||
elif [ "$type" == "ss" ]; then
|
||||
gen_ss_ssr_config_file ss $local_port 0 $node $config_file
|
||||
local plugin_params=""
|
||||
local plugin=$(config_n_get $node ss_plugin)
|
||||
if [ "$plugin" != "none" ]; then
|
||||
[ "$plugin" == "v2ray-plugin" -o "$plugin" == "obfs-local" ] && {
|
||||
local plugin_opts=""
|
||||
local opts=$(config_n_get $node ss_plugin_opts)
|
||||
[ -n "$opts" ] && plugin_opts="--plugin-opts $opts"
|
||||
plugin_params="--plugin $plugin $plugin_opts"
|
||||
}
|
||||
fi
|
||||
ln_start_bin $(find_bin ss-local) ss-local_socks_$5 "-c $config_file -b $bind -u $plugin_params"
|
||||
fi
|
||||
if [ "$type" == "socks" ]; then
|
||||
echolog "Socks节点不能使用Socks代理节点!"
|
||||
elif [ "$type" == "v2ray" ]; then
|
||||
lua $API_GEN_V2RAY $node nil nil $local_port > $config_file
|
||||
ln_start_bin $(config_t_get global_app v2ray_file $(find_bin v2ray))/v2ray v2ray "-config=$config_file"
|
||||
elif [ "$type" == "trojan" ]; then
|
||||
lua $API_GEN_TROJAN $node client $bind $local_port > $config_file
|
||||
ln_start_bin $(find_bin trojan) trojan "-c $config_file"
|
||||
elif [ "$type" == "brook" ]; then
|
||||
local protocol=$(config_n_get $node brook_protocol client)
|
||||
local brook_tls=$(config_n_get $node brook_tls 0)
|
||||
[ "$protocol" == "wsclient" ] && {
|
||||
[ "$brook_tls" == "1" ] && server_host="wss://${server_host}" || server_host="ws://${server_host}"
|
||||
}
|
||||
ln_start_bin $(config_t_get global_app brook_file $(find_bin brook)) brook_socks_$5 "$protocol -l $bind:$local_port -i $$bind -s $server_host:$port -p $(config_n_get $node password)"
|
||||
elif [ "$type" == "ssr" ] || [ "$type" == "ss" ]; then
|
||||
lua $API_GEN_SS $node $local_port > $config_file
|
||||
ln_start_bin $(find_bin ${type}-local) ${type}-local "-c $config_file -b $bind -u"
|
||||
fi
|
||||
}
|
||||
|
||||
run_redir() {
|
||||
local node=$1
|
||||
local bind=$2
|
||||
local local_port=$3
|
||||
local config_file=$4
|
||||
local redir_type=$5
|
||||
local type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
|
||||
local remarks=$(config_n_get $node remarks)
|
||||
local server_host=$(config_n_get $node address)
|
||||
local port=$(config_n_get $node port)
|
||||
[ -n "$server_host" -a -n "$port" ] && {
|
||||
# 判断节点服务器地址是否URL并去掉~
|
||||
local server_host=$(echo $server_host | sed 's/^\(https:\/\/\|http:\/\/\)//g' | awk -F '/' '{print $1}')
|
||||
# 判断节点服务器地址是否包含汉字~
|
||||
local tmp=$(echo -n $server_host | awk '{print gensub(/[!-~]/,"","g",$0)}')
|
||||
[ -n "$tmp" ] && {
|
||||
echolog "$remarks节点,非法的服务器地址,无法启动!"
|
||||
return 1
|
||||
}
|
||||
[ "$bind" != "127.0.0.1" ] && echolog "${redir_type}_${6}节点:$remarks,节点:${server_host}:${port},监听端口:$local_port"
|
||||
}
|
||||
eval ${redir_type}_NODE${6}_PORT=$port
|
||||
|
||||
if [ "$redir_type" == "UDP" ]; then
|
||||
eval UDP_NODE${5}_PORT=$port
|
||||
|
||||
if [ "$type" == "socks5" ]; then
|
||||
if [ "$type" == "socks" ]; then
|
||||
local node_address=$(config_n_get $node address)
|
||||
local node_port=$(config_n_get $node port)
|
||||
local server_username=$(config_n_get $node username)
|
||||
local server_password=$(config_n_get $node password)
|
||||
eval port=\$UDP_REDIR_PORT$5
|
||||
ln_start_bin $(find_bin ipt2socks) ipt2socks_udp_$5 "-4 -U -l $port -b 0.0.0.0 -s $node_address -p $node_port -R"
|
||||
eval port=\$UDP_REDIR_PORT$6
|
||||
ln_start_bin $(find_bin ipt2socks) ipt2socks_udp_$6 "-U -l $port -b 0.0.0.0 -s $node_address -p $node_port -R"
|
||||
elif [ "$type" == "v2ray" ]; then
|
||||
lua $API_GEN_V2RAY $node udp $local_port nil >$config_file
|
||||
ln_start_bin $(config_t_get global_app v2ray_file $(find_bin v2ray))/v2ray v2ray_udp_$5 "-config=$config_file"
|
||||
elif [ "$type" == "v2ray_balancing" ]; then
|
||||
lua $API_GEN_V2RAY_BALANCING $node udp $local_port nil >$config_file
|
||||
ln_start_bin $(config_t_get global_app v2ray_file $(find_bin v2ray))/v2ray v2ray_udp_$5 "-config=$config_file"
|
||||
elif [ "$type" == "v2ray_shunt" ]; then
|
||||
lua $API_GEN_V2RAY_SHUNT $node udp $local_port nil >$config_file
|
||||
ln_start_bin $(config_t_get global_app v2ray_file $(find_bin v2ray))/v2ray v2ray_udp_$5 "-config=$config_file"
|
||||
lua $API_GEN_V2RAY $node udp $local_port nil > $config_file
|
||||
ln_start_bin $(config_t_get global_app v2ray_file $(find_bin v2ray))/v2ray v2ray "-config=$config_file"
|
||||
elif [ "$type" == "trojan" ]; then
|
||||
SOCKS_REDIR_PORT4=$(expr $SOCKS_REDIR_PORT3 + 1)
|
||||
local_port=$(get_new_port $SOCKS_REDIR_PORT4 tcp)
|
||||
socks_port=$local_port
|
||||
lua $API_GEN_TROJAN $node client "127.0.0.1" $socks_port >$config_file
|
||||
ln_start_bin $(find_bin trojan) trojan_udp_$5 "-c $config_file"
|
||||
local_port=$(get_new_port 2080 tcp)
|
||||
lua $API_GEN_TROJAN $node client "127.0.0.1" $local_port > $config_file
|
||||
ln_start_bin $(find_bin trojan) trojan "-c $config_file"
|
||||
|
||||
local node_address=$(config_n_get $node address)
|
||||
local node_port=$(config_n_get $node port)
|
||||
local server_username=$(config_n_get $node username)
|
||||
local server_password=$(config_n_get $node password)
|
||||
eval port=\$UDP_REDIR_PORT$5
|
||||
ln_start_bin $(find_bin ipt2socks) ipt2socks_udp_$5 "-4 -U -l $port -b 0.0.0.0 -s 127.0.0.1 -p $socks_port -R"
|
||||
eval port=\$UDP_REDIR_PORT$6
|
||||
ln_start_bin $(find_bin ipt2socks) ipt2socks_udp_$6 "-U -l $port -b 0.0.0.0 -s 127.0.0.1 -p $local_port -R"
|
||||
elif [ "$type" == "brook" ]; then
|
||||
local protocol=$(config_n_get $node brook_protocol client)
|
||||
if [ "$protocol" == "wsclient" ]; then
|
||||
echolog "Brook的WebSocket不支持UDP转发!"
|
||||
else
|
||||
ln_start_bin $(config_t_get global_app brook_file $(find_bin brook)) brook_udp_$5 "tproxy -l 0.0.0.0:$local_port -s $server_host:$port -p $(config_n_get $node password)"
|
||||
ln_start_bin $(config_t_get global_app brook_file $(find_bin brook)) brook_udp_$6 "tproxy -l 0.0.0.0:$local_port -s $server_host:$port -p $(config_n_get $node password)"
|
||||
fi
|
||||
elif [ "$type" == "ssr" ]; then
|
||||
gen_ss_ssr_config_file ssr $local_port 0 $node $config_file
|
||||
ln_start_bin $(find_bin ssr-redir) ssr-redir_udp_$5 "-c $config_file -U"
|
||||
elif [ "$type" == "ss" ]; then
|
||||
gen_ss_ssr_config_file ss $local_port 0 $node $config_file
|
||||
local plugin_params=""
|
||||
local plugin=$(config_n_get $node ss_plugin)
|
||||
if [ "$plugin" != "none" ]; then
|
||||
[ "$plugin" == "v2ray-plugin" -o "$plugin" == "obfs-local" ] && {
|
||||
local plugin_opts=""
|
||||
local opts=$(config_n_get $node ss_plugin_opts)
|
||||
[ -n "$opts" ] && plugin_opts="--plugin-opts $opts"
|
||||
plugin_params="--plugin $plugin $plugin_opts"
|
||||
}
|
||||
fi
|
||||
ln_start_bin $(find_bin ss-redir) ss-redir_udp_$5 "-c $config_file -U $plugin_params"
|
||||
elif [ "$type" == "ssr" ] || [ "$type" == "ss" ]; then
|
||||
lua $API_GEN_SS $node $local_port > $config_file
|
||||
ln_start_bin $(find_bin ${type}-redir) ${type}-redir "-c $config_file -U"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$redir_type" == "TCP" ]; then
|
||||
eval TCP_NODE${5}_PORT=$port
|
||||
|
||||
if [ "$type" == "socks5" ]; then
|
||||
if [ "$type" == "socks" ]; then
|
||||
local node_address=$(config_n_get $node address)
|
||||
local node_port=$(config_n_get $node port)
|
||||
local server_username=$(config_n_get $node username)
|
||||
local server_password=$(config_n_get $node password)
|
||||
eval port=\$TCP_REDIR_PORT$5
|
||||
ln_start_bin $(find_bin ipt2socks) ipt2socks_tcp_$5 "-4 -T -l $port -b 0.0.0.0 -s $node_address -p $node_port -R"
|
||||
eval port=\$TCP_REDIR_PORT$6
|
||||
local extra_param="-T"
|
||||
[ "$6" == 1 ] && [ "$UDP_NODE1" == "tcp" ] && extra_param=""
|
||||
ln_start_bin $(find_bin ipt2socks) ipt2socks_tcp_$6 "-l $port -b 0.0.0.0 -s $node_address -p $node_port -R $extra_param"
|
||||
elif [ "$type" == "v2ray" ]; then
|
||||
lua $API_GEN_V2RAY $node tcp $local_port nil >$config_file
|
||||
ln_start_bin $(config_t_get global_app v2ray_file $(find_bin v2ray))/v2ray v2ray_tcp_$5 "-config=$config_file"
|
||||
elif [ "$type" == "v2ray_balancing" ]; then
|
||||
lua $API_GEN_V2RAY_BALANCING $node tcp $local_port nil >$config_file
|
||||
ln_start_bin $(config_t_get global_app v2ray_file $(find_bin v2ray))/v2ray v2ray_tcp_$5 "-config=$config_file"
|
||||
elif [ "$type" == "v2ray_shunt" ]; then
|
||||
lua $API_GEN_V2RAY_SHUNT $node tcp $local_port nil >$config_file
|
||||
ln_start_bin $(config_t_get global_app v2ray_file $(find_bin v2ray))/v2ray v2ray_tcp_$5 "-config=$config_file"
|
||||
local extra_param="tcp"
|
||||
[ "$6" == 1 ] && [ "$UDP_NODE1" == "tcp" ] && extra_param="tcp,udp"
|
||||
lua $API_GEN_V2RAY $node $extra_param $local_port nil > $config_file
|
||||
ln_start_bin $(config_t_get global_app v2ray_file $(find_bin v2ray))/v2ray v2ray "-config=$config_file"
|
||||
elif [ "$type" == "trojan" ]; then
|
||||
lua $API_GEN_TROJAN $node nat "0.0.0.0" $local_port >$config_file
|
||||
lua $API_GEN_TROJAN $node nat "0.0.0.0" $local_port > $config_file
|
||||
[ "$6" == 1 ] && [ "$UDP_NODE1" == "tcp" ] && echolog "Trojan的NAT模式不支持UDP转发!"
|
||||
for k in $(seq 1 $process); do
|
||||
ln_start_bin $(find_bin trojan) trojan_tcp_$5 "-c $config_file"
|
||||
ln_start_bin $(find_bin trojan) trojan "-c $config_file"
|
||||
done
|
||||
else
|
||||
local kcptun_use=$(config_n_get $node use_kcp 0)
|
||||
@ -424,28 +362,19 @@ gen_start_config() {
|
||||
local run_kcptun_ip=$server_host
|
||||
[ -n "$kcptun_server_host" ] && run_kcptun_ip=$(get_host_ip $network_type $kcptun_server_host)
|
||||
KCPTUN_REDIR_PORT=$(get_new_port $KCPTUN_REDIR_PORT tcp)
|
||||
ln_start_bin $(config_t_get global_app kcptun_client_file $(find_bin kcptun-client)) kcptun_tcp_$5 "-l 0.0.0.0:$KCPTUN_REDIR_PORT -r $run_kcptun_ip:$kcptun_port $kcptun_config"
|
||||
ln_start_bin $(config_t_get global_app kcptun_client_file $(find_bin kcptun-client)) kcptun_tcp_$6 "-l 0.0.0.0:$KCPTUN_REDIR_PORT -r $run_kcptun_ip:$kcptun_port $kcptun_config"
|
||||
fi
|
||||
fi
|
||||
if [ "$type" == "ssr" ]; then
|
||||
gen_ss_ssr_config_file ssr $local_port $kcptun_use $node $config_file
|
||||
for k in $(seq 1 $process); do
|
||||
ln_start_bin $(find_bin ssr-redir) ssr-redir_tcp_$5 "-c $config_file"
|
||||
done
|
||||
elif [ "$type" == "ss" ]; then
|
||||
gen_ss_ssr_config_file ss $local_port $kcptun_use $node $config_file
|
||||
local plugin_params=""
|
||||
local plugin=$(config_n_get $node ss_plugin)
|
||||
if [ "$plugin" != "none" ]; then
|
||||
[ "$plugin" == "v2ray-plugin" -o "$plugin" == "obfs-local" ] && {
|
||||
local plugin_opts=""
|
||||
local opts=$(config_n_get $node ss_plugin_opts)
|
||||
[ -n "$opts" ] && plugin_opts="--plugin-opts $opts"
|
||||
plugin_params="--plugin $plugin $plugin_opts"
|
||||
}
|
||||
if [ "$type" == "ssr" ] || [ "$type" == "ss" ]; then
|
||||
if [ "$kcptun_use" == "1" ]; then
|
||||
lua $API_GEN_SS $node $local_port 127.0.0.1 $KCPTUN_REDIR_PORT > $config_file
|
||||
[ "$6" == 1 ] && [ "$UDP_NODE1" == "tcp" ] && echolog "Kcptun不支持UDP转发!"
|
||||
else
|
||||
lua $API_GEN_SS $node $local_port > $config_file
|
||||
[ "$6" == 1 ] && [ "$UDP_NODE1" == "tcp" ] && extra_param="-u"
|
||||
fi
|
||||
for k in $(seq 1 $process); do
|
||||
ln_start_bin $(find_bin ss-redir) ss-redir_tcp_$5 "-c $config_file $plugin_params"
|
||||
ln_start_bin $(find_bin ${type}-redir) ${type}-redir "-c $config_file $extra_param"
|
||||
done
|
||||
elif [ "$type" == "brook" ]; then
|
||||
local server_ip=$server_host
|
||||
@ -453,17 +382,18 @@ gen_start_config() {
|
||||
local brook_tls=$(config_n_get $node brook_tls 0)
|
||||
if [ "$protocol" == "wsclient" ]; then
|
||||
[ "$brook_tls" == "1" ] && server_ip="wss://${server_ip}" || server_ip="ws://${server_ip}"
|
||||
socks_port=$(get_new_port $(expr $SOCKS_REDIR_PORT3 + 3) tcp)
|
||||
ln_start_bin $(config_t_get global_app brook_file $(find_bin brook)) brook_tcp_$5 "wsclient -l 127.0.0.1:$socks_port -i 127.0.0.1 -s $server_ip:$port -p $(config_n_get $node password)"
|
||||
eval port=\$TCP_REDIR_PORT$5
|
||||
ln_start_bin $(find_bin ipt2socks) ipt2socks_tcp_$5 "-4 -T -l $port -b 0.0.0.0 -s 127.0.0.1 -p $socks5_port -R"
|
||||
socks_port=$(get_new_port 2081 tcp)
|
||||
ln_start_bin $(config_t_get global_app brook_file $(find_bin brook)) brook_tcp_$6 "wsclient -l 127.0.0.1:$socks_port -i 127.0.0.1 -s $server_ip:$port -p $(config_n_get $node password)"
|
||||
eval port=\$TCP_REDIR_PORT$6
|
||||
ln_start_bin $(find_bin ipt2socks) ipt2socks_tcp_$6 "-T -l $port -b 0.0.0.0 -s 127.0.0.1 -p $socks_port -R"
|
||||
echolog "Brook的WebSocket不支持透明代理,将使用ipt2socks转换透明代理!"
|
||||
[ "$6" == 1 ] && [ "$UDP_NODE1" == "tcp" ] && echolog "Brook的WebSocket不支持UDP转发!"
|
||||
else
|
||||
[ "$kcptun_use" == "1" ] && {
|
||||
server_ip=127.0.0.1
|
||||
port=$KCPTUN_REDIR_PORT
|
||||
}
|
||||
ln_start_bin $(config_t_get global_app brook_file $(find_bin brook)) brook_tcp_$5 "tproxy -l 0.0.0.0:$local_port -s $server_ip:$port -p $(config_n_get $node password)"
|
||||
ln_start_bin $(config_t_get global_app brook_file $(find_bin brook)) brook_tcp_$6 "tproxy -l 0.0.0.0:$local_port -s $server_ip:$port -p $(config_n_get $node password)"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@ -479,7 +409,7 @@ node_switch() {
|
||||
local config_file=$TMP_PATH/${1}_${i}.json
|
||||
eval current_port=\$${1}_REDIR_PORT${i}
|
||||
local port=$(cat $TMP_PORT_PATH/${1}_${i})
|
||||
gen_start_config $node $port $1 $config_file $i
|
||||
run_redir $node "0.0.0.0" $port $config_file $1 $i
|
||||
echo $node > $TMP_ID_PATH/${1}_${i}
|
||||
local node_net=$(echo $1 | tr 'A-Z' 'a-z')
|
||||
uci set $CONFIG.@global[0].${node_net}_node${i}=$node
|
||||
@ -498,7 +428,7 @@ start_redir() {
|
||||
eval current_port=\$${1}_REDIR_PORT$i
|
||||
local port=$(echo $(get_new_port $current_port $2))
|
||||
eval ${1}_REDIR${i}=$port
|
||||
gen_start_config $node $port $1 $config_file $i
|
||||
run_redir $node "0.0.0.0" $port $config_file $1 $i
|
||||
#eval ip=\$${1}_NODE${i}_IP
|
||||
echo $node > $TMP_ID_PATH/${1}_${i}
|
||||
echo $port > $TMP_PORT_PATH/${1}_${i}
|
||||
@ -506,6 +436,23 @@ start_redir() {
|
||||
done
|
||||
}
|
||||
|
||||
start_socks() {
|
||||
local ids=$(uci show $CONFIG | grep "=socks" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}')
|
||||
for id in $ids; do
|
||||
local enabled=$(config_n_get $id enabled 0)
|
||||
[ "$enabled" == "0" ] && continue
|
||||
local node=$(config_n_get $id node nil)
|
||||
if [ "$(echo $node | grep ^tcp)" ]; then
|
||||
local num=$(echo $node | sed "s/tcp//g")
|
||||
eval node=\$TCP_NODE$num
|
||||
fi
|
||||
[ "$node" == "nil" ] && continue
|
||||
local config_file=$TMP_PATH/SOCKS_${id}.json
|
||||
local port=$(config_n_get $id port)
|
||||
run_socks $node "0.0.0.0" $port $config_file $id
|
||||
done
|
||||
}
|
||||
|
||||
clean_log() {
|
||||
logsnum=$(cat $LOG_FILE 2>/dev/null | wc -l)
|
||||
[ "$logsnum" -gt 300 ] && {
|
||||
@ -515,6 +462,7 @@ clean_log() {
|
||||
}
|
||||
|
||||
start_crontab() {
|
||||
touch /etc/crontabs/root
|
||||
sed -i '/$CONFIG/d' /etc/crontabs/root >/dev/null 2>&1 &
|
||||
auto_on=$(config_t_get global_delay auto_on 0)
|
||||
if [ "$auto_on" = "1" ]; then
|
||||
@ -565,6 +513,7 @@ start_crontab() {
|
||||
}
|
||||
|
||||
stop_crontab() {
|
||||
touch /etc/crontabs/root
|
||||
sed -i "/$CONFIG/d" /etc/crontabs/root >/dev/null 2>&1 &
|
||||
ps | grep "$APP_PATH/test.sh" | grep -v "grep" | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 &
|
||||
/etc/init.d/cron restart
|
||||
@ -580,24 +529,24 @@ start_dns() {
|
||||
echolog "DNS:使用本机7913端口DNS服务器解析域名..."
|
||||
;;
|
||||
dns2socks)
|
||||
if [ -n "$SOCKS_NODE1" -a "$SOCKS_NODE1" != "nil" ]; then
|
||||
DNS2SOCKS_FORWARD=$(config_t_get global dns2socks_forward 8.8.4.4)
|
||||
ln_start_bin $(find_bin dns2socks) dns2socks "127.0.0.1:$SOCKS_REDIR_PORT1 $DNS2SOCKS_FORWARD 127.0.0.1:$DNS_PORT"
|
||||
echolog "DNS:dns2socks..."
|
||||
else
|
||||
echolog "DNS:dns2socks模式需要使用Socks代理节点,请开启!"
|
||||
force_stop
|
||||
fi
|
||||
DNS2SOCKS_SOCKS_SERVER=$(echo $(config_t_get global socks_server nil) | sed "s/#/:/g")
|
||||
[ "$DNS2SOCKS_SOCKS_SERVER" != "nil" ] && {
|
||||
DNS2SOCKS_FORWARD=$(echo $DNS_FORWARD | awk -F ',' '{print $1}')
|
||||
[ -z "$DNS2SOCKS_FORWARD" ] && DNS2SOCKS_FORWARD="8.8.4.4"
|
||||
[ "$DNS_CACHE" == "0" ] && local _cache="/d"
|
||||
ln_start_bin $(find_bin dns2socks) dns2socks "$DNS2SOCKS_SOCKS_SERVER $DNS2SOCKS_FORWARD 127.0.0.1:$DNS_PORT $_cache"
|
||||
echolog "DNS:dns2socks($DNS2SOCKS_FORWARD)..."
|
||||
}
|
||||
;;
|
||||
pdnsd)
|
||||
if [ -z "$TCP_NODE1" -o "$TCP_NODE1" == "nil" ]; then
|
||||
echolog "DNS:pdnsd 模式需要启用TCP节点!"
|
||||
force_stop
|
||||
else
|
||||
gen_pdnsd_config $DNS_PORT 2048
|
||||
DNS_FORWARD=$(echo $DNS_FORWARD | sed 's/,/ /g')
|
||||
gen_pdnsd_config $DNS_PORT
|
||||
ln_start_bin $(find_bin pdnsd) pdnsd "--daemon -c $pdnsd_dir/pdnsd.conf -d"
|
||||
echolog "DNS:pdnsd + 使用TCP节点解析DNS($DNS_FORWARD)..."
|
||||
DNS_FORWARD=$(echo $DNS_FORWARD | sed 's/,/ /g')
|
||||
fi
|
||||
;;
|
||||
chinadns-ng)
|
||||
@ -610,36 +559,43 @@ start_dns() {
|
||||
[ -f "$RULES_PATH/chnlist" ] && cp -a $RULES_PATH/chnlist $TMP_PATH/chnlist
|
||||
[ -f "$TMP_PATH/chnlist" ] && {
|
||||
[ -f "$RULES_PATH/whitelist_host" -a -s "$RULES_PATH/whitelist_host" ] && cat $RULES_PATH/whitelist_host >> $TMP_PATH/chnlist
|
||||
local chnlist_param="-m $TMP_PATH/chnlist -M -f"
|
||||
local chnlist_param="-m $TMP_PATH/chnlist -M"
|
||||
}
|
||||
|
||||
local fair_mode=$(config_t_get global fair_mode 1)
|
||||
if [ "$fair_mode" == "1" ]; then
|
||||
fair_mode="-f"
|
||||
else
|
||||
fair_mode=""
|
||||
fi
|
||||
|
||||
up_trust_chinadns_ng_dns=$(config_t_get global up_trust_chinadns_ng_dns "pdnsd")
|
||||
if [ "$up_trust_chinadns_ng_dns" == "pdnsd" ]; then
|
||||
if [ -z "$TCP_NODE1" -o "$TCP_NODE1" == "nil" ]; then
|
||||
echolog "DNS:ChinaDNS-NG + pdnsd 模式需要启用TCP节点!"
|
||||
force_stop
|
||||
else
|
||||
gen_pdnsd_config $other_port 0
|
||||
DNS_FORWARD=$(echo $DNS_FORWARD | sed 's/,/ /g')
|
||||
gen_pdnsd_config $other_port
|
||||
ln_start_bin $(find_bin pdnsd) pdnsd "--daemon -c $pdnsd_dir/pdnsd.conf -d"
|
||||
ln_start_bin $(find_bin chinadns-ng) chinadns-ng "-l $DNS_PORT -c $UP_CHINA_DNS -t 127.0.0.1#$other_port $gfwlist_param $chnlist_param"
|
||||
ln_start_bin $(find_bin chinadns-ng) chinadns-ng "-l $DNS_PORT -c $UP_CHINA_DNS -t 127.0.0.1#$other_port $gfwlist_param $chnlist_param $fair_mode"
|
||||
echolog "DNS:ChinaDNS-NG + pdnsd($DNS_FORWARD),国内DNS:$UP_CHINA_DNS"
|
||||
DNS_FORWARD=$(echo $DNS_FORWARD | sed 's/,/ /g')
|
||||
fi
|
||||
elif [ "$up_trust_chinadns_ng_dns" == "dns2socks" ]; then
|
||||
if [ -n "$SOCKS_NODE1" -a "$SOCKS_NODE1" != "nil" ]; then
|
||||
DNS2SOCKS_FORWARD=$(config_t_get global dns2socks_forward 8.8.4.4)
|
||||
ln_start_bin $(find_bin dns2socks) dns2socks "127.0.0.1:$SOCKS_REDIR_PORT1 $DNS2SOCKS_FORWARD 127.0.0.1:$other_port"
|
||||
ln_start_bin $(find_bin chinadns-ng) chinadns-ng "-l $DNS_PORT -c $UP_CHINA_DNS -t 127.0.0.1#$other_port $gfwlist_param $chnlist_param"
|
||||
DNS2SOCKS_SOCKS_SERVER=$(echo $(config_t_get global socks_server nil) | sed "s/#/:/g")
|
||||
[ "$DNS2SOCKS_SOCKS_SERVER" != "nil" ] && {
|
||||
DNS2SOCKS_FORWARD=$(echo $DNS_FORWARD | awk -F ',' '{print $1}')
|
||||
[ -z "$DNS2SOCKS_FORWARD" ] && DNS2SOCKS_FORWARD="8.8.4.4"
|
||||
[ "$DNS_CACHE" == "0" ] && local _cache="/d"
|
||||
ln_start_bin $(find_bin dns2socks) dns2socks "$DNS2SOCKS_SOCKS_SERVER $DNS2SOCKS_FORWARD 127.0.0.1:$other_port $_cache"
|
||||
ln_start_bin $(find_bin chinadns-ng) chinadns-ng "-l $DNS_PORT -c $UP_CHINA_DNS -t 127.0.0.1#$other_port $gfwlist_param $chnlist_param $fair_mode"
|
||||
echolog "DNS:ChinaDNS-NG + dns2socks($DNS2SOCKS_FORWARD),国内DNS:$UP_CHINA_DNS"
|
||||
else
|
||||
echolog "DNS:dns2socks模式需要使用Socks代理节点,请开启!"
|
||||
force_stop
|
||||
fi
|
||||
else
|
||||
}
|
||||
elif [ "$up_trust_chinadns_ng_dns" == "udp" ]; then
|
||||
use_udp_node_resolve_dns=1
|
||||
DNS_FORWARD=$(echo $up_trust_chinadns_ng_dns | sed 's/,/ /g')
|
||||
ln_start_bin $(find_bin chinadns-ng) chinadns-ng "-l $DNS_PORT -c $UP_CHINA_DNS -t $up_trust_chinadns_ng_dns $gfwlist_param $chnlist_param"
|
||||
ln_start_bin $(find_bin chinadns-ng) chinadns-ng "-l $DNS_PORT -c $UP_CHINA_DNS -t $DNS_FORWARD $gfwlist_param $chnlist_param $fair_mode"
|
||||
echolog "DNS:ChinaDNS-NG,国内DNS:$UP_CHINA_DNS,可信DNS:$up_trust_chinadns_ng_dns,如果不能使用,请确保UDP节点已打开并且支持UDP转发。"
|
||||
DNS_FORWARD=$(echo $DNS_FORWARD | sed 's/,/ /g')
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
@ -656,7 +612,7 @@ add_dnsmasq() {
|
||||
|
||||
[ "$DNS_MODE" != "nonuse" ] && {
|
||||
[ -f "$RULES_PATH/whitelist_host" -a -s "$RULES_PATH/whitelist_host" ] && cat $RULES_PATH/whitelist_host | sed -e "/^$/d" | sort -u | awk '{if (mode == 0 && dns1 != "") print "server=/."$1"/'$UP_CHINA_DNS1'"; if (mode == 0 && dns2 != "") print "server=/."$1"/'$UP_CHINA_DNS2'"; print "ipset=/."$1"/whitelist"}' mode=$chinadns_mode dns1=$UP_CHINA_DNS1 dns2=$UP_CHINA_DNS2 > $TMP_DNSMASQ_PATH/whitelist_host.conf
|
||||
uci show $CONFIG | grep "@nodes" | grep "address" | cut -d "'" -f 2 | sed 's/^\(https:\/\/\|http:\/\/\)//g' | awk -F '/' '{print $1}' | grep -v "google.c" | grep -E '.*\..*$' | grep '[a-zA-Z]$' | sort -u | awk '{if (dns1 != "") print "server=/."$1"/'$UP_CHINA_DNS1'"; if (dns2 != "") print "server=/."$1"/'$UP_CHINA_DNS2'"; print "ipset=/."$1"/vpsiplist"}' dns1=$UP_CHINA_DNS1 dns2=$UP_CHINA_DNS2 > $TMP_DNSMASQ_PATH/vpsiplist_host.conf
|
||||
uci show $CONFIG | grep ".address=" | cut -d "'" -f 2 | sed 's/^\(https:\/\/\|http:\/\/\)//g' | awk -F '/' '{print $1}' | grep -v "google.c" | grep -E '.*\..*$' | grep '[a-zA-Z]$' | sort -u | awk '{if (dns1 != "") print "server=/."$1"/'$UP_CHINA_DNS1'"; if (dns2 != "") print "server=/."$1"/'$UP_CHINA_DNS2'"; print "ipset=/."$1"/vpsiplist"}' dns1=$UP_CHINA_DNS1 dns2=$UP_CHINA_DNS2 > $TMP_DNSMASQ_PATH/vpsiplist_host.conf
|
||||
[ -f "$RULES_PATH/blacklist_host" -a -s "$RULES_PATH/blacklist_host" ] && cat $RULES_PATH/blacklist_host | sed -e "/^$/d" | sort -u | awk '{if (mode == 0) print "server=/."$1"/127.0.0.1#'$DNS_PORT'"; print "ipset=/."$1"/blacklist"}' mode=$chinadns_mode > $TMP_DNSMASQ_PATH/blacklist_host.conf
|
||||
if [ "$chinadns_mode" == 0 ]; then
|
||||
[ -f "$RULES_PATH/gfwlist.conf" -a -s "$RULES_PATH/gfwlist.conf" ] && ln -s $RULES_PATH/gfwlist.conf $TMP_DNSMASQ_PATH/gfwlist.conf
|
||||
@ -703,7 +659,6 @@ add_dnsmasq() {
|
||||
no-resolv
|
||||
EOF
|
||||
else
|
||||
# 防呆
|
||||
[ -z "$DEFAULT_DNS1" ] && {
|
||||
local tmp=$(get_host_ip ipv4 www.baidu.com 1)
|
||||
[ -z "$tmp" ] && {
|
||||
@ -728,9 +683,12 @@ gen_pdnsd_config() {
|
||||
mkdir -p $pdnsd_dir
|
||||
touch $pdnsd_dir/pdnsd.cache
|
||||
chown -R root.nogroup $pdnsd_dir
|
||||
local perm_cache=2048
|
||||
local _cache="on"
|
||||
[ "$DNS_CACHE" == "0" ] && _cache="off" && perm_cache=0
|
||||
cat > $pdnsd_dir/pdnsd.conf <<-EOF
|
||||
global {
|
||||
perm_cache = $2;
|
||||
perm_cache = $perm_cache;
|
||||
cache_dir = "$pdnsd_dir";
|
||||
run_as = "root";
|
||||
server_ip = 127.0.0.1;
|
||||
@ -748,7 +706,7 @@ gen_pdnsd_config() {
|
||||
}
|
||||
|
||||
EOF
|
||||
|
||||
|
||||
cat >> $pdnsd_dir/pdnsd.conf <<-EOF
|
||||
server {
|
||||
label = "node";
|
||||
@ -759,6 +717,7 @@ gen_pdnsd_config() {
|
||||
interval = 10m;
|
||||
uptest = none;
|
||||
purge_cache = off;
|
||||
caching = $_cache;
|
||||
}
|
||||
|
||||
EOF
|
||||
@ -918,7 +877,7 @@ boot() {
|
||||
start() {
|
||||
! load_config && return 1
|
||||
start_haproxy
|
||||
start_redir SOCKS tcp
|
||||
start_socks
|
||||
start_redir TCP tcp
|
||||
start_redir UDP udp
|
||||
start_dns
|
||||
@ -935,7 +894,7 @@ stop() {
|
||||
kill_all v2ray-plugin obfs-local
|
||||
ps -w | grep -v "grep" | grep $CONFIG/test.sh | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 &
|
||||
ps -w | grep -v "grep" | grep $CONFIG/monitor.sh | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 &
|
||||
ps -w | grep -v "grep" | grep -E "$TMP_PATH" | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 &
|
||||
ps -w | grep -v -E "grep|${TMP_PATH}_server" | grep -E "$TMP_PATH" | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 &
|
||||
ps -w | grep -v "grep" | grep "sleep 1m" | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 &
|
||||
rm -rf $TMP_DNSMASQ_PATH $TMP_PATH
|
||||
stop_crontab
|
||||
@ -948,8 +907,11 @@ case $1 in
|
||||
get_new_port)
|
||||
get_new_port $2 $3
|
||||
;;
|
||||
gen_start_config)
|
||||
gen_start_config $2 $3 $4 $5 $6 $7
|
||||
run_socks)
|
||||
run_socks $2 $3 $4 $5 $6
|
||||
;;
|
||||
run_redir)
|
||||
run_redir $2 $3 $4 $5 $6 $7
|
||||
;;
|
||||
node_switch)
|
||||
node_switch $2 $3 $4 $5
|
||||
|
||||
@ -1,74 +0,0 @@
|
||||
|
||||
config global
|
||||
option enabled '0'
|
||||
option tcp_node1 'nil'
|
||||
option udp_node1 'nil'
|
||||
option socks_node1 'nil'
|
||||
option dns_mode 'pdnsd'
|
||||
option up_china_dns 'default'
|
||||
option dns_forward '8.8.4.4'
|
||||
option use_tcp_node_resolve_dns '1'
|
||||
option tcp_proxy_mode 'chnroute'
|
||||
option udp_proxy_mode 'chnroute'
|
||||
option localhost_tcp_proxy_mode 'gfwlist'
|
||||
option localhost_udp_proxy_mode 'gfwlist'
|
||||
|
||||
config global_haproxy
|
||||
option balancing_enable '0'
|
||||
|
||||
config global_delay
|
||||
option auto_on '0'
|
||||
option start_daemon '0'
|
||||
option start_delay '1'
|
||||
|
||||
config global_forwarding
|
||||
option process '0'
|
||||
option tcp_no_redir_ports 'disable'
|
||||
option udp_no_redir_ports '80,443'
|
||||
option tcp_redir_ports '22,25,53,143,465,587,993,995,80,443'
|
||||
option udp_redir_ports '1:65535'
|
||||
option socks_proxy_port1 '1081'
|
||||
option socks_proxy_port2 '1082'
|
||||
option socks_proxy_port3 '1083'
|
||||
option proxy_ipv6 '0'
|
||||
|
||||
config global_other
|
||||
option use_tcping '1'
|
||||
option auto_ping '1'
|
||||
option tcp_node_num '1'
|
||||
option udp_node_num '1'
|
||||
option socks_node_num '1'
|
||||
option status_use_big_icon '1'
|
||||
option status_show_check_port '0'
|
||||
option status_show_ip111 '0'
|
||||
option compact_display_nodes '0'
|
||||
option show_group '0'
|
||||
option show_add_mode '0'
|
||||
|
||||
config global_rules
|
||||
option auto_update '0'
|
||||
option chnlist_update '1'
|
||||
option chnroute_update '1'
|
||||
option gfwlist_update '1'
|
||||
option gfwlist_version '2020-03-10'
|
||||
option chnroute_version '2020-03-10'
|
||||
option chnlist_version '2020-03-10'
|
||||
|
||||
config global_app
|
||||
option v2ray_file '/usr/bin/v2ray/'
|
||||
option kcptun_client_file '/usr/bin/kcptun-client'
|
||||
option brook_file '/usr/bin/brook'
|
||||
|
||||
config global_subscribe
|
||||
option subscribe_proxy '0'
|
||||
option auto_update_subscribe '0'
|
||||
option filter_enabled '1'
|
||||
option filter_keyword_discarded '1'
|
||||
list filter_keyword '过期时间'
|
||||
list filter_keyword '剩余流量'
|
||||
list filter_keyword 'QQ群'
|
||||
list filter_keyword '官网'
|
||||
|
||||
config auto_switch
|
||||
option testing_time '1'
|
||||
option enable '0'
|
||||
@ -137,26 +137,26 @@ load_acl() {
|
||||
eval TCP_NODE_TYPE=$(echo $(config_n_get $TCP_NODE type) | tr 'A-Z' 'a-z')
|
||||
local is_tproxy
|
||||
[ "$TCP_NODE_TYPE" == "brook" -a "$(config_n_get $TCP_NODE brook_protocol client)" == "client" ] && ipt_tmp=$ipt_m && is_tproxy="TPROXY"
|
||||
[ "$tcp_no_redir_ports" != "disable" ] && $ipt_tmp -A PSW_ACL $(comment "$remarks") $(factor $ip "-s") $(factor $mac "-m mac --mac-source") -p tcp -m multiport --dport $tcp_no_redir_ports -j RETURN
|
||||
[ "$tcp_no_redir_ports" != "disable" ] && $ipt_tmp -A PSW $(comment "$remarks") $(factor $ip "-s") $(factor $mac "-m mac --mac-source") -p tcp -m multiport --dport $tcp_no_redir_ports -j RETURN
|
||||
eval tcp_port=\$TCP_REDIR_PORT$tcp_node
|
||||
$ipt_tmp -A PSW_ACL $(comment "$remarks") -p tcp $(factor $ip "-s") $(factor $mac "-m mac --mac-source") $(factor $tcp_redir_ports "-m multiport --dport") $(dst $IPSET_BLACKLIST) $(REDIRECT $tcp_port $is_tproxy)
|
||||
$ipt_tmp -A PSW_ACL $(comment "$remarks") -p tcp $(factor $ip "-s") $(factor $mac "-m mac --mac-source") $(factor $tcp_redir_ports "-m multiport --dport") $(get_redirect_ipt $tcp_proxy_mode $tcp_port $is_tproxy)
|
||||
$ipt_tmp -A PSW $(comment "$remarks") -p tcp $(factor $ip "-s") $(factor $mac "-m mac --mac-source") $(factor $tcp_redir_ports "-m multiport --dport") $(dst $IPSET_BLACKLIST) $(REDIRECT $tcp_port $is_tproxy)
|
||||
$ipt_tmp -A PSW $(comment "$remarks") -p tcp $(factor $ip "-s") $(factor $mac "-m mac --mac-source") $(factor $tcp_redir_ports "-m multiport --dport") $(get_redirect_ipt $tcp_proxy_mode $tcp_port $is_tproxy)
|
||||
unset is_tproxy
|
||||
unset tcp_port
|
||||
}
|
||||
}
|
||||
$ipt_tmp -A PSW_ACL $(comment "$remarks") $(factor $ip "-s") $(factor $mac "-m mac --mac-source") -p tcp -j RETURN
|
||||
$ipt_tmp -A PSW $(comment "$remarks") $(factor $ip "-s") $(factor $mac "-m mac --mac-source") -p tcp -j RETURN
|
||||
|
||||
[ "$udp_proxy_mode" != "disable" ] && {
|
||||
[ "$UDP_NODE" != "nil" ] && {
|
||||
eval udp_port=\$UDP_REDIR_PORT$udp_node
|
||||
[ "$udp_no_redir_ports" != "disable" ] && $ipt_m -A PSW_ACL $(comment "$remarks") $(factor $ip "-s") $(factor $mac "-m mac --mac-source") -p udp -m multiport --dport $udp_no_redir_ports -j RETURN
|
||||
$ipt_m -A PSW_ACL $(comment "$remarks") -p udp $(factor $ip "-s") $(factor $mac "-m mac --mac-source") $(factor $UDP_REDIR_PORTS "-m multiport --dport") $(dst $IPSET_BLACKLIST) $(REDIRECT $udp_port TPROXY)
|
||||
$ipt_m -A PSW_ACL $(comment "$remarks") -p udp $(factor $ip "-s") $(factor $mac "-m mac --mac-source") $(factor $UDP_REDIR_PORTS "-m multiport --dport") $(get_redirect_ipt $udp_proxy_mode $udp_port TPROXY)
|
||||
[ "$udp_no_redir_ports" != "disable" ] && $ipt_m -A PSW $(comment "$remarks") $(factor $ip "-s") $(factor $mac "-m mac --mac-source") -p udp -m multiport --dport $udp_no_redir_ports -j RETURN
|
||||
$ipt_m -A PSW $(comment "$remarks") -p udp $(factor $ip "-s") $(factor $mac "-m mac --mac-source") $(factor $UDP_REDIR_PORTS "-m multiport --dport") $(dst $IPSET_BLACKLIST) $(REDIRECT $udp_port TPROXY)
|
||||
$ipt_m -A PSW $(comment "$remarks") -p udp $(factor $ip "-s") $(factor $mac "-m mac --mac-source") $(factor $UDP_REDIR_PORTS "-m multiport --dport") $(get_redirect_ipt $udp_proxy_mode $udp_port TPROXY)
|
||||
unset udp_port
|
||||
}
|
||||
}
|
||||
$ipt_m -A PSW_ACL $(comment "$remarks") $(factor $ip "-s") $(factor $mac "-m mac --mac-source") -p udp -j RETURN
|
||||
$ipt_m -A PSW $(comment "$remarks") $(factor $ip "-s") $(factor $mac "-m mac --mac-source") -p udp -j RETURN
|
||||
done
|
||||
}
|
||||
|
||||
@ -166,27 +166,28 @@ load_acl() {
|
||||
local TCP_NODE1_TYPE=$(echo $(config_n_get $TCP_NODE1 type) | tr 'A-Z' 'a-z')
|
||||
local is_tproxy
|
||||
[ "$TCP_NODE1_TYPE" == "brook" -a "$(config_n_get $TCP_NODE1 brook_protocol client)" == "client" ] && ipt_tmp=$ipt_m && is_tproxy="TPROXY"
|
||||
[ "$TCP_NO_REDIR_PORTS" != "disable" ] && $ipt_tmp -A PSW_ACL $(comment "默认") -p tcp -m multiport --dport $TCP_NO_REDIR_PORTS -j RETURN
|
||||
$ipt_tmp -A PSW_ACL $(comment "默认") -p tcp $(factor $TCP_REDIR_PORTS "-m multiport --dport") $(dst $IPSET_BLACKLIST) $(REDIRECT $TCP_REDIR_PORT1 $is_tproxy)
|
||||
$ipt_tmp -A PSW_ACL $(comment "默认") -p tcp $(factor $TCP_REDIR_PORTS "-m multiport --dport") $(get_redirect_ipt $TCP_PROXY_MODE $TCP_REDIR_PORT1 $is_tproxy)
|
||||
[ "$TCP_NO_REDIR_PORTS" != "disable" ] && $ipt_tmp -A PSW $(comment "默认") -p tcp -m multiport --dport $TCP_NO_REDIR_PORTS -j RETURN
|
||||
$ipt_tmp -A PSW $(comment "默认") -p tcp $(factor $TCP_REDIR_PORTS "-m multiport --dport") $(dst $IPSET_BLACKLIST) $(REDIRECT $TCP_REDIR_PORT1 $is_tproxy)
|
||||
$ipt_tmp -A PSW $(comment "默认") -p tcp $(factor $TCP_REDIR_PORTS "-m multiport --dport") $(get_redirect_ipt $TCP_PROXY_MODE $TCP_REDIR_PORT1 $is_tproxy)
|
||||
}
|
||||
$ipt_tmp -A PSW_ACL $(comment "默认") -p tcp -j RETURN
|
||||
$ipt_tmp -A PSW $(comment "默认") -p tcp -j RETURN
|
||||
echolog "TCP默认代理模式:$(get_action_chain_name $TCP_PROXY_MODE)"
|
||||
|
||||
# 加载UDP默认代理模式
|
||||
[ "$UDP_NODE1" != "nil" -a "$UDP_PROXY_MODE" != "disable" ] && {
|
||||
[ "$UDP_NO_REDIR_PORTS" != "disable" ] && $ipt_m -A PSW_ACL $(comment "默认") -p udp -m multiport --dport $UDP_NO_REDIR_PORTS -j RETURN
|
||||
$ipt_m -A PSW_ACL $(comment "默认") -p udp $(factor $UDP_REDIR_PORTS "-m multiport --dport") $(dst $IPSET_BLACKLIST) $(REDIRECT $UDP_REDIR_PORT1 TPROXY)
|
||||
$ipt_m -A PSW_ACL $(comment "默认") -p udp $(factor $UDP_REDIR_PORTS "-m multiport --dport") $(get_redirect_ipt $UDP_PROXY_MODE $UDP_REDIR_PORT1 TPROXY)
|
||||
[ "$UDP_NO_REDIR_PORTS" != "disable" ] && $ipt_m -A PSW $(comment "默认") -p udp -m multiport --dport $UDP_NO_REDIR_PORTS -j RETURN
|
||||
$ipt_m -A PSW $(comment "默认") -p udp $(factor $UDP_REDIR_PORTS "-m multiport --dport") $(dst $IPSET_BLACKLIST) $(REDIRECT $UDP_REDIR_PORT1 TPROXY)
|
||||
$ipt_m -A PSW $(comment "默认") -p udp $(factor $UDP_REDIR_PORTS "-m multiport --dport") $(get_redirect_ipt $UDP_PROXY_MODE $UDP_REDIR_PORT1 TPROXY)
|
||||
}
|
||||
$ipt_m -A PSW_ACL $(comment "默认") -p udp -j RETURN
|
||||
$ipt_m -A PSW $(comment "默认") -p udp -j RETURN
|
||||
echolog "UDP默认代理模式:$(get_action_chain_name $UDP_PROXY_MODE)"
|
||||
}
|
||||
|
||||
filter_vpsip() {
|
||||
echolog "开始过滤所有IPV4节点到白名单"
|
||||
uci show $CONFIG | grep "@nodes" | grep "address" | cut -d "'" -f 2 | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | sed -e "/^$/d" | sed -e "s/^/add $IPSET_VPSIPLIST &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R
|
||||
echolog "过滤所有IPV4节点完成"
|
||||
echolog "开始过滤所有节点到白名单"
|
||||
uci show $CONFIG | grep ".address=" | cut -d "'" -f 2 | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | sed -e "/^$/d" | sed -e "s/^/add $IPSET_VPSIPLIST &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R
|
||||
#uci show $CONFIG | grep ".address=" | cut -d "'" -f 2 | grep -E "([[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){0,7}::[a-f0-9]{0,4}(:[a-f0-9]{1,4}){0,7}])" | sed -e "/^$/d" | sed -e "s/^/add $IPSET_VPSIP6LIST &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R
|
||||
echolog "过滤所有节点完成"
|
||||
}
|
||||
|
||||
filter_node() {
|
||||
@ -199,37 +200,46 @@ filter_node() {
|
||||
local port=$(config_n_get $1 port)
|
||||
|
||||
if [ -n "$3" ] && [ "$3" == "1" ] && [ -n "$4" ]; then
|
||||
if [ "$i" == "$ipt_m" ]; then
|
||||
$i -I PSW_OUTPUT 2 -p $2 -d $address --dport $port $(REDIRECT 1 MARK)
|
||||
else
|
||||
$i -I PSW_OUTPUT 2 -p $2 -d $address --dport $port $(REDIRECT $4)
|
||||
fi
|
||||
is_exist=$($i -n -L PSW_OUTPUT 2>/dev/null | grep -c "$address:$port")
|
||||
[ "$is_exist" == 0 ] && {
|
||||
if [ "$i" == "$ipt_m" ]; then
|
||||
$i -I PSW_OUTPUT 2 $(comment "$address:$port") -p $2 -d $address --dport $port $(REDIRECT 1 MARK)
|
||||
else
|
||||
$i -I PSW_OUTPUT 2 $(comment "$address:$port") -p $2 -d $address --dport $port $(REDIRECT $4)
|
||||
fi
|
||||
}
|
||||
else
|
||||
is_exist=$($i -n -L PSW_OUTPUT 2>/dev/null | grep -c "$address:$port")
|
||||
[ "$is_exist" == 0 ] && {
|
||||
local ADD_INDEX=2
|
||||
local INDEX=$($i -n -L PSW_OUTPUT --line-numbers | grep "$IPSET_VPSIPLIST" | sed -n '$p' | awk '{print $1}')
|
||||
[ -n "$INDEX" ] && ADD_INDEX=$INDEX
|
||||
$i -I PSW_OUTPUT $ADD_INDEX -p $2 -d $address --dport $port $(comment "$address:$port") -j RETURN
|
||||
$i -I PSW_OUTPUT $ADD_INDEX $(comment "$address:$port") -p $2 -d $address --dport $port -j RETURN
|
||||
}
|
||||
fi
|
||||
}
|
||||
}
|
||||
local tmp_type=$(echo $(config_n_get $1 type) | tr 'A-Z' 'a-z')
|
||||
if [ "$tmp_type" == "v2ray_shunt" ]; then
|
||||
local v2ray_protocol=$(config_n_get $1 v2ray_protocol)
|
||||
if [ "$v2ray_protocol" == "_shunt" ]; then
|
||||
local default_node=$(config_n_get $1 default_node nil)
|
||||
filter_rules $default_node $2
|
||||
local default_node_address=$(get_host_ip ipv4 $(config_n_get $default_node address) 1)
|
||||
local default_node_port=$(config_n_get $default_node port)
|
||||
|
||||
local youtube_node=$(config_n_get $1 youtube_node)
|
||||
local youtube_proxy=$(config_n_get $1 youtube_proxy 0)
|
||||
[ "$default_node" == "$youtube_node" ] && youtube_proxy=0
|
||||
local netflix_node=$(config_n_get $1 netflix_node)
|
||||
local netflix_proxy=$(config_n_get $1 netflix_proxy 0)
|
||||
[ "$default_node" == "$netflix_node" ] && netflix_proxy=0
|
||||
filter_rules $(config_n_get $1 youtube_node) $2 $youtube_proxy $3
|
||||
filter_rules $(config_n_get $1 netflix_node) $2 $netflix_proxy $3
|
||||
|
||||
elif [ "$tmp_type" == "v2ray_balancing" ]; then
|
||||
local shunt_ids=$(uci show $CONFIG | grep "=shunt_rules" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}')
|
||||
for shunt_id in $shunt_ids; do
|
||||
local _proxy=$(config_n_get $1 "${shunt_id}_proxy" 0)
|
||||
local _node=$(config_n_get $1 "${shunt_id}" nil)
|
||||
[ "$_proxy" == 1 ] && {
|
||||
local _node_address=$(get_host_ip ipv4 $(config_n_get $_node address) 1)
|
||||
local _node_port=$(config_n_get $_node port)
|
||||
[ "$_node_address" == "$default_node_address" ] && [ "$_node_port" == "$default_node_port" ] && {
|
||||
_proxy=0
|
||||
}
|
||||
}
|
||||
filter_rules $(config_n_get $1 $shunt_id) $2 $_proxy $3
|
||||
done
|
||||
elif [ "$v2ray_protocol" == "_balancing" ]; then
|
||||
local balancing_node=$(config_n_get $1 v2ray_balancing_node)
|
||||
for node_id in $balancing_node
|
||||
do
|
||||
@ -282,7 +292,6 @@ add_firewall_rule() {
|
||||
$ipt_n -A PSW $(dst $IPSET_LANIPLIST) -j RETURN
|
||||
$ipt_n -A PSW $(dst $IPSET_VPSIPLIST) -j RETURN
|
||||
$ipt_n -A PSW $(dst $IPSET_WHITELIST) -j RETURN
|
||||
$ipt_n -N PSW_ACL
|
||||
|
||||
$ipt_n -N PSW_OUTPUT
|
||||
$ipt_n -A PSW_OUTPUT $(dst $IPSET_LANIPLIST) -j RETURN
|
||||
@ -293,7 +302,6 @@ add_firewall_rule() {
|
||||
$ipt_m -A PSW $(dst $IPSET_LANIPLIST) -j RETURN
|
||||
$ipt_m -A PSW $(dst $IPSET_VPSIPLIST) -j RETURN
|
||||
$ipt_m -A PSW $(dst $IPSET_WHITELIST) -j RETURN
|
||||
$ipt_m -N PSW_ACL
|
||||
|
||||
$ipt_m -N PSW_OUTPUT
|
||||
$ipt_m -A PSW_OUTPUT $(dst $IPSET_LANIPLIST) -j RETURN
|
||||
@ -302,13 +310,20 @@ add_firewall_rule() {
|
||||
|
||||
ip rule add fwmark 1 lookup 100
|
||||
ip route add local 0.0.0.0/0 dev lo table 100
|
||||
|
||||
for i in $(seq 1 $SOCKS_NODE_NUM); do
|
||||
eval node=\$SOCKS_NODE$i
|
||||
[ "$node" != "nil" ] && {
|
||||
filter_node $node tcp
|
||||
filter_node $node udp
|
||||
}
|
||||
|
||||
# 过滤Socks节点
|
||||
local ids=$(uci show $CONFIG | grep "=socks" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}')
|
||||
for id in $ids; do
|
||||
local enabled=$(config_n_get $id enabled 0)
|
||||
[ "$enabled" == "0" ] && continue
|
||||
local node=$(config_n_get $id node nil)
|
||||
if [ "$(echo $node | grep ^tcp)" ]; then
|
||||
local num=$(echo $node | sed "s/tcp//g")
|
||||
eval node=\$TCP_NODE$num
|
||||
fi
|
||||
[ "$node" == "nil" ] && continue
|
||||
filter_node $node tcp
|
||||
filter_node $node udp
|
||||
done
|
||||
|
||||
for i in $(seq 1 $TCP_NODE_NUM); do
|
||||
@ -319,42 +334,36 @@ add_firewall_rule() {
|
||||
|
||||
# 加载路由器自身代理 TCP
|
||||
if [ "$TCP_NODE1" != "nil" ]; then
|
||||
local ipt_tmp=$ipt_n
|
||||
local dns_l="PSW_OUTPUT"
|
||||
local dns_r=$(REDIRECT $TCP_REDIR_PORT1)
|
||||
local blist_r=$(REDIRECT $TCP_REDIR_PORT1)
|
||||
local p_r=$(get_redirect_ipt $LOCALHOST_TCP_PROXY_MODE $TCP_REDIR_PORT1)
|
||||
TCP_NODE1_TYPE=$(echo $(config_n_get $TCP_NODE1 type) | tr 'A-Z' 'a-z')
|
||||
if [ "$TCP_NODE1_TYPE" == "brook" -a "$(config_n_get $TCP_NODE1 brook_protocol client)" == "client" ]; then
|
||||
[ "$use_tcp_node_resolve_dns" == 1 -a -n "$DNS_FORWARD" ] && {
|
||||
for dns in $DNS_FORWARD ; do
|
||||
local dns_ip=$(echo $dns | sed "s/:/#/g" | awk -F "#" '{print $1}')
|
||||
ipset test $IPSET_LANIPLIST $dns_ip 2>/dev/null
|
||||
[ $? == 0 ] && continue
|
||||
local dns_port=$(echo $dns | sed "s/:/#/g" | awk -F "#" '{print $2}')
|
||||
[ -z "$dns_port" ] && dns_port=53
|
||||
$ipt_m -I PSW 2 -p tcp -d $dns_ip --dport $dns_port $(REDIRECT $TCP_REDIR_PORT1 TPROXY)
|
||||
done
|
||||
}
|
||||
$ipt_m -A OUTPUT -p tcp -j PSW_OUTPUT
|
||||
[ "$TCP_NO_REDIR_PORTS" != "disable" ] && $ipt_m -A PSW_OUTPUT -p tcp -m multiport --dport $TCP_NO_REDIR_PORTS -j RETURN
|
||||
$ipt_m -A PSW_OUTPUT -p tcp $(factor $TCP_REDIR_PORTS "-m multiport --dport") $(dst $IPSET_BLACKLIST) $(REDIRECT 1 MARK)
|
||||
$ipt_m -A PSW_OUTPUT -p tcp $(factor $TCP_REDIR_PORTS "-m multiport --dport") $(get_redirect_ipt $LOCALHOST_TCP_PROXY_MODE 1 MARK)
|
||||
else
|
||||
[ "$use_tcp_node_resolve_dns" == 1 -a -n "$DNS_FORWARD" ] && {
|
||||
for dns in $DNS_FORWARD ; do
|
||||
local dns_ip=$(echo $dns | sed "s/:/#/g" | awk -F "#" '{print $1}')
|
||||
ipset test $IPSET_LANIPLIST $dns_ip 2>/dev/null
|
||||
[ $? == 0 ] && continue
|
||||
local dns_port=$(echo $dns | sed "s/:/#/g" | awk -F "#" '{print $2}')
|
||||
[ -z "$dns_port" ] && dns_port=53
|
||||
local ADD_INDEX=2
|
||||
$ipt_n -I PSW_OUTPUT $ADD_INDEX -p tcp -d $dns_ip --dport $dns_port $(REDIRECT $TCP_REDIR_PORT1)
|
||||
done
|
||||
}
|
||||
$ipt_n -A OUTPUT -p tcp -j PSW_OUTPUT
|
||||
[ "$TCP_NO_REDIR_PORTS" != "disable" ] && $ipt_n -A PSW_OUTPUT -p tcp -m multiport --dport $TCP_NO_REDIR_PORTS -j RETURN
|
||||
$ipt_n -A PSW_OUTPUT -p tcp $(factor $TCP_REDIR_PORTS "-m multiport --dport") $(dst $IPSET_BLACKLIST) $(REDIRECT $TCP_REDIR_PORT1)
|
||||
$ipt_n -A PSW_OUTPUT -p tcp $(factor $TCP_REDIR_PORTS "-m multiport --dport") $(get_redirect_ipt $LOCALHOST_TCP_PROXY_MODE $TCP_REDIR_PORT1)
|
||||
if [ "$TCP_NODE1_TYPE" == "brook" ] && [ "$(config_n_get $TCP_NODE1 brook_protocol client)" == "client" ]; then
|
||||
ipt_tmp=$ipt_m
|
||||
dns_l="PSW"
|
||||
dns_r="$(REDIRECT $TCP_REDIR_PORT1 TPROXY)"
|
||||
blist_r=$(REDIRECT 1 MARK)
|
||||
p_r=$(get_redirect_ipt $LOCALHOST_TCP_PROXY_MODE 1 MARK)
|
||||
fi
|
||||
[ "$use_tcp_node_resolve_dns" == 1 -a -n "$DNS_FORWARD" ] && {
|
||||
for dns in $DNS_FORWARD ; do
|
||||
local dns_ip=$(echo $dns | sed "s/:/#/g" | awk -F "#" '{print $1}')
|
||||
ipset test $IPSET_LANIPLIST $dns_ip 2>/dev/null
|
||||
[ $? == 0 ] && continue
|
||||
local dns_port=$(echo $dns | sed "s/:/#/g" | awk -F "#" '{print $2}')
|
||||
[ -z "$dns_port" ] && dns_port=53
|
||||
$ipt_tmp -I $dns_l 2 -p tcp -d $dns_ip --dport $dns_port $dns_r
|
||||
[ "$ipt_tmp" == "$ipt_m" ] && $ipt_tmp -I PSW_OUTPUT 2 -p tcp -d $dns_ip --dport $dns_port $(REDIRECT 1 MARK)
|
||||
done
|
||||
}
|
||||
$ipt_tmp -A OUTPUT -p tcp -j PSW_OUTPUT
|
||||
[ "$TCP_NO_REDIR_PORTS" != "disable" ] && $ipt_tmp -A PSW_OUTPUT -p tcp -m multiport --dport $TCP_NO_REDIR_PORTS -j RETURN
|
||||
$ipt_tmp -A PSW_OUTPUT -p tcp $(factor $TCP_REDIR_PORTS "-m multiport --dport") $(dst $IPSET_BLACKLIST) $blist_r
|
||||
$ipt_tmp -A PSW_OUTPUT -p tcp $(factor $TCP_REDIR_PORTS "-m multiport --dport") $p_r
|
||||
fi
|
||||
|
||||
$ipt_n -A PSW -j PSW_ACL
|
||||
local PRE_INDEX=1
|
||||
ADBYBY_INDEX=$($ipt_n -L PREROUTING --line-numbers | grep "ADBYBY" | sed -n '$p' | awk '{print $1}')
|
||||
if [ -n "$ADBYBY_INDEX" ]; then
|
||||
@ -370,7 +379,6 @@ add_firewall_rule() {
|
||||
lan_ipv6=$(ip address show $lan_ifname | grep -w "inet6" | awk '{print $2}') #当前LAN IPv6段
|
||||
[ -n "$lan_ipv6" ] && {
|
||||
$ip6t_n -N PSW
|
||||
$ip6t_n -N PSW_ACL
|
||||
$ip6t_n -A PREROUTING -j PSW
|
||||
[ -n "$lan_ipv6" ] && {
|
||||
for ip in $lan_ipv6; do
|
||||
@ -387,6 +395,7 @@ add_firewall_rule() {
|
||||
for i in $(seq 1 $UDP_NODE_NUM); do
|
||||
eval node=\$UDP_NODE$i
|
||||
eval port=\$UDP_REDIR_PORT$i
|
||||
[ "$node" == "tcp" ] && eval node=\$TCP_NODE$i && eval port=\$TCP_REDIR_PORT$i
|
||||
[ "$node" != "nil" ] && filter_node $node udp $port
|
||||
done
|
||||
|
||||
@ -411,7 +420,6 @@ add_firewall_rule() {
|
||||
$ipt_m -A PSW_OUTPUT -p udp $(factor $UDP_REDIR_PORTS "-m multiport --dport") $(get_redirect_ipt $LOCALHOST_UDP_PROXY_MODE 1 MARK)
|
||||
fi
|
||||
|
||||
$ipt_m -A PSW -j PSW_ACL
|
||||
$ipt_m -A PREROUTING -j PSW
|
||||
|
||||
# 加载ACLS
|
||||
@ -426,20 +434,17 @@ del_firewall_rule() {
|
||||
$ipt_n -D PREROUTING -p tcp -j PSW 2>/dev/null
|
||||
$ipt_n -D OUTPUT -p tcp -j PSW_OUTPUT 2>/dev/null
|
||||
$ipt_n -F PSW 2>/dev/null && $ipt_n -X PSW 2>/dev/null
|
||||
$ipt_n -F PSW_ACL 2>/dev/null && $ipt_n -X PSW_ACL 2>/dev/null
|
||||
$ipt_n -F PSW_OUTPUT 2>/dev/null && $ipt_n -X PSW_OUTPUT 2>/dev/null
|
||||
|
||||
$ipt_m -D PREROUTING -j PSW 2>/dev/null
|
||||
$ipt_m -D OUTPUT -p tcp -j PSW_OUTPUT 2>/dev/null
|
||||
$ipt_m -D OUTPUT -p udp -j PSW_OUTPUT 2>/dev/null
|
||||
$ipt_m -F PSW 2>/dev/null && $ipt_m -X PSW 2>/dev/null
|
||||
$ipt_m -F PSW_ACL 2>/dev/null && $ipt_m -X PSW_ACL 2>/dev/null
|
||||
$ipt_m -F PSW_OUTPUT 2>/dev/null && $ipt_m -X PSW_OUTPUT 2>/dev/null
|
||||
|
||||
$ip6t_n -D PREROUTING -j PSW 2>/dev/null
|
||||
$ip6t_n -D OUTPUT -j PSW_OUTPUT 2>/dev/null
|
||||
$ip6t_n -F PSW 2>/dev/null && $ip6t_n -X PSW 2>/dev/null
|
||||
$ip6t_n -F PSW_ACL 2>/dev/null && $ip6t_n -X PSW_ACL 2>/dev/null
|
||||
$ip6t_n -F PSW_OUTPUT 2>/dev/null && $ip6t_n -X PSW_OUTPUT 2>/dev/null
|
||||
|
||||
ip rule del fwmark 1 lookup 100 2>/dev/null
|
||||
|
||||
@ -36,11 +36,6 @@ do
|
||||
eval UDP_NODE$i=$(config_t_get global udp_node$i nil)
|
||||
done
|
||||
|
||||
SOCKS_NODE_NUM=$(config_t_get global_other socks_node_num 1)
|
||||
for i in $(seq 1 $SOCKS_NODE_NUM); do
|
||||
eval SOCKS_NODE$i=$(config_t_get global socks_node$i nil)
|
||||
done
|
||||
|
||||
dns_mode=$(config_t_get global dns_mode)
|
||||
use_haproxy=$(config_t_get global_haproxy balancing_enable 0)
|
||||
|
||||
@ -51,13 +46,13 @@ do
|
||||
#kcptun
|
||||
use_kcp=$(config_n_get $tmp_node use_kcp 0)
|
||||
if [ $use_kcp -gt 0 ]; then
|
||||
icount=$(ps -w | grep -v grep | grep $RUN_BIN_PATH | grep kcptun_tcp_${i} | wc -l)
|
||||
icount=$(ps -w | grep -v grep | grep "$RUN_BIN_PATH/kcptun" | grep -i "tcp_${i}" | wc -l)
|
||||
if [ $icount = 0 ]; then
|
||||
/etc/init.d/passwall restart
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
icount=$(ps -w | grep -v grep | grep -v kcptun | grep $RUN_BIN_PATH | grep -i -E "TCP_${i}" | wc -l)
|
||||
icount=$(ps -w | grep -v -E 'grep|kcptun' | grep "$RUN_BIN_PATH" | grep -i "TCP_${i}" | wc -l)
|
||||
if [ $icount = 0 ]; then
|
||||
/etc/init.d/passwall restart
|
||||
exit 0
|
||||
@ -69,20 +64,9 @@ do
|
||||
for i in $(seq 1 $UDP_NODE_NUM); do
|
||||
eval tmp_node=\$UDP_NODE$i
|
||||
if [ "$tmp_node" != "nil" ]; then
|
||||
[ "$tmp_node" == "default" ] && tmp_node=$TCP_NODE1
|
||||
icount=$(ps -w | grep -v grep | grep $RUN_BIN_PATH | grep -i -E "UDP_${i}" | wc -l)
|
||||
if [ $icount = 0 ]; then
|
||||
/etc/init.d/passwall restart
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
#socks
|
||||
for i in $(seq 1 $SOCKS_NODE_NUM); do
|
||||
eval tmp_node=\$SOCKS_NODE$i
|
||||
if [ "$tmp_node" != "nil" ]; then
|
||||
icount=$(ps -w | grep -v grep | grep -v kcptun | grep $RUN_BIN_PATH | grep -i "SOCKS_${i}" | wc -l)
|
||||
[ "$tmp_node" == "tcp" ] && continue
|
||||
[ "$tmp_node" == "tcp_" ] && tmp_node=$TCP_NODE1
|
||||
icount=$(ps -w | grep -v grep | grep "$RUN_BIN_PATH" | grep -i "UDP_${i}" | wc -l)
|
||||
if [ $icount = 0 ]; then
|
||||
/etc/init.d/passwall restart
|
||||
exit 0
|
||||
@ -101,7 +85,7 @@ do
|
||||
|
||||
#haproxy
|
||||
if [ $use_haproxy -gt 0 ]; then
|
||||
icount=$(ps -w | grep -v grep | grep $RUN_BIN_PATH | grep haproxy | wc -l)
|
||||
icount=$(ps -w | grep -v grep | grep "$RUN_BIN_PATH/haproxy" | wc -l)
|
||||
if [ $icount = 0 ]; then
|
||||
/etc/init.d/passwall restart
|
||||
exit 0
|
||||
|
||||
@ -6,6 +6,49 @@ local ucic = luci.model.uci.cursor()
|
||||
local name = 'passwall'
|
||||
local arg1 = arg[1]
|
||||
|
||||
local rule_path = "/usr/share/" .. name .. "/rules"
|
||||
local url_main = 'https://cdn.jsdelivr.net/gh/hq450/fancyss/rules'
|
||||
local reboot = 0
|
||||
local gfwlist_update = 0
|
||||
local chnroute_update = 0
|
||||
local chnlist_update = 0
|
||||
|
||||
-- match comments/title/whitelist/ip address
|
||||
local comment_pattern = "^[!\\[@]+"
|
||||
local ip_pattern = "^%d+%.%d+%.%d+%.%d+"
|
||||
local domain_pattern = "([%w%-%_]+%.[%w%.%-%_]+)[%/%*]*"
|
||||
|
||||
-- gfwlist parameter
|
||||
local mydnsip = '127.0.0.1'
|
||||
local mydnsport = '7913'
|
||||
local ipsetname = 'gfwlist'
|
||||
|
||||
-- custom url
|
||||
local enable_custom_url = ucic:get_first(name, 'global_rules', "enable_custom_url", 0)
|
||||
local gfwlist_url = ucic:get_first(name, 'global_rules', "gfwlist_url", "https://cdn.jsdelivr.net/gh/Loukky/gfwlist-by-loukky/gfwlist.txt")
|
||||
local chnroute_url = ucic:get_first(name, 'global_rules', "chnroute_url", "https://ispip.clang.cn/all_cn.txt")
|
||||
local chnlist_url_1 = 'https://cdn.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/accelerated-domains.china.conf'
|
||||
local chnlist_url_2 = 'https://cdn.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/apple.china.conf'
|
||||
local chnlist_url_3 = 'https://cdn.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/google.china.conf'
|
||||
|
||||
local bc='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||||
|
||||
-- base64decoding
|
||||
local function base64_dec(data)
|
||||
data = string.gsub(data, '[^'..bc..'=]', '')
|
||||
return (data:gsub('.', function(x)
|
||||
if (x == '=') then return '' end
|
||||
local r,f='',(bc:find(x)-1)
|
||||
for i=6,1,-1 do r=r..(f%2^i-f%2^(i-1)>0 and '1' or '0') end
|
||||
return r;
|
||||
end):gsub('%d%d%d?%d?%d?%d?%d?%d?', function(x)
|
||||
if (#x ~= 8) then return '' end
|
||||
local c=0
|
||||
for i=1,8 do c=c+(x:sub(i,i)=='1' and 2^(8-i) or 0) end
|
||||
return string.char(c)
|
||||
end))
|
||||
end
|
||||
|
||||
local log = function(...)
|
||||
if arg1 then
|
||||
local result = os.date("%Y-%m-%d %H:%M:%S: ") ..
|
||||
@ -27,6 +70,7 @@ local function trim(text)
|
||||
if not text or text == "" then return "" end
|
||||
return (string.gsub(text, "^%s*(.-)%s*$", "%1"))
|
||||
end
|
||||
|
||||
-- wget
|
||||
local function wget(url, file)
|
||||
local cmd = "/usr/bin/wget --no-check-certificate -t 3 -T 10 -O"
|
||||
@ -39,12 +83,119 @@ local function wget(url, file)
|
||||
return trim(stdout)
|
||||
end
|
||||
|
||||
local rule_path = "/usr/share/" .. name .. "/rules"
|
||||
local url_main = "https://raw.githubusercontent.com/hq450/fancyss/master/rules"
|
||||
local reboot = 0
|
||||
local gfwlist_update = 0
|
||||
local chnroute_update = 0
|
||||
local chnlist_update = 0
|
||||
-- curl
|
||||
local function curl(url, file)
|
||||
local cmd = "curl -skL -w %{http_code} --retry 3 --connect-timeout 3 '" .. url .. "'"
|
||||
if file then
|
||||
cmd = cmd .. " -o " .. file
|
||||
end
|
||||
local stdout = luci.sys.exec(cmd)
|
||||
|
||||
if file then
|
||||
return tonumber(trim(stdout))
|
||||
else
|
||||
return trim(stdout)
|
||||
end
|
||||
end
|
||||
|
||||
--获取gfwlist
|
||||
local function fetch_gfwlist()
|
||||
--请求gfwlist
|
||||
local sret = curl(gfwlist_url, "/tmp/gfwlist.txt")
|
||||
if sret == 200 then
|
||||
--解码gfwlist
|
||||
local gfwlist = io.open("/tmp/gfwlist.txt", "r")
|
||||
local decode = base64_dec(gfwlist:read("*all"))
|
||||
gfwlist:close()
|
||||
--写回gfwlist
|
||||
gfwlist = io.open("/tmp/gfwlist.txt", "w")
|
||||
gfwlist:write(decode)
|
||||
gfwlist:close()
|
||||
end
|
||||
|
||||
return sret;
|
||||
end
|
||||
|
||||
--获取chnroute
|
||||
local function fetch_chnroute()
|
||||
--请求chnroute
|
||||
local sret = curl(chnroute_url, "/tmp/chnroute_tmp")
|
||||
return sret;
|
||||
end
|
||||
|
||||
--获取chnlist
|
||||
local function fetch_chnlist()
|
||||
--请求chnlist
|
||||
local sret = 0
|
||||
local sret1 = curl(chnlist_url_1, "/tmp/chnlist_1")
|
||||
local sret2 = curl(chnlist_url_2, "/tmp/chnlist_2")
|
||||
local sret3 = curl(chnlist_url_3, "/tmp/chnlist_3")
|
||||
|
||||
if sret1 == 200 and sret2 ==200 and sret3 == 200 then
|
||||
sret=200
|
||||
end
|
||||
return sret;
|
||||
end
|
||||
|
||||
--gfwlist转码至dnsmasq格式
|
||||
local function generate_gfwlist()
|
||||
local domains = {}
|
||||
local out = io.open("/tmp/gfwlist_tmp", "w")
|
||||
|
||||
for line in io.lines("/tmp/gfwlist.txt") do
|
||||
if not (string.find(line, comment_pattern) or string.find(line, ip_pattern)) then
|
||||
local start, finish, match = string.find(line, domain_pattern)
|
||||
if (start) then
|
||||
domains[match] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for k,v in pairs(domains) do
|
||||
out:write(string.format("server=/.%s/%s#%s\n", k,mydnsip,mydnsport))
|
||||
out:write(string.format("ipset=/.%s/%s\n", k,ipsetname))
|
||||
end
|
||||
|
||||
out:close()
|
||||
end
|
||||
|
||||
--处理合并chnlist列表
|
||||
local function generate_chnlist()
|
||||
local domains = {}
|
||||
local out = io.open("/tmp/cdn_tmp", "w")
|
||||
|
||||
for line in io.lines("/tmp/chnlist_1") do
|
||||
local start, finish, match = string.find(line, domain_pattern)
|
||||
if (start) then
|
||||
domains[match] = true
|
||||
end
|
||||
end
|
||||
|
||||
for line in io.lines("/tmp/chnlist_2") do
|
||||
local start, finish, match = string.find(line, domain_pattern)
|
||||
if (start) then
|
||||
domains[match] = true
|
||||
end
|
||||
end
|
||||
|
||||
for line in io.lines("/tmp/chnlist_3") do
|
||||
local start, finish, match = string.find(line, domain_pattern)
|
||||
if (start) then
|
||||
domains[match] = true
|
||||
end
|
||||
end
|
||||
|
||||
--写入临时文件
|
||||
for k,v in pairs(domains) do
|
||||
out:write(string.format("%s\n", k))
|
||||
end
|
||||
|
||||
out:close()
|
||||
|
||||
--删除重复条目并排序
|
||||
luci.sys.call("cat /tmp/cdn_tmp | sort -u > /tmp/chnlist_tmp")
|
||||
end
|
||||
|
||||
if arg[2] then
|
||||
if arg[2]:find("gfwlist") then
|
||||
gfwlist_update = 1
|
||||
@ -63,83 +214,161 @@ end
|
||||
if gfwlist_update == 0 and chnroute_update == 0 and chnlist_update == 0 then
|
||||
os.exit(0)
|
||||
end
|
||||
local version = wget(url_main .. "/version1")
|
||||
if version then
|
||||
|
||||
log("开始更新规则...")
|
||||
if tonumber(enable_custom_url) == 1 then
|
||||
local new_version = os.date("%Y-%m-%d")
|
||||
log("已启用自定义规则地址...")
|
||||
if tonumber(gfwlist_update) == 1 then
|
||||
local gfwlist = luci.sys.exec("echo -n $(echo '" .. version .. "' | sed -n 1p)")
|
||||
local new_version = luci.sys.exec("echo -n $(echo '" .. gfwlist .. "' | awk '{print $1}')")
|
||||
local new_md5 = luci.sys.exec("echo -n $(echo '" .. gfwlist .. "' | awk '{print $3}')")
|
||||
if new_version ~= "" and new_md5 ~= "" then
|
||||
local old_version = ucic:get_first(name, 'global_rules', "gfwlist_version", "nil")
|
||||
local old_md5 = luci.sys.exec("echo -n $(md5sum " .. rule_path .. "/gfwlist.conf | awk '{print $1}')")
|
||||
if old_md5 ~= new_md5 or old_version ~= new_version then
|
||||
log("开始更新gfwlist...")
|
||||
wget(url_main .. "/gfwlist.conf", "/tmp/gfwlist_tmp")
|
||||
local download_md5 = luci.sys.exec("echo -n $([ -f '/tmp/gfwlist_tmp' ] && md5sum /tmp/gfwlist_tmp | awk '{print $1}')")
|
||||
if download_md5 == new_md5 then
|
||||
luci.sys.exec("mv -f /tmp/gfwlist_tmp " .. rule_path .. "/gfwlist.conf")
|
||||
ucic:set(name, ucic:get_first(name, 'global_rules'), "gfwlist_version", new_version)
|
||||
reboot = 1
|
||||
log("更新gfwlist成功...")
|
||||
end
|
||||
log("开始更新gfwlist...")
|
||||
local old_md5 = luci.sys.exec("echo -n $(md5sum " .. rule_path .. "/gfwlist.conf | awk '{print $1}')")
|
||||
local status = fetch_gfwlist()
|
||||
if status == 200 then
|
||||
generate_gfwlist()
|
||||
local new_md5 = luci.sys.exec("echo -n $([ -f '/tmp/gfwlist_tmp' ] && md5sum /tmp/gfwlist_tmp | awk '{print $1}')")
|
||||
if old_md5 ~= new_md5 then
|
||||
luci.sys.exec("mv -f /tmp/gfwlist_tmp " .. rule_path .. "/gfwlist.conf")
|
||||
ucic:set(name, ucic:get_first(name, 'global_rules'), "gfwlist_version", new_version)
|
||||
reboot = 1
|
||||
log("更新gfwlist成功...")
|
||||
else
|
||||
log("gfwlist版本一致,不用更新。")
|
||||
end
|
||||
else
|
||||
log("gfwlist文件下载失败!")
|
||||
end
|
||||
os.remove("/tmp/gfwlist.txt")
|
||||
os.remove("/tmp/gfwlist_tmp")
|
||||
end
|
||||
|
||||
if tonumber(chnroute_update) == 1 then
|
||||
local chnroute = luci.sys.exec("echo -n $(echo '" .. version .. "' | sed -n 2p)")
|
||||
local new_version = luci.sys.exec("echo -n $(echo '" .. chnroute .. "' | awk '{print $1}')")
|
||||
local new_md5 = luci.sys.exec("echo -n $(echo '" .. chnroute .. "' | awk '{print $3}')")
|
||||
if new_version ~= "" and new_md5 ~= "" then
|
||||
local old_version = ucic:get_first(name, 'global_rules', "chnroute_version", "nil")
|
||||
local old_md5 = luci.sys.exec("echo -n $(md5sum " .. rule_path .. "/chnroute | awk '{print $1}')")
|
||||
if old_md5 ~= new_md5 or old_version ~= new_version then
|
||||
log("开始更新chnroute...")
|
||||
wget(url_main .. "/chnroute.txt", "/tmp/chnroute_tmp")
|
||||
local download_md5 = luci.sys.exec("echo -n $([ -f '/tmp/chnroute_tmp' ] && md5sum /tmp/chnroute_tmp | awk '{print $1}')")
|
||||
if download_md5 == new_md5 then
|
||||
luci.sys.exec("mv -f /tmp/chnroute_tmp " .. rule_path .. "/chnroute")
|
||||
ucic:set(name, ucic:get_first(name, 'global_rules'), "chnroute_version", new_version)
|
||||
reboot = 1
|
||||
log("更新chnroute成功...")
|
||||
end
|
||||
log("开始更新chnroute...")
|
||||
local old_md5 = luci.sys.exec("echo -n $(md5sum " .. rule_path .. "/chnroute | awk '{print $1}')")
|
||||
local status = fetch_chnroute()
|
||||
if status == 200 then
|
||||
local new_md5 = luci.sys.exec("echo -n $([ -f '/tmp/chnroute_tmp' ] && md5sum /tmp/chnroute_tmp | awk '{print $1}')")
|
||||
if old_md5 ~= new_md5 then
|
||||
luci.sys.exec("mv -f /tmp/chnroute_tmp " .. rule_path .. "/chnroute")
|
||||
ucic:set(name, ucic:get_first(name, 'global_rules'), "chnroute_version", new_version)
|
||||
reboot = 1
|
||||
log("更新chnroute成功...")
|
||||
else
|
||||
log("chnroute版本一致,不用更新。")
|
||||
end
|
||||
else
|
||||
log("chnroute文件下载失败!")
|
||||
end
|
||||
os.remove("/tmp/chnroute_tmp")
|
||||
end
|
||||
|
||||
|
||||
if tonumber(chnlist_update) == 1 then
|
||||
local chnlist = luci.sys.exec("echo -n $(echo '" .. version .. "' | sed -n 4p)")
|
||||
local new_version = luci.sys.exec("echo -n $(echo '" .. chnlist .. "' | awk '{print $1}')")
|
||||
local new_md5 = luci.sys.exec("echo -n $(echo '" .. chnlist .. "' | awk '{print $3}')")
|
||||
if new_version ~= "" and new_md5 ~= "" then
|
||||
local old_version = ucic:get_first(name, 'global_rules', "chnlist_version", "nil")
|
||||
local old_md5 = luci.sys.exec("echo -n $(md5sum " .. rule_path .. "/chnlist | awk '{print $1}')")
|
||||
if old_md5 ~= new_md5 or old_version ~= new_version then
|
||||
log("开始更新chnlist...")
|
||||
wget(url_main .. "/cdn.txt", "/tmp/chnlist_tmp")
|
||||
local download_md5 = luci.sys.exec("echo -n $([ -f '/tmp/chnlist_tmp' ] && md5sum /tmp/chnlist_tmp | awk '{print $1}')")
|
||||
if download_md5 == new_md5 then
|
||||
luci.sys.exec("mv -f /tmp/chnlist_tmp " .. rule_path .. "/chnlist")
|
||||
ucic:set(name, ucic:get_first(name, 'global_rules'), "chnlist_version", new_version)
|
||||
reboot = 1
|
||||
log("更新chnlist成功...")
|
||||
end
|
||||
log("开始更新chnlist...")
|
||||
local old_md5 = luci.sys.exec("echo -n $(md5sum " .. rule_path .. "/chnlist | awk '{print $1}')")
|
||||
local status = fetch_chnlist()
|
||||
if status == 200 then
|
||||
generate_chnlist()
|
||||
local new_md5 = luci.sys.exec("echo -n $([ -f '/tmp/chnlist_tmp' ] && md5sum /tmp/chnlist_tmp | awk '{print $1}')")
|
||||
if old_md5 ~= new_md5 then
|
||||
luci.sys.exec("mv -f /tmp/chnlist_tmp " .. rule_path .. "/chnlist")
|
||||
ucic:set(name, ucic:get_first(name, 'global_rules'), "chnlist_version", new_version)
|
||||
reboot = 1
|
||||
log("更新chnlist成功...")
|
||||
else
|
||||
log("chnlist版本一致,不用更新。")
|
||||
end
|
||||
else
|
||||
log("chnlist文件下载失败!")
|
||||
end
|
||||
os.remove("/tmp/chnlist_1")
|
||||
os.remove("/tmp/chnlist_2")
|
||||
os.remove("/tmp/chnlist_3")
|
||||
os.remove("/tmp/cdn_tmp")
|
||||
os.remove("/tmp/chnlist_tmp")
|
||||
end
|
||||
end
|
||||
|
||||
if (enable_custom_url) == 0 then
|
||||
local version = curl(url_main .. "/version1")
|
||||
if version and tonumber(version) ~= 0 then
|
||||
if tonumber(gfwlist_update) == 1 then
|
||||
log("开始更新gfwlist...")
|
||||
local gfwlist = luci.sys.exec("echo -n $(echo '" .. version .. "' | sed -n 1p)")
|
||||
local new_version = luci.sys.exec("echo -n $(echo '" .. gfwlist .. "' | awk '{print $1}')")
|
||||
local new_md5 = luci.sys.exec("echo -n $(echo '" .. gfwlist .. "' | awk '{print $3}')")
|
||||
if new_version ~= "" and new_md5 ~= "" then
|
||||
local old_version = ucic:get_first(name, 'global_rules', "gfwlist_version", "nil")
|
||||
local old_md5 = luci.sys.exec("echo -n $(md5sum " .. rule_path .. "/gfwlist.conf | awk '{print $1}')")
|
||||
if old_md5 ~= new_md5 or old_version ~= new_version then
|
||||
curl(url_main .. "/gfwlist.conf", "/tmp/gfwlist_tmp")
|
||||
local download_md5 = luci.sys.exec("echo -n $([ -f '/tmp/gfwlist_tmp' ] && md5sum /tmp/gfwlist_tmp | awk '{print $1}')")
|
||||
if download_md5 == new_md5 then
|
||||
luci.sys.exec("mv -f /tmp/gfwlist_tmp " .. rule_path .. "/gfwlist.conf")
|
||||
ucic:set(name, ucic:get_first(name, 'global_rules'), "gfwlist_version", new_version)
|
||||
reboot = 1
|
||||
log("更新gfwlist成功...")
|
||||
end
|
||||
else
|
||||
log("gfwlist版本一致,不用更新。")
|
||||
end
|
||||
else
|
||||
log("gfwlist文件下载失败!")
|
||||
end
|
||||
end
|
||||
|
||||
if tonumber(chnroute_update) == 1 and tonumber(enable_custom_url) == 0 then
|
||||
log("开始更新chnroute...")
|
||||
local chnroute = luci.sys.exec("echo -n $(echo '" .. version .. "' | sed -n 2p)")
|
||||
local new_version = luci.sys.exec("echo -n $(echo '" .. chnroute .. "' | awk '{print $1}')")
|
||||
local new_md5 = luci.sys.exec("echo -n $(echo '" .. chnroute .. "' | awk '{print $3}')")
|
||||
if new_version ~= "" and new_md5 ~= "" then
|
||||
local old_version = ucic:get_first(name, 'global_rules', "chnroute_version", "nil")
|
||||
local old_md5 = luci.sys.exec("echo -n $(md5sum " .. rule_path .. "/chnroute | awk '{print $1}')")
|
||||
if old_md5 ~= new_md5 or old_version ~= new_version then
|
||||
curl(url_main .. "/chnroute.txt", "/tmp/chnroute_tmp")
|
||||
local download_md5 = luci.sys.exec("echo -n $([ -f '/tmp/chnroute_tmp' ] && md5sum /tmp/chnroute_tmp | awk '{print $1}')")
|
||||
if download_md5 == new_md5 then
|
||||
luci.sys.exec("mv -f /tmp/chnroute_tmp " .. rule_path .. "/chnroute")
|
||||
ucic:set(name, ucic:get_first(name, 'global_rules'), "chnroute_version", new_version)
|
||||
reboot = 1
|
||||
log("更新chnroute成功...")
|
||||
end
|
||||
else
|
||||
log("chnroute版本一致,不用更新。")
|
||||
end
|
||||
else
|
||||
log("chnroute文件下载失败!")
|
||||
end
|
||||
end
|
||||
|
||||
if tonumber(chnlist_update) == 1 then
|
||||
log("开始更新chnlist...")
|
||||
local chnlist = luci.sys.exec("echo -n $(echo '" .. version .. "' | sed -n 4p)")
|
||||
local new_version = luci.sys.exec("echo -n $(echo '" .. chnlist .. "' | awk '{print $1}')")
|
||||
local new_md5 = luci.sys.exec("echo -n $(echo '" .. chnlist .. "' | awk '{print $3}')")
|
||||
if new_version ~= "" and new_md5 ~= "" then
|
||||
local old_version = ucic:get_first(name, 'global_rules', "chnlist_version", "nil")
|
||||
local old_md5 = luci.sys.exec("echo -n $(md5sum " .. rule_path .. "/chnlist | awk '{print $1}')")
|
||||
if old_md5 ~= new_md5 or old_version ~= new_version then
|
||||
curl(url_main .. "/cdn.txt", "/tmp/chnlist_tmp")
|
||||
local download_md5 = luci.sys.exec("echo -n $([ -f '/tmp/chnlist_tmp' ] && md5sum /tmp/chnlist_tmp | awk '{print $1}')")
|
||||
if download_md5 == new_md5 then
|
||||
luci.sys.exec("mv -f /tmp/chnlist_tmp " .. rule_path .. "/chnlist")
|
||||
ucic:set(name, ucic:get_first(name, 'global_rules'), "chnlist_version", new_version)
|
||||
reboot = 1
|
||||
log("更新chnlist成功...")
|
||||
end
|
||||
else
|
||||
log("chnlist版本一致,不用更新。")
|
||||
end
|
||||
else
|
||||
log("chnlist文件下载失败!")
|
||||
end
|
||||
end
|
||||
else
|
||||
log("版本信息下载失败!")
|
||||
end
|
||||
end
|
||||
|
||||
ucic:set(name, ucic:get_first(name, 'global_rules'), "gfwlist_update", gfwlist_update)
|
||||
ucic:set(name, ucic:get_first(name, 'global_rules'), "chnroute_update", chnroute_update)
|
||||
ucic:set(name, ucic:get_first(name, 'global_rules'), "chnlist_update", chnlist_update)
|
||||
@ -149,4 +378,5 @@ luci.sys.call("uci commit " .. name)
|
||||
if reboot == 1 then
|
||||
log("重启服务,应用新的规则。")
|
||||
luci.sys.call("/usr/share/" .. name .. "/iptables.sh flush_ipset && /etc/init.d/" .. name .. " restart")
|
||||
end
|
||||
end
|
||||
log("规则脚本执行完毕...")
|
||||
File diff suppressed because it is too large
Load Diff
@ -71,12 +71,12 @@
|
||||
1.202.0.0/15
|
||||
1.204.0.0/14
|
||||
2.20.54.23
|
||||
3.5.214.0/23
|
||||
3.5.216.0/24
|
||||
8.128.0.0/10
|
||||
8.209.36.0/22
|
||||
8.209.40.0/21
|
||||
8.209.48.0/20
|
||||
8.209.192.0/18
|
||||
8.210.0.0/15
|
||||
8.211.0.0/16
|
||||
8.212.0.0/14
|
||||
8.216.0.0/13
|
||||
14.0.0.0/21
|
||||
@ -98,6 +98,7 @@
|
||||
14.196.0.0/15
|
||||
14.204.0.0/15
|
||||
14.208.0.0/12
|
||||
20.62.0.0/24
|
||||
20.81.0.0/24
|
||||
20.134.160.0/20
|
||||
20.139.160.0/20
|
||||
@ -190,7 +191,15 @@
|
||||
39.0.64.0/18
|
||||
39.0.128.0/17
|
||||
39.64.0.0/11
|
||||
39.96.0.0/13
|
||||
39.96.0.0/16
|
||||
39.97.0.0/17
|
||||
39.97.128.0/18
|
||||
39.97.192.0/21
|
||||
39.97.200.0/22
|
||||
39.97.208.0/20
|
||||
39.97.224.0/19
|
||||
39.98.0.0/15
|
||||
39.100.0.0/14
|
||||
39.104.0.0/14
|
||||
39.108.0.0/16
|
||||
39.109.120.0/23
|
||||
@ -436,7 +445,7 @@
|
||||
43.242.16.0/20
|
||||
43.242.48.0/22
|
||||
43.242.53.0/24
|
||||
43.242.54.0/23
|
||||
43.242.54.0/24
|
||||
43.242.56.0/21
|
||||
43.242.64.0/22
|
||||
43.242.72.0/21
|
||||
@ -465,6 +474,7 @@
|
||||
43.246.0.0/18
|
||||
43.246.64.0/19
|
||||
43.246.96.0/22
|
||||
43.246.147.0/24
|
||||
43.246.228.0/22
|
||||
43.247.4.0/22
|
||||
43.247.8.0/22
|
||||
@ -580,6 +590,8 @@
|
||||
45.40.208.0/21
|
||||
45.40.224.0/19
|
||||
45.65.16.0/20
|
||||
45.87.53.0/24
|
||||
45.87.54.0/23
|
||||
45.112.132.0/22
|
||||
45.112.188.0/22
|
||||
45.112.208.0/22
|
||||
@ -956,6 +968,7 @@
|
||||
82.156.0.0/15
|
||||
87.254.207.0/24
|
||||
91.223.53.0/24
|
||||
91.234.36.0/24
|
||||
91.239.190.0/24
|
||||
93.183.14.0/24
|
||||
93.183.18.0/24
|
||||
@ -965,11 +978,13 @@
|
||||
101.2.172.0/22
|
||||
101.4.0.0/14
|
||||
101.16.0.0/12
|
||||
101.32.0.0/14
|
||||
101.32.112.0/20
|
||||
101.32.128.0/17
|
||||
101.33.0.0/16
|
||||
101.34.0.0/15
|
||||
101.36.0.0/18
|
||||
101.36.64.0/20
|
||||
101.36.88.0/21
|
||||
101.36.96.0/19
|
||||
101.36.128.0/17
|
||||
101.37.0.0/16
|
||||
101.38.0.0/15
|
||||
@ -1082,7 +1097,7 @@
|
||||
103.4.168.0/22
|
||||
103.4.184.0/22
|
||||
103.5.36.0/22
|
||||
103.5.52.0/23
|
||||
103.5.52.0/24
|
||||
103.5.56.0/22
|
||||
103.5.152.0/22
|
||||
103.5.168.0/22
|
||||
@ -1542,7 +1557,6 @@
|
||||
103.68.100.0/22
|
||||
103.68.128.0/22
|
||||
103.69.16.0/22
|
||||
103.69.212.0/23
|
||||
103.70.8.0/22
|
||||
103.70.148.0/22
|
||||
103.70.236.0/22
|
||||
@ -1629,7 +1643,6 @@
|
||||
103.79.188.0/22
|
||||
103.79.192.0/20
|
||||
103.79.208.0/21
|
||||
103.79.243.0/24
|
||||
103.80.44.0/22
|
||||
103.80.72.0/22
|
||||
103.80.176.0/21
|
||||
@ -1888,7 +1901,6 @@
|
||||
103.107.208.0/20
|
||||
103.108.52.0/22
|
||||
103.108.160.0/21
|
||||
103.108.194.0/24
|
||||
103.108.196.0/22
|
||||
103.108.208.0/21
|
||||
103.108.224.0/22
|
||||
@ -1897,7 +1909,7 @@
|
||||
103.109.20.0/22
|
||||
103.109.48.0/22
|
||||
103.109.88.0/22
|
||||
103.109.106.0/23
|
||||
103.109.107.0/24
|
||||
103.109.248.0/22
|
||||
103.110.32.0/22
|
||||
103.110.92.0/22
|
||||
@ -2050,7 +2062,6 @@
|
||||
103.138.248.0/23
|
||||
103.139.22.0/23
|
||||
103.139.134.0/23
|
||||
103.139.136.0/23
|
||||
103.139.172.0/23
|
||||
103.139.204.0/23
|
||||
103.139.212.0/23
|
||||
@ -2075,7 +2086,7 @@
|
||||
103.142.156.0/23
|
||||
103.142.180.0/23
|
||||
103.142.186.0/23
|
||||
103.142.220.0/23
|
||||
103.142.221.0/24
|
||||
103.142.230.0/24
|
||||
103.142.234.0/23
|
||||
103.142.238.0/23
|
||||
@ -2092,16 +2103,14 @@
|
||||
103.144.136.0/23
|
||||
103.144.158.0/23
|
||||
103.145.40.0/22
|
||||
103.145.73.0/24
|
||||
103.145.80.0/23
|
||||
103.145.90.0/23
|
||||
103.145.92.0/22
|
||||
103.145.98.0/23
|
||||
103.145.107.0/24
|
||||
103.145.188.0/23
|
||||
103.146.6.0/23
|
||||
103.146.72.0/23
|
||||
103.146.90.0/23
|
||||
103.146.91.0/24
|
||||
103.146.126.0/23
|
||||
103.146.138.0/23
|
||||
103.146.236.0/23
|
||||
@ -2110,6 +2119,28 @@
|
||||
103.147.198.0/23
|
||||
103.147.206.0/23
|
||||
103.148.174.0/23
|
||||
103.149.6.0/23
|
||||
103.149.17.0/24
|
||||
103.149.44.0/23
|
||||
103.149.190.0/23
|
||||
103.149.210.0/23
|
||||
103.149.214.0/23
|
||||
103.149.220.0/23
|
||||
103.149.242.0/23
|
||||
103.149.244.0/22
|
||||
103.149.248.0/23
|
||||
103.150.24.0/23
|
||||
103.150.66.0/23
|
||||
103.150.72.0/23
|
||||
103.150.122.0/23
|
||||
103.150.126.0/23
|
||||
103.150.128.0/22
|
||||
103.150.146.0/23
|
||||
103.150.164.0/23
|
||||
103.150.172.0/23
|
||||
103.150.200.0/23
|
||||
103.150.210.0/23
|
||||
103.150.216.0/23
|
||||
103.192.0.0/19
|
||||
103.192.48.0/21
|
||||
103.192.56.0/22
|
||||
@ -2161,7 +2192,6 @@
|
||||
103.198.200.0/22
|
||||
103.198.216.0/21
|
||||
103.198.224.0/20
|
||||
103.198.240.0/21
|
||||
103.199.164.0/22
|
||||
103.199.196.0/22
|
||||
103.199.228.0/22
|
||||
@ -2343,7 +2373,8 @@
|
||||
103.220.160.0/19
|
||||
103.220.192.0/21
|
||||
103.220.200.0/22
|
||||
103.220.240.0/20
|
||||
103.220.240.0/21
|
||||
103.220.252.0/22
|
||||
103.221.0.0/19
|
||||
103.221.32.0/21
|
||||
103.221.88.0/21
|
||||
@ -2383,6 +2414,7 @@
|
||||
103.224.220.0/22
|
||||
103.224.224.0/21
|
||||
103.224.232.0/22
|
||||
103.225.32.0/22
|
||||
103.226.40.0/22
|
||||
103.226.56.0/21
|
||||
103.226.80.0/22
|
||||
@ -2454,7 +2486,7 @@
|
||||
103.235.56.0/21
|
||||
103.235.80.0/22
|
||||
103.235.85.0/24
|
||||
103.235.86.0/23
|
||||
103.235.87.0/24
|
||||
103.235.128.0/20
|
||||
103.235.144.0/21
|
||||
103.235.184.0/22
|
||||
@ -2636,7 +2668,12 @@
|
||||
106.2.16.0/20
|
||||
106.2.32.0/19
|
||||
106.2.64.0/18
|
||||
106.2.128.0/17
|
||||
106.2.128.0/20
|
||||
106.2.144.0/21
|
||||
106.2.152.0/22
|
||||
106.2.156.0/23
|
||||
106.2.160.0/19
|
||||
106.2.192.0/18
|
||||
106.3.16.0/20
|
||||
106.3.32.0/19
|
||||
106.3.64.0/20
|
||||
@ -2850,7 +2887,6 @@
|
||||
114.28.128.0/18
|
||||
114.28.192.0/19
|
||||
114.28.232.0/22
|
||||
114.28.236.0/23
|
||||
114.28.240.0/20
|
||||
114.31.64.0/21
|
||||
114.54.0.0/15
|
||||
@ -3160,11 +3196,6 @@
|
||||
118.191.248.0/21
|
||||
118.192.0.0/16
|
||||
118.193.0.0/22
|
||||
118.193.32.0/20
|
||||
118.193.56.0/21
|
||||
118.193.68.0/22
|
||||
118.193.72.0/24
|
||||
118.193.77.0/24
|
||||
118.193.96.0/19
|
||||
118.194.0.0/17
|
||||
118.194.128.0/18
|
||||
@ -3353,7 +3384,9 @@
|
||||
121.101.0.0/18
|
||||
121.101.208.0/20
|
||||
121.192.0.0/13
|
||||
121.200.192.0/21
|
||||
121.200.192.0/23
|
||||
121.200.194.0/24
|
||||
121.200.196.0/22
|
||||
121.201.0.0/16
|
||||
121.204.0.0/14
|
||||
121.224.0.0/12
|
||||
@ -3362,14 +3395,14 @@
|
||||
122.0.64.0/18
|
||||
122.0.128.0/17
|
||||
122.4.0.0/14
|
||||
122.9.0.0/16
|
||||
122.10.132.0/23
|
||||
122.10.136.0/23
|
||||
122.10.196.0/23
|
||||
122.10.216.0/22
|
||||
122.10.228.0/22
|
||||
122.10.232.0/21
|
||||
122.10.240.0/21
|
||||
122.10.248.0/22
|
||||
122.10.250.0/23
|
||||
122.11.0.0/17
|
||||
122.12.0.0/15
|
||||
122.14.0.0/17
|
||||
@ -3391,7 +3424,6 @@
|
||||
122.112.0.0/18
|
||||
122.112.64.0/19
|
||||
122.112.96.0/22
|
||||
122.112.107.0/24
|
||||
122.112.118.0/24
|
||||
122.112.122.0/24
|
||||
122.112.125.0/24
|
||||
@ -3434,7 +3466,13 @@
|
||||
123.49.136.0/22
|
||||
123.49.152.0/21
|
||||
123.49.160.0/19
|
||||
123.49.192.0/18
|
||||
123.49.192.0/19
|
||||
123.49.224.0/20
|
||||
123.49.240.0/23
|
||||
123.49.243.0/24
|
||||
123.49.245.0/24
|
||||
123.49.246.0/23
|
||||
123.49.248.0/21
|
||||
123.50.160.0/19
|
||||
123.52.0.0/14
|
||||
123.56.0.0/15
|
||||
@ -3443,7 +3481,8 @@
|
||||
123.58.80.0/21
|
||||
123.58.88.0/22
|
||||
123.58.96.0/19
|
||||
123.58.128.0/17
|
||||
123.58.128.0/18
|
||||
123.58.224.0/19
|
||||
123.59.0.0/16
|
||||
123.61.0.0/16
|
||||
123.62.0.0/16
|
||||
@ -3509,7 +3548,10 @@
|
||||
124.68.0.0/17
|
||||
124.68.128.0/18
|
||||
124.68.192.0/19
|
||||
124.68.224.0/20
|
||||
124.68.224.0/23
|
||||
124.68.226.0/24
|
||||
124.68.228.0/22
|
||||
124.68.232.0/21
|
||||
124.68.240.0/23
|
||||
124.68.242.0/24
|
||||
124.68.244.0/23
|
||||
@ -3589,22 +3631,23 @@
|
||||
129.204.0.0/16
|
||||
129.211.0.0/16
|
||||
129.223.254.0/24
|
||||
129.227.99.0/24
|
||||
130.36.146.0/23
|
||||
130.214.218.0/23
|
||||
131.228.96.0/24
|
||||
131.253.12.0/29
|
||||
131.253.12.80/28
|
||||
131.253.12.240/29
|
||||
132.159.251.0/24
|
||||
132.232.0.0/16
|
||||
132.237.134.0/24
|
||||
132.237.150.0/24
|
||||
134.175.0.0/16
|
||||
135.84.247.0/24
|
||||
135.84.255.0/24
|
||||
135.159.208.0/20
|
||||
135.244.80.0/20
|
||||
137.59.59.0/24
|
||||
137.59.88.0/22
|
||||
138.32.244.0/22
|
||||
138.32.244.0/24
|
||||
139.5.56.0/21
|
||||
139.5.80.0/22
|
||||
139.5.92.0/22
|
||||
@ -3756,6 +3799,7 @@
|
||||
150.242.232.0/21
|
||||
150.242.240.0/21
|
||||
150.242.248.0/22
|
||||
150.248.0.0/16
|
||||
150.255.0.0/16
|
||||
152.32.178.0/23
|
||||
152.104.128.0/17
|
||||
@ -3796,6 +3840,7 @@
|
||||
157.148.0.0/16
|
||||
157.156.0.0/16
|
||||
157.255.0.0/16
|
||||
158.116.80.0/22
|
||||
159.75.0.0/16
|
||||
159.221.232.0/22
|
||||
159.226.0.0/16
|
||||
@ -3836,7 +3881,6 @@
|
||||
163.53.160.0/20
|
||||
163.53.188.0/22
|
||||
163.53.220.0/22
|
||||
163.53.236.0/22
|
||||
163.53.240.0/22
|
||||
163.116.202.0/23
|
||||
163.125.0.0/16
|
||||
@ -3846,7 +3890,16 @@
|
||||
163.204.0.0/16
|
||||
163.244.246.0/24
|
||||
164.52.80.0/24
|
||||
165.84.251.0/25
|
||||
165.84.251.128/26
|
||||
165.84.251.192/27
|
||||
165.84.251.224/28
|
||||
165.84.251.240/29
|
||||
165.84.251.248/30
|
||||
165.84.251.253
|
||||
165.84.251.254/31
|
||||
165.156.30.0/24
|
||||
165.254.82.27
|
||||
166.111.0.0/16
|
||||
167.139.0.0/16
|
||||
167.189.0.0/16
|
||||
@ -4031,7 +4084,6 @@
|
||||
192.102.204.0/22
|
||||
192.124.154.0/24
|
||||
192.137.31.0/24
|
||||
192.139.136.0/24
|
||||
192.140.128.0/21
|
||||
192.140.136.0/22
|
||||
192.140.156.0/22
|
||||
@ -4044,12 +4096,15 @@
|
||||
193.9.22.0/24
|
||||
193.17.120.0/22
|
||||
193.20.64.0/22
|
||||
193.32.54.0/24
|
||||
193.112.0.0/16
|
||||
193.143.92.0/24
|
||||
193.200.196.0/24
|
||||
193.200.222.160/28
|
||||
194.138.136.0/24
|
||||
194.138.202.0/23
|
||||
194.138.245.0/24
|
||||
195.142.215.0/24
|
||||
198.175.100.0/22
|
||||
198.208.17.0/24
|
||||
198.208.19.0/24
|
||||
@ -4409,6 +4464,16 @@
|
||||
202.146.188.0/22
|
||||
202.146.196.0/22
|
||||
202.146.200.0/21
|
||||
202.147.12.0/26
|
||||
202.147.12.64/27
|
||||
202.147.12.96/28
|
||||
202.147.12.128/29
|
||||
202.147.12.136/30
|
||||
202.147.12.140/31
|
||||
202.147.12.142
|
||||
202.147.12.144/28
|
||||
202.147.12.160/27
|
||||
202.147.12.192/26
|
||||
202.147.144.0/20
|
||||
202.148.32.0/20
|
||||
202.148.64.0/18
|
||||
@ -4429,7 +4494,6 @@
|
||||
202.157.192.0/19
|
||||
202.158.160.0/19
|
||||
202.158.242.0/24
|
||||
202.160.140.0/22
|
||||
202.160.156.0/22
|
||||
202.160.176.0/20
|
||||
202.162.67.0/24
|
||||
@ -4854,7 +4918,16 @@
|
||||
203.22.163.0/24
|
||||
203.22.166.0/24
|
||||
203.22.170.0/24
|
||||
203.22.176.0/21
|
||||
203.22.176.0/22
|
||||
203.22.180.0/23
|
||||
203.22.182.0/30
|
||||
203.22.182.6/31
|
||||
203.22.182.8/29
|
||||
203.22.182.16/28
|
||||
203.22.182.32/27
|
||||
203.22.182.64/26
|
||||
203.22.182.128/25
|
||||
203.22.183.0/24
|
||||
203.22.194.0/24
|
||||
203.22.242.0/23
|
||||
203.22.245.0/24
|
||||
@ -4963,7 +5036,6 @@
|
||||
203.26.148.0/23
|
||||
203.26.154.0/24
|
||||
203.26.158.0/23
|
||||
203.26.161.0/24
|
||||
203.26.170.0/24
|
||||
203.26.173.0/24
|
||||
203.26.176.0/24
|
||||
@ -5180,7 +5252,9 @@
|
||||
203.34.161.0/24
|
||||
203.34.162.0/24
|
||||
203.34.187.0/24
|
||||
203.34.192.0/21
|
||||
203.34.192.0/22
|
||||
203.34.197.0/24
|
||||
203.34.198.0/23
|
||||
203.34.204.0/22
|
||||
203.34.232.0/24
|
||||
203.34.240.0/24
|
||||
@ -5372,7 +5446,6 @@
|
||||
203.119.113.0/24
|
||||
203.119.114.0/23
|
||||
203.119.116.0/22
|
||||
203.119.120.0/21
|
||||
203.119.128.0/17
|
||||
203.123.58.0/24
|
||||
203.128.32.0/19
|
||||
@ -5442,7 +5515,9 @@
|
||||
203.193.224.0/19
|
||||
203.195.64.0/19
|
||||
203.195.128.0/17
|
||||
203.196.0.0/20
|
||||
203.196.0.0/21
|
||||
203.196.10.0/23
|
||||
203.196.12.0/22
|
||||
203.196.28.0/22
|
||||
203.201.181.0/24
|
||||
203.201.182.0/24
|
||||
@ -5458,14 +5533,9 @@
|
||||
203.212.80.0/20
|
||||
203.217.164.0/22
|
||||
203.223.0.0/20
|
||||
203.223.16.0/24
|
||||
203.223.22.0/24
|
||||
204.55.160.0/24
|
||||
204.74.96.0/24
|
||||
204.114.176.0/23
|
||||
206.219.44.0/23
|
||||
206.219.50.0/23
|
||||
206.219.52.0/23
|
||||
207.89.20.0/24
|
||||
210.2.0.0/23
|
||||
210.2.2.0/24
|
||||
@ -5474,7 +5544,6 @@
|
||||
210.2.8.0/21
|
||||
210.2.24.0/21
|
||||
210.5.0.0/19
|
||||
210.5.56.0/24
|
||||
210.5.60.0/24
|
||||
210.5.128.0/19
|
||||
210.7.56.0/21
|
||||
@ -5572,6 +5641,7 @@
|
||||
211.160.0.0/13
|
||||
212.64.0.0/17
|
||||
212.129.128.0/17
|
||||
213.199.169.0/24
|
||||
218.0.0.0/12
|
||||
218.16.0.0/13
|
||||
218.24.0.0/14
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,6 @@
|
||||
#!/usr/bin/lua
|
||||
|
||||
------------------------------------------------
|
||||
-- This file from luci-app-ssr-plus transplant to luci-app-passwall
|
||||
-- This file is part of the luci-app-ssr-plus subscribe.lua
|
||||
-- @author William Chan <root@williamchan.me>
|
||||
------------------------------------------------
|
||||
require 'nixio'
|
||||
@ -10,6 +8,7 @@ require 'uci'
|
||||
require 'luci.util'
|
||||
require 'luci.jsonc'
|
||||
require 'luci.sys'
|
||||
local _api = require "luci.model.cbi.passwall.api.api"
|
||||
|
||||
-- these global functions are accessed all the time by the event handler
|
||||
-- so caching them is worth the effort
|
||||
@ -23,6 +22,7 @@ local application = 'passwall'
|
||||
local uciType = 'nodes'
|
||||
local ucic2 = uci.cursor()
|
||||
local arg2 = arg[2]
|
||||
local allowInsecure_default = ucic2:get(application, "@global_subscribe[0]", "allowInsecure")
|
||||
ucic2:revert(application)
|
||||
|
||||
local log = function(...)
|
||||
@ -68,7 +68,22 @@ do
|
||||
end
|
||||
import_config("tcp")
|
||||
import_config("udp")
|
||||
import_config("socks")
|
||||
|
||||
ucic2:foreach(application, "socks", function(t)
|
||||
local node = t.node
|
||||
local currentNode
|
||||
if node then
|
||||
currentNode = ucic2:get_all(application, node)
|
||||
end
|
||||
CONFIG[#CONFIG + 1] = {
|
||||
log = true,
|
||||
remarks = "Socks节点" .. t[".name"],
|
||||
currentNode = currentNode,
|
||||
set = function(server)
|
||||
ucic2:set(application, t[".name"], "node", server)
|
||||
end
|
||||
}
|
||||
end)
|
||||
|
||||
local tcp_node1_table = ucic2:get(application, "@auto_switch[0]", "tcp_node1")
|
||||
if tcp_node1_table then
|
||||
@ -110,40 +125,29 @@ do
|
||||
end
|
||||
|
||||
ucic2:foreach(application, uciType, function(node)
|
||||
if node.type == 'V2ray_shunt' then
|
||||
if node.type == 'V2ray' and node.v2ray_protocol == '_shunt' then
|
||||
local node_id = node[".name"]
|
||||
local youtube_node_id = node.youtube_node
|
||||
local netflix_node_id = node.netflix_node
|
||||
local default_node_id = node.default_node
|
||||
ucic2:foreach(application, "shunt_rules", function(e)
|
||||
local _node_id = node[e[".name"]] or nil
|
||||
local _node
|
||||
if _node_id then
|
||||
_node = ucic2:get_all(application, _node_id)
|
||||
end
|
||||
CONFIG[#CONFIG + 1] = {
|
||||
log = false,
|
||||
currentNode = _node,
|
||||
remarks = "V2ray分流" .. e.remarks .. "节点",
|
||||
set = function(server)
|
||||
ucic2:set(application, node_id, e[".name"], server)
|
||||
end
|
||||
}
|
||||
end)
|
||||
|
||||
local youtube_node
|
||||
local netflix_node
|
||||
local default_node_id = node.default_node
|
||||
local default_node
|
||||
if youtube_node_id then
|
||||
youtube_node = ucic2:get_all(application, youtube_node_id)
|
||||
end
|
||||
if netflix_node_id then
|
||||
netflix_node = ucic2:get_all(application, netflix_node_id)
|
||||
end
|
||||
if default_node_id then
|
||||
default_node = ucic2:get_all(application, default_node_id)
|
||||
end
|
||||
CONFIG[#CONFIG + 1] = {
|
||||
log = false,
|
||||
currentNode = youtube_node,
|
||||
remarks = "V2ray分流youtube节点",
|
||||
set = function(server)
|
||||
ucic2:set(application, node_id, "youtube_node", server)
|
||||
end
|
||||
}
|
||||
CONFIG[#CONFIG + 1] = {
|
||||
log = false,
|
||||
currentNode = netflix_node,
|
||||
remarks = "V2ray分流Netflix节点",
|
||||
set = function(server)
|
||||
ucic2:set(application, node_id, "netflix_node", server)
|
||||
end
|
||||
}
|
||||
CONFIG[#CONFIG + 1] = {
|
||||
log = false,
|
||||
currentNode = default_node,
|
||||
@ -152,7 +156,7 @@ do
|
||||
ucic2:set(application, node_id, "default_node", server)
|
||||
end
|
||||
}
|
||||
elseif node.type == 'V2ray_balancing' then
|
||||
elseif node.type == 'V2ray' and node.v2ray_protocol == '_balancing' then
|
||||
local node_id = node[".name"]
|
||||
local nodes = {}
|
||||
local new_nodes = {}
|
||||
@ -370,7 +374,7 @@ local function processData(szType, content, add_mode)
|
||||
if info.tls == "tls" or info.tls == "1" then
|
||||
result.v2ray_stream_security = "tls"
|
||||
result.tls_serverName = info.host
|
||||
result.tls_allowInsecure = 1
|
||||
result.tls_allowInsecure = allowInsecure_default
|
||||
else
|
||||
result.v2ray_stream_security = "none"
|
||||
end
|
||||
@ -428,7 +432,7 @@ local function processData(szType, content, add_mode)
|
||||
if Info then
|
||||
local address, port, peer
|
||||
local password = Info[1]
|
||||
local allowInsecure = 1
|
||||
local allowInsecure = allowInsecure_default
|
||||
local params = {}
|
||||
local hostInfo = split(Info[2], ":")
|
||||
if hostInfo then
|
||||
@ -469,14 +473,19 @@ local function processData(szType, content, add_mode)
|
||||
return nil
|
||||
end
|
||||
if not result.remarks then
|
||||
result.remarks = result.address .. ':' .. result.port
|
||||
if result.address and result.port then
|
||||
result.remarks = result.address .. ':' .. result.port
|
||||
else
|
||||
result.remarks = "NULL"
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
-- wget
|
||||
local function wget(url)
|
||||
|
||||
-- curl
|
||||
local function curl(url)
|
||||
local ua = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36"
|
||||
local stdout = luci.sys.exec('/usr/bin/wget --user-agent="' .. ua .. '" --no-check-certificate -t 3 -T 10 -O- "' .. url .. '"')
|
||||
local stdout = luci.sys.exec('curl -sL --user-agent "' .. ua .. '" -k --retry 3 --connect-timeout 3 "' .. url .. '"')
|
||||
return trim(stdout)
|
||||
end
|
||||
|
||||
@ -485,19 +494,29 @@ local function truncate_nodes()
|
||||
local function clear(type)
|
||||
local node_num = ucic2:get(application, "@global_other[0]", type .. "_node_num") or 1
|
||||
for i = 1, node_num, 1 do
|
||||
local node = ucic2:get(application, "@global[0]", type.."_node" .. i)
|
||||
local node = ucic2:get(application, "@global[0]", type .. "_node" .. i)
|
||||
if node then
|
||||
local is_sub_node = ucic2:get(application, node, "is_sub") or 0
|
||||
if is_sub_node == "1" then
|
||||
is_stop = 1
|
||||
ucic2:set(application, '@global[0]', type.."_node" .. i, "nil")
|
||||
ucic2:set(application, '@global[0]', type .. "_node" .. i, "nil")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
clear("tcp")
|
||||
clear("udp")
|
||||
clear("socks")
|
||||
|
||||
ucic2:foreach(application, "socks", function(t)
|
||||
local node = t.node
|
||||
if node then
|
||||
local is_sub_node = ucic2:get(application, node, "is_sub") or 0
|
||||
if is_sub_node == "1" then
|
||||
is_stop = 1
|
||||
ucic2:set(application, t[".name"], "node", "nil")
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
ucic2:foreach(application, uciType, function(node)
|
||||
if (node.is_sub or node.hashkey) and node.add_mode ~= '导入' then
|
||||
@ -516,7 +535,7 @@ local function select_node(nodes, config)
|
||||
local server
|
||||
if config.currentNode then
|
||||
-- 特别优先级 V2ray分流 + 备注
|
||||
if config.currentNode.type == 'V2ray_shunt' then
|
||||
if config.currentNode.type == 'V2ray' and config.currentNode.v2ray_protocol == '_shunt' then
|
||||
for id, node in pairs(nodes) do
|
||||
if node.remarks == config.currentNode.remarks then
|
||||
log('选择【' .. config.remarks .. '】V2ray分流匹配节点:' .. node.remarks)
|
||||
@ -526,7 +545,7 @@ local function select_node(nodes, config)
|
||||
end
|
||||
end
|
||||
-- 特别优先级 V2ray负载均衡 + 备注
|
||||
if config.currentNode.type == 'V2ray_balancing' then
|
||||
if config.currentNode.type == 'V2ray' and config.currentNode.v2ray_protocol == '_balancing' then
|
||||
for id, node in pairs(nodes) do
|
||||
if node.remarks == config.currentNode.remarks then
|
||||
log('选择【' .. config.remarks .. '】V2ray负载均衡匹配节点:' .. node.remarks)
|
||||
@ -620,6 +639,9 @@ local function update_node(manual)
|
||||
for _, v in ipairs(nodeResult) do
|
||||
for _, vv in ipairs(v) do
|
||||
local cfgid = ucic2:add(application, uciType)
|
||||
local uuid = _api.gen_uuid()
|
||||
ucic2:rename(application, cfgid, uuid)
|
||||
cfgid = uuid
|
||||
for kkk, vvv in pairs(vv) do
|
||||
ucic2:set(application, cfgid, kkk, vvv)
|
||||
end
|
||||
@ -631,9 +653,7 @@ local function update_node(manual)
|
||||
local nodes = {}
|
||||
local ucic3 = uci.cursor()
|
||||
ucic3:foreach(application, uciType, function(node)
|
||||
if (node.port and node.address and node.remarks) or node.type == 'V2ray_shunt' or node.type == 'V2ray_balancing' then
|
||||
nodes[node['.name']] = node
|
||||
end
|
||||
nodes[node['.name']] = node
|
||||
end)
|
||||
for _, config in pairs(CONFIG) do
|
||||
if config.nodes and type(config.nodes) == "table" then
|
||||
@ -721,6 +741,7 @@ local function parse_link(raw, remark, manual)
|
||||
if result then
|
||||
if is_filter_keyword(result.remarks) or
|
||||
not result.address or
|
||||
result.remarks == "NULL" or
|
||||
result.address:match("[^0-9a-zA-Z%-%_%.%s]") or -- 中文做地址的 也没有人拿中文域名搞,就算中文域也有Puny Code SB 机场
|
||||
not result.address:find("%.") or -- 虽然没有.也算域,不过应该没有人会这样干吧
|
||||
result.address:sub(#result.address) == "." -- 结尾是.
|
||||
@ -749,7 +770,7 @@ local execute = function()
|
||||
local remark = obj.remark
|
||||
local url = obj.url
|
||||
log('正在订阅: ' .. url)
|
||||
local raw = wget(url)
|
||||
local raw = curl(url)
|
||||
parse_link(raw, remark)
|
||||
end
|
||||
end)
|
||||
|
||||
@ -5,6 +5,7 @@ LOG_FILE=/var/log/$CONFIG.log
|
||||
|
||||
echolog() {
|
||||
local d="$(date "+%Y-%m-%d %H:%M:%S")"
|
||||
#echo -e "$d: $1"
|
||||
echo -e "$d: $1" >> $LOG_FILE
|
||||
}
|
||||
|
||||
@ -21,18 +22,19 @@ test_url() {
|
||||
[ -n "$2" ] && try=$2
|
||||
local timeout=2
|
||||
[ -n "$3" ] && timeout=$3
|
||||
status=$(/usr/bin/wget -4 --no-check-certificate --spider --timeout=$timeout --tries $try "$url" 2>/dev/null)
|
||||
if [ "$?" == 0 ]; then
|
||||
status=200
|
||||
else
|
||||
status=$(/usr/bin/wget --no-check-certificate --spider --timeout=$timeout --tries $try "$url" 2>/dev/null)
|
||||
[ "$?" == 0 ] && status=200
|
||||
fi
|
||||
local extra_params=$4
|
||||
status=$(/usr/bin/curl -I -o /dev/null -skL $extra_params --connect-timeout $timeout --retry $try -w %{http_code} "$url")
|
||||
case "$status" in
|
||||
204|\
|
||||
200)
|
||||
status=200
|
||||
;;
|
||||
esac
|
||||
echo $status
|
||||
}
|
||||
|
||||
test_proxy() {
|
||||
local try=5
|
||||
local try=3
|
||||
result=0
|
||||
status=$(test_url "https://www.google.com/generate_204" $try)
|
||||
if [ "$status" = "200" ]; then
|
||||
@ -68,6 +70,22 @@ test_auto_switch() {
|
||||
return 2
|
||||
elif [ "$status" == 1 ]; then
|
||||
echolog "自动切换检测:${type}_${index}节点异常,开始切换节点!"
|
||||
|
||||
#检测自动切换列表主节点是否能使用
|
||||
local main_node=$(echo $b_tcp_nodes | awk -F ' ' '{print $1}')
|
||||
if [ "$now_node" != "$main_node" ]; then
|
||||
local tmp_port=$(/usr/share/passwall/app.sh get_new_port 61080 tcp)
|
||||
/usr/share/passwall/app.sh run_socks "$main_node" "127.0.0.1" "$tmp_port" "/var/etc/passwall/auto_switch_main.json" "10"
|
||||
proxy_status=$(test_url "https://www.google.com/generate_204" 3 3 "-x socks5h://127.0.0.1:$tmp_port")
|
||||
ps -w | grep -v "grep" | grep "/var/etc/passwall/auto_switch_main.json" | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1
|
||||
if [ "$proxy_status" -eq 200 ]; then
|
||||
#主节点正常,切换到主节点
|
||||
echolog "自动切换检测:${type}_${index}主节点正常,切换到主节点!"
|
||||
/usr/share/passwall/app.sh node_switch $type $2 $index $main_node
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
local new_node
|
||||
in_backup_nodes=$(echo $b_tcp_nodes | grep $now_node)
|
||||
# 判断当前节点是否存在于备用节点列表里
|
||||
@ -100,31 +118,32 @@ test_auto_switch() {
|
||||
}
|
||||
|
||||
start() {
|
||||
if [ "$(ps -w | grep -v grep | grep $CONFIG/test.sh | wc -l)" -gt 2 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ENABLED=$(config_t_get global enabled 0)
|
||||
[ "$ENABLED" != 1 ] && return 1
|
||||
ENABLED=$(config_t_get auto_switch enable 0)
|
||||
[ "$ENABLED" != 1 ] && return 1
|
||||
delay=$(config_t_get auto_switch testing_time 1)
|
||||
sleep ${delay}m
|
||||
while [ "$ENABLED" -eq 1 ]
|
||||
do
|
||||
# TCP_NODE_NUM=$(config_t_get global_other tcp_node_num 1)
|
||||
# 暂时只能检测TCP1
|
||||
TCP_NODE_NUM=1
|
||||
for i in $(seq 1 $TCP_NODE_NUM); do
|
||||
eval TCP_NODE$i=\"$(config_t_get auto_switch tcp_node$i nil)\"
|
||||
eval tmp=\$TCP_NODE$i
|
||||
[ -n "$tmp" -a "$tmp" != "nil" ] && {
|
||||
test_auto_switch TCP tcp $i "$tmp"
|
||||
}
|
||||
done
|
||||
(
|
||||
flock -xn 200
|
||||
[ "$?" != "0" ] && exit 0
|
||||
|
||||
ENABLED=$(config_t_get global enabled 0)
|
||||
[ "$ENABLED" != 1 ] && return 1
|
||||
ENABLED=$(config_t_get auto_switch enable 0)
|
||||
[ "$ENABLED" != 1 ] && return 1
|
||||
delay=$(config_t_get auto_switch testing_time 1)
|
||||
sleep ${delay}m
|
||||
done
|
||||
while [ "$ENABLED" -eq 1 ]
|
||||
do
|
||||
# TCP_NODE_NUM=$(config_t_get global_other tcp_node_num 1)
|
||||
# 暂时只能检测TCP1
|
||||
TCP_NODE_NUM=1
|
||||
for i in $(seq 1 $TCP_NODE_NUM); do
|
||||
eval TCP_NODE$i=\"$(config_t_get auto_switch tcp_node$i nil)\"
|
||||
eval tmp=\$TCP_NODE$i
|
||||
[ -n "$tmp" -a "$tmp" != "nil" ] && {
|
||||
test_auto_switch TCP tcp $i "$tmp"
|
||||
}
|
||||
done
|
||||
delay=$(config_t_get auto_switch testing_time 1)
|
||||
sleep ${delay}m
|
||||
done
|
||||
) 200>"/var/lock/passwall_auto_switch.lock"
|
||||
}
|
||||
|
||||
case $1 in
|
||||
|
||||
Loading…
Reference in New Issue
Block a user