Arbitrary TCP (and HTTP) over port


#1

Hi all,

Just a question I have been struggling with for a while; how can I get arbitrary TCP protocols (have been testing with SSH) over HAProxy, while also servicing HTTP requests on the same port. I am using the following configuration on a test machine:

frontend one
        bind :443 #ssl crt cert.pem (the implementation will include SSL wrapping, but removed for debugging this issue)
        mode tcp
        option tcplog
        tcp-request inspect-delay 5s
        tcp-request content accept #if HTTP
        use_backend http_backend if HTTP
        use_backend tcp_backend if !HTTP

backend tcp_backend
        mode tcp
        server tcp_server localhost:22 #SSH for debugging

backend http_backend
        mode http
        server http_server localhost:8080

If I run with the above configuration, then all traffic is diverted to tcp_backend (rather than just non-HTTP), and if I add the ‘if HTTP’ (commented out currently), then HTTP works okay, but any SSH connections are returned a 400 error code (Bad Request) from HAProxy because it is presumably expecting HTTP.

I can get this set up to work (with SSH) if I include an ACL looking for the magic bytes at the beginning of the request (as described in http://blog.chmd.fr/ssh-over-ssl-episode-4-a-haproxy-based-configuration.html), however this requires me to change the config every time I want to change what is proxying through tcp_backend, and seems impossible for instances where the protocol will not have a magic string.

I have tried a whole bunch of combinations for the config file, but none have worked as I would like.

Any advice on if the requirement is possible would be appreciated, or suggestions on how it might be implemented.

Regards,
Pete

Edit: Tested on HAProxy 1.6.3.


#2

Here is how I do this:

listen 443
 mode tcp
 bind :443 name https4
 acl is_ssl req_ssl_ver 2:3.3
 tcp-request inspect-delay 1s
 tcp-request content accept if is_ssl
 use-server ft_global if is_ssl
 use-server ssh if !is_ssl
 server ft_global 127.0.0.1:443 send-proxy
 server ssh 127.0.0.1:22

And ft_global is my regular HAProxy frontend for HTTP(s) traffic.


#3

Thanks Baptiste.

Is there a way to do this when all protocols are SSL wrapped, and all the SSL is terminated at the HAProxy instance? Ultimately the aim is to have HTTP go to one server, and everything else go to another, but all incoming protocols are SSL wrapped until they hit HAProxy the listener/frontend.


#4

Yes, you may want to use this type of ACLs:

use-server ft_global if HTTP
use-server ssh if ! HTTP