Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I am faced with the following problem: Servers get saturated since current load balancing strategy is based on client IP. Some corporate clients access our servers from behind large proxies so all clients appear with same IP to our load balancer. I think we are using some hardware load balancing device (can investigate further if necessary). We need to maintain session affinity (site is constructed in ASP), so all requests with same IP get routed to the same node.

Since all the communication goes over the HTTPS, no request data (like session Id) is available to balancer as a client discriminator. Is there a way to use some other data besides the IP to distinguish between clients and route the clients even when coming from same IP to different nodes?

Note: I need to maintain the traffic between the balancer and nodes safe (encrypted).

share|improve this question
add comment

5 Answers

up vote 5 down vote accepted

The easiest way of doing this if you currently have a load balancer in place is to decrypt the data on the load balancer and look at a cookie. At that point you can either send the request to the backend server un-ecnrypted or you can re-encrypt it and send it on.

Most setups I know of consider the network connection between the load balancer and the backend server secure and don't bother to re-encrypt the traffic for multiple reasons. One reason is that hardware based load balancers also act as SSL accelerators and this is another reason the HTTPS traffic ends at their door. Another is that it allows the traffic to be inspected for attacks.

share|improve this answer
    
Pardon my noobness, but is the capacity to encrypt/decrypt data a standard feature of hardware load balancers? –  Dan Feb 8 '10 at 16:41
    
A lot of them seem to have it out of the box now but your mileage may vary. Some may do the encode/decode in software on their base models with an upgrade path to a dedicated hardware module or completely different appliance. You would need to ask the vendor to know for sure. –  carson Feb 9 '10 at 0:04
add comment

There are three common ways of doing this:

First you can change your load balancer forwarding logic (either keep track of the number of connections to each host & try to distribute load evenly, do a simple round-robin, etc.). Either of the options I mention eliminate the deterministic nature of your current setup (clients from IP X no longer go to server Y), which also eliminates (or reduces) your problem.

Note that you want to implement "sticky sessions" or their equivalent so that once a client is randomly assigned to a back-end server they keep going to the same one as long as their connection is active.

Second you can decrypt the information, read some server identifier from it and then pass it off (either re-encrypting it or passing it in the clear over your back-end network). Note that this isn't really practical at large scale unless your load-balancing hardware is SSL-accelerated (e.g. a Cisco content switch with SSL modules) since the device you're funneling all the traffic through has to do ALL the SSL work.

Per note in the original question, #2 is probably not an option since the traffic needs to be kept encrypted end-to-end (sounds like decrypting on the load balancer would be a policy violation?)

The third method I don't recommend: Setting up split-horizon or round-robin DNS for your target server (either directly pointing to a back-end server or pointing to separate IPs on the load balancer which are statically tied to a back-end, have different balancing pools, etc.) -- This is pretty common in smaller operations as "ghetto load balancing", but in your situation (where you already have a load-balancing equipment) it adds needless complexity compared to the other solutions.

share|improve this answer
    
"(clients from IP X always go to server Y), which also eliminates (or reduces) your problem.". But this is exactly my problem. We already have load-balancing schema in place, but IP based distribution is not efficient in our case. Also, I already mentioned I need to maintain session affinity... –  Dan Feb 2 '10 at 15:30
    
Clarified in the above - A load or round-robin distribution means clients from IP X go to {some server in the pool, but not always the same server}. –  voretaq7 Feb 2 '10 at 15:50
    
Re: Session affinity, see the note in grey above. Most load balancers have something called "sticky sessions" which keeps track of which outside IP is going to which back-end server for as long as the connection is active, and for "a while" (usually an hour) after it goes idle, which maintains session affinity reasonably well. –  voretaq7 Feb 2 '10 at 15:52
    
sorry, but still don't understand what you mean by: "A load or round-robin distribution means clients from IP X go to {some server in the pool, but not always the same server}.". If I use only IP to identify clients and I need to maintain session affinity, then all my clients coming from certain IP will end up on the same node... I already have round-robin in place, but affinity is based on IP... –  Dan Feb 2 '10 at 17:10
    
I think openbsd.org/faq/pf/pools.html#incoming explains it better than I am - The salient bit is in the bottom paragraph in that section :) –  voretaq7 Feb 2 '10 at 17:26
add comment

The only way to do what you want is to terminate SSL on or before your load balancer and then load-balance based on session ID. Open-source solutions for doing both steps in one piece of software would be nginx, haproxy, varnish, any many others.

Some hardware load balancers used to balance based upon SSL session ID, but browsers now re-negotiate SSL sessions, so this no longer works reliably.

share|improve this answer
add comment

Depends on the exact type of box but if you can change the load-balancing discriminator to take into account (src ip + src port) instead of just (src ip) you'd be done. I know Citrix Netscaler supports this, probably other devices as well.

share|improve this answer
add comment

I don't know if your problem is fixed. Any way, a good solution is to use session affinity based on SSL ID.

In this case, your device remembers the SSL ID in the memory table to route user requests with the same SSL ID to the same server node.

So you'll have to investigate further if your load-balancing device in compliant.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.