GitHub SSH 连接故障速查(我的踩坑总结)
目标:下次遇到 Permission denied (publickey)、git pull/push 失败时,看一眼就能定位 & 修好。
适用:Linux(也适用于 WSL)。
核心原则:GitHub SSH = 公钥在 GitHub,私钥在本机,SSH 必须“用到”那把私钥。
0. 典型报错与含义
- 含义:SSH 没有用上任何一个 GitHub认可的私钥(最常见)
- 常见原因:
- 私钥文件名不是默认
id_ed25519/id_rsa,SSH 没自动尝试
- SSH 尝试了错误的 key(有多把 key)
- ssh-agent 没启动/没加载 key(尤其 key 有 passphrase)
- key 权限不对,SSH 忽略该 key/config
B) fatal: could not read from remote repository
1. 一分钟诊断流程(先跑这些命令)
1.1 看远端用的是 SSH 还是 HTTPS
1 2 3 4 5 6 7 8 9 10
| git remote -v ````
* 如果是 `git@github.com:...` → SSH(本文适用) * 如果是 `https://github.com/...` → 走 HTTPS(需要 PAT/浏览器授权,不用 SSH key)
```bash ssh -T git@github.com
|
- ✅ 成功:会显示
Hi <username>! You've successfully authenticated...
- ❌ 失败:
Permission denied (publickey) → 继续下面步骤
1.3 开启详细日志(定位“SSH 到底用哪把 key”)
重点看:
Offering public key: ...
Trying private key: ...
如果没有出现你期望的私钥文件名,就是 SSH 没用上你那把 key。
2. 正确生成一对新的 SSH 密钥(推荐:自定义名字)
强烈建议:不要拷贝旧电脑私钥,新机器重新生成一对 key 更安全。
2.1 生成 ed25519 key(自定义文件名)
例如命名为 github_cad:
1 2 3 4
| mkdir -p ~/.ssh chmod 700 ~/.ssh
ssh-keygen -t ed25519 -C "wu-diu-diu@github" -f ~/.ssh/github_cad
|
生成:
- 私钥:
~/.ssh/github_cad
- 公钥:
~/.ssh/github_cad.pub
2.2 把公钥添加到 GitHub
1
| cat ~/.ssh/github_cad.pub
|
复制输出 → GitHub:Settings → SSH and GPG keys → New SSH key → 粘贴保存。
2.3 修正权限(SSH 很挑)
1 2
| chmod 600 ~/.ssh/github_cad chmod 644 ~/.ssh/github_cad.pub
|
3. 让 SSH “只用指定密钥”连接 GitHub(一劳永逸,强烈推荐)
这一步能解决:多 key 混乱、默认 key 找不到、一直 denied 等问题。
编辑 ~/.ssh/config(没有就创建):
写入(把文件名改成你的):
1 2 3 4 5
| Host github.com HostName github.com User git IdentityFile ~/.ssh/github_cad IdentitiesOnly yes
|
权限:
验证:
4. ssh-agent:什么时候需要?怎么用?(避免每次输入 passphrase)
4.1 什么时候“需要” ssh-agent?
- 你的私钥设置了 passphrase:不使用 agent 也能用,但会频繁要求输入 passphrase。
- 你希望一次登录后缓存 key:用 agent 最舒服。
注意:你遇到的 Permission denied (publickey) 多数是没用上正确 key,不一定是缺 agent。
4.2 临时启动 agent 并加载 key(本次会话有效)
1 2 3
| eval "$(ssh-agent -s)" ssh-add ~/.ssh/github_cad ssh-add -l
|
ssh-add -l 能看到你的 key(如 github_cad)才算加载成功。
4.3(可选)让 agent 更“自动”(systemd 用户)
1
| systemctl --user enable --now ssh-agent
|
在 ~/.bashrc 或 ~/.zshrc 增加:
1
| export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent.socket"
|
然后重新开终端,执行一次:
1
| ssh-add ~/.ssh/github_cad
|
5. 常见问题对照表(看到症状就知道该干啥)
5.1 明明已经把公钥加到 GitHub,还是 denied
✅ 做:
ssh -vT git@github.com 看它到底尝试了哪把 key
- 用
~/.ssh/config 强制 IdentityFile + IdentitiesOnly yes
- 检查权限:
chmod 700 ~/.ssh && chmod 600 ~/.ssh/config ~/.ssh/<private_key>
可能原因:
- 认证到的是另一个 GitHub 账号(没仓库权限)
- 仓库在组织下,可能需要 SSO 授权(网页端提示)
✅ 做:
- 先看
ssh -T 输出的用户名是不是你预期的
- 确认仓库权限/组织授权
5.3 本机有很多 key,SSH 乱试导致失败
✅ 做:
~/.ssh/config 加 IdentitiesOnly yes
- 明确指定
IdentityFile
6. Git 操作:只同步远端更新(不用重新克隆)
6.1 正常拉取
1 2
| git switch main git pull
|
6.2 本地没有要保留的改动,强制对齐远端
1 2 3
| git fetch origin git switch main git reset --hard origin/main
|
(可选)清理未跟踪文件(谨慎,会删)
7. 如何检测 SSH “管道/隧道”(端口转发)是否连通(额外常用)
场景:服务器服务只监听 127.0.0.1:8008,外部访问不到,用 SSH 隧道从本地转发。
7.1 在本地开启隧道(本地 8008 → 服务器 127.0.0.1:8008)
1
| ssh -N -L 8008:127.0.0.1:8008 user@<server_ip>
|
7.2 新开终端验证隧道是否通
1
| curl -v http://127.0.0.1:8008/
|
7.3 确认本地 8008 监听者是谁(避免“连到自己本机服务”)
看到 ssh 在监听才对。
7.4 本地端口冲突,换端口
1 2
| ssh -N -L 18008:127.0.0.1:8008 user@<server_ip> curl -v http://127.0.0.1:18008/
|
8. 最终自检清单(从上到下跑一遍就能修)
- 远端是 SSH 吗?
- SSH 能认证 GitHub 吗?
- 失败就看详细日志(看它尝试哪把 key):
- 强制指定 key(config):
1 2 3
| nano ~/.ssh/config
chmod 600 ~/.ssh/config
|
- 必要时启用 agent 并加载 key:
1 2 3
| eval "$(ssh-agent -s)" ssh-add ~/.ssh/<your_key> ssh-add -l
|
- 再试:
1 2
| ssh -T git@github.com git pull
|
9. 常用命令速记
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| ssh -T git@github.com ssh -vT git@github.com
ls -la ~/.ssh chmod 700 ~/.ssh chmod 600 ~/.ssh/config ~/.ssh/<private_key> chmod 644 ~/.ssh/<public_key>.pub
eval "$(ssh-agent -s)" ssh-add ~/.ssh/<private_key> ssh-add -l
git remote -v
|
1
| ::contentReference[oaicite:0]{index=0}
|