I'm currently re-configuring HAProxy using 1.5dev-17. What I'd like to do is return a 404 error when there is no backend to use for a particular request.
Our current configuration uses the default_backend to route to our django app servers, but when there are a whole lot of probing requests (like a pen-test) that match none of the other configured backends, our django servers grind to a halt as they try to serve these invalid requests, eventually returning a 404.
I'd like to serve the 404 from HAProxy rather than delegating to the django backends. I'm currently achieving this with a hack:
frontend www
...
default_backend nomatch
backend nomatch
errorfile 503 /var/www/http/404.http
And within the 404.http file I set the 404 status code in the headers. This works, but feels very wrong. Is there a better way of achieving this with HAProxy? Or should I use a regular backend and just let that handle responding with a 404?
If you would be okay with any of the following response codes: 200, 400, 403, 405, 408, 429, 500, 502, 503, or 504.
Then you could do something like this:
http-request
: http://cbonte.github.io/haproxy-dconv/1.7/configuration.html#4-http-requesterrorfile
: http://cbonte.github.io/haproxy-dconv/1.7/configuration.html#errorfileAfter wanting something similar this is the same thing I came up with. It felt wrong but it works very well in practice and is much cleaner than trying to blacklist particular urls. Just be sure to leave a comment so no one comes across it thinking it's incorrect.
This is not what the OP asked for, but in case you the reader stumbled across here while using TCP mode (like I did), the corresponding directive you want to use is
tcp-request content
. So you would have:Of course in TCP mode there's no HTTP response code. You can also use
silent-drop
instead ofreject
if you so wish.Note that you CANNOT use
tcp-request connection
because it cannot be used in abackend
section. If you try to put it in afrontend
section instead,haproxy
will warn you:... which means it's overriding all your
use_backend
anddefault_backend
directives.While you technically CAN use
tcp-response content
, there's no good reason to do so in this use case (as compared to usingtcp-request content
.