reCAPTCHA v2
In v2 mode, the load balancer displays a web page that shows the challenge. The user will not be able to proceed until they've solved it. This works well for stopping users that you have already flagged as suspicious, but you will typically only display it for specific users.
Installing
Run the following command to install the reCAPTCHA module.
$ # On Debian/Ubuntu
$ sudo apt-get install hapee-2.5r1-lb-recaptcha
$ # On CentOS/RedHat/Oracle/Photon OS
$ sudo yum install hapee-2.5r1-lb-recaptcha
$ # On SUSE
$ sudo zypper install hapee-2.5r1-lb-recaptcha
$ # On FreeBSD
$ sudo pkg install hapee-2.5r1-lb-recaptcha
Go to https://www.google.com/recaptcha/admin and register your website for a Google reCAPTCHA. Choose reCAPTCHA v2. This will give you a site key and a secret key. If testing on
localhost
or127.0.0.1
, enter them as domains in the Google reCAPTCHA settings.-
Edit the file:
/etc/hapee-2.5/hapee-lb-recaptcha.cfg
. Find the line that reads:recaptcha_private XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Replace the
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
value with the secret key you got when you registered for a reCAPTCHA. Search the file for
data-sitekey
and replaceXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
with the corresponding site key you got when you registered for a reCAPTCHA.-
Put a new random string in for
hmac_secret
to prevent someone else with this module from generating cookies for your site to get around the reCAPTCHA. This field is the HMAC secret used when encrypting the cookie that indicates whether the user has already solved the CAPTCHA. It can be any set of random numbers and letters. You can use the following command to create an alphanumeric string 42 characters long:$ tr -cd [:alnum:] </dev/urandom | head -c 42
-
Optional: Change the values for
ip_in_cookie
andvalid_duration
:The
ip_in_cookie
setting will put the client's IP address into the HMAC so that cookie sharing is more difficult.The
valid_duration
setting sets how long in seconds the cookie will be accepted. During testing you may want to set this to a small value such as15
(seconds).
-
Add the following line to the global section of your HAProxy Enterprise configuration:
global lua-load
/opt/hapee-2.5/modules/hapee-lb-recaptcha.luac -
Add a
frontend
section and abackend
section to your HAProxy Enterprise configuration to communicate with Google and verify reCAPTCHAs:frontend google_recaptcha_fe mode http bind 127.0.0.1:3859 option httpclose timeout client 5s default_backend google_recaptcha_be backend google_recaptcha_be mode http timeout server 5s server google www.google.com:443 ssl verify none maxconn 10 check inter 60s fall 2 rise 2
The LUA module connects locally to this frontend, and the backend forwards the challenge to Google reCAPTCHA.
-
Add the following
tcp-request inspect-delay
andhttp-request use-service
lines inside anyfrontend
orlisten
section from which you want to send reCAPTCHA challenges:Add the
tcp-request
andhttp-request
directives.frontend www bind :80 tcp-request inspect-delay 1s http-request use-service lua.verify_recaptcha if { path
/.well-known/haproxy/captcha_callback} http-request use-service lua.request_recaptcha unless { lua.verify_solved_captcha "ok" } default_backend webapp_be backend webapp_be server app1 192.168.56.33:8080 server app2 192.168.56.34:8080 -
Optional: Add other conditions to the
if
clauses to enable Google reCAPTCHA only for some requests. In the example below, we configure rate limiting so that the challenge displays only for clients that make more than 100 requests within 10 seconds:# share requests rate data with load balancer peers peers mycluster peer
loadbalancer1192.168.1.10:10000 peerloadbalancer2192.168.1.11:10000 table request_rates type ip size 1m expire 10s store http_req_rate(10s) frontend fe_main bind *:80 # track this client's request rate based on their IP address http-request track-sc0 src table mycluster/request_rates # reCAPTCHA logic with rate limit tcp-request inspect-delay 1s http-request use-service lua.verify_recaptcha if { path/.well-known/haproxy/captcha_callback} http-request use-service lua.request_recaptcha if { sc_http_req_rate(0,mycluster/request_rates) gt 100 } !{ lua.verify_solved_captcha "ok" } default_backend webapp_be backend webapp_be server app1 192.168.56.33:8080 server app2 192.168.56.34:8080 Reload HAProxy Enterprise.
-
Make an HTTP request and see if it works. A client will need to solve the challenge before they can continue past the reCAPTCHA web page.
Google reCAPTCHA v2 checkbox challenge:
This HTML page is defined in the reCAPTCHA configuration file
/etc/hapee-2.5/hapee-lb-recaptcha.cfg
.
Troubleshooting
If your request does not work:
On the page in question press
Ctrl-Shift-i
, which brings up the developer console on both Chrome and Firefox. Look at the Javascript "Console" and check for errors. They will usually be highlighted in red. If you see a message about an "unfulfilled promise" in the reCAPTCHA javascript files, check that the hostname setting is correct in your Google admin console for this reCAPTCHA site key. For example, did you set it toexample.com
but are visitinglocalhost/login.html
? The actual error is generated in the heavily obfuscated code that is reCAPTCHA so debugging this error other than checking settings like that is largely impossible.Check the HAProxy Enterprise request logs. If you see LUA errors appear above the request lines (notably above a request for
verify_recaptcha
that returned a 500 status code), they should indicate what is going wrong.-
Enable debug-level logging in HAProxy. The reCAPTCHA module will log the JSON that it gets from Google's verification service on this level. This approach may not be helpful for general production traffic, but for individual requests which are failing, examining the logs can help reveal the cause. For example, if the private site key is wrong, the JSON will say that.
To enable debug-level logging, update the
log
line in theglobal
section.Add
debug
to the end of thelog
line.log 127.0.0.1 local0 debug
If these approaches do not solve the problem, contact Support.
Next up
reCAPTCHA v3