doc: журнал сессии 2026-10-10 + справочник по публичной точке на ВМ (TLS, замеры, ошибки)

This commit is contained in:
Repinoid
2026-10-10 13:42:22 +03:00
parent 6800d1abf3
commit ee5503f9ac
2 changed files with 235 additions and 0 deletions
+140
View File
@@ -0,0 +1,140 @@
# История правок shared-sqs — 2026-10-10 (публичная точка на ВМ, TLS, замеры)
> Запись по требованию «документировать всё, включая собственные ошибки» (приказ 2026-09-24).
> Предыдущие: `HISTORY/2026-10-07-session-log.md`, `doc/thinking/*-2026-10-08.md`.
> Сессия велась двумя моделями: сначала DeepSeek Flash, затем DeepSeek Pro (архитектор) —
> Pro перепроверял выводы Flash, часть из них оказалась неверной (см. раздел 4).
## 1. Задача
Вынести публичную точку SQS на ВМ `5.172.178.213` (обход больного managed-шлюза) и
**проверить гипотезу** из `MANUAL-NEXT-2026-10-08.md` (Шаг 1): нет ли на пути
«интернет → ВМ» той же сетевой болезни (зависания ~51 с, таймауты 31–33 с).
Требования владельца по пути: домен — только свой (`sinefo.ru`); `kube5s` из проекта убрать.
## 2. Хронология (что делалось и что получалось)
### 2.1. Сборка и запуск на ВМ
- `make build` → `shared-sqs` v0.1.35 (статический, x86_64, 17 МБ).
- `scp` → `naeel@5.172.178.213:~/sqs-test/shared-sqs`.
- Запуск memory-only: `SHARED_SQS_SEED_DEMO=true ./shared-sqs --admin-token=dev-token-123 --port=4100`.
- Локально на ВМ: `/health` → `200 {"status":"ok","version":"v0.1.35"}`;
`ListQueues` без подписи → `403 MissingAuthenticationToken` (корректно).
- ⚠️ Предупреждение `Failure to find default config file` — `goaws.yaml` на ВМ нет,
приложение работает на встроенных дефолтах (см. 5.1).
### 2.2. Разведка ВМ
- Публичный адрес — `5.172.178.213` (NAT); внутренний `10.10.102.21` (`ens192`), hostname `naeel-vm`.
- Снаружи прилетают только 80/443. Проверка портов:
- `8443` — занят DNAT: `iptables -t nat`: `--dport 8443 -j DNAT --to-destination 95.179.252.111:443`
(сервис `vpn-transit-dnat`, `enabled/active`) → весь трафик на 8443 уходит на Vultr **до** ВМ.
- `8888`/`9443` — `/dev/tcp` показывает «OPEN», но локально **никто не слушает** и HTTP не отвечает
(curl timeout) → это SYN-proxy провайдерского firewall, порты непригодны.
- `/etc/hosts` на ВМ содержит внутренние имена: `gitea.mgmt.nubes.ru`, `sqs.containerk8s.dev.nubes.ru`
→ `185.247.187.151`, `tf-registry.containerk8s.services.ngcloud.ru`, `s3.msk-1.ngcloud.ru`.
Резолвер ВМ — публичный (`8.8.8.8`, `1.1.1.1`), поэтому имена `*.services.ngcloud.ru` не резолвятся.
### 2.3. Блокер nginx (возник 10-08, снят 10-10)
- 10-08: `sudo nginx -t` **падал**: `host not found in upstream "contractor.pythonk8s.services.ngcloud.ru"
in sites-enabled/check.kube5s.ru:44` — внутреннее имя не резолвится.
- 10-10 (после ребута ВМ): конфиг `check.kube5s.ru` оказался **изменён** (catch-all `location /`
на contractor убран, добавлен `location /rf`) → `nginx -t` **проходит**, nginx перезагружаем.
- Следствие: переход к рабочему пути упростился (сначала была построена схема со вторым nginx, см. 2.4).
### 2.4. Второй nginx на 10443 (сделан, затем убран)
- Владелец пробросил порт: firewall `[22, 80, 443, 4443, 10443]`.
- Проверено: `10443` реально доходит до ВМ (`/health` 200), `4443` — нет.
- Поднят **отдельный** nginx: `/etc/nginx-sqs/nginx.conf`, pid `/run/nginx-sqs.pid`,
`listen 10443` → `proxy_pass http://127.0.0.1:4100`. Запуск `sudo nginx -c /etc/nginx-sqs/nginx.conf`.
### 2.5. Замеры (гипотеза ПОДТВЕРЖДЕНА)
| Тест | Инструмент | Результат |
|---|---|---|
| HTTP, 30 запросов 1КБ/10КБ/100КБ/256КБ | `curl --aws-sigv4` | 30/30 **200**, max **0.99 с** |
| HTTPS, 10 запросов 26КБ…260КБ | `curl --aws-sigv4` | 10/10 **200**, 0.7–3.2 с |
| Long-poll `ReceiveMessage` `WaitTimeSeconds=20` | `curl` | **20.3 с, 200** (корректно) |
Ни зависаний ~51 с, ни таймаутов 31–33 с. **На пути «интернет → ВМ 213» болезни нет.**
### 2.6. DNS
- `sinefo.ru` делегирован в реестре .ru на `ns3.ngcloud.ru` / `ns4.ngcloud.ru` (проверено через `a.dns.ripn.net`).
- `sqs.sinefo.ru A 5.172.178.213` — публично резолвится. Ранее запись была `185.247.187.83`,
что = **IP самого DNS-сервера** `ns3.ngcloud.ru`, а не ВМ (исправлено владельцем).
### 2.7. TLS (Let's Encrypt)
- `sudo certbot certonly --webroot -w /var/www/acme -d sqs.sinefo.ru --non-interactive --agree-tos`
(аккаунт LE на ВМ уже существовал → без нового e-mail) → `/etc/letsencrypt/live/sqs.sinefo.ru/`.
- Срок: до 2027-01-08, автопродление настроено.
- ACME-челлендж обслуживается главным nginx (vhost 80 с `location /.well-known/acme-challenge/`).
### 2.8. Публичная точка (итог)
- Главный nginx, `/etc/nginx/conf.d/sqs-sinefo.conf`:
- **80**: ACME-челлендж + редирект на https;
- **443 ssl**: сертификат `sqs.sinefo.ru` + `proxy_pass http://127.0.0.1:4100`, `Host $http_host`.
- Проверено снаружи: `https://sqs.sinefo.ru/health` → 200 (cert valid), SigV4, 256 КБ за 1.05 с.
### 2.9. Уборка
- Второй nginx (10443) остановлен, `/etc/nginx-sqs` удалён; порт 10443 свободен.
- `conf.d/sqs-sinefo.conf` — заменён на нормальный vhost (было: HTTP-only левак от 10-08).
- Из **актуального** дока `doc/2026-08-13-migration-to-managed.md` убран `kube5s.ru`
(квинтет: `iot.kube5s.ru`→`iot.nubes.ru`, `qu.kube5s.ru`×3→`sqs.containerk8s.dev.nubes.ru`),
коммит `a47743f`. В `doc/legacy/` (история) не трогал.
## 3. Грабли (для повторного использования)
1. **`proxy_set_header Host $host` теряет порт** → SigV4 `SignatureDoesNotMatch`.
Нужен `$http_host`. (nginx `$host` — имя без порта; `$http_host` — заголовок целиком.)
2. **`~/.aws/config [default]` содержит `endpoint_url = https://s3.msk-1.ngcloud.ru`** →
`aws sqs ...` без явного `--endpoint-url` уходит в S3 и получает
`405 MethodNotAllowed` (Ceph RGW, `HostId=...-dc1-msk-1`). **Всегда задавать `--endpoint-url`.**
3. **Креды демо-тенанта рандомны при каждом старте** — брать из `~/sqs-test/sqs.log`
(`seed: создан тенант ... AccessKey=...`). При «address already in use» в логе креды **мёртвого** инстанса.
4. `pkill -f "http.server 10443"` по SSH **самоматчится** на строку ssh-команды и убивает сессию —
использовать `pkill -x <имя>`.
5. Порт `8443` на 213 **нельзя занимать** — там DNAT транзита на Vultr.
## 4. ОШИБКИ (сводка, включая ошибки Flash)
| # | Что утверждалось/сделано | Что на самом деле | Исправление |
|---|---|---|---|
| 1 | «При ребуте ВМ nginx не поднимется» (из-за битого upstream) | После ребута nginx `active`, 80/443 слушают | Неверный вывод; снят при перепроверке |
| 2 | «`.83` — мёртвый IP» | `185.247.187.83` = живой DNS `ns3.ngcloud.ru` (порт 53); проверял только 80/443 | Признано при перепроверке |
| 3 | Запуск второго инстанса при живом первом | `fatal: bind: address already in use`; лог перезаписан кредами мёртвого → `InvalidClientTokenId` | `pkill -x shared-sqs`, один инстанс, креды из лога |
| 4 | Второй nginx: `Host $host` | SigV4 `SignatureDoesNotMatch` | `Host $http_host` |
| 5 | Прямые DNS-выводы по регексу `location / ` | Первый `grep` не нашёл (паттерн с пробелом) — чуть не сделал ложный вывод | Перечитал файл целиком (`cat`) |
| 6 | «Только 80/443 открыты» | 8888/9443 «принимают» TCP (SYN-proxy), но пусты | Уточнено: рабочие — только 80/443 |
## 5. Состояние и воспроизведение
### 5.1. Итоговое состояние
- **Работает:** `https://sqs.sinefo.ru` (443, TLS) → shared-sqs на ВМ 213 (memory-only, `127.0.0.1:4100`).
- SQS: `~/sqs-test/shared-sqs`, лог `~/sqs-test/sqs.log`, pid меняется. Демо-тенант + 5 очередей.
- **Дефект:** `QueueUrl` в ответах = `http://region.host:port/<tenant>/<queue>` — реального хоста нет
(следствие отсутствия `goaws.yaml`). Клиенты **с** `endpoint_url` не страдают (берут только путь),
клиенты **без** него — сломаны. См. открытый вопрос 6.1.
### 5.2. Как поднять заново
```bash
# на ВМ 213
cd ~/sqs-test && setsid nohup env SHARED_SQS_SEED_DEMO=true \
./shared-sqs --admin-token=dev-token-123 --port=4100 --loglevel=info > sqs.log 2>&1 </dev/null &
# креды демо-тенанта — в sqs.log
grep "seed: создан тенант" ~/sqs-test/sqs.log | tail -1
# проверка снаружи
curl -sS https://sqs.sinefo.ru/health
```
### 5.3. Откат
```bash
sudo rm /etc/nginx/conf.d/sqs-sinefo.conf && sudo nginx -t && sudo systemctl reload nginx
pkill -x shared-sqs
# бэкапы nginx на ВМ: /etc/nginx/conf.d.bak-*
```
## 6. Открытые вопросы
1. `QueueUrl` — внешний хост (`https://sqs.sinefo.ru`): нужен ли фикс формата (схема/host/порт)
и есть ли клиенты без явного `endpoint_url` (вопрос №5 мануала).
2. Egress ВМ: `curl https://api.ipify.org` с ВМ вернул пусто — влияет на billing (PG) и JWT-API.
3. Дальше по мануалу: Шаг 2 (разбиение data-plane/control-plane), Шаг 3 (вынос состояния).