Configuring UFW / firewalld / iptables / nftables: Audit and Configuration

Filtering rules take on a life of their own: someone adds an exception, and the perimeter becomes a sieve. We provide turnkey audit and filtering configuration — from the design to the access policy. Once order is restored, questionable rules disappear and the access scope narrows to what is required.

Our competencies:

Frequently Asked Questions

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1365
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1330
  • B2B Advance company logo design
    B2B Advance company logo design
    776
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1077
  • AIDER company logo development
    AIDER company logo development
    1022
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1113

Configuring UFW: where traffic filtering breaks

Configuring UFW looks like a few allow commands — and that is why host traffic filtering often turns out to be decorative. UFW is not a standalone filter but a wrapper over iptables and nftables: it builds chains from files in /etc/ufw and applies them in full on reload.

A failure is usually not a "forgotten rule" but an incorrect default policy, filtering rule order, or loss of state on reboot.

Order matters more than composition: the filter triggers on first match, so an allow rule added before a deny rule overrides it.

The second quiet error is interface binding: a rule is attached to the external interface, but traffic arrives through a tunnel or internal bridge and simply does not fall under it.

A separate class is rule bypass by containers. Docker and orchestrator insert their own chains above user chains, so a published port opens on all interfaces regardless of what ufw status shows.

Same for IPv6: when the stack is disabled, rules for it are not created, and part of traffic goes around the filter.

Finally, configuration survivability: rules added manually via iptables disappear after reboot, and ufw without autostart comes up empty. This must be checked against the actual set of chains at boot time, not by status output.

We start with an audit: capture the current state, compare it with the declared default policy, and check external access — this shows exactly where the bypass is.

Then — how it is closed: rule order, interface binding, integration with the container network, and configuration persistence.

What changes after a rule audit: measurable effects

The audit begins by reconciling three lists: what listens on the interfaces, what is actually needed externally, and what is allowed in the rules.

The discrepancy between them is the attack surface — debug ports, admin panels, DBMS, opened "for a couple of days." After cleanup, only user traffic remains external, and engineer access moves to a separate circuit.

The second result is predictable configuration. Rules move from manual edits to a declarative description in version control and are applied in full, not line by line.

A change goes through a test bench and one node, then rolls out to the rest: behavior on the next edit no longer depends on who touched the file and when.

Access recovery time is measured in minutes instead of hours. A typical failure is a rule that cuts an administrator off from a node; with preserved console access and a fixed application order, access is restored by rolling back the configuration, without rebuilding the server. Default deny here does not hinder but helps: the cause of access loss is visible immediately.

A whole class of failures also goes away: a service accidentally published externally after an update, different rule versions on nodes, a rule no one dares to delete.

In UFW and same-level wrappers, this is closed by profiles, explicit application order, and checking port state as a regular procedure.

Configuring UFW and alternatives: comparison of filtering modes

Filtering inside the host and at the cloud perimeter solve different tasks, so choosing between them is rarely necessary — more often they are combined.

On the machine, built-in tools are available: UFW as a simple wrapper with ready-made application profiles, firewalld with trust zones and interface binding, nftables for complex routing and address translation, iptables where legacy modules remain. Externally, traffic is cut by the cloud network security group.

Option When it fits Limitations
UFW Single host, rules by ports and addresses, fast commissioning No trust zones; routing and translation require manual insertions; rule order is implicit
firewalld Multiple interfaces, trust zones, services, and rich rules with live reload Requires discipline in zones: without it, rules duplicate and conflict
nftables Complex routing scenarios, address sets, atomic replacement of the entire rule set Higher entry threshold; no ready-made application profiles
iptables Legacy systems and modules not yet ported to the new stack Sequential chain traversal; rule updates are non-atomic
Cloud security group Perimeter moved to the cloud, dozens of machines, unified policy Does not see traffic between services inside the host; limit on rule count; application delay

Application order is more important than tool choice: the cloud filter cuts off excess before the packet reaches the machine, while host rules remain the second line and the only place where interaction of local services is visible.

When rules are duplicated at two levels and diverge, finding the cause of a failure drags on — so we fix the source of truth and reconcile both layers on every change.

Work stages: rule audit, diagram, configuration, verification, handover

Configuration audit begins not with editing rules but with inventory: which services listen on ports, who accesses them and from where, where traffic goes through a load balancer and where directly.

Without a traffic flow diagram, any change is a guess, and the first closed port breaks a working scenario. Therefore the implementation order is strict: first we capture the state as is, then we change — in groups, with a ready rollback.

  1. Service inventory. We collect a list of listening ports and their consumers, including internal networks and the office. This surfaces forgotten administrative ports and ranges opened "just in case."
  2. Capturing current rules. We export the active ufw, firewalld, iptables, or nftables sets, compare them with the node's actual behavior, and mark duplicates and rules that no longer affect anything.
  3. Traffic flow diagram. For each route, we record the chain "perimeter — load balancer — application — database" with source, destination, and port. The diagram becomes the basis for both policy and incident analysis.
  4. Policy design. Default deny, targeted allows for confirmed routes, separate zones for service networks, and an order in which specific rules trigger before general ones.
  5. Implementation. We apply in groups — by service or segment, first on a test node, then on production, in an agreed window and with a prepared rollback.
  6. Rule verification. We run traffic from outside and inside: what is needed is accessible, excess is closed, denials are logged. Separately, we make sure the rules survive a reboot.
  7. Handover of procedures. We deliver configurations in version control, the traffic diagram, policy description, and change approval procedure — so the next edit does not start from scratch.

Access policies, configurations, and procedures as deliverables

An audit does not end with a report: the result is a reproducible set of artifacts by which the infrastructure can be rebuilt and safely changed. Everything we edit on servers settles in files, not in command history and process memory. Below is what remains with the customer.

  • Configuration files of rules in your stack's syntax (ufw, firewalld, nftables) — with a comment for each exception, not just rule lines.
  • Default access policies: explicitly captured what is closed, what is allowed, and by what criterion a rule is considered redundant.
  • Service map: which ports and addresses are needed by whom, who owns the service, and which maintenance window it is tied to.
  • Address groups and roles: named address sets instead of scattered subnets — editing a group updates rules everywhere at once.
  • Change procedure: who approves a new rule, which checks are mandatory before publication, and after what period the rule is reviewed.
  • Network zone diagram and the order of traffic flow between them — in a form suitable for handing over to a new engineer.
  • Rollback procedure: a snapshot of the working configuration and the sequence to return to it in minutes, not hours of analysis.
  • List of removed rules with the reason: outdated allows do not remain in the configuration "just in case."

The set is self-contained: it can be used for a repeat audit and to see what changed since last time.

Case study: how filtering bypass was closed on a host with containers

Background

This implementation case study began with external scanning: on a host with a container environment, 23 services responded externally, even though a firewall was configured and the default policy denied incoming.

The cause turned out to be not an error in the rules but the traffic processing order: Docker, when publishing ports, writes its own forwarding chains that trigger before user chains.

As a result, the metrics panel, queue admin panel, and internal image registry were available to anyone who knew the address.

What was changed

Service publication was divided by role: what receives external traffic remained on the external interface; the rest was moved to a local address with access through a reverse proxy.

Custom chains for containers were described explicitly — default deny, source whitelist, separate permissions for inter-container exchange and database access.

The rules were moved to versioned configuration: rollout is automated, rollback is a single change, without edits on a live host with the risk of cutting off your own access.

Before and after metrics

Externally available services became 4 instead of 23; the rest respond only inside the container network. Making the next filtering change takes a few minutes instead of manually checking chains across the entire host.

We conduct a repeat audit once a quarter: compare actual rules with documented ones, check whether a new service has opened a port externally, and review chains after container environment updates.

What to do if iptables is already deployed and rules live inconsistently

An accumulated rule set is a problem not of syntax but of missing model: reading chain after chain, it is impossible to understand why a rule was added and what will break if it is removed. Counters show the volume of passing traffic but not the service owner.

Therefore the first step is inventory: capture active sets from all nodes, match rules to services, and mark those that actually allow connections.

Then there is a choice of three strategies, and they differ not in amount of work but in the cost of an error.

Option When it fits Limitations
Inventory and configuration migration Rules are working but scattered across chains and hosts Old errors are migrated too; each chain needs manual review
Parallel filtering layer The service cannot be stopped; a gradual transition is needed Double filtering complicates request analysis; removed after migration
Clean start Rules are undocumented; some are clearly redundant Requires a test circuit; risk of losing a non-obvious permission

The change risk is the same in any option: applying a policy on a live node, it is easy to cut off your own access to it. This is mitigated by delayed rollback — the rule restores the previous set after a specified interval if we have not confirmed node availability.

The second protection circuit is a test bench with the same set of services, where the policy is tested before production.

We finish not with a one-time edit but by moving the configuration to a versioned form: the set lives in a file, application is automated, and changes are checked before application. Then the next audit takes minutes, not a day.

Common technical concerns before starting work

Concerns before starting are usually the same: will a new rule cut off remote access, how to roll back if connectivity is lost. The concern is justified — the filter starts working immediately, and an error in one line closes the entrance before you notice it.

Therefore we apply rules in stages: first allows for the current session, then restrictions, with verification on a separate circuit and a timer that restores the previous set if connectivity is not confirmed.

The configuration lives in a repository, so any change is rolled back with one command, rather than restoring access through the provider console.

What happens if a rule cuts off remote access?

Before applying the production set, we test it on a copy of the circuit and keep a delayed return to the previous state. If the session is not confirmed within the allotted time, the set is automatically restored — access is not lost.

How do you version rules?

All sets are stored in version control: you can see who changed a rule and why, and rollback to a working state takes minutes. The change history remains with you, not in a chat.

Do you account for containers when publishing ports?

Yes. Container environment rules and system filter rules are configured consistently; otherwise a service ends up open in bypass of restrictions. We bring both layers to a single access model and verify the result by scanning ports from outside.

Does this work with next-generation addressing?

Yes, sets for the new addressing protocol are configured separately from the usual ones. A common problem is open access over one address type while closed over another, so we check both variants.

Do you restrict control panels?

By default, panels and administrative interfaces are closed from the external network and accessible only through a trusted circuit or secure tunnel. This removes the most common vector — password brute force against an open panel.

Let's discuss the task: rule audit and change plan

The task usually sounds like "close the extra ports," but in essence it is bringing filtering policies to a state that can be explained to a colleague and reproduced on a new machine.

The more accurate the initial data at the start, the fewer iterations of "changed a rule — lost access." Below is what speeds up task discussion and change plan preparation.

  • Access: how we log into the node — key or console, whether there is an intermediate host, whether permissions are sufficient, who else accesses the machine. This determines the order of edits so as not to cut off your own entry.
  • Network diagram: interfaces, addressing and subnets, load balancer, VPN, reverse proxy. Without it, traffic sources cannot be correctly described in rules.
  • Service list: what listens externally and what is available only inside the node, where TCP is and where UDP is, who actually needs external access.
  • Current state: configuration outputs, hit counters, order of chains and zones, whether two rule managers are running simultaneously.
  • Constraints: audit and internal policy requirements, agreed exceptions, services that must not be touched.
  • Change window: acceptable downtime, low-load hours, on-call person available, rollback procedure.

Based on this data, we assemble a change plan: sequence of edits, checks before and after each step, return point, and criteria by which we consider the result achieved. A backup of rules is prepared before work begins, and the change window itself is agreed in advance.

The work estimate comes together with the plan: stages, timelines, and who confirms the result on the customer side.