SSH安全指南:什么是SSH

157 阅读7分钟

SSH

安全外壳(SSH)是一种网络协议,用于在计算机之间建立加密连接,实现安全的远程访问。它运行在 TCP 22 端口上,提供身份验证、加密和完整性保护,确保数据在不安全的网络中传输时不被窃取或篡改。

目录

SSH 如何工作

TCP/IP 协议

SSH 基于 TCP/IP 协议套件运行,这是互联网通信的基础。TCP/IP 负责传输和传递数据包。SSH 使用 TCP 协议而非 UDP,这让它比某些隧道技术更可靠(虽然速度稍慢)。

公钥加密

SSH 之所以"安全",是因为它结合了加密和身份验证,采用的是公钥加密法

公钥加密法的原理是:用两把不同的密钥来加密或签名数据。一把是公钥(可以公开),一把是私钥(必须保密)。这两把密钥是配对的,只有持有私钥的人才能证明自己是公钥的主人。

这种"非对称"密钥(因为两把密钥的值不同)还能让通信双方协商出一个共享的对称密钥,用于后续的数据加密。协商完成后,双方就用这个对称密钥来加密传输的数据。

在 SSH 连接中,客户端和服务器都有自己的公钥/私钥对,双方互相验证身份。这和 HTTPS 不同——HTTPS 通常只验证服务器的身份。另外,HTTPS 一般不允许客户端访问服务器的命令行,而且防火墙很少会拦截 HTTPS,但可能会拦截 SSH。

常见 SSH 密钥类型

  • ed25519(推荐):安全性高、速度快、密钥短,是目前最佳选择
  • ecdsa:椭圆曲线算法,常见的有 nistp256/384/521
  • rsa:传统类型,兼容性最好,建议使用 3072 或 4096 位
  • dsa:已过时,不建议使用

选择建议:优先使用 ed25519;只有在需要兼容老系统时才考虑 rsa。

基础名词解释

  • 私钥口令(passphrase):给私钥文件加的一层本地密码锁。即使别人拿到你的私钥文件,没有口令也无法使用;在解锁(如 ssh-add)时需要输入。
  • 公钥指纹(fingerprint):公钥内容的短摘要(哈希值),用来快速比对"这是不是同一把公钥",常见于服务器或平台显示的识别码。
  • 公钥(public key):可以公开分发的密钥,用于验证身份或加密协商。
  • 私钥(private key):必须保密的密钥,用于证明身份或解密签名。
  • ssh-agent:密钥代理进程,用于在会话中缓存已解锁的私钥,避免重复输入口令。
  • authorized_keys:服务器端保存的允许登录的公钥列表(位于 ~/.ssh/authorized_keys)。

macOS 常用操作

启动 ssh-agent

eval "$(ssh-agent -s)"

如果看到 Agent pid 98549 这样的输出,说明 ssh-agent 已经启动成功,进程号是 98549

添加 SSH 密钥

ssh-add ~/.ssh/id_ed25519

macOS 特有:添加到钥匙串(推荐)

ssh-add --apple-use-keychain ~/.ssh/id_ed25519

这样做的好处是重启后密钥会自动加载,不用每次都手动添加。

检查密钥是否添加成功

ssh-add -l

Windows 常用操作

启用并启动 ssh-agent

Get-Service ssh-agent | Set-Service -StartupType Automatic
Start-Service ssh-agent

添加 SSH 密钥

ssh-add $env:USERPROFILE\.ssh\id_ed25519

检查密钥是否添加成功

ssh-add -l

Linux 常用操作

启动 ssh-agent

eval "$(ssh-agent -s)"

添加 SSH 密钥

ssh-add ~/.ssh/id_ed25519

检查密钥是否添加成功

ssh-add -l

ssh-agent / ssh-add(密钥管理)

  • eval "$(ssh-agent -s)":启动 ssh-agent 并把环境变量写入当前 shell,这样后续的 ssh/ssh-add 命令才能找到 agent。
  • ssh-add ~/.ssh/id_ed25519:把私钥加载到当前 ssh-agent 会话里(仅当前会话有效)。
  • ssh-add --apple-use-keychain ~/.ssh/id_ed25519:macOS 专用,加载到 agent 的同时保存到钥匙串,重启后可自动取用。
  • ssh-add -l:列出当前 agent 已加载的密钥(只看 agent,不看磁盘上的文件)。
  • ssh-add -d ~/.ssh/id_ed25519:从 agent 中移除指定密钥(文件仍在磁盘上)。
  • ssh-add -D:从 agent 中移除所有密钥(文件仍在磁盘上)。
  • ssh-add -x:锁定 agent,需要密码才能再次使用已加载的密钥。
  • ssh-add -X:解锁 agent。
  • ssh-agent -k:关闭 agent(并清理相关环境变量)。

ssh-keygen(生成与管理密钥)

生成密钥

生成 ED25519 密钥对(推荐)

ssh-keygen -t ed25519 -C "your_email@example.com"
  • -t ed25519:选择 ED25519 算法,安全且速度快
  • -C:添加注释(通常写邮箱),会出现在公钥末尾,方便在服务器或 GitHub 上识别

生成 RSA 密钥对(兼容老系统)

ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
  • -t rsa:使用 RSA 算法
  • -b 4096:指定 4096 位长度,越长越安全但速度稍慢

指定生成路径/文件名

ssh-keygen -t ed25519 -f ~/.ssh/custom_key
  • -f:自定义输出文件名和路径,便于区分多把密钥(例如按用途命名)

管理密钥

修改私钥口令

ssh-keygen -p -f ~/.ssh/id_ed25519
  • -p:会提示你输入旧口令和新口令,仅更新私钥文件的加密口令,不改变密钥内容

查看公钥指纹

ssh-keygen -lf ~/.ssh/id_ed25519.pub
  • 输出指纹用于比对密钥是否一致,常用来核对服务器或平台上登记的公钥

从私钥重新生成公钥

ssh-keygen -y -f ~/.ssh/id_ed25519 > ~/.ssh/id_ed25519.pub
  • -y:从私钥导出公钥,重定向到 .pub 文件
  • 常用于公钥丢失但私钥还在的情况

其他常用 SSH 命令

  • ssh user@hostname:连接到服务器
  • ssh -p 2222 user@hostname:指定端口连接(默认是 22 端口)
  • ssh -i ~/.ssh/custom_key user@hostname:指定使用哪把私钥连接
  • ssh-copy-id user@hostname:把本地公钥复制到服务器的 ~/.ssh/authorized_keys,实现免密登录(macOS 可能需要额外安装该命令)
  • ssh -T git@github.com:测试到 GitHub 的 SSH 认证(不会执行远程命令)

示例 1:切换 GitHub 仓库的连接方式

步骤 1:创建本地 SSH 密钥

使用上面介绍的命令生成密钥:

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

步骤 2:将密钥添加到 ssh-agent

ssh-add ~/.ssh/id_ed25519

步骤 3:在 GitHub 中添加公钥

  1. 打开 GitHub,进入 SettingsSSH and GPG keys
  2. 点击 New SSH key
  3. Key 处填写你的公钥内容

如何获取公钥内容?

在 macOS 上,打开 ~/.ssh/id_ed25519.pub 文件,复制全部内容到 Key 中。

GitHub SSH 设置

添加 SSH Key

步骤 4:切换远程连接方式

# 查看当前远程 URL
git remote -v

# 如果是 HTTPS(https://github.com/...)
# 转换为 SSH(git@github.com:...)
git remote set-url origin git@github.com:用户名/仓库名.git

示例:

# HTTPS URL
https://github.com/Shadow1086/myJavaStudy.git

# 转换为 SSH URL
git@github.com:Shadow1086/myJavaStudy.git

# 执行转换
git remote set-url origin git@github.com:Shadow1086/myJavaStudy.git

步骤 5:验证是否切换成功

# 查看远程 URL(应该显示 git@github.com:...)
git remote -v

# 测试连接
git fetch origin

常见问题

Q: 切换后提示 "Permission denied (publickey)"?

A: 检查以下几点:

  1. SSH 密钥是否已添加到 GitHub
  2. ssh-agent 中是否有对应的密钥(ssh-add -l
  3. SSH config 配置是否正确

Q: 如何测试 SSH 连接?

ssh -T git@github.com
# 成功会显示:Hi 用户名! You've successfully authenticated...

Q: 已有的本地分支会受影响吗?

A: 不会。只是改变了与远程仓库的连接方式,本地代码和分支不受影响。

示例 2:使用 Termius 连接服务器

使用 SSH 密钥连接(推荐)

这种方式比密码登录更安全。

步骤 1:在 Termius 中添加 SSH 密钥

在 Termius 主页面左侧的 密钥链 中添加你的 SSH 密钥。

Termius 密钥链

添加密钥

SSH 密钥位置:

在 macOS 上,SSH 密钥位于用户目录下的 .ssh 目录中。使用文本编辑器打开私钥文件(如 id_ed25519),复制全部内容到上图中的 私钥 部分。

私钥格式如下:

-----BEGIN OPENSSH PRIVATE KEY-----
你的密钥内容
-----END OPENSSH PRIVATE KEY-----

注意: BEGINEND 这两行也要一起复制。这个密钥非常重要,请妥善保管!

步骤 2:添加主机并关联密钥

像添加普通主机一样操作,但要在配置中关联刚才添加的密钥:

添加主机

关联密钥

完成配置

步骤 3:连接服务器

点击连接,如果用户名、密钥等配置都正确,就会成功进入服务器终端。

参考: CloudFlare

注: 笔者使用的是Mac,所以对Windows和Linux的部分可能略为简陋