Files
obsidian-vault/personal/tech/flaresolverr-taiga.md
T

20 KiB
Executable File
Raw Blame History

FlareSolverr на Тайге + обход блокировок индексеров

✅ СОСТОЯНИЕ 2026-09-29: РАБОТАЕТ. Prowlarr логинится на RuTracker автоматически, поиск отдаёт CF-индексеры. IndexerStatus → [], health → [], 6/6 индексеров enabled. Приёмочный замер: search?query=radiohead&indexerIds=1 → 50 результатов (RuTracker). FS — штатный образ ghcr.io/flaresolverr/flaresolverr:latest, порт 8191, media_net, shm_size: 1gb, PROXY_URL=socks5://vless-proxy:1080. Compose — /mnt/RED_2TB/docker/arr/docker-compose.yml (сервис flaresolverr). ⚠️ Открыто: RuTor — no results in the configured categories (на стороне трекера, не блок). Связка: personal/plans/flaresolverr-taiga-deploy, family/projects/media-toolbox-taiga, personal/tech/prowlarr-flaresolverr-cloudflare, family/how-to/arr-stack-kraken, family/plans/lidarr-taiga-deploy.

🔴 ИСТИННАЯ ПРИЧИНА «RuTracker не логинится» (найдена 2026-09-29)

Три дня диагностики уходили в ложные следы. Настоящая причина — банальная:

Prowlarr хранит:   username = mallexxx           (8 символов)
                   password = m@n*w$uperP@$$w0rD (18 символов)
Мои тесты шли с:   username = keropjan_88 / I70aj7Igpr   ← ДРУГОЙ аккаунт

Капча RuTracker — не блокер, а СИМПТОМ неверного пароля. Трекер отдаёт форму Вы ввели неверное/неактивное имя пользователя или неверный пароль + картинку cap_code. С верной парой логин проходит без капчи вообще, автоматически.

Проверка (рабочий путь):

POST /forum/login.php  session=<uuid>
  login_username=mallexxx&login_password=<пароль>&login=<Вход>
→ len=105 510, cookies = [bb_session, bb_ssl, bb_guid, cf_clearance]
→ bb_session PRESENT, «неверное/неактивное» = 0

🔴 Кука авторизации RuTracker — bb_session, НЕ bb_data

В этом доке раньше фигурировала bb_data как «кука авторизации». Это неверно. Признак живого логина — наличие bb_session в .solution.cookies[]. Без неё Prowlarr пишет Empty cookies returned by FlareSolverr (FlareSolverr.cs:68).

🔴 Порядок диагностики «Auth Failed» / «Empty cookies returned» (НЕ переставлять)

  1. Сверить пару логин/пароль из БД Prowlarr с тем, чем тестируешь:
    DB=/mnt/RED_2TB/docker/arr/prowlarr/prowlarr.db
    sqlite3 "file:$DB?mode=ro" "SELECT Settings FROM Indexers WHERE Id=1;"   # JSON: username/password
    
    Это первое, что нужно делать при Auth Failed. Здесь потеряно три дня.
  2. Проверить, что FS-сессия ходит через прокси (см. ниже).
  3. Только потом — карантин в IndexerStatus (см. ниже).
  4. И только если п.1–3 чисты — думать про пароль на трекере.

🔑 ОТКРЫТИЕ: FS-СЕССИЯ НЕ НАСЛЕДУЕТ PROXY_URL

PROXY_URL (глобальный прокси FS) применяется к Chrome в момент создания сессии. Сессия, созданная до появления PROXY_URL, остаётся без прокси навсегда — Chrome получает net::ERR_NAME_NOT_RESOLVED (DNS-блок провайдера), Prowlarr интерпретирует это как «blocked by CloudFlare Protection» и уходит в retry → карантин.

Пруф (сессия создана до PROXY_URL):

request.get kinozal + session:"prowlarr"
  → {"status":"error","message":"Error solving the challenge.
     Message: unknown error: net::ERR_NAME_NOT_RESOLVED (chrome=152.0.7977.82)"}

Тот же запрос с сессией, созданной после PROXY_URL → Challenge solved! 200.

Подтверждение, что прокси применяется (нужен LOG_LEVEL=debug):

INFO  Using proxy URL ENV
DEBUG Using webdriver proxy: socks5://vless-proxy:1080

Имя сессии Prowlarr — prowlarr (видно через sessions.list).

Фикс: удалить устаревшую сессию — Prowlarr пересоздаёт её сам при следующем запросе, уже с рабочим PROXY_URL:

curl -s -X POST http://localhost:8191/v1 -H "Content-Type: application/json" \
  -d '{"cmd":"sessions.destroy","session":"prowlarr"}'

🔴 Правило: после ЛЮБОЙ правки PROXY_URL в compose — убить сессию prowlarr. При обычном рестарте контейнера проблема не повторяется (сессия создастся заново).

🔑 ВТОРОЕ: FlareSolverr сам обязан ходить через прокси (PROXY_URL)

На Тайге два блока одновременно: DNS-блок провайдера (NXDOMAIN на 4 трекера) + Cloudflare. FS без прокси сам получит NXDOMAIN и не поможет. Решение — env PROXY_URL=socks5://vless-proxy:1080.

⚠️ Имя переменной — PROXY_URL, НЕ HTTP_PROXY/HTTPS_PROXY. Схема обязательна (socks5://host:port). Приоритет: request > session > global. PROXY_USERNAME/PROXY_PASSWORD не нужны — vless-proxy без авторизации.

🔴 ПИТФОЛЛ: IndexerStatus снимается ТОЛЬКО SQL, тест его ПРОДЛЕВАЕТ

Симптом-петля: «снимаю карантин тестом → warning возвращается → тест падает».

ProviderId  Индексер     EscalationLevel  DisabledTill
1           RuTracker    9                2026-09-29 09:46   ← СУТКИ
5           Kinozal      2                2026-09-28 10:08
6           Kinozal M    2                —

EscalationLevel 0–9 (9 — максимум, DisabledTill = +24 ч). Пока запись есть: caps → 429 → фоновый health-чек Radarr/Sonarr/Lidarr бьёт в 429 → warning каскадом во все четыре сервиса. Отсюда парадокс «health Radarr пуст, а warning про индексе́ры живёт» — он живёт не у Radarr, а в БД Prowlarr.

🔴 POST /indexer/test карантин НЕ снимает, а ПРОДЛЕВАЕТ (наблюдалось 15:44 → 21:45).

Рабочая процедура снятия

DB=/mnt/RED_2TB/docker/arr/prowlarr/prowlarr.db
# 1. БЭКАП через .backup, НЕ cp (БД в WAL-режиме)
sqlite3 "file:$DB?mode=ro" ".backup /home/truenas_admin/prowlarr.db.bak-$(date +%Y%m%d-%H%M%S)"
# 2. стоп → удалить строки → старт
docker stop prowlarr
sqlite3 "$DB" "DELETE FROM IndexerStatus;"
sqlite3 "$DB" "PRAGMA quick_check;"     # → ok
docker start prowlarr
# 3. приёмка
curl -s -H "X-Api-Key: $PK" http://localhost:9696/api/v1/indexerstatus   # → []

Таблицы: Indexers, IndexerStatus, IndexerProxies, ApplicationIndexerMapping.

🔴 ПРИЁМКА: search, а НЕ caps и не health

Пустой ответ трекера выглядит как успех инфраструктуры. caps 200 + пустой IndexerStatus

  • health: [] не доказывают, что поиск работает.
curl -s -m 240 -H "X-Api-Key: $PK" \
  "http://localhost:9696/api/v1/search?query=radiohead&type=search&indexerIds=1" \
  | python3 -c "import json,sys; print(len(json.load(sys.stdin)))"
# ожидается: 50

⚠️ ПИТФОЛЛ: requestTimeout = 60 с мало, нужно 180

Дефолт прокси-элемента FlareSolverr в Prowlarr = 60 с. Решение CF-челленджа занимает 78 с холодный / 20 с прогретый, POST-логин — 97 с → Error solving the challenge. Timeout after 60.0 seconds. Фикс: requestTimeout = 180 (PUT /api/v1/indexerproxy/2).

⚠️ ПИТФОЛЛ: тег нужен И на прокси, И на индексере — и на ОБА прокси

Прокси id Тег Назначение
vless-socks5 1 proxy (id=1) обход DNS-блока провайдера
flaresolverr 2 flaresolverr (id=2) обход Cloudflare

На CF-индексер вешаются оба тега: tags=[1,2]. Фактически: id 1, 4, 5, 6 → [1,2]; id 2, 3 → [1] (RuTor/Byrutor живут на одном прокси).

⚠️ ПИТФОЛЛ: PUT /api/v1/indexer/N → 400, нужен ?forceSave=true

Prowlarr при PUT сразу тестирует индексер; если FS не прошёл — 400 с validationFailures, теги откатываются. Рабочий путь: PUT /api/v1/indexer/N?forceSave=true → 202. То же для /indexerproxy/N.

⚠️ ПИТФОЛЛ: test требует ПОЛНЫЙ объект, не {id} → 400

Во всех arr-сервисах POST /api/vN/indexer/test с телом {"id":N} → 400. Правильно — полный объект индексера (GET → --data-binary @file). {} + 200 = успех. POST /indexer/testall в Radarr/Sonarr не работает (400, Sonarr виснет >300 с). GET /indexerstatus есть только в Prowlarr (в остальных 404).

⚠️ ПИТФОЛЛ: параллельный testall устраивает гонку за Chrome

У FlareSolverr один Chrome. При testall челленджи сыпятся таймаутами; по одному — проходят. Не верить результату параллельного testall. curl без --max-time виснет — всегда ставить лимит.

⚠️ ПИТФОЛЛ: 429 на caps = запись в IndexerStatus → каскад во все arr

GET http://prowlarr:9696/5/api?t=caps&apikey=… → 429, пока индексер в карантине. Radarr/Sonarr/Lidarr не могут синкнуть индексер → Unable to connect to indexer [429]. Порядок лечения (снизу вверх): снять карантин в Prowlarr через SQL → проверить indexerstatus → PUT /api/v3/indexer/N?forceSave=true в самом arr (сброс FailureCount) → docker restart radarr sonarr lidarr (health пересчитывается только при старте).

⚠️ ПИТФОЛЛ: proxyBypassFilter Lidarr без внутренних имён → таймауты к Prowlarr

Дефолт localhost,127.0.0.1,vless-proxy не содержит prowlarr → внутренний запрос Lidarr → Prowlarr уходит в прокси и падает Http request timed out, хотя Prowlarr отвечает 200. proxyBypassLocalAddresses=true на docker-имена не действует (только IP-литералы).

Фикс — дописать в config/host.proxyBypassFilter все docker-имена стека:

localhost,127.0.0.1,vless-proxy,prowlarr,lidarr,radarr,sonarr,transmission,jellyfin,navidrome,caddy,gluetun,taiga

После правки — docker restart lidarr.

⚠️ Правило: включая приложению прокси-конфиг, сразу прописать в bypass все имена своего стека.

Общий вывод: три РАЗНЫХ механизма прокси на одном хосте

Кто Механизм Ключ
Prowlarr (индексеры) SOCKS5-прокси в Prowlarr + FlareSolverr теги [1,2], PROXY_URL у FS
FlareSolverr (Chrome) глобальный прокси образа env PROXY_URL=socks5://... (НЕ HTTP_PROXY)
Lidarr (SkyHook) встроенный конфиг приложения config/host.proxyEnabled (env НЕ работает)

⚠️ Не переносить рецепт одного сервиса на другой. Проверять фактическим запросом.

Compose-сервис (штатный, /mnt/RED_2TB/docker/arr/docker-compose.yml)

  flaresolverr:
    image: ghcr.io/flaresolverr/flaresolverr:latest
    container_name: flaresolverr
    restart: unless-stopped
    environment:
      - LOG_LEVEL=warning          # НЕ info — info пишет пароли трекеров в plaintext
      - BROWSER_TIMEOUT=60000
      - TZ=Asia/Novosibirsk
      - PROXY_URL=socks5://vless-proxy:1080
    ports:
      - "8191:8191"
    networks:
      - media_net
    shm_size: 1gb                  # 64 MB /dev/shm убивает Chrome
    sysctls:
      - net.ipv6.conf.all.disable_ipv6=1

Порядок деплоя: бэкап compose → правка локально (не sed на сервере) → scp → cd /mnt/RED_2TB/docker/arr && docker compose up -d flaresolverr. ⚠️ docker compose up -d только из своего каталога, иначе name-conflict.

Swap на Тайге = 0 и не нужен: RAM 21 GB, доступно 5.6 GB, FS держит 710 MB, CPU 0.68%.

Практические замечания

  • Логи FS пусты при LOG_LEVEL=warning — это правильно: на info он пишет login_password трекеров в plaintext. Поднимать уровень только для диагностики прокси и сразу опускать.
  • sleep 35 после старта контейнера — Chrome поднимается ~30 с; раньше :8191 может не отвечать.
  • ERR_NAME_NOT_RESOLVED в ответе FS = сессия без прокси, а не «FS сломан».
  • Ключ API ломается многоуровневым экранированием (ssh → docker → sh). Приём: printf "X-Api-Key: $PK" > /tmp/h.txt внутри контейнера, затем curl -H @/tmp/h.txt.
  • python3 внутри контейнера prowlarr НЕТ. На хосте Тайги python3 и sqlite3 есть, curl — нет. sqlite3 в контейнерах отсутствует.
  • Порт 8191 наружу с Mac НЕ проброшен (Connection refused) — скрипты запускать на хосте Тайги (scp → ssh ... python3), не локально.
  • shm_size и sysctls — в блок сервиса compose, не в environment.

Индексеры (актуальный состав)

id Индексер Теги Статус
1 RuTracker [1,2] ✅ работает (логин проходит)
2 RuTor [1] ⚠️ caps ок, но нет результатов в категориях фильмов/сериалов (дефект трекера)
3 Byrutor [1] ✅ valid
4 NoNaMe Club [1,2] ✅ valid
5 Kinozal [1,2] ✅ valid
6 Kinozal (M) [1,2] ✅ valid (зеркало Kinozal, magnet-приоритет)

Смежное: Lidarr (SkyHook + путь загрузки)

Кратко; полный разбор — family/plans/lidarr-taiga-deploy.

  • api.lidarr.audio за Cloudflare: напрямую 403, через socks5h://vless-proxy:1080 200. Домен резолвится — это чисто CF, не DNS-блок. FlareSolverr тут бесполезен (обслуживает Prowlarr).
  • 🔴 env HTTP_PROXY/HTTPS_PROXY Lidarr НЕ ЧИТАЕТ — .NET-клиент SkyHook игнорирует env. Работает только встроенный прокси-конфиг (config/host): proxyEnabled=true, proxyType=http, proxyHostname=vless-proxy, proxyPort=1081 (HTTP, не 1080 SOCKS5), proxyBypassFilter — см. питфолл выше. Применяется без рестарта.
  • 🔴 musicCategory обязателен. Дефолт пустой → Transmission кладёт файл плоско → импорт в библиотеку падает. Значение — lidarr; каталоги /mnt/storage/Downloads/{lidarr,radarr,sonarr} созданы, RemotePathMapping /mnt/storage/Downloads/ → /storage/Downloads/, rootFolder /storage/Music.
  • monitored=false у добавленного артиста → Lidarr не начнёт качать без включения мониторинга.

Как проверить, что всё живо (быстрый чек-лист)

PK=$(grep -o "<ApiKey>[^<]*" /mnt/RED_2TB/docker/arr/prowlarr/config.xml | cut -d">" -f2)
# 1. FS отвечает
curl -s -X POST http://localhost:8191/v1 -H "Content-Type: application/json" \
  -d '{"cmd":"sessions.list"}'                       # → {"status":"ok","version":"3.5.2"}
# 2. Карантина нет
curl -s -H "X-Api-Key: $PK" http://localhost:9696/api/v1/indexerstatus    # → []
# 3. ПРИЁМКА — реальный поиск
curl -s -m 240 -H "X-Api-Key: $PK" \
  "http://localhost:9696/api/v1/search?query=radiohead&indexerIds=1" \
  | python3 -c "import json,sys; print(len(json.load(sys.stdin)))"        # → 50

Откат неудачного эксперимента 2026-09-29 (образ flaresolverr-vnc)

В сессии пробовался свой образ flaresolverr-vnc (Xvfb + fluxbox + x11vnc + noVNC, порт 6080) под гипотезу «капчу решает человек». Гипотеза оказалась ложной (капча была симптомом неверного пароля) → всё снесено: образ заменён на штатный, порт 6080 и volume /config убраны из compose, каталог /mnt/RED_2TB/docker/arr/fs-vnc/ удалён, роут vnc.mallexxx.duckdns.org убран из Caddyfile, Caddy отключён от media_net (вернулся в caddy_default + transmission_default).

⚠️ Не переизобретать. VNC-браузер не нужен: Prowlarr логинится автоматически. Если однажды CF реально потребует ручной вход — сначала сверить пару логин/пароль в БД.

Что оказалось мифом (не тратить время повторно)

Версия Вердикт
«RuTracker требует капчу, нужен человек» ❌ Капча = симптом неверного пароля. Верная пара логинится автоматически
«Кука авторизации — bb_data» ❌ Она называется bb_session
«Капча привязана к холодной сессии, сессия prowlarr её обходит» ❌ Ложный след, оставлен в истории диагностики
«На Кра́кене всё работает, надо сделать так же» ❌ На Кра́кене та же запись карантина (не снятая с 2026-09-27) и нет капча-солвера
CAPTCHA_SOLVER в FlareSolverr ❌ Официально non-functional (DeepWiki FS, issue #1452) — адаптеры удалены из образа
Persistent Chrome-профиль спасает cookies ❌ На Кра́кене /config пуст, профиль не используется. Причина была не в профиле