61 lines
4.0 KiB
Markdown
61 lines
4.0 KiB
Markdown
# Captcha-solver infra: sidecar contention + proxy-egress alignment
|
|
|
|
Cross-farm rules for ANY registration wave that solves Turnstile/reCAPTCHA through a
|
|
local browser solver (cs_sidecar `server.py`, or conol's `chrome_cdp`) while rotating
|
|
proxies. These bite when running several farms at once or behind proxy rotation.
|
|
|
|
## 1. One solver instance per concurrent wave (else HTTP 408)
|
|
The local captcha sidecar enforces a server-side per-solve deadline (~60s). Two
|
|
concurrent farm waves pointed at the SAME port (e.g. miarouter + ablit both on `:8877`)
|
|
queue their solves past the deadline and get `HTTP 408 Request Timeout`; the farm then
|
|
retries forever and makes zero progress.
|
|
- Fix: start a SECOND instance on another port via the `PORT` env var
|
|
(`PORT=8879 python -u server.py`), and repoint one farm's solver URL
|
|
(`SIDE = "http://127.0.0.1:8879/solve"`). The sidecar reads its port from
|
|
`os.getenv("PORT", "8877")`, so no code edit is needed to spawn an extra instance.
|
|
- Rule: N concurrent captcha-consuming waves → N sidecar instances, one port each.
|
|
Never share a single solver across parallel farms.
|
|
- A contended sidecar still answers `GET /health` instantly — health is NOT proof of
|
|
capacity. Verify with a real `POST /solve` round-trip before declaring it working.
|
|
|
|
## 2. Captcha-browser egress IP MUST equal the registration egress IP
|
|
reCAPTCHA v3 / Turnstile are score-based and IP-bound: the server-side siteverify
|
|
compares the IP that SOLVED the captcha against the IP that SUBMITS the register token.
|
|
If the register HTTP goes through a proxy (`HTTPS_PROXY` env → requests honors it) but
|
|
the captcha browser solves from the home IP, the token is rejected with
|
|
`CAPTCHA_VERIFICATION_FAILED` ("Human verification failed") even though the solve itself
|
|
returned a valid-looking token. Symptom: solve succeeds, register 403s on captcha.
|
|
- Fix: route the captcha browser through the SAME proxy as the register calls. For a
|
|
Chrome-CDP solver, patch the launcher to append `--proxy-server=<proxy>` (read from an
|
|
env var, e.g. `CONOL_CHROME_PROXY`), and KILL + RELAUNCH the captcha Chrome before each
|
|
proxy rotation — the browser is launched once and reused, so a stale proxy persists
|
|
across every subsequent solve otherwise.
|
|
- Kill the captcha Chrome by the PID LISTENING on its CDP port (e.g. `netstat -ano |
|
|
grep :9228` → `taskkill /F /T /PID <pid>`). That Chrome is the dedicated solver
|
|
instance (own `--user-data-dir`), NOT the user's main browser — never kill by image
|
|
name (`taskkill /IM chrome.exe` would take down the user's browser).
|
|
- Caveat: free datacenter proxies usually cannot even load a Cloudflare-fronted captcha
|
|
page (browser hangs, solve fails before a token exists). Egress alignment only pays off
|
|
with residential/clean proxies that can actually render the captcha site. If every
|
|
proxy in a free pool fails the captcha load, the bottleneck is proxy quality, not the
|
|
alignment wiring.
|
|
|
|
## 3. Key-pool drain: never trust pool order
|
|
Farm scripts that read the first key of a captcha-key pool file (`keys[0]`) fail with
|
|
`ERROR_ZERO_BALANCE` the moment that key drains — even when funded backups sit next to
|
|
it in the same file. A mid-wave drain looks like a captcha outage, not a billing problem.
|
|
- Before a wave, check EVERY pool key: `POST https://api.2captcha.com/res.php` with
|
|
`{key, action:getbalance}` — balance checks must be POST; a GET returns a misleading
|
|
`ERROR_WRONG_USER_KEY`.
|
|
- Scripts should iterate the pool: on `ERROR_ZERO_BALANCE`, move to the next key with a
|
|
positive balance instead of aborting the run.
|
|
- Turnstile solves are cheap per unit but long waves add up; re-check balances before
|
|
each wave, not once per day.
|
|
|
|
## 4. Gateway interruption kills background waves
|
|
A Hermes gateway restart/interruption terminates background farm processes. After any
|
|
interruption, do NOT trust the in-memory process list — check each wave's log mtime
|
|
(`stat -c %y <log>`) against `date`; a stale mtime means the wave died and must be
|
|
relaunched. Resume-able farms (state file per wave) pick up where they left off; others
|
|
restart from scratch.
|