I am using Nginx as a proxy to 4 apache instances. My problem is that SSL negotiation takes a lot of time (600 ms). See this as an example: http://www.webpagetest.org/result/101020_8JXS/1/details/

Here is my Nginx Conf:

user www-data;
worker_processes  4;

events {
    worker_connections 2048;
    use epoll;

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    access_log  /var/log/nginx/access.log;
    sendfile        on;
    keepalive_timeout  0;
    tcp_nodelay        on;
    gzip  on;
    gzip_proxied any;
    server_names_hash_bucket_size 128;


upstream abc {
     server weight=1;
     server weight=1;
     server weight=1;


server {
    listen   443;
    server_name  blah;

    keepalive_timeout 5;

    ssl  on;
    ssl_certificate  /blah.crt;
    ssl_certificate_key  /blah.key;
    ssl_session_cache  shared:SSL:10m;
    ssl_session_timeout  5m;
    ssl_protocols  SSLv2 SSLv3 TLSv1;
    ssl_ciphers RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
    ssl_prefer_server_ciphers   on;

    location / { proxy_pass http://abc;

                 proxy_set_header X-Real-IP  $remote_addr;
                 proxy_set_header Host $host;
                 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;



The machine is a VPS on Linode with 1 G of RAM. Can anyone please tell why SSL Hand shake is taking ages?


4 Answers 4


You need to disable "ephemeral diffie-hellman" ciphers. Browsers don't use them anyway, but openSSL will when used with tools like cURL or apachebench. So I am betting that webpagetest.org is using them.

See this thread for more details.

I personally use these settings in nginx to force the fastest-but-still-secure SSL ciphers based on the server's preferences, and not the browsers:

Update 2014-01-13: This advice has changed given recent attacks on RC4, browser updates which protect against BEAST, and the more widespread availability of TLS v1.2 in clients and servers.

Updated 2015-10-16: current nginx TLS settings 2015-10-16 as recommended by CloudFlare. Please check the preceeding link for updates, as TLSv1 will likely be removed from the recommended configuration at some point. The current settings disable SSLv3 and RC4 in accordance with current best practice and the latest PCI-DSS as of this date.

ssl_protocols               TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers                 EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers   on;

This supersedes the earlier advice in this answer, which has been removed to avoid confustion.

  • RC4 is insecure and not suitable fr use in TLS. "While the RC4 algorithm is known to have a variety of cryptographic weaknesses (see [26] for an excellent survey), it has not been previously explored how these weaknesses can be exploited in the context of TLS. Here we show that new and recently discovered biases in the RC4 keystream do create serious vulnerabilities in TLS when using RC4 as its encryption algorithm." See On the Security of RC4 in TLS and WPA.
    – user145545
    Jan 7, 2014 at 6:52
  • 2
    @noloader that Rc4 attack was announced years after my post; until very recently most cryptographers were recommending RC4 over AES because of the BEAST attack against TLS v1.0 and earlier. Now that most browsers protect against BEAST client-side, and there have been further attacks against RC4, the advice has changed. See this post for some good nginx settings for TLS v1.2: blog.cloudflare.com/staying-on-top-of-tls-attacks
    – rmalayter
    Jan 14, 2014 at 4:00
  • Oh my! Sorry about that. I did not think to check the dates. Sorry.
    – user145545
    Jan 14, 2014 at 4:04

You may not have a good entropy source. Does /dev/urandom exist? If not Nginx will block on reading /dev/random.

What is the size of your key? Longer is slower.

Try straceing the processes to see what they are doing.

  • +1 Seems like a good possibility as urandom is often missing on VPSs Oct 21, 2010 at 1:41

check that you're not waiting on DNS resolution somewhere.



ssl_protocols  SSLv2 SSLv3 TLSv1;


ssl_protocols  SSLv3 TLSv1 SSLv2;

Tries protocols in the order that they are listed.

  • Didn't really help. See webpagetest.org/result/101020_8KVR/1/details -- negotiation still take >50% of the whole time. Oct 20, 2010 at 15:26
  • 2
    SSLv2 should NOT be used, it is insecure. At the time of this comment all major browser should support TLSv1 so SSLv3 should no longer be needed as well. (ideally it should be TLSv1 TLSv1.1 TLSv1.2 until most of the browsers adopt 1.1).
    – KBeezie
    Dec 17, 2012 at 7:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .