SSL acceleration is a technique that off-loads the processor intensive public key encryption algorithms used in SSL transactions to a hardware accelerator. These solutions often involve a considerable up front investment as the specialized equipment is rather costly. This article though looks at using off the shelf server hardware and open source software to build a cost effective SSL accelerator.
Ultimately there are two ways to do SSL Acceleration or SSL off-load. It can be done on the server side by installing an SSL Accelerator card, which has special custom processors designed to perform the public key encryption algorithms in hardware rather than software. A quick search on Google will provide a number of guides on how to use those cards with projects such as Apache. This solution has the server performing the SSL transaction but the SSL transaction is processed on the card rather than using server resources. In fact, adding one of the higher end versions of these cards to the solution in this article would further increase its performance. However, it may simply be cheaper to add more horsepower to the server itself than to invest in expensive SSL off-load cards.
The other way to do SSL acceleration is to install a device in front of the web servers, this is typically an appliance or switch with comparable hardware to the SSL accelerator card. These devices often provide other features such as load balancing. They typically have higher transactions per second and thruputcapacity than a single server with an SSL accelerator card. The SSL accelerator in front of the servers takes the incoming SSL transactions, decrypts them, and then forwards them on to the servers as HTTP. This is still secure as the connection between the SSL accelerator and the servers is a private local network, there is no unsecured transaction going over the public Internet. This is the type of solution provided in this article, but instead of using an expensive SSL accelerator, it leverages the power of open source and off the shelf server processors.
SSL Acceleration reduces the amount of server processing considerably. The transaction coming into the web servers is simply a HTTP request, so there is no SSL encryption or decryption that needs to be done. The cost of managing SSL certificates and the number of SSL certificates is drastically reduced, now those SSL certificates reside on one or two SSL Accelerators, instead of many web servers. Improved security, as the SSL Accelerator is the only device that needs to be accessible to the Internet, the back-end web servers can reside on private IP subnets. The solution hides the back-end topology and the only IPs that need to access the web server ports are the SSL Accelerators.
The Open Source SSL Accelerator requires a dedicated server running Linux. Which Linux distribution does not matter, Ubuntu Server works just as well as CentOS or Fedora Core. A multi-core or multi-processor system is highly recommended, with an emphasis on processing power and to a lesser degree RAM. This would be a good opportunity to leverage new hardware options such as Solid State Drives for added performance. The only software requirement is Nginx (Engine-X) which is an Open Source web server project. Nginx is designed to handle a large number of transactions per second, and has very well designed I/O subsystem code, which is what gives it a serious advantage over other options such as Lighttpd and Apache. The solution can be extended by combining a balancer such as HAproxy and a cache solution such as Varnish. These could be placed on the Accelerator in the path between the Nginx and the back-end web servers. Adding such options to the mix requires some trickery on the back-end to preserve the original client IP request.
In this solution, Nginx will handle the inbound SSL connections just like a regular HTTPS web server, but it will pass the request off to another web server rather than handling it by itself.
Nginx can be built from source or installed using your favorite package management tool. Building it from source has been discussed in previous articles, and is well documented on the Nginx site itself. So to avoid duplication, this article will dive straight into the configuration. Within the http {} block, enable gzip compression.
With gzip compression enabled on the SSL Accelerator, there is no need to enable gzip compression on the web servers behind it. Thus further reducing the load on the servers. The upstream {} command is used to define which back-end set of servers to send requests to. For this example, the configuration is for ssl.b.o3magazine.com with three servers defined by private IPs. The SSL Accelerator in the test example had two NICs, one facing the public side and one facing the back-end server network, with an IP of 192.168.77.1/24.
Finally the magic is configured within the server block.
So this looks like a regular configuration entry for an SSL virtual server. It will listen on 10.77.4.43 port 443, the site is called ssl.o3magazine.com, has the usual ssl certificate and key configuration. The accelerator part is handled by the configuration within the location block. The X-Real-IP header is set to pass back the remote client IP, add the X-Forwarded-For, and set the HTTP host header. The X-FORWARDED_PROTO is there for web applications such as those running under Ruby on Rails. This command tells the web application to map its URLs to the HTTPS protocol even though the web application is receiving the request via HTTP. This is important because without it, the web application will generate HTTP rather than HTTPS type URLs, which will break links for the user.
The proxy_pass command passes the request via HTTP to the upstream block configured as ssl.b.o3magazine.com. This is what generates the HTTP request rather than a HTTPS request to the back-end servers. That is it, entries can be stacked in the server_name group, so if the same IP is used to bind to multiple sites and they use the same certificate. The block can be duplicated with the appropriate certificate lines changed and server_name lines changed to handle sites bound to the same servers but using different certificates.
The worker processes and worker connections determine the number of simultaneous connections Nginx can handle. Typically the number of worker processes should match the number of CPU cores on the system, then tweak the worker connections to meet the project requirements. It may also make sense to run multiple instances on Nginx, with the worker processes defined as 2, and the connections tweaked as needed. Then utilize the CPU affinity capabilities of the Linux distribution in use to assign each Nginx instance (the worker processes) to a particular CPU core. This is particular useful if one particular site is heavily hit, that site could be handled by a dedicated Nginx instance and assigned to a dedicated CPU core.
One thing that this solution can do that many commercial SSL accelerators cannot, is the ability to store files locally. In the example above, the conditional if statement only passes requests back to the web servers if the file is not found locally first. The ! -f in the if statement means if not found. To have files served by the SSL accelerator instead of back passing the request to the server, simply store the file in the document root within the appropriate path. In the example above, placing images in /sslacc/www/o3magazine/htdocs/images/ would have the SSL accelerator using local storage to serve up https://ssl.o3magazine.com/images/. On the flip side, if nothing is stored locally, simply remove the if statement completely to avoid the extra processing. On a high traffic site, it might make sense to store small heavily used files such as CSS, Javascript and Images on the SSL accelerator instead. This avoids passing traffic back to the web servers.
The conditional statements within Nginx are very powerful, its possible to perform a wide variety of Layer 7 packet processing on the HTTP or HTTPS request itself. This feature enables the solution to be deployed in non-traditional ways. A customer web site may consist of PHP and Rails components, along with static content. It might make sense to deploy the static content directly on the SSL Accelerator, then define two upstream blocks one for PHP and one for Rails. For example, php.ssl.o3magazine.com and rails.ssl.o3magazine.com. These would point to different IPs in the same format as the upstream block above. The conditional statement would simply redirect requests that matched the PHP application (perhaps by the .php and .inc extensions), using $request_uri and regular regex matching to http://php.ssl.o3magazine.com. Place that conditional above the existing one. Anything not PHP and not stored locally will get passed on to the rails back end. This makes the configuration simple and able to handle the URL based routing used in Rails. Further conditionals could be used to map the URLs used by the Rails App only to further secure the solution but depending on the application that maybe tedious.
There are many different reasons for limiting the types of ciphers that can be used. Perhaps a commerce solution where only high-end ciphers are desired. In that case, the follow lines added to any server block will restrict the ciphers and SSL version that can be used. The SSL Accelerator makes implementing site-wide policies like this very easy to do.
This solution can also be used to off-load gzip compression to the SSL Accelerator. Perhaps a HTTP device does not support gzip compression or the system administrator wants to reduce the processing overhead on the entire web server farm. To achieve gzip compression offloading, simply place the SSL accelerator in front of the web servers, configure the web servers in an upstream block, and add regular HTTP server entries to the nginx configuration. This would be the same process as above, just listening on port 80, without the ssl commands and without the proxy_set_header options. HTTP requests would be passed through the SSL Accelerator to the web servers, the return traffic being compressed on its way back to the client.
The lab test system was a dual processor AMD Opteron 2380 2.5GHz Quad-Core system, for a total of 8 processor cores, L2 cache was 4 x 512k, and L3 cache was 6MB. Standard Intel Server Gigabit NICs, and 32GB of RAM. On a Tyan Transport platform, the system cost was under $5k. The system had no problems handling over 26,590 TPS, the test lab ran out of capacity to generate additional transactions. Compare that to the F5 Networks Big-IP 6900 which handles a maximum of 25,000 TPS but carries a starting price tag of $55,000. That starting price only includes 500 SSL TPS, so expect to pay a lot more to get up to the 25,000 level. It should be possible using this solution and even better hardware (8xxx series Opterons and more RAM), and perhaps some 10GbE adapters from Intel to come close, if not beat the performance of the BIG-IP 8900. Which has a maximum rate of 58,000 TPS. While obviously not as polished as the F5 solution, this Open Source solution does get the job done for a fraction of the price.
Nginx once again has shown that it is a versatile open source project. For the cost of a server and a few hours work, any system administrator can increase the capacity of their existing server farm by building an Open Source SSL Accelerator. Reducing the complexity of certificate management, reducing the number of certificates needed and reducing the overall load per request on the existing server farm, this solution offers a cost-effective way of breathing new life into an existing server farm.