From 4f61d13de824018500a1b2337cd83b0505f43909 Mon Sep 17 00:00:00 2001 From: xiaorouji <60100640+xiaorouji@users.noreply.github.com> Date: Wed, 15 Feb 2023 14:44:13 +0800 Subject: [PATCH] luci: optimization code --- .../luasrc/model/cbi/passwall/api/api.lua | 12 + .../model/cbi/passwall/api/gen_hysteria.lua | 83 -- .../model/cbi/passwall/api/gen_naiveproxy.lua | 28 - .../cbi/passwall/api/gen_shadowsocks.lua | 108 -- .../model/cbi/passwall/api/gen_trojan.lua | 86 -- .../model/cbi/passwall/api/gen_v2ray.lua | 805 --------------- .../cbi/passwall/api/gen_v2ray_proto.lua | 111 --- .../model/cbi/passwall/api/util_hysteria.lua | 94 ++ .../cbi/passwall/api/util_naiveproxy.lua | 39 + .../cbi/passwall/api/util_shadowsocks.lua | 119 +++ .../model/cbi/passwall/api/util_trojan.lua | 97 ++ .../model/cbi/passwall/api/util_xray.lua | 926 ++++++++++++++++++ .../model/cbi/passwall/server/api/app.lua | 4 +- .../server/api/{v2ray.lua => xray.lua} | 4 +- .../root/usr/share/passwall/app.sh | 57 +- 15 files changed, 1319 insertions(+), 1254 deletions(-) delete mode 100644 luci-app-passwall/luasrc/model/cbi/passwall/api/gen_hysteria.lua delete mode 100644 luci-app-passwall/luasrc/model/cbi/passwall/api/gen_naiveproxy.lua delete mode 100644 luci-app-passwall/luasrc/model/cbi/passwall/api/gen_shadowsocks.lua delete mode 100644 luci-app-passwall/luasrc/model/cbi/passwall/api/gen_trojan.lua delete mode 100644 luci-app-passwall/luasrc/model/cbi/passwall/api/gen_v2ray.lua delete mode 100644 luci-app-passwall/luasrc/model/cbi/passwall/api/gen_v2ray_proto.lua create mode 100644 luci-app-passwall/luasrc/model/cbi/passwall/api/util_hysteria.lua create mode 100644 luci-app-passwall/luasrc/model/cbi/passwall/api/util_naiveproxy.lua create mode 100644 luci-app-passwall/luasrc/model/cbi/passwall/api/util_shadowsocks.lua create mode 100644 luci-app-passwall/luasrc/model/cbi/passwall/api/util_trojan.lua create mode 100644 luci-app-passwall/luasrc/model/cbi/passwall/api/util_xray.lua rename luci-app-passwall/luasrc/model/cbi/passwall/server/api/{v2ray.lua => xray.lua} (97%) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/api/api.lua b/luci-app-passwall/luasrc/model/cbi/passwall/api/api.lua index 940d3d872..35698aede 100755 --- a/luci-app-passwall/luasrc/model/cbi/passwall/api/api.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/api/api.lua @@ -147,6 +147,18 @@ function get_args(arg) return var end +function get_function_args(arg) + local var = nil + if arg and #arg > 1 then + local param = {} + for i = 2, #arg do + param[#param + 1] = arg[i] + end + var = get_args(param) + end + return var +end + function strToTable(str) if str == nil or type(str) ~= "string" then return {} diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_hysteria.lua b/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_hysteria.lua deleted file mode 100644 index d5d6faba5..000000000 --- a/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_hysteria.lua +++ /dev/null @@ -1,83 +0,0 @@ -local api = require "luci.model.cbi.passwall.api.api" -local uci = api.uci -local jsonc = api.jsonc - -local var = api.get_args(arg) -local node_id = var["-node"] -if not node_id then - print("-node 不能为空") - return -end -local node = uci:get_all("passwall", node_id) -local local_tcp_redir_port = var["-local_tcp_redir_port"] -local local_udp_redir_port = var["-local_udp_redir_port"] -local local_socks_address = var["-local_socks_address"] or "0.0.0.0" -local local_socks_port = var["-local_socks_port"] -local local_socks_username = var["-local_socks_username"] -local local_socks_password = var["-local_socks_password"] -local local_http_address = var["-local_http_address"] or "0.0.0.0" -local local_http_port = var["-local_http_port"] -local local_http_username = var["-local_http_username"] -local local_http_password = var["-local_http_password"] -local tcp_proxy_way = var["-tcp_proxy_way"] -local server_host = var["-server_host"] or node.address -local server_port = var["-server_port"] or node.port - -if api.is_ipv6(server_host) then - server_host = api.get_ipv6_full(server_host) -end -local server = server_host .. ":" .. server_port - -if (node.hysteria_hop) then - server = server .. "," .. node.hysteria_hop -end - -local config = { - server = server, - protocol = node.protocol or "udp", - obfs = node.hysteria_obfs, - auth = (node.hysteria_auth_type == "base64") and node.hysteria_auth_password or nil, - auth_str = (node.hysteria_auth_type == "string") and node.hysteria_auth_password or nil, - alpn = node.hysteria_alpn or nil, - server_name = node.tls_serverName, - insecure = (node.tls_allowInsecure == "1") and true or false, - up_mbps = tonumber(node.hysteria_up_mbps) or 10, - down_mbps = tonumber(node.hysteria_down_mbps) or 50, - retry = -1, - retry_interval = 5, - recv_window_conn = (node.hysteria_recv_window_conn) and tonumber(node.hysteria_recv_window_conn) or nil, - recv_window = (node.hysteria_recv_window) and tonumber(node.hysteria_recv_window) or nil, - handshake_timeout = (node.hysteria_handshake_timeout) and tonumber(node.hysteria_handshake_timeout) or nil, - idle_timeout = (node.hysteria_idle_timeout) and tonumber(node.hysteria_idle_timeout) or nil, - hop_interval = (node.hysteria_hop_interval) and tonumber(node.hysteria_hop_interval) or nil, - disable_mtu_discovery = (node.hysteria_disable_mtu_discovery) and true or false, - fast_open = (node.fast_open == "1") and true or false, - socks5 = (local_socks_address and local_socks_port) and { - listen = local_socks_address .. ":" .. local_socks_port, - timeout = 300, - disable_udp = false, - user = (local_socks_username and local_socks_password) and local_socks_username, - password = (local_socks_username and local_socks_password) and local_socks_password, - } or nil, - http = (local_http_address and local_http_port) and { - listen = local_http_address .. ":" .. local_http_port, - timeout = 300, - disable_udp = false, - user = (local_http_username and local_http_password) and local_http_username, - password = (local_http_username and local_http_password) and local_http_password, - } or nil, - redirect_tcp = ("redirect" == tcp_proxy_way and local_tcp_redir_port) and { - listen = "0.0.0.0:" .. local_tcp_redir_port, - timeout = 300 - } or nil, - tproxy_tcp = ("tproxy" == tcp_proxy_way and local_tcp_redir_port) and { - listen = "0.0.0.0:" .. local_tcp_redir_port, - timeout = 300 - } or nil, - tproxy_udp = (local_udp_redir_port) and { - listen = "0.0.0.0:" .. local_udp_redir_port, - timeout = 60 - } or nil -} - -print(jsonc.stringify(config, 1)) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_naiveproxy.lua b/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_naiveproxy.lua deleted file mode 100644 index 054941fc0..000000000 --- a/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_naiveproxy.lua +++ /dev/null @@ -1,28 +0,0 @@ -local api = require "luci.model.cbi.passwall.api.api" -local uci = api.uci -local jsonc = api.jsonc - -local var = api.get_args(arg) -local node_id = var["-node"] -if not node_id then - print("-node 不能为空") - return -end -local node = uci:get_all("passwall", node_id) -local run_type = var["-run_type"] -local local_addr = var["-local_addr"] -local local_port = var["-local_port"] -local server_host = var["-server_host"] or node.address -local server_port = var["-server_port"] or node.port - -if api.is_ipv6(server_host) then - server_host = api.get_ipv6_full(server_host) -end -local server = server_host .. ":" .. server_port - -local config = { - listen = run_type .. "://" .. local_addr .. ":" .. local_port, - proxy = node.protocol .. "://" .. node.username .. ":" .. node.password .. "@" .. server -} - -print(jsonc.stringify(config, 1)) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_shadowsocks.lua b/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_shadowsocks.lua deleted file mode 100644 index 8e2f179b2..000000000 --- a/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_shadowsocks.lua +++ /dev/null @@ -1,108 +0,0 @@ -local api = require "luci.model.cbi.passwall.api.api" -local uci = api.uci -local jsonc = api.jsonc - -local var = api.get_args(arg) -local node_id = var["-node"] -if not node_id then - print("-node 不能为空") - return -end -local node = uci:get_all("passwall", node_id) -local server_host = var["-server_host"] or node.address -local server_port = var["-server_port"] or node.port -local local_addr = var["-local_addr"] -local local_port = var["-local_port"] -local mode = var["-mode"] -local local_socks_address = var["-local_socks_address"] or "0.0.0.0" -local local_socks_port = var["-local_socks_port"] -local local_socks_username = var["-local_socks_username"] -local local_socks_password = var["-local_socks_password"] -local local_http_address = var["-local_http_address"] or "0.0.0.0" -local local_http_port = var["-local_http_port"] -local local_http_username = var["-local_http_username"] -local local_http_password = var["-local_http_password"] -local local_tcp_redir_port = var["-local_tcp_redir_port"] -local local_tcp_redir_address = var["-local_tcp_redir_address"] or "0.0.0.0" -local local_udp_redir_port = var["-local_udp_redir_port"] -local local_udp_redir_address = var["-local_udp_redir_address"] or "0.0.0.0" - -if api.is_ipv6(server_host) then - server_host = api.get_ipv6_only(server_host) -end -local server = server_host - -local config = { - server = server, - server_port = tonumber(server_port), - local_address = local_addr, - local_port = tonumber(local_port), - password = node.password, - method = node.method, - timeout = tonumber(node.timeout), - fast_open = (node.tcp_fast_open and node.tcp_fast_open == "true") and true or false, - reuse_port = true, - tcp_tproxy = var["-tcp_tproxy"] and true or nil -} - -if node.type == "SS" then - if node.plugin and node.plugin ~= "none" then - config.plugin = node.plugin - config.plugin_opts = node.plugin_opts or nil - end - config.mode = mode -elseif node.type == "SSR" then - config.protocol = node.protocol - config.protocol_param = node.protocol_param - config.obfs = node.obfs - config.obfs_param = node.obfs_param -elseif node.type == "SS-Rust" then - config = { - servers = { - { - address = server, - port = tonumber(server_port), - method = node.method, - password = node.password, - timeout = tonumber(node.timeout), - plugin = (node.plugin and node.plugin ~= "none") and node.plugin or nil, - plugin_opts = (node.plugin and node.plugin ~= "none") and node.plugin_opts or nil - } - }, - locals = {}, - fast_open = (node.tcp_fast_open and node.tcp_fast_open == "true") and true or false - } - if local_socks_address and local_socks_port then - table.insert(config.locals, { - local_address = local_socks_address, - local_port = tonumber(local_socks_port), - mode = "tcp_and_udp" - }) - end - if local_http_address and local_http_port then - table.insert(config.locals, { - protocol = "http", - local_address = local_http_address, - local_port = tonumber(local_http_port) - }) - end - if local_tcp_redir_address and local_tcp_redir_port then - table.insert(config.locals, { - protocol = "redir", - mode = "tcp_only", - tcp_redir = var["-tcp_tproxy"] and "tproxy" or nil, - local_address = local_tcp_redir_address, - local_port = tonumber(local_tcp_redir_port) - }) - end - if local_udp_redir_address and local_udp_redir_port then - table.insert(config.locals, { - protocol = "redir", - mode = "udp_only", - local_address = local_udp_redir_address, - local_port = tonumber(local_udp_redir_port) - }) - end -end - -print(jsonc.stringify(config, 1)) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_trojan.lua b/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_trojan.lua deleted file mode 100644 index 844f5032b..000000000 --- a/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_trojan.lua +++ /dev/null @@ -1,86 +0,0 @@ -local api = require "luci.model.cbi.passwall.api.api" -local uci = api.uci -local json = api.jsonc - -local var = api.get_args(arg) -local node_id = var["-node"] -if not node_id then - print("-node 不能为空") - return -end -local node = uci:get_all("passwall", node_id) -local run_type = var["-run_type"] -local local_addr = var["-local_addr"] -local local_port = var["-local_port"] -local server_host = var["-server_host"] or node.address -local server_port = var["-server_port"] or node.port -local loglevel = var["-loglevel"] or 2 -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" - -if api.is_ipv6(server_host) then - server_host = api.get_ipv6_only(server_host) -end -local server = server_host - -local trojan = { - run_type = run_type, - local_addr = local_addr, - local_port = tonumber(local_port), - remote_addr = server, - remote_port = tonumber(server_port), - password = {node.password}, - log_level = tonumber(loglevel), - ssl = { - verify = (node.tls_allowInsecure ~= "1") and true or false, - verify_hostname = true, - cert = nil, - cipher = cipher, - cipher_tls13 = cipher13, - sni = node.tls_serverName or server, - alpn = {"h2", "http/1.1"}, - reuse_session = true, - session_ticket = (node.tls_sessionTicket and node.tls_sessionTicket == "1") and true or false, - curves = "" - }, - udp_timeout = 60, - tcp = { - use_tproxy = (node.type == "Trojan-Plus" and var["-use_tproxy"]) and true or nil, - no_delay = true, - keep_alive = true, - reuse_port = true, - fast_open = (node.tcp_fast_open == "true") and true or false, - fast_open_qlen = 20 - } -} -if node.type == "Trojan-Go" then - trojan.ssl.cipher = nil - trojan.ssl.cipher_tls13 = nil - trojan.ssl.fingerprint = (node.fingerprint ~= "disable") and node.fingerprint or "" - trojan.ssl.alpn = (node.trojan_transport == 'ws') and {} or {"h2", "http/1.1"} - if node.tls ~= "1" and node.trojan_transport == "original" then trojan.ssl = nil end - trojan.transport_plugin = ((not node.tls or node.tls ~= "1") 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, - 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 == 'ws') and { - enabled = true, - path = node.ws_path or "/", - host = node.ws_host or (node.tls_serverName or server) - } or nil - trojan.shadowsocks = (node.ss_aead == "1") and { - enabled = true, - method = node.ss_aead_method or "aes_128_gcm", - password = node.ss_aead_pwd or "" - } or nil - trojan.mux = (node.smux == "1") and { - enabled = true, - concurrency = tonumber(node.mux_concurrency), - idle_timeout = tonumber(node.smux_idle_timeout) - } or nil -end -print(json.stringify(trojan, 1)) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_v2ray.lua b/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_v2ray.lua deleted file mode 100644 index 1944e57d8..000000000 --- a/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_v2ray.lua +++ /dev/null @@ -1,805 +0,0 @@ -module("luci.model.cbi.passwall.api.gen_v2ray", package.seeall) -local api = require "luci.model.cbi.passwall.api.api" - -local var = api.get_args(arg) -local flag = var["-flag"] -local node_id = var["-node"] -local tcp_proxy_way = var["-tcp_proxy_way"] or "redirect" -local tcp_redir_port = var["-tcp_redir_port"] -local udp_redir_port = var["-udp_redir_port"] -local sniffing = var["-sniffing"] -local route_only = var["-route_only"] -local buffer_size = var["-buffer_size"] -local local_socks_address = var["-local_socks_address"] or "0.0.0.0" -local local_socks_port = var["-local_socks_port"] -local local_socks_username = var["-local_socks_username"] -local local_socks_password = var["-local_socks_password"] -local local_http_address = var["-local_http_address"] or "0.0.0.0" -local local_http_port = var["-local_http_port"] -local local_http_username = var["-local_http_username"] -local local_http_password = var["-local_http_password"] -local dns_listen_port = var["-dns_listen_port"] -local dns_query_strategy = var["-dns_query_strategy"] -local remote_dns_server = var["-remote_dns_server"] -local remote_dns_port = var["-remote_dns_port"] -local remote_dns_tcp_server = var["-remote_dns_tcp_server"] -local remote_dns_doh_url = var["-remote_dns_doh_url"] -local remote_dns_doh_host = var["-remote_dns_doh_host"] -local remote_dns_fake = var["-remote_dns_fake"] -local dns_cache = var["-dns_cache"] -local dns_client_ip = var["-dns_client_ip"] -local dns_socks_address = var["-dns_socks_address"] -local dns_socks_port = var["-dns_socks_port"] -local loglevel = var["-loglevel"] or "warning" -local new_port - -local uci = api.uci -local sys = api.sys -local jsonc = api.jsonc -local appname = api.appname -local fs = api.fs -local dns = nil -local fakedns = nil -local inbounds = {} -local outbounds = {} -local routing = nil - -local function get_new_port() - if new_port then - new_port = tonumber(sys.exec(string.format("echo -n $(/usr/share/%s/app.sh get_new_port %s tcp)", appname, new_port + 1))) - else - new_port = tonumber(sys.exec(string.format("echo -n $(/usr/share/%s/app.sh get_new_port auto tcp)", appname))) - end - return new_port -end - -local function get_domain_excluded() - local path = string.format("/usr/share/%s/rules/domains_excluded", appname) - local content = fs.readfile(path) - if not content then return nil end - local hosts = {} - string.gsub(content, '[^' .. "\n" .. ']+', function(w) - local s = w:gsub("^%s*(.-)%s*$", "%1") -- Trim - if s == "" then return end - if s:find("#") and s:find("#") == 1 then return end - if not s:find("#") or s:find("#") ~= 1 then table.insert(hosts, s) end - end) - if #hosts == 0 then hosts = nil end - return hosts -end - -function gen_outbound(node, tag, proxy_table) - local proxy = 0 - local proxy_tag = "nil" - local dialerProxy = nil - if proxy_table ~= nil and type(proxy_table) == "table" then - proxy = proxy_table.proxy or 0 - proxy_tag = proxy_table.tag or "nil" - dialerProxy = proxy_table.dialerProxy - end - local result = nil - if node and node ~= "nil" then - local node_id = node[".name"] - if tag == nil then - tag = node_id - end - - if node.type == "V2ray" or node.type == "Xray" then - proxy = 0 - if proxy_tag ~= "nil" then - if dialerProxy and dialerProxy == "1" then - node.streamSettings = { - sockopt = { - dialerProxy = proxy_tag - } - } - else - node.proxySettings = { - tag = proxy_tag, - transportLayer = true - } - end - end - end - - if node.type ~= "V2ray" and node.type ~= "Xray" then - if node.type == "Socks" then - node.protocol = "socks" - node.transport = "tcp" - else - local relay_port = node.port - new_port = get_new_port() - sys.call(string.format('/usr/share/%s/app.sh run_socks "%s"> /dev/null', - appname, - string.format("flag=%s node=%s bind=%s socks_port=%s config_file=%s relay_port=%s", - new_port, --flag - node_id, --node - "127.0.0.1", --bind - new_port, --socks port - string.format("%s_%s_%s_%s.json", flag, tag, node_id, new_port), --config file - (proxy == 1 and relay_port) and tostring(relay_port) or "" --relay port - ) - ) - ) - node = {} - node.protocol = "socks" - node.transport = "tcp" - node.address = "127.0.0.1" - node.port = new_port - end - node.stream_security = "none" - else - if node.tls and node.tls == "1" then - node.stream_security = "tls" - end - end - - result = { - _flag_tag = node_id, - _flag_proxy = proxy, - _flag_proxy_tag = proxy_tag, - tag = tag, - proxySettings = node.proxySettings or nil, - protocol = node.protocol, - mux = { - enabled = (node.mux == "1") and true or false, - concurrency = (node.mux_concurrency) and tonumber(node.mux_concurrency) or 8 - } or nil, - -- 底层传输配置 - streamSettings = (node.streamSettings or node.protocol == "vmess" or node.protocol == "vless" or node.protocol == "socks" or node.protocol == "shadowsocks" or node.protocol == "trojan") and { - sockopt = { - mark = 255, - dialerProxy = (node.streamSettings and dialerProxy and dialerProxy == "1") and node.streamSettings.sockopt.dialerProxy or nil - }, - network = node.transport, - security = node.stream_security, - tlsSettings = (node.stream_security == "tls") and { - serverName = node.tls_serverName, - allowInsecure = (node.tls_allowInsecure == "1") and true or false, - fingerprint = (node.type == "Xray" and node.fingerprint and node.fingerprint ~= "") and node.fingerprint or nil - } or nil, - tcpSettings = (node.transport == "tcp" and node.protocol ~= "socks") and { - header = { - type = node.tcp_guise or "none", - request = (node.tcp_guise == "http") and { - path = node.tcp_guise_http_path or {"/"}, - headers = { - Host = node.tcp_guise_http_host or {} - } - } or nil - } - } or nil, - 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), - seed = (node.mkcp_seed and node.mkcp_seed ~= "") and node.mkcp_seed or nil, - header = {type = node.mkcp_guise} - } or nil, - wsSettings = (node.transport == "ws") and { - path = node.ws_path or "", - headers = (node.ws_host ~= nil) and - {Host = node.ws_host} or nil, - maxEarlyData = tonumber(node.ws_maxEarlyData) or nil, - earlyDataHeaderName = (node.ws_earlyDataHeaderName) and node.ws_earlyDataHeaderName or nil - } or nil, - httpSettings = (node.transport == "h2") and { - path = node.h2_path, - host = node.h2_host, - read_idle_timeout = tonumber(node.h2_read_idle_timeout) or nil, - health_check_timeout = tonumber(node.h2_health_check_timeout) or nil - } or nil, - 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, - grpcSettings = (node.transport == "grpc") and { - serviceName = node.grpc_serviceName, - multiMode = (node.grpc_mode == "multi") and true or nil, - idle_timeout = tonumber(node.grpc_idle_timeout) or nil, - health_check_timeout = tonumber(node.grpc_health_check_timeout) or nil, - permit_without_stream = (node.grpc_permit_without_stream == "1") and true or nil, - initial_windows_size = tonumber(node.grpc_initial_windows_size) or nil - } or nil - } or nil, - settings = { - vnext = (node.protocol == "vmess" or node.protocol == "vless") and { - { - address = node.address, - port = tonumber(node.port), - users = { - { - id = node.uuid, - level = 0, - security = (node.protocol == "vmess") and node.security or nil, - encryption = node.encryption or "none", - flow = (node.protocol == "vless" and node.tls == '1' and node.tlsflow) and node.tlsflow or nil - } - } - } - } or nil, - servers = (node.protocol == "socks" or node.protocol == "http" or node.protocol == "shadowsocks" or node.protocol == "trojan") and { - { - address = node.address, - port = tonumber(node.port), - method = node.method or nil, - ivCheck = (node.protocol == "shadowsocks") and node.iv_check == "1" or nil, - uot = (node.protocol == "shadowsocks") and node.uot == "1" or nil, - password = node.password or "", - users = (node.username and node.password) and { - { - user = node.username, - pass = node.password - } - } or nil - } - } or nil, - address = (node.protocol == "wireguard" and node.wireguard_local_address) and node.wireguard_local_address or nil, - secretKey = (node.protocol == "wireguard") and node.wireguard_secret_key or nil, - peers = (node.protocol == "wireguard") and { - { - publicKey = node.wireguard_public_key, - endpoint = node.address .. ":" .. node.port, - preSharedKey = node.wireguard_preSharedKey, - keepAlive = node.wireguard_keepAlive and tonumber(node.wireguard_keepAlive) or nil - } - } or nil, - mtu = (node.protocol == "wireguard" and node.wireguard_mtu) and tonumber(node.wireguard_mtu) or nil - } - } - local alpn = {} - if node.alpn and node.alpn ~= "default" then - string.gsub(node.alpn, '[^' .. "," .. ']+', function(w) - table.insert(alpn, w) - end) - end - if alpn and #alpn > 0 then - if result.streamSettings.tlsSettings then - result.streamSettings.tlsSettings.alpn = alpn - end - end - end - return result -end - -if node_id then - local node = uci:get_all(appname, node_id) - if local_socks_port then - local inbound = { - listen = local_socks_address, - port = tonumber(local_socks_port), - protocol = "socks", - settings = {auth = "noauth", udp = true}, - sniffing = {enabled = true, destOverride = {"http", "tls"}} - } - if local_socks_username and local_socks_password and local_socks_username ~= "" and local_socks_password ~= "" then - inbound.settings.auth = "password" - inbound.settings.accounts = { - { - user = local_socks_username, - pass = local_socks_password - } - } - end - table.insert(inbounds, inbound) - end - if local_http_port then - local inbound = { - listen = local_http_address, - port = tonumber(local_http_port), - protocol = "http", - settings = {allowTransparent = false} - } - if local_http_username and local_http_password and local_http_username ~= "" and local_http_password ~= "" then - inbound.settings.accounts = { - { - user = local_http_username, - pass = local_http_password - } - } - end - table.insert(inbounds, inbound) - end - - if tcp_redir_port or udp_redir_port then - local inbound = { - protocol = "dokodemo-door", - settings = {network = "tcp,udp", followRedirect = true}, - streamSettings = {sockopt = {tproxy = "tproxy"}}, - sniffing = {enabled = sniffing and true or false, destOverride = {"http", "tls", (remote_dns_fake) and "fakedns"}, metadataOnly = false, routeOnly = route_only and true or nil, domainsExcluded = (sniffing and not route_only) and get_domain_excluded() or nil} - } - - if tcp_redir_port then - local tcp_inbound = api.clone(inbound) - tcp_inbound.tag = "tcp_redir" - tcp_inbound.settings.network = "tcp" - tcp_inbound.port = tonumber(tcp_redir_port) - tcp_inbound.streamSettings.sockopt.tproxy = tcp_proxy_way - table.insert(inbounds, tcp_inbound) - end - - if udp_redir_port then - local udp_inbound = api.clone(inbound) - udp_inbound.tag = "udp_redir" - udp_inbound.settings.network = "udp" - udp_inbound.port = tonumber(udp_redir_port) - table.insert(inbounds, udp_inbound) - end - end - - if node.protocol == "_shunt" then - local rules = {} - - local default_node_id = node.default_node or "_direct" - local default_outboundTag - if default_node_id == "_direct" then - default_outboundTag = "direct" - elseif default_node_id == "_blackhole" then - default_outboundTag = "blackhole" - else - local default_node = uci:get_all(appname, default_node_id) - local main_node_id = node.main_node or "nil" - local proxy = 0 - local proxy_tag - if main_node_id ~= "nil" then - local main_node = uci:get_all(appname, main_node_id) - if main_node and api.is_normal_node(main_node) and main_node_id ~= default_node_id then - local main_node_outbound = gen_outbound(main_node, "main") - if main_node_outbound then - table.insert(outbounds, main_node_outbound) - proxy = 1 - proxy_tag = "main" - if default_node.type ~= "V2ray" and default_node.type ~= "Xray" then - proxy_tag = nil - new_port = get_new_port() - table.insert(inbounds, { - tag = "proxy_default", - listen = "127.0.0.1", - port = new_port, - protocol = "dokodemo-door", - settings = {network = "tcp,udp", address = default_node.address, port = tonumber(default_node.port)} - }) - if default_node.tls_serverName == nil then - default_node.tls_serverName = default_node.address - end - default_node.address = "127.0.0.1" - default_node.port = new_port - table.insert(rules, 1, { - type = "field", - inboundTag = {"proxy_default"}, - outboundTag = "main" - }) - end - end - end - end - if default_node and api.is_normal_node(default_node) then - local default_outbound = gen_outbound(default_node, "default", { proxy = proxy, tag = proxy_tag, dialerProxy = node.dialerProxy }) - if default_outbound then - table.insert(outbounds, default_outbound) - default_outboundTag = "default" - end - end - end - - uci:foreach(appname, "shunt_rules", function(e) - local name = e[".name"] - if name and e.remarks then - local _node_id = node[name] or "nil" - local proxy_tag = node[name .. "_proxy_tag"] or "nil" - local outboundTag - if _node_id == "_direct" then - outboundTag = "direct" - elseif _node_id == "_blackhole" then - outboundTag = "blackhole" - elseif _node_id == "_default" then - outboundTag = "default" - else - if _node_id ~= "nil" then - local _node = uci:get_all(appname, _node_id) - if _node and api.is_normal_node(_node) then - local new_outbound - for index, value in ipairs(outbounds) do - if value["_flag_tag"] == _node_id and value["_flag_proxy_tag"] == proxy_tag then - new_outbound = api.clone(value) - break - end - end - if new_outbound then - new_outbound["tag"] = name - table.insert(outbounds, new_outbound) - outboundTag = name - else - if _node.type ~= "V2ray" and _node.type ~= "Xray" then - if proxy_tag ~= "nil" then - new_port = get_new_port() - table.insert(inbounds, { - tag = "proxy_" .. name, - listen = "127.0.0.1", - port = new_port, - protocol = "dokodemo-door", - settings = {network = "tcp,udp", address = _node.address, port = tonumber(_node.port)} - }) - if _node.tls_serverName == nil then - _node.tls_serverName = _node.address - end - _node.address = "127.0.0.1" - _node.port = new_port - table.insert(rules, 1, { - type = "field", - inboundTag = {"proxy_" .. name}, - outboundTag = proxy_tag - }) - end - end - local _outbound = gen_outbound(_node, name, { proxy = (proxy_tag ~= "nil") and 1 or 0, tag = (proxy_tag ~= "nil") and proxy_tag or nil, dialerProxy = node.dialerProxy }) - if _outbound then - table.insert(outbounds, _outbound) - outboundTag = name - end - end - end - end - end - if outboundTag then - if outboundTag == "default" then - outboundTag = default_outboundTag - end - local protocols = nil - if e["protocol"] and e["protocol"] ~= "" then - protocols = {} - string.gsub(e["protocol"], '[^' .. " " .. ']+', function(w) - table.insert(protocols, w) - end) - end - if e.domain_list then - local _domain = {} - string.gsub(e.domain_list, '[^' .. "\r\n" .. ']+', function(w) - table.insert(_domain, w) - end) - table.insert(rules, { - type = "field", - outboundTag = outboundTag, - domain = _domain, - protocol = protocols - }) - end - if e.ip_list then - local _ip = {} - string.gsub(e.ip_list, '[^' .. "\r\n" .. ']+', function(w) - table.insert(_ip, w) - end) - table.insert(rules, { - type = "field", - outboundTag = outboundTag, - ip = _ip, - protocol = protocols - }) - end - if not e.domain_list and not e.ip_list and protocols then - table.insert(rules, { - type = "field", - outboundTag = outboundTag, - protocol = protocols - }) - end - end - end - end) - - if default_outboundTag then - table.insert(rules, { - type = "field", - outboundTag = default_outboundTag, - network = "tcp,udp" - }) - end - - routing = { - domainStrategy = node.domainStrategy or "AsIs", - domainMatcher = node.domainMatcher or "hybrid", - rules = rules - } - 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 = uci:get_all(appname, nodes[i]) - local outbound = gen_outbound(node) - if outbound then table.insert(outbounds, outbound) end - end - routing = { - domainStrategy = node.domainStrategy or "AsIs", - domainMatcher = node.domainMatcher or "hybrid", - balancers = {{tag = "balancer", selector = nodes}}, - rules = { - {type = "field", network = "tcp,udp", balancerTag = "balancer"} - } - } - end - else - local outbound = nil - if node.protocol == "_iface" then - if node.iface then - outbound = { - protocol = "freedom", - tag = "outbound", - streamSettings = { - sockopt = { - interface = node.iface - } - } - } - end - else - outbound = gen_outbound(node) - end - if outbound then table.insert(outbounds, outbound) end - routing = { - domainStrategy = "AsIs", - domainMatcher = "hybrid", - rules = {} - } - end -end - -if remote_dns_server or remote_dns_doh_url or remote_dns_fake then - local rules = {} - local _remote_dns_proto = "tcp" - local _remote_dns_host - - if not routing then - routing = { - domainStrategy = "IPOnDemand", - rules = {} - } - end - - dns = { - tag = "dns-in1", - hosts = {}, - disableCache = (dns_cache and dns_cache == "0") and true or false, - disableFallback = true, - disableFallbackIfMatch = true, - servers = {}, - clientIp = (dns_client_ip and dns_client_ip ~= "") and dns_client_ip or nil, - queryStrategy = (dns_query_strategy and dns_query_strategy ~= "") and dns_query_strategy or "UseIPv4" - } - - local _remote_dns = { - --_flag = "remote" - } - - if remote_dns_tcp_server then - _remote_dns.address = remote_dns_tcp_server - _remote_dns.port = tonumber(remote_dns_port) - end - - if remote_dns_doh_url and remote_dns_doh_host then - if remote_dns_server and remote_dns_doh_host ~= remote_dns_server and not api.is_ip(remote_dns_doh_host) then - dns.hosts[remote_dns_doh_host] = remote_dns_server - _remote_dns_host = remote_dns_doh_host - end - _remote_dns.address = remote_dns_doh_url - _remote_dns.port = tonumber(remote_dns_port) - _remote_dns_proto = "doh" - end - - if remote_dns_fake then - remote_dns_server = "1.1.1.1" - fakedns = {} - fakedns[#fakedns + 1] = { - ipPool = "198.18.0.0/16", - poolSize = 65535 - } - if dns_query_strategy == "UseIP" then - fakedns[#fakedns + 1] = { - ipPool = "fc00::/18", - poolSize = 65535 - } - end - _remote_dns.address = "fakedns" - end - - table.insert(dns.servers, _remote_dns) - - if dns_listen_port then - table.insert(inbounds, { - listen = "127.0.0.1", - port = tonumber(dns_listen_port), - protocol = "dokodemo-door", - tag = "dns-in", - settings = { - address = remote_dns_server, - port = (_remote_dns_proto ~= "doh" and tonumber(remote_dns_port)) and tonumber(remote_dns_port) or 53, - network = "tcp,udp" - } - }) - - table.insert(outbounds, { - tag = "dns-out", - protocol = "dns", - settings = { - address = remote_dns_server, - port = (_remote_dns_proto ~= "doh" and tonumber(remote_dns_port)) and tonumber(remote_dns_port) or 53, - network = "tcp", - } - }) - - table.insert(routing.rules, 1, { - type = "field", - inboundTag = { - "dns-in" - }, - outboundTag = "dns-out" - }) - end - ---[[ - local default_dns_flag = "remote" - if node_id and tcp_redir_port then - local node = uci:get_all(appname, node_id) - if node.protocol == "_shunt" then - if node.default_node == "_direct" then - default_dns_flag = "direct" - end - end - end - - if dns.servers and #dns.servers > 0 then - local dns_servers = nil - for index, value in ipairs(dns.servers) do - if not dns_servers and value["_flag"] == default_dns_flag then - dns_servers = { - _flag = "default", - address = value.address, - port = value.port - } - break - end - end - if dns_servers then - table.insert(dns.servers, 1, dns_servers) - end - end -]]-- - if true then - local dns_outboundTag = "direct" - if dns_socks_address and dns_socks_port then - dns_outboundTag = "out" - table.insert(outbounds, 1, { - tag = dns_outboundTag, - protocol = "socks", - streamSettings = { - network = "tcp", - security = "none", - sockopt = { - mark = 255 - } - }, - settings = { - servers = { - { - address = dns_socks_address, - port = tonumber(dns_socks_port) - } - } - } - }) - else - if node_id and tcp_redir_port and not remote_dns_fake then - dns_outboundTag = node_id - local node = uci:get_all(appname, node_id) - if node.protocol == "_shunt" then - dns_outboundTag = "default" - end - end - end - table.insert(rules, { - type = "field", - inboundTag = { - "dns-in1" - }, - ip = { - remote_dns_server - }, - port = tonumber(remote_dns_port), - outboundTag = dns_outboundTag - }) - if _remote_dns_host then - table.insert(rules, { - type = "field", - inboundTag = { - "dns-in1" - }, - domain = { - _remote_dns_host - }, - port = tonumber(remote_dns_port), - outboundTag = dns_outboundTag - }) - end - end - - local default_rule_index = #routing.rules > 0 and #routing.rules or 1 - for index, value in ipairs(routing.rules) do - if value["_flag"] == "default" then - default_rule_index = index - break - end - end - for index, value in ipairs(rules) do - local t = rules[#rules + 1 - index] - table.insert(routing.rules, default_rule_index, t) - end - - local dns_hosts_len = 0 - for key, value in pairs(dns.hosts) do - dns_hosts_len = dns_hosts_len + 1 - end - - if dns_hosts_len == 0 then - dns.hosts = nil - end -end - -if inbounds or outbounds then - local config = { - log = { - -- error = string.format("/tmp/etc/%s/%s.log", appname, node[".name"]), - loglevel = loglevel - }, - -- DNS - dns = dns, - fakedns = fakedns, - -- 传入连接 - inbounds = inbounds, - -- 传出连接 - outbounds = outbounds, - -- 路由 - routing = routing, - -- 本地策略 - policy = { - levels = { - [0] = { - -- handshake = 4, - -- connIdle = 300, - -- uplinkOnly = 2, - -- downlinkOnly = 5, - bufferSize = buffer_size and tonumber(buffer_size) or nil, - statsUserUplink = false, - statsUserDownlink = false - } - }, - -- system = { - -- statsInboundUplink = false, - -- statsInboundDownlink = false - -- } - } - } - table.insert(outbounds, { - protocol = "freedom", - tag = "direct", - settings = { - domainStrategy = (dns_query_strategy and dns_query_strategy ~= "") and dns_query_strategy or "UseIPv4" - }, - streamSettings = { - sockopt = { - mark = 255 - } - } - }) - table.insert(outbounds, { - protocol = "blackhole", - tag = "blackhole" - }) - print(jsonc.stringify(config, 1)) -end diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_v2ray_proto.lua b/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_v2ray_proto.lua deleted file mode 100644 index c90624fc0..000000000 --- a/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_v2ray_proto.lua +++ /dev/null @@ -1,111 +0,0 @@ -local api = require "luci.model.cbi.passwall.api.api" -local jsonc = api.jsonc -local inbounds = {} -local outbounds = {} -local routing = nil - -local var = api.get_args(arg) -local local_socks_address = var["-local_socks_address"] or "0.0.0.0" -local local_socks_port = var["-local_socks_port"] -local local_socks_username = var["-local_socks_username"] -local local_socks_password = var["-local_socks_password"] -local local_http_address = var["-local_http_address"] or "0.0.0.0" -local local_http_port = var["-local_http_port"] -local local_http_username = var["-local_http_username"] -local local_http_password = var["-local_http_password"] -local server_proto = var["-server_proto"] -local server_address = var["-server_address"] -local server_port = var["-server_port"] -local server_username = var["-server_username"] -local server_password = var["-server_password"] - -function gen_outbound(proto, address, port, username, password) - local result = { - protocol = proto, - streamSettings = { - network = "tcp", - security = "none" - }, - settings = { - servers = { - { - address = address, - port = tonumber(port), - users = (username and password) and { - { - user = username, - pass = password - } - } or nil - } - } - } - } - return result -end - -if local_socks_address and local_socks_port then - local inbound = { - listen = local_socks_address, - port = tonumber(local_socks_port), - protocol = "socks", - settings = { - udp = true, - auth = "noauth" - } - } - if local_socks_username and local_socks_password and local_socks_username ~= "" and local_socks_password ~= "" then - inbound.settings.auth = "password" - inbound.settings.accounts = { - { - user = local_socks_username, - pass = local_socks_password - } - } - end - table.insert(inbounds, inbound) -end - -if local_http_address and local_http_port then - local inbound = { - listen = local_http_address, - port = tonumber(local_http_port), - protocol = "http", - settings = { - allowTransparent = false - } - } - if local_http_username and local_http_password and local_http_username ~= "" and local_http_password ~= "" then - inbound.settings.accounts = { - { - user = local_http_username, - pass = local_http_password - } - } - end - table.insert(inbounds, inbound) -end - -if server_proto ~= "nil" and server_address ~= "nil" and server_port ~= "nil" then - local outbound = gen_outbound(server_proto, server_address, server_port, server_username, server_password) - if outbound then table.insert(outbounds, outbound) end -end - --- 额外传出连接 -table.insert(outbounds, { - protocol = "freedom", tag = "direct", settings = {keep = ""}, sockopt = {mark = 255} -}) - -local config = { - log = { - -- error = string.format("/tmp/etc/passwall/%s.log", node[".name"]), - loglevel = "warning" - }, - -- 传入连接 - inbounds = inbounds, - -- 传出连接 - outbounds = outbounds, - -- 路由 - routing = routing -} -print(jsonc.stringify(config, 1)) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/api/util_hysteria.lua b/luci-app-passwall/luasrc/model/cbi/passwall/api/util_hysteria.lua new file mode 100644 index 000000000..f0e8184f3 --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/api/util_hysteria.lua @@ -0,0 +1,94 @@ +module("luci.model.cbi.passwall.api.util_hysteria", package.seeall) +local api = require "luci.model.cbi.passwall.api.api" +local uci = api.uci +local jsonc = api.jsonc + +function gen_config(var) + local node_id = var["-node"] + if not node_id then + print("-node 不能为空") + return + end + local node = uci:get_all("passwall", node_id) + local local_tcp_redir_port = var["-local_tcp_redir_port"] + local local_udp_redir_port = var["-local_udp_redir_port"] + local local_socks_address = var["-local_socks_address"] or "0.0.0.0" + local local_socks_port = var["-local_socks_port"] + local local_socks_username = var["-local_socks_username"] + local local_socks_password = var["-local_socks_password"] + local local_http_address = var["-local_http_address"] or "0.0.0.0" + local local_http_port = var["-local_http_port"] + local local_http_username = var["-local_http_username"] + local local_http_password = var["-local_http_password"] + local tcp_proxy_way = var["-tcp_proxy_way"] + local server_host = var["-server_host"] or node.address + local server_port = var["-server_port"] or node.port + + if api.is_ipv6(server_host) then + server_host = api.get_ipv6_full(server_host) + end + local server = server_host .. ":" .. server_port + + if (node.hysteria_hop) then + server = server .. "," .. node.hysteria_hop + end + + local config = { + server = server, + protocol = node.protocol or "udp", + obfs = node.hysteria_obfs, + auth = (node.hysteria_auth_type == "base64") and node.hysteria_auth_password or nil, + auth_str = (node.hysteria_auth_type == "string") and node.hysteria_auth_password or nil, + alpn = node.hysteria_alpn or nil, + server_name = node.tls_serverName, + insecure = (node.tls_allowInsecure == "1") and true or false, + up_mbps = tonumber(node.hysteria_up_mbps) or 10, + down_mbps = tonumber(node.hysteria_down_mbps) or 50, + retry = -1, + retry_interval = 5, + recv_window_conn = (node.hysteria_recv_window_conn) and tonumber(node.hysteria_recv_window_conn) or nil, + recv_window = (node.hysteria_recv_window) and tonumber(node.hysteria_recv_window) or nil, + handshake_timeout = (node.hysteria_handshake_timeout) and tonumber(node.hysteria_handshake_timeout) or nil, + idle_timeout = (node.hysteria_idle_timeout) and tonumber(node.hysteria_idle_timeout) or nil, + hop_interval = (node.hysteria_hop_interval) and tonumber(node.hysteria_hop_interval) or nil, + disable_mtu_discovery = (node.hysteria_disable_mtu_discovery) and true or false, + fast_open = (node.fast_open == "1") and true or false, + socks5 = (local_socks_address and local_socks_port) and { + listen = local_socks_address .. ":" .. local_socks_port, + timeout = 300, + disable_udp = false, + user = (local_socks_username and local_socks_password) and local_socks_username, + password = (local_socks_username and local_socks_password) and local_socks_password, + } or nil, + http = (local_http_address and local_http_port) and { + listen = local_http_address .. ":" .. local_http_port, + timeout = 300, + disable_udp = false, + user = (local_http_username and local_http_password) and local_http_username, + password = (local_http_username and local_http_password) and local_http_password, + } or nil, + redirect_tcp = ("redirect" == tcp_proxy_way and local_tcp_redir_port) and { + listen = "0.0.0.0:" .. local_tcp_redir_port, + timeout = 300 + } or nil, + tproxy_tcp = ("tproxy" == tcp_proxy_way and local_tcp_redir_port) and { + listen = "0.0.0.0:" .. local_tcp_redir_port, + timeout = 300 + } or nil, + tproxy_udp = (local_udp_redir_port) and { + listen = "0.0.0.0:" .. local_udp_redir_port, + timeout = 60 + } or nil + } + + return jsonc.stringify(config, 1) +end + +_G.gen_config = gen_config + +if arg[1] then + local func =_G[arg[1]] + if func then + print(func(api.get_function_args(arg))) + end +end diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/api/util_naiveproxy.lua b/luci-app-passwall/luasrc/model/cbi/passwall/api/util_naiveproxy.lua new file mode 100644 index 000000000..d8576a4ff --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/api/util_naiveproxy.lua @@ -0,0 +1,39 @@ +module("luci.model.cbi.passwall.api.util_naiveproxy", package.seeall) +local api = require "luci.model.cbi.passwall.api.api" +local uci = api.uci +local jsonc = api.jsonc + +function gen_config(var) + local node_id = var["-node"] + if not node_id then + print("-node 不能为空") + return + end + local node = uci:get_all("passwall", node_id) + local run_type = var["-run_type"] + local local_addr = var["-local_addr"] + local local_port = var["-local_port"] + local server_host = var["-server_host"] or node.address + local server_port = var["-server_port"] or node.port + + if api.is_ipv6(server_host) then + server_host = api.get_ipv6_full(server_host) + end + local server = server_host .. ":" .. server_port + + local config = { + listen = run_type .. "://" .. local_addr .. ":" .. local_port, + proxy = node.protocol .. "://" .. node.username .. ":" .. node.password .. "@" .. server + } + + return jsonc.stringify(config, 1) +end + +_G.gen_config = gen_config + +if arg[1] then + local func =_G[arg[1]] + if func then + print(func(api.get_function_args(arg))) + end +end diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/api/util_shadowsocks.lua b/luci-app-passwall/luasrc/model/cbi/passwall/api/util_shadowsocks.lua new file mode 100644 index 000000000..cc8e29317 --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/api/util_shadowsocks.lua @@ -0,0 +1,119 @@ +module("luci.model.cbi.passwall.api.util_shadowsocks", package.seeall) +local api = require "luci.model.cbi.passwall.api.api" +local uci = api.uci +local jsonc = api.jsonc + +function gen_config(var) + local node_id = var["-node"] + if not node_id then + print("-node 不能为空") + return + end + local node = uci:get_all("passwall", node_id) + local server_host = var["-server_host"] or node.address + local server_port = var["-server_port"] or node.port + local local_addr = var["-local_addr"] + local local_port = var["-local_port"] + local mode = var["-mode"] + local local_socks_address = var["-local_socks_address"] or "0.0.0.0" + local local_socks_port = var["-local_socks_port"] + local local_socks_username = var["-local_socks_username"] + local local_socks_password = var["-local_socks_password"] + local local_http_address = var["-local_http_address"] or "0.0.0.0" + local local_http_port = var["-local_http_port"] + local local_http_username = var["-local_http_username"] + local local_http_password = var["-local_http_password"] + local local_tcp_redir_port = var["-local_tcp_redir_port"] + local local_tcp_redir_address = var["-local_tcp_redir_address"] or "0.0.0.0" + local local_udp_redir_port = var["-local_udp_redir_port"] + local local_udp_redir_address = var["-local_udp_redir_address"] or "0.0.0.0" + + if api.is_ipv6(server_host) then + server_host = api.get_ipv6_only(server_host) + end + local server = server_host + + local config = { + server = server, + server_port = tonumber(server_port), + local_address = local_addr, + local_port = tonumber(local_port), + password = node.password, + method = node.method, + timeout = tonumber(node.timeout), + fast_open = (node.tcp_fast_open and node.tcp_fast_open == "true") and true or false, + reuse_port = true, + tcp_tproxy = var["-tcp_tproxy"] and true or nil + } + + if node.type == "SS" then + if node.plugin and node.plugin ~= "none" then + config.plugin = node.plugin + config.plugin_opts = node.plugin_opts or nil + end + config.mode = mode + elseif node.type == "SSR" then + config.protocol = node.protocol + config.protocol_param = node.protocol_param + config.obfs = node.obfs + config.obfs_param = node.obfs_param + elseif node.type == "SS-Rust" then + config = { + servers = { + { + address = server, + port = tonumber(server_port), + method = node.method, + password = node.password, + timeout = tonumber(node.timeout), + plugin = (node.plugin and node.plugin ~= "none") and node.plugin or nil, + plugin_opts = (node.plugin and node.plugin ~= "none") and node.plugin_opts or nil + } + }, + locals = {}, + fast_open = (node.tcp_fast_open and node.tcp_fast_open == "true") and true or false + } + if local_socks_address and local_socks_port then + table.insert(config.locals, { + local_address = local_socks_address, + local_port = tonumber(local_socks_port), + mode = "tcp_and_udp" + }) + end + if local_http_address and local_http_port then + table.insert(config.locals, { + protocol = "http", + local_address = local_http_address, + local_port = tonumber(local_http_port) + }) + end + if local_tcp_redir_address and local_tcp_redir_port then + table.insert(config.locals, { + protocol = "redir", + mode = "tcp_only", + tcp_redir = var["-tcp_tproxy"] and "tproxy" or nil, + local_address = local_tcp_redir_address, + local_port = tonumber(local_tcp_redir_port) + }) + end + if local_udp_redir_address and local_udp_redir_port then + table.insert(config.locals, { + protocol = "redir", + mode = "udp_only", + local_address = local_udp_redir_address, + local_port = tonumber(local_udp_redir_port) + }) + end + end + + return jsonc.stringify(config, 1) +end + +_G.gen_config = gen_config + +if arg[1] then + local func =_G[arg[1]] + if func then + print(func(api.get_function_args(arg))) + end +end diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/api/util_trojan.lua b/luci-app-passwall/luasrc/model/cbi/passwall/api/util_trojan.lua new file mode 100644 index 000000000..ed804cba2 --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/api/util_trojan.lua @@ -0,0 +1,97 @@ +module("luci.model.cbi.passwall.api.util_trojan", package.seeall) +local api = require "luci.model.cbi.passwall.api.api" +local uci = api.uci +local json = api.jsonc + +function gen_config(var) + local node_id = var["-node"] + if not node_id then + print("-node 不能为空") + return + end + local node = uci:get_all("passwall", node_id) + local run_type = var["-run_type"] + local local_addr = var["-local_addr"] + local local_port = var["-local_port"] + local server_host = var["-server_host"] or node.address + local server_port = var["-server_port"] or node.port + local loglevel = var["-loglevel"] or 2 + 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" + + if api.is_ipv6(server_host) then + server_host = api.get_ipv6_only(server_host) + end + local server = server_host + + local trojan = { + run_type = run_type, + local_addr = local_addr, + local_port = tonumber(local_port), + remote_addr = server, + remote_port = tonumber(server_port), + password = {node.password}, + log_level = tonumber(loglevel), + ssl = { + verify = (node.tls_allowInsecure ~= "1") and true or false, + verify_hostname = true, + cert = nil, + cipher = cipher, + cipher_tls13 = cipher13, + sni = node.tls_serverName or server, + alpn = {"h2", "http/1.1"}, + reuse_session = true, + session_ticket = (node.tls_sessionTicket and node.tls_sessionTicket == "1") and true or false, + curves = "" + }, + udp_timeout = 60, + tcp = { + use_tproxy = (node.type == "Trojan-Plus" and var["-use_tproxy"]) and true or nil, + no_delay = true, + keep_alive = true, + reuse_port = true, + fast_open = (node.tcp_fast_open == "true") and true or false, + fast_open_qlen = 20 + } + } + if node.type == "Trojan-Go" then + trojan.ssl.cipher = nil + trojan.ssl.cipher_tls13 = nil + trojan.ssl.fingerprint = (node.fingerprint ~= "disable") and node.fingerprint or "" + trojan.ssl.alpn = (node.trojan_transport == 'ws') and {} or {"h2", "http/1.1"} + if node.tls ~= "1" and node.trojan_transport == "original" then trojan.ssl = nil end + trojan.transport_plugin = ((not node.tls or node.tls ~= "1") 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, + 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 == 'ws') and { + enabled = true, + path = node.ws_path or "/", + host = node.ws_host or (node.tls_serverName or server) + } or nil + trojan.shadowsocks = (node.ss_aead == "1") and { + enabled = true, + method = node.ss_aead_method or "aes_128_gcm", + password = node.ss_aead_pwd or "" + } or nil + trojan.mux = (node.smux == "1") and { + enabled = true, + concurrency = tonumber(node.mux_concurrency), + idle_timeout = tonumber(node.smux_idle_timeout) + } or nil + end + return json.stringify(trojan, 1) +end + +_G.gen_config = gen_config + +if arg[1] then + local func =_G[arg[1]] + if func then + print(func(api.get_function_args(arg))) + end +end diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/api/util_xray.lua b/luci-app-passwall/luasrc/model/cbi/passwall/api/util_xray.lua new file mode 100644 index 000000000..66bf669a4 --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/api/util_xray.lua @@ -0,0 +1,926 @@ +module("luci.model.cbi.passwall.api.util_xray", package.seeall) +local api = require "luci.model.cbi.passwall.api.api" +local uci = api.uci +local sys = api.sys +local jsonc = api.jsonc +local appname = api.appname +local fs = api.fs + +local new_port + +local function get_new_port() + if new_port then + new_port = tonumber(sys.exec(string.format("echo -n $(/usr/share/%s/app.sh get_new_port %s tcp)", appname, new_port + 1))) + else + new_port = tonumber(sys.exec(string.format("echo -n $(/usr/share/%s/app.sh get_new_port auto tcp)", appname))) + end + return new_port +end + +local function get_domain_excluded() + local path = string.format("/usr/share/%s/rules/domains_excluded", appname) + local content = fs.readfile(path) + if not content then return nil end + local hosts = {} + string.gsub(content, '[^' .. "\n" .. ']+', function(w) + local s = w:gsub("^%s*(.-)%s*$", "%1") -- Trim + if s == "" then return end + if s:find("#") and s:find("#") == 1 then return end + if not s:find("#") or s:find("#") ~= 1 then table.insert(hosts, s) end + end) + if #hosts == 0 then hosts = nil end + return hosts +end + +function gen_outbound(flag, node, tag, proxy_table) + local proxy = 0 + local proxy_tag = "nil" + local dialerProxy = nil + if proxy_table ~= nil and type(proxy_table) == "table" then + proxy = proxy_table.proxy or 0 + proxy_tag = proxy_table.tag or "nil" + dialerProxy = proxy_table.dialerProxy + end + local result = nil + if node and node ~= "nil" then + local node_id = node[".name"] + if tag == nil then + tag = node_id + end + + if node.type == "V2ray" or node.type == "Xray" then + proxy = 0 + if proxy_tag ~= "nil" then + if dialerProxy and dialerProxy == "1" then + node.streamSettings = { + sockopt = { + dialerProxy = proxy_tag + } + } + else + node.proxySettings = { + tag = proxy_tag, + transportLayer = true + } + end + end + end + + if node.type ~= "V2ray" and node.type ~= "Xray" then + if node.type == "Socks" then + node.protocol = "socks" + node.transport = "tcp" + else + local relay_port = node.port + new_port = get_new_port() + local config_file = string.format("%s_%s_%s.json", flag, tag, new_port) + if tag and node_id and tag ~= node_id then + config_file = string.format("%s_%s_%s_%s.json", flag, tag, node_id, new_port) + end + sys.call(string.format('/usr/share/%s/app.sh run_socks "%s"> /dev/null', + appname, + string.format("flag=%s node=%s bind=%s socks_port=%s config_file=%s relay_port=%s", + new_port, --flag + node_id, --node + "127.0.0.1", --bind + new_port, --socks port + config_file, --config file + (proxy == 1 and relay_port) and tostring(relay_port) or "" --relay port + ) + ) + ) + node = {} + node.protocol = "socks" + node.transport = "tcp" + node.address = "127.0.0.1" + node.port = new_port + end + node.stream_security = "none" + else + if node.tls and node.tls == "1" then + node.stream_security = "tls" + end + end + + result = { + _flag_tag = node_id, + _flag_proxy = proxy, + _flag_proxy_tag = proxy_tag, + tag = tag, + proxySettings = node.proxySettings or nil, + protocol = node.protocol, + mux = { + enabled = (node.mux == "1") and true or false, + concurrency = (node.mux_concurrency) and tonumber(node.mux_concurrency) or 8 + } or nil, + -- 底层传输配置 + streamSettings = (node.streamSettings or node.protocol == "vmess" or node.protocol == "vless" or node.protocol == "socks" or node.protocol == "shadowsocks" or node.protocol == "trojan") and { + sockopt = { + mark = 255, + dialerProxy = (node.streamSettings and dialerProxy and dialerProxy == "1") and node.streamSettings.sockopt.dialerProxy or nil + }, + network = node.transport, + security = node.stream_security, + tlsSettings = (node.stream_security == "tls") and { + serverName = node.tls_serverName, + allowInsecure = (node.tls_allowInsecure == "1") and true or false, + fingerprint = (node.type == "Xray" and node.fingerprint and node.fingerprint ~= "") and node.fingerprint or nil + } or nil, + tcpSettings = (node.transport == "tcp" and node.protocol ~= "socks") and { + header = { + type = node.tcp_guise or "none", + request = (node.tcp_guise == "http") and { + path = node.tcp_guise_http_path or {"/"}, + headers = { + Host = node.tcp_guise_http_host or {} + } + } or nil + } + } or nil, + 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), + seed = (node.mkcp_seed and node.mkcp_seed ~= "") and node.mkcp_seed or nil, + header = {type = node.mkcp_guise} + } or nil, + wsSettings = (node.transport == "ws") and { + path = node.ws_path or "", + headers = (node.ws_host ~= nil) and + {Host = node.ws_host} or nil, + maxEarlyData = tonumber(node.ws_maxEarlyData) or nil, + earlyDataHeaderName = (node.ws_earlyDataHeaderName) and node.ws_earlyDataHeaderName or nil + } or nil, + httpSettings = (node.transport == "h2") and { + path = node.h2_path, + host = node.h2_host, + read_idle_timeout = tonumber(node.h2_read_idle_timeout) or nil, + health_check_timeout = tonumber(node.h2_health_check_timeout) or nil + } or nil, + 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, + grpcSettings = (node.transport == "grpc") and { + serviceName = node.grpc_serviceName, + multiMode = (node.grpc_mode == "multi") and true or nil, + idle_timeout = tonumber(node.grpc_idle_timeout) or nil, + health_check_timeout = tonumber(node.grpc_health_check_timeout) or nil, + permit_without_stream = (node.grpc_permit_without_stream == "1") and true or nil, + initial_windows_size = tonumber(node.grpc_initial_windows_size) or nil + } or nil + } or nil, + settings = { + vnext = (node.protocol == "vmess" or node.protocol == "vless") and { + { + address = node.address, + port = tonumber(node.port), + users = { + { + id = node.uuid, + level = 0, + security = (node.protocol == "vmess") and node.security or nil, + encryption = node.encryption or "none", + flow = (node.protocol == "vless" and node.tls == '1' and node.tlsflow) and node.tlsflow or nil + } + } + } + } or nil, + servers = (node.protocol == "socks" or node.protocol == "http" or node.protocol == "shadowsocks" or node.protocol == "trojan") and { + { + address = node.address, + port = tonumber(node.port), + method = node.method or nil, + ivCheck = (node.protocol == "shadowsocks") and node.iv_check == "1" or nil, + uot = (node.protocol == "shadowsocks") and node.uot == "1" or nil, + password = node.password or "", + users = (node.username and node.password) and { + { + user = node.username, + pass = node.password + } + } or nil + } + } or nil, + address = (node.protocol == "wireguard" and node.wireguard_local_address) and node.wireguard_local_address or nil, + secretKey = (node.protocol == "wireguard") and node.wireguard_secret_key or nil, + peers = (node.protocol == "wireguard") and { + { + publicKey = node.wireguard_public_key, + endpoint = node.address .. ":" .. node.port, + preSharedKey = node.wireguard_preSharedKey, + keepAlive = node.wireguard_keepAlive and tonumber(node.wireguard_keepAlive) or nil + } + } or nil, + mtu = (node.protocol == "wireguard" and node.wireguard_mtu) and tonumber(node.wireguard_mtu) or nil + } + } + local alpn = {} + if node.alpn and node.alpn ~= "default" then + string.gsub(node.alpn, '[^' .. "," .. ']+', function(w) + table.insert(alpn, w) + end) + end + if alpn and #alpn > 0 then + if result.streamSettings.tlsSettings then + result.streamSettings.tlsSettings.alpn = alpn + end + end + end + return result +end + +function gen_config(var) + local flag = var["-flag"] + local node_id = var["-node"] + local tcp_proxy_way = var["-tcp_proxy_way"] or "redirect" + local tcp_redir_port = var["-tcp_redir_port"] + local udp_redir_port = var["-udp_redir_port"] + local sniffing = var["-sniffing"] + local route_only = var["-route_only"] + local buffer_size = var["-buffer_size"] + local local_socks_address = var["-local_socks_address"] or "0.0.0.0" + local local_socks_port = var["-local_socks_port"] + local local_socks_username = var["-local_socks_username"] + local local_socks_password = var["-local_socks_password"] + local local_http_address = var["-local_http_address"] or "0.0.0.0" + local local_http_port = var["-local_http_port"] + local local_http_username = var["-local_http_username"] + local local_http_password = var["-local_http_password"] + local dns_listen_port = var["-dns_listen_port"] + local dns_query_strategy = var["-dns_query_strategy"] + local remote_dns_server = var["-remote_dns_server"] + local remote_dns_port = var["-remote_dns_port"] + local remote_dns_tcp_server = var["-remote_dns_tcp_server"] + local remote_dns_doh_url = var["-remote_dns_doh_url"] + local remote_dns_doh_host = var["-remote_dns_doh_host"] + local remote_dns_fake = var["-remote_dns_fake"] + local dns_cache = var["-dns_cache"] + local dns_client_ip = var["-dns_client_ip"] + local dns_socks_address = var["-dns_socks_address"] + local dns_socks_port = var["-dns_socks_port"] + local loglevel = var["-loglevel"] or "warning" + + local dns = nil + local fakedns = nil + local routing = nil + local inbounds = {} + local outbounds = {} + + if node_id then + local node = uci:get_all(appname, node_id) + if local_socks_port then + local inbound = { + listen = local_socks_address, + port = tonumber(local_socks_port), + protocol = "socks", + settings = {auth = "noauth", udp = true}, + sniffing = {enabled = true, destOverride = {"http", "tls"}} + } + if local_socks_username and local_socks_password and local_socks_username ~= "" and local_socks_password ~= "" then + inbound.settings.auth = "password" + inbound.settings.accounts = { + { + user = local_socks_username, + pass = local_socks_password + } + } + end + table.insert(inbounds, inbound) + end + if local_http_port then + local inbound = { + listen = local_http_address, + port = tonumber(local_http_port), + protocol = "http", + settings = {allowTransparent = false} + } + if local_http_username and local_http_password and local_http_username ~= "" and local_http_password ~= "" then + inbound.settings.accounts = { + { + user = local_http_username, + pass = local_http_password + } + } + end + table.insert(inbounds, inbound) + end + + if tcp_redir_port or udp_redir_port then + local inbound = { + protocol = "dokodemo-door", + settings = {network = "tcp,udp", followRedirect = true}, + streamSettings = {sockopt = {tproxy = "tproxy"}}, + sniffing = {enabled = sniffing and true or false, destOverride = {"http", "tls", (remote_dns_fake) and "fakedns"}, metadataOnly = false, routeOnly = route_only and true or nil, domainsExcluded = (sniffing and not route_only) and get_domain_excluded() or nil} + } + + if tcp_redir_port then + local tcp_inbound = api.clone(inbound) + tcp_inbound.tag = "tcp_redir" + tcp_inbound.settings.network = "tcp" + tcp_inbound.port = tonumber(tcp_redir_port) + tcp_inbound.streamSettings.sockopt.tproxy = tcp_proxy_way + table.insert(inbounds, tcp_inbound) + end + + if udp_redir_port then + local udp_inbound = api.clone(inbound) + udp_inbound.tag = "udp_redir" + udp_inbound.settings.network = "udp" + udp_inbound.port = tonumber(udp_redir_port) + table.insert(inbounds, udp_inbound) + end + end + + if node.protocol == "_shunt" then + local rules = {} + + local default_node_id = node.default_node or "_direct" + local default_outboundTag + if default_node_id == "_direct" then + default_outboundTag = "direct" + elseif default_node_id == "_blackhole" then + default_outboundTag = "blackhole" + else + local default_node = uci:get_all(appname, default_node_id) + local main_node_id = node.main_node or "nil" + local proxy = 0 + local proxy_tag + if main_node_id ~= "nil" then + local main_node = uci:get_all(appname, main_node_id) + if main_node and api.is_normal_node(main_node) and main_node_id ~= default_node_id then + local main_node_outbound = gen_outbound(flag, main_node, "main") + if main_node_outbound then + table.insert(outbounds, main_node_outbound) + proxy = 1 + proxy_tag = "main" + if default_node.type ~= "V2ray" and default_node.type ~= "Xray" then + proxy_tag = nil + new_port = get_new_port() + table.insert(inbounds, { + tag = "proxy_default", + listen = "127.0.0.1", + port = new_port, + protocol = "dokodemo-door", + settings = {network = "tcp,udp", address = default_node.address, port = tonumber(default_node.port)} + }) + if default_node.tls_serverName == nil then + default_node.tls_serverName = default_node.address + end + default_node.address = "127.0.0.1" + default_node.port = new_port + table.insert(rules, 1, { + type = "field", + inboundTag = {"proxy_default"}, + outboundTag = "main" + }) + end + end + end + end + if default_node and api.is_normal_node(default_node) then + local default_outbound = gen_outbound(flag, default_node, "default", { proxy = proxy, tag = proxy_tag, dialerProxy = node.dialerProxy }) + if default_outbound then + table.insert(outbounds, default_outbound) + default_outboundTag = "default" + end + end + end + + uci:foreach(appname, "shunt_rules", function(e) + local name = e[".name"] + if name and e.remarks then + local _node_id = node[name] or "nil" + local proxy_tag = node[name .. "_proxy_tag"] or "nil" + local outboundTag + if _node_id == "_direct" then + outboundTag = "direct" + elseif _node_id == "_blackhole" then + outboundTag = "blackhole" + elseif _node_id == "_default" then + outboundTag = "default" + else + if _node_id ~= "nil" then + local _node = uci:get_all(appname, _node_id) + if _node and api.is_normal_node(_node) then + local new_outbound + for index, value in ipairs(outbounds) do + if value["_flag_tag"] == _node_id and value["_flag_proxy_tag"] == proxy_tag then + new_outbound = api.clone(value) + break + end + end + if new_outbound then + new_outbound["tag"] = name + table.insert(outbounds, new_outbound) + outboundTag = name + else + if _node.type ~= "V2ray" and _node.type ~= "Xray" then + if proxy_tag ~= "nil" then + new_port = get_new_port() + table.insert(inbounds, { + tag = "proxy_" .. name, + listen = "127.0.0.1", + port = new_port, + protocol = "dokodemo-door", + settings = {network = "tcp,udp", address = _node.address, port = tonumber(_node.port)} + }) + if _node.tls_serverName == nil then + _node.tls_serverName = _node.address + end + _node.address = "127.0.0.1" + _node.port = new_port + table.insert(rules, 1, { + type = "field", + inboundTag = {"proxy_" .. name}, + outboundTag = proxy_tag + }) + end + end + local _outbound = gen_outbound(flag, _node, name, { proxy = (proxy_tag ~= "nil") and 1 or 0, tag = (proxy_tag ~= "nil") and proxy_tag or nil, dialerProxy = node.dialerProxy }) + if _outbound then + table.insert(outbounds, _outbound) + outboundTag = name + end + end + end + end + end + if outboundTag then + if outboundTag == "default" then + outboundTag = default_outboundTag + end + local protocols = nil + if e["protocol"] and e["protocol"] ~= "" then + protocols = {} + string.gsub(e["protocol"], '[^' .. " " .. ']+', function(w) + table.insert(protocols, w) + end) + end + if e.domain_list then + local _domain = {} + string.gsub(e.domain_list, '[^' .. "\r\n" .. ']+', function(w) + table.insert(_domain, w) + end) + table.insert(rules, { + type = "field", + outboundTag = outboundTag, + domain = _domain, + protocol = protocols + }) + end + if e.ip_list then + local _ip = {} + string.gsub(e.ip_list, '[^' .. "\r\n" .. ']+', function(w) + table.insert(_ip, w) + end) + table.insert(rules, { + type = "field", + outboundTag = outboundTag, + ip = _ip, + protocol = protocols + }) + end + if not e.domain_list and not e.ip_list and protocols then + table.insert(rules, { + type = "field", + outboundTag = outboundTag, + protocol = protocols + }) + end + end + end + end) + + if default_outboundTag then + table.insert(rules, { + type = "field", + outboundTag = default_outboundTag, + network = "tcp,udp" + }) + end + + routing = { + domainStrategy = node.domainStrategy or "AsIs", + domainMatcher = node.domainMatcher or "hybrid", + rules = rules + } + 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 = uci:get_all(appname, nodes[i]) + local outbound = gen_outbound(flag, node) + if outbound then table.insert(outbounds, outbound) end + end + routing = { + domainStrategy = node.domainStrategy or "AsIs", + domainMatcher = node.domainMatcher or "hybrid", + balancers = {{tag = "balancer", selector = nodes}}, + rules = { + {type = "field", network = "tcp,udp", balancerTag = "balancer"} + } + } + end + else + local outbound = nil + if node.protocol == "_iface" then + if node.iface then + outbound = { + protocol = "freedom", + tag = "outbound", + streamSettings = { + sockopt = { + interface = node.iface + } + } + } + end + else + outbound = gen_outbound(flag, node) + end + if outbound then table.insert(outbounds, outbound) end + routing = { + domainStrategy = "AsIs", + domainMatcher = "hybrid", + rules = {} + } + end + end + + if remote_dns_server or remote_dns_doh_url or remote_dns_fake then + local rules = {} + local _remote_dns_proto = "tcp" + local _remote_dns_host + + if not routing then + routing = { + domainStrategy = "IPOnDemand", + rules = {} + } + end + + dns = { + tag = "dns-in1", + hosts = {}, + disableCache = (dns_cache and dns_cache == "0") and true or false, + disableFallback = true, + disableFallbackIfMatch = true, + servers = {}, + clientIp = (dns_client_ip and dns_client_ip ~= "") and dns_client_ip or nil, + queryStrategy = (dns_query_strategy and dns_query_strategy ~= "") and dns_query_strategy or "UseIPv4" + } + + local _remote_dns = { + --_flag = "remote" + } + + if remote_dns_tcp_server then + _remote_dns.address = remote_dns_tcp_server + _remote_dns.port = tonumber(remote_dns_port) + end + + if remote_dns_doh_url and remote_dns_doh_host then + if remote_dns_server and remote_dns_doh_host ~= remote_dns_server and not api.is_ip(remote_dns_doh_host) then + dns.hosts[remote_dns_doh_host] = remote_dns_server + _remote_dns_host = remote_dns_doh_host + end + _remote_dns.address = remote_dns_doh_url + _remote_dns.port = tonumber(remote_dns_port) + _remote_dns_proto = "doh" + end + + if remote_dns_fake then + remote_dns_server = "1.1.1.1" + fakedns = {} + fakedns[#fakedns + 1] = { + ipPool = "198.18.0.0/16", + poolSize = 65535 + } + if dns_query_strategy == "UseIP" then + fakedns[#fakedns + 1] = { + ipPool = "fc00::/18", + poolSize = 65535 + } + end + _remote_dns.address = "fakedns" + end + + table.insert(dns.servers, _remote_dns) + + if dns_listen_port then + table.insert(inbounds, { + listen = "127.0.0.1", + port = tonumber(dns_listen_port), + protocol = "dokodemo-door", + tag = "dns-in", + settings = { + address = remote_dns_server, + port = (_remote_dns_proto ~= "doh" and tonumber(remote_dns_port)) and tonumber(remote_dns_port) or 53, + network = "tcp,udp" + } + }) + + table.insert(outbounds, { + tag = "dns-out", + protocol = "dns", + settings = { + address = remote_dns_server, + port = (_remote_dns_proto ~= "doh" and tonumber(remote_dns_port)) and tonumber(remote_dns_port) or 53, + network = "tcp", + } + }) + + table.insert(routing.rules, 1, { + type = "field", + inboundTag = { + "dns-in" + }, + outboundTag = "dns-out" + }) + end + + --[[ + local default_dns_flag = "remote" + if node_id and tcp_redir_port then + local node = uci:get_all(appname, node_id) + if node.protocol == "_shunt" then + if node.default_node == "_direct" then + default_dns_flag = "direct" + end + end + end + + if dns.servers and #dns.servers > 0 then + local dns_servers = nil + for index, value in ipairs(dns.servers) do + if not dns_servers and value["_flag"] == default_dns_flag then + dns_servers = { + _flag = "default", + address = value.address, + port = value.port + } + break + end + end + if dns_servers then + table.insert(dns.servers, 1, dns_servers) + end + end + ]]-- + if true then + local dns_outboundTag = "direct" + if dns_socks_address and dns_socks_port then + dns_outboundTag = "out" + table.insert(outbounds, 1, { + tag = dns_outboundTag, + protocol = "socks", + streamSettings = { + network = "tcp", + security = "none", + sockopt = { + mark = 255 + } + }, + settings = { + servers = { + { + address = dns_socks_address, + port = tonumber(dns_socks_port) + } + } + } + }) + else + if node_id and tcp_redir_port and not remote_dns_fake then + dns_outboundTag = node_id + local node = uci:get_all(appname, node_id) + if node.protocol == "_shunt" then + dns_outboundTag = "default" + end + end + end + table.insert(rules, { + type = "field", + inboundTag = { + "dns-in1" + }, + ip = { + remote_dns_server + }, + port = tonumber(remote_dns_port), + outboundTag = dns_outboundTag + }) + if _remote_dns_host then + table.insert(rules, { + type = "field", + inboundTag = { + "dns-in1" + }, + domain = { + _remote_dns_host + }, + port = tonumber(remote_dns_port), + outboundTag = dns_outboundTag + }) + end + end + + local default_rule_index = #routing.rules > 0 and #routing.rules or 1 + for index, value in ipairs(routing.rules) do + if value["_flag"] == "default" then + default_rule_index = index + break + end + end + for index, value in ipairs(rules) do + local t = rules[#rules + 1 - index] + table.insert(routing.rules, default_rule_index, t) + end + + local dns_hosts_len = 0 + for key, value in pairs(dns.hosts) do + dns_hosts_len = dns_hosts_len + 1 + end + + if dns_hosts_len == 0 then + dns.hosts = nil + end + end + + if inbounds or outbounds then + local config = { + log = { + -- error = string.format("/tmp/etc/%s/%s.log", appname, node[".name"]), + loglevel = loglevel + }, + -- DNS + dns = dns, + fakedns = fakedns, + -- 传入连接 + inbounds = inbounds, + -- 传出连接 + outbounds = outbounds, + -- 路由 + routing = routing, + -- 本地策略 + policy = { + levels = { + [0] = { + -- handshake = 4, + -- connIdle = 300, + -- uplinkOnly = 2, + -- downlinkOnly = 5, + bufferSize = buffer_size and tonumber(buffer_size) or nil, + statsUserUplink = false, + statsUserDownlink = false + } + }, + -- system = { + -- statsInboundUplink = false, + -- statsInboundDownlink = false + -- } + } + } + table.insert(outbounds, { + protocol = "freedom", + tag = "direct", + settings = { + domainStrategy = (dns_query_strategy and dns_query_strategy ~= "") and dns_query_strategy or "UseIPv4" + }, + streamSettings = { + sockopt = { + mark = 255 + } + } + }) + table.insert(outbounds, { + protocol = "blackhole", + tag = "blackhole" + }) + return jsonc.stringify(config, 1) + end +end + +function gen_proto_config(var) + local local_socks_address = var["-local_socks_address"] or "0.0.0.0" + local local_socks_port = var["-local_socks_port"] + local local_socks_username = var["-local_socks_username"] + local local_socks_password = var["-local_socks_password"] + local local_http_address = var["-local_http_address"] or "0.0.0.0" + local local_http_port = var["-local_http_port"] + local local_http_username = var["-local_http_username"] + local local_http_password = var["-local_http_password"] + local server_proto = var["-server_proto"] + local server_address = var["-server_address"] + local server_port = var["-server_port"] + local server_username = var["-server_username"] + local server_password = var["-server_password"] + + local inbounds = {} + local outbounds = {} + local routing = nil + + if local_socks_address and local_socks_port then + local inbound = { + listen = local_socks_address, + port = tonumber(local_socks_port), + protocol = "socks", + settings = { + udp = true, + auth = "noauth" + } + } + if local_socks_username and local_socks_password and local_socks_username ~= "" and local_socks_password ~= "" then + inbound.settings.auth = "password" + inbound.settings.accounts = { + { + user = local_socks_username, + pass = local_socks_password + } + } + end + table.insert(inbounds, inbound) + end + + if local_http_address and local_http_port then + local inbound = { + listen = local_http_address, + port = tonumber(local_http_port), + protocol = "http", + settings = { + allowTransparent = false + } + } + if local_http_username and local_http_password and local_http_username ~= "" and local_http_password ~= "" then + inbound.settings.accounts = { + { + user = local_http_username, + pass = local_http_password + } + } + end + table.insert(inbounds, inbound) + end + + if server_proto ~= "nil" and server_address ~= "nil" and server_port ~= "nil" then + local outbound = { + protocol = server_proto, + streamSettings = { + network = "tcp", + security = "none" + }, + settings = { + servers = { + { + address = server_address, + port = tonumber(server_port), + users = (server_username and server_password) and { + { + user = server_username, + pass = server_password + } + } or nil + } + } + } + } + if outbound then table.insert(outbounds, outbound) end + end + + -- 额外传出连接 + table.insert(outbounds, { + protocol = "freedom", tag = "direct", settings = {keep = ""}, sockopt = {mark = 255} + }) + + local config = { + log = { + loglevel = "warning" + }, + -- 传入连接 + inbounds = inbounds, + -- 传出连接 + outbounds = outbounds, + -- 路由 + routing = routing + } + return jsonc.stringify(config, 1) +end + +_G.gen_config = gen_config +_G.gen_proto_config = gen_proto_config + +if arg[1] then + local func =_G[arg[1]] + if func then + print(func(api.get_function_args(arg))) + end +end diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/server/api/app.lua b/luci-app-passwall/luasrc/model/cbi/passwall/server/api/app.lua index af2c548b9..46cb4e893 100755 --- a/luci-app-passwall/luasrc/model/cbi/passwall/server/api/app.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/server/api/app.lua @@ -143,10 +143,10 @@ local function start() config = require(require_dir .. "shadowsocks").gen_config(user) bin = ln_run("/usr/bin/ssserver", "ssserver", "-c " .. config_file, log_path) elseif type == "V2ray" then - config = require(require_dir .. "v2ray").gen_config(user) + config = require(require_dir .. "xray").gen_config(user) bin = ln_run(api.get_v2ray_path(), "v2ray", "run -c " .. config_file, log_path) elseif type == "Xray" then - config = require(require_dir .. "v2ray").gen_config(user) + config = require(require_dir .. "xray").gen_config(user) bin = ln_run(api.get_xray_path(), "xray", "run -c " .. config_file, log_path) elseif type == "Trojan" then config = require(require_dir .. "trojan").gen_config(user) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/server/api/v2ray.lua b/luci-app-passwall/luasrc/model/cbi/passwall/server/api/xray.lua similarity index 97% rename from luci-app-passwall/luasrc/model/cbi/passwall/server/api/v2ray.lua rename to luci-app-passwall/luasrc/model/cbi/passwall/server/api/xray.lua index ca883d038..2e05735a9 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/server/api/v2ray.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/server/api/xray.lua @@ -1,4 +1,4 @@ -module("luci.model.cbi.passwall.server.api.v2ray", package.seeall) +module("luci.model.cbi.passwall.server.api.xray", package.seeall) local uci = require"luci.model.uci".cursor() function gen_config(user) @@ -141,7 +141,7 @@ function gen_config(user) password = (user.outbound_node_password and user.outbound_node_password ~= "") and user.outbound_node_password or nil, } end - outbound = require("luci.model.cbi.passwall.api.gen_v2ray").gen_outbound(outbound_node_t, "outbound") + outbound = require("luci.model.cbi.passwall.api.util_xray").gen_outbound(nil, outbound_node_t, "outbound") end if outbound then table.insert(outbounds, 1, outbound) diff --git a/luci-app-passwall/root/usr/share/passwall/app.sh b/luci-app-passwall/root/usr/share/passwall/app.sh index 79e9b85d8..53c8692bb 100755 --- a/luci-app-passwall/root/usr/share/passwall/app.sh +++ b/luci-app-passwall/root/usr/share/passwall/app.sh @@ -32,12 +32,11 @@ resolve_dns=0 use_tcp_node_resolve_dns=0 use_udp_node_resolve_dns=0 LUA_API_PATH=/usr/lib/lua/luci/model/cbi/$CONFIG/api -API_GEN_SS=$LUA_API_PATH/gen_shadowsocks.lua -API_GEN_V2RAY=$LUA_API_PATH/gen_v2ray.lua -API_GEN_V2RAY_PROTO=$LUA_API_PATH/gen_v2ray_proto.lua -API_GEN_TROJAN=$LUA_API_PATH/gen_trojan.lua -API_GEN_NAIVE=$LUA_API_PATH/gen_naiveproxy.lua -API_GEN_HYSTERIA=$LUA_API_PATH/gen_hysteria.lua +UTIL_SS=$LUA_API_PATH/util_shadowsocks.lua +UTIL_XRAY=$LUA_API_PATH/util_xray.lua +UTIL_TROJAN=$LUA_API_PATH/util_trojan.lua +UTIL_NAIVE=$LUA_API_PATH/util_naiveproxy.lua +UTIL_HYSTERIA=$LUA_API_PATH/util_hysteria.lua echolog() { local d="$(date "+%Y-%m-%d %H:%M:%S")" @@ -359,7 +358,7 @@ run_v2ray() { esac _extra_param="${_extra_param} -tcp_proxy_way $tcp_proxy_way" _extra_param="${_extra_param} -loglevel $loglevel" - lua $API_GEN_V2RAY ${_extra_param} > $config_file + lua $UTIL_XRAY gen_config ${_extra_param} > $config_file ln_run "$(first_type $(config_t_get global_app ${type}_file) ${type})" ${type} $log_file run -c "$config_file" local protocol=$(config_n_get $node protocol) [ "$protocol" == "_iface" ] && { @@ -449,7 +448,7 @@ run_socks() { config_file=$(echo $config_file | sed "s/SOCKS/HTTP_SOCKS/g") local _extra_param="-local_http_port $http_port" } - lua $API_GEN_V2RAY_PROTO -local_socks_port $socks_port ${_extra_param} -server_proto socks -server_address ${_socks_address} -server_port ${_socks_port} -server_username ${_socks_username} -server_password ${_socks_password} > $config_file + lua $UTIL_XRAY gen_proto_config -local_socks_port $socks_port ${_extra_param} -server_proto socks -server_address ${_socks_address} -server_port ${_socks_port} -server_username ${_socks_username} -server_password ${_socks_password} > $config_file ln_run "$bin" $type $log_file run -c "$config_file" ;; v2ray|\ @@ -462,15 +461,15 @@ run_socks() { run_v2ray flag=$flag node=$node socks_port=$socks_port config_file=$config_file log_file=$log_file ${_v2ray_args} ;; trojan-go) - lua $API_GEN_TROJAN -node $node -run_type client -local_addr $bind -local_port $socks_port -server_host $server_host -server_port $port > $config_file + lua $UTIL_TROJAN gen_config -node $node -run_type client -local_addr $bind -local_port $socks_port -server_host $server_host -server_port $port > $config_file ln_run "$(first_type $(config_t_get global_app trojan_go_file) trojan-go)" trojan-go $log_file -config "$config_file" ;; trojan*) - lua $API_GEN_TROJAN -node $node -run_type client -local_addr $bind -local_port $socks_port -server_host $server_host -server_port $port > $config_file + lua $UTIL_TROJAN gen_config -node $node -run_type client -local_addr $bind -local_port $socks_port -server_host $server_host -server_port $port > $config_file ln_run "$(first_type ${type})" "${type}" $log_file -c "$config_file" ;; naiveproxy) - lua $API_GEN_NAIVE -node $node -run_type socks -local_addr $bind -local_port $socks_port -server_host $server_host -server_port $port > $config_file + lua $UTIL_NAIVE gen_config -node $node -run_type socks -local_addr $bind -local_port $socks_port -server_host $server_host -server_port $port > $config_file ln_run "$(first_type naive)" naive $log_file "$config_file" ;; brook) @@ -489,11 +488,11 @@ run_socks() { ln_run "$(first_type $(config_t_get global_app brook_file) brook)" "brook_SOCKS_${flag}" $log_file "$protocol" --socks5 "$bind:$socks_port" -s "${server_host}:${port}${ws_path}" -p "$(config_n_get $node password)" ;; ssr) - lua $API_GEN_SS -node $node -local_addr "0.0.0.0" -local_port $socks_port -server_host $server_host -server_port $port > $config_file + lua $UTIL_SS gen_config -node $node -local_addr "0.0.0.0" -local_port $socks_port -server_host $server_host -server_port $port > $config_file ln_run "$(first_type ssr-local)" "ssr-local" $log_file -c "$config_file" -v -u ;; ss) - lua $API_GEN_SS -node $node -local_addr "0.0.0.0" -local_port $socks_port -server_host $server_host -server_port $port -mode tcp_and_udp > $config_file + lua $UTIL_SS gen_config -node $node -local_addr "0.0.0.0" -local_port $socks_port -server_host $server_host -server_port $port -mode tcp_and_udp > $config_file ln_run "$(first_type ss-local)" "ss-local" $log_file -c "$config_file" -v ;; ss-rust) @@ -502,7 +501,7 @@ run_socks() { config_file=$(echo $config_file | sed "s/SOCKS/HTTP_SOCKS/g") local _extra_param="-local_http_port $http_port" } - lua $API_GEN_SS -node $node -local_socks_port $socks_port -server_host $server_host -server_port $port ${_extra_param} > $config_file + lua $UTIL_SS gen_config -node $node -local_socks_port $socks_port -server_host $server_host -server_port $port ${_extra_param} > $config_file ln_run "$(first_type sslocal)" "sslocal" $log_file -c "$config_file" -v ;; hysteria) @@ -511,7 +510,7 @@ run_socks() { config_file=$(echo $config_file | sed "s/SOCKS/HTTP_SOCKS/g") local _extra_param="-local_http_port $http_port" } - lua $API_GEN_HYSTERIA -node $node -local_socks_port $socks_port -server_host $server_host -server_port $port ${_extra_param} > $config_file + lua $UTIL_HYSTERIA gen_config -node $node -local_socks_port $socks_port -server_host $server_host -server_port $port ${_extra_param} > $config_file ln_run "$(first_type $(config_t_get global_app hysteria_file))" "hysteria" $log_file -c "$config_file" client ;; esac @@ -526,7 +525,7 @@ run_socks() { [ -n "$bin" ] && type="xray" fi [ -z "$type" ] && return 1 - lua $API_GEN_V2RAY_PROTO -local_http_port $http_port -server_proto socks -server_address "127.0.0.1" -server_port $socks_port -server_username $_username -server_password $_password > $http_config_file + lua $UTIL_XRAY gen_proto_config -local_http_port $http_port -server_proto socks -server_address "127.0.0.1" -server_port $socks_port -server_username $_username -server_password $_password > $http_config_file ln_run "$bin" ${type} /dev/null run -c "$http_config_file" } unset http_flag @@ -578,12 +577,12 @@ run_redir() { ;; trojan-go) local loglevel=$(config_t_get global trojan_loglevel "2") - lua $API_GEN_TROJAN -node $node -run_type nat -local_addr "0.0.0.0" -local_port $local_port -loglevel $loglevel > $config_file + lua $UTIL_TROJAN gen_config -node $node -run_type nat -local_addr "0.0.0.0" -local_port $local_port -loglevel $loglevel > $config_file ln_run "$(first_type $(config_t_get global_app trojan_go_file) trojan-go)" trojan-go $log_file -config "$config_file" ;; trojan*) local loglevel=$(config_t_get global trojan_loglevel "2") - lua $API_GEN_TROJAN -node $node -run_type nat -local_addr "0.0.0.0" -local_port $local_port -loglevel $loglevel > $config_file + lua $UTIL_TROJAN gen_config -node $node -run_type nat -local_addr "0.0.0.0" -local_port $local_port -loglevel $loglevel > $config_file ln_run "$(first_type ${type})" "${type}" $log_file -c "$config_file" ;; naiveproxy) @@ -598,19 +597,19 @@ run_redir() { fi ;; ssr) - lua $API_GEN_SS -node $node -local_addr "0.0.0.0" -local_port $local_port > $config_file + lua $UTIL_SS gen_config -node $node -local_addr "0.0.0.0" -local_port $local_port > $config_file ln_run "$(first_type ssr-redir)" "ssr-redir" $log_file -c "$config_file" -v -U ;; ss) - lua $API_GEN_SS -node $node -local_addr "0.0.0.0" -local_port $local_port -mode udp_only > $config_file + lua $UTIL_SS gen_config -node $node -local_addr "0.0.0.0" -local_port $local_port -mode udp_only > $config_file ln_run "$(first_type ss-redir)" "ss-redir" $log_file -c "$config_file" -v ;; ss-rust) - lua $API_GEN_SS -node $node -local_udp_redir_port $local_port > $config_file + lua $UTIL_SS gen_config -node $node -local_udp_redir_port $local_port > $config_file ln_run "$(first_type sslocal)" "sslocal" $log_file -c "$config_file" -v ;; hysteria) - lua $API_GEN_HYSTERIA -node $node -local_udp_redir_port $local_port > $config_file + lua $UTIL_HYSTERIA gen_config -node $node -local_udp_redir_port $local_port > $config_file ln_run "$(first_type $(config_t_get global_app hysteria_file))" "hysteria" $log_file -c "$config_file" client ;; esac @@ -708,7 +707,7 @@ run_redir() { UDP_NODE="nil" } local loglevel=$(config_t_get global trojan_loglevel "2") - lua $API_GEN_TROJAN -node $node -run_type nat -local_addr "0.0.0.0" -local_port $local_port -loglevel $loglevel > $config_file + lua $UTIL_TROJAN gen_config -node $node -run_type nat -local_addr "0.0.0.0" -local_port $local_port -loglevel $loglevel > $config_file ln_run "$(first_type $(config_t_get global_app trojan_go_file) trojan-go)" trojan-go $log_file -config "$config_file" ;; trojan*) @@ -719,11 +718,11 @@ run_redir() { UDP_NODE="nil" } local loglevel=$(config_t_get global trojan_loglevel "2") - lua $API_GEN_TROJAN -node $node -run_type nat -local_addr "0.0.0.0" -local_port $local_port -loglevel $loglevel $lua_tproxy_arg > $config_file + lua $UTIL_TROJAN gen_config -node $node -run_type nat -local_addr "0.0.0.0" -local_port $local_port -loglevel $loglevel $lua_tproxy_arg > $config_file ln_run "$(first_type ${type})" "${type}" $log_file -c "$config_file" ;; naiveproxy) - lua $API_GEN_NAIVE -node $node -run_type redir -local_addr "0.0.0.0" -local_port $local_port > $config_file + lua $UTIL_NAIVE gen_config -node $node -run_type redir -local_addr "0.0.0.0" -local_port $local_port > $config_file ln_run "$(first_type naive)" naive $log_file "$config_file" ;; brook) @@ -747,7 +746,7 @@ run_redir() { UDP_NODE="nil" _extra_param="-u" } - lua $API_GEN_SS -node $node -local_addr "0.0.0.0" -local_port $local_port $lua_tproxy_arg > $config_file + lua $UTIL_SS gen_config -node $node -local_addr "0.0.0.0" -local_port $local_port $lua_tproxy_arg > $config_file ln_run "$(first_type ssr-redir)" "ssr-redir" $log_file -c "$config_file" -v ${_extra_param} ;; ss) @@ -759,7 +758,7 @@ run_redir() { UDP_NODE="nil" lua_mode_arg="-mode tcp_and_udp" } - lua $API_GEN_SS -node $node -local_addr "0.0.0.0" -local_port $local_port $lua_mode_arg $lua_tproxy_arg > $config_file + lua $UTIL_SS gen_config -node $node -local_addr "0.0.0.0" -local_port $local_port $lua_mode_arg $lua_tproxy_arg > $config_file ln_run "$(first_type ss-redir)" "ss-redir" $log_file -c "$config_file" -v ;; ss-rust) @@ -781,7 +780,7 @@ run_redir() { UDP_NODE="nil" _extra_param="${_extra_param} -local_udp_redir_port $local_port" } - lua $API_GEN_SS -node $node ${_extra_param} > $config_file + lua $UTIL_SS gen_config -node $node ${_extra_param} > $config_file ln_run "$(first_type sslocal)" "sslocal" $log_file -c "$config_file" -v ;; hysteria) @@ -803,7 +802,7 @@ run_redir() { _extra_param="${_extra_param} -local_udp_redir_port $local_port" } _extra_param="${_extra_param} -tcp_proxy_way $tcp_proxy_way" - lua $API_GEN_HYSTERIA -node $node ${_extra_param} > $config_file + lua $UTIL_HYSTERIA gen_config -node $node ${_extra_param} > $config_file ln_run "$(first_type $(config_t_get global_app hysteria_file))" "hysteria" $log_file -c "$config_file" client ;; esac