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。


参考文档


最后一句话总结:

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

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

相关推荐
是专家不是砖家4 小时前
linux USB摄像头不停掉线问题
linux·运维·服务器
yuanManGan4 小时前
走进Linux的世界:初识进程(Task)
linux·运维·服务器
小马哥编程4 小时前
【软考架构】案例分析-瘦客户端C/S架构
运维·服务器·架构
老黄编程4 小时前
09-ubuntu20.04 执行 apt update时报错,是因为官网已停止维护不再更新的缘故吗?
linux·运维·服务器·ubuntu·数字证书
Supernova_Jun4 小时前
ffmpeg图片转视频
linux·运维·服务器
脑子不好的小菜鸟4 小时前
用vscode连接远端ubuntu无法git push,vscode无法连接centos
git·vscode·ubuntu·centos
水月wwww4 小时前
ubuntu网络连接出错解决办法
linux·运维·计算机网络·ubuntu·操作系统·ubuntu网络连接
0wioiw04 小时前
Ubuntu(①shell脚本)
linux·运维·ubuntu
illuspas4 小时前
AMD MI50 在Ubuntu 24.04下安装驱动和ROCm
linux·运维·ubuntu
HIT_Weston4 小时前
19、【Ubuntu】【远程开发】技术方案分析:远程桌面
linux·运维·ubuntu