A simple turnstile validation using ingress-nginx.
This is a simple example of validating a turnstile challenge using ingress-nginx.
If the turnstile validation passes, lua in ingress-nginx will validate the challenge, and send the request on to the server which will respond with You're probably human! Good luck.
Other responses are generated by lua. Typically they would be 403's, but here I'm using 200 so the response content can be easily swapped into the webpage.
See me live at https://human.alphabet5.dev
This is the relevent lua in the ingress object to filter based on the turnstile validation.
lua_ssl_verify_depth 5;
lua_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
resolver kube-dns.kube-system ipv6=off valid=60;
access_by_lua_block {
ngx.req.read_body()
local args, err = ngx.req.get_post_args(1)
if not args or not args["cf-turnstile-response"] then
ngx.say("Try harder, bot.")
return ngx.exit(ngx.HTTP_OK)
end
local httpc = require("resty.http").new()
local res, err = httpc:request_uri("https://challenges.cloudflare.com/turnstile/v0/siteverify", {
method = "POST",
body = "secret="..os.getenv("MANAGED_SECRET").."&response="..args["cf-turnstile-response"],
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
},
})
if err then
ngx.say("Houston, we have a problem.")
return ngx.exit(ngx.HTTP_OK)
end
local cjson = require "cjson"
ngx.log(ngx.ERR, res.body)
local stat = cjson.decode(res.body)["success"]
if not stat then
ngx.say("<div title=\"Refresh the page to check again, the token only works once.\">ಠ_ಠ</div>")
return ngx.exit(ngx.HTTP_OK)
else
ngx.say("You're probably human! Good luck.")
return ngx.exit(ngx.HTTP_OK)
end
}