Table of contents of the article:
The problem: When managing hundreds of servers becomes a nightmare
If you've been managing Linux servers for a few years, you know exactly what we're talking about. In recent months, the phenomenon has become simply unsustainable: increasingly aggressive waves of bots from Southeast Asia, China, and Russia, and more recently, a new generation of AI-powered crawlers combing through every single page of every single website, completely ignoring robots.txt and any form of digital etiquette.
we at Managedserver.it We manage a globally distributed fleet of machines. We're talking about thousands of Linux servers spread across OVH, Hetzner, Aruba, AWS, Azure, Google Cloud, and on-premise client infrastructures in Italy, Europe, and beyond. For about six months, we'd been receiving ticket after ticket: "The site is slow," "The server is under load," "Something's wrong." And in the vast majority of cases, the culprit was the same: unwanted traffic. Bots pounding API endpoints, AI crawlers downloading entire websites, SSH brute-force attempts, and widespread port scans.
The classic response was always the same: log in to the server via SSH, analyze the logs, identify the IPs, add iptables rules manually, maybe configure Fail2ban, check to make sure no one else's rules were broken. Then move on to the next server. And the one after that. And so on.
It had become a full-time business that wasn't scaling.
The moment we said “enough”
The breaking point came during a particularly busy week when we had to simultaneously manage a distributed DDoS attack on a dozen customer servers, a wave of aggressive crawling by GPTBot and ClaudeBot on dozens of WordPress sites, and a series of automated scans on IP ranges hosting multiple customer servers.
Our workflow was embarrassingly fragmented:
- Bash command line on each individual server to apply iptables rules
- netdata to monitor resources, but on a separate interface for each server
- UptimeRobot for availability alerts, with notifications arriving without context
- Spreadsheets to keep track of which rules were applied where
We didn't have a clear overview. We couldn't immediately see which servers had the same rules, which were protected against a specific IP range, and which weren't. Applying a new blocking rule to all servers meant connecting one by one, with the real risk of forgetting a machine or, worse, inserting the wrong rule that blocked legitimate traffic with no quick rollback.
We needed a single, centralized tool that gave us total control.
And since we couldn't find anything on the market that did exactly what we needed—something lightweight, compatible with any Linux distribution, and that didn't require heavy agents or crazy dependencies—we decided to build it ourselves.
It was born like this CFM 4 Linux — Centralized Firewall Manager — or more simply, CFM.
Architecture: One server, many agents, zero NAT issues
Before we dive into the features, it's worth a quick word about the architecture, as it's one of the design choices we're most pleased with.
CFM is composed of two components:
The Server (the “control room”)
The server is a web application built in PHP 8.3 to Nginx e PostgreSQL 18 as a database. The choice of PostgreSQL is not accidental: its native type CIDR and GIST indexes allow us to query IP addresses with a speed and precision that MySQL couldn't offer. JSONB for structured data, advanced aggregation capabilities, and triggers to ensure audit log immutability.
The server exposes a modern web console built with Table (Bootstrap 5 framework for administrative dashboards) that offers a clean, responsive interface that's a joy to use for hours. It supports light and dark themes, and—for those with a nostalgic streak—a "Matrix" mode with a green phosphor-on-black background aesthetic, including a CRT scanline effect.
The Agent (the “soldier in the field”)
The agent is a single static binary written in Go 1.22, cross-compiled for Linux amd64 and arm64. No dependencies, no runtimes to install, no shared libraries. Download it, make it executable, run it. Done.
The agent adopts a pull model: it periodically contacts the server via HTTPS to ask "anything new?", download the updated policy, and apply it. This elegantly solves the problem of NAT and intermediate firewalls—no need to open incoming ports on managed servers, no need to configure VPNs, no need to do anything. If the server can make an outgoing HTTPS connection, it works.
Authentication occurs via Bearer token (SHA-256 hash stored in the database) and initial enrollment uses one-time tokens. Policy changes are detected via HTTP ETag — if there is nothing new, the agent receives a 304 Not Modified and wastes no bandwidth or resources.
How the rules are applied
The agent automatically detects the firewall backend available on the system:
- iptables (the classic, supported everywhere)
- nftables (the modern successor, with named sets for O(1) lookup)
- firewalld (RHEL/CentOS/Fedora, with intelligent fallback)
Rules are applied using custom chains (CFM_SAFETY, CFM_INPUT, CFM_FORWARD) through iptables-restore --noflushThe flag --noflush it is fundamental: it means that CFM touches only his chains, without interfering with Fail2ban, CSF, Docker, or any other tool that manages its own iptables rules on the same server. Coexistence is guaranteed by design.
The chain CFM_SAFETY It is inserted in position 1 on the INPUT chain with maximum priority and contains:
- The ESTABLISHED/RELATED rule (traffic from already established connections is never blocked)
- The loopback (same for obvious reasons)
- The IPs of the server's local interfaces (to prevent the node from blocking itself)
- The CFM server IP (to never lose management connectivity)
- The system's DNS nameservers and the most common public DNS (to avoid breaking DNS resolution)
- The global whitelist (IPs that must always be reachable, no matter what)
Only after the safety chain are the blocking rules processed CFM_INPUT e CFM_FORWARD.
In case of an error in applying the rules, the agent performs a automatic rollback to the previous configuration, ensuring that the server is never left in an inconsistent state.
The Dashboard: Everything under control at a glance
When you log in to CFM, the first thing you see is the dashboard. And it's designed to answer the most important question: "What's up now?"
The KPI cards at the top
A row of colored cards immediately shows you:
- Active nodes / stale / revoked / total
- Policy Rules active
- Geoblocks active
- ASN Blocks active
- White list entries
- Groups configured
- Threat feeds active
- Override node-specific
- Temporary blocks (last 24 hours)
If there are situations that require attention — disabled firewalls, out-of-sync nodes, expiring blocks — an orange warning panel automatically appears with the details.
The map of the world
In the center of the dashboard is a interactive map (based on amCharts) that shows the geographic distribution of your nodes. Each point on the map represents a managed server, with color indicating its status. It's incredibly useful for getting an immediate visual overview of your infrastructure.
Timeline of activities
On the right, a timeline shows recent actions: who added a rule, who modified an override, when a node last synced. It's your firewall's "news feed."
Synchronization graph
A dedicated graph shows the synchronization status of nodes over time: how many are aligned with the latest policy, how many are behind, and how many have experienced errors.
Policy Management: The Heart of CFM
The Policy page is where the magic happens. It's the central point from which you control firewall rules. all your servers at the same time.
The Global Whitelist
At the top of the page you will find the global whitelist — the IPs and CIDRs that must always be reachable, on all nodes, regardless of any blocking rules. Each entry requires a mandatory reason (for the audit trail) and supports an optional expiration.
The whitelist is powerful: you can add individual IPs (93.184.216.34), CIDR (10.0.0.0/24), IP range (192.168.1.100-192.168.1.200 — which are automatically converted to the minimum CIDR set), and even integers ASN (AS13335 for Cloudflare, for example, which automatically resolves all IPv4 and IPv6 prefixes from the autonomous system).
Whitelist rules are inserted into the chain CFM_SAFETY with target ACCEPT and processed before of any blocking rule. If an IP is both blocked and whitelisted, the whitelist always wins.
The Blocking Rules
The Active Rules table shows all policies in effect with:
- CIDR of the blocked IP
- Direction (Input, Forward, or both)
- Action (Drop or Reject)
- Protocol e Port (optional — for surgical blocks)
- Motivation
- Expiration date (colored badge indicating the remaining time)
- Who created the rule
Above the table, you'll find a real-time search bar and filters by direction, action, and status (permanent, temporary, expiring). Pagination seamlessly manages policies with thousands of rules.
The rule add form accepts flexible input. You can enter:
- A single IP:
185.220.101.34 - A CIDR:
185.220.101.0/24 - A range:
185.220.101.1-185.220.101.50 - An ASN:
AS4134(China Telecom — and CFM automatically resolves all prefixes) - A country code:
CN(and CFM blocks all associated GeoIP prefixes)
For each rule you can specify the duration: permanent, 1 hour, 3 hours, 6 hours, 12 hours, 24 hours, 3 days, 7 days, or 30 days. Temporary rules expire automatically and are removed by a dedicated cron job.
Geo-Blocking
This is one of the features we use most. The Geo-Blocking section allows you to block entire countries or entire continents with one click.
Two display modes:
- By Country: a list of all countries with checkboxes, search bar and quick action
- By Continent: Select a continent and all countries within it are blocked/unblocked
GeoIP data comes from two configurable sources:
- DB-IP Lite (free, high-precision database)
- RIR Delegations (the regional Internet registries: RIPE, ARIN, APNIC, LACNIC, AFRINIC)
The system imports the CIDR prefixes associated with each country and inserts them as normal policy rules, except that they are marked as “GEO:” in the reason and are protected from accidental deletion (you cannot remove them from the rules table — you must use the dedicated Geo section).
When the agent applies large-scale geo-blocking (blocking China means ~80.000 IPv4 prefixes), it uses optimized strategies to avoid creating hundreds of thousands of linear iptables rules:
- Su nftables: use named set with interval flag — O(1) lookup regardless of the number of prefixes
- Su iptables: use a proprietary system to increase performance and reduce the recordset in memory.
The Block for ASN
The Autonomous System Number is a network's identifier. Instead of blocking individual IPs, you can block an entire network by ASN. CFM automatically resolves the ASN into its IP prefixes using two sources:
- RIPEstat API (primary source)
- BGPView (fall back)
ASN blocking is dynamic: with the "Refresh All" button, you can re-resolve all blocked ASNs to capture any new prefixes added by the network operator. A maximum of 5.000 prefixes per ASN is allowed to prevent abuse.
Threat Feeds
CFM can automatically import blocklists from threat intelligence sources:
- FireHOL (blocklist aggregator)
- Spamhaus DROP (Don't Route Or Peer)
- Abuse.ch (malware, C2 botnet)
- And many more — with the ability to add custom feeds
Each feed is automatically updated according to the configured schedule, and rules are tagged with “Feed: feed_name” for easy identification.
Bulk Operations
For emergency situations (read: it's Friday night and a botnet is hammering 47 servers), CFM offers:
- Bulk imports: paste a list of IPs (one per line, supports # comments), choose direction/action/duration/motivation, preview and then execute in one click
- Delete bulk: select the rules with the checkboxes and delete them in bulk
- Delete filters: apply a filter and clear all visible rules
- Export/Import configuration: Export the entire configuration (policy, whitelist, geo, ASN, groups, overrides) to a JSON file and reimport it on another CFM instance
Policy Versioning
Every single change to the policy — be it an addition, a removal, an import — automatically generates a new immutable versionNo “draft” to save manually: change something, a new version is created, and at the next poll the agents download it.
From the page Historical Policy you can:
- See all versions with timestamp, author and number of rules
- Compare two versions side-by-side (visual diff)
- Do rollback to any previous version with one click
Rolling back doesn't erase the current version; it creates a new version identical to the target version. The history is always preserved for a complete audit trail.
Draft Mode
For complex changes that require multiple steps, CFM offers a draft mode. When you activate it:
- Agents continue to see the “frozen” version (the one active when the draft is activated)
- You work on the live version in the web console
- A yellow banner shows you how many changes you have pending.
- You can see thepreview of the differences (rules added/removed)
- When you're satisfied, publish the draft and all agents receive the new version.
- If you change your mind, discarded the draft and everything goes back to how it was before
This is especially useful when you need to do significant rule restructuring without risking exposing agents to incomplete intermediate policies.
The Nodes: individual and group management
The Nodes page
The node list is your fleet. Viewable in mode list (detailed table) or card (visual grid with state), each node shows:
- Name, IP, operating system
- Status (active/stale/revoked) with colored badge
- Last sync
- Version of the applied policy
- Version of the installed agent (with indication if an update is available)
- Firewall status (enabled/disabled)
- Toggle for various monitors (CPU, RAM, traffic, disks, network)
Enrolling a new node is simple: generate a token from the console, run the enrollment command on the agent, and the node automatically appears in the list.
Node Detail
By clicking on a node, a very rich detail page opens:
Information card at the top with hostname, IP, OS, time since last contact, sync status, and toggle to enable/disable the firewall on that specific node.
Override per node: you can add rules that apply required for that node — either “allow” (local whitelist) or “deny” (local block). This is perfect for situations like “client X’s server needs to be reachable from their office IP address even if that IP address is in a globally blocked range.”
ExclusionsYou can override global rules specific to a node. If you've globally blocked a certain CIDR, but a specific node needs to reach it, overriding it solves the problem without affecting the global policy.
Geo-Policy per node: each node can have its own independent geographic policy, with three modes:
- inherit: follows global policy
- Allow-Only: only whitelisted countries can reach the server (useful for servers serving a specific market)
- Deny-Only: block specific countries (the default for most scenarios)
With quick actions to block/allow entire continents or search for individual countries.
Synchronization history: table with each agent sync — timestamp, policy version, outcome (applied/failed/rollback), number of rules applied, any error message.
Group membership: list of groups the node is part of, with a direct link to group management.
Tags: customizable key-value pairs (environment: production, client: acme, role: webserver) useful for organizing and filtering nodes.
The Groups
Groups allow you to organize nodes by customer, environment, role, or any other criteria. A node can belong to multiple groups at the same time.
The power of groups lies in the ability to define group rules: Rules that apply only to member nodes of that group, in addition to global rules. Perfect for scenarios like:
- “All ACME client servers must block this IP range”
- “All production servers must have this additional whitelist”
- “All web servers must block non-standard ports”
The effective policy of a node is always: global rules + membership group rules + node-specific overrides.
The Policy Tester
One of the most useful features in daily operations. Enter an IP, CIDR, or ASN, and CFM tells you immediately on which nodes that traffic would be blocked, by which rule, and with what action.
This is invaluable for troubleshooting: “Client says he can't reach his server, his IP is 203.0.113.45” → you enter it into Policy Tester → you find out he's blocked by the GEO:CN rule because his ISP uses an IP range originally assigned to China → you add an override allow for that node → problem solved in 30 seconds.
And then we thought, “What if we added monitoring, too?”
Having centralized control over the firewall was fantastic. But we still had to jump between CFM, Netdata, CheckMK, and UptimeRobot to get the full picture. Every time a load alert came in, we had to open another interface to understand what was happening.
So we said to ourselves: the agent is already on the server, it already communicates with the central server, why not have it collect monitoring data too?
And since then CFM has become much more than a firewall manager.
Uptime Monitoring
The Uptime page shows the historical availability of each node on 7, 30 and 90 day windows.
For each node see:
- Uptime percentage (with colors: green >99.9%, yellow >99%, red the rest)
- Number of checks carried out
- Number of accidents
- An temporal heatmap expandable that visually shows when the node was up/down
Uptime data is derived from the agent's heartbeat: if the agent does not contact the server within the configured threshold (default 10 minutes), the node is considered “stale” and the incident is logged.
CPU Monitor
The agent reads /proc/loadavg and send the values of load average at 1, 5 and 15 minutes along with the number of active threads. The server stores the history, and the CPU Monitor page shows:
- List of all nodes with active CPU monitoring
- Sortable columns: Load 1m, Load 5m, Load 15m, CPU%
- For each node, a expandable graph with time interval selector (30 minutes, 1 hour, 3 hours, 6 hours, 12 hours, 24 hours)
- Toggle Live for automatic update every 10 seconds
- List or card view
The button groups for selecting the time range use a consistent style across all monitoring pages: compact buttons with active states highlighted in blue and a Live checkbox for auto-refresh.
RAM Monitor
The agent reads /proc/meminfo and collects:
- Total, available, and used memory (in MB and percentage)
- Buffer and cache
- Total and used swap
The RAM Monitor page displays synthetic badges for each node (RAM%, Used MB, Cached MB, Swap Used) and expandable graphs with the same time-range controls and live update as CPU.
This allowed us to quickly identify servers with memory leaks, runaway processes, or improper swap configurations—all from a single interface.
HDD Monitor (Disk Health)
Here the agent does something particularly clever: it automatically detects the disk subsystem in use and monitors its health:
- RAID array (mdadm): Array status, active disks, degraded/failed disks
- ZFS Pool: pool status, vdev status, read/write/checksum errors
- Single discs: SMART information (if available)
The page shows the status with colored badges:
- Healthy (green): everything's ok
- Degraded (yellow): attention required
- Failed (red): urgent intervention
For each node, you can expand the details to see exactly which disk or array is having problems.
Disk Monitor (Disk Space)
Complementary to the HDD Monitor, the Disk Monitor shows theusing partitions:
- Device, mount point, filesystem type
- Total, used, free space (in MB/GB)
- Usage percentage with colored progress bars
- Historical charts to track the growth of space used over time
Data is collected by the agent every 10 minutes and allows you to predict when a disk space will run out, before it becomes an emergency.
Net Monitor (Network I/O)
The agent collects statistics for each network interface:
- Bytes received (RX) and transmitted (TX)
- RX and TX errors
- Delta between subsequent readings
The graphs show throughput over time for each interface, allowing you to quickly identify bandwidth saturations, abnormal peaks, or interfaces with errors.
Traffic (Firewall Statistics)
This is the functionality that ties monitoring to the firewall. The agent collects the iptables counters (iptables -L <chain> -v -n -x) for all CFM chains and calculates the deltas between the readings.
The Traffic page offers:
- Summary cards: Total packets and bytes processed
- Historical chart: timeline with range from 1 hour to 7 days
- Top knots for firewall traffic
- Detail per node with bar chart of individual chains
This tells you not only how much traffic your rules are blocking, but also which rules are working the hardest and on which nodes. Traffic data retention is 30 days, which is sufficient for trend analysis.
Page Traffic Nodes It offers the same information but organized by node, with expandable graphs for each one and the same time range controls (1h, 3h, 6h, 12h, 24h, 3 days, 7 days) + Live toggle.
The Alerting System
Monitoring is useful. Being automatically notified when something goes wrong it is essential.
CFM includes an advanced alerting system with integrated anti-storm:
Types of Alerts
- Node Offline: a node has not communicated for more than X minutes
- CPU High: the load average exceeds a threshold for a prolonged period
- Traffic Spike: abnormal spike in firewall traffic
- RAID Degraded: A RAID array or ZFS pool is not in an optimal state
Configuring Rules
For each type of alert you can configure:
- Name descriptive
- Threshold (threshold) type-specific
- Duration (how many consecutive minutes must the condition be true before triggering the alert — anti-flapping)
- Cool down (How many minutes to wait after an alert before sending another — anti-storm)
- Scope: all nodes or a specific node
- Recovery notification: optional, alerts you when the condition returns to normal
Notification Channels
Notifications can be sent via:
- Telegram: The team's favorite channel — instant, with formatting and emoji support
- Email: for formal notifications and traceability
- webhook: for integrations with external systems (Slack, Discord, PagerDuty, or any custom HTTP endpoint)
Each channel can be configured to receive only certain types of events.
The Bell Icon
In the CFM topbar, abell icon It displays the number of active alerts in real time with a red badge. Hovering over it displays a dropdown list of the latest alerts, with icons indicating the type, name of the affected node, and elapsed time. Clicking "See all" takes you to the full alert page with history and timeline.
The Toolkit: The Systems Engineer's War Room
The Toolkit page is the first one we open when a report comes in. It's a true operational intelligence center integrated directly into CFM.
Quick Intel
Enter an IP and instantly get:
- Reverse-DNS (rDNS)
- GeoIP: country with flag, ISO code
- ASN: organization number and name
- IP Prefix of belonging
- DNSBL Status: how many blacklists contain that IP (with colors: green = clean, yellow = some reports, red = highly reported)
- CFM StateIs the IP whitelisted? Is it blocked? By which rule? Is it blocked for a specific group?
Analysis Tools
A series of tabs provide in-depth investigation tools:
| Tool | Description |
|---|---|
| WHOIS | Domain/IP Registration Information |
| DNS | Query for A, AAAA, MX, NS, TXT, SOA, CNAME, PTR records with type selector |
| Ping | ICMP echo test with response times |
| traceroute | Trace the network path to the target |
| Port Scan | Scan main ports (22, 80, 443, 8080, 3306, etc.) |
| DNSBL | Check against 50+ blacklists |
| DNSBL Extended | Additional blacklists |
| HTTP headers | Target HTTP response header |
| SSL/TLS Info | Certificate and chain details |
| AbuseIPDB | Abuse Report and Trust Score |
| CIDR Info | Expanding an IP range into a minimal CIDR set |
| Reverse IP | Domains hosted on the same IP |
| BGP Info | BGP routing information |
| ASN Lookup | ASN resolution to name and prefix |
| Log Search | Search node traffic logs for that IP |
Quick Actions
From the same page, without navigating elsewhere, you can:
- Quick Block: add IP to global policy with reason and duration
- Quick Whitelist: add IP to global whitelist
- Quick Block ASN: block the entire IP ASN
- Quick Whitelist ASN: whitelist the entire ASN
The Toolkit also supports deep linking: https://cfm.example.com/toolkit#192.168.1.1 It directly opens the toolkit with that IP pre-populated and the analysis already started. Perfect for integrating with other tools or sharing links within your team.
The SSH Web Client: One-Click Access
And here we come to one of the features that has changed our daily lives.
The problem
When an alert arrives, the first thing you want to do is log in to the server to investigate. But that meant opening a terminal, searching for the hostname, remembering (or searching for) the credentials, typing the SSH command, entering the password, and finally getting started. Multiply that by the 10-15 servers you might need to monitor during an incident, and you have a workflow that dramatically slows down the response.
The solution
CFM integrates a full-featured web SSH client based on xterm.jsFrom any node's detail page, clicking the terminal icon opens a pop-up window with a real SSH terminal in your browser.
But the best part is the VaultEach node can have SSH credentials saved in a vault protected by a master key. Once you unlock the vault (enter the master key once per session), you can connect to any server with a single click — the credentials are injected automatically and the connection starts immediately.
Credentials never pass through the browser's local storage in clear text: they are decrypted server-side and passed via URL to the popup window, where they are immediately removed from the address bar for security.
Multiple Sessions
You can have multiple SSH terminals open at onceEach session is represented by a floating bar at the bottom of the page, with the node name. The bars align side-by-side and allow you to:
- Click to bring the corresponding window to the foreground
- Close the session with the X button
- Keep your session active while you navigate between CFM pages
The system uses heartbeats via localStorage with a two-level logic: window reference as the primary signal (immune to browser timer throttling) and a 30-second heartbeat timeout as a safety net. This ensures that floating bars remain visible even when popups are in the background.
Good Bots: The Problem with “Good” Bots
Not all bots are bad. Google, Bing, Cloudflare, UptimeRobot, and many other legitimate services use bots to index, monitor, and serve the web. Blocking them would mean disappearing from search engines or disrupting essential monitoring services.
CFM includes a section Good Bots with a pre-curated list of legitimate bots organized by category:
- Search engine: Google, Bing, Yandex, DuckDuckGo, Baidu
- Social media: Facebook, Twitter, LinkedIn, Pinterest
- CDN: Cloudflare, Fastly, Akamai
- Monitoring: UptimeRobot, Pingdom, StatusCake
- webhook: Stripe, PayPal, GitHub
- AI (the “good ones”): OpenAI (for API integrations, not the crawler), Anthropic
- Cloud: AWS, Azure, Google Cloud (health checks, load balancer)
- Security: Let's Encrypt, CertBot
This feature allows you to implement a “block all except known good” strategy with the guarantee of not blocking essential legitimate traffic.
Security: Not an afterthought
CFM security itself was designed from day one, not added on afterward.
Cloudflare Turnstiles
The login page is protected by Cloudflare Turnstiles, the successor to reCAPTCHA. Unlike reCAPTCHA, Turnstile is privacy-focused and doesn't require users to select traffic lights and buses. Verification is transparent.
The setup only requires a Site Key and Secret Key (which can be obtained for free from the Cloudflare panel). The system is fail-open: if Cloudflare is unreachable, the login will still work (better a login without CAPTCHA than an impossible login in an emergency).
Two-Factor Authentication (2FA/TOTP)
Every user can (and should) enable two-factor authentication based on TOTP (Time-based One-Time Password). Setup is guided:
- Scan the QR code with your favorite app (Google Authenticator, Authy, Microsoft Authenticator, 1Password, Bitwarden)
- Enter the verification code to confirm
- Download the recovery codes (8 single-use codes, keep safe)
From that moment on, every login requires username + password + TOTP code.
Recovery codes can be regenerated at any time, and 2FA can be disabled (requires the current TOTP code + password, to prevent unauthorized disabling).
Roles and Permissions
CFM implements an RBAC system with three roles:
- admin: full access, user management, system settings
- Operator: policy management, nodes, monitoring (everything except system settings)
- Viewer: Read-only on everything (perfect for monitoring team or clients)
Immutable Audit Log
Every single action is recorded in a immutable audit log (protected by PostgreSQL triggers that prevent UPDATE and DELETE):
- Who did what?
- When
- From which IP?
- With what parameters?
The log can be filtered by action type, date, node, and user. It supports pagination and can easily handle millions of records.
Secure Communication
- All agent-server communication occurs on HTTPS
- Authentication tokens are stored as SHA-256 hash in the database (the clear token is never stored)
- User passwords use Argon2id (the winner of the Password Hashing Competition)
- Enrollment tokens are single use (once used, they are invalidated)
- The agent verifies the server's SSL certificate (no MITM)
Agent Protections
The agent itself implements several protections:
- Refusal of 0.0.0.0/0: can never block all traffic, not even by mistake
- CFM server auto-whitelist: the agent can never block its own management server
- Auto-whitelist local interfaces: the node cannot block itself
- DNS Auto-Whitelist: System nameservers and public DNS (8.8.8.8, 1.1.1.1, 9.9.9.9, etc.) are always reachable on port 53
- Automatic rollback: if the application of the rules fails, the previous rules are restored
- Input sanitization: validated protocols, ports limited to 0-65535, comments sanitized against injection
Agent Auto-Update
When we release a new version of the agent, we don't have to connect to hundreds of servers to update them. The agent automatically checks for an update every hour, downloads the new binary, and verifies the hash. SHA-256 for integrity, and restarts with the new version.
From the console you can:
- See the version installed on each node
- See if an update is available
- Force all nodes to update with one click
- Monitor update logs for each node
Internationalization
CFM is fully localized in 5 languages:
- Italian
- English
- Spanish
- French
- German
The language is changed on the fly from the selector in the top bar and is saved in a cookie + localStorage for persistence.
Statistics and Analytics
The Statistics page offers graphs Chart.js interactive:
- Nodes for state over time: timeline of how many nodes were active, stale, revoked
- Growth of rules: How your policy has grown over time
- Sync state distribution: how many nodes are in sync vs out-of-sync
- Top CIDRs blocked: ranking of the most present CIDRs in the policy
The pages we use the most (real daily use)
After months of daily use, here's our typical workflow:
The morning
- Let's open the Dashboard for an overview of the situation
- Let's check the Alert (bell in the top bar) for any night-time problems
- A quick look at the CPU Monitor e RAM Monitor for anomalies
When a report arrives
- Toolkit: we enter the reported IP, in 2 seconds we know everything: where it comes from, who it belongs to, if it is blacklisted, if it is already blocked by us
- If it needs to be blocked: Quick Block from the Toolkit → rule applied on all servers in 30 seconds
- If you need to investigate: SSH with one click from the node detail
When a scale intervention is needed
- Policy: add the IP range or ASN
- Or: Geo-blocking to block an entire country
- Or: Threat Feeds to enable an automatic blocklist
- The policy automatically propagates to all nodes
For proactive monitoring
- Uptime to check historical availability
- Traffic to see if there is anything abnormal in the firewall traffic
- HDD Monitor to prevent disk problems before they become emergencies
- NetMonitor to check the bandwidth used
Complete technology stack
For those who want the technical details:
| Components | Technology |
|---|---|
| Web server | PHP 8.3-FPM + Nginx |
| Database | PostgreSQL 18 |
| UI Framework | Tabler (Bootstrap 5) |
| Graphs | Chart.js |
| Map | amCharts 5 |
| SSH Terminal | xterm.js |
| Agent | Go 1.23 (static binary) |
| Password hashing | Argon2id |
| CAPTCHA | Cloudflare Turnstiles |
| 2FA | TOTP (RFC 6238) |
| Firewall backends | iptables, nftables, firewalld |
| Geo database | DB-IP Lite + RIR delegations |
| ASN resolution | RIPEstat API + BGPView |
| IP intelligence | AbuseIPDB |
The result: from hours of work to seconds
Before CFM, applying a firewall rule across the entire fleet meant hours of manual labor with the real risk of errors and oversights.
Today, the same operation requires 30 seconds: we enter the IP in the form, choose the action, and press Enter. The rule is automatically distributed to all nodes and applied with iptables-restore --noflush (without disturbing anything else), and verified by the agent which reports success to the server.
If something goes wrong, rollback is automatic. If we've made a mistake, versioning allows us to undo it with a click. If the customer asks "why is my IP blocked?", the Policy Tester and Audit Log give us the answer in 5 seconds.
CFM has transformed firewall management from a manual, risky, and unscalable operation to a centralized, automated process with an integrated security network.
And the integrated monitoring has eliminated the need to jump between 4-5 different tools: everything is in one place, with one interface, one login.
What awaits us
CFM is constantly evolving. Our roadmap includes:
- Rate Limiting: SYN flood protection and connection limits directly from the console
- Visual Diff of Policies: side-by-side comparison between versions with differences highlighted
- Implementation of the Commercial GeoIP Max Mind
- IP Reputation Score: aggregate score from multiple intelligence sources
- Schedulable rules: automatic activation and deactivation based on time
- Documented public REST API: for integrations with third-party systems
- Multi-tenancy and granular RBAC: to manage teams and clients with fine-grained permissions
- Customizable dashboard: drag & drop widget to adapt the view to your needs
- Fail2ban Integration: Two-way sync with existing Fail2ban jails
Conclusion
CFM 4 Linux was born from a real need, from the daily frustration of a team of system administrators managing hundreds of servers around the world. It's not an academic project or a proof of concept: it's a tool we use every day, on production servers, with real customers.
If you find yourself managing more than a handful of Linux servers and spend too much time copying iptables rules from one machine to another, or if you're tired of jumping between five different tools to get the picture, CFM might be the answer you've been looking for.
We built it for ourselves. And we discover every day that it's exactly what we needed.
This post was written by the Managedserver.it technical team. CFM 4 Linux is an internal project developed for the operational needs of our system administration team.
For questions, curiosities or to find out if CFM is right for you, contact us at info@managedserver.it.