跳转至

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

  • Titlelinuxdc-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/configIdentityFile 路径正确
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 实践任务

  1. ops 用户身份安装 Git,完成全局配置(用户名、邮箱、默认分支 main、编辑器 vim)。
  2. 生成 ed25519 密钥对,配置 ~/.ssh/config,将公钥添加到 GitHub,验证:

    ssh -T git@github.com
    
  3. 在 GitHub 创建仓库 linuxdc-ops,本地初始化并推送首次提交。

  4. 创建功能分支 feature/add-docs,提交一个变更,合并回 main 并推送,删除功能分支。
  5. 创建 ~/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/configIdentitiesOnly yes 的作用是什么,何时必须设置?

IdentitiesOnly yes 强制 SSH 客户端只使用 IdentityFile 明确指定的密钥进行认证,不尝试 ~/.ssh/ 目录下的其他默认密钥(如 id_rsaid_ed25519),也不使用 ssh-agent 中托管的其他密钥。在同一台机器配置了多个 GitHub 账户(如个人账户和公司账户,各自对应不同密钥)时,必须设置此参数,确保连接特定 Host 时使用正确的密钥,避免因尝试错误密钥导致认证失败或账户混淆。


30.11 章节总结

本章完成了 Git 与 GitHub 的完整配置:ed25519 SSH 密钥生成与 GitHub 集成(含 ~/.ssh/config 精准配置)、两种常见场景(新环境上传 / 换设备继续开发)、日常工作流(约定式提交格式、功能分支管理)、自动化推送脚本,以及多设备密钥管理规范与旧设备安全清理流程。规范的 Git 使用习惯是 Infrastructure as Code 和团队协作的重要基础。