From 27f1de9c36c7bb62aba87a3b7651c97c3630ca9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=9F=E6=9C=88?= Date: Mon, 20 Apr 2026 18:36:21 +0800 Subject: [PATCH] feat: remote assist bootstrap script for macOS --- README.md | 33 ++++++++++ remote-assist.sh | 158 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 191 insertions(+) create mode 100644 README.md create mode 100644 remote-assist.sh diff --git a/README.md b/README.md new file mode 100644 index 0000000..0d4b4fe --- /dev/null +++ b/README.md @@ -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 --url localhost:2222 + +# 2. SSH(另一个终端) +ssh -p 2222 @localhost +``` + +## 要求 + +- macOS(Intel / Apple Silicon) +- 管理员密码(用于开启 Remote Login) diff --git a/remote-assist.sh b/remote-assist.sh new file mode 100644 index 0000000..f003b9f --- /dev/null +++ b/remote-assist.sh @@ -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