Github创建提交密钥最容易踩的坑 cover image

Github创建提交密钥最容易踩的坑

git fetch --all
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
error: could not fetch upstream
error: RPC failed; curl 28 Recv failure: Connection was reset
fatal: expected flush after ref listing
error: could not fetch origin

这个错误信息表明在使用 Git 从远程仓库获取代码时出现了问题,下面为你详细解释并给出解决办法。

错误原因剖析
  1. 权限问题(公钥错误)
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

这个错误是因为 GitHub 没办法通过 SSH 密钥验证你的身份。一般是由以下情况导致的:
- 你没有生成 SSH 密钥。
- 生成的 SSH 密钥没有添加到 GitHub 账户。
- 私钥文件的权限设置不正确。
- SSH 代理没有加载私钥。

  1. 网络连接问题
error: RPC failed; curl 28 Recv failure: Connection was reset
fatal: expected flush after ref listing

这个错误是在数据传输时网络连接中断造成的。可能的因素有:
- 网络不稳定或者防火墙限制了访问。
- 仓库体积过大,超出了 HTTP 请求的超时时间。
- GitHub 服务器暂时不可用。

解决办法
1. 解决 SSH 权限问题

首先,确认 SSH 密钥是否存在并且配置正确:

# 查看是否已有 SSH 密钥
ls -al ~/.ssh/id_rsa.pub  # 若没有该文件,需生成新的 SSH 密钥

# 生成新的 SSH 密钥(如果需要)
ssh-keygen -t rsa -b 4096 -C "[email protected]"
# 按提示操作,无需修改默认值

# 启动 SSH 代理并添加私钥
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_rsa

# 复制公钥到剪贴板
cat ~/.ssh/id_rsa.pub | pbcopy  # macOS
xclip -sel clip < ~/.ssh/id_rsa.pub  # Linux

接着,把公钥添加到 GitHub 账户:

  • 登录 GitHub,进入 Settings → SSH and GPG keys。
  • 点击 New SSH key,粘贴刚才复制的公钥内容。

最后,测试 SSH 连接:

ssh -T git@github.com
# 成功的话会看到:Hi username! You've successfully authenticated...
2. 解决网络连接问题

可以尝试以下几种方法:

# 增加 Git 的 HTTP 缓冲区大小
git config --global http.postBuffer 524288000  # 500MB

# 修改远程仓库的 URL,从 SSH 改为 HTTPS
git remote set-url origin <https://github.com/your-username/your-repo.git>

# 或者,如果你想用 SSH,先克隆 HTTPS 版本,之后再切换回 SSH
git clone <https://github.com/your-username/your-repo.git>
cd your-repo
git remote set-url origin git@github.com:your-username/your-repo.git

# 若网络不稳定,可以分多次获取
git fetch --depth=1 origin main  # 只获取最近的提交
总结处理步骤
  1. 生成 SSH 密钥并添加到 GitHub。
  2. 检查并更新远程仓库的 URL。
  3. 增大 HTTP 缓冲区,避免传输中断。
  4. 尝试使用 HTTPS 替代 SSH 进行克隆和获取操作。
错误原因分析

在运行ssh-keygen命令时,系统会提示你输入几个信息:

  1. 密钥保存位置
    Enter file in which to save the key (C:\\Users\\somebody/.ssh/id_rsa):
    

    你在这里输入了eval "$(ssh-agent -s)",这是错误的。这个提示需要的是一个文件路径,而不是命令。

  2. 密码短语(Passphrase)

    接下来系统要求你设置一个密码短语来保护私钥,但你两次输入的密码不一致:

    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:
    Passphrases do not match.  Try again.
    
  3. 最终错误
    Saving key "eval "$(ssh-agent -s)"" failed: No such file or directory
    

    由于你输入的是一个无效的文件路径,系统无法创建名为eval "$(ssh-agent -s)"的文件,因此报错。

正确生成SSH密钥的步骤
1. 重新运行密钥生成命令
ssh-keygen -t rsa -b 4096 -C "[email protected]"
2. 正确回答提示问题
  • 保存位置:直接按回车键使用默认路径(C:\\Users\\somebody/.ssh/id_rsa
  • 密码短语:可以输入一个安全的密码(也可以留空不设置),但必须确保两次输入一致

完整示例:

Generating public/private rsa key pair.
Enter file in which to save the key (C:\\Users\\somebody/.ssh/id_rsa):  # 直接回车
Enter passphrase (empty for no passphrase):  # 输入密码(密码不会显示)
Enter same passphrase again:  # 再次输入相同密码
Your identification has been saved in C:\\Users\\somebody/.ssh/id_rsa.
Your public key has been saved in C:\\Users\\somebody/.ssh/id_rsa.pub.
3. 启动SSH代理并添加私钥
# Windows上使用Git Bash的正确命令
eval $(ssh-agent -s)
ssh-add ~/.ssh/id_rsa
总结
  • 错误点:将命令eval "$(ssh-agent -s)"作为文件路径输入了
  • 解决方案:重新运行ssh-keygen,使用默认路径,确保密码一致

在 Windows 系统上,复制 SSH 公钥的方法取决于你使用的终端工具。以下是几种常见的方法:

1. 使用 Git Bash(推荐)

如果你使用的是 Git Bash(安装 Git 时附带的终端),可以使用以下命令:

cat ~/.ssh/id_rsa.pub | clip  # 将公钥复制到剪贴板
2. 使用 PowerShell

如果你使用的是 PowerShell,可以使用以下命令:

Get-Content ~/.ssh/id_rsa.pub | Set-Clipboard  # PowerShell 5.1+

或者使用更通用的方法:

type $env:USERPROFILE\\.ssh\\id_rsa.pub | clip  # 适用于所有 PowerShell 版本
3. 使用 Windows 命令提示符(CMD)

如果你使用的是 命令提示符(CMD),可以使用以下命令:

type %USERPROFILE%\\.ssh\\id_rsa.pub | clip  # 将公钥复制到剪贴板
4. 手动复制

如果你不想使用命令,也可以手动打开并复制:

# 用记事本打开公钥文件
notepad ~/.ssh/id_rsa.pub

然后在记事本中手动选中所有内容(Ctrl+A)并复制(Ctrl+C)。
文件位置:C:\Users\Administrator/.ssh/id_rsa.pub

验证是否复制成功

复制后,可以打开一个文本编辑器(如记事本),按 Ctrl+V 粘贴,如果能看到类似下面的内容,说明复制成功:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC... 你的邮箱@example.com

接下来,你可以将这段内容粘贴到 GitHub 的 SSH 密钥设置页面中。

在 GitHub 中添加 SSH 密钥时,TitleKey Type 是两个不同的设置,它们的作用和填写方式如下:

1. Title(标题)
  • 作用:标题是你给这个 SSH 密钥起的别名,仅用于在 GitHub 界面中标识该密钥,方便你管理多个密钥(例如区分不同设备或用途的密钥)。
  • 填写方式:可以随便填,但建议使用有意义的名称,例如:
    • My Laptop(你的笔记本电脑)
    • Work Desktop(工作电脑)
    • Personal GitHub Key(个人 GitHub 密钥)
2. Key Type(密钥类型)
  • 作用:密钥类型决定了该 SSH 密钥的用途,GitHub 支持两种类型:
    1. Authentication Key(认证密钥):用于登录和访问 GitHub 仓库(例如通过 git clonegit push 等操作)。
    2. Signing Key(签名密钥):用于代码签名,确保提交或标签来自可信来源(与 GPG 签名类似)。
  • 如何选择
    • 如果你只是想克隆/推送代码,选择 Authentication Key(默认选项)。
    • 如果你需要对提交进行签名(例如开源项目要求验证身份),选择 Signing Key,并在 Git 中配置该密钥用于签名。
总结
设置项 是否必填 填写建议 用途示例
Title 填写设备或用途名称(如 MacBook Pro 区分不同设备的密钥
Key Type 默认为 Authentication Key 认证密钥用于登录,签名密钥用于代码签名
操作步骤示例
  1. 复制 SSH 公钥(参考之前的回复):
    cat ~/.ssh/id_rsa.pub | clip  # Git Bash
    
  2. 在 GitHub 添加密钥
    • 进入 GitHub Settings > SSH and GPG keys
    • 点击 New SSH key
    • Title:输入 My Development Machine
    • Key Type:选择 Authentication Key
    • Key:粘贴你复制的公钥内容(以 ssh-rsa 开头)
    • 点击 Add SSH key

完成后,如果报以下错误,

> git fetch --all
From github.com:youxiaohanpian/astro-notion-blog-main
   b52b41f..e8c9be6  main       -> upstream/main
fatal: unable to access 'https://github.com/youxiaohanpian/astro-notion-blog-main.git/': Failed to connect to github.com port 443 after 21075 ms: Couldn't connect to server
error: could not fetch origin

查询下状态

PS E:\astro-notion-blog-main> git remote -v
origin  https://github.com/youxiaohanpian/astro-notion-blog-main.git (fetch)
origin  https://github.com/youxiaohanpian/astro-notion-blog-main.git (push)
upstream        git@github.com:youxiaohanpian/astro-notion-blog-main.git (fetch)
upstream        git@github.com:youxiaohanpian/astro-notion-blog-main.git (push)

仓库配置显示,origin 使用的是 HTTPS 协议,而 upstream 使用的是 SSH 协议。切换到 SSH 协议 就是将 origin 的 URL 从 HTTPS 改为 SSH,这样你就可以通过 SSH 密钥验证访问 GitHub,避免 HTTPS 连接可能遇到的网络问题。

为什么需要切换?
  • HTTPS 连接失败:你的错误 Failed to connect to github.com port 443 表明网络阻止了 HTTPS 访问。
  • SSH 协议优势:SSH 通过 22 端口通信,通常不会被防火墙拦截,且验证更安全(基于密钥而非密码)。
如何切换?

根据你的输出,你已经成功配置了 upstream 的 SSH 连接([email protected]:...),说明你的 SSH 密钥设置正确。只需将 origin 也切换到 SSH 协议即可:

# 将origin的URLHTTPS切换到SSH
git remote set-url origin git@github.com:youxiaohanpian/astro-notion-blog-main.git

# 验证配置是否更新
git remote -v

预期输出

origin  git@github.com:youxiaohanpian/astro-notion-blog-main.git (fetch)
origin  git@github.com:youxiaohanpian/astro-notion-blog-main.git (push)
upstream        git@github.com:youxiaohanpian/astro-notion-blog-main.git (fetch)
upstream        git@github.com:youxiaohanpian/astro-notion-blog-main.git (push)
验证 SSH 连接

在切换后,测试 SSH 连接是否正常:

ssh -T git@github.com

如果看到类似以下信息,说明 SSH 连接成功:

Hi youxiaohanpian! You've successfully authenticated...
后续操作

切换后,再次尝试拉取代码:

git fetch --all

如果仍然遇到问题,可能是网络环境限制了 SSH 端口(22)。这种情况下,你可以尝试使用 SSH 代理跳转HTTPS 带凭证方式(需输入 GitHub 用户名和 PAT 令牌)。

总结
  1. 切换协议:将 origin 从 HTTPS 改为 SSH 解决连接问题。
  2. 利用现有配置:你已经正确配置了 upstream 的 SSH,说明密钥可用。
  3. 测试连接:通过 ssh -T [email protected] 验证 SSH 连通性。

SSH 密钥的缓存时间和使用方式取决于你的操作系统和配置。以下是不同环境下的详细说明:

1. 缓存有效期
Windows Git Bash
  • 默认行为:SSH Agent 随 Git Bash 会话启动,缓存仅在当前终端窗口有效。关闭窗口后,缓存的密钥会丢失,下次需要重新执行 ssh-add
  • 持久化方法
    # 启动时自动加载密钥(添加到 ~/.bashrc 或 ~/.bash_profile)
    if [ -z "$SSH_AUTH_SOCK" ]; then
       eval $(ssh-agent -s)
       ssh-add /c/Users/somebody/.ssh/id_rsa
    fi
    
macOS
  • 默认行为:macOS 的 Keychain 会永久记住 SSH 密钥(如果添加时使用了 K 参数)。
    # 添加密钥并存储到 Keychain
    ssh-add -K /c/Users/somebody/.ssh/id_rsa
    
  • 配置文件方法:编辑 ~/.ssh/config 添加:
    Host *
      UseKeychain yes
      AddKeysToAgent yes
      IdentityFile ~/.ssh/id_rsa
    
Linux
  • 默认行为:缓存仅在当前 SSH Agent 会话有效(通常是终端窗口生命周期)。
  • 持久化方法:使用 gnome-keyringkwallet 等密钥管理器,或在 ~/.bashrc 中添加:
    eval $(ssh-agent -s)
    ssh-add ~/.ssh/id_rsa
    
2. 是否每次打开 Git Bash 都要执行?
  • 未配置自动加载:是的,每次打开新的 Git Bash 窗口都需要手动执行 ssh-add
  • 配置自动加载:通过修改配置文件(如 ~/.bashrc~/.ssh/config),可以实现自动加载,无需每次手动操作。
3. 推荐配置方案
Windows Git Bash 用户
  1. 编辑 ~/.bashrc 文件(在 Git Bash 中执行):
    nano ~/.bashrc
    
  2. 添加以下内容
    # 启动 SSH Agent 并自动加载密钥
    if [ -z "$SSH_AUTH_SOCK" ]; then
      eval $(ssh-agent -s)
      ssh-add /c/Users/somebody/.ssh/id_rsa
    fi
    
  3. 保存并退出(按 Ctrl+X,然后按 Y,最后按 Enter)。
  4. 重新启动 Git Bash,密钥将自动加载。
4. 验证配置
# 查看已加载的密钥
ssh-add -l

# 如果看到你的密钥,则表示已成功加载
2048 SHA256:xxx... /c/Users/somebody/.ssh/id_rsa (RSA)
总结
  • 缓存时间:默认仅在当前会话有效,通过配置可实现持久化。
  • 自动加载:通过修改 ~/.bashrc~/.ssh/config,可避免每次手动执行 ssh-add
  • 跨平台方案:macOS 有内置的 Keychain 支持,Windows/Linux 需要手动配置。

配置完成后,你可以在任意新打开的终端窗口中直接使用 SSH 连接 GitHub,无需重复输入 passphrase。

💡
欢迎分享文章,或是 来信 与我交流