Convert CloudFlare Rules to HAPROXY

Hi,
I am trying to convert the following rule to HAPROXY rule but it is not working for some reason. maybe somebody can help :star_struck:

CF Rule

(http.request.method eq "GET" and http.request.uri.query eq "" and http.request.version eq "HTTP/1.1" and any(len(http.request.headers.values[*])[*] gt 60) )

HAPROXY:

 acl test1 hdr_cnt() gt 60
 http-request deny  if METH_GET test1

also tried with same method above and it didn’t work

req.fhdr_cnt

acl test1 hdr_cnt() gt 60 is testing if there are more than 60 headers. I think any(len(http.request.headers.values[*])[*] gt 60) is testing if any header has a value greater than 60 bytes (I’m not familiar with cloudflare though).

I think you’d either need to use a lua fetch to define this behaviour or use a regex like:

acl test1 req.hdrs -m reg ':[^\r]{60,}'
1 Like

the regex probably needs to be hardened somewhat, but basically the idea is to match any header value that is more than 60 characters.

1 Like

Thank you very much for your response. I tried your solution but still denying all the requests in that rule, but when using CF rule with deny it doesn’t deny all requests.
Had to edit rule in which it worked 50% but still can’t understand how CF is matching it.

acl test1 req.hdrs() -m reg ‘:[^\r]{138,}’
http-request deny if METH_GET HTTP_1.1 test1

Tried 60 but it is blocking total connection. CF seems to be matching GET Requests + HTTP Version with Header request size, meanwhile if you try rule on CF it doesn’t deny all requests.

assuming you are using PCRE2 regex, try this:

  acl test1 req.hdrs -m reg '(*CRLF)(?m)^[^:]+:.{61,}$'

breakdown:
(*CRLF) treat CRLF as the line ending
(?m) enable multi-line mode
^[^:]+: match the beginning of the line, followed by one or more non-: characters, followed by a colon
.{61,} match 61 or more characters
$ match the end of the line (CRLF due to the CRLF line ending mode)

1 Like

:hugs:

Rules are forbidding total access with value 61.

160 is working fine.

  acl test1 req.hdrs -m reg '(*CRLF)(?m)^[^:]+:.{61,}$'
   http-request deny  if METH_GET HTTP_1.1 test1

On CF rule with “Deny Option” is not blocking access with value above 60

still matching is not accurate somehow, hope we can make it work same as CF.

could it be the http.request.uri.query eq "" part? I don’t see an equivalent of that in your haproxy config.

1 Like

yep it seems to be, I am trying to convert this rule so I can add it to the above and test but still couldn’t find it in haproxy documentation :slight_smile:

acl has-query query,length gt 0

#...
http-request deny if METH_GET HTTP_1.1 !has-query test1

I tried following rules but unfortunately still the same problem

acl has-query query,length gt 0
acl test1 req.hdrs -m reg '(*CRLF)(?m)^[^:]+:.{138,}$'
http-request deny  if METH_GET HTTP_1.1 !has-query test1