SSH(Secure Shell)是远程管理服务器、传输文件和构建安全隧道的工具。本教程将从零开始,覆盖 Linux、macOS 和 Windows 三大平台,带你从基础登录一路进阶到跳板、隧道和连接复用等高级技巧。


SSH 是什么?

SSH 是一种加密网络协议,用于在不安全的网络中安全地访问远程计算机。它的核心目的是替代不安全的 Telnet、rlogin、FTP 等,提供强加密的远程 shell 和文件传输。SSH 目前使用的主要版本为 SSH-2(SSH-1 因安全缺陷已被淘汰),本教程所有内容均基于 SSH-2。

工作简理
SSH 连接分为三个阶段:

  1. 传输层建立:客户端与服务器协商加密算法,通过 Diffie‑Hellman 密钥交换生成会话密钥,后续通信全部加密。
  2. 用户认证:服务器向客户端提供自己的主机密钥指纹供验证(防止中间人攻击),客户端再向服务器证明自己的身份,最常用的是密码和公钥认证。
  3. 服务会话:认证通过后,打开加密通道,可以运行远程 shell、执行命令、转发端口等。

本教程的命令均基于 OpenSSH,它是全球 Linux、macOS、Windows 的标准 SSH 实现,也是其他 SSH 工具的底层基础。


安装 SSH

我们分别说明客户端的安装,如果想让本机作为 SSH 服务器被连接,则需要额外安装并启用 sshd 服务。

Linux

绝大多数现代发行版已预装 OpenSSH 客户端,可通过以下命令检查:

1
ssh -V

若未安装或需要最新版本:

  • Debian / Ubuntu / Linux Mint
    1
    sudo apt update && sudo apt install openssh-client
  • Red Hat / CentOS / Fedora / RHEL
    1
    sudo dnf install openssh-clients
  • Arch Linux / Manjaro
    1
    sudo pacman -S openssh
  • openSUSE
    1
    sudo zypper install openssh

若想让本机作为 SSH 服务器 被连接,需要安装 openssh-server 并启动服务(如 sudo systemctl enable ssh --now)。详细服务器配置请见第 8 节。

macOS

macOS 从很早的版本就自带了 OpenSSH 客户端和服务器,终端直接可用,无需安装任何东西。可运行 ssh -V 确认。如果需要更新版本,最方便的是通过 Homebrew:brew install openssh(它不会替换系统自带版本,但会让你使用最新的 ssh)。系统自带的 sshd 服务默认未开启,如需开启可在“系统设置 → 通用 → 共享”中勾选“远程登录”,或使用 sudo systemsetup -setremotelogin on。详细配置见第 8 节。

Windows

方法一:内置 OpenSSH(推荐)
Windows 10 1809 及以上、Windows Server 2019 及以上已内置 OpenSSH 客户端。

  • PowerShell命令提示符 中直接运行 ssh 测试是否可用。
  • 若未启用,通过 设置 → 应用 → 可选功能 → 添加功能 → OpenSSH 客户端 安装。
  • 也可通过 PowerShell 管理员命令安装:
    1
    Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0

方法二:WSL(Windows Subsystem for Linux)
安装 WSL2 后,你将获得一个完整的 Linux 环境,其内的 OpenSSH 与 Linux 完全一致。日常管理工作可以将配置集中放在 WSL 里,并通过 \\wsl$ 互访文件。

方法三:第三方图形客户端
如 PuTTY、MobaXterm、Termius 等,它们提供图形界面,适合不习惯命令行的用户。本教程主要聚焦命令行(OpenSSH)的统一用法,学会后所有平台通用。


基本用法:第一次连接

最基础的用法:

1
2
3
ssh username@remote_host
# 例如
ssh root@192.168.1.100

如果 SSH 服务端口不是默认的 22,使用 -p 指定(注意是小写 p):

1
ssh -p 2222 user@host

首次连接与主机密钥

第一次连接时,你会看到类似信息:

1
2
3
The authenticity of host 'example.com (93.184.216.34)' can't be established.
ED25519 key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
Are you sure you want to continue connecting (yes/no)?

这是 SSH 主机密钥验证,目的是防止中间人攻击。你应当通过可信渠道(如控制台、带外通信)核对这个指纹,确认无误后输入 yes。一旦确认,该指纹被保存在:

  • Linux / macOS:~/.ssh/known_hosts
  • Windows:C:\Users\你的用户名\.ssh\known_hosts

后续连接若指纹发生变化(服务器重装系统或发生攻击),你会得到醒目的警告并拒绝连接。如果确认是正常变更,可以用下面命令清除旧指纹:

1
ssh-keygen -R 主机名或IP

输入 yes 后,会提示你输入远程用户的密码,密码输入时不显示字符,输入完按回车即可登录。不过密码登录既麻烦又有被暴力破解的风险,因此强烈建议立即设置密钥登录


密钥认证(免密登录)

公钥认证是目前最安全且方便的 SSH 认证方式。原理:你生成一对密钥(私钥自己保管,公钥放到服务器上),连接时客户端用私钥签名一个挑战,服务器用公钥验证签名。

生成密钥对

推荐使用更安全的 ED25519 算法(速度快、密钥短、安全强度相当于 RSA 3072 位):

1
ssh-keygen -t ed25519 -C "your_email@example.com"

-C 后面跟的注释可随意填写,通常用于标识密钥来源。

如果您的系统或目标服务器较旧不支持 ED25519,可降级使用 RSA:

1
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

命令会提示你:

  • 保存路径:直接回车使用默认 ~/.ssh/id_ed25519(私钥)和 ~/.ssh/id_ed25519.pub(公钥)。
  • passphrase:强烈建议设置一个强密码短语。即使私钥泄露,没有 passphrase 也无法直接使用。如果不希望每次都输入,可配合 ssh-agent 使用(见后文)。留空则无密码保护。

将公钥复制到远程服务器

最简单的方式是使用 ssh-copy-id

1
ssh-copy-id username@remote_host

该命令会自动登录服务器,将本机默认公钥追加到远程的 ~/.ssh/authorized_keys,并自动纠正目录和文件的权限。

若系统无 ssh-copy-id(某些精简版或 Windows 环境),可手动复制:

1
2
# 通用一行命令
cat ~/.ssh/id_ed25519.pub | ssh user@host "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

注意:必须使用 >> 追加,不能只用 > 覆盖已有密钥。

权限设置

远程服务器上的 SSH 对目录和文件权限非常敏感。如果权限不正确,密钥认证会静默失败。在远程主机上执行:

1
2
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

本地私钥的权限同样需要是 600

1
2
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub # 公钥可为 644

在 Windows 上使用内置 OpenSSH,权限管理机制不同,但同样要求只有当前用户和 SYSTEM 可以访问私钥(通过文件属性 → 安全 → 高级,移除其他账户权限)。

管理多个密钥

当你有多个服务器或不同用途的密钥时,可以生成并保存为不同文件名,然后连接时用 -i 指定:

1
ssh -i ~/.ssh/my_ec2_key.pem ubuntu@ec2-host

更优雅的方式是在 ~/.ssh/config 中为不同主机指定 IdentityFile,见下一章。


SSH 客户端配置文件 ~/.ssh/config

通过配置文件,可以为不同主机定义别名、端口、用户名、密钥路径,甚至高级代理规则,让连接变得异常简单。

配置文件位置:

  • Linux / macOS:~/.ssh/config
  • Windows:C:\Users\你的用户名\.ssh\config (PowerShell 中也可用 ~/.ssh/config

该文件由多个 Host 块组成。解析顺序从上到下,匹配第一个符合的配置。

基础配置示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 一个开发服务器
Host dev
HostName 192.168.1.100
User root
Port 2222
IdentityFile ~/.ssh/dev_ed25519

# 跳板机
Host jump
HostName jump.example.com
User admin

# 内网主机,通过跳板机连接
Host internal
HostName 10.0.0.5
User ubuntu
ProxyJump jump # 自动先连 jump 再连此主机
ForwardAgent no # 明确禁用 agent 转发

配置完成后,直接 ssh dev 即可连接;ssh internal 则自动通过跳板机。

常用配置选项:

选项 说明
Host 别名或通配符 **.example.com
HostName 实际主机名或 IP
User 登录用户名
Port 端口号
IdentityFile 指定私钥路径,可多个
ProxyJump 跳板主机,可多个(逗号分隔)
ForwardAgent yes/no 是否启用 agent 转发
Compression yes 开启压缩(低带宽时有用)
ServerAliveInterval 心跳间隔(秒)
ControlMaster auto 启用连接复用
ControlPath 控制套接字路径
LogLevel INFO 输出日志级别,调试时用 DEBUG1

通配符示例:

1
2
3
Host *.mydomain.com
User admin
IdentityFile ~/.ssh/corp_ed25519

任何匹配 *.mydomain.com 的主机都会自动应用此配置。


文件传输:scp、rsync、sftp

scp(Secure Copy)

scp 是 SSH 协议的原生文件传输工具,用法和 cp 类似。

1
2
3
4
5
6
7
8
9
10
11
# 上传文件(注意 -P 大写指定端口)
scp -P 2222 local_file.txt user@host:/remote/path/

# 下载文件
scp user@host:/remote/file.txt ./local_folder/

# 递归复制整个目录
scp -r my_project user@host:/opt/

# 跨服务器复制(流量从 server1 直接到 server2,不经过本机)
scp user@server1:/path/file user@server2:/another/path/

其他常用参数:

  • -C:传输时压缩
  • -p:保留原文件的修改时间和权限
  • -v:显示详细过程

rsync(增量同步,更高效)

rsync 通过 SSH 通道同步文件和目录,只传输差异部分,适合大批量文件或定时备份。

1
2
3
4
5
6
7
8
# 同步本地目录到远程(-a 归档模式,-v 显示详情,-z 压缩)
rsync -avz -e "ssh -p 2222" local_dir/ user@host:/remote_dir/

# 从远程同步到本地
rsync -avz user@host:/remote/dir/ ./local_dir/

# 删除目标端多余文件,完全镜像
rsync -avz --delete -e ssh local/ user@host:/backup/

注意:本地源路径末尾加 / 表示复制目录内容,不加 / 则连同目录本身一起复制。

配合 ~/.ssh/config 使用会更简单,因为 rsync 会继承 SSH 配置:

1
rsync -avz dev:/data/backup/ ./backup/

SFTP(交互式文件管理)

sftp 提供了一个类似 FTP 的交互式会话,但全程通过 SSH 加密。

1
2
3
sftp user@host
# 或者使用配置文件中的别名
sftp dev

进入后常用命令:

1
2
3
4
5
6
7
8
ls, cd, pwd          -- 操作远程目录
lls, lcd, lpwd -- 操作本地目录(前缀 l 表示 local)
put file -- 上传文件
get remotefile -- 下载文件
mput *.txt -- 批量上传
mget *.log -- 批量下载
!command -- 执行本地 shell 命令
exit -- 退出

sftp 同样可以使用 -P 指定端口,也完全遵循 ~/.ssh/config 中的配置。


SSH 端口转发与隧道

SSH 最强大的功能之一:将任何 TCP 流量封装在加密隧道中。无论是保护不安全的协议,还是穿越防火墙访问内网,都非常实用。

本地转发(-L

把本地计算机的某个端口,通过 SSH 服务器转发到目标地址。

格式:
ssh -L 本地端口:目标主机:目标端口 用户@SSH服务器

典型场景: 远程 SSH 服务器 server 能访问内网数据库 db.internal:3306,而你的本地笔记本无法直连内网。你可以这样:

1
ssh -L 3307:db.internal:3306 user@server

现在,本地 localhost:3307 的所有流量都会被加密后送到 server,再由 server 转发给 db.internal:3306。你在本机用数据库客户端连接 127.0.0.1:3307 即可。

多主机、多端口可以叠加

1
ssh -L 8080:intra-web:80 -L 8443:intra-web:443 user@gateway

远程转发(-R

与本地转发相反,它把远程 SSH 服务器上的端口流量,转到本地或本地能访问的主机。

格式:
ssh -R 远程端口:目标主机:目标端口 用户@SSH服务器

示例: 你本地开发了一个 Web 应用监在 localhost:3000,想让远程搭档临时访问。执行:

1
ssh -R 8080:localhost:3000 user@public-server

之后,你的搭档在 public-server 上访问 localhost:8080 就能看到你本机的 Web 服务。

注意:默认情况下,远程绑定的端口只能由 SSH 服务器本机(127.0.0.1)访问。如果希望外网也能访问该远程端口,需要在服务器 /etc/ssh/sshd_config 中配置 GatewayPorts yes,然后重启 sshd。此时远程绑定的地址变为 0.0.0.0

动态转发(-D)—— SOCKS 代理

将 SSH 客户端变成一个 SOCKS5 代理服务器,所有支持 SOCKS 的应用程序都能通过该隧道访问网络。这是最常用的“安全上网”或“翻墙”方法。

1
ssh -D 1080 user@server

然后在操作系统的网络代理设置中填入 SOCKS5 代理:127.0.0.1 端口 1080。或者在浏览器(如 Firefox)中单独设置 SOCKS5 代理,并可勾选“通过代理发送 DNS 请求”以避免 DNS 泄露。

配合 ~/.ssh/config,可以创建专门的代理主机别名:

1
2
3
4
5
Host proxy
HostName your-vps.com
User user
DynamicForward 1080
ServerAliveInterval 60

然后只需 ssh proxy,后台保持连接,代理就绪。


SSH 服务器安装与配置

如果你需要让自己的机器成为 SSH 服务器(让别人或自己远程连接),就必须安装并正确配置 OpenSSH 服务端(sshd)。本节将详细说明安装、基本配置与安全加固。

安装 SSH 服务器

Linux
根据发行版使用对应的包管理器安装 openssh-server

  • Debian / Ubuntu:sudo apt install openssh-server
  • RHEL / CentOS / Fedora:sudo dnf install openssh-server
  • Arch Linux:sudo pacman -S openssh(已包含服务端)

安装后启动并设置开机自启:

1
sudo systemctl enable ssh --now   # 部分系统服务名为 sshd,请确认

macOS
系统自带 sshd,开启方式:

  • 图形界面:系统设置 → 通用 → 共享 → 远程登录,勾选并选择允许的用户。
  • 命令行:sudo systemsetup -setremotelogin on(关闭则为 off)。
    通过 sudo launchctl list | grep ssh 检查服务状态。

Windows
Windows Server 2019 / Windows 10 1809 及以上可安装 OpenSSH 服务器:

1
2
3
4
5
6
# 以管理员身份运行 PowerShell
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0

# 启动并设置自动运行
Start-Service sshd
Set-Service -Name sshd -StartupType 'Automatic'

确认防火墙规则已自动创建(通常名为“OpenSSH SSH Server”),若未创建则手动允许端口 22。

基础配置

SSH 服务器的主配置文件:

  • Linux / macOS:/etc/ssh/sshd_config
  • Windows:%ProgramData%\ssh\sshd_config

修改配置文件前,建议先备份:

1
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

常见基础选项(编辑后需重启服务生效):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# 监听端口(可改为非默认端口以降低扫描风险)
Port 22

# 监听地址(默认 0.0.0.0 所有接口,可限定 IP)
ListenAddress 0.0.0.0

# 允许或禁止 root 直接登录(强烈建议 no)
PermitRootLogin no

# 最大认证尝试次数
MaxAuthTries 6

# 登录宽限期(秒),超时断开未完成认证的连接
LoginGraceTime 30

# 最大并发未认证连接数
MaxStartups 10:30:100

# 是否允许密码认证
PasswordAuthentication yes

# 是否允许公钥认证
PubkeyAuthentication yes

# 授权密钥文件路径
AuthorizedKeysFile .ssh/authorized_keys

# 是否允许空密码
PermitEmptyPasswords no

# 是否允许 TCP 转发(根据需求开启)
AllowTcpForwarding yes

# 是否允许 X11 转发(通常桌面环境需要时再开)
X11Forwarding no

# 日志级别
LogLevel INFO

密钥认证与禁用密码登录

为了安全,推荐只使用密钥登录。首先确保你能用密钥成功登录(见第 4 节),然后修改 sshd_config

1
2
3
PasswordAuthentication no
ChallengeResponseAuthentication no
PubkeyAuthentication yes

保存后重启服务。此后所有用户都必须使用密钥认证,密码登录将被彻底拒绝。

安全加固

除了禁用密码和 root 登录外,以下措施可大幅提高服务器安全性:

更改默认端口

1
Port 2222

更改后需要在防火墙放行新端口,客户端连接时使用 -p 2222

限制可登录用户

1
2
3
AllowUsers alice bob
# 或使用组限制
AllowGroups sshusers

指定现代安全算法
sshd_config 中明确禁用老旧不安全算法:

1
2
3
KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com

禁用短密钥与协议 1
确保以下配置存在:

1
2
Protocol 2
HostKeyAlgorithms ssh-ed25519,rsa-sha2-512,rsa-sha2-256

空闲超时与环境隔离

1
2
3
4
5
6
7
8
9
# 客户端无操作多少秒后自动断开
ClientAliveInterval 300
ClientAliveCountMax 3
# 为 sftp 用户限制目录(可选)
Subsystem sftp internal-sftp
Match Group sftpusers
ChrootDirectory /home/%u
ForceCommand internal-sftp
AllowTcpForwarding no

防火墙与 SELinux

确保服务器防火墙允许 SSH 端口(默认 22,或自定义端口):

  • ufw(Ubuntu 等):
    1
    2
    3
    4
    sudo ufw allow 22/tcp
    # 或自定义端口
    sudo ufw allow 2222/tcp
    sudo ufw enable
  • firewalld(CentOS/RHEL):
    1
    2
    sudo firewall-cmd --add-port=22/tcp --permanent
    sudo firewall-cmd --reload
  • iptables:直接添加规则或使用 iptables-persistent

如果启用了 SELinux,需要允许 SSH 使用非标准端口(例如 2222):

1
sudo semanage port -a -t ssh_port_t -p tcp 2222

配置测试与服务管理

每次修改 sshd_config 后,先用测试模式验证语法,然后再重启服务:

1
sudo sshd -t

若输出为空则表示配置正确;若有错误会提示具体行号。

管理 SSH 服务的常用命令(Linux):

1
2
3
sudo systemctl restart sshd    # 重启
sudo systemctl status sshd # 查看状态
sudo systemctl reload sshd # 重载配置(不中断现有连接,适用于部分参数)

Windows 上对应 PowerShell 命令:

1
2
Restart-Service sshd
Get-Service sshd

查看日志

连接出现问题时的排查思路:

  • Linux:根据发行版查看 /var/log/auth.log(Debian/Ubuntu)或 /var/log/secure(RHEL/CentOS)。
    1
    sudo tail -f /var/log/auth.log
  • macOS:使用 log show --predicate 'process == "sshd"' --last 1h 或查看 /var/log/system.log
  • Windows:通过“事件查看器”进入“应用程序和服务日志 → OpenSSH → 操作”,或使用 PowerShell:
    1
    Get-WinEvent -LogName "OpenSSH/Operational" | Select-Object -Last 20
    日志中会详细记录认证失败的原因、权限问题、算法协商错误等。

8.8 额外防护工具
强烈建议部署 fail2ban,它能检测暴力破解并动态封锁 IP:

1
2
3
4
5
sudo apt install fail2ban
# 创建并编辑本地配置
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
# 在 [sshd] 部分设置 enabled = true,根据需要调整 bantime、maxretry 等
sudo systemctl restart fail2ban

还可结合双因素认证(如 Google Authenticator + PAM)进一步增强安全性。


高级用法

跳板机(ProxyJump)

在内网环境中,你往往需要先登录一台暴露在公网的堡垒机,再通过它访问内部的机器。ProxyJump 让这一过程全透明。

配置文件方式:

1
2
3
4
5
6
7
8
9
Host bastion
HostName jump.example.com
User admin
IdentityFile ~/.ssh/bastion_key

Host target
HostName 192.168.10.10
User alice
ProxyJump bastion

直接 ssh target 即可完成两步连接。

命令行方式:

1
ssh -J admin@jump.example.com alice@192.168.10.10

也可以使用多级跳板(用逗号分隔):

1
ssh -J user@hop1,user@hop2 user@final

SSH 内部会自动建立到各跳板机的连接,然后从最后一跳连接最终目标,整个过程对用户透明,并且 不会自动转发 ssh-agent,安全性远高于 agent forwarding(见下)。

SSH Agent 与转发

ssh-agent 是一个在后台运行的程序,用于缓存解密的私钥。当你生成密钥并设置了 passphrase,每次使用都需要输入密码很麻烦。把密钥添加到 agent 后,只要 agent 不关闭,后续连接就无需输入 passphrase。

启动与添加密钥:

1
2
3
4
5
6
# 启动 agent(多数桌面环境已自动启动)
eval "$(ssh-agent -s)"
# 添加默认密钥,输入一次 passphrase
ssh-add ~/.ssh/id_ed25519
# 列出已加载的密钥
ssh-add -l

Agent 转发(谨慎使用)
使用 ssh -A user@server 时,远端的 SSH 客户端可以访问你本地的 ssh-agent,从而用你本机的密钥继续登录其他机器。这在过去经常用来跨跳板机连接内网,但存在重大安全隐患:如果远程服务器被攻陷,root 用户能够通过 agent 套接字冒用你的身份。
现代最佳实践:用 ProxyJumpssh -J 替代 agent 转发,它们在本地完成跳转,根本不需要在远程访问 agent。除非万不得已,否则始终关闭 agent 转发(在配置中设置 ForwardAgent no)。

Windows 上的 ssh-agent
Windows 提供了一个 ssh-agent 服务,可设置为自动启动,然后在 PowerShell 中用 ssh-add 添加密钥。WSL2 也可以桥接使用该 agent(ssh-agent 在 WSL 中可通过 socket 与 Windows 端互通,环境变量 SSH_AUTH_SOCK 可配置)。

连接复用(多路复用)

如果你需要频繁向同一台主机发起 SSH 连接(比如执行命令、传文件、开新会话),每次都进行完整的认证和加密协商会慢且浪费资源。连接复用让后续连接共享同一条已认证的 TCP 连接。

~/.ssh/config 中添加:

1
2
3
4
Host *
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h:%p
ControlPersist 600
  • ControlMaster auto:自动试用已存在的连接,没有则新建。
  • ControlPath:指定控制套接字存放路径,%r 远程用户名,%h 主机,%p 端口。
  • ControlPersist 600:主连接退出后,后台保持该连接 600 秒,供后续复用。

首次连接后,再次 sshsftp 同一主机几乎瞬间完成。你可以用以下命令管理主连接:

1
2
3
ssh -O check dev      # 检查主连接是否存在
ssh -O exit dev # 关闭主连接
ssh -O stop dev # 停止接受新的复用并关闭(已有会话不受影响)

保持连接不中断

闲置的 SSH 连接容易被防火墙或 NAT 设备切断。可以在配置文件中加入心跳机制:

1
2
3
Host *
ServerAliveInterval 60
ServerAliveCountMax 5

客户端每 60 秒发送一个加密的空包(心跳),连续 5 次(共 5 分钟)无响应则断开连接。也可以使用 TCPKeepAlive yes,但服务器端心跳可能更可靠。

远程执行命令

SSH 可以非交互式地远程执行命令,常用于脚本或自动化。

1
2
3
4
5
6
7
ssh user@host "ls -la /var/log"
# 执行多条命令
ssh user@host "cd /opt && ./backup.sh"
# 执行本地脚本(将脚本内容通过 SSH 传递)
ssh user@host 'bash -s' < local_script.sh
# 运行需要伪终端的命令(如 top、tcpdump),加 -t 参数
ssh -t user@host "top"

注意引号的使用:外部用双引号,内部需要保留原样就用单引号,或合理转义。

挂载远程文件系统(SSHFS)

SSHFS 基于 FUSE(用户空间文件系统),允许你将远程目录直接挂载到本地,像操作本地硬盘一样读写。

安装:

  • Linux:sudo apt install sshfs(或对应包管理器)
  • macOS:brew install macfuse && brew install sshfs
  • Windows:安装 WinFsp 和 SSHFS-Win,挂载后会出现盘符。(GUI : sshfs-win-manager)

使用方法:

1
2
3
4
5
6
7
8
# 创建挂载点
mkdir ~/remote_mount
# 挂载远程目录
sshfs user@host:/remote/path ~/remote_mount
# 指定端口或附加选项
sshfs -p 2222 user@host:/path ~/mnt -o allow_other,reconnect
# Windows 专用
net use Z: \\sshfs.r\user@192.168.1.100\home\user

卸载:

1
2
3
4
5
# Linux
fusermount -u ~/remote_mount
# macOS
umount ~/remote_mount
# Windows:在资源管理器中弹出,或 net use 删除网络驱动器

SSHFS 适合临时工作,性能不如 NFS,但在安全性与便捷性之间取得了很好的平衡。

X11 转发(运行远程图形程序)

如果你需要在本地显示运行在远程 Linux 上的图形程序(如 gedit、firefox、安装向导等),可以启用 SSH 的 X11 转发。

服务器端要求:安装 xauth,并在 /etc/ssh/sshd_config 中确保:

1
2
X11Forwarding yes
X11DisplayOffset 10

重启 sshd。

客户端连接:

1
2
3
4
# -X 启用 X11 转发,-C 压缩流量
ssh -XC user@host
# 登录后运行应用程序
xclock &
  • macOS 用户 需安装 XQuartz(brew install --cask xquartz)并启动它。
  • Windows 用户 需安装 X Server 如 VcXsrv 或 Xming,启动后设置 DISPLAY 环境变量(如 export DISPLAY=localhost:0.0,WSL 下可能自动设置)。连接时使用 ssh -Y(可信转发)可解决某些权限问题。

跨平台注意事项

  • 权限:Linux/macOS 下 .ssh 目录和密钥的权限必须严格(目录 700,私钥 600)。Windows OpenSSH 对文件权限也有要求,通常只需确保只有自己的用户和 SYSTEM 账户有完全控制,可通过文件属性 → 安全 → 高级 → 更改权限来调整。在 WSL 内访问 Windows 文件系统时,权限继承自 Windows,可能需要单独设置 chmod 但可能不生效(NTFS 无 Unix 权限),建议将私钥存放在 WSL 原生 ext4 文件系统中。
  • 路径分隔符:Windows 原生 OpenSSH 支持正斜杠 ~/.ssh/config,不必使用反斜杠。
  • SSH Agent:Windows 上可通过服务管理控制台或 PowerShell 设置 ssh-agent 自启动:
    1
    2
    Set-Service ssh-agent -StartupType Automatic
    Start-Service ssh-agent
    之后 ssh-add 添加密钥,WSL 内可通过 wsl-env 等工具共享 agent。
  • WSL 互操作:WSL 中可以创建符号链接将 Windows 的 .ssh 挂接到 Linux 路径,如 ln -s /mnt/c/Users/You/.ssh ~/.ssh,但注意权限问题。更好的方式是在 WSL 内部维护独立的 .ssh 目录,并通过脚本同步。
  • 终端:推荐 Windows Terminal,支持多选项卡、GPU 渲染、完整字体,可在 PowerShell、CMD、WSL 会话间无缝切换。
  • git 与 SSH:在 Windows 上使用 git 时,可通过设置环境变量 GIT_SSH_COMMAND 指向原生 ssh.exe,例如 setx GIT_SSH_COMMAND "C:\Windows\System32\OpenSSH\ssh.exe",避免 git 自带 ssh 引起的混乱。

常见问题排查

SSH 连接失败时,添加 -v(verbose)是诊断的第一准则,可多次叠加(-vvv)获得超详细日志。

  1. Permission denied (publickey)

    • 确认远程服务器上的公钥已正确添加到 ~/.ssh/authorized_keys
    • 检查本地私钥路径,可显式使用 -i 指定。
    • 检查远程权限:chmod 700 ~/.ssh; chmod 600 ~/.ssh/authorized_keys
    • 确认 ssh-agent 里有对应的密钥(ssh-add -l)。
    • 查看服务器日志:sudo tail -f /var/log/auth.log(Debian系)或 /var/log/secure(RHEL系),可能提示具体原因。
  2. Host key verification failed

    • 远程主机指纹与本机记录不符。若确认为正常变更,可清除旧记录:ssh-keygen -R 主机名或IP
    • 如果不想检查,可在测试环境临时禁用:ssh -o StrictHostKeyChecking=no user@host生产环境切勿使用)。
  3. Connection timed out / No route to host

    • 检查防火墙是否开放 SSH 端口(包括本地防火墙和云服务商安全组)。
    • 在服务器上确认 sshd 正在监听:ss -tlnp | grep ssh
    • 测试网络连通性:ping 主机IP,若 ping 不通则基础设施层存在问题。
    • 尝试 telnet 端口:telnet host 22,看是否响应 SSH banner。
  4. ssh-agent 未运行

    • Linux/macOS:执行 eval "$(ssh-agent -s)" 然后 ssh-add
    • Windows:确定 ssh-agent 服务已启动,或手动 Start-Service ssh-agent
    • 若 agent 转发失败,在远程主机上检查环境变量 SSH_AUTH_SOCK 是否存在。
  5. 密钥权限太开放

    • 典型错误:Permissions 0644 for '/home/user/.ssh/id_ed25519' are too open.
      解决:chmod 600 ~/.ssh/id_ed25519。若密钥存放于 NTFS 分区且无法修改权限,可将密钥移入 WSL 的 home 目录,或使用 Windows 属性 -> 安全 -> 高级 -> 禁用继承,仅保留自己的账户。
  6. SCP / SFTP 卡住或无响应

    • 可能是 shell 配置文件(如 .bashrc)中输出了文本,干扰了协议。确保远程用户的 shell 启动文件不产生非交互式输出,或仅在交互模式下输出(检查 $-PS1)。
  7. 连接复用导致的问题

    • 如果修改了密钥或配置但似乎未生效,可能是旧的复用连接仍在使用旧参数。执行 ssh -O exit 主机名 关闭主连接后重试。