You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何配置Varnish让WHM中cPanel的启停请求及页面不缓存?

Varnish Config Fixes for cPanel/WHM Suspend/Unsuspend Immediate Effect

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:

  1. Create a purge script at /usr/local/cpanel/scripts/varnish_purge_after_suspend with 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
  1. Make the script executable:
chmod +x /usr/local/cpanel/scripts/varnish_purge_after_suspend
  1. 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:
    1. The action takes effect immediately in WHM
    2. The user's site shows the correct status (suspended/active) without waiting for cache to expire
    3. No cached content lingers for the affected domain

内容的提问来源于stack exchange,提问作者behnam bahadori

火山引擎 最新活动