局域网双机远程访问 - 完整学习教程

局域网双机远程访问 - 完整学习教程

教程级别: 从零到一 预计学习时间: 8-10 小时 前置知识: 基本计算机操作、了解 IP 地址概念、会使用命令行终端

环境搭建指南

系统要求

本教程覆盖 Windows、macOS、Linux 三大平台。你需要两台连接到同一局域网的计算机(以下称为"本机"和"远程机"):

组件 最低要求 推荐配置
网络 同一局域网,百兆以太网或 Wi-Fi 千兆以太网
操作系统 Windows 10+ / macOS 12+ / Ubuntu 20.04+ 任意组合均可互通
权限 远程机需要管理员/sudo 权限

确认两台机器在同一局域网:

# 在本机执行,查看本机 IP
# macOS/Linux
ifconfig | grep "inet " | grep -v 127.0.0.1

# Windows
ipconfig | findstr "IPv4"

执行结果:

# macOS 示例输出
inet 192.168.1.10 netmask 0xffffff00 broadcast 192.168.1.255

# Windows 示例输出
IPv4 地址 . . . . . . . . . . . . . . . . . . . . 192.168.1.20

确认两台机器的 IP 地址在同一网段(如都是 192.168.1.x),然后验证互通:

# 在本机 ping 远程机(替换为远程机的实际 IP)
ping -c 4 192.168.1.100    # macOS/Linux
ping -n 4 192.168.1.100    # Windows

执行结果:

64 bytes from 192.168.1.100: icmp_seq=0 ttl=64 time=0.352 ms
64 bytes from 192.168.1.100: icmp_seq=1 ttl=64 time=0.289 ms
64 bytes from 192.168.1.100: icmp_seq=2 ttl=64 time=0.315 ms
--- 192.168.1.100 ping statistics ---
4 packets transmitted, 4 packets received, 0.0% packet loss

如果 ping 通,说明两台机器网络互通,可以继续。

安装步骤

本教程涉及四个工具,按需安装:

# 1. SSH(通常系统已内置,无需安装)
# 验证:
ssh -V

# 2. Windows RDP(Windows Pro/Enterprise 内置,Home 版不支持被控)
# Windows 上启用:设置 → 系统 → 远程桌面 → 启用远程桌面

# 3. RustDesk(跨平台图形化远程桌面)
# macOS
brew install --cask rustdesk

# Ubuntu/Debian
wget https://github.com/rustdesk/rustdesk/releases/download/1.4.6/rustdesk-1.4.6-x86_64.deb
sudo dpkg -i rustdesk-1.4.6-x86_64.deb

# Windows
# 从 https://rustdesk.com/ 下载安装包

# 4. VNC(以 TigerVNC 为例,Linux 场景)
# Ubuntu/Debian
sudo apt install tigervnc-standalone-server tigervncviewer

# macOS 使用内置的"屏幕共享"应用(VNC 兼容)

验证安装

# 验证 SSH
ssh -V
# 预期输出:OpenSSH_9.6p1, LibreSSL 3.3.6 (或其他版本号)

# 验证 RustDesk(通过 GUI 查看版本)
# 打开 RustDesk → 关于 → 查看版本号
# 当前最新稳定版:1.4.6

# 验证 VNC(Linux)
vncserver -version
# 预期输出:TigerVNC Server 1.13.x

第一部分:入门篇

1.1 SSH 远程登录——最基础的远程访问

概念讲解:

SSH(Secure Shell)是局域网远程访问的基石。它通过加密通道让你在本机终端上操作远程机的命令行。SSH 采用客户端-服务器模型:远程机运行 SSH 服务端(sshd),本机使用 SSH 客户端连接。

SSH 的安全性来自三层协议架构: - 传输层:使用 Diffie-Hellman 或 Curve25519 算法协商加密密钥,建立加密隧道 - 认证层:验证你的身份(密码或公钥) - 连接层:在加密隧道中打开多个逻辑通道(shell、文件传输、端口转发)

代码示例:

# 第一步:确保远程机的 SSH 服务已启动
# 在远程机上执行:
# macOS:系统设置 → 通用 → 共享 → 远程登录(开启)
# Linux:
sudo systemctl start sshd
sudo systemctl enable sshd    # 开机自启

# 第二步:从本机连接远程机
# 基本格式:ssh 用户名@远程机IP
ssh user@192.168.1.100

# 首次连接会提示确认指纹,输入 yes
# 然后输入远程机用户密码

# 第三步:连接成功后,你就在远程机的终端中了
# 可以执行任何远程机命令
whoami           # 显示当前用户
hostname         # 显示远程机主机名
uptime           # 显示运行时间
ls -la /home     # 列出远程机 home 目录

# 第四步:退出远程连接
exit

执行结果:

$ ssh user@192.168.1.100
The authenticity of host '192.168.1.100 (192.168.1.100)' can't be established.
ED25519 key fingerprint is SHA256:abc123def456...
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.1.100' (ED25519) to the known hosts.
user@192.168.1.100's password:
Welcome to Ubuntu 24.04 LTS
Last login: Sat Apr 12 10:00:00 2026

$ whoami
user
$ hostname
remote-server
$ uptime
 10:30:00 up 5 days,  3:20,  1 user,  load average: 0.05, 0.02, 0.00
$ exit
Connection to 192.168.1.100 closed.

练习题: 1. 使用 SSH 连接到远程机,执行 uname -a 查看远程机的系统信息 2. 尝试使用 ssh -p 2222 user@192.168.1.100 指定非默认端口连接(需要远程机配置了 2222 端口)


1.2 SSH 密钥认证——告别密码登录

概念讲解:

密码认证存在被暴力破解的风险。SSH 密钥认证使用非对称加密(公钥/私钥对)替代密码,更安全也更方便。原理:你在本机生成一对密钥(私钥 + 公钥),将公钥放到远程机上。连接时,SSH 用私钥做数学证明你拥有对应的公钥,无需传输密码。

代码示例:

# 第一步:在本机生成密钥对(使用 Ed25519 算法,比 RSA 更安全更短)
ssh-keygen -t ed25519 -C "my-lan-key"

# 按三次回车使用默认值:
# 1. 密钥保存位置(默认 ~/.ssh/id_ed25519)
# 2. 密钥口令(可选,留空则无口令)
# 3. 确认口令

# 第二步:将公钥复制到远程机
ssh-copy-id user@192.168.1.100

# 输入远程机密码(这是最后一次需要密码)

# 第三步:测试免密码登录
ssh user@192.168.1.100
# 不再需要密码,直接登录成功

# 第四步:查看生成的密钥文件
ls ~/.ssh/
# id_ed25519      ← 私钥(绝不能泄露)
# id_ed25519.pub  ← 公钥(可以公开)
# known_hosts     ← 已信任的远程机指纹

执行结果:

$ ssh-keygen -t ed25519 -C "my-lan-key"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/user/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user/.ssh/id_ed25519
Your public key has been saved in /home/user/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:xyz789abc456... my-lan-key
The key's randomart image is:
+--[ED25519 256]--+
|       .o o      |
|      ...= .     |
|     . +o *      |
+----[SHA256]-----+

$ ssh-copy-id user@192.168.1.100
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/user/.ssh/id_ed25519.pub"
user@192.168.1.100's password:
Number of key(s) added: 1
Now try logging into the machine, with:   "ssh 'user@192.168.1.100'"
and check to make sure that only the key(s) you wanted were added.

$ ssh user@192.168.1.100
Welcome to Ubuntu 24.04 LTS
Last login: Sat Apr 12 10:30:00 2026
# 直接登录,无需密码!

练习题: 1. 生成一个新的 Ed25519 密钥对,并设置一个密钥口令(passphrase),体验双重保护 2. 查看远程机上的 ~/.ssh/authorized_keys 文件,确认公钥已添加


1.3 Windows RDP 远程桌面——图形化远程控制

概念讲解:

RDP(Remote Desktop Protocol)是 Microsoft 开发的远程桌面协议,深度集成在 Windows 中。与 SSH 的纯命令行不同,RDP 传输的是完整的图形界面,你在本机看到的就是远程机的桌面。

RDP 的核心技术是"命令级渲染"——它不传输原始像素,而是传输绘图指令(如"在坐标 (x,y) 绘制一个按钮"),客户端在本地重新执行这些指令来呈现画面。这让 RDP 在局域网中带宽消耗极低(0.5-2 Mbps),延迟仅 10-30ms。

代码示例:

# ===== 在远程机(Windows)上启用 RDP =====

# 方法一:GUI 操作
# 设置 → 系统 → 远程桌面 → 开启"远程桌面"
# 注意:需要 Windows Pro/Enterprise 版本

# 方法二:命令行启用(以管理员运行 PowerShell)
Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server' -name "fDenyTSConnections" -value 0
Enable-NetFirewallRule -DisplayGroup "Remote Desktop"

# ===== 在本机连接 =====

# macOS:安装 Microsoft Remote Desktop
# 从 App Store 搜索 "Microsoft Remote Desktop" 安装
# 打开应用 → 添加 PC → 输入 192.168.1.100 → 输入 Windows 用户名密码

# Linux:使用 FreeRDP 或 Remmina
# FreeRDP 方式
xfreerdp3 /v:192.168.1.100 /u:username

# Windows:自带远程桌面连接
# 按 Win+R → 输入 mstsc → 回车 → 输入远程机 IP → 连接
# Windows PowerShell:快速启动远程桌面连接
mstsc /v:192.168.1.100

执行结果:

# FreeRDP 连接成功的输出示例
$ xfreerdp3 /v:192.168.1.100 /u:admin
Password:
[10:35:00:000] [INFO] Connected to 192.168.1.100:3389
[10:35:00:123] [INFO] SSL/TLS connected with protocol TLS 1.3
[10:35:00:456] [INFO] Authentication: NLA
[10:35:01:789] [INFO] Desktop resolution: 1920x1080
# 随后弹出远程桌面窗口,可以看到远程机的完整桌面

练习题: 1. 在两台 Windows 电脑之间建立 RDP 连接,尝试在远程桌面中打开一个应用程序 2. 在远程桌面中尝试复制一段文字,在本机粘贴,体验剪贴板同步功能


第二部分:进阶篇

2.1 SSH 端口转发——加密隧道中转任意流量

概念讲解:

SSH 端口转发(又称 SSH 隧道)是 SSH 最强大的扩展能力。它可以在加密的 SSH 连接中"穿透"任意 TCP 流量。三种模式:

  • 本地转发(-L):将本机端口转发到远程网络中的目标
  • 远程转发(-R):将远程机端口转发到本地网络中的目标
  • 动态转发(-D):创建 SOCKS 代理,按需转发

典型用途:为不加密的 VNC 连接加上 SSH 加密保护。

代码示例:

# 场景:通过 SSH 隧道安全访问远程机上的 VNC 服务(端口 5900)

# 第一步:建立本地端口转发
# 将本机 5901 端口 → SSH 隧道 → 远程机 localhost:5900
ssh -L 5901:localhost:5900 user@192.168.1.100

# 这个 SSH 会话保持打开状态,充当隧道

# 第二步:在另一个终端,连接本机 5901 端口(实际访问远程机的 VNC)
# 使用 VNC 客户端连接 localhost:5901
# 流量路径:VNC客户端 → localhost:5901 → SSH加密隧道 → 远程机:5900

# 第三步:远程端口转发示例
# 让远程网络的用户访问本机的 Web 服务(端口 80)
ssh -R 8080:localhost:80 user@192.168.1.100
# 远程机上的用户访问 localhost:8080 即可看到本机的 Web 服务

# 第四步:动态端口转发(SOCKS 代理)
ssh -D 1080 user@192.168.1.100
# 本机 1080 端口变成 SOCKS5 代理
# 浏览器设置 SOCKS5 代理为 localhost:1080 即可通过远程机上网

执行结果:

$ ssh -L 5901:localhost:5900 user@192.168.1.100
Welcome to Ubuntu 24.04 LTS
Last login: Sat Apr 12 10:35:00 2026
# 此终端保持连接状态,隧道已建立

# 另一个终端验证隧道:
$ vncviewer localhost:5901
# 连接成功,VNC 流量通过 SSH 加密传输

注意事项: - SSH 隧道会话不能关闭,关闭则隧道断开 - 可以加 -f -N 参数让隧道在后台运行:ssh -f -N -L 5901:localhost:5900 user@192.168.1.100 - 如果报错 bind: Address already in use,说明端口被占用,换一个端口号

练习题: 1. 建立一个 SSH 隧道,将本机 8080 端口转发到远程机的 80 端口,然后用浏览器访问 localhost:8080 2. 使用 -f -N 参数让隧道在后台运行,然后用 ps aux | grep ssh 确认隧道进程存在


2.2 VNC 远程桌面——跨平台的经典方案

概念讲解:

VNC(Virtual Network Computing)基于 RFB 协议,采用"帧缓冲"模型:服务端维护屏幕的像素矩阵,客户端请求变化区域并重建画面。与 RDP 的"命令级渲染"不同,VNC 传输的是实际像素数据,因此带宽消耗更大,但平台无关性极好。

VNC 的增量更新机制:客户端请求"仅发送自上次更新以来变化的区域",服务端只传输变化矩形的像素数据。CopyRect 编码在窗口拖动时仅传输"从 A 位置复制到 B 位置"的指令,而非整块像素。

代码示例:

# ===== 在远程机(Linux)上配置 VNC 服务端 =====

# 第一步:设置 VNC 密码
vncpasswd
# 输入并确认密码(6-8 位)
# 提示是否设置 view-only 密码,选 n

# 第二步:配置桌面环境
# 创建 VNC 启动配置文件
mkdir -p ~/.vnc
cat > ~/.vnc/xstartup << 'EOF'
#!/bin/bash
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
exec startxfce4    # 使用 XFCE 桌面(需安装 xfce4)
EOF
chmod +x ~/.vnc/xstartup

# 第三步:启动 VNC 服务
vncserver :1 -geometry 1920x1080 -depth 24
# :1 表示显示编号 1,对应端口 5901(5900 + 1)
# -geometry 分辨率
# -depth 色深

# 第四步:从本机连接
# Linux:
vncviewer 192.168.1.100:5901

# macOS:使用内置"屏幕共享"
# Finder → 前往 → 连接服务器 → vnc://192.168.1.100:5901

# 第五步:通过 SSH 隧道加密连接(推荐)
# 先建隧道
ssh -f -N -L 5901:localhost:5901 user@192.168.1.100
# 然后连接本地端口
vncviewer localhost:5901

执行结果:

$ vncpasswd
Password:
Verify:
Would you like to enter a view-only password (y/n)? n

$ vncserver :1 -geometry 1920x1080 -depth 24
New 'remote-server:1 (user)' desktop is remote-server:1
Starting applications specified in /home/user/.vnc/xstartup
Log file is /home/user/.vnc/remote-server:1.log

$ vncviewer 192.168.1.100:5901
# 弹出远程桌面窗口,可以操作远程机的 XFCE 桌面

注意事项: - 标准 VNC 默认不加密,务必通过 SSH 隧道使用 - VNC 端口规则:显示编号 :N 对应端口 5900+N - 关闭 VNC 服务:vncserver -kill :1 - 如果连接黑屏,检查 xstartup 文件是否正确配置了桌面环境

练习题: 1. 在远程机上启动 VNC 服务,从本机连接并尝试在远程桌面中打开终端 2. 通过 SSH 隧道加密连接 VNC,比较直接连接和隧道连接的安全性差异


2.3 RustDesk——开箱即用的跨平台方案

概念讲解:

RustDesk 是一个开源的远程桌面工具,使用 Rust 语言编写。它的核心架构是 P2P(点对点)优先:在局域网中,两台电脑直接通过 IP 地址发现对方并建立连接,无需任何中继服务器。

RustDesk 使用 VP8/VP9/AV1 视频编码器压缩屏幕画面,配合 NaCl 加密库(x25519 + XSalsa20 + Poly1305)实现端到端加密。在局域网中延迟通常 10-50ms,体验接近本地操作。

代码示例:

# ===== 最简方式:局域网直连 =====

# 第一步:在两台机器上分别安装并启动 RustDesk
# macOS
open /Applications/RustDesk.app

# Linux
rustdesk &

# Windows:双击桌面图标启动

# 第二步:在远程机上查看 ID 和设置密码
# RustDesk 主界面显示一个 9 位数字 ID(如 123 456 789)
# 点击"设置密码"输入一个连接密码

# 第三步:在本机连接远程机
# 在 RustDesk 本机界面输入远程机的 ID
# 输入密码即可连接

# ===== 命令行/服务方式 =====

# 在远程机以服务模式启动 RustDesk(Linux)
# 注意:RustDesk 主要通过 GUI 操作,CLI 功能有限
# Linux 上以服务方式运行:
rustdesk --service

# 从命令行直接连接(传入对方 ID 或 IP)
# 局域网中可直接使用 IP 地址
rustdesk 192.168.1.100

# 注意:密码设置和文件传输建议通过 GUI 完成
# RustDesk GUI → 设置 → 安全 → 设置固定密码
# RustDesk GUI → 连接后工具栏 → 文件传输

执行结果:

# RustDesk 启动后的主界面显示:
# ┌─────────────────────────┐
# │  您的桌面 ID:           │
# │     123 456 789         │
# │                         │
# │  [设置密码]             │
# │                         │
# │  远程桌面 ID:           │
# │  [________________]     │
# │  [连接]                 │
# └─────────────────────────┘

# 输入对方 ID 并连接后,弹出远程桌面窗口

注意事项: - 局域网中使用 IP 直连更快,不需要经过注册服务器 - 首次连接会提示确认对方指纹,类似 SSH - 如果连接不上,检查防火墙是否放行了 RustDesk 端口(默认 21116-21119)

练习题: 1. 在两台不同操作系统的电脑上安装 RustDesk,建立跨平台远程连接 2. 使用 RustDesk 的文件传输功能,从本机发送一个文件到远程机


第三部分:高级篇

3.1 SSH 安全加固

生产环境中的 SSH 需要额外的安全配置:

# 编辑远程机的 SSH 配置文件
sudo nano /etc/ssh/sshd_config

# 推荐的安全配置(修改以下项):
Port 22                          # 可改为非标准端口(如 2222)
PermitRootLogin no               # 禁止 root 直接登录
PasswordAuthentication no        # 禁用密码登录(仅密钥认证)
MaxAuthTries 3                   # 最多尝试 3 次认证
ClientAliveInterval 300          # 5 分钟无操作发送心跳
ClientAliveCountMax 2            # 2 次无响应则断开

# 保存后重启 SSH 服务
sudo systemctl restart sshd
# 安装 fail2ban 防止暴力破解
sudo apt install fail2ban    # Debian/Ubuntu
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

# 默认配置已足够:5 次失败登录后封禁 IP 10 分钟
# 配置文件:/etc/fail2ban/jail.local

执行结果:

$ sudo systemctl restart sshd
# 无输出表示成功

$ sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed: 0
|  |- Total failed:     0
`- Actions
   |- Currently banned: 0
   |- Total banned:     0

3.2 SSH 配置文件简化连接

每次输入 ssh user@192.168.1.100 很繁琐,可以用配置文件简化:

# 编辑 SSH 客户端配置文件
nano ~/.ssh/config

# 添加以下内容
Host myserver
    HostName 192.168.1.100
    User admin
    Port 22
    IdentityFile ~/.ssh/id_ed25519
    LocalForward 5901 localhost:5901

Host win-desktop
    HostName 192.168.1.50
    User administrator
    Port 22

# 保存后,直接使用别名连接
ssh myserver       # 等效于 ssh -i ~/.ssh/id_ed25519 -L 5901:localhost:5901 admin@192.168.1.100
ssh win-desktop     # 等效于 ssh -p 22 administrator@192.168.1.50

执行结果:

$ ssh myserver
Welcome to Ubuntu 24.04 LTS
Last login: Sat Apr 12 11:00:00 2026 from 192.168.1.10
# 一条命令直接连接,自动使用密钥认证和端口转发

3.3 RustDesk 自托管服务器

在需要管理多台机器的场景中,搭建自托管服务器实现集中管理:

# ===== 在局域网内一台服务器上部署 RustDesk Server =====

# 第一步:下载 RustDesk Server
wget https://github.com/rustdesk/rustdesk-server/releases/download/1.1.15/rustdesk-server-linux-amd64.zip
unzip rustdesk-server-linux-amd64.zip

# 第二步:启动注册服务器(hbbs)
./hbbs
# 默认监听端口 21115(TCP)、21116(TCP/UDP)
# 负责设备注册和发现

# 第三步:启动中继服务器(hbbr)
./hbbr
# 默认监听端口 21117(TCP)
# 在 P2P 直连失败时转发流量

# 第四步:在客户端配置服务器地址
# RustDesk → 设置 → 网络 → ID/中继服务器
# 填入服务器 IP:192.168.1.50
# Key:hbbs 启动时生成的密钥

# 第五步:验证
# 所有配置了相同服务器的客户端可以互相发现和连接

执行结果:

$ ./hbbs
[2026-04-12 11:05:00.123456 +08:00] INFO [src/common.rs:113] Private key file id_ed25519 not found, generating one...
[2026-04-12 11:05:00.234567 +08:00] INFO [src/rendezvous_mediator.rs:89] Key: abc123xyz456...
[2026-04-12 11:05:00.345678 +08:00] INFO listening on tcp :21115
[2026-04-12 11:05:00.456789 +08:00] INFO listening on websocket tcp :21116

$ ./hbbr
[2026-04-12 11:05:01.123456 +08:00] INFO listening on tcp :21117

最佳实践: 1. SSH 始终使用密钥认证,禁用密码登录 2. VNC 必须通过 SSH 隧道使用,不要裸连 3. 定期更新所有远程访问工具到最新版本 4. 为不同场景使用不同方案:命令行用 SSH,图形化用 RustDesk/RDP 5. 局域网中优先使用 IP 直连,减少中间环节


第四部分:实战项目

项目需求

搭建一个完整的局域网远程管理环境,实现: - 通过 SSH 安全管理远程 Linux 服务器 - 通过 RustDesk 图形化操作远程桌面 - 通过 SSH 隧道加密 VNC 连接作为备用图形化方案 - 使用 SSH 配置文件简化日常连接

综合运用教程中的 5 个知识点:SSH 密钥认证、SSH 端口转发、SSH 配置文件、VNC 配置、RustDesk 部署。

项目设计

本机 (192.168.1.10, macOS)
  │
  ├── SSH ──────────→ 远程机 (192.168.1.100, Ubuntu)
  │   ├── 命令行管理         │
  │   └── SSH 隧道 → VNC     │
  │                          │
  └── RustDesk ─────→ 远程机
      └── 图形化远程桌面       │
                               │
                    RustDesk Server (192.168.1.50)
                    (可选:集中管理)

完整实现代码

#!/bin/bash
# setup-remote-access.sh
# 在本机执行,一键配置局域网远程访问环境
# 用法:./setup-remote-access.sh <远程机IP> <用户名>

set -e

REMOTE_IP=${1:-"192.168.1.100"}
REMOTE_USER=${2:-"user"}

echo "===== 局域网远程访问环境配置 ====="
echo "远程机:$REMOTE_USER@$REMOTE_IP"
echo ""

# 1. 生成 SSH 密钥(如果不存在)
if [ ! -f ~/.ssh/id_ed25519 ]; then
    echo "[Step 1/5] 生成 SSH 密钥..."
    ssh-keygen -t ed25519 -C "lan-remote-$(date +%Y%m%d)" -f ~/.ssh/id_ed25519 -N ""
    echo "密钥已生成:~/.ssh/id_ed25519"
else
    echo "[Step 1/5] SSH 密钥已存在,跳过生成"
fi

# 2. 复制公钥到远程机
echo "[Step 2/5] 复制公钥到远程机(需要输入密码)..."
ssh-copy-id -i ~/.ssh/id_ed25519.pub "$REMOTE_USER@$REMOTE_IP"

# 3. 配置 SSH 配置文件
echo "[Step 3/5] 配置 SSH 快捷连接..."
SSH_CONFIG_ENTRY=$(cat <<EOF

# 自动生成 - 局域网远程访问配置
Host remote
    HostName $REMOTE_IP
    User $REMOTE_USER
    IdentityFile ~/.ssh/id_ed25519
    LocalForward 5901 localhost:5901
    ServerAliveInterval 60
    ServerAliveCountMax 3
EOF
)

# 避免重复添加
if ! grep -q "Host remote" ~/.ssh/config 2>/dev/null; then
    mkdir -p ~/.ssh
    echo "$SSH_CONFIG_ENTRY" >> ~/.ssh/config
    echo "已添加 'remote' 别名到 ~/.ssh/config"
else
    echo "'remote' 别名已存在,跳过"
fi

# 4. 在远程机上安装和配置 VNC(通过 SSH)
echo "[Step 4/5] 在远程机上配置 VNC..."
ssh remote << 'REMOTE_SCRIPT'
# 安装 VNC 服务端和 XFCE 桌面(如未安装)
if ! command -v vncserver &> /dev/null; then
    echo "安装 TigerVNC 和 XFCE..."
    sudo apt update
    sudo apt install -y tigervnc-standalone-server tigervncviewer xfce4 xfce4-goodies
fi

# 配置 VNC
mkdir -p ~/.vnc
cat > ~/.vnc/xstartup << 'EOF'
#!/bin/bash
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
exec startxfce4
EOF
chmod +x ~/.vnc/xstartup

# 设置 VNC 密码(如果尚未设置)
if [ ! -f ~/.vnc/passwd ]; then
    echo "请设置 VNC 密码:"
    vncpasswd
fi

echo "VNC 配置完成"
REMOTE_SCRIPT

# 5. 启动 VNC 服务(通过 SSH)
echo "[Step 5/5] 启动远程 VNC 服务..."
ssh remote 'vncserver -kill :1 2>/dev/null || true; vncserver :1 -geometry 1920x1080 -depth 24'

echo ""
echo "===== 配置完成 ====="
echo ""
echo "使用方法:"
echo "  SSH 命令行:  ssh remote"
echo "  VNC(加密):  先执行 ssh remote,然后在另一终端执行 vncviewer localhost:5901"
echo "  RustDesk:    在本机和远程机启动 RustDesk,输入 ID 连接"
echo ""
echo "快速启动加密 VNC:"
echo "  ssh -f -N remote && vncviewer localhost:5901"

代码解析

代码段 运用的知识点 说明
ssh-keygen -t ed25519 1.2 SSH 密钥认证 生成 Ed25519 密钥对
ssh-copy-id 1.2 SSH 密钥认证 将公钥部署到远程机
~/.ssh/config 配置 3.2 SSH 配置文件 别名 + 自动密钥 + 端口转发
LocalForward 5901 2.1 SSH 端口转发 每次连接自动建立 VNC 隧道
vncserver :1 配置 2.2 VNC 远程桌面 设置分辨率、色深、桌面环境

扩展挑战

  1. 添加自动重连:编写一个 watchdog.sh 脚本,监控 SSH 隧道是否断开,断开后自动重连
  2. 多机管理:扩展脚本支持多台远程机的配置,在 SSH config 中为每台机器创建独立别名
  3. RustDesk Server 集成:在脚本中加入 RustDesk Server 的自动部署,实现集中管理

第五部分:常见问题与排查指南

常见错误及解决方案

错误信息 原因 解决方案
Connection refused (SSH) 远程机未启动 SSH 服务 sudo systemctl start sshd
Connection refused (RDP) 远程机未启用远程桌面 Windows 设置中开启远程桌面
Connection refused (VNC) VNC 服务未启动或端口错误 vncserver :1 启动,确认端口 5901
Permission denied (publickey) 密钥未部署或被禁用密码登录 重新执行 ssh-copy-id,或临时启用密码登录
Host key verification failed 远程机重装系统导致指纹变化 ssh-keygen -R 192.168.1.100 删除旧指纹
bind: Address already in use 端口转发端口被占用 更换本地端口号,如 -L 5902:localhost:5901
VNC 黑屏 xstartup 未正确配置桌面环境 检查 ~/.vnc/xstartup 是否指定了桌面环境
RustDesk 连接超时 防火墙阻止或不在同一网段 检查防火墙设置,确认网络互通
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED 远程机重装或密钥变更 删除 known_hosts 中对应条目后重连

调试技巧

  1. SSH 详细日志:使用 ssh -vvv user@192.168.1.100 查看连接过程的每一步详情,定位认证或网络问题
  2. 端口检测:使用 nc -zv 192.168.1.100 22 快速检测远程端口是否可达,不需要建立完整连接
  3. VNC 日志分析:检查 ~/.vnc/机器名:1.log 文件,VNC 启动或连接错误信息都在此文件中

第六部分:学习路线推荐

官方文档推荐阅读顺序

SSH/OpenSSH: 1. OpenSSH 官方手册 — 理解 ssh、sshd、ssh_config 的完整参数 2. RFC 4251 - SSH Protocol Architecture — 理解三层协议设计 3. RFC 4254 - SSH Connection Protocol — 深入理解端口转发和通道复用

RDP: 1. Microsoft 远程桌面服务文档 — 部署和配置指南 2. Understanding RDP — 协议原理

VNC/RFB: 1. RFC 6143 - The Remote Framebuffer Protocol — VNC 协议规范 2. TigerVNC 项目文档 — 实现细节

RustDesk: 1. RustDesk 官方文档 — 安装、配置、自托管 2. RustDesk GitHub Wiki — FAQ 和高级配置

推荐进阶资源

  • 书籍:《SSH Mastery》(Michael W. Lucas 著)— SSH 的权威实践指南
  • 课程:Linux Foundation 的 Linux 系统管理课程 — 包含 SSH 和远程管理的系统讲解
  • 开源项目FreeRDP — 开源 RDP 客户端,阅读源码理解协议实现