[bug] | [feat] Cloudflare Turnstile is broken
Hi,
Configuring this bouncer with Cloudflare Turnstile will always return:
error verifying captcha: 503,<html><body><h1>503 Service Unavailable</h1>.No server is available to handle this request..</body></html>.; verifier: 104.18.95.41:443
The problem disappears when switching to hCaptcha.
The problem appears to be: Lua core.httpclient() is too weak for this task triggering Cloudflare to block its requests.
The solution would be to create a sidecar container to handle http request to Cloudflare something like:
from fastapi import FastAPI, Request, HTTPException
import httpx
import os
app = FastAPI()
CLOUDFLARE_URL = "https://challenges.cloudflare.com/turnstile/v0/siteverify"
CLOUDFLARE_SECRET = os.getenv("TURNSTILE_SECRET")
@app.post("/validate")
async def validate_captcha(request: Request):
data = await request.json()
# Extract and validate required fields
captcha_response = data.get("response")
remoteip = data.get("remoteip")
if not captcha_response:
raise HTTPException(status_code=400, detail="Missing captcha response")
payload = {
"secret": CLOUDFLARE_SECRET,
"response": captcha_response,
"remoteip": remoteip
}
# POST to Cloudflare
async with httpx.AsyncClient(timeout=5) as client:
try:
cloudflare_resp = await client.post(CLOUDFLARE_URL, data=payload, headers={
"Content-Type": "application/x-www-form-urlencoded",
"User-Agent": "captcha-proxy/1.0"
})
except httpx.RequestError as e:
raise HTTPException(status_code=503, detail=f"Cloudflare unreachable: {e}")
if cloudflare_resp.status_code != 200:
raise HTTPException(status_code=503, detail="Failed to verify captcha")
result = cloudflare_resp.json()
return result
and change the lua call to
local status, res = pcall(function()
return core.httpclient():post{
url = "http://localhost:8081/validate",
body = json.encode({
secret = M.SecretKey,
response = captcha_res,
remoteip = remote_ip
}),
headers = {
["Content-Type"] = {"application/json"}
},
timeout = 2000
}
end)
This is also probably the reason for #37
Maybe. The linked issue #37 I closed because it went away very soon (hours maybe) after logging it on github. No changes from my side, perhaps a restart of one of the elements. So my setup was not changed and the issue dissappeared once I had pretty much finished all the testing I was doing. In other words, no code needed to change. Maybe it is another problem but seems (to me the untrained eye), that is not related.