diff --git a/package/ctcgfw/luci-app-jd-dailybonus/Makefile b/package/ctcgfw/luci-app-jd-dailybonus/Makefile index eb9953bfa4..fbd3aedb45 100644 --- a/package/ctcgfw/luci-app-jd-dailybonus/Makefile +++ b/package/ctcgfw/luci-app-jd-dailybonus/Makefile @@ -7,8 +7,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-jd-dailybonus LUCI_PKGARCH:=all -PKG_VERSION:=0.8 -PKG_RELEASE:=20200715 +PKG_VERSION:=0.8.1 +PKG_RELEASE:=20200716 include $(INCLUDE_DIR)/package.mk diff --git a/package/ctcgfw/luci-app-jd-dailybonus/relnotes.txt b/package/ctcgfw/luci-app-jd-dailybonus/relnotes.txt index 8011b7715d..dac56e603d 100644 --- a/package/ctcgfw/luci-app-jd-dailybonus/relnotes.txt +++ b/package/ctcgfw/luci-app-jd-dailybonus/relnotes.txt @@ -4,6 +4,18 @@ # ######################################################## +######################################################## +// +// 0.8.1 2020-07-16 +// +// +######################################################## + + +Updates + +- UPDATE: 修正部分cookie无法更新到脚本的问题。 + ######################################################## // // 0.8 2020-07-15 diff --git a/package/ctcgfw/luci-app-jd-dailybonus/root/usr/share/jd-dailybonus/newapp.sh b/package/ctcgfw/luci-app-jd-dailybonus/root/usr/share/jd-dailybonus/newapp.sh index 37ce062258..94db34dd92 100755 --- a/package/ctcgfw/luci-app-jd-dailybonus/root/usr/share/jd-dailybonus/newapp.sh +++ b/package/ctcgfw/luci-app-jd-dailybonus/root/usr/share/jd-dailybonus/newapp.sh @@ -55,13 +55,19 @@ fill_cookie() { cookie1=$(uci_get_by_type global cookie) if [ ! "$cookie1" = "" ]; then varb="var Key = '$cookie1';" - sed -i "s/^var Key =.*/$varb/g" $JD_SCRIPT + a=$(sed -n '/var Key =/=' $JD_SCRIPT) + b=$((a-1)) + sed -i "${a}d" $JD_SCRIPT + sed -i "${b}a ${varb}" $JD_SCRIPT fi cookie2=$(uci_get_by_type global cookie2) if [ ! "$cookie2" = "" ]; then varb2="var DualKey = '$cookie2';" - sed -i "s/^var DualKey =.*/$varb2/g" $JD_SCRIPT + aa=$(sed -n '/var DualKey =/=' $JD_SCRIPT) + bb=$((aa-1)) + sed -i "${aa}d" $JD_SCRIPT + sed -i "${bb}a ${varb2}" $JD_SCRIPT fi stop=$(uci_get_by_type global stop) diff --git a/package/libs/lzo/Makefile b/package/libs/lzo/Makefile index 3ce5f53349..09885e8d9b 100644 --- a/package/libs/lzo/Makefile +++ b/package/libs/lzo/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=lzo PKG_VERSION:=2.10 -PKG_RELEASE:=3 +PKG_RELEASE:=4 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=http://www.oberhumer.com/opensource/lzo/download/ @@ -49,6 +49,8 @@ define Build/InstallDev $(CP) $(PKG_INSTALL_DIR)/usr/include/lzo $(1)/usr/include/ $(CP) $(PKG_INSTALL_DIR)/usr/lib/liblzo2.{a,so*} $(1)/usr/lib/ $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/lzo2.pc $(1)/usr/lib/pkgconfig + $(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/lzo2.pc + $(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/lzo2.pc endef define Package/liblzo/install diff --git a/package/lienol/luci-app-passwall/Makefile b/package/lienol/luci-app-passwall/Makefile index 92680f5640..ec1b37d34f 100644 --- a/package/lienol/luci-app-passwall/Makefile +++ b/package/lienol/luci-app-passwall/Makefile @@ -7,8 +7,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-passwall PKG_VERSION:=3.9 -PKG_RELEASE:=4 -PKG_DATE:=20200705 +PKG_RELEASE:=18 +PKG_DATE:=20200717 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) @@ -41,6 +41,10 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_Trojan bool "Include Trojan" default n +config PACKAGE_$(PKG_NAME)_INCLUDE_Trojan_GO + bool "Include Trojan_GO" + default n + config PACKAGE_$(PKG_NAME)_INCLUDE_Brook bool "Include Brook" default n @@ -90,8 +94,8 @@ define Package/$(PKG_NAME) +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 \ + +PACKAGE_$(PKG_NAME)_INCLUDE_Trojan:trojan-plus \ + +PACKAGE_$(PKG_NAME)_INCLUDE_Trojan_GO:trojan-go \ +PACKAGE_$(PKG_NAME)_INCLUDE_Brook:brook \ +PACKAGE_$(PKG_NAME)_INCLUDE_kcptun:kcptun-client \ +PACKAGE_$(PKG_NAME)_INCLUDE_haproxy:haproxy \ diff --git a/package/lienol/luci-app-passwall/luasrc/controller/passwall.lua b/package/lienol/luci-app-passwall/luasrc/controller/passwall.lua index 301f8c71ea..c37c07e3e4 100644 --- a/package/lienol/luci-app-passwall/luasrc/controller/passwall.lua +++ b/package/lienol/luci-app-passwall/luasrc/controller/passwall.lua @@ -6,181 +6,184 @@ local http = require "luci.http" 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" +local trojan_go = require "luci.model.cbi.passwall.api.trojan_go" 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", "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 - 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 - if nixio.fs.access("/usr/sbin/haproxy") then - 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", "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 + 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", "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 + 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 + if nixio.fs.access("/usr/sbin/haproxy") then + 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", "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", "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", "status"}, call("status")).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 + 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", "status"}, call("status")).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 + entry({"admin", "vpn", "passwall", "trojan_go_check"}, call("trojan_go_check")).leaf = true + entry({"admin", "vpn", "passwall", "trojan_go_update"}, call("trojan_go_update")).leaf = true end local function http_write_json(content) - http.prepare_content("application/json") - http.write_json(content or {code = 1}) + http.prepare_content("application/json") + http.write_json(content or {code = 1}) 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.http.redirect(luci.dispatcher.build_url("admin", "vpn", "passwall")) + 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 function show_menu() - luci.sys.call("touch /etc/config/passwall_show") - luci.http.redirect(luci.dispatcher.build_url("admin", "vpn", "passwall")) + luci.sys.call("touch /etc/config/passwall_show") + luci.http.redirect(luci.dispatcher.build_url("admin", "vpn", "passwall")) end function hide_menu() - luci.sys.call("rm -rf /etc/config/passwall_show") - luci.http.redirect(luci.dispatcher.build_url("admin", "status", "overview")) + luci.sys.call("rm -rf /etc/config/passwall_show") + luci.http.redirect(luci.dispatcher.build_url("admin", "status", "overview")) 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("lua /usr/share/passwall/subscribe.lua add log") + local link = luci.http.formvalue("link") + 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.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")) end function clear_log() - luci.sys.call("echo '' > /var/log/passwall.log") + luci.sys.call("echo '' > /var/log/passwall.log") end function status() - -- 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 = 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/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 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 = 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/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 = ucic:get(appname, "@global_other[0]", "udp_node_num") or 1 - for i = 1, udp_node_num, 1 do - 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) + local udp_node_num = ucic:get(appname, "@global_other[0]", "udp_node_num") or 1 + for i = 1, udp_node_num, 1 do + 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 socks_status() - local e = {} - 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) + local e = {} + 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 - luci.http.prepare_content("application/json") - luci.http.write_json(e) + 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_starttransfer}" ' .. 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 + luci.http.prepare_content("application/json") + luci.http.write_json(e) end function ping_node() - local index = luci.http.formvalue("index") - local address = luci.http.formvalue("address") - local port = luci.http.formvalue("port") - local e = {} - e.index = index - 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) - end - luci.http.prepare_content("application/json") - luci.http.write_json(e) + local index = luci.http.formvalue("index") + local address = luci.http.formvalue("address") + local port = luci.http.formvalue("port") + local e = {} + e.index = index + 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 2 -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) + end + luci.http.prepare_content("application/json") + luci.http.write_json(e) end function set_node() - local protocol = luci.http.formvalue("protocol") - local number = luci.http.formvalue("number") - local section = luci.http.formvalue("section") - 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")) + local protocol = luci.http.formvalue("protocol") + local number = luci.http.formvalue("number") + local section = luci.http.formvalue("section") + 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() - local e = {} - local section = luci.http.formvalue("section") - luci.http.prepare_content("application/json") - luci.http.write_json(e) + local e = {} + local section = luci.http.formvalue("section") + luci.http.prepare_content("application/json") + luci.http.write_json(e) end function clear_all_nodes() - ucic:foreach(appname, "nodes", function(node) + ucic:foreach(appname, "nodes", function(node) ucic:delete(appname, node['.name']) - end) - - local function clear(type) + 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) @@ -192,128 +195,144 @@ function clear_all_nodes() clear("tcp") clear("udp") - ucic:commit(appname) - luci.sys.call("/etc/init.d/" .. appname .. " restart") + 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") + 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 node_name = "" + local node_name = "" - local retstring = "
" - -- retstring = retstring .. "暂时不支持UDP检测
" + local retstring = "
" + -- retstring = retstring .. "暂时不支持UDP检测
" - retstring = retstring .. "检测端口可用性
" - 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 - (s.v2ray_transport and s.v2ray_transport == "mkcp" and s.port) then - else - local type = s.type - if type and type ~= "V2ray_balancing" and type ~= "V2ray_shunt" and - s.address and s.port and s.remarks then - node_name = "%s:[%s] %s:%s" % - {s.type, s.remarks, s.address, s.port} - tcp_socket = nixio.socket("inet", "stream") - tcp_socket:setopt("socket", "rcvtimeo", 3) - tcp_socket:setopt("socket", "sndtimeo", 3) - ret = tcp_socket:connect(s.address, s.port) - if tostring(ret) == "true" then - retstring = retstring .. "" .. node_name .. " OK.
" - else - retstring = retstring .. "" .. node_name .. " Error.
" - end - ret = "" - end - end - if tcp_socket then tcp_socket:close() end - end) - luci.http.prepare_content("application/json") - luci.http.write_json({ret = retstring}) + retstring = retstring .. "检测端口可用性
" + 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 + (s.v2ray_transport and s.v2ray_transport == "mkcp" and s.port) then + else + local type = s.type + if type and type ~= "V2ray_balancing" and type ~= "V2ray_shunt" and + s.address and s.port and s.remarks then + node_name = "%s:[%s] %s:%s" % {s.type, s.remarks, s.address, s.port} + tcp_socket = nixio.socket("inet", "stream") + tcp_socket:setopt("socket", "rcvtimeo", 3) + tcp_socket:setopt("socket", "sndtimeo", 3) + ret = tcp_socket:connect(s.address, s.port) + if tostring(ret) == "true" then + retstring = retstring .. "" .. node_name .. " OK.
" + else + retstring = retstring .. "" .. node_name .. " Error.
" + end + ret = "" + end + end + if tcp_socket then tcp_socket:close() end + end) + luci.http.prepare_content("application/json") + luci.http.write_json({ret = retstring}) 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 &") + local update = luci.http.formvalue("update") + luci.sys.call("lua /usr/share/passwall/rule_update.lua log '" .. update .. "' > /dev/null 2>&1 &") end 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) + 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 server_get_log() - luci.http.write(luci.sys.exec("[ -f '/var/log/passwall_server.log' ] && cat /var/log/passwall_server.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") + luci.sys.call("echo '' > /var/log/passwall_server.log") end function kcptun_check() - local json = kcptun.to_check("") - http_write_json(json) + local json = kcptun.to_check("") + http_write_json(json) end function kcptun_update() - local json = nil - local task = http.formvalue("task") - if task == "extract" then - json = kcptun.to_extract(http.formvalue("file"), - http.formvalue("subfix")) - elseif task == "move" then - json = kcptun.to_move(http.formvalue("file")) - else - json = kcptun.to_download(http.formvalue("url")) - end + local json = nil + local task = http.formvalue("task") + if task == "extract" then + json = kcptun.to_extract(http.formvalue("file"), http.formvalue("subfix")) + elseif task == "move" then + json = kcptun.to_move(http.formvalue("file")) + else + json = kcptun.to_download(http.formvalue("url")) + end - http_write_json(json) + http_write_json(json) end function brook_check() - local json = brook.to_check("") - http_write_json(json) + local json = brook.to_check("") + http_write_json(json) end function brook_update() - local json = nil - local task = http.formvalue("task") - if task == "move" then - json = brook.to_move(http.formvalue("file")) - else - json = brook.to_download(http.formvalue("url")) - end + local json = nil + local task = http.formvalue("task") + if task == "move" then + json = brook.to_move(http.formvalue("file")) + else + json = brook.to_download(http.formvalue("url")) + end - http_write_json(json) + http_write_json(json) end function v2ray_check() - local json = v2ray.to_check("") - http_write_json(json) + local json = v2ray.to_check("") + http_write_json(json) end function v2ray_update() - local json = nil - local task = http.formvalue("task") - if task == "extract" then - json = - v2ray.to_extract(http.formvalue("file"), http.formvalue("subfix")) - elseif task == "move" then - json = v2ray.to_move(http.formvalue("file")) - else - json = v2ray.to_download(http.formvalue("url")) - end + local json = nil + local task = http.formvalue("task") + if task == "extract" then + json = v2ray.to_extract(http.formvalue("file"), http.formvalue("subfix")) + elseif task == "move" then + json = v2ray.to_move(http.formvalue("file")) + else + json = v2ray.to_download(http.formvalue("url")) + end - http_write_json(json) + http_write_json(json) +end + +function trojan_go_check() + local json = trojan_go.to_check("") + http_write_json(json) +end + +function trojan_go_update() + local json = nil + local task = http.formvalue("task") + if task == "extract" then + json = trojan_go.to_extract(http.formvalue("file"), http.formvalue("subfix")) + elseif task == "move" then + json = trojan_go.to_move(http.formvalue("file")) + else + json = trojan_go.to_download(http.formvalue("url")) + end + + http_write_json(json) end diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/api.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/api.lua index 8321f90101..3ecc304853 100644 --- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/api.lua +++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/api.lua @@ -20,7 +20,7 @@ function gen_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 @@ -28,22 +28,47 @@ 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 chmod_755(file) + if file and file ~= "" then + if not fs.access(file, "rwx", "rx", "rx") then + fs.chmod(file, 755) + end + end +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 +function get_v2ray_version(file) + if file == nil then file = get_v2ray_path() end + chmod_755(file) + if fs.access(file) then + return sys.exec("echo -n $(%s -version | awk '{print $2}' | sed -n 1P)" % file) + end + return "" +end + +function get_trojan_go_path() + local path = uci_get_type("global_app", "trojan_go_file") + return path +end + +function get_trojan_go_version(file) + if file == nil then file = get_trojan_go_path() end + chmod_755(file) + if fs.access(file) then + return sys.exec("echo -n $(%s -version | awk '{print $2}' | sed -n 1P)" % file) + end + return "" end function get_kcptun_path() @@ -51,10 +76,13 @@ function get_kcptun_path() 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 +function get_kcptun_version(file) + if file == nil then file = get_kcptun_path() end + chmod_755(file) + if fs.access(file) then + return sys.exec("echo -n $(%s -v | awk '{print $3}')" % file) + end + return "" end function get_brook_path() @@ -62,10 +90,13 @@ function get_brook_path() 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 +function get_brook_version(file) + if file == nil then file = get_brook_path() end + chmod_755(file) + if fs.access(file) then + return sys.exec("echo -n $(%s -v | awk '{print $3}')" % file) + end + return "" end function _unpack(t, i) @@ -144,12 +175,10 @@ end function auto_get_arch() local arch = nixio.uname().machine or "" if fs.access("/usr/lib/os-release") then - LEDE_BOARD = sys.exec( - "echo -n `grep 'LEDE_BOARD' /usr/lib/os-release | awk -F '[\\042\\047]' '{print $2}'`") + LEDE_BOARD = sys.exec("echo -n `grep 'LEDE_BOARD' /usr/lib/os-release | awk -F '[\\042\\047]' '{print $2}'`") end if fs.access("/etc/openwrt_release") then - DISTRIB_TARGET = sys.exec( - "echo -n `grep 'DISTRIB_TARGET' /etc/openwrt_release | awk -F '[\\042\\047]' '{print $2}'`") + DISTRIB_TARGET = sys.exec("echo -n `grep 'DISTRIB_TARGET' /etc/openwrt_release | awk -F '[\\042\\047]' '{print $2}'`") end if arch == "mips" then @@ -157,15 +186,13 @@ function auto_get_arch() if string.match(LEDE_BOARD, "ramips") == "ramips" then arch = "ramips" else - arch = sys.exec("echo '" .. LEDE_BOARD .. - "' | grep -oE 'ramips|ar71xx'") + arch = sys.exec("echo '" .. LEDE_BOARD .. "' | grep -oE 'ramips|ar71xx'") end elseif DISTRIB_TARGET and DISTRIB_TARGET ~= "" then if string.match(DISTRIB_TARGET, "ramips") == "ramips" then arch = "ramips" else - arch = sys.exec("echo '" .. DISTRIB_TARGET .. - "' | grep -oE 'ramips|ar71xx'") + arch = sys.exec("echo '" .. DISTRIB_TARGET .. "' | grep -oE 'ramips|ar71xx'") end end end @@ -204,7 +231,6 @@ end function get_api_json(url) local jsonc = require "luci.jsonc" - local json_content = luci.sys.exec(curl .. " " .. _unpack(curl_args) .. " " .. url) if json_content == "" then return {} end return jsonc.parse(json_content) or {} diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/brook.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/brook.lua index ad8dcc6375..05f716470b 100644 --- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/brook.lua +++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/brook.lua @@ -5,31 +5,7 @@ local util = require "luci.util" local i18n = require "luci.i18n" local api = require "luci.model.cbi.passwall.api.api" -local brook_api = - "https://api.github.com/repos/txthinking/brook/releases/latest" - -function get_brook_file_path() - return api.uci_get_type("global_app", "brook_file") -end - -function get_brook_version(file) - if file == nil then file = get_brook_file_path() end - - if file and file ~= "" then - if not fs.access(file, "rwx", "rx", "rx") then - fs.chmod(file, 755) - end - - local info = util.trim(sys.exec("%s -v 2>/dev/null" % file)) - - if info ~= "" then - local tb = util.split(info, "%s+", nil, true) - return tb[1] == "Brook" and tb[3] or "" - end - end - - return "" -end +local brook_api = "https://api.github.com/repos/txthinking/brook/releases/latest" function to_check(arch) if not arch or arch == "" then arch = api.auto_get_arch() end @@ -56,12 +32,9 @@ function to_check(arch) } end + local now_version = api.get_brook_version() local remote_version = json.tag_name:match("[^v]+") - - local client_file = get_brook_file_path() - - local needs_update = api.compare_versions(get_brook_version(client_file), - "<", remote_version) + local needs_update = api.compare_versions(now_version, "<", remote_version) local html_url, download_url if needs_update then @@ -77,18 +50,17 @@ function to_check(arch) if needs_update and not download_url then return { code = 1, - now_version = get_brook_version(client_file), + now_version = now_version, version = remote_version, html_url = html_url, - error = i18n.translate( - "New version found, but failed to get new version download 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_brook_version(client_file), + now_version = now_version, version = remote_version, url = {html = html_url, download = download_url} } @@ -122,17 +94,16 @@ function to_move(file) return {code = 1, error = i18n.translate("Client file is required.")} end - local version = get_brook_version(file) + local version = api.get_brook_version(file) if version == "" then sys.call("/bin/rm -rf /tmp/brook_download.*") return { code = 1, - error = i18n.translate( - "The client file is not suitable for current device.") + error = i18n.translate("The client file is not suitable for current device.") } end - local client_file = get_brook_file_path() + local client_file = api.get_brook_path() local client_file_bak if fs.access(client_file) then @@ -140,8 +111,7 @@ function to_move(file) api.exec("/bin/mv", {"-f", client_file, client_file_bak}) end - local result = api.exec("/bin/mv", {"-f", file, client_file}, nil, - api.command_timeout) == 0 + local result = api.exec("/bin/mv", {"-f", file, client_file}, nil, api.command_timeout) == 0 if not result or not fs.access(client_file) then sys.call("/bin/rm -rf /tmp/brook_download.*") @@ -150,8 +120,7 @@ function to_move(file) end return { code = 1, - error = i18n.translatef("Can't move new file to path: %s", - client_file) + error = i18n.translatef("Can't move new file to path: %s", client_file) } end diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_shadowsocks.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_shadowsocks.lua old mode 100755 new mode 100644 index eb0210c1ba..f69fdc18da --- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_shadowsocks.lua +++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_shadowsocks.lua @@ -25,7 +25,7 @@ if node.type == "SS" then end elseif node.type == "SSR" then config.method = node.ssr_encrypt_method - config.protocol = node.protocol + config.protocol = node.ssr_protocol config.protocol_param = node.protocol_param config.obfs = node.obfs config.obfs_param = node.obfs_param diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_trojan.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_trojan.lua old mode 100755 new mode 100644 index 6b73815af5..2ee08bd4c4 --- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_trojan.lua +++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_trojan.lua @@ -6,26 +6,34 @@ local local_addr = arg[3] local local_port = arg[4] local node = ucursor:get_all("passwall", node_section) +local 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" +local cipher13 = "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384" local trojan = { run_type = run_type, local_addr = local_addr, - local_port = local_port, + local_port = tonumber(local_port), remote_addr = node.address, remote_port = tonumber(node.port), password = {node.password}, log_level = 1, ssl = { - verify = (node.trojan_verify_cert == "1") and true or false, + verify = (node.tls_allowInsecure ~= "1") and true or false, verify_hostname = true, cert = node.trojan_cert_path, - 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", + cipher = cipher, + cipher_tls13 = cipher13, sni = node.tls_serverName, alpn = {"h2", "http/1.1"}, reuse_session = true, - session_ticket = false, + session_ticket = (node.tls_sessionTicket == "1") and true or false, curves = "" }, + udp_timeout = 60, + mux = (node.mux == "1") and { + enabled = true, + concurrency = tonumber(node.mux_concurrency), + idle_timeout = 60, + } or nil, tcp = { no_delay = true, keep_alive = true, @@ -34,4 +42,29 @@ local trojan = { fast_open_qlen = 20 } } +if node.type == "Trojan-Go" then + trojan.ssl.cipher = node.fingerprint == nil and cipher or (node.fingerprint == "disable" and cipher13 .. ":" .. cipher or "") + trojan.ssl.cipher_tls13 = node.fingerprint == nil and cipher13 or nil + trojan.ssl.fingerprint = (node.fingerprint ~= nil and node.fingerprint ~= "disable" ) and node.fingerprint or "" + trojan.ssl.alpn = node.trojan_transport == 'ws' and {} or {"h2", "http/1.1"} + if node.stream_security ~= "tls" and node.trojan_transport == "original" then trojan.ssl = nil end + trojan.transport_plugin = node.stream_security == "none" and node.trojan_transport == "original" and { + enabled = node.plugin_type ~= nil, + type = node.plugin_type or "plaintext", + command = node.plugin_type ~= "plaintext" and node.plugin_cmd or nil, + plugin_option = node.plugin_type ~= "plaintext" and node.plugin_option or nil, + arg = node.plugin_type ~= "plaintext" and { node.plugin_arg } or nil, + env = {} + } or nil + trojan.websocket = node.trojan_transport and node.trojan_transport:find('ws') and { + enabled = true, + path = (node.ws_path ~= nil) and node.ws_path or "/", + host = (node.ws_host ~= nil) and node.ws_host or (node.tls_serverName ~= nil and node.tls_serverName or node.address) + } or nil + trojan.shadowsocks = (node.ss_aead == "1") and { + enabled = true, + method = (node.ss_aead_method ~= nil) and node.ss_aead_method or "aead_aes_128_gcm", + password = (node.ss_aead_pwd ~= nil) and node.ss_aead_pwd or "" + } or nil +end print(json.stringify(trojan, 1)) diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_v2ray.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_v2ray.lua old mode 100755 new mode 100644 index fe4411fdbf..1da513ba53 --- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_v2ray.lua +++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_v2ray.lua @@ -21,8 +21,8 @@ local function gen_outbound(node, tag) end if node.type ~= "V2ray" then if node.type == "Socks" then - node.v2ray_protocol = "socks" - node.v2ray_transport = "tcp" + node.protocol = "socks" + node.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)) @@ -35,83 +35,87 @@ local function gen_outbound(node, tag) string.format("/var/etc/%s/v2_%s_%s.json", appname, node_type, node_id), "4") ) - node.v2ray_protocol = "socks" - node.v2ray_transport = "tcp" + node.protocol = "socks" + node.transport = "tcp" node.address = "127.0.0.1" end end result = { tag = tag, - protocol = node.v2ray_protocol or "vmess", + protocol = node.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 + enabled = (node.mux == "1") and true or false, + concurrency = (node.mux_concurrency) and tonumber(node.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 { + streamSettings = (node.protocol == "vmess") and { + network = node.transport, + security = node.stream_security, + tlsSettings = (node.stream_security == "tls") and { + disableSessionResumption = node.sessionTicket ~= "1" and true or false, 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 { + tcpSettings = (node.transport == "tcp" and + node.protocol ~= "socks") and { header = { - type = node.v2ray_tcp_guise, + type = node.tcp_guise, request = { - path = node.v2ray_tcp_guise_http_path or {"/"}, + path = node.tcp_guise_http_path or {"/"}, headers = { - Host = node.v2ray_tcp_guise_http_host or {} + Host = node.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} + kcpSettings = (node.transport == "mkcp") and { + mtu = tonumber(node.mkcp_mtu), + tti = tonumber(node.mkcp_tti), + uplinkCapacity = tonumber(node.mkcp_uplinkCapacity), + downlinkCapacity = tonumber(node.mkcp_downlinkCapacity), + congestion = (node.mkcp_congestion == "1") and true or false, + readBufferSize = tonumber(node.mkcp_readBufferSize), + writeBufferSize = tonumber(node.mkcp_writeBufferSize), + header = {type = node.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 + wsSettings = (node.transport == "ws") and { + path = node.ws_path or "", + headers = (node.ws_host ~= nil) and + {Host = node.ws_host} or nil } or nil, - httpSettings = (node.v2ray_transport == "h2") and - {path = node.v2ray_h2_path, host = node.v2ray_h2_host} or + httpSettings = (node.transport == "h2") and + {path = node.h2_path, host = node.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} + dsSettings = (node.transport == "ds") and + {path = node.ds_path} or nil, + quicSettings = (node.transport == "quic") and { + security = node.quic_security, + key = node.quic_key, + header = {type = node.quic_guise} } or nil } or nil, settings = { - vnext = (node.v2ray_protocol == "vmess") and { + vnext = (node.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 + id = node.vmess_id, + alterId = tonumber(node.alter_id), + level = tonumber(node.vmess_level), + security = node.security } } } } or nil, - servers = (node.v2ray_protocol == "socks") and { + servers = (node.protocol == "socks" or node.protocol == "http" or node.protocol == "shadowsocks") and { { address = node.address, port = tonumber(node.port), + method = node.v_ss_encrypt_method or nil, + password = node.password or "", + ota = node.ss_ota == '1' and true or false, users = (node.username and node.password) and {{user = node.username, pass = node.password}} or nil } @@ -139,17 +143,17 @@ if redir_port ~= "nil" then settings = {network = proto, followRedirect = true}, sniffing = {enabled = true, destOverride = {"http", "tls"}} }) - if proto == "tcp" and node.v2ray_tcp_socks == "1" then + if proto == "tcp" and node.tcp_socks == "1" then table.insert(inbounds, { listen = "0.0.0.0", - port = tonumber(node.v2ray_tcp_socks_port), + port = tonumber(node.tcp_socks_port), protocol = "socks", settings = { - auth = node.v2ray_tcp_socks_auth, - accounts = (node.v2ray_tcp_socks_auth == "password") and { + auth = node.tcp_socks_auth, + accounts = (node.tcp_socks_auth == "password") and { { - user = node.v2ray_tcp_socks_auth_username, - pass = node.v2ray_tcp_socks_auth_password + user = node.tcp_socks_auth_username, + pass = node.tcp_socks_auth_password } } or nil, udp = true @@ -158,7 +162,7 @@ if redir_port ~= "nil" then end end -if node.v2ray_protocol == "_shunt" then +if node.protocol == "_shunt" then local rules = {} ucursor:foreach(appname, "shunt_rules", function(e) @@ -211,9 +215,9 @@ if node.v2ray_protocol == "_shunt" then routing = {domainStrategy = "IPOnDemand", rules = rules} -elseif node.v2ray_protocol == "_balancing" then - if node.v2ray_balancing_node then - local nodes = node.v2ray_balancing_node +elseif node.protocol == "_balancing" then + if node.balancing_node then + local nodes = node.balancing_node local length = #nodes for i = 1, length do local node = ucursor:get_all(appname, nodes[i]) diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/trojan_go.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/trojan_go.lua new file mode 100644 index 0000000000..0ea54d4e75 --- /dev/null +++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/trojan_go.lua @@ -0,0 +1,149 @@ +module("luci.model.cbi.passwall.api.trojan_go", package.seeall) +local fs = require "nixio.fs" +local sys = require "luci.sys" +local util = require "luci.util" +local i18n = require "luci.i18n" +local ipkg = require("luci.model.ipkg") +local api = require "luci.model.cbi.passwall.api.api" + +local trojan_go_api = api.uci_get_type("global_app", "trojan_go_latest", "https://api.github.com/repos/trojan-gfw/trojan-go/releases/latest") + +function to_check(arch) + if not arch or arch == "" then arch = api.auto_get_arch() end + + local file_tree, sub_version = api.get_file_info(arch) + + if file_tree == "" then + return { + code = 1, + error = i18n.translate( + "Can't determine ARCH, or ARCH not supported.") + } + end + + if file_tree == "mips" then file_tree = "mips%-hardfloat" end + if file_tree == "mipsle" then file_tree = "mipsle%-hardfloat" end + if file_tree == "arm64" then + file_tree = "armv8" + else + if sub_version and sub_version:match("^[5-8]$") then file_tree = file_tree .. "v" .. sub_version end + end + + local json = api.get_api_json(trojan_go_api) + + if json == nil or json.tag_name == nil then + return { + code = 1, + error = i18n.translate("Get remote version info failed.") + } + end + + local now_version = api.get_trojan_go_version() + local remote_version = json.tag_name:match("[^v]+") + local needs_update = api.compare_versions(now_version, "<", remote_version) + local html_url, download_url + + if needs_update then + html_url = json.html_url + for _, v in ipairs(json.assets) do + if v.name and v.name:match("linux%-" .. file_tree .. "%.zip") then + download_url = v.browser_download_url + break + end + end + end + + if needs_update and not download_url then + return { + code = 1, + now_version = now_version, + version = remote_version, + html_url = html_url, + error = i18n.translate( + "New version found, but failed to get new version download url.") .. " [linux-" .. file_tree .. ".zip]" + } + end + + return { + code = 0, + update = needs_update, + now_version = now_version, + version = remote_version, + url = {html = html_url, download = download_url} + } +end + +function to_download(url) + if not url or url == "" then + return {code = 1, error = i18n.translate("Download url is required.")} + end + + sys.call("/bin/rm -f /tmp/trojan-go_download.*") + + local tmp_file = util.trim(util.exec("mktemp -u -t trojan-go_download.XXXXXX")) + + 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}) + return { + code = 1, + error = i18n.translatef("File download failed or timed out: %s", url) + } + end + + return {code = 0, file = tmp_file} +end + +function to_extract(file, subfix) + local isinstall_unzip = ipkg.installed("unzip") + if isinstall_unzip == nil then + ipkg.update() + ipkg.install("unzip") + end + + if not file or file == "" or not fs.access(file) then + return {code = 1, error = i18n.translate("File path required.")} + end + + sys.call("/bin/rm -rf /tmp/trojan-go_extract.*") + local tmp_dir = util.trim(util.exec("mktemp -d -t trojan-go_extract.XXXXXX")) + + local output = {} + api.exec("/usr/bin/unzip", {"-o", file, "-d", tmp_dir}, + function(chunk) output[#output + 1] = chunk end) + + local files = util.split(table.concat(output)) + + api.exec("/bin/rm", {"-f", file}) + + return {code = 0, file = tmp_dir} +end + +function to_move(file) + if not file or file == "" then + sys.call("/bin/rm -rf /tmp/trojan-go_extract.*") + return {code = 1, error = i18n.translate("Client file is required.")} + end + + local client_file = api.get_trojan_go_path() + local client_file_bak + + if fs.access(client_file) then + client_file_bak = client_file .. ".bak" + api.exec("/bin/mv", {"-f", client_file, client_file_bak}) + end + + local result = api.exec("/bin/mv", { "-f", file .. "/trojan-go", client_file }, nil, api.command_timeout) == 0 + sys.call("/bin/rm -rf /tmp/trojan-go_extract.*") + if not result or not fs.access(client_file) then + return { + code = 1, + error = i18n.translatef("Can't move new file to path: %s", client_file) + } + end + + api.exec("/bin/chmod", {"-R", "755", client_file}) + + return {code = 0} +end diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/v2ray.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/v2ray.lua index 7ebbd39117..e5339acba2 100644 --- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/v2ray.lua +++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/v2ray.lua @@ -6,8 +6,7 @@ local i18n = require "luci.i18n" local ipkg = require("luci.model.ipkg") local api = require "luci.model.cbi.passwall.api.api" -local v2ray_api = - "https://api.github.com/repos/v2ray/v2ray-core/releases/latest" +local v2ray_api = "https://api.github.com/repos/v2fly/v2ray-core/releases/latest" local is_armv7 = false function get_v2ray_file_path() @@ -17,9 +16,7 @@ end function get_v2ray_version() if get_v2ray_file_path() and get_v2ray_file_path() ~= "" then if fs.access(get_v2ray_file_path() .. "/v2ray") then - return sys.exec("echo -n `" .. get_v2ray_file_path() .. - "/v2ray -version | awk '{print $2}' | sed -n 1P" .. - "`") + return sys.exec("echo -n $(" .. get_v2ray_file_path() .. "/v2ray -version | awk '{print $2}' | sed -n 1P" .. ")") end end return "" @@ -52,8 +49,7 @@ function to_check(arch) end local remote_version = json.tag_name:match("[^v]+") - local needs_update = api.compare_versions(get_v2ray_version(), "<", - remote_version) + local needs_update = api.compare_versions(get_v2ray_version(), "<", remote_version) local html_url, download_url if needs_update then @@ -160,8 +156,7 @@ function to_move(file) if not result or not fs.access(client_file) then return { code = 1, - error = i18n.translatef("Can't move new file to path: %s", - client_file) + error = i18n.translatef("Can't move new file to path: %s", client_file) } end diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/auto_switch.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/auto_switch.lua index 5392ec5cfe..a98b01d2ac 100644 --- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/auto_switch.lua +++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/auto_switch.lua @@ -5,8 +5,8 @@ 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} + if e.type == "V2ray" and (e.protocol == "_balancing" or e.protocol == "_shunt") then + remarks = "%s:[%s] " % {translatef(e.type .. e.protocol), e.remarks} else remarks = "%s:[%s] %s:%s" % {e.type, e.remarks, e.address, e.port} end diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/global.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/global.lua index b199d13d9e..7bc3647e1a 100644 --- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/global.lua +++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/global.lua @@ -16,8 +16,8 @@ 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} + if e.type == "V2ray" and (e.protocol == "_balancing" or e.protocol == "_shunt") then + remarks = "%s:[%s] " % {translatef(e.type .. e.protocol), e.remarks} else if e.use_kcp and e.use_kcp == "1" then remarks = "%s+%s:[%s] %s" % {e.type, "Kcptun", e.remarks, e.address} diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/node_config.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/node_config.lua index 2c9b5e4311..6aac3202f8 100644 --- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/node_config.lua +++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/node_config.lua @@ -44,15 +44,27 @@ local ssr_obfs_list = { "tls1.0_session_auth", "tls1.2_ticket_auth" } -local v2ray_ss_encrypt_method_list = { +local v_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_security_list = {"none", "auto", "aes-128-gcm", "chacha20-poly1305"} +local security_list = {"none", "auto", "aes-128-gcm", "chacha20-poly1305"} -local v2ray_header_type_list = { +local header_type_list = { "none", "srtp", "utp", "wechat-video", "dtls", "wireguard" } +local force_fp = { + "disable", "firefox", "chrome", "ios" +} +local encrypt_methods_ss_aead = { + "dummy", + "aead_chacha20_poly1305", + "aead_aes_128_gcm", + "aead_aes_256_gcm", + "chacha20-ietf-poly1305", + "aes-128-gcm", + "aes-256-gcm", +} m = Map(appname, translate("Node Config")) m.redirect = d.build_url("admin", "vpn", appname) @@ -82,18 +94,21 @@ 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")) +if is_installed("trojan-plus") or is_finded("trojan-plus") then + type:value("Trojan", translate("Trojan-Plus")) +end +if is_installed("trojan-go") or is_finded("trojan-go") then + type:value("Trojan-Go", translate("Trojan-Go")) 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:value("_balancing", translate("Balancing")) -v2ray_protocol:value("_shunt", translate("Shunt")) -v2ray_protocol:depends("type", "V2ray") +protocol = s:option(ListValue, "protocol", translate("Protocol")) +protocol:value("vmess", translate("Vmess")) +protocol:value("http", translate("HTTP")) +protocol:value("socks", translate("Socks")) +protocol:value("shadowsocks", translate("Shadowsocks")) +protocol:value("_balancing", translate("Balancing")) +protocol:value("_shunt", translate("Shunt")) +protocol:depends("type", "V2ray") local nodes_table = {} uci:foreach(appname, "nodes", function(e) @@ -108,26 +123,26 @@ uci:foreach(appname, "nodes", function(e) end) -- 负载均衡列表 -v2ray_balancing_node = s:option(DynamicList, "v2ray_balancing_node", translate("Load balancing node list"), translate("Load balancing node list, document")) -for k, v in pairs(nodes_table) do v2ray_balancing_node:value(v.id, v.remarks) end -v2ray_balancing_node:depends("v2ray_protocol", "_balancing") +balancing_node = s:option(DynamicList, "balancing_node", translate("Load balancing node list"), translate("Load balancing node list, document")) +for k, v in pairs(nodes_table) do balancing_node:value(v.id, v.remarks) end +balancing_node:depends("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:depends("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") + o:depends("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") +default_node:depends("protocol", "_shunt") -- Brook协议 brook_protocol = s:option(ListValue, "brook_protocol", @@ -144,12 +159,13 @@ address.rmempty = false address:depends("type", "Socks") address:depends("type", "SS") address:depends("type", "SSR") -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 = "V2ray", protocol = "vmess" }) +address:depends({ type = "V2ray", protocol = "http" }) +address:depends({ type = "V2ray", protocol = "socks" }) +address:depends({ type = "V2ray", protocol = "shadowsocks" }) address:depends("type", "Brook") address:depends("type", "Trojan") +address:depends("type", "Trojan-Go") --[[ use_ipv6 = s:option(Flag, "use_ipv6", translate("Use IPv6")) @@ -157,12 +173,13 @@ use_ipv6.default = 0 use_ipv6:depends("type", "Socks") use_ipv6:depends("type", "SS") use_ipv6:depends("type", "SSR") -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 = "V2ray", protocol = "vmess" }) +use_ipv6:depends({ type = "V2ray", protocol = "http" }) +use_ipv6:depends({ type = "V2ray", protocol = "socks" }) +use_ipv6:depends({ type = "V2ray", protocol = "shadowsocks" }) use_ipv6:depends("type", "Brook") use_ipv6:depends("type", "Trojan") +use_ipv6:depends("type", "Trojan-Go") --]] port = s:option(Value, "port", translate("Port")) @@ -171,17 +188,18 @@ port.rmempty = false port:depends("type", "Socks") port:depends("type", "SS") 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 = "V2ray", protocol = "vmess" }) +port:depends({ type = "V2ray", protocol = "http" }) +port:depends({ type = "V2ray", protocol = "socks" }) +port:depends({ type = "V2ray", protocol = "shadowsocks" }) port:depends("type", "Brook") port:depends("type", "Trojan") +port:depends("type", "Trojan-Go") username = s:option(Value, "username", translate("Username")) username:depends("type", "Socks") -username:depends("v2ray_protocol", "http") -username:depends("v2ray_protocol", "socks") +username:depends("protocol", "http") +username:depends("protocol", "socks") password = s:option(Value, "password", translate("Password")) password.password = true @@ -190,9 +208,10 @@ password:depends("type", "SS") password:depends("type", "SSR") password:depends("type", "Brook") password:depends("type", "Trojan") -password:depends("v2ray_protocol", "http") -password:depends("v2ray_protocol", "socks") -password:depends("v2ray_protocol", "shadowsocks") +password:depends("type", "Trojan-Go") +password:depends("protocol", "http") +password:depends("protocol", "socks") +password:depends("protocol", "shadowsocks") ss_encrypt_method = s:option(ListValue, "ss_encrypt_method", translate("Encrypt Method")) @@ -204,24 +223,24 @@ ssr_encrypt_method = s:option(ListValue, "ssr_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_security = s:option(ListValue, "v2ray_security", +security = s:option(ListValue, "security", translate("Encrypt Method")) -for a, t in ipairs(v2ray_security_list) do v2ray_security:value(t) end -v2ray_security:depends("v2ray_protocol", "vmess") +for a, t in ipairs(security_list) do security:value(t) end +security:depends("protocol", "vmess") -v2ray_ss_encrypt_method = s:option(ListValue, "v2ray_ss_encrypt_method", +v_ss_encrypt_method = s:option(ListValue, "v_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") +for a, t in ipairs(v_ss_encrypt_method_list) do v_ss_encrypt_method:value(t) end +v_ss_encrypt_method:depends("protocol", "shadowsocks") -v2ray_ss_ota = s:option(Flag, "v2ray_ss_ota", translate("OTA"), translate( +ss_ota = s:option(Flag, "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") +ss_ota.default = "0" +ss_ota:depends("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") +ssr_protocol = s:option(ListValue, "ssr_protocol", translate("Protocol")) +for a, t in ipairs(ssr_protocol_list) do ssr_protocol:value(t) end +ssr_protocol:depends("type", "SSR") protocol_param = s:option(Value, "protocol_param", translate("Protocol_param")) protocol_param:depends("type", "SSR") @@ -246,6 +265,7 @@ tcp_fast_open:value("true") tcp_fast_open:depends("type", "SS") tcp_fast_open:depends("type", "SSR") tcp_fast_open:depends("type", "Trojan") +tcp_fast_open:depends("type", "Trojan-Go") ss_plugin = s:option(ListValue, "ss_plugin", translate("plugin")) ss_plugin:value("none", translate("none")) @@ -281,205 +301,281 @@ kcp_opts.placeholder = "--crypt aes192 --key abc123 --mtu 1350 --sndwnd 128 --rcvwnd 1024 --mode fast" kcp_opts:depends("use_kcp", "1") -v2ray_VMess_id = s:option(Value, "v2ray_VMess_id", translate("ID")) -v2ray_VMess_id.password = true -v2ray_VMess_id:depends("v2ray_protocol", "vmess") +vmess_id = s:option(Value, "vmess_id", translate("ID")) +vmess_id.password = true +vmess_id:depends("protocol", "vmess") -v2ray_VMess_alterId = s:option(Value, "v2ray_VMess_alterId", +alter_id = s:option(Value, "alter_id", translate("Alter ID")) -v2ray_VMess_alterId:depends("v2ray_protocol", "vmess") +alter_id:depends("protocol", "vmess") -v2ray_VMess_level = - s:option(Value, "v2ray_VMess_level", translate("User Level")) -v2ray_VMess_level.default = 1 -v2ray_VMess_level:depends("v2ray_protocol", "vmess") +vmess_level = + s:option(Value, "vmess_level", translate("User Level")) +vmess_level.default = 1 +vmess_level:depends("protocol", "vmess") -v2ray_stream_security = s:option(ListValue, "v2ray_stream_security", +stream_security = s:option(ListValue, "stream_security", translate("Transport Layer Encryption"), translate( 'Whether or not transport layer encryption is enabled, the supported options are "none" for unencrypted (default) and "TLS" for using TLS.')) -v2ray_stream_security:value("none", "none") -v2ray_stream_security:value("tls", "tls") -v2ray_stream_security:depends("v2ray_protocol", "vmess") -v2ray_stream_security:depends("v2ray_protocol", "http") -v2ray_stream_security:depends("v2ray_protocol", "shadowsocks") +stream_security:value("none", "none") +stream_security:value("tls", "tls") +stream_security.default = "tls" +stream_security:depends("protocol", "vmess") +stream_security:depends("protocol", "shadowsocks") +stream_security:depends("type", "Trojan") +stream_security:depends("type", "Trojan-Go") +stream_security.validate = function(self, value) + if value == "none" and type:formvalue(arg[1]) == "Trojan" then + return nil, translate("'none' not supported for original Trojan.") + end + return value +end -- [[ TLS部分 ]] -- -tls_serverName = s:option(Value, "tls_serverName", translate("Domain")) -tls_serverName:depends("v2ray_stream_security", "tls") -tls_serverName:depends("trojan_verify_cert", "1") -tls_allowInsecure = s:option(Flag, "tls_allowInsecure", - translate("allowInsecure"), translate( +tls_sessionTicket = s:option(Flag, "tls_sessionTicket", translate("Session Ticket")) +tls_sessionTicket.default = "0" +tls_sessionTicket:depends("stream_security", "tls") + +-- [[ Trojan TLS ]]-- + +trojan_force_fp = s:option(ListValue, "fingerprint", translate("Finger Print")) +for a, t in ipairs(force_fp) do trojan_force_fp:value(t) end +trojan_force_fp.default = "firefox" +trojan_force_fp:depends({ type = "Trojan-Go", stream_security = "tls" }) + +tls_serverName = s:option(Value, "tls_serverName", translate("Domain")) +tls_serverName:depends("stream_security", "tls") + +tls_allowInsecure = s:option(Flag, "tls_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.")) tls_allowInsecure.default = "0" -tls_allowInsecure.rmempty = false -tls_allowInsecure:depends("v2ray_stream_security", "tls") +tls_allowInsecure:depends("stream_security", "tls") -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") +-- [[ Trojan Cert ]]-- + +trojan_cert_path = s:option(Value, "trojan_cert_path", translate("Trojan Cert Path")) +trojan_cert_path.default = "" +trojan_cert_path:depends({ stream_security = "tls", tls_allowInsecure = false }) + +trojan_transport = s:option(ListValue, "trojan_transport", translate("Transport")) +trojan_transport:value("original", "Original") +trojan_transport:value("ws", "WebSocket") +trojan_transport:value("h2", "HTTP/2") +trojan_transport:value("h2+ws", "HTTP/2 & WebSocket") +trojan_transport.default = "ws" +trojan_transport:depends("type", "Trojan-Go") + +trojan_plugin = s:option(ListValue, "plugin_type", translate("Plugin Type")) +trojan_plugin:value("plaintext", "Plain Text") +trojan_plugin:value("shadowsocks", "ShadowSocks") +trojan_plugin:value("other", "Other") +trojan_plugin.default = "plaintext" +trojan_plugin:depends({ stream_security = "none", trojan_transport = "original" }) + +trojan_plugin_cmd = s:option(Value, "plugin_cmd", translate("Plugin Binary")) +trojan_plugin_cmd.placeholder = "eg: /usr/bin/v2ray-plugin" +trojan_plugin_cmd:depends({ plugin_type = "shadowsocks" }) +trojan_plugin_cmd:depends({ plugin_type = "other" }) + +trojan_plugin_op = s:option(Value, "plugin_option", translate("Plugin Option")) +trojan_plugin_op.placeholder = "eg: obfs=http;obfs-host=www.baidu.com" +trojan_plugin_op:depends({ plugin_type = "shadowsocks" }) +trojan_plugin_op:depends({ plugin_type = "other" }) + +trojan_plugin_arg = s:option(DynamicList, "plugin_arg", translate("Plugin Option Args")) +trojan_plugin_arg.placeholder = "eg: [\"-config\", \"test.json\"]" +trojan_plugin_arg:depends({ plugin_type = "shadowsocks" }) +trojan_plugin_arg:depends({ plugin_type = "other" }) + +transport = s:option(ListValue, "transport", translate("Transport")) +transport:value("tcp", "TCP") +transport:value("mkcp", "mKCP") +transport:value("ws", "WebSocket") +transport:value("h2", "HTTP/2") +transport:value("ds", "DomainSocket") +transport:value("quic", "QUIC") +transport:depends("protocol", "vmess") --[[ -v2ray_ss_transport = s:option(ListValue, "v2ray_ss_transport", translate("Transport")) -v2ray_ss_transport:value("ws", "WebSocket") -v2ray_ss_transport:value("h2", "HTTP/2") -v2ray_ss_transport:depends("v2ray_protocol", "shadowsocks") +ss_transport = s:option(ListValue, "ss_transport", translate("Transport")) +ss_transport:value("ws", "WebSocket") +ss_transport:value("h2", "HTTP/2") +ss_transport:value("ws", "WebSocket") +ss_transport:value("h2+ws", "HTTP/2 & WebSocket") +ss_transport:depends("protocol", "shadowsocks") ]]-- -- [[ TCP部分 ]]-- -- TCP伪装 -v2ray_tcp_guise = s:option(ListValue, "v2ray_tcp_guise", +tcp_guise = s:option(ListValue, "tcp_guise", translate("Camouflage Type")) -v2ray_tcp_guise:value("none", "none") -v2ray_tcp_guise:value("http", "http") -v2ray_tcp_guise:depends("v2ray_transport", "tcp") +tcp_guise:value("none", "none") +tcp_guise:value("http", "http") +tcp_guise:depends("transport", "tcp") -- HTTP域名 -v2ray_tcp_guise_http_host = s:option(DynamicList, "v2ray_tcp_guise_http_host", +tcp_guise_http_host = s:option(DynamicList, "tcp_guise_http_host", translate("HTTP Host")) -v2ray_tcp_guise_http_host:depends("v2ray_tcp_guise", "http") +tcp_guise_http_host:depends("tcp_guise", "http") -- HTTP路径 -v2ray_tcp_guise_http_path = s:option(DynamicList, "v2ray_tcp_guise_http_path", +tcp_guise_http_path = s:option(DynamicList, "tcp_guise_http_path", translate("HTTP Path")) -v2ray_tcp_guise_http_path:depends("v2ray_tcp_guise", "http") +tcp_guise_http_path:depends("tcp_guise", "http") -- [[ mKCP部分 ]]-- -v2ray_mkcp_guise = s:option(ListValue, "v2ray_mkcp_guise", +mkcp_guise = s:option(ListValue, "mkcp_guise", translate("Camouflage Type"), translate( '
none: default, no masquerade, data sent is packets with no characteristics.
srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).
utp: packets disguised as uTP will be recognized as bittorrent downloaded data.
wechat-video: packets disguised as WeChat video calls.
dtls: disguised as DTLS 1.2 packet.
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") +for a, t in ipairs(header_type_list) do mkcp_guise:value(t) end +mkcp_guise:depends("transport", "mkcp") -v2ray_mkcp_mtu = s:option(Value, "v2ray_mkcp_mtu", translate("KCP MTU")) -v2ray_mkcp_mtu:depends("v2ray_transport", "mkcp") +mkcp_mtu = s:option(Value, "mkcp_mtu", translate("KCP MTU")) +mkcp_mtu:depends("transport", "mkcp") -v2ray_mkcp_tti = s:option(Value, "v2ray_mkcp_tti", translate("KCP TTI")) -v2ray_mkcp_tti:depends("v2ray_transport", "mkcp") +mkcp_tti = s:option(Value, "mkcp_tti", translate("KCP TTI")) +mkcp_tti:depends("transport", "mkcp") -v2ray_mkcp_uplinkCapacity = s:option(Value, "v2ray_mkcp_uplinkCapacity", +mkcp_uplinkCapacity = s:option(Value, "mkcp_uplinkCapacity", translate("KCP uplinkCapacity")) -v2ray_mkcp_uplinkCapacity:depends("v2ray_transport", "mkcp") +mkcp_uplinkCapacity:depends("transport", "mkcp") -v2ray_mkcp_downlinkCapacity = s:option(Value, "v2ray_mkcp_downlinkCapacity", +mkcp_downlinkCapacity = s:option(Value, "mkcp_downlinkCapacity", translate("KCP downlinkCapacity")) -v2ray_mkcp_downlinkCapacity:depends("v2ray_transport", "mkcp") +mkcp_downlinkCapacity:depends("transport", "mkcp") -v2ray_mkcp_congestion = s:option(Flag, "v2ray_mkcp_congestion", +mkcp_congestion = s:option(Flag, "mkcp_congestion", translate("KCP Congestion")) -v2ray_mkcp_congestion:depends("v2ray_transport", "mkcp") +mkcp_congestion:depends("transport", "mkcp") -v2ray_mkcp_readBufferSize = s:option(Value, "v2ray_mkcp_readBufferSize", +mkcp_readBufferSize = s:option(Value, "mkcp_readBufferSize", translate("KCP readBufferSize")) -v2ray_mkcp_readBufferSize:depends("v2ray_transport", "mkcp") +mkcp_readBufferSize:depends("transport", "mkcp") -v2ray_mkcp_writeBufferSize = s:option(Value, "v2ray_mkcp_writeBufferSize", +mkcp_writeBufferSize = s:option(Value, "mkcp_writeBufferSize", translate("KCP writeBufferSize")) -v2ray_mkcp_writeBufferSize:depends("v2ray_transport", "mkcp") +mkcp_writeBufferSize:depends("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") +ws_host = s:option(Value, "ws_host", translate("WebSocket Host")) +ws_host:depends("transport", "ws") +ws_host:depends("ss_transport", "ws") +ws_host:depends("trojan_transport", "h2+ws") +ws_host:depends("trojan_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") +ws_path = s:option(Value, "ws_path", translate("WebSocket Path")) +ws_path:depends("transport", "ws") +ws_path:depends("ss_transport", "ws") +ws_path:depends("trojan_transport", "h2+ws") +ws_path:depends("trojan_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") +h2_host = s:option(Value, "h2_host", translate("HTTP/2 Host")) +h2_host:depends("transport", "h2") +h2_host:depends("ss_transport", "h2") +h2_host:depends("trojan_transport", "h2+ws") +h2_host:depends("trojan_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") +h2_path = s:option(Value, "h2_path", translate("HTTP/2 Path")) +h2_path:depends("transport", "h2") +h2_path:depends("ss_transport", "h2") +h2_path:depends("trojan_transport", "h2+ws") +h2_path:depends("trojan_transport", "h2") -- [[ DomainSocket部分 ]]-- -v2ray_ds_path = s:option(Value, "v2ray_ds_path", "Path", translate( +ds_path = s:option(Value, "ds_path", "Path", translate( "A legal file path. This file must not exist before running V2Ray.")) -v2ray_ds_path:depends("v2ray_transport", "ds") +ds_path:depends("transport", "ds") -- [[ QUIC部分 ]]-- -v2ray_quic_security = s:option(ListValue, "v2ray_quic_security", +quic_security = s:option(ListValue, "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") +quic_security:value("none") +quic_security:value("aes-128-gcm") +quic_security:value("chacha20-poly1305") +quic_security:depends("transport", "quic") -v2ray_quic_key = s:option(Value, "v2ray_quic_key", +quic_key = s:option(Value, "quic_key", translate("Encrypt Method") .. translate("Key")) -v2ray_quic_key:depends("v2ray_transport", "quic") +quic_key:depends("transport", "quic") -v2ray_quic_guise = s:option(ListValue, "v2ray_quic_guise", +quic_guise = s:option(ListValue, "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") +for a, t in ipairs(header_type_list) do quic_guise:value(t) end +quic_guise:depends("transport", "quic") + +-- [[ Trojan-Go Shadowsocks2 ]] -- + +ss_aead = s:option(Flag, "ss_aead", translate("Shadowsocks2")) +ss_aead:depends("type", "Trojan-Go") +ss_aead.default = "0" + +ss_aead_method = s:option(ListValue, "ss_aead_method", translate("Encrypt Method")) +for _, v in ipairs(encrypt_methods_ss_aead) do ss_aead_method:value(v, v:upper()) end +ss_aead_method.default = "aead_aes_128_gcm" +ss_aead_method:depends("ss_aead", "1") + +ss_aead_pwd = s:option(Value, "ss_aead_pwd", translate("Password")) +ss_aead_pwd.password = true +ss_aead_pwd:depends("ss_aead", "1") -- [[ Mux ]]-- -v2ray_mux = s:option(Flag, "v2ray_mux", translate("Mux")) -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" }) +mux = s:option(Flag, "mux", translate("Mux")) +mux:depends({ type = "V2ray", protocol = "vmess" }) +mux:depends({ type = "V2ray", protocol = "http" }) +mux:depends({ type = "V2ray", protocol = "socks" }) +mux:depends({ type = "V2ray", protocol = "shadowsocks" }) +mux:depends("type", "Trojan-Go") -v2ray_mux_concurrency = s:option(Value, "v2ray_mux_concurrency", - translate("Mux Concurrency")) -v2ray_mux_concurrency.default = 8 -v2ray_mux_concurrency:depends("v2ray_mux", "1") +mux_concurrency = s:option(Value, "mux_concurrency", translate("Mux Concurrency")) +mux_concurrency.default = 8 +mux_concurrency:depends("mux", "1") -- [[ 当作为TCP节点时,是否同时开启socks代理 ]]-- --[[ -v2ray_tcp_socks = s:option(Flag, "v2ray_tcp_socks", translate("TCP Open Socks"), +tcp_socks = s:option(Flag, "tcp_socks", translate("TCP Open Socks"), translate( "When using this TCP node, whether to open the socks proxy at the same time")) -v2ray_tcp_socks.default = 0 -v2ray_tcp_socks:depends("type", "V2ray") +tcp_socks.default = 0 +tcp_socks:depends("type", "V2ray") -v2ray_tcp_socks_port = s:option(Value, "v2ray_tcp_socks_port", +tcp_socks_port = s:option(Value, "tcp_socks_port", "Socks " .. translate("Port"), translate("Do not conflict with other ports")) -v2ray_tcp_socks_port.datatype = "port" -v2ray_tcp_socks_port.default = 1080 -v2ray_tcp_socks_port:depends("v2ray_tcp_socks", "1") +tcp_socks_port.datatype = "port" +tcp_socks_port.default = 1080 +tcp_socks_port:depends("tcp_socks", "1") -v2ray_tcp_socks_auth = s:option(ListValue, "v2ray_tcp_socks_auth", +tcp_socks_auth = s:option(ListValue, "tcp_socks_auth", translate("Socks for authentication"), translate( 'Socks protocol authentication, support anonymous and password.')) -v2ray_tcp_socks_auth:value("noauth", translate("anonymous")) -v2ray_tcp_socks_auth:value("password", translate("User Password")) -v2ray_tcp_socks_auth:depends("v2ray_tcp_socks", "1") +tcp_socks_auth:value("noauth", translate("anonymous")) +tcp_socks_auth:value("password", translate("User Password")) +tcp_socks_auth:depends("tcp_socks", "1") -v2ray_tcp_socks_auth_username = s:option(Value, "v2ray_tcp_socks_auth_username", +tcp_socks_auth_username = s:option(Value, "tcp_socks_auth_username", "Socks " .. translate("Username")) -v2ray_tcp_socks_auth_username:depends("v2ray_tcp_socks_auth", "password") +tcp_socks_auth_username:depends("tcp_socks_auth", "password") -v2ray_tcp_socks_auth_password = s:option(Value, "v2ray_tcp_socks_auth_password", +tcp_socks_auth_password = s:option(Value, "tcp_socks_auth_password", "Socks " .. translate("Password")) -v2ray_tcp_socks_auth_password:depends("v2ray_tcp_socks_auth", "password") +tcp_socks_auth_password:depends("tcp_socks_auth", "password") --]] --- [[ Trojan Cert ]]-- -trojan_verify_cert = s:option(Flag, "trojan_verify_cert", - translate("Trojan Verify Cert")) -trojan_verify_cert:depends("type", "Trojan") - -trojan_cert_path = s:option(Value, "trojan_cert_path", - translate("Trojan Cert Path")) -trojan_cert_path.default = "" -trojan_cert_path:depends("trojan_verify_cert", "1") +protocol.validate = function(self, value) + if value == "_shunt" or value == "_balancing" then + address.rmempty = true + port.rmempty = true + end + return value +end return m diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/node_list.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/node_list.lua index 30a80d41ad..b573e4b5d6 100644 --- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/node_list.lua +++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/node_list.lua @@ -72,7 +72,7 @@ if m:get("@global_other[0]", "compact_display_nodes") == "1" then 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") + local protocol = m:get(n, "protocol") if protocol == "_balancing" then type = type .. " 负载均衡" elseif protocol == "_shunt" then @@ -111,7 +111,7 @@ else if v then result = translate(v) if v == "V2ray" then - local protocol = m:get(n, "v2ray_protocol") + local protocol = m:get(n, "protocol") if protocol == "_balancing" then result = result .. " 负载均衡" elseif protocol == "_shunt" then @@ -149,7 +149,7 @@ end o.cfgvalue = function(t, n) local type = m:get(n, "type") or "" if type == "V2ray" then - local protocol = m:get(n, "v2ray_protocol","") + local protocol = m:get(n, "protocol","") if protocol == "_balancing" or protocol == "_shunt" then return "---" end diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/other.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/other.lua index e13c578110..3fe56770cc 100644 --- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/other.lua +++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/other.lua @@ -165,8 +165,8 @@ 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} + if e.type == "V2ray" and (e.protocol == "_balancing" or e.protocol == "_shunt") then + remarks = "%s:[%s] " % {translatef(e.type .. e.protocol), e.remarks} else if e.use_kcp and e.use_kcp == "1" then remarks = "%s+%s:[%s] %s" % {e.type, "Kcptun", e.remarks, e.address} diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/rule.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/rule.lua index 4334742134..ffac408df9 100644 --- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/rule.lua +++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/rule.lua @@ -69,32 +69,37 @@ s = m:section(TypedSection, "global_app", translate("App Update"), "") s.anonymous = true s:append(Template(appname .. "/rule/v2ray_version")) +s:append(Template(appname .. "/rule/trojan_go_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( - "if you want to run from memory, change the path, such as /tmp/v2ray/, Then save the application and update it manually.")) +o = s:option(Value, "v2ray_file", translate("V2ray Path"), translatef("if you want to run from memory, change the path, such as %s, Then save the application and update it manually.", "/tmp/v2ray/")) o.default = "/usr/bin/v2ray/" o.rmempty = false +---- Trojan-Go Path +o = s:option(Value, "trojan_go_file", translate("Trojan-Go Path"), translatef("if you want to run from memory, change the path, such as %s, Then save the application and update it manually.", "/tmp/trojan-go")) +o.default = "/usr/bin/trojan-go" +o.rmempty = false + +o = s:option(Value, "trojan_go_latest", translate("Trojan-Go Version API"), translate("alternate API URL for version checking")) +o.default = "https://api.github.com/repos/peter-tank/trojan-go/releases/latest" + ---- Kcptun client Path -o = s:option(Value, "kcptun_client_file", translate("Kcptun Client Path"), - translate( - "if you want to run from memory, change the path, such as /tmp/kcptun-client, Then save the application and update it manually.")) +o = s:option(Value, "kcptun_client_file", translate("Kcptun Client Path"), translatef("if you want to run from memory, change the path, such as %s, Then save the application and update it manually.", "/tmp/kcptun-client")) o.default = "/usr/bin/kcptun-client" o.rmempty = false --[[ -o = s:option(Button, "_check_kcptun", translate("Manually update"), translate("Make sure there is enough space to install Kcptun")) +o = s:option(Button, "_check_kcptun", translate("Manually update"), translatef("Make sure there is enough space to install %s", "kcptun")) o.template = appname .. "/kcptun" o.inputstyle = "apply" o.btnclick = "onBtnClick_kcptun(this);" o.id = "_kcptun-check_btn"]] -- ---- Brook Path -o = s:option(Value, "brook_file", translate("Brook Path"), translate( - "if you want to run from memory, change the path, such as /tmp/brook, Then save the application and update it manually.")) +o = s:option(Value, "brook_file", translate("Brook Path"), translatef("if you want to run from memory, change the path, such as %s, Then save the application and update it manually.", "/tmp/brook")) o.default = "/usr/bin/brook" o.rmempty = false diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/api/app.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/api/app.lua index 3c405b9cea..76c7937e1b 100644 --- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/api/app.lua +++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/api/app.lua @@ -81,7 +81,7 @@ local function start() 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) + bin = ln_start("/usr/sbin/trojan-plus", "trojan-plus", "-c " .. config_file) elseif type == "Brook" then local brook_protocol = user.brook_protocol local brook_password = user.password @@ -127,4 +127,4 @@ if action then elseif action == "stop" then stop() end -end \ No newline at end of file +end diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/api/ssr.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/api/ssr.lua index 2651f328c2..a00dd0fb23 100644 --- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/api/ssr.lua +++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/api/ssr.lua @@ -7,7 +7,7 @@ function gen_config(user) 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 = user.ssr_protocol config.protocol_param = user.protocol_param config.obfs = user.obfs config.obfs_param = user.obfs_param diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/api/trojan.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/api/trojan.lua index 077998c3f7..a32319fcf2 100644 --- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/api/trojan.lua +++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/api/trojan.lua @@ -1,28 +1,58 @@ module("luci.model.cbi.passwall.server.api.trojan", package.seeall) function gen_config(user) + local 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" + local cipher13 = "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384" 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, + password = { user.password }, log_level = 1, - ssl = { + (user.stream_security == nil or user.stream_security == "tls") and 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"}, + cipher = user.fingerprint == nil and cipher or (user.fingerprint == "disable" and cipher13 .. ":" .. cipher or ""), + cipher_tls13 = user.fingerprint == nil and cipher13 or nil, + sni = "", + verify = false, + verify_hostname = false, reuse_session = true, - session_ticket = false, + session_ticket = (user.tls_sessionTicket == "1") and true or false, + prefer_server_cipher = true, session_timeout = 600, plain_http_response = "", curves = "", dhparam = "" - }, + } or nil, + udp_timeout = 60, + disable_http_check = true, + tcp = { + mux = (user.mux == "1") and { + enabled = true, + concurrency = tonumber(user.mux_concurrency), + idle_timeout = 60, + } or nil, + transport_plugin = user.stream_security == "none" and user.trojan_transport == "original" and { + enabled = user.plugin_type ~= nil, + type = user.plugin_type or "plaintext", + command = user.plugin_type ~= "plaintext" and user.plugin_cmd or nil, + plugin_option = user.plugin_type ~= "plaintext" and user.plugin_option or nil, + arg = user.plugin_type ~= "plaintext" and { user.plugin_arg } or nil, + env = {} + } or nil, + websocket = user.trojan_transport and user.trojan_transport:find('ws') and { + enabled = true, + path = (user.ws_path ~= nil) and user.ws_path or "/", + hostname = (user.ws_host ~= nil) and user.ws_host or (user.tls_serverName ~= nil and user.tls_serverName or user.address) + } or nil, + shadowsocks = (user.ss_aead == "1") and { + enabled = true, + method = (user.ss_aead_method ~= nil) and user.ss_aead_method or "aead_aes_128_gcm", + password = (user.ss_aead_pwd ~= nil) and user.ss_aead_pwd or "" + } or nil, tcp = { prefer_ipv4 = false, no_delay = true, diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/api/v2ray.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/api/v2ray.lua index 5e0c11af86..bc6023565b 100644 --- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/api/v2ray.lua +++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/api/v2ray.lua @@ -8,19 +8,19 @@ function gen_config(user) {protocol = "freedom"}, {protocol = "blackhole", tag = "blocked"} } - if user.v2ray_protocol == "vmess" then + if user.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) + alterId = tonumber(user.alter_id) } end settings = {clients = clients} end - elseif user.v2ray_protocol == "socks" then + elseif user.protocol == "socks" then settings = { auth = (user.username == nil and user.password == nil) and "noauth" or "password", accounts = { @@ -30,7 +30,7 @@ function gen_config(user) } } } - elseif user.v2ray_protocol == "http" then + elseif user.protocol == "http" then settings = { allowTransparent = false, accounts = { @@ -40,13 +40,13 @@ function gen_config(user) } } } - elseif user.v2ray_protocol == "shadowsocks" then + elseif user.protocol == "shadowsocks" then settings = { - method = user.v2ray_ss_encrypt_method, + method = user.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 + network = user.ss_network or "TCP,UDP", + ota = (user.ss_ota == '1') and true or false } end @@ -68,84 +68,83 @@ function gen_config(user) if node and node ~= "nil" and node.type and node.type == "V2ray" then local transit_node = { tag = "transit", - protocol = node.v2ray_protocol or "vmess", + protocol = node.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 + enabled = (node.mux == "1") and true or false, + concurrency = (node.mux_concurrency) and tonumber(node.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 { + streamSettings = (node.protocol == "vmess") and { + network = node.transport, + security = node.stream_security, + tlsSettings = (node.stream_security == "tls") and { + disableSessionResumption = node.sessionTicket ~= "1" and true or false, serverName = node.tls_serverName, allowInsecure = (node.tls_allowInsecure == "1") and true or false } or nil, - tcpSettings = (node.v2ray_transport == "tcp") and { + tcpSettings = (node.transport == "tcp") and { header = { - type = node.v2ray_tcp_guise, + type = node.tcp_guise, request = { - path = node.v2ray_tcp_guise_http_path or {"/"}, + path = node.tcp_guise_http_path or {"/"}, headers = { - Host = node.v2ray_tcp_guise_http_host or {} + Host = node.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), + kcpSettings = (node.transport == "mkcp") and { + mtu = tonumber(node.mkcp_mtu), + tti = tonumber(node.mkcp_tti), + uplinkCapacity = tonumber(node.mkcp_uplinkCapacity), downlinkCapacity = tonumber( - node.v2ray_mkcp_downlinkCapacity), - congestion = (node.v2ray_mkcp_congestion == "1") and + node.mkcp_downlinkCapacity), + congestion = (node.mkcp_congestion == "1") and true or false, - readBufferSize = tonumber(node.v2ray_mkcp_readBufferSize), + readBufferSize = tonumber(node.mkcp_readBufferSize), writeBufferSize = tonumber( - node.v2ray_mkcp_writeBufferSize), - header = {type = node.v2ray_mkcp_guise} + node.mkcp_writeBufferSize), + header = {type = node.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 + wsSettings = (node.transport == "ws") and { + path = node.ws_path or "", + headers = (node.ws_host ~= nil) and + {Host = node.ws_host} or nil } or nil, - httpSettings = (node.v2ray_transport == "h2") and - {path = node.v2ray_h2_path, host = node.v2ray_h2_host} or + httpSettings = (node.transport == "h2") and + {path = node.h2_path, host = node.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} + dsSettings = (node.transport == "ds") and + {path = node.ds_path} or nil, + quicSettings = (node.transport == "quic") and { + security = node.quic_security, + key = node.quic_key, + header = {type = node.quic_guise} } or nil } or nil, settings = { - vnext = (node.v2ray_protocol == "vmess") and { + vnext = (node.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 + id = node.vmess_id, + alterId = tonumber(node.alter_id), + level = tonumber(node.vmess_level), + security = node.security } } } } or nil, - servers = (node.v2ray_protocol == "http" or - node.v2ray_protocol == "socks" or node.v2ray_protocol == "shadowsocks") and { + servers = (node.protocol == "http" or node.protocol == "socks" or node.protocol == "shadowsocks") and { { address = node.address, port = tonumber(node.port), - method = node.v2ray_ss_encrypt_method, + method = node.v_ss_encrypt_method, password = node.password or "", - ota = (node.v2ray_ss_ota == '1') and true or false, + ota = (node.ss_ota == '1') and true or false, users = (node.username and node.password) and { { @@ -171,13 +170,14 @@ function gen_config(user) { listen = (user.bind_local == "1") and "127.0.0.1" or nil, port = tonumber(user.port), - protocol = user.v2ray_protocol, + protocol = user.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 { + streamSettings = (user.protocol == "vmess") and { + network = user.transport, + security = (user.stream_security == 'tls') and "tls" or "none", + tlsSettings = (user.stream_security == 'tls') and { + disableSessionResumption = user.sessionTicket ~= "1" and true or false, -- serverName = (user.tls_serverName), allowInsecure = false, disableSystemRoot = false, @@ -188,41 +188,41 @@ function gen_config(user) } } } or nil, - tcpSettings = (user.v2ray_transport == "tcp") and { + tcpSettings = (user.transport == "tcp") and { header = { - type = user.v2ray_tcp_guise, + type = user.tcp_guise, request = { - path = user.v2ray_tcp_guise_http_path or {"/"}, + path = user.tcp_guise_http_path or {"/"}, headers = { - Host = user.v2ray_tcp_guise_http_host or {} + Host = user.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} + kcpSettings = (user.transport == "mkcp") and { + mtu = tonumber(user.mkcp_mtu), + tti = tonumber(user.mkcp_tti), + uplinkCapacity = tonumber(user.mkcp_uplinkCapacity), + downlinkCapacity = tonumber(user.mkcp_downlinkCapacity), + congestion = (user.mkcp_congestion == "1") and true or false, + readBufferSize = tonumber(user.mkcp_readBufferSize), + writeBufferSize = tonumber(user.mkcp_writeBufferSize), + header = {type = user.mkcp_guise} } or nil, - wsSettings = (user.v2ray_transport == "ws") and + wsSettings = (user.transport == "ws") and { - headers = (user.v2ray_ws_host) and {Host = user.v2ray_ws_host} or + headers = (user.ws_host) and {Host = user.ws_host} or nil, - path = user.v2ray_ws_path + path = user.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} + httpSettings = (user.transport == "h2") and + {path = user.h2_path, host = user.h2_host} or nil, + dsSettings = (user.transport == "ds") and + {path = user.ds_path} or nil, + quicSettings = (user.transport == "quic") and { + security = user.quic_security, + key = user.quic_key, + header = {type = user.quic_guise} } or nil } or nil } diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/user.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/user.lua index 9f91afee87..1d28cefbad 100644 --- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/user.lua +++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/user.lua @@ -31,14 +31,24 @@ local ssr_obfs_list = { "tls1.0_session_auth", "tls1.2_ticket_auth" } -local v2ray_ss_encrypt_method_list = { +local v_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 = { +local header_type_list = { "none", "srtp", "utp", "wechat-video", "dtls", "wireguard" } +local encrypt_methods_ss_aead = { + "dummy", + "aead_chacha20_poly1305", + "aead_aes_128_gcm", + "aead_aes_256_gcm", + "chacha20-ietf-poly1305", + "aes-128-gcm", + "aes-256-gcm", +} + map = Map("passwall_server", translate("Server Config")) map.redirect = d.build_url("admin", "vpn", "passwall", "server") @@ -64,16 +74,19 @@ 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")) +if is_installed("trojan-plus") or is_finded("trojan-plus") then + type:value("Trojan", translate("Trojan-Plus")) +end +if is_installed("trojan-go") or is_finded("trojan-go") then + type:value("Trojan-Go", translate("Trojan-Go")) 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") +protocol = s:option(ListValue, "protocol", translate("Protocol")) +protocol:value("vmess", translate("Vmess")) +protocol:value("http", translate("HTTP")) +protocol:value("socks", translate("Socks")) +protocol:value("shadowsocks", translate("Shadowsocks")) +protocol:depends("type", "V2ray") -- Brook协议 brook_protocol = s:option(ListValue, "brook_protocol", @@ -89,51 +102,53 @@ 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 = "V2ray", protocol = "vmess" }) +port:depends({ type = "V2ray", protocol = "http" }) +port:depends({ type = "V2ray", protocol = "socks" }) +port:depends({ type = "V2ray", protocol = "shadowsocks" }) port:depends("type", "Brook") port:depends("type", "Trojan") +port:depends("type", "Trojan-Go") username = s:option(Value, "username", translate("Username")) -username:depends("v2ray_protocol", "http") -username:depends("v2ray_protocol", "socks") +username:depends("protocol", "http") +username:depends("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" }) +password:depends("type", "Trojan-Go") +password:depends({ type = "V2ray", protocol = "http" }) +password:depends({ type = "V2ray", protocol = "socks" }) +password:depends({ type = "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") +v_ss_encrypt_method = s:option(ListValue, "v_ss_encrypt_method", translate("Encrypt Method")) +for a, t in ipairs(v_ss_encrypt_method_list) do v_ss_encrypt_method:value(t) end +v_ss_encrypt_method:depends("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") +ss_network = s:option(ListValue, "ss_network", translate("Transport")) +ss_network.default = "tcp,udp" +ss_network:value("tcp", "TCP") +ss_network:value("udp", "UDP") +ss_network:value("tcp,udp", "TCP,UDP") +ss_network:depends("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") +ss_ota = s:option(Flag, "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.")) +ss_ota.default = "0" +ss_ota:depends("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") +ssr_protocol = s:option(ListValue, "ssr_protocol", translate("Protocol")) +for a, t in ipairs(ssr_protocol_list) do ssr_protocol:value(t) end +ssr_protocol:depends("type", "SSR") -protocol_param = s:option(Value, "protocol_param", translate("Protocol_param")) -protocol_param:depends("type", "SSR") +ssr_protocol_param = s:option(Value, "protocol_param", translate("Protocol_param")) +ssr_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 @@ -152,6 +167,7 @@ tcp_fast_open:value("false") tcp_fast_open:value("true") tcp_fast_open:depends("type", "SSR") tcp_fast_open:depends("type", "Trojan") +tcp_fast_open:depends("type", "Trojan-Go") udp_forward = s:option(Flag, "udp_forward", translate("UDP Forward")) udp_forward.default = "1" @@ -163,107 +179,169 @@ 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_id:depends({ type = "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" }) +alter_id = s:option(Value, "alter_id", translate("Alter ID")) +alter_id.default = 16 +alter_id:depends({ type = "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" }) +vmess_level:depends({ type = "V2ray", protocol = "vmess" }) +vmess_level:depends({ type = "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") +stream_security = s:option(ListValue, "stream_security", + translate("Transport Layer Encryption"), + translate( + 'Whether or not transport layer encryption is enabled, the supported options are "none" for unencrypted (default) and "TLS" for using TLS.')) +stream_security:value("none", "none") +stream_security:value("tls", "tls") +stream_security.default = "tls" +stream_security:depends({ type = "V2ray", protocol = "vmess", transport = "ws" }) +stream_security:depends({ type = "V2ray", protocol = "vmess", transport = "h2" }) +stream_security:depends("protocol", "shadowsocks") +stream_security:depends("type", "Trojan-Go") + +-- [[ TLS部分 ]] -- + +tls_sessionTicket = s:option(Flag, "tls_sessionTicket", translate("Session Ticket")) +tls_sessionTicket.default = "0" +tls_sessionTicket:depends("stream_security", "tls") + +tls_certificateFile = s:option(Value, "tls_certificateFile", translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem") +tls_certificateFile:depends("stream_security", "tls") + +tls_keyFile = s:option(Value, "tls_keyFile", translate("Private key absolute path"), translate("as:") .. "/etc/ssl/private.key") +tls_keyFile:depends("stream_security", "tls") + +transport = s:option(ListValue, "transport", translate("Transport")) +transport:value("tcp", "TCP") +transport:value("mkcp", "mKCP") +transport:value("ws", "WebSocket") +transport:value("h2", "HTTP/2") +transport:value("ds", "DomainSocket") +transport:value("quic", "QUIC") +transport:depends("protocol", "vmess") + +trojan_transport = s:option(ListValue, "trojan_transport", translate("Transport")) +trojan_transport:value("original", "Original") +trojan_transport:value("ws", "WebSocket") +trojan_transport:value("h2", "HTTP/2") +trojan_transport:value("h2+ws", "HTTP/2 & WebSocket") +trojan_transport.default = "ws" +trojan_transport:depends("type", "Trojan-Go") + +trojan_plugin = s:option(ListValue, "plugin_type", translate("Plugin Type")) +trojan_plugin:value("plaintext", "Plain Text") +trojan_plugin:value("shadowsocks", "ShadowSocks") +trojan_plugin:value("other", "Other") +trojan_plugin.default = "plaintext" +trojan_plugin:depends({ stream_security = "none", trojan_transport = "original" }) + +trojan_plugin_cmd = s:option(Value, "plugin_cmd", translate("Plugin Binary")) +trojan_plugin_cmd.placeholder = "eg: /usr/bin/v2ray-plugin" +trojan_plugin_cmd:depends({ plugin_type = "shadowsocks" }) +trojan_plugin_cmd:depends({ plugin_type = "other" }) + +trojan_plugin_op = s:option(Value, "plugin_option", translate("Plugin Option")) +trojan_plugin_op.placeholder = "eg: obfs=http;obfs-host=www.baidu.com" +trojan_plugin_op:depends({ plugin_type = "shadowsocks" }) +trojan_plugin_op:depends({ plugin_type = "other" }) + +trojan_plugin_arg = s:option(DynamicList, "plugin_arg", translate("Plugin Option Args")) +trojan_plugin_arg.placeholder = "eg: [\"-config\", \"test.json\"]" +trojan_plugin_arg:depends({ plugin_type = "shadowsocks" }) +trojan_plugin_arg:depends({ plugin_type = "other" }) -- [[ 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") +tcp_guise = s:option(ListValue, "tcp_guise", translate("Camouflage Type")) +tcp_guise:value("none", "none") +tcp_guise:value("http", "http") +tcp_guise:depends("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") +tcp_guise_http_host = s:option(DynamicList, "tcp_guise_http_host", translate("HTTP Host")) +tcp_guise_http_host:depends("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") +tcp_guise_http_path = s:option(DynamicList, "tcp_guise_http_path", translate("HTTP Path")) +tcp_guise_http_path:depends("tcp_guise", "http") -- [[ mKCP部分 ]]-- -v2ray_mkcp_guise = s:option(ListValue, "v2ray_mkcp_guise", translate("Camouflage Type"), translate('
none: default, no masquerade, data sent is packets with no characteristics.
srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).
utp: packets disguised as uTP will be recognized as bittorrent downloaded data.
wechat-video: packets disguised as WeChat video calls.
dtls: disguised as DTLS 1.2 packet.
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") +mkcp_guise = s:option(ListValue, "mkcp_guise", translate("Camouflage Type"), translate('
none: default, no masquerade, data sent is packets with no characteristics.
srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).
utp: packets disguised as uTP will be recognized as bittorrent downloaded data.
wechat-video: packets disguised as WeChat video calls.
dtls: disguised as DTLS 1.2 packet.
wireguard: disguised as a WireGuard packet. (not really WireGuard protocol)')) +for a, t in ipairs(header_type_list) do mkcp_guise:value(t) end +mkcp_guise:depends("transport", "mkcp") -v2ray_mkcp_mtu = s:option(Value, "v2ray_mkcp_mtu", translate("KCP MTU")) -v2ray_mkcp_mtu:depends("v2ray_transport", "mkcp") +mkcp_mtu = s:option(Value, "mkcp_mtu", translate("KCP MTU")) +mkcp_mtu:depends("transport", "mkcp") -v2ray_mkcp_tti = s:option(Value, "v2ray_mkcp_tti", translate("KCP TTI")) -v2ray_mkcp_tti:depends("v2ray_transport", "mkcp") +mkcp_tti = s:option(Value, "mkcp_tti", translate("KCP TTI")) +mkcp_tti:depends("transport", "mkcp") -v2ray_mkcp_uplinkCapacity = s:option(Value, "v2ray_mkcp_uplinkCapacity", translate("KCP uplinkCapacity")) -v2ray_mkcp_uplinkCapacity:depends("v2ray_transport", "mkcp") +mkcp_uplinkCapacity = s:option(Value, "mkcp_uplinkCapacity", translate("KCP uplinkCapacity")) +mkcp_uplinkCapacity:depends("transport", "mkcp") -v2ray_mkcp_downlinkCapacity = s:option(Value, "v2ray_mkcp_downlinkCapacity", translate("KCP downlinkCapacity")) -v2ray_mkcp_downlinkCapacity:depends("v2ray_transport", "mkcp") +mkcp_downlinkCapacity = s:option(Value, "mkcp_downlinkCapacity", translate("KCP downlinkCapacity")) +mkcp_downlinkCapacity:depends("transport", "mkcp") -v2ray_mkcp_congestion = s:option(Flag, "v2ray_mkcp_congestion", translate("KCP Congestion")) -v2ray_mkcp_congestion:depends("v2ray_transport", "mkcp") +mkcp_congestion = s:option(Flag, "mkcp_congestion", translate("KCP Congestion")) +mkcp_congestion:depends("transport", "mkcp") -v2ray_mkcp_readBufferSize = s:option(Value, "v2ray_mkcp_readBufferSize", translate("KCP readBufferSize")) -v2ray_mkcp_readBufferSize:depends("v2ray_transport", "mkcp") +mkcp_readBufferSize = s:option(Value, "mkcp_readBufferSize", translate("KCP readBufferSize")) +mkcp_readBufferSize:depends("transport", "mkcp") -v2ray_mkcp_writeBufferSize = s:option(Value, "v2ray_mkcp_writeBufferSize", translate("KCP writeBufferSize")) -v2ray_mkcp_writeBufferSize:depends("v2ray_transport", "mkcp") +mkcp_writeBufferSize = s:option(Value, "mkcp_writeBufferSize", translate("KCP writeBufferSize")) +mkcp_writeBufferSize:depends("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") +ws_host = s:option(Value, "ws_host", translate("WebSocket Host")) +ws_host:depends("transport", "ws") +ws_host:depends("ss_transport", "ws") +ws_host:depends("trojan_transport", "h2+ws") +ws_host:depends("trojan_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") +ws_path = s:option(Value, "ws_path", translate("WebSocket Path")) +ws_path:depends("transport", "ws") +ws_path:depends("ss_transport", "ws") +ws_path:depends("trojan_transport", "h2+ws") +ws_path:depends("trojan_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") +h2_host = s:option(Value, "h2_host", translate("HTTP/2 Host")) +h2_host:depends("transport", "h2") +h2_host:depends("ss_transport", "h2") +h2_host:depends("trojan_transport", "h2+ws") +h2_host:depends("trojan_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") +h2_path = s:option(Value, "h2_path", translate("HTTP/2 Path")) +h2_path:depends("transport", "h2") +h2_path:depends("ss_transport", "h2") +h2_path:depends("trojan_transport", "h2+ws") +h2_path:depends("trojan_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") +ds_path = s:option(Value, "ds_path", "Path", translate("A legal file path. This file must not exist before running V2Ray.")) +ds_path:depends("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") +quic_security = s:option(ListValue, "quic_security", translate("Encrypt Method")) +quic_security:value("none") +quic_security:value("aes-128-gcm") +quic_security:value("chacha20-poly1305") +quic_security:depends("transport", "quic") -v2ray_quic_key = s:option(Value, "v2ray_quic_key", translate("Encrypt Method") .. translate("Key")) -v2ray_quic_key:depends("v2ray_transport", "quic") +quic_key = s:option(Value, "quic_key", translate("Encrypt Method") .. translate("Key")) +quic_key:depends("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") +quic_guise = s:option(ListValue, "quic_guise", translate("Camouflage Type")) +for a, t in ipairs(header_type_list) do quic_guise:value(t) end +quic_guise:depends("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" @@ -279,20 +357,28 @@ 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 +ss_aead = s:option(Flag, "ss_aead", translate("Shadowsocks2")) +ss_aead:depends("type", "Trojan-Go") +ss_aead.default = "0" -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") +ss_aead_method = s:option(ListValue, "ss_aead_method", translate("Encrypt Method")) +for _, v in ipairs(encrypt_methods_ss_aead) do ss_aead_method:value(v, v:upper()) end +ss_aead_method.default = "aead_aes_128_gcm" +ss_aead_method.rmempty = false +ss_aead_method:depends("ss_aead", "1") -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") +ss_aead_pwd = s:option(Value, "ss_aead_pwd", translate("Password")) +ss_aead_pwd.password = true +ss_aead_pwd.rmempty = false +ss_aead_pwd:depends("ss_aead", "1") + +-- [[ Mux ]]-- +mux = s:option(Flag, "mux", translate("Mux")) + +mux_concurrency = s:option(Value, "mux_concurrency", + translate("Mux Concurrency")) +mux_concurrency.default = 8 +mux_concurrency:depends("mux", "1") local nodes_table = {} uci:foreach("passwall", "nodes", function(e) diff --git a/package/lienol/luci-app-passwall/luasrc/view/passwall/global/status.htm b/package/lienol/luci-app-passwall/luasrc/view/passwall/global/status.htm index 79104d96f8..7dadda6b64 100644 --- a/package/lienol/luci-app-passwall/luasrc/view/passwall/global/status.htm +++ b/package/lienol/luci-app-passwall/luasrc/view/passwall/global/status.htm @@ -26,80 +26,80 @@ Licensed under the BSD License. https://github.com/pure-css/pure/blob/master/LICENSE.md */ .pure-g{letter-spacing:-.31em;text-rendering:optimizespeed;font-family:FreeSans,Arimo,"Droid Sans",Helvetica,Arial,sans-serif;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap;-webkit-align-content:flex-start;-ms-flex-line-pack:start;align-content:flex-start}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){table .pure-g{display:block}}.opera-only :-o-prefocus,.pure-g{word-spacing:-.43em}.pure-u{display:inline-block;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-g [class*=pure-u]{font-family:sans-serif}.pure-u-1,.pure-u-1-1,.pure-u-1-12,.pure-u-1-2,.pure-u-1-24,.pure-u-1-3,.pure-u-1-4,.pure-u-1-5,.pure-u-1-6,.pure-u-1-8,.pure-u-10-24,.pure-u-11-12,.pure-u-11-24,.pure-u-12-24,.pure-u-13-24,.pure-u-14-24,.pure-u-15-24,.pure-u-16-24,.pure-u-17-24,.pure-u-18-24,.pure-u-19-24,.pure-u-2-24,.pure-u-2-3,.pure-u-2-5,.pure-u-20-24,.pure-u-21-24,.pure-u-22-24,.pure-u-23-24,.pure-u-24-24,.pure-u-3-24,.pure-u-3-4,.pure-u-3-5,.pure-u-3-8,.pure-u-4-24,.pure-u-4-5,.pure-u-5-12,.pure-u-5-24,.pure-u-5-5,.pure-u-5-6,.pure-u-5-8,.pure-u-6-24,.pure-u-7-12,.pure-u-7-24,.pure-u-7-8,.pure-u-8-24,.pure-u-9-24{display:inline-block;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-u-1-24{width:4.1667%}.pure-u-1-12,.pure-u-2-24{width:8.3333%}.pure-u-1-8,.pure-u-3-24{width:12.5%}.pure-u-1-6,.pure-u-4-24{width:16.6667%}.pure-u-1-5{width:20%}.pure-u-5-24{width:20.8333%}.pure-u-1-4,.pure-u-6-24{width:25%}.pure-u-7-24{width:29.1667%}.pure-u-1-3,.pure-u-8-24{width:33.3333%}.pure-u-3-8,.pure-u-9-24{width:37.5%}.pure-u-2-5{width:40%}.pure-u-10-24,.pure-u-5-12{width:41.6667%}.pure-u-11-24{width:45.8333%}.pure-u-1-2,.pure-u-12-24{width:50%}.pure-u-13-24{width:54.1667%}.pure-u-14-24,.pure-u-7-12{width:58.3333%}.pure-u-3-5{width:60%}.pure-u-15-24,.pure-u-5-8{width:62.5%}.pure-u-16-24,.pure-u-2-3{width:66.6667%}.pure-u-17-24{width:70.8333%}.pure-u-18-24,.pure-u-3-4{width:75%}.pure-u-19-24{width:79.1667%}.pure-u-4-5{width:80%}.pure-u-20-24,.pure-u-5-6{width:83.3333%}.pure-u-21-24,.pure-u-7-8{width:87.5%}.pure-u-11-12,.pure-u-22-24{width:91.6667%}.pure-u-23-24{width:95.8333%}.pure-u-1,.pure-u-1-1,.pure-u-24-24,.pure-u-5-5{width:100%} - .block{ - margin: 0.5rem; - padding: 0; - font-weight: normal; - font-style: normal; - line-height: 1; - font-family: inherit; - min-width: inherit; - overflow-x: auto; - overflow-y: hidden; - border: 1px solid rgba(0,0,0,.05); - border-radius: .375rem; - background-color: #fff; - box-shadow: 0 0 2rem 0 rgba(136,152,170,.15); - } - .img-con{ - margin: 1rem; + .block{ + margin: 0.5rem; + padding: 0; + font-weight: normal; + font-style: normal; + line-height: 1; + font-family: inherit; + min-width: inherit; + overflow-x: auto; + overflow-y: hidden; + border: 1px solid rgba(0,0,0,.05); + border-radius: .375rem; + background-color: #fff; + box-shadow: 0 0 2rem 0 rgba(136,152,170,.15); + } + .img-con{ + margin: 1rem; - } - .green{ + } + .green{ font-size:.9rem; - color: #2dce89; - } - .red{ + color: #2dce89; + } + .red{ font-size:.9rem; - color: #fb6340; - } + color: #fb6340; + } .yellow{ font-size:.9rem; - color: #fb9a05; - } - .block img{ - width: 48px; - height: auto; + color: #fb9a05; + } + .block img{ + width: 48px; + height: auto; float:right; - } - .pure-u-5-8{ - display:flex; - align-items:center; - } + } + .pure-u-5-8{ + display:flex; + align-items:center; + } - .block h4{ - font-size: .8125rem; - font-weight: 600; - margin: 1rem; + .block h4{ + font-size: .8125rem; + font-weight: 600; + margin: 1rem; color:#8898aa!important; - line-height: 1.8em; + line-height: 1.8em; min-height: 48px; - } + } .check { cursor: pointer; } - @media screen and (max-width: 720px) { + @media screen and (max-width: 720px) { .block{ margin: 0.2rem; } - .pure-u-1-4{ - width: 50%; - } + .pure-u-1-4{ + width: 50%; + } .pure-u-1-2{ - width: 100%; - } - } + width: 100%; + } + } @media screen and (max-width: 480px) { - .img-con{ + .img-con{ margin: 1.5rem 0.5rem; - } + } .block img{ - width: 36px; - } - } + width: 36px; + } + } @@ -107,155 +107,144 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md <%:Running Status%> -
-
-
-
-

TCP
<%:NOT RUNNING%>

-
-
-
- -
-
-
-
-
-
-
-
-

UDP
<%:NOT RUNNING%>

-
-
-
- -
-
-
-
-
-
-
-

DNS
<%:NOT RUNNING%>

-
-
-
- -
-
-
-
+
-
-
-

<%:Load Balancing%>
<%:NOT RUNNING%>

-
-
-
- +
+
+
+
-
-
-
+
+
+

TCP
<%:NOT RUNNING%>

+
+
+
-
-
-

Kcptun
<%:NOT RUNNING%>

-
-
-
- +
+
+
+
-
-
-
+
+
+

UDP
<%:NOT RUNNING%>

+
+
+
+
+
+
+
+ +
+
+
+

DNS
<%:NOT RUNNING%>

+
+
+
+
+
+
+
+ +
+
+
+

<%:Load Balancing%>
<%:NOT RUNNING%>

+
+
+
+
+
+
+
+ +
+
+
+

Kcptun
<%:NOT RUNNING%>

+
+
+
-
-
-

<%:Baidu Connection%>
<%:Touch Check%>

-
-
-
- +
+
+
+
-
-
-
+
+
+

<%:Baidu Connection%>
<%:Touch Check%>

+
+
+
-
-
-

<%:Google Connection%>
<%:Touch Check%>

-
-
-
- +
+
+
+
-
-
-
+
+
+

<%:Google Connection%>
<%:Touch Check%>

+
+
+
-
-
-

<%:GitHub Connection%>
<%:Touch Check%>

-
-
-
- +
+
+
+
-
-
-
+
+
+

<%:GitHub Connection%>
<%:Touch Check%>

+
+
+
<% if tonumber(status_show_check_port) == 1 then %>
-
-
-

<%:Node Check%>
<%:Touch Check%>

- -
-
-
- +
+
+
+
-
-
-
+
+
+

<%:Node Check%>
<%:Touch Check%>

+ +
+
+
<% end %> <% if tonumber(status_show_ip111) == 1 then %>
-
-
-

IP111.cn
<%:Touch Check%>

-
-
-
- +
+
+
+
-
-
-
+
+
+

IP111.cn
<%:Touch Check%>

+
+
+
<% end %> -
- + diff --git a/package/lienol/luci-app-passwall/luasrc/view/passwall/global/status2.htm b/package/lienol/luci-app-passwall/luasrc/view/passwall/global/status2.htm index cb7802a1e6..61f169cb19 100644 --- a/package/lienol/luci-app-passwall/luasrc/view/passwall/global/status2.htm +++ b/package/lienol/luci-app-passwall/luasrc/view/passwall/global/status2.htm @@ -209,7 +209,8 @@ local status_show_ip111 = api.uci_get_type("global_other", "status_show_ip111", text += ' X'; } } - kcptun_tcp_node_status.innerHTML = text; + if(kcptun_tcp_node_status) + kcptun_tcp_node_status.innerHTML = text; } } diff --git a/package/lienol/luci-app-passwall/luasrc/view/passwall/haproxy/status.htm b/package/lienol/luci-app-passwall/luasrc/view/passwall/haproxy/status.htm index 2149a06a0a..813749dc6e 100644 --- a/package/lienol/luci-app-passwall/luasrc/view/passwall/haproxy/status.htm +++ b/package/lienol/luci-app-passwall/luasrc/view/passwall/haproxy/status.htm @@ -1,11 +1,7 @@ -<% -local dsp = require "luci.dispatcher" --%> -

+ +
+ +
+
+ 【 <%=trojan_go_version%> 】 + + +
+
+
\ No newline at end of file diff --git a/package/lienol/luci-app-passwall/luasrc/view/passwall/rule/v2ray_version.htm b/package/lienol/luci-app-passwall/luasrc/view/passwall/rule/v2ray_version.htm index e48cea991b..56baa70555 100644 --- a/package/lienol/luci-app-passwall/luasrc/view/passwall/rule/v2ray_version.htm +++ b/package/lienol/luci-app-passwall/luasrc/view/passwall/rule/v2ray_version.htm @@ -1,8 +1,5 @@ <% -local api = require "luci.model.cbi.passwall.api.api" -local dsp = require "luci.dispatcher" - -local v2ray_version = api.get_v2ray_version() +local v2ray_version = require "luci.model.cbi.passwall.api.api".get_v2ray_version() -%>