Tailscale + SSH 多设备并网完整教程
适用人群:完全小白,零基础也能懂 目标:让多台设备(Windows、macOS、Linux)通过 Tailscale 组网,实现双向 SSH 免密访问 工具:Claude Code + 命令行
预计时间:30 分钟(首次),5 分钟(熟练后)
什么是 Tailscale + SSH?(必读!)
小白友好的解释
类比理解:
- Tailscale = 就像给所有设备拉了一根"虚拟网线",让它们在同一个"虚拟房间"里
- SSH = 就像"远程控制",让你在一台设备上操作另一台设备
- 免密登录 = 就像给家里的门装了"人脸识别",不用带钥匙也能进
为什么要这样做?
传统方式的问题:
- ❌ 家里设备不在同一局域网(如公司电脑无法直接连家里的电脑)
- ❌ 每次连远程都要输密码(麻烦且不安全)
- ❌ 没有公网 IP(运营商不提供,很难远程访问)
Tailscale + SSH 的优势:
- ✅ 穿透内网:在任何地方都能连家里的设备(咖啡厅、公司、出差)
- ✅ 免密登录:配置一次,永久生效
- ✅ 端到端加密:比很多 VPN 更安全
- ✅ 跨平台:Windows、Mac、Linux、手机都能互联
- ✅ 免费且简单:个人使用完全免费,只需安装登录
实际使用场景
| 场景 | 操作 |
|---|---|
| 在公司操作家里的 Mac |
|
| Mac 上运行 Windows 的命令 |
|
| 手机远程控制家里服务器 | 用 Termius 连接 Tailscale IP |
| 在咖啡厅调试家里服务器 |
|
快速检查清单
开始前确保:
- 所有设备都已安装 Tailscale 并登录同一账号
- 了解如何使用 Claude Code 执行命令(或会打开终端)
- 有设备的管理员权限(Windows 知道管理员密码,Mac 知道开机密码)
- 所有设备都已开启 Tailscale(状态显示为 "Online")
第零步:安装 Tailscale(首次必看)
目标:在所有设备上安装并登录 Tailscale,让它们加入同一个虚拟网络。
为什么要安装?
Tailscale 是什么?
- 基于 WireGuard 的零配置 VPN 工具
- 自动 NAT 穿透,无需公网 IP
- 端到端加密,安全性极高
- 跨平台支持:Windows、macOS、Linux、Android、iOS、路由器、NAS
官方地址:
各平台安装指南
Windows
下载安装:
- 访问 https://tailscale.com/download/windows
- 下载
安装包.exe - 双击安装,一路"下一步"
登录账号:
- 安装完成后会自动弹出登录页面
- 选择登录方式(推荐使用 Google/GitHub/邮箱)
- 授权登录
验证成功:
- 系统托盘会出现 Tailscale 图标(小恐龙🦖)
- 图标显示为绿色 = 已连接
- 图标显示为灰色 = 未连接
手动启动(如果没自动启动):
# 在开始菜单搜索"Tailscale"并打开# 或在系统托盘找到图标点击
macOS
下载安装:
- 访问 https://tailscale.com/download/macos
- 下载
文件.dmg - 打开 dmg,拖拽 Tailscale 到 Applications 文件夹
- 打开 Tailscale.app
登录账号:
- 首次打开会弹出登录页面
- 选择登录方式(Google/GitHub/邮箱)
- 授权登录
授权系统扩展(首次会提示):
- 系统会提示"系统扩展已阻止"
- 点击"打开安全设置"
- 点击"允许"按钮
- 重启 Mac(如果需要)
验证成功:
- 菜单栏会出现 Tailscale 图标
- 图标显示为绿色 = 已连接
Linux (Ubuntu/Debian)
安装命令:
# 添加 Tailscale 的 APT 仓库curl -fsSL https://tailscale.com/install.sh | sh# 启动服务sudo systemctl enable --now tailscaled# 登录sudo tailscale up
登录流程:
- 执行
后会显示一个链接sudo tailscale up - 复制链接到浏览器打开
- 授权登录
- 回到终端,等待显示"Success"
验证成功:
tailscale status# 应该能看到当前设备的信息
路由器(OpenWrt/梅林固件)
OpenWrt:
# SSH 到路由器ssh root@路由器IP# 安装 Tailscaleopkg updateopkg install tailscale# 启动并登录/etc/init.d/tailscale starttailscale up
梅林固件(ASUSWRT-Merlin):
- 下载
安装包(从 Tailscale 官网或论坛).ipk - 进入路由器管理后台
- 系统设置 → 软件中心 → 安装
文件.ipk - 安装完成后,在软件中心找到 Tailscale
- 点击登录,会弹出浏览器授权页面
验证成功:
# 在路由器上执行tailscale status# 或在电脑上 ping 路由器的 Tailscale IPping 100.x.x.x
NAS(群晖/威联通)
群晖 Synology:
- 访问 https://tailscale.com/download/synology
- 下载对应机型的
安装包.spk - 登录群晖管理后台
- 套件中心 → 手动安装 → 选择
文件.spk - 安装完成后,在主菜单找到 Tailscale
- 点击登录,完成授权
威联通 QNAP:
- 访问 https://tailscale.com/download/qnap
- 下载
安装包.qpkg - 登录 QNAP 管理后台
- App Center → 手动安装 → 选择
文件.qpkg - 安装完成后,在应用列表找到 Tailscale
- 点击登录,完成授权
验证成功:
# 在 NAS 的终端执行tailscale status
iOS/Android
iOS:
- App Store 搜索"Tailscale"
- 安装并打开
- 登录账号
Android:
- Google Play 搜索"Tailscale"
- 安装并打开
- 授权 VPN 权限(必须)
- 登录账号
验证成功:
- App 显示"Connected"状态
- 显示分配的 Tailscale IP 地址
第一次连接(验证组网成功)
步骤 1:在第一台设备上安装并登录
安装完成后,Tailscale 会自动给这台设备分配一个
的内网 IP 地址。100.x.x.x
查看本机的 Tailscale IP:
# Windows/macOS/Linuxtailscale status -self
输出示例:
100.80.153.60 macmini qyc macOS
步骤 2:在第二台设备上安装并登录
使用相同的账号登录!
步骤 3:验证两台设备已连通
方法 1:Ping 测试
# 在第一台设备上,ping 第二台设备的 Tailscale IPping 100.91.53.84# 成功输出(会持续显示):# Reply from 100.91.53.84: bytes=32 time<1ms TTL=64
方法 2:访问共享文件(Windows)
# 在文件管理器地址栏输入\\100.91.53.84# 或在运行框(Win+R)输入\\100.91.53.84
方法 3:访问共享文件(Mac)
# 在 Finder 中,按 Cmd+K,然后输入smb://100.91.53.84# 或在终端open smb://100.91.53.84
方法 4:查看设备列表
# 在任意设备上执行tailscale status# 应该能看到所有已登录的设备
成功标志:
- ✅ Ping 通了
- ✅ 能访问共享文件(如果开启了共享)
- ✅
能看到多台设备tailscale status
常见安装问题
问题 1:Windows 提示"系统扩展被阻止"
解决:
- 按
,输入Win + R
,回车sysdm.cpl - 切换到"硬件"选项卡
- 点击"设备安装设置"
- 选择"是(自动安装驱动程序)"
- 重启电脑
问题 2:macOS 提示"无法验证开发者"
解决:
# 方法 1:右键点击 Tailscale.app,选择"打开"# 点击"打开"按钮,而不是双击# 方法 2:在系统设置中允许# 系统设置 → 隐私与安全性 → 仍要打开
问题 3:Linux 提示"tailscale: command not found"
解决:
# 确保 Tailscale 服务已启动sudo systemctl start tailscaled# 检查安装which tailscale# 如果还是找不到,重新安装curl -fsSL https://tailscale.com/install.sh | sh
问题 4:设备显示"Offline"状态
原因:设备未连接到互联网或 Tailscale 服务未运行
解决:
# 检查网络连接ping google.com# 重启 Tailscale 服务# Windows:在系统托盘右键 Tailscale 图标 → 退出 → 重新打开# macOS/Linuxsudo tailscale downsudo tailscale up
问题 5:多台设备登录了不同账号
症状:
只能看到一台设备tailscale status
解决:
- 在所有设备上退出登录
- 使用同一个账号重新登录
- 验证:
能看到所有设备tailscale status
安装完成检查清单
完成以下检查,确认所有设备都正确安装:
- 所有设备都已安装 Tailscale
- 所有设备使用同一账号登录
- 所有设备显示"Connected"或"Online"状态
- 任意设备 ping 其他设备都能通
-
能看到所有设备列表tailscale status
✅ 全部通过? 恭喜,Tailscale 组网成功!继续下一步。
第一步:确认 Tailscale 组网
目标:确认所有设备都在同一个 Tailscale 网络中,并记录每台设备的信息。
1.1 在所有设备上查看 Tailscale 状态
Windows / PowerShell:
tailscale status
macOS / Linux:
tailscale status
正常输出示例:
100.91.53.84 laptop qyc@windows windows;100.80.153.60 macmini qyc macOS;100.94.2.125 server root linux;
关键点:
- 如果看到多台设备列表 → Tailscale 组网成功 ✅
- 如果只看到一台 → 检查其他设备是否登录同一账号
- IP 地址格式:
(Tailscale 专用 IP 段)100.x.x.x
1.2 记录设备信息(非常重要!)
为什么需要记录?
- SSH 连接需要知道:目标设备的 IP + 用户名
- 用户名 ≠ Tailscale 账号名(是设备本地的用户名)
创建一个设备清单(示例):
| 设备名 | Tailscale IP | 系统 | 用户名 | 用途 |
|---|---|---|---|---|
| laptop | 100.91.53.84 | Windows | Qyc | 主要工作电脑 |
| macmini | 100.80.153.60 | macOS | qyc | 家庭服务器 |
| server | 100.94.2.125 | Linux | root | 云服务器 |
⚠️ 常见误区:
- ❌ 错误:用户名 = Tailscale 账号邮箱
- ✅ 正确:用户名 = 设备本地登录名(如
、qyc
、Qyc
)root
获取用户名命令:
# Windows PowerShell$env:USERNAME# macOS/Linux 终端whoami
💡 小技巧:把设备清单存到手机备忘录或 Obsidian,以后随时查看
第一步完成检查
# 在任意设备上测试能否 ping 通其他设备ping 100.80.153.60 # 替换成你的设备 IP
如果能 ping 通(有回复) → Tailscale 组网成功,继续下一步 ✅ 如果 ping 不通 → 检查 Tailscale 是否登录同一账号
第二步:生成 SSH 密钥对
目标:在每台设备上生成"钥匙"和"锁",让设备之间互相认识。
什么是 SSH 密钥对?(小白必读)
类比理解:
- 公钥(Public Key) = 你家的"门锁",可以公开给别人
- 私钥(Private Key) = 你家的"钥匙",必须保密,只能自己保管
- authorized_keys = 就像一个"访客名单",里面存了所有被允许进入的人的公钥
工作原理:
- 设备 A 生成密钥对(钥匙 A + 锁 A)
- 把"锁 A"放到设备 B 的"访客名单"里
- 以后设备 A 想连设备 B,就拿出"钥匙 A",设备 B 检查名单 → 允许进入
2.1 检查是否已有密钥
在所有设备上执行:
# Windows PowerShellls $env:USERPROFILE\.ssh\id_ed25519*# macOS/Linuxls ~/.ssh/id_ed25519*
输出示例(如果已存在):
Mode LastWriteTime Length Name---- ------------- ------ -----a---- 2026/03/26 10:30 411 id_ed25519-a---- 2026/03/26 10:30 103 id_ed25519.pub
如果已存在:跳过生成步骤,直接用现有密钥 如果不存在(或提示找不到文件):继续执行下一步
2.2 生成新密钥
在需要生成密钥的设备上执行:
ssh-keygen -t ed25519 -C "你的邮箱或设备标识"
示例:
ssh-keygen -t ed25519 -C "qyc@macmini"
执行后会看到(示例交互):
Generating public/private ed25519 key pair.Enter file in which to save the key (/Users/qyc/.ssh/id_ed25519):
→ 直接按回车(使用默认路径)
Enter passphrase (empty for no passphrase):
→ 直接按回车(不设置密码,否则每次连接还是要输入)
Enter same passphrase again:
→ 直接按回车(确认不设置密码)
成功后会看到:
Your identification has been saved in /Users/qyc/.ssh/id_ed25519Your public key has been saved in /Users/qyc/.ssh/id_ed25519.pubThe key fingerprint is:SHA256:xxxxxxxxxxxxxxxxxxxx qyc@macmini
2.3 验证密钥生成
查看公钥内容(后面会用到):
# Windows PowerShellcat $env:USERPROFILE\.ssh\id_ed25519.pub# macOS/Linuxcat ~/.ssh/id_ed25519.pub
输出示例:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExxxxxxxxxxxxxxxxxxxxxxxxxxxxxx qyc@macmini
⚠️ 重要提示:
- 私钥(id_ed25519):绝对不能分享给别人!就像家门钥匙
- 公钥(id_ed25519.pub):可以公开,就是要复制到其他设备的
第二步完成检查
# 在每台设备上验证密钥存在ls ~/.ssh/id_ed25519* # Mac/Linuxls $env:USERPROFILE\.ssh\id_ed25519* # Windows
如果看到两个文件(id_ed25519 和 id_ed25519.pub)→ 密钥生成成功 ✅
第三步:配置免密登录
目标:把每台设备的"公钥"放到其他设备的"访客名单"里,实现免密登录。
核心理解(最重要!)
公钥存储位置差异(新手最容易踩坑):
| 系统 | 公钥存储位置 | 谁能访问 |
|---|---|---|
| macOS/Linux |
| 当前用户 |
| Windows |
| 管理员组用户 ⚠️ |
⚠️ Windows 的坑:
- ❌ 错误:Windows 公钥也在 ~/.ssh/authorized_keys
- ✅ 正确:Windows 公钥在
(系统级)C:\ProgramData\ssh\administrators_authorized_keys - 而且需要特殊权限和重启 SSH 服务
工作流程图(帮助理解)
设备 A (100.1.1.1) 设备 B (100.2.2.2)│ ││ 1. A 生成密钥对 (钥匙A + 锁A) ││ ││ 2. 复制"锁A" ───────────────────→ ││ ││ 3. 把"锁A"写入 B 的访客名单 ││ (authorized_keys) ││ ││ 4. A 用"钥匙A"解锁 B ────────────→ ││ │└────────────────────→ 免密登录成功 ✅
3.1 场景一:macOS/Linux → macOS/Linux(最简单)
假设场景:
- 设备 A(你的 Mac):
,用户名100.80.153.60qyc - 设备 B(你的服务器):
,用户名100.94.2.125root
目标:从 Mac 免密登录服务器
在设备 A(Mac)上执行:
ssh-copy-id [email protected]
第一次会提示:
The authenticity of host '100.94.2.125 (ECDSA)' can't be established.ECDSA key fingerprint is SHA256:xxxxxxxxxxx.Are you sure you want to continue connecting (yes/no/[fingerprint])?
→ 输入
(第一次连接该设备,需要确认)yes
然后提示输入密码:
[email protected]'s password:
→ 输入目标设备(服务器)的密码
成功输出:
Number of key(s) added: 1
✅ 配置完成!之后测试:
如果不需要输入密码 → 成功!
3.2 场景二:macOS/Linux → Windows(易错)
假设场景:
- 你的 Mac:
,用户名100.80.153.60qyc - 你的 Windows:
,用户名100.91.53.84Qyc
目标:从 Mac 免密登录 Windows
方法 1:使用 ssh-copy-id(推荐,最简单)
在 Mac 上执行:
ssh-copy-id [email protected]
输入 Windows 密码后,会自动处理:
- 创建目录
- 写入公钥到正确位置
- 设置权限
方法 2:手动复制(如果 ssh-copy-id 失败)
步骤 1:在 Mac 上获取公钥
cat ~/.ssh/id_ed25519.pub
复制输出的内容(类似):
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExxxxxxxxxxxxx qyc@macmini
步骤 2:在 Windows 上操作(需要管理员 PowerShell)
打开管理员 PowerShell:
- 按
,选择"终端(管理员)"或"Windows PowerShell(管理员)"Win + X
执行以下命令:
# 1. 创建目录(如果不存在)New-Item -ItemType Directory -Force -Path "C:\ProgramData\ssh"# 2. 写入公钥(替换 <公钥内容> 为你复制的公钥)$sshKey = @"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExxxxxxxxxxxxx qyc@macmini"@Add-Content -Path "C:\ProgramData\ssh\administrators_authorized_keys" -Value $sshKey -Force# 3. 设置正确权限(重要!)icacls "C:\ProgramData\ssh\administrators_authorized_keys" /inheritance:ricacls "C:\ProgramData\ssh\administrators_authorized_keys" /grant "Administrators:F"icacls "C:\ProgramData\ssh\administrators_authorized_keys" /grant "SYSTEM:F"# 4. 重启 SSH 服务(必须!)Restart-Service sshd
✅ 验证:
# 在 Mac 上测试
3.3 场景三:Windows → macOS/Linux
假设场景:
- 你的 Windows:
,用户名100.91.53.84Qyc - 你的 Mac:
,用户名100.80.153.60qyc
目标:从 Windows 免密登录 Mac
在 Windows 上执行:
# 复制公钥到目标设备的 authorized_keystype $env:USERPROFILE\.ssh\id_ed25519.pub | ssh [email protected] "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
第一次会提示:
The authenticity of host '100.80.153.60' can't be established.Are you sure you want to continue connecting (yes/no)?
→ 输入
yes
然后输入 Mac 的密码:
[email protected]'s password:
✅ 验证:
3.4 场景四:Windows → Windows
假设场景:
- Windows A(笔记本):100.91.53.84
- Windows B(台式机):100.92.54.85
步骤 1:在源 Windows (A) 上获取公钥
cat $env:USERPROFILE\.ssh\id_ed25519.pub
复制公钥内容
步骤 2:在目标 Windows (B) 上操作(管理员 PowerShell)
# 写入公钥(替换 <公钥内容>)$sshKey = @"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExxxxxxxxxxxxx user@laptop"@Add-Content -Path "C:\ProgramData\ssh\administrators_authorized_keys" -Value $sshKey -Force# 设置权限icacls "C:\ProgramData\ssh\administrators_authorized_keys" /inheritance:ricacls "C:\ProgramData\ssh\administrators_authorized_keys" /grant "Administrators:F"icacls "C:\ProgramData\ssh\administrators_authorized_keys" /grant "SYSTEM:F"# 重启 SSH 服务Restart-Service sshd
✅ 验证:
# 在 Windows A 上测试
3.5 实战案例:多多的设备配置
假设你有三台设备:
- 笔记本(Windows):
,用户100.91.53.84Qyc - Mac mini:
,用户100.80.153.60qyc - 服务器:
,用户100.94.2.125root
目标:任意设备都能免密访问其他设备
配置矩阵
| 源设备 | 目标设备 | 命令(在源设备执行) |
|---|---|---|
| 笔记本 | Mac mini |
|
| 笔记本 | 服务器 |
|
| Mac mini | 笔记本 |
|
| Mac mini | 服务器 |
|
| 服务器 | 笔记本 |
|
| 服务器 | Mac mini |
|
批量操作脚本(可选):
在每台设备上创建一个
(或setup-ssh.sh
)脚本,一次性配置所有目标。.ps1
第三步完成检查
在每台设备上验证能否连接其他设备:
# 示例:从笔记本连接 Mac minissh [email protected] "hostname && whoami"
期望输出(不需要输入密码):
Mac-mini.localqyc
如果所有组合都能免密连接 → 配置完成 ✅
3.1 场景一:macOS/Linux → macOS/Linux
假设:设备 A (100.x.x.1) 要免密登录设备 B (100.x.x.2)
在设备 A 上执行:
# 复制公钥到目标设备ssh-copy-id [email protected]
输入一次密码后永久生效
3.2 场景二:macOS/Linux → Windows
假设:Mac (100.80.153.60) 要免密登录 Windows (100.91.53.84)
方法 1:使用 ssh-copy-id(推荐)
# 在 Mac 上执行ssh-copy-id [email protected]
方法 2:手动复制(如果 ssh-copy-id 失败)
在 Mac 上获取公钥:
cat ~/.ssh/id_ed25519.pub
在 Windows 上(管理员 PowerShell):
# 创建目录(如果不存在)New-Item -ItemType Directory -Force -Path "C:\ProgramData\ssh"# 追加公钥(替换 <公钥内容>)Add-Content -Path "C:\ProgramData\ssh\administrators_authorized_keys" -Value "<公钥内容>" -Force# 重启 SSH 服务Restart-Service sshd
3.3 场景三:Windows → macOS/Linux
在 Windows 上执行:
# 复制公钥到目标type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh [email protected] "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
输入一次密码后永久生效
3.4 场景四:Windows → Windows
在源 Windows 上获取公钥:
cat $env:USERPROFILE\.ssh\id_ed25519.pub
在目标 Windows 上(管理员 PowerShell):
Add-Content -Path "C:\ProgramData\ssh\administrators_authorized_keys" -Value "<公钥内容>" -ForceRestart-Service sshd
第四步:验证免密登录
目标:确保所有配置都生效,设备之间可以免密互通。
4.1 快速批量测试(推荐)
创建测试脚本(在任意设备上):
#!/bin/bash# 文件名:test-ssh-connectivity.sh# 设备列表(按你的实际情况修改)declare -A devices=(["macmini"]="[email protected]"["windows"]="[email protected]"["server"]="[email protected]")echo "🔍 开始测试 SSH 免密连接..."echo "================================"success=0failed=0for name in "${!devices[@]}"; dotarget="${devices[$name]}"echo -n "测试连接 $name ($target)... "# 使用 BatchMode 强制不输入密码if ssh -o BatchMode=yes -o ConnectTimeout=5 "$target" "echo 'OK'" >/dev/null 2>&1; thenecho "✅ 成功"((success++))elseecho "❌ 失败"((failed++))fidoneecho "================================"echo "测试完成:成功 $success 个,失败 $failed 个"
执行测试:
chmod +x test-ssh-connectivity.sh./test-ssh-connectivity.sh
期望输出:
🔍 开始测试 SSH 免密连接...================================测试连接 macmini ([email protected])... ✅ 成功测试连接 windows ([email protected])... ✅ 成功测试连接 server ([email protected])... ✅ 成功================================测试完成:成功 3 个,失败 0 个
4.2 单个设备测试
基础连接测试:
# 测试免密连接(BatchMode 模式不会提示输入密码)ssh -o BatchMode=yes user@目标IP "echo 免密成功"
成功输出:
失败输出:免密成功
Permission denied (publickey,password)
实际登录测试:
# 实际连接并执行命令ssh user@目标IP "hostname && whoami && date"
期望输出(不需要输入密码):
Mac-mini.localqyc2026年 3月 26日 星期四 10:30:45 CST
交互式登录测试:
# 实际登录到目标设备(会进入交互式 Shell)ssh user@目标IP
成功标志:直接进入目标设备的 Shell,不需要输入密码
4.3 Windows PowerShell 测试脚本
在 Windows 上创建
:test-ssh.ps1
# 设备列表$devices = @{"macmini" = "[email protected]""server" = "[email protected]"}Write-Host "🔍 开始测试 SSH 免密连接..." -ForegroundColor CyanWrite-Host ("=" * 50) -ForegroundColor Gray$success = 0$failed = 0foreach ($name in $devices.Keys) {$target = $devices[$name]Write-Host -NoNewline "测试连接 $name ($target)... "# 测试连接$result = ssh -o BatchMode=yes -o ConnectTimeout=5 "$target" "echo 'OK'" 2>&1if ($LASTEXITCODE -eq 0) {Write-Host "✅ 成功" -ForegroundColor Green$success++} else {Write-Host "❌ 失败" -ForegroundColor Red$failed++}}Write-Host ("=" * 50) -ForegroundColor GrayWrite-Host "测试完成:成功 $success 个,失败 $failed 个" -ForegroundColor Cyan
执行测试:
.\test-ssh.ps1
4.4 双向测试(验证所有设备互通)
目标:确保设备 A ↔ 设备 B 双向都能免密连接
测试矩阵(手动执行或写脚本):
| 从 → | 笔记本 | Mac mini | 服务器 |
|---|---|---|---|
| 笔记本 | — | ✅ 测试 | ✅ 测试 |
| Mac mini | ✅ 测试 | — | ✅ 测试 |
| 服务器 | ✅ 测试 | ✅ 测试 | — |
示例测试命令(在笔记本上执行):
# 笔记本 → Mac minissh [email protected] "echo '从笔记本访问 Mac mini 成功'"# 笔记本 → 服务器ssh [email protected] "echo '从笔记本访问服务器成功'"
第四步完成检查
验证清单:
- 所有设备都能单向访问其他设备
- 所有设备都能双向互通(A→B 和 B→A 都行)
- 连接时不需要输入任何密码
- 执行远程命令能正常返回结果
全部通过? → 恭喜,配置完成!🎉
有失败? → 查看故障排查章节
第五步:(可选)自动化密码输入
适用场景:
- 使用 Claude Code 等 AI 工具,无法手动输入密码
- 需要批量配置多台设备
方法 1:使用 expect(macOS/Linux)
安装 expect:
# macOSbrew install expect# Ubuntu/Debiansudo apt install expect# CentOS/RHELsudo yum install expect
自动化脚本:
#!/bin/bash# 文件名:auto-ssh-copy-id.shTARGET_USER="目标用户名"TARGET_IP="目标IP"PASSWORD="目标设备密码"cat << 'EOF' | expectset timeout 30spawn ssh-copy-id ${TARGET_USER}@${TARGET_IP}expect {"yes/no" { send "yes\r"; exp_continue }"password:" { send "${PASSWORD}\r" }}expect eofEOF
使用示例:
# 配置变量TARGET_USER="qyc"TARGET_IP="100.80.153.60"PASSWORD="你的密码"# 执行脚本./auto-ssh-copy-id.sh
方法 2:使用 sshpass(跨平台)
安装 sshpass:
# macOSbrew install sshpass# Ubuntu/Debiansudo apt install sshpass# Windows(使用 WSL 或 Git Bash)# 下载:https://github.com/kevinburke/sshpass/releases
使用示例:
# 直接使用sshpass -p "你的密码" ssh-copy-id user@目标IP# 或从环境变量读取(更安全)export SSHPASS="你的密码"sshpass -e ssh-copy-id user@目标IP
⚠️ 安全提示:
- 密码会以明文形式出现在命令历史中
- 仅用于一次性配置,配置完成后删除脚本
- 生产环境不推荐
方法 3:管道传递(适用于 Windows → Linux/Mac)
在 Windows 上执行:
# 生成包含公钥的临时文件type $env:USERPROFILE\.ssh\id_ed25519.pub > temp_key.pub# 手动复制到目标设备(然后用文件传输工具或粘贴)
或使用 PowerShell 的凭据管理器(更安全):
# 存储凭据$cred = Get-Credential# 使用凭据连接ssh user@target# 在提示密码时,凭据管理器会自动填充
第五步完成检查
验证自动化脚本是否生效:
# 运行自动化脚本后,立即测试免密连接ssh -o BatchMode=yes user@目标IP "echo '自动化配置成功'"
成功输出:
自动化配置成功
故障排查速查表
遇到问题?90% 的问题都在这里能找到答案。
快速诊断流程(按顺序排查)
问题出现↓1. Tailscale 连接正常吗?↓ tailscale status2. 目标设备 SSH 开启了吗?↓ 测试端口连接3. 密钥对存在吗?↓ ls ~/.ssh/id_ed25519*4. 公钥位置正确吗?↓ 检查对应系统路径5. 权限设置对吗?↓ 修复权限6. 测试连接
问题 1:Permission denied (publickey,password)
症状:
Permission denied (publickey,password).
原因分析:
- 公钥未正确添加到目标设备
- 公钥路径错误(Windows 最常见)
- 权限设置不正确
排查步骤:
步骤 1:确认公钥在目标设备上
# macOS/Linux 目标设备cat ~/.ssh/authorized_keys# 应该能看到你的公钥内容# Windows 目标设备type "C:\ProgramData\ssh\administrators_authorized_keys"# 应该能看到你的公钥内容
步骤 2:确认公钥内容完整
# 在源设备上查看公钥cat ~/.ssh/id_ed25519.pub# 对比目标设备上的公钥是否一致
步骤 3:检查权限(见下文"权限问题")
问题 2:Windows 免密失败
症状:
- Windows 上始终要求输入密码
- 或提示"Access denied"
最常见原因:公钥路径错误!
Windows 的正确路径(记住!):
C:\ProgramData\ssh\administrators_authorized_keys
❌ 错误路径(Linux/macOS 的路径):
C:\Users\YourName\.ssh\authorized_keys ← 这是错的!
解决方法:
# 1. 确认公钥在正确位置type "C:\ProgramData\ssh\administrators_authorized_keys"# 2. 如果文件不存在,创建它New-Item -ItemType Directory -Force -Path "C:\ProgramData\ssh"New-Item -ItemType File -Force -Path "C:\ProgramData\ssh\administrators_authorized_keys"# 3. 复制公钥内容(替换 <公钥内容>)Add-Content -Path "C:\ProgramData\ssh\administrators_authorized_keys" -Value "<公钥内容>"# 4. 修复权限(见下方"权限问题")# 5. 重启 SSH 服务Restart-Service sshd
问题 3:权限设置不正确
症状:
- Authentication refused: bad ownership or modes
- 或其他权限相关错误
macOS/Linux 权限修复:
# 检查当前权限ls -la ~/.ssh/authorized_keys# 期望输出# -rw------- (600 权限)# 修复权限chmod 600 ~/.ssh/authorized_keyschmod 700 ~/.ssh
Windows 权限修复:
# 检查当前权限icacls "C:\ProgramData\ssh\administrators_authorized_keys"# 期望输出(包含)# Administrators:(F)# SYSTEM:(F)# 修复权限(重新设置)icacls "C:\ProgramData\ssh\administrators_authorized_keys" /inheritance:ricacls "C:\ProgramData\ssh\administrators_authorized_keys" /grant "Administrators:F"icacls "C:\ProgramData\ssh\administrators_authorized_keys" /grant "SYSTEM:F"# 重启服务Restart-Service sshd
问题 4:No route to host
症状:
ssh: connect to host 100.x.x.x port 22: No route to host
原因:Tailscale 连接断开或设备离线
排查步骤:
步骤 1:检查 Tailscale 状态
tailscale status
期望输出:能看到目标设备列表
如果看不到:
- 检查目标设备是否在线
- 确认目标设备登录了同一 Tailscale 账号
- 在 Tailscale 管理后台检查设备状态
步骤 2:测试网络连通性
# Ping 测试ping 100.80.153.60# 如果 ping 不通,说明是网络层面的问题# 而不是 SSH 配置的问题
步骤 3:检查 Tailscale 是否启用
# macOS/Linuxifconfig tun0# Windowsipconfig | findstr Tailscale
问题 5:Connection refused
症状:
ssh: connect to host 100.x.x.x port 22: Connection refused
原因:SSH 服务未启动
解决方案:
Windows:
# 检查 SSH 服务状态Get-Service sshd# 如果未运行,启动服务Start-Service sshd# 设置开机自启Set-Service sshd -StartupType Automatic# 安装 OpenSSH Server(如果未安装)# → 设置 → 应用 → 可选功能 → 添加功能 → OpenSSH Server
macOS:
# 检查 SSH 状态sudo systemsetup -getremotelogin# 如果输出 "Remote Login: Off",启用它sudo systemsetup -setremotelogin on
Linux:
# 检查 SSH 状态sudo systemctl status sshd# 启动服务sudo systemctl start sshdsudo systemctl enable sshd
问题 6:Windows 写入公钥失败
症状:
Access to the path 'C:\ProgramData\ssh\administrators_authorized_keys' is denied.
原因:权限不足
解决方法:
-
确保使用管理员 PowerShell
- 右键开始菜单 → "终端(管理员)"
- 或按
→ "Windows PowerShell(管理员)"Win + X
-
如果仍然失败,手动创建文件:
# 以管理员身份运行notepad C:\ProgramData\ssh\administrators_authorized_keys# 粘贴公钥内容,保存# 然后修复权限(见上方"权限问题")
问题 7:第一次连接提示"Are you sure you want to continue?"
症状:
The authenticity of host '100.x.x.x' can't be established.ECDSA key fingerprint is SHA256:xxxxxxxxxxx.Are you sure you want to continue connecting (yes/no/[fingerprint])?
这不是错误! 正常现象。
解决方法:
# 输入 yes 并回车yes
或在命令中自动确认:
ssh -o StrictHostKeyChecking=no user@目标IP "echo 'OK'"
⚠️ 安全提示:
- 首次连接应手动验证指纹
- 仅在可信网络使用 StrictHostKeyChecking=no
问题 8:配置成功后突然又需要密码
症状:
- 之前免密成功,突然又要求输入密码
可能原因:
- 重新生成了密钥(旧密钥失效)
- 目标设备重装了系统
- authorized_keys 文件被清空
解决方法:
# 重新复制公钥ssh-copy-id user@目标IP
问题 9:Verbose 模式调试(终极武器)
如果以上方法都无效,使用详细日志模式:
# 开启详细输出(3 级详细度)ssh -vvv user@目标IP
会输出大量调试信息,找到关键错误:
- debug1: Offering public key: ...
- debug1: Authentications that can continue: ...
- Permission denied (publickey,password)
关键信息位置:
- 找
→ 确认是否发送了正确的密钥Offering public key - 找
→ 查看具体拒绝原因Authentication refused
故障排查总结表
| 错误信息 | 首要检查项 | 快速命令 |
|---|---|---|
| 公钥是否在目标设备 |
|
| Tailscale 是否连接 |
|
| SSH 服务是否运行 | /
|
| 文件权限是否正确 |
|
| Windows 免密失败 | 公钥路径是否正确 |
|
💡 记住:
- 90% 的问题都是公钥位置或权限问题
- Windows 最容易出错(路径和权限都特殊)
- 使用
可以看到详细错误信息-vvv
Windows 常见问题
检查 SSH 服务状态:
Get-Service sshd
如果未运行:
Start-Service sshdSet-Service sshd -StartupType Automatic
检查公钥文件权限:
icacls "C:\ProgramData\ssh\administrators_authorized_keys"# 应显示:Administrators:(F) 和 SYSTEM:(F)
修复权限:
icacls "C:\ProgramData\ssh\administrators_authorized_keys" /inheritance:ricacls "C:\ProgramData\ssh\administrators_authorized_keys" /grant "Administrators:F"icacls "C:\ProgramData\ssh\administrators_authorized_keys" /grant "SYSTEM:F"
macOS/Linux 常见问题
检查 SSH 权限:
ls -la ~/.ssh/authorized_keys# 应该是:-rw------- (600)
修复权限:
chmod 600 ~/.ssh/authorized_keyschmod 700 ~/.ssh
快速配置模板(复制粘贴用)
模板 A:两台 macOS/Linux 互连
# 设备 1 → 设备 2ssh-copy-id user2@设备2的IP# 设备 2 → 设备 1ssh-copy-id user1@设备1的IP
模板 B:Mac → Windows
# 在 Mac 上ssh-copy-id windows_user@Windows的IP
模板 C:Windows → Mac
# 在 Windows 上type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh mac_user@Mac的IP "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
验证清单
完成后测试:
# 从设备 A 连接设备 Bssh user@设备B的IP "hostname"# 从设备 B 连接设备 Assh user@设备A的IP "hostname"# 如果都返回主机名,配置成功!
进阶配置(可选)
配置 SSH 别名(懒人必备)
为什么需要?
- 不用记复杂的 IP 和用户名
- 一条命令直达设备
- 可以设置更多高级选项
编辑 SSH 配置文件:
# macOS/Linuxnano ~/.ssh/config# Windowsnotepad C:\Users\你的用户名\.ssh\config
配置示例:
# Mac miniHost macminiHostName 100.80.153.60User qycIdentityFile ~/.ssh/id_ed25519# Windows 笔记本Host windowsHostName 100.91.53.84User QycIdentityFile ~/.ssh/id_ed25519# 服务器Host serverHostName 100.94.2.125User rootIdentityFile ~/.ssh/id_ed25519Port 22# 别名也可以用简短的名字Host mHostName 100.80.153.60User qycHost wHostName 100.91.53.84User Qyc
使用示例:
# 之前:ssh [email protected]# 现在:ssh macmini# 或更短:ssh m# 执行远程命令ssh macmini "ls -la ~/Downloads"ssh server "docker ps"
高级选项:
Host server-prodHostName 100.94.2.125User root# 保持连接不断开ServerAliveInterval 60ServerAliveCountMax 3# 压缩传输(适合慢速网络)Compression yes# 优化文件传输ControlMaster autoControlPath ~/.ssh/socket-%r@%h:%p
禁用密码登录(提升安全性)
⚠️ 警告:
- 确保免密登录100% 可用后再执行
- 否则可能把自己锁在外面
macOS/Linux:
# 编辑配置sudo nano /etc/ssh/sshd_config# 找到并修改PasswordAuthentication noPubkeyAuthentication yes# 重启服务sudo systemctl restart sshd # Linuxsudo launchctl stop com.openssh.sshd && sudo launchctl start com.openssh.sshd # macOS
Windows:
# 编辑配置(管理员 notepad)notepad C:\ProgramData\ssh\sshd_config# 找到并修改PasswordAuthentication noPubkeyAuthentication yes# 重启服务Restart-Service sshd
验证:
# 应该能免密登录ssh user@目标IP# 如果尝试密码登录,会被拒绝ssh -o PreferredAuthentications=password user@目标IP# → Permission denied (publickey)
批量执行命令(运维神器)
场景:同时在多台设备上执行相同命令
创建脚本
:run-on-all.sh
#!/bin/bash# 设备列表devices=()# 要执行的命令command="$1"if [ -z "$command" ]; thenecho "Usage: $0 'command'"exit 1fifor device in "${devices[@]}"; doecho "🖥️ $device"ssh "$device" "$command"echo "---"done
使用示例:
# 查看所有设备的磁盘使用./run-on-all.sh "df -h"# 更新所有设备./run-on-all.sh "sudo apt update && sudo apt upgrade -y"# 查看所有设备的运行时间./run-on-all.sh "uptime"
文件快速传输(比 SCP 更方便)
使用 rsync 同步文件:
# 从 Mac 复制文件到 Windowsrsync -avz ~/Documents/file.txt [email protected]:/C/Users/Qyc/Documents/# 从 Windows 复制到 Macrsync -avz [email protected]:/C/Users/Qyc/Documents/file.txt ~/Downloads/# 同步整个目录(带进度条)rsync -avz --progress ~/Projects/ [email protected]:~/Projects/
使用 SCP 传输单个文件:
# 本地 → 远程scp file.txt user@目标IP:/path/to/destination/# 远程 → 本地scp user@目标IP:/path/to/file.txt /local/path/
保持连接不断开
问题:长时间不操作,SSH 连接会断开
解决方法:
客户端配置(推荐):
# 编辑 ~/.ssh/configHost *ServerAliveInterval 60ServerAliveCountMax 3
或临时使用:
# 自动保持连接ssh -o ServerAliveInterval=60 user@目标IP
多台设备跳跃(Jump Host)
场景:需要通过设备 A 访问设备 B
配置示例:
# 跳板机配置Host jumpHostName 100.80.153.60User qyc# 目标机器(通过跳板机访问)Host targetHostName 100.94.2.125User rootProxyJump jump
使用:
# 会自动通过 jump 连接到 targetssh target# 等同于
安全最佳实践
1. 密钥管理
✅ 好的习惯:
- 为不同设备/用途使用不同密钥
- 给密钥设置描述性名称(如
)id_ed25519_mac - 定期轮换密钥(敏感环境)
❌ 避免的做法:
- 不要用同一密钥对注册所有服务
- 不要把私钥上传到云端(除非加密)
- 不要在多台设备间共享私钥
2. 权限控制
限制特定用户 SSH 访问:
# 编辑 /etc/ssh/sshd_configAllowUsers qyc root anotheruserDenyUsers guest
限制 root 远程登录:
# /etc/ssh/sshd_configPermitRootLogin prohibit-password# 或PermitRootLogin no
3. 审计日志
查看 SSH 登录历史:
# macOS/Linuxlast | grep qyc# 或grep "Accepted" /var/log/auth.log# Windows# Windows Event Viewer → Windows Logs → Security# Event ID 4624 (Logon)
4. 备份配置
备份 SSH 配置和密钥:
# 创建备份脚本mkdir -p ~/backups/sshcp -r ~/.ssh ~/backups/ssh/$(date +%Y%m%d)
加密备份(敏感环境):
# 加密备份tar -czf - ~/.ssh | gpg -e -r [email protected] > ssh-backup.tar.gz.gpg# 解密恢复gpg -d ssh-backup.tar.gz.gpg | tar -xzf -
总结
核心流程回顾
1️⃣ 安装 Tailscale → 所有设备在同一虚拟网络↓2️⃣ 生成 SSH 密钥 → 每台设备生成 id_ed25519↓3️⃣ 交换公钥 → 复制到目标设备的 authorized_keys↓4️⃣ 验证 → 测试免密连接↓5️⃣ 完成 → 享受随时随地的设备互联 ✅
核心要点(必须记住)
| 要点 | macOS/Linux | Windows |
|---|---|---|
| 公钥位置 |
| ⚠️ |
| 权限设置 |
| 修复权限 |
| 服务重启 |
|
|
常见误区(新手必看)
| 误区 | 正确做法 |
|---|---|
❌ Windows 公钥也在
| ✅ Windows 在
|
| ❌ 用户名 = Tailscale 邮箱 | ✅ 用户名 = 设备本地用户名 |
| ❌ 配置完立即删除密码登录 | ✅ 先验证免密 100% 可用 |
| ❌ 所有设备用同一个密钥 | ✅ 推荐每台设备独立密钥 |
| ❌ 以为配置一次永久有效 | ✅ 设备重装系统后需重新配置 |
快速命令参考卡
复制保存,随时查看:
# === Tailscale 检查 ===tailscale status # 查看所有设备ping 100.80.153.60 # 测试连通性# === 密钥生成 ===ssh-keygen -t ed25519 -C "标识" # 生成密钥cat ~/.ssh/id_ed25519.pub # 查看公钥# === 复制公钥 ===ssh-copy-id user@IP # Mac/Linux → 所有type ~/.ssh/id_ed25519.pub | ssh user@IP "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys" # Windows → Linux# === 测试连接 ===ssh -o BatchMode=yes user@IP "echo OK" # 快速测试ssh user@IP "hostname && whoami" # 实际测试# === 调试模式 ===ssh -vvv user@IP # 详细日志# === Windows 特殊 ===type "C:\ProgramData\ssh\administrators_authorized_keys" # 查看公钥Restart-Service sshd # 重启 SSH 服务icacls "C:\ProgramData\ssh\..." /inheritance:r # 修复权限
常见问题(FAQ)
Q1: Tailscale 免费吗?
A: 个人使用完全免费!
- 免费版支持:100 台设备、所有核心功能
- 付费版:更多高级功能(如 SSO、ACL 等)
Q2: 安全性如何?
A: 非常安全:
- 端到端加密:所有流量都经过加密
- 密钥认证:比密码更安全
- 零信任网络:只有在授权列表中的设备才能连接
- 开源可审计:Tailscale 的 WireGuard 协议是开源的
Q3: 能在手机上用吗?
A: 可以!
- iOS/Android 都有 Tailscale 官方 App
- 配合 Termius 等终端 App,可以在手机上 SSH 到家里的设备
Q4: 需要公网 IP 吗?
A: 不需要!
- Tailscale 使用 NAT 穿透技术
- 即使在咖啡厅的公共 WiFi,也能连家里的设备
Q5: 设备离线后怎么办?
A:
- 设备离线时无法连接(正常)
- 重新上线后 Tailscale 会自动重新连接
- 可以在管理后台查看设备在线状态
Q6: 能连接别人的设备吗?
A: 可以,两种方式:
- 接受邀请:对方在 Tailscale 后台邀请你加入网络
- 共享网络:使用 Tailscale 的"网络共享"功能
Q7: 速度如何?
A: 取决于多种因素:
- 两端设备的网络速度
- 中间经过的 NAT 转发次数
- 一般体验:本地局域网速度,外地访问取决于双方宽带
Q8: 支持端口转发吗?
A: 支持!
- Tailscale 可以转发任意端口
- 例如:访问家里的 NAS、摄像头、Web 服务等
进阶学习资源
官方文档:
推荐阅读:
- Tailscale 的 ACL(访问控制列表)配置
- SSH 密钥管理最佳实践
- WireGuard 协议原理(Tailscale 底层技术)
社区资源:
- r/Tailscale subreddit
- Tailscale GitHub Discussions
- SSH 教程(推荐 DigitalOcean 的教程)
更新日志
| 版本 | 日期 | 更新内容 |
|---|---|---|
| v1.0 | 2026-03-26 | 初始版本 |
| v1.1 | 2026-03-26 | 🎉 大幅展开:增加背景知识、实战案例、故障排查、进阶配置、FAQ |
贡献与反馈
发现问题或有建议?
- 欢迎提出改进建议
- 可以分享你的配置经验
- 帮助更多小白用户
使用体验分享:
- 如果这个教程帮到了你,欢迎分享给更多人
- 可以在 X (Twitter) 上 @nopinduoduo 反馈
最后的话
"技术不是目的,自由才是。" — Kevin (多多)
这套配置能带给你:
- ✅ 随时随地访问家里的设备
- ✅ 不再受物理位置限制
- ✅ 真正的数字自由
下一步建议:
- 先完成基础配置(30 分钟)
- 验证免密登录成功
- 探索进阶功能(别名、脚本等)
- 分享给你的朋友
记住:
- 遇到问题先看"故障排查"部分
- 90% 的问题都是公钥位置或权限问题
- 实在不行,用
查看详细日志-vvv
教程版本:v1.1 最后更新:2026-03-26 作者:Kevin (多多) @nopinduoduo 问题反馈:查看故障排查速查表
附录:完整配置示例
日常使用:
# 快速查看 Mac mini 的磁盘ssh macmini "df -h"# 重启服务器上的 Dockerssh server "docker restart $(docker ps -aq)"# 从 Windows 下载文件到 Macscp Qyc@windows:/C/Users/Qyc/Documents/file.pdf ~/Downloads/# 批量更新所有设备for host in macmini windows server; dossh $host "sudo apt update && sudo apt upgrade -y"done
祝你配置顺利!有问题随时查故障排查部分。 🚀