406 lines
12 KiB
HTML
406 lines
12 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self'; font-src 'self' data:; img-src 'self' data:; connect-src 'self'; base-uri 'self'; form-action 'self' https://defcon.social https://bsky.app;">
|
|
<meta http-equiv="X-Content-Type-Options" content="nosniff">
|
|
<link rel="stylesheet" href="../assets/css/style.css">
|
|
<link rel="icon" type="image/x-icon" href="../favicon.ico">
|
|
<script>
|
|
// Apply theme immediately to prevent flash
|
|
(function() {
|
|
const theme = localStorage.getItem('theme') ||
|
|
(window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
|
|
document.documentElement.setAttribute('data-theme', theme);
|
|
})();
|
|
</script>
|
|
<title>nftables Cheatsheet - Cheatsheets - Launch Pad</title>
|
|
</head>
|
|
<body>
|
|
<button class="theme-toggle" id="themeToggle" aria-label="Toggle dark mode">
|
|
<svg class="theme-icon theme-icon-moon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>
|
|
<svg class="theme-icon theme-icon-sun" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display: none;"><circle cx="12" cy="12" r="5"></circle><line x1="12" y1="1" x2="12" y2="3"></line><line x1="12" y1="21" x2="12" y2="23"></line><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line><line x1="1" y1="12" x2="3" y2="12"></line><line x1="21" y1="12" x2="23" y2="12"></line><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line></svg>
|
|
</button>
|
|
<br/><br/>
|
|
<div class="name">
|
|
__ _______________________ _________._________________________
|
|
\_ _____/ \______ \ / _ \ / _____/ / _____/ | | \_ _____/
|
|
| __) | _/ / /_\ \ / \ ___ / \ ___ | | | __)_
|
|
| \ | | \ / | \ \ \_\ \ \ \_\ \ | |___ | \
|
|
\___ / |____|_ / \____|__ / \______ / \______ / |_______ \ /_______ /
|
|
\/ \/ \/ \/ \/ \/ \/
|
|
</div>
|
|
<div class="blog-page-header">
|
|
<div class="blog-header-content">
|
|
<a href="/cheatsheets" class="back-link" title="Back to Cheatsheets">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="42" height="42" viewBox="0 0 24 24" class="home-icon"><path fill="currentColor" d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/></svg>
|
|
</a>
|
|
<h1 class="blog-page-title">nftables Cheatsheet</h1>
|
|
</div>
|
|
</div>
|
|
<div class="blog-post-container">
|
|
<div class="blog-posts-container" style="max-width: 900px; margin: 0 auto;">
|
|
<div class="blog-post">
|
|
<div class="blog-post-content">
|
|
<p><a href="index.html">← Back to cheatsheets</a></p>
|
|
<p><a href="../index.html">← Home</a></p>
|
|
<hr>
|
|
<p>nftables is the modern Linux firewall framework, replacing iptables. It provides a unified interface for IPv4, IPv6, ARP, and bridge filtering with improved performance and syntax.</p>
|
|
<hr>
|
|
<h2>Basic Commands</h2>
|
|
<ul>
|
|
<li>nft list ruleset - List all rules</li>
|
|
</ul>
|
|
<ul>
|
|
<li>nft list tables - List all tables</li>
|
|
</ul>
|
|
<ul>
|
|
<li>nft list table <family> <name> - List specific table</li>
|
|
</ul>
|
|
<ul>
|
|
<li>nft list chain <family> <table> <chain> - List specific chain</li>
|
|
</ul>
|
|
<ul>
|
|
<li>nft flush ruleset - Clear all rules</li>
|
|
</ul>
|
|
<ul>
|
|
<li>nft flush table <family> <name> - Clear specific table</li>
|
|
</ul>
|
|
<ul>
|
|
<li>nft -s list ruleset - List with handle numbers</li>
|
|
</ul>
|
|
<ul>
|
|
<li>nft monitor - Watch for rule changes in real-time</li>
|
|
</ul>
|
|
<hr>
|
|
<h2>Address Families</h2>
|
|
<ul>
|
|
<li>ip - IPv4 (default)</li>
|
|
</ul>
|
|
<ul>
|
|
<li>ip6 - IPv6</li>
|
|
</ul>
|
|
<ul>
|
|
<li>inet - IPv4 and IPv6 combined</li>
|
|
</ul>
|
|
<ul>
|
|
<li>arp - ARP</li>
|
|
</ul>
|
|
<ul>
|
|
<li>bridge - Bridge filtering</li>
|
|
</ul>
|
|
<ul>
|
|
<li>netdev - Ingress filtering</li>
|
|
</ul>
|
|
<hr>
|
|
<h2>Tables</h2>
|
|
<h3>Create Table</h3>
|
|
<pre><code>nft add table inet filter
|
|
nft add table ip nat</code></pre>
|
|
<h3>Delete Table</h3>
|
|
<pre><code>nft delete table inet filter</code></pre>
|
|
<hr>
|
|
<h2>Chains</h2>
|
|
<h3>Chain Types</h3>
|
|
<ul>
|
|
<li>filter - Packet filtering</li>
|
|
</ul>
|
|
<ul>
|
|
<li>route - Rerouting packets</li>
|
|
</ul>
|
|
<ul>
|
|
<li>nat - Network address translation</li>
|
|
</ul>
|
|
<h3>Chain Hooks</h3>
|
|
<ul>
|
|
<li>prerouting - Before routing decision</li>
|
|
</ul>
|
|
<ul>
|
|
<li>input - Incoming packets to local</li>
|
|
</ul>
|
|
<ul>
|
|
<li>forward - Forwarded packets</li>
|
|
</ul>
|
|
<ul>
|
|
<li>output - Outgoing packets from local</li>
|
|
</ul>
|
|
<ul>
|
|
<li>postrouting - After routing decision</li>
|
|
</ul>
|
|
<ul>
|
|
<li>ingress - Earliest hook (netdev only)</li>
|
|
</ul>
|
|
<h3>Create Chain</h3>
|
|
<pre><code>nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; }
|
|
nft add chain inet filter output { type filter hook output priority 0 \; policy accept \; }
|
|
nft add chain inet filter forward { type filter hook forward priority 0 \; policy drop \; }</code></pre>
|
|
<h3>Delete Chain</h3>
|
|
<pre><code>nft delete chain inet filter input</code></pre>
|
|
<hr>
|
|
<h2>Adding Rules</h2>
|
|
<ul>
|
|
<li>nft add rule <family> <table> <chain> <rule> - Append rule</li>
|
|
</ul>
|
|
<ul>
|
|
<li>nft insert rule <family> <table> <chain> <rule> - Insert at beginning</li>
|
|
</ul>
|
|
<ul>
|
|
<li>nft add rule <family> <table> <chain> position <handle> <rule> - Add after handle</li>
|
|
</ul>
|
|
<ul>
|
|
<li>nft delete rule <family> <table> <chain> handle <handle> - Delete by handle</li>
|
|
</ul>
|
|
<hr>
|
|
<h2>Rule Matching</h2>
|
|
<h3>Interface Matching</h3>
|
|
<ul>
|
|
<li>iifname "eth0" - Input interface name</li>
|
|
</ul>
|
|
<ul>
|
|
<li>oifname "eth0" - Output interface name</li>
|
|
</ul>
|
|
<ul>
|
|
<li>iif eth0 - Input interface (faster, index-based)</li>
|
|
</ul>
|
|
<ul>
|
|
<li>oif eth0 - Output interface (faster, index-based)</li>
|
|
</ul>
|
|
<h3>Address Matching</h3>
|
|
<ul>
|
|
<li>ip saddr 192.168.1.0/24 - Source IPv4 address</li>
|
|
</ul>
|
|
<ul>
|
|
<li>ip daddr 10.0.0.1 - Destination IPv4 address</li>
|
|
</ul>
|
|
<ul>
|
|
<li>ip6 saddr fe80::/10 - Source IPv6 address</li>
|
|
</ul>
|
|
<ul>
|
|
<li>ip6 daddr ::1 - Destination IPv6 address</li>
|
|
</ul>
|
|
<h3>Protocol Matching</h3>
|
|
<ul>
|
|
<li>ip protocol tcp - TCP protocol</li>
|
|
</ul>
|
|
<ul>
|
|
<li>ip protocol udp - UDP protocol</li>
|
|
</ul>
|
|
<ul>
|
|
<li>ip protocol icmp - ICMP protocol</li>
|
|
</ul>
|
|
<ul>
|
|
<li>meta l4proto tcp - Layer 4 protocol (works with inet)</li>
|
|
</ul>
|
|
<h3>Port Matching</h3>
|
|
<ul>
|
|
<li>tcp sport 22 - TCP source port</li>
|
|
</ul>
|
|
<ul>
|
|
<li>tcp dport 80 - TCP destination port</li>
|
|
</ul>
|
|
<ul>
|
|
<li>udp dport 53 - UDP destination port</li>
|
|
</ul>
|
|
<ul>
|
|
<li>tcp dport { 22, 80, 443 } - Multiple ports</li>
|
|
</ul>
|
|
<ul>
|
|
<li>tcp dport 1024-65535 - Port range</li>
|
|
</ul>
|
|
<hr>
|
|
<h2>Verdicts (Actions)</h2>
|
|
<ul>
|
|
<li>accept - Accept the packet</li>
|
|
</ul>
|
|
<ul>
|
|
<li>drop - Drop silently</li>
|
|
</ul>
|
|
<ul>
|
|
<li>reject - Reject with error</li>
|
|
</ul>
|
|
<ul>
|
|
<li>queue - Send to userspace</li>
|
|
</ul>
|
|
<ul>
|
|
<li>continue - Continue rule processing</li>
|
|
</ul>
|
|
<ul>
|
|
<li>return - Return to calling chain</li>
|
|
</ul>
|
|
<ul>
|
|
<li>jump <chain> - Jump to another chain</li>
|
|
</ul>
|
|
<ul>
|
|
<li>goto <chain> - Go to chain without returning</li>
|
|
</ul>
|
|
<hr>
|
|
<h2>Connection Tracking</h2>
|
|
<ul>
|
|
<li>ct state new - New connections</li>
|
|
</ul>
|
|
<ul>
|
|
<li>ct state established - Established connections</li>
|
|
</ul>
|
|
<ul>
|
|
<li>ct state related - Related connections</li>
|
|
</ul>
|
|
<ul>
|
|
<li>ct state invalid - Invalid packets</li>
|
|
</ul>
|
|
<ul>
|
|
<li>ct state { established, related } - Multiple states</li>
|
|
</ul>
|
|
<hr>
|
|
<h2>Common Examples</h2>
|
|
<h3>Allow SSH</h3>
|
|
<pre><code>nft add rule inet filter input tcp dport 22 accept</code></pre>
|
|
<h3>Allow Established Connections</h3>
|
|
<pre><code>nft add rule inet filter input ct state established,related accept</code></pre>
|
|
<h3>Block IP Address</h3>
|
|
<pre><code>nft add rule inet filter input ip saddr 192.168.1.100 drop</code></pre>
|
|
<h3>Allow HTTP/HTTPS</h3>
|
|
<pre><code>nft add rule inet filter input tcp dport { 80, 443 } accept</code></pre>
|
|
<h3>Allow Loopback</h3>
|
|
<pre><code>nft add rule inet filter input iifname "lo" accept</code></pre>
|
|
<h3>Log and Drop</h3>
|
|
<pre><code>nft add rule inet filter input log prefix "nftables-dropped: " drop</code></pre>
|
|
<hr>
|
|
<h2>NAT Configuration</h2>
|
|
<h3>Masquerading (SNAT)</h3>
|
|
<pre><code>nft add table ip nat
|
|
nft add chain ip nat postrouting { type nat hook postrouting priority 100 \; }
|
|
nft add rule ip nat postrouting oifname "eth0" masquerade</code></pre>
|
|
<h3>Port Forwarding (DNAT)</h3>
|
|
<pre><code>nft add chain ip nat prerouting { type nat hook prerouting priority -100 \; }
|
|
nft add rule ip nat prerouting iifname "eth0" tcp dport 8080 dnat to 192.168.1.10:80</code></pre>
|
|
<hr>
|
|
<h2>Complete Firewall Example</h2>
|
|
<pre><code>#!/usr/sbin/nft -f
|
|
|
|
flush ruleset
|
|
|
|
table inet filter {
|
|
chain input {
|
|
type filter hook input priority 0; policy drop;
|
|
|
|
# Allow loopback
|
|
iifname "lo" accept
|
|
|
|
# Allow established/related
|
|
ct state established,related accept
|
|
|
|
# Drop invalid
|
|
ct state invalid drop
|
|
|
|
# Allow ICMP
|
|
ip protocol icmp accept
|
|
ip6 nexthdr icmpv6 accept
|
|
|
|
# Allow SSH
|
|
tcp dport 22 accept
|
|
|
|
# Allow HTTP/HTTPS
|
|
tcp dport { 80, 443 } accept
|
|
}
|
|
|
|
chain forward {
|
|
type filter hook forward priority 0; policy drop;
|
|
}
|
|
|
|
chain output {
|
|
type filter hook output priority 0; policy accept;
|
|
}
|
|
}</code></pre>
|
|
<hr>
|
|
<h2>Sets and Maps</h2>
|
|
<h3>Named Set</h3>
|
|
<pre><code>nft add set inet filter allowed_ips { type ipv4_addr \; }
|
|
nft add element inet filter allowed_ips { 192.168.1.1, 192.168.1.2 }
|
|
nft add rule inet filter input ip saddr @allowed_ips accept</code></pre>
|
|
<h3>Anonymous Set</h3>
|
|
<pre><code>nft add rule inet filter input ip saddr { 192.168.1.1, 192.168.1.2 } accept</code></pre>
|
|
<h3>Port Set</h3>
|
|
<pre><code>nft add set inet filter allowed_ports { type inet_service \; }
|
|
nft add element inet filter allowed_ports { 22, 80, 443 }
|
|
nft add rule inet filter input tcp dport @allowed_ports accept</code></pre>
|
|
<hr>
|
|
<h2>Rate Limiting</h2>
|
|
<pre><code># Limit to 10 packets per second
|
|
nft add rule inet filter input tcp dport 22 limit rate 10/second accept
|
|
|
|
# Limit with burst
|
|
nft add rule inet filter input tcp dport 22 limit rate over 10/second burst 5 packets drop</code></pre>
|
|
<hr>
|
|
<h2>Saving and Loading</h2>
|
|
<ul>
|
|
<li>nft list ruleset > /etc/nftables.conf - Save rules</li>
|
|
</ul>
|
|
<ul>
|
|
<li>nft -f /etc/nftables.conf - Load rules from file</li>
|
|
</ul>
|
|
<ul>
|
|
<li>systemctl enable nftables - Enable at boot</li>
|
|
</ul>
|
|
<ul>
|
|
<li>systemctl start nftables - Start nftables service</li>
|
|
</ul>
|
|
<hr>
|
|
<h2>Migration from iptables</h2>
|
|
<ul>
|
|
<li>iptables-translate - Convert iptables rule to nft syntax</li>
|
|
</ul>
|
|
<ul>
|
|
<li>iptables-restore-translate - Convert iptables-save output to nft</li>
|
|
</ul>
|
|
<ul>
|
|
<li>iptables-nft - iptables compatibility layer using nftables backend</li>
|
|
</ul>
|
|
<pre><code># Translate a single rule
|
|
iptables-translate -A INPUT -p tcp --dport 22 -j ACCEPT
|
|
|
|
# Translate saved rules
|
|
iptables-save | iptables-restore-translate</code></pre>
|
|
<hr>
|
|
<h2>Tips</h2>
|
|
<ul>
|
|
<li>Use inet family for combined IPv4/IPv6 rules</li>
|
|
</ul>
|
|
<ul>
|
|
<li>Use sets for multiple addresses or ports (more efficient)</li>
|
|
</ul>
|
|
<ul>
|
|
<li>Use iifname/oifname for dynamic interfaces, iif/oif for static</li>
|
|
</ul>
|
|
<ul>
|
|
<li>Chain priority determines order (lower = earlier)</li>
|
|
</ul>
|
|
<ul>
|
|
<li>Use handles (-a flag) to identify rules for deletion</li>
|
|
</ul>
|
|
<ul>
|
|
<li>nft monitor is useful for debugging rule changes</li>
|
|
</ul>
|
|
<ul>
|
|
<li>Put rules in /etc/nftables.conf for persistence</li>
|
|
</ul>
|
|
<ul>
|
|
<li>Use flush ruleset carefully - it removes everything</li>
|
|
</ul>
|
|
<ul>
|
|
<li>Escape semicolons with backslash in shell commands</li>
|
|
</ul>
|
|
<ul>
|
|
<li>nftables is the future - iptables is in maintenance mode</li>
|
|
</ul>
|
|
<hr>
|
|
<p><a href="index.html">← Back to cheatsheets</a></p>
|
|
<p><a href="../index.html">← Home</a></p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<script async type="text/javascript" src="../blog/analytics.js"></script>
|
|
<script src="../theme.js"></script>
|
|
</body>
|
|
</html> |