CSF - Core Shield Firewall
CSF is a modern, free, open-source firewall and intrusion-prevention system for cPanel & WHM, CloudPanel and Linux servers with no control panel - a next-generation fork of ConfigServer Security & Firewall, rebuilt on native nftables with first-class IPv4 + IPv6, an event-driven LFD 2.0, and live Threat Intelligence. This documentation covers the 2.3.2 stable release.
Overview
CSF keeps the operational model administrators already know - the same csf commands, the same csf.conf/csf.allow/csf.deny/csf.ignore files - while replacing the underlying engine with a single atomic nftables table (table inet csf). Blocking or unblocking an IP updates one set element in-kernel; it never rebuilds the whole ruleset.
- Native nftables - one
inettable for IPv4 and IPv6, dynamic sets with interval (CIDR) and timeout (temporary ban) support. - LFD 2.0 - modular log collectors feed a single decaying risk score per source, with progressive enforcement from temporary to permanent bans.
- Threat Intelligence - reputable IP/CIDR feeds load into dedicated sets with per-feed toggles and category policies.
- cPanel-native - embedded WHM interface, service/version detection, cPHulk and ModSecurity awareness, automatic port presets on install.
- Safe by design - atomic reloads, an SSH lockout guard, and a self-reverting
--safe-reloadwatchdog.
Requirements
| Component | Requirement |
|---|---|
| Operating system | AlmaLinux, CloudLinux, RHEL and Rocky 8 / 9 / 10 (supported). Ubuntu 22.04 / 24.04 LTS on the same nftables engine (community beta). |
| Control panel | cPanel & WHM (for the WHM interface and cPanel integration). The engine and CLI also run standalone. |
| Kernel / firewall | nftables with the inet family (default on modern EL9 kernels). |
| Runtime | Perl 5 (system Perl). The WHM plugin runs under cPanel's bundled Perl. |
| Privileges | root, to install and to manage the firewall. |
Installation
Download the release, verify its SHA-256 checksum, then run the installer as root. The installer detects and cleanly removes legacy CSF v15 (backing up its configuration first), migrates your settings, and auto-detects the active SSH and cPanel ports.
# 1. download + verify curl -fSLO https://shield.underhost.com/firewall/download/csf-2.3.2.tar.gz curl -fSLO https://shield.underhost.com/firewall/download/csf-2.3.2.tar.gz.sha256 sha256sum -c csf-2.3.2.tar.gz.sha256 # 2. extract + install tar xzf csf-2.3.2.tar.gz cd csf2 && ./install.sh # 3. verify, then enable enforcement csf --cpanel-check csf -l # edit /etc/csf/csf.conf, set TESTING="0", then: systemctl enable --now csf.service lfd.service csf --safe-reload
TESTING="1") so a mistaken ruleset can't lock you out. The ruleset is generated and validated but not enforced until you set TESTING="0" and reload. Use csf --safe-reload for the first enforced reload - it auto-reverts in 30 seconds unless you run csf --confirm.After install, open WHM → Plugins → Core Shield Firewall. The plugin is registered through AppConfig and renders inside the WHM chrome.
Migrating from CSF v15 or cPanel CSF
The installer handles migration automatically when it detects an existing ConfigServer Security & Firewall v15 install or the cPanel-maintained CSF fork (github.com/cpanel/cpanel-csf):
- Backs up the existing
/etc/csfbefore making changes. - Reads and carries over
csf.conf,csf.allow,csf.denyandcsf.ignore. - Removes the legacy iptables-based CSF and its
lfddaemon so no stale rules remain. - Installs the nftables engine and re-applies your allow/deny lists as set elements.
/etc/csf/csf.conf after upgrading - a few legacy-only options have no nftables equivalent and are ignored. Old deny entries from a previous CSF are preserved but can be pruned at any time.CloudPanel & servers with no panel
From 2.3 CSF also runs on CloudPanel and on Linux servers with no control panel (tested on Debian 12 / 13, Ubuntu 22.04 / 24.04 / 26.04, AlmaLinux 8 / 9 / 10, Rocky 9 and CloudLinux 9). The installer detects the platform and sets the ports for you, and installs any missing Perl modules and nftables; instead of WHM you get a standalone web interface. If ufw or firewalld is active, disable it once CSF is enforcing.
| Platform | Ports opened on a fresh install | Interface |
|---|---|---|
| cPanel & WHM | auto-detected SSH + cPanel service ports | WHM plugin |
| CloudPanel | TCP 22, 80, 443, 8443 · UDP 443 (HTTP/3); 22 and 8443 are lockout-protected | standalone web UI |
| No control panel | TCP 22, 80, 443; a custom SSH port in sshd_config or sshd_config.d is detected | standalone web UI |
# 1. download + verify curl -fSLO https://shield.underhost.com/firewall/download/csf-2.3.2.tar.gz curl -fSLO https://shield.underhost.com/firewall/download/csf-2.3.2.tar.gz.sha256 sha256sum -c csf-2.3.2.tar.gz.sha256 # 2. install (platform is detected automatically) tar xzf csf-2.3.2.tar.gz cd csf2 && sh install.sh # CloudPanel: also publish the web UI on your own HTTPS domain CSF_UI_DOMAIN=fw.example.com sh install.sh # 3. check the platform and create a web UI login csf --platform csf --ui-user add admin # password + authenticator (2FA) code
The web interface (csf2-ui, a systemd service) listens on 127.0.0.1:6789 only, so it is never exposed directly. Reach it in one of three ways:
- CloudPanel: install with
CSF_UI_DOMAIN=fw.example.com, or add it yourself in CloudPanel: Add Site → Reverse Proxy → http://127.0.0.1:6789. - Any server: an SSH tunnel,
ssh -L 6789:127.0.0.1:6789 root@your-server, then openhttp://127.0.0.1:6789. - Your own reverse proxy (nginx, Caddy…) with HTTPS in front of
127.0.0.1:6789.
Sign-in uses SHA-512 hashed passwords with TOTP two-factor authentication, CSRF protection, session timeouts and a per-IP lockout; failed sign-ins are written to /var/log/csf2-ui.log, which LFD watches. Manage accounts with csf --ui-user add|passwd|del|list. To change the port preset later: csf --platform-setup cloudpanel or csf --platform-setup generic.
Malicious upload scanning
New in 2.3. Every 5 minutes CSF scans the website files that changed since the last run with ClamAV (with the rfxn / Linux Malware Detect signatures), YARA (rfxn + YARA-Forge rules) and built-in checks. A file matching a web-malware signature is moved to quarantine (/var/lib/csf/quarantine) and its uploader is blocked for 24 hours when the FTP log, or the web log within 2 minutes of the upload, names exactly one public IP. Built-in heuristic findings are only logged. One alert e-mail is sent per run with detections.
csf --scan-setup # install ClamAV + YARA, download signatures, turn scanning on csf --scan-status # engines, signatures, last scan csf --scan /home/user/public_html --report-only # full scan of one site, change nothing csf --quarantine list # then: restore <id> or delete <id>
Website folders are found per platform (cPanel accounts, CloudPanel sites, /var/www), plus SCAN_PATHS. Settings: SCAN_ENABLE, SCAN_ACTION (quarantine or alert), SCAN_BLOCK_UPLOADER, SCAN_ALERT_TO (empty = root, none = off), SCAN_EXCLUDE, SCAN_MAX_SIZE. When Imunify360 is installed CSF leaves scanning to it unless SCAN_FORCE="1".
WHM interface
The embedded WHM interface presents everything through a light, tabbed UI designed to stay usable with thousands of blocked IPs (every list is searchable and paginated).
| Tab | What it does |
|---|---|
| Dashboard | Protection score, threat level, quick block/allow/unblock, and a safe reload button. |
| Security Level | One-click Low / Medium / High / Attack presets that set risk thresholds and enforcement policy. |
| Threat Intel | Master switch plus per-feed ON/OFF toggles, feed status, and "Update feeds now". |
| Firewall | Start / stop / restart the firewall (with a live operation log), safe reload, flush temporary blocks, a status overview, an open-ports view, and the one-click Cloudflare edge allowlist. |
| Deny / Allow / Temporary | Searchable, paginated lists with inline add and remove. |
| LFD & Events | The most recent LFD detections and enforcement actions. |
| Malware Scan | Upload scanning on/off, action (quarantine or alert only), uploader blocking, alert e-mail, set-up and signature update buttons, the quarantine with Restore / Delete, and recent scan activity. |
| Configuration | The full csf.conf - every setting with help text and Off/On toggles, searchable. |
| Diagnostics | System health plus cPanel, cPHulk, ModSecurity, IPv6 and nftables status. |
| Update | Installed vs latest version, a one-click in-place updater with a live progress bar. |
Updating
CSF checks the release channel and shows an update-available indicator in the interface. There are two ways to update in place - both preserve your configuration, deny/allow lists and Threat Intel sets, and reload the firewall automatically when finished.
From WHM (recommended)
Open the Update tab (or click the "Update now" indicator), then press Update. CSF downloads the new release, verifies its SHA-256, installs it, and shows progress live. When it reaches 100% the interface reloads on the new version.
From the command line
csf --self-update # update to the latest stable release csf --self-update --force # reinstall the current version
The updater downloads from releases/latest.json, aborts on any checksum mismatch, and writes progress to /var/lib/csf/update.progress for the WHM progress bar.
CLI reference
The csf command preserves the familiar CSF flags and adds modern long forms. Every mutating command goes through the engine, so single-IP operations touch one set element and never rebuild the ruleset.
| Command | Description |
|---|---|
csf -a IP [comment] | Allow an IP / CIDR. |
csf -d IP [comment] | Deny an IP / CIDR. |
csf -dr IP / -ar IP | Remove a deny / allow entry. |
csf -td IP [ttl] | Temporary deny (native set timeout; ttl like 3600, 30m, 2h). |
csf -ta IP [ttl] / -tr IP | Temporary allow / remove a temporary entry. |
csf -tf | Flush all temporary entries. |
csf -g IP / csf inspect IP | Inspect the state of an IP (blocked, allowed, where). |
csf -l | Firewall status summary. |
csf -r / --safe-reload | Rebuild + apply atomically; --safe-reload auto-reverts unless confirmed. |
csf --confirm / --revert | Keep or roll back a safe reload. |
csf health | Run health checks (table, sets, policy, IPv6). |
csf --selftest | Verify CSF is actually protecting the server. |
csf --ti-update / --ti-status | Refresh / show Threat Intelligence feeds. |
csf --self-update | Download + verify + install the latest release. |
csf --cf-enable / --cf-update | Add all Cloudflare edge IP ranges to the allow list. |
csf --cf-disable | Remove the Cloudflare ranges from the allow list. |
csf migrate | Import legacy CSF configuration and lists. |
csf -v / -h | Version / help. |
Configuration
Configuration lives in /etc/csf/csf.conf, a familiar KEY="value" file. Every setting is also editable in the WHM Configuration tab, which shows help text for each key. Common keys:
| Key | Purpose |
|---|---|
TESTING | 1 = validate only (not enforced), 0 = enforce. Installs default to 1. |
TCP_IN / TCP_OUT | Permitted inbound / outbound TCP ports. |
UDP_IN / UDP_OUT | Permitted inbound / outbound UDP ports. |
INPUT_POLICY | Default input policy (drop recommended). |
IPV6 | Enable first-class IPv6 filtering. |
TI_ENABLE | Master switch for Threat Intelligence. |
TI_<FEED> | Per-feed toggles (e.g. TI_SPAMHAUS_DROP4, TI_FEODO). |
PERM_AFTER, HALFLIFE | Risk-scoring thresholds used by LFD 2.0 (set via Security Levels). |
After editing ports or policy, apply with a reload (WHM Firewall → Reload, or csf --safe-reload).
Security levels
Security Level presets set the risk-scoring and enforcement posture in one click:
- Low - lenient thresholds, slower escalation. Fewest false positives.
- Medium - balanced defaults for a typical shared/hosting server.
- High - aggressive scoring and faster permanent bans.
- Attack - hardened posture for an active incident; quickest escalation and strictest drop logging.
LFD 2.0 & risk scoring
The Login Failure Daemon (lfd) tails service logs through independent collectors (SSH, Exim, Dovecot, FTP, web server, ModSecurity/WAF), normalises each hit into a structured event, and rolls all signals for one source into a single decaying risk score. As the score crosses thresholds, enforcement escalates from a short temporary block to a longer one and finally to a permanent deny. Every action carries a human-readable reason. High-confidence, repeated WAF attacks are escalated from the application layer to a network-layer drop.
Threat Intelligence
The Threat Intelligence module downloads reputable IP/CIDR reputation feeds and loads them into dedicated nftables sets - never into csf.deny - so your manual lists stay clean and the feeds can be toggled independently. Feeds refresh hourly via cron and on demand with csf --ti-update.
| Category | Feeds | Policy |
|---|---|---|
| High confidence | Spamhaus DROP / DROPv6 | Block inbound and outbound. |
| Botnet C2 | Feodo Tracker | Block outbound (cuts active command-and-control). |
| Attackers | CINS Army, IPsum, Blocklist.de | Block inbound. |
Outbound Threat Intel drops are placed before the outbound established-accept rule, so an already-open connection to a known-malicious host is severed rather than grandfathered.
Cloudflare
When sites sit behind Cloudflare, all visitor traffic arrives from Cloudflare's edge network. If LFD ever blocked one of those shared edge addresses, it would break every proxied site at once. The Cloudflare edge allowlist prevents that: enable it from the WHM Firewall tab (or run csf --cf-enable) and CSF fetches Cloudflare's published IPv4 and IPv6 ranges and adds them to your allow list, tagged Cloudflare so they're easy to see and remove.
- Ranges are fetched live from
cloudflare.com/ips-v4andips-v6, with a pinned fallback if the server can't reach them. - Entries appear in the Allow List tab tagged
Cloudflare; direct-to-origin abuse is still blocked normally. - Use Refresh ranges (or
csf --cf-update) after Cloudflare changes its network; Disable (orcsf --cf-disable) removes them cleanly.
Architecture
CSF maintains a single atomic table, table inet csf, applied via nft -f. Traffic is filtered against named sets:
csf_allow4/csf_allow6- allowlisted sources.csf_deny4/csf_deny6- permanent denies (interval/CIDR).csf_temp4/csf_temp6- temporary blocks with native timeouts.csf_ti_high4/6,csf_ti_botnet4/6,csf_ti_attackers4/6- Threat Intelligence sets by category.
Because state lives in sets, adding or removing a single IP is an incremental set operation - fast, atomic, and safe under load - while a full reload regenerates and validates the entire ruleset before swapping it in.
Uninstalling
cd csf2 && ./uninstall.sh # removes CSF, keeps /etc/csf config + backups cd csf2 && ./uninstall.sh --purge # also removes config and state
The uninstaller removes the nftables table so no stale rules remain, detaches services, and unregisters the WHM plugin. Verify nothing remains with nft list ruleset | grep -i csf.
Troubleshooting
The firewall isn't enforcing
Check TESTING in csf.conf. When TESTING="1" the ruleset is validated but not applied. Set it to 0, enable the services, and run csf --safe-reload.
The WHM plugin opens as a blank/standalone page
The plugin must run under cPanel's Perl. Re-running ./install.sh rewrites the shebang and re-registers AppConfig. Confirm the menu entry is Core Shield Firewall at /cgi/cpanelshield/firewall.cgi.
Am I actually protected?
Run csf --selftest: it confirms the kernel table is loaded, runs a block test, and checks that services are active and enabled.
An update failed
The updater aborts safely on any checksum mismatch and leaves the running version intact. See /var/lib/csf/update.log for the installer output.
Changelog
2.3.2 - 2026-11-06 · Security update - please update
- Critical: the firewall interface could run a script from an uploaded file name. The comment the malware scanner writes for a blocked uploader includes the file name, and the allow, deny and temporary lists showed comments without escaping them. A crafted file name could run a script in the administrator's interface (inside WHM on cPanel). Comments are now escaped, and the scanner removes markup from file names before storing them.
- High: quarantine restore no longer writes as root. A restore could follow a folder that the site owner had replaced with a symbolic link and write the file outside the website. A restore now refuses any path through a symbolic link and writes the file as its original owner.
- Quarantine never follows a symbolic link swapped in after the scan, and only removes the file it actually scanned.
- The web interface trusts a proxy's visitor address only with a secret key. Other processes on the server could send a fake address to slip past the sign-in lockout or get another address blocked. The installer creates
/etc/csf/ui.proxykeyand adds it to the nginx sites that proxy to the interface. Sign-in is also paused for everyone after 50 failed attempts in 15 minutes. - File names with line breaks are no longer scanned (they are reported as suspicious), and scanner results are only accepted for files that were actually scanned.
- The version now comes from a single
VERSIONfile.
2.3.1 - 2026-11-06 · Never lock out the administrator
- The installer allows your SSH address. Like legacy ConfigServer CSF, the IP of the SSH session running
install.shis added to the allow list, also undersudo. Updates run from cron or the web interface have no SSH session and skip this. - The malware scanner never blocks a trusted uploader: an IP on the allow list, in
csf.ignore, or an administrator who signed in to the web interface. The file is still quarantined. On servers without a panel the interface shares the web server log with the sites, so an administrator signing in at the moment of an upload could be taken for the uploader. csf --scan-setupruns the first scan right away instead of waiting for the 5-minute schedule.
2.3.0 - 2026-11-06 · Core Shield Firewall, stable for every platform
- New name: CSF is now Core Shield Firewall (formerly cPanel Shield Firewall), one code base for cPanel, CloudPanel and servers with no control panel, with a new full logo.
- Important - the firewall now comes back after a reboot. The
csf.serviceunit had an ordering cycle, so systemd silently skipped it at boot: a rebooted 2.1.x / 2.2.x server ran with no CSF rules and no LFD until restarted. Update every 2.x server. - Longer LFD blocks really last longer. Repeat attackers are escalated, but nftables kept the first, short timeout, so the IP was free again after 5 minutes. Each IP now has one entry and the longer block is applied in the kernel; a shorter request never shortens a block.
- LFD never blocks the server's own addresses. The list of local IPs was always empty.
- New: malicious upload scanning - ClamAV + rfxn signatures and YARA every 5 minutes, quarantine, uploader blocking, e-mail alerts and the Malware Scan tab. See Malicious upload scanning.
- New: LFD reads the systemd journal when there is no
/var/log/auth.logor/var/log/secure(Debian 12 / 13), so SSH brute force is detected there too (LF_JOURNAL).csf --selftestnow fails when LFD has no source for SSH failures. - CloudPanel and no panel are stable (they were the 2.2 release candidate), tested on 10 Linux distributions with a reboot and a real SSH brute-force attack on each.
- Installer: installs missing Perl modules and nftables (minimal images), restores SELinux labels (AlmaLinux / CloudLinux 8: the units were invisible to systemd), warns when firewalld is active, and shows the real version and the next steps for your platform. Scanner set-up waits for the package lock, enables EPEL on CloudLinux and works with YARA 4.1.
2.1.6 - 2026-11-06 · Important: LFD really runs
- LFD now starts after an install or update. The installer (and therefore every update, which re-runs it) only enabled
lfd.servicefor the next boot without starting it, so a server installed or updated since its last reboot was not banning brute-force attackers. When the firewall is enforcing, the installer now enables and (re)starts LFD - an update also loads the new LFD code - and prints whether LFD is running. csf --selftestcatches it. A stopped LFD on an enforcing firewall is now a FAIL with the fix command (it was only a warning, and an oldlfd.logmade the detection check pass).csf.serviceis judged together with the loaded ruleset.- Update now from the WHM Update tab or with
csf --self-update, then runcsf --selftest.
2.2.0 RC2 - 2026-11-06 · Release candidate: CloudPanel & no control panel
- Runs beyond cPanel. Detects cPanel, CloudPanel or a plain Linux server (
csf --platform) and applies the right port preset on a fresh install (csf --platform-setup cloudpanel|generic), readingsshd_config.dfor the SSH port. - Standalone web interface (
csf2-ui) for servers without WHM: the same firewall UI on 127.0.0.1:6789 with login, TOTP two-factor authentication, CSRF protection, sessions and per-IP lockout; accounts viacsf --ui-user. Failed sign-ins are logged for LFD. - CloudPanel:
CSF_UI_DOMAIN=fw.example.com sh install.shpublishes the UI as an HTTPS reverse-proxy site. - The firewall CGI now refuses to run outside WHM unless the standalone UI launched it. Migration drops the unused legacy
UI_*settings. - Includes the 2.1.6 LFD start and self-test fixes (RC2; RC1 was built 2026-11-05).
- Superseded by 2.3.0 stable.
2.1.5 - 2026-08-26 · Critical: Threat Intel hang fix
- Fixed a hang in Threat Intelligence updates. Large feed sets were fed to
nftover a stdin pipe, which could deadlock once the script exceeded the OS pipe buffer - leavingcsf --ti-updateand itsnft -fchild stuck at 0% CPU. The hourly cron then stacked a new hung pair every hour until the server ran out of resources. nft is now fed via a temporary file (no pipe, no deadlock). csf --ti-updatenow takes a single-instance lock (a second run skips instead of stacking) and a hard 5-minute timeout so a run can never live forever.
2.1.4 - 2026-08-26 · Update-tab fix
- Fixed a reload loop on the WHM Update tab: progress is followed with AJAX polling, and the page reloads only once when an update genuinely completes - never on a stale progress value from a previous run.
2.1.3 - 2026-08-26 · UI & update polish
- Firewall operation log is now a readable light panel (it was low-contrast under WHM's default styling).
- Cleaner Cloudflare cloud mark on the Firewall tab.
- The update check is cache-busted so an intermediate CDN or a stale local cache can no longer report an old "latest release"; a cached manifest behind the installed version is discarded, and the cache is cleared after an update.
2.1.2 - 2026-08-26 · Update reliability
- Fixed the WHM /
csf --self-updateupdater on hardened servers: the installer now runs viashand extracts under/var/lib/csf, so updates work even when/tmpis mountednoexec. - In-place upgrades replace the module tree cleanly (no more nested
CSF2/CSF2path). - Cloudflare fetch backfills a blocked IPv4 or IPv6 endpoint from the pinned list; the test suite no longer depends on outbound network.
- Cleaner WHM module footer.
2.1.1 - 2026-08-26 · Firewall control & Cloudflare
- Redesigned Firewall tab: Start / Stop / Restart controls with a live operation log, status badges, and an open-ports view (TCP/UDP in & out).
- One-click Cloudflare edge allowlist - adds all Cloudflare IP ranges to the allow list (
csf --cf-enable/--cf-disable/--cf-update). - Redesigned Diagnostics tab: status cards plus an "Administrator tests" panel that runs the self-test in place.
- Compatibility: AlmaLinux / CloudLinux / RHEL / Rocky 8, 9, 10 supported; Ubuntu 22.04 / 24.04 (beta).
2.1.0 - 2026-08-26 · First stable GA
- First stable general-availability release.
- New WHM Update tab: one-click in-place update with SHA-256 verification and a live progress bar.
- New
csf --self-updateCLI command. - Update-available indicator in the interface.
- Full-logo WHM header and "Powered by UnderHost" attribution.
- Real ON/OFF (green/red) toggle switches for Threat Intelligence feeds.
- Full documentation site and stable release framing.
2.0.x - pre-release testing
- Threat Intelligence feed manager with dedicated nftables sets and category policies.
- Branded installer, Security Level presets, extensive WHM configuration editor.
- Embedded WHM interface, cPanel auto port detection,
csf --selftest. - Native nftables engine, LFD 2.0 risk scoring, legacy CSF v15 migration/uninstall.
License
CSF - Core Shield Firewall is free software distributed under the GNU General Public License v3. It is a next-generation fork of ConfigServer Security & Firewall (© 2006-2025 Jonathan Michaelson) and is part of the UnderShield security suite by UnderHost.
