SSH 常见用法(二):通过 SSH 认证访问 Git 仓库
系列导读
本系列共包含一篇总览和四篇专题文章:
| 系列位置 | 文章主题 | 主要内容 |
|---|---|---|
| 总览 | 浅谈 SSH:原理、认证与四种常见用法 | 认识 SSH 及其四种常见用法 |
| 第一篇 | SSH 常见用法(一):远程登录服务器 | 密码登录、密钥认证和~/.ssh/config |
| 第二篇(本文) | SSH 常见用法(二):通过 SSH 认证访问 Git 仓库 | 配置 SSH Key,并通过 SSH 操作远程仓库 |
| 第三篇 | SSH 常见用法(三):本地端口转发与远程端口转发 | -L本地端口转发与-R远程端口转发 |
| 第四篇 | SSH 常见用法(四):使用 SCP 和 SFTP 远程传输文件 | 在本机与服务器之间安全传输文件 |
一、前言
SSH 的全称是Secure Shell(安全外壳协议),是一种用于安全访问和操作远程计算机的加密网络协议。它可以提供加密通信、服务器身份验证和客户端身份验证。
SSH 常见的使用场景包括远程登录服务器、Git 身份认证、端口转发和远程文件传输。本文讨论其中的第二种:通过 SSH 认证访问 Git 仓库。
在访问远程 Git 仓库时,可以使用 SSH Key 证明“你是谁”,不需要反复输入远程平台的账号密码。
简单来说:私钥保存在本机,公钥添加到 GitHub;当本机发起 SSH 连接时,GitHub 通过公钥验证当前客户端是否持有对应的私钥。
GitHub 是最常见的场景,但不只是 GitHub,GitLab、Bitbucket、公司内部 Git 服务器也可以使用这种认证方式。
1.1 HTTPS 和 SSH 的区别
平时使用 GitHub 时,通常可以看到 HTTPS 和 SSH 两种仓库地址。
HTTPS:
git clone https://github.com/user/project.gitSSH:
git clone git@github.com:user/project.gitSSH 和 HTTPS 都是在解决“Git 如何连接 GitHub”的问题,只是使用的连接协议和身份认证方式不同。
| 对比项 | HTTPS | SSH |
|---|---|---|
| 仓库地址 | https://github.com/user/project.git | git@github.com:user/project.git |
| 连接方式 | HTTPS | SSH |
| 常见认证方式 | Personal Access Token、Git Credential Manager 或 GitHub CLI | SSH Key |
| 前期配置 | 相对简单 | 需要生成密钥,并把公钥添加到 GitHub |
| 日常使用 | 凭据可以由工具缓存 | 配置完成后,通常不需要重复输入账号凭据 |
| 网络适应性 | 通常更容易在受限网络中使用 | 某些网络可能限制 SSH 默认使用的 22 端口 |
简单来说:HTTPS 通常使用令牌等凭据证明身份,SSH 使用密钥对证明身份。两种方式都可以安全地操作 GitHub 仓库。
需要注意,GitHub 已经不再支持使用账号密码完成 Git 命令行的 HTTPS 身份认证。使用 HTTPS 操作需要认证的仓库时,应当使用 Personal Access Token、Git Credential Manager 或 GitHub CLI。
本文主要介绍通过 SSH Key 进行身份认证,因此后续使用的是 SSH 仓库地址:
git@github.com:user/project.gitGitHub 官方说明:About authentication to GitHub
【本机 / 你的电脑】 │ │ 1. 检查是否已有 SSH Key │ ls -la ~/.ssh ▼ 【是否存在完整密钥对?】 │ ├── 已存在 → 使用已有密钥 │ └── 不存在 → 2. 生成 SSH Key ssh-keygen -t ed25519 \ -C "your_email@example.com" │ ▼ 【本机保存一对密钥】 │ ├── 私钥 │ ~/.ssh/id_ed25519 │ 只保存在本机 │ 不要泄露 │ └── 公钥 ~/.ssh/id_ed25519.pub │ │ 3. 把公钥添加到 GitHub ▼ 【GitHub 账号】 Settings │ ▼ SSH and GPG keys ▼ 【GitHub 保存公钥】 │ │ 4. 测试 SSH 认证 │ │ ssh -T git@github.com ▼ 【SSH 建立连接】 │ │ 本机使用私钥证明身份 │ │ GitHub 使用保存的公钥验证 ▼ 【身份验证成功】 │ │ GitHub 确认: │ “这个 SSH Key 属于哪个 GitHub 账号?” ▼ 【5. 使用 SSH 地址操作 Git 仓库】 │ ├── git clone git@github.com:user/project.git │ ├── git pull │ └── git push │ ▼ 【GitHub 检查仓库权限】 │ ├── 有权限 → 允许操作 │ └── 没权限 → 拒绝操作二、GitHub SSH Key 配置示例
私钥在你电脑上,公钥在 GitHub 上;当你用 SSH 操作 Git 仓库时,GitHub 通过这对密钥确认“你是谁”。
最典型的流程是这样的:
你的电脑 │ │ 本地保存 SSH 私钥 │ ▼ GitHub │ │ 保存你的 SSH 公钥 │ ▼ 当你 git clone / pull / push 时 GitHub 验证: “你是否真的拥有对应的私钥?” │ ▼ 验证成功 │ ▼ 允许访问仓库整个配置通常分 5 步:
- 检查本机是否已有 SSH Key
- 没有密钥时生成 SSH Key
- 把公钥添加到 GitHub
- 测试 SSH 身份认证
- 使用 SSH 地址操作仓库
2.1 检查本机是否已有 SSH Key
生成新的 SSH Key 之前,先查看本机的~/.ssh目录:
ls-la~/.ssh常见的 SSH 密钥对有:
Ed25519: id_ed25519 # 私钥 id_ed25519.pub # 公钥 RSA: id_rsa # 私钥 id_rsa.pub # 公钥SSH Key 需要成对使用:
- 没有
.pub后缀的是私钥,只能保存在本机,不能发送给别人。 - 带
.pub后缀的是公钥,可以添加到 GitHub。 - 只有公钥、没有对应私钥,无法完成 SSH 身份认证。
如果已经存在完整的密钥对,可以继续使用,不需要再次生成。例如:
id_ed25519 id_ed25519.pub如果~/.ssh目录不存在,或者目录中只有known_hosts、config等文件,没有完整密钥对,再进行下一步。
不要直接覆盖已有私钥。原来的私钥可能正在用于访问 GitHub、GitLab 或其他服务器,覆盖后可能导致已有连接失效。
2.2 没有密钥时生成 SSH Key
例如现在比较常用:
ssh-keygen -t ed25519 -C "your_email@example.com"生成以后通常会得到:
~/.ssh/id_ed25519 ~/.ssh/id_ed25519.pub其中:
id_ed25519 ↓ 私钥 只保存在你自己电脑上 绝对不要给别人 id_ed25519.pub ↓ 公钥 可以给 GitHub2.3 把公钥添加到 GitHub
你查看公钥:
cat ~/.ssh/id_ed25519.pub这里以 Ed25519 公钥为例。如果使用的是 RSA 密钥,则查看:
cat~/.ssh/id_rsa.pub会看到类似:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI...... your_email@example.com然后把这一整行复制到 GitHub 的 SSH Keys 设置中。
Github配置SSH,
个人头像 --> Settings --> SSH And GPG Keys --> New SSH key
然后进行添加title和key
这样就形成:
你的电脑 ──────────────────────────── 私钥: ~/.ssh/id_ed25519 GitHub ──────────────────────────── 公钥: ssh-ed25519 AAAA......2.4 测试 SSH 身份认证
通常可以执行:
ssh -T git@github.com第一次连接可能会问你是否信任 GitHub 的主机指纹。
认证成功以后,GitHub 会告诉你认证成功。如下图所示;
认证失败如下所示,说明配置SSH Key没有配置成功
注意这里:
git@github.com这个git一般不是你的 GitHub 用户名。
它是 GitHub SSH 服务使用的固定 SSH 用户。
GitHub 最终是通过你的SSH Key来判断:
这个 key 属于哪个 GitHub 账号?
2.5 使用 SSH 地址操作仓库
之后:
git clone git@github.com:user/project.git成功情况下一般就是这样
失败会类似如下所示
成功如图所示
或者:
git pullgit pushGit 就会在底层通过 SSH 建立连接。
可以把一次git push粗略理解成:
你执行: git push │ ▼ Git 发现远程地址是: git@github.com:user/project.git │ ▼ 启动 SSH │ ▼ 连接 github.com │ ▼ SSH 使用你的私钥 │ ▼ GitHub 使用你上传的公钥进行验证 │ ▼ 验证成功 │ ▼ GitHub 确认你的账号 │ ▼ 检查你是否有这个仓库的 push 权限 │ ▼ 允许 push这里有一个特别容易混淆的概念:
SSH 身份认证 ≠ Git 提交身份。
比如你设置:
git config --global user.name "Tom" git config --global user.email "tom@example.com"这是告诉 Git:
“这次 commit 的作者是谁。”
而 SSH Key 是告诉 GitHub:
“现在连接 GitHub 的这个人是谁,以及他有没有访问仓库的权限。”
所以两者完全不同:
| 东西 | 作用 |
|---|---|
| git config user.name | Commit 作者名字 |
| git config user.email | Commit 作者邮箱 |
| SSH Key | 登录 / 认证 GitHub 身份 |
| GitHub 仓库权限 | 决定你能不能 clone / pull / push |
你可以把 GitHub SSH 认证浓缩成一句话:
本机保存私钥,GitHub 保存公钥;当你通过 SSH 操作 Git 仓库时,GitHub 验证你是否拥有对应私钥,验证成功后再判断你有没有仓库权限。
三、同一台电脑使用多个 GitHub 账号
如果一台电脑同时使用个人账号和工作账号,不能把同一个公钥分别添加到两个账号。正确做法是:
- 为每个 GitHub 账号生成独立的密钥对。
- 把不同的公钥添加到对应账号。
- 使用
~/.ssh/config为不同账号配置不同的主机别名。 - 在仓库地址中使用对应的主机别名。
3.1 生成两组不同的 SSH Key
为个人账号生成密钥:
ssh-keygen-ted25519\-C"personal@example.com"\-f~/.ssh/id_ed25519_github_personal为工作账号生成密钥:
ssh-keygen-ted25519\-C"work@example.com"\-f~/.ssh/id_ed25519_github_work生成后会得到两组不同的密钥:
个人账号: ~/.ssh/id_ed25519_github_personal ~/.ssh/id_ed25519_github_personal.pub 工作账号: ~/.ssh/id_ed25519_github_work ~/.ssh/id_ed25519_github_work.pub其中,没有.pub后缀的是私钥;带.pub后缀的是需要添加到 GitHub 的公钥。
3.2 把公钥添加到对应的 GitHub 账号
查看个人账号的公钥:
cat~/.ssh/id_ed25519_github_personal.pub查看工作账号的公钥:
cat~/.ssh/id_ed25519_github_work.pub分别登录两个 GitHub 账号,把对应的公钥添加到各自的SSH and GPG keys设置中。
3.3 配置 ~/.ssh/config
编辑~/.ssh/config,为两个账号设置不同的主机别名:
Host github-personal HostName github.com User git IdentityFile ~/.ssh/id_ed25519_github_personal IdentitiesOnly yes Host github-work HostName github.com User git IdentityFile ~/.ssh/id_ed25519_github_work IdentitiesOnly yes这里的github-personal和github-work是本机使用的别名,真正连接的服务器仍然是github.com。
IdentitiesOnly yes表示只使用当前配置中指定的密钥,避免 SSH Agent 中存在多把密钥时选错身份。
3.4 分别测试两个账号
测试个人账号:
ssh-Tgit@github-personal测试工作账号:
ssh-Tgit@github-work认证成功后,GitHub 返回的信息中会包含当前密钥对应的账号名,可以据此检查是否使用了正确的身份。
3.5 使用不同的仓库地址
个人账号的仓库使用:
gitclone git@github-personal:personal-user/project.git工作账号的仓库使用:
gitclone git@github-work:work-user/project.git如果仓库已经克隆,可以修改远程地址:
gitremote set-url origin git@github-work:work-user/project.git需要特别注意,SSH 配置解决的是“使用哪个 GitHub 账号进行身份认证”,提交记录中的作者仍然由 Git 配置决定。例如,可以在工作仓库中单独设置:
gitconfig user.name"Work Name"gitconfig user.email"work@example.com"GitHub 官方说明:Managing multiple accounts
个人声明:本文为个人学习笔记,如有错误,欢迎指正。