Servers & Infrastructure

Advanced nftables Firewall Architecture: Production Linux Guide 2026

nftables Advanced Firewall Architecture: Building a Scalable Production Linux Firewall

A Linux firewall often starts with a few simple rules: allow SSH, permit web traffic, accept established connections, and drop everything else. That approach works for a small server, but it becomes difficult to maintain when the system grows to include multiple interfaces, VLANs, a DMZ, NAT, IPv4 and IPv6, policy routing, monitoring, and different security zones.

The challenge is no longer learning another nftables command. It is designing the ruleset as an architecture.

A production firewall should make it easy to answer five questions:

  • Where did this packet come from?
  • Where is it going?
  • What connection state does it belong to?
  • Which security policy applies?
  • Why was it accepted or dropped?

This guide shows how to build an advanced nftables firewall architecture using tables, base chains, custom chains, connection tracking, sets, maps, counters, controlled logging, NAT, and clearly separated security zones.

It builds on the CorgiNetwork guides covering nftables Sets and Maps, nftables Dynamic Sets and Meters, nftables Inter-VLAN Firewall, and nftables Conntrack States and Troubleshooting.

For authoritative reference material, the official nftables documentation maintained by the Netfilter project should be used when validating syntax and behavior for a particular nftables and Linux kernel version.

Why Firewall Architecture Matters

Consider a Linux router connecting several networks:

                    Internet
                       |
                      WAN
                       |
                +-------------+
                | Linux       |
                | nftables    |
                | Firewall    |
                +-------------+
                  /    |     \
                 /     |      \
              Users  Servers   DMZ
              VLAN    VLAN      VLAN
                         \
                       Management
                          VLAN

A flat ruleset might contain hundreds of statements such as:

ip saddr 192.168.10.0/24 ip daddr 192.168.20.10 tcp dport 443 accept
ip saddr 192.168.30.0/24 ip daddr 192.168.20.10 tcp dport 22 accept
ip saddr 192.168.40.0/24 ip daddr 192.168.20.53 udp dport 53 accept

These rules may be technically correct, but as their number grows it becomes increasingly difficult to understand the security policy.

A better design starts with zones and relationships:

Users      → Servers       HTTPS
Management → Servers       SSH
Users      → DNS Servers   DNS
Internet   → DMZ           HTTP/HTTPS
DMZ        → LAN           Restricted

The firewall configuration should express those relationships clearly.

That is the central principle of scalable nftables design:

Organize rules around security policy rather than individual packets, addresses, or ports.


Start with Security Zones

Before writing nftables rules, identify the trust boundaries in the network.

A typical environment might contain:

Zone Example Network Purpose
WAN Public Internet Untrusted external traffic
USERS 192.168.10.0/24 Workstations
SERVERS 192.168.20.0/24 Internal services
MANAGEMENT 192.168.30.0/24 Administrative access
IOT 192.168.40.0/24 Restricted devices
DMZ 192.168.50.0/24 Public-facing servers

Now policy becomes easier to define.

For example:

USERS → SERVERS
Allow HTTPS and DNS where required.

MANAGEMENT → SERVERS
Allow administrative services.

IOT → SERVERS
Deny by default; allow explicitly required services.

WAN → DMZ
Allow only published services.

DMZ → LAN
Deny by default.

If VLAN routing is part of the topology, the packet-flow foundation is explained in Linux Inter-VLAN Routing with Network Namespaces, while actual filtering between those networks is covered in nftables Inter-VLAN Firewall.


Choose the Correct nftables Family

For many dual-stack firewalls, the inet family provides a convenient place for filtering both IPv4 and IPv6 traffic.

A basic structure can begin with:

table inet firewall {
}

Inside that table, you can create filtering chains for:

INPUT
FORWARD
OUTPUT

while using protocol-specific expressions such as:

ip saddr

for IPv4 and:

ip6 saddr

for IPv6 when necessary.

Using inet does not mean IPv4 and IPv6 policies become automatically identical. Both still need to be considered explicitly.

The nftables Families documentation explains the available families and their purposes.


Understand INPUT, FORWARD and OUTPUT

A scalable firewall begins by putting policy in the correct packet path.

INPUT

Traffic destined for the firewall itself.

Examples:

SSH to the firewall
DNS service running on the firewall
Monitoring of the firewall

FORWARD

Traffic passing through the Linux system.

Examples:

Users → Servers
Internet → DMZ
VLAN 10 → VLAN 20

OUTPUT

Traffic generated locally by the firewall.

Examples:

DNS queries generated by the firewall
package updates
monitoring traffic

A common troubleshooting mistake is putting a routing rule in input when the packet is actually traversing forward.

Before debugging a rule, determine whether the Linux host is the destination or the router.


Build Minimal Base Chains

A clean base structure might look like:

table inet firewall {

    chain input {
        type filter hook input priority filter;
        policy drop;
    }

    chain forward {
        type filter hook forward priority filter;
        policy drop;
    }

    chain output {
        type filter hook output priority filter;
        policy accept;
    }
}

This example uses default-drop policies for inbound and forwarded traffic.

That creates a simple security model:

Not explicitly permitted
        ↓
      DROP

A default-drop architecture can make policy easier to reason about, but it must be deployed carefully on remote systems because missing management rules can lock out administrators.


Keep Base Chains Short

One of the most useful structural improvements is keeping base chains relatively small.

Instead of placing every policy directly inside forward, use it primarily for classification and dispatch.

Conceptually:

FORWARD
   |
   +-- invalid handling
   |
   +-- established traffic
   |
   +-- WAN policy
   |
   +-- VLAN policy
   |
   +-- DMZ policy
   |
   +-- final handling

This makes the packet path much easier to inspect.


Use Custom Chains to Separate Policy

You can create custom chains such as:

chain wan_to_dmz {
}

chain users_to_servers {
}

chain management_to_servers {
}

chain iot_policy {
}

Then dispatch traffic from the base chain.

Conceptually:

FORWARD
   |
   +-- USERS → SERVERS
   |        |
   |        └── users_to_servers
   |
   +-- MANAGEMENT → SERVERS
   |        |
   |        └── management_to_servers
   |
   +-- WAN → DMZ
            |
            └── wan_to_dmz

This provides two major benefits.

First, the ruleset becomes easier to read.

Second, troubleshooting becomes easier because each chain has a clearly defined responsibility.


Connection Tracking Should Appear Early

Most production firewalls are stateful.

A common pattern is:

ct state invalid counter drop
ct state established,related counter accept

before evaluating rules for new connections.

The architecture becomes:

Packet
   |
   +-- INVALID? → DROP
   |
   +-- ESTABLISHED/RELATED? → ACCEPT
   |
   └-- NEW → evaluate security policy

This prevents every packet belonging to an already approved connection from being repeatedly evaluated against the full new-connection policy.

Connection tracking is sufficiently important that it should be understood independently. See nftables Conntrack States and Troubleshooting for the detailed packet-state model.


Use Sets for Network Objects

Do not repeatedly hard-code the same networks.

Instead of:

ip saddr 192.168.10.0/24 ...
ip saddr 192.168.20.0/24 ...
ip saddr 192.168.30.0/24 ...

define meaningful objects.

For example:

set management_networks {
    type ipv4_addr
    flags interval
    elements = {
        192.168.30.0/24
    }
}

and:

set server_networks {
    type ipv4_addr
    flags interval
    elements = {
        192.168.20.0/24
    }
}

Now rules can express intent:

ip saddr @management_networks \
ip daddr @server_networks \
tcp dport 22 \
accept

This reads almost like a policy statement.

For deeper coverage of named sets, interval sets, maps, concatenations, and verdict maps, see nftables Sets and Maps.


Create Service Sets

The same principle applies to ports.

Instead of:

tcp dport 80 accept
tcp dport 443 accept

define:

set web_ports {
    type inet_service
    elements = { 80, 443 }
}

Then:

tcp dport @web_ports accept

Other useful service groups might include:

@web_ports
@dns_ports
@monitoring_ports
@management_ports

Do not create a set for every single value simply because nftables allows it. Use sets when they improve reuse or readability.


Example: Management-to-Server Policy

Suppose:

Management:
192.168.30.0/24

Servers:
192.168.20.0/24

Administrators need SSH access to servers.

A dedicated chain might contain:

chain management_to_servers {

    ip saddr @management_networks \
    ip daddr @server_networks \
    tcp dport 22 \
    ct state new \
    counter \
    accept
}

The policy is clear:

Management
     ↓
Servers
     ↓
SSH
     ↓
ACCEPT

No unrelated DMZ or IoT rules belong in this chain.


Example: User-to-Server Policy

Suppose normal users should reach internal web applications but not SSH.

A dedicated chain can implement:

chain users_to_servers {

    ip saddr @user_networks \
    ip daddr @web_servers \
    tcp dport @web_ports \
    ct state new \
    counter \
    accept
}

This keeps user access separate from management access.

If SSH is later added to the management policy, it does not accidentally become available to user networks.


Example: IoT Segmentation

IoT networks deserve explicit restrictions because many devices require only a narrow set of services.

A reasonable architecture is:

IoT
 |
 +→ DNS
 |
 +→ NTP
 |
 +→ selected Internet services
 |
 └→ Internal servers → DENY unless required

Instead of trusting the entire IoT network because it is “internal,” treat it as its own security zone.

This is exactly the kind of policy that becomes easier to maintain with dedicated chains and named sets.


Design the DMZ as a Separate Trust Boundary

A DMZ should not simply be another internal subnet.

Conceptually:

Internet
   ↓
Firewall
   ↓
DMZ
   X
Internal LAN

Public services may need inbound access from the Internet, but that does not imply unrestricted access from the DMZ to internal systems.

A stronger policy is:

WAN → DMZ
Allow published services.

DMZ → LAN
Drop by default.

MANAGEMENT → DMZ
Allow required administrative services.

DMZ → Internet
Allow only what the servers actually require.

For a complete implementation, see Linux DMZ with nftables, VLAN, NAT and Firewall.


Keep NAT Separate from Filtering Logic

Filtering answers:

Should this traffic be permitted?

NAT answers:

Should an address or port be translated?

These are different responsibilities.

A clean architecture therefore treats NAT and filtering as related but separate components.

For example:

Internet
   ↓
DNAT
   ↓
Internal/DMZ Server
   ↓
FORWARD filtering
   ↓
ACCEPT or DROP

A DNAT rule does not automatically mean that forwarding policy is correct.

Likewise, an accept rule does not automatically configure destination translation.

This distinction is critical when troubleshooting published services.

If port forwarding is involved, use nftables DNAT Port Forwarding Not Working to trace the full path.


Understand Hairpin NAT Separately

Internal clients sometimes access an internal service using its public address:

LAN Client
    ↓
Public IP
    ↓
Firewall
    ↓
Internal Server

This is a special NAT path and should not be mixed conceptually with ordinary Internet-to-server DNAT.

Depending on the topology, both destination and source translation may be necessary for the return path to remain symmetrical.

For that scenario, use nftables Hairpin NAT and NAT Loopback.

Keeping specialized NAT behavior in dedicated logic makes the overall firewall easier to maintain.


Use Maps When Relationships Grow

Sets answer questions such as:

Is this address a member of this group?

Maps answer:

Given this key, what value corresponds to it?

When a firewall grows, maps can replace repeated relationships.

Verdict maps can also direct traffic to specific verdicts or chains.

For example, a service-dispatch architecture can conceptually behave like:

TCP/22
   ↓
SSH policy

TCP/80
   ↓
Web policy

TCP/443
   ↓
Web policy

rather than using a long sequence of repetitive dispatch rules.

The official nftables Maps documentation provides the underlying syntax and behavior.


Use Dynamic State Only Where It Adds Value

After the static architecture is correct, dynamic sets and per-source rate controls can be added for selected services.

Do not begin with complex dynamic logic.

The correct progression is:

Routing
   ↓
Security zones
   ↓
Stateful firewall
   ↓
Static sets/maps
   ↓
Logging/counters
   ↓
Dynamic controls

For example, an Internet-facing SSH service might use dynamic state to track new connections per source.

But if SSH should only be reachable through the management VLAN or VPN, restricting access at the zone level is usually the more fundamental control.

For dynamic tracking, see nftables Dynamic Sets and Meters.


Counters Should Be Part of the Architecture

A production firewall should be observable.

Adding:

counter

to important policy rules allows you to answer:

Is this rule actually being used?

For example:

ip saddr @management_networks \
ip daddr @server_networks \
tcp dport 22 \
counter \
accept

If the counter remains zero while testing SSH, the packet is probably:

  • not reaching this chain,
  • not matching one of the conditions,
  • or being handled earlier.

That immediately narrows the troubleshooting scope.


Log Decisions, Not Everything

Logging every dropped packet can create enormous log volumes.

Instead, log meaningful events with appropriate rate controls.

A typical design is:

Packet
   ↓
Counter
   ↓
Rate-limited log
   ↓
DROP

The rate limit should control logging volume, not accidentally determine whether prohibited traffic is dropped.

For example, conceptually:

limit rate 5/second \
log prefix "NFT_FORWARD_DROP: "

counter drop

The first rule controls how many messages are generated.

The second enforces the policy.

This separation is much safer than combining logging and enforcement without understanding the control flow.


Use Consistent Log Prefixes

A firewall with random log prefixes is difficult to search.

Use predictable names such as:

NFT_INPUT_DROP:
NFT_FORWARD_DROP:
NFT_WAN_DMZ_DROP:
NFT_IOT_DROP:
NFT_INVALID:

Then tools such as journalctl, log collectors, or SIEM platforms can filter events by policy area.

Logging becomes part of the firewall architecture rather than an emergency debugging feature.


A Complete Simplified Architecture

The following example demonstrates the overall structure rather than serving as a drop-in configuration for every network:

table inet firewall {

    set user_networks {
        type ipv4_addr
        flags interval
        elements = { 192.168.10.0/24 }
    }

    set server_networks {
        type ipv4_addr
        flags interval
        elements = { 192.168.20.0/24 }
    }

    set management_networks {
        type ipv4_addr
        flags interval
        elements = { 192.168.30.0/24 }
    }

    set web_servers {
        type ipv4_addr
        elements = {
            192.168.20.10,
            192.168.20.11
        }
    }

    set web_ports {
        type inet_service
        elements = { 80, 443 }
    }

    chain input {
        type filter hook input priority filter;
        policy drop;

        iifname "lo" accept

        ct state invalid counter drop
        ct state established,related counter accept

        ip saddr @management_networks \
        tcp dport 22 \
        ct state new \
        counter \
        accept

        limit rate 5/second \
        log prefix "NFT_INPUT_DROP: "

        counter drop
    }

    chain forward {
        type filter hook forward priority filter;
        policy drop;

        ct state invalid counter drop
        ct state established,related counter accept

        ip saddr @management_networks \
        ip daddr @server_networks \
        jump management_to_servers

        ip saddr @user_networks \
        ip daddr @server_networks \
        jump users_to_servers

        limit rate 5/second \
        log prefix "NFT_FORWARD_DROP: "

        counter drop
    }

    chain management_to_servers {

        tcp dport 22 \
        ct state new \
        counter \
        accept

        return
    }

    chain users_to_servers {

        ip daddr @web_servers \
        tcp dport @web_ports \
        ct state new \
        counter \
        accept

        return
    }
}

Notice what this architecture does not do.

It does not put hundreds of unrelated rules into one chain.

Instead:

BASE CHAIN
    ↓
classify traffic
    ↓
CUSTOM CHAIN
    ↓
apply zone-specific policy
    ↓
VERDICT

That is the structure we want.


Rule Ordering Strategy

Inside a busy filtering chain, a logical order is often:

1. Essential special handling

2. INVALID handling

3. ESTABLISHED / RELATED

4. Explicitly trusted infrastructure

5. New-connection policies

6. Zone-specific dispatch

7. Controlled logging

8. Default drop

The exact order depends on the firewall.

The important principle is that rules should follow a deliberate hierarchy rather than being appended wherever convenient.


Avoid Broad “Internal Network = Trusted” Rules

A rule such as:

ip saddr 192.168.0.0/16 accept

may undermine an otherwise carefully segmented architecture.

It effectively says:

Any host in a huge internal address range
        ↓
trusted

This can bypass distinctions between:

users
servers
IoT
management
DMZ

Internal does not automatically mean trusted.

Security zones exist precisely because different internal systems have different risk profiles and access requirements.


Avoid Interface-Only Security Models

Interfaces are useful classification signals:

iifname "wan0"

or:

iifname "vlan30"

but production policy often benefits from checking additional context such as:

source network
destination network
service
connection state

A packet arriving through the expected interface is not automatically authorized.


Do Not Mix Routing Problems with Firewall Problems

Suppose:

nftables counter increases

and the rule accepts the packet, but the application still fails.

At that point, investigate routing.

On multi-homed Linux systems, a packet may enter through one interface while the reply leaves through another.

If the kernel selects an unexpected route, see Linux Traffic Uses the Wrong Interface and Linux Policy Routing with ip rule and Multiple Routing Tables.

The firewall can approve a connection and still be blamed for a routing failure it did not cause.


Watch for rp_filter on Multi-Homed Systems

Reverse-path filtering can interact with asymmetric routing.

A topology such as:

Request → eth0
Reply   → eth1

deserves special attention.

Do not disable security controls blindly because a multi-homed service fails.

First understand the routing path and the host’s rp_filter configuration.

Our Linux rp_filter and Asymmetric Routing guide covers this scenario in detail.


ARP Problems Occur Below nftables

If multiple interfaces are connected to the same Layer 2 network, unexpected ARP behavior can make a firewall problem appear mysterious.

Before rewriting nftables rules, inspect:

neighbor table
ARP replies
interface addresses
routing
packet capture

For multi-NIC same-subnet systems, see Linux ARP Flux with Multiple NICs on the Same Subnet.

The important troubleshooting principle is:

Do not fix a Layer 2 problem with a Layer 3/4 firewall rule.


Production Troubleshooting Workflow

When traffic fails, use the same workflow every time.

1. Confirm the route

Check:

ip route get 192.168.20.10

For policy-routing environments, inspect:

ip rule show
ip route show table all

2. Confirm the packet exists

Use:

tcpdump -ni any host 192.168.20.10

Add protocol and port filters where possible.

3. Inspect nftables counters

Use:

nft list ruleset

Determine which counters increase.

4. Inspect conntrack

For stateful problems:

conntrack -L

Narrow the output whenever possible.

5. Inspect NAT

If DNAT or SNAT is involved, determine what the packet looks like before and after translation.

6. Trace the firewall

For difficult cases, the official nftables tracing documentation describes how nftrace can be combined with:

nft monitor trace

to follow selected packets through the ruleset.

The workflow is therefore:

ROUTE
  ↓
PACKET CAPTURE
  ↓
COUNTERS
  ↓
CONNTRACK
  ↓
NAT
  ↓
TRACE

This is far more effective than randomly adding accept rules.


Validate Before Applying Changes

A syntax error in a production firewall configuration can cause serious problems.

When using a persistent nftables configuration, validate it before applying it.

For example, depending on the deployment:

sudo nft -c -f /etc/nftables.conf

The -c option performs a check without applying the ruleset.

Then, after validation, the configuration can be loaded using the appropriate deployment procedure.

This is particularly important when editing a firewall remotely.


Prefer Atomic Ruleset Updates

One of nftables’ important design advantages is support for atomic ruleset replacement through its transactional model.

That matters because firewall updates should not temporarily leave the machine in an inconsistent state.

The official nftables project documents nftables as the modern Netfilter packet-classification framework replacing the older iptables-family tools.

For complex production configurations, maintaining the ruleset in a file and loading a validated configuration is generally easier to review than executing hundreds of independent commands manually.


Keep the Ruleset Under Version Control

A production firewall is infrastructure code.

The configuration should ideally have:

version history
change descriptions
peer review
rollback capability
documentation

A Git repository can make it possible to answer:

Who changed the firewall?

What changed?

When?

Why?

What was the previous working configuration?

Do not store passwords, private keys, or other secrets in an ordinary ruleset repository.


Comment the Policy, Not the Syntax

Bad comment:

# Allow port 443

The rule itself already tells you that.

Better:

# Allow user VLANs to reach the internal customer portal over HTTPS

A useful comment explains why the rule exists.

Months later, that context is much more valuable than restating the command.


Name Objects Consistently

A consistent naming convention might use:

@user_networks
@server_networks
@management_networks

@web_servers
@dns_servers

@web_ports
@management_ports

and chains such as:

users_to_servers
management_to_servers
wan_to_dmz
dmz_to_internal
iot_policy

This makes large configurations self-documenting.


Keep IPv4 and IPv6 Policy Aligned

A firewall architecture is incomplete if IPv4 is carefully filtered while IPv6 is effectively ignored.

For every service, ask:

Is it reachable through IPv4?

Is it reachable through IPv6?

Should the policy be equivalent?

Are both paths logged and monitored?

Does routing differ?

The inet family can help organize dual-stack filtering, but it does not automatically design IPv6 security policy for you.


Test Failure Cases, Not Only Successful Connections

A firewall test plan should verify both:

what should work

and:

what must fail

For example:

Management → Server SSH
EXPECTED: ACCEPT

Users → Server HTTPS
EXPECTED: ACCEPT

Users → Server SSH
EXPECTED: DROP

IoT → Management
EXPECTED: DROP

Internet → Internal LAN
EXPECTED: DROP

Internet → Published DMZ HTTPS
EXPECTED: ACCEPT

A firewall is not validated simply because the administrator can still connect.


Common Architecture Mistakes

The most damaging nftables architecture problems are usually structural rather than syntactic.

One giant chain: Hundreds of unrelated rules become difficult to audit and troubleshoot.

Duplicated IP addresses: Use named sets when values are reused.

Duplicated ports: Group meaningful services where appropriate.

Mixing NAT and filtering mentally: Translation and authorization solve different problems.

Allowing entire internal address ranges: Internal networks should still be segmented by role.

Ignoring conntrack: Stateful policy becomes unnecessarily complex.

Logging everything: Excessive logs can hide the events that matter.

No counters: Troubleshooting becomes guesswork.

No IPv6 policy: Services may remain reachable through a path that was never reviewed.

No rollback strategy: A small configuration error can become an outage.

Random rule ordering: Policy becomes dependent on accidental placement rather than deliberate design.


Advanced nftables Architecture Checklist

Before considering a firewall production-ready, verify:

□ Security zones are documented.

□ INPUT, FORWARD and OUTPUT responsibilities are understood.

□ Default policies are intentional.

□ INVALID traffic has an explicit policy.

□ ESTABLISHED and RELATED traffic is handled deliberately.

□ New connections follow explicit zone policies.

□ Repeated networks are represented with meaningful sets.

□ Repeated services are grouped where useful.

□ Custom chains have clear responsibilities.

□ NAT and filtering are designed separately.

□ DMZ-to-internal access is restricted.

□ Management traffic has its own policy.

□ IoT traffic is not implicitly trusted.

□ IPv6 has been reviewed.

□ Important rules have counters.

□ Logging is selective and rate-controlled.

□ Log prefixes are consistent.

□ Routing has been tested separately from filtering.

□ Multi-homed systems have been checked for asymmetric routing.

□ Configuration can be validated before deployment.

□ A rollback or console recovery path exists.

□ Allowed and denied flows have both been tested.

If these questions have clear answers, the firewall is much easier to maintain.


Frequently Asked Questions

What is the best structure for an nftables firewall?

There is no universal ruleset for every network, but a scalable architecture usually separates base chains, connection-state handling, security zones, reusable sets, zone-specific custom chains, NAT, counters, and logging.

The objective is to make policy understandable rather than minimize the number of lines at any cost.

Should I use one nftables chain for everything?

Small servers can work with a few base-chain rules, but larger routers and firewalls benefit from custom chains that separate policies such as WAN-to-DMZ, management-to-server, and user-to-server traffic.

Should nftables use a default drop policy?

Default-drop policies are common when administrators want only explicitly permitted traffic to pass. They require careful planning because missing management or service rules can cause outages.

Should established connections be accepted before new connection rules?

In many stateful firewall architectures, established,related traffic is handled early while new connections proceed through the full access policy. The exact ordering must still match the network’s security requirements.

Should I use nftables sets?

Use sets when collections of addresses, networks, ports, or other values are reused or when they make the policy easier to understand and maintain.

What is the difference between a set and a map?

A set primarily tests membership. A map associates a key with a value. Verdict maps can associate keys with firewall verdicts or control flow.

The detailed explanation is available in nftables Sets and Maps.

Should NAT rules be inside the filtering architecture?

NAT and filtering are related parts of the packet path, but they perform different functions. Keep their purposes separate so that translation problems are not confused with authorization problems.

How should I debug a large nftables ruleset?

Use a repeatable sequence:

route
→ packet capture
→ counters
→ conntrack
→ NAT inspection
→ targeted nftables trace

This identifies the failing layer instead of relying on trial and error.


Conclusion

A production nftables firewall should not be designed as an ever-growing list of accept and drop commands.

The architecture should move from:

hundreds of independent rules

toward:

              NETWORK DESIGN
                    ↓
              SECURITY ZONES
                    ↓
               BASE CHAINS
                    ↓
               CONNTRACK
                    ↓
            SETS / MAPS / OBJECTS
                    ↓
              POLICY CHAINS
                    ↓
           COUNTERS + LOGGING
                    ↓
                 VERDICT

Each component should have a clear responsibility.

Routing determines where traffic travels.

Conntrack identifies connection state.

Sets represent reusable groups.

Maps represent relationships.

Custom chains organize security policy.

Counters show whether policy is actually being used.

Logging records important events.

NAT performs translation.

Verdicts enforce the final decision.

This structure also connects the CorgiNetwork Linux networking cluster into one logical learning path.

Start with Linux Bridge Networking with Network Namespaces and veth when building virtual network topologies, then move to Linux Inter-VLAN Routing with Network Namespaces for routed segmentation.

Use nftables Inter-VLAN Firewall to secure those routed networks and Linux DMZ with nftables when public services require a separate trust zone.

For NAT problems, continue with nftables DNAT Port Forwarding Not Working and nftables Hairpin NAT and NAT Loopback.

For stateful filtering, use nftables Conntrack States and Troubleshooting, followed by nftables Sets and Maps and nftables Dynamic Sets and Meters.

When packets still follow the wrong path despite correct firewall rules, move outside nftables and inspect Linux Traffic Uses the Wrong Interface, Linux Policy Routing with ip rule and Multiple Routing Tables, Linux rp_filter and Asymmetric Routing, and Linux ARP Flux with Multiple NICs on the Same Subnet.

The result is not merely a collection of tutorials. It is a connected technical architecture covering the complete path from Linux routing and Layer 2 behavior to VLAN segmentation, NAT, stateful filtering, advanced nftables policy, and production troubleshooting.

And the key design principle is simple:

A good firewall should make the network’s security policy easier to understand—not hide it behind more rules.

corginetwork

Recent Posts

AI Agents as Code: Git, Versioning & CI/CD Guide

AI Agents as Code: Managing AI Agent Configurations, Prompts and Tools with Git AI agents…

1 week ago

Data Center Power Distribution Architecture Guide

Data Center Power Distribution Architecture: UPS, PDU, Redundancy and Rack Power Explained Data center power…

1 week ago

DNSSEC Troubleshooting: How to Fix SERVFAIL, DS, DNSKEY and RRSIG Errors

DNSSEC Troubleshooting: Fix SERVFAIL & DNSKEY Errors DNSSEC Troubleshooting: How to Fix SERVFAIL, DS, DNSKEY…

2 weeks ago

Terraform State Management: Remote State, Locking & Backends

Terraform State Management Explained: Remote State, Locking, Backends and Best Practices Terraform makes infrastructure reproducible…

2 weeks ago

RTO vs RPO Explained: Disaster Recovery Objectives & Examples

RTO vs RPO Explained: Disaster Recovery Objectives, Examples and Planning A disaster recovery plan is…

2 weeks ago

Network Intrusion Detection: NIDS, Sensors & Traffic Analysis

Network Intrusion Detection Explained: NIDS, Sensors, Signatures and Traffic Analysis A firewall can decide whether…

2 weeks ago