Key Features
- Multi-layered Security Rules:
- IP Address/CIDR (with priority for exact IP match over subnet).
- Country (with exceptions for trusted bots).
- User-Agent (types: contains, exact match, regular expression).
- Referrer (types: contains, exact match, regular expression).
- Request URI (types: contains, exact match, regular expression, starts with; with or without query string matching).
- Intelligent Rule Automation:
- Automatic creation of allow rules for subnets of trusted bots (Google, Yandex, etc.).
- Automatic creation of block rules for subnets of unwanted hosters/proxies.
- Rules are generated based on Autonomous System (ASN) data via CRON.
- Realtime checks (no waiting for CRON):
- Country resolved directly from the local IP2Location database at request time (
iskwaf_country_check_mode = realtime).
- Instant block/allow by ASN and company name (
iskwaf_enable_realtime_asn_rules), without waiting for CRON.
- Country whitelist: allow traffic only from listed countries, blocking all others (
iskwaf_allowed_countries); takes precedence over the blacklist.
- Search bot verification: hybrid ASN + DNS (rDNS/fDNS) method. Verified Google/Yandex/Bing/Apple/DuckDuckGo bots bypass country and ASN blocking.
- CSV export/import of rules: export and import rules (IP, User-Agent, Referrer, Request URI) right from the interface; import via the standard MODX file manager, with per-row validation.
- Request inspection (SQL injection protection): checks GET/POST/Cookie values (and optionally the request body) against configurable attack signatures, with "log only" and "block" modes.
- Flexible Rule Actions: Block (403), CAPTCHA, Allow.
- Local CAPTCHA: Numeric, with a "first/last 3 digits" task from a 6-digit image, session-based.
- Optional WAF Check Modes:
- Check on every request (standard behavior).
- Check once per session (reduces load for already verified users).
- Logging System: Detailed WAF trigger logs, configurable modes (`full`, `triggered`, `off`), automatic old log cleanup. Logs also reflect if WAF rules were skipped due to the "once per session" mode.
- IP Address Analysis: Determination of country, region, city, ASN, and ISP for IP addresses from logs using local IP2Location LITE databases (via CRON).
- Daily Reports: Aggregated statistics on WAF events, rule types, search engine bot hits, top-N offenders (in JSON), including geolocation data.
- Management Interface (CMP): Tabs for logs (displaying country/city), each rule type, and reports; create, edit, enable/disable, delete rules.
Installation
- Upload the component package via the "Installer" (Extras -> Installer) in the MODX manager.
- Find the "IskWaf" package and click "Install".
- Follow the on-screen instructions.
Configuration
After installing the component, you need to configure a few system settings, a page for CAPTCHA, and prepare the environment for GeoIP databases.
1. System Settings
Find them in "System" (cog icon) -> "System Settings", selecting the iskwaf namespace.
| Key |
Description |
Possible Values/Action |
iskwaf_iskwaf_captcha_resource_id |
MODX Resource ID for displaying the CAPTCHA page. |
Create a new MODX resource (e.g., with alias captcha-verify), ensure it is not cacheable. In the "Resource Content" field, place the snippet call [[!IskWafCaptcha]]. Specify the ID of this resource here. |
iskwaf_iskwaf_option_log |
WAF Logging Mode. |
full: (Default) All requests are logged (triggered rules + normal visits, including those where rules were skipped due to session check).
triggered: Only requests that trigger a rule are logged. May optionally log when rules are skipped due to session check (see plugin code).
off: Logging is disabled (but rules continue to operate).
|
iskwaf_waf_check_mode |
WAF Rule Check Mode. |
on_every_request: (Default) WAF rules are checked on every request.
once_per_session: WAF rules are checked for a user only once per session. If the check is passed, subsequent requests in the same session do not undergo full WAF checking (but visits may be logged according to the iskwaf_iskwaf_option_log setting).
|
iskwaf_iskwaf_log_retention_days |
Number of days to retain records in the iskwaf_logs log. Old records are deleted by a CRON script. |
Number (e.g., 7, 30). Default in script: 7. |
iskwaf_ip2location_download_token |
Your personal token for downloading databases from the IP2Location website. |
Obtain the token after registering at lite.ip2location.com and enter it here. |
iskwaf_ip_analysis_limit_per_run |
Maximum number of new/outdated IPs to analyze per single run of the analyze_ip2location_details.php CRON script. |
Number. Default in script: 500. |
iskwaf_ip_analysis_update_interval |
Frequency in days for updating information for an IP already existing in the details table. |
Number. Default in script: 30. |
| Automatic Rule Management & Country Blocking |
iskwaf_iskwaf_country_check_mode |
Country check mode |
cached (default): country is taken from the details table populated by CRON. Fast, but new IPs are only blocked after the cron run.
realtime: country is resolved by querying the local IP2Location database at request time — blocking is instant; the result is written back to the table. Requires geoip_db/IP2LOCATION-LITE-DB11.BIN.
|
iskwaf_iskwaf_blocked_countries |
Blocked Countries (blacklist) |
Comma-separated two-letter country codes (ISO 3166-1 alpha-2). Traffic from these countries is blocked (except trusted bots). Example: CN,RU,KP. Ignored if a whitelist is set. |
iskwaf_iskwaf_allowed_countries |
Allowed Countries (whitelist) |
If filled, only traffic from the listed countries is allowed; all others are blocked (trusted bots still pass). Takes precedence over the blacklist. Example: RU,BY,KZ. If an IP cannot be resolved to a country, it is not blocked (fail-open). |
iskwaf_iskwaf_enable_dns_verification |
Search bot verification |
If "Yes", the WAF verifies Google/Yandex/Bing/Apple/DuckDuckGo bots. A verified bot bypasses all rules, including country blocking. Strongly recommended when country blocking is used. |
iskwaf_iskwaf_bot_verification_method |
Bot verification method |
asn_dns (default) — fast local ASN check first, then DNS as a fallback; asn — ASN only (no external DNS; requires IP2LOCATION-LITE-ASN.BIN); dns — double DNS check only (rDNS+fDNS). |
iskwaf_iskwaf_auto_allow_as_names |
Allowed Company Names (AS Name) |
Company names (ASN) that are allowed. Highest priority: checked in realtime and before country blocking — such companies are not blocked even if their country is blacklisted. Delimiter — |. Example: Google LLC|Cloudflare. Also used by CRON to auto-create /24 rules. |
iskwaf_iskwaf_auto_allow_as_numbers |
Allowed AS Numbers (ASN) |
AS numbers that are allowed. Highest priority (as above). Delimiter — |. Example: AS15169|AS13238 |
iskwaf_iskwaf_auto_block_as_names |
Blocked Company Names (AS Name) |
Company names (ASN) to block. Delimiter — |. Example: DigitalOcean|OVH |
iskwaf_iskwaf_auto_block_as_numbers |
Blocked AS Numbers (ASN) |
AS numbers to block. Delimiter — |. Example: AS14061|AS16276 |
iskwaf_iskwaf_enable_realtime_asn_rules |
Realtime ASN checks |
Controls instant ASN blocking at request time (without waiting for CRON). Allow lists always work regardless of this option. Requires geoip_db/IP2LOCATION-LITE-ASN.BIN. |
iskwaf_iskwaf_csv_delimiter |
CSV delimiter (rules export) |
Column delimiter for exporting rules. Default ; (so Excel opens columns correctly). Allowed: ;, , or tab. On import the delimiter is auto-detected or chosen in the import dialog. |
Request Inspection Settings (SQL injection protection)
A separate group of settings (the "Request inspection" area). The module is disabled by default.
| Key | Description | Possible Values |
iskwaf_iskwaf_payload_inspection_mode |
Request payload inspection mode. |
off (default) — disabled; log — only record hits to the log; block — block the request (403). Recommended to run log first to tune signatures. |
iskwaf_iskwaf_payload_scan_sources |
Which inputs to inspect. |
Comma-separated from: get, post, cookie, body (raw body). Default: get,post,cookie. |
iskwaf_iskwaf_payload_max_body |
Max body size to inspect (bytes). |
Number. Default 262144 (256 KB). |
iskwaf_iskwaf_payload_signatures |
Signatures (regular expressions). |
One expression per line (lines starting with # are comments). Case-insensitive, pattern delimiter is ~. If empty, a built-in set for common SQL injections is used. |
2. CAPTCHA Page
As mentioned above, create a MODX resource to display the CAPTCHA. It should be non-cacheable and contain the snippet call [[!IskWafCaptcha? &tpl=`your_form_chunk_name`]] (the `&tpl` parameter is optional, defaults to `iskWafCaptchaFormTpl`).
3. GeoIP Setup (IP2Location)
The IskWaf component uses IP2Location LITE databases to determine geolocation, ASN, and other information for IP addresses. The database files themselves are not included in the component installation package but are downloaded using a special CRON script.
- Get Token: Register at lite.ip2location.com and obtain your personal download token. Enter it into the
iskwaf_ip2location_download_token system setting.
- IP2Location PHP Library:
To work with IP2Location BIN database files, the appropriate PHP library is required. The IskWaf component uses PHP library files that should be placed in the core/components/iskwaf/lib/ip2location/src/ folder. You can download the "IP2Location PHP Module" (for BIN Data File) from the official IP2Location website and place the contents of its `src` folder in the specified path.
- Directories for Databases: Ensure that the following directories exist on the server and are writable by PHP (relative to
core/components/iskwaf/):
tmp_db_download/ (for temporary files during download)
geoip_db/ (for storing unpacked BIN database files)
- Initial Database Download: After setting up the token and placing the PHP library, run the
ip2location_download.php CRON script (see below) once manually from the server's command line for the initial download of the databases (IP2LOCATION-LITE-DB11.BIN and IP2LOCATION-LITE-ASN.BIN).
4. CRON Jobs
For automatic component operation, set up three CRON jobs:
Downloading/Updating GeoIP Databases (IP2Location):
- Script:
core/components/iskwaf/elements/cron/ip2location_download.php
- Frequency: Recommended once a month (e.g., on the 1st of each month).
- Example command:
/usr/bin/php /path/to/your/site/core/components/iskwaf/elements/cron/ip2location_download.php
Analyzing IPs, populating GeoIP details, and auto-creating rules:
- Script:
core/components/iskwaf/elements/cron/analyze_ip2location_details.php
- Frequency: Recommended every 5-15 minutes for timely rule creation.
- Example command:
/usr/bin/php /path/to/your/site/core/components/iskwaf/elements/cron/analyze_ip2location_details.php
Cleaning up old logs:
- Script:
core/components/iskwaf/elements/cron/clear_log.php
- Frequency: Recommended once daily.
- Example command:
/usr/bin/php /path/to/your/site/core/components/iskwaf/elements/cron/clear_log.php
Generating Reports:
- Script:
core/components/iskwaf/elements/cron/reports_daily.php
- Frequency: Recommended once daily.
- Example command:
/usr/bin/php /path/to/your/site/core/components/iskwaf/elements/cron/reports_daily.php
Ensure the paths to the PHP interpreter and scripts are correct for your server.
Usage (CMP)
Access the IskWaf management interface via the main MODX manager menu (usually in the "Extras" or "Applications" section).
- "Logs" Tab: View all WAF log entries with search. "Country" and "City" columns are shown, plus an "Injection" column (marked "YES" for request-inspection hits).
- Rule Tabs (IP, User-Agent, Referrer, Request URI): Manage rules, plus "Export CSV" and "Import CSV" buttons to export/import rules.
- "Report" Tab: View daily summary reports.
Rule Types (Detailed)
IP Rules
Designed to block, allow, or show CAPTCHA based on the visitor's IP address or CIDR subnet.
- Fields:
IP/CIDR, Rule Type (action), Description, Active.
- Priority Logic: An exact IP match takes precedence over a CIDR subnet. Among CIDR subnets containing the same IP, the narrower one (largest mask) takes precedence.
Pattern Examples for IP/CIDR:
- Single IPv4:
192.168.1.100
- IPv4 CIDR (subnet):
10.0.0.0/8
- IPv6 CIDR:
2001:db8::/32
Country Blocking (black/white list)
This is not a separate rule type in the interface but a built-in WAF mechanism. Two list modes are supported:
- Blacklist (
iskwaf_iskwaf_blocked_countries): traffic from the listed countries is blocked.
- Whitelist (
iskwaf_iskwaf_allowed_countries): if set, only the listed countries are allowed and all others are blocked. The whitelist takes precedence over the blacklist (when a whitelist is set, the blacklist is ignored).
- Country resolution mode: depends on
iskwaf_iskwaf_country_check_mode — cached (from the details table populated by CRON) or realtime (direct IP2Location lookup at request time; new IPs are blocked instantly).
- Exceptions: verified search bots and companies in the ASN allow lists pass even if the country is blocked (see below).
- If the country cannot be resolved (not in the database), the IP is not blocked (fail-open) so that unidentified addresses are not cut off.
- In the log, such a block records the reason, mode and source in the notes, e.g.:
Reason: country not in whitelist. Mode: realtime (source: table).
User-Agent Rules
Allow applying actions based on the User-Agent string.
- Fields:
User-Agent Pattern, Pattern Type ('contains', 'exact', 'regex'), Rule Type (action), Description, Active.
Pattern Examples for User-Agent Pattern:
- Type:
contains, Pattern: AhrefsBot
- Type:
regex, Pattern: /^EvilCorp Crawler\/[0-9\.]+/i
Referrer Rules
Filter requests based on the HTTP Referrer.
- Fields:
Referrer Pattern, Pattern Type ('contains', 'exact', 'regex'), Rule Type (action), Description, Active.
Pattern Examples for Referrer Pattern:
- Type:
contains, Pattern: spam-site.com
- Type:
regex, Pattern: /^https?:\/\/([\w-]+\.)*spammerdomain\.com/i
Request URI Rules
Apply actions based on the requested URI.
- Fields:
URI Pattern, Pattern Type ('contains', 'exact', 'regex', 'starts_with'), Match Query String (yes/no), Rule Type (action), Description, Active.
Pattern Examples for URI Pattern:
- Type:
exact, Query String: no, Pattern: /wp-login.php
- Type:
starts_with, Query String: no, Pattern: /admin-backup/
- Type:
contains, Query String: yes, Pattern: eval(
Search Bot Verification
To prevent genuine search bots from being caught by blocking (by country, ASN, etc.), IskWaf verifies their authenticity. The check runs at the very beginning of request processing: if a bot is verified, it bypasses all rules.
- Enable: the
iskwaf_iskwaf_enable_dns_verification setting = "Yes".
- Hybrid method (
iskwaf_iskwaf_bot_verification_method):
asn_dns (default) — first a fast local ASN check against the IP2Location database (Googlebot=AS15169, YandexBot=AS13238, bingbot=AS8075, Applebot=AS714), then, if needed, a double DNS check (rDNS+fDNS) as a fallback;
asn — ASN only (no external DNS, faster);
dns — rDNS+fDNS only (as in previous versions).
- Caching: a successful verification of an IP is cached for 24 hours.
- Supported bots: Google, Yandex, Bing, Apple, DuckDuckGo (the latter — DNS only).
A spoofer with the "YandexBot" UA but not from Yandex's network will fail verification and fall under the regular rules.
ASN Rules & Priorities
Besides auto-creating /24 rules via CRON, IskWaf can make decisions by ASN/company name right at request time (requires geoip_db/IP2LOCATION-LITE-ASN.BIN).
- Allow lists (
iskwaf_iskwaf_auto_allow_as_names / ..._numbers) — highest priority: they always apply (regardless of the realtime-block option) and before country blocking. A trusted company is not blocked even if its country is blacklisted (or not in the whitelist).
- Block lists (
..._block_as_names / ..._numbers) — instant blocking is enabled by the iskwaf_iskwaf_enable_realtime_asn_rules option.
- Priority: allow is checked first, then block.
- In the log:
Rule type: asn ... Match: allow by AS name. Mode: realtime (source: ip2location_db|table).
CSV Export & Import of Rules
Each rule tab (IP, User-Agent, Referrer, Request URI) has "Export CSV" and "Import CSV" buttons.
- Export: exports all rules of the selected type to CSV (with a BOM for correct Cyrillic in Excel). The delimiter is set by
iskwaf_iskwaf_csv_delimiter (default ;).
- Import: the file is chosen via the standard MODX file manager (a new one can be uploaded too) and read on the server. The delimiter is auto-detected or chosen in the dialog.
- Validation on import: each row is checked (IP/CIDR format, pattern type, regex compilability, rule type). Invalid rows are skipped with a line number and reason, valid ones are imported.
- On-duplicate mode: "skip duplicates" or "update existing".
- On completion a summary is shown: added / updated / skipped / errors.
Request Inspection (SQL injection protection)
An additional defence-in-depth layer: inspecting request inputs against attack signatures (primarily SQL injections). This is not a replacement for fixing vulnerable code, but a compensating control. Disabled by default.
- What is inspected:
GET, POST, Cookie values and (optionally) the raw request body — the iskwaf_iskwaf_payload_scan_sources setting.
- Modes (
iskwaf_iskwaf_payload_inspection_mode): off — disabled; log — log only; block — 403. Run log first, tune signatures, and only then switch to block.
- Signatures (
iskwaf_iskwaf_payload_signatures): one regex per line; empty → a built-in set for common SQLi (UNION SELECT, INFORMATION_SCHEMA, SLEEP(, BENCHMARK(, ORD(MID(, UPDATEXML(, etc.). Values are normalized (raw/urldecode) before matching.
- Logging: hits are written to the main log (
triggered_rule = payload); the "Logs" tab has an "Injection" column marked "YES", with the pattern, source and parameter in the notes.
- Note: broad signatures cause false positives. For requests to component connectors (which may not fire
OnHandleRequest) you can include the iskwaf-guard.php file.
CAPTCHA System
IskWaf uses a local numeric CAPTCHA. An image with 6 digits is generated, and the user is asked to enter either the first or last three digits. Completion is remembered in the session. Displayed via the [[!IskWafCaptcha]] snippet (supports &tpl).
Reporting System
Daily summaries in IskWafReportDaily include: total WAF events, blocks, CAPTCHAs, rule allowances, triggers by rule type, search engine bot hits, top N IPs and rules (JSON). Generated by a CRON script.
Important Notes
- Order of Rule Execution: Bot verification → Request inspection (SQLi) → IP Rules → ASN (allow/block) → Country Blocking → User-Agent → Referrer → Request URI. The first triggered rule determines the action.
- Regular Expressions: Must include delimiters/flags (e.g.,
/badbot/i). Test thoroughly.
- Visitor's IP Address: Uses
$_SERVER['REMOTE_ADDR'] by default. Adapt for sites behind a proxy.
- Performance: A large number of rules or
full logging mode can impact performance.
- False Positives: Possible. Review logs regularly.
Disclaimer
IskWaf is a tool for basic protection and is not a substitute for comprehensive enterprise security solutions or specialized WAF services. Use it at your own risk. It is always recommended to have up-to-date backups of your site.