Synopsis
Some time ago, we wrote an article which explained how to load-balance SSL services, maintaining affinity using the SSLID.
The main limitation of this kind of architecture is that you must dedicate a public IP address and port per service.
If you’re hosting web or mail services, you could run out of public IP address quickly.
TLS protocol has been extended in 2003, RFC 3546, by an extension called SNI: Server Name Indication, which allows a client to announce in clear the server name it is contacting.
NOTE: two RFC have obsoleted the one above, the latest one is RFC 6066
The Aloha Load-balancer can use this information to choose a backend or a server.
This allows people to share a single VIP for several services.
Of course, we can use SNI switching with SSLID affinity to build a smart and reliable SSL load-balanced platform.
NOTE: Server Name information is sent with each SSL Handshake, whether you’re establishing a new session or you’re resuming an old one.
SNI is independent from the protocol used at layer 7. So basically, it will work with IMAP, HTTP, SMTP, POP, etc…
Limitation
Bear in mind, that in 2012, not all clients are compatible with SNI.
Concerning web browsers, a few of used in 2012 them are still not compatible with this TLS protocol extension.
We strongly recommend you to read the Wikipedia Server Name Indication page which lists all the limitation of this extension.
- Only HAProxy nightly snapshots from 8th of April are compatible (with no bug knows) with it.
- Concerning Aloha, it will be available by Aloha Load-balancer firmware 5.0.2.
Diagram
The picture below shows a platform with a single VIP which host services for 2 applications:

We can use SNI information to choose a backend, then, inside a backend, we can use SSLID affinity.
Configuration
Choose a backend using SNI TLS extension
The configuration below matches names provided by the SNI extention and choose a farm based on it.
In the farm, it provides SSLID affinity.
If no SNI extention is sent, then we redirect the user to a server farm which can be used to tell the user to upgrade its software.
# Adjust the timeout to your needs
defaults
timeout client 30s
timeout server 30s
timeout connect 5s
# Single VIP with sni content switching
frontend ft_ssl_vip
bind 10.0.0.10:443
mode tcp
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
acl application_1 req_ssl_sni -i application1.domain.com
acl application_2 req_ssl_sni -i application2.domain.com
use_backend bk_ssl_application_1 if application_1
use_backend bk_ssl_application_2 if application_2
default_backend bk_ssl_default
# Application 1 farm description
backend bk_ssl_application_1
mode tcp
balance roundrobin
# maximum SSL session ID length is 32 bytes.
stick-table type binary len 32 size 30k expire 30m
acl clienthello req_ssl_hello_type 1
acl serverhello rep_ssl_hello_type 2
# use tcp content accepts to detects ssl client and server hello.
tcp-request inspect-delay 5s
tcp-request content accept if clienthello
# no timeout on response inspect delay by default.
tcp-response content accept if serverhello
stick on payload_lv(43,1) if clienthello
# Learn on response if server hello.
stick store-response payload_lv(43,1) if serverhello
option ssl-hello-chk
server server1 192.168.1.1:443 check
server server2 192.168.1.2:443 check
# Application 2 farm description
backend bk_ssl_application_2
mode tcp
balance roundrobin
# maximum SSL session ID length is 32 bytes.
stick-table type binary len 32 size 30k expire 30m
acl clienthello req_ssl_hello_type 1
acl serverhello rep_ssl_hello_type 2
# use tcp content accepts to detects ssl client and server hello.
tcp-request inspect-delay 5s
tcp-request content accept if clienthello
# no timeout on response inspect delay by default.
tcp-response content accept if serverhello
stick on payload_lv(43,1) if clienthello
# Learn on response if server hello.
stick store-response payload_lv(43,1) if serverhello
option ssl-hello-chk
server server1 192.168.2.1:443 check
server server2 192.168.2.2:443 check
# Sorry backend which should invite the user to update its client
backend bk_ssl_default
mode tcp
balance roundrobin
# maximum SSL session ID length is 32 bytes.
stick-table type binary len 32 size 30k expire 30m
acl clienthello req_ssl_hello_type 1
acl serverhello rep_ssl_hello_type 2
# use tcp content accepts to detects ssl client and server hello.
tcp-request inspect-delay 5s
tcp-request content accept if clienthello
# no timeout on response inspect delay by default.
tcp-response content accept if serverhello
stick on payload_lv(43,1) if clienthello
# Learn on response if server hello.
stick store-response payload_lv(43,1) if serverhello
option ssl-hello-chk
server server1 10.0.0.11:443 check
server server2 10.0.0.12:443 check
Choose a server using SNI: aka SSL routing
The configuration below matches names provided by the SNI extention and choose a server based on it.
If no SNI is provided or we can’t find the expected name, then the traffic is forwarded to server3 which can be used to tell the user to upgrade its software.
# Adjust the timeout to your needs
defaults
timeout client 30s
timeout server 30s
timeout connect 5s
# Single VIP
frontend ft_ssl_vip
bind 10.0.0.10:443
mode tcp
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
default_backend bk_ssl_default
# Using SNI to take routing decision
backend bk_ssl_default
mode tcp
acl application_1 req_ssl_sni -i application1.domain.com
acl application_2 req_ssl_sni -i application2.domain.com
use-server server1 if application_1
use-server server2 if application_2
use-server server3 if !application_1 !application_2
option ssl-hello-chk
server server1 10.0.0.11:443 check
server server2 10.0.0.12:443 check
server server3 10.0.0.13:443 check
Related Links
- HOWTO SSL native in HAProxy
- Maintain affinity based on SSL session ID
- Send users to the same backend for both HTTP and HTTPS
- Scaling out SSL
- Benchmarking SSL performance
- Transport Layer Security (TLS) Extensions (RFC 3546)
- Transport Layer Security (TLS) Extensions: Extension Definitions (RFC 6066)
- Wikipedia Server Name Indication

Pingback: Benchmarking SSL performance | Exceliance – Aloha Load Balancer
Pingback: Preserve source IP address despite reverse proxies | Exceliance – Aloha Load Balancer
Pingback: HOWTO SSL native in HAProxy | Exceliance – Aloha Load Balancer
Pingback: Scaling out SSL | Exceliance – Aloha Load Balancer
Pingback: How to get SSL with HAProxy getting rid of stunnel, stud, nginx or pound | Exceliance – Aloha Load Balancer
Pingback: SSL Client certificate management at application level | Exceliance – Aloha Load Balancer
Hi,
Thanks for this, very usefull
Is it possible to specifiy multiple ssl certs ? For example one for application 1 and another for application 2 ?
In pound in can set à list of certificates to use, how can i do the same ?
Thanks