[2026-09-29] eagle: family/how-to/arr-stack-taiga.md family/plans/lidarr-taiga-deploy.md personal/plans/flaresolverr-taiga-deploy.md personal/plans/lidarr-taiga-and-indexer-unblock.md personal/tech/flaresolverr-taiga.md personal/tech/prowlarr-flaresolverr-cloudflare.md

This commit is contained in:
Alexey Martemyanov committed 2026-09-29 00:47:45 +06:00
1 parent a3e7bddc09
commit d8313b126f
6 files changed
+225 -2287

No files matched your search

-410
View File
@@ -1,410 +0,0 @@
# FlareSolverr на Тайге + обход блокировок индексеров — план/отчёт
> 🟡 **СТАТУС 2026-09-29 (конец сессии): НЕ ЗАКРЫТА — регресс.** Prowlarr → RuTracker снова даёт **0**
> (`Invalid Credentials`, карантин `disabledTill 2026-09-28T15:47`). NoNaMe **47**, RuTor **33** — живы.
> 🔴 **Причина найдена:** FS-сессия `prowlarr` **сломана** — отдаёт 251 KB **Chrome-страницы ошибки**
> вместо форума и **пустые cookies**. Причём она **переживает `docker restart flaresolverr`**.
> Диагноз «50 результатов» был поставлен на этой же сломанной сессии и оказался ложным:
> `len≈250 KB` ≠ «залогинен». **Причина отравления сессии не установлена** — открытый вопрос.
> 🔴 **Исправление (чеклист):** `sessions.destroy prowlarr` → `DELETE FROM IndexerStatus` SQL →
> проверка **по cookies `bb_session`** и реальным `search`. Полный чеклист —
> [[personal/tech/flaresolverr-taiga]] §«ЧЕКЛИСТ "не всё зелёное"».
> 🔴 **Истинная причина исходного «не логинится»:** в Prowlarr хранится пара `mallexxx` /
> `m@n*w$uperP@$$w0rD`, а все диагностические тесты шли **другим аккаунтом** (`keropjan_88`).
> Капча RuTracker — **симптом неверного пароля**, а не блокер. Кука авторизации — **`bb_session`**.
> 🔴 **Откат:** эксперимент с образом `flaresolverr-vnc` + noVNC (порт 6080, роут
> `vnc.mallexxx.duckdns.org`, Caddy в `media_net`) **снесён как ненужный** — гипотеза
> «капчу решает человек» оказалась ложной. FS вернулся на штатный образ. **Откат выполнен верно.**
> 🔧 **Журнал отката** (что снесено, питфоллы `docker rm`/bind-mount/root-каталог) —
> [[personal/tech/flaresolverr-taiga]] §«ЖУРНАЛ ОТКАТА».
> Полный разбор и питфоллы — [[personal/tech/flaresolverr-taiga]].
> Связано: [[personal/plans/lidarr-taiga-and-indexer-unblock]],
> [[family/projects/media-toolbox-taiga]], [[family/how-to/arr-stack-kraken]],
> [[personal/tech/prowlarr-flaresolverr-cloudflare]], [[family/plans/lidarr-taiga-deploy]].
>
> 🔴 **Питфолл №1:** FS-сессия может быть «отравлена» — `sessions.list` + `sessions.destroy`.
> 🔴 **Питфолл №2:** `POST /indexer/test` карантин **НЕ снимает, а продлевает**.
> Карантин живёт в `IndexerStatus` и снимается **только SQL** (`DELETE FROM IndexerStatus`).
> 🔴 **Порядок диагностики «Auth Failed»:** (1) `sessions.list` → убить сессию; (2) cookies → есть ли
> `bb_session`; (3) пара логин/пароль из `prowlarr.db`; (4) `IndexerStatus`. **Не по длине HTML!**
## ФАКТИЧЕСКОЕ СОСТОЯНИЕ (2026-09-28, после деплоя)
### Контейнер `flaresolverr` — ✅ работает
`/mnt/RED_2TB/docker/arr/docker-compose.yml` (122 строки), сервис `flaresolverr`:
```yaml
flaresolverr:
image: ghcr.io/flaresolverr/flaresolverr:latest
container_name: flaresolverr
restart: unless-stopped
environment:
- LOG_LEVEL=warning
- BROWSER_TIMEOUT=60000
- TZ=Asia/Novosibirsk
- PROXY_URL=socks5://vless-proxy:1080 # ← ключ: обход DNS-блока
ports:
- "8191:8191"
networks:
- media_net
shm_size: 1gb # ← Кра́кен: 64 MB убивал Chrome
sysctls:
- net.ipv6.conf.all.disable_ipv6=1
```
Поднят: `cd /mnt/RED_2TB/docker/arr && docker compose up -d flaresolverr` → `Up`, рестартов 0.
Логи пусты при `LOG_LEVEL=warning` — это норма (пароли трекеров не пишутся).
**Swap НЕ трогали.** Alex отклонил идею: «Назуя тебе свап? Памяти мало что-ли?» — и был прав:
RAM 21 GB, FS держит 710 MB / 21 GB, CPU 0.68%. Swap на этом хосте не нужен.
### 🔑 ГЛАВНОЕ ОТКРЫТИЕ №1: FS нужен `PROXY_URL`, иначе он бесполезен на Тайге
На Кра́кене DNS-блока нет → FS ходит в трекер напрямую. **На Тайге DNS-блок есть** → FS сам
должен ходить через `vless-proxy`. Решается глобальной env **`PROXY_URL`** (НЕ `HTTPS_PROXY`):
| Что | Значение |
|---|---|
| Переменная | **`PROXY_URL`** (проверено по DeepWiki FlareSolverr §4.2) |
| Формат | **со схемой обязателен**: `socks5://vless-proxy:1080` |
| Приоритет | request > session > global |
| Авторизация | не нужна (`PROXY_USERNAME`/`PROXY_PASSWORD` пусты) |
⚠️ Prowlarr обращается к FS с параметром `session`; при наличии сессии request-прокси
**игнорируется** → срабатывает именно global `PROXY_URL`. Схема A (env) — единственный
рабочий вариант: у Prowlarr-прокси `Socks5` только host/port/user/pass, поля «передать в FS» нет.
### 🔑 ГЛАВНОЕ ОТКРЫТИЕ №2: FS-сессия НЕ наследует `PROXY_URL`
Самая дорогая грабля задачи. `PROXY_URL` применяется к Chrome **в момент создания сессии**.
Сессия, созданная **до** появления `PROXY_URL`, остаётся без прокси навсегда и падает
с `ERR_NAME_NOT_RESOLVED`, а Prowlarr трактует это как «blocked by CloudFlare Protection».
**Имя сессии Prowlarr — `prowlarr`.** Фикс: `sessions.destroy` → пересоздастся сама.
> ⚠️ После ЛЮБОЙ правки `PROXY_URL` — убить сессию `prowlarr`.
> ✅ При обычном перезапуске FS (watchtower/reboot) проблема не повторится.
### Prowlarr: прокси-элементы и теги
| Элемент | id | Настройки | tags |
|---|---|---|---|
| `vless-socks5` (Socks5) | 1 | host `vless-proxy`, port `1080` | `[1]` |
| `flaresolverr` (FlareSolverr) | 2 | host `http://flaresolverr:8191/`, **requestTimeout 180** | `[2]` |
Теги: `proxy` = id 1, `flaresolverr` = id 2.
**Индексерам нужны ОБА тега** — `proxy` (DNS-обход через SOCKS5) **и** `flaresolverr`
(CF-челлендж). Финальное состояние:
| id | Индексер | tags | Статус |
|---|---|---|---|
| 1 | RuTracker | **[1, 2]** | ✅ valid |
| 4 | NoNaMe Club | **[1, 2]** | ✅ valid |
| 5 | Kinozal | **[1, 2]** | ✅ valid |
| 6 | Kinozal (M) | **[1, 2]** | ✅ valid |
| 2 | RuTor | [1] | ✅ valid |
| 3 | Byrutor | [1] | ✅ valid |
### Пруф работы FS (не UI — прямой HTTP)
```bash
docker exec prowlarr sh -c 'curl -s --max-time 150 -X POST http://flaresolverr:8191/v1 \
-H "Content-Type: application/json" \
-d "{\"cmd\":\"request.get\",\"url\":\"https://rutracker.org/forum/login.php\",\"maxTimeout\":130000}"'
# → {"status": "ok", "message": "Challenge solved!", "solution": {"status": 200, ...}}
```
Результаты прямых тестов:
| URL | Ответ FS |
|---|---|
| `rutracker.org/forum/index.php` | ok / Challenge not detected / 200 |
| `rutracker.org/forum/login.php` | ok / **Challenge solved!** / 200 |
| `kinozal.me/browse.php` | ok / **Challenge solved!** / 200 |
| `nnmclub.to/forum/index.php` | ok / Challenge not detected / 200 |
| `sessions.create` | ok / Session created successfully / v3.5.2 |
### 🔴 ПИТФОЛЛ: `PUT /api/v1/indexer/N` падает 400 из-за теста FS
Prowlarr при PUT **сразу тестирует** индексер. Если FS в этот момент не прошёл — **HTTP 400**
с `validationFailures` (`HTTP request failed: [500:InternalServerError] [POST] at
[http://flaresolverr:8191/v1]`). Теги при этом **НЕ применяются** (откатываются).
Обход — **`?forceSave=true`**:
```bash
curl -X PUT -H @/tmp/h.txt -H "Content-Type: application/json" \
-d @/tmp/ix1-new.json "http://localhost:9696/api/v1/indexer/1?forceSave=true"
# → 202 (сохранил, тест пропущен)
```
### 🔴 ПИТФОЛЛ: `requestTimeout=60` у FS-прокси МАЛО
Дефолт прокси-элемента — 60 с. CF-челлендж на `/forum/login.php` и kinozal занимает **78–97 с** →
`Error solving the challenge. Timeout after 60.0 seconds`, индексер краснеет.
**Поднять до 180** (правка PUT-ом прокси-элемента `/2`). PUT → **202**.
### 🔴 ПИТФОЛЛ: `testall` параллельный → Chrome захлёбывается
`POST /api/v1/indexer/testall` тестирует все 6 индексеров **одновременно**, а Chrome в FS — один.
Часть челленджей отваливается по таймауту (ложный «blocked by CloudFlare Protection»).
**Правило диагностики:** если `testall` показал Cloudflare-блок — перепроверять **одиночным**
`request.get` с большим `maxTimeout`, а не верить `testall`. Это грабля, стоившая времени.
### ПЛАН ВЫПОЛНЕН — по фазам
| Фаза | Что | Статус |
|---|---|---|
| 0 | Внешняя блокировка / DNS-прокси | ✅ была закрыта ранее (2026-09-26) |
| 1 | FlareSolverr контейнер + `PROXY_URL` | ✅ выполнено |
| 2 | Прокси-элемент + теги `[1,2]` + карантин | ✅ выполнено |
| 3 | Проверка поиска | ✅ 256 результатов |
| 4 | `sessions.destroy` (не входила в план, найдена по ходу) | ✅ выполнено |
### 🔴 Что чуть не стало ложным выводом (методический урок)
Первые прогоны дали «4/6», и вывод «Kinozal упирается в скорость CF-челленджа, не в конфиг»
был **неверным**. Спасло то, что замер падения показал **7 секунд** — при 78–97 с у челленджа
это физически не таймаут. Отсюда найден `ERR_NAME_NOT_RESOLVED` и корень.
**Урок:** когда «таймаут» короче самого медленного шага — это не таймаут, а другая ошибка.
Смотреть фактическое время, а не текст сообщения.
### Бэкапы (перед изменениями)
| Файл | Путь |
|---|---|
| compose (до правки) | `~truenas_admin/docker-compose.yml.bak-20260928-flaresolverr` (2313 B) |
| индексеры (до тегов) | `~/backup-indexers-20260928-flaresolverr.json` (390701 B, на Mac) |
### Рабочая техника API-вызовов (повтор от грабель)
Ключ Prowlarr в **файл** внутри контейнера + `-H @/tmp/h.txt` — иначе кавычки ломаются на
уровне ssh/sh, и API отвечает **401** даже с верным ключом:
```bash
docker exec prowlarr sh -c 'printf "X-Api-Key: 35c8b3f497114076a6150ea0d9504845" > /tmp/h.txt; \
printf "Content-Type: application/json" > /tmp/ct.txt'
docker exec prowlarr sh -c 'curl -s -H @/tmp/h.txt http://localhost:9696/api/v1/indexer'
```
Разбор JSON — **на хосте** (`python3` в контейнере Prowlarr НЕТ: `sh: python3: not found`).
Долгие операции (`testall`) — через `docker exec -d` в фон + файл-маркер `.done`.
`curl` без `--max-time` виснет, если FS не отвечает — всегда ставить лимит.
## Разведка (2026-09-28, что было ДО работы)
### Что УЖЕ было сделано (не переделывать!)
Прошлый план (2026-09-26) предполагал два блока. **Блокер №2 (DNS) был закрыт**, а с ним
и большая часть Фазы 0:
| Что | Факт 2026-09-28 |
|---|---|
| `vless-proxy` в `media_net` | ✅ есть, IP `172.16.17.6`, резолвится из prowlarr |
| Прокси в Prowlarr | ✅ `vless-socks5` (id=1), Socks5, host `vless-proxy`, port `1080` |
| Тег | ✅ `proxy` (id=1); навешен и на прокси, и на **все 6 индексеров** |
| Работоспособность прокси | ✅ `rutracker.org` → **301**, `nnmclub.to` → **200**, `kinozal.me` → **200** |
| URL индексеров | ✅ Kinozal/Kinozal(M) уже на `kinozal.me` (не мёртвый `.tv`) |
| Поиск через Prowlarr | ✅ RuTor 100 + Byrutor 6 на «matrix» |
### Что ОСТАВАЛОСЬ (суть задачи)
Остаточная проблема — **не DNS, а Cloudflare**. Прямой факт:
```
GET https://rutracker.org/forum/login.php через socks5h://vless-proxy:1080
→ <title>Just a moment...</title> + challenges.cloudflare.com ← JS-челлендж
```
`IndexerStatus` (без снятия): карантин у id **1 (RuTracker)**, **5 (Kinozal)**, **6 (Kinozal M)**.
`initialFailure = 2026-05-20` (день деплоя).
**FlareSolverr на Тайге отсутствовал** (`docker ps -a | grep flare` → пусто).
### Риски (грабли Кра́кена — что проверяли заранее)
Из [[personal/tech/prowlarr-flaresolverr-cloudflare]] §2026-09-24 — там FlareSolverr ушёл
в **crash-loop**, Chrome не поднимался под chromedriver.
| Условие | Кра́кен (сломано) | Тайга | Итог |
|---|---|---|---|
| `/dev/shm` | 64 MB → Chrome падал | 64 MB | ✅ задали `shm_size: 1gb` |
| swap | пуст → пик старта убивал | пуст, Swap=0 | ✅ **не нужен** — RAM 21 GB |
| RAM | мало | 21 GB, 5.6 GB free | ✅ хватает |
| IPv6 | `::1 localhost` | — | добавили `disable_ipv6=1` (безвредно) |
## История
- **2026-09-26** — разведка под Lidarr. Найдено: DNS-блок провайдера (NXDOMAIN на 4 трекера),
`vless-proxy` не в `media_net`. Прокси-маршрут для Prowlarr починен в тот же день (3/6 индексеров).
Остаток — Cloudflare. Первоначальный план — [[personal/plans/lidarr-taiga-and-indexer-unblock]].
- **2026-09-28** — разведка: DNS-блокер уже закрыт, остаток — Cloudflare, FS отсутствует.
Составлен план, ждал «go». Ничего не изменено.
- **2026-09-28 (тот же день, после «Го»)** — **ВЫПОЛНЕНО.** FlareSolverr развёрнут, 6/6 индексеров,
health `[]`, поиск 256. Питфоллы: `requestTimeout` 60→180, `?forceSave=true`, гонка `testall`,
и главный — **смена `PROXY_URL` не обновляет существующую FS-сессию**.
- **2026-09-28 (вечер, тот же день)** — **Lidarr дозакрыт до прод-уровня.** SkyHook-блокер снят:
`api.lidarr.audio` → 403 прямым, 200 через прокси; **env `HTTP_PROXY` Lidarr НЕ читает**,
рабочий фикс — встроенный `config/host.proxyEnabled` → `vless-proxy:1081`. Проверено
end-to-end: lookup → артист → **23 раздачи**. Попутно: созданы каталоги
`Downloads/{radarr,sonarr}` (Radarr/Sonarr их ждали), выявлен **неверный пароль RuTracker**.
Детали — [[family/plans/lidarr-taiga-deploy]], [[personal/tech/flaresolverr-taiga]].
## 🔴 2026-09-28 (ночь): НАЙДЕНА ИСТИННАЯ ПРИЧИНА ЗАЛИПА — таблица `IndexerStatus`
Итог долгой петли: «снять карантин тестом → warning возвращается → тест падает заново».
Петля не сходилась, потому что **причина лежит в БД Prowlarr, а не в прокси/FlareSolverr**.
**Пруф — прямой дамп таблицы (хост Тайги, `sqlite3` в контейнере НЕТ, на хосте ЕСТЬ):**
```bash
DB=/mnt/RED_2TB/docker/arr/prowlarr/prowlarr.db
sqlite3 "file:$DB?mode=ro" \
"SELECT Id, ProviderId, InitialFailure, MostRecentFailure, EscalationLevel, DisabledTill FROM IndexerStatus;"
```
```
Id ProviderId InitialFailure EscalationLevel DisabledTill
1 5 Kinozal 2026-09-28 09:43:24 2 2026-09-28 10:08
2 6 Kinozal M 2026-09-28 09:32:45 2 —
3 4 NoNaMe 2026-09-28 07:57:42 0 —
4 2 RuTor 2026-05-20 05:45:18 0 —
5 1 RuTracker 2026-09-28 09:04:28 9 2026-09-29 09:46 ← СУТКИ
6 3 Byrutor — 0 —
```
🔴 **RuTracker: `EscalationLevel = 9` (максимум), `DisabledTill` = +24 ч.** Prowlarr сам
выключил индексер на сутки. Пока запись держится, `caps` отдаёт **429**, Prowlarr не делает
новых попыток, фоновый health-чек Radarr/Sonarr/Lidarr бьёт по 429 → **warning каскадом во все
четыре сервиса**. Отсюда «Radarr health чист, а warning живёт» — он живёт не у Radarr.
⚠️ **Тест индексера карантин НЕ снимает, а ПРОДЛЕВАЕТ.** Наблюдалось вживую: `DisabledTill`
`15:44` → `21:45` после одного `POST /indexer/test`. То есть каждая попытка «починить тестом»
удлиняла блокировку. **Это и была петля.**
### ✅ РАБОЧИЙ ПЛАН СНЯТИЯ (согласован, 2 команды + бэкап)
На Кра́кене применялся тот же приём — см. [[family/how-to/arr-stack-kraken]]
§«(3) Блокировки индексера в БД — рестарт их НЕ сбрасывает».
**1. Бэкап через `.backup`, НЕ `cp`** (БД в WAL-режиме):
```bash
DB=/mnt/RED_2TB/docker/arr/prowlarr/prowlarr.db
TS=$(date +%Y%m%d-%H%M%S)
sqlite3 "file:$DB?mode=ro" ".backup /home/truenas_admin/prowlarr.db.bak-$TS"
shasum -a 256 "$DB" "$OUT" # сверить, что копия снята
```
✅ **Сделано:** `~/prowlarr.db.bak-20260928-032611` — 581 632 байт,
sha256 исходника `d792777c3545969dba57339d1b956f11aef40da91596b266839068a1a1af7845`.
**2. Стоп → очистка → старт** (⚠️ `docker stop` требует апрува Alex — истёк дважды):
```bash
docker stop prowlarr
sqlite3 "$DB" "DELETE FROM IndexerStatus WHERE ProviderId IN (1,5,6);"
docker start prowlarr
```
**3. Проверка:**
```bash
PK=$(cat /home/truenas_admin/pk.txt)
curl -s -H "X-Api-Key: $PK" http://localhost:9696/api/v1/indexerstatus # → пусто
for I in 1 5 6; do curl -s -o /dev/null -w "idx$I=%{http_code}\n" \
"http://localhost:9696/$I/api?t=caps&apikey=$PK"; done # → 200
```
**Таблицы в `prowlarr.db` (для справки):** `Indexers`, `IndexerStatus`, `IndexerProxies`,
`ApplicationIndexerMapping`, `IndexerDefinitionVersions`.
> ⚠️ **Урок:** health-эндпоинты arr-сервисов **не являются источником истины** о блокировках.
> На Кра́кене это записано отдельно: «`GET /api/v1/health` и `/api/v1/indexerstatus` НЕ показывают
> причины блокировки» — авторитет за `prowlarr.debug.txt` и таблицей `IndexerStatus`.
> На Тайге `indexerstatus` причины показывал, но **снятие через API не срабатывало** — только SQL.
## Остаток после сессии 2026-09-28 (не блокирует Prowlarr/FlareSolverr)
1. ✅ **СНЯТО через SQL 2026-09-29.** `docker stop prowlarr` → `DELETE FROM IndexerStatus;` →
`docker start prowlarr`. Результат: `rows=0`, `quick_check=ok`, 6 определений на месте,
`health` → `[]`, `indexerstatus` → `[]`, **все 6 `caps` → 200**.
🔴 **НО поиск не починился:** через минуты CF-индексеры снова в карантине, поиск даёт
`total=79` (только NoNaMe 47 + RuTor 32). Причина — **отсутствие `bb_data`**, см. п. 6.
Скрипт: `/tmp/clear_indexerstatus.sh`. Бэкап: `~/prowlarr.db.bak-20260928-032611`.
2. ✅ **Пароль RuTracker — вопрос закрыт: пароль ВЕРНЫЙ.** Проверено `request.post` через FS:
`len=251 792`, форма логина не вернулась. Первый диагноз «пароль неверен» был ложным —
признак «форма вернулась» проверять по **`final_url` + длине HTML**, а не по подстроке
`login_username` (она есть и на залогиненной странице). Подтверждено и через сессию
`prowlarr`: логин `254 410`, поиск `254 745`, `Auth Failed` в HTML отсутствует.
`Auth Failed` в Prowlarr при живом логине = **следствие `IndexerStatus`**, а не пароля.
3. ✅ **Radarr/Sonarr:** `docker restart radarr sonarr lidarr` выполнен → `RemotePathMappingCheck`
ушла, health **пуст** у обоих.
4. ⚠️ **RuTor:** `no results in the configured categories` — не блокировка. На Кра́кене тот же
дефект, лечение известно: RuTor не фильтрует по категориям, ему нужна **`8000(Other)`**,
не `5000`. На Тайге не применено.
5. **Приёмка Alex в UI:** `https://prowlarr.mallexxx.duckdns.org` → 6 зелёных;
`https://lidarr.mallexxx.duckdns.org` → поиск артиста работает. Alex подтвердил:
**«все зеленое, логин починен»**. Открытый вопрос по swap закрыт Alex (не нужен — RAM 21 GB).
6. 🔴 **ГЛАВНЫЙ НЕЗАКРЫТЫЙ ПУНКТ (2026-09-29): логин RuTracker не выполняется.**
В cookies сессии нет **`bb_data`** (кука авторизации) — только `cf_clearance` + `bb_guid`.
Лог Prowlarr: `FlareSolverrException: "Empty cookies returned by FlareSolverr"` (`FlareSolverr.cs:68`).
Форма индексера принимает только `username`/`password` — поля для cookie нет, подставить
живую сессию из браузера **нельзя**. Нужен Alex: зайти на `rutracker.org` браузером
**с того же IP** (`vless-proxy`), пройти капчу один раз, либо отключить капчу в профиле.
Полный разбор — [[personal/tech/flaresolverr-taiga]] §«ИТОГОВЫЙ КОРЕНЬ» и §«СВЕРКА С КРА́КЕНОМ».
7. 🔴 **«Как на Кра́кене» — НЕ рецепт (2026-09-29).** Проверено на живом Кра́кене:
капча-солвера там **нет** (только FlareSolverr, `requestTimeout: 60`), а карантин
**идентичен Тайге** — RuTracker/Kinozal/Kinozal(M) `EscalationLevel=9`, `DisabledTill=2026-09-27`.
**Обе площадки красные по одной и той же причине.** Не строить план на посылке
«на Кра́кене работает». Детали — [[personal/tech/flaresolverr-taiga]] §«СВЕРКА С КРА́КЕНОМ»,
[[family/how-to/arr-stack-kraken]].
## 🔴 СЕССИЯ 2026-09-29 (вечер): разбор идеи Alex + свой образ `flaresolverr-vnc`
**Задача Alex:** «ароматизировать процесс насколько возможно — уведомление в ТГ от hermes-taiga,
соединение моего браузера через 3x-ui через тот же туннель, выдача и установка куки обратно».
**Результат — три из четырёх идей отвергнуты фактами:**
| Идея | Вердикт | Причина |
|---|---|---|
| Свой браузер через 3x-ui по тому же туннелю | ❌ | `vless-proxy` — **клиент** xray, не сервер. `cf_clearance` привязан к **IP + UA + TLS-fingerprint** |
| Впихнуть куки обратно в Prowlarr | ❌ | Индексер RuTracker принимает только `username`/`password` — поля для cookie нет |
| Капча-солвер FS (`CAPTCHA_SOLVER`) | ❌ | **Официально non-functional** (DeepWiki FS; issue #1452 закрыт без решения) |
| Ручной вход **в Chrome внутри FS** + persistent профиль | ✅ | Единственный рабочий путь |
**Сделано (шаг 1 из 3) ✅:**
- Собран образ **`flaresolverr-vnc:latest`** — база FS + `Xvfb` + `fluxbox` + `x11vnc` + `novnc`
+ `supervisor`, 5 процессов. Файлы: `/mnt/RED_2TB/docker/arr/fs-vnc/{Dockerfile,supervisord.conf,entrypoint-vnc.sh}`.
- Compose: образ подменён, добавлены порт **`6080:6080`** (noVNC) и volume
`/mnt/RED_2TB/docker/arr/flaresolverr-config:/config` (persistent профиль Chromium).
- Профиль вынесен через `XDG_CONFIG_HOME=/config/chromium-profile`, FS запущен с `HEADLESS=false`.
- Проверено: `docker compose config -q` OK, сборка ~215 с, контейнер `Up`,
API → `{"status":"ok","version":"3.5.2"}`, `http://localhost:6080/vnc.html` → **200**.
- Бэкап: `/mnt/RED_2TB/docker/arr/docker-compose.yml.bak-20260928-profvol` (2723 B).
## 🔴 ОТКАТ: эксперимент `flaresolverr-vnc` снесён (2026-09-29)
Раздел ниже — **история неудачного эксперимента**, оставлен чтобы не повторять.
Итог: **гипотеза «капчу решает человек» была ложной** → всё построенное снесено.
**Что было построено и что с ним стало:**
| Артефакт | Статус |
|---|---|
| Образ `flaresolverr-vnc:latest` (Xvfb+fluxbox+x11vnc+noVNC) | ❌ снесён, FS вернулся на `ghcr.io/flaresolverr/flaresolverr:latest` |
| Порт `6080:6080` в compose | ❌ убран |
| Volume `/mnt/RED_2TB/docker/arr/flaresolverr-config:/config` | ❌ убран |
| Каталог сборки `/mnt/RED_2TB/docker/arr/fs-vnc/` | ❌ удалён |
| Роут `vnc.mallexxx.duckdns.org` в Caddyfile | ❌ убран, config валиден, reload сделан |
| `docker network connect media_net caddy` | ❌ откачен (`network disconnect`), Caddy снова в `caddy_default` + `transmission_default` |
**Почему это было лишним:** Prowlarr логинится на RuTracker **сам**, без VNC и без человека.
Капча в ответе трекера была **реакцией на неверный пароль** (тесты шли аккаунтом `keropjan_88`
вместо хранящегося в Prowlarr `mallexxx`), а не требованием трекера к живому человеку.
⚠️ **Правильный порядок при «Auth Failed» — начинать с данных, а не со сборки инфраструктуры:**
```bash
DB=/mnt/RED_2TB/docker/arr/prowlarr/prowlarr.db
sqlite3 "file:$DB?mode=ro" "SELECT Settings FROM Indexers WHERE Id=1;"
# сверить username/password с тем, чем тестируешь — ЭТО ПЕРВЫЙ ШАГ
```
⚠️ **Уточнение методики:** Alex работает по схеме **коммит → правка → заливка → проверка Alex**.
Но это не значит, что под каждую гипотезу нужно строить инфраструктуру: сначала проверять
исходные данные (пара логин/пароль в БД), и только потом — строить.
@@ -1,336 +0,0 @@
---
title: Lidarr на Тайге + разблокировка индексеров — план
created: '2026-09-26'
updated: '2026-09-26'
type: plan
namespace: personal
status: awaiting-approval
tags:
- lidarr
- taiga
- truenas
- arr
- music
- dns
- prowlarr
- blocked
related:
- '[[family/projects/media-toolbox-taiga]]'
- '[[family/how-to/jellyfin-config]]'
- '[[personal/tech/music-tags-repair-truenas]]'
- '[[personal/tech/truenas-nfs4-acl-and-arrmultiuser]]'
---
# Lidarr на Тайге + разблокировка индексеров — план
> **Статус Фазы 0: ✅ ЗАКРЫТА 2026-09-28.** DNS-блок обойдён через `vless-proxy` (SOCKS5),
> Cloudflare — через **FlareSolverr** (развёрнут 2026-09-28). Остаток: тег FS на NoNaMe,
> проверка Kinozal. Полный разбор — [[personal/plans/flaresolverr-taiga-deploy]].
> Lidarr уже развёрнут (см. [[family/plans/lidarr-taiga-deploy]] §2026-09-28).
> Задача поставлена 2026-09-26: «поставить lidarr в дополнение к sonarr/prowlarr, настроить на музыку,
> синк с jellyfin, проверка что весь стек живой».
> Разведка выполнена, найдены 2 блокера, план ниже.
## 🔴 ГЛАВНАЯ НАХОДКА СЕССИИ: DNS-блок у провайдера Тайги
**Стек НЕ сломан. Индексеры мертвы из-за внешней блокировки на стороне Тайги.**
Диагностика (2026-09-26, все команды с живой машины):
```bash
# Из контейнера prowlarr:
docker exec prowlarr sh -c "wget -qO- --timeout=12 -S 'https://rutracker.org/'"
# → wget: bad address 'rutracker.org'
docker exec prowlarr sh -c "wget -qO- --timeout=12 -S 'https://byrutgame.org/'"
# → HTTP/1.1 200 OK ← этот резолвится
```
```bash
# На хосте TrueNAS, ДВА разных резолвера:
nslookup rutracker.org 192.168.2.2 # роутер → NXDOMAIN
nslookup rutracker.org 8.8.8.8 # Google → NXDOMAIN
nslookup google.com 192.168.2.2 # → OK (142.250.181.238)
```
**Вывод:** NXDOMAIN приходит **и с роутера, и с 8.8.8.8** → это **не Pi-hole и не роутер**.
Блок на стороне аплинка Тайги (провайдер Ростелеком / региональный DNS-фильтр).
**Что НЕ резолвится (все 4 трекера):** `rutracker.org`, `rutor.info`, `kinozal.tv`, `nnmclub.to`
**Что резолвится:** `byrutgame.org` (185.200.198.230), `google.com`
> ⚠️ Это **другой** класс проблемы, чем задокументированные ранее «Cloudflare 403 на
> `indexers.prowlarr.com`» и «RuTracker Cloudflare Turnstile». Здесь **DNS не отдаёт IP вообще** —
> до Cloudflare/TLS дело не доходит.
### Следствие в Prowlarr
```
GET /api/v1/health →
"Indexers unavailable due to failures for more than 6 hours:
RuTracker, RuTor, NoNaMe Club, Kinozal, Kinozal (M)"
GET /api/v1/indexerstatus → 5 записей, у всех:
disabledTill = "2026-09-27T08:07:26Z" (сутки карантина)
initialFailure = "2026-05-20T05:4x:xx" ← ЛОМАЕТСЯ С ДНЯ ДЕПЛОЯ, не «сейчас»
```
> 🔑 **`initialFailure` = 2026-05-20** — дата первоначального деплоя стека.
> Значит индексеры через Prowlarr на Тайге **не работали ни одного дня**. Это не регресс.
В Radarr/Sonarr это даёт каскад:
```
IndexerLongTermStatusCheck error All indexers are unavailable due to failures for more than 6 hours
IndexerRssCheck warning All rss-capable indexers are temporarily unavailable
IndexerSearchCheck warning All search-capable indexers are temporarily unavailable
```
## 🔴 БЛОКЕР 2: vless-proxy НЕ виден из media_net
Задокументировано в `media-toolbox-taiga.md`: «vless-proxy доступен в `media_net` как
`vless-proxy:1080` (SOCKS5)». **Факт 2026-09-26 — это НЕ ТАК:**
```bash
docker inspect vless-proxy --format '{{range $n,$c := .NetworkSettings.Networks}}{{$n}} {{$c.IPAddress}}{{end}}'
# hermes_taiga_net 172.16.15.2 ← ТОЛЬКО одна сеть
docker exec prowlarr getent hosts vless-proxy
# NO DNS
```
`docker network inspect media_net` → участники: `prowlarr radarr transmission sonarr`
(**vless-proxy отсутствует**).
**Вывод:** прокси-маршрут для заблокированных индексеров, описанный в доке, **никогда не работал** —
не был реализован. При этом `docker exec prowlarr getent hosts xray-admin` → `172.16.1.9` (работает,
обе в `caddy_default`).
## Фактическое состояние стека (2026-09-26)
Всё проверено на живой машине. **Стек работает**, кроме индексеров.
| Сервис | Статус | UID | Порты | Сети |
|---|---|---|---|---|
| prowlarr | Up 3d | 950 | 9696 | media_net + caddy_default |
| radarr | Up 3d | 950 | 7878 | media_net + caddy_default |
| sonarr | Up 3d | 950 | 8989 | media_net + caddy_default |
| jellyfin | Up 7d | 950 | 8096 | caddy_default |
| transmission | Up 7d | 950 | 9091, 51413 | media_net + transmission_default |
| caddy | Up 3d | — | — | caddy_default |
Проект compose: `arr` (все 4 в `media_net` + `caddy_default`). `media_net` существует.
### Compose (актуальный, `/mnt/RED_2TB/docker/arr/docker-compose.yml`)
Все сервисы: `PUID=950 PGID=950 TZ=Asia/Novosibirsk`, `dns: [8.8.8.8, 8.8.4.4]`.
radarr/sonarr монтируют `/mnt/RED_2TB/storage:/storage`; jellyfin — `:ro`; prowlarr — только `/config`.
**У prowlarr НЕТ монтирования `/storage`.** Порты проброшены (`ports:`) — можно обращаться к API с хоста.
### Индексеры Prowlarr (все 6, `enable=true`)
| id | Name | definitionName | URL |
|---|---|---|---|
| 1 | RuTracker | `RuTracker.org` | rutracker.org |
| 2 | RuTor | `rutor` | rutor.info |
| 3 | Byrutor | `byrutor` | byrutgame.org ← **единственный живой DNS** |
| 4 | NoNaMe Club | `noname-club` | nnmclub.to |
| 5 | Kinozal | `kinozal` | kinozal.tv |
| 6 | Kinozal (M) | `kinozal-magnet` | kinozal.tv |
### Applications Prowlarr
| id | Name | syncLevel | baseUrl |
|---|---|---|---|
| 1 | Radarr | `fullSync` | `http://radarr:7878` |
| 2 | Sonarr | `fullSync` | `http://sonarr:8989` |
### Radarr — практические факты
- Root folder: `/storage/radarr` (id 1, accessible)
- Download client: `Transmission` (id 1, enable=true)
- Индексеров **5** (Byrutor не синкается — нет RSS):
`Kinozal (M)`, `Kinozal`, `NoNaMe Club`, `RuTor`, `RuTracker`
- ⚠️ **БАГ Prowlarr-синка:** baseUrl индексеров = `http://prowlarr:9696/6/` —
**БЕЗ `/prowlarr` urlBase**. Прямая проверка:
`docker exec radarr wget -qO- "http://prowlarr:9696/6/api?t=caps"` → **401 Unauthorized**
Ожидалось `http://prowlarr:9696/prowlarr/6/`. См. skill `arr-media-stack-setup`
§«Корень проблемы короткий URL в синхронизации индексеров».
⚠️ Но у Тайги `<UrlBase>` у prowlarr — **пустой** (`config.xml`), т.е. на этом хосте
форма `9696/6/` может быть и корректной. **Разобрать перед фиксом** — не менять вслепую.
### Ключи API (полные, сняты с живой машины)
| Сервис | Полный ключ |
|---|---|
| Prowlarr | `35c8b3f497114076a6150ea0d9504845` |
| Radarr | `51e201f2d61b4fe2a0c322d5e99349fe` |
| Sonarr | `b1eb9cdd5c804e6c956dc9c8bd305dc8` |
| Jellyfin | `eaglesetup2026taiga` |
### Питфолл: на Тайге нет curl И НЕТ python3 на хосте
Ранее задокументировано «нет curl и python3 в PATH хоста». **Уточнение 2026-09-26:**
`python3` **есть** — использовался для парсинга JSON (`python3 -c 'import json...'`).
Нет **`curl`** и **нет `sqlite3`** на хосте (sqlite3 — подтверждено в `jellyfin-config`).
**Рабочий паттерн для API-вызовов на Тайге:** `wget` **внутри контейнера** + `python3` на хосте для разбора:
```bash
# JSON забираем wget-ом ИЗ КОНТЕЙНЕРА (busybox wget: только -qO- / --header / --timeout)
ssh truenas_admin@mallexxx.duckdns.org \
"docker exec prowlarr sh -c 'wget -qO- --header=\"X-Api-Key: <KEY>\" http://localhost:9696/api/v1/health'"
# ↓ или в файл, затем разбор хостовым python3
ssh truenas_admin@... "docker exec prowlarr sh -c 'wget -qO- ... > /tmp/x.json'"
python3 -c 'import json; d=json.load(open("/tmp/x.json")); ...'
```
> ⚠️ **busybox wget НЕ поддерживает `-e use_proxy=yes`** (это GNU-опция). Для прокси-тестов внутри
> контейнеров нужен другой инструмент (в linuxserver-образах есть `curl`? — проверить) или
> тестировать с хоста. Проверено: `wget: unrecognized option: e`.
### Питфолл: shell-экранирование при выкачивании JSON через ssh
Кавычки в `--header="X-Api-Key: $K"` ломаются на нескольких уровнях ssh/sh. Рабочий приём —
**положить результат в файл внутри контейнера или на хосте**, потом разбирать отдельно.
`jq` с дефисами в ключах (`download-dir`) требует `.["download-dir"]`, не `.download-dir`.
### Питфолл: `/etc/resolv.conf` контейнеров
```
nameserver 127.0.0.11 ← Docker embedded DNS
search local
options ndots:0
```
Поэтому в контейнерах **нет `getent`** — использовать `nslookup`/`wget` для проверки DNS.
Хостовый `resolv.conf`: `domain local` + `nameserver 192.168.2.2`.
## RemotePathMapping — существующая ошибка (состояние 2026-09-26)
Transmission download-dir (факт):
```json
{"download-dir": "/mnt/storage/Downloads",
"incomplete-dir": "/mnt/storage/Downloads/transmission/incomplete",
"script-torrent-done-enabled": false,
"script-torrent-done-filename": "",
"rpc-whitelist": "172.16.*.*",
"rpc-url": "/transmission/"}
```
Radarr/Sonarr health:
```
RemotePathMappingCheck error
"download client Transmission places downloads in /storage/Downloads/radarr
but this directory does not appear to exist inside the container"
```
> 🔑 **Фактическая причина (важно, опровергает старую доку):** Transmission **не раскладывает**
> по `Downloads/radarr` — download-dir плоский `/mnt/storage/Downloads`. Radarr ОЖИДАЕТ
> подкаталог категории (`/storage/Downloads/radarr`), которого нет.
>
> **Задокументированный в `media-toolbox-taiga.md` маппинг `host=transmission`,
> `remotePath=/mnt/storage/Downloads/`, `localPath=/storage/Downloads/` — НЕ ПРИМЕНЁН**
> (в API Radarr/Sonarr записей remotepathmapping нет, health жалуется).
>
> **Второй слой:** Transmission монтирует `/mnt/storage`, radarr — `/storage`. Один и тот же
> хост-путь под двумя именами. Prowlarr/radarr-контейнеры **не видят `/mnt/storage`**.
## ПЛАН
### Фаза 0 — внешняя блокировка (БЛОКЕР для всего остального)
> ✅ **ЗАКРЫТА 2026-09-28 — НЕ ВЫПОЛНЯТЬ ПОВТОРНО.** `vless-proxy` подключён к `media_net`
> (persistent, `172.16.17.6`), прокси `vless-socks5` (id=1) создан, тег `proxy` (id=1) навешен
> на все 6 индексеров. Проверено вживую: `rutracker.org` → 301, `nnmclub.to` → 200,
> `kinozal.me` → 200; поиск RuTor 100 + Byrutor 6. **Остаточная проблема — Cloudflare**
> (RuTracker/Kinozal/Kinozal M, карантин id 1/5/6), решается FlareSolverr.
> Текущий активный план: [[personal/plans/flaresolverr-taiga-deploy]].
1. Подключить `vless-proxy` к `media_net`:
`docker network connect media_net vless-proxy` (runtime) + добавить сеть в compose
`/mnt/RED_2TB/docker/vless-proxy/docker-compose.yml` (иначе потеряется при пересоздании).
2. Проверить из prowlarr: `getent`/`nslookup vless-proxy`, затем доступ до `rutracker.org`
**через прокси** (SOCKS5 `vless-proxy:1080`).
3. Если через прокси резолвится — создать Proxy в Prowlarr (Settings → Indexers → Add Proxy,
SOCKS5, host `vless-proxy`, порт `1080`, тег `proxy`) и повесить тег `proxy` на
RuTracker / RuTor / Kinozal / NoNaMe.
4. Сбросить `indexerstatus`: `POST /api/v1/indexer/testall` (снимает `disabledTill`).
5. **ПРИЁМКА ALEX:** `https://prowlarr.mallexxx.duckdns.org` → Indexers → Test All → зелёные.
> ⚠️ Byrutor (id 3) резолвится — его прокси не нужен, но в Radarr он не синкается (нет RSS).
> Он полезен только в Sonarr/Radarr с `enableRss: false` — применимо и к Lidarr.
### Фаза 1 — Lidarr контейнер
1. **Бэкап** `/mnt/RED_2TB/docker/arr/docker-compose.yml` → `~truenas_admin/` (не в
`/mnt/RED_2TB/backup` — он root-owned, truenas_admin туда не пишет).
2. Добавить сервис `lidarr` по образцу `radarr`:
- image `lscr.io/linuxserver/lidarr:latest`
- `PUID=950 PGID=950 TZ=Asia/Novosibirsk`, `dns: [8.8.8.8, 8.8.4.4]`
- port `8686:8686`
- volumes: `/mnt/RED_2TB/docker/arr/lidarr:/config`, `/mnt/RED_2TB/storage:/storage`
- networks: `media_net` + `caddy_default`
3. Поднять **из правильной папки**: `cd /mnt/RED_2TB/docker/arr && docker compose up -d lidarr`
(не через временную копию compose — name-conflict).
4. Caddy: добавить блок `lidarr.mallexxx.duckdns.org { reverse_proxy lidarr:8686 }`.
Caddyfile root-owned → **только через alpine-контейнер** (`docker run --rm -i -v /:/host:rw alpine ...`,
см. skill `truenas-caddy-service-deploy`). Отправлять **весь файл**, не патч.
5. **ПРИЁМКА ALEX:** `https://lidarr.mallexxx.duckdns.org` открывается.
### Фаза 2 — Lidarr на музыку
1. Root folder — **РЕШЕНИЕ АЛЕКСА НУЖНО** (см. вопросы ниже).
2. Download client — Transmission: host `transmission`, port `9091`, urlBase `/transmission/`,
category `lidarr`.
3. Индексеры: добавить Application `Lidarr` в Prowlarr (`syncLevel: fullSync`,
`baseUrl: http://lidarr:8686`) — либо вставить Torznab вручную, если синк не пройдёт.
> ⚠️ Lidarr требует **audio-категории (3000-я серия)** в профиле индексера. Посмотреть,
> отдают ли их наши трекеры — RuTracker/Kinozal обычно да; RuTor — нет (см. skill: RuTor
> не даёт movie-категорий; для audio проверить отдельно).
4. `preferMagnetUrl: true` — применить (нет дневного лимита на .torrent).
5. Прокси-тег для заблокированных (из Фазы 0).
6. **ПРИЁМКА ALEX:** тестовый поиск артиста → релиз найден → торрент ушёл в Transmission.
### Фаза 3 — синк с Jellyfin
> 🔴 **ЗАБЛОКИРОВАНО.** Создавать `collectionType=music` на текущих тегах нельзя:
> 7906 файлов → `mojibake` 2759, `lost` 662 (данные уничтожены), `empty` 1026, `partial` 2920.
> Jellyfin раскладывает музыку **по тегам**, не по папкам → получится свалка `Unknown Artist`.
> Полный контекст: [[personal/tech/music-tags-repair-truenas]] — этапы 1–2 готовы (CSV v2),
> ждёт апрув Alex, правки файлов не начаты.
1. Решить порядок (см. вопрос 2 ниже).
2. `/storage/Music` **уже смонтирован** в jellyfin (ro) — доп. монтирование НЕ нужно.
3. Создание: `POST /Library/VirtualFolders?name=Music&collectionType=music&paths=/storage/Music`
(**name/paths в query string**, не в body — Jellyfin 10.11).
4. Возможный митигирующий вариант: `EnableFolderView` — навигация по папкам, теги вторичны.
5. **ПРИЁМКА ALEX:** вкладка Music → треки видны.
### Фаза 4 — приёмка всего стека
1. `docker ps` — все 6 (+ lidarr) Up, uid 950.
2. Radarr/Sonarr/Lidarr health — без ошибок Indexer* и RemotePathMapping.
3. Разобрать RemotePathMapping (см. раздел выше) — нужен подкаталог категории в Transmission
**или** корректный маппинг.
4. **ПРИЁМКА ALEX:** панели открываются, плейбек идёт, поиск работает.
## ❓ ВОПРОСЫ, ЖДУЩИЕ ОТВЕТА АЛЕКСА
1. **Куда Lidarr складывает музыку?**
- (A) отдельный staging `/storage/Music-lidarr` + router-симлинки в `Music/`
— безопасно, не трогает 7890 существующих файлов. **Рекомендую.**
- (B) прямо в `/storage/Music` с отключённым переименованием — риск конфликтов с существующей
категорийной структурой (`!Rock&Folk` и т.д.).
2. **Музыка в Jellyfin — до или после ремонта тегов?**
- Док от 2026-09-26: «сначала теги». Lidarr принесёт часть файлов с чистыми тегами,
но 7890 старых останутся битыми.
## Открытые техвопросы (разобрать по ходу)
- Баг «короткого URL» Prowlarr→Radarr: `http://prowlarr:9696/6/` vs `/prowlarr/6/`.
Нужно решить, корректен ли он при **пустом** `<UrlBase>` у prowlarr. 401 на `?t=caps` — сигнал,
что что-то не так, но не однозначно.
- Битый `image.imageHeight`/пост-обработка не в scope.
- RuTor не даёт movie-категорий; для audio проверить отдельно.
- Есть ли `curl` внутри linuxserver-образов (для прокси-тестов) — проверить.
## История
- **2026-09-26** — разведка, найдены 2 блокера (DNS-фильтр провайдера + vless-proxy не в media_net),
план составлен, ожидает 2 ответов Alex. Ничего не изменено.