Ssl – Trying to setup transparent, load balancing, SSL reverse proxy. Is it possible

load balancingpoundssltransparent-proxy

I've done a few weeks worth of research on this topic for a project, and unfortunately I'm a simple code monkey, my knowledge of networking and SSL are limited. Pretty much every search I've done so far has brought me to serverfault, where I believe I've come to the conclusion that this might not be possible.

I basically need to develop a solution that will take incoming https and seamlessly pass it through to a cluster of cloned web servers. They are all serving the same exact content. The client SSL should not terminate at the load balancer. (https -> load balance -> cluster)

So technically my question is misleading, reverse proxy isn't really necessary but all my solutions so far have tended to be a proxy of some kind. I just basically need an transparent SSL load balancing solution.

Here is what I've tried so far.

  • Apache 2.4.x mod_proxy: Worked for https -> proxy -> http -> cluster. The full ssl solution failed.

  • Pound: Worked https -> proxy -> https very well, however the endpoint server receives the cert/info of the pound server. I need the clients cert, because the endpoint servers need to be able to do revocation. (Revocation cannot be handled by the proxy/MITM due to security concerns).

Other options I've research are: Squid, Charles, HAproxy, nginx, Charles, Pen and maybe some others I can't remember, my brain is basically mush at this point.

Pen might be the best solution as it's TCP traffic and shouldn't require decoding the ssl headers to handle the traffic, but I've had difficulty locating information on configuring it.

A hardware solution is not off the table. So I guess the questions are 1. Is this possible? 2. How would it be best done (cheap/open source preferable)? Thanks!

Best Answer

Just confirming, you don't want the SSL to terminate at the load balancer? So your backend server is going to be serving up https.

This is what I'd do. Under Ubuntu or debian.

Setup a couple of servers as your loadbalancer/proxy servers (for HA if you want it). They don't really need to be super high end but reasonable.

1) Install keepalived

sudo apt-get install keepalived

2) Setup /etc/keepalived/keepalived.conf like this:

vrrp_script chk_haproxy {
   script "killall -0 haproxy"   # verify the pid existance
   interval 2                    # check every 2 seconds
   weight 2                      # add 2 points of prio if OK
}

vrrp_instance VI_1 {
   interface eth0                # interface to monitor
   virtual_router_id 51          # Assign one ID for this route
   priority 100                  # 101 on master, 100 on backup
   nopreempt
   virtual_ipaddress {
       a.b.c.d             # the virtual IP
   }
   track_script {
     chk_haproxy
   }
}

2) Install haproxy

sudo apt-get install haproxy

3) Set the /etc/haproxy/haproxy.cfg with a config like this:

global
        log 127.0.0.1   local0
        log 127.0.0.1   local1 notice
        maxconn 4096
        chroot /var/lib/haproxy
        user haproxy
        group haproxy
        daemon

defaults
        log     global
        mode    tcp
        option  dontlognull
        option  redispatch
        retries 3
        maxconn 2000
        contimeout      5000
        clitimeout      50000
        srvtimeout      50000


listen myproxy a.b.c.d:443
        mode tcp
        option tcplog
        balance leastconn

        server http1 x.x.x.a:443
        server http2 x.x.x.b:443
        server http3 x.x.x.c:443
        server http4 x.x.x.d:443

What this does is use TCP mode (no https). If you want https you could install stud or similar in front of this (on the same server).

a.b.c.d is your vrrp virtual ip address. x.x.x.a, x.x.x.b, x.x.x.c, x.x.x.d are the IP's of the load balanced servers. These can safely be behind a firewall if you prefer.

If you went with the HA option make sure you set this option in /etc/sysctl.conf:

net.ipv4.ip_nonlocal_bind = 1

If one of the haproxy servers goes down or the haproxy service is stopped, the other server will step in. Some users may get broken connections when that happens, but a refresh should fix that.

This works for me, although my setup is slightly different. I terminate SSL at the load balancer and then serve unencrypted traffic from the backend.