From aa408042054913984336057c569024f02edfbb13 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 16 Apr 2026 20:36:17 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=8D=93=20Sync=202026-04-16=2020:36:17?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- easytier/Makefile | 14 +- hickory-dns/Makefile | 4 +- luci-app-easytier/Makefile | 7 +- .../luasrc/controller/easytier.lua | 564 +++++++- .../luasrc/model/cbi/easytier.lua | 215 +-- .../luasrc/model/cbi/easytier_log.lua | 5 - .../luasrc/model/cbi/easytier_status.lua | 16 + .../luasrc/model/cbi/easytierweb_log.lua | 5 - .../luasrc/view/easytier/easytier_cli.htm | 1166 ++++++++++++++++ .../view/easytier/easytier_conninfo.htm | 408 ------ .../luasrc/view/easytier/easytier_log.htm | 569 +++++++- .../luasrc/view/easytier/easytier_status.htm | 1195 ++++++++++++++++- .../luasrc/view/easytier/easytier_upload.htm | 847 ++++++++++++ .../luasrc/view/easytier/easytier_web.htm | 645 +++++++++ .../luasrc/view/easytier/easytierweb_log.htm | 49 - .../luasrc/view/easytier/other_dvalue.htm | 8 - .../luasrc/view/easytier/other_upload.htm | 5 - luci-app-easytier/po/templates/easytier.pot | 313 +++++ luci-app-easytier/po/zh_Hans/easytier.po | 967 +++++++++++-- luci-app-easytier/root/etc/init.d/easytier | 89 +- .../root/usr/share/easytier/firewall.sh | 16 +- .../share/rpcd/acl.d/luci-app-easytier.json | 3 +- luci-app-passwall/Makefile | 2 +- luci-app-passwall2/Makefile | 2 +- 24 files changed, 6145 insertions(+), 969 deletions(-) delete mode 100644 luci-app-easytier/luasrc/model/cbi/easytier_log.lua create mode 100644 luci-app-easytier/luasrc/model/cbi/easytier_status.lua delete mode 100644 luci-app-easytier/luasrc/model/cbi/easytierweb_log.lua create mode 100644 luci-app-easytier/luasrc/view/easytier/easytier_cli.htm delete mode 100644 luci-app-easytier/luasrc/view/easytier/easytier_conninfo.htm create mode 100644 luci-app-easytier/luasrc/view/easytier/easytier_upload.htm create mode 100644 luci-app-easytier/luasrc/view/easytier/easytier_web.htm delete mode 100644 luci-app-easytier/luasrc/view/easytier/easytierweb_log.htm delete mode 100644 luci-app-easytier/luasrc/view/easytier/other_dvalue.htm delete mode 100644 luci-app-easytier/luasrc/view/easytier/other_upload.htm diff --git a/easytier/Makefile b/easytier/Makefile index 4eef117f4..cc2073a7f 100644 --- a/easytier/Makefile +++ b/easytier/Makefile @@ -2,8 +2,8 @@ include $(TOPDIR)/rules.mk -include $(dir $(lastword $(MAKEFILE_LIST)))../version.mk PKG_NAME:=easytier -PKG_VERSION:=$(or $(EASYTIER_VERSION),2.5.0) -PKG_RELEASE:=1 +PKG_VERSION:=$(or $(EASYTIER_VERSION),2.6.0) +PKG_RELEASE:=2 ifeq ($(ARCH),mipsel) APP_ARCH:=mipsel @@ -54,15 +54,19 @@ define Package/$(PKG_NAME)/config config EASYTIER_INCLUDE_WEBCONSOLE bool "Include Web Console (easytier-web)" depends on PACKAGE_$(PKG_NAME) - depends on !@(mips||mipsel) + depends on !(mips || mipsel) default y help Install the easytier-web web console. endef define Build/Prepare - [ ! -f $(PKG_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION).zip ] && wget https://github.com/EasyTier/EasyTier/releases/download/v$(PKG_VERSION)/$(PKG_NAME)-linux-$(APP_ARCH)-v$(PKG_VERSION).zip -O $(PKG_NAME)-$(PKG_VERSION).zip - unzip -j $(PKG_NAME)-$(PKG_VERSION).zip -d $(PKG_BUILD_DIR) + mkdir -p $(PKG_BUILD_DIR) + if [ ! -f $(PKG_BUILD_DIR)/easytier-core ]; then \ + wget https://github.com/EasyTier/EasyTier/releases/download/v$(PKG_VERSION)/$(PKG_NAME)-linux-$(APP_ARCH)-v$(PKG_VERSION).zip -O $(PKG_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION).zip; \ + unzip -o -j $(PKG_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION).zip -d $(PKG_BUILD_DIR); \ + rm -f $(PKG_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION).zip; \ + fi endef define Build/Compile diff --git a/hickory-dns/Makefile b/hickory-dns/Makefile index 337ad1968..6a5a0fa59 100644 --- a/hickory-dns/Makefile +++ b/hickory-dns/Makefile @@ -1,8 +1,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=hickory-dns -PKG_VERSION:=0.26.0-beta.4 -PKG_RELEASE:=14 +PKG_VERSION:=0.26.0-beta.2 +PKG_RELEASE:=15 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/hickory-dns/hickory-dns/tar.gz/v$(PKG_VERSION)? diff --git a/luci-app-easytier/Makefile b/luci-app-easytier/Makefile index 514e9acf5..f80881fd7 100644 --- a/luci-app-easytier/Makefile +++ b/luci-app-easytier/Makefile @@ -7,8 +7,8 @@ include $(TOPDIR)/rules.mk -include $(dir $(lastword $(MAKEFILE_LIST)))../version.mk -PKG_VERSION:=$(or $(EASYTIER_VERSION),2.5.0) -PKG_RELEASE:=1 +PKG_VERSION:=$(or $(EASYTIER_VERSION),2.6.0) +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for EasyTier LUCI_DEPENDS:=+kmod-tun +easytier +luci-compat @@ -54,9 +54,6 @@ if [ -d /tmp/et_config_backup ] ; then fi endef -$(eval $(call Build/Template,Package/$(PKG_NAME)/prerm)) -$(eval $(call Build/Template,Package/$(PKG_NAME)/postinst)) - include $(TOPDIR)/feeds/luci/luci.mk # call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-easytier/luasrc/controller/easytier.lua b/luci-app-easytier/luasrc/controller/easytier.lua index 29aca2d8f..8d12aa550 100644 --- a/luci-app-easytier/luasrc/controller/easytier.lua +++ b/luci-app-easytier/luasrc/controller/easytier.lua @@ -1,5 +1,6 @@ module("luci.controller.easytier", package.seeall) +local i18n = require "luci.i18n" -- 安全执行命令并返回结果 local function safe_exec(cmd) @@ -45,17 +46,34 @@ function index() if not nixio.fs.access("/etc/config/easytier") then return end - - entry({"admin", "vpn", "easytier"}, alias("admin", "vpn", "easytier", "easytier"),_("EasyTier"), 46).dependent = true - entry({"admin", "vpn", "easytier", "easytier"}, cbi("easytier"),_("EasyTier"), 47).leaf = true - entry({"admin", "vpn", "easytier", "easytier_log"}, form("easytier_log"),_("core log"), 48).leaf = true + + entry({"admin", "vpn"}, firstchild(), "VPN", 45).dependent = false + entry({"admin", "vpn", "easytier"}, firstchild(),_("EasyTier"), 46).dependent = true + entry({"admin", "vpn", "easytier", "status"}, cbi("easytier_status"),_("Status"), 1).leaf = true + entry({"admin", "vpn", "easytier", "config"}, cbi("easytier"),_("EasyTier Core"), 2).leaf = true + entry({"admin", "vpn", "easytier", "webconsole"}, template("easytier/easytier_web"),_("EasyTier Web"), 3).leaf = true + entry({"admin", "vpn", "easytier", "log"}, template("easytier/easytier_log"),_("Logs"), 4).leaf = true + entry({"admin", "vpn", "easytier", "upload"}, template("easytier/easytier_upload"),_("Upload Program"), 5).leaf = true + entry({"admin", "vpn", "easytier", "upload_binary"}, call("upload_binary")).leaf = true + entry({"admin", "vpn", "easytier", "get_upload_config"}, call("get_upload_config")).leaf = true + entry({"admin", "vpn", "easytier", "save_upload_config"}, call("save_upload_config")).leaf = true + entry({"admin", "vpn", "easytier", "get_disk_space"}, call("get_disk_space")).leaf = true + entry({"admin", "vpn", "easytier", "get_tun_info"}, call("get_tun_info")).leaf = true entry({"admin", "vpn", "easytier", "get_log"}, call("get_log")).leaf = true + entry({"admin", "vpn", "easytier", "get_log_size"}, call("get_log_size")).leaf = true entry({"admin", "vpn", "easytier", "clear_log"}, call("clear_log")).leaf = true - entry({"admin", "vpn", "easytier", "easytierweb_log"}, form("easytierweb_log"),_("web log"), 49).leaf = true entry({"admin", "vpn", "easytier", "get_wlog"}, call("get_wlog")).leaf = true + entry({"admin", "vpn", "easytier", "get_wlog_size"}, call("get_wlog_size")).leaf = true entry({"admin", "vpn", "easytier", "clear_wlog"}, call("clear_wlog")).leaf = true - entry({"admin", "vpn", "easytier", "status"}, call("act_status")).leaf = true - entry({"admin", "vpn", "easytier", "conninfo"}, call("act_conninfo")).leaf = true + entry({"admin", "vpn", "easytier", "clear_version_cache"}, call("clear_version_cache")).leaf = true + entry({"admin", "vpn", "easytier", "get_web_config"}, call("get_web_config")).leaf = true + entry({"admin", "vpn", "easytier", "save_web_config"}, call("save_web_config")).leaf = true + entry({"admin", "vpn", "easytier", "check_web_status"}, call("check_web_status")).leaf = true + entry({"admin", "vpn", "easytier", "api_status"}, call("act_status")).leaf = true + entry({"admin", "vpn", "easytier", "api_conninfo"}, call("act_conninfo")).leaf = true + entry({"admin", "vpn", "easytier", "restart_service"}, call("restart_service")).leaf = true + entry({"admin", "vpn", "easytier", "toggle_core"}, call("toggle_core")).leaf = true + entry({"admin", "vpn", "easytier", "toggle_web"}, call("toggle_web")).leaf = true end function act_status() @@ -66,6 +84,8 @@ function act_status() e.crunning = luci.sys.call("pgrep easytier-core >/dev/null") == 0 e.wrunning = luci.sys.call("pgrep easytier-web >/dev/null") == 0 e.port = (port or 0) + e.cenabled = uci:get_first("easytier", "easytier", "enabled") == "1" + e.wenabled = uci:get_first("easytier", "easytier", "web_enabled") == "1" -- 使用 Lua 原生计算运行时长 e.etsta = calc_uptime("/tmp/easytier_time") @@ -105,16 +125,229 @@ function act_status() e.ettag = cached_tag:gsub("[\r\n]+", "") else local easytierbin = uci:get_first("easytier", "easytier", "easytierbin") or "/usr/bin/easytier-core" - e.ettag = safe_exec(easytierbin .. " -V | sed 's/^[^0-9]*//'") - if e.ettag == "" then e.ettag = "?" end + e.ettag = safe_exec(easytierbin .. " -V 2>/dev/null | sed 's/^[^0-9]*//'") + if e.ettag == "" or e.ettag == nil then e.ettag = "unknown" end local f = io.open("/tmp/easytier.tag", "w") if f then f:write(e.ettag); f:close() end end + + local cached_webtag = safe_read_file("/tmp/easytierweb.tag") + if cached_webtag and cached_webtag ~= "" then + e.etwebtag = cached_webtag:gsub("[\r\n]+", "") + else + local easytierwebbin = uci:get_first("easytier", "easytier", "easytierwebbin") or "/usr/bin/easytier-web" + e.etwebtag = safe_exec(easytierwebbin .. " -V 2>/dev/null | sed 's/^[^0-9]*//'") + if e.etwebtag == "" or e.etwebtag == nil then e.etwebtag = "unknown" end + local f = io.open("/tmp/easytierweb.tag", "w") + if f then f:write(e.etwebtag); f:close() end + end + + e.no_tun = uci:get_first("easytier", "easytier", "no_tun") == "1" + e.dev_name = uci:get_first("easytier", "easytier", "dev_name") or "tun0" luci.http.prepare_content("application/json") luci.http.write_json(e) end +function get_upload_config() + local uci = require "luci.model.uci".cursor() + local http = require "luci.http" + + http.prepare_content("application/json") + + local config = { + easytierbin = uci:get_first("easytier", "easytier", "easytierbin") or "/usr/bin/easytier-core", + webbin = uci:get_first("easytier", "easytier", "easytierwebbin") or "/usr/bin/easytier-web", + github_proxys = {}, + fallback_version = uci:get_first("easytier", "easytier", "fallback_version") or "v2.6.0" + } + + -- 读取代理列表(list 类型) + uci:foreach("easytier", "easytier", function(s) + local proxys = s.github_proxys + if proxys then + if type(proxys) == "table" then + config.github_proxys = proxys + else + table.insert(config.github_proxys, proxys) + end + end + end) + + http.write_json(config) +end + +function save_upload_config() + local uci = require "luci.model.uci".cursor() + local http = require "luci.http" + local json = require "luci.jsonc" + + http.prepare_content("application/json") + + -- 读取 POST 数据 + local content = http.content() + local data = json.parse(content) + + if not data then + http.write_json({success = false, message = "Invalid JSON data"}) + return + end + + -- 保存配置 + uci:set("easytier", "@easytier[0]", "easytierbin", data.easytierbin or "/usr/bin/easytier-core") + uci:set("easytier", "@easytier[0]", "easytierwebbin", data.webbin or "/usr/bin/easytier-web") + uci:set("easytier", "@easytier[0]", "fallback_version", data.fallback_version or "v2.6.0") + + -- 删除旧的代理列表 + uci:delete("easytier", "@easytier[0]", "github_proxys") + + -- 保存代理列表(list 类型) + if data.github_proxys and type(data.github_proxys) == "table" then + for _, proxy in ipairs(data.github_proxys) do + if proxy and proxy ~= "" then + local current = uci:get("easytier", "@easytier[0]", "github_proxys") or {} + if type(current) ~= "table" then + current = {current} + end + table.insert(current, proxy) + uci:set("easytier", "@easytier[0]", "github_proxys", current) + end + end + end + + uci:commit("easytier") + + http.write_json({success = true, message = "Configuration saved successfully"}) +end + +function get_disk_space() + local http = require "luci.http" + local json = require "luci.jsonc" + local nixio = require "nixio" + + http.prepare_content("application/json") + + local content = http.content() + local data = json.parse(content) + + if not data or not data.path then + http.write_json({success = false, message = "Invalid path"}) + return + end + + local path = data.path + local full_path = data.full_path + local input_type = data.type + + local df_output = luci.sys.exec("df -h '" .. path .. "' 2>/dev/null | tail -n 1") + local df_kb = luci.sys.exec("df -k '" .. path .. "' 2>/dev/null | tail -n 1") + + if df_output and df_output ~= "" and df_kb and df_kb ~= "" then + local available = df_output:match("%S+%s+%S+%s+%S+%s+(%S+)") + local available_kb = df_kb:match("%S+%s+%S+%s+%S+%s+(%d+)") + local available_mb = available_kb and math.floor(tonumber(available_kb) / 1024) or 0 + + if available and available_mb then + local result = { + success = true, + available = available, + available_mb = available_mb + } + + if input_type == "easytierbin" and full_path then + if nixio.fs.access(full_path) then + local size = luci.sys.exec("ls -lh '" .. full_path .. "' 2>/dev/null | awk '{print $5}'") + if size and size ~= "" then + result.core_size = size:gsub("[\r\n]+$", "") + end + end + + local dir = full_path:match("(.*/)") + local cli_path = (dir or "/usr/bin/") .. "easytier-cli" + if nixio.fs.access(cli_path) then + local size = luci.sys.exec("ls -lh '" .. cli_path .. "' 2>/dev/null | awk '{print $5}'") + if size and size ~= "" then + result.cli_size = size:gsub("[\r\n]+$", "") + end + end + elseif input_type == "webbin" and full_path then + if nixio.fs.access(full_path) then + local size = luci.sys.exec("ls -lh '" .. full_path .. "' 2>/dev/null | awk '{print $5}'") + if size and size ~= "" then + result.web_size = size:gsub("[\r\n]+$", "") + end + end + end + + http.write_json(result) + return + end + end + + http.write_json({success = false, message = "Unable to query disk space"}) +end + +function get_tun_info() + luci.http.prepare_content("application/json") + + local ifname = luci.http.formvalue("ifname") or "tun0" + + local exists = luci.sys.exec("ip link show " .. ifname .. " >/dev/null 2>&1 && echo 1 || echo 0") + if not exists:match("1") then + luci.http.write('{"success":false,"exists":false}') + return + end + + local ifconfig_out = luci.sys.exec("ifconfig " .. ifname .. " 2>/dev/null") + + local ip = ifconfig_out:match("inet addr:([%d%.]+)") or ifconfig_out:match("inet ([%d%.]+)") + + local netmask = "" + local netmask_full = ifconfig_out:match("Mask:([%d%.]+)") or ifconfig_out:match("netmask ([%d%.]+)") + + if not netmask_full or netmask_full == "" then + local ip_output = luci.sys.exec("ip -4 addr show " .. ifname .. " 2>/dev/null | grep 'inet ' | head -n1 | awk '{print $2}'") + local cidr = ip_output:match("/(%d+)") + if cidr then + cidr = tonumber(cidr) + local mask = 0xFFFFFFFF - (2 ^ (32 - cidr) - 1) + netmask = string.format("%d.%d.%d.%d", + math.floor(mask / 16777216) % 256, + math.floor(mask / 65536) % 256, + math.floor(mask / 256) % 256, + mask % 256) + end + else + netmask = netmask_full + end + + local ipv6_cmd = luci.sys.exec("ip -6 addr show " .. ifname .. " 2>/dev/null | grep 'inet6' | head -n1 | awk '{print $2}'") + local ipv6 = ipv6_cmd:gsub("%s", "") + if ipv6 == "" then ipv6 = nil end + + local mtu = ifconfig_out:match("MTU:(%d+)") or luci.sys.exec("ip link show " .. ifname .. " 2>/dev/null | head -n1 | sed -n 's/.*mtu \\([0-9]*\\).*/\\1/p'"):gsub("%s", "") + + local state = "UNKNOWN" + if ifconfig_out:match("UP") then + state = "UP" + elseif ifconfig_out:match("DOWN") then + state = "DOWN" + end + + local rx = luci.sys.exec("cat /sys/class/net/" .. ifname .. "/statistics/rx_bytes 2>/dev/null || echo 0"):gsub("%s", "") + local tx = luci.sys.exec("cat /sys/class/net/" .. ifname .. "/statistics/tx_bytes 2>/dev/null || echo 0"):gsub("%s", "") + + local response = string.format('{"success":true,"exists":true,"ip":"%s","netmask":"%s","mtu":"%s","state":"%s","rx_bytes":%s,"tx_bytes":%s', + ip or "", netmask, mtu, state, rx, tx) + + if ipv6 then + response = response .. ',"ipv6":"' .. ipv6 .. '"' + end + + response = response .. '}' + + luci.http.write(response) +end function get_log() local log = "" @@ -127,10 +360,212 @@ function get_log() luci.http.write(log) end +function get_log_size() + local size = luci.sys.exec("[ -f '/tmp/easytier.log' ] && stat -c%s /tmp/easytier.log 2>/dev/null || echo 0") + luci.http.prepare_content("application/json") + luci.http.write_json({size = tonumber(size) or 0}) +end + +function get_wlog_size() + local size = luci.sys.exec("[ -f '/tmp/easytierweb.log' ] && stat -c%s /tmp/easytierweb.log 2>/dev/null || echo 0") + luci.http.prepare_content("application/json") + luci.http.write_json({size = tonumber(size) or 0}) +end + function clear_log() luci.sys.call("echo '' >/tmp/easytier.log") end +local function test_binary(path) + local handle = io.popen(path .. " -h 2>&1") + local output = handle:read("*a") + handle:close() + + local line_count = 0 + for _ in output:gmatch("[^\r\n]+") do + line_count = line_count + 1 + end + + return line_count >= 3 and output:lower():match("easytier") +end + +local function cleanup_files(...) + for _, file in ipairs({...}) do + nixio.fs.remove(file) + end +end + +function upload_binary() + local http = require "luci.http" + local uci = require "luci.model.uci".cursor() + local nixio = require "nixio" + local translate = i18n.translate + + local fp + local filename = "" + local tmp_file = "" + + http.setfilehandler( + function(meta, chunk, eof) + if meta and meta.file then + filename = meta.file + tmp_file = "/tmp/upload_" .. filename + end + if not fp and tmp_file ~= "" then + fp = io.open(tmp_file, "w") + end + if chunk and fp then + fp:write(chunk) + end + if eof and fp then + fp:close() + end + end + ) + + http.prepare_content("application/json") + + if not http.formvalue("file") or tmp_file == "" then + http.write_json({success = false, message = translate("No file uploaded")}) + return + end + + local is_archive = filename:match("%.zip$") or filename:match("%.tar%.gz$") or filename:match("%.tgz$") or filename:match("%.tar$") + + if is_archive then + local extract_dir = "/tmp/easytier_extract" + os.execute("rm -rf " .. extract_dir .. " && mkdir -p " .. extract_dir) + + if filename:match("%.zip$") then + if os.execute("which unzip >/dev/null 2>&1") ~= 0 then + cleanup_files(tmp_file) + http.write_json({success = false, message = translate("System lacks unzip package, cannot extract zip archive")}) + return + end + os.execute("unzip -o -q " .. tmp_file .. " -d " .. extract_dir) + else + os.execute("tar -xzf " .. tmp_file .. " -C " .. extract_dir .. " 2>/dev/null || tar -xf " .. tmp_file .. " -C " .. extract_dir) + end + + os.execute("find " .. extract_dir .. "/easytier-linux-* -maxdepth 1 -type f -exec mv {} " .. extract_dir .. "/ \\; 2>/dev/null") + cleanup_files(tmp_file) + + if nixio.fs.access(extract_dir .. "/easytier-web") then + nixio.fs.remove(extract_dir .. "/easytier-web") + end + + local binaries = {"easytier-core", "easytier-cli", "easytier-web-embed"} + local valid_bins = {} + + for _, bin in ipairs(binaries) do + local src = extract_dir .. "/" .. bin + if nixio.fs.access(src) then + nixio.fs.chmod(src, "755") + if test_binary(src) then + table.insert(valid_bins, {name = bin, path = src}) + else + cleanup_files(src) + end + end + end + + if #valid_bins == 0 then + os.execute("rm -rf " .. extract_dir) + http.write_json({success = false, message = translate("Not a valid EasyTier program or architecture mismatch")}) + return + end + + local core_path = uci:get_first("easytier", "easytier", "easytierbin") or "/usr/bin/easytier-core" + local web_path = uci:get_first("easytier", "easytier", "easytierwebbin") or "/usr/bin/easytier-web" + + for _, bin in ipairs(valid_bins) do + local final_path + if bin.name == "easytier-web-embed" then + final_path = web_path + elseif bin.name == "easytier-core" then + final_path = core_path + elseif bin.name == "easytier-cli" then + local core_dir = core_path:match("(.*/)") + final_path = (core_dir or "/usr/bin/") .. "easytier-cli" + end + + os.execute("rm -f " .. final_path) + + if os.execute("mv " .. bin.path .. " " .. final_path) ~= 0 then + os.execute("rm -rf " .. extract_dir) + http.write_json({success = false, message = translate("Failed to move file. Insufficient space or permission denied")}) + return + end + + os.execute("chmod 755 " .. final_path) + if not test_binary(final_path) then + os.execute("rm -f " .. final_path) + os.execute("rm -rf " .. extract_dir) + http.write_json({success = false, message = translate("Not a valid EasyTier program or architecture mismatch")}) + return + end + end + + os.execute("rm -rf " .. extract_dir) + nixio.fs.remove("/tmp/easytier.tag") + nixio.fs.remove("/tmp/easytierweb.tag") + http.write_json({success = true, message = translate("Successfully installed") .. " " .. #valid_bins .. " " .. translate("binary file(s)")}) + else + local valid_names = {["easytier-core"] = true, ["easytier-cli"] = true, ["easytier-web-embed"] = true, ["easytier-web"] = true} + + if not valid_names[filename] then + cleanup_files(tmp_file) + http.write_json({success = false, message = translate("Not a valid EasyTier program")}) + return + end + + if filename == "easytier-web" then + cleanup_files(tmp_file) + http.write_json({success = false, message = translate("easytier-web is not used by this plugin, please upload easytier-web-embed")}) + return + end + + nixio.fs.chmod(tmp_file, "755") + if not test_binary(tmp_file) then + cleanup_files(tmp_file) + http.write_json({success = false, message = translate("Not a valid EasyTier program or architecture mismatch")}) + return + end + + local core_path = uci:get_first("easytier", "easytier", "easytierbin") or "/usr/bin/easytier-core" + local web_path = uci:get_first("easytier", "easytier", "easytierwebbin") or "/usr/bin/easytier-web" + + local final_path + if filename == "easytier-web-embed" then + final_path = web_path + elseif filename == "easytier-core" then + final_path = core_path + elseif filename == "easytier-cli" then + local core_dir = core_path:match("(.*/)") + final_path = (core_dir or "/usr/bin/") .. "easytier-cli" + end + + os.execute("rm -f " .. final_path) + + if os.execute("mv " .. tmp_file .. " " .. final_path) ~= 0 then + cleanup_files(tmp_file) + http.write_json({success = false, message = translate("Failed to move file. Insufficient space or permission denied")}) + return + end + + os.execute("chmod 755 " .. final_path) + if not test_binary(final_path) then + os.execute("rm -f " .. final_path) + http.write_json({success = false, message = translate("Not a valid EasyTier program or architecture mismatch")}) + return + end + + nixio.fs.remove("/tmp/easytier.tag") + nixio.fs.remove("/tmp/easytierweb.tag") + http.write_json({success = true, message = translate("Binary uploaded successfully to") .. " " .. final_path}) + end +end + function get_wlog() local log = "" local files = {"/tmp/easytierweb.log"} @@ -146,6 +581,16 @@ function clear_wlog() luci.sys.call("echo '' >/tmp/easytierweb.log") end +function clear_version_cache() + local type = luci.http.formvalue("type") + if type == "core" then + luci.sys.call("rm -f /tmp/easytiernew.tag /tmp/easytier.tag") + elseif type == "web" then + luci.sys.call("rm -f /tmp/easytiernew.tag /tmp/easytierweb.tag") + end + luci.http.write("OK") +end + function act_conninfo() local e = {} local uci = require "luci.model.uci".cursor() @@ -186,8 +631,15 @@ function act_conninfo() else e.cmdline = "" end + + -- 检查是否使用配置文件启动 + if e.cmdline:match("%-%-config%-file") or e.cmdline:match("%-c%s+/") then + e.config_file = safe_read_file("/etc/easytier/config.toml") or "" + else + e.config_file = "" + end else - local errMsg = "错误:程序未运行!请启动程序后刷新" + local errMsg = i18n.translate("Error: Program not running! Please start the program and refresh") e.node = errMsg e.peer = errMsg e.connector = errMsg @@ -205,3 +657,95 @@ function act_conninfo() luci.http.prepare_content("application/json") luci.http.write_json(e) end + + +function get_web_config() + local uci = require "luci.model.uci".cursor() + local config = {} + + config.web_enabled = uci:get_first("easytier", "easytier", "web_enabled") or "0" + config.web_db_path = uci:get_first("easytier", "easytier", "web_db_path") or "/etc/easytier/et.db" + config.web_protocol = uci:get_first("easytier", "easytier", "web_protocol") or "udp" + config.web_port = uci:get_first("easytier", "easytier", "web_port") or "22020" + config.web_fw_web = uci:get_first("easytier", "easytier", "web_fw_web") or "0" + config.web_api_port = uci:get_first("easytier", "easytier", "web_api_port") or "11211" + config.web_html_port = uci:get_first("easytier", "easytier", "web_html_port") or "11211" + config.web_fw_api = uci:get_first("easytier", "easytier", "web_fw_api") or "0" + config.web_api_host = uci:get_first("easytier", "easytier", "web_api_host") or "" + config.web_geoip_db = uci:get_first("easytier", "easytier", "web_geoip_db") or "" + config.web_weblog = uci:get_first("easytier", "easytier", "web_weblog") or "off" + + luci.http.prepare_content("application/json") + luci.http.write_json(config) +end + +function save_web_config() + local uci = require "luci.model.uci".cursor() + + uci:set("easytier", "@easytier[0]", "web_enabled", luci.http.formvalue("web_enabled") or "0") + uci:set("easytier", "@easytier[0]", "web_db_path", luci.http.formvalue("web_db_path") or "/etc/easytier/et.db") + uci:set("easytier", "@easytier[0]", "web_protocol", luci.http.formvalue("web_protocol") or "udp") + uci:set("easytier", "@easytier[0]", "web_port", luci.http.formvalue("web_port") or "22020") + uci:set("easytier", "@easytier[0]", "web_fw_web", luci.http.formvalue("web_fw_web") or "0") + uci:set("easytier", "@easytier[0]", "web_api_port", luci.http.formvalue("web_api_port") or "11211") + uci:set("easytier", "@easytier[0]", "web_html_port", luci.http.formvalue("web_html_port") or "11211") + uci:set("easytier", "@easytier[0]", "web_fw_api", luci.http.formvalue("web_fw_api") or "0") + uci:set("easytier", "@easytier[0]", "web_api_host", luci.http.formvalue("web_api_host") or "") + uci:set("easytier", "@easytier[0]", "web_geoip_db", luci.http.formvalue("web_geoip_db") or "") + uci:set("easytier", "@easytier[0]", "web_weblog", luci.http.formvalue("web_weblog") or "off") + + uci:commit("easytier") + + luci.sys.exec("/etc/init.d/easytier restart >/dev/null 2>&1 &") + + luci.http.prepare_content("application/json") + luci.http.write_json({success = true}) +end + +function check_web_status() + local running = luci.sys.call("pgrep easytier-web >/dev/null") == 0 + local uci = require "luci.model.uci".cursor() + local port = uci:get_first("easytier", "easytier", "web_html_port") or "11211" + + luci.http.prepare_content("application/json") + luci.http.write_json({ + running = running, + port = port + }) +end + +function restart_service() + luci.http.prepare_content("application/json") + luci.sys.exec("/etc/init.d/easytier restart >/dev/null 2>&1 &") + luci.http.write_json({success = true}) +end + +function toggle_core() + local enabled = luci.http.formvalue("enabled") + local uci = require "luci.model.uci".cursor() + uci:set("easytier", uci:get_first("easytier", "easytier"), "enabled", enabled) + uci:commit("easytier") + + if enabled == "1" then + luci.sys.exec("/etc/init.d/easytier start >/dev/null 2>&1 &") + else + luci.sys.exec("/etc/init.d/easytier restart >/dev/null 2>&1 &") + end + luci.http.prepare_content("application/json") + luci.http.write_json({success = true}) +end + +function toggle_web() + local enabled = luci.http.formvalue("enabled") + local uci = require "luci.model.uci".cursor() + uci:set("easytier", uci:get_first("easytier", "easytier"), "web_enabled", enabled) + uci:commit("easytier") + + if enabled == "1" then + luci.sys.exec("/etc/init.d/easytier start >/dev/null 2>&1 &") + else + luci.sys.exec("/etc/init.d/easytier restart >/dev/null 2>&1 &") + end + luci.http.prepare_content("application/json") + luci.http.write_json({success = true}) +end diff --git a/luci-app-easytier/luasrc/model/cbi/easytier.lua b/luci-app-easytier/luasrc/model/cbi/easytier.lua index b2b83da4b..ec83091c5 100644 --- a/luci-app-easytier/luasrc/model/cbi/easytier.lua +++ b/luci-app-easytier/luasrc/model/cbi/easytier.lua @@ -2,36 +2,17 @@ local http = luci.http local nixio = require "nixio" m = Map("easytier") -m.description = translate("A simple, secure, decentralized VPN solution for intranet penetration, implemented in Rust using the Tokio framework. " - .. "Project URL: github.com/EasyTier/EasyTier  " - .. "Official Documentation  " - .. "QQ Group  ") - -m:section(SimpleSection).template = "easytier/easytier_status" -- easytier-core -s=m:section(TypedSection, "easytier", translate("EasyTier Configuration")) +s=m:section(TypedSection, "easytier") s.addremove=false s.anonymous=true s:tab("general", translate("General Settings")) s:tab("privacy", translate("Advanced Settings")) -s:tab("webconsole", translate("Self-hosted Web Server")) -s:tab("infos", translate("Connection Info")) -s:tab("upload", translate("Upload Program")) switch = s:taboption("general",Flag, "enabled", translate("Enable")) switch.rmempty = false -btncq = s:taboption("general", Button, "btncq", translate("Restart")) -btncq.inputtitle = translate("Restart") -btncq.description = translate("Quickly restart once without modifying any parameters") -btncq.inputstyle = "apply" -btncq:depends("enabled", "1") -btncq.write = function() - luci.sys.call("rm -rf /tmp/easytier*.tag /tmp/easytier*.newtag >/dev/null 2>&1 &") -- 执行删除版本号信息 - luci.sys.call("/etc/init.d/easytier restart >/dev/null 2>&1 &") -- 执行重启命令 -end - etcmd = s:taboption("general", ListValue, "etcmd", translate("Startup Method"), translate("Official Web Console: https://easytier.cn/web
" .. "Official Configuration File Generator: " @@ -113,8 +94,6 @@ peeradd = s:taboption("general", DynamicList, "peeradd", translate("Peer Nodes") translate("Initial connected peer nodes (-p parameter)
" .. "Public server status check:
" .. "Click here to check")) -peeradd.placeholder = "tcp://public.easytier.top:11010" -peeradd:value("tcp://public.easytier.top:11010", translate("Official Server - tcp://public.easytier.top:11010")) peeradd:depends("etcmd", "etcmd") --[=[ @@ -471,8 +450,9 @@ et_forward:value("etfwlan", translate("Allow traffic from EasyTier virtual netwo et_forward:value("etfwwan", translate("Allow traffic from EasyTier virtual network to WAN")) et_forward:value("lanfwet", translate("Allow traffic from LAN to EasyTier virtual network")) et_forward:value("wanfwet", translate("Allow traffic from WAN to EasyTier virtual network")) -et_forward.default = "etfwlan etfwwan lanfwet" et_forward.rmempty = true +et_forward.optional = true +et_forward:depends("auto_config_firewall", "1") check = s:taboption("privacy", Flag, "check", translate("Connectivity Check"), translate("Enable connectivity check to specify remote device IPs; if all specified IPs fail to ping, " @@ -492,193 +472,4 @@ for s = 1, 60 do end checktime:depends("check", "1") -local process_status = luci.sys.exec("ps | grep easytier-core| grep -v grep") - --- 连接信息 tab - 使用 HTM 模板展示 -conninfo = s:taboption("infos", DummyValue, "_conninfo") -conninfo.template = "easytier/easytier_conninfo" -conninfo.rawhtml = true - -btnrm = s:taboption("infos", Button, "btnrm") -btnrm.inputtitle = translate("Check for Updates") -btnrm.description = translate("Click the button to start checking for updates and refresh the version display in the status bar above") -btnrm.inputstyle = "apply" -btnrm.write = function() - os.execute("rm -rf /tmp/easytier*.tag /tmp/easytier*.newtag /tmp/easytier-core_*") -end - - -easytierbin = s:taboption("upload", Value, "easytierbin", translate("easytier-core Binary Path"), - translate("Customize the storage path for easytier-core. Make sure to provide the full path and filename. " - .. "If the specified path has insufficient space, it will automatically move to /tmp/easytier-core")) -easytierbin.placeholder = "/usr/bin/easytier-core" -easytierbin.default = "/usr/bin/easytier-core" - -webbin = s:taboption("upload", Value, "webbin", translate("easytier-web Binary Path"), - translate("Customize the storage path for easytier-web. Make sure to provide the full path and filename, " - .. "then upload the installer")) -webbin.placeholder = "/usr/bin/easytier-web" -webbin.default = "/usr/bin/easytier-web" - -github_proxys = s:taboption("upload", Value, "github_proxys", translate("GitHub Proxy URLs"), - translate("Space-separated list of GitHub proxy URLs for downloading binaries. " - .. "Leave empty to use default proxies.")) -github_proxys.placeholder = "https://ghproxy.net/ https://gh-proxy.com/" - -fallback_version = s:taboption("upload", Value, "fallback_version", translate("Fallback Version"), - translate("Fallback version to use when unable to fetch the latest version from GitHub.")) -fallback_version.placeholder = "v2.5.0" -fallback_version.default = "v2.5.0" - -local upload = s:taboption("upload", FileUpload, "upload_file") -upload.optional = true -upload.default = "" -upload.template = "easytier/other_upload" -upload.description = translate("You can directly upload the binary programs easytier-core and easytier-cli, or a compressed .zip archive. " - .. "Uploading a new version will automatically overwrite the old one. Download link: " - .. "github.com/EasyTier/EasyTier
" - .. "The uploaded files will be saved in the /tmp folder. If a custom program path is specified, " - .. "the program will be automatically moved to that path when started.
") -local um = s:taboption("upload",DummyValue, "", nil) -um.template = "easytier/other_dvalue" - -local dir, fd, chunk -dir = "/tmp/" -nixio.fs.mkdir(dir) -http.setfilehandler( - function(meta, chunk, eof) - if not fd then - if not meta then return end - - if meta and chunk then fd = nixio.open(dir .. meta.file, "w") end - - if not fd then - um.value = translate("Error: Upload failed!") - return - end - end - - if chunk and fd then - fd:write(chunk) - end - - if eof and fd then - fd:close() - fd = nil - um.value = translate("File has been uploaded to") .. ' "/tmp/' .. meta.file .. '"' - - if string.sub(meta.file, -4) == ".zip" then - local file_path = dir .. meta.file - os.execute("unzip -q " .. file_path .. " -d " .. dir) - local extracted_dir = "/tmp/easytier-linux-*/" - os.execute("mv " .. extracted_dir .. "easytier-cli /tmp/easytier-cli") - os.execute("mv " .. extracted_dir .. "easytier-core /tmp/easytier-core") - os.execute("mv " .. extracted_dir .. "easytier-web-embed /tmp/easytier-web-embed") - if nixio.fs.access("/tmp/easytier-cli") then - um.value = um.value .. "\n" .. translate("- Program /tmp/easytier-cli uploaded successfully, restart the plugin to take effect") - end - if nixio.fs.access("/tmp/easytier-core") then - um.value = um.value .. "\n" .. translate("- Program /tmp/easytier-core uploaded successfully, restart the plugin to take effect") - end - if nixio.fs.access("/tmp/easytier-web-embed") then - um.value = um.value .. "\n" .. translate("- Program /tmp/easytier-web uploaded successfully, restart the plugin to take effect") - end - end - - if string.sub(meta.file, -7) == ".tar.gz" then - local file_path = dir .. meta.file - os.execute("tar -xzf " .. file_path .. " -C " .. dir) - local extracted_dir = "/tmp/easytier-linux-*/" - os.execute("mv " .. extracted_dir .. "easytier-cli /tmp/easytier-cli") - os.execute("mv " .. extracted_dir .. "easytier-core /tmp/easytier-core") - os.execute("mv " .. extracted_dir .. "easytier-web-embed /tmp/easytier-web-embed") - if nixio.fs.access("/tmp/easytier-cli") then - um.value = um.value .. "\n" .. translate("- Program /tmp/easytier-cli uploaded successfully, restart the plugin to take effect") - end - if nixio.fs.access("/tmp/easytier-core") then - um.value = um.value .. "\n" .. translate("- Program /tmp/easytier-core uploaded successfully, restart the plugin to take effect") - end - if nixio.fs.access("/tmp/easytier-web-embed") then - um.value = um.value .. "\n" .. translate("- Program /tmp/easytier-web uploaded successfully, restart the plugin to take effect") - end - end - - os.execute("chmod +x /tmp/easytier-core") - os.execute("chmod +x /tmp/easytier-cli") - os.execute("chmod +x /tmp/easytier-web-embed") - - end - end -) -if luci.http.formvalue("upload") then - local f = luci.http.formvalue("ulfile") -end - --- Self-hosted Web Console tab options - -web_enabled = s:taboption("webconsole", Flag, "web_enabled", translate("Enable")) -web_enabled.rmempty = false - -web_btncq = s:taboption("webconsole", Button, "web_btncq", translate("Restart")) -web_btncq.inputtitle = translate("Restart") -web_btncq.description = translate("Quickly restart once without modifying any parameters") -web_btncq.inputstyle = "apply" -web_btncq.write = function() - luci.sys.call("/etc/init.d/easytier restart >/dev/null 2>&1 &") -end - -web_db_path = s:taboption("webconsole", Value, "web_db_path", translate("Database File Path"), - translate("Path to the sqlite3 database file used to store all data. (-d parameter)")) -web_db_path.default = "/etc/easytier/et.db" - -web_protocol = s:taboption("webconsole", ListValue, "web_protocol", translate("Listening Protocol"), - translate("Configure the server's listening protocol for easytier-core to connect. (-p parameter)")) -web_protocol.default = "udp" -web_protocol:value("udp",translate("UDP")) -web_protocol:value("tcp",translate("TCP")) -web_protocol:value("ws",translate("WS")) - -web_port = s:taboption("webconsole", Value, "web_port", translate("Server Port"), - translate("Configure the server's listening port for easytier-core to connect. (-c parameter)")) -web_port.datatype = "range(1,65535)" -web_port.placeholder = "22020" -web_port.default = "22020" - -web_fw_web = s:taboption("webconsole", Flag, "web_fw_web", translate("WAN access to WEB"), - translate("Automatically add firewall rules to allow WAN access to this WEB console")) - -web_api_port = s:taboption("webconsole", Value, "web_api_port", translate("API Port"), - translate("Listening port of the RESTful server, used as ApiHost by the web frontend. (-a parameter)")) -web_api_port.datatype = "range(1,65535)" -web_api_port.placeholder = "11211" -web_api_port.default = "11211" - -web_html_port = s:taboption("webconsole", Value, "web_html_port", translate("Web Interface Port"), - translate("Frontend listening port for the web dashboard server. Leave empty to disable. (-l parameter)")) -web_html_port.datatype = "range(1,65535)" -web_html_port.default = "11211" - -web_fw_api = s:taboption("webconsole", Flag, "web_fw_api", translate("WAN access to API"), - translate("Automatically add firewall rules to allow WAN access to the API control page")) - -web_api_host = s:taboption("webconsole", Value, "web_api_host", translate("Default API Server URL"), - translate("The URL of the API server, used for connecting the web frontend. (--api-host parameter)
" - .. "Example: http://[current device IP or resolved domain name]:[API port]")) - -web_geoip_db = s:taboption("webconsole", Value, "web_geoip_db", translate("GEOIP_DB Path"), - translate("GeoIP2 database file path used to locate the client. Defaults to an embedded file (country-level information only)." - .. "
Recommended: https://github.com/P3TERX/GeoLite.mmdb (--geoip-db parameter)")) -web_geoip_db.placeholder = "/etc/easytier/GeoLite.mmdb" - -web_weblog = s:taboption("webconsole", ListValue, "web_weblog", translate("Program Log"), - translate("Runtime log located at /tmp/easytierweb.log, viewable in the log section above.
" - .. "Levels: Error < Warning < Info < Debug < Trace")) -web_weblog.default = "off" -web_weblog:value("off", translate("Off")) -web_weblog:value("error", translate("Error")) -web_weblog:value("warn", translate("Warning")) -web_weblog:value("info", translate("Info")) -web_weblog:value("debug", translate("Debug")) -web_weblog:value("trace", translate("Trace")) - return m diff --git a/luci-app-easytier/luasrc/model/cbi/easytier_log.lua b/luci-app-easytier/luasrc/model/cbi/easytier_log.lua deleted file mode 100644 index 70b85233a..000000000 --- a/luci-app-easytier/luasrc/model/cbi/easytier_log.lua +++ /dev/null @@ -1,5 +0,0 @@ -f = SimpleForm("easytier") -f.reset = false -f.submit = false -f:append(Template("easytier/easytier_log")) -return f diff --git a/luci-app-easytier/luasrc/model/cbi/easytier_status.lua b/luci-app-easytier/luasrc/model/cbi/easytier_status.lua new file mode 100644 index 000000000..31f225798 --- /dev/null +++ b/luci-app-easytier/luasrc/model/cbi/easytier_status.lua @@ -0,0 +1,16 @@ +local http = luci.http + +m = Map("easytier", translate("EasyTier Status")) +m.description = translate("A simple, secure, decentralized VPN solution for intranet penetration, implemented in Rust using the Tokio framework. " + .. "Project URL: github.com/EasyTier/EasyTier  " + .. "Official Documentation  " + .. "QQ Group  ") +m.pageaction = false + +-- 状态卡片 +m:section(SimpleSection).template = "easytier/easytier_status" + +-- 连接信息卡片 +m:section(SimpleSection).template = "easytier/easytier_cli" + +return m diff --git a/luci-app-easytier/luasrc/model/cbi/easytierweb_log.lua b/luci-app-easytier/luasrc/model/cbi/easytierweb_log.lua deleted file mode 100644 index ebd559f5c..000000000 --- a/luci-app-easytier/luasrc/model/cbi/easytierweb_log.lua +++ /dev/null @@ -1,5 +0,0 @@ -f = SimpleForm("easytier") -f.reset = false -f.submit = false -f:append(Template("easytier/easytierweb_log")) -return f diff --git a/luci-app-easytier/luasrc/view/easytier/easytier_cli.htm b/luci-app-easytier/luasrc/view/easytier/easytier_cli.htm new file mode 100644 index 000000000..2436db1a2 --- /dev/null +++ b/luci-app-easytier/luasrc/view/easytier/easytier_cli.htm @@ -0,0 +1,1166 @@ +<% +local uci = require 'luci.model.uci'.cursor() +-%> + + + +
+
+
<%:Connection Information%>
+ +
+ +
+
+ + + + + + + + + + + + +
+
+ +
+
+
+ <%:Collecting data...%> +
+
+
+
+
+ <%:Collecting data...%> +
+
+
+
+
+ <%:Collecting data...%> +
+
+
+
+
+ <%:Collecting data...%> +
+
+
+
+
+ <%:Collecting data...%> +
+
+
+
+
+ <%:Collecting data...%> +
+
+
+
+
+ <%:Collecting data...%> +
+
+
+
+
+ <%:Collecting data...%> +
+
+
+
+
+ <%:Collecting data...%> +
+
+
+
+
+ <%:Collecting data...%> +
+
+
+
+
+ <%:Collecting data...%> +
+
+
+
+
+ <%:Collecting data...%> +
+
+ + + +
+ + diff --git a/luci-app-easytier/luasrc/view/easytier/easytier_conninfo.htm b/luci-app-easytier/luasrc/view/easytier/easytier_conninfo.htm deleted file mode 100644 index d3de16658..000000000 --- a/luci-app-easytier/luasrc/view/easytier/easytier_conninfo.htm +++ /dev/null @@ -1,408 +0,0 @@ -<% - local uci = require 'luci.model.uci'.cursor() -%> - - - - -
-
- - 加载中... -
- -
-
- ▼ - 节点信息 -
-
- <%:Collecting data...%> -
-
- -
-
- ▼ - 节点列表 -
-
- <%:Collecting data...%> -
-
- -
-
- ▼ - 连接器信息 -
-
- <%:Collecting data...%> -
-
- -
-
- ▼ - STUN信息 -
-
- <%:Collecting data...%> -
-
- -
-
- ▼ - 路由信息 -
-
- <%:Collecting data...%> -
-
- -
-
- ▼ - 节点中心 -
-
- <%:Collecting data...%> -
-
- -
-
- ▼ - VPN门户 -
-
- <%:Collecting data...%> -
-
- -
-
- ▼ - TCP/KCP代理 -
-
- <%:Collecting data...%> -
-
- -
-
- ▼ - ACL规则 -
-
- <%:Collecting data...%> -
-
- -
-
- ▼ - 映射监听器 -
-
- <%:Collecting data...%> -
-
- -
-
- ▼ - 统计信息 -
-
- <%:Collecting data...%> -
-
- -
-
- ▼ - 启动参数 -
-
- <%:Collecting data...%> -
-
-
diff --git a/luci-app-easytier/luasrc/view/easytier/easytier_log.htm b/luci-app-easytier/luasrc/view/easytier/easytier_log.htm index f1c96de4a..0751b67b0 100644 --- a/luci-app-easytier/luasrc/view/easytier/easytier_log.htm +++ b/luci-app-easytier/luasrc/view/easytier/easytier_log.htm @@ -1,49 +1,542 @@ <% -local dsp = require "luci.dispatcher" +local util = require "luci.util" +local i18n = require "luci.i18n" +local translate = i18n.translate -%> +<%+header%> + + + +
+
+
+ + +
+
+ + + + +
+
+
+
<%=translate("Loading logs...")%>
+
+ +
-
- <%:Auto Refresh%> - - - -
+ +<%+footer%> diff --git a/luci-app-easytier/luasrc/view/easytier/easytier_status.htm b/luci-app-easytier/luasrc/view/easytier/easytier_status.htm index b46d842a0..50a3349cc 100644 --- a/luci-app-easytier/luasrc/view/easytier/easytier_status.htm +++ b/luci-app-easytier/luasrc/view/easytier/easytier_status.htm @@ -1,60 +1,1143 @@ <% - local uci = require 'luci.model.uci'.cursor() - protocol="http://" -%> +local uci = require 'luci.model.uci'.cursor() +local util = require "luci.util" +local i18n = require "luci.i18n" +local translate = i18n.translate +protocol = "http://" +-%> + + + +
+
+
<%=translate("Quick Actions")%>
+ +
+
+
EasyTier Core
+
+ +
+
+
+
EasyTier Web
+
+ +
+
+
+ +
+
<%=translate("Collecting data...")%>
+
+ + + -
-

- <%:Collecting data...%> -

-
+ +
+
+
<%=translate("Refresh Version")%>
+
<%=translate("Clear cached version and fetch latest version from GitHub?")%>
+
+ + +
+
+
+ +
+
+
<%=translate("Restart Service")%>
+
<%=translate("Restart EasyTier service?")%>
+
+ + +
+
+
+ + diff --git a/luci-app-easytier/luasrc/view/easytier/easytier_upload.htm b/luci-app-easytier/luasrc/view/easytier/easytier_upload.htm new file mode 100644 index 000000000..06e3789f7 --- /dev/null +++ b/luci-app-easytier/luasrc/view/easytier/easytier_upload.htm @@ -0,0 +1,847 @@ +<% +local util = require "luci.util" +local i18n = require "luci.i18n" +local translate = i18n.translate +-%> +<%+header%> + + + +
+
+
<%=translate("Configuration")%>
+
+ + +
+
+
+
+ + +
+
+
+
+ +
+
+ + +
+
+ <%=translate("Used to accelerate GitHub downloads when fetching binaries online")%> +
+
+
+ + +
+ <%=translate("Used when unable to fetch the latest version during online download")%> +
+
+ +
+ +
+
📦
+
<%=translate("Upload EasyTier Binary")%>
+
<%=translate("Drag *.tar.gz / *.zip / easytier binaries here or click to select file")%>
+ + +
+ +
+
+
+
+
<%=translate("Uploading...")%> 0%
+
+ + + +
+ +
+
<%=translate("Supported Files")%>
+
    +
  • easytier-core - <%=translate("Core service binary")%>
  • +
  • easytier-cli - <%=translate("Command line tool")%>
  • +
  • easytier-web-embed - <%=translate("Embedded web console")%> (<%=translate("Recommended")%>)
  • +
  • easytier-web - <%=translate("Web console binary")%> (<%=translate("Will be ignored, use embed version instead")%>)
  • +
  • *.zip / *.tar.gz - <%=translate("Compressed archive containing binaries")%>
  • +
+
+
+ <%=translate("Note")%>: +
+
+ <%=translate("Files will be uploaded to the paths specified above")%>. <%=translate("EasyTier console uses easytier-web-embed. The easytier-web binary will be rejected during upload validation.")%> +
+
+
+
+ <%=translate("Warning")%>: +
+
+ <%=translate("If the device has insufficient storage space, the upload may fail and existing programs may be deleted. Please ensure adequate free space before uploading.")%> +
+
+
+ <%=translate("Download from")%>: https://github.com/EasyTier/EasyTier +
+
+
+ + + + + +<%+footer%> diff --git a/luci-app-easytier/luasrc/view/easytier/easytier_web.htm b/luci-app-easytier/luasrc/view/easytier/easytier_web.htm new file mode 100644 index 000000000..69ce4ee35 --- /dev/null +++ b/luci-app-easytier/luasrc/view/easytier/easytier_web.htm @@ -0,0 +1,645 @@ +<% +local util = require "luci.util" +local uci = require "luci.model.uci".cursor() +-%> +<%+header%> + + + +
+
+

<%:Self-hosted Web Console%>

+ +
+
+
+ + +
+
+ +
+ + + <%:Path to the sqlite3 database file used to store all data. (-d parameter)%> +
+ +
+ + + <%:Configure the server's listening protocol for easytier-core to connect. (-p parameter)%> +
+ +
+ + + <%:Configure the server's listening port for easytier-core to connect. (-c parameter)%> +
+ +
+
+ + +
+ <%:Automatically add firewall rules to allow WAN access to this WEB console%> +
+ +
+ + + <%:Listening port of the RESTful server, used as ApiHost by the web frontend. (-a parameter)%> +
+ +
+ + + <%:Frontend listening port for the web dashboard server. Leave empty to disable. (-l parameter)%> +
+ +
+
+ + +
+ <%:Automatically add firewall rules to allow WAN access to the API control page%> +
+ +
+ + + <%:The URL of the API server, used for connecting the web frontend%>. (--api-host <%:parameter%>)
+ <%:Example%>: http://[<%:current device IP or domain%>]:[<%:API port%>]
+
+ +
+ + + <%:GeoIP2 database file path used to locate the client%>. <%:Defaults to an embedded file (country-level information only)%>.
+ <%:Recommended%>: https://github.com/P3TERX/GeoLite.mmdb (--geoip-db <%:parameter%>)
+
+ +
+ + + <%:Runtime log located at%> /tmp/easytierweb.log, <%:viewable in the log section%>.
+ <%:Log levels%>: Error < Warning < Info < Debug < Trace
+
+ +
+ +
+
+
+ + +
+ + +
+ + + +<%+footer%> diff --git a/luci-app-easytier/luasrc/view/easytier/easytierweb_log.htm b/luci-app-easytier/luasrc/view/easytier/easytierweb_log.htm deleted file mode 100644 index 7594bdbba..000000000 --- a/luci-app-easytier/luasrc/view/easytier/easytierweb_log.htm +++ /dev/null @@ -1,49 +0,0 @@ -<% -local dsp = require "luci.dispatcher" --%> - - -
- <%:Auto Refresh%> - - - -
diff --git a/luci-app-easytier/luasrc/view/easytier/other_dvalue.htm b/luci-app-easytier/luasrc/view/easytier/other_dvalue.htm deleted file mode 100644 index 296c61e4d..000000000 --- a/luci-app-easytier/luasrc/view/easytier/other_dvalue.htm +++ /dev/null @@ -1,8 +0,0 @@ -<%+cbi/valueheader%> - -<% - local val = self:cfgvalue(section) or self.default or "" - write(pcdata(val)) -%> - -<%+cbi/valuefooter%> diff --git a/luci-app-easytier/luasrc/view/easytier/other_upload.htm b/luci-app-easytier/luasrc/view/easytier/other_upload.htm deleted file mode 100644 index a112ae94d..000000000 --- a/luci-app-easytier/luasrc/view/easytier/other_upload.htm +++ /dev/null @@ -1,5 +0,0 @@ -<%+cbi/valueheader%> - - - -<%+cbi/valuefooter%> diff --git a/luci-app-easytier/po/templates/easytier.pot b/luci-app-easytier/po/templates/easytier.pot index 664ef8ef0..96f3b2a0a 100644 --- a/luci-app-easytier/po/templates/easytier.pot +++ b/luci-app-easytier/po/templates/easytier.pot @@ -72,6 +72,14 @@ msgstr "" msgid "Allow traffic from WAN to EasyTier virtual network" msgstr "" +#: applications/luci-app-easytier/luasrc/view/easytier/easytier_unified_log.htm:210 +msgid "Stop Auto Refresh" +msgstr "" + +#: applications/luci-app-easytier/luasrc/view/easytier/easytier_unified_log.htm:210 +msgid "Start Auto Refresh" +msgstr "" + #: applications/luci-app-easytier/luasrc/view/easytier/easytier_log.htm:30 #: applications/luci-app-easytier/luasrc/view/easytier/easytierweb_log.htm:30 msgid "Auto Refresh" @@ -1090,3 +1098,308 @@ msgstr "" msgid "If true, allow relay kcp packets from foreign network. default is false (not forward foreign network kcp packets). (--enable-relay-foreign-network-kcp parameter)" msgstr "" +msgid "Auto Configure Interface" +msgstr "" + +msgid "Automatically create and configure the EasyTier network interface" +msgstr "" + +msgid "Interface Netmask" +msgstr "" + +msgid "Subnet mask for the EasyTier interface (default: 255.0.0.0)" +msgstr "" + +msgid "Auto Configure Firewall" +msgstr "" + +msgid "Automatically add and manage firewall rules" +msgstr "" + +msgid "GitHub Proxy URLs" +msgstr "" + +msgid "Used to accelerate GitHub downloads when fetching binaries online" +msgstr "" + +msgid "Add" +msgstr "" + +msgid "Delete" +msgstr "" + +msgid "No proxy configured" +msgstr "" + +msgid "No proxy configured, using default proxy" +msgstr "" + +msgid "Please enter proxy URL" +msgstr "" + +msgid "Invalid URL format" +msgstr "" + +msgid "Proxy already exists" +msgstr "" + +msgid "Proxy added successfully" +msgstr "" + +msgid "Space-separated list of GitHub proxy URLs for downloading binaries. Leave empty to use default proxies." +msgstr "" + +msgid "Fallback Version" +msgstr "" + +msgid "Fallback version to use when unable to fetch the latest version from GitHub." +msgstr "" + +msgid "Logs" +msgstr "" + +msgid "EasyTier Core" +msgstr "" + +msgid "EasyTier Web" +msgstr "" + +msgid "All Levels" +msgstr "" + +msgid "Auto Refresh" +msgstr "" + +msgid "Stop Auto Refresh" +msgstr "" + +msgid "Start Auto Refresh" +msgstr "" + +msgid "Clear Logs" +msgstr "" + +msgid "Download Log" +msgstr "" + +msgid "Loading logs..." +msgstr "" + +msgid "No logs available" +msgstr "" + +msgid "Logs cleared" +msgstr "" + +msgid "Settings" +msgstr "" + +msgid "Running" +msgstr "" + +msgid "Stopped" +msgstr "" + +msgid "Memory" +msgstr "" + +msgid "Uptime" +msgstr "" + +msgid "Version" +msgstr "" + +msgid "Refresh Version" +msgstr "" + +msgid "Clear cached version and fetch latest version from GitHub?" +msgstr "" + +msgid "Cancel" +msgstr "" + +msgid "Confirm" +msgstr "" + +msgid "Web Console" +msgstr "" + +msgid "Service not running" +msgstr "" + +msgid "Collecting data..." +msgstr "" + +msgid "New" +msgstr "" + +msgid "Unknown" +msgstr "" + +msgid "Quick Actions" +msgstr "" + +msgid "Restart Service" +msgstr "" + +msgid "Restart EasyTier service?" +msgstr "" + +msgid "Please wait, operation in progress..." +msgstr "" + +msgid "Restarting service..." +msgstr "" + +msgid "Upload Program" +msgstr "" + +msgid "Upload EasyTier Binary" +msgstr "" + +msgid "Drag and drop file here or click to browse" +msgstr "" + +msgid "Select File" +msgstr "" + +msgid "Uploading..." +msgstr "" + +msgid "Supported Files" +msgstr "" + +msgid "Core service binary" +msgstr "" + +msgid "Command line tool" +msgstr "" + +msgid "Web console binary" +msgstr "" + +msgid "Embedded web console" +msgstr "" + +msgid "Download from" +msgstr "" + +msgid "Upload Successful" +msgstr "" + +msgid "Binary uploaded successfully. Restart the service to apply changes?" +msgstr "" + +msgid "Restart the service to apply changes?" +msgstr "" + +msgid "Later" +msgstr "" + +msgid "Restart Now" +msgstr "" + +msgid "Invalid file name" +msgstr "" + +msgid "Only easytier binaries or compressed archives (.zip, .tar.gz, .tar) are allowed" +msgstr "" + +msgid "Upload failed" +msgstr "" + +msgid "Network error" +msgstr "" + +msgid "Service restarted successfully" +msgstr "" + +msgid "Restart failed" +msgstr "" + +msgid "No changes to save" +msgstr "" + +msgid "Configuration" +msgstr "" + +msgid "Save Configuration" +msgstr "" + +msgid "Configuration saved successfully" +msgstr "" + +msgid "Save failed" +msgstr "" + +msgid "Recommended" +msgstr "" + +msgid "Will be ignored, use embed version instead" +msgstr "" + +msgid "Note" +msgstr "" + +msgid "Files will be uploaded to the paths specified above" +msgstr "" + +msgid "EasyTier console uses easytier-web-embed. The easytier-web binary will be rejected during upload validation." +msgstr "" + +msgid "Compressed archive containing binaries" +msgstr "" + +msgid "Drag *.tar.gz / *.zip / easytier binaries here or click to select file" +msgstr "" + +msgid "Used when unable to fetch the latest version during online download" +msgstr "" + +msgid "Error: Program not running! Please start the program and refresh" +msgstr "" + +msgid "Status" +msgstr "" + +msgid "Failed to connect to RPC server. Please check if the RPC port is set to 15888 in the configuration." +msgstr "" + +msgid "Self-hosted Web Console" +msgstr "" + +msgid "Enable Self-hosted Web Console" +msgstr "" + +msgid "Log Level" +msgstr "" + +msgid "Runtime log located at" +msgstr "" + +msgid "viewable in the log section" +msgstr "" + +msgid "Log levels" +msgstr "" + +msgid "parameter" +msgstr "" + +msgid "Example" +msgstr "" + +msgid "current device IP or domain" +msgstr "" + +msgid "API port" +msgstr "" + +msgid "GeoIP2 database file path used to locate the client" +msgstr "" + +msgid "Defaults to an embedded file (country-level information only)" +msgstr "" + +msgid "GEOIP Database Path" +msgstr "" diff --git a/luci-app-easytier/po/zh_Hans/easytier.po b/luci-app-easytier/po/zh_Hans/easytier.po index 279aec294..df8bae639 100644 --- a/luci-app-easytier/po/zh_Hans/easytier.po +++ b/luci-app-easytier/po/zh_Hans/easytier.po @@ -1,25 +1,3 @@ -#: applications/luci-app-easytier/luasrc/model/cbi/easytier.lua:648 -#: applications/luci-app-easytier/luasrc/model/cbi/easytier.lua:666 -msgid "" -"- Program /tmp/easytier-cli uploaded successfully, restart the plugin to " -"take effect" -msgstr "- 程序/tmp/easytier-cli上传成功,重启一次插件才生效" - -#: applications/luci-app-easytier/luasrc/model/cbi/easytier.lua:640 -#: applications/luci-app-easytier/luasrc/model/cbi/easytier.lua:658 -msgid "" -"- Program /tmp/easytier-core uploaded successfully, restart the plugin to " -"take effect" -msgstr "- 程序/tmp/easytier-core上传成功,重启一次插件才生效" - -#: applications/luci-app-easytier/luasrc/model/cbi/easytier.lua:654 -#: applications/luci-app-easytier/luasrc/model/cbi/easytier.lua:672 -msgid "" -"- Program /tmp/easytier-web uploaded successfully, restart the plugin to " -"take effect" -msgstr "- 程序/tmp/easytier-web上传成功,重启一次插件才生效" - -#: applications/luci-app-easytier/luasrc/model/cbi/easytier.lua:5 msgid "" "A simple, secure, decentralized VPN solution for intranet penetration, " "implemented in Rust using the Tokio framework. Project URL: " "默认值为 0,建议选 15888 防止无法获取状态信息 (-r 参数)" -#: applications/luci-app-easytier/luasrc/model/cbi/easytier.lua:25 -#: applications/luci-app-easytier/luasrc/model/cbi/easytier.lua:26 -#: applications/luci-app-easytier/luasrc/model/cbi/easytier.lua:694 -#: applications/luci-app-easytier/luasrc/model/cbi/easytier.lua:695 msgid "Restart" msgstr "重启" -#: applications/luci-app-easytier/luasrc/model/cbi/easytier.lua:288 -msgid "Route CIDR" -msgstr "路由CIDR" - -#: applications/luci-app-easytier/luasrc/model/cbi/easytier.lua:488 -msgid "Route Info" -msgstr "Route信息" - #: applications/luci-app-easytier/luasrc/model/cbi/easytier.lua:370 msgid "" "Runtime log is located at /tmp/easytier.log. View it in the log section " @@ -986,7 +905,7 @@ msgstr "easytier-web程序路径" #: applications/luci-app-easytier/luasrc/controller/easytier.lua:14 msgid "web log" -msgstr "web日志" +msgstr "控制台日志" #: applications/luci-app-easytier/luasrc/model/cbi/easytier.lua:264 msgid "zstd" @@ -1044,43 +963,28 @@ msgid "Extra Parameters" msgstr "额外参数" msgid "Additional command-line arguments passed to the backend process" -msgstr "传递给后端进程的额外命令行参数" +msgstr "运行easytier-core时额外增加的命令参数" msgid "ACL rules" msgstr "ACL 规则" -msgid "Click the button to refresh and view ACL rules information" -msgstr "点击按钮刷新,查看 ACL 规则统计信息" - -msgid "Mapped listener" -msgstr "Mapped listener信息" - -msgid "Click the button to refresh and view manage mapped listeners" -msgstr "点击按钮刷新,查看管理映射的监听器" - msgid "Encryption Algorithm" msgstr "加密算法" msgid "encryption algorithm to use, supported: xor, chacha20, aes-gcm, aes-256-gcm, openssl-aes-gcm, openssl-chacha20, openssl-aes-256-gcm. default (aes-gcm) (--encryption-algorithm parameter)" msgstr "使用的加密算法,支持:xor、chacha20、aes-gcm、aes-256-gcm、openssl-aes-gcm、openssl-chacha20、openssl-aes-256-gcm。默认(aes-gcm)(--encryption-algorithm 参数)" -msgid "Stats" -msgstr "Stats统计信息" - -msgid "Click the button to refresh and view statistics information" -msgstr "点击按钮刷新,查看统计信息" - msgid "WAN access to WEB" msgstr "外网连接WEB" msgid "Automatically add firewall rules to allow WAN access to this WEB console" -msgstr "自动添加防火墙端口放行规则,外网可连接此WEB控制台" +msgstr "自动添加防火墙端口放行规则,外网可通过服务端口连接此WEB控制台" msgid "WAN access to API" msgstr "外网访问API" msgid "Automatically add firewall rules to allow WAN access to the API control page" -msgstr "自动添加防火墙端口放行规则,外网可访问API控制页面" +msgstr "自动添加防火墙端口放行规则,外网可通过API端口访问API控制页面" msgid "P2P only" msgstr "仅P2P" @@ -1124,3 +1028,826 @@ msgstr "转发 KCP" msgid "If true, allow relay kcp packets from foreign network. default is false (not forward foreign network kcp packets). (--enable-relay-foreign-network-kcp parameter)" msgstr "如果开启,则作为共享节点时也可以转发其他网络的 KCP 数据包。默认关闭(不转发)( --enable-relay-foreign-network-kcp 参数)" +msgid "EasyTier Core" +msgstr "EasyTier 配置" + +msgid "EasyTier Web" +msgstr "自建控制台" + +msgid "All Levels" +msgstr "全部级别" + +msgid "Auto Refresh" +msgstr "自动刷新" + +msgid "Stop Auto Refresh" +msgstr "停止自动刷新" + +msgid "Start Auto Refresh" +msgstr "开启自动刷新" + +msgid "Clear Logs" +msgstr "清除日志" + +msgid "Download Log" +msgstr "下载日志" + +msgid "Loading logs..." +msgstr "加载日志中..." + +msgid "No logs available" +msgstr "暂无日志" + +msgid "Logs cleared" +msgstr "日志已清除" + +msgid "Settings" +msgstr "设置" + +msgid "Running" +msgstr "运行中" + +msgid "Stopped" +msgstr "已停止" + +msgid "Memory" +msgstr "内存" + +msgid "Uptime" +msgstr "运行时长" + +msgid "Version" +msgstr "版本" + +msgid "Refresh Version" +msgstr "刷新版本" + +msgid "Clear cached version and fetch latest version from GitHub?" +msgstr "清除缓存版本信息以重新获取版本号信息?" + +msgid "Cancel" +msgstr "取消" + +msgid "Confirm" +msgstr "确认" + +msgid "Web Console" +msgstr "Web 控制台主页" + +msgid "Service not running" +msgstr "服务未运行" + +msgid "Collecting data..." +msgstr "收集数据..." + +msgid "New" +msgstr "发现新版本" + +msgid "Unknown" +msgstr "未知" + +msgid "Quick Actions" +msgstr "快捷操作" + +msgid "Restart Service" +msgstr "重启服务" + +msgid "Restart EasyTier service?" +msgstr "确认重启 EasyTier 服务?" + +msgid "Please wait, operation in progress..." +msgstr "请稍候,操作进行中..." + +msgid "Restarting service..." +msgstr "正在重启服务..." + +msgid "Upload Program" +msgstr "上传程序" + +msgid "Upload EasyTier Binary" +msgstr "上传 EasyTier 程序" + +msgid "Drag and drop file here or click to browse" +msgstr "拖放文件到此处或点击浏览" + +msgid "Select File" +msgstr "选择文件" + +msgid "Uploading..." +msgstr "上传中..." + +msgid "Supported Files" +msgstr "支持的文件" + +msgid "Core service binary" +msgstr "核心服务程序" + +msgid "Command line tool" +msgstr "连接信息获取工具" + +msgid "Web console binary" +msgstr "Web 控制台程序" + +msgid "Embedded web console" +msgstr "内嵌 Web 的控制台" + +msgid "Download from" +msgstr "程序下载地址" + +msgid "Upload Successful" +msgstr "上传成功" + +msgid "Binary uploaded successfully. Restart the service to apply changes?" +msgstr "程序上传成功,是否立即重启服务以使用新版本?" + +msgid "Restart the service to apply changes?" +msgstr "是否立即重启服务以使用新版本?" + +msgid "Later" +msgstr "稍后" + +msgid "Restart Now" +msgstr "立即重启" + +msgid "Invalid file name" +msgstr "无效的文件名" + +msgid "Only easytier binaries or compressed archives (.zip, .tar.gz, .tar) are allowed" +msgstr "仅允许上传 easytier 相关程序文件或压缩包(.zip、.tar.gz、.tar)" + +msgid "Upload failed" +msgstr "上传失败" + +msgid "Network error" +msgstr "网络错误" + +msgid "Service restarted successfully" +msgstr "服务重启成功" + +msgid "Restart failed" +msgstr "重启失败" + +msgid "No changes to save" +msgstr "没有需要保存的更改" + +msgid "Configuration" +msgstr "配置" + +msgid "Save Configuration" +msgstr "保存并应用" + +msgid "Configuration saved successfully" +msgstr "配置保存成功" + +msgid "Save failed" +msgstr "保存失败" + +msgid "Recommended" +msgstr "推荐" + +msgid "Will be ignored, use embed version instead" +msgstr "由于未内嵌WEB静态页面此程序将被忽略,请上传使用内嵌版本" + +msgid "Note" +msgstr "注意" + +msgid "Files will be uploaded to the paths specified above" +msgstr "程序文件将上传到上方指定的程序路径" + +msgid "EasyTier console uses easytier-web-embed. The easytier-web binary will be rejected during upload validation." +msgstr "EasyTier 自建控制台使用 easytier-web-embed 上传成功后会更名为easytier-web使用,上传的 easytier-web 程序将在验证时被忽略" + +msgid "Compressed archive containing binaries" +msgstr "包含EasyTier相关程序的压缩包" + +msgid "Drag *.tar.gz / *.zip / easytier binaries here or click to select file" +msgstr "支持拖放 *.tar.gz / *.zip 压缩包和 easytier 二进制程序到此处,或点击选择文件" + +msgid "Used when unable to fetch the latest version during online download" +msgstr "在线下载时无法获取最新版本时使用的回退版本" + +msgid "Error: Program not running! Please start the program and refresh" +msgstr "错误:程序未运行!请先启动程序后刷新" + +msgid "Status" +msgstr "状态" + +msgid "Failed to connect to RPC server. Please check if the RPC port is set to 15888 in the configuration." +msgstr "无法连接到 RPC 服务器,请检查配置中 RPC 端口是否设置为 15888" + +msgid "Self-hosted Web Console" +msgstr "自建 Web 控制台" + +msgid "Enable Self-hosted Web Console" +msgstr "启用EasyTier-web控制台" + +msgid "Log Level" +msgstr "日志级别" + +msgid "Runtime log located at" +msgstr "运行日志位于" + +msgid "viewable in the log section" +msgstr "可在上方日志页面查看" + +msgid "Log levels" +msgstr "日志详细程度" + +msgid "parameter" +msgstr "参数" + +msgid "Example" +msgstr "示例" + +msgid "current device IP or domain" +msgstr "当前设备IP或解析的域名" + +msgid "API port" +msgstr "API端口" + +msgid "GeoIP2 database file path used to locate the client" +msgstr "GeoIP2 数据库文件路径,用于查找客户端所在位置" + +msgid "Defaults to an embedded file (country-level information only)" +msgstr "默认使用内嵌文件(仅包含国家级别信息)" + +msgid "GEOIP Database Path" +msgstr "GeoIP 数据库路径" + +msgid "Connection Information" +msgstr "连接信息" + +msgid "Node Info" +msgstr "本机信息" + +msgid "Peer List" +msgstr "节点列表" + +msgid "Route Info" +msgstr "路由信息" + +msgid "STUN" +msgstr "STUN信息" + +msgid "Peer Center" +msgstr "节点中心" + +msgid "VPN Portal" +msgstr "Wireguard管理" + +msgid "Proxy" +msgstr "代理信息" + +msgid "ACL" +msgstr "ACL规则" + +msgid "Mapped Listener" +msgstr "映射监听" + +msgid "Statistics" +msgstr "统计数据" + +msgid "Command Line" +msgstr "启动参数" + +msgid "IPv4 Address" +msgstr "IPv4地址" + +msgid "Route Cost" +msgstr "路由" + +msgid "Latency(ms)" +msgstr "延迟(ms)" + +msgid "Loss Rate" +msgstr "丢包率" + +msgid "RX Traffic" +msgstr "下载" + +msgid "TX Traffic" +msgstr "上传" + +msgid "Tunnel Protocol" +msgstr "协议" + +msgid "NAT Type" +msgstr "NAT类型" + +msgid "ERROR: Wireguard VPN Portal Not Started" +msgstr "错误:WireGuard VPN 门户未启动" + +msgid "Refresh" +msgstr "立即刷新" + +msgid "EasyTier Status" +msgstr "EasyTier 状态总览" + +msgid "Virtual IP" +msgstr "虚拟IP" + +msgid "Proxy CIDRs" +msgstr "代理网段" + +msgid "Peer ID" +msgstr "节点ID" + +msgid "Public IPv4" +msgstr "公网IPv4" + +msgid "Public IPv6" +msgstr "公网IPv6" + +msgid "Listener" +msgstr "监听器" + +msgid "Next Hop IPv4" +msgstr "下一跳IPv4" + +msgid "Interface IPv4" +msgstr "接口IPv4" + +msgid "Interface IPv6" +msgstr "接口IPv6" + +msgid "UDP Stun Type" +msgstr "UDP NAT类型" + +msgid "Port Restricted" +msgstr "端口受限型" + +msgid "No PAT" +msgstr "无端口映射" + +msgid "Direct" +msgstr "直连" + +msgid "Connected" +msgstr "已连接" + +msgid "Connecting" +msgstr "连接中" + +msgid "Disconnected" +msgstr "已断开连接" + +msgid "Next Hop Hostname" +msgstr "下一跳主机名" + +msgid "Next Hop Latency" +msgstr "下一跳延迟" + +msgid "Path Length" +msgstr "路径长度" + +msgid "Path Latency" +msgstr "路径延迟" + +msgid "Next Hop IPv4 Lat First" +msgstr "下一跳 IPv4(延迟优先)" + +msgid "Path Length Lat First" +msgstr "路径长度(延迟优先)" + +msgid "Path Latency Lat First" +msgstr "路径延迟(延迟优先)" + +msgid "Source" +msgstr "源地址" + +msgid "Destination" +msgstr "目标地址" + +msgid "Start Time" +msgstr "开始时间" + +msgid "State" +msgstr "状态" + +msgid "Transport Type" +msgstr "传输协议" + +msgid "Last Update Time" +msgstr "最后更新时间" + +msgid "Node ID" +msgstr "节点ID" + +msgid "Direct Peers" +msgstr "直连节点" + +msgid "Metric Name" +msgstr "指标名称" + +msgid "Value" +msgstr "值" + +msgid "Labels" +msgstr "标签" + +msgid "Listener" +msgstr "监听器" + +msgid "Client Config Start" +msgstr "客户端配置开始" + +msgid "Client Config End" +msgstr "客户端配置结束" + +msgid "Local" +msgstr "本机" + +msgid "Symmetric" +msgstr "对称型" + +msgid "Restricted" +msgstr "受限型" + +msgid "Full Cone" +msgstr "全锥型" + +msgid "Address Restricted" +msgstr "地址受限型" + +msgid "P2P" +msgstr "P2P" + +msgid "Server" +msgstr "服务器" + +msgid "UDP NAT Type" +msgstr "UDP NAT 类型" + +msgid "TCP NAT Type" +msgstr "TCP NAT 类型" + +msgid "Invalid Service Name" +msgstr "无效的服务名称" + +msgid "Protocol Name" +msgstr "协议名称" + +msgid "Next Hop Hostname Lat First" +msgstr "下一跳主机名(延迟优先)" + +msgid "Response" +msgstr "响应" + +msgid "List Connector Response" +msgstr "连接器列表响应" + +msgid "Connectors" +msgstr "连接器" + +msgid "Connector" +msgstr "连接器" + +msgid "URL" +msgstr "地址" + +msgid "Public IP" +msgstr "公网IP" + +msgid "Min Port" +msgstr "最小端口" + +msgid "Max Port" +msgstr "最大端口" + +msgid "Portal Name" +msgstr "门户名称" + +msgid "WireGuard" +msgstr "WireGuard" + +msgid "Connected Clients" +msgstr "已连接客户端" + +msgid "ACL Stats" +msgstr "ACL 统计数据" + +msgid "Global" +msgstr "全局" + +msgid "Cache Max Size" +msgstr "缓存最大大小" + +msgid "Cache Size" +msgstr "缓存大小" + +msgid "Connection Track" +msgstr "连接追踪" + +msgid "Rules" +msgstr "规则" + +msgid "List Mapped Listener Response" +msgstr "列出映射监听器响应" + +msgid "Compression RX Before" +msgstr "接收前压缩" + +msgid "Compression RX After" +msgstr "接收后压缩" + +msgid "Compression TX Before" +msgstr "发送前压缩" + +msgid "Compression TX After" +msgstr "发送后压缩" + +msgid "Peer RPC Client RX" +msgstr "节点 RPC 客户端接收流量" + +msgid "Peer RPC Client TX" +msgstr "节点 RPC 客户端发送流量" + +msgid "Peer RPC Server RX" +msgstr "节点 RPC 服务端接收流量" + +msgid "Peer RPC Server TX" +msgstr "节点 RPC 服务端发送流量" + +msgid "Peer RPC Duration" +msgstr "节点 RPC 持续时间" + +msgid "Traffic Bytes RX" +msgstr "接收流量字节" + +msgid "Traffic Bytes TX" +msgstr "发送流量字节" + +msgid "Traffic Bytes Self RX" +msgstr "本机接收流量字节" + +msgid "Traffic Bytes Self TX" +msgstr "本机发送流量字节" + +msgid "Traffic Packets RX" +msgstr "接收数据包数" + +msgid "Traffic Packets TX" +msgstr "发送数据包数" + +msgid "Traffic Packets Self RX" +msgstr "本机接收数据包数" + +msgid "Traffic Packets Self TX" +msgstr "本机发送数据包数" + +msgid "Traffic Packets Forwarded" +msgstr "转发数据包数" + +msgid "Traffic Bytes Forwarded" +msgstr "转发流量字节" + +msgid "Destination Peer ID" +msgstr "目标节点ID" + +msgid "Source Peer ID" +msgstr "源节点ID" + +msgid "Method Name" +msgstr "方法名" + +msgid "Service Name" +msgstr "服务名" + +msgid "Success" +msgstr "成功" + +msgid "Failure" +msgstr "失败" + +msgid "Timeout" +msgstr "超时" + +msgid "Sync Route Info" +msgstr "同步路由信息" + +msgid "Get Global Peer Map" +msgstr "获取全局节点映射表" + +msgid "Report Peers" +msgstr "上报节点信息" + +msgid "OSPF Route RPC" +msgstr "OSPF路由RPC" + +msgid "Peer Center RPC" +msgstr "节点中心RPC" + +msgid "Caused by" +msgstr "由以下原因引起:" + +msgid "failed to get peer manager client" +msgstr "无法获取节点管理客户端" + +msgid "failed to get peer center client" +msgstr "无法获取节点中心客户端" + +msgid "failed to connect to server" +msgstr "无法连接到服务器" + +msgid "Connection refused" +msgstr "连接被拒绝" + +msgid "scheme" +msgstr "方式" + +msgid "cannot_be_a_base" +msgstr "不能作为基础节点" + +msgid "username" +msgstr "用户名" + +msgid "password" +msgstr "密码" + +msgid "host" +msgstr "主机地址" + +msgid "port" +msgstr "端口" + +msgid "path" +msgstr "路径" + +msgid "query" +msgstr "查询" + +msgid "fragment" +msgstr "片段" + +msgid "Some" +msgstr "有" + +msgid "None" +msgstr "无" + +msgid "Domain" +msgstr "域名" + +msgid "Failed to connect to RPC server. Please check if the RPC port is set to 15888 in the configuration." +msgstr "无法连接到 RPC 服务器,请检查配置中的 RPC 端口是否设置为 15888" + +msgid "Configuration File Content" +msgstr "配置文件内容" + +msgid "No data available" +msgstr "暂无数据" + +msgid "Peer Center service not available. This feature requires multiple nodes in the network." +msgstr "节点中心服务不可用,此功能要求网络中包含多个节点。" + +msgid "Refreshing..." +msgstr "正在刷新..." + +msgid "Failed to parse response:" +msgstr "解析响应失败:" + +msgid "GitHub Proxy URLs" +msgstr "GitHub 加速镜像地址" + +msgid "Add" +msgstr "添加" + +msgid "Used to accelerate GitHub downloads when fetching binaries online" +msgstr "用于从GitHub在线下载EasyTier程序使用镜像加速GitHub" + +msgid "Fallback Version" +msgstr "备用版本" + +msgid "Used when unable to fetch the latest version during online download" +msgstr "用于无法获取GitHub最新版本时在线下载使用的版本" + +msgid "Save Configuration" +msgstr "保存并应用" + +msgid "No proxy configured, using default proxy" +msgstr "未配置加速镜像,将使用脚本内默认地址,可能会失效" + +msgid "Delete" +msgstr "删除" + +msgid "Please enter proxy URL" +msgstr "请输入一个加速镜像地址!" + +msgid "Invalid URL format" +msgstr "地址格式不正确!" + +msgid "Proxy already exists" +msgstr "镜像地址已存在!" + +msgid "The URL of the API server, used for connecting the web frontend" +msgstr "API 服务器的 URL,用于 web 前端连接" + +msgid "Peer Nodes" +msgstr "节点/服务器" + +msgid "Route CIDR" +msgstr "路由CIDR" + +msgid "Auto Configure Interface" +msgstr "自动配置接口" + +msgid "Automatically create and configure the EasyTier network interface" +msgstr "自动创建并配置 EasyTier 网络接口" + +msgid "Interface Netmask" +msgstr "接口子网掩码" + +msgid "Subnet mask for the EasyTier interface (default: 255.0.0.0)" +msgstr "EasyTier 接口的子网掩码(默认值:255.0.0.0)" + +msgid "Auto Configure Firewall" +msgstr "自动配置防火墙" + +msgid "Automatically add and manage firewall rules" +msgstr "自动添加和管理防火墙规则" + +msgid "Invalid JSON data" +msgstr "无效的 JSON 数据" + +msgid "No file uploaded" +msgstr "未上传文件" + +msgid "binary file(s)" +msgstr "个二进制程序" + +msgid "Failed to move file. Insufficient space or permission denied" +msgstr "移动文件失败。空间不足或权限不足。" + +msgid "Binary uploaded successfully to" +msgstr "二进制文件已成功上传至" + + +msgid "If the device has insufficient storage space, the upload may fail and existing programs may be deleted. Please ensure adequate free space before uploading." +msgstr "如果当前设备内部可用空间不足时,可能无法成功处理上传的程序并导致现有的程序被清除,请确保有足够的可用空间后再上传" + +msgid "Available space" +msgstr "当前路径可用空间" + +msgid "Unable to query disk space" +msgstr "无法查询此路径磁盘空间" + +msgid "Program size" +msgstr "程序大小" + +msgid "Virtual Network Interface" +msgstr "虚拟网卡接口" + +msgid "Real-time Traffic" +msgstr "实时流量" + +msgid "Download" +msgstr "下载" + +msgid "Upload" +msgstr "上传" + +msgid "Total Download" +msgstr "总下载量" + +msgid "Total Upload" +msgstr "总上传量" + +msgid "Address" +msgstr "地址" + +msgid "Contributors" +msgstr "贡献者" + +msgid "Traffic Control Bytes RX" +msgstr "流量控制接收字节数" + +msgid "Traffic Control Bytes TX" +msgstr "流量控制发送字节数" + +msgid "Traffic Control Bytes RX By Instance" +msgstr "按实例统计接收字节数" + +msgid "Traffic Control Bytes TX By Instance" +msgstr "按实例统计发送字节数" + +msgid "Traffic Control Packets RX" +msgstr "流量控制接收数据包" + +msgid "Traffic Control Packets TX" +msgstr "流量控制发送数据包" + +msgid "Traffic Control Packets RX By Instance" +msgstr "按实例统计接收数据包" + +msgid "Traffic Control Packets TX By Instance" +msgstr "按实例统计发送数据包" + +msgid "From Instance ID" +msgstr "来源实例ID" + +msgid "To Instance ID" +msgstr "目标实例ID" + +msgid "Logs" +msgstr "日志" + diff --git a/luci-app-easytier/root/etc/init.d/easytier b/luci-app-easytier/root/etc/init.d/easytier index 4b22129ed..a9df6c354 100755 --- a/luci-app-easytier/root/etc/init.d/easytier +++ b/luci-app-easytier/root/etc/init.d/easytier @@ -72,15 +72,27 @@ get_tz() { fi check_bin() { + # 优先使用 UCI 配置的代理列表(list 类型),否则使用默认值 + local proxys="" + local proxy_list=$(uci -q get easytier.@easytier[0].github_proxys) + + # 判断是否有多个代理 + if [ ! -z "$proxy_list" ]; then + if [[ "$(grep "list github_proxys" /etc/config/easytier | awk '{print $3}' | wc -l)" -eq 1 ]]; then + proxys="$proxy_list" + else + proxys=$(cat /etc/config/easytier | grep 'list github_proxys' | awk -F 'list github_proxys' '{print $2}' | sed "s/'/\n/g" | tr -d " ' ") + fi + fi + + # 如果没有配置代理,使用默认值 + if [ -z "$proxys" ]; then + proxys="https://ghproxy.net/ https://gh-proxy.com/ https://cdn.gh-proxy.com/ https://ghfast.top/" + fi + curltest=`which curl` user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36' - #github加速地址,一行一个 你可以自建改为你自己的 - proxys=" - https://ghproxy.net/ - https://gh-proxy.com/ - https://cdn.gh-proxy.com/ - https://ghfast.top/ - " + if [ -z "$curltest" ] || [ ! -s "`which curl`" ] ; then tag="$( wget --no-check-certificate -T 5 -t 3 --user-agent "$user_agent" --max-redirect=0 --output-document=- https://api.github.com/repos/EasyTier/EasyTier/releases/latest 2>&1 | grep 'tag_name' | cut -d\" -f4 )" [ -z "$tag" ] && tag="$( wget --no-check-certificate -T 5 -t 3 --user-agent "$user_agent" --quiet --output-document=- https://api.github.com/repos/EasyTier/EasyTier/releases/latest 2>&1 | grep 'tag_name' | cut -d\" -f4 )" @@ -396,25 +408,7 @@ start_et() { etcmd="$(uci -q get easytier.@easytier[0].etcmd)" echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : easytier-core_${cpucore}开始启动" >>/tmp/easytier.log path=$(dirname "$easytierbin") - if [[ -f /tmp/easytier-core || -f /tmp/easytier-cli ]] && [[ "${path:0:4}" != "/tmp" ]]; then - chmod +x /tmp/easytier-core 2>/dev/null - chmod +x /tmp/easytier-cli 2>/dev/null - mkdir -p "$path" - echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 找到上传的程序/tmp/easytier-core,替换为$easytierbin " >>/tmp/easytier.log - upsize="$(du -k /tmp/easytier-core | cut -f1)" - result=$(expr $size - $upsize) - [ -z "$size"] && echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 获取可用空间失败,请使用ssh手动上传至 ${easytierbin} ${path}/easytier-cli" >>/tmp/easytier.log - if [ "$(($(/tmp/easytier-core -h 2>&1 | wc -l)))" -gt 3 ] && [ "$result" -gt 1000 ] ; then - mv -f /tmp/easytier-core "$easytierbin" 2>/dev/null - mv -f /tmp/easytier-cli "${path}/easytier-cli" 2>/dev/null - else - if [ -z "$size" ] && [ "$(($(/tmp/easytier-core -h 2>&1 | wc -l)))" -gt 3 ] ; then - mv -f /tmp/easytier-core "$easytierbin" 2>/dev/null - mv -f /tmp/easytier-cli "${path}/easytier-cli" 2>/dev/null - fi - echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 无法替换,上传的程序不完整或自定义路径的可用空间不足,当前空间剩余${size}kb" >>/tmp/easytier.log - fi - fi + if [ ! -f "$easytierbin" ] && [ "$size" -lt 5000 ] && [ ! -z "$size" ] ; then echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 自定义程序路径的可用空间不足,当前可用空间剩余${size}kb,自动切换为内存/tmp/easytier-core" >>/tmp/easytier.log sed -i "/easytierbin/c option easytierbin '/tmp/easytier-core' " /etc/config/easytier @@ -761,17 +755,28 @@ start_service() { size="$(df -k | awk '/\/overlay$/ {sub(/K$/, "", $4); print $4}')" [ -z "$size" ] && size="$(df -kP /usr/bin | awk 'NR==2 {print $(NF-2) }')" if [ -z "$(uci -q get easytier.@easytier[0].web_enabled)" ] ; then - # Migrate old config if needed or just init - # For now just set default 0 if not present uci -q set easytier.@easytier[0].web_enabled='0' uci commit easytier fi [ "$(uci -q get easytier.@easytier[0].web_enabled)" = "1" ] && start_web [ "$(uci -q get easytier.@easytier[0].enabled)" = "1" ] && start_et easytier - echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 重载防火墙和网络配置...会出现短暂断网现象... " >>/tmp/easytier.log - echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 重载防火墙和网络配置...会出现短暂断网现象... " >>/tmp/easytierweb.log - [ -n "$(uci changes network)" ] && uci commit network && /etc/init.d/network reload >/dev/null 2>&1 - [ -n "$(uci changes firewall)" ] && uci commit firewall && /etc/init.d/firewall reload >/dev/null 2>&1 + + # 延迟重载网络配置,避免与拨号等网络事件冲突 + if [ -n "$(uci changes network)" ] || [ -n "$(uci changes firewall)" ]; then + echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 检测到配置变更,将在5秒后后台重载... " >>/tmp/easytier.log + ( + sleep 5 + # 使用锁文件防止重复重载 + LOCK_FILE="/var/lock/easytier_reload.lock" + if [ ! -f "$LOCK_FILE" ]; then + touch "$LOCK_FILE" + [ -n "$(uci changes network)" ] && uci commit network && /etc/init.d/network reload >/dev/null 2>&1 + [ -n "$(uci changes firewall)" ] && uci commit firewall && /etc/init.d/firewall reload >/dev/null 2>&1 + echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 网络配置重载完成 " >>/tmp/easytier.log + rm -f "$LOCK_FILE" + fi + ) & + fi } @@ -796,8 +801,22 @@ stop_service() { uci -q delete firewall.easytier_quic >/dev/null 2>&1 uci -q delete firewall.easytier_wireguard >/dev/null 2>&1 uci -q delete firewall.easytier_socks5 >/dev/null 2>&1 - [ -n "$(uci changes network)" ] && uci commit network && /etc/init.d/network reload >/dev/null 2>&1 - [ -n "$(uci changes firewall)" ] && uci commit firewall && /etc/init.d/firewall reload >/dev/null 2>&1 + + # 延迟重载,避免与网络事件冲突 + if [ -n "$(uci changes network)" ] || [ -n "$(uci changes firewall)" ]; then + echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 停止服务,将在5秒后后台重载配置... " >>/tmp/easytier.log + ( + sleep 5 + LOCK_FILE="/var/lock/easytier_reload.lock" + if [ ! -f "$LOCK_FILE" ]; then + touch "$LOCK_FILE" + [ -n "$(uci changes network)" ] && uci commit network && /etc/init.d/network reload >/dev/null 2>&1 + [ -n "$(uci changes firewall)" ] && uci commit firewall && /etc/init.d/firewall reload >/dev/null 2>&1 + rm -f "$LOCK_FILE" + fi + ) & + fi + rm -rf /tmp/easytier-cli_peer /tmp/easytier-cli_connector /tmp/easytier-cli_stun /tmp/easytier-cli_route /tmp/easytier-cli_acl >/dev/null 2>&1 rm -rf /tmp/easytier-cli_peer-center /tmp/easytier-cli_vpn-portal /tmp/easytier_cmd /tmp/easytier-cli_node /tmp/easytier-cli_mapped_listener >/dev/null 2>&1 rm -rf /tmp/easytier-*.* /tmp/easytier.log >/dev/null 2>&1 @@ -820,6 +839,6 @@ reload_service() { service_triggers() { procd_add_reload_trigger "easytier" #如果WAN网络接口上线则触发重新启动easytier - procd_add_interface_trigger "interface.*.up" wan /etc/init.d/easytier reload + # procd_add_interface_trigger "interface.*.up" wan /etc/init.d/easytier reload } diff --git a/luci-app-easytier/root/usr/share/easytier/firewall.sh b/luci-app-easytier/root/usr/share/easytier/firewall.sh index 8d3fe3955..3de8bc36d 100755 --- a/luci-app-easytier/root/usr/share/easytier/firewall.sh +++ b/luci-app-easytier/root/usr/share/easytier/firewall.sh @@ -187,8 +187,18 @@ setup_web_firewall() { fi } -# 应用防火墙和网络配置更改 +# 应用防火墙和网络配置更改(延迟后台执行) apply_network_changes() { - [ -n "$(uci changes network)" ] && uci commit network && /etc/init.d/network reload >/dev/null 2>&1 - [ -n "$(uci changes firewall)" ] && uci commit firewall && /etc/init.d/firewall reload >/dev/null 2>&1 + if [ -n "$(uci changes network)" ] || [ -n "$(uci changes firewall)" ]; then + ( + sleep 5 + LOCK_FILE="/var/lock/easytier_reload.lock" + if [ ! -f "$LOCK_FILE" ]; then + touch "$LOCK_FILE" + [ -n "$(uci changes network)" ] && uci commit network && /etc/init.d/network reload >/dev/null 2>&1 + [ -n "$(uci changes firewall)" ] && uci commit firewall && /etc/init.d/firewall reload >/dev/null 2>&1 + rm -f "$LOCK_FILE" + fi + ) & + fi } diff --git a/luci-app-easytier/root/usr/share/rpcd/acl.d/luci-app-easytier.json b/luci-app-easytier/root/usr/share/rpcd/acl.d/luci-app-easytier.json index d65f1cf17..508bf9ec1 100644 --- a/luci-app-easytier/root/usr/share/rpcd/acl.d/luci-app-easytier.json +++ b/luci-app-easytier/root/usr/share/rpcd/acl.d/luci-app-easytier.json @@ -2,7 +2,8 @@ "luci-app-easytier": { "description": "Grant UCI access for luci-app-easytier", "read": { - "uci": [ "easytier" ] + "uci": [ "easytier" ], + "cgi-io": [ "upload" ] }, "write": { "uci": [ "easytier" ] diff --git a/luci-app-passwall/Makefile b/luci-app-passwall/Makefile index 8d7ca509f..c5d3119ff 100644 --- a/luci-app-passwall/Makefile +++ b/luci-app-passwall/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-passwall PKG_VERSION:=26.4.15 -PKG_RELEASE:=73 +PKG_RELEASE:=74 PKG_PO_VERSION:=$(PKG_VERSION) PKG_CONFIG_DEPENDS:= \ diff --git a/luci-app-passwall2/Makefile b/luci-app-passwall2/Makefile index 38e687115..db58cde83 100644 --- a/luci-app-passwall2/Makefile +++ b/luci-app-passwall2/Makefile @@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-passwall2 PKG_VERSION:=26.4.10 -PKG_RELEASE:=29 +PKG_RELEASE:=30 PKG_PO_VERSION:=$(PKG_VERSION) PKG_CONFIG_DEPENDS:= \