diff --git a/family/how-to/arr-stack-kraken.md b/family/how-to/arr-stack-kraken.md index 01a798f4..ccef09ab 100644 --- a/family/how-to/arr-stack-kraken.md +++ b/family/how-to/arr-stack-kraken.md @@ -8,6 +8,7 @@ tags: [arr, radarr, sonarr, prowlarr, transmission, jellyfin, infra, kraken] related: - "[[tech/jellyfin-config]]" - "[[tech/arr-stack-taiga]]" + - "[[tech/prowlarr-flaresolverr-cloudflare]]" - "[[concepts/kraken-media-stack]]" --- @@ -112,9 +113,9 @@ Prowlarr → Radarr + Sonarr → Transmission → Jellyfin **Где менять:** `watchlist-sync/watchlist_sync/arr.py` строки `qualityProfileId: 7` (radarr_add ~L77, sonarr_add ~L112). НЕ редактировать профили вручную иначе watchlist-sync надо обновить на новый id. Создать/править профиль «WEB-4K (no remux)» — Radarr/Sonarr → Settings → Quality Profiles. -## Ports (default Docker network) +## Ports (Docker network `media_net`) -All services accessible at `kraken:`: +All services in the shared external network `media_net` — доступны друг другу по имени контейнера (`radarr:7878`, `prowlarr:9696`, `transmission:9091`, `flaresolverr:8191`) и с хоста по `kraken:`: | Service | Port | |--------------|------| @@ -123,6 +124,10 @@ All services accessible at `kraken:`: | Prowlarr | 9696 | | Transmission | 9091 | | Jellyfin | 8096 | +| FlareSolverr | 8191 | + +**Сеть (проверено 2026-09-20):** radarr, sonarr, prowlarr, transmission, flaresolverr — все в `media_net`. Пересечение сетей (radarr и transmission дополнительно ещё в `docker_default`) — нормально, роутинг по `media_net`. +Порядок починки, если контейнер выпал из сети: `sudo docker network connect media_net ` (обратимо, без пересоздания) либо `docker compose up -d` из каталога сервиса. ## Jellyfin библиотеки @@ -137,22 +142,23 @@ All services accessible at `kraken:`: > `movies-radarr` и `series-sonarr` НЕ добавлены в Jellyfin — router.py создаёт symlink'и из них в перечисленные пути. -## 🔴 Диагностика индексеров — «красные трекеры» (2026-09-20) +## Индексера Prowlarr — диагностика и починка (2026-09-20) -Полная диагностика запрошена Alex: «что с torrent трекерами в arr, красные». Диагноз снят по логам Prowlarr, не по теории. +> ✅ **Задача закрыта в тот же день.** Ниже — история диагностики (полезна как метод), а актуальное решение с командами — в секции «🔴 Индексера Prowlarr — починка Cloudflare (2026-09-20)». +> **Итог: было 3 «красных» из 6, стало 6/6 рабочих. Radarr 4/4, Sonarr 5/5 зелёные.** -### Фактическое состояние индексеров Prowlarr (id / name / enable / privacy) +Запрос Alex: «что с torrent трекерами в arr, красные». Диагноз снят по логам Prowlarr, не по теории. -| id | Индексер | enable | privacy | Реально работает? | -|----|----------|--------|---------|-------------------| -| 1 | RuTracker | true | semiPrivate | ❌ **красный** — Cloudflare | -| 5 | Kinozal | true | semiPrivate | ❌ **красный** — Cloudflare | -| 6 | Kinozal (M) | true | semiPrivate | ❌ **красный** — Cloudflare | -| 2 | RuTor | true | public | ✅ 100 результатов на «matrix» | -| 4 | NoNaMe Club | true | public | ✅ 50 результатов | -| 3 | Byrutor | true | public | ✅ 6 результатов | +### Что показывал UI на момент диагностики -`indexerstatus` пуст, и `health` показывает только warning про апдейт — то есть Prowlarr **сам себя маскирует**: он не пишет в health, а вместо этого помечает индексер «temporarily ignoring till <+24h>». Диагноз надо снимать из **debug-лога**, не из health API. +| id | Индексер | privacy | Было | Стало | +|----|----------|---------|------|-------| +| 1 | RuTracker | semiPrivate | ❌ красный (Cloudflare) | ✅ 48 результатов на «matrix» | +| 5 | Kinozal | semiPrivate | ❌ красный (Cloudflare) | ✅ 50 | +| 6 | Kinozal (M) | semiPrivate | ❌ красный (Cloudflare) | ✅ 50 | +| 2 | RuTor | public | ✅ 100 | ✅ 100 | +| 4 | NoNaMe Club | public | ✅ 50 | ✅ 50 | +| 3 | Byrutor | public | ✅ 6 | ✅ 6 | ### Root cause #1 — Cloudflare (RuTracker + Kinozal + Kinozal (M)) @@ -170,33 +176,22 @@ Debug|IndexerFactory|Temporarily ignoring indexer RuTracker till 09/21/2026 17:3 - RuTracker: CF **managed Turnstile** на `/forum/login.php` → Prowlarr не может залогиниться (нужен JS-челлендж). Аккаунт при этом может быть жив — падает именно логин. - Kinozal / Kinozal (M): kinozal.me тоже за Cloudflare, Prowlarr сам пишет «Flaresolverr may be required». -- Версия Prowlarr на момент диагностики: **v2.5.2.5491**, доступен апдейт **v2.6.5.5623**. +- Лечится FlareSolverr-прокси (см. решение). На момент диагностики версия была **v2.5.2.5491**. ### Root cause #2 — Docker network split (Radarr полностью без индексеров) ``` -radarr: docker_default 172.22.0.3 ← НЕ видит prowlarr +radarr: docker_default 172.22.0.3 ← НЕ видел prowlarr sonarr: media_net 172.23.0.2 prowlarr: media_net 172.23.0.3 -transmission: docker_default 172.22.0.2 ← НЕ виден сонаром +transmission: docker_default 172.22.0.2 ← НЕ был виден сонаром ``` Radarr `POST /api/v3/indexer/testall` → **все 4 индексера** `false`: `Unable to connect to indexer... Name does not resolve (prowlarr:9696)` -Sonarr `testall` (он в `media_net`, DNS резолвится) → доходит до Prowlarr и получает осмысленные ошибки: - -| Sonarr indexer id | Имя | Результат testall | -|---|---|---| -| 1 | RuTracker | ❌ `[429:TooManyRequests]` через Prowlarr (это самоисключение Prowlarr отдаёт как 429) | -| 2 | NoNaMe Club | ✅ `true` | -| 6 | Kinozal (M) | ❌ 429 (тот же эффект) | -| 8 | RuTor | ⚠️ `Query successful, but no results in the configured categories` — **не баг коннекта**: у Sonarr id=8 категории `[5000]`, а caps RuTor отдаёт `2000 5000 8000 100001 100002 100003`. tvsearch в Prowlarr живой: `t=tvsearch&q=lost` на `/prowlarr/2/api` → 100 ``. Лечится расширением категорий на стороне Sonarr. | -| 9 | Kinozal | ❌ 429 (тот же эффект) | - -**Analog:** Sonarr `health` → `error DownloadClientCheck: Unable to communicate with Transmission. Name does not resolve (transmission:9091)`. Тот же network-split, отдельный симптом. - -Вывод: **Radarr красный не из-за трекеров, а из-за сети.** У Sonarr красные = реальные трекеры (CF). +Вывод: **Radarr был красный не из-за трекеров, а из-за сети.** У Sonarr красные = реальные трекеры (CF). +Ключевой урок: compose-файлы уже содержали `media_net`, но контейнеры остались в старой сети — **проверять фактическое `docker inspect`, а не compose-файл**. ### ⚠️ Питфолл: `POST /api/v3/indexer/test` по одному id НЕ работает @@ -221,26 +216,22 @@ curl -s -H "X-Api-Key: $PKEY" "http://localhost:9696/prowlarr/api/v1/search?quer | jq -r 'group_by(.indexer)[] | "\(.[0].indexer): \(length)"' ``` -(`Prowlarr /api/v1/indexer/test` тоже возвращает 400 на `{indexerId}` — см. § Питфоллы скилла `torrent-agent-pipeline`.) - Поиск через Prowlarr полезнее теста индексеров: `?query=X&type=search` по умолчанию возвращает **до 100 результатов на индексер** (был соблазн прочитать «156 всего» как «по 26 на каждый» — неверно; смотреть `group_by(.indexer)`). -### План лечения (составлен 2026-09-20, ждёт подтверждения Alex) +### Итог и уроки -1. **FlareSolverr** — развернуть контейнер на Kraken (порт 8191), прописать его как прокси в Prowlarr Settings → Indexers. Без FlareSolverr CF-челлендж RuTracker/Kinozal не проходится. -2. **Обновить Prowlarr** v2.5.2.5491 → v2.6.5.5623 (свежая интеграция FlareSolverr). -3. **Починить сеть** — подключить Radarr и Transmission в `media_net` (обратимо, без пересоздания контейнеров): - `sudo docker network connect media_net radarr` / `sudo docker network connect media_net transmission` -4. **Раскрыть категории** Sonarr indexer id=8 (RuTor) — сейчас `[5000]`, добавить 2000/8000. -5. **Проверка приёмки:** `testall` в Radarr и Sonarr → все `isValid=true`; поиск RuTracker с ненулевым результатом. +Все три причины были независимы и требовали независимых фиксов: +1. **Сеть** — `docker network connect media_net radarr|transmission` (обратимо, без пересоздания контейнеров). +2. **FlareSolverr не применялся** — нужен одинаковый tag на прокси И на индексере (главная засада: при `tags=[]` молча не работает). +3. **Блокировки в `IndexerStatus`** — рестарт контейнера их НЕ сбрасывает, чистить через `sqlite3` между stop/start. -**Честные границы:** FlareSolverr против CF Turnstile даёт ~70-80% на RuTracker (при жёстком managed-challenge может понадобиться cookie из браузера, вручную). Пароли трекеров у агента отсутствуют — если сессия RuTracker инвалидировалась, логин/пароль вводит Alex в UI Prowlarr. Гарантий на CF нет ни у кого: трекеры обновляют защиту. +Плюс побочно: RuTor не фильтрует по категориям → ему нужна категория `8000(Other)`, не `5000`. -**Статус:** диагностика завершена, план не начат (ждёт апрува). Безопасный первый шаг — п.3 (сети), не требует паролей и полностью обратим. +**⚠️ Безопасность:** FlareSolverr на `LOG_LEVEL=info` пишет логин и пароль RuTracker в plaintext в свои логи. Обязательно `warning`. ## Известные проблемы -- **⚠️ 2026-09-20: `jellyfin_default` в compose Radarr** — реально Radarr живёт в `docker_default`; при разборе сетей проверять фактическое `docker inspect`, а не docker-compose.yml. +- **⚠️ 2026-09-20: compose-файл может ВРАТЬ про сеть.** Ранее в compose Radarr был указан `jellyfin_default`, а реально контейнер жил в `docker_default`; при починке выяснилось, что compose уже писал `media_net`, но контейнеры не были пересозданы. **Всегда проверять фактическое `docker inspect -f '{{range $k,$v := .NetworkSettings.Networks}}{{$k}} {{end}}' `, а не docker-compose.yml.** - **17 фильмов в Radarr `hasFile=False`** — ждут подходящего релиза в Prowlarr. Scream (1996) в процессе загрузки. - **Prowlarr** — если долго не находит релизы, проверить статус индексеров (`/api/v1/health`). ⚠️ health врёт, реальную причину блокировки смотреть в `config/logs/prowlarr.debug.txt` — см. секцию «🔴 Индексера Prowlarr — починка Cloudflare (2026-09-20)» ниже. - ✅ **2026-09-20: все индексера Prowlarr починены (6/6), Radarr 4/4 и Sonarr 5/5 зелёные.** Причины были: сеть (`docker_default` вместо `media_net`), непривязанный tag у FlareSolverr-прокси, и блокировки в `IndexerStatus`. Детали и команды — в секции ниже. @@ -368,4 +359,5 @@ sudo docker start prowlarr - See [[arr-stack-taiga]] for Taiga (secondary) arr stack - Media pipeline pitfalls: [[media-pipeline-pitfalls]] +- FlareSolverr / Cloudflare / Prowlarr-питфоллы: [[prowlarr-flaresolverr-cloudflare]] - Синтез: [[concepts/kraken-media-stack]] diff --git a/personal/tech/prowlarr-flaresolverr-cloudflare.md b/personal/tech/prowlarr-flaresolverr-cloudflare.md new file mode 100644 index 00000000..ceb57043 --- /dev/null +++ b/personal/tech/prowlarr-flaresolverr-cloudflare.md @@ -0,0 +1,120 @@ +--- +title: Prowlarr FlareSolverr — Cloudflare-обход и починка индексеров +created: '2026-09-20' +updated: '2026-09-20' +type: tech +namespace: personal +tags: [prowlarr, flaresolverr, cloudflare, rutracker, kinozal, torrent, arr, kraken, infra] +related: + - "[[family/how-to/arr-stack-kraken]]" + - "[[personal/projects/media-pipeline-pitfalls]]" +--- + +# Prowlarr + FlareSolverr — обход Cloudflare + +Зеркало ключевых питфоллов скилла `torrent-agent-pipeline` (§ Питфоллы). +Контекст: 2026-09-20, Kraken. RuTracker / Kinozal / Kinozal (M) были «красными» в Prowlarr. + +## Схема + +``` +Prowlarr (Kraken:9696) → FlareSolverr (Kraken:8191) → Cloudflare-защищённый трекер + ⚠️ прокси применяется ТОЛЬКО при одинаковом tag на прокси И на индексере +``` + +Все контейнеры — в общей внешней сети `media_net`: radarr, sonarr, prowlarr, transmission, flaresolverr. +Проверять фактическую сеть, а не compose-файл: +```bash +ssh kraken 'sudo docker inspect -f "{{range $k,$v := .NetworkSettings.Networks}}{{$k}} {{end}}" radarr sonarr prowlarr transmission flaresolverr' +``` + +## 🔴 Главная засада: прокси без tag молча не применяется + +Созданный прокси (`POST /api/v1/indexerproxy`) с `tags: []` **не используется вообще** — в UI и логе Prowlarr об этом ни слова, запросы продолжают идти напрямую в Cloudflare. Прокси применяется к индексерам только когда у прокси И у каждого индексера стоит **один и тот же tag id**. + +```bash +KEY=$(grep -oP "(?<=)[^<]+" /srv/.../docker/prowlarr/config/config.xml) + +# 1. создать тег → получить id (обычно 1) +curl -X POST -H "X-Api-Key: $KEY" -H "Content-Type: application/json" \ + -d '{"label":"flaresolverr"}' http://localhost:9696/prowlarr/api/v1/tag + +# 2. повесить tag на ПРОКСИ: GET целиком → jq .tags=[1] → PUT +curl -s -H "X-Api-Key: $KEY" http://localhost:9696/prowlarr/api/v1/indexerproxy/1 | jq ".tags=[1]" > /tmp/p.json +curl -X PUT -H "X-Api-Key: $KEY" -H "Content-Type: application/json" -d @/tmp/p.json \ + http://localhost:9696/prowlarr/api/v1/indexerproxy/1 + +# 3. повесить ТОТ ЖЕ tag на индексера (RuTracker=1, Kinozal=5, Kinozal M=6) +curl -s -H "X-Api-Key: $KEY" http://localhost:9696/prowlarr/api/v1/indexer/1 | jq ".tags=[1]" > /tmp/i.json +curl -X PUT -H "X-Api-Key: $KEY" -H "Content-Type: application/json" -d @/tmp/i.json \ + http://localhost:9696/prowlarr/api/v1/indexer/1 +``` + +**Пруф работы — только лог FlareSolverr, не лог и не UI Prowlarr:** +```bash +ssh kraken 'sudo docker logs --tail 30 flaresolverr' +# → Challenge detected. Title found: Just a moment... +# → Challenge solved! +``` +Непустой `GET /api/v1/indexerproxy` **не означает**, что прокси работает. +Требуется Prowlarr ≥ 2.6 (в 2.5.2 прокси-модель только вводилась). + +## 🔴 Блокировка индексера в SQLite — рестарт НЕ снимает + +Prowlarr сам выключает упавший индексер на 24ч (`Temporarily ignoring indexer X till +24h`), состояние в таблице `IndexerStatus` в `prowlarr.db`. `docker restart prowlarr` его **не сбрасывает** — запрос продолжает отдавать `429 Indexer is disabled till ...`. + +```bash +# бэкап перед правкой БД +cp /srv/.../docker/prowlarr/config/prowlarr.db / +ssh kraken 'sudo docker stop prowlarr' +sqlite3 /srv/.../docker/prowlarr/config/prowlarr.db "DELETE FROM IndexerStatus WHERE ProviderId IN (1,5,6);" +ssh kraken 'sudo docker start prowlarr' +``` +`ProviderId` = id индексера. **В контейнерах `sqlite3` НЕТ** — на хосте Kraken `/usr/bin/sqlite3` ЕСТЬ. + +## ⚠️ Безопасность: FlareSolverr логирует пароли в plaintext + +На `LOG_LEVEL=info` его лог печатает `postData` запроса, т.е. `login_username=...&login_password=...` **открытым текстом**. Ставить `LOG_LEVEL=warning` в compose. +Проверка после понижения: `docker logs --since 5m flaresolverr | grep -c login_password` → `0`. + +```yaml + flaresolverr: + image: ghcr.io/flaresolverr/flaresolverr:latest + environment: + - LOG_LEVEL=warning # ← не info: info пишет пароли трекеров + - BROWSER_TIMEOUT=60000 + ports: + - 8191:8191 + networks: + - media_net +``` + +## RuTor не фильтрует по категориям + +В caps заявлены `2000(Movies)/5000(TV)/8000(Other)`, но с `cat=5000` отдаёт **0** результатов, без `cat` — 100. Prowlarr сам пишет в полях индексера: *«RuTor does not return categories in its search results. To sync to your apps, include 8000(Other)»*. В Sonarr/Radarr ставить категорию RuTor = `8000`, не `5000`. + +## 429 в Sonarr/Radarr от упавшего индексера + +`HTTP request failed: [429:TooManyRequests] [GET] at [http://prowlarr:9696/prowlarr/N/api?t=caps...]` — это **не** rate-limit трекера, а самоисключение Prowlarr. Не «ждать и повторять» — снимать `IndexerStatus`. + +## Диагностические грабли + +- **`POST /api/v3/indexer/test` с `{"indexerId": N}` не работает** (Radarr v6.1.1, Sonarr, Prowlarr v2.5.2) → HTTP 400 с `validationFailures` (`'Name' must not be empty`, … `'Priority' must be between 1 and 50`). Эндпоинт валидирует тело как **новый** индексер. Ответ — массив, поэтому `jq '.validationFailures'` падает с `Cannot index array with string`. + Рабочая альтернатива — `testall`: + ```bash + curl -s -X POST -H "X-Api-Key: $KEY" "http://localhost:7878/radarr/api/v3/indexer/testall" \ + | jq -r '.[] | "\(.id)\t\(.isValid)\t\(.validationFailures[0].errorMessage // "")"' + # Sonarr: порт 8989, UrlBase /sonarr + ``` +- **Prowlarr маскирует упавшие индексеры** — `GET /api/v1/health` и `/api/v1/indexerstatus` могут быть **пустыми**, пока индексер красный. Диагноз снимать из лога `/logs/prowlarr.debug.txt` (НЕ `logs/prowlarr.txt`). Искать: `grep -iE "rutracker|kinozal|Cloudflare|429"`. +- **«Кто живой» быстрее всего — поиском**, не caps-тестом: + ```bash + curl -s -H "X-Api-Key: $KEY" "http://localhost:9696/prowlarr/api/v1/search?query=matrix&type=search" \ + | jq -r 'group_by(.indexer)[] | "\(.[0].indexer): \(length)"' + ``` + По умолчанию до 100 результатов на индексер — «156 всего» ≠ «по 26 на каждый». + +## Источники + +- Скилл: `torrent-agent-pipeline` (§ Питфоллы) +- Живой разбор: [[family/how-to/arr-stack-kraken]] — секции про починку индексера 2026-09-20