nftables Syntax erweitert

This commit is contained in:
Alfred Krohmer 2014-03-23 20:08:47 +01:00
parent 8a3c2c511c
commit dc6c68af63
2 changed files with 123 additions and 4 deletions

View File

@ -57,7 +57,7 @@ Zur besseren Anschaulichkeit auch in logarithmischer Ordinatenskalierung: \\
\pagebreak
Die Datenrate und die Anzahl an PPS liegen initial bei den bereits zuvor gemessenen ca. 980 MBit/s und 250000 Paketen pro Sekunde. Jedoch bricht die Leistungsfähigkeit bei beiden Firewall-Lösungen schnell erheblich ein. So kann \texttt{iptables} bei 5000 Regeln nur noch ca. 100 MBit/s bei 28000 Paketen verarbeiten, \texttt{nftables} schafft hier nur ca. 50 MBit/s bei 14000 Paketen. Im weiteren Verlauf wird jedoch in der logarithmischen Skalierung sichtbar, dass \texttt{nftables} bei mehr als ca. 25000 Regeln beginnt besser zu skalieren.
Die Datenrate und die Anzahl an PPS liegen initial bei den bereits zuvor gemessenen ca. 980 MBit/s und 250000 Paketen pro Sekunde. Jedoch bricht die Leistungsfähigkeit bei beiden Firewall-Lösungen schnell erheblich ein. So kann \texttt{iptables} bei 5000 Regeln nur noch ca. 100 MBit/s bei 28000 Paketen verarbeiten, \texttt{nftables} schafft hier nur ca. 50 MBit/s bei 14000 Paketen. Im weiteren Verlauf wird jedoch in der logarithmischen Skalierung sichtbar, dass \texttt{nftables} bei mehr als ca. 25000 Regeln beginnt besser zu skalieren. Die starken Schwankungen bei vielen Regeln lassen sich eventuell auf zu kleine statisch allokierte Buffer im Kernel oder durch zunehmenden RAM-Zugriff bei vollem Cache zurückführen. RAM-Zugriff würde auch die noch stärker abnehmende PPS-Rate bei sehr vielen Regeln erklären.
\paragraph{Antwortzeit} Unter Verwendung der vorherigen Regeln habe ich nun die Antwortzeit gemessen. \\
@ -65,10 +65,12 @@ Die Datenrate und die Anzahl an PPS liegen initial bei den bereits zuvor gemesse
In diesem Diagramm erkennt man, dass hier \texttt{nftables}, im Gegensatz zum Paketdurchsatz, bei der Antwortzeit bei Skalierung auf sehr viele Firewall-Regeln besser abschneidet als \texttt{iptables}. Bis ca. 20000 Regeln reagieren beide Firewall-Lösungen in etwa gleich schnell, danach entwickeln sich die Reaktionszeiten linear auseinander. Bei 100000 Regeln hat hier \texttt{nftables} einen Vorteil von ca. 4 ms.
\pagebreak
\paragraph{Weitere Regeln} Ursprünglich wollte ich für weitere Benchmarks noch andere Regeltypen verwenden. Dies scheiterte jedoch grundsätzlich an zwei Punkten:
\begin{itemize}
\item \texttt{nftables} ist bisher sehr schlecht dokumentiert. Es ist mir bspw. nicht gelungen eine Möglichkeit zu finden, um komplette Pakete (nicht nur den Header) nach bestimmten Strings zu durchsuchen. Während dies auf Kernel-Seite durch die virtuelle Maschine eigentlich ohne Weiteres möglich sein sollte, ist diese Möglichkeit im Userspace-Tool \texttt{nft} offenbar noch nicht enthalten (oder nirgends dokumentiert).
\item NAT-Regeln (oder generell modifizierende Regeltypen) lassen sich nicht ohne weiteres mit der Skalierung auf eine große Anzahl von Regeln benchmarken, da die Paketbearbeitung nach der ersten, den Filterkriterien entsprechenden Regel abbricht.
\item NAT-Regeln (oder generell modifizierende Regeltypen) lassen sich nicht ohne weiteres mit der Skalierung auf eine große Anzahl von Regeln benchmarken, da die Paketbearbeitung nach der ersten, den Filterkriterien entsprechenden Regel abbricht. Zukünftig sollte sich die Vereinheitlichung und die leichte Erweiterbarkeit von \texttt{nftables} gegenüber \texttt{iptables} durchsetzen können.
\end{itemize}
\pagebreak

View File

@ -46,13 +46,130 @@ Während \texttt{iptables} noch vordefinierte Tabellen (\texttt{filter}, \texttt
\subsubsection{Syntax}
Im folgenden werde ich einige Regeltypen zeigen und wie sich diese bei den beiden Firewall-System unterscheiden.
\paragraph{Einfache Targets} \mbox{} \\
Für \texttt{iptables} könnte man bspw. folgenden Aufruf verwenden, um eingehende TCP-Pakete auf Port 22 zunächst zu loggen und anschließend zu verwerfen: \\
\shellcmd{iptables -A INPUT -p tcp ---dport 22 -j LOG} \\
\shellcmd{iptables -A INPUT -p tcp ---dport 22 -j DROP} \\
Für \texttt{nftables} müsste man sich zunächst mit folgenden Befehlen je eine beispielhafte Tabelle und Chain anlegen (oder dies entsprechend in ein Script einbauen): \\
Als Script:
\begin{lstlisting}
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -p tcp ---dport 22 -j LOG
-A INPUT -p tcp ---dport 22 -j DROP
COMMIT
\end{lstlisting}
\begin{center}
\rule{0.5\paperwidth}{0.4pt}
\end{center}
Für \texttt{nftables} müsste man sich zunächst mit folgenden Befehlen je eine beispielhafte Tabelle und Chain anlegen: \\
\shellcmd{nft add table filter} \\
\shellcmd{nft add chain filter input \enquote{\{ type filter hook input priority 0; \}}} \\
Die Regel kann man nun bspw. wie folgt einfügen: \\
\shellcmd{nft add rule filter input tcp dport 80 log drop}
\shellcmd{nft add rule filter input tcp dport 22 log drop} \\
Als Script:
\begin{lstlisting}
table filter {
chain input {
type filter hook input priority 0;
tcp dport 22 log drop
}
}
\end{lstlisting}
\paragraph{Mehrere benutzerdefinierte Chains} \mbox{} \\
In \texttt{iptables} kann wie folgt eine neue Chain eingefügt werden: \\
\shellcmd{iptables -N sshchain} \\
Der Name dieser Chain kann nun auch direkt als Target bei weiteren Regeln angegeben werden: \\
\shellcmd{iptables -A INPUT -p tcp --dport 22 -j sshchain} \\
Dieser Chain lassen sich nun ebenfalls weitere Regeln hinzufügen. \\
\shellcmd{iptables -A sshchain -j DROP} \\
\shellcmd{iptables -A sshchain -j LOG} \\
Als Script:
\begin{lstlisting}
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:sshchain - [0:0]
-A INPUT -p tcp --dport 22 -j sshchain
-A sshchain -j LOG
-A sshchain -j DROP
COMMIT
\end{lstlisting}
\begin{center}
\rule{0.5\paperwidth}{0.4pt}
\end{center}
In \texttt{nftables} sieht der Befehl zum Anlegen einer neuen Chain (in einer bereits existierenden Tabelle \texttt{filter}) wie folgt aus: \\
\shellcmd{nft add chain ip filter sshchain} \\
Um diese Chain »anspringen« zu können muss bei \texttt{nftables} das \texttt{jump}-Target verwendet werden: \\
\shellcmd{nft add rule ip filter input tcp dport 22 jump sshchain} \\
Regeln lassen sich dann wie gewohnt hinzufügen: \\
\shellcmd{nft add rule ip filter sshchain log drop} \\
Als Script:
\begin{lstlisting}
table ip filter {
chain input {
type filter hook input priority 0;
tcp dport ssh jump sshchain
}
chain sshchain {
log drop
}
}
\end{lstlisting}
\paragraph{Mehrfaches Matching auf ein Paketheader-Feld}
Möchte man bei \texttt{iptables} in einer Regel mehrere Werte für ein Header-Feld matchen, so muss man für jeden Wert eine eigene Regel anlegen. Beispiel für das Matching von ICMP-Paketen: \\
\shellcmd{iptables -A INPUT -p icmp --icmp-type echo-request -j DROP} \\
\shellcmd{iptables -A INPUT -p icmp --icmp-type echo-reply -j DROP} \\
oder für IP-Adressen: \\
\shellcmd{iptables -A INPUT -s 10.30.44.7 -j DROP} \\
\shellcmd{iptables -A INPUT -s 10.27.21.2 -j DROP}
\begin{center}
\rule{0.5\paperwidth}{0.4pt}
\end{center}
Bei \texttt{nftables} lässt sich dies zu einer Regel zusammenfassen: \\
\shellcmd{nft add rule ip filter input icmp type \{ echo-request, echo-reply \} drop} \\
und für IP-Adressen: \\
\shellcmd{nft add rule ip filter input saddr \{ 10.30.44.7, 10.27.21.2 \} drop} \\
Während sich bei \texttt{iptables} das Matching für IP-Adressen noch auf \texttt{ipset}s übertragen lässt, bei denen in einem Set mehrere IP-Adressen gespeichert sein können, gegen die dann gematcht werden können, so existiert hierfür aber kein Äquivalent für andere Datentypen wie ICMP-Typen, einzelne Ports usw. Bei \texttt{nftables} hingegen lassen sich in diesen »unnamed sets« alle möglichen Datentypen speichern und matchen. Außerdem gibt es noch die »named sets«, die man in mehreren Regeln gleichzeitig verwenden kann: \\
\shellcmd{nft add set filter ipmatches \enquote{\{ type ipv4\_address; \}}} \\
\shellcmd{nft add element filter ipmatches \enquote{\{ 10.30.44.7, 10.27.21.2 \}}} \\
Gematcht werden können diese Sets dann wie folgt: \\
\shellcmd{nft add rule ip input ip saddr @ipmatches drop} \\