Apache SSL Offloading

Application servers such as Jetty abd Tomcat are widely used in today’s world. If SSL termination is done on the application server, such as Jetty, it may impact the performance of Jetty. You can also terminate SSL on the load balancer, but load balancers often have a limit on the amount of SSL traffic they can handle. For instance a load balancer might be able to handle 10Gbps, so if your traffic is more than that, it will cause a problem. Another way of reducing load on Jetty is to offload SSL termination to Apache. Apache will then pass the traffic to Jetty in an unencrypted connection. Let’s say you have a load balancer that is in front of your Jetty servers, you can install Apache on each of the servers running Jetty. Each Jetty server will also run Apache. So the connection would look something like this:

Clients--(SSL)-->Load Balancer--(SSL)-->Apache--(Unencrypted)-->Jetty

Apache will be listening on port 443, and Jetty on port 8080. Apache will then forward the traffic to port 8080 on the same host. In the logs of Apache you will see the source IP address of the clients. Configure the load balancer to use DSR, or direct server return. Apache acts as a proxy server. You can find a configuration for Apache here https://github.com/syedaali/configs/blob/master/apache-proxy.conf. I will explain some of the configuration settings below.

#Load the SSL module that is needed to terminate SSL on Apache
LoadModule ssl_module modules/mod_ssl.so

#We don't want to pass Apache server status to the Jetty server
ProxyPass /server-status !

#Apache is listening on port 443
Listen 443

SSLSessionCache         shmcb:/var/cache/mod_ssl/scache(512000)
SSLSessionCacheTimeout  300
SSLMutex default
SSLRandomSeed startup file:/dev/urandom  256
SSLRandomSeed connect builtin
SSLCryptoDevice builtin

#Location for SSL error logs
ErrorLog logs/ssl_error_log

#Location for SSL traffic logs
TransferLog logs/ssl_access_log

#Log level, this can be emrg, alert, crti, error, warn, notice, info, or debug
#See https://httpd.apache.org/docs/2.2/mod/core.html#loglevel for details
LogLevel warn

#Dont' use SSLv2, instead use SSLv3 and TLSv1
SSLProtocol all -SSLv2

#When choosing a cipher during an SSLv3 ot TLSv1 handshake, normally the client's preference is used. We want Apache to use the server's preference.
SSLHonorCipherOrder On

#SSL Tuning. We want to optimize our SSL chipher by removing some and adding other
SSLCipherSuite ALL:!ADH:!EXP:!LOW:!RC2:!3DES:!SEED:!RC4:+HIGH:+MEDIUM

#SSL certificate file location
#you can generate a self signed certificate file using this command
#$sudo openssl req -x509 -newkey rsa:2048 -keyout apache.key -out apache.crt -days 999 -nodes
#the ca.crt file is a certificate chain file
SSLCertificateFile /etc/httpd/certs/apache.crt

#SSL private key file location
SSLCertificateKeyFile /etc/httpd/certs/apache.key

#This directive sets the all-in-one file where you can assemble the Certificates of Certification Authorities (CA) whose clients you deal with.
SSLCACertificateFile /etc/httpd/certs/ca.crt

#The * is for listening on all IP interfaces.
<VirtualHost *:443>
ServerName <fill-in-server-name>
SSLEngine on

#Allow %2F in URLs. See https://httpd.apache.org/docs/2.2/mod/core.html#allowencodedslashes
AllowEncodedSlashes On
</VirtualHost>

#Disable forward proxy. See https://httpd.apache.org/docs/2.2/mod/mod_proxy.html#proxyrequests
ProxyRequests Off

#Any incoming URL is forwarded to localhost port 8080 where Jetty is listening. The noncanon allows raw passing of URLs without any canonicalise of URLS.
# See https://httpd.apache.org/docs/2.2/mod/mod_proxy.html#proxypassmatch.
ProxyPassMatch  (.*) http://localhost:8080 nocanon

#"When enabled, this option will pass the Host: line from the incoming request to the proxied host, instead of the hostname specified in the ProxyPass line." See #https://httpd.apache.org/docs/2.2/mod/mod_proxy.html#proxypreservehost
ProxyPreserveHost On

#Display proxy status in server status Apache page See https://httpd.apache.org/docs/2.2/mod/mod_proxy.html#proxystatus.
ProxyStatus On

#Keep alive proxy connections
SetEnv proxy-nokeepalive 0

#Set the X-Forwarded-Proto to be https for Jetty to understand. See https://httpd.apache.org/docs/2.2/mod/mod_headers.html#requestheader.
RequestHeader set X-Forwarded-Proto "https" env=HTTPS