SSL Handshake negotiation on Nginx terribly slow
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 1.1.1.1 weight=1;
server 1.1.1.2 weight=1;
server 1.1.1.3 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?
Solution 1:
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.
Solution 2:
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 strace
ing the processes to see what they are doing.