Nginx trowing error Error 400 Bad Request on Varnish
Hello, pretty weird thing is happening to one of my sites, I use Nginx 1.6.2 and everything works normal, but visitors who come from Varnish nodes (on another servers) receive some intermittent error 400 Bad Request.
If I modify my hosts file to point my domain directly to Nginx there is no error, if I pass trough Varnish as normal y get error 400 bad request (from Nginx) from time to time, so my guess is there is something wrong on Varnish.
Any Idea where to start?
Here my config:
Varnish default.vcl
vcl 4.0;
backend default {
.host = "23.23.143.32";
.port = "80";
.probe = {
.url = "/";
.timeout = 1000ms;
.interval = 5s;
.window = 10;
.threshold = 8;
}
}
backend backup {
.host = "23.23.143.32";
.port = "80";
.probe = {
.url = "/";
.timeout = 1000ms;
.interval = 5s;
.window = 10;
.threshold = 8;
}
}
backend espejo {
.host = "54.163.206.168";
.port = "80";
.probe = {
.url = "/";
.timeout = 1000ms;
.interval = 5s;
.window = 10;
.threshold = 8;
}
}
import directors; # load the directors
sub vcl_init {
new cluster1 = directors.random(); #use .random() for weight, round_robin() for equal load balancing.
cluster1.add_backend(default,10); #use (default,weight); with .random() ie: (default,2); (backup,1); = 2/3 to default, 1/3 to backup backend.
cluster1.add_backend(backup,0);
}
# Routine to identify and classify a device based on User-Agent
sub identify_device {
# Default to classification as a PC
set req.http.X-Device = "pc";
if (req.http.User-Agent ~ "iPad" ) {
# The User-Agent indicates it's a iPad - so classify as a tablet
set req.http.X-Device = "mobile-tablet";
}
elsif (req.http.User-Agent ~ "iP(hone|od)" || req.http.User-Agent ~ "Android" || req.http.User-Agent ~ "Mobile.+Firefox") {
# The User-Agent indicates it's a iPhone, iPod or Android - so let's classify as a touch/smart phone
set req.http.X-Device = "mobile-smart";
}
elsif (req.http.User-Agent ~ "SymbianOS" || req.http.User-Agent ~ "^BlackBerry" || req.http.User-Agent ~ "^SonyEricsson" || req.http.User-Agent ~ "^Nokia" || req.http.User-Agent ~ "^SAMSUNG" || req.http.User-Agent ~ "^LG") {
# The User-Agent indicates that it is some other mobile devices, so let's classify it as such.
set req.http.X-Device = "mobile-other";
}
}
sub vcl_recv {
call identify_device;
# send all traffic to the cluster1 director:
set req.backend_hint = cluster1.backend();
if (req.http.host == "espejo.na.com") {
set req.backend_hint = espejo;
}
if (req.method == "GET" || req.method == "HEAD") {
return (hash);
}
if (req.http.User-Agent ~ "(?i)ipad") {
return (hash);
}
# Add header for sending client ip to backend
set req.http.X-Forwarded-For = client.ip;
# Remove has_js and CloudFlare/Google Analytics __* cookies.
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_[_a-z]+|has_js)=[^;]*", "");
# Remove a ";" prefix, if present.
set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");
# Remove cookies and query string for real static files
if (req.url ~ "^/[^?]+\.(gif|jpg|jpeg|swf|css|js|txt|flv|mp3|mp4|pdf|ico|png|gz|zip|lzma|bz2|tgz|tbz)(\?.*|)$") {
unset req.http.cookie;
set req.url = regsub(req.url, "\?.*$", "");
}
# Don't cache admin
# if (req.url ~ "((wp-(login|admin|comments-post.php|cron.php))|login)" || req.url ~ "preview=true" || req.url ~ "xmlrpc.php" || req.url ~ "on.gamemode.es/" || req.url ~ "phpMyAdmin" || req.url ~ "foro" || req.url ~ "contactform.php") {
# return (pass);
# } else {
# unset req.http.cookie;
# }
#Blocks some urls
if (req.url ~ "(wp-(login|admin))|login") {
return (synth(405, "Su computador no esta dirigido al servidor correcto, contacte a TI por ayuda."));
}
}
sub vcl_backend_response {
# Dont cache admin
if (bereq.url ~ "(wp-(login|admin|comments-post.php|cron.php))|login" || bereq.url ~ "preview=true" || bereq.url ~ "xmlrpc.php" || bereq.url ~ "on.gamemode.es/" || bereq.url ~ "phpMyAdmin" || bereq.url ~ "foro" || bereq.url ~ "contactform.php") {
set beresp.uncacheable = true;
set beresp.ttl = 120s;
return (deliver);
} else {
if ( beresp.ttl > 0s ) {
unset beresp.http.set-cookie;
}
# Our cache TTL
set beresp.ttl = 10s;
set beresp.grace = 24h;
return(deliver);
}
if (beresp.status == 404 || beresp.status >= 500) {
set beresp.ttl = 0s;
set beresp.grace = 24h;
}
}
sub vcl_hash {
# If the device has been classified as any sort of mobile device, include the User-Agent in the hash
# However, do not do this for any static assets as our web application returns the same ones for every device.
if (!(req.url ~ ".(gif|jpg|jpeg|swf|flv|mp3|mp4|pdf|ico|png|gz|tgz|bz2)$")) {
hash_data(req.http.X-Device);
}
}
So It happens to be a error caused by a pluggin on wordpress, funny thing is it only happens trough Varnish and not connected to Nginx directly as commented abode. While the problem is solved, I still wondering why such behavior.