if (req.http.Cookie !~ "(^|;\s*)(province=(.*?))(;|$)") {
return (pass);
}
if (req.http.Cookie) {
set req.http.Cookie = ";" + req.http.Cookie;
set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
set req.http.Cookie = regsuball(req.http.Cookie, ";(allgroups|viewed-products)=", "; \1=");
set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");
if (req.http.Cookie == "") {
unset req.http.Cookie;
}
}
I need to prevent the first cookie to get deleted, I noticed varnish kept removing all of my cookies for some reason, so I was wondering what the hell was happening, so I checked and I think the latter part is at fault, so do I need to prevent set and unset from happening by doing the following?
if (req.http.Cookie !~ "(^|;\s*)(province=(.*?))(;|$)") {
return (pass);
}
if (req.http.Cookie) {
set req.http.Cookie = ";" + req.http.Cookie;
set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
set req.http.Cookie = regsuball(req.http.Cookie, ";(allgroups|viewed-products|province)=", "; \1=");
set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");
if (req.http.Cookie == "") {
unset req.http.Cookie;
}
}
Here's the snippet I would use in your case to prevent the following cookies from being removed:
allgroups
viewed-products
province
sub vcl_recv {
if (req.http.Cookie) {
set req.http.Cookie = ";" + req.http.Cookie;
set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
set req.http.Cookie = regsuball(req.http.Cookie, ";(allgroups|viewed\-products|province)=", "; \1=");
set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");
if (req.http.cookie ~ "^\s*$") {
unset req.http.cookie;
}
}
}
In the end after all the cookie substitutions took place and the cookie is just a collection of whitespace characters, or if the cookie is an empty string, we remove the entire cookie header.
Of course that won't be the case if any of the above cookies are present.
That should really do the trick. However I see a lot of confusion regarding this approach, and rightfully so, because these regular expression substitutions are ugly and hard to interpret.
vmod_cookie
An alternative is to use vmod_cookie and leverage the clean cookie management API it offers. See http://varnish-cache.org/docs/6.6/reference/vmod_cookie.html for docs.
vmod_cookie is a native Varnish VMOD as of version 6.4. This means that versions 6.4, 6.5 and 6.6 ship it by default. If you're on an older version, you can compile the module from source by using https://github.com/varnish/varnish-modules
Here's the how you use it in your case:
import cookie;
sub vcl_recv {
if (req.http.Cookie) {
cookie.parse(req.http.cookie);
cookie.keep("allgroups,view-products,province");
set req.http.cookie = cookie.get_string();
if (req.http.cookie ~ "^\s*$") {
unset req.http.cookie;
}
}
}
See what works best for you, but you have to admit that vmod_cookie is easier to use and understand than the regsub() calls.
Related
I try to create a regex for varnish cache v4
sub vcl_backend_response {
if (bereq.url ~ "(/media|/bundles|/sonata_admin/|/build)$" ) {
{
unset beresp.http.set-cookie;
set beresp.http.cache-control = "public, max-age=2592000";
set beresp.ttl = 30d;
return (deliver);
}
also I try
if (bereq.url ~ "(\/media|\/bundles|\/sonata_admin|\/build)$" ) {
I want to include all files where location starts from /media or /bundles or ...
this not work
In your config, it doesn't work because you're matching up with $ that stands for "at the end of string".
You want to use ^ which is "match at the beginning", thus:
if (bereq.url ~ "^/(media|bundles|sonata_admin|build)") {
unset beresp.http.set-cookie;
set beresp.http.cache-control = "public, max-age=2592000";
set beresp.ttl = 30d;
return (deliver);
}
My varnish cache is accelerator mode and it cause adding more slash after URL.
I check with gtmetrix:
Avoid landing page redirects for the following chain of redirected URLs.
https://www.example2.com/
https://www.example2.com//
https://www.example2.com/
and with google pagespeed test:
Reduce server response time
In our test, your server responded in 1.6 seconds. There are many factors that can slow down your server response time.
Here is my config:
vcl 4.0;
backend default {
.host = "localhost";
.port = "8080";
}
acl purger {
"localhost";
"XXX.XXX.XXX.XXX";
}
sub vcl_recv {
if (client.ip != "127.0.0.1" && req.http.host ~ "XXX.com") {
set req.http.x-redir = "https://www.example.com/" + req.url;
return(synth(850, ""));
}
if (client.ip != "127.0.0.1" && req.http.host ~ "YYY.com") {
set req.http.x-redir = "https://www.example2.com/" + req.url;
return(synth(850, ""));
}
if (req.method == "PURGE") {
if (!client.ip ~ purger) {
return(synth(405, "This IP is not allowed to send PURGE requests."));
}
return (purge);
}
if (req.restarts == 0) {
if (req.http.X-Forwarded-For) {
set req.http.X-Forwarded-For = client.ip;
}
}
if (req.http.Authorization || req.method == "POST") {
return (pass);
}
if (req.url ~ "/feed") {
return (pass);
}
set req.http.cookie = regsuball(req.http.cookie, "wp-settings-\d+=[^;]+(; )?", "");
set req.http.cookie = regsuball(req.http.cookie, "wp-settings-time-\d+=[^;]+(; )?", "");
if (req.http.cookie == "") {
unset req.http.cookie;
}
}
sub vcl_synth {
if (resp.status == 850) {
set resp.http.Location = req.http.x-redir;
set resp.status = 302;
return (deliver);
}
}
sub vcl_purge {
set req.method = "GET";
set req.http.X-Purger = "Purged";
return (restart);
}
sub vcl_backend_response {
set beresp.ttl = 24h;
set beresp.grace = 1h;
}
sub vcl_deliver {
if (req.http.X-Purger) {
set resp.http.X-Purger = req.http.X-Purger;
}
}
Somebody know the reason why varnish do that ?
req.url always includes a / at the beginning.
so correct would be:
set req.http.x-redir = "https://www.example2.com" + req.url;
your question does not correspond to the example1/example2 as it includes XXX and YYY
if you can post a less redacted VCL - i may can help you a bit more
you may need a != "/" on req.url before redirecting. as this would result in a //
We are currently configure Varnish on our server. This is the mess...
We encounter some difficulties with Varnish. Indeed when we return the response for uncached page, varnish include systematically the PHPSSID of the current user in the response. When another user ask the page wich is cached, he inherites of the PHPSSSID of a foreign user...
vcl 4.0;
include "includes/devicedetect.vcl";
import std;
backend local {
.host = "127.0.0.1";
.port = "80";
.connect_timeout = 5s;
.first_byte_timeout = 300s;
.between_bytes_timeout = 300s;
}
acl purge {
# ACL we'll use later to allow purges
# web01
# web02
"localhost";
"127.0.0.1";
}
sub vcl_recv {
# Disable all
# return (pass);
# Allow purging
if (req.method == "PURGE") {
if (!std.ip(regsub(req.http.X-Forwarded-For, "[, ].*$", ""), client.ip) ~ purge) {
# Not from an allowed IP? Then die with an error.
return (synth(405, "This IP is not allowed to send PURGE requests."));
}
# If you got this stage (and didn't error out above), purge the cached result
return (purge);
}
# Allow ban (global purge)
if (req.method == "BAN") {
if (!std.ip(regsub(req.http.X-Forwarded-For, "[, ].*$", ""), client.ip) ~ purge) {
# Not from an allowed IP? Then die with an error.
return (synth(405, "This IP is not allowed to send BAN requests."));
}
# If you got this stage (and didn't error out above), purge the cached result
ban("obj.http.x-url ~ /");
return (synth(200, "Ban added"));
}
# Only cache GET or HEAD requests. This makes sure the POST requests are always passed.
if (req.method != "GET" && req.method != "HEAD") {
return (pass);
}
if (req.http.Authorization) {
return (pass);
}
if (req.http.host ~ "(api\.domain\.com|api2\.domain\.com)") {
return (pass);
}
# Do not cache logout/login/forgot password url
if (req.url ~ "/(logout|forgotten-password|login|register|facebookLogin)") {
return (pass);
}
# Do not cache when Set-Cookie contain user[id] OR identity OR PHPSESSID OR PHPSERVERID
if (req.http.Set-Cookie ~ "(user\[id\]|identity|SERVERID)") {
return (pass);
}
# Do not cache customer french page
if (req.url ~ "/fr/(client|personnaliser|panier)") {
return (pass);
}
# Do not cache customer english page
if (req.url ~ "/en/(customer|personalize|cart)") {
return (pass);
}
# Do not cache checkout
if (req.url ~ "/checkout") {
return (pass);
}
# Normalize the header, remove the port (in case you're testing this on various TCP ports)
set req.http.Host = regsub(req.http.Host, ":[0-9]+", "");
# Remove the proxy header (see https://httpoxy.org/#mitigate-varnish)
unset req.http.proxy;
# Strip hash, server doesn't need it.
if (req.url ~ "\#") {
set req.url = regsub(req.url, "\#.*$", "");
}
# Strip a trailing ? if it exists
if (req.url ~ "\?$") {
set req.url = regsub(req.url, "\?$", "");
}
# Normalize the query arguments
# set req.url = std.querysort(req.url);
# Remove the backend cache parameter for pagination
if (req.url ~ "(\&|\?)_=[0-9]+$") {
set req.url = regsub(req.url, "(\&|\?)_=[0-9]+$", "");
}
# Cache static files
if (req.url ~ "^[^?]*\.(7z|avi|bmp|bz2|css|csv|doc|docx|eot|flac|flv|gif|gz|ico|jpeg|jpg|js|less|mka|mkv|mov|mp3|mp4|mpeg|mpg|odt|otf|ogg|ogm|opus|pdf|png|ppt|pptx|rar|rtf|svg|svgz|swf|tar|tbz|tgz|ttf|txt|txz|wav|webm|webp|woff|woff2|xls|xlsx|xml|xz|zip)(\?.*)?$") {
unset req.http.Cookie;
return (hash);
}
# Mobile Detection set req.http.X-UA-Device
call devicedetect;
# Normalize accept-encoding
if (req.http.Accept-Encoding) {
if (req.http.Accept-Encoding ~ "gzip") {
set req.http.Accept-Encoding = "gzip";
} elsif (req.http.Accept-Encoding ~ "deflate") {
set req.http.Accept-Encoding = "deflate";
} else {
unset req.http.Accept-Encoding;
}
}
# Send Surrogate-Capability headers to announce ESI support to backend
set req.http.Surrogate-Capability = "abc=ESI/1.0";
if (req.http.cookie ~ "id_devise=") {
set req.http.Devise = regsuball(req.http.cookie, "(.*?)(id_devise=[^;]*)(.*)$", "\2");
}
if (req.http.cookie ~ "id_mesure=") {
set req.http.Mesure = regsuball(req.http.cookie, "(.*?)(id_mesure=[^;]*)(.*)$", "\2");
}
# Cache the rest
return (hash);
}
sub vcl_backend_response {
if (bereq.http.X-UA-Device) {
if (!beresp.http.Vary) { # no Vary at all
set beresp.http.Vary = "X-UA-Device";
} elsif (beresp.http.Vary !~ "X-UA-Device") { # add to existing Vary
set beresp.http.Vary = beresp.http.Vary + ", X-UA-Device";
}
}
if (bereq.url ~ "/esi/" || bereq.url ~ "checkout" || bereq.url ~ "/fr/(client|personnaliser)" || bereq.url ~ "/en/(customer|personalize)") {
unset beresp.http.Surrogate-Control;
set beresp.ttl = 0s;
} else {
set beresp.do_esi = true;
set beresp.ttl = 10m;
}
set beresp.grace = 6h;
return (deliver);
}
sub vcl_backend_error {
if (beresp.status == 503) {
set beresp.http.Content-Type = "text/html; charset=utf-8";
synthetic(std.fileread("/home/domain/www/503.html"));
return(deliver);
}
if (beresp.status == 500) {
set beresp.http.Content-Type = "text/html; charset=utf-8";
synthetic(std.fileread("/home/domain/www/500.html"));
return(deliver);
}
}
sub vcl_hash {
hash_data(req.url);
if (req.http.host) {
hash_data(req.http.host);
} else {
hash_data(server.ip);
}
if (req.http.Devise) {
hash_data(req.http.Devise);
}
if (req.http.Mesure) {
hash_data(req.http.Mesure);
}
if (req.http.X-Requested-With) {
hash_data(req.http.X-Requested-With);
}
hash_data(req.http.cookie);
return (lookup);
}
sub vcl_hit {
if (obj.ttl == 0s) {
return (fetch);
} else if (obj.ttl >= 0s) {
return (deliver);
}
if (!std.healthy(req.backend_hint)) {
# backend is sick - use full grace
if (obj.ttl + obj.grace > 0s) {
return (deliver);
}
}
return (fetch);
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
if ((req.http.X-UA-Device) && (resp.http.Vary)) {
set resp.http.Vary = regsub(resp.http.Vary, "X-UA-Device", "User-Agent");
}
set resp.http.X-Cache-Hits = obj.hits;
unset resp.http.X-Powered-By;
unset resp.http.Server;
unset resp.http.X-Drupal-Cache;
unset resp.http.X-Varnish;
unset resp.http.Via;
unset resp.http.Link;
unset resp.http.X-Generator;
return (deliver);
}
sub vcl_pipe {
set bereq.http.Connection = "Close";
return (pipe);
}
sub vcl_pass {
return (fetch);
}
sub vcl_purge {
# Only handle actual PURGE HTTP methods, everything else is discarded
if (req.method != "PURGE") {
# restart request
set req.http.X-Purge = "Yes";
return(restart);
}
}
sub vcl_synth {
if (resp.status == 720) {
# We use this special error status 720 to force redirects with 301 (permanent) redirects
# To use this, call the following from anywhere in vcl_recv: return (synth(720, "http://host/new.html"));
set resp.http.Location = resp.reason;
set resp.status = 301;
return (deliver);
} elseif (resp.status == 721) {
# And we use error status 721 to force redirects with a 302 (temporary) redirect
# To use this, call the following from anywhere in vcl_recv: return (synth(720, "http://host/new.html"));
set resp.http.Location = resp.reason;
set resp.status = 302;
return (deliver);
}
return (deliver);
}
1) By default Varnish does not cache any responses which set a cookie:
sub vcl_backend_response {
if (beresp.ttl <= 0s ||
beresp.http.Set-Cookie ||
beresp.http.Surrogate-control ~ "no-store" ||
(!beresp.http.Surrogate-Control &&
beresp.http.Cache-Control ~ "no-cache|no-store|private") ||
beresp.http.Vary == "*") {
/*
* Mark as "Hit-For-Pass" for the next 2 minutes
*/
set beresp.ttl = 120s;
set beresp.uncacheable = true;
}
return (deliver);
}
See https://github.com/varnish/Varnish-Cache/blob/4.1/bin/varnishd/builtin.vcl
In your "sub vcl_backend_response" you always "return (deliver);". This means that the Varnish builtin VCL is never executed. Just remove "return (deliver);" from your own "sub vcl_backend_response" and things should get better.
2) Set-Cookie is a respose header and not a request header so this does not make sense to me
# Do not cache when Set-Cookie contain user[id] OR identity OR PHPSESSID OR PHPSERVERID
if (req.http.Set-Cookie ~ "(user\[id\]|identity|SERVERID)") {
return (pass);
}
3) In general you should not always call "return" in your own versions of "vcl_*" as it will always prevent the builtin VCL (with sensible default behaviour) from being executed. For example you should not call "return (hash);" at the end of "vcl_receive". If you did not do this you would not need stuff like
if (req.method != "GET" && req.method != "HEAD") {
return (pass);
}
if (req.http.Authorization) {
return (pass);
}
in your "vcl_receive" because this would also be handled in the builtin version.
4) Also your "sub vcl_hash" looks very dodgy to me. I would never hash on cookies like you do:
hash_data(req.http.cookie);
By default Varnish does not cache any request which has a Cookie - also see the builtin.vcl
if (req.http.Authorization || req.http.Cookie) {
/* Not cacheable by default */
return (pass);
}
That is why normally you remove any Cookies in your own "vcl_receive" for requests you want Varnish to cache, like you do for static files.
So yes - it is a bit of a mess.
I'm looking to rewrite an ESI include url in Varnish.
In my template, I have:
<esi:include src="/esi/user.html" />
which just includes static content i.e. "Welcome Guest".
If they login I add the session into my .vcl.
What I want to do is rewrite the include to:
<esi:include src="/esi/user.active.html" />
where I'll do the db query.
Currently, in my sub vcl_recv I have:
if (req.http.Cookie) {
if (req.url ~ "^/esi/(.*)\.html") {
set req.url = regsub("^/esi/(.*)\.html", "$0", ".active");
}
}
It causes a 503 error on the front-end. How would I update this to rewrite the URL and make it work?
Ok, got this working. Here is my .VCL file if anyone's interested
backend default {
.host = "127.0.0.1";
.port = "8080";
}
sub vcl_recv {
if (req.request != "GET" &&
req.request != "HEAD" &&
req.request != "PUT" &&
req.request != "POST" &&
req.request != "TRACE" &&
req.request != "OPTIONS" &&
req.request != "DELETE") {
/* Non-RFC2616 or CONNECT which is weird. */
return (pipe);
}
# Remove cookie for static files
if (req.url ~ "(?i)\.(png|gif|jpeg|jpg|ico|swf|css|js|woff|ttf|eot|svg)(\?[a-zA-Z0-9\=\.\-]+)?$") {
remove req.http.cookie;
}
# Quick hack for now to clear the cache on post
if (req.request == "POST") {
ban("req.http.host == "+ req.http.Host);
return(pass);
}
# If CraftSessionId isn't active, remove cookies altogether
if (req.http.Cookie) {
set req.http.Cookie = ";" + req.http.Cookie;
set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
set req.http.Cookie = regsuball(req.http.Cookie, ";(CraftSessionId)=", "; \1=");
set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");
if (req.http.Cookie == "") {
remove req.http.Cookie;
}
}
# If user is logged in/has cookies enabled, rewrite esi files to include *.active.html
if (req.http.cookie ~ "CraftSessionId=") {
if (req.url ~ "^/esi") {
set req.url = regsub(req.url, "^/esi/(.*).html", "/esi/\1-active.html");
}
}
# Grace period for falldown
set req.grace = 1h;
}
sub vcl_fetch {
set beresp.ttl = 24h; # Make cache last 24 hours
# Allow cookies in admin and account areas
if (req.url !~ "(admin/login|account/login|account/register)") {
unset beresp.http.set-cookie;
}
set beresp.do_gzip = true;
set beresp.do_esi = true; # Allow ESI
# Grace period for falldown
set beresp.grace = 1h;
}
I have installed Varnish on my Linux server and configured for my websites including a wordpress site (www.mywordpress.com) and it is working fine. Now I have installed mantis bug tracker under my website (www.mywordpress.com/mantis). But when I am trying to login to the MantisBT as the default user (administrator/root), it shows an error like "Your browser either does not know how to handle cookies, or refuses to handle them". How can I set up a Varnish exception or allow cookies (in default.vcl) for Mantis url's. My default.vcl file looks like:
###my default.vcl file:
backend default {
.host = "127.0.0.1";
.port = "8080";
}
backend master {
.host = "127.0.0.1";
.port = "8080";
}
acl purge {
"localhost";
}
sub vcl_recv {
if (req.request == "PURGE") {
if (!client.ip ~ purge) {
error 405 "Not allowed.";
}
return(lookup);
}
if (req.restarts == 0) {
if (req.http.x-forwarded-for) {
set req.http.X-Forwarded-For =
req.http.X-Forwarded-For + ", " + client.ip;
} else {
set req.http.X-Forwarded-For = client.ip;
}
}
### do not cache these files:
if (req.url ~ "/svn" || req.http.Authorization || req.http.Authenticate)
{
return (pass);
}
##never cache the admin pages, or the server-status page
if (req.url ~ "wp-(admin|login)" || req.http.Content-Type ~ "multipart/form-data")
{
set req.backend = master;
return(pass);
}
if (req.url ~ "opportunity-attachments" || req.http.Content-Type ~ "multipart/form-data")
{
set req.backend = master;
return(pass);
}
if (req.url ~ "^phpmyadmin") {
set req.backend = master;
return(pipe);
}
if (req.url ~ "^/login") {
set req.backend = master;
return(pipe);
}
## always cache these images & static assets
if (req.request == "GET" && req.url ~ "\.(css|js|gif|jpg|jpeg|bmp|png|ico|img|tga|wmf)$") {
remove req.http.cookie;
return(lookup);
}
if (req.request == "GET" && req.url ~ "(xmlrpc.php|wlmanifest.xml)") {
remove req.http.cookie;
return(lookup);
}
#never cache POST requests
if (req.request == "POST")
{
return(pass);
}
#DO cache this ajax request
if(req.http.X-Requested-With == "XMLHttpRequest" && req.url ~ "recent_reviews")
{
return (lookup);
}
#dont cache ajax requests
if(req.http.X-Requested-With == "XMLHttpRequest" || req.url ~ "nocache" || req.url ~ "(control.php|wp-comments-post.php|wp-login.php|bb-login.php|bb-reset-password.php|register.php)")
{
return (pass);
}
if (req.http.Cookie && req.http.Cookie ~ "wordpress_") {
set req.http.Cookie = regsuball(req.http.Cookie, "wordpress_test_cookie=", "; wpjunk=");
}
### don't cache authenticated sessions
if (req.http.Cookie && req.http.Cookie ~ "(wordpress_|PHPSESSID)") {
return(pass);
}
### parse accept encoding rulesets to make it look nice
if (req.http.Accept-Encoding) {
if (req.http.Accept-Encoding ~ "gzip") {
set req.http.Accept-Encoding = "gzip";
} elsif (req.http.Accept-Encoding ~ "deflate") {
set req.http.Accept-Encoding = "deflate";
} else {
# unkown algorithm
remove req.http.Accept-Encoding;
}
}
if (req.http.Cookie)
{
set req.http.Cookie = ";" + req.http.Cookie;
set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
set req.http.Cookie = regsuball(req.http.Cookie, ";(vendor_region|PHPSESSID|themetype2)=", "; \1=");
set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");
if (req.http.Cookie == "") {
remove req.http.Cookie;
}
}
if (req.url ~ "^/$") {
unset req.http.cookie;
}
return(lookup);
}
sub vcl_hit {
if (req.request == "PURGE") {
set obj.ttl = 0s;
error 200 "Purged.";
}
}
sub vcl_miss {
if (req.request == "PURGE") {
error 404 "Not in cache.";
}
if (!(req.url ~ "wp-(login|admin)")) {
unset req.http.cookie;
}
if (req.url ~ "^/[^?]+.(jpeg|jpg|png|gif|ico|js|css|txt|gz|zip|lzma|bz2|tgz|tbz|html|htm)(\?.|)$") {
unset req.http.cookie;
set req.url = regsub(req.url, "\?.$", "");
}
if (req.url ~ "^/$") {
unset req.http.cookie;
}
}
sub vcl_fetch {
if (req.url ~ "^/$") {
unset beresp.http.set-cookie;
}
if (!(req.url ~ "wp-(login|admin)")) {
unset beresp.http.set-cookie;
}
}
First, change this, it is unsetting any cookie which not inside wp-login or wp-admin:
if (!(req.url ~ "wp-(login|admin)")) {
unset req.http.cookie;
}
to something like this:
if (!(req.url ~ "wp-(login|admin)") || !(req.url ~ "mantis")) {
unset req.http.cookie;
}
(Where '||' means OR, '~' means equals to about, and 'req.url' - the requested URL)
and in vcl_recv (no matter where, put it in the beggining), ignore caching /mantis URLs:
sub vcl_recv {
...
if (req.url ~ "/mantis")
{
return (pass);
}
...
}
and restart varnish (usually sudo service varnish restart on ubuntu). check again and it should be fine (If its not working, clean your browser's cookies and cache).
...And, why is mantis not inside the wp-admin directory? is it a wordpress plugin?