新装一台机器——开发机也好、服务器也好——想 clone、pull、push 你的 GitHub 仓库时,常会卡在认证。先理清什么时候需要认证

  • 只读 clone 公开仓库 → 不用认证,直接拉;
  • 访问私有仓库(clone / pull / push) → 要认证;
  • 向任何仓库 push(哪怕是公开仓库) → 也要认证。

也就是说,除了「拉公开仓库」,机器要对仓库做任何带权限的操作都得先有「身份」。配一次,之后这台机器就能正常 clone / pull / push 了。

主线:身份有两条路——SSH 密钥Token(PAT),区别在于「这把钥匙能开多少扇门、能干什么」。

原理:公钥私钥怎么验证身份

下面两种 SSH 方式都基于一对密钥,先把它怎么验证身份说清楚:

  • 私钥:留在你机器上(~/.ssh/ 里),绝不外传
  • 公钥:可以公开,交给 GitHub 登记。

它们是「非对称」的——用私钥算出的签名,只有配对的公钥能验证;而从公钥推不出私钥。验证流程大致是:

  1. 你事先把公钥登记到 GitHub(账号的 SSH keys,或仓库的 Deploy keys);
  2. 连接时你的机器发起 SSH,表示「我持有某公钥对应的私钥」;
  3. GitHub 用登记的公钥出一道随机「考题」(challenge);
  4. 你的机器用私钥对考题签名,把结果发回;
  5. GitHub 用公钥验证这个签名——验得过,就证明你确实握有配对的私钥,身份成立,放行。
你的机器                              GitHub
   │  ① 我持有某公钥对应的私钥           │
   │ ───────────────────────────────▶ │
   │            ② 随机考题 challenge    │
   │ ◀─────────────────────────────── │
   │  ③ 用「私钥」签名考题,发回         │
   │ ───────────────────────────────▶ │
   │       ④ 用登记的「公钥」验签 → 放行 │

关键点:私钥从头到尾没离开过你的机器,网络上传的只是「用私钥算出的证明」。所以即使全程被监听,也偷不到私钥——这就是为什么公钥能随便公开、私钥必须保密。

方式一:SSH 密钥(账号级,最通用)

一把绑在你 GitHub 账号上的密钥,你名下所有仓库、clone / pull / push 全都能用,适合你自己常用的开发机。

① 生成密钥(一路回车即可):

ssh-keygen -t ed25519 -C "my-laptop"

它会问你保存路径(回车用默认 ~/.ssh/id_ed25519)和密码(回车 = 不设)。生成两个文件:id_ed25519私钥,保密)和 id_ed25519.pub公钥)。

  • -t ed25519:密钥类型,比老的 RSA 更短更安全,现在的推荐;
  • -C "my-laptop":一段注释/标签,纯粹方便日后辨认,不影响功能。

② 把公钥加到账号

cat ~/.ssh/id_ed25519.pub      # 复制这串

GitHub → Settings → SSH and GPG keys → New SSH key → 粘贴。

③ 用 SSH 地址操作(默认名字的密钥 SSH 会自动使用,无需额外配置):

git clone [email protected]:ldddi/your-repo.git
ssh -T [email protected]          # 验证:看到 "Hi ldddi!" 就通了
  • 优点:配一次,覆盖你所有仓库所有操作
  • 缺点:权限大——机器一旦失守,你所有仓库都暴露。所以服务器上更适合下面的只读 Deploy Key

方式二:Deploy Key(只绑单个仓库,服务器/CI 首选)

一把只对一个仓库生效、还能设成只读的 SSH 密钥。适合 VPS 拉某个项目来部署——权限最小,机器被攻破也只影响这一个仓库的读取。

① 在那台机器上生成(同样一路回车):

ssh-keygen -t ed25519 -C "deploy-my-blog"

② 公钥加到「仓库」(不是账号):GitHub → 进入该仓库 → Settings → Deploy keys → Add deploy key → 粘贴 ~/.ssh/id_ed25519.pub。只是拉代码就别勾 “Allow write access”(保持只读最安全)。

③ 用 SSH 地址 clone / 切换远程

git clone [email protected]:ldddi/my-blog.git
# 之前用 https clone 过的,改成 SSH:
git remote set-url origin [email protected]:ldddi/my-blog.git

进阶:一台机器要拉多个私有仓库

一把 Deploy Key 只能绑一个仓库,而默认名字 id_ed25519 一台机器只有一份。所以多个仓库时,要给每个仓库单独生成一把、用 -f 指定不同文件名

ssh-keygen -t ed25519 -C "deploy-blog"  -f ~/.ssh/key-blog  -N ""
ssh-keygen -t ed25519 -C "deploy-repoA" -f ~/.ssh/key-repoA -N ""

(这里 -f 指定文件名、-N "" 设空密码,正是为了区分多把 key、且免交互。)

但自定义名字的 key,SSH 默认不会主动去用(它只认 id_ed25519 这类默认名)。所以要在这台机器上(不是 GitHub)编辑 ~/.ssh/config,告诉它「连哪个仓库用哪把 key」:

# 文件在拉代码的机器上:~/.ssh/config
Host github-blog                      # 自定义别名,随便起
    HostName github.com
    User git
    IdentityFile ~/.ssh/key-blog      # 这个别名用这把私钥
    IdentitiesOnly yes

Host github-repoA
    HostName github.com
    User git
    IdentityFile ~/.ssh/key-repoA
    IdentitiesOnly yes
  • Host github-blog:一个别名——因为两个仓库都在 github.com,靠别名区分该用哪把 key;
  • HostName / User git:实际连的还是 github.com、用户名固定 git
  • IdentityFile:这个别名用哪把私钥;
  • IdentitiesOnly yes:只用这把,别去试机器上其它 key(避免连错/被拒)。

clone 时把地址里的 github.com 换成你的别名

git clone git@github-blog:ldddi/my-blog.git     # 注意是 github-blog 不是 github.com

单仓库时用默认名字 id_ed25519 即可,SSH 自动会用,不用折腾这个 config

方式三:Personal Access Token(PAT,走 HTTPS)

不想用 SSH、或在 CI 里跑,就用 Token 走 HTTPS:

  1. GitHub → Settings → Developer settings → Fine-grained token,限定到指定仓库 + 给所需权限(只拉给 Contents: Read,要推送给 Read and write);
  2. clone:
git clone https://<TOKEN>@github.com/ldddi/your-repo.git
  • 优点:权限可细到「某仓库只读」;适合 CI、纯 HTTPS 环境;
  • 缺点:Token 会过期,要妥善保存、定期轮换。

怎么选

方式能访问能干什么适合
账号 SSH 密钥所有仓库clone / pull / push自己的开发机
Deploy Key单个仓库默认只读(可开写)服务器 / CI 拉单个仓库
PAT(HTTPS)可细粒度限定按授予的权限CI、HTTPS 环境

小结

  • 只读拉公开仓库不用认证;私有仓库、以及任何 push 都要
  • 自己的开发机 → 账号 SSH 密钥,一次配好、全仓库全操作通吃;
  • 服务器拉单个仓库部署 → 只读 Deploy Key,权限最小、最安全;
  • CI / HTTPS 环境 → PAT。