Files
obsidian-vault/personal/tech/prowlarr-flaresolverr-cloudflare.md
T

7.3 KiB
Raw Blame History

title, created, updated, type, namespace, tags, related
title created updated type namespace tags related
Prowlarr FlareSolverr — Cloudflare-обход и починка индексеров 2026-09-20 2026-09-20 tech personal
prowlarr
flaresolverr
cloudflare
rutracker
kinozal
torrent
arr
kraken
infra
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-файл:

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.

KEY=$(grep -oP "(?<=<ApiKey>)[^<]+" /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:

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

# бэкап перед правкой БД
cp /srv/.../docker/prowlarr/config/prowlarr.db <backup>/
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.

  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:
    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 могут быть пустыми, пока индексер красный. Диагноз снимать из лога <config>/logs/prowlarr.debug.txt (НЕ logs/prowlarr.txt). Искать: grep -iE "rutracker|kinozal|Cloudflare|429".
  • «Кто живой» быстрее всего — поиском, не caps-тестом:
    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