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

227 lines
15 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-28: ГОТОВО. Все 6 индексеров рабочие, health чистый.**
> Контейнер `flaresolverr` (v3.5.2), порт `8191`, сеть `media_net`, `shm_size: 1gb`,
> `LOG_LEVEL=warning`, **`PROXY_URL=socks5://vless-proxy:1080`**.
> Compose — `/mnt/RED_2TB/docker/arr/docker-compose.yml` (6-й сервис).
> Бэкапы: `~truenas_admin/docker-compose.yml.bak-20260928-flaresolverr`,
> `~/backup-indexers-20260928-flaresolverr.json` (снимок 6 индексеров до правки тегов).
> Связка: [[personal/plans/flaresolverr-taiga-deploy]], [[personal/plans/lidarr-taiga-and-indexer-unblock]],
> [[family/projects/media-toolbox-taiga]], [[personal/tech/prowlarr-flaresolverr-cloudflare]],
> [[family/how-to/arr-stack-kraken]].
## ✅ РЕЗУЛЬТАТ (поиск «matrix» через `/api/v1/search`)
```
TOTAL 256
RuTor 100 ← был живой
RuTracker 50 ← ВПЕРВЫЕ с 2026-05-20
NoNaMe 50 ← ВПЕРВЫЕ
Kinozal 50 ← ВПЕРВЫЕ
Byrutor 6
```
`GET /api/v1/health` → `[]`, `GET /api/v1/indexerstatus` → `[]`. **Ни одной ошибки,
ни одного карантина.** Было 3/6, стало 6/6 (по выдаче — 5 трекеров; Kinozal (M) — зеркало
Kinozal с magnet-приоритетом, в общую выдачу дублируется).
## 🔑 ГЛАВНОЕ ОТКРЫТИЕ: FS-СЕССИЯ НЕ НАСЛЕДУЕТ `PROXY_URL`
Самый неочевидный пункт всей задачи. Симптом был **ложный**: Prowlarr писал
`blocked by CloudFlare Protection`, а лог FS — мгновенную ошибку за **7 секунд** (не таймаут!).
**Причина:** `PROXY_URL` (глобальный прокси) применяется к Chrome **в момент создания сессии**.
Сессия, созданная **до** появления `PROXY_URL`, остаётся **без прокси** навсегда —
в ней Chrome получает `net::ERR_NAME_NOT_RESOLVED` (DNS-блок!). Prowlarr шлёт запросы
с параметром `session`, и global-прокси её не перебивает.
Пруф — прямой вызов с сессией, созданной ДО прокси:
```
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`.
**Имя сессии Prowlarr — `prowlarr`** (обнаружено через `sessions.list`).
**Фикс:** удалить устаревшую сессию — `sessions.destroy`; Prowlarr пересоздаёт её сам
при следующем запросе, уже с рабочим `PROXY_URL`.
```bash
docker exec prowlarr sh -c 'curl -s -X POST http://flaresolverr:8191/v1 \
-H "Content-Type: application/json" \
-d "{\"cmd\":\"sessions.destroy\",\"session\":\"prowlarr\"}"'
```
> ⚠️ **Правило на будущее:** после ЛЮБОЙ правки `PROXY_URL` в compose **убить сессию
> `prowlarr`**, иначе старые сессии продолжат ходить без прокси и индексера будут
> «blocked by CloudFlare» при живом FS.
> ✅ При обычном перезапуске FS (watchtower/reboot) проблема НЕ повторится — сессия
> создастся заново уже с `PROXY_URL`.
## 🔑 ВТОРОЕ ОТКРЫТИЕ: FlareSolverr сам идёт через прокси (`PROXY_URL`)
На Кра́кене два механизма независимы: Cloudflare лечится FlareSolverr, DNS-блока нет.
**На Тайге блоков ДВА (DNS + Cloudflare), и FlareSolverr обязан ходить через `vless-proxy`** —
иначе он сам получит NXDOMAIN и не поможет.
**Решение:** глобальная env-переменная FlareSolverr **`PROXY_URL=socks5://vless-proxy:1080`**.
> ⚠️ Имя переменной — **`PROXY_URL`**, НЕ `HTTP_PROXY`/`HTTPS_PROXY` (проверено по DeepWiki
> FlareSolverr §4.2 «Proxy Configuration»). Формат **со схемой обязателен**
> (`socks5://host:port`); без схемы `urllib.parse` не разберёт.
> Приоритет: request > session > global. `PROXY_USERNAME`/`PROXY_PASSWORD` не нужны —
> `vless-proxy` без авторизации.
**Почему срабатывает именно global:** Prowlarr обращается к FS с параметром `session`,
а при наличии сессии request-прокси **игнорируется** → применяется global (`PROXY_URL`).
## ⚠️ ПИТФОЛЛ: `requestTimeout` = 60 с МАЛО, поднят до 180
Дефолтный `requestTimeout` прокси-элемента FlareSolverr в Prowlarr = **60 с**.
Решение CF-челленджа на `/forum/login.php` RuTracker и на kinozal занимает **80–100 с** →
`Error solving the challenge. Timeout after 60.0 seconds` в логе FS, Prowlarr отдаёт
`500 InternalServerError [POST] at http://flaresolverr:8191/v1`, в UI — «blocked by CloudFlare».
**Фикс:** `requestTimeout` = **180** (PUT `/api/v1/indexerproxy/2`).
Проверка: `docker logs flaresolverr` → `Challenge solved!`, а не `Timeout`.
> Замеры времени челленджа (kinozal.me/browse.php через FS): **78 с** холодный,
> **20 с** прогретый (CF-клэренс привязан к IP прокси), POST-логин — **97 с**.
## ⚠️ ПИТФОЛЛ: параллельный `testall` устраивает гонку за Chrome
Prowlarr тестирует все индексеры **одновременно**, а у FlareSolverr **один** Chrome.
При `testall` челленджи сыпятся таймаутами; если тестировать **по одному** (sequential) —
проходят. **Не верить результату параллельного `testall`** — гонять по одному.
Дополнительно: `curl` без `--max-time` виснет, если FS не отвечает — всегда ставить лимит.
## ⚠️ ПИТФОЛЛ: тег нужен И на прокси, И на индексере — и на ОБА прокси
Индексерам за DNS-блоком нужны **два** прокси-элемента и **два** тега:
| Прокси | id | Тег | Назначение |
|---|---|---|---|
| `vless-socks5` | 1 | `proxy` (id=1) | обход **DNS-блока** провайдера |
| `flaresolverr` | 2 | `flaresolverr` (id=2) | обход **Cloudflare** |
Значит на индексер вешаются **оба** тега: `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 в этот момент не прошёл
(таймаут/гонка) — `HTTP 400` с `validationFailures`. Именно так «потерялись» теги
после первого PUT: они откатились к `[1]`.
**Рабочий путь:** `PUT /api/v1/indexer/N?forceSave=true` → **202** (сохраняет, тест пропускает).
Тест гонять отдельно, по одному. То же для `/indexerproxy/N`.
## Практические замечания
- **Логи FS пусты при `LOG_LEVEL=warning`** — это правильно: на `info` он пишет
`login_password` трекеров в plaintext. Не поднимать уровень ради «посмотреть».
- `sessions.create` → `ok`, `version 3.5.2` — быстрый smoke-тест живости FS.
- Прямая проверка FS из prowlarr:
```bash
docker exec prowlarr sh -c 'curl -s --max-time 150 -X POST http://flaresolverr:8191/v1 \
-H "Content-Type: application/json" \
-d "{\"cmd\":\"request.get\",\"url\":\"https://rutracker.org/forum/login.php\",\"maxTimeout\":130000}"'
# ожидается: {"status":"ok","message":"Challenge solved!", ...}
```
- `sleep 35` после старта контейнера — Chrome поднимается ~30 с; раньше этого `:8191` может не отвечать.
- `shm_size` и `sysctls` — **в блок сервиса** compose, не в `environment`.
- **`ERR_NAME_NOT_RESOLVED` в ответе FS = сессия без прокси** (см. открытие выше), а не «FS сломан».
- **Ключ API в `-H` ломается многоуровневым экранированием** (ssh → docker → sh).
Рабочий приём: `printf "X-Api-Key: <KEY>" > /tmp/h.txt` внутри контейнера, затем `curl -H @/tmp/h.txt`.
- **`python3` внутри контейнера prowlarr НЕТ** — разбирать JSON хостовым `python3`
(на Тайге есть `python3`, нет `curl` и `sqlite3`).
## Состояние индексеров после деплоя (2026-09-28, финал)
| id | Индексер | Теги | Статус |
|---|---|---|---|
| 1 | RuTracker | `[1,2]` | ✅ valid (был красный с 2026-05-20) |
| 2 | RuTor | `[1]` | ✅ valid |
| 3 | Byrutor | `[1]` | ✅ valid |
| 4 | NoNaMe Club | `[1,2]` | ✅ valid |
| 5 | Kinozal | `[1,2]` | ✅ valid |
| 6 | Kinozal (M) | `[1,2]` | ✅ valid |
## ✅ ЗАКРЫТО: Kinozal — «blocked by CloudFlare» при живом FS
Самая долгая часть задачи. Симптом маскировался под таймаут, причина оказалась другой.
**Что замерено (история диагностики):**
- Прямой socks5 к `kinozal.me/browse.php` → **403 Just a moment** за **0.9 с** (CF реален).
- FS `request.get` kinozal → `Challenge solved! 200`: **78 с** холодный, **20 с** прогретый.
- FS `request.post` kinozal/takelogin.php → `Challenge solved! 200`, **97 с**.
- Prowlarr: `blocked by CloudFlare Protection`, в логе FS — падение за **7 с** (не таймаут!).
**Ложный след:** `HTTP request failed: [500:InternalServerError] [POST] at http://flaresolverr:8191/v1`
и `Error solving the challenge. Timeout after 60/120/180 seconds` — выглядело как «челлендж
дольше таймаута». Поднятие `requestTimeout` 60→120→180 **не помогло**.
**Настоящая причина:** FS-сессия без прокси (см. главное открытие выше). Сессия `prowlarr`,
созданная до появления `PROXY_URL`, падала с `ERR_NAME_NOT_RESOLVED` за 7 с, Prowlarr
интерпретировал это как «CF блокирует» и уходил в retry → карантин.
**Фикс:** `sessions.destroy` сессии `prowlarr` → пересоздана с прокси →
Kinozal (5) и Kinozal (M) (6) прошли с первого раза (`{}`).
**Что исключено (не тратить время повторно):** ресурсы FS в норме (710 MB / 21 GB, shm 1 GB,
CPU 0.68%); канал прокси нормальный (kinozal через socks5 **0.6 с**, 908 KB/s); внутренний
таймаут Prowlarr в `config.xml` не настраивается.
## 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 убивал Chrome
sysctls:
- net.ipv6.conf.all.disable_ipv6=1
```
Порядок деплоя: бэкап compose → правка **локально** (не sed на сервере) → `scp` → `cp` →
`cd /mnt/RED_2TB/docker/arr && docker compose up -d flaresolverr`.
⚠️ `docker compose up -d` **только из своего каталога**, иначе name-conflict (грабля Кра́кена).
> ⚠️ **Swap на Тайге = 0** (`/proc/swaps` пуст). На Кра́кене мёртвый swap + 64 MB `/dev/shm`
> убили Chrome в crash-loop. Здесь обошлось без swap: RAM 21 GB, доступно 5.6 GB, FS держит
> 710 MB, CPU 0.68%. **Swap не трогали** — не нужен при таком объёме памяти.
## История
- **2026-09-26** — разведка под Lidarr. Найдено: DNS-блок провайдера (NXDOMAIN на 4 трекера),
`vless-proxy` не в `media_net`. Прокси-маршрут для Prowlarr починен в тот же день (3/6 индексеров).
Остаток — Cloudflare на RuTracker/Kinozal. [[personal/plans/lidarr-taiga-and-indexer-unblock]]
- **2026-09-28** — **FlareSolverr развёрнут** по задаче Alex «ставь как на Кра́кене + прокси-контейнер».
Решено последовательно: (1) FS сам ходит через `vless-proxy` (`PROXY_URL`) — двойной обход DNS+CF;
(2) `requestTimeout` 60→180; (3) теги `[1,2]` на все CF-индексеры; (4) **`sessions.destroy`
сессии `prowlarr`** — последний блокер (сессия была создана до `PROXY_URL`).
Итог: **6/6 индексеров, health `[]`, поиск 256 результатов.**
RuTracker впервые `valid` за всё время существования стека (с 2026-05-20).
## Открытые пункты
- **Приёмка Alex в UI:** `https://prowlarr.mallexxx.duckdns.org` → Indexers → 6 зелёных без карантинов.
- Проверить, что RuTracker реально **логинится** (не только челлендж на login.php) —
выдача 50 результатов намекает, что да.
- Lidarr: метаданные `api.lidarr.audio` → 403 CF прямым, 200 через `vless-proxy`.
Заготовка `/tmp/add_proxy_env.py` (HTTP_PROXY/HTTPS_PROXY) — **не применена**;
Lidarr ходит в SkyHook сам, НЕ через FS. Разбирать отдельно —
[[family/plans/lidarr-taiga-deploy]].