Dear list!
We use HAProxy in TCP Mode for non-HTTP protocols.
The request of one particular protocol looks like this:
- length of message (binary value, 4 bytes long)
- binary part (40-200 bytes)
- XML part
Goal: We want to use a particular backend when the XML part of the request
contains the string "<tag>".
We used this ACL:
acl tag_found req.payload(0,0) -m sub <tag>
The problem:
The substring matching stops on a Null byte (\0) in a binary fetch. We
always have this case (the request normally starts with Null bytes). Therefore,
the match never succeeds. As there might be null bytes in the binary part too,
we
cannot just start the payload fetch after byte 4.
==========================
frontend fe_test
bind *:3000
tcp-request inspect-delay 5s
acl content_present req_len gt 0
acl tag_found req.payload(0,0) -m sub <tag>
tcp-request content accept if content_present
tcp-request content reject
# depending on if the payload contains the string "<tag>", we use different
backends
# right now, the two backends are exactly the same.
use_backend be_tag if tag_found
default_backend be_default
backend be_tag
server srv_1:4000
backend be_default
server srv_1:4000
Test cases:
(tested on versions 2.0.10, 1.5.18)
echo -e '<tag>' | nc 127.0.0.1 3000 # will use backend be_tag
echo -e '\0<tag>' | nc 127.0.0.1 3000 # will use backend be_default, but
should use be_tag
==========================
Workaround:
=>convert payload into hexified string, parse against hex:
acl tag_found req.payload(0,0),hex -m sub 3C7461673E # this is <tag> in
hexadecimal
Dear list members, these are the questions I am twisting my mind with. Do you
have a good take one these?
- Is there another (better) way to do a substring match on a payload which
contains Null bytes?
- Would another, new match method make sense here (something like sub_bin ? )
- Do we run into a problem with the hex conversion because the size of the
sample has double the size than the original (maybe bigger than bufsize?)
Best regards
Mathias