update 2026-01-19 14:27:35

This commit is contained in:
kenzok8
2026-01-19 14:27:35 +08:00
parent 1921f97204
commit a2898dfd72
12 changed files with 559 additions and 51 deletions

View File

@@ -1,7 +1,8 @@
include $(TOPDIR)/rules.mk
-include $(dir $(lastword $(MAKEFILE_LIST)))../version.mk
PKG_NAME:=easytier
PKG_VERSION:=2.5.0
PKG_VERSION:=$(or $(EASYTIER_VERSION),2.5.0)
ifeq ($(ARCH),mipsel)
APP_ARCH:=mipsel

View File

@@ -1,7 +1,8 @@
include $(TOPDIR)/rules.mk
-include $(dir $(lastword $(MAKEFILE_LIST)))../version.mk
PKG_NAME:=easytier
PKG_VERSION:=2.5.0
PKG_VERSION:=$(or $(EASYTIER_VERSION),2.5.0)
ifeq ($(ARCH),mipsel)
APP_ARCH:=mipsel

View File

@@ -5,8 +5,9 @@
#
include $(TOPDIR)/rules.mk
-include $(dir $(lastword $(MAKEFILE_LIST)))../version.mk
PKG_VERSION:=2.5.0
PKG_VERSION:=$(or $(EASYTIER_VERSION),2.5.0)
PKG_RELEASE:=2
LUCI_TITLE:=LuCI support for EasyTier
@@ -16,6 +17,7 @@ LUCI_PKGARCH:=all
PKG_NAME:=luci-app-easytier
define Package/$(PKG_NAME)/conffiles
/etc/config/easytier
/etc/easytier/
endef

View File

@@ -1,6 +1,46 @@
module("luci.controller.easytier", package.seeall)
-- 安全执行命令并返回结果
local function safe_exec(cmd)
local handle = io.popen(cmd)
if not handle then return "" end
local result = handle:read("*all") or ""
handle:close()
return result:gsub("[\r\n]+$", "")
end
-- 安全读取文件内容
local function safe_read_file(path)
local file = io.open(path, "r")
if not file then return nil end
local content = file:read("*all")
file:close()
return content
end
-- 计算运行时长
local function calc_uptime(start_time_file)
local content = safe_read_file(start_time_file)
if not content or content == "" then return "" end
local start_time = tonumber(content:match("%d+"))
if not start_time then return "" end
local now = os.time()
local elapsed = now - start_time
local days = math.floor(elapsed / 86400)
local hours = math.floor((elapsed % 86400) / 3600)
local mins = math.floor((elapsed % 3600) / 60)
local secs = elapsed % 60
local result = ""
if days > 0 then result = days .. "" end
result = result .. string.format("%02d小时%02d分%02d秒", hours, mins, secs)
return result
end
function index()
if not nixio.fs.access("/etc/config/easytier") then
return
@@ -27,62 +67,55 @@ function act_status()
e.wrunning = luci.sys.call("pgrep easytier-web >/dev/null") == 0
e.port = (port or 0)
local tagfile = io.open("/tmp/easytier_time", "r")
if tagfile then
local tagcontent = tagfile:read("*all")
tagfile:close()
if tagcontent and tagcontent ~= "" then
os.execute("start_time=$(cat /tmp/easytier_time) && time=$(($(date +%s)-start_time)) && day=$((time/86400)) && [ $day -eq 0 ] && day='' || day=${day}天 && time=$(date -u -d @${time} +'%H小时%M分%S秒') && echo $day $time > /tmp/command_easytier 2>&1")
local command_output_file = io.open("/tmp/command_easytier", "r")
if command_output_file then
e.etsta = command_output_file:read("*all")
command_output_file:close()
end
end
end
-- 使用 Lua 原生计算运行时长
e.etsta = calc_uptime("/tmp/easytier_time")
e.etwebsta = calc_uptime("/tmp/easytierweb_time")
local command2 = io.popen('test ! -z "`pidof easytier-core`" && (top -b -n1 | grep -E "$(pidof easytier-core)" 2>/dev/null | grep -v grep | awk \'{for (i=1;i<=NF;i++) {if ($i ~ /easytier-core/) break; else cpu=i}} END {print $cpu}\')')
-- 获取 CPU 和内存使用率(使用原始命令)
local command2 = io.popen('test ! -z "`pidof easytier-core`" && (top -b -n1 | grep -E "$(pidof easytier-core)" 2>/dev/null | grep -v grep | awk \'{for (i=1;i<=NF;i++) {if ($i ~ /easytier-core/) break; else cpu=i}} END {print $cpu}\')')
e.etcpu = command2:read("*all")
command2:close()
local command3 = io.popen("test ! -z `pidof easytier-core` && (cat /proc/$(pidof easytier-core | awk '{print $NF}')/status | grep -w VmRSS | awk '{printf \"%.2f MB\", $2/1024}')")
local command3 = io.popen("test ! -z `pidof easytier-core` && (cat /proc/$(pidof easytier-core | awk '{print $NF}')/status | grep -w VmRSS | awk '{printf \"%.2f MB\", $2/1024}')")
e.etram = command3:read("*all")
command3:close()
local wtagfile = io.open("/tmp/easytierweb_time", "r")
if wtagfile then
local wtagcontent = wtagfile:read("*all")
wtagfile:close()
if wtagcontent and wtagcontent ~= "" then
os.execute("start_time=$(cat /tmp/easytierweb_time) && time=$(($(date +%s)-start_time)) && day=$((time/86400)) && [ $day -eq 0 ] && day='' || day=${day}天 && time=$(date -u -d @${time} +'%H小时%M分%S秒') && echo $day $time > /tmp/command_easytierweb 2>&1")
local wcommand_output_file = io.open("/tmp/command_easytierweb", "r")
if wcommand_output_file then
e.etwebsta = wcommand_output_file:read("*all")
wcommand_output_file:close()
end
end
end
local command4 = io.popen('test ! -z "`pidof easytier-web`" && (top -b -n1 | grep -E "$(pidof easytier-web)" 2>/dev/null | grep -v grep | awk \'{for (i=1;i<=NF;i++) {if ($i ~ /easytier-web/) break; else cpu=i}} END {print $cpu}\')')
e.etwebcpu = command4:read("*all")
command4:close()
local command5 = io.popen("test ! -z `pidof easytier-web` && (cat /proc/$(pidof easytier-web | awk '{print $NF}')/status | grep -w VmRSS | awk '{printf \"%.2f MB\", $2/1024}')")
local command5 = io.popen("test ! -z `pidof easytier-web` && (cat /proc/$(pidof easytier-web | awk '{print $NF}')/status | grep -w VmRSS | awk '{printf \"%.2f MB\", $2/1024}')")
e.etwebram = command5:read("*all")
command5:close()
local command8 = io.popen("([ -s /tmp/easytiernew.tag ] && cat /tmp/easytiernew.tag ) || ( curl -L -k -s --connect-timeout 3 --user-agent 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36' https://api.github.com/repos/EasyTier/EasyTier/releases/latest | grep tag_name | sed 's/[^0-9.]*//g' >/tmp/easytiernew.tag && cat /tmp/easytiernew.tag )")
e.etnewtag = command8:read("*all")
command8:close()
-- 获取版本信息
local cached_newtag = safe_read_file("/tmp/easytiernew.tag")
if cached_newtag and cached_newtag ~= "" then
e.etnewtag = cached_newtag:gsub("[\r\n]+", "")
else
e.etnewtag = safe_exec("curl -L -k -s --connect-timeout 3 --user-agent 'Mozilla/5.0' https://api.github.com/repos/EasyTier/EasyTier/releases/latest | grep tag_name | sed 's/[^0-9.]*//g'")
if e.etnewtag ~= "" then
local f = io.open("/tmp/easytiernew.tag", "w")
if f then f:write(e.etnewtag); f:close() end
end
end
local command9 = io.popen("([ -s /tmp/easytier.tag ] && cat /tmp/easytier.tag ) || ( echo `$(uci -q get easytier.@easytier[0].easytierbin) -V | sed 's/^[^0-9]*//'` > /tmp/easytier.tag && cat /tmp/easytier.tag && [ ! -s /tmp/easytier.tag ] && echo '' >> /tmp/easytier.tag && cat /tmp/easytier.tag )")
e.ettag = command9:read("*all")
command9:close()
local cached_tag = safe_read_file("/tmp/easytier.tag")
if cached_tag and cached_tag ~= "" then
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
local f = io.open("/tmp/easytier.tag", "w")
if f then f:write(e.ettag); f:close() end
end
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function get_log()
local log = ""
local files = {"/tmp/easytier.log"}

View File

@@ -74,12 +74,20 @@ network_name = s:taboption("general", Value, "network_name", translate("Network
translate("The network name used to identify this VPN network (--network-name parameter)"))
network_name.password = true
network_name.placeholder = "easytier-name"
network_name.maxlength = 64
network_name.validate = function(self, value)
if value and value ~= "" and value:match("[^%w%-_]") then
return nil, translate("Only alphanumeric characters, hyphens and underscores allowed")
end
return value
end
network_name:depends("etcmd", "etcmd")
network_secret = s:taboption("general", Value, "network_secret", translate("Network Secret"),
translate("Network secret used to verify whether this node belongs to the VPN network (--network-secret parameter)"))
network_secret.password = true
network_secret.placeholder = "easytier-password"
network_secret.maxlength = 128
network_secret:depends("etcmd", "etcmd")
ip_dhcp = s:taboption("general", Flag, "ip_dhcp", translate("Enable DHCP"),
@@ -192,14 +200,14 @@ local model = nixio.fs.readfile("/proc/device-tree/model") or ""
local hostname = nixio.fs.readfile("/proc/sys/kernel/hostname") or ""
model = model:gsub("\n", "")
hostname = hostname:gsub("\n", "")
local device_name = (model ~= "" and model) or (hostname ~= "" and hostname) or "OpenWrt"
device_name = device_name:gsub(" ", "_")
desvice_name = s:taboption("general", Value, "desvice_name", translate("Hostname"),
local device_name_default = (model ~= "" and model) or (hostname ~= "" and hostname) or "OpenWrt"
device_name_default = device_name_default:gsub(" ", "_")
hostname_opt = s:taboption("general", Value, "desvice_name", translate("Hostname"),
translate("The hostname used to identify this device (--hostname parameter)"))
desvice_name.placeholder = device_name
desvice_name.default = device_name
desvice_name:depends("etcmd", "etcmd")
desvice_name:depends("etcmd", "web")
hostname_opt.placeholder = device_name_default
hostname_opt.default = device_name_default
hostname_opt:depends("etcmd", "etcmd")
hostname_opt:depends("etcmd", "web")
uuid = s:taboption("general", Value, "uuid", translate("UUID"),
translate("Unique identifier used to recognize this device when connecting to the web console, for issuing configuration files"))
@@ -496,6 +504,16 @@ webbin = s:taboption("upload", Value, "webbin", translate("easytier-web Binary P
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 = ""

View File

@@ -1,6 +1,4 @@
config easytier
option enabled '0'
option easytierbin '/usr/bin/easytier-core'
option easytierbin '/usr/bin/easytier-core'

View File

@@ -4,6 +4,12 @@
START=99
USE_PROCD=1
# 引入模块化脚本
EASYTIER_LIB_DIR="/usr/share/easytier"
[ -f "${EASYTIER_LIB_DIR}/utils.sh" ] && . "${EASYTIER_LIB_DIR}/utils.sh"
[ -f "${EASYTIER_LIB_DIR}/firewall.sh" ] && . "${EASYTIER_LIB_DIR}/firewall.sh"
[ -f "${EASYTIER_LIB_DIR}/download.sh" ] && . "${EASYTIER_LIB_DIR}/download.sh"
check() {
if [ ! -z "$checkip" ]; then
echo ' ' >/tmp/easytier_check
@@ -49,6 +55,9 @@ EOF
fi
}
# get_tz 函数已移至 utils.sh保留兼容性包装
# 如果 utils.sh 未加载,使用内联定义
if ! type get_tz >/dev/null 2>&1; then
get_tz() {
SET_TZ=""
[ -e "/etc/localtime" ] && return
@@ -60,6 +69,7 @@ get_tz() {
[ -z "$tz" ] && return
SET_TZ=$tz
}
fi
check_bin() {
curltest=`which curl`
@@ -78,7 +88,11 @@ check_bin() {
tag="$( curl -k --connect-timeout 3 --user-agent "$user_agent" https://api.github.com/repos/EasyTier/EasyTier/releases/latest 2>&1 | grep 'tag_name' | cut -d\" -f4 )"
[ -z "$tag" ] && tag="$( curl -Lk --connect-timeout 3 --user-agent "$user_agent" -s https://api.github.com/repos/EasyTier/EasyTier/releases/latest 2>&1 | grep 'tag_name' | cut -d\" -f4 )"
fi
[ -z "$tag"] && tag=v2.5.0
# 如果获取失败,从 UCI 配置或使用默认版本
if [ -z "$tag" ]; then
tag=$(uci -q get easytier.@easytier[0].fallback_version)
[ -z "$tag" ] && tag="v2.5.0"
fi
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 开始在线下载${tag}版本,${proxy}https://github.com/EasyTier/EasyTier/releases/download/${tag}/easytier-linux-${cpucore}-${tag}.zip下载较慢耐心等候" >>/tmp/easytier.log
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 开始在线下载${tag}版本,${proxy}https://github.com/EasyTier/EasyTier/releases/download/${tag}/easytier-linux-${cpucore}-${tag}.zip下载较慢耐心等候" >>/tmp/easytierweb.log
mkdir -p "$path"

View File

@@ -6,6 +6,8 @@ uci -q batch <<-EOF >/dev/null
set ucitrack.@easytier[-1].init=easytier
commit ucitrack
EOF
chmod +x /etc/init.d/easytier
/etc/init.d/easytier enable
rm -rf /tmp/luci-indexcache /tmp/luci-modulecache
exit 0

View File

@@ -0,0 +1,151 @@
#!/bin/sh
# EasyTier Download Management
# Handles binary downloads from GitHub with proxy support
# 引入工具函数
. /usr/share/easytier/utils.sh 2>/dev/null || true
# 默认 GitHub 加速代理列表
DEFAULT_PROXYS="
https://ghproxy.net/
https://gh-proxy.com/
https://cdn.gh-proxy.com/
https://ghfast.top/
"
# 获取代理列表
# 优先从 UCI 配置读取,否则使用默认值
get_proxy_list() {
local proxys=$(uci -q get easytier.@easytier[0].github_proxys)
[ -z "$proxys" ] && proxys="$DEFAULT_PROXYS"
echo "$proxys"
}
# 获取最新版本号
get_latest_version() {
local 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'
local tag=""
local curltest=$(which curl)
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)
else
tag=$(curl -k --connect-timeout 3 --user-agent "$user_agent" \
https://api.github.com/repos/EasyTier/EasyTier/releases/latest 2>&1 | grep 'tag_name' | cut -d\" -f4)
[ -z "$tag" ] && tag=$(curl -Lk --connect-timeout 3 --user-agent "$user_agent" -s \
https://api.github.com/repos/EasyTier/EasyTier/releases/latest 2>&1 | grep 'tag_name' | cut -d\" -f4)
fi
# 如果获取失败,从 UCI 配置或使用默认版本
if [ -z "$tag" ]; then
tag=$(uci -q get easytier.@easytier[0].fallback_version)
[ -z "$tag" ] && tag="v2.5.0"
fi
echo "$tag"
}
# 下载二进制文件
# 参数: $1=版本号 $2=CPU架构 $3=目标路径
download_binary() {
local tag="$1"
local cpucore="$2"
local path="$3"
local proxys=$(get_proxy_list)
local download_url="https://github.com/EasyTier/EasyTier/releases/download/${tag}/easytier-linux-${cpucore}-${tag}.zip"
mkdir -p "$path"
for proxy in $proxys; do
log_message "INFO" "easytier" "尝试使用代理 ${proxy} 下载" "/tmp/easytier.log"
if curl -L -k -o /tmp/easytier.zip --connect-timeout 10 --retry 3 "${proxy}${download_url}" || \
wget --no-check-certificate --timeout=10 --tries=3 -O /tmp/easytier.zip "${proxy}${download_url}"; then
unzip -j -q -o /tmp/easytier.zip -d /tmp
chmod +x /tmp/easytier-core /tmp/easytier-cli /tmp/easytier-web /tmp/easytier-web-embed 2>/dev/null || true
rm -rf /tmp/easytier.zip
log_message "INFO" "easytier" "下载成功" "/tmp/easytier.log"
return 0
else
log_message "WARN" "easytier" "${proxy}${download_url} 下载失败" "/tmp/easytier.log"
fi
done
log_message "ERROR" "easytier" "所有代理下载均失败,请手动下载上传程序" "/tmp/easytier.log"
return 1
}
# 检查并下载程序
# 参数: $1=程序路径 $2=目标路径 $3=CPU架构
check_and_download() {
local easytierbin="$1"
local path="$2"
local cpucore="$3"
# 检查程序是否存在且完整
if [ ! -f "$easytierbin" ] || [ "$($easytierbin -h 2>&1 | wc -l)" -lt 3 ]; then
log_message "INFO" "easytier" "$easytierbin 不存在或程序不完整,开始在线下载..." "/tmp/easytier.log"
local tag=$(get_latest_version)
log_message "INFO" "easytier" "开始在线下载${tag}版本" "/tmp/easytier.log"
if download_binary "$tag" "$cpucore" "$path"; then
# 移动下载的文件到目标位置
if [ "$(uci -q get easytier.@easytier[0].enabled)" = "1" ]; then
mv -f /tmp/easytier-core "${path}/" 2>/dev/null
mv -f /tmp/easytier-cli "${path}/" 2>/dev/null
chmod +x "$easytierbin" 2>/dev/null
fi
if [ "$(uci -q get easytier.@easytier[0].web_enabled)" = "1" ]; then
local webbin=$(uci -q get easytier.@easytier[0].webbin)
[ -z "$webbin" ] && webbin="/usr/bin/easytier-web"
mv -f /tmp/easytier-web-embed "$webbin" 2>/dev/null || true
chmod +x "$webbin" 2>/dev/null
fi
return 0
fi
return 1
fi
return 0
}
# 处理上传的程序
# 参数: $1=目标路径 $2=程序路径
handle_uploaded_binary() {
local path="$1"
local easytierbin="$2"
local size=$(get_available_space "$path")
if [ -f /tmp/easytier-core ] || [ -f /tmp/easytier-cli ]; then
if [ "${path:0:4}" != "/tmp" ]; then
chmod +x /tmp/easytier-core 2>/dev/null
chmod +x /tmp/easytier-cli 2>/dev/null
mkdir -p "$path"
log_message "INFO" "easytier" "找到上传的程序/tmp/easytier-core替换为$easytierbin" "/tmp/easytier.log"
local upsize=$(du -k /tmp/easytier-core 2>/dev/null | cut -f1)
local result=$((size - upsize))
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
return 0
else
log_message "WARN" "easytier" "无法替换,上传的程序不完整或自定义路径的可用空间不足,当前空间剩余${size}kb" "/tmp/easytier.log"
return 1
fi
fi
fi
return 1
}

View File

@@ -0,0 +1,194 @@
#!/bin/sh
# EasyTier Firewall Management
# Manages firewall rules and network interfaces for EasyTier
# 引入工具函数
. /usr/share/easytier/utils.sh 2>/dev/null || true
# 添加单条防火墙规则
# 参数: $1=规则名称 $2=协议 $3=端口 $4=描述
add_firewall_rule() {
local rule_name="$1"
local proto="$2"
local port="$3"
local desc="$4"
[ -z "$port" ] && return 1
log_message "INFO" "easytier" "添加防火墙规则 ${rule_name} 放行端口 ${port}" "/tmp/easytier.log"
uci -q delete "firewall.${rule_name}"
uci set "firewall.${rule_name}=rule"
uci set "firewall.${rule_name}.name=${rule_name}"
uci set "firewall.${rule_name}.target=ACCEPT"
uci set "firewall.${rule_name}.src=wan"
uci set "firewall.${rule_name}.proto=${proto}"
uci set "firewall.${rule_name}.dest_port=${port}"
uci set "firewall.${rule_name}.enabled=1"
}
# 设置所有 EasyTier 防火墙规则
# 需要设置的变量: tcp_port, udp_port, ws_port, wss_port, wg_port, quic_port, socks_port
set_firewall_rules() {
[ -n "$tcp_port" ] && add_firewall_rule "easytier_tcp_udp" "tcp udp" "$tcp_port" "EasyTier TCP/UDP"
[ -n "$udp_port" ] && add_firewall_rule "easytier_udp" "udp" "$udp_port" "EasyTier UDP"
[ -n "$ws_port" ] && add_firewall_rule "easytier_ws" "tcp" "$ws_port" "EasyTier WS"
[ -n "$wss_port" ] && add_firewall_rule "easytier_wss" "tcp" "$wss_port" "EasyTier WSS"
[ -n "$wg_port" ] && add_firewall_rule "easytier_wg" "udp" "$wg_port" "EasyTier WG"
[ -n "$quic_port" ] && add_firewall_rule "easytier_quic" "tcp udp" "$quic_port" "EasyTier QUIC"
[ -n "$socks_port" ] && add_firewall_rule "easytier_socks5" "tcp" "$socks_port" "EasyTier SOCKS5"
}
# 设置网络接口
# 参数: $1=接口名称 $2=IP地址(可选)
setup_network_interface() {
local tunname="${1:-tun0}"
local ipaddr="$2"
uci -q delete network.EasyTier >/dev/null 2>&1
if [ -z "$(uci -q get network.EasyTier)" ]; then
uci set network.EasyTier='interface'
if [ -z "$ipaddr" ]; then
uci set network.EasyTier.proto='none'
else
uci set network.EasyTier.proto='static'
uci set network.EasyTier.ipaddr="$ipaddr"
uci set network.EasyTier.netmask='255.0.0.0'
fi
log_message "INFO" "easytier" "添加网络接口 EasyTier 绑定虚拟接口 ${tunname}" "/tmp/easytier.log"
uci set network.EasyTier.device="$tunname"
uci set network.EasyTier.ifname="$tunname"
fi
}
# 设置防火墙区域
setup_firewall_zone() {
if [ -z "$(uci -q get firewall.easytierzone)" ]; then
log_message "INFO" "easytier" "添加防火墙规则,放行网络接口 EasyTier 允许出入转发开启IP动态伪装 MSS钳制" "/tmp/easytier.log"
uci set firewall.easytierzone='zone'
uci set firewall.easytierzone.input='ACCEPT'
uci set firewall.easytierzone.output='ACCEPT'
uci set firewall.easytierzone.forward='ACCEPT'
uci set firewall.easytierzone.masq='1'
uci set firewall.easytierzone.mtu_fix='1'
uci set firewall.easytierzone.name='EasyTier'
uci set firewall.easytierzone.network='EasyTier'
fi
}
# 设置转发规则
# 参数: $1=et_forward 配置值
setup_forwarding_rules() {
local et_forward="$1"
if [ "${et_forward#*etfwlan}" != "$et_forward" ]; then
log_message "INFO" "easytier" "允许从虚拟网络 EasyTier 到局域网 lan 的流量" "/tmp/easytier.log"
uci set firewall.easytierfwlan=forwarding
uci set firewall.easytierfwlan.dest='lan'
uci set firewall.easytierfwlan.src='EasyTier'
else
uci -q delete firewall.easytierfwlan
fi
if [ "${et_forward#*etfwwan}" != "$et_forward" ]; then
log_message "INFO" "easytier" "允许从虚拟网络 EasyTier 到广域网 wan 的流量" "/tmp/easytier.log"
uci set firewall.easytierfwwan=forwarding
uci set firewall.easytierfwwan.dest='wan'
uci set firewall.easytierfwwan.src='EasyTier'
else
uci -q delete firewall.easytierfwwan
fi
if [ "${et_forward#*lanfwet}" != "$et_forward" ]; then
log_message "INFO" "easytier" "允许从局域网 lan 到虚拟网络 EasyTier 的流量" "/tmp/easytier.log"
uci set firewall.lanfweasytier=forwarding
uci set firewall.lanfweasytier.dest='EasyTier'
uci set firewall.lanfweasytier.src='lan'
else
uci -q delete firewall.lanfweasytier
fi
if [ "${et_forward#*wanfwet}" != "$et_forward" ]; then
log_message "INFO" "easytier" "允许从广域网 wan 到虚拟网络 EasyTier 的流量" "/tmp/easytier.log"
uci set firewall.wanfweasytier=forwarding
uci set firewall.wanfweasytier.dest='EasyTier'
uci set firewall.wanfweasytier.src='wan'
else
uci -q delete firewall.wanfweasytier
fi
}
# 清理所有 EasyTier 防火墙规则
clean_firewall_rules() {
uci -q delete network.EasyTier >/dev/null 2>&1
uci -q delete firewall.easytierzone >/dev/null 2>&1
uci -q delete firewall.easytierfwlan >/dev/null 2>&1
uci -q delete firewall.easytierfwwan >/dev/null 2>&1
uci -q delete firewall.lanfweasytier >/dev/null 2>&1
uci -q delete firewall.wanfweasytier >/dev/null 2>&1
uci -q delete firewall.easytier_tcp >/dev/null 2>&1
uci -q delete firewall.easytier_udp >/dev/null 2>&1
uci -q delete firewall.easytier_tcp_udp >/dev/null 2>&1
uci -q delete firewall.easytier_wss >/dev/null 2>&1
uci -q delete firewall.easytier_ws >/dev/null 2>&1
uci -q delete firewall.easytier_wg >/dev/null 2>&1
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
uci -q delete firewall.easytier_webserver >/dev/null 2>&1
uci -q delete firewall.easytier_webapi >/dev/null 2>&1
uci -q delete firewall.easytier_webhtml >/dev/null 2>&1
}
# 设置 Web 控制台防火墙规则
# 参数: $1=web_port $2=api_port $3=html_port $4=fw_web $5=fw_api
setup_web_firewall() {
local web_port="$1"
local api_port="$2"
local html_port="$3"
local fw_web="$4"
local fw_api="$5"
if [ -n "$web_port" ] && [ "$fw_web" = "1" ]; then
log_message "INFO" "easytier" "添加防火墙规则 easytier_web 放行服务端口 ${web_port}" "/tmp/easytierweb.log"
uci -q delete firewall.easytier_webserver
uci set firewall.easytier_webserver=rule
uci set firewall.easytier_webserver.name="easytier_webserver"
uci set firewall.easytier_webserver.target="ACCEPT"
uci set firewall.easytier_webserver.src="wan"
uci set firewall.easytier_webserver.proto="tcp udp"
uci set firewall.easytier_webserver.dest_port="$web_port"
uci set firewall.easytier_webserver.enabled="1"
fi
if [ -n "$api_port" ] && [ "$fw_api" = "1" ]; then
log_message "INFO" "easytier" "添加防火墙规则 easytier_web 放行API端口 ${api_port}" "/tmp/easytierweb.log"
uci -q delete firewall.easytier_webapi
uci set firewall.easytier_webapi=rule
uci set firewall.easytier_webapi.name="easytier_webapi"
uci set firewall.easytier_webapi.target="ACCEPT"
uci set firewall.easytier_webapi.src="wan"
uci set firewall.easytier_webapi.proto="tcp"
uci set firewall.easytier_webapi.dest_port="$api_port"
uci set firewall.easytier_webapi.enabled="1"
fi
if [ -n "$html_port" ] && [ "$fw_api" = "1" ] && [ "$html_port" != "$api_port" ]; then
log_message "INFO" "easytier" "添加防火墙规则 easytier_web 放行html端口 ${html_port}" "/tmp/easytierweb.log"
uci -q delete firewall.easytier_webhtml
uci set firewall.easytier_webhtml=rule
uci set firewall.easytier_webhtml.name="easytier_webhtml"
uci set firewall.easytier_webhtml.target="ACCEPT"
uci set firewall.easytier_webhtml.src="wan"
uci set firewall.easytier_webhtml.proto="tcp"
uci set firewall.easytier_webhtml.dest_port="$html_port"
uci set firewall.easytier_webhtml.enabled="1"
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
}

View File

@@ -0,0 +1,89 @@
#!/bin/sh
# EasyTier Utility Functions
# Common helper functions for EasyTier init scripts
# 获取时区设置
get_tz() {
SET_TZ=""
[ -e "/etc/localtime" ] && return
for tzfile in /etc/TZ /var/etc/TZ; do
[ -e "$tzfile" ] || continue
tz="$(cat $tzfile 2>/dev/null)"
done
[ -z "$tz" ] && return
SET_TZ=$tz
}
# 获取 CPU 架构
get_cpu_arch() {
local cputype=$(uname -ms | tr ' ' '_' | tr '[A-Z]' '[a-z]')
local cpucore=""
[ -n "$(echo $cputype | grep -E 'linux.*armv.*')" ] && cpucore="arm"
[ -n "$(echo $cputype | grep -E 'linux.*armv7.*')" ] && [ -n "$(cat /proc/cpuinfo | grep vfp)" ] && cpucore="armv7"
[ -n "$(echo $cputype | grep -E 'linux.*aarch64.*|linux.*armv8.*')" ] && cpucore="aarch64"
[ -n "$(echo $cputype | grep -E 'linux.*86.*')" ] && cpucore="i386"
[ -n "$(echo $cputype | grep -E 'linux.*86_64.*')" ] && cpucore="x86_64"
if [ -n "$(echo $cputype | grep -E 'linux.*mips.*')" ]; then
local mipstype=$(echo -n I | hexdump -o 2>/dev/null | awk '{ print substr($2,6,1); exit}')
[ "$mipstype" = "0" ] && cpucore="mips" || cpucore="mipsel"
fi
echo "$cpucore"
}
# 统一日志记录
log_message() {
local level="$1"
local component="$2"
local message="$3"
local logfile="${4:-/tmp/easytier.log}"
echo "$(date '+%Y-%m-%d %H:%M:%S') ${component} : ${message}" >> "$logfile"
}
# 日志大小管理
manage_log_size() {
local logfile="$1"
local max_size_kb="${2:-5120}"
local keep_lines="${3:-500}"
while true; do
local log_size=$(ls -l "$logfile" 2>/dev/null | awk '{print int($5/1024)}')
if [ "${log_size:-0}" -gt "$max_size_kb" ]; then
tail -n "$keep_lines" "$logfile" > "${logfile}.tmp"
mv "${logfile}.tmp" "$logfile"
fi
sleep 300
done
}
# 获取可用磁盘空间 (KB)
get_available_space() {
local path="$1"
local size=$(df -k | awk '/\/overlay$/ {sub(/K$/, "", $4); print $4}')
[ -z "$size" ] && size=$(df -kP "$path" 2>/dev/null | awk 'NR==2 {print $(NF-2)}')
echo "${size:-0}"
}
# 安全执行命令并返回结果
safe_exec() {
local cmd="$1"
local result=$(eval "$cmd" 2>/dev/null)
echo "$result"
}
# 检查进程是否运行
is_process_running() {
local process_name="$1"
pgrep -f "$process_name" >/dev/null 2>&1
return $?
}
# 停止进程
stop_process() {
local process_name="$1"
ps | grep "$process_name" | grep -v grep | awk '{print $1}' | xargs kill >/dev/null 2>&1
ps | grep "$process_name" | grep -v grep | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1
}

View File

@@ -0,0 +1,5 @@
# EasyTier Version Configuration
# This file is the single source of truth for the EasyTier version
# Used by: easytier/Makefile, luci-app-easytier/Makefile, init.d/easytier
EASYTIER_VERSION=2.5.0