SSH 常见用法(一):远程登录服务器
系列导读
本系列共包含一篇总览和四篇专题文章:
| 系列位置 | 文章主题 | 主要内容 |
|---|---|---|
| 总览 | 浅谈 SSH | 认识 SSH 及其四种常见用法 |
| 第一篇(本文) | SSH 常见用法(一):远程登录服务器 | 密码登录、密钥认证和~/.ssh/config |
| 第二篇 | SSH 常见用法(二):通过 SSH 认证访问 Git 仓库 | 配置 SSH Key,并通过 SSH 操作远程仓库 |
| 第三篇 | SSH 常见用法(三):SSH 隧道与端口转发 | 本地、远程和动态端口转发 |
| 第四篇 | SSH 常见用法(四):使用 SCP 和 SFTP 远程传输文件 | 在本机与服务器之间安全传输文件 |
一、SSH 远程登录基础
1.1 什么是 SSH
SSH 的全称是Secure Shell(安全外壳协议),是一种通过网络安全访问远程计算机的加密协议。
在没有加密保护的远程连接中,用户名、密码和执行的命令可能被网络中的其他人截获。SSH 会在客户端和服务器之间建立一条经过加密和身份认证的连接,用来保护传输的数据。
可以把 SSH 简单理解为:
本机 SSH 客户端 │ │ 加密连接 + 身份认证 ▼ 远程 SSH 服务器SSH 可以用于远程登录、Git 身份认证、端口转发和远程文件传输。本文聚焦其中最基础、也最常见的场景:通过 SSH 远程登录服务器。
1.2 SSH 远程登录的基本命令
SSH 远程登录服务器最基础的命令是:
ssh用户名@服务器IP如果服务器使用的不是默认 22 端口,需要通过-p指定端口:
ssh-p端口号 用户名@服务器IP例如,使用用户名devuser,通过31022端口登录服务器203.0.113.10:
ssh-p31022devuser@203.0.113.10第一次登录通常需要输入服务器账号密码。完成 SSH 密钥认证和~/.ssh/config配置后,可以把登录命令简化为:
sshdev-server本文将依次介绍:
- 使用账号密码远程登录服务器
- 配置 SSH 密钥认证(免密登录)
- 使用
~/.ssh/config简化登录命令
1.3 案例环境
| 项目 | 示例值 | 说明 |
|---|---|---|
| 本机 IP | 192.168.1.20 | 你自己的电脑在局域网里的 IP |
| 服务器 IP | 203.0.113.10 | 远程 Linux 服务器的 IP |
| 服务器用户名 | devuser | 你登录服务器使用的账号 |
| 服务器密码 | DemoPass123! | 仅作为示例,真实环境不要使用这种简单密码 |
| SSH 端口 | 22 | SSH 默认端口,后文也会用 31022 演示非默认端口 |
服务器 IP 可以是公网 IP,也可以是私网 IP。前提是你的电脑和服务器之间存在可达的网络路径,并且服务器的 SSH 端口允许访问。
【本机 / 你的电脑】 IP:192.168.1.20 用户:你当前登录本机的用户 │ │ │ 发起 SSH 连接 │ ssh devuser@203.0.113.10 │ ▼ 【本机网络 / 路由器】 │ │ │ 经过互联网 │ ▼ 【远程服务器】 公网 IP:203.0.113.10 SSH 端口:22 服务器用户名:devuser 服务器密码:DemoPass123! │ │ │ 服务器要求身份认证 ▼ 输入密码: DemoPass123! │ │ │ 认证成功 ▼ 【进入远程服务器 Shell】 当前身份:devuser 当前机器:203.0.113.10 │ ├── pwd ├── ls ├── cd ├── ps └── 其他 Linux 命令1.4 远程登录连接案例
关键命令
# 语法 ssh 用户名@服务器IP # 具体样例 ssh devuser@203.0.113.10 # 如果不是 22 端口 ssh -p 具体端口 用户名@服务器IP # 具体样例 这里假设是 ssh -p 31022 devuser@203.0.113.10ssh → 使用 SSH -p 31022 → 指定 SSH 端口为 31022 【通常为22】 devuser → 服务器用户名 203.0.113.10 → 服务器 IP整体关系就是:
你的电脑 IP: 192.168.1.20 │ │ SSH 加密连接 │ │ ssh devuser@203.0.113.10 ▼ 远程 Linux 服务器 IP: 203.0.113.10 用户名: devuser 密码: DemoPass123! SSH端口: 22你在自己的电脑终端里执行:
ssh devuser@203.0.113.10第一次连接时,可能会看到类似:
The authenticity of host '203.0.113.10' can't be established. Are you sure you want to continue connecting (yes/no/[fingerprint])?你确认服务器身份后输入:
yes然后服务器会要求密码:
devuser@203.0.113.10's password:这时候你输入:
DemoPass123!注意一个很重要的点:输入密码时终端通常不会显示任何字符,连******都不会显示,这是正常的。
登录成功之后,可能看到:
devuser@server:~$这意味着:
原来: 你↓ 本机终端 ↓ 192.168.1.20 现在: 你 ↓ 本机终端 ↓ SSH ↓ 203.0.113.10 ↓ 远程服务器 Shell此时你执行:
pwd看到:
/home/devuser执行:
ls看到的是:
project logs backup这些文件和目录不是你本机192.168.1.20上的,而是服务器203.0.113.10上的。
所以整个过程可以记成:
本机 192.168.1.20 ssh devuser@203.0.113.10 │ ▼ SSH建立加密连接 │ ▼ 输入服务器密码 DemoPass123! │ ▼ 身份认证成功 │ ▼ 远程服务器 203.0.113.10 当前身份: devuser 你现在输入的 Linux 命令 主要都在这台远程服务器上执行1.4.1 注意事项
还有一个容易混淆的地方:本机 IP 通常不需要写进ssh命令。
你不需要写:
ssh 192.168.1.20 devuser@203.0.113.10只需要:
ssh devuser@203.0.113.10因为 SSH 客户端本来就是从你当前这台电脑发起连接的。
所以这个案例里真正最核心的三个信息其实是:
服务器地址:203.0.113.10 用户名:devuser 密码:DemoPass123!然后:
ssh devuser@203.0.113.10输入密码,就完成一次最基础的SSH 密码登录。
二、配置 SSH 密钥认证(免密登录)
每次连接服务器都输入密码比较麻烦,也不方便后续执行自动化任务。SSH 支持使用密钥对完成身份认证,这种方式通常被称为“SSH 免密登录”。
不过,“免密登录”并不是取消身份认证,而是把服务器密码认证替换成了更安全的SSH 密钥认证:
本机私钥 │ │ 证明客户端持有正确的私钥 ▼ 服务器上的公钥 │ │ 验证成功 ▼ 允许登录2.1 检查本机是否已经存在 SSH 密钥
生成新密钥之前,先在自己的电脑上查看~/.ssh目录:
ls-la~/.ssh如果系统提示目录不存在,或者目录中没有下面这些密钥文件,说明本机可能还没有生成 SSH 密钥。
目前常见的 SSH 密钥对主要有以下两种:
Ed25519 密钥: ~/.ssh/id_ed25519 # 私钥 ~/.ssh/id_ed25519.pub # 公钥 RSA 密钥: ~/.ssh/id_rsa # 私钥 ~/.ssh/id_rsa.pub # 公钥| 密钥类型 | 私钥文件 | 公钥文件 | 使用建议 |
|---|---|---|---|
| Ed25519 | id_ed25519 | id_ed25519.pub | 现代环境优先推荐,密钥较短且安全性高 |
| RSA | id_rsa | id_rsa.pub | 仍然很常见,兼容较旧的 SSH 环境 |
需要特别注意:SSH 密钥是成对使用的。
- 没有
.pub后缀的是私钥,必须保存在本机并严格保密。 - 带
.pub后缀的是公钥,可以复制到服务器。 - 只有
id_rsa.pub或id_ed25519.pub、却没有对应私钥时,无法使用这组密钥完成身份认证。
如果本机已经存在完整的密钥对,可以直接使用,不需要再次生成。例如看到:
id_ed25519 id_ed25519.pub就可以跳过下一步,直接把id_ed25519.pub安装到服务器。
不要删除或覆盖用途不明的已有私钥,否则可能失去对 Git 仓库或其他服务器的访问权限。
2.2 没有密钥时生成 SSH 密钥
在自己的电脑上执行:
ssh-keygen-ted25519-C"devuser-client"命令中的参数含义如下:
ssh-keygen → SSH 密钥生成工具 -t ed25519 → 生成 Ed25519 类型的密钥 -C "devuser-client" → 为密钥添加备注,方便以后识别执行过程中会询问密钥的保存位置:
Enter file in which to save the key (/Users/yourname/.ssh/id_ed25519):如果不需要修改文件名,可以直接按回车,密钥默认保存在本机的~/.ssh目录中:
~/.ssh/id_ed25519 # 私钥,只能由自己保管,不能发送给别人 ~/.ssh/id_ed25519.pub # 公钥,可以复制到服务器如果系统提示id_ed25519已经存在,不要直接确认覆盖。可以取消生成并使用已有密钥,也可以为新密钥指定一个单独的文件名:
ssh-keygen-ted25519-f~/.ssh/dev_server_ed25519-C"dev-server"这会生成:
~/.ssh/dev_server_ed25519 # 私钥 ~/.ssh/dev_server_ed25519.pub # 公钥随后,命令会询问是否为私钥设置保护密码(passphrase):
Enter passphrase (empty for no passphrase):- 直接按回车:使用私钥时通常不需要再次输入内容,操作更方便。
- 设置 passphrase:私钥被盗后仍有额外保护,安全性更高,可以配合
ssh-agent使用。
私钥必须保留在本机,不能上传到服务器、发送给别人或提交到 Git 仓库。无论私钥名是
id_ed25519、id_rsa还是自定义名称,都要遵守这一原则。
2.3 把公钥安装到服务器
如果服务器使用上文举例的31022端口,则在本机执行:
ssh-copy-id-i~/.ssh/id_ed25519.pub-p31022devuser@203.0.113.10如果服务器使用默认的 22 端口,则执行:
ssh-copy-id-i~/.ssh/id_ed25519.pub devuser@203.0.113.10这里通过-i明确指定要安装的公钥。如果使用的是 RSA 密钥,需要把路径换成:
~/.ssh/id_rsa.pub如果生成了单独命名的密钥,则换成对应的公钥路径,例如:
ssh-copy-id-i~/.ssh/dev_server_ed25519.pub-p31022devuser@203.0.113.10第一次安装公钥时,仍然需要输入一次服务器账号devuser的密码。认证成功后,ssh-copy-id会把本机公钥追加到服务器的下面这个文件中:
/home/devuser/.ssh/authorized_keys客户端与服务器上的相关文件可以这样理解:
| 文件 | 所在位置 | 作用 |
|---|---|---|
~/.ssh/id_ed25519 | 本机 | SSH 私钥,必须严格保密 |
~/.ssh/id_ed25519.pub | 本机 | SSH 公钥,可以安装到服务器 |
~/.ssh/config | 本机 | 保存服务器地址、用户、端口和私钥等连接配置 |
~/.ssh/known_hosts | 本机 | 记录连接过的服务器及其主机公钥信息 |
~/.ssh/authorized_keys | 服务器 | 保存允许登录当前服务器账号的客户端公钥 |
2.4 验证密钥登录
公钥安装完成后,重新连接服务器:
ssh-p31022devuser@203.0.113.10默认名称的id_ed25519和id_rsa通常可以被 SSH 客户端自动发现。如果使用的是单独命名的私钥,需要通过-i指定私钥路径:
ssh-i~/.ssh/dev_server_ed25519-p31022devuser@203.0.113.10如果没有再要求输入devuser的服务器密码,就说明 SSH 密钥认证已经配置成功。
需要注意:如果生成密钥时设置了 passphrase,此处可能要求输入的是私钥的 passphrase,而不是服务器账号密码。这两者不是同一个密码。
在确认密钥登录成功之前,不要关闭当前已经登录的 SSH 窗口,也不要立即禁用服务器的密码登录。否则一旦配置错误,可能无法再次进入服务器。
2.5 密钥认证失败时检查文件权限
在 Linux 或 macOS 本机上,可以设置以下权限:
chmod700~/.sshchmod600~/.ssh/id_ed25519如果使用的是 RSA 私钥或自定义名称的私钥,需要把id_ed25519换成实际的私钥文件名。
在服务器上,可以设置以下权限:
chmod700~/.sshchmod600~/.ssh/authorized_keys如果仍然无法通过密钥登录,可以使用-v查看详细连接过程:
ssh-v-p31022devuser@203.0.113.102.6 如何撤销 SSH 密钥登录【如有需要】
如果某台电脑不再允许通过密钥登录服务器,需要在服务器上删除对应的公钥。
需要注意:
/home/devuser/.ssh/authorized_keys是文件,不是目录。文件中通常每一行对应一把允许登录的公钥。
操作前先在服务器上备份:
cp~/.ssh/authorized_keys ~/.ssh/authorized_keys.bak查看已经安装的公钥及其所在行:
nl-ba~/.ssh/authorized_keys也可以查看公钥指纹,辅助确认需要撤销的密钥:
ssh-keygen-lf~/.ssh/authorized_keys然后编辑文件:
vim~/.ssh/authorized_keys删除需要撤销的公钥所在的完整一行,保存后确认文件权限:
chmod700~/.sshchmod600~/.ssh/authorized_keys如果需要撤销当前用户的全部密钥登录,可以先把authorized_keys改名,而不是直接删除整个~/.ssh目录:
mv~/.ssh/authorized_keys ~/.ssh/authorized_keys.disabled需要恢复时执行:
mv~/.ssh/authorized_keys.disabled ~/.ssh/authorized_keyschmod600~/.ssh/authorized_keys不要直接删除整个~/.ssh目录,因为其中可能还保存着其他 SSH 配置。
还需要注意,删除本机私钥并不能从服务器端撤销授权。私钥可能还存在于备份或其他电脑中,真正撤销权限应当删除服务器authorized_keys中对应的公钥。
删除公钥只会影响之后建立的新连接,不会立即断开当前已经建立的 SSH 会话。
修改前不要关闭当前 SSH 会话。修改后应打开另一个终端测试登录,确认结果后再退出原来的会话,避免在密码登录已经关闭的情况下把自己锁在服务器外面。
三、使用 ~/.ssh/config 简化登录命令
~/.ssh/config是当前用户的SSH 客户端配置文件。每次执行ssh命令时,SSH 客户端都会读取这个文件,并根据Host匹配对应的连接配置。
它不仅可以保存服务器地址、用户名、端口和私钥路径,还可以配置 SSH 的多种连接能力:
| 配置能力 | 常用配置项 | 作用 |
|---|---|---|
| 远程登录 | HostName、User、Port、IdentityFile | 简化服务器登录命令 |
| 本地端口转发 | LocalForward | 通过本地端口访问远程网络中的服务 |
| 远程端口转发 | RemoteForward | 让远程端通过 SSH 隧道访问本机服务 |
| 动态端口转发 | DynamicForward | 创建 SOCKS 代理,将应用流量转入 SSH 隧道 |
| 跳板机连接 | ProxyJump | 通过一台跳板机继续连接内网服务器 |
例如,下面这些选项都可以写进~/.ssh/config:
Host tunnel-server HostName 203.0.113.10 User devuser Port 31022 IdentityFile ~/.ssh/id_ed25519 IdentitiesOnly yes # 本地端口转发:访问远程网络中的数据库 LocalForward 15432 127.0.0.1:5432 # 远程端口转发:让远程端通过 8080 端口访问本机的 3000 服务 RemoteForward 8080 127.0.0.1:3000 # 动态端口转发:在本机创建 SOCKS 代理 DynamicForward 1080远程端口转发有时会被用于反向访问或内网穿透,但它与 Nginx 这类处理 HTTP 请求的“反向代理”并不是同一个概念。
还需要区分下面两个文件:
~/.ssh/config # 本机当前用户的 SSH 客户端配置 /etc/ssh/sshd_config # 服务器端 SSH 服务的配置本文讨论的是第一个文件:本机的~/.ssh/config。这一节先使用它保存远程登录参数,把一条较长的 SSH 命令简化成服务器别名。
完成密钥认证后,每次都输入下面这条完整命令仍然比较麻烦:
ssh-p31022devuser@203.0.113.10下面把这条命令中的服务器地址、用户名、端口和私钥路径写进~/.ssh/config,再为服务器设置一个容易记忆的别名。
3.1 创建或编辑 config 文件
在本机执行:
mkdir-p~/.sshchmod700~/.sshtouch~/.ssh/configchmod600~/.ssh/config然后编辑~/.ssh/config,写入:
Host dev-server HostName 203.0.113.10 User devuser Port 31022 IdentityFile ~/.ssh/id_ed25519 IdentitiesOnly yes如果使用的是 RSA 私钥或单独命名的私钥,需要把IdentityFile改成对应的私钥路径,例如:
IdentityFile ~/.ssh/dev_server_ed25519每个配置项的含义如下:
| 配置项 | 示例值 | 说明 |
|---|---|---|
Host | dev-server | 自定义的服务器别名,可以自行修改 |
HostName | 203.0.113.10 | 服务器真实 IP 或域名 |
User | devuser | 登录服务器使用的用户名 |
Port | 31022 | SSH 服务监听的端口 |
IdentityFile | ~/.ssh/id_ed25519 | 本次连接使用的本机私钥 |
IdentitiesOnly | yes | 只使用当前配置指定的身份文件,避免尝试 SSH Agent 中的其他密钥 |
IdentitiesOnly yes在本机只有一把密钥时区别通常不大;如果本机保存了多把密钥,或者同时使用多个 GitHub、GitLab 账号,建议添加,避免 SSH 选择错误的身份。
3.2 可选:配置连接保活
如果 SSH 连接经常在长时间没有操作后断开,可以在对应的Host中添加:
Host dev-server HostName 203.0.113.10 User devuser Port 31022 IdentityFile ~/.ssh/id_ed25519 IdentitiesOnly yes # 以下为可选的连接保活配置 ServerAliveInterval 30 ServerAliveCountMax 3两个配置项的含义如下:
| 配置项 | 作用 |
|---|---|
ServerAliveInterval 30 | 连续 30 秒没有收到服务器数据时,客户端发送一条加密的保活消息 |
ServerAliveCountMax 3 | 连续 3 次没有收到保活响应时,客户端主动断开连接 |
这组配置可以理解为:
30 秒没有收到服务器数据 ↓ 客户端发送保活消息 ↓ 服务器正常响应 → 继续保持连接 服务器连续 3 次未响应 → 结束失效连接按照上面的配置,服务器失去响应后,客户端大约会在 90 秒后断开连接。
ServerAliveInterval的默认值是0,表示不发送 SSH 层的保活消息;ServerAliveCountMax的默认值通常是3。因此,只配置ServerAliveCountMax而不启用ServerAliveInterval,通常不会产生实际的保活效果。
这两个参数不是必填项。如果 SSH 连接一直稳定,可以不添加;它们也无法解决电脑休眠、网络切换或服务器主动结束会话造成的断开。
3.3 通过别名登录
保存配置后,不再需要输入完整的连接参数,只需要执行:
sshdev-server效果等价于:
ssh-p31022-i~/.ssh/id_ed25519-oIdentitiesOnly=yes devuser@203.0.113.10整个配置过程可以概括为:
执行 ssh dev-server │ ▼ 读取本机 ~/.ssh/config │ ├── HostName 203.0.113.10 ├── User devuser ├── Port 31022 ├── IdentityFile ~/.ssh/id_ed25519 └── IdentitiesOnly yes │ ▼ 通过 SSH 密钥认证登录远程服务器如果有多台服务器,可以继续在同一个~/.ssh/config文件中添加多个Host配置:
Host dev-server HostName 203.0.113.10 User devuser Port 31022 IdentityFile ~/.ssh/id_ed25519 IdentitiesOnly yes Host test-server HostName 192.168.1.100 User testuser Port 22 IdentityFile ~/.ssh/id_ed25519 IdentitiesOnly yes之后分别使用下面的命令登录:
sshdev-serversshtest-server这样既可以减少重复输入,也便于统一管理多台服务器的 SSH 连接信息。
个人声明:本文为个人学习笔记,如有错误,欢迎指正。