Initial commit: grok-free-register-oss
Open-source Grok free registration CLI, xai_enroller auth pipeline, local auth service, tests and docs.
This commit is contained in:
commit
d10009d639
72 files changed
+18752
No files matched your search
Executable
+153
@@ -0,0 +1,153 @@
|
||||
#!/usr/bin/env bash
|
||||
# 本机注册 → 推 SSO 源到远端 auth 机(local 模式吃 keys/)
|
||||
#
|
||||
# 动态公网 IP 不适合「远端 SSH 拉本机」;改由本机主动推:
|
||||
# keys/auth-sessions.jsonl
|
||||
# keys/accounts.txt
|
||||
# → AUTH_HOST:REMOTE_ROOT/keys/
|
||||
#
|
||||
# 用法(本机项目根或任意 cwd):
|
||||
# bash scripts/push_keys_to_auth.sh # 推一次
|
||||
# bash scripts/push_keys_to_auth.sh --watch # 常驻,文件变了再推
|
||||
# bash scripts/push_keys_to_auth.sh --interval 15
|
||||
#
|
||||
# 环境变量(可写本机 .env,本脚本会 source):
|
||||
# AUTH_SSH_HOST=user@auth-server.example
|
||||
# AUTH_REMOTE_ROOT=/opt/grok-free-register
|
||||
# AUTH_SSH_IDENTITY= # 可选 -i 路径
|
||||
# AUTH_PUSH_INTERVAL=20 # --watch 轮询秒
|
||||
#
|
||||
# 无内置默认主机/路径:必须显式设置 AUTH_SSH_HOST 与 AUTH_REMOTE_ROOT。
|
||||
|
||||
set -euo pipefail
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
# 调用方已 export 的 AUTH_* 优先(.env 不得盖掉),方便并行推多台 auth
|
||||
_PRE_AUTH_SSH_HOST="${AUTH_SSH_HOST-}"
|
||||
_PRE_AUTH_REMOTE_ROOT="${AUTH_REMOTE_ROOT-}"
|
||||
_PRE_AUTH_SSH_IDENTITY="${AUTH_SSH_IDENTITY-}"
|
||||
_PRE_AUTH_PUSH_INTERVAL="${AUTH_PUSH_INTERVAL-}"
|
||||
|
||||
if [[ -f "$ROOT/.env" ]]; then
|
||||
set -a
|
||||
# shellcheck disable=SC1091
|
||||
. "$ROOT/.env"
|
||||
set +a
|
||||
fi
|
||||
|
||||
AUTH_SSH_HOST="${_PRE_AUTH_SSH_HOST:-${AUTH_SSH_HOST:-}}"
|
||||
AUTH_REMOTE_ROOT="${_PRE_AUTH_REMOTE_ROOT:-${AUTH_REMOTE_ROOT:-}}"
|
||||
AUTH_SSH_IDENTITY="${_PRE_AUTH_SSH_IDENTITY:-${AUTH_SSH_IDENTITY:-}}"
|
||||
AUTH_PUSH_INTERVAL="${_PRE_AUTH_PUSH_INTERVAL:-${AUTH_PUSH_INTERVAL:-20}}"
|
||||
|
||||
if [[ -z "$AUTH_SSH_HOST" || -z "$AUTH_REMOTE_ROOT" ]]; then
|
||||
echo "push_keys_to_auth: set AUTH_SSH_HOST and AUTH_REMOTE_ROOT (env or .env)" >&2
|
||||
echo " e.g. AUTH_SSH_HOST=user@auth-server.example AUTH_REMOTE_ROOT=/opt/grok-free-register" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
WATCH=0
|
||||
INTERVAL="$AUTH_PUSH_INTERVAL"
|
||||
for a in "$@"; do
|
||||
case "$a" in
|
||||
--watch) WATCH=1 ;;
|
||||
--interval)
|
||||
# next arg handled below if present as --interval=N form preferred
|
||||
;;
|
||||
--interval=*) INTERVAL="${a#--interval=}" ;;
|
||||
-h|--help)
|
||||
sed -n '2,22p' "$0"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
# support: --interval 15
|
||||
prev=""
|
||||
for a in "$@"; do
|
||||
if [[ "$prev" == "--interval" ]]; then
|
||||
INTERVAL="$a"
|
||||
fi
|
||||
prev="$a"
|
||||
done
|
||||
|
||||
SSH_OPTS=(-o BatchMode=yes -o ConnectTimeout=15 -o ServerAliveInterval=15)
|
||||
if [[ -n "$AUTH_SSH_IDENTITY" ]]; then
|
||||
SSH_OPTS+=(-i "$AUTH_SSH_IDENTITY")
|
||||
fi
|
||||
|
||||
KEYS_SRC="$ROOT/keys"
|
||||
REMOTE_KEYS="${AUTH_REMOTE_ROOT}/keys"
|
||||
# 只推 auth 源,不推 cpa_ready/acc(远端自己整备)
|
||||
FILES=(auth-sessions.jsonl accounts.txt)
|
||||
|
||||
log() { printf '[push_keys %s] %s\n' "$(date +%H:%M:%S)" "$*"; }
|
||||
|
||||
fingerprint() {
|
||||
local f
|
||||
for f in "${FILES[@]}"; do
|
||||
if [[ -f "$KEYS_SRC/$f" ]]; then
|
||||
# size + mtime + sha256 head — cheap change detect
|
||||
stat -c '%s %Y' "$KEYS_SRC/$f" 2>/dev/null || stat -f '%z %m' "$KEYS_SRC/$f"
|
||||
sha256sum "$KEYS_SRC/$f" 2>/dev/null | awk '{print $1}'
|
||||
else
|
||||
echo "missing:$f"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
push_once() {
|
||||
local missing=0 f
|
||||
for f in "${FILES[@]}"; do
|
||||
if [[ ! -f "$KEYS_SRC/$f" ]]; then
|
||||
log "⚠ 缺 $KEYS_SRC/$f"
|
||||
missing=1
|
||||
fi
|
||||
done
|
||||
if [[ "$missing" -eq 1 ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 远端原子替换:先推 .push.tmp 再 mv
|
||||
ssh "${SSH_OPTS[@]}" "$AUTH_SSH_HOST" "mkdir -p $(printf %q "$REMOTE_KEYS") && chmod 700 $(printf %q "$REMOTE_KEYS") 2>/dev/null || true"
|
||||
|
||||
local remote_tmp remote_final
|
||||
for f in "${FILES[@]}"; do
|
||||
remote_tmp="${REMOTE_KEYS}/.${f}.push.tmp"
|
||||
remote_final="${REMOTE_KEYS}/${f}"
|
||||
# rsync over ssh when available; fallback scp
|
||||
if command -v rsync >/dev/null 2>&1; then
|
||||
rsync -az -e "ssh ${SSH_OPTS[*]}" \
|
||||
"$KEYS_SRC/$f" \
|
||||
"${AUTH_SSH_HOST}:${remote_tmp}"
|
||||
else
|
||||
scp "${SSH_OPTS[@]}" "$KEYS_SRC/$f" "${AUTH_SSH_HOST}:${remote_tmp}"
|
||||
fi
|
||||
ssh "${SSH_OPTS[@]}" "$AUTH_SSH_HOST" \
|
||||
"chmod 600 $(printf %q "$remote_tmp") && mv -f $(printf %q "$remote_tmp") $(printf %q "$remote_final")"
|
||||
done
|
||||
|
||||
local n_sess n_acc
|
||||
n_sess=$(wc -l < "$KEYS_SRC/auth-sessions.jsonl" | tr -d ' ')
|
||||
n_acc=$(wc -l < "$KEYS_SRC/accounts.txt" | tr -d ' ')
|
||||
log "→ ${AUTH_SSH_HOST}:${REMOTE_KEYS}/ sessions=${n_sess} accounts=${n_acc}"
|
||||
}
|
||||
|
||||
LAST_FP=""
|
||||
if [[ "$WATCH" -eq 0 ]]; then
|
||||
push_once
|
||||
exit $?
|
||||
fi
|
||||
|
||||
log "watch host=${AUTH_SSH_HOST} root=${AUTH_REMOTE_ROOT} interval=${INTERVAL}s"
|
||||
while true; do
|
||||
FP="$(fingerprint)"
|
||||
if [[ "$FP" != "$LAST_FP" ]]; then
|
||||
if push_once; then
|
||||
LAST_FP="$FP"
|
||||
else
|
||||
log "推送失败,${INTERVAL}s 后重试"
|
||||
fi
|
||||
fi
|
||||
sleep "$INTERVAL"
|
||||
done
|
||||
Reference in new issue
Block a user