SOLVED: IE, SSL and Nginx problems
GoDaddy who is the certificate authority insists there is no problem with the certificate itself and that it must be something with our server config. The certificate is set up to accept SSL 2.0, SSL 3.0 and TLS 1.0 as well as every conceivable encryption algorithm. Again this is a problem with IE only. Any advice, suggestions or insight would be very helpful!
Thanks
Edit: Some additional information from the access.log. This is what we see in the log when the problem occurs:
207.152.167.191 - - [10/Feb/2012:11:00:27 -0500] "-" 400 0 "-" "-"
207.152.167.191 - - [10/Feb/2012:11:00:27 -0500] "-" 400 0 "-" "-"
and nothing in the error.log
14 Replies
user www-data www-data;
worker_processes 4;
pid /var/run/nginx.pid;
events {
worker_connections 256;
multi_accept on;
}
http {
#
Basic Settings
#
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 75 20;
typeshashmax_size 2048;
clientbodybuffer_size 1k;
clientheaderbuffer_size 1k;
clientmaxbody_size 10m;
largeclientheader_buffers 3 3k;
connectionpoolsize 256;
requestpoolsize 4k;
clientbodytimeout 60;
clientheadertimeout 60;
send_timeout 60;
server_tokens off;
servernameshashbucketsize 128;
servernamein_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
#
Logging Settings
#
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
Log Format
logformat main '$remoteaddr $host $remoteuser [$timelocal] "$request" $status $bodybytessent "$httpreferer" "$httpuseragent" $sslcipher $request_time';
Create zone request limit
limitreqzone $binaryremoteaddr zone=iapp:10m rate=60r/m;
#
Gzip Settings
#
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzipcomplevel 1;
gzip_buffers 16 8k;
gziphttpversion 1.1;
gzip_disable "MSIE [1-6].";
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
Global SSL options
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:AES128-SHA;
ssl_engine aesni;
sslpreferserver_ciphers on;
ssl_protocols SSLv2 SSLv3 TLSv1;
sslsessioncache off;
sslsessiontimeout 5m;
sslsessioncache shared:SSL:10m;
sslsessiontimeout 10m;
#
If HTTPS, then set a variable so it can be passed along.
#
map $scheme $server_https {
default off;
https on;
}
#
Virtual Host Configs
#
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
This webpage has a redirect loop
The webpage at http://www.privacyassociation.org/ has resulted in too many redirects. Clearing your cookies for this site or allowing third-party cookies may fix the problem. If not, it is possibly a server configuration issue and not a problem with your computer.
Here are some suggestions:
Reload this webpage later.
Learn more about this problem.
Error 310 (net::ERR_TOO_MANY_REDIRECTS): There were too many redirects.
The next request gets redirected to
server {
server_name .
access_log /var/log/nginx/www.
error_log /var/log/nginx/www.
expires max;
limit_req zone=iapp burst=200 nodelay;
listen 443 ssl;
ssl on;
sslsessioncache shared:SSL:10m;
ssl_certificate /path;
sslcertificatekey /path;
root /var/empty;
rewrite ^
}
server {
listen 80;
listen 443 ssl;
limit_req zone=iapp burst=200 nodelay;
server_name .
root /var/path;
errorpage 401 /errorpage.php?c=401;
errorpage 403 /errorpage.php?c=403;
errorpage 404 /errorpage.php?c=404;
errorpage 500 /errorpage.php?c=500;
errorpage 502 503 504 /errorpage.php?c=50x;
add_header Cache-Control "public";
add_header Strict-Transport-Security "max-age=315360000; includeSubdomains";
ssl on;
sslsessioncache shared:SSL:10m;
ssl_certificate /etc/nginx/ssl/path;
sslcertificatekey /etc/nginx/ssl/path;
access_log /var/log/nginx/www.
error_log /var/log/nginx/www.
Redirects non-www to www
if ($host = '
rewrite ^/(.*)
}
location / {
index index.php;
Only server pages to the these domain requests.
if ($host !~ ^(
return 444;
}
Only honor http GET HEAD and POST. This will ignore all others.
if ($request_method !~ ^(GET|HEAD|POST)$ ) {
return 444;
}
So long as all the previous tests have passed, load the rewritten index.php page.
try_files $uri $uri/ @ee;
}
create the reference rewrite and the rewrite rule.
location @ee {
rewrite ^(.*) /index.php?/$1 last;
}
Deny access to hidden files (start with .)
location ~ /. {
access_log off;
lognotfound off;
deny all;
}
location /search/crawl {
rewrite ^(.*) /index.php?/$1 last;
allow 127.0.0.1;
deny all;
}
location /
rewrite ^(.*) /index.php?/$1 last;
allow 127.0.0.1;
deny all;
}
Don't log access to thes files
location = /favicon.ico {
lognotfound off;
access_log off;
}
location = /robots.txt {
allow all;
lognotfound off;
access_log off;
}
Only allow our network to these types of files.
location ~* .(rb|log)$ {
deny all;
}
location ~ .(jpe?g|png|gif|mp3|pdf|flv)$ {
valid_referers none blocked
if ($invalid_referer) {
return 403;
}
}
location =/error_page.php {
fastcgi_pass unix:/tmp/phpfpm.sock;
fastcgiparam SCRIPTFILENAME $documentroot$fastcgiscript_name;
include fastcgi_params;
internal;
}
Web conference alias and flash video settings
location ^~ /media {
Block specific agents, mostly bots that don't honor our robots.txt file.
if ($httpuseragent ~ "Wget/|Teleport Pro|WebCopier|fetch|Download|Alligator|FileHound|free-downloads.net|Charon/|BackStreet|EyeCatcher|FDM|FreshDownloads"){
return 403;
}
root /var/www/;
flv;
}
Setup the expires for caching static files. max=Dec 31, 2037, 1y=One Year, 31d=31 Days, 24h=24 Hours
location ~* ^.+.(js|css|png|jpg|jpeg|gif|ico)$ {
access_log off;
expires off;
}
location ~* .(?:ico|css|js|gif|jpe?g|png)$ {
Some basic cache-control for static files to be sent to the browser
expires off;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
This is the index.php specific settings
location /index.php {
include fastcgi_params;
set $script $uri;
set $path_info $uri;
this will set the path_info when it exists as query string: /index.php?/something/here
if ($args ~* "^(/.+)$") {
set $path_info $1;
}
fastcgiintercepterrors on;
fastcgi_pass unix:/tmp/phpfpm.sock;
fastcgi_index index.php;
fastcgiparam SCRIPTFILENAME $documentroot$fastcgiscript_name;
fastcgiparam PATHINFO $path_info;
}
These will process all other .php pages
location ~ .php$ {
if (!-f $documentroot$fastcgiscript_name){
return 404;
}
fastcgipassrequest_body off;
clientbodyinfileonly clean;
fastcgiparam REQUESTBODYFILE $requestbody_file;
fastcgisplitpath_info ^(.+.php)(/.+)$;
fastcgiintercepterrors on;
fastcgiparam SCRIPTFILENAME $documentroot$fastcgiscript_name;
fastcgi_pass unix:/tmp/phpfpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
}
I know there were some issues with some older OpenSSL libraries that refused the ciphers from IE, but that that was back for IE6-7. I don't know when that was fixed, or if was just IE's move to SSLv3+. The problem sounds a little like that one, or another nginx issue when built with threaded perl on red hat/centos.
@AgentOfPork:
What versions of IE have you tested with? And what version of OpenSSL are you running? OS? Any other data may help…
I know there were some issues with some older OpenSSL libraries that refused the ciphers from IE, but that that was back for IE6-7. I don't know when that was fixed, or if was just IE's move to SSLv3+. The problem sounds a little like that one, or another nginx issue when built with threaded perl on red hat/centos.
We are running Ubuntu 11.10 with OpenSSL 1.0.0e
The problem is with IE 8 on one instance but it could happen in others.
Thanks!
Edit: And you can see in the config that we are allowing ssl 2,3 and tls 1 with a large number of ciphers.
It's getting a little deeper than I can swim, I'm hoping with the info someone else can jump in? Sorry I can't be more help atm.
@AgentOfPork:
It's getting a little deeper than I can swim, I'm hoping with the info someone else can jump in? Sorry I can't be more help atm.
:(
I appreciate the help! The rewrite rule is pretty simple and is in the sites config above. But I do suspect that to be at the heart of the issue, I just don't see anything wrong.
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:AES128-SHA;
That was our mistake. When we commented that out the problem went away. For those that may come across this at a future date the Wireshark packet capture showed the follow attempt to negotiate with the above config line enabled:
4 0.028693 10.0.2.15 50.116.48.191 TLSv1 131 Client Hello
5 0.029430 50.116.48.191 10.0.2.15 TCP 60 https > csdm [ACK] Seq=1 Ack=78 Win=65535 Len=0
6 0.080633 50.116.48.191 10.0.2.15 TLSv1 61 Alert (Level: Fatal, Description: Handshake Failure)
And here is the same part of the capture with the line commented out:
6 0.067025 10.0.2.15 50.116.48.191 TLSv1 163 Client Hello
7 0.067793 50.116.48.191 10.0.2.15 TCP 60 https > saiseh [ACK] Seq=1 Ack=110 Win=65535 Len=0
8 0.079714 50.116.48.191 10.0.2.15 TLSv1 191 Server Hello, Change Cipher Spec, Encrypted Handshake Message
I am unclear why there was a different in negotiation without ciphers specified but it definitely fixed the issue. A little additional information for investigation purposes:
https > csdm was negotiating on port 1472.
The details of the alert failure on line 6 of the failed capture error out with "Content Type: Alert (21)" which is a failed to decrypt error.
https > saiseh was negotiating on port 1644.
I hope this helps someone in the future and if anyone can add more information please do!
ssl_ciphers HIGH:!ADH:!MD5:!aNULL:!eNULL:!MEDIUM:!LOW:!EXP:!kEDH;
ssl_protocols SSLv3 TLSv1;
ssl_prefer_server_ciphers on;
It's also a bad idea to lump all virtual hosts into a giant server { } block and use "if" blocks to handle redirects. The nginx official guide strongly recommends that you use one separate virtual hosts for this. Have an SSL virtual host that handles the www domain at port 443. This is your main site. Also have a none-SSL virtual host that handles the www domain at port 80. You can make this redirect to the SSL site if you want. Finally, have a non-SSL virtual host that handles the non-www domain. Everything in this virtual host should redirect to the www domain. That'll make a very short server { } block, but it's many times more manageable than an "if" block inside another virtual host. This would have prevented your redirection woes.