Servers & Infrastructure

Linux nftables Inter-VLAN Firewall: Stateful VLAN Rules 2026

Linux nftables Inter-VLAN Firewall: Build Stateful Firewall Rules Between VLANs

Inter-VLAN routing solves one problem: it allows hosts in different VLANs to communicate.

But in a production network, simply making every VLAN reachable from every other VLAN is rarely the desired end state.

Consider a network containing:

VLAN 10 — Users
VLAN 20 — Servers
VLAN 30 — Management
VLAN 40 — IoT

Routing can connect all four networks.

Security policy should decide which connections are actually permitted.

For example:

Users      → Web Servers       ALLOW HTTP/HTTPS
Users      → Management        DENY
IoT        → Servers           DENY by default
Management → Servers           ALLOW SSH
Servers    → DNS               ALLOW DNS

This is where nftables becomes a critical part of Linux network architecture.

In this practical guide, we will transform the Linux router built in the Linux Inter-VLAN Routing with Network Namespaces guide into a stateful inter-VLAN firewall.

Instead of simply asking:

Can Linux route this packet?

we will also ask:

Should Linux allow this connection?

The final architecture will combine:

VLAN segmentation
        ↓
Linux routing
        ↓
nftables
        ↓
Connection tracking
        ↓
Stateful firewall policy

Routing and Firewalling Solve Different Problems

One of the most important concepts in Linux networking is that routing and filtering are separate decisions.

Routing answers:

Where should this packet go?

The firewall answers:

Should this packet be allowed to go there?

NAT answers another question:

Should an address or port be translated?

Therefore:

Routing ≠ Firewalling ≠ NAT

This distinction matters when troubleshooting.

Suppose:

192.168.10.10

needs to communicate with:

192.168.20.20

Linux may correctly determine:

192.168.20.0/24
        ↓
      VLAN 20

but nftables may still intentionally drop the packet.

That is not a routing failure.

It is a security policy.

If you need to review the routing layer first, use the Linux Inter-VLAN Routing with Network Namespaces guide before implementing the firewall.


Our Inter-VLAN Firewall Architecture

We will expand the previous virtual router into four logical security zones.

                         Linux Router
                         + nftables
                              |
          +-------------------+-------------------+
          |                   |                   |
       VLAN 10             VLAN 20            VLAN 30
        USERS              SERVERS           MANAGEMENT
   192.168.10.0/24     192.168.20.0/24    192.168.30.0/24

Later we will add:

VLAN 40
IoT
192.168.40.0/24

The security model will be:

USERS
   |
   | HTTP/HTTPS
   v
SERVERS


MANAGEMENT
   |
   | SSH
   v
SERVERS


IoT
   |
   X
SERVERS


USERS
   |
   X
MANAGEMENT

Anything we have not explicitly allowed will be denied.

That is our core policy.


Why Use a Default-Deny Policy?

There are two broad firewall philosophies.

The first is:

Allow everything
      ↓
Block specific unwanted traffic

The second is:

Block everything
      ↓
Allow required traffic

For controlled inter-VLAN segmentation, the second model is usually much easier to reason about.

We therefore want:

policy drop

on our forwarding chain.

Traffic must match an explicit accept rule or an appropriate stateful rule before it can cross the router.

This creates:

DEFAULT
   ↓
 DROP

EXCEPT
   ↓
explicitly permitted traffic

How nftables Sees Routed Traffic

nftables integrates with the Linux Netfilter framework.

For routed traffic, the simplified packet path is:

Network Interface
       ↓
   PREROUTING
       ↓
Routing Decision
       ↓
    FORWARD
       ↓
  POSTROUTING
       ↓
Outgoing Interface

The official Netfilter documentation identifies forward as the hook used for packets that enter the machine but are destined for another system.

That makes the forwarding chain the natural place to enforce our inter-VLAN security policy.


Before Creating Firewall Rules

Confirm that routing works before introducing filtering.

Inside the router namespace from our previous lab:

sudo ip netns exec ns-rtr ip -br addr

Check routes:

sudo ip netns exec ns-rtr ip route

Check forwarding:

sudo ip netns exec ns-rtr \
sysctl net.ipv4.ip_forward

Expected:

net.ipv4.ip_forward = 1

If routing does not work before the firewall is installed, do not expect firewall rules to fix it.

The correct order is:

Layer 2
   ↓
VLAN
   ↓
Layer 3
   ↓
Routing
   ↓
Firewall

For VLAN troubleshooting, see Linux Bridge VLAN Filtering Explained.


Inspect Existing nftables Rules First

Before modifying a Linux firewall, always inspect the current ruleset.

Run:

sudo ip netns exec ns-rtr \
nft list ruleset

On a production machine, this step is mandatory.

Never blindly run:

nft flush ruleset

on a remote or production server.

Doing so can remove:

SSH access rules
NAT rules
VPN rules
container rules
security policies

and potentially disconnect you from the machine.

Our examples assume an isolated lab router namespace.


Create the Firewall Table

We’ll use the inet family.

Create:

sudo ip netns exec ns-rtr \
nft add table inet vlan_firewall

The inet family is useful because it can accommodate IPv4 and IPv6 rules in the same logical table when the rules are designed appropriately.

Verify:

sudo ip netns exec ns-rtr \
nft list tables

You should see:

table inet vlan_firewall

Create the Forward Chain

Now create a base chain:

sudo ip netns exec ns-rtr \
nft 'add chain inet vlan_firewall forward { type filter hook forward priority 0; policy drop; }'

The critical part is:

hook forward

because we are filtering routed traffic.

And:

policy drop

means unmatched forwarded packets are discarded.

Our router has now moved from:

Route everything

to:

Route only traffic permitted by firewall policy

Verify the Chain

Run:

sudo ip netns exec ns-rtr \
nft list table inet vlan_firewall

You should see something conceptually similar to:

table inet vlan_firewall {

    chain forward {

        type filter hook forward priority filter;
        policy drop;

    }

}

At this point, inter-VLAN communication may stop.

That is expected.

We created a firewall whose default behavior is:

DROP

but have not added any exceptions yet.


Understanding Stateful Firewalling

A stateless firewall might inspect every packet independently.

A stateful firewall understands that packets belong to connections.

For example:

Client
  |
  | TCP SYN
  v
Server

followed by:

Client
  ^
  | SYN-ACK
  |
Server

and later:

Client ←→ Server

These packets belong to the same connection.

Linux Netfilter tracks connection information using conntrack.

Important connection states include:

NEW
ESTABLISHED
RELATED
INVALID

This allows us to express policies such as:

Allow VLAN 10 to initiate HTTPS to VLAN 20

without writing a separate broad rule that allows VLAN 20 to initiate arbitrary connections back toward VLAN 10.


What Does ct state established Mean?

Suppose VLAN 10 starts:

192.168.10.10
      ↓
TCP/443
      ↓
192.168.20.20

The initial connection is new.

After connection tracking has seen the appropriate traffic, packets can be associated with an established connection.

So instead of creating a broad reverse rule:

VLAN 20 → VLAN 10
ALLOW EVERYTHING

we can permit:

ESTABLISHED
RELATED

traffic.

This is one of the central benefits of a stateful firewall.


Allow Established and Related Traffic

Add:

sudo ip netns exec ns-rtr \
nft add rule inet vlan_firewall forward \
ct state established,related accept

Now inspect:

sudo ip netns exec ns-rtr \
nft list chain inet vlan_firewall forward

The conceptual policy becomes:

Existing permitted connection?
           |
          YES
           |
           v
         ACCEPT


Otherwise
           |
           v
Continue evaluating rules

The Netfilter nftables documentation defines established and related as connection-tracking states that can be matched directly by nftables rules.


Drop Invalid Traffic Early

We can also explicitly handle invalid connection-tracking state:

sudo ip netns exec ns-rtr \
nft add rule inet vlan_firewall forward \
ct state invalid drop

Our early chain becomes:

INVALID
   ↓
 DROP


ESTABLISHED / RELATED
          ↓
        ACCEPT

Then new connections must match explicit security policy.


Build the User-to-Server Policy

Assume:

VLAN 10
192.168.10.0/24

contains users.

And:

VLAN 20
192.168.20.0/24

contains application servers.

Users need:

HTTP  → TCP/80
HTTPS → TCP/443

but they should not receive unrestricted access to server services.

Add:

sudo ip netns exec ns-rtr \
nft add rule inet vlan_firewall forward \
ip saddr 192.168.10.0/24 \
ip daddr 192.168.20.0/24 \
tcp dport { 80, 443 } \
ct state new accept

The policy is now:

VLAN 10
   |
   +------ TCP/80 ------+
   |                    |
   +------ TCP/443 -----+----> VLAN 20

while something like:

VLAN 10
   |
 TCP/22
   |
   X
   |
VLAN 20

does not match the rule and eventually reaches the default-drop policy.


Why Specify Source and Destination Networks?

You could create an overly broad rule such as:

tcp dport 443 accept

but that may allow HTTPS traffic between zones you never intended to connect.

A stronger security rule expresses context:

SOURCE
+
DESTINATION
+
PROTOCOL
+
PORT
+
STATE

For example:

192.168.10.0/24
        ↓
192.168.20.0/24
        ↓
TCP
        ↓
80 / 443
        ↓
NEW
        ↓
ACCEPT

This makes the firewall policy easier to audit.


Create a Management VLAN

Now imagine:

VLAN 30
192.168.30.0/24

is reserved for administrators.

The management network needs SSH access to servers.

Policy:

Management
     |
     | SSH
     v
 Servers

Add:

sudo ip netns exec ns-rtr \
nft add rule inet vlan_firewall forward \
ip saddr 192.168.30.0/24 \
ip daddr 192.168.20.0/24 \
tcp dport 22 \
ct state new accept

Now:

VLAN 30 → VLAN 20 → SSH

is permitted.

But:

VLAN 10 → VLAN 20 → SSH

remains blocked unless another rule allows it.

This is real network segmentation.


Restrict SSH to Specific Administration Hosts

We can go further.

Instead of allowing the entire management subnet:

192.168.30.0/24

suppose only:

192.168.30.10

is the administration workstation.

Then use:

sudo ip netns exec ns-rtr \
nft add rule inet vlan_firewall forward \
ip saddr 192.168.30.10 \
ip daddr 192.168.20.0/24 \
tcp dport 22 \
ct state new accept

The security boundary becomes much narrower:

Admin Workstation
192.168.30.10
       |
      SSH
       |
       v
Server VLAN

rather than:

Anything in Management VLAN
           ↓
          SSH
           ↓
Servers

Restrict SSH to One Server

Suppose only:

192.168.20.10

should accept administrative SSH.

Use:

sudo ip netns exec ns-rtr \
nft add rule inet vlan_firewall forward \
ip saddr 192.168.30.10 \
ip daddr 192.168.20.10 \
tcp dport 22 \
ct state new accept

Now the rule describes:

WHO
192.168.30.10

CAN REACH
192.168.20.10

USING
TCP/22

This is substantially easier to reason about during a security audit.


Add an IoT VLAN

IoT networks are a useful example because devices often need restricted outbound connectivity but should not have broad access to trusted infrastructure.

Suppose:

VLAN 40
192.168.40.0/24

contains cameras, sensors, and smart devices.

We do not create a general rule:

192.168.40.0/24
        ↓
192.168.20.0/24
        ↓
ACCEPT

Therefore, under our default-drop model:

IoT
 |
 X
 |
Servers

is already blocked.

This demonstrates an important property of default-deny design:

You do not need a drop rule for every unwanted relationship.

Unmatched traffic is denied automatically.


Allow DNS to a Dedicated Resolver

Suppose the network has an internal DNS resolver:

192.168.20.53

and VLAN 10 needs DNS.

Allow UDP DNS:

sudo ip netns exec ns-rtr \
nft add rule inet vlan_firewall forward \
ip saddr 192.168.10.0/24 \
ip daddr 192.168.20.53 \
udp dport 53 \
ct state new accept

DNS can also use TCP, so if your design requires normal TCP DNS operation, add:

sudo ip netns exec ns-rtr \
nft add rule inet vlan_firewall forward \
ip saddr 192.168.10.0/24 \
ip daddr 192.168.20.53 \
tcp dport 53 \
ct state new accept

Now users can reach:

192.168.20.53:53

without gaining broad access to the entire server VLAN.


Allow Multiple Services with Sets

One of nftables’ strengths is its support for sets.

Instead of separate rules:

TCP/80
TCP/443

we used:

tcp dport { 80, 443 }

You can extend this concept.

For example:

{ 22, 80, 443 }

But do not combine ports simply because nftables allows it.

Security policy should remain understandable.

A rule representing:

Web services

should not quietly include:

SSH
database
monitoring

unless those services genuinely share the same trust relationship.


Rule Order Matters

Suppose your chain contains:

1. established,related accept
2. VLAN10 → Web Server HTTPS accept
3. VLAN30 → Server SSH accept
4. default policy drop

Packets are evaluated according to the ruleset.

Design rule order intentionally.

A useful conceptual structure is:

Invalid traffic
       ↓
Established traffic
       ↓
Highly specific trusted rules
       ↓
Application/service rules
       ↓
Logging
       ↓
Default drop

This also makes the ruleset easier for another administrator to understand.


Add Counters

During troubleshooting, it is useful to know whether a rule is actually being matched.

For example:

sudo ip netns exec ns-rtr \
nft add rule inet vlan_firewall forward \
ip saddr 192.168.10.0/24 \
ip daddr 192.168.20.0/24 \
tcp dport 443 \
counter \
ct state new accept

After generating traffic:

sudo ip netns exec ns-rtr \
nft list chain inet vlan_firewall forward

you can inspect packet and byte counters.

This helps answer:

Did traffic reach this rule?

rather than assuming the firewall is responsible.


Add Logging Carefully

You can log selected traffic before dropping it.

For example:

sudo ip netns exec ns-rtr \
nft add rule inet vlan_firewall forward \
ip saddr 192.168.40.0/24 \
ip daddr 192.168.20.0/24 \
limit rate 5/second \
log prefix \"IOT_BLOCKED: \"

Because the chain policy is already drop, traffic can then fall through to the default policy.

Why rate-limit logging?

Because a busy or malicious host could otherwise generate enormous numbers of log messages.

Never turn a firewall into a log-based denial-of-service against your own server.


Test Allowed HTTPS Traffic

Assume a web server is listening at:

192.168.20.20:443

From VLAN 10:

curl -k https://192.168.20.20/

If the HTTPS policy is correct:

VLAN 10
   |
TCP/443
   |
   v
VLAN 20

should succeed.

Then inspect:

sudo ip netns exec ns-rtr \
nft list chain inet vlan_firewall forward

The relevant counter should increase if one was configured.


Test Blocked SSH Traffic

From VLAN 10:

ssh 192.168.20.20

Under our policy:

USERS
  |
SSH
  |
  X
  |
SERVERS

should be blocked.

But from the authorized management workstation:

192.168.30.10

SSH should be permitted if the server and routing configuration are correct.

This gives us a useful validation matrix:

Source Destination Service Expected
Users Web Server HTTPS Allow
Users Server SSH Block
Management Server SSH Allow
IoT Server SSH Block
Users DNS Server DNS Allow

Do not test only the traffic you expect to work.

A security policy must also be tested for traffic that must fail.


Why Return Traffic Works

Suppose the user VLAN starts an HTTPS session:

VLAN 10
   |
NEW HTTPS
   |
   v
VLAN 20

The initial connection matches our explicit HTTPS rule.

Return traffic can then match:

ct state established,related accept

Therefore we do not need:

VLAN 20
   ↓
allow all traffic
   ↓
VLAN 10

This is the foundation of stateful firewalling.

The nftables conntrack system recognizes states including new, established, related, invalid, and untracked.


NEW vs ESTABLISHED vs RELATED

A simplified mental model is:

NEW
 |
 | connection begins
 v
ESTABLISHED
 |
 | connection continues
 v
ESTABLISHED

RELATED is used for traffic associated with an existing connection but represented as a separate connection.

Do not confuse:

RELATED

with:

any packet from a host we previously trusted

It has a specific connection-tracking meaning.


Inspect Connection Tracking

If the conntrack utility is installed, you can inspect tracked connections:

sudo ip netns exec ns-rtr \
conntrack -L

Generate an HTTPS connection and inspect again.

You can then correlate:

Application traffic
       ↓
Conntrack entry
       ↓
nftables state rule

This is an excellent way to understand why return traffic is accepted.


Firewalling Does Not Replace VLANs

A tempting design is:

One giant LAN
     +
Firewall rules

But VLANs and firewalls solve different parts of segmentation.

VLANs provide Layer 2 separation.

Routing creates controlled Layer 3 paths.

nftables applies security policy to those paths.

Together:

VLAN
 ↓
Layer 2 boundary
 ↓
Router
 ↓
Layer 3 boundary
 ↓
Firewall
 ↓
Security policy

For the Layer 2 component, see Linux Bridge VLAN Filtering Explained.


Firewalling Does Not Replace Routing

Another mistake is to troubleshoot every failed connection by editing firewall rules.

Suppose:

192.168.10.10

has no route to its gateway.

Adding:

accept

to nftables will not fix that.

Likewise, if Linux chooses the wrong interface, the underlying issue may be route selection.

CorgiNetwork’s Linux Traffic Uses the Wrong Interface covers that diagnostic path.


Firewalling and Policy Routing

Now consider a more advanced router:

VLAN 10 → ISP A
VLAN 20 → ISP B

The firewall may allow the packet correctly, while policy routing determines which WAN connection it uses.

The path becomes:

Packet
  ↓
Firewall / Netfilter processing
  ↓
Routing policy
  ↓
Routing table
  ↓
WAN interface

If source-dependent routing is required, use Linux Policy Routing with ip rule and Multiple Routing Tables.

For persistent Ubuntu configurations involving several gateways, see Netplan Multiple Default Routes and Policy Routing.


Firewalling and Asymmetric Routing

Stateful firewalls care about connection state.

That makes asymmetric network paths particularly important.

Imagine:

Request
VLAN 10
   ↓
Router A
   ↓
Server


Reply
Server
   ↓
Router B
   ↓
VLAN 10

Depending on the architecture, one firewall may not observe both directions as expected.

Before blaming conntrack, inspect:

forward path
return path
routing tables
policy rules

CorgiNetwork’s Linux rp_filter and Asymmetric Routing explains another Linux mechanism that can affect asymmetric designs.


Troubleshooting: Everything Is Blocked

You enable:

policy drop

and suddenly nothing works.

First inspect:

sudo ip netns exec ns-rtr \
nft list ruleset

Then verify whether you have:

ct state established,related accept

and explicit rules for new permitted connections.

Check counters.

Then capture traffic:

sudo ip netns exec ns-rtr \
tcpdump -eni any

If the packet never reaches the router, nftables is not the first problem.


Troubleshooting: HTTPS Is Blocked

Check the routing decision:

sudo ip netns exec ns-rtr \
ip route get 192.168.20.20

Then verify:

sudo ip netns exec ns-rtr \
nft list chain inet vlan_firewall forward

Confirm:

source network
destination network
protocol
destination port

all match the traffic you are generating.

Then capture:

sudo ip netns exec ns-rtr \
tcpdump -eni any host 192.168.20.20

Do not assume a port number without verifying what the application actually uses.


Troubleshooting: Request Arrives but Reply Fails

This is a classic problem.

Suppose:

Client → Server

appears in the packet capture, but:

Server → Client

does not return.

Inspect the server’s route:

ip route

The server needs a valid return path.

Then inspect conntrack:

conntrack -L

and firewall counters.

A firewall cannot compensate for a fundamentally incorrect return route.


Troubleshooting: Rule Counter Stays at Zero

If you added:

counter

and the value remains zero, the traffic is not matching that rule.

Possible causes include:

wrong source subnet
wrong destination subnet
wrong protocol
wrong port
earlier rule already handled packet
traffic never reached router
wrong chain/hook

This is valuable evidence.

A zero counter can be more useful than repeatedly rewriting the rule.


Troubleshooting: VLAN Traffic Never Reaches nftables

Return to Layer 2.

Check:

bridge vlan show

Then:

bridge fdb show

Inspect interfaces:

ip -br link

Capture the VLAN/trunk:

tcpdump -eni INTERFACE vlan

If VLAN tagging or bridge membership is wrong, nftables cannot fix it.

Read Linux Bridge Networking with Network Namespaces and veth if the bridge path itself is unclear.


A Professional Troubleshooting Workflow

For a failed connection:

Client
  ↓
Firewall Router
  ↓
Server

check the following order:

1. Client interface
        ↓
2. Client IP address
        ↓
3. Client route
        ↓
4. Gateway ARP
        ↓
5. VLAN membership
        ↓
6. Router ingress
        ↓
7. Routing decision
        ↓
8. nftables forward rule
        ↓
9. Router egress
        ↓
10. Server receives packet
        ↓
11. Server return route
        ↓
12. Conntrack state
        ↓
13. Return firewall processing
        ↓
14. Client receives reply

This is dramatically more effective than changing firewall rules until something starts working.


Use nft monitor trace for Difficult Problems

For advanced nftables troubleshooting, packet tracing can show how packets move through the ruleset.

A typical workflow involves enabling nftables tracing for carefully selected traffic and then using:

nft monitor trace

This can reveal:

which chain was entered
which rule matched
which verdict was returned

Because tracing can generate substantial output, target it narrowly in production environments.


Build Security Zones, Not Random Rules

As the network grows, think in terms of zones:

USERS
SERVERS
MANAGEMENT
IoT
GUEST
DMZ
BACKUP
MONITORING

Then document relationships:

USERS → SERVERS
HTTP/HTTPS


MANAGEMENT → SERVERS
SSH/HTTPS


SERVERS → BACKUP
Backup protocol


IoT → INTERNAL
DENY


GUEST → INTERNAL
DENY

This scales better than accumulating hundreds of unrelated firewall commands.


Example Production Policy Matrix

A more realistic architecture might use:

Source Zone Destination Service Policy
Users Web Servers 80/443 Allow
Users Database 5432 Deny
Users Management Any Deny
App Servers Database 5432 Allow
Management Servers 22/443 Allow
IoT Internal Servers Any Deny
Guest Internal Networks Any Deny

The firewall configuration should be derived from this policy—not the other way around.


Application-to-Database Segmentation

Suppose:

VLAN 20
Application Servers
192.168.20.0/24

and:

VLAN 50
Database
192.168.50.0/24

Only PostgreSQL should be permitted:

nft add rule inet vlan_firewall forward \
ip saddr 192.168.20.0/24 \
ip daddr 192.168.50.0/24 \
tcp dport 5432 \
ct state new accept

Now:

Application
     |
 PostgreSQL
     |
     v
 Database

is allowed while unrelated services remain blocked by the default policy.

This is significantly stronger than merely placing the database in another VLAN while permitting unrestricted routing to it.


Why Internal Segmentation Matters

A firewall should not exist only at the Internet edge.

Consider an attacker who compromises a user workstation.

Without internal controls:

Compromised PC
      ↓
Servers
      ↓
Database
      ↓
Management
      ↓
Backups

may all be reachable.

With segmentation:

Compromised PC
      ↓
User VLAN
      ↓
Firewall
      ↓
Only explicitly allowed services

the network places additional constraints on lateral movement.

VLANs create the topology.

The firewall enforces the trust relationships.


nftables and Linux Network Namespaces

Our lab uses a router namespace because network namespaces isolate networking resources.

This lets us maintain a separate:

routing table
interfaces
neighbor table
firewall

for the virtual router.

The architecture started in Linux Network Namespaces Explained and now evolves into:

Network Namespace
       ↓
Virtual Router
       ↓
VLAN Interfaces
       ↓
Routing
       ↓
nftables Firewall

This is an excellent platform for learning enterprise networking without requiring multiple physical routers and switches.


Persist the Ruleset

Interactive commands are ideal for a lab.

Production firewalls should be stored in a persistent configuration and loaded through the operating system’s supported nftables service.

A typical ruleset structure might resemble:

table inet vlan_firewall {
    chain forward {
        type filter hook forward priority filter;
        policy drop;

        ct state invalid drop
        ct state established,related accept

        # Explicit zone policies follow
    }
}

The exact persistence mechanism depends on the Linux distribution.

Always validate the ruleset before applying major firewall changes remotely.


Production Safety

Before changing a remote firewall:

✓ Back up the existing ruleset
✓ Keep an active management session
✓ Verify out-of-band access if available
✓ Validate syntax
✓ Avoid flushing production rules blindly
✓ Test new policy incrementally
✓ Confirm SSH management rules first
✓ Monitor counters
✓ Capture packets when behavior is unclear

A technically correct firewall policy is still dangerous if deployed without a recovery path.


Do Not Forget IPv6

A common security mistake is designing excellent IPv4 segmentation while ignoring IPv6.

If IPv6 is enabled and routed in your environment, the security model must account for it as well.

Using the inet nftables family can help organize IPv4 and IPv6 filtering under one table, but address-family-specific expressions and policies still need to be designed correctly.

Do not assume:

IPv4 blocked

automatically means:

all network paths blocked

Frequently Asked Questions

What is an nftables inter-VLAN firewall?

It is a Linux firewall configuration that filters routed traffic between different VLAN networks using nftables.

For example:

VLAN 10
   ↓
nftables
   ↓
VLAN 20

The router provides reachability while nftables determines which connections are permitted.


Should inter-VLAN traffic be allowed by default?

That depends on the network’s requirements, but security-focused segmentation commonly benefits from a default-deny model in which required communication is explicitly permitted.

The important point is to derive the policy from actual application and administration requirements.


What is the nftables forward chain?

A base chain attached to the forward hook can inspect packets that are being routed through the Linux system rather than delivered to a local process.

That makes it central to Linux router and firewall configurations.


What does ct state established,related do?

It matches packets associated with established connections and related connections tracked by Netfilter conntrack.

This allows return traffic for permitted stateful connections without creating broad reverse-direction access rules.


Do I need NAT between VLANs?

Usually not when the router has direct routes to both internal networks and each network has a valid return path.

NAT and routing solve different problems.


Should I use iptables or nftables?

Modern Linux systems commonly use nftables as the current Netfilter packet-classification interface. When maintaining an existing environment, however, first determine which firewall framework and compatibility layers the distribution and applications are already using before replacing anything.


How can I see my nftables rules?

Use:

nft list ruleset

For our namespace lab:

sudo ip netns exec ns-rtr \
nft list ruleset

How do I troubleshoot an nftables rule that is not matching?

Use:

nft list ruleset
counters
tcpdump
conntrack
ip route get
nft monitor trace

and troubleshoot from the source toward the destination rather than changing multiple layers simultaneously.


Conclusion

Building VLANs is only the beginning of network segmentation.

A complete architecture looks like:

Endpoint
   ↓
VLAN
   ↓
Linux Bridge
   ↓
Router
   ↓
nftables
   ↓
Security Policy
   ↓
Destination VLAN

The VLAN answers:

Which Layer 2 domain does this system belong to?

The router answers:

Where should the packet go?

nftables answers:

Should this connection be permitted?

And conntrack gives the firewall the state required to distinguish new connections from traffic belonging to established or related flows.

The essential design pattern is:

Default Drop
      +
Established/Related
      +
Explicit New Connections
      =
Controlled Inter-VLAN Communication

The most useful diagnostic commands are:

nft list ruleset
ip route
ip route get DESTINATION
ip neigh
bridge vlan show
bridge fdb show
conntrack -L
tcpdump -eni INTERFACE
nft monitor trace

But the commands are less important than the troubleshooting order.

First prove that Layer 2 works.

Then prove that routing works.

Then inspect the firewall.

Then verify the return path.

This article extends the CorgiNetwork Linux networking path established in Linux Network Namespaces Explained, Linux Bridge Networking with Network Namespaces and veth, Linux Bridge VLAN Filtering Explained, and Linux Inter-VLAN Routing with Network Namespaces.

For more complex route selection, Linux Policy Routing with ip rule and Multiple Routing Tables explains how Linux can select different routing tables based on policy.

For persistent multi-gateway Ubuntu environments, Netplan Multiple Default Routes and Policy Routing extends that architecture.

When packets unexpectedly leave through the wrong NIC, Linux Traffic Uses the Wrong Interface provides a packet-path troubleshooting workflow.

For multi-interface ARP behavior, Linux ARP Flux and Multiple NICs on the Same Subnet addresses neighbor-resolution problems.

And when asymmetric routing interacts with Linux reverse-path validation, Linux rp_filter and Asymmetric Routing explains how to diagnose the issue correctly.

Together, the cluster now forms:

Network Namespaces
        ↓
       veth
        ↓
Linux Bridge
        ↓
VLAN Filtering
        ↓
Inter-VLAN Routing
        ↓
nftables Firewall
        ↓
Stateful Security
        ↓
Policy Routing
        ↓
Advanced Linux Network Architecture
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