4.0 KiB
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
PORTenv 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 fromos.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 /healthinstantly — health is NOT proof of capacity. Verify with a realPOST /solveround-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.exewould 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.phpwith{key, action:getbalance}— balance checks must be POST; a GET returns a misleadingERROR_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.