展示 SSH 密钥、多账号身份节点和仓库分支的科技风插画

GitHub SSH 多账号 Windows / macOS / Linux 更新于 2026-05-26

让每个仓库都走对身份

一台电脑同时维护个人、公司、客户账号时,真正稳定的方案不是反复切凭据,而是把 SSH 密钥、Host 别名、remote URL 和 Git 提交身份拆成清晰的路由层。

开始配置
1:1 每个 GitHub 账号对应一把独立 SSH 私钥
Host github-work 这样的别名选择认证账号
Repo 每个仓库单独配置提交作者和邮箱
git clone git@github-work:OWNER/REPO.git
git config user.email "[email protected]"
ssh -T git@github-work

核心原则:把身份问题拆成五层

多账号的关键不是“GitHub 账号切换”,而是让每次 SSH 连接都有明确入口,让每次 Git 提交都有明确作者。

SSH Identity Pipeline Keypair -> Host Alias -> Remote URL -> Repository Identity
keypair 独立私钥 id_ed25519_github_work
ssh config Host 别名 github-work
git remote 仓库地址 git@github-work:OWNER/REPO.git
只用 SSH 多账号场景里不要混用 HTTPS 凭据,否则凭据缓存会让排错变得混乱。
每号一密钥 GitHub 不允许同一把公钥绑定多个账号,独立密钥也是最清晰的隔离边界。
Host 显式选择账号 github-personalgithub-workgithub-client 指向同一个 github.com
remote URL 决定认证身份 还写 [email protected]:... 就会走默认账号;写别名才会走对应密钥。
Git 作者单独配置 SSH 只解决登录是谁,提交记录里的作者邮箱要靠仓库级 git config
启用 IdentitiesOnly 让 SSH 只尝试你指定的那把钥匙,减少 agent 里多把 key 时选错的概率。

命名先定好,后面就不乱

推荐把“账号用途”写进私钥名和 Host 名。命名越朴素,长期维护越稳定。

用途 私钥文件 SSH Host 克隆地址形态
个人账号 id_ed25519_github_personal github-personal git@github-personal:OWNER/REPO.git
工作账号 id_ed25519_github_work github-work git@github-work:OWNER/REPO.git
客户账号 id_ed25519_github_client github-client git@github-client:OWNER/REPO.git

示例邮箱请替换为对应 GitHub 账号邮箱。真实私钥口令不要写进脚本、笔记、教程或仓库,建议放进密码管理器。

Windows:用 PowerShell 建立多账号 SSH 路由

Windows 默认建议把密钥放在当前用户的 .ssh 目录。自定义目录也可以,但要把 IdentityFile 和权限一起处理好。

检查现有密钥 已有 id_ed25519 不要急着删,给新账号生成新密钥即可。
每个账号生成独立密钥 -f 后面写私钥文件路径,不需要加 .pub
启动 ssh-agent 并加载密钥 agent 负责记住私钥口令,避免每次 push 都重复输入。
配置 Host 别名并验证账号 ssh -T 返回的 USERNAME 必须是你期望的账号。

生成密钥

Get-ChildItem "$env:USERPROFILE\.ssh"
New-Item -ItemType Directory -Force "$env:USERPROFILE\.ssh"

ssh-keygen -t ed25519 -C "[email protected]" -f "$env:USERPROFILE\.ssh\id_ed25519_github_personal"
ssh-keygen -t ed25519 -C "[email protected]"     -f "$env:USERPROFILE\.ssh\id_ed25519_github_work"

如果你希望放在自定义目录,例如 D:\git-ssh

New-Item -ItemType Directory -Force "D:\git-ssh"

ssh-keygen -t ed25519 -C "[email protected]" -f "D:\git-ssh\id_ed25519_github_personal"
ssh-keygen -t ed25519 -C "[email protected]"     -f "D:\git-ssh\id_ed25519_github_work"

启动 agent,复制公钥

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

ssh-add "$env:USERPROFILE\.ssh\id_ed25519_github_personal"
ssh-add "$env:USERPROFILE\.ssh\id_ed25519_github_work"
ssh-add -l

Get-Content "$env:USERPROFILE\.ssh\id_ed25519_github_work.pub" | Set-Clipboard

然后进入对应 GitHub 账号:Settings -> SSH and GPG keys -> New SSH key。每个账号各贴自己的公钥。

写入 SSH config

New-Item -ItemType Directory -Force "$env:USERPROFILE\.ssh"
New-Item -ItemType File -Force "$env:USERPROFILE\.ssh\config"
notepad "$env:USERPROFILE\.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

自定义目录时,Windows 的 SSH config 建议使用正斜杠:

Host github-work
    HostName github.com
    User git
    IdentityFile D:/git-ssh/id_ed25519_github_work
    IdentitiesOnly yes

验证账号

ssh -T git@github-personal
ssh -T git@github-work

成功时会看到类似 Hi USERNAME! You've successfully authenticated, but GitHub does not provide shell access.。确认每个 Host 显示的是预期账号。

macOS:把密钥交给钥匙串

macOS 的重点是 AddKeysToAgent yesUseKeychain yes,让系统钥匙串保存私钥口令。

生成密钥

mkdir -p ~/.ssh
chmod 700 ~/.ssh

ssh-keygen -t ed25519 -C "[email protected]" -f ~/.ssh/id_ed25519_github_personal
ssh-keygen -t ed25519 -C "[email protected]"     -f ~/.ssh/id_ed25519_github_work

如果想放在 ~/git-ssh

mkdir -p ~/git-ssh
chmod 700 ~/git-ssh

ssh-keygen -t ed25519 -C "[email protected]" -f ~/git-ssh/id_ed25519_github_personal
ssh-keygen -t ed25519 -C "[email protected]"     -f ~/git-ssh/id_ed25519_github_work

保存口令并复制公钥

eval "$(ssh-agent -s)"
ssh-add --apple-use-keychain ~/.ssh/id_ed25519_github_personal
ssh-add --apple-use-keychain ~/.ssh/id_ed25519_github_work
ssh-add -l

pbcopy < ~/.ssh/id_ed25519_github_work.pub

旧系统如果不支持 --apple-use-keychain,可以尝试 ssh-add -K ~/.ssh/id_ed25519_github_work

推荐 config

test -f ~/.ssh/config && echo "config exists" || echo "config missing"
touch ~/.ssh/config
chmod 600 ~/.ssh/config
nano ~/.ssh/config
Host github-personal
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_github_personal
    IdentitiesOnly yes
    AddKeysToAgent yes
    UseKeychain yes

Host github-work
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_github_work
    IdentitiesOnly yes
    AddKeysToAgent yes
    UseKeychain yes
chmod 600 ~/.ssh/config
chmod 600 ~/.ssh/id_ed25519_github_*
chmod 644 ~/.ssh/*.pub

ssh -T git@github-personal
ssh -T git@github-work

Linux:权限是稳定性的底线

Linux 路线和 macOS 接近,但更要注意 ~/.ssh、私钥和 config 的权限。

生成密钥并添加到 agent

mkdir -p ~/.ssh
chmod 700 ~/.ssh

ssh-keygen -t ed25519 -C "[email protected]" -f ~/.ssh/id_ed25519_github_personal
ssh-keygen -t ed25519 -C "[email protected]"     -f ~/.ssh/id_ed25519_github_work

eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519_github_personal
ssh-add ~/.ssh/id_ed25519_github_work
ssh-add -l

自定义目录示例:

mkdir -p /data/git-ssh
chmod 700 /data/git-ssh

ssh-keygen -t ed25519 -C "[email protected]" -f /data/git-ssh/id_ed25519_github_work
ssh-add /data/git-ssh/id_ed25519_github_work

复制公钥和配置 Host

xclip -selection clipboard < ~/.ssh/id_ed25519_github_work.pub
# Wayland:
wl-copy < ~/.ssh/id_ed25519_github_work.pub
# 没有剪贴板工具:
cat ~/.ssh/id_ed25519_github_work.pub
Host github-personal
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_github_personal
    IdentitiesOnly yes
    AddKeysToAgent yes

Host github-work
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_github_work
    IdentitiesOnly yes
    AddKeysToAgent yes
chmod 700 ~/.ssh
chmod 600 ~/.ssh/config
chmod 600 ~/.ssh/id_ed25519_github_*
chmod 644 ~/.ssh/*.pub

ssh -T git@github-personal
ssh -T git@github-work

日常使用:看 remote,也看提交邮箱

认证账号和提交作者是两套系统。推送失败时检查 SSH;提交身份不对时检查 Git config。

用指定账号克隆 冒号前面的主机名必须是 ~/.ssh/config 里的 Host 别名。
仓库内设置作者 不要只依赖全局邮箱。工作仓库、客户仓库建议分别配置。
# 个人账号
git clone git@github-personal:OWNER/REPO.git

# 工作账号
git clone git@github-work:OWNER/REPO.git
git config user.name "Your Name"
git config user.email "[email protected]"

git config --get user.name
git config --get user.email

已有仓库改用另一个账号

git remote -v
git remote set-url origin git@github-work:OWNER/REPO.git
git fetch

确认当前仓库到底连到哪里

git remote -v
ssh -T git@github-work
git config --show-origin --get user.email

可选增强:按目录自动切换提交身份

如果个人项目和工作项目固定放在不同目录,可以让 Git 根据路径自动加载不同的作者信息。

[user]
    name = Personal Name
    email = [email protected]

[includeIf "gitdir:~/code/work/"]
    path = ~/.gitconfig-work
[user]
    name = Work Name
    email = [email protected]

Windows 也可以使用类似写法,路径建议用正斜杠:

[includeIf "gitdir:C:/Users/YourName/code/work/"]
    path = C:/Users/YourName/.gitconfig-work

includeIf 只负责提交作者身份,不负责 SSH 认证。SSH 认证仍然由 remote URL 里的 Host 别名决定。

第三个账号、自建 Git 服务,也是一套逻辑

新增账号时重复三件事:生成新私钥,把公钥加到对应账号,在 SSH config 新增 Host。

Host github-client
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_github_client
    IdentitiesOnly yes
git clone git@github-client:OWNER/REPO.git

如果使用公司或客户自建 Git 服务,Host 是本机别名,HostName 才是真实服务器域名。

Host client-git
    HostName ssh.example-git.net
    User git
    IdentityFile ~/.ssh/id_ed25519_client_git
    IdentitiesOnly yes

常见问题排查:先定位是哪一层错了

不要从头重配。先看错误信息,再判断是仓库路径、账号权限、密钥加载、Host 别名还是提交身份。

Repository not found 检查 OWNER/REPO 是否正确、私有仓库是否授权、remote 是否误用 github.com
Permission denied (publickey) 检查 ssh-add -l、公钥是否贴到正确账号、IdentityFile 路径是否存在。
仍然使用旧账号 大概率 remote URL 还是 [email protected]:OWNER/REPO.git,改成 Host 别名。
每次都要输入口令 Windows 看 ssh-agent,macOS 看钥匙串,Linux 看当前 shell 是否有 agent。
ssh-add -l
ssh -vT git@github-work
git remote -v
git config --show-origin --get user.email

Windows 私钥权限过宽

如果看到 UNPROTECTED PRIVATE KEY FILEBad permissions,说明私钥文件继承了过宽 ACL,OpenSSH 会忽略它。

$key = "E:\codeIDE\github-ssh-id_ed25519\id_ed25519_juice520"
icacls $key

如果出现 NT AUTHORITY\Authenticated UsersBUILTIN\UsersEveryone,可以收紧权限:

$key = "E:\codeIDE\github-ssh-id_ed25519\id_ed25519_juice520"
$me = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name

takeown /F $key
icacls $key /inheritance:r
icacls $key /remove:g "NT AUTHORITY\Authenticated Users" "BUILTIN\Users" "Everyone"
icacls $key /grant:r "$($me):(R)"
icacls $key

ssh-add "E:\codeIDE\github-ssh-id_ed25519\id_ed25519_juice520"

如果目录本身也继承了过宽权限,把目录一起收紧:

$dir = "E:\codeIDE\github-ssh-id_ed25519"
$me = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name

icacls $dir /inheritance:r
icacls $dir /remove:g "NT AUTHORITY\Authenticated Users" "BUILTIN\Users" "Everyone"
icacls $dir /grant:r "$($me):(OI)(CI)(F)"

最小可用清单

做到下面六点,多账号长期并存就会非常稳定。

  • 每个账号有独立私钥,例如 ~/.ssh/id_ed25519_github_work
  • GitHub 对应账号里添加了这把私钥的 .pub 公钥。
  • ~/.ssh/config 有独立 Host,例如 github-work
  • ssh -T git@github-work 显示正确 GitHub 用户名。
  • 仓库 remote 使用 git@github-work:OWNER/REPO.git
  • 仓库内 git config user.email 是该账号希望展示的提交邮箱。