Firewall and access control
The firewall device article already covered how a firewall makes its decision — packet filtering, stateful connection tracking, and what an NGFW adds on top of both. What it didn't cover is the question that comes before any of that mechanism: given a network with dozens of hosts and hundreds of services, who decided which traffic should be allowed at all, and on what basis? That's access control — a policy question, not a mechanism question — and it's just as easy to get technically correct rules that enforce a genuinely bad policy as it is to misconfigure the mechanism itself.
Default-deny versus default-allow
Every firewall ruleset answers one question before any individual rule matters: what happens to traffic that matches none of the explicit rules? There are exactly two possible answers, and they produce very different networks.
Default-deny means anything not explicitly permitted is blocked. A new service on a new port is unreachable the moment it starts listening, until someone adds a rule for it — which is exactly the behavior the firewall article's own practical scenario showed, where a freshly deployed API on port 8443 was silently unreachable because nobody had added a rule for it yet. That's default-deny working correctly, even though it felt like a bug to the developer who hit it.
Default-allow means anything not explicitly blocked gets through. A new service is reachable immediately, with zero configuration — convenient, and also the reason default-allow is now considered a serious misconfiguration on anything facing untrusted networks. Every future mistake — a debug port left open, a database bound to the wrong interface, a development tool nobody meant to expose — is silently permitted by default rather than silently blocked by default, and the administrator finds out only if someone notices the exposure, rather than the moment a legitimate new service needs deliberate access.
That Default: deny (incoming), allow (outgoing) line is ufw — Ubuntu's front end for the same nftables framework the firewall article's nft list ruleset output showed directly — stating its policy in exactly these terms: anything inbound is blocked unless a rule says otherwise, while outbound traffic is permitted by default, on the reasoning that a host's own outbound connections are generally initiated deliberately by processes the administrator already trusts.
A default-deny policy makes every exposure the result of a decision someone made; a default-allow policy makes every restriction the result of a decision someone made instead — and forgetting to make a decision fails safe under one and fails open under the other. That asymmetry is why default-deny is the standard recommendation for anything reachable from an untrusted network, even though it costs more upfront friction every time a legitimate new service needs a rule added for it.
Least privilege applied to network access
Least privilege — a principle NIST defines as restricting access "to the minimum necessary to accomplish assigned tasks" — applies to network access exactly the way it applies to file permissions or database grants. A rule that's broader than what a service genuinely needs isn't a convenience held in reserve; it's an unused capability an attacker can exploit if that specific host or account is ever compromised, and it stays that way indefinitely unless someone actively audits and narrows it.
The gap between a lazy rule and a least-privilege rule is usually small in effort and large in blast radius:
versus
The first line allows any host on the internet to attempt a connection to PostgreSQL's default port — a rule someone might write during initial setup, intending to come back and restrict it "later." The second allows the same port only from the specific subnet where the application servers that genuinely need database access actually live. Checking which rule is actually active is the same status command shown above, just without verbose for a shorter listing:
That single line is the entire security posture for this port, readable at a glance — which is itself a reason to prefer a small number of precisely scoped rules over a large number of broad ones: a ruleset nobody can read at a glance is a ruleset nobody actually audits.
Segmentation: least privilege applied to whole networks
Least privilege scales up from individual rules to entire network zones. Segmentation means splitting a network into separate zones — by function, by trust level, or both — and controlling what's allowed to cross between them, rather than treating every host on the network as equally trusted just because it's on the same physical or virtual network as everything else.
A common three-zone pattern in a small company's infrastructure illustrates why this matters in practice:
Internet
│
▼
[ Public zone: reverse proxy, load balancer ]
│ allowed: proxy -> app servers, port 8080 only
▼
[ Application zone: app servers ]
│ allowed: app servers -> database, port 5432 only
▼
[ Data zone: database servers ]
A rule permitting the public zone to reach the data zone directly would defeat the entire point of having zones at all — it would mean a compromise of the internet-facing reverse proxy grants immediate, unmediated access to the database, skipping straight past the application zone's own logic and logging entirely. With proper segmentation, an attacker who compromises the reverse proxy still has to separately compromise something in the application zone before ever reaching the data zone — segmentation doesn't prevent every breach, but it turns one successful compromise into a chain of several, each one a chance to detect and stop the attack before it reaches the most sensitive zone.
Segmentation is a design decision, not a firewall feature
Nothing about nftables, ufw, or any specific firewall product implements segmentation automatically — it's the deliberate choice to place hosts in different subnets or VLANs by trust level, then write rules that only permit the specific, minimal cross-zone traffic each tier genuinely needs. A flat network with every host in one subnet can't be segmented after the fact by firewall rules alone; the network topology itself has to reflect the zones.
Allowlisting versus blocklisting
A related but distinct choice shows up at the rule level, not just at the default-policy level: does a given rule name what's allowed (an allowlist) or what's blocked (a blocklist)?
- An allowlist rule — like the
10.0.1.0/24PostgreSQL example above — names the specific, known-good sources permitted, and blocks everything else by implication under a default-deny policy. - A blocklist rule names specific known-bad sources — an IP address seen brute-forcing SSH, a range associated with a known attack — and allows everything else through.
Blocklisting has a structural weakness allowlisting doesn't: it can only block what's already been identified as bad, while an allowlist under default-deny blocks everything by default, including threats nobody has seen yet. Blocklisting still has a real, narrow role — blocking a specific IP actively hammering a login endpoint right now, for instance — but it's a reactive supplement to a default-deny allowlist policy, not a substitute for one. A network secured primarily by blocklists is, structurally, a default-allow network with extra steps.
Practical scenario: a rule that was correct on the day it was written
A security review of a three-year-old production server finds a firewall rule allowing inbound TCP traffic on port 8081 from 0.0.0.0/0 — the entire internet. Nobody currently on the team remembers what runs on port 8081, and ss -tulnp confirms nothing is actually listening on it anymore.
The rule was almost certainly correct and deliberate when it was added — a debugging tool, a monitoring agent, a service later decommissioned or migrated to a different port — but nobody removed the rule when whatever it was protecting went away. This is the least-privilege problem in its most common real-world form: not a rule that was wrong when written, but a rule that stayed after the reason for it stopped being true, sitting open to the entire internet for a service that no longer exists to receive the traffic.
Deleting a stale rule for a port nothing is listening on is close to zero-risk, unlike editing a rule that's actively in use — but it's still worth confirming with ss -tulnp first, exactly as done above, rather than assuming a rule is safe to remove just because nobody remembers its purpose. The durable fix isn't just removing this one rule; it's treating firewall rules the way least privilege demands generally — reviewed periodically, tied to a specific, documented service, and removed as part of that service's own decommissioning process rather than left to be discovered by the next audit.
Practice exercises
- Explain, in terms of default-deny versus default-allow, why the developer's port-8443 timeout in the firewall device article's scenario was the firewall working as intended, not a misconfiguration.
- Design a three-zone segmentation scheme, similar to the one in this article, for a system with a public web frontend, an internal API the frontend calls, and a Redis cache only the API should reach. Write out which zone-to-zone connections should be explicitly allowed and which should be blocked by default.
- A teammate proposes replacing an allowlist rule (
allow from 10.0.1.0/24) with a blocklist rule (deny from <list of known bad IPs>) to "simplify" a database firewall rule. Explain what security property this change gives up.
Everything in this article assumed a firewall correctly blocking or allowing traffic is enough to stop an intrusion. It isn't — a firewall only sees what it's configured to look for, and traffic that matches an allowed rule sails through even if it's part of an active attack. Before that layer is worth discussing, though, there's a more immediate gap: this article argued for default-deny and least privilege without once showing a rule. The next article writes them, on Linux, with the safety procedure that keeps a default-deny policy from locking you out of the server enforcing it.
Sources
- NIST, least privilege – Glossary
- Ubuntu Community Help Wiki, UFW
- Ubuntu Manpages, ufw(8) – program for managing a netfilter firewall