目录
SSH 是什么?
SSH(Secure Shell)是一种加密的网络协议,用于在不安全的网络中为网络服务提供安全的远程登录和其他安全网络服务,它就像一个加密的“超级终端”,让你能安全地远程管理和操作另一台计算机。

默认情况下,SSH 服务监听 22 端口。
基础用法
最基本、最常用的 SSH 命令格式如下:
ssh [用户名]@[主机地址]
[用户名]: 你想登录到远程主机上的哪个用户账户,如果不指定,默认为你当前本地的用户名。[主机地址]: 远程主机的 IP 地址或域名。
示例:
-
以当前本地用户身份登录
168.1.100
(图片来源网络,侵删)ssh 192.168.1.100
-
以
root用户身份登录example.comssh root@example.com
-
以
ubuntu用户身份登录 IP168.1.101ssh ubuntu@192.168.1.101
首次连接时,SSH 客户端会无法验证服务器的真实性,因此会显示服务器的公钥指纹(一个哈希值),并询问你是否要继续连接。
The authenticity of host '192.168.1.100 (192.168.1.100)' can't be established.
ECDSA key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
输入 yes 并回车,该主机的密钥就会被保存在你本地的 ~/.ssh/known_hosts 文件中,下次连接就不会再提示了。

常用选项
SSH 命令有很多强大的选项,可以让你更灵活、更安全地使用它。
| 选项 | 全称 | 描述 | 示例 |
|---|---|---|---|
-p |
port |
指定连接的端口号,默认为 22。 | ssh -p 2222 user@example.com |
-i |
identity_file |
指定私钥文件进行身份验证。 | ssh -i ~/.ssh/my_key user@host |
-C |
compression |
开启数据压缩,适用于网络较慢的环境。 | ssh -C user@example.com |
-N |
不执行远程命令,仅用于端口转发。 | ssh -N -L 8080:localhost:80 user@host |
|
-f |
在后台运行 SSH 命令,常与 -N 一起使用。 |
ssh -f -N -L 8080:localhost:80 user@host |
|
-L |
localport:host:remoteport |
本地端口转发,将本地端口流量转发到远程主机的指定端口。 | ssh -L 9999:db_server:3306 user@firewall |
-R |
remoteport:host:localport |
远程端口转发,将远程主机的端口流量转发到本地主机的指定端口。 | ssh -R 8080:localhost:3000 user@server |
-D |
port |
动态端口转发 (创建 SOCKS 代理)。 | ssh -D 1080 user@example.com |
-v |
verbose |
显示详细的调试信息,用于排查连接问题。 | ssh -v user@example.com |
-q |
quiet |
安静模式,不显示警告和诊断信息。 | ssh -q user@example.com |
-o |
option |
指定一个配置选项,覆盖默认或配置文件中的设置。 | ssh -o "StrictHostKeyChecking=no" user@host |
高级用法与技巧
文件传输
虽然 SSH 本身是用于登录的,但它内置了两个强大的文件传输工具:scp 和 sftp。
a) scp (Secure Copy)
scp 的语法和 cp 类似,但可以在不同主机间安全地复制文件。
# 从本地复制到远程 scp /path/to/local_file.txt user@remote:/path/to/remote/ # 从远程复制到本地 scp user@remote:/path/to/remote_file.txt /path/to/local/ # 复制整个目录,需要加上 -r 选项 scp -r /path/to/local_dir user@remote:/path/to/remote/ # 通过指定端口和密钥文件 scp -P 2222 -i ~/.ssh/my_key file.txt user@host:~
b) sftp (SSH File Transfer Protocol)
sftp 提供了一个交互式的命令行界面,类似于 FTP,但所有传输都是加密的。
sftp user@remote_host # 进入 sftp 提示符后,可以使用以下命令: sftp> ls # 列出远程目录内容 sftp> get remote_file.txt # 下载文件到本地 sftp> put local_file.txt # 上传本地文件到远程 sftp> cd /path/to/dir # 切换远程目录 sftp> lls # 列出本地目录内容 sftp> exit # 退出 sftp
端口转发
SSH 端口转发(或称隧道)是其最强大的功能之一,允许你绕过防火墙或加密不安全的网络流量。
a) 本地端口转发
场景:你想从你的电脑访问公司内网的数据库服务器,但你的电脑只能访问跳板机。
# 命令格式: ssh -L [本地端口]:[目标主机]:[目标端口] [跳板机用户]@[跳板机地址] ssh -L 9999:db_server_ip:3306 jump_user@jump_server_ip
执行后,在你的电脑上,访问 localhost:9999 的请求就会被安全地通过跳板机转发到内网的 db_server_ip:3306 端口。
b) 远程端口转发
场景:你的电脑在家庭内网,无法被外网访问,你想让外网的朋友能访问到你电脑上的一个 Web 服务。
# 命令格式: ssh -R [远程端口]:[本地主机]:[本地端口] [服务器用户]@[服务器地址] ssh -R 8080:localhost:3000 your_server_user@your_server_ip
执行后,所有访问你服务器 your_server_ip:8080 的请求,都会被转发到你本地电脑的 localhost:3000 端口。
SSH 密钥认证 (免密登录)
使用密码登录容易被暴力破解,强烈推荐使用 SSH 密钥对进行认证,它更安全,也更方便。
步骤 1:在本地客户端生成密钥对
如果你还没有密钥对,运行以下命令生成一个(一路按回车即可使用默认设置)。
ssh-keygen -t ed25519 -C "your_email@example.com"
这会在 ~/.ssh/ 目录下创建 id_ed25519 (私钥) 和 id_ed25519.pub (公钥) 两个文件。
步骤 2:将公钥复制到远程服务器
使用 ssh-copy-id 命令可以非常方便地完成这一步。
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@remote_host
这个命令会将你的公钥追加到远程服务器上 user 用户的 ~/.ssh/authorized_keys 文件中,并会自动设置好正确的权限。
步骤 3:测试免密登录
再次登录,你会发现不再需要输入密码了。
ssh user@remote_host
配置文件 ~/.ssh/config
每次都输入 -i、-p 等选项很麻烦。~/.ssh/config 文件可以让你为每个主机设置别名和默认参数,让连接变得极其简单。
编辑 ~/.ssh/config 文件(如果不存在则创建):
# 编辑配置文件 nano ~/.ssh/config
示例配置:
# 公司跳板机
Host jump-server
HostName 192.168.1.100
User john
Port 2222
IdentityFile ~/.ssh/jump_key
# 个人服务器
Host personal-server
HostName example.com
User ubuntu
IdentityFile ~/.ssh/personal_ed25519
# 默认配置
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
配置说明:
Host: 你在命令行中使用的别名(ssh jump-server)。HostName: 实际的主机名或 IP 地址。User: 登录用户名。Port: 连接端口。IdentityFile: 指定私钥文件路径。
有了这个配置文件,你就可以简单地使用 ssh jump-server 来连接,而无需记住一堆复杂的参数。
故障排查
当连接失败时,-v (verbose) 选项是你的好朋友。
ssh -v user@remote_host
它会打印出从 DNS 解析、TCP 连接、密钥交换到最终认证的每一步详细信息,帮助你定位问题所在。
常见问题:
Permission denied (publickey,password).: 这是最常见的错误,通常意味着:- 你没有使用正确的私钥。
- 远程服务器的
sshd服务可能没有开启密钥认证。 - 远程服务器上
~/.ssh/authorized_keys文件权限不正确(所有者必须是用户自己,且权限通常为600或644)。 - 你本地的私钥文件权限过于开放(所有者必须是用户自己,且权限通常为
600)。
Connection timed out: 无法到达目标主机,检查网络、防火墙(本地和远程)以及 IP 地址是否正确。Could not resolve hostname: DNS 解析失败,检查主机名是否拼写正确。
总结与最佳实践
- 优先使用密钥认证:永远不要在生产服务器上允许密码登录,在
/etc/ssh/sshd_config中设置PasswordAuthentication no。 - 使用非标准端口:将 SSH 端口从 22 改为一个高端口号,可以大大减少自动化攻击的扫描。
- 使用配置文件:为常用主机配置
~/.ssh/config,简化命令,减少错误。 - 限制登录用户:在
/etc/ssh/sshd_config中使用AllowUsers或AllowGroups指定哪些用户或组可以登录。 - 保持更新:定期更新你的 OpenSSH 客户端和服务器,以获取最新的安全补丁。
- 使用
scp或sftp代替直接传输:通过 SSH 传输文件时,优先使用它们,而不是自己写脚本加密。 - 利用端口转发:善用 SSH 的隧道功能来保护你的网络流量。
