GIT使用SSH 多账户配置

GIT使用SSH 多账户配置

问题场景

需要同时使用:

  • GitHub
  • Gitee 码云

要求:零破坏性,完全隔离


核心原理

数据结构:

复制代码
SSH 密钥对 ←→ SSH Config 路由规则 ←→ Git 远程仓库

路由逻辑:

  • SSH 根据目标主机(github.com / gitee.com)自动选择对应密钥
  • Git 命令无需任何修改,完全透明

操作步骤

1. 生成 Gitee/GitHub 专用密钥

bash 复制代码
ssh-keygen -t rsa -b 4096 -C "11956111@qq.com" -f ~/.ssh/id_rsa_gitee -N ""

参数说明:

  • -t rsa -b 4096:RSA 算法,4096 位强度
  • -C:注释(通常填邮箱)
  • -f:指定文件名(避免覆盖现有密钥)
  • -N "":空密码(可选,视安全需求)

输出:

  • 私钥:~/.ssh/id_rsa_gitee
  • 公钥:~/.ssh/id_rsa_gitee.pub

2. 创建 SSH Config 配置

bash 复制代码
cat > ~/.ssh/config << 'EOF'
# gitbub
Host gitbub.com
    HostName gitbub.com
    User git
    IdentityFile ~/.ssh/id_rsa
    IdentitiesOnly yes

# Gitee 码云(个人账户)
Host gitee.com
    HostName gitee.com
    User git
    IdentityFile ~/.ssh/id_rsa_gitee
    IdentitiesOnly yes
EOF

关键配置项:

  • Host:匹配规则(对应 git@gitbub.comgit@gitee.com 中的主机部分)
  • HostName:实际连接的主机地址(IP 或域名)
  • IdentityFile:指定使用的私钥
  • IdentitiesOnly yes只使用指定密钥(防止 SSH 尝试所有密钥)

注意:

  • Gitee 使用域名,Host 写域名

3. 设置正确权限

bash 复制代码
chmod 600 ~/.ssh/id_rsa_gitee ~/.ssh/config

为什么:

  • SSH 要求私钥和配置文件必须是 600 权限(仅所有者可读写)
  • 否则 SSH 会拒绝使用,报 permissions are too open 错误

4. 添加主机密钥(可选但推荐)

bash 复制代码
ssh-keyscan gitbub.com >> ~/.ssh/known_hosts 2>/dev/null
ssh-keyscan gitee.com >> ~/.ssh/known_hosts 2>/dev/null

作用:

  • 避免首次连接时的 Host key verification failed 错误
  • 相当于预先信任这些主机

注意:

  • 公司内网服务器可能无法通过 ssh-keyscan 扫描,首次连接时手动确认即可

5. 添加公钥到 Gitee

5.1 查看公钥
bash 复制代码
cat ~/.ssh/id_rsa_gitee.pub
5.2 添加到 Gitee
  1. 访问:https://gitee.com/profile/sshkeys
  2. 点击 "添加公钥"
  3. 标题Linux 工作站(或任意标识)
  4. 公钥 :粘贴公钥全部内容(包括 ssh-rsa 开头到邮箱结尾)
  5. 点击 "确定"

6. 测试连接

bash 复制代码
# 测试 Gitee
ssh -T git@gitee.com

预期输出:

复制代码
Hi [你的用户名]! You've successfully authenticated, but GITEE.COM does not provide shell access.
bash 复制代码
# 测试公司 GitLab(验证现有配置未被破坏)
ssh -T git@gitbub.com

预期输出:

复制代码
Welcome to GitLab, @[你的用户名]!

如果gitbub测试失败:


日常使用

完全透明,无需任何特殊操作

bash 复制代码
# Gitee 仓库
git clone git@gitee.com:username/repo.git
cd repo
git add .
git commit -m "update"
git push origin master

# 公司 GitLab 仓库
git clone git@gitbub.com:username/repo.git
cd repo
git add .
git commit -m "fix: 修复bug"
git push origin master

SSH 自动根据主机地址选择密钥,零心智负担。


故障排查

问题 1:Permission denied (publickey)

原因:

  • 公钥未添加到远程平台
  • SSH Config 配置错误

排查:

bash 复制代码
# 查看 SSH 详细日志
ssh -vT git@gitee.com

# 检查 config 语法
cat ~/.ssh/config

# 验证密钥权限
ls -l ~/.ssh/id_rsa_gitee

问题 2:Bad owner or permissions on ~/.ssh/config

原因:

  • 配置文件权限不对

修复:

bash 复制代码
chmod 600 ~/.ssh/config

问题 3:仍然使用错误的密钥

原因:

  • IdentitiesOnly yes 未配置
  • SSH Agent 缓存了其他密钥

修复:

bash 复制代码
# 清空 SSH Agent
ssh-add -D

# 确认 config 中有 IdentitiesOnly yes
grep -A4 "Host gitee.com" ~/.ssh/config

最佳实践

1. 密钥命名规范

复制代码
~/.ssh/id_rsa                 # 公司 GitLab(已有)
~/.ssh/id_rsa_gitee           # Gitee 码云
~/.ssh/id_rsa_github          # GitHub(如果需要)
~/.ssh/id_rsa_company_vpn     # 公司 VPN

原则:

  • 文件名清晰表达用途
  • 已有的默认密钥 id_rsa 保持不动(向后兼容)
  • 新密钥用描述性名称

2. 配置文件组织

bash 复制代码
# ~/.ssh/config

# ============================================
# 工作相关
# ============================================
Host 10.xx.xx.xx 
    HostName 10.xx.xx.xx
    User git
    IdentityFile ~/.ssh/id_rsa
    IdentitiesOnly yes

# ============================================
# 个人开发
# ============================================
Host gitee.com
    HostName gitee.com
    User git
    IdentityFile ~/.ssh/id_rsa_gitee
    IdentitiesOnly yes

# ============================================
# 服务器跳板机(示例)
# ============================================
Host jumpserver
    HostName jump.company.com
    User your_username
    IdentityFile ~/.ssh/id_rsa_server
    Port 2222

原则:

  • 分组注释
  • 相关配置放一起
  • 复杂配置写注释

3. 安全建议

密钥保护:

bash 复制代码
# 生产环境密钥必须设置密码
ssh-keygen -t rsa -b 4096 -C "email@example.com" -f ~/.ssh/id_rsa_production

# 使用 SSH Agent 避免重复输入密码
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_rsa_production

定期轮换:

  • 生产环境密钥每 6-12 个月更换一次
  • 离职/设备丢失立即吊销对应公钥

备份:

bash 复制代码
# 备份私钥到加密存储(如 KeePassXC、1Password)
# 永远不要把私钥提交到 Git 仓库

核心思想

为什么这样设计?

  1. 好品味:无特殊情况

    • 所有远程仓库走统一路由规则
    • 无需在 Git 命令里指定密钥参数
  2. 零破坏性:向后兼容

    • 现有配置完全不动
    • 只添加新规则,不修改旧规则
  3. 最简实现:SSH 原生功能

    • 无需任何第三方工具
    • 无需 ssh-add 动态管理
    • 无需环境变量或 shell 脚本
  4. 数据分离:最小权限原则

    • 每个密钥职责单一
    • GitLab 密钥无法访问 GitHub(反之亦然)

典型错误(不要这么干):

  • ❌ 一个密钥给所有平台(安全风险,密钥泄露影响范围大)
  • ❌ 用 GIT_SSH_COMMAND 环境变量(每次都要设置,复杂且易错)
  • ❌ 在 .gitconfig 里硬编码密钥路径(不同仓库需要不同配置)

特殊说明:IP 地址作为 Host

为什么公司 GitLab 配置中 Host 和 HostName 都是 IP?

bash 复制代码
Host 10.xx.xx.xx        # 匹配规则
    HostName 10.xx.xx.xx   # 实际连接地址

原理:

  • Git URL 是 git@10.xx.xx.xx:cd/oneos/oneos-one.git
  • SSH 提取主机部分 10.xx.xx.xx
  • 在 config 中查找 Host 10.xx.xx.xx
  • 匹配成功,使用对应的 IdentityFile

等价于域名配置:

bash 复制代码
# 域名示例
Host gitlab.example.com
    HostName gitlab.example.com
    
# IP 示例  
Host 10.xx.xx.xx
    HostName 10.xx.xx.xx

两者完全一样的逻辑,只是一个用域名,一个用 IP。


参考文档


最后一句话总结:

好的配置应该是透明的。用户不需要知道它的存在,它就能正确工作。

--- 这就是 "好品味" 的体现。

相关推荐
程序猿小三7 小时前
Linux下基于关键词文件搜索
linux·运维·服务器
虚拟指尖8 小时前
Ubuntu编译安装COLMAP【实测编译成功】
linux·运维·ubuntu
椎4959 小时前
苍穹外卖前端nginx错误之一解决
运维·前端·nginx
刘某的Cloud9 小时前
parted磁盘管理
linux·运维·系统·parted
极验9 小时前
iPhone17实体卡槽消失?eSIM 普及下的安全挑战与应对
大数据·运维·安全
爱倒腾的老唐9 小时前
24、Linux 路由管理
linux·运维·网络
yannan201903139 小时前
Docker容器
运维·docker·容器
_清浅9 小时前
计算机网络【第六章-应用层】
运维·服务器·计算机网络
正在努力的小河9 小时前
Linux 自带的 LED 灯驱动实验
linux·运维·服务器