Advertisement
Guest User

varnish

a guest
Dec 15th, 2014
237
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.86 KB | None | 0 0
  1. vcl 4.0;
  2. import std;
  3. import directors;
  4. backend www1 { # Define one backend
  5. .host = "192.168.1.5"; # IP or Hostname of backend
  6. .port = "80"; # Port Apache or whatever is listening
  7. .max_connections = 1000; # That's it
  8. .probe = {
  9. #.url = "/check"; # short easy way (GET /)
  10. # We prefer to only do a HEAD /
  11. .request =
  12. "HEAD /check HTTP/1.1"
  13. "Host: 192.168.1.5"
  14. "Connection: close";
  15. .interval = 5s; # check the health of each backend every 5 seconds
  16. .timeout = 1s; # timing out after 1 second.
  17. # If 3 out of the last 5 polls succeeded the backend is considered healthy, otherwise it will be marked as sick
  18. .window = 5;
  19. .threshold = 3;
  20. }
  21. .first_byte_timeout = 300s; # How long to wait before we receive a first byte from our backend?
  22. .connect_timeout = 5s; # How long to wait for a backend connection?
  23. .between_bytes_timeout = 2s; # How long to wait between bytes received from our backend?
  24. }
  25. backend www2 { # Define second backend
  26. .host = "192.168.1.6"; # IP or Hostname of backend
  27. .port = "80"; # Port Apache or whatever is listening
  28. .max_connections = 1000; # That's it
  29. .probe = {
  30. #.url = "/check"; # short easy way (GET /)
  31. # We prefer to only do a HEAD /
  32. .request =
  33. "HEAD /check HTTP/1.1"
  34. "Host: 192.168.1.6"
  35. "Connection: close";
  36. .interval = 5s; # check the health of each backend every 5 seconds
  37. .timeout = 1s; # timing out after 1 second.
  38. # If 3 out of the last 5 polls succeeded the backend is considered healthy, otherwise it will be marked as sick
  39. .window = 5;
  40. .threshold = 3;
  41. }
  42. .first_byte_timeout = 300s; # How long to wait before we receive a first byte from our backend?
  43. .connect_timeout = 5s; # How long to wait for a backend connection?
  44. .between_bytes_timeout = 2s; # How long to wait between bytes received from our backend?
  45. }
  46. acl purge {
  47. "localhost";
  48. "10.0.0.0/24";
  49. "127.0.0.1";
  50. "::1";
  51. }
  52. /*
  53. acl editors {
  54. "localhost";
  55. "127.0.0.1";
  56. "::1";
  57. }
  58. */
  59. sub vcl_init {
  60. new vdir = directors.round_robin();
  61. vdir.add_backend(www1);
  62. // vdir.add_backend(www2);
  63. new vdir2 = directors.round_robin();
  64. vdir2.add_backend(www2);
  65. }
  66. sub vcl_recv {
  67. // Add a Surrogate-Capability header to announce ESI support.
  68. set req.http.Surrogate-Capability = "abc=ESI/1.0";
  69. if (req.http.host ~ "^(www\.)?site\.company\.com$") {
  70. set req.http.host = "site.lan.company.com";
  71. set req.backend_hint = vdir.backend();
  72. }
  73. // set req.backend_hint = vdir.backend(); # send all traffic to the vdir director
  74. if (req.restarts == 0) {
  75. if (req.http.X-Forwarded-For) { # set or append the client.ip to X-Forwarded-For header
  76. set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
  77. } else {
  78. set req.http.X-Forwarded-For = client.ip;
  79. }
  80. }
  81. # Normalize the header, remove the port (in case you're testing this on various TCP ports)
  82. set req.http.Host = regsub(req.http.Host, ":[0-9]+", "");
  83. # Normalize the query arguments
  84. set req.url = std.querysort(req.url);
  85. # Allow purging
  86. if (req.method == "PURGE") {
  87. if (!client.ip ~ purge) { # purge is the ACL defined at the begining
  88. # Not from an allowed IP? Then die with an error.
  89. return (synth(405, "This IP is not allowed to send PURGE requests."));
  90. }
  91. # If you got this stage (and didn't error out above), purge the cached result
  92. return (purge);
  93. }
  94. # Only deal with "normal" types
  95. if (req.method != "GET" &&
  96. req.method != "HEAD" &&
  97. req.method != "PUT" &&
  98. req.method != "POST" &&
  99. req.method != "TRACE" &&
  100. req.method != "OPTIONS" &&
  101. req.method != "PATCH" &&
  102. req.method != "DELETE") {
  103. /* Non-RFC2616 or CONNECT which is weird. */
  104. return (pipe);
  105. }
  106. # Implementing websocket support (https://www.varnish-cache.org/docs/4.0/users-guide/vcl-example-websockets.html)
  107. if (req.http.Upgrade ~ "(?i)websocket") {
  108. return (pipe);
  109. }
  110. # Only cache GET or HEAD requests. This makes sure the POST requests are always passed.
  111. if (req.method != "GET" && req.method != "HEAD") {
  112. return (pass);
  113. }
  114. # Some generic URL manipulation, useful for all templates that follow
  115. # First remove the Google Analytics added parameters, useless for our backend
  116. if (req.url ~ "(\?|&)(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=") {
  117. set req.url = regsuball(req.url, "&(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=([A-z0-9_\-\.%25]+)", "");
  118. set req.url = regsuball(req.url, "\?(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=([A-z0-9_\-\.%25]+)", "?");
  119. set req.url = regsub(req.url, "\?&", "?");
  120. set req.url = regsub(req.url, "\?$", "");
  121. }
  122. # Strip hash, server doesn't need it.
  123. if (req.url ~ "\#") {
  124. set req.url = regsub(req.url, "\#.*$", "");
  125. }
  126. # Strip a trailing ? if it exists
  127. if (req.url ~ "\?$") {
  128. set req.url = regsub(req.url, "\?$", "");
  129. }
  130. # Some generic cookie manipulation, useful for all templates that follow
  131. # Remove the "has_js" cookie
  132. set req.http.Cookie = regsuball(req.http.Cookie, "has_js=[^;]+(; )?", "");
  133. # Remove any Google Analytics based cookies
  134. set req.http.Cookie = regsuball(req.http.Cookie, "__utm.=[^;]+(; )?", "");
  135. set req.http.Cookie = regsuball(req.http.Cookie, "_ga=[^;]+(; )?", "");
  136. set req.http.Cookie = regsuball(req.http.Cookie, "utmctr=[^;]+(; )?", "");
  137. set req.http.Cookie = regsuball(req.http.Cookie, "utmcmd.=[^;]+(; )?", "");
  138. set req.http.Cookie = regsuball(req.http.Cookie, "utmccn.=[^;]+(; )?", "");
  139. # Remove DoubleClick offensive cookies
  140. set req.http.Cookie = regsuball(req.http.Cookie, "__gads=[^;]+(; )?", "");
  141. # Remove the Quant Capital cookies (added by some plugin, all __qca)
  142. set req.http.Cookie = regsuball(req.http.Cookie, "__qc.=[^;]+(; )?", "");
  143. # Remove the AddThis cookies
  144. set req.http.Cookie = regsuball(req.http.Cookie, "__atuv.=[^;]+(; )?", "");
  145. # Remove a ";" prefix in the cookie if present
  146. set req.http.Cookie = regsuball(req.http.Cookie, "^;\s*", "");
  147. # Are there cookies left with only spaces or that are empty?
  148. if (req.http.cookie ~ "^\s*$") {
  149. unset req.http.cookie;
  150. }
  151. # Normalize Accept-Encoding header
  152. # straight from the manual: https://www.varnish-cache.org/docs/3.0/tutorial/vary.html
  153. # TODO: Test if it's still needed, Varnish 4 now does this by itself if http_gzip_support = on
  154. # https://www.varnish-cache.org/docs/trunk/users-guide/compression.html
  155. # https://www.varnish-cache.org/docs/trunk/phk/gzip.html
  156. if (req.http.Accept-Encoding) {
  157. if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") {
  158. # No point in compressing these
  159. unset req.http.Accept-Encoding;
  160. } elsif (req.http.Accept-Encoding ~ "gzip") {
  161. set req.http.Accept-Encoding = "gzip";
  162. } elsif (req.http.Accept-Encoding ~ "deflate") {
  163. set req.http.Accept-Encoding = "deflate";
  164. } else {
  165. # unkown algorithm
  166. unset req.http.Accept-Encoding;
  167. }
  168. }
  169. if (req.http.Cache-Control ~ "(?i)no-cache") {
  170. #if (req.http.Cache-Control ~ "(?i)no-cache" && client.ip ~ editors) { # create the acl editors if you want to restrict the Ctrl-F5
  171. # http://varnish.projects.linpro.no/wiki/VCLExampleEnableForceRefresh
  172. # Ignore requests via proxy caches and badly behaved crawlers
  173. # like msnbot that send no-cache with every request.
  174. if (! (req.http.Via || req.http.User-Agent ~ "(?i)bot" || req.http.X-Purge)) {
  175. #set req.hash_always_miss = true; # Doesn't seems to refresh the object in the cache
  176. return(purge); # Couple this with restart in vcl_purge and X-Purge header to avoid loops
  177. }
  178. }
  179. # Large static files are delivered directly to the end-user without
  180. # waiting for Varnish to fully read the file first.
  181. # Varnish 4 fully supports Streaming, so set do_stream in vcl_backend_response()
  182. if (req.url ~ "^[^?]*\.(mp[34]|rar|tar|tgz|gz|wav|zip|bz2|xz|7z|avi|mov|ogm|mpe?g|mk[av])(\?.*)?$") {
  183. unset req.http.Cookie;
  184. return (hash);
  185. }
  186. # Remove all cookies for static files
  187. # A valid discussion could be held on this line: do you really need to cache static files that don't cause load? Only if you have memory left.
  188. # Sure, there's disk I/O, but chances are your OS will already have these files in their buffers (thus memory).
  189. # Before you blindly enable this, have a read here: http://mattiasgeniar.be/2012/11/28/stop-caching-static-files/
  190. if (req.url ~ "^[^?]*\.(bmp|bz2|css|doc|eot|flv|gif|gz|ico|jpeg|jpg|js|less|pdf|png|rtf|swf|txt|woff|xml)(\?.*)?$") {
  191. unset req.http.Cookie;
  192. return (hash);
  193. }
  194. # Send Surrogate-Capability headers to announce ESI support to backend
  195. set req.http.Surrogate-Capability = "key=ESI/1.0";
  196. if (req.http.Authorization) {
  197. # Not cacheable by default
  198. return (pass);
  199. }
  200. return (hash);
  201. }
  202. sub vcl_pipe {
  203. # Note that only the first request to the backend will have
  204. # X-Forwarded-For set. If you use X-Forwarded-For and want to
  205. # have it set for all requests, make sure to have:
  206. # set bereq.http.connection = "close";
  207. # here. It is not set by default as it might break some broken web
  208. # applications, like IIS with NTLM authentication.
  209. #set bereq.http.Connection = "Close";
  210. # Implementing websocket support (https://www.varnish-cache.org/docs/4.0/users-guide/vcl-example-websockets.html)
  211. if (req.http.upgrade) {
  212. set bereq.http.upgrade = req.http.upgrade;
  213. }
  214. return (pipe);
  215. }
  216. sub vcl_pass {
  217. # return (pass);
  218. }
  219. sub vcl_hash {
  220. hash_data(req.url);
  221. if (req.http.host) {
  222. hash_data(req.http.host);
  223. } else {
  224. hash_data(server.ip);
  225. }
  226. # hash cookies for requests that have them
  227. if (req.http.Cookie) {
  228. hash_data(req.http.Cookie);
  229. }
  230. }
  231. sub vcl_hit {
  232. if (obj.ttl >= 0s) {
  233. # A pure unadultered hit, deliver it
  234. return (deliver);
  235. }
  236. # https://www.varnish-cache.org/docs/trunk/users-guide/vcl-grace.html
  237. # When several clients are requesting the same page Varnish will send one request to the backend and place the others on hold while fetching one copy from the backend. In some products this is called request coalescing and Varnish does this automatically.
  238. # If you are serving thousands of hits per second the queue of waiting requests can get huge. There are two potential problems - one is a thundering herd problem - suddenly releasing a thousand threads to serve content might send the load sky high. Secondly - nobody likes to wait. To deal with this we can instruct Varnish to keep the objects in cache beyond their TTL and to serve the waiting requests somewhat stale content.
  239. # We have no fresh fish. Lets look at the stale ones.
  240. if (std.healthy(req.backend_hint)) {
  241. # Backend is healthy. Limit age to 10s.
  242. if (obj.ttl + 10s > 0s) {
  243. #set req.http.grace = "normal(limited)";
  244. return (deliver);
  245. } else {
  246. # No candidate for grace. Fetch a fresh object.
  247. return(fetch);
  248. }
  249. } else {
  250. # backend is sick - use full grace
  251. if (obj.ttl + obj.grace > 0s) {
  252. #set req.http.grace = "full";
  253. return (deliver);
  254. } else {
  255. # no graced object.
  256. return (fetch);
  257. }
  258. }
  259. # fetch & deliver once we get the result
  260. return (fetch); # Dead code, keep as a safeguard
  261. }
  262. sub vcl_miss {
  263. return (fetch);
  264. }
  265. sub vcl_backend_response {
  266. // Check for ESI acknowledgement and remove Surrogate-Control header
  267. if (beresp.http.Surrogate-Control ~ "ESI/1.0") {
  268. unset beresp.http.Surrogate-Control;
  269. set beresp.do_esi = true;
  270. }
  271. /* By default Varnish ignores Pragma: nocache
  272. (https://www.varnish-cache.org/docs/4.0/users-guide/increasing-your-hitrate.html#cache-control)
  273. so in order avoid caching it has to be done explicitly */
  274. if (beresp.http.Pragma ~ "no-cache") {
  275. // https://www.varnish-cache.org/docs/4.0/whats-new/upgrading.html#hit-for-pass-objects-are-created-using-beresp-uncacheable
  276. set beresp.uncacheable = true;
  277. set beresp.ttl = 20m;
  278. return (deliver);
  279. }
  280. # Pause ESI request and remove Surrogate-Control header
  281. /*
  282. if (beresp.http.Surrogate-Control ~ "ESI/1.0") {
  283. unset beresp.http.Surrogate-Control;
  284. set beresp.do_esi = true;
  285. }
  286. */
  287. # Enable cache for all static files
  288. # The same argument as the static caches from above: monitor your cache size, if you get data nuked out of it, consider giving up the static file cache.
  289. # Before you blindly enable this, have a read here: http://mattiasgeniar.be/2012/11/28/stop-caching-static-files/
  290. if (bereq.url ~ "^[^?]*\.(bmp|bz2|css|doc|eot|flv|gif|gz|ico|jpeg|jpg|js|less|mp[34]|pdf|png|rar|rtf|swf|tar|tgz|txt|wav|woff|xml|zip)(\?.*)?$") {
  291. unset beresp.http.set-cookie;
  292. }
  293. # Large static files are delivered directly to the end-user without
  294. # waiting for Varnish to fully read the file first.
  295. # Varnish 4 fully supports Streaming, so use streaming here to avoid locking.
  296. if (bereq.url ~ "^[^?]*\.(mp[34]|rar|tar|tgz|gz|wav|zip|bz2|xz|7z|avi|mov|ogm|mpe?g|mk[av])(\?.*)?$") {
  297. unset beresp.http.set-cookie;
  298. set beresp.do_stream = true; # Check memory usage it'll grow in fetch_chunksize blocks (128k by default) if
  299. # the backend doesn't send a Content-Length header, so only enable it for big objects
  300. set beresp.do_gzip = false; # Don't try to compress it for storage
  301. }
  302. # Sometimes, a 301 or 302 redirect formed via Apache's mod_rewrite can mess with the HTTP port that is being passed along.
  303. # This often happens with simple rewrite rules in a scenario where Varnish runs on :80 and Apache on :8080 on the same box.
  304. # A redirect can then often redirect the end-user to a URL on :8080, where it should be :80.
  305. # This may need finetuning on your setup.
  306. #
  307. # To prevent accidental replace, we only filter the 301/302 redirects for now.
  308. if (beresp.status == 301 || beresp.status == 302) {
  309. set beresp.http.Location = regsub(beresp.http.Location, ":[0-9]+", "");
  310. }
  311. # Set 2min cache if unset for static files
  312. if (beresp.ttl <= 0s || beresp.http.Set-Cookie || beresp.http.Vary == "*") {
  313. set beresp.ttl = 120s; # Important, you shouldn't rely on this, SET YOUR HEADERS in the backend
  314. set beresp.uncacheable = true;
  315. return (deliver);
  316. }
  317. # Allow stale content, in case the backend goes down.
  318. # make Varnish keep all objects for 6 hours beyond their TTL
  319. set beresp.grace = 6h;
  320. return (deliver);
  321. }
  322. sub vcl_deliver {
  323. if (obj.hits > 0) { # Add debug header to see if it's a HIT/MISS and the number of hits, disable when not needed
  324. set resp.http.X-Cache = "HIT";
  325. } else {
  326. set resp.http.X-Cache = "MISS";
  327. }
  328. # Please note that obj.hits behaviour changed in 4.0, now it counts per objecthead, not per object
  329. # and obj.hits may not be reset in some cases where bans are in use. See bug 1492 for details.
  330. # So take hits with a grain of salt
  331. set resp.http.X-Cache-Hits = obj.hits;
  332. # Remove some headers: PHP version
  333. unset resp.http.X-Powered-By;
  334. # Remove some headers: Apache version & OS
  335. #unset resp.http.Server;
  336. #unset resp.http.X-Drupal-Cache;
  337. #unset resp.http.X-Varnish;
  338. #unset resp.http.Via;
  339. #unset resp.http.Link;
  340. return (deliver);
  341. }
  342. sub vcl_purge {
  343. # restart request
  344. set req.http.X-Purge = "Yes";
  345. return(restart);
  346. }
  347. sub vcl_synth {
  348. if (resp.status == 720) {
  349. # We use this special error status 720 to force redirects with 301 (permanent) redirects
  350. # To use this, call the following from anywhere in vcl_recv: error 720 "http://host/new.html"
  351. set resp.status = 301;
  352. set resp.http.Location = resp.reason;
  353. return (deliver);
  354. } elseif (resp.status == 721) {
  355. # And we use error status 721 to force redirects with a 302 (temporary) redirect
  356. # To use this, call the following from anywhere in vcl_recv: error 720 "http://host/new.html"
  357. set resp.status = 302;
  358. set resp.http.Location = resp.reason;
  359. return (deliver);
  360. }
  361. return (deliver);
  362. }
  363. sub vcl_fini {
  364. return (ok);
  365. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement