HAProxy in `mode tcp` accepts HTTP with HTTPS backend

I’m seeing a pretty strange behavior with one HAProxy setup using mode tcp trying to do pass-through to 2 HTTPS enabled servers.

Relevant configuration:

frontend front-ssl
  default_backend back-ssl
  mode tcp

backend back-ssl
  server back-ssl-001 weight 100 check check-ssl maxconn 128 ssl verify none
  server back-ssl-002 weight 100 check check-ssl maxconn 128 ssl verify none
  log global
  balance leastconn
  mode tcp
  option httpchk GET /check
  http-check expect status 200

As far as I can tell from the configuration & documentation this should work by just passing through the TCP packets. However, what I see is that the bind address accepts plain text HTTP requests which it encapsulates in HTTPS requests to the backend:

telnet 443
Connected to
Escape character is '^]'.
GET / HTTP/1.1
Connection: close
Accept: */*
Host: myservice.mydomain

HTTP/1.1 404 Not Found
Date: Tue, 03 Mar 2020 14:28:06 GMT
Connection: close

HAproxy is 1.7.12-1ppa1~xenial

You configured haproxy to do that, because of the ssl keyword on the server line, which means: encrypt whatever is in the buffer.

So plaintext traffic will be encrypted by haproxy and passed as HTTPS to the backend and encrypted traffic from port 443 of the frontend will be encrypted another time (which doesn’t make any sense and will break this setup).

Remove the ssl keyword from the server lines.