How to Find and Restrict the Services Your Firewall Exposes
Your firewall listens on more ports than you think. Learn how to inventory its control-plane services and shut off the ones that face the internet.
Most teams can name the services they deliberately expose: the VPN portal, the management web interface, maybe an API. Far fewer can list everything their edge appliance is actually listening for. The Fortinet flaw behind the PivotC2 campaign, CVE-2025-25249, is a case in point. The vulnerable service was a CAPWAPCAPWAP🌐Control and Provisioning of Wireless Access Points, a standard protocol that lets a controller manage remote wireless access points. On FortiOS the cw_acd daemon speaks CAPWAP, and enabling the Security Fabric service makes an interface listen for it on UDP ports 5246 to 5249. controller daemon that many affected organizations were not consciously using, yet it answered packets from the internet because of one permissive interface setting. This guide is about finding those forgotten listeners and shutting the ones that face untrusted networks.
The Problem: Services You Did Not Choose to Run
Security appliances bundle features, and features open ports. On FortiOS, enabling the Security Fabric Connection on an interface adds `fabric` to that interface's `allowaccess` list. Since FortiOS 6.4 that single keyword turns on both FortiTelemetry and CAPWAP, so an interface configured for fabric management is also listening for CAPWAP control traffic whether or not you manage any access points on it. An administrator who enabled fabric once, for a reason that made sense at the time, left a network-reachable daemon running indefinitely.
This is not unique to Fortinet. Every network operating system ships management planes, discovery protocols, and clustering services that listen by default or get switched on during setup. The attack surfaceAttack Surface🛡️The sum of all points where an unauthorized user could attempt to enter or extract data from a system: exposed services, interfaces, accounts, and integrations. Reducing attack surface means removing reachability, not just patching. of an appliance is the union of every such listener on every interface, not the short list of services you think you offer.
Step 1: Inventory What Actually Listens
Start from the outside. Scan each public interface from an external vantage point for open TCP and UDP ports, then reconcile the results against what you believe should be reachable. UDP matters here: the Fortinet CAPWAP service listens on UDP 5246 through 5249, and UDP is easy to overlook because it does not show up in a casual TCP scan.
Then check from the inside. On FortiOS, review each interface's `allowaccess` list and note every enabled service: HTTPS and SSH for management, ping, and crucially `fabric`. Do the same audit on any device with a similar management model. The goal is a written map of interface, service, and the source networks that can currently reach it.
Step 2: Decide What Belongs on Each Interface
Sort every listener into three buckets. Some services must face the internet, such as the SSL-VPN portal that remote staff depend on. Some should be reachable only from a management network, such as the admin web interface and SSH. And some should not be reachable from untrusted networks at all, such as fabric and CAPWAP control on an internet-facing WAN interface.
The principle is least exposure. A service that only ever talks to internal peers has no business answering the WAN, and leaving it there converts a bug you will never patch in time into a breach. The heap-overflow explainer How a Heap OverflowHeap Overflow🛡️A memory-corruption bug where a program writes more data into a heap allocation than it was sized to hold, spilling into adjacent memory. When the overwritten neighbor is the allocator's own bookkeeping, an attacker can steer it toward code execution. in a Network Daemon Becomes Code Execution shows why an exposed control daemon is the worst place for a memory bug to live.
Step 3: Enforce the Boundary
Two controls do the work. First, trim `allowaccess`. Remove `fabric`, and any other unneeded service, from every interface that does not require it. This is exactly the mitigation Fortinet published for CVE-2025-25249 alongside the patch.
Second, add local-in policies. A local-in policy filters traffic destined for the appliance itself, as opposed to traffic passing through it. Where you cannot remove a service, restrict who can reach it: a policy that permits CAPWAP-CONTROL only from your known access-point subnets and denies it everywhere else neutralizes internet-based exploitation even before you patch. Restricting a web console to trusted addresses follows the same logic, covered in the companion piece on locking a management interface to known IPs.
Step 4: Make It Stick
An interface audit done once drifts within a quarter. Bake the checks into change control so that enabling a management feature on a public interface requires a reason and a matching local-in policy. Re-scan your public ranges on a schedule, because a firmwareFirmware🏠Permanent software programmed into a device's hardware that controls its basic functions. upgrade or a restored configuration can quietly re-enable a service you turned off. And keep the inventory current, because the day a vendor advisory lands you want to answer "is this daemon exposed on any of our devices" in minutes, not days.
Reducing exposure does not replace patching, and it does not undo a breach that already happened. If a device was reachable and vulnerable during the exploitation window, treat it as potentially compromised and work through After a FirewallFirewall🌐Security system that monitors and controls network traffic based on predetermined rules. Breach, Assume Every Stored Credential Is Compromised. But an appliance that never answered the malicious packet in the first place is the cheapest defense you have, and it is entirely within your control.