#!/bin/bash # 给 codexsvc 配一只读 deploy key(按仓库通用化,控制面不存凭证)。 # # 用法(主机上以 root 跑): # ./provision_codexsvc_key.sh git@github.com:ORG/REPO.git [key-name] # ./provision_codexsvc_key.sh --check git@github.com:ORG/REPO.git [key-name] # ./provision_codexsvc_key.sh --list # # 流程: # 1. 在 /home/codexsvc/.ssh/ 生成 ed25519 key(已存在则复用,绝不覆盖); # 2. 打印公钥(只打印公钥,私钥绝不打印),请把公钥以只读 deploy key # 加到 GitHub 仓库 Settings -> Deploy keys; # 3. 在 /home/codexsvc/.ssh/config 里幂等地写一个 Host 别名 # github-(HostName github.com、该 key、IdentitiesOnly): # 多仓各用各的别名,项目 repo_url 写 git@github-:ORG/REPO.git # 形,git 按别名自动选 key,不用在 worker 里拼 GIT_SSH_COMMAND, # 也不用担心 ssh 试遍全部 key 撞 GitHub 的尝试上限; # 别名块带 # codexsvc- 标记,已存在时不重复写。 # 4. --check 时以 codexsvc 身份跑 git ls-remote,通了才算配好。 # 5. 另有现成的 key 要复用时,把 key 文件拷到上述目录并 chown # codexsvc、chmod 600,再用 --check 验,不要改本脚本去读 root 的 key。 # # 安全边界:本脚本不往控制面、环境文件或任何日志里写私钥;公钥 # 本来就是公开的,打印它没有风险;key 名只允许 [A-Za-z0-9_-]。 set -eu CHECK=0 if [ "${1:-}" = "--check" ]; then CHECK=1; shift fi if [ "${1:-}" = "--list" ]; then ls -1 /home/codexsvc/.ssh/id_*.pub 2>/dev/null || true grep -h "^Host github-" /home/codexsvc/.ssh/config 2>/dev/null || true exit 0 fi URL="${1:-}" NAME="${2:-codex-github}" if [ -z "$URL" ]; then echo "用法: $0 [--check] git@github.com:ORG/REPO.git [key-name]" >&2 exit 2 fi case "$URL" in git@github.com:*:*.git) ;; *) echo "只接受 git@github.com:ORG/REPO.git 形(https 形在本机常被出口策略挡)" >&2; exit 2 ;; esac case "$NAME" in *[!A-Za-z0-9_-]*) echo "key 名只允许字母数字 _ -" >&2; exit 2 ;; esac SSH_DIR=/home/codexsvc/.ssh KEY="$SSH_DIR/id_$NAME" mkdir -p "$SSH_DIR" chown codexsvc:codexsvc "$SSH_DIR" chmod 700 "$SSH_DIR" if [ ! -f "$KEY" ]; then sudo -u codexsvc ssh-keygen -t ed25519 -f "$KEY" -N "" -C "codexsvc-$NAME" chmod 600 "$KEY" chown codexsvc:codexsvc "$KEY" fi chmod 600 "$KEY" 2>/dev/null || true chown codexsvc:codexsvc "$KEY" "$KEY.pub" 2>/dev/null || true CONFIG="$SSH_DIR/config" touch "$CONFIG" chown codexsvc:codexsvc "$CONFIG" chmod 600 "$CONFIG" if ! grep -q "^# codexsvc-$NAME$" "$CONFIG" 2>/dev/null; then cat >> "$CONFIG" <