Haproxy dummy backends: don’t disable them in 2.2

Tags: django, nelenschuurmans

We’ve got quite a number of different websites on different servers. We use a central haproxy server (well, two, for fail-over) to distribute the various domains to the (django) websites.

There are two special categories I wanted to handle:

  • Internal-only sites that are only available on our interal IP range. When accessed from elsewhere, you should get a “403” error with an error page saying it is an internal-only site plus a hint to use VPN.

  • Domains that aren’t found. A 404 with a “we don’t know about this one” error message.

With haproxy 2.2, which is the version we’re using now on ubuntu 22.04, there’s support for this with http return status 404 or something like that. Until two months ago, we were on an older ubuntu with haproxy 1.8. There the trick to accomplish it was to use dummy backends:

backend no-domain-found
    # No servers here, it is used for showing the "404" page.  Well, haproxy
    # knows no 404 itself, so we let the empty backend generate a 503, but we
    # sneakily return a 404 error page (including 404 header). See
    # https://serverfault.com/q/496460/52614
    errorfile 503 /some/where/503-as-404.http
    disabled  # Don't show it in the interface.

backend deny-external
    # External requests to internal resources get denied. No servers here, it
    # is used for showing the "403 forbidden" page.
    http-request deny
    disabled  # Don't show it in the interface.

In the list of regular backends, there would be a default_backend no-domain-found to shuffle all unknown domains to no-domain-found. That had no available backends, so a 503 unavailable is generated. The errorfile directive defines a custom error page including the proper 404 response:

HTTP/1.0 404 Not Found
Cache-Control: no-cache
Connection: close
Content-Type: text/html

<h1>404: website not found</h1>
  The website you've requested is not known here.

But…. since updating to version 2.2, this trick didn’t work anymore. I’d only get the basic “503 backend unavaible” error. I couldn’t find any documentation as to the cause.

In the end the problem was the ‘disabled’ keyword that I used. With it, the dummy backend isn’t shown in haproxy’s status page. But somewhere between 1.8 and 2.2, haproxy treated those disabled backends as completely disabled, not even looking at the errorfile statement or the http-request deny line.

After removing the disabled line, the old dummy backend trick worked again.

Anyway, perhaps this blog post helps someone :-)

vanrees.org logo

About me

My name is Reinout van Rees and I work a lot with Python (programming language) and Django (website framework). I live in The Netherlands and I'm happily married to Annie van Rees-Kooiman.

Weblog feeds

Most of my website content is in my weblog. You can keep up to date by subscribing to the automatic feeds (for instance with Google reader):