From c06f6662d4a75de511cb24ee27f347d14eaeed96 Mon Sep 17 00:00:00 2001 From: Mattraks <16359027+Mattraks@users.noreply.github.com> Date: Wed, 9 Dec 2020 15:04:55 +0800 Subject: [PATCH] luci-app-v2ray-server: bump to 13-1 version (#5894) --- package/lean/luci-app-v2ray-server/Makefile | 11 +- .../luasrc/controller/v2ray_server.lua | 45 +-- .../luasrc/model/cbi/v2ray_server/api/app.lua | 109 ++++++ .../model/cbi/v2ray_server/api/gen_config.lua | 184 ++++++++++ .../cbi/v2ray_server/api/genv2rayconfig.lua | 135 -------- .../model/cbi/v2ray_server/api/v2ray.lua | 58 +--- .../luasrc/model/cbi/v2ray_server/config.lua | 238 ------------- .../luasrc/model/cbi/v2ray_server/index.lua | 82 +---- .../luasrc/model/cbi/v2ray_server/user.lua | 315 ++++++++++++++++++ .../luasrc/view/v2ray_server/log.htm | 4 +- .../view/v2ray_server/users_list_status.htm | 18 +- .../luasrc/view/v2ray_server/users_status.htm | 3 - .../luasrc/view/v2ray_server/v2ray.htm | 28 +- .../po/zh-cn/v2ray_server.po | 81 +++++ .../root/etc/config/v2ray_server | 25 -- .../root/etc/init.d/v2ray_server | 52 +-- .../etc/uci-defaults/luci-app-v2ray-server | 7 +- .../rpcd/acl.d/luci-app-v2ray-server.json | 11 + .../usr/share/v2ray_server/firewall.include | 29 -- 19 files changed, 785 insertions(+), 650 deletions(-) create mode 100755 package/lean/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/api/app.lua create mode 100755 package/lean/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/api/gen_config.lua delete mode 100644 package/lean/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/api/genv2rayconfig.lua mode change 100644 => 100755 package/lean/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/api/v2ray.lua delete mode 100644 package/lean/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/config.lua create mode 100644 package/lean/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/user.lua delete mode 100644 package/lean/luci-app-v2ray-server/luasrc/view/v2ray_server/users_status.htm create mode 100644 package/lean/luci-app-v2ray-server/root/usr/share/rpcd/acl.d/luci-app-v2ray-server.json delete mode 100755 package/lean/luci-app-v2ray-server/root/usr/share/v2ray_server/firewall.include diff --git a/package/lean/luci-app-v2ray-server/Makefile b/package/lean/luci-app-v2ray-server/Makefile index dbdae4d03..209a9ab8c 100644 --- a/package/lean/luci-app-v2ray-server/Makefile +++ b/package/lean/luci-app-v2ray-server/Makefile @@ -1,18 +1,17 @@ -# Copyright (C) 2018-2019 Lienol +# Copyright (C) 2018-2020 Lienol # # This is free software, licensed under the GNU General Public License v3. # include $(TOPDIR)/rules.mk +PKG_NAME:=luci-app-v2ray-server LUCI_TITLE:=LuCI support for V2ray Server -LUCI_DEPENDS:=+v2ray +LUCI_DEPENDS:=+unzip LUCI_PKGARCH:=all -PKG_VERSION:=1.1 -PKG_RELEASE:=5 +PKG_VERSION:=13 +PKG_RELEASE:=1 include $(TOPDIR)/feeds/luci/luci.mk # call BuildPackage - OpenWrt buildroot signature - - diff --git a/package/lean/luci-app-v2ray-server/luasrc/controller/v2ray_server.lua b/package/lean/luci-app-v2ray-server/luasrc/controller/v2ray_server.lua index d2a29ac1c..10de893a1 100644 --- a/package/lean/luci-app-v2ray-server/luasrc/controller/v2ray_server.lua +++ b/package/lean/luci-app-v2ray-server/luasrc/controller/v2ray_server.lua @@ -1,25 +1,17 @@ +-- Copyright 2018-2019 Lienol module("luci.controller.v2ray_server", package.seeall) local http = require "luci.http" local v2ray = require "luci.model.cbi.v2ray_server.api.v2ray" function index() if not nixio.fs.access("/etc/config/v2ray_server") then return end - entry({"admin", "vpn"}, firstchild(), "VPN", 45).dependent = false - entry({"admin", "vpn", "v2ray_server"}, cbi("v2ray_server/index"), - _("V2ray Server"), 3).dependent = true - entry({"admin", "vpn", "v2ray_server", "config"}, cbi("v2ray_server/config")).leaf = - true - - entry({"admin", "vpn", "v2ray_server", "users_status"}, - call("v2ray_users_status")).leaf = true - entry({"admin", "vpn", "v2ray_server", "check"}, call("v2ray_check")).leaf = - true - entry({"admin", "vpn", "v2ray_server", "update"}, call("v2ray_update")).leaf = - true - entry({"admin", "vpn", "v2ray_server", "get_log"}, call("get_log")).leaf = - true - entry({"admin", "vpn", "v2ray_server", "clear_log"}, call("clear_log")).leaf = - true + entry({"admin", "services", "v2ray_server"}, cbi("v2ray_server/index"), _("V2ray Server"), 3).dependent = true + entry({"admin", "services", "v2ray_server", "config"}, cbi("v2ray_server/user")).leaf = true + entry({"admin", "services", "v2ray_server", "users_status"}, call("users_status")).leaf = true + entry({"admin", "services", "v2ray_server", "check"}, call("v2ray_check")).leaf = true + entry({"admin", "services", "v2ray_server", "update"}, call("v2ray_update")).leaf = true + entry({"admin", "services", "v2ray_server", "get_log"}, call("get_log")).leaf = true + entry({"admin", "services", "v2ray_server", "clear_log"}, call("clear_log")).leaf = true end local function http_write_json(content) @@ -27,12 +19,18 @@ local function http_write_json(content) http.write_json(content or {code = 1}) end -function v2ray_users_status() +function get_log() + luci.http.write(luci.sys.exec("[ -f '/var/log/v2ray_server/app.log' ] && cat /var/log/v2ray_server/app.log")) +end + +function clear_log() + luci.sys.call("echo '' > /var/log/v2ray_server/app.log") +end + +function users_status() local e = {} e.index = luci.http.formvalue("index") - e.status = luci.sys.call( - "ps -w| grep -v grep | grep '/var/etc/v2ray_server/" .. - luci.http.formvalue("id") .. "' >/dev/null") == 0 + e.status = luci.sys.call("ps -w| grep -v grep | grep '/var/etc/v2ray_server/" .. luci.http.formvalue("id") .. "' >/dev/null") == 0 http_write_json(e) end @@ -56,10 +54,3 @@ function v2ray_update() http_write_json(json) end -function get_log() - luci.http.write(luci.sys.exec( - "[ -f '/var/log/v2ray_server/app.log' ] && cat /var/log/v2ray_server/app.log")) -end - -function clear_log() luci.sys.call("echo '' > /var/log/v2ray_server/app.log") end - diff --git a/package/lean/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/api/app.lua b/package/lean/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/api/app.lua new file mode 100755 index 000000000..32ce2aac0 --- /dev/null +++ b/package/lean/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/api/app.lua @@ -0,0 +1,109 @@ +#!/usr/bin/lua + +local action = arg[1] +local sys = require 'luci.sys' +local jsonc = require "luci.jsonc" +local ucic = require"luci.model.uci".cursor() + +local CONFIG = "v2ray_server" +local CONFIG_PATH = "/var/etc/" .. CONFIG +local LOG_PATH = "/var/log/" .. CONFIG +local LOG_APP_FILE = LOG_PATH .. "/app.log" +local BIN_PATH = "/var/bin/" +local BIN_PATH_FILE = BIN_PATH .. CONFIG + +local function log(...) + local f, err = io.open(LOG_APP_FILE, "a") + if f and err == nil then + local str = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ") + f:write(str .. "\n") + f:close() + end +end + +local function cmd(cmd) + sys.call(cmd) +end + +local function gen_include() + cmd(string.format("echo '#!/bin/sh' > /var/etc/%s.include", CONFIG)) + local function extract_rules(a) + local result = "*" .. a + result = result .. "\n" .. sys.exec('iptables-save -t ' .. a .. ' | grep "V2RAY-SERVER" | sed -e "s/^-A \\(INPUT\\)/-I \\1 1/"') + result = result .. "COMMIT" + return result + end + local f, err = io.open("/var/etc/" .. CONFIG .. ".include", "a") + if f and err == nil then + f:write('iptables-save -c | grep -v "V2RAY-SERVER" | iptables-restore -c' .. "\n") + f:write('iptables-restore -n <<-EOT' .. "\n") + f:write(extract_rules("filter") .. "\n") + f:write("EOT" .. "\n") + f:close() + end +end + +local function start() + local enabled = tonumber(ucic:get(CONFIG, "@global[0]", "enable") or 0) + if enabled == nil or enabled == 0 then + return + end + cmd(string.format("mkdir -p %s %s", CONFIG_PATH, LOG_PATH)) + cmd(string.format("touch %s", LOG_APP_FILE)) + cmd("iptables -N V2RAY-SERVER") + cmd("iptables -I INPUT -j V2RAY-SERVER") + ucic:foreach(CONFIG, "user", function(user) + local id = user[".name"] + local enable = user.enable + if enable and tonumber(enable) == 1 then + local remarks = user.remarks + local port = tonumber(user.port) + if nixio.fs.access("/usr/bin/xray") and not nixio.fs.access(BIN_PATH_FILE) then + cmd(string.format("mkdir -p %s", BIN_PATH)) + cmd(string.format("cp -a /usr/bin/xray %s", BIN_PATH_FILE)) + end + local bin = BIN_PATH_FILE + local config = {} + local config_file = CONFIG_PATH .. "/" .. id .. ".json" + + config = require("luci.model.cbi.v2ray_server.api.gen_config").gen_config(user) + bin = bin .. " -config " .. config_file + + if next(config) then + local f, err = io.open(config_file, "w") + if f and err == nil then + f:write(jsonc.stringify(config, 1)) + f:close() + end + log(string.format("%s %s 生成配置文件并运行 - %s", remarks, port, config_file)) + end + + if bin then + cmd(bin .. ">/dev/null 2>&1 &") + end + + local bind_local = user.bind_local or 0 + if bind_local and tonumber(bind_local) ~= 1 then + cmd(string.format('iptables -A V2RAY-SERVER -p tcp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks)) + cmd(string.format('iptables -A V2RAY-SERVER -p udp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks)) + end + end + end) + gen_include() +end + +local function stop() + cmd(string.format("ps -w | grep -v 'grep' | grep '%s/' | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 &", CONFIG_PATH)) + cmd("iptables -D INPUT -j V2RAY-SERVER 2>/dev/null") + cmd("iptables -F V2RAY-SERVER 2>/dev/null") + cmd("iptables -X V2RAY-SERVER 2>/dev/null") + cmd(string.format("rm -rf %s %s /var/etc/%s.include", CONFIG_PATH, LOG_APP_FILE, CONFIG)) +end + +if action then + if action == "start" then + start() + elseif action == "stop" then + stop() + end +end \ No newline at end of file diff --git a/package/lean/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/api/gen_config.lua b/package/lean/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/api/gen_config.lua new file mode 100755 index 000000000..277be6f8a --- /dev/null +++ b/package/lean/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/api/gen_config.lua @@ -0,0 +1,184 @@ +module("luci.model.cbi.v2ray_server.api.gen_config", package.seeall) + +function gen_config(user) + local settings = nil + local routing = nil + local outbounds = { + {protocol = "freedom", tag = "direct"}, {protocol = "blackhole", tag = "blocked"} + } + + if user.protocol == "vmess" or user.protocol == "vless" then + if user.uuid then + local clients = {} + for i = 1, #user.uuid do + clients[i] = { + id = user.uuid[i], + flow = (user.xtls and user.xtls == "1") and user.flow or nil, + level = tonumber(user.level), + alterId = tonumber(user.alter_id) + } + end + settings = { + clients = clients, + decryption = user.decryption or "none" + } + end + elseif user.protocol == "socks" then + settings = { + auth = (user.auth and user.auth == "1") and "password" or "noauth", + accounts = (user.auth and user.auth == "1") and { + { + user = user.username, + pass = user.password + } + } + } + elseif user.protocol == "http" then + settings = { + allowTransparent = false, + accounts = (user.auth and user.auth == "1") and { + { + user = user.username, + pass = user.password + } + } + } + user.transport = "tcp" + user.tcp_guise = "none" + elseif user.protocol == "shadowsocks" then + settings = { + method = user.method, + password = user.password, + level = tonumber(user.level) or 1, + network = user.ss_network or "TCP,UDP" + } + elseif user.protocol == "trojan" then + if user.uuid then + local clients = {} + for i = 1, #user.uuid do + clients[i] = { + password = user.uuid[i], + level = tonumber(user.level) + } + end + settings = { + clients = clients + } + end + elseif user.protocol == "mtproto" then + settings = { + users = { + { + level = tonumber(user.level) or 1, + secret = (user.password == nil) and "" or user.password + } + } + } + end + + routing = { + domainStrategy = "IPOnDemand", + rules = { + { + type = "field", + ip = {"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"}, + outboundTag = (user.accept_lan == nil or user.accept_lan == "0") and "blocked" or "direct" + } + } + } + + local config = { + log = { + -- error = "/var/etc/v2ray_server/log/" .. user[".name"] .. ".log", + loglevel = "warning" + }, + -- 传入连接 + inbounds = { + { + listen = (user.bind_local == "1") and "127.0.0.1" or nil, + port = tonumber(user.port), + protocol = user.protocol, + settings = settings, + streamSettings = { + network = user.transport, + security = "none", + xtlsSettings = (user.tls and user.tls == "1" and user.xtls and user.xtls == "1") and { + --alpn = {"http/1.1"}, + disableSystemRoot = false, + certificates = { + { + certificateFile = user.tls_certificateFile, + keyFile = user.tls_keyFile + } + } + } or nil, + tlsSettings = (user.tls and user.tls == "1") and { + disableSystemRoot = false, + certificates = { + { + certificateFile = user.tls_certificateFile, + keyFile = user.tls_keyFile + } + } + } or nil, + tcpSettings = (user.transport == "tcp") and { + header = { + type = user.tcp_guise, + request = (user.tcp_guise == "http") and { + path = {user.tcp_guise_http_path} or {"/"}, + headers = { + Host = {user.tcp_guise_http_host} or {} + } + } or nil + } + } or nil, + kcpSettings = (user.transport == "mkcp") and { + mtu = tonumber(user.mkcp_mtu), + tti = tonumber(user.mkcp_tti), + uplinkCapacity = tonumber(user.mkcp_uplinkCapacity), + downlinkCapacity = tonumber(user.mkcp_downlinkCapacity), + congestion = (user.mkcp_congestion == "1") and true or false, + readBufferSize = tonumber(user.mkcp_readBufferSize), + writeBufferSize = tonumber(user.mkcp_writeBufferSize), + seed = (user.mkcp_seed and user.mkcp_seed ~= "") and user.mkcp_seed or nil, + header = {type = user.mkcp_guise} + } or nil, + wsSettings = (user.transport == "ws") and { + acceptProxyProtocol = false, + headers = (user.ws_host) and {Host = user.ws_host} or nil, + path = user.ws_path + } or nil, + httpSettings = (user.transport == "h2") and { + path = user.h2_path, host = user.h2_host + } or nil, + dsSettings = (user.transport == "ds") and { + path = user.ds_path + } or nil, + quicSettings = (user.transport == "quic") and { + security = user.quic_security, + key = user.quic_key, + header = {type = user.quic_guise} + } or nil + } + } + }, + -- 传出连接 + outbounds = outbounds, + routing = routing + } + + if user.tls and user.tls == "1" then + config.inbounds[1].streamSettings.security = "tls" + if user.xtls and user.xtls == "1" then + config.inbounds[1].streamSettings.security = "xtls" + config.inbounds[1].streamSettings.tlsSettings = nil + end + end + + if user.transport == "mkcp" or user.transport == "quic" then + config.inbounds[1].streamSettings.security = "none" + config.inbounds[1].streamSettings.tlsSettings = nil + end + + return config +end diff --git a/package/lean/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/api/genv2rayconfig.lua b/package/lean/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/api/genv2rayconfig.lua deleted file mode 100644 index 6a1879f60..000000000 --- a/package/lean/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/api/genv2rayconfig.lua +++ /dev/null @@ -1,135 +0,0 @@ -local ucursor = require"luci.model.uci".cursor() -local json = require "luci.jsonc" -local server_section = arg[1] -local server = ucursor:get_all("v2ray_server", server_section) - -local settings = nil -local routing = nil - -if server.protocol == "vmess" then - if server.VMess_id then - local clients = {} - for i = 1, #server.VMess_id do - clients[i] = { - id = server.VMess_id[i], - level = tonumber(server.VMess_level), - alterId = tonumber(server.VMess_alterId) - } - end - settings = {clients = clients} - end -elseif server.protocol == "socks" then - settings = { - auth = (server.socks_username == nil and server.socks_password == nil) and - "noauth" or "password", - accounts = { - { - user = (server.socks_username == nil) and "" or - server.socks_username, - pass = (server.socks_password == nil) and "" or - server.socks_password - } - } - } -elseif server.protocol == "http" then - settings = { - allowTransparent = false, - accounts = { - { - user = (server.http_username == nil) and "" or - server.http_username, - pass = (server.http_password == nil) and "" or - server.http_password - } - } - } -elseif server.protocol == "shadowsocks" then - settings = { - method = server.ss_method, - password = server.ss_password, - level = tonumber(server.ss_level), - network = server.ss_network, - ota = (server.ss_ota == '1') and true or false - } -end - -if server.accept_lan == nil or server.accept_lan == "0" then - routing = { - domainStrategy = "IPOnDemand", - rules = { - { - type = "field", - ip = {"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"}, - outboundTag = "blocked" - } - } - } -end - -local v2ray = { - log = { - -- error = "/var/log/v2ray.log", - loglevel = "warning" - }, - -- 传入连接 - inbound = { - listen = (server.bind_local == "1") and "127.0.0.1" or nil, - port = tonumber(server.port), - protocol = server.protocol, - -- 底层传输配置 - settings = settings, - streamSettings = (server.protocol == "vmess") and { - network = server.transport, - security = (server.tls_enable == '1') and "tls" or "none", - tlsSettings = (server.tls_enable == '1') and { - -- serverName = (server.tls_serverName), - allowInsecure = false, - disableSystemRoot = false, - certificates = { - { - certificateFile = server.tls_certificateFile, - keyFile = server.tls_keyFile - } - } - } or nil, - tcpSettings = (server.transport == "tcp") and { - header = { - type = server.tcp_guise, - request = { - path = server.tcp_guise_http_path, - headers = { - Host = server.tcp_guise_http_host - } - } - } - } or nil, - kcpSettings = (server.transport == "mkcp") and { - mtu = tonumber(server.mkcp_mtu), - tti = tonumber(server.mkcp_tti), - uplinkCapacity = tonumber(server.mkcp_uplinkCapacity), - downlinkCapacity = tonumber(server.mkcp_downlinkCapacity), - congestion = (server.mkcp_congestion == "1") and true or false, - readBufferSize = tonumber(server.mkcp_readBufferSize), - writeBufferSize = tonumber(server.mkcp_writeBufferSize), - header = {type = server.mkcp_guise} - } or nil, - wsSettings = (server.transport == "ws") and { - headers = (server.ws_host) and {Host = server.ws_host} or nil, - path = server.ws_path - } or nil, - httpSettings = (server.transport == "h2") and - {path = server.h2_path, host = server.h2_host} or nil, - quicSettings = (server.transport == "quic") and { - security = server.quic_security, - key = server.quic_key, - header = {type = server.quic_guise} - } or nil - } or nil - }, - -- 传出连接 - outbound = {protocol = "freedom"}, - -- 额外传出连接 - outboundDetour = {{protocol = "blackhole", tag = "blocked"}}, - routing = routing -} -print(json.stringify(v2ray, 1)) diff --git a/package/lean/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/api/v2ray.lua b/package/lean/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/api/v2ray.lua old mode 100644 new mode 100755 index e1953caca..e39eb6fb3 --- a/package/lean/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/api/v2ray.lua +++ b/package/lean/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/api/v2ray.lua @@ -7,12 +7,9 @@ local i18n = require "luci.i18n" local ipkg = require "luci.model.ipkg" local appname = "v2ray_server" -local v2ray_api = - "https://api.github.com/repos/v2fly/v2ray-core/releases/latest" +local v2ray_api ="https://api.github.com/repos/XTLS/Xray-core/releases/latest" local wget = "/usr/bin/wget" -local wget_args = { - "--no-check-certificate", "--quiet", "--timeout=100", "--tries=3" -} +local wget_args = {"--no-check-certificate", "--quiet", "--timeout=100", "--tries=3"} local command_timeout = 300 local LEDE_BOARD = nil @@ -95,12 +92,10 @@ end local function auto_get_arch() local arch = nixio.uname().machine or "" if fs.access("/usr/lib/os-release") then - LEDE_BOARD = sys.exec( - "echo -n `grep 'LEDE_BOARD' /usr/lib/os-release | awk -F '[\\042\\047]' '{print $2}'`") + LEDE_BOARD = sys.exec("echo -n `grep 'LEDE_BOARD' /usr/lib/os-release | awk -F '[\\042\\047]' '{print $2}'`") end if fs.access("/etc/openwrt_release") then - DISTRIB_TARGET = sys.exec( - "echo -n `grep 'DISTRIB_TARGET' /etc/openwrt_release | awk -F '[\\042\\047]' '{print $2}'`") + DISTRIB_TARGET = sys.exec("echo -n `grep 'DISTRIB_TARGET' /etc/openwrt_release | awk -F '[\\042\\047]' '{print $2}'`") end if arch == "mips" then @@ -108,15 +103,13 @@ local function auto_get_arch() if string.match(LEDE_BOARD, "ramips") == "ramips" then arch = "ramips" else - arch = sys.exec("echo '" .. LEDE_BOARD .. - "' | grep -oE 'ramips|ar71xx'") + arch = sys.exec("echo '" .. LEDE_BOARD .. "' | grep -oE 'ramips|ar71xx'") end elseif DISTRIB_TARGET and DISTRIB_TARGET ~= "" then if string.match(DISTRIB_TARGET, "ramips") == "ramips" then arch = "ramips" else - arch = sys.exec("echo '" .. DISTRIB_TARGET .. - "' | grep -oE 'ramips|ar71xx'") + arch = sys.exec("echo '" .. DISTRIB_TARGET .. "' | grep -oE 'ramips|ar71xx'") end end end @@ -162,23 +155,19 @@ local function get_api_json(url) -- function(chunk) output[#output + 1] = chunk end) -- local json_content = util.trim(table.concat(output)) - local json_content = luci.sys.exec(wget .. - " --no-check-certificate --timeout=10 -t 1 -O- " .. - url) + local json_content = luci.sys.exec(wget .. " --no-check-certificate --timeout=10 -t 1 -O- " .. url) if json_content == "" then return {} end return jsonc.parse(json_content) or {} end -function get_v2ray_file_path() return "/usr/bin/v2ray" end +function get_v2ray_file_path() return "/usr/bin" end function get_v2ray_version() if get_v2ray_file_path() and get_v2ray_file_path() ~= "" then - if fs.access(get_v2ray_file_path() .. "/v2ray") then - return luci.sys.exec("echo -n `" .. get_v2ray_file_path() .. - "/v2ray -version | awk '{print $2}' | sed -n 1P" .. - "`") + if fs.access(get_v2ray_file_path() .. "/xray") then + return luci.sys.exec("echo -n `" .. get_v2ray_file_path() .. "/xray -version | awk '{print $2}' | sed -n 1P" .. "`") end end return "" @@ -192,8 +181,7 @@ function to_check(arch) if file_tree == "" then return { code = 1, - error = i18n.translate( - "Can't determine ARCH, or ARCH not supported.") + error = i18n.translate("Can't determine ARCH, or ARCH not supported.") } end @@ -207,8 +195,7 @@ function to_check(arch) end local remote_version = json.tag_name:match("[^v]+") - local needs_update = compare_versions(get_v2ray_version(), "<", - remote_version) + local needs_update = compare_versions(get_v2ray_version(), "<",remote_version) local html_url, download_url if needs_update then @@ -227,8 +214,7 @@ function to_check(arch) now_version = get_v2ray_version(), version = remote_version, html_url = html_url, - error = i18n.translate( - "New version found, but failed to get new version download url.") + error = i18n.translate("New version found, but failed to get new version download url.") } end @@ -250,8 +236,7 @@ function to_download(url) local tmp_file = util.trim(util.exec("mktemp -u -t v2ray_download.XXXXXX")) - local result = exec(wget, {"-O", tmp_file, url, _unpack(wget_args)}, nil, - command_timeout) == 0 + local result = exec(wget, {"-O", tmp_file, url, _unpack(wget_args)}, nil, command_timeout) == 0 if not result then exec("/bin/rm", {"-f", tmp_file}) @@ -302,25 +287,16 @@ function to_move(file) if not arch or arch == "" then arch = auto_get_arch() end local file_tree, sub_version = get_file_info(arch) local result = nil - if is_armv7 and is_armv7 == true then - result = exec("/bin/mv", { - "-f", file .. "/v2ray_armv7", file .. "/v2ctl_armv7", client_file - }, nil, command_timeout) == 0 - else - result = exec("/bin/mv", - {"-f", file .. "/v2ray", file .. "/v2ctl", client_file}, - nil, command_timeout) == 0 - end + result = exec("/bin/mv", {"-f", file .. "/xray", client_file}, nil, command_timeout) == 0 if not result or not fs.access(client_file) then sys.call("/bin/rm -rf /tmp/v2ray_extract.*") return { code = 1, - error = i18n.translatef("Can't move new file to path: %s", - client_file) + error = i18n.translatef("Can't move new file to path: %s", client_file) } end - exec("/bin/chmod", {"-R", "755", client_file}) + exec("/bin/chmod", {"-R", "755", client_file .. "/xray"}) sys.call("/bin/rm -rf /tmp/v2ray_extract.*") diff --git a/package/lean/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/config.lua b/package/lean/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/config.lua deleted file mode 100644 index 2ce656ede..000000000 --- a/package/lean/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/config.lua +++ /dev/null @@ -1,238 +0,0 @@ -local app_name = "v2ray_server" -local d = require "luci.dispatcher" - -local header_type = {"none", "srtp", "utp", "wechat-video", "dtls", "wireguard"} - -map = Map(app_name, "V2ray " .. translate("Server Config")) -map.redirect = d.build_url("admin", "vpn", "v2ray_server") - -t = map:section(NamedSection, arg[1], "user", "") -t.addremove = false -t.dynamic = false - -enable = t:option(Flag, "enable", translate("Enable")) -enable.default = "1" -enable.rmempty = false - -remarks = t:option(Value, "remarks", translate("Remarks")) -remarks.default = translate("Remarks") -remarks.rmempty = false - -bind_local = t:option(Flag, "bind_local", translate("Bind Local"), translate( - "When selected, it can only be accessed locally,It is recommended to turn on when using reverse proxies.")) -bind_local.default = "0" -bind_local.rmempty = false - -port = t:option(Value, "port", translate("Port")) -port.datatype = "port" -port.rmempty = false - -protocol = t:option(ListValue, "protocol", translate("Protocol")) -protocol:value("vmess", translate("Vmess")) -protocol:value("socks", translate("Socks")) -protocol:value("http",translate("Http")) -protocol:value("shadowsocks", translate("Shadowsocks")) - -socks_username = t:option(Value, "socks_username", translate("User name")) -socks_username.rmempty = true -socks_username:depends("protocol", "socks") - -socks_password = t:option(Value, "socks_password", translate("Password")) -socks_password.rmempty = true -socks_password.password = true -socks_password:depends("protocol", "socks") - -http_username = t:option(Value, "http_username", translate("User name")) -http_username.rmempty = true -http_username:depends("protocol", "http") - -http_password = t:option(Value, "http_password", translate("Password")) -http_password.rmempty = true -http_password.password = true -http_password:depends("protocol", "http") - -ss_method = t:option(ListValue, "ss_method", translate("Encrypt Method")) -ss_method:value("aes-128-cfb") -ss_method:value("aes-256-cfb") -ss_method:value("aes-128-gcm") -ss_method:value("aes-256-gcm") -ss_method:value("chacha20") -ss_method:value("chacha20-ietf") -ss_method:value("chacha20-poly1305") -ss_method:value("chacha20-ietf-poly1305") -ss_method:depends("protocol", "shadowsocks") - -ss_password = t:option(Value, "ss_password", translate("Password")) -ss_password:depends("protocol", "shadowsocks") - -ss_level = t:option(Value, "ss_level", translate("User Level")) -ss_level.default = 1 -ss_level:depends("protocol", "shadowsocks") - -ss_network = t:option(ListValue, "ss_network", translate("Transport")) -ss_network.default = "tcp,udp" -ss_network:value("tcp", "TCP") -ss_network:value("udp", "UDP") -ss_network:value("tcp,udp", "TCP,UDP") -ss_network:depends("protocol", "shadowsocks") - -ss_ota = t:option(Flag, "ss_ota", translate("OTA"), translate( - "When OTA is enabled, V2Ray will reject connections that are not OTA enabled. This option is invalid when using AEAD encryption.")) -ss_ota.default = "0" -ss_ota:depends("protocol", "shadowsocks") - -VMess_id = t:option(DynamicList, "VMess_id", translate("ID")) -for i = 1, 3 do - local uuid = luci.sys.exec("cat /proc/sys/kernel/random/uuid") - VMess_id:value(uuid) -end -VMess_id:depends("protocol", "vmess") - -VMess_alterId = t:option(Value, "VMess_alterId", translate("Alter ID")) -VMess_alterId.default = 16 -VMess_alterId:depends("protocol", "vmess") - -VMess_level = t:option(Value, "VMess_level", translate("User Level")) -VMess_level.default = 1 -VMess_level:depends("protocol", "vmess") - -transport = t:option(ListValue, "transport", translate("Transport")) -transport:value("tcp", "TCP") -transport:value("mkcp", "mKCP") -transport:value("ws", "WebSocket") -transport:value("h2", "HTTP/2") -transport:value("quic", "QUIC") -transport:depends("protocol", "vmess") - --- [[ TCP部分 ]]-- --- TCP伪装 -tcp_guise = t:option(ListValue, "tcp_guise", translate("Camouflage Type")) -tcp_guise:depends("transport", "tcp") -tcp_guise:value("none", "none") -tcp_guise:value("http", "http") - --- HTTP域名 -tcp_guise_http_host = t:option(DynamicList, "tcp_guise_http_host", - translate("HTTP Host")) -tcp_guise_http_host:depends("tcp_guise", "http") - --- HTTP路径 -tcp_guise_http_path = t:option(DynamicList, "tcp_guise_http_path", - translate("HTTP Path")) -tcp_guise_http_path:depends("tcp_guise", "http") - --- [[ mKCP部分 ]]-- -mkcp_guise = t:option(ListValue, "mkcp_guise", translate("Camouflage Type"), - translate( - '
none: default, no masquerade, data sent is packets with no characteristics.
srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).
utp: packets disguised as uTP will be recognized as bittorrent downloaded data.
wechat-video: packets disguised as WeChat video calls.
dtls: disguised as DTLS 1.2 packet.
wireguard: disguised as a WireGuard packet. (not really WireGuard protocol)')) -for a, t in ipairs(header_type) do mkcp_guise:value(t) end -mkcp_guise:depends("transport", "mkcp") - -mkcp_mtu = t:option(Value, "mkcp_mtu", translate("KCP MTU")) -mkcp_mtu:depends("transport", "mkcp") - -mkcp_tti = t:option(Value, "mkcp_tti", translate("KCP TTI")) -mkcp_tti:depends("transport", "mkcp") - -mkcp_uplinkCapacity = t:option(Value, "mkcp_uplinkCapacity", - translate("KCP uplinkCapacity")) -mkcp_uplinkCapacity:depends("transport", "mkcp") - -mkcp_downlinkCapacity = t:option(Value, "mkcp_downlinkCapacity", - translate("KCP downlinkCapacity")) -mkcp_downlinkCapacity:depends("transport", "mkcp") - -mkcp_congestion = t:option(Flag, "mkcp_congestion", translate("KCP Congestion")) -mkcp_congestion:depends("transport", "mkcp") - -mkcp_readBufferSize = t:option(Value, "mkcp_readBufferSize", - translate("KCP readBufferSize")) -mkcp_readBufferSize:depends("transport", "mkcp") - -mkcp_writeBufferSize = t:option(Value, "mkcp_writeBufferSize", - translate("KCP writeBufferSize")) -mkcp_writeBufferSize:depends("transport", "mkcp") - --- [[ WebSocket部分 ]]-- -ws_path = t:option(Value, "ws_path", translate("WebSocket Path")) -ws_path:depends("transport", "ws") - -ws_host = t:option(Value, "ws_host", translate("WebSocket Host")) -ws_host:depends("transport", "ws") - --- [[ HTTP/2部分 ]]-- -h2_path = t:option(Value, "h2_path", translate("HTTP/2 Path")) -h2_path:depends("transport", "h2") - -h2_host = t:option(DynamicList, "h2_host", translate("HTTP/2 Host"), - translate("Camouflage Domain,you can not fill in")) -h2_host:depends("transport", "h2") - --- [[ QUIC部分 ]]-- -quic_security = - t:option(ListValue, "quic_security", translate("Encrypt Method")) -quic_security:value("none") -quic_security:value("aes-128-gcm") -quic_security:value("chacha20-poly1305") -quic_security:depends("transport", "quic") - -quic_key = t:option(Value, "quic_key", - translate("Encrypt Method") .. translate("Key")) -quic_key:depends("transport", "quic") - -quic_guise = t:option(ListValue, "quic_guise", translate("Camouflage Type")) -for a, t in ipairs(header_type) do quic_guise:value(t) end -quic_guise:depends("transport", "quic") - --- [[ TLS部分 ]] -- -tls_enable = t:option(Flag, "tls_enable", translate("Use HTTPS")) -tls_enable:depends("transport", "ws") -tls_enable:depends("transport", "h2") -tls_enable.default = "1" -tls_enable.rmempty = false - --- tls_serverName = t:option(Value, "tls_serverName", translate("Domain")) --- tls_serverName:depends("transport", "ws") --- tls_serverName:depends("transport", "h2") - -tls_certificateFile = t:option(Value, "tls_certificateFile", - translate("Public key absolute path"), - translate("as:") .. "/etc/ssl/fullchain.pem") -tls_certificateFile:depends("tls_enable", 1) - -tls_keyFile = t:option(Value, "tls_keyFile", - translate("Private key absolute path"), - translate("as:") .. "/etc/ssl/private.key") -tls_keyFile:depends("tls_enable", 1) - -accept_lan = t:option(Flag, "accept_lan", translate("Accept LAN Access"), - translate( - "When selected, it can accessed lan , this will not be safe!")) -accept_lan.default = "0" -accept_lan.rmempty = false - -function rmempty_restore() - VMess_id.rmempty = true - VMess_alterId.rmempty = true - socks_username.rmempty = true - socks_password.rmempty = true - ss_password.rmempty = true - ss_ota.rmempty = true -end - -protocol.validate = function(self, value) - rmempty_restore() - if value == "vmess" then - VMess_id.rmempty = false - VMess_alterId.rmempty = false - elseif value == "socks" then - socks_username.rmempty = true - socks_password.rmempty = true - elseif value == "shadowsocks" then - ss_password.rmempty = false - ss_ota.rmempty = false - end - return value -end - -return map diff --git a/package/lean/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/index.lua b/package/lean/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/index.lua index 395a0f31e..2eea43799 100644 --- a/package/lean/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/index.lua +++ b/package/lean/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/index.lua @@ -1,7 +1,4 @@ -local i = require "luci.dispatcher" -local e = require "nixio.fs" -local e = require "luci.sys" -local e = luci.model.uci.cursor() +local ds = require "luci.dispatcher" local o = "v2ray_server" m = Map(o, translate("V2ray Server")) @@ -17,88 +14,41 @@ t = m:section(TypedSection, "user", translate("Users Manager")) t.anonymous = true t.addremove = true t.template = "cbi/tblsection" -t.extedit = i.build_url("admin", "vpn", o, "config", "%s") +t.extedit = ds.build_url("admin", "services", o, "config", "%s") function t.create(t, e) - local e = TypedSection.create(t, e) - luci.http.redirect(i.build_url("admin", "vpn", o, "config", e)) + local uuid = luci.sys.exec("echo -n $(cat /proc/sys/kernel/random/uuid)") or "" + uuid = string.gsub(uuid, "-", "") + local e = TypedSection.create(t, uuid) + luci.http.redirect(ds.build_url("admin", "services", o, "config", uuid)) end function t.remove(t, a) t.map.proceed = true t.map:del(a) - luci.http.redirect(i.build_url("admin", "vpn", o)) + luci.http.redirect(ds.build_url("admin", "services", o)) end + e = t:option(Flag, "enable", translate("Enable")) e.width = "5%" e.rmempty = false + e = t:option(DummyValue, "status", translate("Status")) -e.template = "v2ray_server/users_status" -e.value = translate("Collecting data...") +e.rawhtml = true +e.cfgvalue = function(t, n) + return string.format('%s', n, translate("Collecting data...")) +end + e = t:option(DummyValue, "remarks", translate("Remarks")) -e.width = "15%" + e = t:option(DummyValue, "port", translate("Port")) e.width = "10%" + e = t:option(DummyValue, "protocol", translate("Protocol")) -e.width = "15%" e.cfgvalue = function(self, section) local str = "未知" local protocol = m:get(section, "protocol") or "" if protocol ~= "" then str = (protocol:gsub("^%l", string.upper)) end return str end -e = t:option(DummyValue, "transport", translate("Transport")) -e.width = "10%" -e.cfgvalue = function(self, section) - local t = "未知" - local b = "" - local protocol = m:get(section, "protocol") or "" - if protocol == "vmess" then - b = "transport" - elseif protocol == "shadowsocks" then - b = "ss_network" - end - local a = m:get(section, b) or "" - if a == "tcp" then - t = "TCP" - elseif a == "udp" then - t = "UDP" - elseif a == "tcp,udp" then - t = "TCP,UDP" - elseif a == "mkcp" then - t = "mKCP" - elseif a == "ws" then - t = "WebSocket" - elseif a == "h2" then - t = "HTTP/2" - elseif a == "quic" then - t = "QUIC" - else - t = "TCP,UDP" - end - return t -end -e = t:option(DummyValue, "password", translate("Password")) -e.width = "30%" -e.cfgvalue = function(self, section) - local e = "" - local protocol = m:get(section, "protocol") or "" - if protocol == "vmess" then - e = "VMess_id" - elseif protocol == "shadowsocks" then - e = "ss_password" - elseif protocol == "socks" then - e = "socks_password" - elseif protocol == "http" then - e = "http_password" - end - local e = m:get(section, e) or "" - local t = "" - if type(e) == "table" then - for a = 1, #e do t = t .. e[a] end - else - t = e - end - return t -end m:append(Template("v2ray_server/log")) diff --git a/package/lean/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/user.lua b/package/lean/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/user.lua new file mode 100644 index 000000000..3002b9950 --- /dev/null +++ b/package/lean/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/user.lua @@ -0,0 +1,315 @@ +local d = require "luci.dispatcher" +local appname = "v2ray_server" + +local v_ss_encrypt_method_list = { + "aes-128-cfb", "aes-256-cfb", "aes-128-gcm", "aes-256-gcm", "chacha20", "chacha20-ietf", "chacha20-poly1305", "chacha20-ietf-poly1305" +} + +local header_type_list = { + "none", "srtp", "utp", "wechat-video", "dtls", "wireguard" +} + +m = Map(appname, translate("Server Config")) +m.redirect = d.build_url("admin", "services", appname) + +s = m:section(NamedSection, arg[1], "user", "") +s.addremove = false +s.dynamic = false + +enable = s:option(Flag, "enable", translate("Enable")) +enable.default = "1" +enable.rmempty = false + +remarks = s:option(Value, "remarks", translate("Remarks")) +remarks.default = translate("Remarks") +remarks.rmempty = false + +protocol = s:option(ListValue, "protocol", translate("Protocol")) +protocol:value("vmess", "Vmess") +protocol:value("vless", "VLESS") +protocol:value("http", "HTTP") +protocol:value("socks", "Socks") +protocol:value("shadowsocks", "Shadowsocks") +protocol:value("trojan", "Trojan") +protocol:value("mtproto", "MTProto") + +port = s:option(Value, "port", translate("Port")) +port.datatype = "port" +port.rmempty = false + +auth = s:option(Flag, "auth", translate("Auth")) +auth.validate = function(self, value, t) + if value and value == "1" then + local user_v = username:formvalue(t) or "" + local pass_v = password:formvalue(t) or "" + if user_v == "" or pass_v == "" then + return nil, translate("Username and Password must be used together!") + end + end + return value +end +auth:depends({ protocol = "socks" }) +auth:depends({ protocol = "http" }) + +username = s:option(Value, "username", translate("Username")) +username:depends("auth", "1") + +password = s:option(Value, "password", translate("Password")) +password.password = true +password:depends("auth", "1") +password:depends({ protocol = "shadowsocks" }) + +mtproto_password = s:option(Value, "mtproto_password", translate("Password"), translate("The MTProto protocol must be 32 characters and can only contain characters from 0 to 9 and a to f.")) +mtproto_password:depends({ protocol = "mtproto" }) +mtproto_password.default = arg[1] +function mtproto_password.cfgvalue(self, section) + return m:get(section, "password") +end +function mtproto_password.write(self, section, value) + m:set(section, "password", value) +end + +decryption = s:option(Value, "decryption", translate("Encrypt Method")) +decryption.default = "none" +decryption:depends({ protocol = "vless" }) + +v_ss_encrypt_method = s:option(ListValue, "v_ss_encrypt_method", translate("Encrypt Method")) +for a, t in ipairs(v_ss_encrypt_method_list) do v_ss_encrypt_method:value(t) end +v_ss_encrypt_method:depends({ protocol = "shadowsocks" }) +function v_ss_encrypt_method.cfgvalue(self, section) + return m:get(section, "method") +end +function v_ss_encrypt_method.write(self, section, value) + m:set(section, "method", value) +end + +ss_network = s:option(ListValue, "ss_network", translate("Transport")) +ss_network.default = "tcp,udp" +ss_network:value("tcp", "TCP") +ss_network:value("udp", "UDP") +ss_network:value("tcp,udp", "TCP,UDP") +ss_network:depends({ protocol = "shadowsocks" }) + +uuid = s:option(DynamicList, "uuid", translate("ID") .. "/" .. translate("Password")) +for i = 1, 3 do + uuid:value(luci.sys.exec("echo -n $(cat /proc/sys/kernel/random/uuid)")) +end +uuid:depends({ protocol = "vmess" }) +uuid:depends({ protocol = "vless" }) +uuid:depends({ protocol = "trojan" }) + +alter_id = s:option(Value, "alter_id", translate("Alter ID")) +alter_id.default = 16 +alter_id:depends({ protocol = "vmess" }) + +level = s:option(Value, "level", translate("User Level")) +level.default = 1 +level:depends({ protocol = "vmess" }) +level:depends({ protocol = "vless" }) +level:depends({ protocol = "shadowsocks" }) +level:depends({ protocol = "trojan" }) +level:depends({ protocol = "mtproto" }) + +tls = s:option(Flag, "tls", translate("TLS")) +tls.default = 0 +tls.validate = function(self, value, t) + if value then + if value == "1" then + local ca = tls_certificateFile:formvalue(t) or "" + local key = tls_keyFile:formvalue(t) or "" + if ca == "" or key == "" then + return nil, translate("Public key and Private key path can not be empty!") + end + end + return value + end +end +tls:depends({ protocol = "vmess" }) +tls:depends({ protocol = "vless" }) +tls:depends({ protocol = "socks" }) +tls:depends({ protocol = "shadowsocks" }) + +xtls = s:option(Flag, "xtls", translate("XTLS")) +xtls.default = 0 +xtls:depends({ protocol = "vless", tls = "1" }) + +flow = s:option(Value, "flow", translate("flow")) +flow.default = "xtls-rprx-direct" +flow:value("xtls-rprx-origin") +flow:value("xtls-rprx-origin-udp443") +flow:value("xtls-rprx-direct") +flow:value("xtls-rprx-direct-udp443") +flow:value("xtls-rprx-splice") +flow:value("xtls-rprx-splice-udp443") +flow:depends("xtls", "1") + +-- [[ TLS部分 ]] -- + +tls_serverName = s:option(Value, "tls_serverName", translate("Domain")) +tls_serverName:depends("tls", "1") + +tls_certificateFile = s:option(Value, "tls_certificateFile", translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem") +tls_certificateFile.validate = function(self, value, t) + if value and value ~= "" then + if not nixio.fs.access(value) then + return nil, translate("Can't find this file!") + else + return value + end + end + return nil +end +tls_certificateFile:depends("tls", "1") + +tls_keyFile = s:option(Value, "tls_keyFile", translate("Private key absolute path"), translate("as:") .. "/etc/ssl/private.key") +tls_keyFile.validate = function(self, value, t) + if value and value ~= "" then + if not nixio.fs.access(value) then + return nil, translate("Can't find this file!") + else + return value + end + end + return nil +end +tls_keyFile:depends("tls", "1") + +transport = s:option(ListValue, "transport", translate("Transport")) +transport:value("tcp", "TCP") +transport:value("mkcp", "mKCP") +transport:value("ws", "WebSocket") +transport:value("h2", "HTTP/2") +transport:value("ds", "DomainSocket") +transport:value("quic", "QUIC") +transport:depends({ protocol = "vmess" }) +transport:depends({ protocol = "vless" }) +transport:depends({ protocol = "socks" }) +transport:depends({ protocol = "shadowsocks" }) +transport:depends({ protocol = "trojan" }) + +-- [[ WebSocket部分 ]]-- + +ws_host = s:option(Value, "ws_host", translate("WebSocket Host")) +ws_host:depends("transport", "ws") +ws_host:depends("ss_transport", "ws") +ws_host:depends("trojan_transport", "h2+ws") +ws_host:depends("trojan_transport", "ws") + +ws_path = s:option(Value, "ws_path", translate("WebSocket Path")) +ws_path:depends("transport", "ws") +ws_path:depends("ss_transport", "ws") +ws_path:depends("trojan_transport", "h2+ws") +ws_path:depends("trojan_transport", "ws") + +-- [[ HTTP/2部分 ]]-- + +h2_host = s:option(Value, "h2_host", translate("HTTP/2 Host")) +h2_host:depends("transport", "h2") +h2_host:depends("ss_transport", "h2") +h2_host:depends("trojan_transport", "h2+ws") +h2_host:depends("trojan_transport", "h2") + +h2_path = s:option(Value, "h2_path", translate("HTTP/2 Path")) +h2_path:depends("transport", "h2") +h2_path:depends("ss_transport", "h2") +h2_path:depends("trojan_transport", "h2+ws") +h2_path:depends("trojan_transport", "h2") + +-- [[ TCP部分 ]]-- + +-- TCP伪装 +tcp_guise = s:option(ListValue, "tcp_guise", translate("Camouflage Type")) +tcp_guise:value("none", "none") +tcp_guise:value("http", "http") +tcp_guise:depends("transport", "tcp") + +-- HTTP域名 +tcp_guise_http_host = s:option(DynamicList, "tcp_guise_http_host", translate("HTTP Host")) +tcp_guise_http_host:depends("tcp_guise", "http") + +-- HTTP路径 +tcp_guise_http_path = s:option(DynamicList, "tcp_guise_http_path", translate("HTTP Path")) +tcp_guise_http_path:depends("tcp_guise", "http") + +-- [[ mKCP部分 ]]-- + +mkcp_guise = s:option(ListValue, "mkcp_guise", translate("Camouflage Type"), translate('
none: default, no masquerade, data sent is packets with no characteristics.
srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).
utp: packets disguised as uTP will be recognized as bittorrent downloaded data.
wechat-video: packets disguised as WeChat video calls.
dtls: disguised as DTLS 1.2 packet.
wireguard: disguised as a WireGuard packet. (not really WireGuard protocol)')) +for a, t in ipairs(header_type_list) do mkcp_guise:value(t) end +mkcp_guise:depends("transport", "mkcp") + +mkcp_mtu = s:option(Value, "mkcp_mtu", translate("KCP MTU")) +mkcp_mtu.default = "1350" +mkcp_mtu:depends("transport", "mkcp") + +mkcp_tti = s:option(Value, "mkcp_tti", translate("KCP TTI")) +mkcp_tti.default = "20" +mkcp_tti:depends("transport", "mkcp") + +mkcp_uplinkCapacity = s:option(Value, "mkcp_uplinkCapacity", translate("KCP uplinkCapacity")) +mkcp_uplinkCapacity.default = "5" +mkcp_uplinkCapacity:depends("transport", "mkcp") + +mkcp_downlinkCapacity = s:option(Value, "mkcp_downlinkCapacity", translate("KCP downlinkCapacity")) +mkcp_downlinkCapacity.default = "20" +mkcp_downlinkCapacity:depends("transport", "mkcp") + +mkcp_congestion = s:option(Flag, "mkcp_congestion", translate("KCP Congestion")) +mkcp_congestion:depends("transport", "mkcp") + +mkcp_readBufferSize = s:option(Value, "mkcp_readBufferSize", translate("KCP readBufferSize")) +mkcp_readBufferSize.default = "1" +mkcp_readBufferSize:depends("transport", "mkcp") + +mkcp_writeBufferSize = s:option(Value, "mkcp_writeBufferSize", translate("KCP writeBufferSize")) +mkcp_writeBufferSize.default = "1" +mkcp_writeBufferSize:depends("transport", "mkcp") + +mkcp_seed = s:option(Value, "mkcp_seed", translate("KCP Seed")) +mkcp_seed:depends("transport", "mkcp") + +-- [[ DomainSocket部分 ]]-- + +ds_path = s:option(Value, "ds_path", "Path", translate("A legal file path. This file must not exist before running V2Ray.")) +ds_path:depends("transport", "ds") + +-- [[ QUIC部分 ]]-- +quic_security = s:option(ListValue, "quic_security", translate("Encrypt Method")) +quic_security:value("none") +quic_security:value("aes-128-gcm") +quic_security:value("chacha20-poly1305") +quic_security:depends("transport", "quic") + +quic_key = s:option(Value, "quic_key", translate("Encrypt Method") .. translate("Key")) +quic_key:depends("transport", "quic") + +quic_guise = s:option(ListValue, "quic_guise", translate("Camouflage Type")) +for a, t in ipairs(header_type_list) do quic_guise:value(t) end +quic_guise:depends("transport", "quic") + +-- [[ VLESS Fallback部分 ]]-- +--[[ +fallback = s:option(Flag, "fallback", translate("Fallback")) +fallback:depends({ protocol = "vless", transport = "tcp", tls = "1" }) + +fallback_alpn = s:option(Value, "fallback_alpn", "Fallback alpn") +fallback_alpn:depends("fallback", "1") + +fallback_path = s:option(Value, "fallback_path", "Fallback path") +fallback_path:depends("fallback", "1") + +fallback_dest = s:option(Value, "fallback_dest", "Fallback dest") +fallback_dest:depends("fallback", "1") + +fallback_xver = s:option(Value, "fallback_xver", "Fallback xver") +fallback_xver.default = 0 +fallback_xver:depends("fallback", "1") +]]-- + +bind_local = s:option(Flag, "bind_local", translate("Bind Local"), translate("When selected, it can only be accessed locally,It is recommended to turn on when using reverse proxies.")) +bind_local.default = "0" + +accept_lan = s:option(Flag, "accept_lan", translate("Accept LAN Access"), translate("When selected, it can accessed lan , this will not be safe!")) +accept_lan.default = "0" +accept_lan.rmempty = false + +return m diff --git a/package/lean/luci-app-v2ray-server/luasrc/view/v2ray_server/log.htm b/package/lean/luci-app-v2ray-server/luasrc/view/v2ray_server/log.htm index fbdd2289b..ff934865c 100644 --- a/package/lean/luci-app-v2ray-server/luasrc/view/v2ray_server/log.htm +++ b/package/lean/luci-app-v2ray-server/luasrc/view/v2ray_server/log.htm @@ -1,7 +1,7 @@