HAProxy community

Cloudflare 520 errors when using "use_backend"

I’m sure this is a simple error on my part, but can’t for the life of me resolve it!

My intention is to use Coudflare to hide my IP, and haproxy so I can use multiple sub-domains going to different hosts/ports on single host. At present, Cloudflare is just being used as a DNS provider, in an attempt to rule out their proxy as the cause of my issues.

When I use the default_backend option in frontend, everything works fine, however when I use “use_backend” option in frontend, I get a 520 from Cloudflare.

Here an example of my config;

root@haproxy-01:/etc/ssl# cat /etc/haproxy/haproxy.cfg
global
        log /dev/log    local0
        log /dev/log    local1 info
        chroot /var/lib/haproxy
        stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
        stats timeout 30s
        user haproxy
        group haproxy
        daemon
        # Default SSL material locations
        ca-base /etc/ssl/certs
        crt-base /etc/ssl/private

        # Default ciphers to use on SSL-enabled listening sockets.
        # For more information, see ciphers(1SSL). This list is from:
        #  https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
        # An alternative list with additional directives can be obtained from
        #  https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=haproxy
        ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
        ssl-default-bind-options no-sslv3

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        timeout connect 5000
        timeout client  50000
        timeout server  50000
        errorfile 400 /etc/haproxy/errors/400.http
        errorfile 403 /etc/haproxy/errors/403.http
        errorfile 408 /etc/haproxy/errors/408.http
        errorfile 500 /etc/haproxy/errors/500.http
        errorfile 502 /etc/haproxy/errors/502.http
        errorfile 503 /etc/haproxy/errors/503.http
        errorfile 504 /etc/haproxy/errors/504.http

frontend http-in
   # redirect all http to https
   bind *:80
   mode http
   redirect scheme https code 301

frontend https_in
    bind *:443 ssl crt /etc/ssl/website/website.pem
    option tcplog
    mode tcp

    acl hassio_host hdr(host) -i hassio.website.com
    use_backend backend_hassio if hassio_host
    #default_backend backend_hassio

backend backend_hassio
    mode tcp
    server hassio.website.com localIP:8123 check

The intention with the above config will be to use multiple sub-domains for multiple different services, with different acl & backend services as needed (for portainer etc)

Apologies if I haven’t included enough info here, let me know and I’ll provide what additional info I can.

Thanks

At a first glance the configuration file seems OK; except why are you using the frontend and backend in tcp mode as opposed to HTTP?

Apparently according to CloudFlare’s documentation (https://support.cloudflare.com/hc/en-us/articles/115003011431#520error) the error is related to invalid HTTP response from the server… And because you are using TCP mode, please double-check that the backend server is “speaking” correctly HTTP.

GAH! I new it would be that simple! I’d come across that article but was lost after staring at this for so long.

I’m assuming I left them over from the tutorials I was attempting to follow (and being somewhat new to HAProxy & overtired) </silly excuses>

Thank you very much for your help. Changing the modes to HTTP rather than TCP did the trick.

However, this just “sweeps the issue under the rug”, because now perhaps HAProxy is the one that has to handle invalid replies from the backend server.

(I say this, because for well-behaved HTTP servers, especially since you have only one backend, this mode tcp shouldn’t have broken CloudFlare…)

Therefore I would double-check if the backend server does actually work properly. (If you find it doesn’t I would use option force-close to make sure that those connections aren’t re-used.)