Files
ykxmz/_build/longstab.sh
T
xmz7891 d4f335b8f9 管理页新增:允许/禁止新设备接入 + 修改设备配对码
== 功能一:允许新设备接入开关 ==

关掉之后只有已经登记过的电脑能继续上线,没见过的新设备一律拒绝。
状态存在 relay_state.json 里,重启不丢。

判断新设备用的是 deviceId,不是配对码 ——
这一点很关键:管理员给老设备改过码之后,
那台设备必须仍然能进来;按码判断的话它会被自己的开关挡在外面。
测试里专门有一条 A3b 守这个行为。

被拒时回 blocked=True,让客户端能区分被管理员挡了
和配对码冲突,而不是去匹配中文错误文案(文案一改就坏)。

== 功能二:修改任意设备的配对码 ==

管理页每台设备一个「改码」按钮,填 6 位数字即生效。
要点:
  * 新旧码冲突检查
  * 旧码映射必须删掉,否则变成孤儿条目,
    管理页配对码占用的数字会虚高
  * 改码踢掉该设备当前会话(会话绑在码上)
  * 立刻持久化

== 顺手修掉两个真 bug ==

1. 改码功能一上线就 500:Session 用了 __slots__,
   根本没有 session_id 属性(会话是以 token 为 key 存在 dict 里的),
   写 s.session_id 直接 AttributeError。
   改成遍历 sessions.items() 拿 key。

2. snapshot() 里有同样的错(清理超时设备那段):
   平时 stale 列表是空的所以从没炸过,一旦真有设备超过 6 小时
   没上报就会 500。这次一起修了。

== 管理页 UI ==
  * 设备小节加了「允许新设备接入」勾选框
  * 每行加「改码」按钮(走 prompt,不引入弹窗层)
  * 改码按钮用 data-recode 而不是 data-device ——
    现有单台删除按 button.danger[data-device] 绑,
    带上 data-device 会被当成删除按钮,点改码变删设备。
    测试 C6 专门断言这一点。

== 测试 ==
新增 _tests/test_admin_device_control.py(23 项),
已注册进 _tests/verify_all.ps1 第 3e 阶段。
2026-10-07 17:01:14 +08:00

105 lines
4.1 KiB
Bash
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/bash
# 隧道长时稳定性测量(默认 30 分钟)
#
# 为什么要长时:
# 短测(60 次请求)看到的可用率都在 98~100%,看不出区别。
# 真实的失败是"某条隧道连接掉了、重连期间打在上面的请求失败",
# 这种事几十分钟才出现一两次 —— 必须跑长才能抓到。
#
# 记录:
# * 连接数采样(每 10 秒)—— 看有没有掉到配置值以下
# * 公网可用率采样(每 30 秒,从**本机**打,所以含设备自身 4G 的影响)
# * 隧道日志里的 重连 / 掉线 / dial 失败 事件
# * 事件时间线(哪一刻掉的)
#
# 用法: bash longstab.sh [分钟数] [标签]
set -u
BASE=https://relay.xxmxxs.top
UA='LanRemote/1.8.2'
MINUTES=${1:-30}
LABEL=${2:-run}
ROUNDS=$((MINUTES * 6)) # 每 10 秒一轮
OUT=/root/longstab_${LABEL}.txt
MARK=$(wc -l < /root/lanremote-relay/tunnel.log 2>/dev/null || echo 0)
echo "════════ 隧道长时稳定性 · $LABEL · ${MINUTES} 分钟 ════════" | tee "$OUT"
echo " 参数: $(grep -oE '\-\-protocol [a-z0-9]+|--ha-connections [0-9]+' /etc/systemd/system/lanremote-tunnel.service | tr '\n' ' ')" | tee -a "$OUT"
echo " MTU: $(cat /sys/class/net/wlan0/mtu)" | tee -a "$OUT"
echo " 开始: $(date '+%H:%M:%S') 共 $ROUNDS 轮" | tee -a "$OUT"
minc=999; maxc=0; sumc=0; nz=0
okA=0; totA=0; timesA=()
declare -a timeline
for r in $(seq 1 "$ROUNDS"); do
n=$(curl -s --max-time 4 http://127.0.0.1:20241/metrics 2>/dev/null \
| grep '^cloudflared_tunnel_ha_connections' | awk '{print $2}')
n=${n:-0}
[ "$n" -lt "$minc" ] && minc="$n"
[ "$n" -gt "$maxc" ] && maxc="$n"
sumc=$((sumc + n))
# 每 3 轮(30 秒)打一次公网
if [ $((r % 3)) -eq 0 ]; then
out=$(curl -s -o /dev/null -w '%{http_code} %{time_total}' --max-time 25 \
-H "User-Agent: $UA" "$BASE/v1/health")
c=$(echo "$out" | awk '{print $1}')
ms=$(echo "$out" | awk '{printf "%d", $2*1000}')
totA=$((totA + 1))
if [ "$c" = "200" ]; then
okA=$((okA + 1)); timesA+=("$ms")
else
timeline+=("$(date '+%H:%M:%S') HTTP $c (连接数 $n)")
printf " [%s] ✗ HTTP %s 连接数 %s\n" "$(date '+%H:%M:%S')" "$c" "$n" | tee -a "$OUT"
fi
# 连接数掉到配置值以下也要记
if [ "$n" -lt 10 ]; then
printf " [%s] ! 连接数只有 %s\n" "$(date '+%H:%M:%S')" "$n" | tee -a "$OUT"
fi
fi
sleep 10
done
echo | tee -a "$OUT"
echo "════════ 结果 ════════" | tee -a "$OUT"
echo " 连接数: 最低 $minc 最高 $maxc 平均 $((sumc / ROUNDS))(配置 10)" | tee -a "$OUT"
pct=$((okA * 100 / (totA > 0 ? totA : 1)))
echo " 公网可用率: $okA/$totA = ${pct}%" | tee -a "$OUT"
if [ "${#timesA[@]}" -gt 0 ]; then
printf '%s\n' "${timesA[@]}" | sort -n | awk '{
a[NR]=$1
} END {
printf " 耗时: 最小 %d 中位 %d P90 %d P99 %d 最大 %d ms\n",
a[1], a[int(NR/2)+1], a[int(NR*0.9)+1], a[int(NR*0.99)+1], a[NR]
}' | tee -a "$OUT"
fi
echo | tee -a "$OUT"
echo " 这段时间的隧道事件:" | tee -a "$OUT"
for kw in 'Registered tunnel connection' 'Lost connection' 'Failed to dial' 'i/o timeout' 'no recent network activity'; do
c=$(tail -n +$((MARK+1)) /root/lanremote-relay/tunnel.log 2>/dev/null | grep -c "$kw" || echo 0)
printf " %-34s %s 次\n" "$kw" "$c" | tee -a "$OUT"
done
echo | tee -a "$OUT"
echo " 掉线/重连时间线(最后 12 条):" | tee -a "$OUT"
tail -n +$((MARK+1)) /root/lanremote-relay/tunnel.log 2>/dev/null \
| grep -E 'Lost connection|Registered tunnel connection' | tail -12 \
| sed 's/^/ /' | tee -a "$OUT"
echo | tee -a "$OUT"
echo " 期间有没有 HTTP 失败:" | tee -a "$OUT"
if [ "${#timeline[@]}" -gt 0 ]; then
printf ' %s\n' "${timeline[@]}" | tee -a "$OUT"
else
echo " 没有" | tee -a "$OUT"
fi
echo | tee -a "$OUT"
echo " watchdog 最近 5 行:" | tee -a "$OUT"
tail -5 /root/lanremote-relay/watchdog.log 2>/dev/null | sed 's/^/ /' | tee -a "$OUT"
echo | tee -a "$OUT"
echo " 存档: $OUT" | tee -a "$OUT"