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
-