We use HAProxy in HTTP mode as a front-end to our middleware. The middleware expects only HTTP packets. Anything that is not an HTTP packet can be discarded by HAProxy. We do get quite a number of packets every hour from malicious sites trying to crawl for various services that they can hack. Sometimes such malicious packets are not even HTTP at all, but rather some binary data. When the incoming packet is not valid HTTP, then we want HAProxy to simply silently close the connection.
The question is how can I create an ACL that detects if a packet is HTTP or not? Is it just as simple as:
frontend middleware
mode http
acl is_http req.proto -m end_str “HTTP/1.”
http-request silent-drop if !is_http
Since the frontend has mode=http, what does HAProxy do when it receives a packet of garbled binary data that can’t be interpreted as HTTP? Does it still process the ACL and other rules?
When you are using HTTP mode, haproxy will only forward valid HTTP requests to your backends. You don’t have to do anything other than putting “mode http” in your relevant config sections.
Ok that’s definitely not happening now. The backend server is periodically receiving a new connection followed by a block of a couple hundred bytes of binary data. The backend server is not exposed to the internet except through HAProxy, and is listening on a non-standard port number (14443), so it’s hard to imagine where these packets might be coming from if not from HAProxy.
[EDIT: In fact, I just realized that if we stop HAProxy, then the binary data also stops. So it must be that these packets are coming from HAProxy]
It seems like it is related to HTTP/2. The middleware is not properly replying with a failure message when the “PRI * HTTP/2.0” message is received to begin HTTP 2 communications. Basically the “PRI” message is just ignored, and therefore the client continues on trying to send HTTP 2.0 messages, which are binary (not human readable).
So now the question is, How can I tell HAProxy to reject all HTTP 2 messages? The middleware only supports HTTP 1.x and I want HAProxy to only pass HTTP 1.x compliant messages.
You will have to share your configuration so that we can make suggestions.
By default a plaintext HTTP backend will never see HTTP 2 messages.