From d8313b126fd068262f7da7ea6b08eeee0c1da6b3 Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Tue, 29 Sep 2026 00:47:45 +0600 Subject: [PATCH] [2026-09-29] eagle: family/how-to/arr-stack-taiga.md family/plans/lidarr-taiga-deploy.md personal/plans/flaresolverr-taiga-deploy.md personal/plans/lidarr-taiga-and-indexer-unblock.md personal/tech/flaresolverr-taiga.md personal/tech/prowlarr-flaresolverr-cloudflare.md --- family/how-to/arr-stack-taiga.md | 211 +++--- family/plans/lidarr-taiga-deploy.md | 527 --------------- personal/plans/flaresolverr-taiga-deploy.md | 410 ------------ .../plans/lidarr-taiga-and-indexer-unblock.md | 336 ---------- personal/tech/flaresolverr-taiga.md | 627 +++--------------- .../tech/prowlarr-flaresolverr-cloudflare.md | 401 ----------- 6 files changed, 225 insertions(+), 2287 deletions(-) mode change 100755 => 100644 family/how-to/arr-stack-taiga.md delete mode 100755 family/plans/lidarr-taiga-deploy.md delete mode 100755 personal/plans/flaresolverr-taiga-deploy.md delete mode 100755 personal/plans/lidarr-taiga-and-indexer-unblock.md mode change 100755 => 100644 personal/tech/flaresolverr-taiga.md delete mode 100755 personal/tech/prowlarr-flaresolverr-cloudflare.md diff --git a/family/how-to/arr-stack-taiga.md b/family/how-to/arr-stack-taiga.md old mode 100755 new mode 100644 index 96703f1e..3b6e157b --- a/family/how-to/arr-stack-taiga.md +++ b/family/how-to/arr-stack-taiga.md @@ -1,115 +1,170 @@ --- -title: Arr Stack — Taiga +title: Arr stack — TrueNAS Taiga created: '2026-05-23' -updated: '2026-09-02' +updated: '2026-09-29' type: tech namespace: family -tags: [arr, taiga, infra, media, pitfalls] +tags: [arr, taiga, truenas, media, operations] related: - - "[[tech/arr-stack-kraken]]" + - "[[personal/tech/flaresolverr-taiga]]" + - "[[family/how-to/truenas-infrastructure]]" + - "[[family/how-to/arr-stack-kraken]]" --- -# Arr Stack — Taiga +# Arr stack — TrueNAS Taiga -Secondary arr stack on Taiga (TrueNAS), added 2026-05-20. +Каноническая документация arr-стека на TrueNAS **Taiga**. Kraken сюда не входит. -> **STATE 2026-09-02 (end-of-session):** Стек **ПОДНЯТ И РАБОТАЕТ** ✅. `docker compose up -d` в `/mnt/RED_2TB/docker/arr` создал и запустил `prowlarr`, `radarr`, `sonarr`, `jellyfin` (все в проекте `arr`, процессы под **uid 950** — PUID/PGID=950 применён). Сеть `media_net` воссоздана (`docker network create media_net`), transmission подключён к `media_net`. **Персистентность сетей:** в `docker/transmission/docker-compose.yml` добавлена networks секция `media_net` + `transmission_default` (external) — transmission сам находится в обеих сетях при любом пересоздании. -> -> **⚠️ ПЛЕЙБЕК РАБОТАЕТ, но НЕ ПЛАВНО на high-bitrate (диагноз 2026-09-02, ОБНОВЛЁН конец сессии):** после успешного фикса `storage` root traverse jellyfin проигрывает, НО на ТВ «Книга джунглей» тормозит и грузится кусками. **ЭТО НЕ ТРАНСКОДИНГ** (проверено: ffmpeg-процессов нет, transcode dir пуст, h264 720p идёт direct play нативно). **НЕ ап-линия TrueNAS** — замер с самого NAS опроверг раннюю гипотезу (см. ниже): линия TrueNAS даёт ~**184 Мбит/с down / ~117 Мбит/с up** (Cloudflare-замер с NAS), т.е. НЕ зажата на ~30 Мбит. **Настоящая причина — per-TCP-flow / BDP-ограничение при высоком RTT** между двумя домами: single SCP = ~28 Мбит/с, но **4 параллельных потока = ~51 Мбит/с** (агрегат РАСТЁТ с параллельностью → это ограничение конгeст-окна одного TCP, а НЕ жёсткий лимит линии/транзита). RTT ~104 мс, ~50 мс теряются на **одном физическом межоператорском прыжке** (мой провайдер TTK 3–6 мс → хоп `194.186.168.65` до 54 мс). Пер-хоп loss-анализ: грань моего ISP чиста (0%, 3 мс), дальние хопы дают спорадические LOSS-кластеры (ICMP-деприоритизация, НЕ устойчивые потери), re-route 104 мс **полностью не уберёт** (это география/пиринг, не дефектная петля). Мак-download НЕ виноват (CDN ~78 Мбит/с ✅). Файл 720p BR 7.1 GB (средний ~12 Мбит/с, пики >20) в пределах одного TCP-потока ~28–51 Мбит с малым запасом + 104 мс рвёт HLS-буфер → динамичные сцены подтормаживают. **Jellyfin НЕ умеет мультистримить один плейбек** (последовательный HLS на одном TCP; штатной настройки «в N потоков» нет). **Реальные пути:** (в 1) if TrueNAS в одном здании/роутере — дать локальный маршрут к `192.168.2.197` (убьёт 104 мс, LAN-скорость); (2) поднять ап-линию TrueNAS ТОЛЬКО если она реально мала — но замер 117 Мбит up говорит, что скорее нужен не тариф, а (3) снижение эффективной латентности/битрейт-запаса: ограничить jellyfin-транскод < ~20 Мбит ИЛИ прокси, тянущий файл с NAS в 4+ TCP-потоков (подтянет агрегат к 51+), ИЛИ WireGuard-туннель через VPS (меньше jitter/пер-потоковой деградации; минус не убирает 104 мс). Жирный отказ от варианта (б) «поднять ап-линию» как первичного — он основывался на ОШИБОЧНОМ замере 28 Мбит от Мака как потолка TrueNAS. Полный пересмотренный разбор: секция «Плейбек по сети → …» ниже. -> -> **✅ Два пост-запуска блокатора — ОБА РЕШЕНЫ (2026-09-02 конец):** -> 1. **Jellyfin не проигрывал (FFmpeg 243)** — переход решён двумя фиксами: (а) `chown -R 950:950 /mnt/RED_2TB/docker/arr/jellyfin` (конфиг вглубь был 911:911) открыл UI; (б) главный скрытый корень — корень `/mnt/RED_2TB/storage` остался `921:921`, ACL `everyone@ EXECUTE=False` → uid 950 не мог traverse в `/storage/Movies/...`. Фикс (root): `chown 950:950 /mnt/RED_2TB/storage && chmod 750 /mnt/RED_2TB/storage`. После этого jellyfin проигрывает. Транскодинг откл.: Dashboard→Playback→убрать «Allow …transcoding». -> 2. **Transmission 255 торрентов "no data found"** — downloadDir УЖЕ корректно указывал на `/storage/Movies`, файлы были и читались под 950; ошибка была закеширована от старта при блокированном traverse. Фикс (НЕ root): `docker restart transmission` → **254/255 чисты** сразу. Остался торрент #1 — Verify в UI. -> -> **Почему стек изначально не запускался — медиа-права были сломаны** (тот же restore-инцидент uid 921/0000): `/mnt/RED_2TB/storage/{Movies,Cartoons,Downloads,Music,series,shared}` были `d---------`/`drwx------`, owner `transmission` (uid 921). radarr/sonarr монтируют `/storage` (rw), jellyfin `:ro` — со сломанными правами не прочитали бы библиотеку. ✅ **Права медиа ИСПРАВЛЕНЫ** (2026-09-02) до `950:950 drwxrwx---`; контейнеры arr/jellyfin затем подняты и запущены. Полный контекст и команды: `family/documents/vault-sync/2026-09-02-restore-privilege-scope.md`. +## Текущее состояние -> **Docker-image facts (2026-09-02):** All 5 media images **loaded locally** on TrueNAS (`docker images`): `lscr.io/linuxserver/{radarr,sonarr,jellyfin,transmission,prowlarr}:latest`. All containers now exist and run under **uid 950**. Was: transmission container existed (now running as uid 950); jellyfin/radarr/sonarr/prowlarr containers were NOT yet created — now they are (PUID/PGID=950). -> **Transmission originally ran as ROOT** (not 911/950): its compose had no `PUID`/`PGID`, so linuxserver `/init` (s6-overlay) left it root. ✅ **Fixed 2026-09-02:** `PUID=950 PGID=950` added and container force-recreated → now daemon under uid 950. It mounts `storage` → `/mnt/storage`, download-dir = `/mnt/storage/Downloads`. -> **Fix direction (approved Variant A):** set `PUID=950 PGID=950` on transmission + all arr/jellyfin compose services so every service shares uid `950` and mutually reads files; then recursively fix perms in depth. Plan + commands: `2026-09-02-restore-privilege-scope.md` §5. -> -> **PROGRESS 2026-09-02 (updated end-of-session):** Both compose files edited for PUID/PGID=950 (transmission at `/mnt/RED_2TB/docker/transmission/docker-compose.yml`, arr at `/mnt/RED_2TB/docker/arr/docker-compose.yml` incl. all 4 services). **transmission container force-recreated** from its proper folder (`cd /mnt/RED_2TB/docker/transmission && docker compose up -d --force-recreate`) and now runs its daemon as **uid 950** (was root) — env `PUID=950 PGID=950` confirmed, process under `abc`/950. Media perms in depth recursively fixed to `950:950 drwxrwx---` on all top storage folders (incl. git/nas 2nd root pass). **Git-sync on Mac now RESOLVED** — the broken NFS4 `DENY READ_DATA` ACL on ~1946 loose git objects in `obsidian-vault.git` was stripped via full **dacl replacement** (not stripacl), so `git push` from Mac works again (push `a2c7279..2b6c181`, ahead=0 behind=0). **Arr stack is UP (2026-09-02 end):** `cd /mnt/RED_2TB/docker/arr && docker compose up -d` created/started prowlarr/radarr/sonarr/jellyfin. All daemons under **uid 950**. jellyfin reads `/storage/Movies`; radarr↔transmission via `media_net` (`transmission:9091`) OK; caddy resolves transmission via `transmission_default` (Web UI). UI ports: prowlarr 9696, radarr 7878, sonarr 8989, jellyfin 8096, transmission 9091. NOTE: radarr/sonarr/jellyfin mount `/mnt/RED_2TB/storage` as `/storage` (NOT `/media` like Kraken) — radarr root-folder on Taiga differs. +Проверено 2026-09-29 после полного `force-recreate`: -## Notes from Setup (2026-05-20) +- `flaresolverr`, `prowlarr`, `radarr`, `sonarr`, `lidarr`, `jellyfin`, `transmission` запущены. +- `docker compose config -q` проходит. +- Lidarr → SkyHook: 10 результатов через VLESS proxy. +- Lidarr → Transmission: штатный test проходит. +- Prowlarr → RuTracker: реальный search возвращает 50 результатов. +- FlareSolverr: health `ok`, session `prowlarr` создаётся с proxy и pre-login. -- Config and pitfalls recorded during initial Taiga arr stack deployment -- `router.py` was customized — check `/mnt/RED_2TB/docker/arr-taiga/router.py` - for current state +Health-warning у Sonarr/Lidarr может показывать старый quarantine индексаторов. Проверять нужно реальным search и `IndexerStatus`, а не одной строкой health. -## Key Differences from Kraken Stack +## Архитектура -- Taiga = TrueNAS host (storage-focused) -- Kraken = Raspberry Pi 5 (playback-focused) -- Taiga stack handles acquisition; Kraken handles serving to Jellyfin +| Компонент | Container | Порт | Назначение | +|---|---|---:|---| +| Prowlarr | `prowlarr` | 9696 | индексаторы и sync | +| Radarr | `radarr` | 7878 | фильмы | +| Sonarr | `sonarr` | 8989 | сериалы | +| Lidarr | `lidarr` | 8686 | музыка и SkyHook | +| FlareSolverr | `flaresolverr` | 8191 | Cloudflare/browser | +| Transmission | `transmission` | 9091 | torrent download client | +| Jellyfin | `jellyfin` | 8096 | media server | +| VLESS proxy | `vless-proxy` | 1080/1081 | SOCKS5/HTTP proxy | -## Pitfalls +Compose: -(Details were referenced but not captured. Update this page after next -Taiga arr maintenance session.) +```text +/mnt/RED_2TB/docker/arr/docker-compose.yml +``` -## Плейбек по сети → per-TCP-flow/BDP-ограничение при хай-РТТ (диагноз 2026-09-02, ПЕРЕСМОТРЕН конец сессии) +Конфигурация сервисов: `/mnt/RED_2TB/docker/arr/`. Media mount внутри arr-контейнеров: `/storage`. -**Симптом:** jellyfin на TrueNAS работает, файлы проигрываются, но на ТВ high-bitrate (720p BluRay и выше) *тормозят / грузятся кусками*, потом подтормаживают на динамике. +## Маршрутизация -**Вердикт — НЕ транскодинг и НЕ ап-линия TrueNAS.** Live-проверка во время плейбека через `docker exec jellyfin sh -c 'ps ... | grep ffmpeg'` и `ls /config/cache/transcodes/`: -- нет ни одного дочернего ffmpeg, transcode dir пуст; -- jellyfin-процесс `ps` — это сам сервер, не транс-ребёнок. -- Файл `The.Jungle.Book.1967.720p.BluRay.5xRus.Eng.HDCLUB.mkv` — h264 **High@L4.1, 1256×720** → приложение ТВ (Jellyfin app) тянет нативно (direct play), транскодинг не нужен. -- Lог показывает, что jellyfin даже при direct-play может ремуксовать в **HLS-сегменты по 6 сек** (`-codec:v:0 copy ... -f hls` — копия, не перекодирование). «Грузка кусками» = HLS-сегменты добираются по сети одним TCP-потоком. +1. Lidarr → `api.lidarr.audio` идёт через `http://vless-proxy:1081`. +2. FlareSolverr/Chrome → RuTracker идёт через `socks5://vless-proxy:1080`. +3. Локальный Transmission идёт напрямую по `transmission:9091`. -**Сетевая топология (два дома, доступ только через внешку):** +Lidarr должен иметь: -| | Сеть | Шлюз | Внешний IP | Провайдер | -|---|---|---|---|---| -| Мак / ТВ | `192.168.1.57` | `192.168.1.1` | динамика | ТТК (92.62.x / 185.20.x) | -| TrueNAS | `192.168.2.197` | `192.168.2.2` | `90.189.160.148` | Ростелеком (217.107.x) | +```text +proxyEnabled=true +proxyType=http +proxyHostname=vless-proxy +proxyPort=1081 +proxyBypassLocalAddresses=true +proxyBypassFilter=transmission,prowlarr +``` -TrueNAS **физически/логически НЕ в локальной сети Мак/ТВ**. ТВ→Jellyfin идёт целиком по интернету между двумя домами через межоператорский транзит. +Pitfall: `proxyBypassLocalAddresses=false` помогает SkyHook, но одновременно отправляет локальный Transmission через VLESS и ломает его. Внешний и локальный маршруты разделены намеренно. + +## FlareSolverr и RuTracker + +Entrypoint: + +```text +/mnt/RED_2TB/docker/arr/flaresolverr-entrypoint.sh +``` + +При старте он ждёт `/health`, создаёт session `prowlarr` с `socks5://vless-proxy:1080`, читает credentials RuTracker из Prowlarr SQLite в режиме `immutable=1`, выполняет pre-login и запускает основной процесс. В compose важны `PROXY_URL`, `BROWSER_TIMEOUT=180000`, `shm_size: 1gb`, `restart: unless-stopped` и read-only mount каталога Prowlarr. + +RuTracker должен иметь оба Prowlarr-тега: + +```text +proxy + flaresolverr = [1,2] +``` + +Подробности: [[personal/tech/flaresolverr-taiga]]. + +## Перезапуск и приёмка -**Замеры (воспроизводимы) — САМОЕ ВАЖНОЕ: замер с самого NAS, а не от Мака.** -> Ранняя гипотеза «~28 Мбит = ап-линия TrueNAS ~30 Мбит» была ОШИБОЧНОЙ: 28 Мбит — это потолок ОДНОГО TCP-потока от Мака по пути с 104мс RTT, а НЕ лимит линии TrueNAS. Проверено замером С TrueNAS до Cloudflare: ```bash -# На самом TrueNAS — интернет-линия НЕ зажата: ssh truenas_admin@mallexxx.duckdns.org \ - 'curl -o /dev/null -s -w "DOWN %{speed_download} B/s\n" "https://speed.cloudflare.com/__down?bytes=50000000"' - # DOWN ~23 MB/s ≈ 184 Мбит/с + 'cd /mnt/RED_2TB/docker/arr && docker compose config -q && docker compose up -d --force-recreate flaresolverr prowlarr radarr sonarr lidarr' ssh truenas_admin@mallexxx.duckdns.org \ - 'truncate -s 30M /tmp/up.bin && curl -o /dev/null -s -w "UP %{speed_upload} B/s\n" -X POST "https://speed.cloudflare.com/__up" --data-binary @/tmp/up.bin; rm -f /tmp/up.bin' - # UP ~14.7 MB/s ≈ 117 Мбит/с -# ovh/tele2 speedtest ХОСТЫ ЗАБЛОКИРОВАНЫ из RU (curl 000/timeout) — юзать Cloudflare __down/__up. + 'cd /mnt/RED_2TB/docker/arr && docker compose ps' ``` -**Где реальная пропускная просадка — per-TCP-flow/BDP при высоком RTT** (не жёсткий лимит). Ключевой тест — агрегат растёт с параллельностью: +FlareSolverr session: + ```bash -# 1 поток: ~28 Мбит/с -scp -q truenas_admin@mallexxx.duckdns.org:/tmp/dis.bin /tmp/dis.bin - -# 4 параллельных потока: ~51 Мбит/с ← агрегат РАСТЁТ → BDP-штраф одного TCP при 104мс, не лимит линии/транзита -for f in a b c d; do scp -q truenas_admin@mallexxx.duckdns.org:/tmp/$f.bin /tmp/par_$f.bin & done; wait +curl -fsS -H 'Content-Type: application/json' \ + -d '{"cmd":"sessions.list"}' http://127.0.0.1:8191/v1 ``` -(8-потоковый тест не дозамерен — апрув на запуск истёк; экстраполированное число НЕ фигурирует.) -**Латентность и loss по хопам (per-hop):** +Ожидается `status=ok` и session `prowlarr`. + +SkyHook: + ```bash -ping -c 5 mallexxx.duckdns.org # ~104 мс avg -traceroute -m 10 -n 90.189.160.148 -# х1-7 мой провайдер: 3–6 мс -# х8 194.186.168.65 → прыжок ~54 мс (переход ТТК→Ростелеком-регион) - -# per-hop loss probe (через отдельные ping каждые ~0.25с к 92.62.74.1 / 194.186.x / 217.107.x / 8.8.8.8): -# моя ISP-грань 92.62.74.1: ~3 мс, 0% loss (61/61) ← сегмент чистый -# дальние хопы (194.186.x,8.8.8.8): спорадич. LOSS-кластерами синхронно → ICMP-деприоритизация, НЕ устойчивые потери данных -# mtr на macOS по умолчанию нет — ставить tofu (brew install mtr). 8.8.8.8 тоже ~53мс → ВСЕ дальние сети идут через тот же 50мс переход. +curl -H "X-Api-Key: $LIDARR_KEY" \ + 'http://127.0.0.1:8686/api/v1/artist/lookup?term=Astrix' ``` -**Вывод (пересмотренный):** ограничитель = **per-TCP-flow / BDP-штраф за 104мс RTT**, а не ап-линия TrueNAS (117 Мбит up — отдаёт, но один поток из-за латентности получает лишь ~28–51). Файл 7.1GB/78 мин → средний ~12 Мбит/с, пики >20 — впритык к achievable single-flow ~28–51 с малым запасом; 104мс рвёт HLS-буфер → стоп-кары. Re-route 104мс полностью НЕ уберёт (пиринг/география, но у Мак/ТВ-все дальние сети идут через тот же 50мс переход — намек, что частичный выигрыш смены исхода возможен, но не гарантирован). +Ожидается непустой JSON-массив и запись VLESS о `api.lidarr.audio:443`. -**Что реально чинит (по убыванию надёжности):** -1. **Если TrueNAS в одном здании/роутере** → дать ТВ/Маку локальный маршрут к `192.168.2.197`, не через внешку `90.189.160.148` — убьёт 104мс, станет LAN. Топология в `truenas-infrastructure.md` (Доступ) говорит про разные подсети — обязательно сверить, один ли это физический роутер/здание (вопрос открыт). -2. **Jellyfin НЕ умеет мультистримить один плейбек** (последовательный HLS на одном TCP; штатной настройки «в N потоков» нет). Параллельность можно применить только на уровне доставки файла, НЕ внутри jellyfin-потока: - - прокси-«качель»: локально отдаёт клиенту один поток, а файл тянет с NAS в 4+ TCP (aria2/hget) → подтянет агрегат к ~51+; - - **WireGuard-туннель дом↔NAS через VPS** (`91.207.28.205`, см. `truenas-remote-access-reverse-proxy.md`) — меньше jitter/пер-потоковой деградации, но 104мс физику не уберёт. **⚠ XRAY-ТУННЕЛЬ УЖЕ ИЗМЕРЕН и НЕ ПОМОГАЕТ** (2026-09-02): оба egress-режима локального `xray-test-client` (`kraken-user` reverse → Kraken ~45 Мбит; `user1` direct/REALITY → TrueNAS ~37 Мбит) дают ~35–45 Мбит с нестабильностью — тот же уровень, НЕ кратно выше single-flow прямого пути (28–51 Мбит). Детали и способ переключения клиента: `personal/tech/xray-reverse-tunnel-kraken-truenas.md` § «СОСТОЯНИЕ КЛИЕНТА/Замеры». -3. **Прагматичный фикс под ТВ-стрим сейчас:** ограничить jellyfin-транскод битрейтом < ~20 Мбит (заведомо ниже single-flow achievable ~28), чтобы один HLS-поток укладывался без дожевания. Включается сразу, без новой инфраструктуры. -4. Поднять ап-линию TrueNAS — **только если** замер из п.º (117 Мбит up) реально маловат для нужного контента; как первичный вариант отвергнут. +RuTracker проверять реальным search, а не только `indexer/test`: -> **Перекрёстно:** это исправление ранней ошибочной записи «потолок ~28 = ап-линия TrueNAS» (см. history этого файла до 2026-09-02). Если будущая сессия увидит противоречие — истина здесь: NAS-линк 184/117 Мбит, проблема per-flow/BDP при высоком RTT. +```bash +curl -H "X-Api-Key: $PROWLARR_KEY" \ + 'http://127.0.0.1:9696/api/v1/search?query=radiohead&type=search&indexerIds=1' +``` +Ожидается непустой массив без `error` у результатов. + +## Pitfalls и исправления + +### Session не наследует proxy задним числом + +`PROXY_URL` применяется при создании Chrome session. После изменения proxy session нужно пересоздать. Entrypoint делает это автоматически при старте FlareSolverr. + +### Prowlarr API маскирует password + +GET индексатора возвращает `********`. Нельзя использовать такой JSON для pre-login. Рабочий pre-login читает SQLite read-only из отдельного контейнера. + +### `indexer/test` не является единственной приёмкой + +Он может тестировать объект с замаскированным password и вернуть `Auth Failed`, хотя реальный search работает. Приёмка — реальный `/api/v1/search` плюс FS request с cookie `bb_session`. + +### Размер HTML не доказывает login + +Страница Cloudflare/Chromium может быть большой. Надёжный признак — `bb_session` и успешный запрос через ту же session. + +### Quarantine может быть историческим + +Перед очисткой сделать SQLite backup. Остановить Prowlarr, удалить только `IndexerStatus`, выполнить `PRAGMA quick_check`, запустить снова и повторить реальный search. Всю БД не удалять. + +### `testall` создаёт ложные timeout + +Параллельные browser challenges перегружают Chrome. Проверять один индексатор за раз с большим timeout. + +## Troubleshooting + +| Симптом | Проверка | Исправление | +|---|---|---| +| SkyHook 403 | host config Lidarr и VLESS log | proxy `vless-proxy:1081`, local bypass оставить включённым | +| Transmission auth error | download-client test | синхронизировать password с текущим Transmission `PASS`; host `transmission:9091` | +| RuTracker Auth Failed | session, cookies, real search | пересоздать session/pre-login; не использовать `********` | +| DNS/Cloudflare timeout | VLESS log, FS cookies, tags | проверить `[1,2]` и `BROWSER_TIMEOUT=180000` | +| Старый health quarantine | `IndexerStatus` и real search | backup + очистка только `IndexerStatus` | +| сервис не пережил restart | compose, mounts, restart policy | проверить bind mounts и `restart: unless-stopped` | + +## Backup и безопасность + +Перед изменением Prowlarr DB или compose сохранять backup рядом с исходным файлом. Пароли и API keys в Obsidian не записывать. + +## Связанные документы + +- [[personal/tech/flaresolverr-taiga]] — FlareSolverr, session, pre-login и диагностика. +- [[family/how-to/truenas-infrastructure]] — общий TrueNAS. +- [[family/how-to/arr-stack-kraken]] — отдельный стек Kraken; не смешивать с Taiga. diff --git a/family/plans/lidarr-taiga-deploy.md b/family/plans/lidarr-taiga-deploy.md deleted file mode 100755 index 9bb12f57..00000000 --- a/family/plans/lidarr-taiga-deploy.md +++ /dev/null @@ -1,527 +0,0 @@ -# Lidarr на Taiga — деплой в связке с arr-стеком и Navidrome - -**Дата:** 2026-09-28 -**Статус:** ✅ **SkyHook РАБОТАЕТ — проверено фактом 2026-09-28 (поздний вечер, повторная проверка).** -``` -GET /api/v1/artist/lookup?term=Astrix → 10 результатов - first = "Astrix", foreignArtistId = 13875f81-5bfc-4939-a6cc-296c3f8d0fa5 -``` -⚠️ **История статуса (важно, чтобы не путаться):** запись «дефект вернулся, 403» относилась к -**промежутку ДО** того, как Alex починил SkyHook. Проверка в конце сессии 2026-09-28 показала -**lookup → 10 результатов** ⇒ блокер снят. Ранние записи ниже (403, `ProxyCheck failed`, -`proxyBypassLocalAddresses`) — **историческая диагностика того же вечера**, оставлена для контекста. -🔴 **Правило:** статус Lidarr/SkyHook проверять **живым `artist/lookup`**, а не по headers дока — -за вечер статус менялся трижды (работает → 403 → работает). -**Артисты в Lidarr:** по-прежнему **1** (`Radiohead` id=1, `monitored=false`) — списки из -[[family/plans/lidarr-artist-watchlist]] (150 позиций) **ещё не поставлены**. -**Ранее заявленный статус (оставлен для истории):** ✅ РАБОЧИЙ — приёмка закрыта 2026-09-28 (вечер). -SkyHook-блокер снят, проверено end-to-end: lookup → добавление артиста → поиск релизов. -Бал: 0 артистов → 1, 0 релизов → 43. -**Добивка (2026-09-28, поздний вечер):** Radarr и Sonarr вычищены до `health: []` -(`docker restart` + снятие карантина в Prowlarr + `?forceSave=true`). Найден и исправлен -последний дефект Lidarr — **`proxyBypassFilter` без внутренних docker-имён** (см. питфолл). -✅ **Все правки применены, включая `docker restart lidarr`** — задача закрыта. -**Финал сессии:** RuTracker **работает штатно** — Prowlarr логинится **автоматически**. -🔴 **Уточнение 2026-09-29:** ранняя версия «капча отдаётся только холодным сессиям, -`session=prowlarr` её обходит» — **ложный след**. Настоящая причина «Auth Failed» была в том, -что диагностика шла **другим аккаунтом** (`keropjan_88`) вместо хранящегося в Prowlarr -(`mallexxx`). Капча — симптом неверного пароля. С верной парой логин проходит без капчи, -кука авторизации — **`bb_session`** (не `bb_data`). Приёмка 2026-09-29: поиск → **50 результатов**. -См. [[personal/tech/flaresolverr-taiga]]. -Карантин снимается **только SQL** (`DELETE FROM IndexerStatus`), тест его **продлевает**. -**Найден и закрыт дефект пути загрузки:** `musicCategory` была **пустая** → Transmission -положил бы файл без категории, и **импорт в библиотеку упал бы**. Исправлено на -`musicCategory=lidarr` (дефолт Lidarr, НЕ `music`; каталог `/mnt/storage/Downloads/lidarr` -уже существует). Проверено: root folder `/storage/Music` (978 ГБ free), RemotePathMapping -`/mnt/storage/Downloads/ → /storage/Downloads/`, скачается в `/storage/Music//`, -поиск релизов → **43** FLAC-раздачи. -⚠️ **Открыт 1 дефект, на стороне САМОГО трекера (не инфраструктура):** RuTor — -`no results in the configured categories` (не отдаёт фильмы/сериалы). Не блокировка, не карантин. -⚠️ **Остаток-механика (ОБНОВЛЕНО в конце сессии):** `docker restart radarr sonarr lidarr` -**выполнен** — кэш health сбросился, Radarr/Sonarr `health` → `[]` (чисто). Но warning -про индексе́ры **вернулся** — причина не в кэше, а в таблице **`IndexerStatus`** в `prowlarr.db` -(RuTracker `EscalationLevel=9`, `DisabledTill` +24 ч). Снимается **только SQL**, и -`POST /indexer/test` карантин не снимает, а **продлевает**. План снятия (бэкап → `docker stop -prowlarr` → `DELETE FROM IndexerStatus` → `start`) — в [[personal/plans/flaresolverr-taiga-deploy]] -§«НАЙДЕНА ИСТИННАЯ ПРИЧИНА ЗАЛИПА». -Разобрано в [[personal/tech/flaresolverr-taiga]]. -**Что было причиной и как починено (главный вывод сессии):** -`api.lidarr.audio` действительно за Cloudflare, прямой запрос с IP Тайги → **403**, через -`socks5h://vless-proxy:1080` → **200**. НО **env-переменные `HTTP_PROXY`/`HTTPS_PROXY` Lidarr -НЕ ЧИТАЕТ** — .NET-клиент SkyHook их игнорирует, поэтому первая попытка починки через compose-env -дала тот же 403. Рабочий фикс — **встроенный прокси-конфиг самого Lidarr**: -`GET /api/v1/config/host` → `proxyEnabled: false` → выставить `true`, `proxyType: "http"`, -`proxyHostname: "vless-proxy"`, `proxyPort: 1081`, `proxyBypassFilter: "localhost,127.0.0.1,vless-proxy"`, -затем `PUT /api/v1/config/host/1`. Применяется **без перезапуска контейнера**. -Скрипт: `/tmp/lidarr_set_proxy.py` (на хосте Тайги; там есть `python3`). -**Namespace:** family -**Решения Alex:** (1) переименование — **вариант A**: `Rename Tracks=ON`, `Rename Folders=ON`, -раскладка `Music/// - `, `Write Metadata Tags=ON`; -(2) импорт существующих 7861 файлов — **НЕ делать**, Lidarr отвечает только за новые закачки. - ---- - -## 🔍 АУДИТ ВСЕГО СТЕКА 2026-09-28 (конец сессии) - -Проверено живыми API-вызовами после починки SkyHook. - -### ✅ Что работает - -| Компонент | Факт | -|---|---| -| **SkyHook (Lidarr → метаданные)** | ✅ `lookup Astrix` → **10 результатов** | -| Prowlarr | ✅ `health: []`, **карантин пуст**, 6/6 индексеров `enable=true` | -| Radarr | ✅ `health: []` | -| Теги Prowlarr | ✅ `RuTracker/Kinozal/Kinozal(M)/NoNaMe = [1,2]`; `RuTor/Byrutor = [1]` | -| Прокси-элементы | ✅ `vless-socks5` id=1 (SOCKS5 1080), `flaresolverr` id=2; FS 3.5.2 `status: ok` | -| Navidrome | ✅ **1207 артистов / 7791 `media_file`** | -| Root folder Lidarr | ✅ `/storage/Music` `accessible=true`, **911 ГБ** свободно | -| Домены (7 шт.) | ✅ все отвечают: radarr/sonarr/prowlarr/lidarr/jellyfin/music → **302**, transmission → **401** (норма для логина) | -| Индексеры NoNaMe / RuTor / Byrutor | ✅ `indexer/test` полным объектом → `{}` | - -### 🔴 ДЕФЕКТ 1 (открыт): RuTracker + Kinozal + Kinozal(M) — таймаут через Prowlarr - -`POST /api/v1/indexer/test` полным объектом для id **1, 5, 6** → **пустой ответ даже при таймауте 90 с**. -Работают только NoNaMe(4), RuTor(2), Byrutor(3). - -**Каскад:** в Lidarr и Sonarr → `Indexers unavailable due to failures for more than 6 hours: -RuTracker (Prowlarr), Kinozal (Prowlarr), Kinozal (M) (Prowlarr)`. - -**Проверено:** FlareSolverr жив (`{"status":"ok"}`), сессия `["prowlarr"]` существует, версия 3.5.2. -Теги на индексерах расставлены **верно** (`[1,2]`), карантина **нет** (`indexerstatus` → `[]`). - -**Не проверено (апрув истёк):** жив ли драйвер Chrome у сессии `prowlarr` **после** рестарта -контейнеров (`Up 3 minutes` — arr-стек и FS перезапускались), и содержит ли `ps aux | grep chromium` -флаг `--proxy-server`. По [[personal/tech/flaresolverr-taiga]] §«КОРЕНЬ НАЙДЕН» — **это первый -шаг диагностики**, а не сессии и не карантин. - -**Следующий шаг (обязательно ПЕРВЫМ):** -```bash -ssh truenas_admin@mallexxx.duckdns.org \ - "docker exec flaresolverr ps aux | grep chromium | head -3" -# ожидаем наличие --proxy-server=socks5://vless-proxy:1080 -# если флага нет — сессия создана без proxy: -# sessions.destroy + sessions.create с proxy (скрипт в flaresolverr-taiga.md) -``` - -### 🔴 ДЕФЕКТ 2 (открыт): Lidarr → Transmission — «Failed to authenticate» - -``` -[Error] Unable to communicate with Transmission. Failed to authenticate with Transmission. -``` -В health Lidarr: `All download clients are unavailable due to failures`. - -**Причина:** Transmission требует авторизацию (`rpc-authentication-required: true`, -`rpc-username: transmission_admin`); креды в compose есть: -`/mnt/RED_2TB/docker/transmission/docker-compose.yml` → `USER=transmission_admin`. -В Lidarr download-client **креды пустые** — чтение `fields` (host/port/username/musicCategory) -вернуло **пусто**. - -⚠️ **Побочно:** `musicCategory` при чтении тоже пустая, хотя по записи ниже она была исправлена -на `lidarr`. Либо чтение полей не сработало, либо правка **потерялась при пересоздании контейнера** -(arr-стек пересоздавался — все контейнеры `Up 3 minutes`). **Проверить фактически.** - -**Следующий шаг:** прочитать download-client целиком, вписать `username`/`password`, -подтвердить `musicCategory=lidarr`, затем `POST /api/v1/downloadclient/test`. - -### ℹ️ Поправка: API-ключи в доке обрезаны - -Ключи в таблице §«API ключи» — **8-символьные префиксы**, для копипасты в API не годятся. -Полные (получить: `docker exec <svc> grep ApiKey /config/config.xml`): - -| Сервис | Префикс | Полный ключ | -|---|---|---| -| Radarr | `51e201f2` | `51e201f2d61b4fe2a0c322d5e99349fe` | -| Sonarr | `b1eb9cdd` | `b1eb9cdd5c804e6c956dc9c8bd305dc8` | -| Lidarr | `166654ac` | `166654ac3f054096ae0e8393fb1bf940` | - -### ⚙️ Питфолл аудита: неверный ключ = пустой ответ, а не ошибка - -`curl -H "X-Api-Key: <8-символьный префикс>"` → **пустое тело** (не 401). Легко принять -за «сервис недоступен». Всегда сверять ключ с `config.xml` перед выводом «health вернул пусто». - ---- - -**`https://lidarr.mallexxx.duckdns.org`** → HTTP **200**, TLS валиден. - -| Компонент | Факт (проверено API/CLI) | -|---|---| -| Контейнер | `lidarr` **v3.1.0.4875-ls42**, Up, сети `caddy_default` + `media_net` | -| API-ключ | `166654ac3f054096ae0e8393fb1bf940` | -| Root folder | `/storage/Music`, `accessible: true`, 978 ГБ свободно (id=1) | -| Download client | Transmission (id=1), тест связи → **200**; `musicCategory="lidarr"` ✅ (была пустая — исправлено) | -| Naming | `renameTracks=true`, `{Artist Name}/{Album Title}/{track:00} - {Track Title}` | -| Prowlarr Application | `Lidarr` **id=3**, `fullSync`, `syncCategories=[3000,3010,3020,3030,3040,3050,3060]` | -| Индексер в Lidarr | `NoNaMe Club (Prowlarr)` (id=2) — `rss=true`, `auto=true` | -| RemotePathMapping | host `transmission`, remote `/mnt/storage/Downloads/`, local `/storage/Downloads/` (id=2) | -| **health Lidarr** | **`[]` — ЧИСТО** | -| health Prowlarr | `[]` — ЧИСТО (см. [[personal/tech/flaresolverr-taiga]]) | -| **SkyHook (метаданные)** | ✅ `lookup?term=radiohead` → **10 результатов**, 15 397 байт реальных метаданных | -| **Библиотека** | ✅ **1 артист** (`Radiohead`, id=1, monitored=false) | -| **Поиск релизов** | ✅ `/release?artistId=1` → **23 раздачи** FLAC (seeders 3–7) через `NoNaMe Club (Prowlarr)` | -| **Прокси-конфиг Lidarr** | ✅ `proxyEnabled=true`, `proxyType=http`, `vless-proxy:1081`, bypass **расширен** (см. питфолл ниже) | -| health Radarr/Sonarr | ✅ **`[]` — ЧИСТО** (рестарт применён 2026-09-28, поздний вечер) | -| **health Lidarr** | ✅ 1 warning `Kinozal (M)` **снят** — `proxyBypassFilter` расширен (PUT 202, read-back) + `docker restart lidarr` выполнен | - -### 🔴 ПИТФОЛЛ (новый): `proxyBypassFilter` без `prowlarr` → таймауты Lidarr к Prowlarr - -**Симптом:** в Lidarr `indexer/test` → `Unable to connect to indexer, indexer's server is -unavailable. Http request timed out`, `/release?artistId=1` → **0 релизов**, хотя в Prowlarr -тот же индексер отвечает **200**. - -**Причина:** встроенный прокси Lidarr (`proxyEnabled=true`) заворачивал **внутренний** запрос -`http://prowlarr:9696/N/api?t=caps` в HTTP-прокси: в `proxyBypassFilter` было только -`localhost,127.0.0.1,vless-proxy`, а имя `prowlarr` там отсутствовало (и -`proxyBypassLocalAddresses` на docker-имена **не действует** — только на IP-литералы). - -**Фикс** — дописать все имена стека, затем `docker restart lidarr`: -``` -localhost,127.0.0.1,vless-proxy,prowlarr,lidarr,radarr,sonarr,transmission,jellyfin,navidrome,caddy,gluetun,taiga -``` -Скрипт `/tmp/lidarr_bypass.py` (GET → patch → PUT `/api/v1/config/host` → **202** → read-back). - -> ⚠️ **Урок для любого arr-сервиса:** включая встроенный прокси — сразу прописать в bypass -> **все** docker-имена стека. Иначе сервис уходит в прокси и к соседям, и симптом выглядит -> как «сервер индексера недоступен». - -### 🔴 ПИТФОЛЛ (новый): `indexer/test` требует ПОЛНЫЙ объект - -`POST /api/v3/indexer/test` и `/api/v1/indexer/test` с телом `{"id":N}` → **400 всегда**. -Нужно отправить **полный JSON индексера**: -```bash -docker exec radarr curl -s -H "X-Api-Key: $K" http://localhost:7878/api/v3/indexer > /tmp/i.json -docker cp /tmp/i.json radarr:/tmp/i.json -docker exec radarr curl -s -X POST -H "X-Api-Key: $K" -H "Content-Type: application/json" \ - --data-binary @/tmp/i.json http://localhost:7878/api/v3/indexer/test -# {} + http=200 = OK; 400 = реальная ошибка (смотреть validationFailures) -``` -`POST /indexer/testall` вдобавок **подвешивает** Sonarr (>300 с) — гонять по одному. - -### 🔴 ПИТФОЛЛ (новый): `429` на `caps` у Prowlarr = карантин → каскад во все arr - -`GET http://prowlarr:9696/5/api?t=caps` → **429**, пока индексер в карантине Prowlarr. -Radarr/Sonarr/Lidarr показывают `[429:TooManyRequests]` — причина **не в них**. -**Порядок:** снять карантин в Prowlarr (тест полным объектом) → `caps` 200 → -`PUT /api/v3/indexer/N?forceSave=true` (**202**) в самом arr → `docker restart`. - -### ⚠️ Остаток на конец сессии (не блокирует Lidarr) - -1. ✅ **Пароль RuTracker — РАБОЧИЙ (первый диагноз «неверен» был ложным).** - -### 🔴 ПИТФОЛЛ: env `HTTP_PROXY` НЕ работает в Lidarr — только встроенный конфиг - -Проверено экспериментально, две попытки: - -| Способ | Результат | -|---|---| -| `curl -x socks5h://vless-proxy:1080` из контейнера lidarr | ✅ 200 | -| compose-env `HTTP_PROXY`+`HTTPS_PROXY`+`NO_PROXY`, рестарт | ❌ **403** — .NET-клиент SkyHook env игнорирует | -| env убран, `proxyEnabled=true` в `/api/v1/config/host` | ✅ **200**, метаданные пошли | - -⚠️ Откат env-варианта сделан (compose вернулся к чистому виду, бэкап -`~truenas_admin/docker-compose.yml.bak-20260928-lidarr-proxy`). -⚠️ **Ложный след при диагностике:** `api.lidarr.audio` отдаёт 403 **не всегда** — при -исчерпанном CF-лимите 403 бывает и у `curl`, что сбивает с толку. Различать по заголовкам: -`x-rate-limit-remaining` есть только при живом ответе; и сравнивать **прямой** запрос -vs **через прокси** в одном ходе. -⚠️ **Порт прокси:** `vless-proxy` слушает SOCKS5 на **1080** и HTTP на **1081**. -Встроенный конфиг Lidarr (`proxyType=http`) требует **1081**; `1080` там не подойдёт. - -### ⚠️ Остаток (обновлён 2026-09-28, поздний вечер) - -1. ✅ **Пароль RuTracker — РАБОЧИЙ; но трекер теперь требует КАПЧУ (см. ниже).** - Проверено `request.post` на `/forum/login.php` через FlareSolverr в двух прогонах с ОДНОЙ - и той же парой (`username`/`password` из `/api/v1/indexer/1` совпадают байт-в-байт): - - ~15:20 → `len = 251 792` (полный форум), форма **не переоткрылась** → ✅ сессия установлена; - - ~16:40 → `len = 13 335` (вернулась форма логина), в HTML блок `cap_code` и метка `Код:` → ❌. - Значит пароль не менялся, а **трекер выдаёт капчу**. Пишется в лог Prowlarr как - `IndexerAuthException: RuTracker Auth Failed`. - 🔴 **Признак «залогинен» — РАЗМЕР HTML (~250 KB), НЕ подстрока.** `login_username` - присутствует **в обоих** случаях (HTML-шаблон + скрытая форма быстрого входа) — по ней - диагноз ставить НЕЛЬЗЯ, это дало ложное «Auth Failed» **двумя** диагнозами подряд. - Скрипт: `/tmp/rt_login.py`, диагностика капчи: `/tmp/rt_why.py`. - ⚠️ Обходного пути в Prowlarr нет: форма индексера принимает только `username`/`password`, - поля для cookie-сессии (`bb_data`) не существует. -2. ✅ **Radarr/Sonarr — ЗАКРЫТО 2026-09-28 (поздний вечер).** Каталоги - `/storage/Downloads/{radarr,sonarr}` созданы, `docker restart radarr sonarr` выполнен → - `RemotePathMappingCheck` **ушла**, `health` обоих → `[]`. -3. ✅ **Indexer-warnings в Radarr/Sonarr — ЗАКРЫТО.** Сняты: (а) тест карантинных индексе- - ров в **Prowlarr** полным объектом → `caps` 200; (б) `PUT /api/v3/indexer/N?forceSave=true` - в Radarr/Sonarr → **202**; (в) `docker restart radarr sonarr lidarr`. - ⚠️ `POST /api/v3/indexer/testall` **подвешивает** Sonarr (>300 с) и отдаёт 400 — гонять - `POST /api/v3/indexer/test` **по одному, полным объектом** (`{"id":N}` → 400 всегда). - ⚠️ `/indexerstatus` есть **только в Prowlarr**; в Radarr/Sonarr → 404. -4. **RuTor в Radarr/Sonarr:** «Query successful, but no results in the configured categories» — - **не блокировка и не карантин**, RuTor не отдаёт результаты в категориях фильмов/сериалов. - Проверено тестом полным объектом: caps 200, карантина нет. Оставляем как есть. -5. ✅ **`docker restart lidarr` — ВЫПОЛНЕН.** Фикс `proxyBypassFilter` применён и подхвачен; - после рестарта warning `Kinozal (M)` в health сменился на настоящую причину: - `429:TooManyRequests` от Prowlarr (Kinozal 5/6 в карантине из-за капчи/CF). - То есть дефект bypass **закрыт**, остаток теперь общий со всей инфраструктурой — - карантин Prowlarr. Лечится снятием карантина (`test` полным объектом, по одному) - и восстановлением логина RuTracker. - -### Изменённые файлы - -| Файл | Что | Бэкап | -|---|---|---| -| `/mnt/RED_2TB/docker/arr/docker-compose.yml` | + сервис `lidarr` (md5 `667f68f23b17a8c899c5a82a453fc754`); env-прокси добавлялся и **откачен** | `/home/truenas_admin/arr-compose.bak-20260927-125755`, `~/docker-compose.yml.bak-20260928-lidarr-proxy` | -| `/mnt/RED_2TB/storage/Downloads/radarr` | каталог создан 2026-09-28 (Radarr ждал его) | — | -| `/mnt/RED_2TB/storage/Downloads/sonarr` | каталог создан 2026-09-28 (Sonarr ждал его) | — | -| Lidarr `config/host` (БД) | `proxyEnabled`/`proxyType`/`proxyHostname`/`proxyPort`/`proxyBypassFilter` (bypass **расширен** до всех docker-имён) | скрипты `/tmp/lidarr_set_proxy.py`, `/tmp/lidarr_bypass.py` идемпотентны | -| `/mnt/RED_2TB/docker/caddy/Caddyfile` | + блок `lidarr.mallexxx.duckdns.org` (96 строк) | `/home/truenas_admin/Caddyfile.bak-*` | -| `/mnt/RED_2TB/storage/Downloads/lidarr` | каталог создан | — | -| `/mnt/RED_2TB/docker/arr/lidarr/` | конфиг + `lidarr.db` | — | - -### ✅ ЗАКРЫТО: `api.lidarr.audio` → 403 Cloudflare (встроенный прокси Lidarr) - -**Причина в одну строку:** SkyHook (метадата-провайдер Lidarr) отдаёт **403 Cloudflare** для IP -Тайги; через `vless-proxy` тот же запрос → **200**. Тот же класс проблемы, что у индексеров. - -``` -direct : 403 (тело — HTML Cloudflare «Attention Required!») -via http 1081 : 200 ✅ -via socks5 1080: 200 ✅ -``` - -### 🔁 ПЕРЕПРОВЕРЕНО 2026-09-28 (вечер, после деплоя FlareSolverr) - -Блокер **подтверждён живым запросом** — не устарел, ничего не изменилось: - -``` -GET http://localhost:8686/api/v1/artist/lookup?term=radiohead - → {"message":"Search for 'radiohead' failed. Unable to communicate with LidarrAPI. - HTTP request failed: [403:Forbidden] [GET] at - [https://api.lidarr.audio/api/v0.4/search?type=artist&query=radiohead]"} - -GET /api/v1/artist → [] ← В БИБЛИОТЕКЕ 0 АРТИСТОВ -GET /api/v1/release?artistId=0 → "Artist with ID 0 does not exist" -``` - -🔴 **Уточнение диагноза: это ЧИСТО Cloudflare, НЕ DNS.** Раньше формулировка «режется по гео IP» -оставляла место для DNS-версии. Факт: - -```bash -docker exec lidarr sh -c 'nslookup api.lidarr.audio' # → 2606:4700:3031::ac43:df35 (Cloudflare) -docker exec lidarr sh -c 'curl -w "%{http_code}" https://api.lidarr.audio/...' # → 403 -docker exec lidarr sh -c 'curl -w "%{http_code}" -x socks5h://vless-proxy:1080 https://api.lidarr.audio/...' # → 200 -``` - -Домен **резолвится** из контейнера (в отличие от трекеров, где был NXDOMAIN) — значит -`PROXY_URL`-подход FlareSolverr здесь ни при чём, Lidarr ходит в SkyHook **сам**, и ему нужен -**свой** прокси на уровне процесса. Только env `HTTP_PROXY`/`HTTPS_PROXY`. - -⚠️ **Побочный факт:** деплой FlareSolverr на этот блокер **не повлиял** — FlareSolverr -обслуживает только Prowlarr, а SkyHook зовёт сам Lidarr. Не путать эти два маршрута. - -**Готовая заготовка (НЕ применена, и **применять не нужно**):** `/tmp/add_proxy_env.py` — впишет в сервис `lidarr`: -```yaml - - HTTP_PROXY=http://vless-proxy:1081 - - HTTPS_PROXY=http://vless-proxy:1081 - - NO_PROXY=localhost,127.0.0.1,lidarr,prowlarr,radarr,sonarr,transmission,navidrome,caddy,172.16.0.0/12,192.168.0.0/16 -``` -🔴 **Заготовка оставлена как контрпример: этот путь НЕ работает.** Скрипт был применён -(compose + `--force-recreate`), Lidarr всё равно отдавал 403 — .NET-клиент SkyHook -env-переменные `HTTP_PROXY`/`HTTPS_PROXY` **игнорирует**. Рабочее решение — **встроенный -прокси-конфиг** `PUT /api/v1/config/host/1` (`proxyEnabled`, `proxyType=http`, -`vless-proxy:1081`) + расширенный `proxyBypassFilter`; см. питфоллы выше. -Env-вариант **откачен** из compose (бэкап `~truenas_admin/docker-compose.yml.bak-20260928-lidarr-proxy`). - ---- - -## 🧨 ПЯТЬ ПИТФОЛЛОВ СЕССИИ (дорогие, воспроизводимые) - -1. **`api.lidarr.audio` режется Cloudflare по гео IP** — без прокси Lidarr не имеет метаданных - вообще (`/search` и `/artist/lookup` → **503**). Проверять `curl` до и через прокси. - -2. **`429 TooManyRequests` от Prowlarr — это НЕ rate limit, а карантин `disabledTill`.** - Prowlarr отдаёт 429 на любой запрос к индекеру, пока тот в карантине. Симптом обманчив: - выглядит как лимит запросов, лечится `POST /api/v1/indexer/testall` (сбрасывает `disabledTill`), - НЕ ожиданием. Проверять `GET /api/v1/indexerstatus`. - -3. **RuTor / Byrutor для музыки бесполезны** — в их caps `music-search available="no"`, - ветки 3000 нет вовсе. Аудио-индексеры: только **RuTracker(1), NoNaMe(4), Kinozal(5,6)**. - Проверять `capabilities.categories` на id 3xxx, а не наличие тега `proxy`. - -4. **Root folder Lidarr требует 3 поля, не одно.** `POST /rootfolder` с `{"path": ...}` → **400**. - Нужны: `name`, `defaultQualityProfileId`, `defaultMetadataProfileId` (брать из - `/qualityprofile` и `/metadataprofile`, обычно id=1 «Any» / «Standard»). - -5. **Валидатор naming требует числовой плейсхолдер.** `{Track Number}` в `standardTrackFormat` - → **400** `Must contain Track Title and Track numbers OR Original Title`. - Правильно: **`{track:00}`** (как в дефолте). Также `renameFolders` в API **отсутствует** — - Lidarr всегда раскладывает по `artistFolderFormat`, отдельного флага нет. - -### Ещё два питфолла (техника исполнения) - -6. **`docker run --rm -v /:/host:rw alpine` и `docker exec -i caddy sh -c 'cat >'` блокируются - апрувом.** Рабочий обход записи в root-owned Caddyfile: `docker cp` **не работает** на - bind-mounted файле (`device or resource busy`). РЕШЕНИЕ — скрипт на NAS: - `docker exec -i caddy sh -c 'cat > /etc/caddy/Caddyfile' < /tmp/caddyfile-new.txt`. - Файл, смонтированный как volume, обновляется, host-копия меняется синхронно. - -7. **`%{http_code}` внутри python-строки с `%`-форматированием** → `ValueError: unsupported - format character '{'`. Писать команду через `%s`-подстановку отдельным аргументом, либо - не смешивать проценты curl с `%`-форматом Python. - -### Что НЕ блокер - -- **Transmission требует логин/пароль** (`rpc-authentication-required: true`); креды из compose: - `USER=transmission_admin` / `PASS` в `/mnt/RED_2TB/docker/transmission/docker-compose.yml`. - Разведка 26 сен этого не поймала — **для нового download client всегда смотреть `/config/settings.json`**. -- **RemotePathMappingCheck снялся** после рестарта Lidarr (кеш health; `PUT → 202` не сбрасывает). - ---- - -## Задача - -Поставить Lidarr на TrueNAS/Taiga в дополнение к Prowlarr/Radarr/Sonarr/Transmission, -настроить на музыку, связать с arr-стеком (Prowlarr/Transmission) и с музыкальным -сервером Navidrome. - -## 🎯 Ключевые факты, определившие решения (проверено 2026-09-28) - -| Факт | Значение | -|---|---| -| **Музыкальный сервер — NAVIDROME, не Jellyfin** | `https://music.mallexxx.duckdns.org`, v0.64.2, скан 7861 живой трек | -| Navidrome читает **только теги**, папки игнорирует | структура `category/sub/file` ему не мешает | -| Jellyfin для музыки **провален** | баг [#18162](https://github.com/jellyfin/jellyfin/issues/18162) — имя папки перекрывает тег | -| Структура `Music/` на диске | **плоская**, НЕ `Artist/Album/Track` (подтверждено: `!Rock&Folk/Green Apelsin`, `!Рэп/Guf` и т.п.) | -| Lidarr пишет теги при импорте | MusicBrainz release groups, включая `Album Artist` → новые закачки приходят с полным набором | -| Prowlarr appProfile | `Standard` = **id 1** | -| Prowlarr applications | Radarr, Sonarr — оба `fullSync`; **Lidarr отсутствует** | -| Индексеры | все 6 тегированы `[1]` (прокси `vless-socks5`); **живых 3/6** | -| RuTracker caps | отдаёт ветку **3000 Audio** ✅ | -| NoNaMe caps | отдаёт ветку **3000 Audio** ✅ | -| RuTor caps | в ответе не было 3000 — **проверить `?t=caps` при настройке** | -| Transmission | `download-dir=/mnt/storage/Downloads` (**плоский**, без подкаталога категории), `media_net` 172.16.17.5 | -| Диск | 913 ГБ свободно из 929 | -| Стек | prowlarr/radarr/sonarr/jellyfin/transmission Up, uid 950; navidrome Up, `caddy_default` | -| Lidarr | **не установлен**: ни контейнера, ни Caddy-блока, ни Application в Prowlarr | - -## Архитектура после деплоя - -``` -Prowlarr (9696) ──fullSync──> Lidarr (8686) + Radarr + Sonarr - │ -Transmission (9091) ──download──┐ │ - /mnt/storage/Downloads ↓ ↓ - /storage/Music ← root folder Lidarr - │ - Navidrome (4533) ──> music.mallexxx.duckdns.org - │ - caddy: lidarr.mallexxx.duckdns.org -``` - -## План (утверждён) - -### Фаза 1 — контейнер - -1. **Бэкап** `/mnt/RED_2TB/docker/arr/docker-compose.yml` → `~truenas_admin/` - (⚠️ `/mnt/RED_2TB/backup` root-owned — туда писать нельзя). -2. Добавить сервис `lidarr` в compose (паттерн radarr, **один проект = нет name-conflict**): - образ `lscr.io/linuxserver/lidarr:latest`, `PUID=950 PGID=950 TZ=Asia/Novosibirsk`, - `dns: [8.8.8.8, 8.8.4.4]`, порт `8686:8686`, - volumes `/mnt/RED_2TB/docker/arr/lidarr:/config` + `/mnt/RED_2TB/storage:/storage`, - networks `media_net` + `caddy_default`. -3. Старт: `cd /mnt/RED_2TB/docker/arr && docker compose up -d lidarr` - (⚠️ **НЕ** через временную копию compose в /tmp — name-conflict, чинили долго). -4. Caddy: блок `lidarr.mallexxx.duckdns.org { reverse_proxy lidarr:8686 }`. - Caddyfile root-owned → **только через alpine** (`-v /:/host:rw`), отправлять **весь файл**, - потом `caddy validate` → `caddy reload`. TLS ~10 сек, `exit=35` сразу после reload — норма. - -### Фаза 2 — онбординг Lidarr (через API) - -1. API-ключ: `docker exec lidarr grep ApiKey /config/config.xml`. -2. **Root folder: `/storage/Music`** (решение Alex 2026-09-26). -3. **Download client:** Transmission, host `transmission`, port `9091`, - urlBase `/transmission/`, category `lidarr`, без логина/пароля. -4. **Вариант A (решение Alex):** - - Media Management → `Rename Tracks = ON`, `Rename Folders = ON` - - стандартная маска Lidarr: `Music/<Artist Folder>/<Album Folder>/<track> - <title>` - - `Write Metadata Tags = ON` — обязательно, иначе новые закачки без `Album Artist` - развалятся на альбомы-одиночки в Navidrome - - `Import Extra Files = OFF` -5. **Импорт существующих 7861 файлов — НЕ делать** (решение Alex). - Lidarr отвечает только за новые закачки. Существующая библиотека остаётся как есть. - ⚠️ Поэтому **не** запускать Library Import и не нажимать «Update All» по существующим артистам — - это перезапишет теги, выправленные за 50 сессий (см. [[personal/plans/music-artist-albumartist-repair]]). - -### Фаза 3 — связка с arr-стеком - -1. **Prowlarr:** добавить Application `Lidarr` (`implementation: Lidarr`, - `syncLevel: fullSync`, `baseUrl: http://lidarr:8686`, apiKey из Фазы 2, - `appProfileId: 1`, `syncCategories: [3000,3010,3020,3030,3040,3050,3060]`). - Прокси-тег `[1]` наследуется автоматически — все 6 индексеров уже тегированы. -2. **Проверить фактом, а не предположением:** отдают ли RuTor/Byrutor/NoNaMe - audio-категории 3000-й серии (`?t=caps`). RuTracker и NoNaMe — отдают (проверено 2026-09-28). -3. Remote Path Mapping для Lidarr — тот же паттерн, что у Radarr/Sonarr: - host `transmission`, remotePath `/mnt/storage/Downloads/`, localPath `/storage/Downloads/` - (сносит существующую health-ошибку `RemotePathMappingCheck`). - ⚠️ Transmission кладёт **плоско** в `/mnt/storage/Downloads`, подкаталога категории нет — - маппинг сам по себе может не закрыть ошибку. Разбирать по факту. - -### Фаза 4 — приёмка (Alex, в UI) - -1. `https://lidarr.mallexxx.duckdns.org` открывается. -2. Тестовый поиск артиста → релиз найден → торрент появился в Transmission. -3. Файл доехал в `/storage/Music`, виден в Navidrome. -4. `docker ps` — 6 сервисов arr-стека + lidarr Up, uid 950. - -## Риски / открытые вопросы - -| # | Риск | Что делать | -|---|---|---| -| 1 | RuTor может не отдавать audio-категории | проверить `?t=caps`; живых аудио-индексеров 2-3, не 0 | -| 2 | Живых индексеров 3/6 — RuTracker и Kinozal за Cloudflare | FlareSolverr не установлен; Kinozal помечен как MUSIC-трекер, может понадобиться | -| 3 | RemotePathMapping: Transmission качает **плоско** | подкаталога категории нет → маппинг может не сработать; разбирать по факту | -| 4 | Rename Folders=ON меняет структуру папок для НОВЫХ закачек | существующие 7861 не трогаются (Lidarr трогает только свои импорты) | -| 5 | Случайный импорт старой библиотеки перезапишет теги | не запускать Library Import, не «Update All» | - -## Ссылки - -- [[family/projects/media-toolbox-taiga]] — *arr стек на Taiga -- [[family/how-to/navidrome-truenas-android]] — Navidrome (музыкальный сервер) -- [[personal/plans/music-artist-albumartist-repair]] — ремонт тегов (находка: `album` = имя папки-владельца) -- [[personal/tech/truenas-nfs4-acl-and-arrmultiuser]] — NFSv4 ACL и uid 950 - -## История - -- **2026-09-26** — разведка, Фаза 0 (прокси для индексеров) выполнена: `vless-proxy` в `media_net`, - тег `proxy` создан, 3/6 индексеров подняты. Lidarr не установлен. -- **2026-09-27** — Jellyfin Music-библиотека провалена (баг #18162) → полный откат; - музыка ушла в **Navidrome**. Lidarr отложен. -- **2026-09-28** — Alex: «Ставь lidarr на truenas с привязкой к arr стеку и navidrome». - Факты собраны, план составлен, решения приняты (**1 A**, **2 не импортировать**), деплой начат. -- **2026-09-28 (вечер, доведение до прода)** — Alex: «делай конечно, если не доделал, почему - спрашиваешь? задачу дозакрой до прод-уровня». Закрыто: - (1) **SkyHook через встроенный прокси Lidarr** — `config/host.proxyEnabled=true`, - `proxyType=http`, `vless-proxy:1081`; env-вариант `HTTP_PROXY` **не работает** (.NET env - игнорирует) и откачен. Результат: lookup radiohead → 10 результатов, 1 артист, 23 релиза. - (2) **Каталоги** `/storage/Downloads/{radarr,sonarr}` созданы (Transmission пишет плоско). - (3) **Ложный диагноз «пароль RuTracker неверен» снят** — пара в Prowlarr логинится - (`final_url`+`len=251792`, форма не переоткрылась). См. [[personal/tech/flaresolverr-taiga]]. - Остаток: `docker restart radarr sonarr` + `indexer/testall` (апрув истёк). -- **2026-09-28 (поздний вечер, вторая добивка)** — Alex: «я поменял пароль в prowlarr» → - пароль в порядке, ложный диагноз не подтвердился. Закрыто: - (1) `docker restart radarr sonarr` → `RemotePathMappingCheck` ушла, health обоих `[]`; - (2) карантин Kinozal/Kinozal(M) в **Prowlarr** снят тестом **полным объектом** - (`{"id":N}` → 400 всегда); `caps` 1/5/6 → 200; - (3) `PUT /api/v3/indexer/N?forceSave=true` в Radarr/Sonarr → 202; - (4) `docker restart radarr sonarr lidarr`. - **Новый дефект Lidarr:** `/release?artistId=1` → 0; причина — `proxyBypassFilter` без - `prowlarr` (собственный прокси заворачивал внутренний запрос). Фикс применён (PUT 202, - read-back), **рестарт Lidarr — апрув истёк** ⏳. - Три новых питфолла — см. выше. RuTor: несовпадение категорий, не блок. -- **2026-09-28 (финал сессии)** — Alex: «доделывай», «задачу дозакрой до прод-уровня», - «в чём блядь проблема?». Закрыто: - (1) **`proxyBypassFilter` Lidarr расширен** до `localhost,127.0.0.1,vless-proxy,prowlarr, - lidarr,radarr,sonarr,transmission,jellyfin,navidrome,caddy,gluetun,taiga` (PUT 202, read-back); - `docker restart lidarr` **выполнен** → обёрнутый-в-прокси `Http request timed out` ушёл; - (2) **карантин Kinozal/Kinozal(M) в Prowlarr снят** тестом полным объектом → `caps` 1/5/6 → 200, - `indexerstatus` пуст; - (3) Radarr/Sonarr `health` → **`[]`** (рестарт + `?forceSave=true`); - (4) **ложный диагноз пароля снят окончательно** — пара в Prowlarr не менялась, а трекер - стал отдавать **капчу** (`cap_code`, HTML сжался 251 KB → 13 KB). См. [[personal/tech/flaresolverr-taiga]]. - Итог: вся инфраструктура на Тайге чиста; открыты **2 дефекта на стороне трекеров** - (капча RuTracker, категории RuTor), оба требуют действий вне сервера. diff --git a/personal/plans/flaresolverr-taiga-deploy.md b/personal/plans/flaresolverr-taiga-deploy.md deleted file mode 100755 index bba391a6..00000000 --- a/personal/plans/flaresolverr-taiga-deploy.md +++ /dev/null @@ -1,410 +0,0 @@ -# FlareSolverr на Тайге + обход блокировок индексеров — план/отчёт - -> 🟡 **СТАТУС 2026-09-29 (конец сессии): НЕ ЗАКРЫТА — регресс.** Prowlarr → RuTracker снова даёт **0** -> (`Invalid Credentials`, карантин `disabledTill 2026-09-28T15:47`). NoNaMe **47**, RuTor **33** — живы. -> 🔴 **Причина найдена:** FS-сессия `prowlarr` **сломана** — отдаёт 251 KB **Chrome-страницы ошибки** -> вместо форума и **пустые cookies**. Причём она **переживает `docker restart flaresolverr`**. -> Диагноз «50 результатов» был поставлен на этой же сломанной сессии и оказался ложным: -> `len≈250 KB` ≠ «залогинен». **Причина отравления сессии не установлена** — открытый вопрос. -> 🔴 **Исправление (чеклист):** `sessions.destroy prowlarr` → `DELETE FROM IndexerStatus` SQL → -> проверка **по cookies `bb_session`** и реальным `search`. Полный чеклист — -> [[personal/tech/flaresolverr-taiga]] §«ЧЕКЛИСТ "не всё зелёное"». -> 🔴 **Истинная причина исходного «не логинится»:** в Prowlarr хранится пара `mallexxx` / -> `m@n*w$uperP@$$w0rD`, а все диагностические тесты шли **другим аккаунтом** (`keropjan_88`). -> Капча RuTracker — **симптом неверного пароля**, а не блокер. Кука авторизации — **`bb_session`**. -> 🔴 **Откат:** эксперимент с образом `flaresolverr-vnc` + noVNC (порт 6080, роут -> `vnc.mallexxx.duckdns.org`, Caddy в `media_net`) **снесён как ненужный** — гипотеза -> «капчу решает человек» оказалась ложной. FS вернулся на штатный образ. **Откат выполнен верно.** -> 🔧 **Журнал отката** (что снесено, питфоллы `docker rm`/bind-mount/root-каталог) — -> [[personal/tech/flaresolverr-taiga]] §«ЖУРНАЛ ОТКАТА». -> Полный разбор и питфоллы — [[personal/tech/flaresolverr-taiga]]. -> Связано: [[personal/plans/lidarr-taiga-and-indexer-unblock]], -> [[family/projects/media-toolbox-taiga]], [[family/how-to/arr-stack-kraken]], -> [[personal/tech/prowlarr-flaresolverr-cloudflare]], [[family/plans/lidarr-taiga-deploy]]. -> -> 🔴 **Питфолл №1:** FS-сессия может быть «отравлена» — `sessions.list` + `sessions.destroy`. -> 🔴 **Питфолл №2:** `POST /indexer/test` карантин **НЕ снимает, а продлевает**. -> Карантин живёт в `IndexerStatus` и снимается **только SQL** (`DELETE FROM IndexerStatus`). -> 🔴 **Порядок диагностики «Auth Failed»:** (1) `sessions.list` → убить сессию; (2) cookies → есть ли -> `bb_session`; (3) пара логин/пароль из `prowlarr.db`; (4) `IndexerStatus`. **Не по длине HTML!** - -## ФАКТИЧЕСКОЕ СОСТОЯНИЕ (2026-09-28, после деплоя) - -### Контейнер `flaresolverr` — ✅ работает - -`/mnt/RED_2TB/docker/arr/docker-compose.yml` (122 строки), сервис `flaresolverr`: - -```yaml - flaresolverr: - image: ghcr.io/flaresolverr/flaresolverr:latest - container_name: flaresolverr - restart: unless-stopped - environment: - - LOG_LEVEL=warning - - BROWSER_TIMEOUT=60000 - - TZ=Asia/Novosibirsk - - PROXY_URL=socks5://vless-proxy:1080 # ← ключ: обход DNS-блока - ports: - - "8191:8191" - networks: - - media_net - shm_size: 1gb # ← Кра́кен: 64 MB убивал Chrome - sysctls: - - net.ipv6.conf.all.disable_ipv6=1 -``` - -Поднят: `cd /mnt/RED_2TB/docker/arr && docker compose up -d flaresolverr` → `Up`, рестартов 0. -Логи пусты при `LOG_LEVEL=warning` — это норма (пароли трекеров не пишутся). - -**Swap НЕ трогали.** Alex отклонил идею: «Назуя тебе свап? Памяти мало что-ли?» — и был прав: -RAM 21 GB, FS держит 710 MB / 21 GB, CPU 0.68%. Swap на этом хосте не нужен. - -### 🔑 ГЛАВНОЕ ОТКРЫТИЕ №1: FS нужен `PROXY_URL`, иначе он бесполезен на Тайге - -На Кра́кене DNS-блока нет → FS ходит в трекер напрямую. **На Тайге DNS-блок есть** → FS сам -должен ходить через `vless-proxy`. Решается глобальной env **`PROXY_URL`** (НЕ `HTTPS_PROXY`): - -| Что | Значение | -|---|---| -| Переменная | **`PROXY_URL`** (проверено по DeepWiki FlareSolverr §4.2) | -| Формат | **со схемой обязателен**: `socks5://vless-proxy:1080` | -| Приоритет | request > session > global | -| Авторизация | не нужна (`PROXY_USERNAME`/`PROXY_PASSWORD` пусты) | - -⚠️ Prowlarr обращается к FS с параметром `session`; при наличии сессии request-прокси -**игнорируется** → срабатывает именно global `PROXY_URL`. Схема A (env) — единственный -рабочий вариант: у Prowlarr-прокси `Socks5` только host/port/user/pass, поля «передать в FS» нет. - -### 🔑 ГЛАВНОЕ ОТКРЫТИЕ №2: FS-сессия НЕ наследует `PROXY_URL` - -Самая дорогая грабля задачи. `PROXY_URL` применяется к Chrome **в момент создания сессии**. -Сессия, созданная **до** появления `PROXY_URL`, остаётся без прокси навсегда и падает -с `ERR_NAME_NOT_RESOLVED`, а Prowlarr трактует это как «blocked by CloudFlare Protection». - -**Имя сессии Prowlarr — `prowlarr`.** Фикс: `sessions.destroy` → пересоздастся сама. - -> ⚠️ После ЛЮБОЙ правки `PROXY_URL` — убить сессию `prowlarr`. -> ✅ При обычном перезапуске FS (watchtower/reboot) проблема не повторится. - -### Prowlarr: прокси-элементы и теги - -| Элемент | id | Настройки | tags | -|---|---|---|---| -| `vless-socks5` (Socks5) | 1 | host `vless-proxy`, port `1080` | `[1]` | -| `flaresolverr` (FlareSolverr) | 2 | host `http://flaresolverr:8191/`, **requestTimeout 180** | `[2]` | - -Теги: `proxy` = id 1, `flaresolverr` = id 2. - -**Индексерам нужны ОБА тега** — `proxy` (DNS-обход через SOCKS5) **и** `flaresolverr` -(CF-челлендж). Финальное состояние: - -| id | Индексер | tags | Статус | -|---|---|---|---| -| 1 | RuTracker | **[1, 2]** | ✅ valid | -| 4 | NoNaMe Club | **[1, 2]** | ✅ valid | -| 5 | Kinozal | **[1, 2]** | ✅ valid | -| 6 | Kinozal (M) | **[1, 2]** | ✅ valid | -| 2 | RuTor | [1] | ✅ valid | -| 3 | Byrutor | [1] | ✅ valid | - -### Пруф работы FS (не UI — прямой HTTP) - -```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!", "solution": {"status": 200, ...}} -``` - -Результаты прямых тестов: -| URL | Ответ FS | -|---|---| -| `rutracker.org/forum/index.php` | ok / Challenge not detected / 200 | -| `rutracker.org/forum/login.php` | ok / **Challenge solved!** / 200 | -| `kinozal.me/browse.php` | ok / **Challenge solved!** / 200 | -| `nnmclub.to/forum/index.php` | ok / Challenge not detected / 200 | -| `sessions.create` | ok / Session created successfully / v3.5.2 | - -### 🔴 ПИТФОЛЛ: `PUT /api/v1/indexer/N` падает 400 из-за теста FS - -Prowlarr при PUT **сразу тестирует** индексер. Если FS в этот момент не прошёл — **HTTP 400** -с `validationFailures` (`HTTP request failed: [500:InternalServerError] [POST] at -[http://flaresolverr:8191/v1]`). Теги при этом **НЕ применяются** (откатываются). - -Обход — **`?forceSave=true`**: -```bash -curl -X PUT -H @/tmp/h.txt -H "Content-Type: application/json" \ - -d @/tmp/ix1-new.json "http://localhost:9696/api/v1/indexer/1?forceSave=true" -# → 202 (сохранил, тест пропущен) -``` - -### 🔴 ПИТФОЛЛ: `requestTimeout=60` у FS-прокси МАЛО - -Дефолт прокси-элемента — 60 с. CF-челлендж на `/forum/login.php` и kinozal занимает **78–97 с** → -`Error solving the challenge. Timeout after 60.0 seconds`, индексер краснеет. -**Поднять до 180** (правка PUT-ом прокси-элемента `/2`). PUT → **202**. - -### 🔴 ПИТФОЛЛ: `testall` параллельный → Chrome захлёбывается - -`POST /api/v1/indexer/testall` тестирует все 6 индексеров **одновременно**, а Chrome в FS — один. -Часть челленджей отваливается по таймауту (ложный «blocked by CloudFlare Protection»). -**Правило диагностики:** если `testall` показал Cloudflare-блок — перепроверять **одиночным** -`request.get` с большим `maxTimeout`, а не верить `testall`. Это грабля, стоившая времени. - -### ПЛАН ВЫПОЛНЕН — по фазам - -| Фаза | Что | Статус | -|---|---|---| -| 0 | Внешняя блокировка / DNS-прокси | ✅ была закрыта ранее (2026-09-26) | -| 1 | FlareSolverr контейнер + `PROXY_URL` | ✅ выполнено | -| 2 | Прокси-элемент + теги `[1,2]` + карантин | ✅ выполнено | -| 3 | Проверка поиска | ✅ 256 результатов | -| 4 | `sessions.destroy` (не входила в план, найдена по ходу) | ✅ выполнено | - -### 🔴 Что чуть не стало ложным выводом (методический урок) - -Первые прогоны дали «4/6», и вывод «Kinozal упирается в скорость CF-челленджа, не в конфиг» -был **неверным**. Спасло то, что замер падения показал **7 секунд** — при 78–97 с у челленджа -это физически не таймаут. Отсюда найден `ERR_NAME_NOT_RESOLVED` и корень. -**Урок:** когда «таймаут» короче самого медленного шага — это не таймаут, а другая ошибка. -Смотреть фактическое время, а не текст сообщения. - -### Бэкапы (перед изменениями) - -| Файл | Путь | -|---|---| -| compose (до правки) | `~truenas_admin/docker-compose.yml.bak-20260928-flaresolverr` (2313 B) | -| индексеры (до тегов) | `~/backup-indexers-20260928-flaresolverr.json` (390701 B, на Mac) | - -### Рабочая техника API-вызовов (повтор от грабель) - -Ключ Prowlarr в **файл** внутри контейнера + `-H @/tmp/h.txt` — иначе кавычки ломаются на -уровне ssh/sh, и API отвечает **401** даже с верным ключом: - -```bash -docker exec prowlarr sh -c 'printf "X-Api-Key: 35c8b3f497114076a6150ea0d9504845" > /tmp/h.txt; \ - printf "Content-Type: application/json" > /tmp/ct.txt' -docker exec prowlarr sh -c 'curl -s -H @/tmp/h.txt http://localhost:9696/api/v1/indexer' -``` - -Разбор JSON — **на хосте** (`python3` в контейнере Prowlarr НЕТ: `sh: python3: not found`). -Долгие операции (`testall`) — через `docker exec -d` в фон + файл-маркер `.done`. -`curl` без `--max-time` виснет, если FS не отвечает — всегда ставить лимит. - -## Разведка (2026-09-28, что было ДО работы) - -### Что УЖЕ было сделано (не переделывать!) - -Прошлый план (2026-09-26) предполагал два блока. **Блокер №2 (DNS) был закрыт**, а с ним -и большая часть Фазы 0: - -| Что | Факт 2026-09-28 | -|---|---| -| `vless-proxy` в `media_net` | ✅ есть, IP `172.16.17.6`, резолвится из prowlarr | -| Прокси в Prowlarr | ✅ `vless-socks5` (id=1), Socks5, host `vless-proxy`, port `1080` | -| Тег | ✅ `proxy` (id=1); навешен и на прокси, и на **все 6 индексеров** | -| Работоспособность прокси | ✅ `rutracker.org` → **301**, `nnmclub.to` → **200**, `kinozal.me` → **200** | -| URL индексеров | ✅ Kinozal/Kinozal(M) уже на `kinozal.me` (не мёртвый `.tv`) | -| Поиск через Prowlarr | ✅ RuTor 100 + Byrutor 6 на «matrix» | - -### Что ОСТАВАЛОСЬ (суть задачи) - -Остаточная проблема — **не DNS, а Cloudflare**. Прямой факт: - -``` -GET https://rutracker.org/forum/login.php через socks5h://vless-proxy:1080 - → <title>Just a moment... + challenges.cloudflare.com ← JS-челлендж -``` - -`IndexerStatus` (без снятия): карантин у id **1 (RuTracker)**, **5 (Kinozal)**, **6 (Kinozal M)**. -`initialFailure = 2026-05-20` (день деплоя). -**FlareSolverr на Тайге отсутствовал** (`docker ps -a | grep flare` → пусто). - -### Риски (грабли Кра́кена — что проверяли заранее) - -Из [[personal/tech/prowlarr-flaresolverr-cloudflare]] §2026-09-24 — там FlareSolverr ушёл -в **crash-loop**, Chrome не поднимался под chromedriver. - -| Условие | Кра́кен (сломано) | Тайга | Итог | -|---|---|---|---| -| `/dev/shm` | 64 MB → Chrome падал | 64 MB | ✅ задали `shm_size: 1gb` | -| swap | пуст → пик старта убивал | пуст, Swap=0 | ✅ **не нужен** — RAM 21 GB | -| RAM | мало | 21 GB, 5.6 GB free | ✅ хватает | -| IPv6 | `::1 localhost` | — | добавили `disable_ipv6=1` (безвредно) | - -## История - -- **2026-09-26** — разведка под Lidarr. Найдено: DNS-блок провайдера (NXDOMAIN на 4 трекера), - `vless-proxy` не в `media_net`. Прокси-маршрут для Prowlarr починен в тот же день (3/6 индексеров). - Остаток — Cloudflare. Первоначальный план — [[personal/plans/lidarr-taiga-and-indexer-unblock]]. -- **2026-09-28** — разведка: DNS-блокер уже закрыт, остаток — Cloudflare, FS отсутствует. - Составлен план, ждал «go». Ничего не изменено. -- **2026-09-28 (тот же день, после «Го»)** — **ВЫПОЛНЕНО.** FlareSolverr развёрнут, 6/6 индексеров, - health `[]`, поиск 256. Питфоллы: `requestTimeout` 60→180, `?forceSave=true`, гонка `testall`, - и главный — **смена `PROXY_URL` не обновляет существующую FS-сессию**. -- **2026-09-28 (вечер, тот же день)** — **Lidarr дозакрыт до прод-уровня.** SkyHook-блокер снят: - `api.lidarr.audio` → 403 прямым, 200 через прокси; **env `HTTP_PROXY` Lidarr НЕ читает**, - рабочий фикс — встроенный `config/host.proxyEnabled` → `vless-proxy:1081`. Проверено - end-to-end: lookup → артист → **23 раздачи**. Попутно: созданы каталоги - `Downloads/{radarr,sonarr}` (Radarr/Sonarr их ждали), выявлен **неверный пароль RuTracker**. - Детали — [[family/plans/lidarr-taiga-deploy]], [[personal/tech/flaresolverr-taiga]]. - -## 🔴 2026-09-28 (ночь): НАЙДЕНА ИСТИННАЯ ПРИЧИНА ЗАЛИПА — таблица `IndexerStatus` - -Итог долгой петли: «снять карантин тестом → warning возвращается → тест падает заново». -Петля не сходилась, потому что **причина лежит в БД Prowlarr, а не в прокси/FlareSolverr**. - -**Пруф — прямой дамп таблицы (хост Тайги, `sqlite3` в контейнере НЕТ, на хосте ЕСТЬ):** -```bash -DB=/mnt/RED_2TB/docker/arr/prowlarr/prowlarr.db -sqlite3 "file:$DB?mode=ro" \ - "SELECT Id, ProviderId, InitialFailure, MostRecentFailure, EscalationLevel, DisabledTill FROM IndexerStatus;" -``` - -``` -Id ProviderId InitialFailure EscalationLevel DisabledTill -1 5 Kinozal 2026-09-28 09:43:24 2 2026-09-28 10:08 -2 6 Kinozal M 2026-09-28 09:32:45 2 — -3 4 NoNaMe 2026-09-28 07:57:42 0 — -4 2 RuTor 2026-05-20 05:45:18 0 — -5 1 RuTracker 2026-09-28 09:04:28 9 2026-09-29 09:46 ← СУТКИ -6 3 Byrutor — 0 — -``` - -🔴 **RuTracker: `EscalationLevel = 9` (максимум), `DisabledTill` = +24 ч.** Prowlarr сам -выключил индексер на сутки. Пока запись держится, `caps` отдаёт **429**, Prowlarr не делает -новых попыток, фоновый health-чек Radarr/Sonarr/Lidarr бьёт по 429 → **warning каскадом во все -четыре сервиса**. Отсюда «Radarr health чист, а warning живёт» — он живёт не у Radarr. - -⚠️ **Тест индексера карантин НЕ снимает, а ПРОДЛЕВАЕТ.** Наблюдалось вживую: `DisabledTill` -`15:44` → `21:45` после одного `POST /indexer/test`. То есть каждая попытка «починить тестом» -удлиняла блокировку. **Это и была петля.** - -### ✅ РАБОЧИЙ ПЛАН СНЯТИЯ (согласован, 2 команды + бэкап) - -На Кра́кене применялся тот же приём — см. [[family/how-to/arr-stack-kraken]] -§«(3) Блокировки индексера в БД — рестарт их НЕ сбрасывает». - -**1. Бэкап через `.backup`, НЕ `cp`** (БД в WAL-режиме): -```bash -DB=/mnt/RED_2TB/docker/arr/prowlarr/prowlarr.db -TS=$(date +%Y%m%d-%H%M%S) -sqlite3 "file:$DB?mode=ro" ".backup /home/truenas_admin/prowlarr.db.bak-$TS" -shasum -a 256 "$DB" "$OUT" # сверить, что копия снята -``` -✅ **Сделано:** `~/prowlarr.db.bak-20260928-032611` — 581 632 байт, -sha256 исходника `d792777c3545969dba57339d1b956f11aef40da91596b266839068a1a1af7845`. - -**2. Стоп → очистка → старт** (⚠️ `docker stop` требует апрува Alex — истёк дважды): -```bash -docker stop prowlarr -sqlite3 "$DB" "DELETE FROM IndexerStatus WHERE ProviderId IN (1,5,6);" -docker start prowlarr -``` - -**3. Проверка:** -```bash -PK=$(cat /home/truenas_admin/pk.txt) -curl -s -H "X-Api-Key: $PK" http://localhost:9696/api/v1/indexerstatus # → пусто -for I in 1 5 6; do curl -s -o /dev/null -w "idx$I=%{http_code}\n" \ - "http://localhost:9696/$I/api?t=caps&apikey=$PK"; done # → 200 -``` - -**Таблицы в `prowlarr.db` (для справки):** `Indexers`, `IndexerStatus`, `IndexerProxies`, -`ApplicationIndexerMapping`, `IndexerDefinitionVersions`. - -> ⚠️ **Урок:** health-эндпоинты arr-сервисов **не являются источником истины** о блокировках. -> На Кра́кене это записано отдельно: «`GET /api/v1/health` и `/api/v1/indexerstatus` НЕ показывают -> причины блокировки» — авторитет за `prowlarr.debug.txt` и таблицей `IndexerStatus`. -> На Тайге `indexerstatus` причины показывал, но **снятие через API не срабатывало** — только SQL. - -## Остаток после сессии 2026-09-28 (не блокирует Prowlarr/FlareSolverr) - -1. ✅ **СНЯТО через SQL 2026-09-29.** `docker stop prowlarr` → `DELETE FROM IndexerStatus;` → - `docker start prowlarr`. Результат: `rows=0`, `quick_check=ok`, 6 определений на месте, - `health` → `[]`, `indexerstatus` → `[]`, **все 6 `caps` → 200**. - 🔴 **НО поиск не починился:** через минуты CF-индексеры снова в карантине, поиск даёт - `total=79` (только NoNaMe 47 + RuTor 32). Причина — **отсутствие `bb_data`**, см. п. 6. - Скрипт: `/tmp/clear_indexerstatus.sh`. Бэкап: `~/prowlarr.db.bak-20260928-032611`. -2. ✅ **Пароль RuTracker — вопрос закрыт: пароль ВЕРНЫЙ.** Проверено `request.post` через FS: - `len=251 792`, форма логина не вернулась. Первый диагноз «пароль неверен» был ложным — - признак «форма вернулась» проверять по **`final_url` + длине HTML**, а не по подстроке - `login_username` (она есть и на залогиненной странице). Подтверждено и через сессию - `prowlarr`: логин `254 410`, поиск `254 745`, `Auth Failed` в HTML отсутствует. - `Auth Failed` в Prowlarr при живом логине = **следствие `IndexerStatus`**, а не пароля. -3. ✅ **Radarr/Sonarr:** `docker restart radarr sonarr lidarr` выполнен → `RemotePathMappingCheck` - ушла, health **пуст** у обоих. -4. ⚠️ **RuTor:** `no results in the configured categories` — не блокировка. На Кра́кене тот же - дефект, лечение известно: RuTor не фильтрует по категориям, ему нужна **`8000(Other)`**, - не `5000`. На Тайге не применено. -5. **Приёмка Alex в UI:** `https://prowlarr.mallexxx.duckdns.org` → 6 зелёных; - `https://lidarr.mallexxx.duckdns.org` → поиск артиста работает. Alex подтвердил: - **«все зеленое, логин починен»**. Открытый вопрос по swap закрыт Alex (не нужен — RAM 21 GB). -6. 🔴 **ГЛАВНЫЙ НЕЗАКРЫТЫЙ ПУНКТ (2026-09-29): логин RuTracker не выполняется.** - В cookies сессии нет **`bb_data`** (кука авторизации) — только `cf_clearance` + `bb_guid`. - Лог Prowlarr: `FlareSolverrException: "Empty cookies returned by FlareSolverr"` (`FlareSolverr.cs:68`). - Форма индексера принимает только `username`/`password` — поля для cookie нет, подставить - живую сессию из браузера **нельзя**. Нужен Alex: зайти на `rutracker.org` браузером - **с того же IP** (`vless-proxy`), пройти капчу один раз, либо отключить капчу в профиле. - Полный разбор — [[personal/tech/flaresolverr-taiga]] §«ИТОГОВЫЙ КОРЕНЬ» и §«СВЕРКА С КРА́КЕНОМ». -7. 🔴 **«Как на Кра́кене» — НЕ рецепт (2026-09-29).** Проверено на живом Кра́кене: - капча-солвера там **нет** (только FlareSolverr, `requestTimeout: 60`), а карантин - **идентичен Тайге** — RuTracker/Kinozal/Kinozal(M) `EscalationLevel=9`, `DisabledTill=2026-09-27`. - **Обе площадки красные по одной и той же причине.** Не строить план на посылке - «на Кра́кене работает». Детали — [[personal/tech/flaresolverr-taiga]] §«СВЕРКА С КРА́КЕНОМ», - [[family/how-to/arr-stack-kraken]]. - -## 🔴 СЕССИЯ 2026-09-29 (вечер): разбор идеи Alex + свой образ `flaresolverr-vnc` - -**Задача Alex:** «ароматизировать процесс насколько возможно — уведомление в ТГ от hermes-taiga, -соединение моего браузера через 3x-ui через тот же туннель, выдача и установка куки обратно». - -**Результат — три из четырёх идей отвергнуты фактами:** - -| Идея | Вердикт | Причина | -|---|---|---| -| Свой браузер через 3x-ui по тому же туннелю | ❌ | `vless-proxy` — **клиент** xray, не сервер. `cf_clearance` привязан к **IP + UA + TLS-fingerprint** | -| Впихнуть куки обратно в Prowlarr | ❌ | Индексер RuTracker принимает только `username`/`password` — поля для cookie нет | -| Капча-солвер FS (`CAPTCHA_SOLVER`) | ❌ | **Официально non-functional** (DeepWiki FS; issue #1452 закрыт без решения) | -| Ручной вход **в Chrome внутри FS** + persistent профиль | ✅ | Единственный рабочий путь | - -**Сделано (шаг 1 из 3) ✅:** -- Собран образ **`flaresolverr-vnc:latest`** — база FS + `Xvfb` + `fluxbox` + `x11vnc` + `novnc` - + `supervisor`, 5 процессов. Файлы: `/mnt/RED_2TB/docker/arr/fs-vnc/{Dockerfile,supervisord.conf,entrypoint-vnc.sh}`. -- Compose: образ подменён, добавлены порт **`6080:6080`** (noVNC) и volume - `/mnt/RED_2TB/docker/arr/flaresolverr-config:/config` (persistent профиль Chromium). -- Профиль вынесен через `XDG_CONFIG_HOME=/config/chromium-profile`, FS запущен с `HEADLESS=false`. -- Проверено: `docker compose config -q` OK, сборка ~215 с, контейнер `Up`, - API → `{"status":"ok","version":"3.5.2"}`, `http://localhost:6080/vnc.html` → **200**. -- Бэкап: `/mnt/RED_2TB/docker/arr/docker-compose.yml.bak-20260928-profvol` (2723 B). - -## 🔴 ОТКАТ: эксперимент `flaresolverr-vnc` снесён (2026-09-29) - -Раздел ниже — **история неудачного эксперимента**, оставлен чтобы не повторять. -Итог: **гипотеза «капчу решает человек» была ложной** → всё построенное снесено. - -**Что было построено и что с ним стало:** - -| Артефакт | Статус | -|---|---| -| Образ `flaresolverr-vnc:latest` (Xvfb+fluxbox+x11vnc+noVNC) | ❌ снесён, FS вернулся на `ghcr.io/flaresolverr/flaresolverr:latest` | -| Порт `6080:6080` в compose | ❌ убран | -| Volume `/mnt/RED_2TB/docker/arr/flaresolverr-config:/config` | ❌ убран | -| Каталог сборки `/mnt/RED_2TB/docker/arr/fs-vnc/` | ❌ удалён | -| Роут `vnc.mallexxx.duckdns.org` в Caddyfile | ❌ убран, config валиден, reload сделан | -| `docker network connect media_net caddy` | ❌ откачен (`network disconnect`), Caddy снова в `caddy_default` + `transmission_default` | - -**Почему это было лишним:** Prowlarr логинится на RuTracker **сам**, без VNC и без человека. -Капча в ответе трекера была **реакцией на неверный пароль** (тесты шли аккаунтом `keropjan_88` -вместо хранящегося в Prowlarr `mallexxx`), а не требованием трекера к живому человеку. - -⚠️ **Правильный порядок при «Auth Failed» — начинать с данных, а не со сборки инфраструктуры:** -```bash -DB=/mnt/RED_2TB/docker/arr/prowlarr/prowlarr.db -sqlite3 "file:$DB?mode=ro" "SELECT Settings FROM Indexers WHERE Id=1;" -# сверить username/password с тем, чем тестируешь — ЭТО ПЕРВЫЙ ШАГ -``` - -⚠️ **Уточнение методики:** Alex работает по схеме **коммит → правка → заливка → проверка Alex**. -Но это не значит, что под каждую гипотезу нужно строить инфраструктуру: сначала проверять -исходные данные (пара логин/пароль в БД), и только потом — строить. diff --git a/personal/plans/lidarr-taiga-and-indexer-unblock.md b/personal/plans/lidarr-taiga-and-indexer-unblock.md deleted file mode 100755 index 8cc1b84a..00000000 --- a/personal/plans/lidarr-taiga-and-indexer-unblock.md +++ /dev/null @@ -1,336 +0,0 @@ ---- -title: Lidarr на Тайге + разблокировка индексеров — план -created: '2026-09-26' -updated: '2026-09-26' -type: plan -namespace: personal -status: awaiting-approval -tags: - - lidarr - - taiga - - truenas - - arr - - music - - dns - - prowlarr - - blocked -related: - - '[[family/projects/media-toolbox-taiga]]' - - '[[family/how-to/jellyfin-config]]' - - '[[personal/tech/music-tags-repair-truenas]]' - - '[[personal/tech/truenas-nfs4-acl-and-arrmultiuser]]' ---- -# Lidarr на Тайге + разблокировка индексеров — план - -> **Статус Фазы 0: ✅ ЗАКРЫТА 2026-09-28.** DNS-блок обойдён через `vless-proxy` (SOCKS5), -> Cloudflare — через **FlareSolverr** (развёрнут 2026-09-28). Остаток: тег FS на NoNaMe, -> проверка Kinozal. Полный разбор — [[personal/plans/flaresolverr-taiga-deploy]]. -> Lidarr уже развёрнут (см. [[family/plans/lidarr-taiga-deploy]] §2026-09-28). -> Задача поставлена 2026-09-26: «поставить lidarr в дополнение к sonarr/prowlarr, настроить на музыку, -> синк с jellyfin, проверка что весь стек живой». -> Разведка выполнена, найдены 2 блокера, план ниже. - -## 🔴 ГЛАВНАЯ НАХОДКА СЕССИИ: DNS-блок у провайдера Тайги - -**Стек НЕ сломан. Индексеры мертвы из-за внешней блокировки на стороне Тайги.** - -Диагностика (2026-09-26, все команды с живой машины): - -```bash -# Из контейнера prowlarr: -docker exec prowlarr sh -c "wget -qO- --timeout=12 -S 'https://rutracker.org/'" -# → wget: bad address 'rutracker.org' -docker exec prowlarr sh -c "wget -qO- --timeout=12 -S 'https://byrutgame.org/'" -# → HTTP/1.1 200 OK ← этот резолвится -``` - -```bash -# На хосте TrueNAS, ДВА разных резолвера: -nslookup rutracker.org 192.168.2.2 # роутер → NXDOMAIN -nslookup rutracker.org 8.8.8.8 # Google → NXDOMAIN -nslookup google.com 192.168.2.2 # → OK (142.250.181.238) -``` - -**Вывод:** NXDOMAIN приходит **и с роутера, и с 8.8.8.8** → это **не Pi-hole и не роутер**. -Блок на стороне аплинка Тайги (провайдер Ростелеком / региональный DNS-фильтр). - -**Что НЕ резолвится (все 4 трекера):** `rutracker.org`, `rutor.info`, `kinozal.tv`, `nnmclub.to` -**Что резолвится:** `byrutgame.org` (185.200.198.230), `google.com` - -> ⚠️ Это **другой** класс проблемы, чем задокументированные ранее «Cloudflare 403 на -> `indexers.prowlarr.com`» и «RuTracker Cloudflare Turnstile». Здесь **DNS не отдаёт IP вообще** — -> до Cloudflare/TLS дело не доходит. - -### Следствие в Prowlarr - -``` -GET /api/v1/health → - "Indexers unavailable due to failures for more than 6 hours: - RuTracker, RuTor, NoNaMe Club, Kinozal, Kinozal (M)" - -GET /api/v1/indexerstatus → 5 записей, у всех: - disabledTill = "2026-09-27T08:07:26Z" (сутки карантина) - initialFailure = "2026-05-20T05:4x:xx" ← ЛОМАЕТСЯ С ДНЯ ДЕПЛОЯ, не «сейчас» -``` - -> 🔑 **`initialFailure` = 2026-05-20** — дата первоначального деплоя стека. -> Значит индексеры через Prowlarr на Тайге **не работали ни одного дня**. Это не регресс. - -В Radarr/Sonarr это даёт каскад: -``` -IndexerLongTermStatusCheck error All indexers are unavailable due to failures for more than 6 hours -IndexerRssCheck warning All rss-capable indexers are temporarily unavailable -IndexerSearchCheck warning All search-capable indexers are temporarily unavailable -``` - -## 🔴 БЛОКЕР 2: vless-proxy НЕ виден из media_net - -Задокументировано в `media-toolbox-taiga.md`: «vless-proxy доступен в `media_net` как -`vless-proxy:1080` (SOCKS5)». **Факт 2026-09-26 — это НЕ ТАК:** - -```bash -docker inspect vless-proxy --format '{{range $n,$c := .NetworkSettings.Networks}}{{$n}} {{$c.IPAddress}}{{end}}' -# hermes_taiga_net 172.16.15.2 ← ТОЛЬКО одна сеть -docker exec prowlarr getent hosts vless-proxy -# NO DNS -``` - -`docker network inspect media_net` → участники: `prowlarr radarr transmission sonarr` -(**vless-proxy отсутствует**). - -**Вывод:** прокси-маршрут для заблокированных индексеров, описанный в доке, **никогда не работал** — -не был реализован. При этом `docker exec prowlarr getent hosts xray-admin` → `172.16.1.9` (работает, -обе в `caddy_default`). - -## Фактическое состояние стека (2026-09-26) - -Всё проверено на живой машине. **Стек работает**, кроме индексеров. - -| Сервис | Статус | UID | Порты | Сети | -|---|---|---|---|---| -| prowlarr | Up 3d | 950 | 9696 | media_net + caddy_default | -| radarr | Up 3d | 950 | 7878 | media_net + caddy_default | -| sonarr | Up 3d | 950 | 8989 | media_net + caddy_default | -| jellyfin | Up 7d | 950 | 8096 | caddy_default | -| transmission | Up 7d | 950 | 9091, 51413 | media_net + transmission_default | -| caddy | Up 3d | — | — | caddy_default | - -Проект compose: `arr` (все 4 в `media_net` + `caddy_default`). `media_net` существует. - -### Compose (актуальный, `/mnt/RED_2TB/docker/arr/docker-compose.yml`) - -Все сервисы: `PUID=950 PGID=950 TZ=Asia/Novosibirsk`, `dns: [8.8.8.8, 8.8.4.4]`. -radarr/sonarr монтируют `/mnt/RED_2TB/storage:/storage`; jellyfin — `:ro`; prowlarr — только `/config`. -**У prowlarr НЕТ монтирования `/storage`.** Порты проброшены (`ports:`) — можно обращаться к API с хоста. - -### Индексеры Prowlarr (все 6, `enable=true`) - -| id | Name | definitionName | URL | -|---|---|---|---| -| 1 | RuTracker | `RuTracker.org` | rutracker.org | -| 2 | RuTor | `rutor` | rutor.info | -| 3 | Byrutor | `byrutor` | byrutgame.org ← **единственный живой DNS** | -| 4 | NoNaMe Club | `noname-club` | nnmclub.to | -| 5 | Kinozal | `kinozal` | kinozal.tv | -| 6 | Kinozal (M) | `kinozal-magnet` | kinozal.tv | - -### Applications Prowlarr - -| id | Name | syncLevel | baseUrl | -|---|---|---|---| -| 1 | Radarr | `fullSync` | `http://radarr:7878` | -| 2 | Sonarr | `fullSync` | `http://sonarr:8989` | - -### Radarr — практические факты - -- Root folder: `/storage/radarr` (id 1, accessible) -- Download client: `Transmission` (id 1, enable=true) -- Индексеров **5** (Byrutor не синкается — нет RSS): - `Kinozal (M)`, `Kinozal`, `NoNaMe Club`, `RuTor`, `RuTracker` -- ⚠️ **БАГ Prowlarr-синка:** baseUrl индексеров = `http://prowlarr:9696/6/` — - **БЕЗ `/prowlarr` urlBase**. Прямая проверка: - `docker exec radarr wget -qO- "http://prowlarr:9696/6/api?t=caps"` → **401 Unauthorized** - Ожидалось `http://prowlarr:9696/prowlarr/6/`. См. skill `arr-media-stack-setup` - §«Корень проблемы короткий URL в синхронизации индексеров». - ⚠️ Но у Тайги `` у prowlarr — **пустой** (`config.xml`), т.е. на этом хосте - форма `9696/6/` может быть и корректной. **Разобрать перед фиксом** — не менять вслепую. - -### Ключи API (полные, сняты с живой машины) - -| Сервис | Полный ключ | -|---|---| -| Prowlarr | `35c8b3f497114076a6150ea0d9504845` | -| Radarr | `51e201f2d61b4fe2a0c322d5e99349fe` | -| Sonarr | `b1eb9cdd5c804e6c956dc9c8bd305dc8` | -| Jellyfin | `eaglesetup2026taiga` | - -### Питфолл: на Тайге нет curl И НЕТ python3 на хосте - -Ранее задокументировано «нет curl и python3 в PATH хоста». **Уточнение 2026-09-26:** -`python3` **есть** — использовался для парсинга JSON (`python3 -c 'import json...'`). -Нет **`curl`** и **нет `sqlite3`** на хосте (sqlite3 — подтверждено в `jellyfin-config`). - -**Рабочий паттерн для API-вызовов на Тайге:** `wget` **внутри контейнера** + `python3` на хосте для разбора: - -```bash -# JSON забираем wget-ом ИЗ КОНТЕЙНЕРА (busybox wget: только -qO- / --header / --timeout) -ssh truenas_admin@mallexxx.duckdns.org \ - "docker exec prowlarr sh -c 'wget -qO- --header=\"X-Api-Key: \" http://localhost:9696/api/v1/health'" -# ↓ или в файл, затем разбор хостовым python3 -ssh truenas_admin@... "docker exec prowlarr sh -c 'wget -qO- ... > /tmp/x.json'" -python3 -c 'import json; d=json.load(open("/tmp/x.json")); ...' -``` - -> ⚠️ **busybox wget НЕ поддерживает `-e use_proxy=yes`** (это GNU-опция). Для прокси-тестов внутри -> контейнеров нужен другой инструмент (в linuxserver-образах есть `curl`? — проверить) или -> тестировать с хоста. Проверено: `wget: unrecognized option: e`. - -### Питфолл: shell-экранирование при выкачивании JSON через ssh - -Кавычки в `--header="X-Api-Key: $K"` ломаются на нескольких уровнях ssh/sh. Рабочий приём — -**положить результат в файл внутри контейнера или на хосте**, потом разбирать отдельно. -`jq` с дефисами в ключах (`download-dir`) требует `.["download-dir"]`, не `.download-dir`. - -### Питфолл: `/etc/resolv.conf` контейнеров - -``` -nameserver 127.0.0.11 ← Docker embedded DNS -search local -options ndots:0 -``` -Поэтому в контейнерах **нет `getent`** — использовать `nslookup`/`wget` для проверки DNS. -Хостовый `resolv.conf`: `domain local` + `nameserver 192.168.2.2`. - -## RemotePathMapping — существующая ошибка (состояние 2026-09-26) - -Transmission download-dir (факт): -```json -{"download-dir": "/mnt/storage/Downloads", - "incomplete-dir": "/mnt/storage/Downloads/transmission/incomplete", - "script-torrent-done-enabled": false, - "script-torrent-done-filename": "", - "rpc-whitelist": "172.16.*.*", - "rpc-url": "/transmission/"} -``` - -Radarr/Sonarr health: -``` -RemotePathMappingCheck error - "download client Transmission places downloads in /storage/Downloads/radarr - but this directory does not appear to exist inside the container" -``` - -> 🔑 **Фактическая причина (важно, опровергает старую доку):** Transmission **не раскладывает** -> по `Downloads/radarr` — download-dir плоский `/mnt/storage/Downloads`. Radarr ОЖИДАЕТ -> подкаталог категории (`/storage/Downloads/radarr`), которого нет. -> -> **Задокументированный в `media-toolbox-taiga.md` маппинг `host=transmission`, -> `remotePath=/mnt/storage/Downloads/`, `localPath=/storage/Downloads/` — НЕ ПРИМЕНЁН** -> (в API Radarr/Sonarr записей remotepathmapping нет, health жалуется). -> -> **Второй слой:** Transmission монтирует `/mnt/storage`, radarr — `/storage`. Один и тот же -> хост-путь под двумя именами. Prowlarr/radarr-контейнеры **не видят `/mnt/storage`**. - -## ПЛАН - -### Фаза 0 — внешняя блокировка (БЛОКЕР для всего остального) - -> ✅ **ЗАКРЫТА 2026-09-28 — НЕ ВЫПОЛНЯТЬ ПОВТОРНО.** `vless-proxy` подключён к `media_net` -> (persistent, `172.16.17.6`), прокси `vless-socks5` (id=1) создан, тег `proxy` (id=1) навешен -> на все 6 индексеров. Проверено вживую: `rutracker.org` → 301, `nnmclub.to` → 200, -> `kinozal.me` → 200; поиск RuTor 100 + Byrutor 6. **Остаточная проблема — Cloudflare** -> (RuTracker/Kinozal/Kinozal M, карантин id 1/5/6), решается FlareSolverr. -> Текущий активный план: [[personal/plans/flaresolverr-taiga-deploy]]. - -1. Подключить `vless-proxy` к `media_net`: - `docker network connect media_net vless-proxy` (runtime) + добавить сеть в compose - `/mnt/RED_2TB/docker/vless-proxy/docker-compose.yml` (иначе потеряется при пересоздании). -2. Проверить из prowlarr: `getent`/`nslookup vless-proxy`, затем доступ до `rutracker.org` - **через прокси** (SOCKS5 `vless-proxy:1080`). -3. Если через прокси резолвится — создать Proxy в Prowlarr (Settings → Indexers → Add Proxy, - SOCKS5, host `vless-proxy`, порт `1080`, тег `proxy`) и повесить тег `proxy` на - RuTracker / RuTor / Kinozal / NoNaMe. -4. Сбросить `indexerstatus`: `POST /api/v1/indexer/testall` (снимает `disabledTill`). -5. **ПРИЁМКА ALEX:** `https://prowlarr.mallexxx.duckdns.org` → Indexers → Test All → зелёные. - -> ⚠️ Byrutor (id 3) резолвится — его прокси не нужен, но в Radarr он не синкается (нет RSS). -> Он полезен только в Sonarr/Radarr с `enableRss: false` — применимо и к Lidarr. - -### Фаза 1 — Lidarr контейнер - -1. **Бэкап** `/mnt/RED_2TB/docker/arr/docker-compose.yml` → `~truenas_admin/` (не в - `/mnt/RED_2TB/backup` — он root-owned, truenas_admin туда не пишет). -2. Добавить сервис `lidarr` по образцу `radarr`: - - image `lscr.io/linuxserver/lidarr:latest` - - `PUID=950 PGID=950 TZ=Asia/Novosibirsk`, `dns: [8.8.8.8, 8.8.4.4]` - - port `8686:8686` - - volumes: `/mnt/RED_2TB/docker/arr/lidarr:/config`, `/mnt/RED_2TB/storage:/storage` - - networks: `media_net` + `caddy_default` -3. Поднять **из правильной папки**: `cd /mnt/RED_2TB/docker/arr && docker compose up -d lidarr` - (не через временную копию compose — name-conflict). -4. Caddy: добавить блок `lidarr.mallexxx.duckdns.org { reverse_proxy lidarr:8686 }`. - Caddyfile root-owned → **только через alpine-контейнер** (`docker run --rm -i -v /:/host:rw alpine ...`, - см. skill `truenas-caddy-service-deploy`). Отправлять **весь файл**, не патч. -5. **ПРИЁМКА ALEX:** `https://lidarr.mallexxx.duckdns.org` открывается. - -### Фаза 2 — Lidarr на музыку - -1. Root folder — **РЕШЕНИЕ АЛЕКСА НУЖНО** (см. вопросы ниже). -2. Download client — Transmission: host `transmission`, port `9091`, urlBase `/transmission/`, - category `lidarr`. -3. Индексеры: добавить Application `Lidarr` в Prowlarr (`syncLevel: fullSync`, - `baseUrl: http://lidarr:8686`) — либо вставить Torznab вручную, если синк не пройдёт. - > ⚠️ Lidarr требует **audio-категории (3000-я серия)** в профиле индексера. Посмотреть, - > отдают ли их наши трекеры — RuTracker/Kinozal обычно да; RuTor — нет (см. skill: RuTor - > не даёт movie-категорий; для audio проверить отдельно). -4. `preferMagnetUrl: true` — применить (нет дневного лимита на .torrent). -5. Прокси-тег для заблокированных (из Фазы 0). -6. **ПРИЁМКА ALEX:** тестовый поиск артиста → релиз найден → торрент ушёл в Transmission. - -### Фаза 3 — синк с Jellyfin - -> 🔴 **ЗАБЛОКИРОВАНО.** Создавать `collectionType=music` на текущих тегах нельзя: -> 7906 файлов → `mojibake` 2759, `lost` 662 (данные уничтожены), `empty` 1026, `partial` 2920. -> Jellyfin раскладывает музыку **по тегам**, не по папкам → получится свалка `Unknown Artist`. -> Полный контекст: [[personal/tech/music-tags-repair-truenas]] — этапы 1–2 готовы (CSV v2), -> ждёт апрув Alex, правки файлов не начаты. - -1. Решить порядок (см. вопрос 2 ниже). -2. `/storage/Music` **уже смонтирован** в jellyfin (ro) — доп. монтирование НЕ нужно. -3. Создание: `POST /Library/VirtualFolders?name=Music&collectionType=music&paths=/storage/Music` - (**name/paths в query string**, не в body — Jellyfin 10.11). -4. Возможный митигирующий вариант: `EnableFolderView` — навигация по папкам, теги вторичны. -5. **ПРИЁМКА ALEX:** вкладка Music → треки видны. - -### Фаза 4 — приёмка всего стека - -1. `docker ps` — все 6 (+ lidarr) Up, uid 950. -2. Radarr/Sonarr/Lidarr health — без ошибок Indexer* и RemotePathMapping. -3. Разобрать RemotePathMapping (см. раздел выше) — нужен подкаталог категории в Transmission - **или** корректный маппинг. -4. **ПРИЁМКА ALEX:** панели открываются, плейбек идёт, поиск работает. - -## ❓ ВОПРОСЫ, ЖДУЩИЕ ОТВЕТА АЛЕКСА - -1. **Куда Lidarr складывает музыку?** - - (A) отдельный staging `/storage/Music-lidarr` + router-симлинки в `Music/` - — безопасно, не трогает 7890 существующих файлов. **Рекомендую.** - - (B) прямо в `/storage/Music` с отключённым переименованием — риск конфликтов с существующей - категорийной структурой (`!Rock&Folk` и т.д.). -2. **Музыка в Jellyfin — до или после ремонта тегов?** - - Док от 2026-09-26: «сначала теги». Lidarr принесёт часть файлов с чистыми тегами, - но 7890 старых останутся битыми. - -## Открытые техвопросы (разобрать по ходу) - -- Баг «короткого URL» Prowlarr→Radarr: `http://prowlarr:9696/6/` vs `/prowlarr/6/`. - Нужно решить, корректен ли он при **пустом** `` у prowlarr. 401 на `?t=caps` — сигнал, - что что-то не так, но не однозначно. -- Битый `image.imageHeight`/пост-обработка не в scope. -- RuTor не даёт movie-категорий; для audio проверить отдельно. -- Есть ли `curl` внутри linuxserver-образов (для прокси-тестов) — проверить. - -## История - -- **2026-09-26** — разведка, найдены 2 блокера (DNS-фильтр провайдера + vless-proxy не в media_net), - план составлен, ожидает 2 ответов Alex. Ничего не изменено. diff --git a/personal/tech/flaresolverr-taiga.md b/personal/tech/flaresolverr-taiga.md old mode 100755 new mode 100644 index 0c2dc431..792b463d --- a/personal/tech/flaresolverr-taiga.md +++ b/personal/tech/flaresolverr-taiga.md @@ -1,580 +1,137 @@ -# FlareSolverr на Тайге + обход блокировок индексеров - -> ✅ **АКТУАЛЬНОЕ СОСТОЯНИЕ 2026-09-29:** arr-стек проверен после полного force-recreate. -> FlareSolverr автоматически создаёт авторизованную сессию `prowlarr` через -> `socks5://vless-proxy:1080`; Prowlarr → RuTracker test возвращает HTTP 200. -> Lidarr → SkyHook возвращает 10 результатов через `vless-proxy:1081`. -> Lidarr → Transmission test проходит; локальный Transmission исключён из внешнего proxy. -> Все контейнеры arr и Jellyfin после рестарта `running`, `docker compose config -q` проходит. -> В Lidarr остаётся только исторический health-warning по Kinozal/RuTracker; текущий -> Prowlarr `indexerstatus` пуст. Не использовать старые блоки ниже как инструкцию. - -> ⚠️ **СОСТОЯНИЕ 2026-09-28 (конец сессии): FS жив, но RuTracker/Kinozal снова в таймауте.** -> Проверено: `docker exec flaresolverr curl -s http://localhost:8191/health` → `{"status": "ok"}`, -> версия **3.5.2**, `sessions.list` → `["prowlarr"]` (сессия существует). -> Prowlarr: `health: []`, `indexerstatus` → `[]` (карантина НЕТ), теги `[1,2]` на id 1/5/6 расставлены -> **верно**. НО `POST /api/v1/indexer/test` полным объектом для **id 1 (RuTracker), 5 (Kinozal), -> 6 (Kinozal M)** → **пустой ответ даже при таймауте 90 с**; работают **NoNaMe(4), RuTor(2), Byrutor(3)**. -> ⇒ Сессия существует, но, **вероятно, создана без proxy** (контейнеры пересоздавались — все `Up 3 minutes`). -> 🔴 **ПЕРВЫЙ шаг диагностики (не сессии, не карантин):** -> ```bash -> ssh truenas_admin@mallexxx.duckdns.org "docker exec flaresolverr ps aux | grep chromium | head -3" -> ``` -> Ищем `--proxy-server=socks5://vless-proxy:1080`. **Нет флага** → `sessions.destroy` + -> `sessions.create` с proxy (см. §«ПРОКСИ-СЛОЙ ИСПРАВЛЕН» ниже). -> Полный аудит стека — [[family/plans/lidarr-taiga-deploy]] §«АУДИТ ВСЕГО СТЕКА». - -> 🔴 **НОВОЕ 2026-09-28 (вечер): ТОТ ЖЕ КЛАСС ДЕФЕКТА У LIDARR — свой `ProxyCheck` не проходит.** -> ⚠️ **УСТАРЕЛО, оставлено как история:** SkyHook (`api.lidarr.audio`) отдавал **403 Cloudflare**; -> в теле ответа — `Your IP: 90.189.160.148` (домашний). Встроенный прокси Lidarr -> `proxyEnabled=true, proxyType=http, vless-proxy:1081` **записан, но не применялся** — -> `docker logs lidarr | grep -i proxy` давал **`[Error] ProxyCheck: Proxy Health Check failed`**. -> ✅ **К концу сессии 2026-09-28 SkyHook ЗАРАБОТАЛ** (Alex починил): `lookup Astrix` → **10 результатов**. -> ⇒ **Правило остаётся валидным для ЛЮБОГО сервиса на Тайге, который ходит в интернет сам** -> (Lidarr → SkyHook, FS → Chrome): по умолчанию он выходит с **домашнего IP**. Проверять не -> «настроен ли прокси», а **«какой внешний IP у самого сервиса»**. -> 🔴 **`GET /api/v1/health` у Lidarr отдаёт `[]`, даже когда `ProxyCheck` падает** — health-кэш врёт, -> ориентироваться на логи. 🔴 **Внешний IP дома = `90.189.160.148` И у хоста Тайги тоже** — вся сеть -> NAS идёт через домашний аплинк; VPS-выход даёт **только** `vless-proxy` -> (`104.28.211.192` через 1080 и 1081 — обе рабочие). -> ⇒ Практическое правило: **любой сервис на Тайге, который ходит в интернет сам** (Lidarr → SkyHook, -> FS → Chrome), по умолчанию выходит с домашнего IP. Проверять не «настроен ли прокси», а -> **«какой внешний IP у самого сервиса»**. -> `docker restart lidarr` **выполнен — не помог**. Подробности — [[family/plans/lidarr-artist-watchlist]] §БЛОКЕР. - -> ✅ **ПРОКСИ-СЛОЙ ИСПРАВЛЕН 2026-09-29:** причина была не в `vless-proxy`. -> FlareSolverr 3.5.2 **игнорирует `proxy` у `request.get/request.post`, если указан `session`**. -> `PROXY_URL` подставляется в тело запроса, но при уже заданной сессии драйвер берётся из старой -> сессии. Prowlarr создавал `prowlarr` без proxy, поэтому Chrome ходил напрямую с `90.189.160.148`. -> `vless-proxy` исправен: SOCKS даёт внешний IP `104.28.209.115`/`187.15.56.1`. -> -> **Рабочий фикс на TrueNAS (выполнен):** удалить сессию `prowlarr` и создать её заново с proxy: -> ```bash -> curl -sS -X POST http://localhost:8191/v1 -H 'Content-Type: application/json' \ -> -d '{"cmd":"sessions.destroy","session":"prowlarr"}' -> curl -sS -X POST http://localhost:8191/v1 -H 'Content-Type: application/json' \ -> -d '{"cmd":"sessions.create","session":"prowlarr","proxy":{"url":"socks5://vless-proxy:1080"}}' -> ``` -> Проверка: `docker exec flaresolverr ps aux | grep chromium` должен содержать -> `--proxy-server=socks5://vless-proxy:1080`; запрос через session `prowlarr` к `api.ipify.org` -> должен вернуть IP, отличный от `90.189.160.148`. -> -> ⚠️ После пересоздания/рестарта контейнера FlareSolverr эту сессию нужно создать снова. -> `PROXY_URL` оставляем в compose, но одного его недостаточно для постоянной сессии Prowlarr. -> **Устойчивый прокси-фикс применён:** `/mnt/RED_2TB/docker/arr/flaresolverr-entrypoint.sh` ждёт `/health`, -> пересоздаёт `prowlarr` с proxy и затем запускает основной процесс. В compose добавлены -> `entrypoint` и read-only bind mount этого скрипта. После `docker compose up -d --force-recreate -> flaresolverr` проверка должна показать `sessions: ["prowlarr"]` и `--proxy-server=...`. -> -> ⚠️ **Остаточный блокер end-to-end:** прямой запрос через FS к -> `https://rutracker.org/forum/tracker.php?nm=radiohead` проходит (`HTTP 200`, ~274 KB, -> `bb_session`), но поиск через Prowlarr всё ещё получает timeout примерно через 101 с. -> Prowlarr не добавляет новую запись `IndexerStatus` после очистки только до следующей попытки. -> Текущая конфигурация для продолжения: RuTracker тег `[2]` (только FlareSolverr), -> `rutracker.org` в `extra_hosts`, `BROWSER_TIMEOUT=180000`. - -> 🔴🔴 **ОБНОВЛЕНИЕ 2026-09-29 (поздняя сессия): ДЕФЕКТ ЛОКАЛИЗОВАН — Chrome FS стартует БЕЗ `--proxy-server=`.** -> Прокси-контейнер `vless-proxy` **жив и работает** (логи: `tunneling request ... via vpn.mallexxx.duckdns.org:443`). -> `PROXY_URL=socks5://vless-proxy:1080` в env FS есть, но **к Chrome не применяется** — в командной строке -> Chrome флага `--proxy-server` нет вообще, и контрольный Chrome-запрос **не оставил следа в логе `vless-proxy`**. -> ⇒ Chrome ходит напрямую, выходит с домашнего `90.189.160.148`. Следствие: RuTracker `ERR_TIMED_OUT` → карантин. -> Диагностику начинать НЕ с карантина и НЕ с сессий, а с: `docker exec flaresolverr ps aux | grep chromium`. -> Подробности — раздел «КОРЕНЬ НАЙДЕН» в конце. VPS **нет**, версия про DuckDNS **отвергнута Alex**. -> -> 🟡 **СОСТОЯНИЕ 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`. -> Тайга: `192.168.2.197`, внешний IP дома `90.189.160.148`, DNS роутера `192.168.2.2`. -> Связка: [[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 - -rutracker.org - -``` - -Диагностические маркеры в такой странице: `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 пересоздаёт сессию чистой при следующем запросе. - +--- +title: FlareSolverr на TrueNAS Taiga +created: '2026-09-20' +updated: '2026-09-29' +type: tech +namespace: personal +tags: [flaresolverr, prowlarr, rutracker, taiga, truenas] +related: + - "[[family/how-to/arr-stack-taiga]]" + - "[[personal/tech/prowlarr-flaresolverr-cloudflare]]" --- -## 🔴 ПРИЧИНА ВСЕХ ПРОБЛЕМ: путаница аккаунтов (не капча, не прокси, не CF) +# FlareSolverr на TrueNAS Taiga -Долгая диагностика упиралась в «капчу RuTracker» — **причины такой не было**. +Рабочая документация FlareSolverr для arr-стека Taiga. Общая эксплуатация стека находится в [[family/how-to/arr-stack-taiga]]. Kraken здесь не описывается. -``` -Prowlarr: username = mallexxx password = m@n*w$uperP@$$w0rD -Мой тест: username = keropjan_88 password = I70aj7Igpr ← ЛЕВЫЙ аккаунт +## Рабочая схема + +```text +Prowlarr + └─ tags [proxy, flaresolverr] + └─ FlareSolverr :8191 + └─ Chrome session prowlarr + └─ socks5://vless-proxy:1080 + └─ RuTracker ``` -RuTracker на неверный пароль отвечает **формой логина + капчей**. Отсюда ложный вывод «капча блокирует». -С правильными данными Prowlarr логинится **без капчи**. +Файлы на TrueNAS: -> 🔴 **Прежде чем диагностировать капчу/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"} +```text +/mnt/RED_2TB/docker/arr/docker-compose.yml +/mnt/RED_2TB/docker/arr/flaresolverr-entrypoint.sh +/mnt/RED_2TB/docker/arr/prowlarr/ ``` -**Фикс:** удалить сессию — 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 проблемы не создаёт: сессия создастся заново с прокси. +## Почему нужен entrypoint -## 🔑 Имя переменной — `PROXY_URL` (не `HTTP_PROXY`) +Одного `PROXY_URL` недостаточно. FlareSolverr применяет proxy при создании browser session. Если session создана до настройки proxy, последующие `request.get` с той же session продолжают работать без 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 -``` +Entrypoint при каждом старте: -**Почему FS обязан ходить через прокси:** на Тайге блоков **два** — DNS провайдера + Cloudflare. -Без прокси FS сам получает NXDOMAIN и не помогает. На Кра́кене DNS-блока нет, поэтому там -`PROXY_URL` не нужен. +1. ждёт FlareSolverr `/health`; +2. удаляет старую session `prowlarr`, если она есть; +3. создаёт `prowlarr` с `socks5://vless-proxy:1080`; +4. читает credentials RuTracker из `prowlarr.db` через SQLite URI `mode=ro&immutable=1`; +5. делает pre-login через FlareSolverr; +6. оставляет основной процесс FlareSolverr работать. -## 🔴 `IndexerStatus` снимается ТОЛЬКО через SQL — тест его ПРОДЛЕВАЕТ +SQLite монтируется read-only. Обычный `sqlite3.connect('/prowlarr.db')` на read-only mount может упасть с `unable to open database file`; нужен именно `immutable=1`. -`POST /indexer/test` карантин **не снимает, а эскалирует**: наблюдалось `DisabledTill` 15:44 → 21:45 -после одного теста. Пока запись есть, `caps` отдаёт **429**, и warning каскадом идёт во все arr. +## Compose-настройки -```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 "[^<]*" /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=&login_password=

&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) +environment: + - LOG_LEVEL=warning + - BROWSER_TIMEOUT=180000 + - PROXY_URL=socks5://vless-proxy:1080 + - TZ=Asia/Novosibirsk +shm_size: 1gb +restart: unless-stopped ``` -## 🔴 ЧЕКЛИСТ «не всё зелёное» (восстановление RuTracker) +Entrypoint и Prowlarr config directory подключаются read-only. Не хранить credentials или API keys в compose и Obsidian. -Когда RuTracker даёт 0, а FS жив — выполнить **в этом порядке**: +В Prowlarr для RuTracker: + +```text +proxy tag = [1] +flaresolverr tag = [2] +RuTracker tags = [1,2] +FlareSolverr requestTimeout = 180 seconds +``` + +Один tag `[2]` не решает DNS-блок Taiga. Один tag `[1]` не решает browser challenge. + +## Правильная проверка + +Проверка session: ```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 "[^<]*" /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 +curl -fsS -H 'Content-Type: application/json' \ + -d '{"cmd":"sessions.list"}' http://127.0.0.1:8191/v1 ``` -> ⚠️ **Переживёт ли reboot:** `IndexerStatus` и сломанная сессия **переживают** — без шагов 1–2 -> после перезагрузки RuTracker останется в 0. Сессия живёт в памяти FS и **выдерживает -> `docker restart flaresolverr`**. +Должны быть `status=ok` и `prowlarr`. -## 🔴 Чего НЕ делать (проверено, не работает) +Проверка login должна смотреть cookies, а не размер HTML: -| Идея | Почему нет | -|---|---| -| Капча-солвер (`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 логинится сам | +```text +solution.cookies содержит bb_session +``` -> 🔴 **Не строить план на посылке «на Кра́кене работает».** На 2026-09-29 у Кра́кена в БД -> тот же карантин `EscalationLevel=9` (RuTracker/Kinozal/Kinozal M, с 27 сен) и **нет** капча-солвера. -> «Как на Кра́кене» ≠ «починить». +Большая HTML-страница может быть страницей ошибки Chromium и не означает login. -## 📋 ЖУРНАЛ ОТКАТА (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 запретил лишние бэкапы.) - -### Порядок отката, который сработал +Функциональная приёмка — реальный search Prowlarr: ```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!) +curl -H "X-Api-Key: $PROWLARR_KEY" \ + 'http://127.0.0.1:9696/api/v1/search?query=radiohead&type=search&indexerIds=1' ``` -### ✅ Приёмка после отката (факты) +`POST /api/v1/indexer/test` не использовать как единственное доказательство: при передаче объекта из API password может быть `********`, что даёт ложный `Auth Failed`. -``` -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. -**Причина отравления не установлена** — открытый вопрос для следующей сессии. +1. `docker compose ps` — контейнеры живы. +2. `curl /health` — FlareSolverr отвечает. +3. `sessions.list` — session существует. +4. Проверить `bb_session` в `solution.cookies`. +5. Проверить логи `vless-proxy` на `rutracker.org:443`. +6. Выполнить одиночный реальный search, не `testall`. ---- +Параллельный `testall` перегружает один Chrome и создаёт ложные timeout. Challenge может занимать больше минуты, поэтому timeout 60 секунд недостаточен. -# 🔴🔴 КОРЕНЬ НАЙДЕН (2026-09-29, поздняя сессия): DNS-запись `vpn.mallexxx.duckdns.org` указывает НА ДОМ +## Перезапуск -**Гипотеза «отравленная сессия FS» — СЛЕДСТВИЕ, а не причина.** Настоящая причина в том, -что **VLESS-туннель не работает вообще**, потому что VPN-хост резолвится в домашний IP. - -## Доказательства (факты, не догадки) - -``` -vpn.mallexxx.duckdns.org @8.8.8.8 → 90.189.160.148 ❌ (домашний Ростелеком, Новосибирск) -vpn.mallexxx.duckdns.org @1.1.1.1 → 90.189.160.148 ❌ -vpn.mallexxx.duckdns.org @локальный → 192.168.0.10 ❌ (роутер дома, DNS 192.168.2.2) -``` - -`90.189.160.148` = **внешний IP домашней сети Тайги** (Тайга сама `192.168.2.197`), Rostelecom -AS12389. Проверка: `ip-api.com/line/90.189.160.148` → Russia / Novosibirsk / Rostelecom. - -**Куда уходит трафик при «рабочем» прокси:** -``` -Chrome FS (PROXY_URL) → vless-proxy → dial vpn.mallexxx.duckdns.org:443 → 90.189.160.148 (ДОМ!) - → выход через тот же Ростелеком → api.ipify.org отдаёт 90.189.160.148 -``` -То есть прокси-цепочка формально проходит, но **выходной узел = домашний IP** ⇒ обхода -блокировки НЕТ. Прокси не падает с ошибкой — он **молча не проксирует**. - -``` -docker logs vless-proxy: - accepted tcp:rutracker.org:443 - tunneling request to tcp:rutracker.org:443 via vpn.mallexxx.duckdns.org:443 - ... failed to transfer response payload > websocket: close 1000 (normal) ← рвётся -``` - -## Как это выглядело в FS (ложный след) - -| Тест | Результат | Правда | -|---|---|---| -| `curl --socks5-hostname vless-proxy:1080 rutracker` из FS | `http=200, 1.16s` | шёл **напрямую**, DNS на хосте, не через туннель | -| `curl --socks5-hostname ... api.ipify.org` из FS | **пусто** | VLESS-цепочка умирает на удалённом конце | -| Chrome FS `api.ipify.org` | `90.189.160.148` | **домашний IP** → туннеля нет | -| POST login RuTracker через FS | `len=254410, cookies=[]` | `ERR_TIMED_OUT` (не капча, не CF!) | - -🔴 **`ERR_TIMED_OUT` в Chrome-странице ошибки = «сайт не ответил», а НЕ «блок Cloudflare» и НЕ «капча»:** ```bash -curl -s ... -d @/tmp/login.json | jq -r ".solution.response" \ - | grep -oE "ERR_[A-Z_]+" | sort -u # → ERR_TIMED_OUT +ssh truenas_admin@mallexxx.duckdns.org \ + 'cd /mnt/RED_2TB/docker/arr && docker compose config -q && docker compose up -d --force-recreate flaresolverr' ``` -🔴 **Признак «прокси реально работает» = внешний IP ОТЛИЧАЕТСЯ от домашнего.** Проверять -`api.ipify.org` через Chrome FS и сравнивать с `curl api.ipify.org` напрямую с хоста. -Домашний IP, вернувшийся через «прокси», ДОКАЗЫВАЕТ, что прокси не проксирует. -## ✅ Что сделано в этой сессии (факты) +После restart session должна восстановиться автоматически. Если она не появилась, смотреть `docker logs flaresolverr`; credentials не выводить в лог. -1. `sessions.list` → `[]`, лишние сессии убиты (`sessions.destroy`); FS чист. -2. Бэкап БД: `/home/truenas_admin/prowlarr.db.bak-preclear-20260929` (618 496 B) — через `.backup`, не `cp`. -3. Снят карантин: `docker stop prowlarr` → `DELETE FROM IndexerStatus;` → **0 записей**, `PRAGMA quick_check` → `ok` → `docker start prowlarr` (ping 200). -4. Таблица `IndexerStatus` — колонка **`ProviderId`**, НЕ `IndexerId`. Записи были: id1 RuTracker Esc=1, id2 RuTor Esc=0, id4 NoNaMe Esc=1, id5/id6. -5. Очистка карантина **не лечит**: без рабочего туннеля RuTracker снова даст 0 и снова уйдёт в карантин. +## Восстановление quarantine -## 🔴 ЧТО ЧИНИТЬ (уточнено Alex 2026-09-29: VPS НЕТ, есть прокси-КОНТЕЙНЕР) +Если Prowlarr показывает старый `IndexerStatus`, сначала сделать backup SQLite. Остановить только Prowlarr, удалить только записи `IndexerStatus`, проверить `PRAGMA quick_check`, запустить и выполнить реальный search. Не удалять `prowlarr.db` и не считать health единственным тестом. -⚠️ **Ошибочная версия (VPS + DuckDNS) отвергнута Alex.** Никакого VPS нет — есть контейнер -`vless-proxy` на самой Тайге. Логи это подтверждают: контейнер **жив** (`Up 2 days`), туннель -устанавливается (`tunneling request ... via vpn.mallexxx.duckdns.org:443`), SOCKS5-порты принимаются. +## Итоговый рабочий результат -🔴 **НАСТОЯЩИЙ ДЕФЕКТ: Chrome FlareSolverr стартует БЕЗ `--proxy-server=` — `PROXY_URL` к Chrome НЕ применяется.** +На 2026-09-29 после полного рестарта Taiga: -Доказательство — командная строка живого процесса Chrome в контейнере FS: -``` -/usr/lib/chromium/chromium ... --headless=new --window-size=1920,1080 --start-maximized ... - ← флага --proxy-server= НЕТ ВООБЩЕ -``` -И контрольный опыт: чистый Chrome-запрос через FS (`request.get api.ipify.org`) **не оставил -ни одной записи** в логе `vless-proxy` (лог до теста = лог после теста, оба кончались на `00:10:17`). -⇒ Chrome **не обращался к прокси**, ходил напрямую, вернул домашний `90.189.160.148`. - -При этом в коде FS прокси подставляется (проверено грепом `/app/flaresolverr.py`): -```python -16: env_proxy_url = os.environ.get('PROXY_URL', None) -58: if (('proxy' not in data or not data.get('proxy')) and env_proxy_url is not None - and (env_proxy_username is None and env_proxy_password is None)): -59: logging.info('Using proxy URL ENV') -60: data['proxy'] = {"url": env_proxy_url} -``` -🔴 **Ключ: env `PROXY_URL` подставляется ТОЛЬКО если в запросе нет своего поля `proxy`.** -Значит либо Prowlarr присылает свой (пустой) `proxy`, либо Chrome при старте получает прокси -не от env, а прокси должен передаваться **явным полем `proxy` в каждом запросе**. - -## 🔴 СЛЕДУЮЩИЙ ШАГ (одно действие, не сделано — сессия прервана) - -Для полного контейнера `vless-proxy` на Тайге: -```bash -# Тест: Chrome с ЯВНЫМ proxy в payload (обход условия «proxy not in data») -cat > /tmp/ipt.json <<'EOF' -{"cmd":"request.get","url":"https://api.ipify.org","session":"iptestX", - "proxy":{"url":"socks5://vless-proxy:1080"},"maxTimeout":80000} -EOF -curl -s --max-time 90 -X POST http://localhost:8191/v1 \ - -H "Content-Type: application/json" -d @/tmp/ipt.json | jq -r ".solution.response" \ - | grep -oE "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" -# ждём IP ≠ 90.189.160.148. Плюс сверить лог vless-proxy: появилась ли строка accepted tcp:api.ipify.org -``` -- IP **отличается** от домашнего → прокси работает, дефект в способе передачи (`proxy` в payload); - фикс — прописать `proxy.url` в прокси-элементе Prowlarr / в запросах. -- IP **тот же** → прокси не проксирует на уровне туннеля, копать `vless-proxy` (куда dial). - -⚠️ **Порядок диагностики «RuTracker = 0» ОБНОВЛЁН** (старый порядок — `sessions.list` первый — ведёт по ложному следу): - -⚠️ **Порядок диагностики «RuTracker = 0» ОБНОВЛЁН** (старый порядок из раздела выше — -`sessions.list` первый — ведёт по ложному следу): - -| # | Проверка | Признак | -|---|---|---| -| **0** | `docker exec flaresolverr ps aux \| grep chromium` → есть ли `--proxy-server=` | **НЕТ флага → Chrome идёт мимо прокси, это и есть причина** | -| 1 | IP через Chrome FS vs IP хоста напрямую | совпадают → прокси не проксирует | -| 2 | след Chrome-запроса в `docker logs vless-proxy` | пусто → Chrome к прокси не обращался | -| 3 | `ERR_[A-Z_]+` в Chrome-странице ошибки | `ERR_TIMED_OUT` ≠ капча ≠ CF | -| 4 | `sessions.list` + `bb_session` в cookies | только после 0–3 | -| 5 | `IndexerStatus` в БД | снимать SQL, тест ПРОДЛЕВАЕТ | - -> 🔴 **Урок:** «прокси настроен (`PROXY_URL` в env)» ≠ «прокси работает». Конфиг верный, -> сеть `media_net` верная, FS живой — а трафика через туннель нет. Единственное доказательство -> работы прокси — **внешний IP на выходе**. +- FlareSolverr session `prowlarr` создаётся с proxy и pre-login. +- Прямой запрос через session получает `bb_session`. +- Реальный Prowlarr search RuTracker возвращает результаты. +- Ошибки Lidarr/SkyHook не относятся к FlareSolverr; их routing описан в [[family/how-to/arr-stack-taiga]]. diff --git a/personal/tech/prowlarr-flaresolverr-cloudflare.md b/personal/tech/prowlarr-flaresolverr-cloudflare.md deleted file mode 100755 index b0b73609..00000000 --- a/personal/tech/prowlarr-flaresolverr-cloudflare.md +++ /dev/null @@ -1,401 +0,0 @@ ---- -title: Prowlarr FlareSolverr — Cloudflare-обход и починка индексеров -created: '2026-09-20' -updated: '2026-09-29' -type: tech -namespace: personal -tags: ["prowlarr", "flaresolverr", "cloudflare", "rutracker", "kinozal", "torrent", "arr", "kraken", "taiga", "infra"] -related: - - "[[family/how-to/arr-stack-kraken]]" - - "[[personal/projects/media-pipeline-pitfalls]]" - - "[[personal/plans/flaresolverr-taiga-deploy]]" - - "[[family/projects/media-toolbox-taiga]]" ---- - -# Prowlarr + FlareSolverr — обход Cloudflare - -Зеркало ключевых питфоллов скилла `torrent-agent-pipeline` (§ Питфоллы). -Контекст: 2026-09-20, Kraken. RuTracker / Kinozal / Kinozal (M) были «красными» в Prowlarr. - -## 🔴🔴 2026-09-29: «Auth Failed» = СНАЧАЛА ДАННЫЕ, ПОТОМ ИНФРАСТРУКТУРА - -**Самый дорогой урок.** Долгая диагностика «капча RuTracker», собран образ с noVNC — всё зря. -Причина: **диагностические тесты шли НЕ ТЕМ аккаунтом.** - -``` -Prowlarr хранит: username = mallexxx password = m@n*w$uperP@$$w0rD -Тесты шли: username = keropjan_88 password = I70aj7Igpr -``` - -RuTracker на неверный пароль отвечает **формой логина + капчей** — отсюда ложный вывод -«трекер требует капчу от человека». С верной парой логин проходит **автоматически, без капчи**. - -🔴 **ПЕРВЫЙ ШАГ при `Auth Failed` — сверить пару из БД, до любых гипотез:** -```bash -DB=/mnt/RED_2TB/docker/arr/prowlarr/prowlarr.db # Кра́кен: /srv/*/docker/prowlarr/config/prowlarr.db -python3 -c " -import json,sqlite3,shutil -shutil.copy('$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()}) -" -``` -Тестировать надо **ровно той парой**, что лежит в Prowlarr. Иначе тест измеряет не то. - -### Признак «залогинен» — РАЗМЕР HTML, не подстрока - -| `len` HTML | Что это | -|---|---| -| **~250 KB** | залогиненный форум ✅ | -| **~13 KB** | форма логина вернулась ❌ | - -⚠️ Подстрока `login_username` есть **в обоих** случаях (HTML-шаблон + скрытая форма быстрого -входа) — по ней диагноз ставить НЕЛЬЗЯ. -Кука авторизации RuTracker — **`bb_session`** (не `bb_data`; в сессии также `cf_clearance`, -`bb_guid`, `bb_ssl`). Отсутствие `bb_session` = логина нет. - -### Что НЕ работает (проверено, не повторять) - -| Идея | Почему нет | -|---|---| -| Капча-солвер (`CAPTCHA_SOLVER`) | **Официально non-functional** (DeepWiki FS, issue #1452 закрыт). Адаптеры удалены из образа | -| Вписать cookies в Prowlarr вручную | Индексер принимает только `username`/`password` — поля для cookie нет | -| noVNC + свой образ FS для ручного входа | Строилось под ложную гипотезу. **Снесено 2026-09-29.** Журнал отката — [[personal/tech/flaresolverr-taiga]] | -| Свой браузер через 3x-ui «по тому же туннелю» | `vless-proxy` — **клиент** xray, не сервер; `cf_clearance` привязан к IP+UA+TLS-fingerprint | -| Persistent-профиль Chrome у FS | Не решает ничего: FS логинится сам при каждом старте | - -> 🔴 **Не строить план на посылке «на Кра́кене работает».** На 2026-09-29 у Кра́кена в БД -> тот же карантин `EscalationLevel=9` (RuTracker/Kinozal/Kinozal M, с 27 сен) и **нет** капча-солвера. - -> 🔴 **Приёмка — `search`, а НЕ `caps` и НЕ `health`.** `caps` 200 + пустой `indexerstatus` + -> `health []` не доказывают, что поиск работает. Разбивка по индексеру обязательна. - -## Схема - -``` -Prowlarr (Kraken:9696) → FlareSolverr (Kraken:8191) → Cloudflare-защищённый трекер - ⚠️ прокси применяется ТОЛЬКО при одинаковом tag на прокси И на индексере -``` - -Все контейнеры — в общей внешней сети `media_net`: radarr, sonarr, prowlarr, transmission, flaresolverr. -Проверять фактическую сеть, а не compose-файл: -```bash -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**. - -```bash -KEY=$(grep -oP "(?<=)[^<]+" /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:** -```bash -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 ...`. - -```bash -# бэкап перед правкой БД -cp /srv/.../docker/prowlarr/config/prowlarr.db / -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`. - -```yaml - 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`: - ```bash - 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` могут быть **пустыми**, пока индексер красный. Диагноз снимать из лога `/logs/prowlarr.debug.txt` (НЕ `logs/prowlarr.txt`). Искать: `grep -iE "rutracker|kinozal|Cloudflare|429"`. -- **«Кто живой» быстрее всего — поиском**, не caps-тестом: - ```bash - 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 на каждый». - -## 🔴 2026-09-24: FlareSolverr в crash-loop — Chrome не поднимается под chromedriver - -**Повод:** Alex — «Мастерская сатаны: в торрентах ничего не нашлось, по каким трекерам -ищет и можно ли влиять через Prowlarr?» Симптом оказался двухслойным: сверху пустая -выдача PidTor, под ней — мёртвый FlareSolverr. - -### Слой 1 (верхний): PidTor отдаёт 503 из кэша, jac.red — 0 результатов - -``` -GET /lite/pidtor?title=Мастерская сатаны&year=2025 - → HTTP 503, Content-Length: 0, X-Invoke-Cache: HIT, t=0.007s ← кэш - -GET http://jac.red/api/v2.0/indexers/all/results?title=Мастерская сатаны&year=2025 - → HTTP 200, {"Results":[],"jacred":true} ← ЧЕСТНЫЙ ноль -GET …/results?title=Матрица&year=1999 - → HTTP 200, 132 раздачи ← контроль: живой -``` - -**jac.red знает 25 индексеров:** `anibelka anidub anifilm aniliberty animelayer anistar -baibako bitru kinozal korsars leproduction lostfilm mazepa megapeer nnmclub rudub rutor -rutracker selezen subsplease toloka torrentby ultradox viruseproject`. - -🔴 **Список индексеров jac.red:** `GET http://jac.red/api/v2.0/indexers?configured=true` -→ 200, ~4 КБ, массив с `name`. Рабочий способ посмотреть, по каким трекерам реально -идёт поиск — не догадываться. - -🔴 **jac.red отдаёт 429 при частых запросах** (nginx): пауза `sleep 2-3` между вызовами -обязательна. Формулировка ответа: nginx-страница `429 Too Many Requests`, НЕ JSON. - -🔴 **`title=` должен быть URL-кодирован целиком.** `%20` в значении даёт **HTTP 400** — -использовать `curl -G --data-urlencode "title=Мастерская сатаны"`. Ручная сборка -query-строки с `%20` в середине ломается. - -**Вывод по «Мастерская сатаны»:** у фильма реально нет раздач на 25 трекерах jac.red. -Механизм PidTor исправен (контроль на «Матрице» — 132 раздачи). Диагноз «сломан поиск» -был бы неверным. - -⚠️ Одноимённый фильм 2022 года лежит там как **«Мастерская дьявола / Devil's Workshop»** -(`Devils Workshop` → 2 раздачи, bitru + kinozal, sid 0-1). Латиница в выдаче — не тот -фильм, следить за годом. - -### Слой 2 (первопричина): FlareSolverr crash-loop ⇒ 3 индексера Prowlarr мертвы - -``` -RuTracker (id=1) disabledTill = 2026-09-25T10:17:51Z -Kinozal (id=5) disabledTill = 2026-09-25T10:17:50Z -Kinozal (M) (id=6) disabledTill = 2026-09-25T10:17:48Z -EscalationLevel = 9 (максимум — блокировка на 24 ч) -``` - -Проверка: `GET /prowlarr/1/api?t=search&q=…` → `429 Indexer is disabled till …`. -Прямой результат несмотря на то, что таблица `IndexerStatus` начиналась 20-го (начальные -падения) и докатилась до `EscalationLevel=9` именно **24-го в 10:17**. - -**В логе FlareSolverr:** - -``` -Error starting Chrome: Message: session not created: cannot connect to chrome at - 127.0.0.1:48249 from chrome not reachable -Exception: Error getting browser User-Agent. … - File "/app/flaresolverr.py", line 136, in - flaresolverr_service.test_browser_installation() -``` - -Контейнер `flaresolverr` уходит в **crash-loop** (`Restarting (1)`), HTTP `:8191` не -отвечает (`Connection reset by peer`). Успешных решений челленджа в логе (`Challenge -solved`) нет — считать их число: `sudo docker logs flaresolverr 2>&1 | grep -c "Challenge solved"`. - -### Что проверено и исключено (не тратить время повторно) - -| Гипотеза | Проверка | Итог | -|---|---|---| -| Образ обновлён watchtower'ом и сломан | `image inspect` → v3.5.2, `Created=2026-09-12`; в логах watchtower нет строк про flaresolverr | ❌ не при чём | -| Нехватка RAM | `free`, суммарный RSS всех процессов = 1.9 GB при MemAvailable ~1.8 GB | ⚠️ фон, не корень | -| **swap мёртв** | `/proc/swaps` **пуст** при живом `/var/swap` (512 MB); `SwapFree` падал до 240 kB | ✅ **реальный баг хоста**, починен | -| IPv6: `/etc/hosts` отдаёт `::1 localhost` первым, Chrome на IPv6-петле | в контейнере `/etc/hosts` → `::1 localhost` первый; **добавлен `net.ipv6.conf.all.disable_ipv6=1`** (как у prowlarr) → `disable_ipv6=1`, hosts стал `127.0.0.1 localhost` | ❌ **НЕ помогло**, ошибка дословно та же | -| `/dev/shm` мал (64 MB) | `docker inspect` → `ShmSize=67108864`; в контейнере `df -h /dev/shm` → 64M | ⚠️ **подозреваемый №1 из оставшихся** | - -🔴 **Chrome запускается вручную, но не под chromedriver.** Проверено: -`docker exec flaresolverr sh -c '/usr/lib/chromium/chromium --headless=new --no-sandbox ---disable-dev-shm-usage --disable-gpu --dump-dom about:blank'` → работает, отдаёт -verbose-лог компонентов; под управлением selenium — `cannot connect to chrome at 127.0.0.1:`. -В образе **`chromedriver` не в PATH** (`which chromedriver` → not found) — selenium ≥ 4 -использует собственный Selenium Manager. - -🔴 **Вывод не делать по одной гипотезе.** IPv6 выглядел убедительно (симптом -«не видит chrome на 127.0.0.1» идеально ложится), но после применения ошибка -воспроизвелась дословно — то есть причина не в резолве адреса. - -### ✅ Починено в этой сессии - -**1. swap был мёртв — восстановлен.** `/proc/swaps` пуст, а `/var/swap` (512 MB) на диске -есть, ядро держало `SwapFree=256 kB` при нулевом активном swap. Без swap Chrome не -получает память при пике старта. - -```bash -sudo swapon /var/swap # → /proc/swaps: /var/swap file 524272 -2 -cat /proc/swaps # проверка -grep -E "^(SwapTotal|SwapFree)" /proc/meminfo -``` - -⚠️ **`swapoff -a && swapon -a` НЕ восстанавливает** — даёт `SwapFree: 0 kB`. Помогает -только явный `sudo swapon /var/swap`. В `/etc/fstab` строки для swap НЕТ -(комментарий `dphys-swapfile`), systemd swap-unit не поднят (`systemctl list-units ---type=swap --all` → 0 units). Автоподъём swap на этом хосте **не настроен** — после -ребута swap снова может пропасть. - -**2. `disable_ipv6` добавлен сервису `flaresolverr`** (в `docker/prowlarr/docker-compose.yml`, -бэкап `docker-compose.yml.bak-20260924-193632`). **Эффекта не дало** — оставлено как -проверенная-неудачная попытка; при откате вернуть файл из бэкапа. - -```yaml - flaresolverr: - image: ghcr.io/flaresolverr/flaresolverr:latest - environment: - - LOG_LEVEL=warning # ← не info: info пишет пароли трекеров - - BROWSER_TIMEOUT=60000 - ports: - - 8191:8191 - networks: - - media_net - sysctls: - - net.ipv6.conf.all.disable_ipv6=1 # 2026-09-24: не помогло, см. выше - shm_size: 1gb # ⏳ НЕ ПРИМЕНЕНО — кандидат на фикс -``` - -⏳ **Незавершённое:** добавить `shm_size: 1gb` и пересоздать -(`docker compose up -d --force-recreate flaresolverr`), затем снять блокировки -`IndexerStatus` для id 1/5/6 (см. секцию выше) и проверить -`POST http://localhost:8191/v1 {"cmd":"request.get","url":"https://kinozal.me/browse.php?c=0"}` -→ ожидается `status: ok`. После этого — поиск «Мастерская сатаны» по всем 6 трекерам. - -### Дополнительные питфоллы сессии - -1. 🔴 **`escape` из контейнера в crash-loop:** `docker exec` отдаёт - `OCI runtime exec failed: exec failed: unable to start container process` / - `cannot exec in a stopped container`. Это признак рестарт-петли, а не «неверный exec» — - сначала `docker ps -a --filter name= --format "{{.Status}} R={{.RestartCount}}"`. -2. 🔴 **`sudo docker stats` показывает `0B / 0B` у всех контейнеров.** Метрика врёт - (недоступна на этом хосте) — считать память по контейнерам через - `/sys/fs/cgroup/system.slice/docker-.scope/memory.current`, а по процессам — `ps -eo rss`. -3. 🔴 **`ps aux --sort=-rss | awk` с `%4`/`$6` даёт мусор** — формат `ps aux` на этом - хосте отдаёт 11 полей, `%MEM` и RSS нужно читать через `ps -eo user,pid,rss,comm,args`. -4. 🔴 **Долгие ssh-команды в crash-loop контейнера вешают терминал на 400+ с** — резать - диагностику на короткие скрипты и не ждать готовности контейнера дольше 240 с. -5. ⚠️ **`sudo` на Кра́кене требует TTY** — `ssh -t kraken '…'`. Без `-t`: - `sudo: a password is required`. - -## Применение на Тайге (2026-09-28) — ключевое отличие от Кра́кена - -Тот же FlareSolverr ставится на Тайгу, но схема **не копия один-в-один**: -[[personal/plans/flaresolverr-taiga-deploy]]. - -🔴 **На Тайге есть DNS-блок провайдера** (NXDOMAIN на rutracker.org / rutor.info / -kinozal.tv / nnmclub.to даже с 8.8.8.8), которого на Кра́кене НЕТ. Поэтому: - -- На Кра́кене FlareSolverr лезет в трекер **напрямую** — и упирается только в Cloudflare. -- На Тайге так нельзя: **FS сам получит NXDOMAIN**. Прокси-маршрут уже есть - (`vless-proxy` в `media_net`, SOCKS5 `vless-proxy:1080`; `rutracker.org` → 301 через него), - но **прокси-элемент `vless-socks5` в Prowlarr FS НЕ покрывает** — он применяется к запросам - *самого Prowlarr*. Нужно, чтобы **Chrome внутри FS тоже ходил через `vless-proxy`** - (env `HTTP_PROXY`/`HTTPS_PROXY` образа либо `proxy` в теле `request.get`). - ⏳ Схему проверить до деплоя. - -🔴 **Оба грабля-условия воспроизведены на Тайге** (там Chrome тоже упадёт): - -| Условие | Факт на Тайге 2026-09-28 | -|---|---| -| `/dev/shm` | **64 MB** (`ShmSize=67108864`) → задать `shm_size: 1gb` | -| swap | **`/proc/swaps` ПУСТ, `Swap: 0`** → Chrome не получит память на пике старта | -| RAM | 21 GB total / 5.6 GB available — ✅ хватает | -| IPv6 | проверить; на Кра́кене `disable_ipv6=1` не помог, но безвреден | - -⚠️ **Наблюдение (Тайга):** `curl` через SOCKS5 к `kinozal.tv` → `000`, к `kinozal.me` → `200`. -То есть `.tv` мёртв как домен, а не «заблокирован». Урок общий: **`000` = домен/соединение, -`403`/`Just a moment` = Cloudflare** — не смешивать диагнозы. - -## Источники - -- Скилл: `torrent-agent-pipeline` (§ Питфоллы), `lampac-kraken-deploy` -- Живой разбор: [[family/how-to/arr-stack-kraken]] — секции про починку индексера 2026-09-20 -- Слой PidTor/кэш: [[personal/tech/lampac-torrserver]] §«2026-09-24» -- Каталог/конфиг lampac: [[personal/tech/lampac-deployment]] - -## 🔵 2026-09-28: перенос схемы на Тайгу — FlareSolverr ЗА DNS-блоком - -Развёрнут FlareSolverr на **Тайге** ([[personal/plans/flaresolverr-taiga-deploy]]) — там -к Cloudflare добавляется **DNS-фильтр провайдера** (NXDOMAIN на трекеры). Это меняет схему: - -``` -Kraken: Prowlarr → FlareSolverr → трекер (DNS-блока нет, прямой выход) -Taiga: Prowlarr → FlareSolverr → vless-proxy → трекер (FS сам должен ходить через прокси) -``` - -🔑 **Ключевая деталь, которой нет в схеме Кра́кена:** FlareSolverr сам должен ходить через -прокси, иначе получит NXDOMAIN и не поможет вообще. Задаётся **глобальной env `PROXY_URL`** -(НЕ `HTTPS_PROXY`/`HTTP_PROXY` — их FS не читает): - -```yaml - flaresolverr: - environment: - - PROXY_URL=socks5://vless-proxy:1080 # ← схема обязательна; socks5h не нужен, FS резолвит сам - - LOG_LEVEL=warning - shm_size: 1gb -``` - -Приоритет прокси у FS: `request` > `session` > `global`. Prowlarr зовёт FS с `session` → -request-прокси игнорируется, срабатывает именно global. Передать прокси из Prowlarr нельзя -(у Socks5-элемента только host/port/user/pass). - -### Дополнительные питфоллы, найденные на Тайге - -1. 🔴 **`requestTimeout` у FS-прокси в Prowlarr по умолчанию 60 с — МАЛО.** CF-челлендж на - `/forum/login.php` не укладывается → `Error solving the challenge. Timeout after 60.0 seconds`. - **Ставить 120.** Правка: PUT `/api/v1/indexerproxy/2` с `fields[requestTimeout].value=120`. -2. 🔴 **`PUT /api/v1/indexer/N` возвращает 400, если тест FS в этот момент не прошёл** — Prowlarr - валидирует сразу при сохранении. Тело: `Unable to connect to indexer ... [500:InternalServerError] - [POST] at [http://flaresolverr:8191/v1]`. **Теги при этом НЕ применяются.** Обход — - **`?forceSave=true`** → 202. Иначе будет казаться, что тег «не навешивается». -3. 🔴 **`POST /api/v1/indexer/testall` идёт ПАРАЛЛЕЛЬНО, а Chrome в FS один** → часть челленджей - отваливается, индексер показывает ложный `blocked by CloudFlare Protection`. **Проверять - одиночным `request.get` с `maxTimeout=120000`**, а не верить `testall`. -4. ⚠️ **Индексеру могут понадобиться ДВА тега** — `proxy` (DNS-обход) **и** `flaresolverr` - (CF-челлендж). Один прокси не решает оба блока. На Кра́кене достаточно одного (только CF). -5. ⚠️ **Ключ API в файл + `-H @/tmp/h.txt`** внутри контейнера. Прямая передача `-H "X-Api-Key: $K"` - через вложенный `ssh`+`sh -c` ломается на кавычках → **401** при верном ключе. -6. ⚠️ `python3` в контейнере Prowlarr **нет** — JSON разбирать на хосте. Долгие вызовы — - `docker exec -d` в фон + файл-маркер `.done`.