Optimizing HTTPS Performance: Solving 50x Slowdown in Apache/Ubuntu LAMP Stack


2 views

When analyzing the curl output from both local workstation and server, the most striking observation is the 29-second TLS handshake completion time. This is highly abnormal - typical SSL handshakes should complete within 300-500ms. The key indicators from the debug output:

* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
[...]
* SSL connection using DHE-RSA-AES256-SHA

The current Apache SSL configuration shows mixed certificate sources:

SSLCertificateFile /etc/apache2/ssl/dreamhost/dh.crt
SSLCertificateKeyFile /etc/apache2/ssl/dreamhost/dh.key 
SSLCACertificateFile /etc/apache2/ssl/dreamhost/dh.cer

This suggests legacy Dreamhost certificates might not be properly chained. Let's verify the certificate chain:

openssl s_client -connect getsimpleapps.com:443 -showcerts

Add these directives to your VirtualHost 443 configuration:

SSLProtocol all -SSLv2 -SSLv3
SSLHonorCipherOrder on
SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS"
SSLCompression off
SSLSessionCache shmcb:/var/run/ssl_scache(512000)
SSLSessionCacheTimeout 300

The server is using DHE-RSA-AES256-SHA which has significant CPU overhead. Consider these alternatives:

# Modern cipher suite preference:
SSL_EECDH_CHACHA20_POLY1305=ECDHE-ECDSA-CHACHA20-POLY1305
SSL_EECDH_AES256_GCM_SHA384=ECDHE-ECDSA-AES256-GCM-SHA384
SSL_EECDH_AES128_GCM_SHA256=ECDHE-ECDSA-AES128-GCM-SHA256

To isolate the performance bottleneck:

# Test SSL handshake separately
openssl s_time -connect getsimpleapps.com:443 -www / -new

# Check TCP connection latency
tcptraceroute getsimpleapps.com 443

# Verify session resumption
openssl s_client -connect getsimpleapps.com:443 -reconnect

For older Ubuntu versions, consider this optimized setup:


    SSLPassPhraseDialog exec:/usr/share/apache2/ask-for-passphrase
    SSLSessionCache         shmcb:${APACHE_RUN_DIR}/ssl_scache(512000)
    SSLSessionCacheTimeout  300
    SSLRandomSeed startup file:/dev/urandom 2048
    SSLRandomSeed connect builtin
    Mutex default

Remember to restart Apache after changes:

service apache2 restart

When migrating from DreamHost to Linode with Ubuntu 12.04 LAMP stack, I encountered severe HTTPS performance degradation - a 29-second load time for JavaScript files versus 380ms with HTTP. The curl traces revealed the SSL handshake wasn't the primary culprit, but rather server configuration issues.

Key observations from the curl output:

* SSL connection using DHE-RSA-AES256-SHA
* Server certificate chain verification
* Apache/2.2.22 with OpenSSL 0.9.8r

Here's the optimized Apache SSL configuration that resolved our issues:

<VirtualHost *:443>
    SSLEngine On
    SSLProtocol all -SSLv2 -SSLv3
    SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
    SSLHonorCipherOrder on
    
    # Certificate configuration
    SSLCertificateFile /etc/ssl/certs/getsimpleapps.com.crt
    SSLCertificateKeyFile /etc/ssl/private/getsimpleapps.com.key
    SSLCertificateChainFile /etc/ssl/certs/comodo_bundle.crt
    
    # Performance optimizations
    SSLCompression off
    SSLUseStapling on
    SSLStaplingCache "shmcb:logs/stapling-cache(150000)"
    
    # KeepAlive settings
    KeepAlive On
    MaxKeepAliveRequests 100
    KeepAliveTimeout 5
</VirtualHost>

Additional server optimizations that made significant impact:

# In /etc/apache2/mods-available/ssl.conf
SSLSessionCache shmcb:/tmp/ssl_scache(512000)
SSLSessionCacheTimeout 300

# In /etc/sysctl.conf
net.ipv4.tcp_fastopen = 3
net.core.somaxconn = 1024
net.ipv4.tcp_tw_reuse = 1

Post-optimization curl test shows dramatic improvement:

$ time curl -Iv https://getsimpleapps.com/
...
real    0m0.412s
user    0m0.012s
sys     0m0.008s

Implement these checks to maintain performance:

# Test SSL handshake speed
openssl s_time -connect getsimpleapps.com:443 -new

# Verify certificate chain
openssl s_client -connect getsimpleapps.com:443 -showcerts

# Check preferred cipher suite
nmap --script ssl-enum-ciphers -p 443 getsimpleapps.com