Setting up SSL Offloading (Termination) on an F5 Big-IP Load Balancer
Article by Nate HaugMay 9, 2012 - 7:00pm
Hardware-based SSL decryption allows web servers (Apache, nginx, Varnish) to focus on serving content.

In a quick, largely unscientific test, here are two Apache Bench results against a stock Apache install, one with SSL and one without. Just serving up a static text file:
ab -c 100 -n 100 http://localhost/EXAMPLE.txt
Requests per second: 611.21 [#/sec] (mean)
Time per request: 163.609 [ms] (mean)
Time per request: 1.636 [ms] (mean, across all concurrent requests)
Transfer rate: 816.54 [Kbytes/sec] received
ab -c 100 -n 100 https://localhost/EXAMPLE.txt
Requests per second: 48.52 [#/sec] (mean)
Time per request: 2060.857 [ms] (mean)
Time per request: 20.609 [ms] (mean, across all concurrent requests)
Transfer rate: 64.82 [Kbytes/sec] received
Yikes, HTTPS is 12 times slower than HTTP! Not to mention more processor intensive. Comparing against nginx or Varnish, the slowness ratio increases as they serve HTTP traffic even faster. Now there are certainly ways to speed up SSL (using faster cyphers for example), but the fact remains that SSL is expensive. By using hardware level decryption at the load balancer, the web server software (or reverse-proxy software like nginx or Varnish) can focus on serving pages.
Getting Started
For those not familiar with a Big-IP load balancer's administration, most of the configuration is done via a web interface, accessible via the device's IP address.The navigation for the site is located in the left-hand column.
Adding SSL Certificates
The first thing you need to do to get SSL termination set up is to install the SSL certificate onto the machine. This is done by navigating to Local Traffic -> SSL Certificates -> Import. You must import the .key and the .crt files obtained from your Certificate Authority (i.e. Verisign, Comodo, etc.) separately with the same "Name" property. So give your certificate and key a name, usually matching the domain name, such as "example-com" or "example-com-wildcard". Upload the .key file as a Key, and the .crt file as a Certficate; both using the same value in the Name field.After finishing, the list of SSL Certificates should inlude your certificate and key in the list as a single entry, meaning they're associated with each other.
Set up SSL Profile
Now that our SSL certificate is uploaded into the load balancer, we need to create an SSL profile that utilizes the certificate. Visit Local Traffic -> Profiles -> SSL -> Client. The term "Client" means traffic between the outside world and the load balancer (conversely "Server" means traffic between your internal servers and the load balancer). Click the "Create..." button to add a new profile.Give your profile a name (it can be the same as the certificate if you like), such as "example-com-wildcard". Leave the Parent profile as the default "clientssl". Check the box for custom options, then select your Certificate and Key that should be used to communicate with your end-user browsers. Leave all the other defaults.
Set up the Virtual Server
F5 Load Balancers use a concept of a "Virtual Server" to accept connections at a certain IP address and hostname. I won't go into the details here and assume you already have a Virtual Server for HTTP.If you already have a Virtual Server for HTTPS, edit it. If not, create a new virtual server with these settings:
Name: [same as your HTTP virual server, with "https" added somewhere]
Destination Type: Host
Destination Address: [same as your HTTP virtual server]
Service Port: 443, HTTPS
HTTP Profile: http
SSL Profile (Client): example-com-wildcard
SSL Profile (Server): None
SNAT Pool: [same as your HTTP virtual server]
The most important part of this configuration is selecting an SSL Profile for the "Client", but not for the "Server". This is all that is needed to actually "enable" SSL termination. The F5 is actually decrypting all incoming traffic no matter what, but by selecting "None" for the Server-side profile, the traffic simply is not re-encrypted before communicating with the back end servers.
Don't skip this: Just because you have SSL termination enabled on this virtual server, you still need to point it at the correct location. If you're editing an existing virtual machine, it is probably currently pointing at a pool of servers on port 443. In the case of Apache, it will throw an error page, refusing to serve insecure HTTP pages over a secure port (443). To fix this (or set it up if this is a new virtual machine), click the "Resources" tab on the new virtual machine.
Under the "Load Balancing" section, select the same "Default Pool" option as you are using for your HTTP virtual machine. This makes it so that both HTTP and traffic that was formerly HTTPS come into the same port on your backend servers.
Identifying HTTPS traffic in your application
The only problem with the above approach to SSL termination is that all traffic getting to your web application is now over HTTP. This is a problem because often times security checks on the page will enforce an HTTPS connection and possibly attempt to redirect the user to HTTPS. In order for the application to avoid redirects like this, we need to inform the web server that the contents of the request were previously encrypted over HTTPS, even though they aren't any more.To do this, it's recommended to set up an iRule that sets a special header. Visit Local Traffic -> iRules -> iRule List. Click the "Create..." button.
In the new iRule, give it a name such as "https-offloaded-header". In the rule contents, use the following code:
##
# Notify the backend servers that this traffic was SSL offloaded by the F5.
##
when HTTP_REQUEST {
HTTP::header insert "X-Forwarded-Proto" "https";
}
Save the iRule, then head back over to your virtual server under Local Traffic -> Virtual Servers -> Virtual Server List and click on your HTTPS virtual server. Under the "Resources" tab, click "Manage..." in the iRules section.
Move your new iRule from the "Available" list into the "Enabled" list. Moving it to the top of the rule list is also a good idea if you're doing any kind of HTTP/HTTPS redirects on your load balancer as setting headers after doing a redirect can cause pages to be undeliverable. Click "Finished" when done.
Now we're setting a special HTTP header on requests that have been SSL offloaded onto the F5. In your application, check this header in your code. For a PHP application, you may want to use this header to set the $_SERVER['HTTPS'] super-global. And even more specifically for Drupal (since that's what we do here at Lullabot), you would probably include code like this in your settings.php file.
<?phpif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
$_SERVER['HTTPS'] = 'On';
}?>
Since most PHP applications (including Drupal) check if they're on an HTTPS page by checking this variable, no further changes are necessary to the application.
If you're looking for more information on setting up an F5, Googling usually will not turn up too much because F5 has put the bulk of their documentation on a private site, for which you must first register (for free thankfully), at https://devcentral.f5.com/wiki.
Updated 5/10/2012: Switched iRule to using "X-Forwarded-Proto".
Comments
F5
BIG IP VE user Guide
Thanks for the user guide. i wonder if you have kind of link or document for such guide for someone like me who just started to learn F5. I have done my Sale and Technical Sales Accreditation on BIG IP F5 and installed BIG IP VE. But i am kind of lost where to start from. I appreciate your assistance,
Cheers
Mas
RE: User Guide
iRules rock
Pound
Pound == OpenSSL
I'm trying to measure the actual difference between the physical hardware and OpenSSL (through nginx) but good benchmarks are proving tricky. I'll link to the results in the article if I can produce something reputable.
X-Forwarded-Proto
http://drupal.org/node/313145
http://en.wikipedia.org/wiki/List_of_HTTP_header_fields
Good stuff, thanks.
Updated
Awesome
A few comments:
1) I realize you already changed the X-Forwarded-For header, but I wanted to point out a few things.
a) Instead of using the iRule, you can use the HTTP Profile. Profiles are way to apply settings that have been "productized". They are faster, and less error prone (through forgetting the iRule or having a typo, etc). So I would recommend going to Local Traffic-->Profiles--> Then creating a new HTTP profile based on HTTP and ENABLE "Insert X-Forwarded-For". Whether you use this header or the X-Forwarded-Proto doesn't really matter internally, you're just trying to preserve the IP address in a NAT/SNAT environment.
b) Now that you have the HTTP profile created, apply it to your virtual server and remove the iRule. You will increase your performance!
c) Another thing the HTTP profile does is a feature called "Redirect Rewrite". In many cases when you're doing this type of load balancing, redirect responses may have the SERVERs hostname instead of the Virtual IP Addresses' hostname, Redirect Rewrite fixes this for you, and all you have to do is Enable it using option like "All" or "Matching"
In any case, I highly recommend the HTTP profile, just don't forget to apply it and remove the iRule!
2) Another optimization besides SSL offload that the BIG-IP can provide is TCP optimization. We see tremendous gains just by turning on these optimizations if you have users coming from various locations on the Internet. The BIG-IP can independently manage window size scaling for each connection, speeding traffic and offloading processing for your servers. Within the Local Traffic--->Virtual Servers, simply change your "Protocol Profile (Client)" to tcp-wan-optimized and your Protocol Profile (Server) to tcp-lan-optimized . You can also clone these profiles and make other changes if you feel comfortable doing that, but for most uses, simply applying the WAN optimized settings will lead some good results for your visitors.
3) Yet another optimization is compression. Depending on the model of BIG-IP you are on, it may have hardware compression. In either case, you can still offload the gzip compression for your servers to the BIG-IP. This is yet another profile that you can just apply.
4) And finally, there are two other optimizations that can lead some amazing results for your servers:
a) First, OneConnect. This profile multiplexes connections back to the servers. BIG-IP is able to simultaneously put multiple HTTP requests through each TCP connection, significantly reducing the CPU on the OS. This works great for most applications, but there are some systems where it is problematic. However, I'm pretty sure Drupal will have no issues with this given the nature of the HTTP traffic there.
b) Second, RamCache or in V11, Web Acceleration. By applying the RamCache (V9 and V10) or Web Acceleration profiles (V11) you can serve up cacheable content right from BIG-IPs memory. Another great way to speed up performance. BIG-IP does have a WebAccelerator module which is a more intelligent and full featured object cache, but the default RamCache or Web Acceleration profiles come with the base license.
I hope this is helpful to all. Any questions, let me know!
Did it go any faster?
Did you experiment with purchasing a (much cheaper) encryption offload pci card for your Apache server?
On !== on
Doesn't play nicely with secure_pages module, which checks for 'on'.
More benchmarks, please
Even better, it would be interesting to see a test with a tool that handled HTTP 1.1 and keep-alive, which is often used in conjunction with SSL in order to improve performance and decrease latency. ab speaks HTTP 1.0 and some servers don't honor its request for keep-alive.
Agreed
So as of right now I haven't found a good way to compare OpenSSL (software) versus the F5 (hardware). I also agree that using persistent connections would speed up the process quite a bit, but that may end up muddying the results more than helping, since then other factors start coming more into play as the bottleneck and you may end up accidentally measuring something else like network latency or web server performance.