From 5756f01e1738d047e5d252015a0ab0b379154358 Mon Sep 17 00:00:00 2001 From: CN_SZTL Date: Sun, 15 Mar 2020 21:11:16 +0800 Subject: [PATCH] luci-app-passwall: sync with upstream source --- package/lienol/luci-app-passwall/Makefile | 4 +- .../model/cbi/passwall/api/gen_v2ray.lua | 5 +- .../cbi/passwall/api/gen_v2ray_balancing.lua | 203 ++++++++++++++++++ .../cbi/passwall/api/gen_v2ray_shunt.lua | 7 +- .../luasrc/model/cbi/passwall/global.lua | 4 +- .../root/usr/share/passwall/app.sh | 16 +- .../root/usr/share/passwall/subscribe.lua | 69 ++++-- 7 files changed, 274 insertions(+), 34 deletions(-) create mode 100755 package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_v2ray_balancing.lua diff --git a/package/lienol/luci-app-passwall/Makefile b/package/lienol/luci-app-passwall/Makefile index a0cacab8d4..ea44d72bf3 100644 --- a/package/lienol/luci-app-passwall/Makefile +++ b/package/lienol/luci-app-passwall/Makefile @@ -7,8 +7,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-passwall PKG_VERSION:=3.6 -PKG_RELEASE:=22 -PKG_DATE:=20200314 +PKG_RELEASE:=25 +PKG_DATE:=20200315 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_v2ray.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_v2ray.lua index 03d20c2690..5747ce8b81 100755 --- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_v2ray.lua +++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_v2ray.lua @@ -10,12 +10,11 @@ local outbounds = {} local network = proto local routing = nil -local function gen_outbound(node, tag) +local function gen_outbound(node) local result = nil if node then result = { - tag = tag or node[".name"], - cbi_id = node[".name"], + tag = node[".name"], protocol = node.v2ray_protocol or "vmess", mux = { enabled = (node.v2ray_mux == "1") and true or false, diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_v2ray_balancing.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_v2ray_balancing.lua new file mode 100755 index 0000000000..3fae6887ed --- /dev/null +++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_v2ray_balancing.lua @@ -0,0 +1,203 @@ +local ucursor = require"luci.model.uci".cursor() +local sys = require "luci.sys" +local json = require "luci.jsonc" +local node_section = arg[1] +local proto = arg[2] +local redir_port = arg[3] +local socks5_proxy_port = arg[4] +local node = ucursor:get_all("passwall", node_section) +local inbounds = {} +local outbounds = {} +local network = proto +local routing = nil + +local function gen_outbound(node) + local result = nil + if node then + local node_id = node[".name"] + if node.type ~= "V2ray" then + if node.type == "Socks5" then + node.v2ray_protocol = "socks" + node.v2ray_transport = "tcp" + else + local node_type = (proto and proto ~= "nil") and proto or + "socks" + local new_port = sys.exec( + "echo -n $(/usr/share/passwall/app.sh get_new_port auto tcp)") + node.port = new_port + sys.call(string.format( + "/usr/share/passwall/app.sh gen_start_config %s %s %s %s %s %s", + node_id, new_port, "SOCKS5", + "/var/etc/passwall/v2_balancing_" .. node_type .. "_" .. + node_id .. ".json", "4", "127.0.0.1")) + node.v2ray_protocol = "socks" + node.v2ray_transport = "tcp" + node.address = "127.0.0.1" + end + end + result = { + tag = node_id, + protocol = node.v2ray_protocol or "vmess", + mux = { + enabled = (node.v2ray_mux == "1") and true or false, + concurrency = (node.v2ray_mux_concurrency) and + tonumber(node.v2ray_mux_concurrency) or 8 + }, + -- 底层传输配置 + streamSettings = { + network = node.v2ray_transport, + security = node.v2ray_stream_security, + tlsSettings = (node.v2ray_stream_security == "tls") and { + serverName = node.tls_serverName, + allowInsecure = (node.tls_allowInsecure == "1") and true or + false + } or nil, + tcpSettings = (node.v2ray_transport == "tcp" and + node.v2ray_protocol ~= "socks") and { + header = { + type = node.v2ray_tcp_guise, + request = { + path = node.v2ray_tcp_guise_http_path or {"/"}, + headers = { + Host = node.v2ray_tcp_guise_http_host or {} + } + } or {} + } + } or nil, + kcpSettings = (node.v2ray_transport == "mkcp") and { + mtu = tonumber(node.v2ray_mkcp_mtu), + tti = tonumber(node.v2ray_mkcp_tti), + uplinkCapacity = tonumber(node.v2ray_mkcp_uplinkCapacity), + downlinkCapacity = tonumber(node.v2ray_mkcp_downlinkCapacity), + congestion = (node.v2ray_mkcp_congestion == "1") and true or + false, + readBufferSize = tonumber(node.v2ray_mkcp_readBufferSize), + writeBufferSize = tonumber(node.v2ray_mkcp_writeBufferSize), + header = {type = node.v2ray_mkcp_guise} + } or nil, + wsSettings = (node.v2ray_transport == "ws") and { + path = node.v2ray_ws_path or "", + headers = (node.v2ray_ws_host ~= nil) and + {Host = node.v2ray_ws_host} or nil + } or nil, + httpSettings = (node.v2ray_transport == "h2") and + {path = node.v2ray_h2_path, host = node.v2ray_h2_host} or + nil, + dsSettings = (node.v2ray_transport == "ds") and + {path = node.v2ray_ds_path} or nil, + quicSettings = (node.v2ray_transport == "quic") and { + security = node.v2ray_quic_security, + key = node.v2ray_quic_key, + header = {type = node.v2ray_quic_guise} + } or nil + }, + settings = { + vnext = (node.v2ray_protocol == "vmess") and { + { + address = node.address, + port = tonumber(node.port), + users = { + { + id = node.v2ray_VMess_id, + alterId = tonumber(node.v2ray_VMess_alterId), + level = tonumber(node.v2ray_VMess_level), + security = node.v2ray_security + } + } + } + } or nil, + servers = (node.v2ray_protocol == "socks") and { + { + address = node.address, + port = tonumber(node.port), + users = (node.username and node.password) and + {{user = node.username, pass = node.password}} or + nil + } + } or (node.v2ray_protocol == "ss") and { + { + email = nil, + address = node.address, + method = nil, + ota = nil, + password = node.password or nil, + port = tonumber(node.port), + level = 1 + } + } or nil + } + } + end + return result +end + +if socks5_proxy_port ~= "nil" then + table.insert(inbounds, { + listen = "0.0.0.0", + port = socks5_proxy_port, + protocol = "socks", + settings = {auth = "noauth", udp = true, ip = "127.0.0.1"} + }) + network = "tcp,udp" +end + +if redir_port ~= "nil" then + table.insert(inbounds, { + port = redir_port, + protocol = "dokodemo-door", + settings = {network = proto, followRedirect = true}, + sniffing = {enabled = true, destOverride = {"http", "tls"}} + }) + if proto == "tcp" and node.v2ray_tcp_socks == "1" then + table.insert(inbounds, { + listen = "0.0.0.0", + port = tonumber(node.v2ray_tcp_socks_port), + protocol = "socks", + settings = { + auth = node.v2ray_tcp_socks_auth, + accounts = (node.v2ray_tcp_socks_auth == "password") and { + { + user = node.v2ray_tcp_socks_auth_username, + pass = node.v2ray_tcp_socks_auth_password + } + } or nil, + udp = true + } + }) + end +end + +if node.v2ray_balancing_node then + local nodes = node.v2ray_balancing_node + local length = #nodes + for i = 1, length do + local node = ucursor:get_all("passwall", nodes[i]) + local outbound = gen_outbound(node) + if outbound then table.insert(outbounds, outbound) end + end + routing = { + domainStrategy = "IPOnDemand", + balancers = {{tag = "balancer", selector = nodes}}, + rules = { + {type = "field", network = "tcp,udp", balancerTag = "balancer"} + } + } +end + +-- 额外传出连接 +table.insert(outbounds, + {protocol = "freedom", tag = "direct", settings = {keep = ""}}) + +local v2ray = { + log = { + -- error = "/var/log/v2ray.log", + loglevel = "warning" + }, + -- 传入连接 + inbounds = inbounds, + -- 传出连接 + outbounds = outbounds, + -- 路由 + routing = routing +} +print(json.stringify(v2ray, 1)) diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_v2ray_shunt.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_v2ray_shunt.lua index ba9d6a315b..534c87468e 100755 --- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_v2ray_shunt.lua +++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_v2ray_shunt.lua @@ -14,7 +14,7 @@ local routing = nil local function gen_outbound(node, tag) local result = nil if node then - local cbi_id = node[".name"] + local node_id = node[".name"] if node.type ~= "V2ray" then if node.type == "Socks5" then node.v2ray_protocol = "socks" @@ -27,9 +27,9 @@ local function gen_outbound(node, tag) node.port = new_port sys.call(string.format( "/usr/share/passwall/app.sh gen_start_config %s %s %s %s %s %s", - cbi_id, new_port, "SOCKS5", + node_id, new_port, "SOCKS5", "/var/etc/passwall/v2_shunt_" .. node_type .. "_" .. - cbi_id .. ".json", "4", "127.0.0.1")) + node_id .. ".json", "4", "127.0.0.1")) node.v2ray_protocol = "socks" node.v2ray_transport = "tcp" node.address = "127.0.0.1" @@ -37,7 +37,6 @@ local function gen_outbound(node, tag) end result = { tag = tag, - cbi_id = cbi_id, protocol = node.v2ray_protocol or "vmess", mux = { enabled = (node.v2ray_mux == "1") and true or false, diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/global.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/global.lua index 9f5eecd658..954a5ae7c0 100644 --- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/global.lua +++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/global.lua @@ -20,7 +20,7 @@ uci:foreach(appname, "nodes", function(e) if type == nil then type = "" end local address = e.address if address == nil then address = "" end - if (type == "V2ray_balancing" or type == "V2ray_shunt") or (address:match("[\u4e00-\u9fa5]") and address:find("%.") and address:sub(#address) ~= ".") then + --if (type == "V2ray_balancing" or type == "V2ray_shunt") or (address:match("[\u4e00-\u9fa5]") and address:find("%.") and address:sub(#address) ~= ".") then if type and address and e.remarks then if e.use_kcp and e.use_kcp == "1" then n[e[".name"]] = "%s+%s:[%s] %s" % @@ -32,7 +32,7 @@ uci:foreach(appname, "nodes", function(e) {translate(type), e.remarks, address} end end - end + --end end) local key_table = {} diff --git a/package/lienol/luci-app-passwall/root/usr/share/passwall/app.sh b/package/lienol/luci-app-passwall/root/usr/share/passwall/app.sh index 101a842820..349a8c4150 100755 --- a/package/lienol/luci-app-passwall/root/usr/share/passwall/app.sh +++ b/package/lienol/luci-app-passwall/root/usr/share/passwall/app.sh @@ -20,6 +20,7 @@ DNS_PORT=7913 LUA_API_PATH=/usr/lib/lua/luci/model/cbi/$CONFIG/api API_GEN_TROJAN=$LUA_API_PATH/gen_trojan.lua API_GEN_V2RAY=$LUA_API_PATH/gen_v2ray.lua +API_GEN_V2RAY_BALANCING=$LUA_API_PATH/gen_v2ray_balancing.lua API_GEN_V2RAY_SHUNT=$LUA_API_PATH/gen_v2ray_shunt.lua echolog() { @@ -288,9 +289,12 @@ gen_start_config() { eval SOCKS5_NODE${5}_PORT=$port if [ "$type" == "socks5" ]; then echolog "Socks5节点不能使用Socks5代理节点!" - elif [ "$type" == "v2ray" -o "$type" == "v2ray_balancing" ]; then + elif [ "$type" == "v2ray" ]; then lua $API_GEN_V2RAY $node nil nil $local_port >$config_file ln_start_bin $(config_t_get global_app v2ray_file $(find_bin v2ray))/v2ray v2ray_socks_$5 "-config=$config_file" + elif [ "$type" == "v2ray_balancing" ]; then + lua $API_GEN_V2RAY_BALANCING $node nil nil $local_port >$config_file + ln_start_bin $(config_t_get global_app v2ray_file $(find_bin v2ray))/v2ray v2ray_socks_$5 "-config=$config_file" elif [ "$type" == "v2ray_shunt" ]; then lua $API_GEN_V2RAY_SHUNT $node nil nil $local_port >$config_file ln_start_bin $(config_t_get global_app v2ray_file $(find_bin v2ray))/v2ray v2ray_socks_$5 "-config=$config_file" @@ -331,9 +335,12 @@ gen_start_config() { local server_password=$(config_n_get $node password) eval port=\$UDP_REDIR_PORT$5 ln_start_bin $(find_bin ipt2socks) ipt2socks_udp_$5 "-U -l $port -b 0.0.0.0 -s $node_address -p $node_port -R" - elif [ "$type" == "v2ray" -o "$type" == "v2ray_balancing" ]; then + elif [ "$type" == "v2ray" ]; then lua $API_GEN_V2RAY $node udp $local_port nil >$config_file ln_start_bin $(config_t_get global_app v2ray_file $(find_bin v2ray))/v2ray v2ray_udp_$5 "-config=$config_file" + elif [ "$type" == "v2ray_balancing" ]; then + lua $API_GEN_V2RAY_BALANCING $node udp $local_port nil >$config_file + ln_start_bin $(config_t_get global_app v2ray_file $(find_bin v2ray))/v2ray v2ray_udp_$5 "-config=$config_file" elif [ "$type" == "v2ray_shunt" ]; then lua $API_GEN_V2RAY_SHUNT $node udp $local_port nil >$config_file ln_start_bin $(config_t_get global_app v2ray_file $(find_bin v2ray))/v2ray v2ray_udp_$5 "-config=$config_file" @@ -384,9 +391,12 @@ gen_start_config() { local server_password=$(config_n_get $node password) eval port=\$TCP_REDIR_PORT$5 ln_start_bin $(find_bin ipt2socks) ipt2socks_tcp_$5 "-T -l $port -b 0.0.0.0 -s $node_address -p $node_port -R" - elif [ "$type" == "v2ray" -o "$type" == "v2ray_balancing" ]; then + elif [ "$type" == "v2ray" ]; then lua $API_GEN_V2RAY $node tcp $local_port nil >$config_file ln_start_bin $(config_t_get global_app v2ray_file $(find_bin v2ray))/v2ray v2ray_tcp_$5 "-config=$config_file" + elif [ "$type" == "v2ray_balancing" ]; then + lua $API_GEN_V2RAY_BALANCING $node tcp $local_port nil >$config_file + ln_start_bin $(config_t_get global_app v2ray_file $(find_bin v2ray))/v2ray v2ray_tcp_$5 "-config=$config_file" elif [ "$type" == "v2ray_shunt" ]; then lua $API_GEN_V2RAY_SHUNT $node tcp $local_port nil >$config_file ln_start_bin $(config_t_get global_app v2ray_file $(find_bin v2ray))/v2ray v2ray_tcp_$5 "-config=$config_file" diff --git a/package/lienol/luci-app-passwall/root/usr/share/passwall/subscribe.lua b/package/lienol/luci-app-passwall/root/usr/share/passwall/subscribe.lua index 97fbc83037..9d83aaba52 100644 --- a/package/lienol/luci-app-passwall/root/usr/share/passwall/subscribe.lua +++ b/package/lienol/luci-app-passwall/root/usr/share/passwall/subscribe.lua @@ -302,8 +302,7 @@ local function processData(szType, content, add_mode) result.group = content.airport result.remarks = content.remarks else - log('暂时不支持' .. szType .. - "类型的节点订阅,跳过此节点。") + log('暂时不支持' .. szType .. "类型的节点订阅,跳过此节点。") return nil end if not result.remarks then @@ -313,7 +312,8 @@ local function processData(szType, content, add_mode) end -- wget local function wget(url) - local stdout = luci.sys.exec('/usr/bin/wget --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36" --no-check-certificate -t 3 -T 10 -O- "' .. url .. '"') + local ua = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36" + local stdout = luci.sys.exec('/usr/bin/wget --user-agent="' .. ua .. '" --no-check-certificate -t 3 -T 10 -O- "' .. url .. '"') return trim(stdout) end @@ -351,31 +351,59 @@ end local function select_node(nodes, config) local server + -- 特别优先级 V2ray分流 + 备注 + if config.currentNode.type == 'V2ray_shunt' then + for id, node in pairs(nodes) do + if node.remarks == config.currentNode.remarks then + log('选择【' .. config.remarks .. '】V2ray分流匹配节点:' .. node.remarks) + server = id + break + end + end + end + -- 特别优先级 V2ray负载均衡 + 备注 + if config.currentNode.type == 'V2ray_balancing' then + for id, node in pairs(nodes) do + if node.remarks == config.currentNode.remarks then + log('选择【' .. config.remarks .. '】V2ray负载均衡匹配节点:' .. node.remarks) + server = id + break + end + end + end -- 第一优先级 IP + 端口 - for id, node in pairs(nodes) do - if node.address .. ':' .. node.port == config.currentNode.address .. ':' .. config.currentNode.port then - log('选择【' .. config.remarks .. '】第一匹配节点:' .. node.remarks) - server = id - break + if not server then + for id, node in pairs(nodes) do + if node.address and node.port then + if node.address .. ':' .. node.port == config.currentNode.address .. ':' .. config.currentNode.port then + log('选择【' .. config.remarks .. '】第一匹配节点:' .. node.remarks) + server = id + break + end + end end end -- 第二优先级 IP if not server then for id, node in pairs(nodes) do - if node.address == config.currentNode.address then - log('选择【' .. config.remarks .. '】第二匹配节点:' .. node.remarks) - server = id - break + if node.address then + if node.address == config.currentNode.address then + log('选择【' .. config.remarks .. '】第二匹配节点:' .. node.remarks) + server = id + break + end end end end -- 第三优先级备注 if not server then for id, node in pairs(nodes) do - if node.remarks == config.currentNode.remarks then - log('选择【' .. config.remarks .. '】第三匹配节点:' .. node.remarks) - server = id - break + if node.remarks then + if node.remarks == config.currentNode.remarks then + log('选择【' .. config.remarks .. '】第三匹配节点:' .. node.remarks) + server = id + break + end end end end @@ -427,14 +455,14 @@ local function update_node(manual) local nodes = {} local ucic3 = uci.cursor() ucic3:foreach(application, uciType, function(node) - if node.port and node.address and node.remarks then + if (node.port and node.address and node.remarks) or node.type == 'V2ray_shunt' or node.type == 'V2ray_balancing' then nodes[node['.name']] = node end end) for _, config in pairs(CONFIG) do select_node(nodes, config) end - ucic3:commit(application) + ucic2:commit(application) luci.sys.call("/etc/init.d/" .. application .. " restart > /dev/null 2>&1 &") -- 不加&的话日志会出现的更早 end end @@ -498,7 +526,8 @@ local function parse_link(raw, remark, manual) if result.remarks:find("过期时间") or result.remarks:find("剩余流量") or result.remarks:find("QQ群") or - result.remarks:find("官网") or not result.address or + result.remarks:find("官网") or + not result.address or result.address:match("[^0-9a-zA-Z%-%_%.%s]") or -- 中文做地址的 也没有人拿中文域名搞,就算中文域也有Puny Code SB 机场 not result.address:find("%.") or -- 虽然没有.也算域,不过应该没有人会这样干吧 result.address:sub(#result.address) == "." -- 结尾是. @@ -548,7 +577,7 @@ if arg[1] then end) log('订阅完毕...') else - log('未设置或启用订阅, 请检查设置...') + log('未设置订阅或未启用订阅, 请检查设置...') end elseif arg[1] == "add" then local f = assert(io.open("/tmp/links.conf", 'r'))