nftables section
Some checks failed
Build and Deploy MITM Webserver / build (push) Has been cancelled
Build and Deploy MITM Webserver / traffic_target (push) Has been cancelled

This commit is contained in:
2026-08-08 17:12:07 +02:00
parent a4b19f8c3e
commit 68827ed7e3
2 changed files with 335 additions and 184 deletions

View File

@@ -75,6 +75,147 @@ A transparent inline bridge occupies the forwarding path without acting as an \a
Transparency should not be understood as complete undetectability. An inline bridge can affect latency, packet ordering, loss behavior, link-state propagation, and bridge-control behavior. If \ac{STP} is enabled, \acp{BPDU} and forwarding-delay behavior may become externally visible \cite{linuxkernelbridgedocs}. If \ac{TLS} proxying is added on top of forwarding, certificate and handshake artifacts can reveal the interception point \cite{durumeric2017httpsinterception}. The transparency goal in this thesis is therefore narrower and technical: the system should forward traffic as a Layer-2 inline bridge without introducing an additional \ac{IP} hop, without requiring endpoint proxy configuration, and without terminating application-layer sessions unless a later manipulation component explicitly does so.
\section{Linux Packet Filtering with \texttt{nftables}}
\label{sec:nftables}
% cites noch ergänzen: nftables_manpage und nf queue noch
\texttt{nftables} is a framework for packet filtering and classification in Linux.
The \texttt{nft} command-line tool is used to set up, maintain, and inspect packet-filtering and classification rules in the Linux kernel.
The corresponding Linux kernel subsystem is called \texttt{nf\_tables} and is part of Netfilter.
An \texttt{nftables} ruleset is organized using several types of objects.
In particular, \textbf{tables} are containers for chains, sets, and stateful objects, while \textbf{chains} are containers for rules.
Tables are identified by an address family and a name.
The supported table families are \texttt{ip}, \texttt{ip6}, \texttt{inet}, \texttt{arp}, \texttt{bridge}, and \texttt{netdev}.
If no family is specified, the \texttt{ip} family is used by default.
\subsection{Address Families and Hooks}
\label{sec:nftables-address-families}
Address families determine the type of packets that \texttt{nftables} processes.
For each address family, the kernel provides hooks at particular stages of the packet-processing path.
These hooks invoke \texttt{nftables} when rules for the respective hooks exist.
The \texttt{ip} family processes IPv4 packets, \texttt{ip6} processes IPv6 packets, and \texttt{inet} provides a combined IPv4/IPv6 family.
The \texttt{arp} family handles IPv4 ARP packets, the \texttt{bridge} family handles packets traversing a bridge device, and the \texttt{netdev} family handles packets on the ingress and egress paths.
\texttt{nftables} objects exist in address-family-specific namespaces.
For the IPv4, IPv6, and \texttt{inet} address families, \texttt{nftables} defines hooks at different stages of packet processing.
The \texttt{prerouting} hook processes packets entering the system before the routing process.
Packets delivered to the local system are processed by the \texttt{input} hook, while packets forwarded to another host are processed by the \texttt{forward} hook.
Packets generated by local processes pass through the \texttt{output} hook, and packets leaving the system pass through the \texttt{postrouting} hook.
The \texttt{inet} family additionally supports an \texttt{ingress} hook, which is invoked before the Layer-3 protocol handlers and therefore before \texttt{prerouting}.
The \texttt{bridge} address family handles Ethernet packets traversing bridge devices.
According to the \texttt{nftables} documentation, its list of supported hooks is identical to that of the IPv4, IPv6, and \texttt{inet} families described above.
\subsection{Tables, Chains, and Rules}
\label{sec:nftables-tables-chains-rules}
Chains exist in two forms: base chains and regular chains.
A base chain is an entry point for packets from the networking stack.
A regular chain can be used as a jump target and for organizing rules.
When a chain is created with a hook and priority, it becomes a base chain and is connected to the networking stack.
For base chains, the chain type, hook, and priority parameters are mandatory.
The \texttt{filter} chain type is supported by all families and hooks.
Other chain types have additional restrictions.
For example, \texttt{nat} chains are supported by the \texttt{ip}, \texttt{ip6}, and \texttt{inet} families, while \texttt{route} chains are restricted to the \texttt{output} hook of those families.
A base chain has a priority that determines its evaluation order relative to other chains attached to the same hook.
Lower numerical priority values are evaluated before higher values.
The evaluation order of chains with identical priorities is undefined.
\texttt{nftables} provides names for several standard priority values, and the priority values used by the \texttt{bridge} family differ from those used by the other families.
For the \texttt{bridge} family, the predefined priorities include \texttt{dstnat} with a value of $-300$ for \texttt{prerouting}, \texttt{filter} with a value of $-200$ for all hooks, \texttt{out} with a value of $100$ for \texttt{output}, and \texttt{srcnat} with a value of $300$ for \texttt{postrouting}.
A base chain can also specify a policy.
The supported policies are \texttt{accept} and \texttt{drop}, with \texttt{accept} being the default.
The policy determines what happens to packets for which the rules in the chain do not explicitly produce an acceptance or refusal.
Rules are contained within chains.
According to the \texttt{nftables} documentation, rules consist of two types of components: expressions and statements.
\subsection{Expressions and Statements}
\label{sec:nftables-expressions-statements}
Expressions represent values.
These values may be constants, such as network addresses and port numbers, or information obtained from a packet during ruleset evaluation.
Expressions can be combined to construct match expressions and can also be used as arguments for operations such as NAT or packet marking.
Each expression has a data type that determines properties including its size, parsing, representation, and compatibility with other expressions.
\texttt{nftables} provides, among others, meta expressions and payload expressions.
A meta expression accesses metadata associated with a packet.
Available metadata includes the packet length, protocol family, Layer-4 protocol, packet mark, input and output interfaces, and packet type.
The input and output interfaces can be accessed using \texttt{iif}, \texttt{oif}, \texttt{iifname}, and \texttt{oifname}.
\texttt{iif} and \texttt{oif} operate on interface indices, whereas \texttt{iifname} and \texttt{oifname} operate on interface names.
\texttt{nftables} also provides \texttt{ibrname} and \texttt{obrname}, representing the input and output bridge interface names, respectively.
Payload expressions refer to information contained in a packet's payload.
For Ethernet headers, \texttt{nftables} provides expressions for the destination address (\texttt{ether daddr}), source address (\texttt{ether saddr}), and EtherType (\texttt{ether type}).
Further payload expressions provide access to fields of higher-layer protocols.
For example, IPv4 expressions can access fields including source and destination addresses and the upper-layer protocol, while IPv6 expressions provide access to fields including source and destination addresses and the next-header field.
TCP and UDP expressions provide access to source and destination ports as well as additional protocol-specific header fields.
Statements represent actions that are performed during rule evaluation.
They may alter the control flow by accepting or dropping a packet or by transferring evaluation to another chain.
Statements may also perform other actions, including logging and rejecting packets.
nftables distinguishes between terminal and non-terminal statements.
Terminal statements unconditionally terminate evaluation of the current rule, whereas non-terminal statements either conditionally terminate evaluation or allow it to continue.
\subsection{Ruleset Evaluation and Verdicts}
\label{sec:nftables-ruleset-evaluation}
Packets traverse the networking stack and are evaluated by base chains attached to the hooks they encounter.
If multiple base chains are attached to the same hook, the chains are evaluated according to their priorities, with lower priority values evaluated first.
Base chains may call regular chains using \texttt{jump} and \texttt{goto}, and regular chains may in turn call other regular chains.
Chains in different tables cannot call each other.
nftables provides the verdict statements \texttt{accept}, \texttt{drop}, \texttt{continue}, \texttt{return}, \texttt{jump}, and \texttt{goto}.
The \texttt{accept} and \texttt{drop} verdicts terminate chain evaluation, but their effects on subsequent processing differ.
An \texttt{accept} verdict terminates evaluation of the current base chain.
Processing can subsequently continue in another base chain attached to the same hook or in a base chain attached to a later hook.
Consequently, a packet that receives an \texttt{accept} verdict may still subsequently receive a \texttt{drop} verdict from another base chain.
A \texttt{drop} verdict immediately drops the packet and terminates evaluation of the ruleset.
No further chains are evaluated, and the verdict cannot be overridden by a later \texttt{accept} verdict.
The \texttt{jump} statement stores the current evaluation position and continues evaluation at the beginning of another regular chain.
When that chain ends, evaluation can return to the stored position.
\texttt{goto} similarly transfers evaluation to another chain but does not store the current position.
\texttt{return} terminates evaluation of the current chain and, where a stored position exists, continues evaluation from that position.
\subsection{Queueing Packets to Userspace}
\label{sec:nftables-queue}
In addition to issuing verdicts directly in the ruleset, nftables provides a \texttt{queue} statement.
The \texttt{queue} statement passes a packet to userspace using the \texttt{nfnetlink\_queue} handler.
The packet is placed into a queue identified by a 16-bit queue number.
The default queue number is 0.
A userspace application receiving a queued packet can inspect it and may optionally modify it.
The userspace application must subsequently provide either an \texttt{accept} or a \texttt{drop} verdict.
If the packet is accepted, nftables processing resumes with the next base-chain hook rather than with the rule following the \texttt{queue} statement.
The nftables documentation refers to the \texttt{libnetfilter\_queue} documentation for further details concerning userspace queue processing.
The \texttt{queue} statement can specify a single queue number, a range of queue numbers, or an expression that determines the queue number.
Queue numbers may be computed at runtime using \texttt{numgen}, \texttt{hash}, or \texttt{symhash} expressions, and a map statement can be used to select fixed queue numbers based on inputs such as source IP addresses or interface names.
Two flags are defined for the \texttt{queue} statement: \texttt{bypass} and \texttt{fanout}.
The \texttt{fanout} flag distributes packets between several queues.
The \texttt{bypass} flag allows packets to proceed when the userspace application cannot process them; the documentation recommends consulting the \texttt{libnetfilter\_queue} documentation for performance-tuning recommendations before using this flag.
```
consulting the \texttt{libnetfilter\_queue} documentation for performance-tuning recommendations before using this flag.
\section{Linux Packet Processing Path}
\label{sec:linux-packet-processing-path}