215 lines
5.2 KiB
Bash
215 lines
5.2 KiB
Bash
|
|
#!/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 "=============================="
|
|||
|
|
|