JingMenBus/install_frp.sh
2026-02-06 18:10:21 +08:00

215 lines
5.2 KiB
Bash
Raw 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
set -euo pipefail
echo "=============================="
echo " FRPC 安装程序"
echo "=============================="
# ==========================================
# 0. 工具函数
# ==========================================
die() { echo "$*" >&2; exit 1; }
info() { echo "$*"; }
step() { echo "$*"; }
need_cmd() {
command -v "$1" >/dev/null 2>&1
}
# 统一下载:优先 wget其次 curl断点续传
download() {
local url="$1"
local out="$2"
if need_cmd wget; then
# -c: 断点续传
# -T: 超时
# -t: 重试次数
info "使用 wget 下载(支持断点续传)"
wget -c \
--timeout=20 \
--read-timeout=20 \
-t 0 \
"$url" -O "$out"
elif need_cmd curl; then
# -C - : 断点续传
# -f : HTTP 非 2xx 失败
# -L : 跟随重定向
# --retry-* : 抗抖动
info "使用 curl 下载(断点续传)"
curl -fL -C - \
--connect-timeout 20 \
--retry 0 \
--retry-delay 3 \
--retry-all-errors \
"$url" -o "$out"
else
die "系统中既没有 wget 也没有 curl无法下载$url"
fi
}
# ==========================================
# 1. 确保 sudo 权限
# ==========================================
if ! need_cmd sudo; then
die "系统未安装 sudo请用 root 执行该脚本"
fi
sudo -v
# ==========================================
# 2. 输入设备名
# ==========================================
read -r -p "请输入设备名称deviceName例如 z200_01 " deviceName
[ -n "${deviceName}" ] || die "设备名不能为空"
# 简单合法性校验:只允许字母数字下划线中划线
if ! [[ "$deviceName" =~ ^[A-Za-z0-9_-]+$ ]]; then
die "设备名不合法:仅允许字母/数字/_/-"
fi
echo ""
info "设备名:$deviceName"
echo ""
# ==========================================
# 3. 检测架构
# ==========================================
ARCH="$(uname -m)"
info "检测到架构:$ARCH"
case "$ARCH" in
aarch64) PKG="frp_0.65.0_linux_arm64.tar.gz" ;;
armv7l|armv7*) PKG="frp_0.65.0_linux_arm.tar.gz" ;;
x86_64|amd64) PKG="frp_0.65.0_linux_amd64.tar.gz" ;;
*) die "不支持架构:$ARCH" ;;
esac
BASE="http://36.153.162.171:20080/frp"
URL="$BASE/$PKG"
# ==========================================
# 4. 下载 / 解压(断电可恢复)
# ==========================================
FRP_DIR="/usr/local/frp"
FRPC_BIN="$FRP_DIR/frpc"
CACHE_DIR="/var/cache/frp"
PKG_PATH="$CACHE_DIR/$PKG"
if sudo test -x "$FRPC_BIN"; then
info "检测到本地已有 FRPC$FRPC_BIN(跳过下载)"
else
step "准备缓存目录:$CACHE_DIR"
sudo mkdir -p "$CACHE_DIR"
sudo chown "$(id -u):$(id -g)" "$CACHE_DIR"
if [ -f "$PKG_PATH" ]; then
info "检测到缓存文件,继续断点续传:$PKG_PATH"
else
info "缓存中不存在安装包,将开始下载"
fi
step "下载:$URL"
download "$URL" "$PKG_PATH"
info "下载完成:$PKG_PATH"
step "解压到:$FRP_DIR"
sudo mkdir -p "$FRP_DIR"
sudo tar -xzf "$PKG_PATH" -C "$FRP_DIR" --strip-components=1
sudo chmod +x "$FRPC_BIN" || true
sudo test -x "$FRPC_BIN" || die "解压后未找到可执行 frpc$FRPC_BIN"
info "解压完成"
# 可选:如果你希望节省空间,确认安装成功后再删
# sudo rm -f "$PKG_PATH"
fi
# ==========================================
# 5. 生成 frpc.toml
# ==========================================
PROXY_NAME="${deviceName}_stcp"
SECRET_KEY="${deviceName}_key"
step "生成配置 /etc/frp/frpc.toml"
sudo mkdir -p /etc/frp
sudo tee /etc/frp/frpc.toml >/dev/null <<EOF
serverAddr = "36.153.162.171"
serverPort = 7001
[auth]
method = "token"
token = "token123456"
[transport]
protocol = "kcp"
[[proxies]]
name = "$PROXY_NAME"
type = "stcp"
localIP = "127.0.0.1"
localPort = 22
secretKey = "$SECRET_KEY"
# visitor 由服务器 callback 自动追加
EOF
info "已生成 /etc/frp/frpc.toml"
# ==========================================
# 6. 回调注册(一定要在重启 frpc 之前)
# ==========================================
CALLBACK_URL="$BASE/callback?device=$deviceName"
step "回调注册(在重启 frpc 之前):$CALLBACK_URL"
# 用 download 抓取返回文本(落到临时文件)
tmp_cb="$(mktemp)"
trap 'rm -f "$tmp_cb"' EXIT
download "$CALLBACK_URL" "$tmp_cb" || die "回调请求失败"
RESULT="$(cat "$tmp_cb" 2>/dev/null || true)"
info "服务器返回:$RESULT"
# ==========================================
# 7. systemd 服务
# ==========================================
step "写入 systemd 服务 /etc/systemd/system/frpc.service"
sudo tee /etc/systemd/system/frpc.service >/dev/null <<EOF
[Unit]
Description=FRPC Client
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=$FRPC_BIN -c /etc/frp/frpc.toml
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable frpc
info "即将重启 frpc当前 SSH 连接可能会断开"
sudo systemctl restart frpc
# 给 1 秒让它起起来再检查
sleep 1
sudo systemctl --no-pager -l status frpc || die "frpc 服务启动失败,请看上面的日志"
info "FRPC 已重新启动(新配置已生效)"
echo "=============================="
echo " 安装完成!"
echo " 设备名:$deviceName"
echo "=============================="