10 KiB
Clerk + Cloudflare Turnstile: IP-match rule & API recon (Kleo case, 2026-09-20)
Кейс: Kleo (mykleo.ai, Clerk auth) — регистрация через Clerk REST API + YesCaptcha Turnstile. Завершён на этапе «все бесплатные residential-пулы мертвы»; техника recon и матрица фейлов валидированы live.
Recon без браузера — Clerk environment endpoint
GET https://clerk.<domain>/v1/environment?_clerk_js_version=6.32.0
Header: Origin: https://app.<domain>
В ответе display_config:
captcha_provider(turnstile/hcaptcha/...)captcha_public_key— sitekey видимого виджетаcaptcha_public_key_invisible— sitekey невидимого (smart-режим может использовать любой)captcha_widget_type(smart= решение принимается сервером по fingerprint/IP)user_settings.sign_up.captcha_enabled
Publishable key ищи в HTML signup-страницы: pk_live_... в атрибуте clerk-publishable-key=.
Для Kleo: sitekey 0x4AAAAAAAWXJGBD7bONzLBd (visible), 0x4AAAAAAAFV93qQdS0ycilX (invisible), pk pk_live_Y2xlcmsubXlrbGVvLmFpJA.
GATING: проверяй auth_config ДО обещания IMAP-авторега (live 2026-09-21, Tusk)
Перед тем как строить пайплайн «email + IMAP OTP», всегда читай auth_config из того же environment-эндпоинта:
GET https://clerk.<domain>/v1/environment
Header: Authorization: Bearer <pk_live_...>
Ключевые поля:
auth_config.email_address—off= email-регистрация ОТКЛЮЧЕНА, письмо с кодом не придёт НИКОГДА, IMAP-путь мёртв (кейс tusksearch.com:email_address = off).auth_config.identification_strategies— чем реально можно зарегистрироваться (oauth_google/oauth_apple/oauth_facebook,phone_number,email_address).auth_config.first_factors/second_factors—phone_code= SMS OTP.auth_config.single_session_mode— одна сессия на клиента.user_settings.attributes.email_address.enabled/required— дубль-подтверждение.
ВАЖНО — environment НЕ полон: у Tusk identification_strategies показывал только OAuth, но ЖИВАЯ форма sign-up содержала First name + Last name + Phone number (+380 UA default) + Terms + Continue. Правило: environment даёт ОТРИЦАТЕЛЬНЫЕ гейты (что точно выключено, например email), а позитивный набор полей проверять headful-пробой реальной страницы sign-up.
Удаление аккаунта для лупа «тратить лимиты → удалить → ре-регать»: Clerk REST DELETE /v1/me с session-токеном (__session cookie/JWT). Для single_session_mode после удаления достаточно нового sign-up.
Edge-блок curl: curl https://accounts.<domain>/sign-up может вернуть 403 при том, что headful Chrome (persistent context, channel="chrome") грузит страницу нормально — диагностику формы делать только браузером, не curl.
Clerk REST signup
POST https://clerk.<domain>/v1/client/sign_ups?_clerk_js_version=6.32.0
Content-Type: application/x-www-form-urlencoded (form data, НЕ json)
Origin: https://app.<domain> # ИЛИ Authorization: Bearer <pk> — ВЗАИМОИСКЛЮЧАЮЩИЕ!
email_address=...&password=***&first_name=...&last_name=...&captcha=<turnstile_token>
Quirk: Setting both the 'Origin' and 'Authorization' headers is forbidden → используй Origin+Referer без Authorization.
Ответ 200 → response.id, response.status (missing_requirements / complete), verifications.
МАТРИЦА ФЕЙЛОВ Turnstile (все проверены live)
| Схема | Результат | Почему |
|---|---|---|
| Proxyless solver (YesCaptcha решает со своего IP), запрос с нашего IP | 400 failed security validations / captcha_missing_token |
Turnstile-токен привязан к IP решения; mismatch |
| Один DC free-прокси для solver И запроса (IP совпадает) | YesCaptcha ERROR_CAPTCHA_UNSOLVABLE на getTaskResult |
Cloudflare smart-виджет флагает датацентровый IP ещё на этапе решения |
| Один residential-прокси для solver И запроса | ожидаемо PASS (не дошли — пул умер) | совпадают IP + репутация residential |
| Headed-браузер на домашнем residential IP | managed-виджет часто self-solves без solver | настоящий браузер + жилой IP = чистый fingerprint |
Правило: turnstile-токен и signup-запрос ОБЯЗАНЫ идти через ОДИН residential/mobile IP.
DC-прокси не годятся даже при совпадении IP. Поле токена: captcha (проверены также captcha_token, turnstiletoken — не они).
Многошаговые Clerk-формы (Kleo UI-flow)
Step 1 = first/last/email ТОЛЬКО (без капчи, без пароля) → кнопка «Continue» (НЕ «Continue with Google» — осторожнее с button:has-text("Continue"), сматчит Google-кнопку; использовать точный текст/exact=True). Step 2 = пароль + turnstile. Капча появляется на шаге 2, а REST sign_ups требует токен сразу — поэтому для API-пути токен нужен заранее.
window.Clerk.client.signUp в браузере даёт {status, id, missingFields, verifications} — удобный критерий успеха вместо парсинга DOM.
Состояние бесплатных residential-пулов (2026-09-20)
- bpproxy (@bpproxy_bot): бесплатный бонус ОТМЕНЁН — 0 проксей из 25 свежих TG-сессий («no proxy, 0 traffic»), подтверждено дважды (09-19, 09-20). Остались только платные.
- TR residential (tr_residential_proxies.txt, 49 шт): 0 живых.
- Free DC (geonode/proxyscrape/TheSpeedX): ~2-8 живых из 4100, но для Turnstile бесполезны (см. матрицу).
- ZTE 4G модем (192.168.0.4:8080): поднят только когда модем физически подключён — проверять ping 192.168.0.1 перед использованием.
- Вывод: для Clerk-Turnstile авторегов без платного residential единственный путь — headed-браузер на домашнем IP пользователя.
Интерактивный Turnstile-чекбокс в cross-origin iframe (live 2026-09-20)
Если step2 показывает «Verify you are human» — это ИНТЕРАКТИВНЫЙ чекбокс, не managed/invisible:
- Родительский документ НЕ видит виджет:
document.querySelector('.cf-turnstile, input[name=cf-turnstile-response]')→ null, respLen=0 вечно. Не делать вывод «капчи нет» по DOM родительской страницы. - Обнаружение: итерация
page.framesпоchallenges.cloudflare.comв URL, ИЛИ скриншот + vision-анализ (именно скриншот показал чекбокс, когда все DOM-запросы返回 пусто). - Автоматический клик по чекбоксу во фрейме (
fr.locator('input[type=checkbox]').click(force=True)/ mouse.click по координатам) верификацию НЕ проходит — Cloudflare валит автоматизированный клик (Playwright headed+headless). - Следствие: парольное поле не появляется, пока чекбокс не решён человеком. Для полного авто нужен либо residential-IP + solver, который умеет interactive turnstile (дорого/редко), либо CDP-подключение к реальному браузеру пользователя, где человек кликает один раз.
- Диагностика «форма зависла в loading, FIELDS пустой» после step1 = почти всегда невидимый turnstile-гейт; проверить скриншотом ДО написания нового fill-кода.
DC-прокси: browser-level провал (дополнение к матрице)
Дешёвые free DC-прокси (geonode/proxyscrape пул) не держат HTTPS CONNECT-туннель к целям за Cloudflare: Playwright page.goto через них → net::ERR_TUNNEL_CONNECTION_FAILED или 75-секундный таймаут, даже когда curl -x к ip-api через тот же прокси работает. Т.е. прокси «живой» по чек-сайту ≠ пригоден для браузера. Валидировать прокси для browser-flow именно page.goto на целевой домен, а не curl.
Kleo-специфика
- Kleo = SMM-ассистент (mykleo.ai), free tier есть, шим-обёртка в OpenAI API:
gitlab.com/ameobius-ai/kleo-shim(клон вtmp/kleo-shim/). Assistant endpoint:POST api.mykleo.ai/v1/assistant/stream/{surface}, Clerk JWT живёт 60с (минтится из cookie-jar),x-kleo-business-idизGET /v1/businesses. - git clone с этой машины:
remote-httpsсломан → качать raw-файлы черезhttps://gitlab.com/<ns>/<repo>/-/raw/main/<file>curl'ом. - Кредиты: 0.8–7/ход, tools-параметр upstream отклоняет (агент, не голая модель).