uberrebu
uberrebu

Reputation: 4329

how to loadbalance tcp on haproxy

I have a tcp service running on port 8080 on 3 servers behind haproxy i will like to loadbalance the tcp traffic between these servers via haproxy

server1 192.168.10.1 8080
server2 192.168.10.2 8080
server3 192.168.10.3 8080

lets say haproxy server ip is 192.168.10.10

1.

what haproxy configuration can i use to achieve this? what will be the endpoint to access the loadbalanced tcp traffic after the config is made active?

2.

one other thing is, is it possible to proxy that endpoint to like a url without a port? similar to http based routing...so can i then put that tcp endpoint and have a way to route an http endpoint via hostname to the loadbalanced tcp service?

so lets say i wan to access the service at http://tcp-app.example.com and then should be routed to the loadbalanced tcp service

Upvotes: 0

Views: 6714

Answers (1)

Aleksandar
Aleksandar

Reputation: 2642

To Answer 1 can you use this as start point

listen tcp-in
  bind :8080

  mode tcp
  log stdout format raw daemon
  option tcplog

  timeout client   5s
  timeout connect 30s
  timeout server  30s

  server server1 192.168.10.1:8080
  server server2 192.168.10.2:8080
  server server3 192.168.10.3:8080

You can the reach the loadbalancer via 192.168.10.10:8080.
For better understanding of haproxy this blog post a good start point IMHO
https://www.haproxy.com/blog/the-four-essential-sections-of-an-haproxy-configuration/

For question 2 should you switch to Server Name Indication (SNI) because TCP have not the concept of "Hostnames".
I have described how SNI routing works in HAProxy in this blog post https://www.me2digital.com/blog/2019/05/haproxy-sni-routing/

Here a example haproxy config for SNI Routing between TCP and HTTP protocol. It's a little bit complex because you will need to check the TCP routing before the HTTP routing.

#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    log stdout format raw daemon debug

    maxconn     5000

    tune.ssl.default-dh-param 3072

    # https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=haproxy-1.8.0&openssl=1.1.0i&hsts=yes&profile=modern
    # set default parameters to the intermediate configuration
    ssl-default-bind-ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
    ssl-default-bind-options ssl-min-ver TLSv1.1 no-tls-tickets

    ssl-default-server-ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
    ssl-default-server-options ssl-min-ver TLSv1.1 no-tls-tickets
    
    # https://www.haproxy.com/blog/dynamic-configuration-haproxy-runtime-api/
    stats socket [email protected]:9999 level admin
    stats socket /var/run/haproxy.sock mode 666 level admin
    stats timeout 2m

#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
    mode                    tcp
    log                     global
    option                  dontlognull
    #option                  logasap
    option                  srvtcpka
    option                  log-separate-errors
    retries                 3
    timeout http-request    10s
    timeout queue           2m
    timeout connect         10s
    timeout client          5m
    timeout server          5m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 750

#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------

##
## Frontend for HTTP
##
frontend http-in
    bind :::80 v4v6
    mode http
    option httplog

    tcp-request inspect-delay 5s
    tcp-request content accept if HTTP

    # redirect http to https .
    http-request redirect scheme https unless { ssl_fc }

##
## Frontend for HTTPS
##
frontend public_ssl

    bind :::443 v4v6 

    option tcplog

    tcp-request inspect-delay 5s
    tcp-request content capture req.ssl_sni len 25
    tcp-request content accept if { req.ssl_hello_type 1 }
    
    # https://www.haproxy.com/blog/introduction-to-haproxy-maps/
    use_backend %[req.ssl_sni,lower,map(tcp-domain2backend-map.txt)]

    default_backend be_sni

##########################################################################
# TLS SNI
#
# When using SNI we can terminate encryption with dedicated certificates.
##########################################################################
backend be_sni
  server fe_sni 127.0.0.1:10444 weight 10 send-proxy-v2-ssl-cn

backend be_sni_xmpp
  server li_tcp-in 127.0.0.1:8080 weight 10 send-proxy-v2-ssl-cn

# handle https incoming
frontend https-in

    # terminate ssl 
    bind 127.0.0.1:10444 accept-proxy ssl strict-sni alpn h2,http/1.1 crt haproxy-certs

    mode http
    option forwardfor
    option httplog
    option http-ignore-probes

    # Strip off Proxy headers to prevent HTTpoxy (https://httpoxy.org/)
    http-request del-header Proxy

    http-request set-header Host %[req.hdr(host),lower]
    http-request set-header X-Forwarded-Proto https
    http-request set-header X-Forwarded-Host %[req.hdr(host),lower]
    http-request set-header X-Forwarded-Port %[dst_port]
    http-request set-header X-Forwarded-Proto-Version h2 if { ssl_fc_alpn -i h2 }
    http-request add-header Forwarded for=\"[%[src]]\";host=%[req.hdr(host),lower];proto=%[req.hdr(X-Forwarded-Proto)];proto-version=%[req.hdr(X-Forwarded-Proto-Version)]

    # Add hsts https://www.haproxy.com/blog/haproxy-and-http-strict-transport-security-hsts-header-in-http-redirects/
    # http-response set-header Strict-Transport-Security "max-age=16000000; includeSubDomains; preload;"

    # https://www.haproxy.com/blog/introduction-to-haproxy-maps/
    use_backend %[req.hdr(host),lower,map(http-domain2backend-map.txt)]

#---------------------------------------------------------------------
#  backends
#---------------------------------------------------------------------
## backend for cloud.DOMAIN
backend nextcloud-backend
    mode http
    option httpchk GET / HTTP/1.1\r\nHost:\ BACKEND_VHOST
    server short-cloud 127.0.0.1:81 check 


## backend for dashboard.DOMAIN
backend dashboard-backend
    mode http
    server short-cloud 127.0.0.1:82 check

## backend for upload.DOMAIN
backend httpupload-backend
    log global
    mode http
    server short-cloud 127.0.0.1:8443 check

listen tcp-in
  bind :8080 accept-proxy ssl strict-sni crt haproxy-certs

  mode tcp
  log stdout format raw daemon
  option tcplog

  timeout client   5s
  timeout connect 30s
  timeout server  30s

  server server1 192.168.10.1:8080
  server server2 192.168.10.2:8080
  server server3 192.168.10.3:8080

File tcp-domain2backend-map.txt

tcp-service.mydomain.im be_sni_xmpp

File http-domain2backend-map.txt

# http backends
nextcloud.MyDomain.com nextcloud-backend
dashboard.MyDomain.com dashboard-backend 
jabupload.MyDomain.com httpupload-backend

Upvotes: 1

Related Questions