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

314 lines
20 KiB
Markdown
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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** с тем, чем тестируешь:
```bash
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`:
```bash
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`).
### Рабочая процедура снятия
```bash
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: []` **не доказывают**, что поиск работает.
```bash
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`)
```yaml
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 не начнёт качать без включения мониторинга.
## Как проверить, что всё живо (быстрый чек-лист)
```bash
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` пуст, профиль не используется. Причина была не в профиле |