#!/bin/bash # MSS 值扫描:1360 可能不是最优。 # # 现状:MTU 修复后 15 分钟长测 78%(最长连续失败从 68 秒降到 15 秒)。 # 失败是孤立单次超时,不是持续中断。 # MSS 夹多少最合适需要实测 —— 夹太小包变小、来回变多; # 夹太大又超出路径能过的尺寸。 set -u URL=https://relay.xxmxxs.top RELAY_DIR=/root/lanremote-relay PROBE=24 clear_mss() { for chain in OUTPUT POSTROUTING; do while iptables -t mangle -C "$chain" -p tcp --tcp-flags SYN,RST SYN \ -j TCPMSS --set-mss 1360 2>/dev/null; do iptables -t mangle -D "$chain" -p tcp --tcp-flags SYN,RST SYN \ -j TCPMSS --set-mss 1360 2>/dev/null || break done while iptables -t mangle -C "$chain" -p tcp --tcp-flags SYN,RST SYN \ -j TCPMSS --set-mss 1300 2>/dev/null; do iptables -t mangle -D "$chain" -p tcp --tcp-flags SYN,RST SYN \ -j TCPMSS --set-mss 1300 2>/dev/null || break done while iptables -t mangle -C "$chain" -p tcp --tcp-flags SYN,RST SYN \ -j TCPMSS --set-mss 1400 2>/dev/null; do iptables -t mangle -D "$chain" -p tcp --tcp-flags SYN,RST SYN \ -j TCPMSS --set-mss 1400 2>/dev/null || break done while iptables -t mangle -C "$chain" -p tcp --tcp-flags SYN,RST SYN \ -j TCPMSS --set-mss 1440 2>/dev/null; do iptables -t mangle -D "$chain" -p tcp --tcp-flags SYN,RST SYN \ -j TCPMSS --set-mss 1440 2>/dev/null || break done done } set_mss() { local value="$1" clear_mss if [ "$value" != "0" ]; then for chain in OUTPUT POSTROUTING; do iptables -t mangle -A "$chain" -p tcp --tcp-flags SYN,RST SYN \ -j TCPMSS --set-mss "$value" 2>/dev/null done fi } measure() { local ok=0 bad=0 consec=0 maxconsec=0 for i in $(seq 1 $PROBE); do c=$(timeout 12 curl -4 -s -o /dev/null -w '%{http_code}' \ -H 'User-Agent: LanRemote/1.4.0' "$URL/v1/health" 2>/dev/null) c=${c:-000} if [ "$c" = "200" ]; then ok=$((ok+1)); consec=0 else bad=$((bad+1)); consec=$((consec+1)) [ "$consec" -gt "$maxconsec" ] && maxconsec=$consec fi sleep 2 done echo "$ok|$maxconsec" } : > /root/mss_result.txt for mss in 0 1300 1360 1400 1440; do label=$( [ "$mss" = "0" ] && echo "不夹(1500)" || echo "MSS $mss" ) set_mss "$mss" # 让新参数生效:重启隧道 systemctl restart lanremote-tunnel >/dev/null 2>&1 sleep 30 result=$(measure) ok=$(echo "$result" | cut -d'|' -f1) mc=$(echo "$result" | cut -d'|' -f2) pct=$((ok * 100 / PROBE)) printf " %-12s 可用 %2d/%d = %3d%% 最长连续失败 %s 次\n" \ "$label" "$ok" "$PROBE" "$pct" "$mc" echo "$label|$pct|$mc" >> /root/mss_result.txt done echo echo "===== 汇总(按可用率排序)=====" sort -t'|' -k2 -rn /root/mss_result.txt | while IFS='|' read -r label pct mc; do printf " %-12s %3d%% (最长连败 %s)\n" "$label" "$pct" "$mc" done BEST=$(sort -t'|' -k2 -rn /root/mss_result.txt | head -1) BEST_LABEL=$(echo "$BEST" | cut -d'|' -f1) BEST_PCT=$(echo "$BEST" | cut -d'|' -f2) echo echo " 最优:$BEST_LABEL($BEST_PCT%)" # 恢复成最优值 case "$BEST_LABEL" in "不夹(1500)") FINAL=0 ;; "MSS 1300") FINAL=1300 ;; "MSS 1360") FINAL=1360 ;; "MSS 1400") FINAL=1400 ;; "MSS 1440") FINAL=1440 ;; *) FINAL=1360 ;; esac set_mss "$FINAL" if [ "$FINAL" != "0" ]; then sed -i "s/^MSS_VALUE=.*/MSS_VALUE=$FINAL/" "$RELAY_DIR/net-tune.sh" 2>/dev/null fi systemctl restart lanremote-tunnel >/dev/null 2>&1 echo " 已把最优值写进 net-tune.sh 并重启隧道" grep '^MSS_VALUE=' "$RELAY_DIR/net-tune.sh" 2>/dev/null | sed 's/^/ /'