30. GitHub 项目配置与密钥管理
本章介绍在 RHEL 9 上配置 Git 与 GitHub 的完整流程,覆盖两种最常见场景:在新环境中配置并上传新项目,以及更换设备后继续开发已有项目。同时提供多设备密钥管理规范、自动化推送脚本和安全清理旧设备的操作步骤。
30.1 前提条件
- 通过 SecureCRT(SSH 端口 2222)以
ops用户、密钥认证方式登录192.168.1.100。 - GitHub 账户已注册。
执行权限说明
Git 操作应以普通用户 ops 身份执行(不使用 root),代码仓库属于用户级资源,不应由 root 账户管理。本章所有命令均以 ops 用户身份运行。
30.2 安装与全局配置
# 以 ops 用户身份操作(不切换 root)
sudo dnf install -y git
git --version
# 配置全局身份信息(写入 ~/.gitconfig)
git config --global user.name "Your Name"
git config --global user.email "your_email@example.com"
# 设置默认主分支为 main(与 GitHub 保持一致)
git config --global init.defaultBranch main
# 设置默认编辑器
git config --global core.editor vim
# Linux 服务器推荐的换行符处理方式
git config --global core.autocrlf input
# 验证配置
git config --list
30.3 场景一:新环境配置并上传新项目
30.3.1 生成 SSH 密钥对
# 生成专用于 GitHub 的 ed25519 密钥(推荐算法,安全且密钥短)
ssh-keygen -t ed25519 \
-C "ops@linuxdc-$(date +%Y%m%d)" \
-f ~/.ssh/id_ed25519_github
# 设置私钥严格权限(SSH 要求私钥权限不超过 600)
chmod 600 ~/.ssh/id_ed25519_github
chmod 644 ~/.ssh/id_ed25519_github.pub
30.3.2 配置 SSH config 文件
tee -a ~/.ssh/config << 'EOF'
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_github
IdentitiesOnly yes
EOF
chmod 600 ~/.ssh/config
30.3.3 将公钥添加到 GitHub
# 查看并复制公钥内容
cat ~/.ssh/id_ed25519_github.pub
在 GitHub 网页端操作:Settings → SSH and GPG keys → New SSH key
- Title:
linuxdc-ops-2025(清晰标注设备名称,便于管理) - Key type:Authentication Key
- Key:粘贴公钥全部内容
30.3.4 验证 SSH 连接
ssh -T git@github.com
# 成功输出:Hi <username>! You've successfully authenticated, but GitHub does not provide shell access.
检查点
ssh -T git@github.com 显示认证成功,无需输入密码。
30.3.5 创建并推送新项目
# 在 GitHub 网页端先创建空仓库 linuxdc-ops,然后在本地:
mkdir ~/linuxdc-ops && cd ~/linuxdc-ops
git init
tee README.md << 'EOF'
# linuxdc-ops
企业级 Linux 运维配置管理项目
## 环境信息
- OS: Red Hat Enterprise Linux 9
- 主机: linuxdc (192.168.1.100)
- SSH 端口: 2222
EOF
git add README.md
git commit -m "feat: initial commit"
git remote add origin git@github.com:<your-username>/linuxdc-ops.git
git branch -M main
git push -u origin main
30.4 场景二:换设备后继续开发已有项目
# 前提:已完成 30.3.1–30.3.3 的密钥配置
# 克隆已有仓库
git clone git@github.com:<your-username>/linuxdc-ops.git
cd linuxdc-ops
# 查看远程仓库配置
git remote -v
# 拉取最新代码(确保与远程同步)
git pull origin main
30.5 日常 Git 工作流
30.5.1 标准提交流程
# 查看工作区状态
git status
# 暂存变更(选择性暂存)
git add . # 暂存所有变更
git add ansible-playbooks/ # 暂存特定目录
# 提交(使用约定式提交格式,便于生成 CHANGELOG)
git commit -m "feat: add nginx config template"
git commit -m "fix: correct sshd port in ansible playbook"
git commit -m "docs: update README with deployment steps"
git commit -m "chore: clean up temporary scripts"
# 推送到远程仓库
git push origin main
30.5.2 分支管理
# 创建功能分支(从 main 分出)
git checkout -b feature/add-monitoring
# 开发完成后,切回 main 并合并
git checkout main
git merge feature/add-monitoring
# 删除已合并的本地和远程分支
git branch -d feature/add-monitoring
git push origin --delete feature/add-monitoring
30.5.3 自动化推送脚本
mkdir -p ~/bin
tee ~/bin/git-push.sh << 'SCRIPT'
#!/usr/bin/env bash
set -euo pipefail
if [[ $# -lt 1 ]]; then
echo "用法: $0 <提交信息>"
echo "示例: $0 'fix: correct nginx config'"
exit 1
fi
COMMIT_MSG="$1"
BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null || echo "main")
# 确认当前在 Git 仓库中
git rev-parse --git-dir > /dev/null 2>&1 || {
echo "错误: 当前目录 $(pwd) 不是 Git 仓库"
exit 1
}
git add .
git commit -m "${COMMIT_MSG}"
git push origin "${BRANCH}"
echo "已成功推送到 origin/${BRANCH}"
SCRIPT
chmod +x ~/bin/git-push.sh
# 将 ~/bin 加入 PATH(若未添加)
grep -q 'export PATH="$HOME/bin:$PATH"' ~/.bashrc || \
echo 'export PATH="$HOME/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
# 使用示例
cd ~/linuxdc-ops
git-push.sh "docs: add deployment guide"
30.6 密钥管理规范
30.6.1 多设备密钥策略
每台设备应使用独立的 SSH 密钥对,便于精准吊销单台设备的访问权限:
设备一(linuxdc 服务器):
私钥:~/.ssh/id_ed25519_github
GitHub 标题:linuxdc-ops-2025
设备二(开发笔记本):
私钥:~/.ssh/id_ed25519_github_laptop
GitHub 标题:laptop-dev-2025
在 GitHub 的 SSH Keys 页面,每个密钥清晰标注对应设备,便于随时识别和管理。
30.6.2 旧设备安全清理
旧设备报废、丢失或不再使用时,立即执行以下操作:
# 第一步:在 GitHub 上删除旧设备的 SSH 密钥
# GitHub → Settings → SSH and GPG keys → 找到旧密钥 → Delete
# 第二步:在旧设备本地安全删除私钥(若仍有操作权限)
shred -u ~/.ssh/id_ed25519_github
shred -u ~/.ssh/id_ed25519_github.pub
# 第三步:验证旧密钥已无法访问 GitHub
ssh -T git@github.com -i /path/to/old-key # 应提示认证失败
30.6.3 Personal Access Token(PAT)管理
HTTPS 方式克隆时使用 PAT 代替密码(SSH 方式更推荐):
# 配置凭证存储,避免每次输入
git config --global credential.helper store
# PAT 安全使用原则:
# - 设置最小权限范围(仅 repo 读写,不授予 admin 权限)
# - 设置过期时间(建议 90 天或更短)
# - 不同用途使用不同 PAT(运维自动化、个人开发分离)
# - 旧 PAT 立即撤销:
# GitHub → Settings → Developer settings → Personal access tokens → Revoke
30.7 常用命令速查表
| 功能 | 命令 |
|---|---|
| 查看工作区状态 | git status |
| 暂存所有变更 | git add . |
| 提交变更 | git commit -m "message" |
| 推送到远程 | git push origin main |
| 拉取最新代码 | git pull origin main |
| 查看提交历史(图形) | git log --oneline --graph --all |
| 创建并切换分支 | git checkout -b feature/name |
| 切换分支 | git switch main |
| 合并分支 | git merge feature/name |
| 撤销暂存 | git restore --staged <file> |
| 丢弃工作区修改 | git restore <file> |
| 撤销最近提交(保留变更) | git reset HEAD^ |
| 安全撤销已推送提交 | git revert HEAD |
| 查看远程仓库配置 | git remote -v |
| 打标签并推送 | git tag v1.0.0 && git push origin v1.0.0 |
| 查看分支列表(含远程) | git branch -a |
30.8 常见问题与排查
| 问题现象 | 排查步骤 |
|---|---|
Permission denied (publickey) |
ssh -vT git@github.com 查看详细握手过程;确认公钥已添加到 GitHub;检查 ~/.ssh/config 中 IdentityFile 路径正确 |
refusing to merge unrelated histories |
首次合并不相关历史时:git pull origin main --allow-unrelated-histories |
| 推送被拒绝(non-fast-forward) | 先同步远程:git pull --rebase origin main,解决冲突后再推送 |
| 提交信息写错(未推送) | git commit --amend -m "正确的提交信息" |
| 提交信息写错(已推送) | 使用 git revert 创建新提交撤销,不要 --force 推送已共享的历史 |
30.9 实践任务
- 以
ops用户身份安装 Git,完成全局配置(用户名、邮箱、默认分支 main、编辑器 vim)。 -
生成 ed25519 密钥对,配置
~/.ssh/config,将公钥添加到 GitHub,验证:ssh -T git@github.com -
在 GitHub 创建仓库
linuxdc-ops,本地初始化并推送首次提交。 - 创建功能分支
feature/add-docs,提交一个变更,合并回 main 并推送,删除功能分支。 - 创建
~/bin/git-push.sh脚本,添加到 PATH,在仓库内测试一键提交推送功能。
30.10 自测问题
Q1:为什么每台设备应使用独立的 SSH 密钥,而不是将同一私钥复制到多台设备?
独立密钥使每台设备拥有唯一身份标识。当某台设备丢失、被盗或报废时,可以精准地只吊销该设备在 GitHub 上的 SSH 密钥,其他设备不受影响、无需任何操作。若多设备共用同一私钥,吊销时所有设备同时失去访问权,且无法从 GitHub 审计日志中追溯是哪台具体设备的操作,违反了最小权限和可追溯性原则。
Q2:git reset HEAD^ 和 git revert HEAD 有什么本质区别,各自的适用场景是什么?
git reset HEAD^ 撤销最近一次提交,将变更退回暂存区或工作区,不产生新提交,会重写提交历史。适用于尚未推送到远程的本地提交,严禁对已推送到共享分支的提交使用(会导致其他协作者历史不一致)。git revert HEAD 通过创建一个新提交来抵消上次提交的变更,完整保留原始历史记录,适合对已推送到共享分支的提交进行安全撤销,是团队协作环境中撤销变更的标准方式。
Q3:~/.ssh/config 中 IdentitiesOnly yes 的作用是什么,何时必须设置?
IdentitiesOnly yes 强制 SSH 客户端只使用 IdentityFile 明确指定的密钥进行认证,不尝试 ~/.ssh/ 目录下的其他默认密钥(如 id_rsa、id_ed25519),也不使用 ssh-agent 中托管的其他密钥。在同一台机器配置了多个 GitHub 账户(如个人账户和公司账户,各自对应不同密钥)时,必须设置此参数,确保连接特定 Host 时使用正确的密钥,避免因尝试错误密钥导致认证失败或账户混淆。
30.11 章节总结
本章完成了 Git 与 GitHub 的完整配置:ed25519 SSH 密钥生成与 GitHub 集成(含 ~/.ssh/config 精准配置)、两种常见场景(新环境上传 / 换设备继续开发)、日常工作流(约定式提交格式、功能分支管理)、自动化推送脚本,以及多设备密钥管理规范与旧设备安全清理流程。规范的 Git 使用习惯是 Infrastructure as Code 和团队协作的重要基础。