skip to Main Content

I need to setup a load balancer for all our applications.

At the moment all our applications are clustered (2-node appservers, and 1 apache on each node as well) and we do not have a LB so we just point our DNS alias to the first webserver of each node, making the second node useless (have to manually do a DNS switch in case of a failure of node1, and we don’t have load balanced https queries).

Each application uses SSL with a specific domain & SSL certificate. we cannot accept to decrypt SSL and send unencrypted traffic to the backends as the LB might be located in another country etc. so we need to use passthrough.

Before anything, i just wanted to know if this is actually possible in HAProxy or not ?

I am talking about ~50 different applications. Our LB configuration would have to be HA so i guess we’ll use something like keepalived with a shared VIP for HAProxy itself.

The setup would look like this i suppose :

domain-a.com-'            '-> backend_dom_a -> 1.1.1.1 (app node1 dom a)
             |            |                    1.1.1.2 (app node2 dom a)
domain-b.com-'            '-> backend_dom_b -> 2.1.1.1 (app node1 dom b)
             |            |                    2.1.1.2 (app node2 dom b)
domain-c.com-'            '-> backend_dom_c -> 3.1.1.1 (app node1 dom c)
             |            |                    3.1.1.2 (app node2 dom c)
domain-N.com-'            '-> backend_dom_N -> 4.1.1.1 (app node1 dom N)
             |            |                    4.1.1.2 (app node2 dom N)
             +-> haproxy -+

Thanks for your support, best regards

3

Answers


  1. Chosen as BEST ANSWER

    FYI i'm using this configuration that works like a charm.

    i have replaced the values in the files to hide our domains & hostnames, and limited the numbers of urls/backends but we have about 50 running now with the load balancer forwarding requests to many apache servers (and each apache forwards requests to tomcat servers behind)

    feel free if you have any question

    we use balance source to ensure session stickyness

    #---------------------------------------------------------------------
    # Global settings
    #---------------------------------------------------------------------
    global
        daemon
        user                haproxy
        group               haproxy
        log                 /dev/log local6 notice
        log                 /dev/log local5 info
        maxconn             50000
        #chroot              /var/lib/haproxy
        pidfile             /var/run/haproxy.pid
    
    #---------------------------------------------------------------------
    # common defaults that all the 'listen' and 'backend' sections will
    # use if not designated in their block
    #---------------------------------------------------------------------
    defaults
        mode                 tcp
        option               tcplog
        log                  global
        option               dontlognull
        timeout connect      5000
        timeout client       50000
        timeout server       50000
    
    #---------------------------------------------------------------------
    # dedicated stats page
    #---------------------------------------------------------------------
    listen stats
        mode http
        bind :22222
        stats enable
        stats uri            /haproxy?stats
        stats realm          Haproxy Statistics
        stats auth           <mylogin>:<mypass>
        stats refresh        30s
    
    #---------------------------------------------------------------------
    # main frontend which proxys to the backends
    #---------------------------------------------------------------------
    frontend main_https_listen
        bind <ip address>:443
        mode                tcp
        option              tcplog
        log                 global
        tcp-request inspect-delay 5s
        tcp-request content accept if { req.ssl_hello_type 1 }
    
    #---------------------------------------------------------------------
    # Common HAProxy nodes configuration
    #---------------------------------------------------------------------
    
    # -------------------------------
    # ACLs
    # -------------------------------
    
    acl acl_SIT_AT35073      req.ssl_sni -i <app_url1>.my.domain.net  # SIT_AT35073 is just an internal code we use, but you can use any alias
    acl acl_SIT_AT34305      req.ssl_sni -i <app_url2>.my.domain.net
    acl acl_SIT_AT28548      req.ssl_sni -i <app_urlN>.my.domain.net
    
    # -------------------------------
    # Conditions
    # -------------------------------
    
    use_backend backend_SIT_AT35073 if acl_SIT_AT35073   # same here
    use_backend backend_SIT_AT34305 if acl_SIT_AT34305
    use_backend backend_SIT_AT28548 if acl_SIT_AT28548
    
    #---------------------------------------------------------------------
    # Backends
    #---------------------------------------------------------------------
    
    # APP 1
    backend backend_SIT_AT35073
        description APPNAME1
        mode tcp
        balance source
        option ssl-hello-chk
        server server_SIT_AT35073_1 <apache_server1>.my.domain.net:443 check
        server server_SIT_AT35073_2 <apache_server2>.my.domain.net:443 check
    
    # APP 2
    backend backend_SIT_AT34305
        description APPNAME2
        mode tcp
        balance source
        option ssl-hello-chk
        server server_SIT_AT34305_1 <apache_server3>.my.domain.net:443 check
        server server_SIT_AT34305_2 <apache_server4>.my.domain.net:443 check
    
    # APP N
    backend backend_SIT_AT28548
        description APPNAMEN
        mode tcp
        balance source
        option ssl-hello-chk
        server server_SIT_AT28548_1 <apache_server5>.my.domain.net:443 check
        server server_SIT_AT28548_2 <apache_server6>.my.domain.net:443 check
    

  2. I think you have two options:

    1. pass the traffic through to the backend by using the TCP mode in haproxy frontend and backend. This has the benefit that your backend SSL certificate is passed through. Though you lose the possibility to have one SSL termination in your site. So I present you

    2. Have one (usual) SSL certificate, acting as termination for your site and enable SSL between your backend and haproxy instance. This gives you the advantage that you still have only one entry point but different backends with unique certificates.

    The second option might look like this:

    frontend f_foo
        bind :443 ssl crt /path/to/bundle
        mode http
        log global
    
        use_backend b2_foo
    
    backend be_foo
        mode http
        timeout connect 5s
        server FOO address:port ssl check crt /path/to/client/bundle force-tlsv10 verify none
    

    The drawback is that you need a client certificate for each backend server but that should be easily automatable.

    Login or Signup to reply.
  3. AS more of an update answer for multi domain configs I use the below for routing different domains.
    in the frontend is where you bind the port and add the certs which multiple have to be on the same line afaik.

     frontend https_in
            bind *:443 ssl crt /link/to/cert+key-file.pem  crt /link/to/cert+key-file.pem
    

    The acl host is where you specify the domain name and which backend to use based on that domain name.

     acl host_example.com hdr(host) -i example.com
    
     use_backend BACKEND_NAME if host_example.com
    

    The backend where you specify the server that domain is running on.

     backend BACKEND_NAME
        mode http
        option httpclose
        option forwardfor
        cookie JSESSIONID prefix
        server server-name server-ip:443 check ssl verify none
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search