一、vps1
#!/usr/bin/env bash
set -euo pipefail
# ==================================================
# 配置区:按需修改
# ==================================================
# VPS2 iperf3 服务端 IP
REMOTE_HOST="你的VPS2_IP"
# VPS2 iperf3 服务端口
IPERF_PORT=5201
# iperf3 测试限速:15 Mbps
LIMIT_MBIT=15
# iperf3 单次运行时长,脚本会根据 frps 是否空闲主动停止它
IPERF_DURATION=86400
# 需要监控的 frps 业务端口
# 不要写 iperf3 的 5201
FRPS_TCP_PORTS=(7000 80 443 6000 6001)
# 如果没有 UDP 映射,保持为空
FRPS_UDP_PORTS=()
# 每几秒检查一次 frps 流量
CHECK_INTERVAL=5
# 每 5 秒 frps 端口新增流量超过 5MB,才算有业务流量
ACTIVE_BYTES_THRESHOLD=5242880
# 连续多少秒没有达到流量阈值后,停止 iperf3
IDLE_STOP_SECONDS=60
# 日志文件
LOG_FILE="/var/log/frps-traffic-iperf3.log"
# systemd 服务名
SERVICE_NAME="frps-traffic-iperf3.service"
# 脚本安装路径
SCRIPT_PATH="/usr/local/bin/frps-traffic-iperf3.sh"
# iptables 监控链名称
CHAIN_NAME="FRPS_TRAFFIC_MON"
IPERF_PID=""
# ==================================================
# 通用函数
# ==================================================
log() {
echo "[$(date '+%F %T')] $*" | tee -a "$LOG_FILE"
}
need_root() {
if [ "$(id -u)" -ne 0 ]; then
echo "请使用 root 运行"
exit 1
fi
}
check_command() {
command -v "$1" >/dev/null 2>&1 || {
echo "缺少命令: $1"
echo "Debian/Ubuntu 可执行: apt update && apt install -y iperf3 iptables"
exit 1
}
}
# ==================================================
# iptables 流量监控
# ==================================================
setup_iptables_monitor() {
log "初始化 frps 端口流量监控规则"
iptables -N "$CHAIN_NAME" 2>/dev/null || true
iptables -F "$CHAIN_NAME"
for port in "${FRPS_TCP_PORTS[@]}"; do
iptables -A "$CHAIN_NAME" -p tcp --sport "$port" -m comment --comment frpsmon -j RETURN
iptables -A "$CHAIN_NAME" -p tcp --dport "$port" -m comment --comment frpsmon -j RETURN
done
for port in "${FRPS_UDP_PORTS[@]}"; do
iptables -A "$CHAIN_NAME" -p udp --sport "$port" -m comment --comment frpsmon -j RETURN
iptables -A "$CHAIN_NAME" -p udp --dport "$port" -m comment --comment frpsmon -j RETURN
done
iptables -A "$CHAIN_NAME" -j RETURN
iptables -C INPUT -j "$CHAIN_NAME" 2>/dev/null || iptables -I INPUT 1 -j "$CHAIN_NAME"
iptables -C OUTPUT -j "$CHAIN_NAME" 2>/dev/null || iptables -I OUTPUT 1 -j "$CHAIN_NAME"
log "frps 端口流量监控规则已启用"
}
get_frps_bytes() {
iptables -L "$CHAIN_NAME" -v -x -n 2>/dev/null \
| awk '/frpsmon/ {sum += $2} END {print sum+0}'
}
remove_iptables_monitor() {
iptables -D INPUT -j "$CHAIN_NAME" 2>/dev/null || true
iptables -D OUTPUT -j "$CHAIN_NAME" 2>/dev/null || true
iptables -F "$CHAIN_NAME" 2>/dev/null || true
iptables -X "$CHAIN_NAME" 2>/dev/null || true
}
# ==================================================
# iperf3 控制
# ==================================================
iperf3_running() {
[ -n "${IPERF_PID:-}" ] && kill -0 "$IPERF_PID" 2>/dev/null
}
start_iperf3() {
if iperf3_running; then
return 0
fi
log "检测到 frps 有实际流量,启动 iperf3"
log "iperf3: VPS1 -> VPS2 ${REMOTE_HOST}:${IPERF_PORT}, TCP, ${LIMIT_MBIT} Mbps"
iperf3 \
-c "$REMOTE_HOST" \
-p "$IPERF_PORT" \
-b "${LIMIT_MBIT}M" \
-t "$IPERF_DURATION" \
-i 5 \
>> "$LOG_FILE" 2>&1 &
IPERF_PID=$!
log "iperf3 已启动,PID=${IPERF_PID}"
}
stop_iperf3() {
if iperf3_running; then
log "frps 连续无有效流量,停止 iperf3,PID=${IPERF_PID}"
kill "$IPERF_PID" 2>/dev/null || true
wait "$IPERF_PID" 2>/dev/null || true
IPERF_PID=""
log "iperf3 已停止"
fi
}
cleanup_runtime() {
stop_iperf3
log "脚本运行进程退出"
}
# ==================================================
# 主运行逻辑
# ==================================================
run_monitor() {
need_root
check_command iptables
check_command iperf3
check_command awk
touch "$LOG_FILE"
setup_iptables_monitor
log "开始监控 frps 实际流量"
log "VPS2 iperf3: ${REMOTE_HOST}:${IPERF_PORT}"
log "iperf3 限速: ${LIMIT_MBIT} Mbps"
log "TCP ports: ${FRPS_TCP_PORTS[*]:-none}"
log "UDP ports: ${FRPS_UDP_PORTS[*]:-none}"
log "检查间隔: ${CHECK_INTERVAL}s"
log "流量阈值: ${ACTIVE_BYTES_THRESHOLD} bytes / ${CHECK_INTERVAL}s"
log "空闲停止: ${IDLE_STOP_SECONDS}s"
trap cleanup_runtime EXIT INT TERM
prev_bytes=$(get_frps_bytes)
idle_seconds=0
while true; do
sleep "$CHECK_INTERVAL"
current_bytes=$(get_frps_bytes)
delta=$((current_bytes - prev_bytes))
prev_bytes="$current_bytes"
if [ "$delta" -ge "$ACTIVE_BYTES_THRESHOLD" ]; then
idle_seconds=0
log "frps 有有效流量: ${delta} bytes / ${CHECK_INTERVAL}s"
start_iperf3
else
idle_seconds=$((idle_seconds + CHECK_INTERVAL))
log "frps 无有效流量: ${delta} bytes / ${CHECK_INTERVAL}s, idle=${idle_seconds}s"
if [ "$idle_seconds" -ge "$IDLE_STOP_SECONDS" ]; then
stop_iperf3
fi
fi
done
}
# ==================================================
# 安装 / 卸载 / 状态
# ==================================================
install_service() {
need_root
check_command systemctl
check_command iperf3
check_command iptables
chmod +x "$SCRIPT_PATH"
cat > "/etc/systemd/system/${SERVICE_NAME}" <<EOF
[Unit]
Description=Run iperf3 when frps has real traffic
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=${SCRIPT_PATH} run
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now "$SERVICE_NAME"
echo "已创建并启动 systemd 服务: ${SERVICE_NAME}"
echo
systemctl --no-pager status "$SERVICE_NAME"
}
uninstall_service() {
need_root
systemctl disable --now "$SERVICE_NAME" 2>/dev/null || true
rm -f "/etc/systemd/system/${SERVICE_NAME}"
systemctl daemon-reload
remove_iptables_monitor
echo "已卸载服务并清理 iptables 监控规则"
}
show_status() {
systemctl --no-pager status "$SERVICE_NAME" || true
}
show_logs() {
tail -f "$LOG_FILE"
}
case "${1:-run}" in
run)
run_monitor
;;
install)
install_service
;;
uninstall)
uninstall_service
;;
status)
show_status
;;
logs)
show_logs
;;
*)
echo "用法:"
echo " $0 run 前台运行监控"
echo " $0 install 创建 systemd 服务并开机自启"
echo " $0 uninstall 停止并卸载 systemd 服务"
echo " $0 status 查看服务状态"
echo " $0 logs 查看日志"
exit 1
;;
esac
二、VPS2
VPS1_IP="你的VPS1_IP" PORT=5201 bash -s <<'EOF'
set -e
echo "[1/5] 安装 iperf3..."
if command -v apt-get >/dev/null 2>&1; then
apt-get update -y
DEBIAN_FRONTEND=noninteractive apt-get install -y iperf3
elif command -v dnf >/dev/null 2>&1; then
dnf install -y iperf3
elif command -v yum >/dev/null 2>&1; then
yum install -y epel-release || true
yum install -y iperf3
else
echo "不支持的系统:未找到 apt-get / dnf / yum"
exit 1
fi
echo "[2/5] 创建 iperf3 systemd 服务..."
cat > /etc/systemd/system/iperf3-server.service <<SERVICE
[Unit]
Description=iperf3 Server
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/iperf3 -s -p ${PORT}
Restart=always
RestartSec=3
DynamicUser=yes
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
[Install]
WantedBy=multi-user.target
SERVICE
echo "[3/5] 启动 iperf3-server..."
systemctl daemon-reload
systemctl enable --now iperf3-server.service
echo "[4/5] 配置防火墙,仅允许 VPS1 访问 ${PORT}/tcp..."
if command -v ufw >/dev/null 2>&1; then
ufw allow from "$VPS1_IP" to any port "$PORT" proto tcp || true
ufw reload || true
elif command -v firewall-cmd >/dev/null 2>&1; then
firewall-cmd --permanent --add-rich-rule="rule family=\"ipv4\" source address=\"$VPS1_IP\" port protocol=\"tcp\" port=\"$PORT\" accept" || true
firewall-cmd --reload || true
else
echo "未检测到 ufw/firewalld,跳过系统防火墙配置"
fi
echo "[5/5] 检查服务状态..."
systemctl --no-pager status iperf3-server.service
echo
echo "完成。VPS2 已启动 iperf3-server。"
echo "监听端口: ${PORT}/tcp"
echo "允许来源: ${VPS1_IP}"
echo
echo "如果云服务商有安全组,也要放行:TCP ${PORT},来源 ${VPS1_IP}/32"
EOF