Linux / Advanced: boundaries, security, and recovery / Lesson 17
Reason about firewall policy safely
Read packet-filtering concepts, namespace context, and rule interactions before designing an isolated lab policy.
On this page
Lesson goals
- Distinguish input, output, and forwarded traffic.
- Explain stateful rules and rule evaluation context.
- Validate a policy without changing host rules.
Classify the traffic before writing a rule
A host firewall evaluates packets along defined kernel hooks. Input traffic targets the local host, output originates locally, and forwarded traffic passes through the host toward another destination. A container bridge or router can make forwarding relevant even when an administrator thinks only about local services. Network namespaces have separate network stacks and can have separate firewall context. Determine source, destination, protocol, port, direction, and namespace before choosing a rule location. A correct port match in the wrong traffic path does not enforce the intended policy.
Tables, chains, and hooks have distinct roles
nftables organizes rules into tables and chains. A regular chain is reached through rule flow; a base chain attaches to a hook with a type and priority. The inet family can address IPv4 and IPv6 together, but individual expressions may still apply to only one protocol. Rule order and base-chain priority affect evaluation. An accept verdict in one base chain does not guarantee that another chain at the same hook will not later drop the packet. Review the complete ruleset and any managing frontend instead of reasoning from a single visible rule.
# Read-only inspection inside an authorized disposable network lab.
nft list tables
nft -a list ruleset
The output may contain sensitive network details and requires suitable lab privileges. These commands list policy only; they do not flush, add, or delete rules.
Stateful filtering tracks connections
Connection tracking lets rules distinguish new traffic from packets belonging to established or related exchanges. A policy often permits established replies while restricting new inbound connections. This does not authenticate the application or encrypt content. UDP has connection-tracking behavior even though its protocol does not establish a TCP-style session. ICMP and ICMPv6 also support essential network functions; indiscriminate blocking can break discovery or path-related behavior. Design policy from required communication and verify both protocol families rather than copying a short ruleset whose assumptions are unknown.
Validate syntax without applying a host policy
The nft --check mode validates a supplied command sequence without applying its changes, but still needs an appropriate kernel and privileges. It is a syntax and semantic preparation step, not a full proof of packet behavior. Use only in an isolated lab and never assume a sample is safe to install remotely. Configuration frontends such as firewalld may own the live ruleset; bypassing them can create inconsistent state or be overwritten later. Keep one authoritative management path and document how generated rules relate to the desired policy.
table inet lab_review {
chain observed_input {
type filter hook input priority 0; policy accept;
ct state established,related counter accept
}
}
This is study-only lab syntax, not a recommended complete firewall. Its default accept policy intentionally demonstrates structure without claiming protection. A prepared isolated lab could inspect it with nft --check -f lab-review.nft; do not apply it to the host.
Test permitted and denied paths
A policy change needs an explicit communication matrix: which source may reach which destination and service, in each direction and protocol family. Verify a permitted path and a denied path from authorized test endpoints. Counters can help confirm which rule observed traffic, while application and socket evidence explain what happened after filtering. Preserve management access through a prepared independent recovery channel before a real deployment. In the lab, change one hypothesis at a time and record the initial ruleset, proposed delta, verification result, and rollback method.
Common errors and fixes
Opening input does not fix forwarded traffic
- Why it happens
- The packet’s path was classified incorrectly.
- How to fix it
- Map the route and namespace to the correct hook.
- Prevent it next time
- Document direction before port policy.
One accept rule is assumed final everywhere
- Why it happens
- Other base chains and priorities were ignored.
- How to fix it
- Review the complete ruleset and frontend ownership.
- Prevent it next time
- Treat policy as a complete evaluation graph.
IPv4 policy leaves an IPv6 gap
- Why it happens
- Only one protocol family was considered.
- How to fix it
- Review both families and required control traffic.
- Prevent it next time
- Include IPv6 in the communication matrix.
Check your understanding
1. A container port fails while the host listener works locally. Which contexts matter?
Show worked solution
Inspect the container network namespace, bridge or forwarding path, address translation if present, host and namespace policy, and listener binding. A successful localhost request exercises a different path from a remote forwarded request. Identify the failed path before editing any rule.
2. Why is a successful nft --check insufficient acceptance evidence?
Show worked solution
It checks whether the prepared sequence can be accepted without applying it; it does not exercise the intended traffic, application state, routing, or interaction with future managed changes. Use an isolated deployment and explicit permitted/denied tests as the next controlled step.
Key takeaways
- Match policy to packet direction, namespace, and family.
- Inspect the complete managed ruleset and test both outcomes.