如何配置Varnish让WHM中cPanel的启停请求及页面不缓存?
Got it, let's break down exactly what you need to do to make cPanel/WHM suspend/unsuspend actions take effect immediately when using Varnish, while also keeping those critical requests and pages from being cached. Here's your step-by-step guide:
1. Bypass Caching for WHM Suspend/Unsuspend Requests
First off, we need to ensure the actual suspend/unsuspend action requests themselves aren't cached—these need to hit the WHM/cPanel backend directly every time. Add these rules to your Varnish Configuration Language (VCL) file in the vcl_recv section:
sub vcl_recv { # Skip cache for WHM's suspend/unsuspend API calls (JSON and XML formats) if (req.url ~ "^/json-api/(suspendacct|unsuspendacct)" || req.url ~ "^/xml-api/(suspendacct|unsuspendacct)") { return (pass); } # Skip cache for WHM UI pages tied to account suspension/unsuspension if (req.url ~ "^/scripts2/(suspendacct|unsuspendacct)" || req.url ~ "^/whm/(accountinformation|accountfunctions)") { return (pass); } }
These lines tell Varnish to skip caching entirely for the core API calls and WHM UI pages that handle account suspension/unsuspension. That way, every time you trigger one of these actions, it's processed in real-time without any cached interference.
2. Purge Cached Content for the Affected Account
Even if we bypass the action requests, existing cached content for the user's site will still show the old status (active or suspended). We need to automatically clear that cache when the suspend/unsuspend runs.
Option 1: Use cPanel Hooks (Most Reliable)
cPanel lets you set up post-action hooks that run right after a suspend or unsuspend. Here's how to set this up:
- Create a purge script at
/usr/local/cpanel/scripts/varnish_purge_after_suspendwith this content:
#!/bin/bash # Grab the affected username from the hook's input USERNAME="$1" # Purge the main domain's cached content # Replace YOUR_VARNISH_IP and YOUR_VARNISH_PORT with your actual values (usually 127.0.0.1:80 if Varnish runs locally) MAIN_DOMAIN=$(whmapi1 listaccts search=$USERNAME | grep -m1 domain | awk '{print $2}') curl -X PURGE "http://YOUR_VARNISH_IP:YOUR_VARNISH_PORT/*" -H "Host: $MAIN_DOMAIN" # Purge addon domains too, if the user has any for ADDON_DOMAIN in $(whmapi1 listaccts search=$USERNAME | grep addon_domains | awk -F'|' '{print $2}' | tr ',' '\n'); do curl -X PURGE "http://YOUR_VARNISH_IP:YOUR_VARNISH_PORT/*" -H "Host: $ADDON_DOMAIN" done
- Make the script executable:
chmod +x /usr/local/cpanel/scripts/varnish_purge_after_suspend
- Register the hook with cPanel so it runs after suspend/unsuspend actions:
/usr/local/cpanel/bin/manage_hooks add script /usr/local/cpanel/scripts/varnish_purge_after_suspend --category Whostmgr --event suspendacct --stage post /usr/local/cpanel/bin/manage_hooks add script /usr/local/cpanel/scripts/varnish_purge_after_suspend --category Whostmgr --event unsuspendacct --stage post
Option 2: VCL-Based Purge (Alternative)
If you prefer handling this directly in VCL, you can trigger a purge when the API completes successfully. Add this to your vcl_backend_response section:
sub vcl_backend_response { # After a successful suspend/unsuspend API call, purge the user's domain cache if (bereq.url ~ "^/json-api/(suspendacct|unsuspendacct)") { # Extract the username from the request parameters set var.user = regsuball(bereq.url, ".*user=([^&]+).*", "\1"); # Get the user's main domain (you may need to adjust this if your backend sends a different header) set var.domain = regsuball(beresp.http.X-Cpanel-Domain, "\"", ""); # Purge all cached content for the domain purge("req.http.Host == " + var.domain); } }
Note: This requires your cPanel backend to send the user's domain in a custom header like X-Cpanel-Domain in the API response. You may need to tweak this based on your actual response structure.
3. Bypass Caching for Suspended Account Pages
Finally, we need to ensure that visitors to a suspended account's site see the suspended page immediately (not old cached content). Add these rules to your VCL:
sub vcl_recv { # Add a header to flag that we need to check if the account is suspended set req.http.X-Check-Suspended = "1"; return (hash); } sub vcl_backend_fetch { if (bereq.http.X-Check-Suspended) { unset bereq.http.X-Check-Suspended; # If the backend returns a 403 or 503 (common suspended status codes), don't cache the response if (beresp.status == 403 || beresp.status == 503) { set beresp.ttl = 0s; set beresp.http.Cache-Control = "no-cache, no-store, must-revalidate"; set beresp.http.Pragma = "no-cache"; set beresp.http.Expires = "0"; } } }
This ensures that suspended account pages are never cached, so visitors always see the correct status right away.
Final Checks
After making these changes:
- Restart Varnish to apply the VCL updates:
systemctl restart varnish - Test suspending/unsuspending an account to confirm:
- The action takes effect immediately in WHM
- The user's site shows the correct status (suspended/active) without waiting for cache to expire
- No cached content lingers for the affected domain
内容的提问来源于stack exchange,提问作者behnam bahadori




