feat: remote assist bootstrap script for macOS

This commit is contained in:
星月 2026-04-20 18:36:21 +08:00
commit 27f1de9c36
2 changed files with 191 additions and 0 deletions

33
README.md Normal file
View File

@ -0,0 +1,33 @@
# Remote Assist
macOS 远程协助一键脚本。启用 SSH + Cloudflare Quick Tunnel,让远程 Agent 可以 SSH 进来帮忙。
## 使用
被协助方执行:
```bash
bash <(curl -fsSL https://git.shazhou.work/scottwei/remote-assist/raw/branch/main/remote-assist.sh) "ssh-ed25519 AAAA..."
```
参数是协助者的 SSH 公钥。脚本会:
1. 将公钥加入 `~/.ssh/authorized_keys`
2. 开启 macOS Remote Login (sshd)
3. 安装并启动 Cloudflare Quick Tunnel
4. 打印连接信息(隧道地址 + 用户名)
## 协助者连接
```bash
# 1. 启动本地代理
cloudflared access tcp --hostname <tunnel-host> --url localhost:2222
# 2. SSH(另一个终端)
ssh -p 2222 <username>@localhost
```
## 要求
- macOS(Intel / Apple Silicon)
- 管理员密码(用于开启 Remote Login)

158
remote-assist.sh Normal file
View File

@ -0,0 +1,158 @@
#!/bin/bash
# ─────────────────────────────────────────────────────────────────
# remote-assist.sh — macOS 远程协助引导脚本
# 用法: bash <(curl -fsSL https://git.shazhou.work/scottwei/remote-assist/raw/branch/main/remote-assist.sh) "ssh-ed25519 AAAA..."
# ─────────────────────────────────────────────────────────────────
set -euo pipefail
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
CYAN='\033[0;36m'
NC='\033[0m'
info() { echo -e "${GREEN}[✓]${NC} $*"; }
warn() { echo -e "${YELLOW}[!]${NC} $*"; }
error() { echo -e "${RED}[✗]${NC} $*"; }
banner() { echo -e "\n${CYAN}═══ $* ═══${NC}\n"; }
# ── 参数检查 ──────────────────────────────────────────────────────
PUBKEY="${1:-}"
if [[ -z "$PUBKEY" ]]; then
error "请提供协助者的 SSH 公钥作为参数"
echo "用法: bash <(curl -fsSL URL) \"ssh-ed25519 AAAA...\""
exit 1
fi
banner "远程协助引导脚本"
echo "协助者公钥: ${PUBKEY:0:30}..."
echo ""
# ── 1. 安装协助者公钥 ────────────────────────────────────────────
banner "1/4 配置 SSH 公钥"
mkdir -p ~/.ssh
chmod 700 ~/.ssh
touch ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
if grep -qF "$PUBKEY" ~/.ssh/authorized_keys 2>/dev/null; then
info "公钥已存在,跳过"
else
echo "$PUBKEY" >> ~/.ssh/authorized_keys
info "公钥已添加到 ~/.ssh/authorized_keys"
fi
# ── 2. 启用 macOS Remote Login (sshd) ────────────────────────────
banner "2/4 启用 SSH 服务"
# 检查是否已经运行
if sudo systemsetup -getremotelogin 2>/dev/null | grep -qi "on"; then
info "Remote Login 已开启"
else
warn "需要管理员权限来开启 Remote Login"
sudo systemsetup -setremotelogin on
if sudo systemsetup -getremotelogin 2>/dev/null | grep -qi "on"; then
info "Remote Login 已开启"
else
# 备用方案:直接启动 sshd
warn "systemsetup 失败,尝试直接启动 sshd..."
sudo launchctl load -w /System/Library/LaunchDaemons/ssh.plist 2>/dev/null || true
if ssh -o ConnectTimeout=2 -o StrictHostKeyChecking=no localhost true 2>/dev/null; then
info "sshd 已通过 launchctl 启动"
else
error "无法启动 SSH 服务,请在系统设置中手动开启:"
echo " 系统设置 → 通用 → 共享 → 远程登录"
exit 1
fi
fi
fi
# ── 3. 安装 cloudflared 并启动隧道 ───────────────────────────────
banner "3/4 启动 Cloudflare Tunnel"
if ! command -v cloudflared &>/dev/null; then
info "正在安装 cloudflared..."
if command -v brew &>/dev/null; then
brew install cloudflared
else
# 直接下载二进制
ARCH=$(uname -m)
if [[ "$ARCH" == "arm64" ]]; then
CF_URL="https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-darwin-arm64.tgz"
else
CF_URL="https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-darwin-amd64.tgz"
fi
curl -fsSL "$CF_URL" -o /tmp/cloudflared.tgz
tar xzf /tmp/cloudflared.tgz -C /tmp
sudo mv /tmp/cloudflared /usr/local/bin/cloudflared
sudo chmod +x /usr/local/bin/cloudflared
rm -f /tmp/cloudflared.tgz
fi
info "cloudflared 已安装"
else
info "cloudflared 已存在: $(cloudflared --version 2>&1 | head -1)"
fi
# 启动 Quick Tunnel(后台运行,捕获输出)
CF_LOG="/tmp/cloudflared-assist.log"
pkill -f "cloudflared tunnel --url ssh://localhost:22" 2>/dev/null || true
sleep 1
cloudflared tunnel --url ssh://localhost:22 > "$CF_LOG" 2>&1 &
CF_PID=$!
info "cloudflared 已启动 (PID: $CF_PID)"
info "等待隧道就绪..."
# 等待隧道 URL
TUNNEL_HOST=""
for i in $(seq 1 30); do
TUNNEL_HOST=$(grep -oE 'https://[a-z0-9-]+\.trycloudflare\.com' "$CF_LOG" 2>/dev/null | head -1 || true)
if [[ -n "$TUNNEL_HOST" ]]; then
break
fi
sleep 1
done
if [[ -z "$TUNNEL_HOST" ]]; then
error "30 秒内未获取到隧道地址,日志如下:"
cat "$CF_LOG"
exit 1
fi
TUNNEL_HOSTNAME=$(echo "$TUNNEL_HOST" | sed 's|https://||')
USERNAME=$(whoami)
# ── 4. 打印连接信息 ──────────────────────────────────────────────
banner "4/4 连接信息"
echo -e "${GREEN}╔══════════════════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}${NC} 远程协助已就绪!请将以下信息发给协助者: ${GREEN}${NC}"
echo -e "${GREEN}╠══════════════════════════════════════════════════════════════╣${NC}"
echo -e "${GREEN}${NC} ${GREEN}${NC}"
echo -e "${GREEN}${NC} 隧道地址: ${CYAN}${TUNNEL_HOSTNAME}${NC}"
echo -e "${GREEN}${NC} 用户名: ${CYAN}${USERNAME}${NC}"
echo -e "${GREEN}${NC} ${GREEN}${NC}"
echo -e "${GREEN}${NC} 协助者连接命令: ${GREEN}${NC}"
echo -e "${GREEN}${NC} ${YELLOW}# 1. 启动本地代理${NC}"
echo -e "${GREEN}${NC} ${CYAN}cloudflared access tcp --hostname ${TUNNEL_HOSTNAME} --url localhost:2222${NC}"
echo -e "${GREEN}${NC} ${YELLOW}# 2. SSH 连接(另一个终端)${NC}"
echo -e "${GREEN}${NC} ${CYAN}ssh -p 2222 ${USERNAME}@localhost${NC}"
echo -e "${GREEN}${NC} ${GREEN}${NC}"
echo -e "${GREEN}╚══════════════════════════════════════════════════════════════╝${NC}"
echo ""
warn "隧道保持运行中,按 Ctrl+C 结束会话"
warn "日志: $CF_LOG"
echo ""
# 保持前台运行,Ctrl+C 退出时清理
cleanup() {
echo ""
info "正在清理..."
kill $CF_PID 2>/dev/null || true
info "隧道已关闭,远程协助结束"
}
trap cleanup EXIT INT TERM
# 等待 cloudflared 进程
wait $CF_PID 2>/dev/null || true