Web Application Firewall — Configure WAF Security Rules on EasyCloudify
TL;DR — The EasyCloudify WAF lets you write custom traffic filtering rules using a Cloudflare-based expression language, with field/operator/value conditions, logic operators, and five possible actions (Block, Skip, Challenge, JS Challenge, Managed Challenge).
What is the EasyCloudify Web Application Firewall?
The EasyCloudify Web Application Firewall (WAF) is a security layer that inspects every HTTP request flowing to your web properties before it reaches your server. Rules you define are evaluated at the edge in the order they appear — the first matching rule determines the outcome. Access the Security page at /cloudpanel/security.
Before You Start
- You have at least one domain or web property connected to EasyCloudify
How to Access WAF Settings
In the sidebar, click Security. You land on /cloudpanel/security, which displays the Firewall panel.
The panel provides a full interface for:
- Viewing and managing existing firewall rules
- Creating new custom rules with the Rule Builder
- Enabling automatic vulnerability protection
Understanding WAF Rule Flow
Rules are evaluated in order from top to bottom. The first rule whose condition matches the incoming request wins — no further rules are checked. This means rule order matters:
- Put more specific Allow rules above broad Block rules (e.g., whitelist your office IP before blocking a whole country)
- Put Block rules above Challenge rules for the same traffic pattern if you want hard blocks
Rule Expression Syntax
Each rule is made of one or more conditions. Each condition has three parts:
[Field] [Operator] [Value]
Multiple conditions can be combined using logic operators (and / or).
Available Fields
| Field label | Expression field | What it matches |
|---|---|---|
| IP | ip.src | The request's source IP address |
| Country | ip.geoip.country | Two-letter ISO country code (e.g. US, FR, CN) |
| Continent | ip.geoip.continent | Continent code (e.g. EU, AS, NA) |
| AS Num | ip.geoip.asnum | Autonomous system number (integer) |
| Host | http.host | The Host header value (e.g. example.com) |
| URI Path | http.request.uri.path | The URL path only (e.g. /admin) |
| URI Query | http.request.uri.query | The query string (e.g. page=1&sort=asc) |
| Full URI | http.request.full_uri | Complete URL including scheme and query string |
| URI | http.request.uri | Path + query string without scheme |
| Request Method | http.request.method | HTTP verb: GET, POST, PUT, DELETE, etc. |
| User Agent | http.user_agent | The browser or bot's User-Agent string |
| Referer | http.referer | The Referer header value |
| Cookie | http.cookie | The full Cookie header string |
| HTTP Version | http.request.version | HTTP protocol version: HTTP/1.1, HTTP/2, etc. |
| Threat Score | cf.threat_score | Cloudflare threat score 0–100 (higher = more suspicious) |
| X Forwarded For | http.x_forwarded_for | X-Forwarded-For header (proxy chains) |
| Header | http.request.headers["name"][*] | Any custom request header by name |
Available Operators
| Operator label | Expression syntax | Meaning |
|---|---|---|
| Equals | eq | Exact match |
| Not Equals | ne | Does not match |
| Contains | contains | String is found anywhere in the field |
| Less Than | lt | Numeric value is less than |
| Less Than or Equal | le | Numeric value is less than or equal to |
| Greater Than | gt | Numeric value is greater than |
| Greater Than or Equal | ge | Numeric value is greater than or equal to |
Available Actions
| Action | What it does |
|---|---|
| Block | Immediately rejects the request — returns an HTTP 403 to the visitor |
| Skip | Bypasses all remaining rules — use to whitelist trusted traffic |
| Challenge | Shows a CAPTCHA challenge; only real humans can pass |
| JS Challenge | Shows a lightweight JavaScript browser challenge; stops most bots with no user interaction |
| Managed Challenge | Cloudflare automatically picks the right challenge type based on the visitor's risk score |
💡 Tip: For most unwanted bot traffic, Managed Challenge is the best default action — it's invisible to real users but blocks automated scanners effectively.
Creating a Custom WAF Rule
Step 1 — Open the Rule Builder
In the Firewall panel at /cloudpanel/security, click Create Rule. The Rule Builder dialog opens.
Step 2 — Name your rule
Give the rule a descriptive name so you can identify it later (e.g. Block admin from outside France, Rate limit wp-login).
Step 3 — Build conditions
Use the row-based condition builder:
- Select a Field from the dropdown (e.g.
Country) - Select an Operator (e.g.
Equals) - Enter the Value (e.g.
RU) - To add another condition, click Add condition and choose a Logic Operator (
and/or) before the new row
Step 4 — Choose an action
Select the action to take when the conditions match: Block, Skip, Challenge, JS Challenge, or Managed Challenge.
Step 5 — Enable and save
Make sure the rule status is set to Enabled, then click Deploy. The rule is added to the top of your rule list.
Practical Rule Examples
Block all traffic from a specific country
Useful when you know your audience is regional and you want to cut off traffic from high-risk countries.
| Field | Operator | Value |
|---|---|---|
| Country | Equals | CN |
Action: Block
Block all traffic except one country
Block everyone, then use a separate Skip rule above it for allowed countries:
Rule 1 (higher priority): Allow your country
| Field | Operator | Value |
|---|---|---|
| Country | Equals | FR |
Action: Skip
Rule 2 (lower priority): Block everyone else
| Field | Operator | Value |
|---|---|---|
| URI Path | Contains | / |
Action: Block
Protect the WordPress login page
Allows your IP through, blocks everyone else on /wp-login.php and /wp-admin:
Rule 1 — Whitelist your IP (action: Skip)
| Field | Operator | Value |
|---|---|---|
| IP | Equals | 203.0.113.10 |
Rule 2 — Block login page (action: Block)
| Field | Operator | Value | Logic |
|---|---|---|---|
| URI Path | Contains | /wp-login.php | — |
| URI Path | Contains | /wp-admin | or |
Action: Block
Block by high threat score
Block requests from IPs Cloudflare has already identified as highly suspicious:
| Field | Operator | Value |
|---|---|---|
| Threat Score | Greater Than | 25 |
Action: Managed Challenge
💡 Tip: A threat score above 25 covers most automated scanners and known bad actors. Raise the threshold to 50 if you see false positives on legitimate visitors.
Block a known bad bot by User-Agent
| Field | Operator | Value |
|---|---|---|
| User Agent | Contains | SemrushBot |
Action: Block
You can repeat this pattern for any bot name you want to block (e.g. AhrefsBot, MJ12bot, DotBot).
Block POST requests to your contact form from outside your region
| Field | Operator | Value | Logic |
|---|---|---|---|
| Request Method | Equals | POST | — |
| URI Path | Contains | /contact | and |
| Country | Not Equals | FR | and |
Action: Block
Allow only specific HTTP methods
Block anything that isn't GET or POST (useful to harden REST APIs):
| Field | Operator | Value | Logic |
|---|---|---|---|
| Request Method | Not Equals | GET | — |
| Request Method | Not Equals | POST | and |
Action: Block
Enabling Automatic Vulnerability Protection
The Firewall panel includes a toggle for Automatic Vulnerability Protection. When enabled, EasyCloudify applies a managed ruleset that automatically defends against:
- SQL injection (SQLi)
- Cross-site scripting (XSS)
- Remote code execution (RCE)
- Path traversal attacks
- Other OWASP Top 10 vulnerability classes
This managed ruleset is updated automatically as new threats are discovered — you do not need to manage it manually.
💡 Tip: Enable automatic vulnerability protection as your baseline, then layer your custom rules on top for more granular control over specific traffic patterns.
Troubleshooting
Issue: Your own IP gets blocked after creating a rule.
Fix: Create a Skip rule with IP eq YOUR_IP and move it to the top of the rule list so it is evaluated first.
Issue: A rule blocks too much legitimate traffic.
Fix: Narrow the conditions — add an and condition to restrict the rule to a specific URI path or request method, rather than matching all traffic.
Issue: Bot traffic is still getting through.
Fix: Combine a Threat Score gt 25 rule with a User Agent contains rule using or logic to cast a wider net.
Frequently Asked Questions
What happens to traffic that does not match any rule?
Traffic that does not match any custom WAF rule is allowed through by default, subject to platform-level and automatic vulnerability protection if enabled.
Can I combine more than two conditions in one rule?
Yes. Click Add condition multiple times to chain as many field/operator/value rows as needed. Each new row requires a logic operator (and or or) preceding it.
Does rule order matter?
Yes. Rules are evaluated top to bottom and the first match wins. Always place Skip/Allow rules above Block rules when they overlap.
Can I temporarily disable a rule without deleting it?
Yes. When editing a rule, set its status to Disabled. Disabled rules remain saved but are not evaluated until re-enabled.
What is the difference between Challenge and JS Challenge?
Challenge shows a visible CAPTCHA that the user must solve. JS Challenge silently runs a JavaScript puzzle in the background — real browsers pass automatically, bots fail. Use JS Challenge when you want to stop bots without interrupting the user experience.
What Threat Score should I use?
Start at 25 for a good balance between blocking bots and avoiding false positives. If legitimate visitors are getting challenged, raise the threshold to 50.