deploy-claude-code: bypass permissions + root по умолчанию (t-261016120111)
This commit is contained in:
parent
ecc9765996
commit
b9755187cf
1 changed files with 35 additions and 14 deletions
|
|
@ -11,14 +11,19 @@
|
||||||
# 5) daemon-reload + enable --now + финальная проверка версий и здоровья
|
# 5) daemon-reload + enable --now + финальная проверка версий и здоровья
|
||||||
#
|
#
|
||||||
# Использование (root или sudo):
|
# Использование (root или sudo):
|
||||||
# bash scripts/deploy-claude-code.sh # дефолты: :7681, юзер claude, токен сгенерится
|
# bash scripts/deploy-claude-code.sh # дефолты: :7681, root + bypass permissions
|
||||||
# bash scripts/deploy-claude-code.sh --port 7681 --user lunar --token MySecret
|
# bash scripts/deploy-claude-code.sh --port 7681 --user lunar --token MySecret
|
||||||
|
# bash scripts/deploy-claude-code.sh --run-as claude # ограниченный режим: юзер claude
|
||||||
# bash scripts/deploy-claude-code.sh --dry-run --port 9000 --user bob --token x
|
# bash scripts/deploy-claude-code.sh --dry-run --port 9000 --user bob --token x
|
||||||
# bash scripts/deploy-claude-code.sh --check # только здоровье, без установки
|
# bash scripts/deploy-claude-code.sh --check # только здоровье, без установки
|
||||||
#
|
#
|
||||||
# Опции:
|
# Опции:
|
||||||
# --port N порт ttyd (по умолчанию 7681, как на Лунаре)
|
# --port N порт ttyd (по умолчанию 7681, как на Лунаре)
|
||||||
# --user NAME OS-юзер сервиса И логин basic-auth (по умолчанию claude)
|
# --user NAME логин basic-auth (по умолчанию claude)
|
||||||
|
# --run-as NAME юзер сервиса ttyd (по умолчанию root — агенту нужны
|
||||||
|
# права на редактирование любых файлов; t-261016120111)
|
||||||
|
# --ask-permissions НЕ прокидывать --dangerously-skip-permissions
|
||||||
|
# (по умолчанию флаг прокидывается всегда — bypass)
|
||||||
# --token SECRET пароль basic-auth (по умолчанию: openssl rand -hex 12)
|
# --token SECRET пароль basic-auth (по умолчанию: openssl rand -hex 12)
|
||||||
# --service NAME имя systemd-юнита (по умолчанию ttyd-claude)
|
# --service NAME имя systemd-юнита (по умолчанию ttyd-claude)
|
||||||
# --ttyd-version V версия ttyd (по умолчанию 1.7.7)
|
# --ttyd-version V версия ttyd (по умолчанию 1.7.7)
|
||||||
|
|
@ -32,14 +37,17 @@
|
||||||
# --check только проверка здоровья (версии + HTTP + сервис)
|
# --check только проверка здоровья (версии + HTTP + сервис)
|
||||||
# -h | --help эта справка
|
# -h | --help эта справка
|
||||||
#
|
#
|
||||||
# Безопасность: веб-терминнал закрыт basic-auth (-c user:token) — как на Лунаре
|
# Безопасность: веб-терминал закрыт basic-auth (-c user:token). ПО УМОЛЧАНИЮ
|
||||||
# (логин lunar / Zm9yZXZ0b25lClaude01). Сервис работает от непривилегированного
|
# сервис работает от root и claude запускается с --dangerously-skip-permissions
|
||||||
# юзера (User=), никакого root-shell в браузере.
|
# (мандат t-261016120111: агент должен уметь редактировать любые файлы).
|
||||||
|
# Для ограниченной развёртки: --run-as <user> --ask-permissions.
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
PORT="7681"
|
PORT="7681"
|
||||||
USER_NAME="claude"
|
USER_NAME="claude"
|
||||||
|
RUN_AS="root"
|
||||||
|
ASK_PERMISSIONS=0
|
||||||
TOKEN=""
|
TOKEN=""
|
||||||
SERVICE="ttyd-claude"
|
SERVICE="ttyd-claude"
|
||||||
TTYD_VERSION="1.7.7"
|
TTYD_VERSION="1.7.7"
|
||||||
|
|
@ -62,6 +70,8 @@ while [ $# -gt 0 ]; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
--port) PORT="${2:-}"; shift 2 ;;
|
--port) PORT="${2:-}"; shift 2 ;;
|
||||||
--user) USER_NAME="${2:-}"; shift 2 ;;
|
--user) USER_NAME="${2:-}"; shift 2 ;;
|
||||||
|
--run-as) RUN_AS="${2:-}"; shift 2 ;;
|
||||||
|
--ask-permissions) ASK_PERMISSIONS=1; shift ;;
|
||||||
--token) TOKEN="${2:-}"; shift 2 ;;
|
--token) TOKEN="${2:-}"; shift 2 ;;
|
||||||
--service) SERVICE="${2:-}"; shift 2 ;;
|
--service) SERVICE="${2:-}"; shift 2 ;;
|
||||||
--ttyd-version) TTYD_VERSION="${2:-}"; shift 2 ;;
|
--ttyd-version) TTYD_VERSION="${2:-}"; shift 2 ;;
|
||||||
|
|
@ -79,6 +89,7 @@ while [ $# -gt 0 ]; do
|
||||||
opt="${1%%=*}"; val="${1#*=}"
|
opt="${1%%=*}"; val="${1#*=}"
|
||||||
case "$opt" in
|
case "$opt" in
|
||||||
--port) PORT="$val" ;; --user) USER_NAME="$val" ;;
|
--port) PORT="$val" ;; --user) USER_NAME="$val" ;;
|
||||||
|
--run-as) RUN_AS="$val" ;; --ask-permissions) ASK_PERMISSIONS=1 ;;
|
||||||
--token) TOKEN="$val" ;; --service) SERVICE="$val" ;;
|
--token) TOKEN="$val" ;; --service) SERVICE="$val" ;;
|
||||||
--ttyd-version) TTYD_VERSION="$val" ;; --node-version) NODE_VERSION="$val" ;;
|
--ttyd-version) TTYD_VERSION="$val" ;; --node-version) NODE_VERSION="$val" ;;
|
||||||
--claude-version) CLAUDE_VERSION="$val" ;; --interface) INTERFACE="$val" ;;
|
--claude-version) CLAUDE_VERSION="$val" ;; --interface) INTERFACE="$val" ;;
|
||||||
|
|
@ -93,6 +104,10 @@ done
|
||||||
|| die "--port должен быть числом 1..65535 (получили: '$PORT')"
|
|| die "--port должен быть числом 1..65535 (получили: '$PORT')"
|
||||||
[[ "$USER_NAME" =~ ^[a-z_][a-z0-9_-]{0,31}$ ]] \
|
[[ "$USER_NAME" =~ ^[a-z_][a-z0-9_-]{0,31}$ ]] \
|
||||||
|| die "--user должен быть валидным unix-логином (a-z, 0-9, _, -; получили: '$USER_NAME')"
|
|| die "--user должен быть валидным unix-логином (a-z, 0-9, _, -; получили: '$USER_NAME')"
|
||||||
|
[[ "$RUN_AS" =~ ^[a-z_][a-z0-9_-]{0,31}$ ]] \
|
||||||
|
|| die "--run-as должен быть валидным unix-логином (получили: '$RUN_AS')"
|
||||||
|
id -u "$RUN_AS" >/dev/null 2>&1 || [ "$DRY_RUN" -eq 1 ] || [ "$CHECK_ONLY" -eq 1 ] \
|
||||||
|
|| die "--run-as: юзер '$RUN_AS' не существует (скрипт его не создаёт — создай сам или запусти без --run-as для root)"
|
||||||
[[ "$SERVICE" =~ ^[a-zA-Z0-9_.@-]+$ ]] || die "--service: некорректное имя юнита '$SERVICE'"
|
[[ "$SERVICE" =~ ^[a-zA-Z0-9_.@-]+$ ]] || die "--service: некорректное имя юнита '$SERVICE'"
|
||||||
case "$TOKEN" in
|
case "$TOKEN" in
|
||||||
*:*) die "--token не может содержать ':' (ломает -c user:token)" ;;
|
*:*) die "--token не может содержать ':' (ломает -c user:token)" ;;
|
||||||
|
|
@ -223,17 +238,22 @@ else
|
||||||
bash -c "set -e; curl -fsSL -o /usr/local/bin/ttyd https://github.com/tsl0922/ttyd/releases/download/$TTYD_VERSION/ttyd.$TARCH && chmod +x /usr/local/bin/ttyd"
|
bash -c "set -e; curl -fsSL -o /usr/local/bin/ttyd https://github.com/tsl0922/ttyd/releases/download/$TTYD_VERSION/ttyd.$TARCH && chmod +x /usr/local/bin/ttyd"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ── 4) OS-юзер и systemd-юнит ────────────────────────────────────────────────
|
# ── 4) systemd-юнит ──────────────────────────────────────────────────────────
|
||||||
if [ "$DRY_RUN" -eq 0 ]; then
|
# По умолчанию сервис работает от root (RUN_AS=root): агент получает право
|
||||||
if ! id -u "$USER_NAME" >/dev/null 2>&1; then
|
# редактировать любые файлы (мандат t-261016120111). Ограниченный режим:
|
||||||
log "создаю юзера $USER_NAME (без root-shell в веб-терминале)"
|
# --run-as <user> (+ можно --ask-permissions).
|
||||||
useradd -m -s /bin/bash "$USER_NAME"
|
if [ "$DRY_RUN" -eq 0 ] && [ "$RUN_AS" != "root" ]; then
|
||||||
fi
|
id -u "$RUN_AS" >/dev/null 2>&1 || { log "создаю юзера $RUN_AS (без root-shell в веб-терминале)"; useradd -m -s /bin/bash "$RUN_AS"; }
|
||||||
fi
|
fi
|
||||||
|
|
||||||
WRITABLE='-W'; [ "$READONLY" -eq 1 ] && WRITABLE=''
|
WRITABLE='-W'; [ "$READONLY" -eq 1 ] && WRITABLE=''
|
||||||
|
# bypass permissions: --dangerously-skip-permissions прокидывается ПО УМОЛЧАНИЮ
|
||||||
|
CLAUDE_ARGS=''
|
||||||
|
[ "$ASK_PERMISSIONS" -eq 0 ] && CLAUDE_ARGS='--dangerously-skip-permissions'
|
||||||
UNIT_PATH="/etc/systemd/system/${SERVICE}.service"
|
UNIT_PATH="/etc/systemd/system/${SERVICE}.service"
|
||||||
ENV_LINES="Environment=HOME=/home/${USER_NAME}
|
SERVICE_HOME="/home/${RUN_AS}"
|
||||||
|
[ "$RUN_AS" = "root" ] && SERVICE_HOME="/root"
|
||||||
|
ENV_LINES="Environment=HOME=${SERVICE_HOME}
|
||||||
Environment=PATH=/usr/local/bin:/usr/bin:/bin"
|
Environment=PATH=/usr/local/bin:/usr/bin:/bin"
|
||||||
if [ ${#UNIT_ENV[@]} -gt 0 ]; then
|
if [ ${#UNIT_ENV[@]} -gt 0 ]; then
|
||||||
for e in "${UNIT_ENV[@]}"; do ENV_LINES+="
|
for e in "${UNIT_ENV[@]}"; do ENV_LINES+="
|
||||||
|
|
@ -245,9 +265,9 @@ After=network-online.target
|
||||||
Wants=network-online.target
|
Wants=network-online.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
User=${USER_NAME}
|
User=${RUN_AS}
|
||||||
${ENV_LINES}
|
${ENV_LINES}
|
||||||
ExecStart=/usr/local/bin/ttyd ${WRITABLE} -c ${USER_NAME}:${TOKEN} -p ${PORT} -i ${INTERFACE} claude
|
ExecStart=/usr/local/bin/ttyd ${WRITABLE} -c ${USER_NAME}:${TOKEN} -p ${PORT} -i ${INTERFACE} claude ${CLAUDE_ARGS}
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=3
|
RestartSec=3
|
||||||
|
|
||||||
|
|
@ -286,4 +306,5 @@ log " URL : http://${IP}:${PORT}"
|
||||||
log " логин : ${USER_NAME}"
|
log " логин : ${USER_NAME}"
|
||||||
log " пароль : ${TOKEN}"
|
log " пароль : ${TOKEN}"
|
||||||
log " сервис : systemctl status ${SERVICE}"
|
log " сервис : systemctl status ${SERVICE}"
|
||||||
|
log " режим : User=${RUN_AS}; claude-флаги: ${CLAUDE_ARGS:-—} (bypass permissions по умолчанию, t-261016120111)"
|
||||||
log " первый вход: открой URL, пройди авторизацию claude (или передай --env ANTHROPIC_BASE_URL=... при развёртке)"
|
log " первый вход: открой URL, пройди авторизацию claude (или передай --env ANTHROPIC_BASE_URL=... при развёртке)"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue