I would like to proxy XMPP with haproxy. But not for loadbalancing which would be easy with mode tcp and different backends. Decission for backend should be based on ‘to’ field in XMPP
<?xml version='1.0'?>
<stream:stream
from='ralf@im.example. com'
to='im.example.com'
version='1.0'
xml:lang='en'
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'>
This should go to backend with internal IP 10.0.1.11
and to=‘im.example-2. com’ should go to IP 10.0.1.12
I understand:
It is not http, so i have to use mode tcp and cannot do: use_backend server1 if { hdr(host) -i im.example-1. com }
It is not SSL with SNI, so i cannot do: use_backend server1 if { ssl_fc_sni im.example-1. com }
Wondering if that is even possible with haproxy? (perhaps ACL?!)
Update - Now i have tried with acl
With tcpflow i was able to see the packet on port 5222:
<?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' to='s-4.example.com'>
in my haproxy.cfg i have tested my backend server with
acl acl-s-4 always_true
use_backend s-4 if acl-s-4
default_backend s-1
and it is taking the backend s-4 which i want to use
Now i tried to analyze the payload on tcp-layer 6 with
# acl acl-s-4 req.payload(0,140) -m sub example
# acl acl-s-4 payload(0,140) -i example # config error
# acl acl-s-4 res.payload(0,140),hex -m sub 732d342e6578616d706c652e636f6d
# acl acl-s-4 req.payload(0,0),hex -m sub 786d6c #xml
# acl acl-s-4 req.payload(0,500) -m reg -i s-4.example.com
None of this works. Someone any idea?
SOLUTION
during test i tried disabling
tcp-request content accept if WAIT_END
but this is necessary.
acl acl-s-4 req.payload(0,140) -m sub example
is actually matching.
From doku:
wait_end
Waits for the end of the analysis period to return true. This may be used in
conjunction with content analysis to avoid returning a wrong verdict early.
It may also be used to delay some actions, such as a delayed reject for some
special addresses. Since it either stops the rules evaluation or immediately
returns true, it is recommended to use this acl as the last one in a rule.