Files

1015 lines
57 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/sh /etc/rc.common
# Copyright (C) 2008-2020 OpenWrt.org
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
cat > /tmp/easytier_check <<'EOF'
#!/bin/sh
time="$(($(uci -q get easytier.@easytier[0].checktime) * 60))"
if [ -z "$time" ]; then
time=120
uci -q set easytier.@easytier[0].checktime=2
uci commit easytier
fi
while true; do
if [ "$(uci -q get easytier.@easytier[0].enabled)" = "1" ]; then
/bin/ping -c 3 223.5.5.5 -w 5 >/dev/null 2>&1
if [ "$?" == "0" ]; then
if [ ! -z "$(uci -q get easytier.@easytier[0].checkip)" ]; then
online=""
for ip in $(uci -q get easytier.@easytier[0].checkip); do
ms=`echo $(/bin/ping -4 $ip -c 2 -w 4 -q) | awk -F '/' '{print $4}'`
[ ! -z "$ms" ] && echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 通断检测:${ip} 延迟:${ms}ms " >>/tmp/easytier.log && online=1
[ -z "$ms" ] && echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 通断检测:${ip} 网络中断 " >>/tmp/easytier.log
done
[ "$online" != "1" ] && echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 通断检测:$(uci -q get easytier.@easytier[0].checkip) 所有指定IP皆无法ping通,重新启动程序! " >>/tmp/easytier.log && /etc/init.d/easytier restart
fi
else
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 通断检测:检测到互联网未能成功访问,跳过检测 " >>/tmp/easytier.log
fi
else
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 通断检测:程序已关闭,退出检测 " >>/tmp/easytier.log
/etc/init.d/easytier restart
break
fi
sleep $((time))
[ "$(du -k /tmp/easytier.log | cut -f1)" = "1000" ] && echo " " >/tmp/easytier.log
done
EOF
chmod +x /tmp/easytier_check
procd_open_instance
procd_set_param respawn
procd_set_param command /tmp/easytier_check
procd_close_instance
fi
}
# get_tz 函数已移至 utils.sh,保留兼容性包装
# 如果 utils.sh 未加载,使用内联定义
if ! type get_tz >/dev/null 2>&1; then
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
}
fi
shell_quote() {
printf "'%s'" "$(printf "%s" "$1" | sed "s/'/'\\\\''/g")"
}
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'
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.7.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
if ! command -v unzip >/dev/null 2>&1; then
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 系统缺少 unzip,无法解压下载的 EasyTier 压缩包,请安装 unzip 后重试" >>/tmp/easytier.log
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 系统缺少 unzip,无法解压下载的 EasyTier 压缩包,请安装 unzip 后重试" >>/tmp/easytierweb.log
return 1
fi
mkdir -p "$path"
for proxy in $proxys ; do
if curl -L -k -o /tmp/easytier.zip --connect-timeout 10 --retry 3 "${proxy}https://github.com/EasyTier/EasyTier/releases/download/${tag}/easytier-linux-${cpucore}-${tag}.zip" || \
wget --no-check-certificate --timeout=10 --tries=3 -O /tmp/easytier.zip "${proxy}https://github.com/EasyTier/EasyTier/releases/download/${tag}/easytier-linux-${cpucore}-${tag}.zip" ; 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 || true
if [ "$(uci -q get easytier.@easytier[0].enabled)" = "1" ] ; then
mv -f /tmp/easytier-core ${path}/
mv -f /tmp/easytier-cli ${path}/
chmod +x "$easytierbin"
if [ "$($easytierbin -h 2>&1 | wc -l)" -gt 3 ] ; then
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : ${easytierbin} 下载成功" >>/tmp/easytier.log
else
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : ${proxy}https://github.com/EasyTier/EasyTier/releases/download/${tag}/easytier-linux-${cpucore}-${tag}.zip 下载不完整,请手动下载上传程序" >>/tmp/easytier.log
fi
fi
if [ "$(uci -q get easytier.@easytier[0].web_enabled)" = "1" ] ; then
mv -f /tmp/easytier-web-embed ${webbin} || true
chmod +x "$webbin"
if [ "$($webbin -h 2>&1 | wc -l)" -gt 3 ] ; then
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : ${webbin} 下载成功" >>/tmp/easytierweb.log
else
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : ${proxy}https://github.com/EasyTier/EasyTier/releases/download/${tag}/easytier-linux-${cpucore}-${tag}.zip 下载不完整,请手动下载上传程序" >>/tmp/easytierweb.log
fi
fi
rm -rf /tmp/easytier.zip
break
else
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : ${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 : ${proxy}https://github.com/EasyTier/EasyTier/releases/download/${tag}/easytier-linux-${cpucore}-${tag}.zip 下载失败,请手动下载上传程序" >>/tmp/easytierweb.log
fi
done
}
check_config() {
config_file="/etc/easytier/config.toml"
instance_name=$(cat $config_file | grep "instance_name =" | awk '{print $3}'| tr -d '" ')
socks_port=$(cat $config_file | grep "socks5_proxy" | awk -F ":" '{print $3}'| tr -d '" ')
[ -z "$(grep -F 'listeners = []' $config_file)" ] && listenermode="ON"
tcp_port=$(grep -oE '"tcp://(\[::\]|0\.0\.0\.0):[0-9]+"' "$config_file" | head -n1 | sed -E 's/.*:([0-9]+)"/\1/')
udp_port=$(grep -oE '"udp://(\[::\]|0\.0\.0\.0):[0-9]+"' "$config_file" | head -n1 | sed -E 's/.*:([0-9]+)"/\1/')
ws_port=$(grep -oE '"ws://(\[::\]|0\.0\.0\.0):[0-9]+"' "$config_file" | head -n1 | sed -E 's/.*:([0-9]+)"/\1/')
wss_port=$(grep -oE '"wss://(\[::\]|0\.0\.0\.0):[0-9]+"' "$config_file" | head -n1 | sed -E 's/.*:([0-9]+)"/\1/')
wg_port=$(grep -oE '"wg://(\[::\]|0\.0\.0\.0):[0-9]+"' "$config_file" | head -n1 | sed -E 's/.*:([0-9]+)"/\1/')
quic_port=$(grep -oE '"quic://(\[::\]|0\.0\.0\.0):[0-9]+"' "$config_file" | head -n1 | sed -E 's/.*:([0-9]+)"/\1/')
tunname=$(grep "dev_name =" "$config_file" | awk '{print $3}' | tr -d "'\", ")
proxy_network=$(grep -F '[[proxy_network]]' $config_file)
wireguard_port=$(cat $config_file | grep "wireguard_listen = " | awk -F ":" '{print $2}'| tr -d '/", ')
log="$(uci -q get easytier.@easytier[0].log || echo off)"
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 检测配置文件可用性 ${easytierbin} --check-config --config-file ${config_file}" >>/tmp/easytier.log
${easytierbin} --check-config --config-file ${config_file} >> /tmp/easytier.log 2>&1
if [ "$?" != "0" ] ; then
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 配置文件 ${config_file} 校验失败,请查看上方 easytier-core 的报错。EasyTier 2.7.0 起配置校验更严格:旧的 [vpn_portal_config] client_cidr 写法与 [flags] 中的未知键都会导致解析失败" >>/tmp/easytier.log
fi
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 开始运行 ${easytierbin} -c ${config_file}" >>/tmp/easytier.log
procd_open_instance
get_tz
[ -z "$SET_TZ" ] || procd_set_param env TZ="$SET_TZ"
procd_set_param command /bin/sh -c "
cd /tmp ; ${easytierbin} -c ${config_file} --console-log-level ${log} >> /tmp/easytier.log 2>&1 &
ET_CORE_PID=\$!
{
while true; do
LOG_SIZE=\$(ls -l /tmp/easytier.log | awk '{print int(\$5/1024)}')
if [ \$LOG_SIZE -gt 5120 ]; then
tail -n 500 /tmp/easytier.log > /tmp/easytier.log.tmp
: > /tmp/easytier.log
cat /tmp/easytier.log.tmp >> /tmp/easytier.log
rm -f /tmp/easytier.log.tmp
fi
sleep 60
done
} &
LOG_MANAGEMENT_PID=\$!
trap \"kill -TERM \$ET_CORE_PID; kill -TERM \$LOG_MANAGEMENT_PID; exit\" SIGINT SIGTERM EXIT
wait \$ET_CORE_PID
"
}
get_etconfig() {
web_config="$(uci -q get easytier.@easytier[0].web_config)"
network_name="$(uci -q get easytier.@easytier[0].network_name)"
network_secret="$(uci -q get easytier.@easytier[0].network_secret)"
ip_dhcp="$(uci -q get easytier.@easytier[0].ip_dhcp || echo 0)"
ipaddr="$(uci -q get easytier.@easytier[0].ipaddr)"
ip6addr="$(uci -q get easytier.@easytier[0].ip6addr)"
external_node="$(uci -q get easytier.@easytier[0].external_node)"
proxy_network="$(uci -q get easytier.@easytier[0].proxy_network)"
rpc_portal="$(uci -q get easytier.@easytier[0].rpc_portal || echo 15888)"
rpc_portal_whitelist="$(uci -q get easytier.@easytier[0].rpc_portal_whitelist)"
listenermode="$(uci -q get easytier.@easytier[0].listenermode)"
tunname="$(uci -q get easytier.@easytier[0].tunname)"
relay_network="$(uci -q get easytier.@easytier[0].relay_network || echo 0)"
tcp_port="$(uci -q get easytier.@easytier[0].tcp_port | awk '{print $1}')"
ws_port="$(uci -q get easytier.@easytier[0].ws_port)"
wss_port="$(uci -q get easytier.@easytier[0].wss_port)"
wg_port="$(uci -q get easytier.@easytier[0].wg_port)"
quic_port="$(uci -q get easytier.@easytier[0].quic_port)"
peeradd="$(uci -q get easytier.@easytier[0].peeradd)"
desvice_name="$(uci -q get easytier.@easytier[0].desvice_name)"
instance_name="$(uci -q get easytier.@easytier[0].instance_name)"
vpn_portal="$(uci -q get easytier.@easytier[0].vpn_portal)"
vpn_portal_clients="$(uci -q get easytier.@easytier[0].vpn_portal_clients)"
vpn_portal_private_key="$(uci -q get easytier.@easytier[0].vpn_portal_private_key)"
mtu="$(uci -q get easytier.@easytier[0].mtu)"
default_protocol="$(uci -q get easytier.@easytier[0].default_protocol)"
disable_encryption="$(uci -q get easytier.@easytier[0].disable_encryption || echo 0)"
whitelist="$(uci -q get easytier.@easytier[0].whitelist)"
multi_thread="$(uci -q get easytier.@easytier[0].multi_thread || echo 0)"
multi_thread_count="$(uci -q get easytier.@easytier[0].multi_thread_count)"
disable_ipv6="$(uci -q get easytier.@easytier[0].disable_ipv6 || echo 0)"
latency_first="$(uci -q get easytier.@easytier[0].latency_first || echo 0)"
exit_node="$(uci -q get easytier.@easytier[0].exit_node || echo 0)"
smoltcp="$(uci -q get easytier.@easytier[0].smoltcp || echo 0)"
exit_nodes="$(uci -q get easytier.@easytier[0].exit_nodes || echo 0)"
no_tun="$(uci -q get easytier.@easytier[0].no_tun || echo 0)"
manual_routes="$(uci -q get easytier.@easytier[0].manual_routes)"
log="$(uci -q get easytier.@easytier[0].log || echo off)"
check="$(uci -q get easytier.@easytier[0].check || echo 0)"
disable_p2p="$(uci -q get easytier.@easytier[0].disable_p2p || echo 0)"
disable_udp="$(uci -q get easytier.@easytier[0].disable_udp || echo 0)"
relay_all="$(uci -q get easytier.@easytier[0].relay_all || echo 0)"
checkip="$(uci -q get easytier.@easytier[0].checkip)"
socks_port="$(uci -q get easytier.@easytier[0].socks_port)"
comp="$(uci -q get easytier.@easytier[0].comp || echo none)"
mapped_listeners="$(uci -q get easytier.@easytier[0].mapped_listeners)"
bind_device="$(uci -q get easytier.@easytier[0].bind_device || echo 0)"
kcp_proxy="$(uci -q get easytier.@easytier[0].kcp_proxy || echo 0)"
kcp_input="$(uci -q get easytier.@easytier[0].kcp_input || echo 0)"
proxy_forward="$(uci -q get easytier.@easytier[0].proxy_forward || echo 0)"
port_forward="$(uci -q get easytier.@easytier[0].port_forward)"
accept_dns="$(uci -q get easytier.@easytier[0].accept_dns || echo 0)"
private_mode="$(uci -q get easytier.@easytier[0].private_mode || echo 0)"
quic_proxy="$(uci -q get easytier.@easytier[0].quic_proxy || echo 0)"
quic_input="$(uci -q get easytier.@easytier[0].quic_input || echo 0)"
foreign_relay_bps_limit="$(uci -q get easytier.@easytier[0].foreign_relay_bps_limit)"
extra_args="$(uci -q get easytier.@easytier[0].extra_args)"
encryption_algorithm="$(uci -q get easytier.@easytier[0].encryption_algorithm)"
p2p_only="$(uci -q get easytier.@easytier[0].p2p_only || echo 0)"
disable_tcp="$(uci -q get easytier.@easytier[0].disable_tcp || echo 0)"
disable_sym="$(uci -q get easytier.@easytier[0].disable_sym || echo 0)"
udp_white_port="$(uci -q get easytier.@easytier[0].udp_white_port)"
tcp_white_port="$(uci -q get easytier.@easytier[0].tcp_white_port)"
disable_relay_kcp="$(uci -q get easytier.@easytier[0].disable_relay_kcp || echo 0)"
relay_kcp="$(uci -q get easytier.@easytier[0].relay_kcp || echo 0)"
auto_config_interface="$(uci -q get easytier.@easytier[0].auto_config_interface || echo 1)"
interface_netmask="$(uci -q get easytier.@easytier[0].interface_netmask)"
auto_config_firewall="$(uci -q get easytier.@easytier[0].auto_config_firewall || echo 1)"
# EasyTier 2.7.0 新增参数
tld_dns_zone="$(uci -q get easytier.@easytier[0].tld_dns_zone)"
instance_recv_bps_limit="$(uci -q get easytier.@easytier[0].instance_recv_bps_limit)"
socket_mark="$(uci -q get easytier.@easytier[0].socket_mark)"
disable_upnp="$(uci -q get easytier.@easytier[0].disable_upnp || echo 0)"
lazy_p2p="$(uci -q get easytier.@easytier[0].lazy_p2p || echo 0)"
need_p2p="$(uci -q get easytier.@easytier[0].need_p2p || echo 0)"
disable_relay_quic="$(uci -q get easytier.@easytier[0].disable_relay_quic || echo 0)"
relay_quic="$(uci -q get easytier.@easytier[0].relay_quic || echo 0)"
stun_servers="$(uci -q get easytier.@easytier[0].stun_servers)"
tcp_stun_servers="$(uci -q get easytier.@easytier[0].tcp_stun_servers)"
}
set_firewall() {
# Check if auto_config_firewall is enabled
if [ "$auto_config_firewall" != "1" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 自动防火墙配置已禁用,跳过配置" >>/tmp/easytier.log
return
fi
if [ ! -z "$tcp_port" ] ; then
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 添加防火墙规则 easytier_tcp_udp 放行端口 ${tcp_port} " >>/tmp/easytier.log
uci -q delete firewall.easytier_tcp_udp
uci set firewall.easytier_tcp_udp=rule
uci set firewall.easytier_tcp_udp.name="easytier_tcp_udp"
uci set firewall.easytier_tcp_udp.target="ACCEPT"
uci set firewall.easytier_tcp_udp.src="wan"
uci set firewall.easytier_tcp_udp.proto="tcp udp"
uci set firewall.easytier_tcp_udp.dest_port="$tcp_port"
uci set firewall.easytier_tcp_udp.enabled="1"
fi
if [ ! -z "$udp_port" ] ; then
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 添加防火墙规则 easytier_udp 放行UDP端口 ${udp_port} " >>/tmp/easytier.log
uci -q delete firewall.easytier_udp
uci set firewall.easytier_udp=rule
uci set firewall.easytier_udp.name="easytier_udp"
uci set firewall.easytier_udp.target="ACCEPT"
uci set firewall.easytier_udp.src="wan"
uci set firewall.easytier_udp.proto="udp"
uci set firewall.easytier_udp.dest_port="$udp_port"
uci set firewall.easytier_udp.enabled="1"
fi
if [ ! -z "$wss_port" ] ; then
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 添加防火墙规则 easytier_wss 放行端口 ${wss_port} " >>/tmp/easytier.log
uci -q delete firewall.easytier_wss
uci set firewall.easytier_wss=rule
uci set firewall.easytier_wss.name="easytier_wss"
uci set firewall.easytier_wss.target="ACCEPT"
uci set firewall.easytier_wss.src="wan"
uci set firewall.easytier_wss.proto="tcp"
uci set firewall.easytier_wss.dest_port="$wss_port"
uci set firewall.easytier_wss.enabled="1"
fi
if [ ! -z "$ws_port" ] ; then
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 添加防火墙规则 easytier_ws 放行端口 ${ws_port} " >>/tmp/easytier.log
uci -q delete firewall.easytier_ws
uci set firewall.easytier_ws=rule
uci set firewall.easytier_ws.name="easytier_ws"
uci set firewall.easytier_ws.target="ACCEPT"
uci set firewall.easytier_ws.src="wan"
uci set firewall.easytier_ws.proto="tcp"
uci set firewall.easytier_ws.dest_port="$ws_port"
uci set firewall.easytier_ws.enabled="1"
fi
if [ ! -z "$wg_port" ] ; then
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 添加防火墙规则 easytier_wg 放行端口 ${wg_port} " >>/tmp/easytier.log
uci -q delete firewall.easytier_wg
uci set firewall.easytier_wg=rule
uci set firewall.easytier_wg.name="easytier_wg"
uci set firewall.easytier_wg.target="ACCEPT"
uci set firewall.easytier_wg.src="wan"
uci set firewall.easytier_wg.proto="udp"
uci set firewall.easytier_wg.dest_port="$wg_port"
uci set firewall.easytier_wg.enabled="1"
fi
if [ ! -z "$quic_port" ] ; then
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 添加防火墙规则 easytier_quic 放行端口 ${quic_port} " >>/tmp/easytier.log
uci -q delete firewall.easytier_quic
uci set firewall.easytier_quic=rule
uci set firewall.easytier_quic.name="easytier_quic"
uci set firewall.easytier_quic.target="ACCEPT"
uci set firewall.easytier_quic.src="wan"
uci set firewall.easytier_quic.proto="tcp udp"
uci set firewall.easytier_quic.dest_port="$quic_port"
uci set firewall.easytier_quic.enabled="1"
fi
[ -z "$tunname" ] && tunname="tun0"
# Check if auto_config_interface is enabled
if [ "$auto_config_interface" = "1" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 自动网络接口配置已启用" >>/tmp/easytier.log
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
[ -z "$interface_netmask" ] && interface_netmask="255.0.0.0"
uci set network.EasyTier.netmask="$interface_netmask"
fi
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 添加网络接口 EasyTier 绑定虚拟接口 ${tunname},子网掩码: ${interface_netmask:-255.0.0.0}" >>/tmp/easytier.log
uci set network.EasyTier.device="$tunname"
uci set network.EasyTier.device="$tunname"
fi
if [ -z "$(uci -q get firewall.easytierzone)" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') 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
else
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 自动网络接口配置已禁用,不创建网络接口" >>/tmp/easytier.log
uci -q delete network.EasyTier >/dev/null 2>&1
uci -q delete firewall.easytierzone >/dev/null 2>&1
fi
et_forward="$(uci -q get easytier.@easytier[0].et_forward)"
if [ "${et_forward//etfwlan/}" != "$et_forward" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') 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
echo "$(date '+%Y-%m-%d %H:%M:%S') 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
echo "$(date '+%Y-%m-%d %H:%M:%S') 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
echo "$(date '+%Y-%m-%d %H:%M:%S') 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
}
start_et() {
easytierbin="$(uci -q get easytier.@easytier[0].easytierbin)"
[ -z "$easytierbin" ] && easytierbin="/usr/bin/easytier-core" && uci -q set easytier.@easytier[0].easytierbin=/usr/bin/easytier-core
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 "$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
easytierbin=/tmp/easytier-core
fi
if [ -f "$easytierbin" ] ; then
if [ ! -x "$easytierbin" ] ; then
chmod +x "$easytierbin"
chmod +x ${path}/easytier-cli
fi
fi
if [ ! -f "$easytierbin" ] || [ "$(($($easytierbin -h 2>&1 | wc -l)))" -lt 3 ] ; then
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : $easytierbin 不存在或程序不完整,开始在线下载..." >>/tmp/easytier.log
check_bin
fi
ver="$($easytierbin -V | awk {'print $2'} | tr -d '~')"
[ ! -z "$ver" ] && echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : ${easytierbin}当前版本号-${ver} " >>/tmp/easytier.log
pgrep -f easytier_check | xargs kill -9 >/dev/null 2>&1
ps | grep 'easytier-core' | grep -v grep | awk '{print $1}' | xargs kill >/dev/null 2>&1
ps | grep 'easytier-core' | grep -v grep | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1
get_etconfig
if [ "$etcmd" = "config" ] ; then
#配置文件启动方式
check_config
else
procd_open_instance "easytier_core"
get_tz
[ -z "$SET_TZ" ] || procd_set_param env TZ="$SET_TZ"
# 门户私钥通过环境变量下发给 easytier-core,避免出现在进程命令行(状态页会展示命令行)
[ -z "$vpn_portal_private_key" ] || procd_set_param env ET_VPN_PORTAL_PRIVATE_KEY="$vpn_portal_private_key"
if [ "$etcmd" = "etcmd" ] ; then
#默认方式启动
[ -z "$network_name" ] || core_cmd="${core_cmd} --network-name $(shell_quote "$network_name")"
[ -z "$network_secret" ] || core_cmd="${core_cmd} --network-secret $(shell_quote "$network_secret")"
[ -z "$ipaddr" ] || core_cmd="${core_cmd} -i $ipaddr"
[ -z "$ip6addr" ] || core_cmd="${core_cmd} --ipv6 $ip6addr"
[ "$ip_dhcp" = "0" ] || core_cmd="${core_cmd} -d"
if [ ! -z "$peeradd" ] ; then
if [[ "$(grep "list peeradd" /etc/config/easytier | awk '{print $3}' | wc -l ) " -eq 1 ]]; then
core_cmd="${core_cmd} -p $peeradd"
else
for peeraddr in $(cat /etc/config/easytier | grep 'list peeradd' | awk -F 'list peeradd' '{print $2}' | sed "s/'/\n/g" | tr -d " ' "); do
core_cmd="${core_cmd} -p $peeraddr"
done
fi
fi
if [ ! -z "$proxy_network" ] ; then
if [[ "$(grep "list proxy_network" /etc/config/easytier | awk '{print $3}' | wc -l ) " -eq 1 ]]; then
core_cmd="${core_cmd} -n '$proxy_network'"
else
for proxy_networks in $(cat /etc/config/easytier | grep 'list proxy_network' | awk -F 'list proxy_network' '{print $2}' | sed "s/'/\n/g" | tr -d " ' "); do
core_cmd="${core_cmd} -n '$proxy_networks'"
done
fi
fi
if [ ! -z "$exit_nodes" ] ; then
if [[ "$(grep "list exit_nodes" /etc/config/easytier | awk '{print $3}' | wc -l ) " -eq 1 ]]; then
core_cmd="${core_cmd} --exit-nodes $exit_nodes"
else
for exit_nodeadds in $(cat /etc/config/easytier | grep 'list exit_nodes' | awk -F 'list exit_nodes' '{print $2}' | sed "s/'/\n/g" | tr -d " ' "); do
core_cmd="${core_cmd} --exit-nodes $exit_nodeadds"
done
fi
fi
if [ ! -z "$manual_routes" ] ; then
if [[ "$(grep "list manual_routes" /etc/config/easytier | awk '{print $3}' | wc -l ) " -eq 1 ]]; then
core_cmd="${core_cmd} --manual-routes $manual_routes"
else
for manual_routeadds in $(cat /etc/config/easytier | grep 'list manual_routes' | awk -F 'list manual_routes' '{print $2}' | sed "s/'/\n/g" | tr -d " ' "); do
core_cmd="${core_cmd} --manual-routes $manual_routeadds"
done
fi
fi
if [ "$relay_network" = "1" ] ; then
if [ ! -z "$whitelist" ] ; then
if [[ "$(grep "list whitelist" /etc/config/easytier | awk '{print $3}' | wc -l ) " -eq 1 ]]; then
core_cmd="${core_cmd} --relay-network-whitelist $whitelist"
else
for whitelists in $(cat /etc/config/easytier | grep 'list whitelist' | awk -F 'list whitelist' '{print $2}' | sed "s/'/\n/g" | tr -d " ' "); do
core_cmd="${core_cmd} --relay-network-whitelist $whitelists"
done
fi
else
core_cmd="${core_cmd} --relay-network-whitelist"
fi
fi
if [ ! -z "$mapped_listeners" ] ; then
if [[ "$(grep "list mapped_listeners" /etc/config/easytier | awk '{print $3}' | wc -l ) " -eq 1 ]]; then
core_cmd="${core_cmd} --mapped-listeners $mapped_listeners"
else
for mapped_listener in $(cat /etc/config/easytier | grep 'list mapped_listeners' | awk -F 'list mapped_listeners' '{print $2}' | sed "s/'/\n/g" | tr -d " ' "); do
core_cmd="${core_cmd} --mapped-listeners $mapped_listener"
done
fi
fi
if [ ! -z "$port_forward" ] ; then
if [[ "$(grep "list port_forward" /etc/config/easytier | awk '{print $3}' | wc -l ) " -eq 1 ]]; then
core_cmd="${core_cmd} --port-forward $port_forward"
else
for port_forwards in $(cat /etc/config/easytier | grep 'list port_forward' | awk -F 'list port_forward' '{print $2}' | sed "s/'/\n/g" | tr -d " ' "); do
core_cmd="${core_cmd} --port-forward $port_forwards"
done
fi
fi
[ -z "$rpc_portal" ] || core_cmd="${core_cmd} -r $rpc_portal"
[ -z "$rpc_portal_whitelist" ] || core_cmd="${core_cmd} --rpc-portal-whitelist $rpc_portal_whitelist"
[ -z "$tcp_port" ] || core_cmd="${core_cmd} -l tcp:$tcp_port"
[ -z "$tcp_port" ] || core_cmd="${core_cmd} -l udp:$tcp_port"
[ -z "$ws_port" ] || core_cmd="${core_cmd} -l ws:$ws_port"
[ -z "$wss_port" ] || core_cmd="${core_cmd} -l wss:$wss_port"
[ -z "$wg_port" ] || core_cmd="${core_cmd} -l wg:$wg_port"
[ -z "$quic_port" ] || core_cmd="${core_cmd} -l quic:$quic_port"
[ -z "$external_node" ] || core_cmd="${core_cmd} -e $external_node"
[ "$listenermode" = "ON" ] || core_cmd="${core_cmd} --no-listener"
[ -z "$desvice_name" ] || core_cmd="${core_cmd} --hostname $(shell_quote "$desvice_name")"
[ -z "$instance_name" ] || core_cmd="${core_cmd} -m $instance_name"
# EasyTier 2.7.0 起 --vpn-portal 只接受 wg://主机:端口,客户端必须逐个具名枚举
if [ -n "$vpn_portal" ]; then
case "$vpn_portal" in
wg://*/*)
# 旧版把客户端网段写在 URL path 里,2.7.0 会直接拒绝并让进程退出,这里跳过门户并提示用户修改
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : VPN 门户地址 ${vpn_portal} 是 2.6.4 旧写法,EasyTier 2.7.0 起只接受 wg://主机:端口,已跳过门户启动;请在界面把客户端网段填入 VPN 门户客户端列表" >>/tmp/easytier.log
;;
wg://*)
if [ -z "$vpn_portal_private_key" ]; then
# 2.7.0 起门户必须有私钥,否则门户监听会启动失败并连带整个实例退出
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 已配置 VPN 门户但未填写门户私钥,EasyTier 2.7.0 起门户必须有私钥,已跳过门户启动;请在界面填写 VPN 门户私钥" >>/tmp/easytier.log
else
core_cmd="${core_cmd} --vpn-portal $vpn_portal"
fi
;;
*)
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : VPN 门户地址 ${vpn_portal} 格式不正确,应为 wg://主机:端口,已跳过门户启动" >>/tmp/easytier.log
;;
esac
fi
# 门户具名客户端,格式 名称=地址/前缀,可配置多条
if [ -n "$vpn_portal_clients" ]; then
if [[ "$(grep "list vpn_portal_clients" /etc/config/easytier | awk '{print $3}' | wc -l)" -eq 1 ]]; then
core_cmd="${core_cmd} --vpn-portal-client $vpn_portal_clients"
else
for vpn_portal_client in $(cat /etc/config/easytier | grep 'list vpn_portal_clients' | awk -F 'list vpn_portal_clients' '{print $2}' | sed "s/'/\n/g" | tr -d " ' "); do
core_cmd="${core_cmd} --vpn-portal-client $vpn_portal_client"
done
fi
fi
[ -z "$mtu" ] || core_cmd="${core_cmd} --mtu $mtu"
[ "$default_protocol" = "-" ] || core_cmd="${core_cmd} --default-protocol $default_protocol"
[ -z "$tunname" ] || core_cmd="${core_cmd} --dev-name $tunname"
[ "$disable_encryption" = "0" ] || core_cmd="${core_cmd} -u"
# 2.7.0 起 multi_thread 的默认值由 false 改为 true,这里始终显式传值,保证升级后行为与界面勾选一致
if [ "$multi_thread" = "0" ]; then
core_cmd="${core_cmd} --multi-thread false"
else
core_cmd="${core_cmd} --multi-thread true"
fi
[ -z "$multi_thread_count" ] || core_cmd="${core_cmd} --multi-thread-count $multi_thread_count"
[ "$no_tun" = "0" ] || core_cmd="${core_cmd} --no-tun"
[ "$smoltcp" = "0" ] || core_cmd="${core_cmd} --use-smoltcp"
[ "$disable_ipv6" = "0" ] || core_cmd="${core_cmd} --disable-ipv6"
[ "$latency_first" = "0" ] || core_cmd="${core_cmd} --latency-first"
[ "$exit_node" = "0" ] || core_cmd="${core_cmd} --enable-exit-node"
[ "$disable_p2p" = "0" ] || core_cmd="${core_cmd} --disable-p2p"
[ "$relay_all" = "0" ] || core_cmd="${core_cmd} --relay-all-peer-rpc"
[ -z "$socks_port" ] || core_cmd="${core_cmd} --socks5 $socks_port"
[ "$comp" = "none" ] || core_cmd="${core_cmd} --compression $comp"
[ "$bind_device" = "0" ] || core_cmd="${core_cmd} --bind-device true"
[ "$bind_device" = "1" ] || core_cmd="${core_cmd} --bind-device false"
[ "$kcp_proxy" = "0" ] || core_cmd="${core_cmd} --enable-kcp-proxy"
[ "$kcp_input" = "0" ] || core_cmd="${core_cmd} --disable-kcp-input"
[ "$proxy_forward" = "0" ] || core_cmd="${core_cmd} --proxy-forward-by-system"
[ "$accept_dns" = "0" ] || core_cmd="${core_cmd} --accept-dns true"
[ "$private_mode" = "0" ] || core_cmd="${core_cmd} --private-mode true"
[ "$quic_proxy" = "0" ] || core_cmd="${core_cmd} --enable-quic-proxy"
[ "$quic_input" = "0" ] || core_cmd="${core_cmd} --disable-quic-input"
[ -z "$foreign_relay_bps_limit" ] || core_cmd="${core_cmd} --foreign-relay-bps-limit $foreign_relay_bps_limit"
if [ -n "$encryption_algorithm" ] && [ "$encryption_algorithm" != "aes-gcm" ]; then
core_cmd="${core_cmd} --encryption-algorithm ${encryption_algorithm}"
fi
[ "$p2p_only" = "0" ] || core_cmd="${core_cmd} --p2p-only"
[ "$disable_tcp" = "0" ] || core_cmd="${core_cmd} --disable-tcp-hole-punching"
[ "$disable_udp" = "0" ] || core_cmd="${core_cmd} --disable-udp-hole-punching"
[ "$disable_sym" = "0" ] || core_cmd="${core_cmd} --disable-sym-hole-punching"
[ "$disable_relay_kcp" = "0" ] || core_cmd="${core_cmd} --disable-relay-kcp true"
[ "$relay_kcp" = "0" ] || core_cmd="${core_cmd} --enable-relay-foreign-network-kcp true"
[ "$disable_relay_quic" = "0" ] || core_cmd="${core_cmd} --disable-relay-quic true"
[ "$relay_quic" = "0" ] || core_cmd="${core_cmd} --enable-relay-foreign-network-quic true"
[ -z "$udp_white_port" ] || core_cmd="${core_cmd} --udp-whitelist $udp_white_port"
[ -z "$tcp_white_port" ] || core_cmd="${core_cmd} --tcp-whitelist $tcp_white_port"
# EasyTier 2.7.0 新增的常用参数
[ -z "$tld_dns_zone" ] || core_cmd="${core_cmd} --tld-dns-zone $tld_dns_zone"
[ -z "$instance_recv_bps_limit" ] || core_cmd="${core_cmd} --instance-recv-bps-limit $instance_recv_bps_limit"
[ -z "$socket_mark" ] || core_cmd="${core_cmd} --socket-mark $socket_mark"
[ "$disable_upnp" = "0" ] || core_cmd="${core_cmd} --disable-upnp"
[ "$lazy_p2p" = "0" ] || core_cmd="${core_cmd} --lazy-p2p"
[ "$need_p2p" = "0" ] || core_cmd="${core_cmd} --need-p2p"
# 自定义 STUN 服务器,可配置多条
if [ -n "$stun_servers" ] ; then
for stun_server in $(cat /etc/config/easytier | grep 'list stun_servers' | awk -F 'list stun_servers' '{print $2}' | sed "s/'/\n/g" | tr -d " ' "); do
core_cmd="${core_cmd} --stun-servers $stun_server"
done
fi
if [ -n "$tcp_stun_servers" ] ; then
for tcp_stun_server in $(cat /etc/config/easytier | grep 'list tcp_stun_servers' | awk -F 'list tcp_stun_servers' '{print $2}' | sed "s/'/\n/g" | tr -d " ' "); do
core_cmd="${core_cmd} --tcp-stun-servers $tcp_stun_server"
done
fi
if [ -n "$extra_args" ] ; then
while IFS= read -r extra_arg; do
[ -n "$extra_arg" ] && core_cmd="${core_cmd} $extra_arg"
done <<EOF
$(sed -n "s/^[[:space:]]*list[[:space:]]\\+extra_args[[:space:]]\\+'\\(.*\\)'[[:space:]]*$/\\1/p" /etc/config/easytier)
EOF
fi
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 运行 ${easytierbin} ${core_cmd} --console-log-level ${log}" >>/tmp/easytier.log
fi
if [ "$etcmd" = "web" ] ; then
#WEB控制台启动
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 运行 ${easytierbin} -w ${web_config}" >>/tmp/easytier.log
[ -f /etc/easytier/et_machine_id ] || touch /etc/easytier/et_machine_id
if [ ! -s /etc/easytier/et_machine_id ]; then
cat /proc/sys/kernel/random/uuid > /etc/easytier/et_machine_id
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 生成新的 UUID 到 /etc/easytier/et_machine_id" >>/tmp/easytier.log
fi
et_uuid="$(cat /etc/easytier/et_machine_id | tr -d ' \n')"
[ -z "$et_uuid" ] || core_cmd="${core_cmd} --machine-id $et_uuid"
# EasyTier 2.7.0 起 -w 必须填写完整 URL(例如 udp://config-server.easytier.cn:22020/账户名),
# 旧版只填账户名的写法会解析失败并让整个进程退出,这里跳过 Web 客户端并提示用户修改
case "$web_config" in
"")
;;
*://*)
core_cmd="${core_cmd} -w $web_config"
;;
*)
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : Web 服务器地址 ${web_config} 不是完整 URL,EasyTier 2.7.0 起必须填写完整地址(例如 udp://config-server.easytier.cn:22020/账户名),已跳过 Web 客户端启动;请在界面把 Web 服务器地址改为完整地址" >>/tmp/easytier.log
;;
esac
[ -z "$desvice_name" ] || core_cmd="${core_cmd} --hostname $(shell_quote "$desvice_name")"
fi
procd_set_param command /bin/sh -c "
cd /tmp ; ${easytierbin} ${core_cmd} --console-log-level ${log} >> /tmp/easytier.log 2>&1 &
ET_CORE_PID=\$!
{
while true; do
LOG_SIZE=\$(ls -l /tmp/easytier.log | awk '{print int(\$5/1024)}')
if [ \$LOG_SIZE -gt 5120 ]; then
tail -n 500 /tmp/easytier.log > /tmp/easytier.log.tmp
: > /tmp/easytier.log
cat /tmp/easytier.log.tmp >> /tmp/easytier.log
rm -f /tmp/easytier.log.tmp
fi
sleep 60
done
} &
LOG_MANAGEMENT_PID=\$!
trap \"kill -TERM \$ET_CORE_PID; kill -TERM \$LOG_MANAGEMENT_PID; exit\" SIGINT SIGTERM EXIT
wait \$ET_CORE_PID
"
fi
procd_set_param limits core="unlimited"
procd_set_param limits nofile="1000000 1000000"
procd_set_param stdout 1
procd_set_param stderr 1
# procd 进程守护参数:threshold=3600 秒、timeout=5 秒、retry=20 次
# 存活满 1 小时后崩溃计数归零;1 小时内崩溃超过 20 次(即第 21 次)才判定崩溃循环并放弃拉起,
# 避免参数配置错误这类必然失败的场景无限重启刷日志、空烧 CPU
procd_set_param respawn 3600 5 20
procd_close_instance
# 不再自动放行 SOCKS5 端口到 WAN —— 无认证 SOCKS5 代理暴露给公网有严重安全风险
# 如需公网访问,请手动在 LuCI 防火墙页面添加规则
# 如需恢复自动放行,去掉下面各行行首的 # 即可
# if [ ! -z "$socks_port" ] ; then
# echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 添加防火墙规则 easytier_socks5 放行端口 ${socks_port} " >>/tmp/easytier.log
# uci -q delete firewall.easytier_socks5
# uci set firewall.easytier_socks5=rule
# uci set firewall.easytier_socks5.name="easytier_socks5"
# uci set firewall.easytier_socks5.target="ACCEPT"
# uci set firewall.easytier_socks5.src="wan"
# uci set firewall.easytier_socks5.proto="tcp"
# uci set firewall.easytier_socks5.dest_port="$socks_port"
# uci set firewall.easytier_socks5.enabled="1"
# fi
if [ "$listenermode" = "ON" ] || [ "$etcmd" = "web" ] ; then
if [ -z "$tcp_port" ] && [ -z "$ws_port" ] && [ -z "$wss_port" ] && [ -z "$wg_port" ] ; then
tcp_port="11010"
ws_port="11011"
wss_port="11012"
wg_port="11011"
fi
fi
set_firewall
sysctl -w net.ipv4.ip_forward=1 >/dev/null 2>&1
[ ! -z "$checkip" ] && check
echo `date +%s` > /tmp/easytier_time
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 启动完成!" >>/tmp/easytier.log
}
start_web() {
webbin="$(uci -q get easytier.@easytier[0].webbin)"
[ -z "$webbin" ] && webbin="/usr/bin/easytier-web" && uci -q set easytier.@easytier[0].webbin=/usr/bin/easytier-web
path=$(dirname "$webbin")
if [ -f /tmp/easytier-web-embed ] ; then
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 找到上传的easytier-web程序,替换${webbin} " >>/tmp/easytierweb.log
mv -f /tmp/easytier-web-embed "$webbin"
fi
if [ ! -f "$webbin" ] || [ "$(($($webbin -h 2>&1 | wc -l)))" -lt 3 ] ; then
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : $webbin 不存在或程序不完整,开始在线下载..." >>/tmp/easytierweb.log
check_bin
fi
if [ -f "$webbin" ] ; then
[ ! -x "$webbin" ] && chmod +x "$webbin"
fi
if [ ! -f "$webbin" ] || [ "$($webbin -h 2>&1 | wc -l)" -lt 3 ] ; then
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 未找到${webbin}程序或程序不适配当前架构,请上传安装后再启动! " >>/tmp/easytierweb.log
return 1
fi
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 开始启动${webbin} " >>/tmp/easytierweb.log
db_path="$(uci -q get easytier.@easytier[0].web_db_path)"
web_protocol="$(uci -q get easytier.@easytier[0].web_protocol)"
web_port="$(uci -q get easytier.@easytier[0].web_port)"
api_port="$(uci -q get easytier.@easytier[0].web_api_port)"
html_port="$(uci -q get easytier.@easytier[0].web_html_port)"
weblog="$(uci -q get easytier.@easytier[0].web_weblog)"
weblog="${weblog:-off}"
api_host="$(uci -q get easytier.@easytier[0].web_api_host)"
geoip_db="$(uci -q get easytier.@easytier[0].web_geoip_db)"
fw_web="$(uci -q get easytier.@easytier[0].web_fw_web || echo 0)"
fw_api="$(uci -q get easytier.@easytier[0].web_fw_api || echo 0)"
api_addr="$(uci -q get easytier.@easytier[0].web_api_addr)"
html_addr="$(uci -q get easytier.@easytier[0].web_html_addr)"
disable_registration="$(uci -q get easytier.@easytier[0].web_disable_registration || echo 0)"
allow_auto_create_user="$(uci -q get easytier.@easytier[0].web_allow_auto_create_user || echo 0)"
# EasyTier 2.7.0 新增的 web 参数
heartbeat_min_response_ms="$(uci -q get easytier.@easytier[0].web_heartbeat_min_response_ms)"
heartbeat_timeout_ms="$(uci -q get easytier.@easytier[0].web_heartbeat_timeout_ms)"
gateway_peer_url="$(uci -q get easytier.@easytier[0].web_gateway_peer_url)"
gateway_relay_data="$(uci -q get easytier.@easytier[0].web_gateway_relay_data || echo 0)"
# OIDC配置
oidc_enabled="$(uci -q get easytier.@easytier[0].web_oidc_enabled || echo 0)"
oidc_issuer_url="$(uci -q get easytier.@easytier[0].web_oidc_issuer_url)"
oidc_client_id="$(uci -q get easytier.@easytier[0].web_oidc_client_id)"
oidc_client_secret="$(uci -q get easytier.@easytier[0].web_oidc_client_secret)"
oidc_redirect_url="$(uci -q get easytier.@easytier[0].web_oidc_redirect_url)"
oidc_username_claim="$(uci -q get easytier.@easytier[0].web_oidc_username_claim)"
oidc_scopes="$(uci -q get easytier.@easytier[0].web_oidc_scopes)"
oidc_frontend_base_url="$(uci -q get easytier.@easytier[0].web_oidc_frontend_base_url)"
oidc_disable_pkce="$(uci -q get easytier.@easytier[0].web_oidc_disable_pkce || echo 0)"
# Webhook配置
webhook_enabled="$(uci -q get easytier.@easytier[0].web_webhook_enabled || echo 0)"
webhook_url="$(uci -q get easytier.@easytier[0].web_webhook_url)"
webhook_secret="$(uci -q get easytier.@easytier[0].web_webhook_secret)"
internal_auth_token="$(uci -q get easytier.@easytier[0].web_internal_auth_token)"
web_instance_id="$(uci -q get easytier.@easytier[0].web_web_instance_id)"
web_instance_api_base_url="$(uci -q get easytier.@easytier[0].web_web_instance_api_base_url)"
procd_open_instance "easytier_web"
get_tz
[ -z "$SET_TZ" ] || procd_set_param env TZ="$SET_TZ"
web_cmd=""
[ -z "$db_path" ] || web_cmd="${web_cmd} -d $db_path"
[ -z "$web_protocol" ] || web_cmd="${web_cmd} -p $web_protocol"
[ -z "$web_port" ] || web_cmd="${web_cmd} -c $web_port"
[ -z "$api_port" ] || web_cmd="${web_cmd} -a $api_port"
[ -z "$api_host" ] || web_cmd="${web_cmd} --api-host $api_host"
[ -z "$geoip_db" ] || web_cmd="${web_cmd} --geoip-db $geoip_db"
if [ -z "$html_port" ] ; then
web_cmd="${web_cmd} --no-web"
else
web_cmd="${web_cmd} -l $html_port"
fi
# 基础配置参数
[ -n "$api_addr" ] && [ "$api_addr" != "0.0.0.0" ] && web_cmd="${web_cmd} --api-server-addr $api_addr"
[ -n "$html_addr" ] && [ "$html_addr" != "0.0.0.0" ] && web_cmd="${web_cmd} --web-server-addr $html_addr"
[ "$disable_registration" = "1" ] && web_cmd="${web_cmd} --disable-registration"
[ "$allow_auto_create_user" = "1" ] && web_cmd="${web_cmd} --allow-auto-create-user"
# EasyTier 2.7.0 新增的 web 参数
[ -z "$heartbeat_min_response_ms" ] || web_cmd="${web_cmd} --heartbeat-min-response-ms $heartbeat_min_response_ms"
[ -z "$heartbeat_timeout_ms" ] || web_cmd="${web_cmd} --heartbeat-timeout-ms $heartbeat_timeout_ms"
[ -z "$gateway_peer_url" ] || web_cmd="${web_cmd} --gateway-peer-url $gateway_peer_url"
[ "$gateway_relay_data" = "1" ] && web_cmd="${web_cmd} --gateway-relay-data true"
# OIDC配置参数
if [ "$oidc_enabled" = "1" ] ; then
[ -z "$oidc_issuer_url" ] || web_cmd="${web_cmd} --oidc-issuer-url $oidc_issuer_url"
[ -z "$oidc_client_id" ] || web_cmd="${web_cmd} --oidc-client-id $oidc_client_id"
[ -z "$oidc_client_secret" ] || web_cmd="${web_cmd} --oidc-client-secret $oidc_client_secret"
[ -z "$oidc_redirect_url" ] || web_cmd="${web_cmd} --oidc-redirect-url $oidc_redirect_url"
[ -z "$oidc_username_claim" ] || web_cmd="${web_cmd} --oidc-username-claim $oidc_username_claim"
[ -z "$oidc_scopes" ] || web_cmd="${web_cmd} --oidc-scopes \"$oidc_scopes\""
[ -z "$oidc_frontend_base_url" ] || web_cmd="${web_cmd} --oidc-frontend-base-url $oidc_frontend_base_url"
[ "$oidc_disable_pkce" = "1" ] && web_cmd="${web_cmd} --oidc-disable-pkce"
fi
# Webhook配置参数
if [ "$webhook_enabled" = "1" ] ; then
[ -z "$webhook_url" ] || web_cmd="${web_cmd} --webhook-url $webhook_url"
[ -z "$webhook_secret" ] || web_cmd="${web_cmd} --webhook-secret $webhook_secret"
[ -z "$internal_auth_token" ] || web_cmd="${web_cmd} --internal-auth-token $internal_auth_token"
[ -z "$web_instance_id" ] || web_cmd="${web_cmd} --web-instance-id $web_instance_id"
[ -z "$web_instance_api_base_url" ] || web_cmd="${web_cmd} --web-instance-api-base-url $web_instance_api_base_url"
fi
if [ "$weblog" != "off" ] ; then
web_cmd="${web_cmd} --console-log-level $weblog"
fi
procd_set_param command /bin/sh -c "
cd /tmp ; ${webbin} ${web_cmd} >> /tmp/easytierweb.log 2>&1 &
ET_WEB_PID=\$!
{
while true; do
LOG_SIZE=\$(ls -l /tmp/easytierweb.log | awk '{print int(\$5/1024)}')
if [ \$LOG_SIZE -gt 5120 ]; then
tail -n 500 /tmp/easytierweb.log > /tmp/easytierweb.log.tmp
: > /tmp/easytierweb.log
cat /tmp/easytierweb.log.tmp >> /tmp/easytierweb.log
rm -f /tmp/easytierweb.log.tmp
fi
sleep 60
done
} &
LOG_MANAGEMENT_PID=\$!
trap \"kill -TERM \$ET_WEB_PID; kill -TERM \$LOG_MANAGEMENT_PID; exit\" SIGINT SIGTERM EXIT
wait \$ET_WEB_PID
"
procd_set_param stdout 1
procd_set_param stderr 1
# procd 进程守护参数:threshold=3600 秒、timeout=5 秒、retry=20 次
# 存活满 1 小时后崩溃计数归零;1 小时内崩溃超过 20 次(即第 21 次)才判定崩溃循环并放弃拉起
procd_set_param respawn 3600 5 20
procd_close_instance
if [ ! -z "$web_port" ] && [ "$fw_web" = "1" ] ; then
echo "$(date '+%Y-%m-%d %H:%M:%S') 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 [ ! -z "$api_port" ] && [ "$fw_api" = "1" ] ; then
echo "$(date '+%Y-%m-%d %H:%M:%S') 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 [ ! -z "$html_port" ] && [ "$fw_api" = "1" ] && [ "$html_port" != "$api_port" ] ; then
echo "$(date '+%Y-%m-%d %H:%M:%S') 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
echo `date +%s` > /tmp/easytierweb_time
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 启动完成! " >>/tmp/easytierweb.log
}
start_service() {
echo "start.."
cputype=$(uname -ms | tr ' ' '_' | tr '[A-Z]' '[a-z]')
[ -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
mipstype=$(echo -n I | hexdump -o 2>/dev/null | awk '{ print substr($2,6,1); exit}')
[ "$mipstype" = "0" ] && cpucore="mips" || cpucore="mipsel"
fi
echo "" >/tmp/easytier.log
echo "" >/tmp/easytierweb.log
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
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
# 延迟重载网络配置,避免与拨号等网络事件冲突
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
}
stop_service() {
echo "stop.."
if [ "$(uci -q get easytier.@easytier[0].enabled)" = "0" ] ; then
pgrep -f easytier_check | xargs kill -9 >/dev/null 2>&1
ps | grep 'easytier-core' | grep -v grep | awk '{print $1}' | xargs kill >/dev/null 2>&1
ps | grep 'easytier-core' | grep -v grep | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1
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
# 延迟重载,避免与网络事件冲突
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
echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : easytier-core 停止运行" >>/tmp/easytier.log
fi
if [ "$(uci -q get easytier.@easytier[0].web_enabled)" = "0" ] ; then
ps | grep 'easytier-web' | grep -v grep | awk '{print $1}' | xargs kill >/dev/null 2>&1
ps | grep 'easytier-web' | grep -v grep | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1
uci -q delete firewall.easytier_webserver
uci -q delete firewall.easytier_webapi
uci -q delete firewall.easytier_webhtml
fi
}
reload_service() {
stop
start
}
service_triggers() {
procd_add_reload_trigger "easytier"
#如果WAN网络接口上线则触发重新启动easytier
# procd_add_interface_trigger "interface.*.up" wan /etc/init.d/easytier reload
}