#!/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