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

375 lines
24 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 (конец сессии): FS настроен верно, НО RuTracker снова упал в 0.**
> Поиск: `search?query=radiohead` → RuTracker **0** ❌, NoNaMe **47** ✅, RuTor **33** ✅.
> Причина падения найдена — **сломанная сессия `prowlarr`** (см. раздел «ДВЕ ЛОВУШКИ ДИАГНОСТИКИ»).
> `IndexerStatus` содержит RuTracker (`disabledTill 2026-09-28T15:47`).
> Health: Prowlarr 1 warning (RuTor), Radarr 1, Sonarr 2, Lidarr 2 — все про RuTracker/Kinozal/RuTor.
> Контейнер `flaresolverr` — штатный образ, `PROXY_URL=socks5://vless-proxy:1080`, порт `8191`, сеть `media_net`,
> `shm_size: 1gb`, `LOG_LEVEL=warning`. Compose: `/mnt/RED_2TB/docker/arr/docker-compose.yml`.
> Связка: [[family/projects/media-toolbox-taiga]], [[family/plans/lidarr-taiga-deploy]],
> [[personal/tech/prowlarr-flaresolverr-cloudflare]], [[family/how-to/arr-stack-kraken]].
## 🔴🔴 ДВЕ ЛОВУШКИ ДИАГНОСТИКИ (главное этой сессии)
Обе стоили часов и обе — про то, что **артефакт врёт**, если смотреть не то поле.
### Ловушка 1: `len≈250 KB` ≠ «залогинен». Это может быть Chrome-страница ОШИБКИ
Прошлый вывод «~250 KB = залогиненный форум» **опровергнут**. В сломанной сессии 251 792 байта —
это **встроенная страница ошибки Chromium**, а не форум:
```html
<html dir="ltr" lang="en"><head><meta name="color-scheme" content="light dark">
<title>rutracker.org</title>
<style>/* Copyright 2017 The Chromium Authors */</style>
```
Диагностические маркеры в такой странице: `logged-in=0`, `logout=0`, `IS_GUEST=0/1` — **ни одного**,
`cap_code=0`, `неверное/неактивное=0`, `challenge-platform=0`. То есть **судить по размеру нельзя**.
🔴 **Правильный признак «залогинен» — наличие cookies, а не длина HTML:**
| Проверка | Залогинен | Не залогинен |
|---|---|---|
| `solution.cookies` | есть **`bb_session`** ✅ | пусто / только `cf_clearance`+`bb_guid` |
| Маркер в HTML | `IS_GUEST: !!'0'` | нет ни одного маркера |
| `len` | **~105 KB** (свежая сессия) | 13 KB форма / 251 KB ошибка Chrome |
> ⚠️ **Всегда проверять `solution.cookies[].name` — наличие `bb_session` единственный надёжный признак.**
> Замеры одной сессии: сессия `prowlarr` → `len=251792, cookies=[]` (ошибка);
> свежая `cmp-fresh` → `len=105507, cookies=[bb_session, bb_ssl, bb_guid, cf_clearance]` ✅.
### Ловушка 2: сессия FS может быть «отравлена» и переживает рестарт FS
Сессия `prowlarr` залипла в сломанном Chrome: **любой** запрос через неё возвращает 251 KB
страницы ошибки и **пустые cookies**. При этом:
- `sessions.list` показывает её живой;
- она **переживает `docker restart flaresolverr`** (наблюдалось: жила 2 часа через рестарты);
- Prowlarr получает `Empty cookies returned` → `RuTracker Auth Failed` → карантин.
```
сессия prowlarr (сломанная): POST login → len=251792, cookies=ПУСТЫЕ ❌
свежая сессия: POST login → len=105507, cookies=[bb_session...] ✅
```
🔴 **Диагностика обязана включать `sessions.list` + убийство сессии `prowlarr`.** Именно это
снимает дефект — Prowlarr пересоздаёт сессию чистой при следующем запросе.
---
## 🔴 ПРИЧИНА ВСЕХ ПРОБЛЕМ: путаница аккаунтов (не капча, не прокси, не CF)
Долгая диагностика упиралась в «капчу RuTracker» — **причины такой не было**.
```
Prowlarr: username = mallexxx password = m@n*w$uperP@$$w0rD
Мой тест: username = keropjan_88 password = I70aj7Igpr ← ЛЕВЫЙ аккаунт
```
RuTracker на неверный пароль отвечает **формой логина + капчей**. Отсюда ложный вывод «капча блокирует».
С правильными данными Prowlarr логинится **без капчи**.
> 🔴 **Прежде чем диагностировать капчу/CF/прокси — сверить пару логин/пароль в Prowlarr:**
> ```bash
> python3 -c "
> import json,sqlite3,shutil
> shutil.copy('/mnt/RED_2TB/docker/arr/prowlarr/prowlarr.db','/tmp/o.db')
> c=sqlite3.connect('/tmp/o.db')
> for r in c.execute('SELECT Name,Settings FROM Indexers'):
> s=json.loads(r[1])
> print(r[0], {k:v for k,v in s.items() if 'user' in k.lower() or 'pass' in k.lower()})
> "
> ```
## 🔑 FS-СЕССИЯ НЕ НАСЛЕДУЕТ `PROXY_URL` — убить сессию после правки
`PROXY_URL` применяется к Chrome **в момент создания сессии**. Сессия, созданная до появления
`PROXY_URL`, навсегда остаётся **без прокси** → `net::ERR_NAME_NOT_RESOLVED` → Prowlarr
интерпретирует это как `blocked by CloudFlare Protection` и уходит в retry → карантин.
```
request.get + session:"prowlarr" (старая)
→ {"status":"error","message":"unknown error: net::ERR_NAME_NOT_RESOLVED"}
```
**Фикс:** удалить сессию — Prowlarr пересоздаст её сам уже с прокси.
```bash
docker exec prowlarr sh -c 'curl -s --max-time 60 -X POST http://flaresolverr:8191/v1 \
-H "Content-Type: application/json" -d "{\"cmd\":\"sessions.destroy\",\"session\":\"prowlarr\"}"'
```
> ⚠️ **После ЛЮБОЙ правки `PROXY_URL`** — убить сессию `prowlarr`.
> ✅ Обычный перезапуск FS проблемы не создаёт: сессия создастся заново с прокси.
## 🔑 Имя переменной — `PROXY_URL` (не `HTTP_PROXY`)
`PROXY_URL=socks5://vless-proxy:1080` — **схема обязательна**. Приоритет: request > session > global.
Prowlarr обращается к FS с параметром `session`, поэтому работает именно global.
Проверка, что прокси применён (нужен `LOG_LEVEL=debug`):
```
INFO Using proxy URL ENV
DEBUG Using webdriver proxy: socks5://vless-proxy:1080
```
**Почему FS обязан ходить через прокси:** на Тайге блоков **два** — DNS провайдера + Cloudflare.
Без прокси FS сам получает NXDOMAIN и не помогает. На Кра́кене DNS-блока нет, поэтому там
`PROXY_URL` не нужен.
## 🔴 `IndexerStatus` снимается ТОЛЬКО через SQL — тест его ПРОДЛЕВАЕТ
`POST /indexer/test` карантин **не снимает, а эскалирует**: наблюдалось `DisabledTill` 15:44 → 21:45
после одного теста. Пока запись есть, `caps` отдаёт **429**, и warning каскадом идёт во все arr.
```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
```
Поля: `EscalationLevel` 0–9 (9 = сутки блокировки), `DisabledTill`.
`sqlite3` на хосте Тайги **есть**, в контейнерах — нет.
## 🔴 ПРИЁМКА — `search`, а НЕ `caps` и НЕ `health`
`caps` 200 + пустой `indexerstatus` + `health []` **не доказывают**, что поиск работает.
```bash
PK=$(grep -o "<ApiKey>[^<]*" /mnt/RED_2TB/docker/arr/prowlarr/config.xml | cut -d">" -f2)
for I in 1 2 4 5 6; do
echo "idx$I=$(curl -s --max-time 200 "http://localhost:9696/api/v1/search?query=radiohead&type=search&indexerIds=$I" \
-H "X-Api-Key: $PK" | python3 -c 'import json,sys
try:
d=json.load(sys.stdin); print(len(d) if isinstance(d,list) else "ERR")
except: print("EMPTY")')"
done
```
## Прокси-элементы и теги (в Prowlarr)
| Прокси | id | Тег | Закрывает |
|---|---|---|---|
| `vless-socks5` | 1 | `proxy` (1) | DNS-блок провайдера |
| `flaresolverr` | 2 | `flaresolverr` (2) | Cloudflare |
CF-индексеры получают **оба** тега: `tags=[1,2]`. RuTor/Byrutor живут на одном (`[1]`).
`requestTimeout` прокси-элемента flareSolverr = **180** (дефолт 60 мало: челлендж занимает 80–100 с).
## ⚠️ ПИТФОЛЛЫ API
- **`PUT /api/v1/indexer/N` → 400**, нужен `?forceSave=true` → **202**. Без него теги откатываются:
Prowlarr при PUT сразу тестирует индексер, и при падении FS откатывает сохранение.
- **`POST /indexer/test` требует ПОЛНЫЙ объект**, не `{"id":N}` (иначе 400). `{}` + **200** = успех.
- **`testall` вреден:** один Chrome у FS → гонка за него, челленджи сыпятся таймаутами. Тестировать по одному.
- **`GET /indexerstatus` есть только в Prowlarr** — в Radarr/Sonarr → 404.
- **`429` на `/N/api?t=caps`** = карантин Prowlarr → каскад `429:TooManyRequests` во все arr.
Лечить снизу вверх: SQL-очистка в Prowlarr → `PUT ?forceSave=true` в arr → `docker restart` arr.
- **Ключ API в `-H` ломается экранированием** (ssh → docker → sh): `printf "X-Api-Key: KEY" > /tmp/h.txt`,
затем `curl -H @/tmp/h.txt`.
- **`python3` в контейнере prowlarr НЕТ** (на хосте Тайги есть; `curl` и `sqlite3` на хосте — нет).
## ⚠️ ПИТФОЛЛЫ FlareSolverr
- `sessions.create` → `{"status":"ok","version":"3.5.2"}` — быстрый smoke-тест живости.
- **`LOG_LEVEL=warning` (не info!)** — `info` пишет `login_password` трекеров в **plaintext** в лог.
- `sleep ~30` после старта контейнера: Chrome поднимается, до этого `:8191` может не отвечать.
- `sessions.destroy` несуществующей сессии → **HTTP 500**, не «ok/not found» (оборачивать в try).
- `shm_size`/`sysctls` — в блок сервиса compose, не в `environment`.
- Порт `8191` с Mac наружу **не проброшен** — скрипты запускать на хосте Тайги (`scp` + `ssh python3`).
## ⚠️ ПИТФОЛЛ: `Auth Failed` — порядок диагностики (обновлён 2026-09-29)
`RuTracker Auth Failed` / `Invalid Credentials` в Prowlarr имеет **три разные причины**, и
симптом у них одинаковый. Проверять **строго в этом порядке**:
| # | Проверка | Признак причины |
|---|---|---|
| 1 | `sessions.list` → есть ли сессия `prowlarr`, и что она отдаёт | сессия «отравлена» → **убить её** |
| 2 | `solution.cookies` после логина | нет **`bb_session`** → логин не прошёл |
| 3 | `SELECT Settings FROM Indexers WHERE Id=1` в `prowlarr.db` | пара логин/пароль не та, что в тесте |
| 4 | `IndexerStatus` в БД | есть запись → карантин (снимать SQL, не тестом) |
🔴 **НИКОГДА не судить о логине по длине HTML.** Ранее в этом доке было записано
«~250 KB = залогинен, ~13 KB = форма» — **это неверно** (см. «ДВЕ ЛОВУШКИ ДИАГНОСТИКИ»):
250 KB бывает страницей ошибки Chrome, а залогиненная свежая сессия даёт ~105 KB.
```bash
# Правильная проверка логина — по cookies
curl -s --max-time 220 -X POST http://localhost:8191/v1 -H "Content-Type: application/json" \
-d '{"cmd":"request.post","url":"https://rutracker.org/forum/login.php",
"session":"prowlarr",
"postData":"login_username=<U>&login_password=<P>&login=%D0%92%D1%85%D0%BE%D0%B4",
"maxTimeout":200000}' | jq -r '.solution.cookies[].name'
# видим bb_session → залогинен. Пусто → сессия сломана, убить и повторить.
```
## ⚠️ Кэш health в arr-сервисах
`RemotePathMappingCheck` и подобные **кэшируются**: создание каталогов ошибку не снимает,
`PUT` по API тоже не сбрасывает. Нужен `docker restart radarr sonarr lidarr`.
## Три механизма прокси на одном хосте — не путать
| Кто | Механизм | Ключ |
|---|---|---|
| Prowlarr (индексеры) | SOCKS5-прокси в Prowlarr + FlareSolverr | теги `[1,2]`, `PROXY_URL` у FS |
| FlareSolverr (Chrome) | глобальный прокси образа | env `PROXY_URL` (**НЕ** `HTTP_PROXY`) |
| Lidarr (SkyHook) | встроенный конфиг приложения | `config/host.proxyEnabled` (**env НЕ работает**) |
> ⚠️ **Не переносить рецепт одного сервиса на другой** — проверять фактическим запросом.
## Compose-сервис
```yaml
flaresolverr:
image: ghcr.io/flaresolverr/flaresolverr:latest
container_name: flaresolverr
restart: unless-stopped
environment:
- LOG_LEVEL=warning # НЕ info — пишет пароли в plaintext
- BROWSER_TIMEOUT=60000
- TZ=Asia/Novosibirsk
- PROXY_URL=socks5://vless-proxy:1080
ports:
- "8191:8191"
networks:
- media_net
shm_size: 1gb
sysctls:
- net.ipv6.conf.all.disable_ipv6=1
```
Деплой: правка **локально** (не sed) → `scp` → `cd /mnt/RED_2TB/docker/arr && docker compose up -d flaresolverr`.
⚠️ `docker compose up -d` **только из своего каталога**, иначе name-conflict.
> ⚠️ **Swap на Тайге = 0** — не мешает: RAM 21 GB, FS держит ~710 MB, CPU 0.68%. **Swap не трогать.**
> ⚠️ У FS **нет** persistent-профиля Chrome: он живёт в контейнере и умирает при пересоздании.
> Это **не проблема** — FS логинится в RuTracker при каждом старте без капчи.
## Состояние индексеров (2026-09-29, конец сессии)
| id | Индексер | Теги | Поиск |
|---|---|---|---|
| 1 | RuTracker | `[1,2]` | ❌ **0** — сессия `prowlarr` сломана, в карантине |
| 2 | RuTor | `[1]` | ✅ 33 |
| 3 | Byrutor | `[1]` | — |
| 4 | NoNaMe Club | `[1,2]` | ✅ 47 |
| 5 | Kinozal | `[1,2]` | ⚠️ CF, периодически в карантине |
| 6 | Kinozal (M) | `[1,2]` | ⚠️ зеркало Kinozal (5) |
**Health по сервисам (2026-09-29):**
```
Prowlarr 1 warning RuTor (no results in categories — дефект трекера)
Radarr 1 warning RuTracker unavailable > 6 hours
Sonarr 2 warning RuTracker + RuTor
Lidarr 2 warning RuTracker + Kinozal (M)
```
## 🔴 ЧЕКЛИСТ «не всё зелёное» (восстановление RuTracker)
Когда RuTracker даёт 0, а FS жив — выполнить **в этом порядке**:
```bash
# 1. Убить сессии FS (главный шаг — сессия переживает рестарт FS!)
for S in prowlarr cmp-fresh; do
curl -s --max-time 60 -X POST http://localhost:8191/v1 \
-H "Content-Type: application/json" \
-d "{\"cmd\":\"sessions.destroy\",\"session\":\"$S\"}" -o /dev/null
done
curl -s -X POST http://localhost:8191/v1 -H "Content-Type: application/json" \
-d '{"cmd":"sessions.list"}' # → sessions: [] (ждём пусто)
# 2. Снять карантин SQL (тест его ПРОДЛЕВАЕТ, не снимает)
DB=/mnt/RED_2TB/docker/arr/prowlarr/prowlarr.db
docker stop prowlarr
sqlite3 "$DB" "DELETE FROM IndexerStatus;"
docker start prowlarr && sleep 20
# 3. ПРИЁМКА — реальный поиск (НЕ caps, НЕ health)
PK=$(grep -o "<ApiKey>[^<]*" /mnt/RED_2TB/docker/arr/prowlarr/config.xml | cut -d">" -f2)
curl -s --max-time 150 "http://localhost:9696/api/v1/search?query=radiohead&type=search&indexerIds=1" \
-H "X-Api-Key: $PK" | python3 -c "import json,sys; print(len(json.load(sys.stdin)))"
# ждём > 0
```
> ⚠️ **Переживёт ли reboot:** `IndexerStatus` и сломанная сессия **переживают** — без шагов 1–2
> после перезагрузки RuTracker останется в 0. Сессия живёт в памяти FS и **выдерживает
> `docker restart flaresolverr`**.
## 🔴 Чего НЕ делать (проверено, не работает)
| Идея | Почему нет |
|---|---|
| Капча-солвер (`CAPTCHA_SOLVER`) | **Официально non-functional** (DeepWiki FS, issue #1452 закрыт). Адаптеры удалены из образа. И по факту капча не нужна — см. главный раздел |
| Вписать cookies в Prowlarr вручную | Индексер принимает только `username`/`password`, поля для cookie нет |
| noVNC/свой образ FS для ручного входа | Строилось под ложную гипотезу «капча». **Снесено 2026-09-29.** Не воссоздавать |
| Браузер Alex через 3x-ui | `vless-proxy` — **клиент**, не сервер; `cf_clearance` привязан к IP+UA+fingerprint |
| Persistent-профиль Chrome у FS | Не решает ничего: FS логинится сам |
> 🔴 **Не строить план на посылке «на Кра́кене работает».** На 2026-09-29 у Кра́кена в БД
> тот же карантин `EscalationLevel=9` (RuTracker/Kinozal/Kinozal M, с 27 сен) и **нет** капча-солвера.
> «Как на Кра́кене» ≠ «починить».
## 📋 ЖУРНАЛ ОТКАТА (2026-09-29) — что снесено и как вернуть
Эксперимент «ручная капча через VNC» построен под ложную гипотезу и полностью откачен.
Записано, чтобы не воссоздавать и чтобы понимать, что удалено.
| Артефакт | Было | Стало |
|---|---|---|
| Compose `image:` | `flaresolverr-vnc:latest` (свой образ) | `ghcr.io/flaresolverr/flaresolverr:latest` |
| Compose порт | `8191:8191` + `6080:6080` | только `8191:8191` |
| Compose volume | `/mnt/RED_2TB/docker/arr/flaresolverr-config:/config` | убран |
| Каталог сборки | `/mnt/RED_2TB/docker/arr/fs-vnc/{Dockerfile,supervisord.conf,entrypoint-vnc.sh}` | удалён |
| Образ | `flaresolverr-vnc:latest` | удалён (`docker rmi`) |
| Отладочный контейнер | `fs-debug` | удалён (`docker rm -f`) |
| Caddyfile | блок `vnc.mallexxx.duckdns.org` (basic_auth + reverse_proxy) | блок убран, config валиден |
| Сеть Caddy | подключён к `media_net` | `docker network disconnect media_net caddy` |
| Каталог профиля | `/mnt/RED_2TB/docker/arr/flaresolverr-config/` | удалён |
### ⚠️ ПИТФОЛЛЫ отката (стоили времени)
1. **`docker compose up -d --force-recreate` падает**, если bind-source уже удалён:
`invalid mount config for type "bind": bind source path does not exist`.
Контейнер держит старый маунт в памяти → нужно **`docker rm -f flaresolverr`**, потом up.
2. **Каталог профиля от root не удаляется по ssh-пользователем** — `Operation not permitted`
(внутренний `chromium/` создан root'ом внутри контейнера). Обход:
```bash
docker run --rm -v /mnt/RED_2TB/docker/arr:/work alpine sh -c "rm -rf /work/flaresolverr-config"
```
3. **`docker rmi` конфликтует**, пока образ держит любой контейнер (`fs-debug` из отладки):
`conflict: unable to remove repository reference (must force) - container ... is using`.
Сначала `docker rm -f fs-debug`, потом `rmi`.
4. **Имя каталога бэкапа рядом с оригиналом** → `Permission denied` (каталог root) — бэкап класть в `~`.
(Здесь не применялось: Alex запретил лишние бэкапы.)
### Порядок отката, который сработал
```bash
# 1. Caddyfile — убрать блок vnc, залить, проверить, перезагрузить
scp Caddyfile.clean truenas_admin@...:/mnt/RED_2TB/docker/caddy/Caddyfile
docker exec caddy caddy validate --config /etc/caddy/Caddyfile # → Valid configuration
docker exec caddy caddy reload --config /etc/caddy/Caddyfile
docker network disconnect media_net caddy
# 2. compose — вернуть штатный образ, убрать порт 6080 и volume
# править ЛОКАЛЬНО → scp → docker compose config -q → up -d
# 3. снести образ/каталог/контейнеры (см. питфоллы выше)
# 4. ПРИЁМКА: логин + поиск (не caps!)
```
### ✅ Приёмка после отката (факты)
```
API FS: {"status":"ok","version":"3.5.2"}
indexerstatus: [] ← сразу после снятия карантина
search: idx1=50 idx2=33 idx4=47 idx5=EMPTY idx6=0 ← НА МОМЕНТ ОТКАТА
```
⚠️ Через ~2 часа `idx1` упал в **0** — сессия `prowlarr` сломалась. `len=251792` тогда был принят
за «залогиненный форум», но это **Chrome-страница ошибки**. См. «ДВЕ ЛОВУШКИ ДИАГНОСТИКИ».
**Вывод сессии:** откат выполнен верно (FS на штатном образе, `PROXY_URL`, noVNC/капча-солвер
снесены как ненужные). Но **логин RuTracker нестабилен**: сессия FS `prowlarr` периодически
«отравляется» и переживает рестарт FS — лечится `sessions.destroy` + снятие карантина SQL.
**Причина отравления не установлена** — открытый вопрос для следующей сессии.