Guest User

Untitled

a guest
Jan 4th, 2021
312
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.99 KB | None | 0 0
  1. #vcl 4.0;
  2. #Based on: #https://github.com/mattiasgeniar/varnish-4.0-configuration-#templates/blob/master/default.vcl
  3.  
  4. import std;
  5. import directors;
  6.  
  7. #BACKEND_SERVERS**
  8.  
  9. #Called when VCL is loaded, before any requests pass through it.
  10. #Typically used to initialize VMODs.
  11.  
  12. #BACKEND_DIRECTORS**
  13. #Called when VCL is loaded, before any requests pass through it.
  14. #Typically used to initialize VMODs.
  15.  
  16. sub vcl_init {
  17. }
  18.  
  19. sub vcl_pass {
  20. return (pass);
  21. }
  22.  
  23. #SET THE ALLOWED IP OF PURGE REQUESTS
  24. ###########################################################
  25. acl purge {
  26. "localhost";
  27. "127.0.0.1";
  28. "Web.Server.IP";
  29. }
  30.  
  31.  
  32. #Called at the beginning of a request, after the complete request has been received and parsed.
  33. #Its purpose is to decide whether or not to serve the request, how to do it, and, if applicable,
  34. #which backend to use.
  35. #also used to modify the request
  36. #Normalize the header, remove the port (in case you're testing this on various TCP ports)
  37. sub vcl_recv {
  38.  
  39. set req.http.Host = regsub(req.http.Host, ":[0-9]+", "");
  40.  
  41. #remove HTTPOXY CGI vulnerability
  42. unset req.http.proxy;
  43.  
  44. #Some generic cookie manipulation, useful for all templates that follow
  45. #Remove the "has_js" cookie
  46. set req.http.Cookie = regsuball(req.http.Cookie, "has_js=[^;]+(; )?", "");
  47.  
  48. #Remove any Google Analytics based cookies
  49. set req.http.Cookie = regsuball(req.http.Cookie, "__utm.=[^;]+(; )?", "");
  50. set req.http.Cookie = regsuball(req.http.Cookie, "_ga=[^;]+(; )?", "");
  51. set req.http.Cookie = regsuball(req.http.Cookie, "_gat=[^;]+(; )?", "");
  52. set req.http.Cookie = regsuball(req.http.Cookie, "utmctr=[^;]+(; )?", "");
  53. set req.http.Cookie = regsuball(req.http.Cookie, "utmcmd.=[^;]+(; )?", "");
  54. set req.http.Cookie = regsuball(req.http.Cookie, "utmccn.=[^;]+(; )?", "");
  55.  
  56. #Remove DoubleClick offensive cookies
  57. set req.http.Cookie = regsuball(req.http.Cookie, "__gads=[^;]+(; )?", "");
  58.  
  59. #Remove the Quant Capital cookies (added by some plugin, all __qca)
  60. set req.http.Cookie = regsuball(req.http.Cookie, "__qc.=[^;]+(; )?", "");
  61.  
  62. #Remove the AddThis cookies
  63. set req.http.Cookie = regsuball(req.http.Cookie, "__atuv.=[^;]+(; )?", "");
  64.  
  65. #Remove a ";" prefix in the cookie if present
  66. set req.http.Cookie = regsuball(req.http.Cookie, "^;\s*", "");
  67.  
  68. #Are there cookies left with only spaces or that are empty?
  69. if (req.http.cookie ~ "^\s*$") {
  70. unset req.http.cookie;
  71. }
  72.  
  73. #Remove all cookies for static files
  74. #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.
  75. #Sure, there's disk I/O, but chances are your OS will already have these files in their buffers ##(thus memory).
  76. #Before you blindly enable this, have a read here: https://ma.ttias.be/stop-caching-static-files/
  77. 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)(\?.*)?$") {
  78. unset req.http.Cookie;
  79. return (hash);
  80. }
  81.  
  82. #remove extraneous host ports
  83. set req.http.host = regsub(req.http.Host, ":[0-9]+", "");
  84.  
  85. #set realIP by trimming CloudFlare IP which will be used for various checks
  86. set req.http.X-Actual-IP = regsub(req.http.X-Forwarded-For, "[, ].*$", "");
  87.  
  88. #Enable smart refreshing
  89. if (req.http.Cache-Control ~ "no-cache" && client.ip ~ purge) {
  90. set req.hash_always_miss = true;
  91. }
  92.  
  93. #Unset cloudflare cookies
  94.  
  95. #Remove has_js and CloudFlare/Google Analytics __* cookies.
  96. set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_[_a-z]+|has_js)=[^;]*", "");
  97. #Remove a ";" prefix, if present.
  98. set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");
  99.  
  100. #For Testing: If you want to test with Varnish passing (not caching) uncomment
  101. #return( pass );
  102.  
  103. #FORWARD THE IP OF THE REQUEST
  104. if (req.restarts == 0) {
  105. if (req.http.x-forwarded-for) {
  106. set req.http.X-Forwarded-For =
  107. req.http.X-Forwarded-For + ", " + client.ip;
  108. } else {
  109. set req.http.X-Forwarded-For = client.ip;
  110. }
  111. }
  112.  
  113. set req.http.Host = regsub(req.http.Host, ":[0-9]+", "");
  114.  
  115. #Remove the proxy header (see https://httpoxy.org/#mitigate-varnish)
  116. unset req.http.proxy;
  117.  
  118. #Normalize the query arguments
  119. set req.url = std.querysort(req.url);
  120.  
  121. #Non-RFC2616 or CONNECT which is weird.
  122. #Only deal with "normal" types
  123. if (req.method != "GET" && req.method != "HEAD" && req.method != "PUT" && req.method != "POST" && req.method != "TRACE" && req.method != "OPTIONS" && req.method != "PATCH" && req.method != "DELETE") {
  124. return (pipe);
  125. }
  126.  
  127. #Implementing websocket support #(https://www.varnish-cache.org/docs/4.0/users-guide/vcl-example-#websockets.html)
  128. if (req.http.Upgrade ~ "(?i)websocket") {
  129. return (pipe);
  130. }
  131.  
  132. #Only cache GET or HEAD requests. This makes sure the POST requests are always passed.
  133. if (req.method != "GET" && req.method != "HEAD") {
  134. return (pass);
  135. }
  136.  
  137. #Not cacheable by default
  138. if (req.http.Authorization) {
  139. return (pass);
  140. }
  141. #For static file access, strip all querystring parameters.
  142. if (req.url ~ "^[^?]*\.(bmp|bz2|css|doc|eot|flv|gif|gz|ico|jpe?g|js|less|mp[34]|otf|pdf|png|rar|rtf|swf|tar|tgz|ttf|txt|wav|webm|woff|xml|zip)(\?.*)?$") {
  143. unset req.http.Cookie;
  144. set req.url = querystring.remove(req.url);
  145. return (hash);
  146. }
  147.  
  148. #Whitelist query string parameters for WordPress.
  149. set req.url = querystring.filter_except(req.url,
  150. "sort" + querystring.filtersep() +
  151. "q" + querystring.filtersep() +
  152. "dom" + querystring.filtersep() +
  153. "dedupe_hl" + querystring.filtersep() +
  154. "filter" + querystring.filtersep() +
  155. "attachment" + querystring.filtersep() +
  156. "attachment_id" + querystring.filtersep() +
  157. "author" + querystring.filtersep() +
  158. "author_name" + querystring.filtersep() +
  159. "cat" + querystring.filtersep() +
  160. "calendar" + querystring.filtersep() +
  161. "category_name" + querystring.filtersep() +
  162. "comments_popup" + querystring.filtersep() +
  163. "cpage" + querystring.filtersep() +
  164. "day" + querystring.filtersep() +
  165. "dedupe_hl" + querystring.filtersep() +
  166. "dom" + querystring.filtersep() +
  167. "error" + querystring.filtersep() +
  168. "exact" + querystring.filtersep() +
  169. "exclude" + querystring.filtersep() +
  170. "feed" + querystring.filtersep() +
  171. "hour" + querystring.filtersep() +
  172. "m" + querystring.filtersep() +
  173. "minute" + querystring.filtersep() +
  174. "monthnum" + querystring.filtersep() +
  175. "more" + querystring.filtersep() +
  176. "name" + querystring.filtersep() +
  177. "order" + querystring.filtersep() +
  178. "orderby" + querystring.filtersep() +
  179. "p" + querystring.filtersep() +
  180. "page_id" + querystring.filtersep() +
  181. "page" + querystring.filtersep() +
  182. "paged" + querystring.filtersep() +
  183. "pagename" + querystring.filtersep() +
  184. "pb" + querystring.filtersep() +
  185. "post_type" + querystring.filtersep() +
  186. "posts" + querystring.filtersep() +
  187. "preview" + querystring.filtersep() +
  188. "q" + querystring.filtersep() +
  189. "robots" + querystring.filtersep() +
  190. "s" + querystring.filtersep() +
  191. "search" + querystring.filtersep() +
  192. "second" + querystring.filtersep() +
  193. "sentence" + querystring.filtersep() +
  194. "sort" + querystring.filtersep() +
  195. "static" + querystring.filtersep() +
  196. "subpost" + querystring.filtersep() +
  197. "subpost_id" + querystring.filtersep() +
  198. "taxonomy" + querystring.filtersep() +
  199. "tag" + querystring.filtersep() +
  200. "tb" + querystring.filtersep() +
  201. "tag_id" + querystring.filtersep() +
  202. "term" + querystring.filtersep() +
  203. "tb" + querystring.filtersep() +
  204. "url" + querystring.filtersep() +
  205. "w" + querystring.filtersep() +
  206. "withcomments" + querystring.filtersep() +
  207. "withoutcomments" + querystring.filtersep() +
  208. "year");
  209. #Sort the querystring parameters, so different orders of the same produce a single cache #object.
  210. if (req.url ~ "\?") {
  211. set req.url = querystring.sort(req.url);
  212. }
  213.  
  214. #Keep WordPress cookies for preview
  215. #drop all cookies.
  216. if (req.http.cookie) {
  217. if (req.url ~ "preview") {
  218. return (pass);
  219. } else {
  220. unset req.http.cookie;
  221. }
  222. return (hash);
  223. }
  224.  
  225. #The data on which the hashing will take place
  226. #Called after vcl_recv to create a hash value for the request. This is used as a key
  227. #to look up the object in Varnish.
  228. sub vcl_hash {
  229. if (req.http.cookie) {
  230. hash_data(req.http.cookie);
  231. }
  232.  
  233. return(lookup);
  234. }
  235. #fix flexible ssl css
  236. if (req.http.x-forwarded-proto) {
  237. hash_data(req.http.x-forwarded-proto);
  238. }
  239. if (req.http.host) {
  240. hash_data(req.http.host);
  241. } else {
  242. hash_data(server.ip);
  243. set req.http.ccsuri = regsub(req.url, "\?(.*)", "");
  244. hash_data(req.http.ccsuri);
  245. }
  246. return (hash);
  247. }
  248.  
  249.  
  250. #Called upon entering pass mode. In this mode, the request is passed on to the backend, and #the
  251. #backend's response is passed on to the client, but is not entered into the cache. Subsequent
  252. #requests submitted over the same client connection are handled normally.
  253.  
  254. #The data on which the hashing will take place
  255.  
  256.  
  257. #Called when a cache lookup is successful.
  258. #A pure unadultered hit, deliver it
  259. sub vcl_hit {
  260. if (obj.ttl >= 0s) {
  261. return (deliver);
  262. }
  263.  
  264. if (req.request == "PURGE") {
  265. purge;
  266. error 200 "Purged.";
  267. }
  268. return (deliver);
  269.  
  270. #https://www.varnish-cache.org/docs/trunk/users-guide/vcl-grace.html
  271. #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.
  272. #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.
  273.  
  274. #Object is in grace, deliver it
  275. #Automatically triggers a background fetch
  276. if (obj.ttl + obj.grace > 0s) {
  277. return (deliver);
  278. }
  279. #fetch & deliver once we get the result
  280. return (fetch);
  281. }
  282.  
  283. if (!std.healthy(req.backend_hint) && (obj.ttl + obj.grace > 0s)) {
  284. return (deliver);
  285. } else {
  286. return (miss);
  287. }
  288.  
  289. #We have no fresh fish. Lets look at the stale ones.
  290. #Backend is healthy. Limit age to 10s.
  291. set req.http.grace = "normal(limited)";
  292. #No candidate for grace. Fetch a fresh object.
  293. #backend is sick - use full grace
  294. #no graced object.
  295.  
  296. if (std.healthy(req.backend_hint)) {
  297. if (obj.ttl + 10s > 0s) {
  298. return (deliver);
  299. } else {
  300. return (fetch);
  301. }
  302. } else {
  303. if (obj.ttl + obj.grace > 0s) {
  304. set req.http.grace = "full";
  305. return (deliver);
  306. } else {
  307. return (fetch);
  308. }
  309. }
  310.  
  311. #fetch & deliver once we get the result
  312. #Dead code, keep as a safeguard
  313. return (fetch);
  314. }
  315.  
  316. #Called after a cache lookup if the requested document was not found in the cache. Its purpose
  317. #is to decide whether or not to attempt to retrieve the document from the backend, and which
  318. #backend to use.
  319. sub vcl_miss {
  320. return (fetch);
  321. }
  322.  
  323. #Handle the HTTP request coming from our backend
  324. #Called after the response headers has been successfully retrieved from the backend.
  325. #Pause ESI request and remove Surrogate-Control header
  326. sub vcl_backend_response {
  327. if (beresp.http.Surrogate-Control ~ "ESI/1.0") {
  328. unset beresp.http.Surrogate-Control;
  329. set beresp.do_esi = true;
  330. }
  331. if (!(bereq.url ~ "wp-(login|admin)|cart|my-account|wc-api|resetpass") &&
  332. !bereq.http.cookie ~ "wordpress_logged_in|woocommerce_items_in_cart|resetpass" && !beresp.status == 302) {
  333. unset beresp.http.set-cookie;
  334. set beresp.ttl = 1w;
  335. set beresp.grace = 1d;
  336. }
  337.  
  338.  
  339. #Enable cache for all static files
  340. #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.
  341. #Before you blindly enable this, have a read here: https://ma.ttias.be/stop-caching-static-files/
  342. if (bereq.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)(\?.*)?$") {
  343. unset beresp.http.set-cookie;
  344. }
  345.  
  346. #Large static files are delivered directly to the end-user without
  347. #waiting for Varnish to fully read the file first.
  348. #Varnish 4 fully supports Streaming, so use streaming here to avoid locking.
  349. if (bereq.url ~ "^[^?]*\.(7z|avi|bz2|flac|flv|gz|mka|mkv|mov|mp3|mp4|mpeg|mpg|ogg|ogm|opus|rar|tar|tgz|tbz|txz|wav|webm|xz|zip)(\?.*)?$") {
  350. unset beresp.http.set-cookie;
  351. set beresp.do_stream = true;
  352. return (hash);
  353. }
  354.  
  355. #Don't cache 50x responses
  356. if (beresp.status == 500 || beresp.status == 502 || beresp.status == 503 || beresp.status == 504) {
  357. return (abandon);
  358. }
  359.  
  360. #Sometimes, a 301 or 302 redirect formed via Apache's mod_rewrite can mess with the HTTP #port that #is being passed along.
  361. #This often happens with simple rewrite rules in a scenario where Varnish runs on :80 and #Apache on #:8080 on the same box.
  362. #A redirect can then often redirect the end-user to a URL on :8080, where it should be :80.
  363. #This may need finetuning on your setup.
  364. #To prevent accidental replace, we only filter the 301/302 redirects for now.
  365. if (beresp.status == 301 || beresp.status == 302) {
  366. set beresp.http.Location = regsub(beresp.http.Location, ":[0-9]+", "");
  367. }
  368.  
  369. #Set 2min cache if unset for static files
  370. if (beresp.ttl <= 0s || beresp.http.Set-Cookie || beresp.http.Vary == "*") {
  371. set beresp.ttl = 120s;
  372. set beresp.uncacheable = true;
  373. return (deliver);
  374. }
  375.  
  376. #Allow stale content, in case the backend goes down.
  377. #make Varnish keep all objects for 6 hours beyond their TTL
  378. set beresp.grace = 6h;
  379.  
  380. return (deliver);
  381. }
  382.  
  383.  
  384. #The routine when we deliver the HTTP request to the user
  385. #Last chance to modify headers that are sent to the client
  386. #Called before a cached object is delivered to the client.
  387. #Add debug header to see if it's a HIT/MISS and the number of hits, disable when not needed
  388. sub vcl_deliver {
  389. if (obj.hits > 0) {
  390. set resp.http.X-Cache = "HIT";
  391. } else {
  392. set resp.http.X-Cache = "MISS";
  393. return (deliver);
  394. }
  395.  
  396. #Please note that obj.hits behaviour changed in 4.0, now it counts per objecthead, not per #object
  397. #and obj.hits may not be reset in some cases where bans are in use. See bug 1492 for #details.
  398. #So take hits with a grain of salt
  399.  
  400. set resp.http.X-Cache-Hits = obj.hits;
  401. if (req.http.sticky) {
  402. if(!resp.http.Set-Cookie) {
  403. set resp.http.Set-Cookie = "";
  404. }
  405. set resp.http.Set-Cookie = "ccsvs=ccs" + req.http.sticky + "; Expires=" + (now + 10d) + ";" + resp.http.Set-Cookie;
  406. }
  407. #Remove some headers: PHP version
  408. unset resp.http.X-Powered-By;
  409.  
  410. #Remove some headers: Apache version & OS
  411. unset resp.http.Server;
  412. unset resp.http.X-Drupal-Cache;
  413. unset resp.http.X-Varnish;
  414. unset resp.http.Via;
  415. unset resp.http.Link;
  416. unset resp.http.X-Generator;
  417. return (deliver);
  418. }
  419.  
  420. #Only handle actual PURGE HTTP methods, everything else is discarded
  421. #restart request
  422. sub vcl_purge {
  423. if (req.method != "PURGE") {
  424. set req.http.X-Purge = "Yes";
  425. return(restart);
  426. }
  427. }
  428.  
  429. #You may need to add other locations like membership sites here, 302 is necessary if you use #redirect to cart
  430. ###########################################################
  431. if (!(req.url ~ "wp-(login|admin)|wc-api|resetpass|cart|checkout|my-account|\?wc-ajax=get_refreshed_fragments") && !req.http.cookie ~ "wordpress_logged_in|resetpass" && !beresp.status == 302) {
  432. unset beresp.http.set-cookie;
  433. set beresp.ttl = 1w;
  434. set beresp.grace =3d;
  435. }
  436.  
  437. if (beresp.ttl <= 0s || beresp.http.Set-Cookie || beresp.http.Vary == "*") {
  438. set beresp.ttl = 120 s;
  439. return (hit_for_pass);
  440. }
  441. return (deliver);
  442. }
  443.  
  444. #We use this special error status 8201 for clear cache messages
  445. #We use this special error status 720 to force redirects with 301 (permanent) redirects
  446. #To use this, call the following from anywhere in vcl_recv: return (synth(720, #"http://host/new.html"));
  447. #And we use error status 721 to force redirects with a 302 (temporary) redirect
  448. #To use this, call the following from anywhere in vcl_recv: return (synth(720, #"http://host/new.html"));
  449. sub vcl_synth {
  450. if (resp.status == 720) {
  451. set resp.http.Location = resp.reason;
  452. set resp.status = 301;
  453. return (deliver);
  454. } elseif (resp.status == 721) {
  455. set resp.http.Location = resp.reason;
  456. set resp.status = 302;
  457. return (deliver);
  458. }
  459.  
  460.  
  461. #Called when VCL is discarded only after all requests have exited the VCL.
  462. #Typically used to clean up VMODs.
  463.  
  464. sub vcl_fini {
  465. return (ok);
  466. }
  467.  
  468. #Called upon entering pipe mode.
  469. #In this mode, the request is passed on to the backend, and any further data from both the #client
  470. #and backend is passed on unaltered until either end closes the connection. Basically, Varnish #will
  471. #degrade into a simple TCP proxy, shuffling bytes back and forth. For a connection in pipe #mode,
  472. #no other VCL subroutine will ever get called after vcl_pipe.
  473.  
  474. #Note that only the first request to the backend will have
  475. #X-Forwarded-For set. If you use X-Forwarded-For and want to
  476. #have it set for all requests, make sure to have:
  477. #here. It is not set by default as it might break some broken web
  478. #applications, like IIS with NTLM authentication.
  479. #Implementing websocket support #(https://www.varnish-cache.org/docs/4.0/users-guide/vcl-example-#websockets.html)
  480. sub vcl_pipe {
  481. set bereq.http.Connection = "Close";
  482. set bereq.http.connection = "close";
  483. if (req.http.upgrade) {
  484. set bereq.http.upgrade = req.http.upgrade;
  485. }
  486. return (pipe);
  487. }
  488.  
  489.  
  490.  
  491.  
  492.  
  493.  
Advertisement
Add Comment
Please, Sign In to add comment