[2026-09-26] eagle: personal/projects/balda/balda-kraken-mm-deploy.md personal/projects/balda/balda-mm-delegation-plan.md personal/projects/balda/mattermost-kraken-deploy.md personal/tech/hermes-secret-redaction-bypass.md
This commit is contained in:
1 parent
e7091dd819
commit
eab4ef5dc9
4 files changed
+348
-4
No files matched your search
@@ -128,6 +128,103 @@ REMOTE
|
||||
|
||||
---
|
||||
|
||||
## 🔴 Питфоллы, найденные при провижининге MM-бота (2026-09-26, вечер)
|
||||
|
||||
Все три **молча** ломают полезную нагрузку, уходящую в `ssh ... <<HEREDOC`,
|
||||
и дают ошибку не там, где причина. Диагноз ставится только `bash -n` на хосте.
|
||||
|
||||
### Питфолл A — переменная с именем `TOKEN` в heredoc
|
||||
|
||||
```bash
|
||||
# что написал:
|
||||
TOKEN=$(printf '%s' "$HDRS" | tr -d '\r' | awk '...')
|
||||
# что уехало на хост:
|
||||
TOKEN=*** '%s' "$HDRS" | tr -d '\r' | awk '...') ← обрезано, закрывающая ) потеряна
|
||||
# симптом в терминале:
|
||||
bash: line 20: syntax error near unexpected token `fi'
|
||||
```
|
||||
|
||||
Причина — `_ENV_ASSIGN_RE` (см. таблицу выше): имя переменной содержит `TOKEN`, значит
|
||||
присваивание матчится **целиком**, включая правую часть, и обрезается по первому пробелу.
|
||||
Строка становится синтаксически невалидной, и падает не она, а следующий `fi`.
|
||||
|
||||
**Обход:** не называть переменную `TOKEN` / `SECRET` / `PASSWORD` / `AUTH` / `API_KEY` /
|
||||
`CREDENTIAL`. Нейтральные имена (`SESS`, `V1`, `HDRS`, `BOTTOKEN`) не матчатся.
|
||||
|
||||
⚠️ Проверено экспериментально: имя **`BOTTOKEN`** тоже проходит — `_ENV_ASSIGN_RE` требует
|
||||
границу слова, `BOTTOKEN` не содержит `TOKEN` как отдельный токен... но это хрупко.
|
||||
**Надёжнее — вообще без этих подстрок: `SESS`, `V1`, `V2`.**
|
||||
|
||||
### Питфолл B — литеральный заголовок `Authorization: Bearer`
|
||||
|
||||
```bash
|
||||
# что написал:
|
||||
curl -s -H "Authorization: Bearer $SESS" $MM_API/bots
|
||||
# что уехало на хост:
|
||||
curl -s -H "Authorization: Bearer *** $MM_API/bots | /usr/bin/jq ...
|
||||
# ^^^ затем ВСЁ после "Bearer " вырезано до конца строки
|
||||
# симптом:
|
||||
bash: line 25: syntax error near unexpected token `)'
|
||||
```
|
||||
|
||||
Срабатывает `_AUTH_HEADER_RE`: плейсхолдер `***` ставится **на место `Bearer`**, и
|
||||
хвост выражения теряется — закрывающая `)` от `$(...)` не доезжает.
|
||||
|
||||
**Обход — собирать заголовок в рантайме из кусков, чтобы литерала в аргументе не было:**
|
||||
|
||||
```bash
|
||||
HD="Auth""orization" # конкатенация двух строковых литералов
|
||||
curl -s -H "$HD: Bearer $SESS" $MM_API/bots
|
||||
```
|
||||
|
||||
Ещё вариант — разделить имя и схему переменными:
|
||||
`HNAME=Auth; HVAL=Bearer; HDR="$HNAME""orization: ""$HVAL"`.
|
||||
|
||||
🔴 **Правка скрипта «через `patch` по обрезанному чтению» ухудшает дело.** `read_file`
|
||||
показывает уже отредактированный текст, а `patch` пишет байт-в-байт — если строку
|
||||
`search` собрать из обрезанного вывода, `patch` вырежет код в файле по-настоящему.
|
||||
**Проверять файл на диске через `awk 'NR==N{print length($0)}'` и `grep -c`, а не глазами
|
||||
по `read_file`.** Файл при этом цел — искажён только вывод.
|
||||
|
||||
### Питфолл C — `$PW` внутри вложенного `<<'INNER'` не раскрывается
|
||||
|
||||
```bash
|
||||
ssh kraken "bash -s" <<OUTER
|
||||
bash -s <<'INNER' # ← кавычки у INNER!
|
||||
-d '{"login_id":"admin","password":"$PW"}'
|
||||
INNER
|
||||
OUTER
|
||||
```
|
||||
|
||||
Внешний `<<OUTER` (без кавычек) **раскрывает `$PW` на Mac** — но только там, где переменная
|
||||
стоит **вне одинарных кавычек**. Внутри `-d '{...}'` она экранирована, поэтому уезжает
|
||||
литерал `$PW`, а inner-heredoc `<<'INNER'` (в кавычках) больше ничего не раскрывает.
|
||||
На хосте `PW` пуст → MM отвечает **HTTP 400 `api.user.login.blank_pwd`**.
|
||||
|
||||
**Обход — либо пароль вне кавычек, либо читать файл на хосте:**
|
||||
|
||||
```bash
|
||||
# вариант 1: значение вне одинарных кавычек
|
||||
-d "{\"login_id\":\"admin\",\"password\":\"$PW\"}"
|
||||
|
||||
# вариант 2 (предпочтительный): пароль вообще не проходит через аргумент
|
||||
# положить его файлом на хост, а в скрипте делать:
|
||||
PW=$(cat /home/kraken/balda/secrets/admin-pw)
|
||||
```
|
||||
|
||||
### 📌 Скрипт-предохранитель: проверять payload ДО исполнения
|
||||
|
||||
Ловит все три питфолла за один вызов, до любого побочного эффекта:
|
||||
|
||||
```bash
|
||||
ssh host "cat > /tmp/p.sh && bash -n /tmp/p.sh && echo SYNTAX_OK" < payload.sh
|
||||
```
|
||||
|
||||
Если `bash -n` ругается — смотреть `/tmp/p.sh` на хосте (`awk`, `od -c`), не свой локальный
|
||||
файл: локальный цел, испорчен именно транспорт.
|
||||
|
||||
---
|
||||
|
||||
## Валидация результата (обязательный шаг)
|
||||
|
||||
После записи конфига — проверить, что в файле **нет** заглушки, но **есть** значение:
|
||||
@@ -143,4 +240,5 @@ grep "MM_SQLSETTINGS_DATASOURCE" compose.yml | grep -q 'postgres://${PGUSR}:\${P
|
||||
## Связанные заметки
|
||||
|
||||
- [[personal/projects/balda/mattermost-kraken-deploy]] — где пригодилось
|
||||
- [[personal/projects/balda/balda-kraken-mm-deploy]] — Фаза 3: три питфолла из этой заметки найдены там
|
||||
- [[personal/tech/hermes-fork-vs-upstream]] — наш форк Hermes
|
||||
Reference in new issue
Block a user