Self-Hosting CAPTCHA, Haproxy(Login 2)
James+Stephen
Self-Hosting CAPTCHA, Haproxy(Login 2)
Protecting Your Website Without Third-Party Services
In the digital battlefield of website security, distinguishing between legitimate users and automated threats is crucial. Before a user even reaches your login page, you need a frontline defense that separates humans from bots and AI systems. This is where CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart) comes into play.
The Problem with Third-Party CAPTCHAs
While Google’s reCAPTCHA, Cloudflare’s Turnstile, and Amazon’s AWS WAF CAPTCHA are powerful solutions, they come with a significant drawback: they require modifying your Content Security Policy (CSP) to allow external connections. This creates potential security vulnerabilities and privacy concerns.
For those running sensitive applications or wanting complete control over their security infrastructure, self-hosting a CAPTCHA solution becomes an attractive alternative.
Self-Hosted CAPTCHA with HAProxy
Let me share how you can implement a simple yet effective self-hosted CAPTCHA using HAProxy, a reliable open-source load balancer and proxy server:
global
lua-load /etc/haproxy/verify_captcha_auth.lua
frontend https443_j3
bind 0.0.0.0:443 ssl crt /etc/nginx/ssl/jjj123.com.pem crt /etc/nginx/ssl/chinadsf.org.pem alpn h2,http/1.1
bind quic4@0.0.0.0:443 ssl crt /etc/nginx/ssl/jjj123.com.pem crt /etc/nginx/ssl/chinadsf.org.pem alpn h3
http-response set-header alt-svc 'h3=":443"; ma=86400'
# ACLs
acl acl_site_blog0 hdr(host) -i blog.jjj123.com blog0.jjj123.com blog00.jjj123.com blog01.jjj123.com blog02.jjj123.com
acl acl_protect_path_blog0 path_beg /editor001/
acl acl_captcha_png path /captcha_png
acl acl_captcha_check path /captcha_check
acl acl_captcha_auth path /captcha_auth
acl acl_captcha_html path /captcha_html.html
# Cookie and auth checks
acl acl_has_captcha_session cook(captcha_session) -m found
acl acl_has_captcha_auth cook(captcha_auth) -m found
# Run Lua script to verify captcha auth for protected paths
http-request set-var(txn.captcha_auth_valid) bool(false)
http-request lua.verify_captcha_auth if acl_site_blog0 acl_protect_path_blog0 acl_has_captcha_session acl_has_captcha_auth
acl acl_valid_captcha_auth var(txn.captcha_auth_valid) -m bool
# Redirect to captcha if protected path and no valid auth
http-request redirect location /captcha_html.html if acl_site_blog0 acl_protect_path_blog0 !acl_valid_captcha_auth
# Backend selection
# CAPTCHA service endpoints
use_backend backend_captcha if acl_site_blog0 acl_captcha_png
use_backend backend_captcha if acl_site_blog0 acl_captcha_check
use_backend backend_captcha if acl_site_blog0 acl_captcha_auth
use_backend backend_blog0 if acl_site_blog0 acl_captcha_html
# Protected paths with valid captcha auth
use_backend backend_blog0 if acl_site_blog0 acl_protect_path_blog0 acl_valid_captcha_auth
# Non-protected blog traffic
use_backend backend_blog0 if acl_site_blog0 !acl_protect_path_blog0
# Default backend for blog domain traffic that doesn't match other rules
use_backend backend_default_for_debug if acl_site_blog0
How This Self-Hosted CAPTCHA Works
This configuration creates a simple yet effective self-hosted CAPTCHA solution:
- First-Time Visitors: When someone visits your site without a verification cookie, they’re presented with a math challenge
- Challenge Generation: HAProxy dynamically generates two random numbers and their sum
- User Experience: The visitor sees a clean, professionally styled math problem to solve
- Verification: Upon submission, HAProxy compares the answer with the expected result
- Success Path: If correct, a validation cookie is set, and the user proceeds to your site
- Static Resources: Images, CSS, and JavaScript files bypass the CAPTCHA for better user experience
Benefits of Self-Hosting
This approach offers several advantages:
- Complete Control: No external dependencies or third-party servers
- Privacy Preservation: User data stays on your servers
- CSP Integrity: No need to weaken your Content Security Policy
- Customization: Easy to modify challenges or appearance
- Performance: Minimal overhead compared to third-party solutions
Beyond Math Problems
While this example uses a simple math challenge, you can extend the concept with:
- Custom image-based CAPTCHAs generated on your server
- Slider puzzles implemented with JavaScript
- Time-based challenges measuring human-like interaction patterns
Conclusion
Self-hosting your CAPTCHA solution provides an excellent balance between security and autonomy. It eliminates the privacy and dependency concerns of third-party services while still offering effective protection against automated threats.
For sites where security and privacy are paramount, this approach provides a powerful alternative to the dominant third-party CAPTCHA providers.