feat(zhulan): add guarded Codex Remote SSH lane
This commit is contained in:
parent
ce92414f07
commit
3a950fe029
7 changed files with 551 additions and 1 deletions
|
|
@ -0,0 +1,154 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
if [[ "$(id -u)" -ne 0 ]]; then
|
||||
echo "INSTALL_REQUIRES_ROOT" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SOURCE_DIR="${1:-}"
|
||||
AUTHORIZED_KEY_FILE="${2:-}"
|
||||
if [[ -z "$SOURCE_DIR" || ! -f "$SOURCE_DIR/remote/zhulan_guard.py" ]]; then
|
||||
echo "SOURCE_DIR_INVALID" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ -z "$AUTHORIZED_KEY_FILE" || ! -s "$AUTHORIZED_KEY_FILE" ]]; then
|
||||
echo "AUTHORIZED_KEY_REQUIRED" >&2
|
||||
exit 1
|
||||
fi
|
||||
if grep -qvE '^ssh-ed25519 [A-Za-z0-9+/=]+( .*)?$' "$AUTHORIZED_KEY_FILE"; then
|
||||
echo "AUTHORIZED_KEY_INVALID" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
EXPECTED_HOST="${ZHULAN_EXPECTED_HOST:-VM-12-12-ubuntu}"
|
||||
EXPECTED_DMI="${ZHULAN_EXPECTED_DMI:-7a500f2d-9aed-4b93-b3b8-59c87c65d031}"
|
||||
ACTUAL_HOST="$(hostname)"
|
||||
ACTUAL_DMI="$(tr '[:upper:]' '[:lower:]' </sys/class/dmi/id/product_uuid)"
|
||||
if [[ "$ACTUAL_HOST" != "$EXPECTED_HOST" || "$ACTUAL_DMI" != "$EXPECTED_DMI" ]]; then
|
||||
echo "TARGET_IDENTITY_MISMATCH" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
REMOTE_USER="zhulan-codex"
|
||||
REMOTE_HOME="/srv/guanghu/zhulan-codex/home"
|
||||
REMOTE_ROOT="/srv/guanghu/zhulan-codex"
|
||||
WORKSPACE_ROOT="$REMOTE_ROOT/workspaces"
|
||||
CANDIDATE_ROOT="$REMOTE_ROOT/candidates"
|
||||
POLICY_ROOT="/etc/guanghu/zhulan-codex"
|
||||
HOOK_ROOT="$POLICY_ROOT/hooks"
|
||||
REQUIREMENTS_ROOT="/etc/codex"
|
||||
SSHD_DROPIN="/etc/ssh/sshd_config.d/60-zhulan-codex.conf"
|
||||
REPOSITORY_URL="https://guanghulab.com/code/bingshuo/guanghu-ice-heart.git"
|
||||
REPOSITORY_DIR="$WORKSPACE_ROOT/guanghu-ice-heart"
|
||||
CODEX_VERSION="${ZHULAN_CODEX_VERSION:-0.147.0}"
|
||||
SOURCE_COMMIT="${ZHULAN_SOURCE_COMMIT:-}"
|
||||
|
||||
if [[ ! "$SOURCE_COMMIT" =~ ^[0-9a-f]{40}$ ]]; then
|
||||
echo "SOURCE_COMMIT_REQUIRED" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
getent passwd "$REMOTE_USER" >/dev/null || useradd \
|
||||
--home-dir "$REMOTE_HOME" \
|
||||
--create-home \
|
||||
--shell /bin/bash \
|
||||
--comment "Zhulan Codex Remote restricted developer" \
|
||||
"$REMOTE_USER"
|
||||
passwd -l "$REMOTE_USER" >/dev/null
|
||||
gpasswd -d "$REMOTE_USER" sudo >/dev/null 2>&1 || true
|
||||
gpasswd -d "$REMOTE_USER" adm >/dev/null 2>&1 || true
|
||||
|
||||
install -d -o root -g root -m 0755 "$REMOTE_ROOT"
|
||||
install -d -o "$REMOTE_USER" -g "$REMOTE_USER" -m 0700 "$REMOTE_HOME" "$WORKSPACE_ROOT" "$CANDIDATE_ROOT"
|
||||
install -d -o "$REMOTE_USER" -g "$REMOTE_USER" -m 0700 "$REMOTE_HOME/.ssh"
|
||||
install -d -o "$REMOTE_USER" -g "$REMOTE_USER" -m 0700 "$REMOTE_HOME/.codex"
|
||||
{
|
||||
printf 'restrict,pty '
|
||||
cat "$AUTHORIZED_KEY_FILE"
|
||||
} >"$REMOTE_HOME/.ssh/authorized_keys.tmp"
|
||||
chown "$REMOTE_USER:$REMOTE_USER" "$REMOTE_HOME/.ssh/authorized_keys.tmp"
|
||||
chmod 0600 "$REMOTE_HOME/.ssh/authorized_keys.tmp"
|
||||
mv "$REMOTE_HOME/.ssh/authorized_keys.tmp" "$REMOTE_HOME/.ssh/authorized_keys"
|
||||
|
||||
install -d -o root -g root -m 0755 "$POLICY_ROOT" "$HOOK_ROOT" "$REQUIREMENTS_ROOT"
|
||||
install -o root -g root -m 0444 "$SOURCE_DIR/remote/LANE.hdlp" "$POLICY_ROOT/LANE.hdlp"
|
||||
install -o root -g root -m 0555 "$SOURCE_DIR/remote/zhulan_guard.py" "$HOOK_ROOT/zhulan_guard.py"
|
||||
install -o root -g root -m 0444 "$SOURCE_DIR/remote/requirements.toml" "$REQUIREMENTS_ROOT/requirements.toml"
|
||||
|
||||
cat >"$SSHD_DROPIN.tmp" <<'EOF'
|
||||
Match User zhulan-codex
|
||||
AuthenticationMethods publickey
|
||||
PasswordAuthentication no
|
||||
KbdInteractiveAuthentication no
|
||||
PubkeyAuthentication yes
|
||||
AllowAgentForwarding no
|
||||
AllowTcpForwarding no
|
||||
X11Forwarding no
|
||||
PermitTunnel no
|
||||
PermitTTY yes
|
||||
PermitUserEnvironment no
|
||||
EOF
|
||||
chmod 0644 "$SSHD_DROPIN.tmp"
|
||||
mv "$SSHD_DROPIN.tmp" "$SSHD_DROPIN"
|
||||
/usr/sbin/sshd -t
|
||||
systemctl reload ssh
|
||||
|
||||
if ! command -v codex >/dev/null 2>&1 || [[ "$(codex --version 2>/dev/null)" != *"$CODEX_VERSION"* ]]; then
|
||||
npm install --global "@openai/codex@$CODEX_VERSION"
|
||||
fi
|
||||
|
||||
if [[ ! -d "$REPOSITORY_DIR/.git" ]]; then
|
||||
runuser -u "$REMOTE_USER" -- git clone "$REPOSITORY_URL" "$REPOSITORY_DIR"
|
||||
fi
|
||||
runuser -u "$REMOTE_USER" -- git -C "$REPOSITORY_DIR" fetch --prune origin main
|
||||
runuser -u "$REMOTE_USER" -- git -C "$REPOSITORY_DIR" remote set-url --push origin DISABLED_CENTRAL_PUSH
|
||||
if [[ ! -d "$CANDIDATE_ROOT/guanghu-ice-heart.git" ]]; then
|
||||
runuser -u "$REMOTE_USER" -- git init --bare "$CANDIDATE_ROOT/guanghu-ice-heart.git"
|
||||
fi
|
||||
if runuser -u "$REMOTE_USER" -- git -C "$REPOSITORY_DIR" remote get-url candidate >/dev/null 2>&1; then
|
||||
runuser -u "$REMOTE_USER" -- git -C "$REPOSITORY_DIR" remote set-url candidate "$CANDIDATE_ROOT/guanghu-ice-heart.git"
|
||||
else
|
||||
runuser -u "$REMOTE_USER" -- git -C "$REPOSITORY_DIR" remote add candidate "$CANDIDATE_ROOT/guanghu-ice-heart.git"
|
||||
fi
|
||||
install -o "$REMOTE_USER" -g "$REMOTE_USER" -m 0644 "$SOURCE_DIR/remote/AGENTS.md" "$REMOTE_HOME/.codex/AGENTS.md"
|
||||
install -d -o "$REMOTE_USER" -g "$REMOTE_USER" -m 0700 "$REPOSITORY_DIR/.zhulan/continuity"
|
||||
if ! grep -qxF '/.zhulan/' "$REPOSITORY_DIR/.git/info/exclude"; then
|
||||
printf '%s\n' '/.zhulan/' >>"$REPOSITORY_DIR/.git/info/exclude"
|
||||
fi
|
||||
chown "$REMOTE_USER:$REMOTE_USER" "$REPOSITORY_DIR/.git/info/exclude"
|
||||
runuser -u "$REMOTE_USER" -- git -C "$REPOSITORY_DIR" config user.name "Zhulan Remote Candidate"
|
||||
runuser -u "$REMOTE_USER" -- git -C "$REPOSITORY_DIR" config user.email "zhulan-remote@localhost"
|
||||
|
||||
if id -nG "$REMOTE_USER" | tr ' ' '\n' | grep -qx sudo; then
|
||||
echo "REMOTE_USER_HAS_SUDO" >&2
|
||||
exit 1
|
||||
fi
|
||||
if sudo -n -u "$REMOTE_USER" sudo -n true >/dev/null 2>&1; then
|
||||
echo "REMOTE_USER_CAN_SUDO" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
RECEIPT="$REMOTE_ROOT/install-receipt.json"
|
||||
cat >"$RECEIPT.tmp" <<EOF
|
||||
{
|
||||
"schema": "guanghu.zhulan-codex-remote-ssh-install/v1",
|
||||
"development_id": "DEV-20260813-005",
|
||||
"persona_id": "ICE-GL-ZL-001",
|
||||
"runtime_node": "BS-SG-003",
|
||||
"front_node_role": "BS-GZ-006_PROXY_ONLY",
|
||||
"source_commit": "$SOURCE_COMMIT",
|
||||
"codex_version": "$CODEX_VERSION",
|
||||
"remote_user": "$REMOTE_USER",
|
||||
"workspace": "$REPOSITORY_DIR",
|
||||
"sudo": false,
|
||||
"central_push_credentials": false,
|
||||
"managed_hooks": true,
|
||||
"candidate_remote_only": true,
|
||||
"health": "PASS"
|
||||
}
|
||||
EOF
|
||||
chown root:root "$RECEIPT.tmp"
|
||||
chmod 0444 "$RECEIPT.tmp"
|
||||
mv "$RECEIPT.tmp" "$RECEIPT"
|
||||
cat "$RECEIPT"
|
||||
Loading…
Reference in a new issue