--- 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