{"id":1049,"date":"2025-09-09T11:02:55","date_gmt":"2025-09-09T08:02:55","guid":{"rendered":"https:\/\/itgen.itbumper.com\/?page_id=1049"},"modified":"2025-09-09T11:44:23","modified_gmt":"2025-09-09T08:44:23","slug":"0041_iptables_vs_nftables","status":"publish","type":"page","link":"https:\/\/itgen.itbumper.com\/?page_id=1049","title":{"rendered":"0041_iptables_vs_nftables"},"content":{"rendered":"<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\nsudo apt-get update &amp;&amp; sudo apt-get install -y nftables\nsudo systemctl enable --now nftables\nsudo nft -f \/etc\/nftables.conf\nsudo nft list ruleset   # check\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n# 1. Check and manage rules\n# Show all rules\nsudo nft list ruleset\n\n# Save rules to a file\nsudo nft list ruleset &gt; \/etc\/nftables.conf\n\n# Load rules from a file\nsudo nft -f \/etc\/nftables.conf\n\n# 2. Working with tables\n# Create a table\nsudo nft add table inet filter\n\n# Delete a table\nsudo nft delete table inet filter\n\n# 3. Working with chains\n# Create a chain for incoming traffic\nsudo nft add chain inet filter input { type filter hook input priority 0; }\n\n# Delete a chain\nsudo nft delete chain inet filter input\n\n#4. Adding rules\n# Allow SSH (port 22)\nsudo nft add rule inet filter input tcp dport 22 accept\n\n# Allow HTTP and HTTPS\nsudo nft add rule inet filter input tcp dport { 80, 443 } accept\n\n# Allow ICMP (ping)\nsudo nft add rule inet filter input icmp type echo-request accept\n\n# Allow traffic from a specific IP\nsudo nft add rule inet filter input ip saddr 192.168.1.100 accept\n\n# Deny everything else\nsudo nft add rule inet filter input drop\n\n# 5. Managing rules\n# Delete a specific rule (by handle)\n\n# First, list the rules:\nsudo nft list chain inet filter input\n\n# Then delete, e.g., rule with handle 2:\nsudo nft delete rule inet filter input handle 2\n\n# 6. System integration\n# Enable rules at boot\n# Main config file: \/etc\/nftables.conf\n# Enable service:\nsudo systemctl enable nftables\nsudo systemctl start nftables\n\n\n# Concepts:\ntable = a ruleset (e.g., filter, nat).\nchain = a hook for traffic (input, forward, output).\nrule = the actual filtering rule (accept, drop, etc.).\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n# iptables (SSH, HTTP, HTTPS)\niptables -A INPUT -p tcp --dport 22 -j ACCEPT\niptables -A INPUT -p tcp --dport 80 -j ACCEPT\niptables -A INPUT -p tcp --dport 443 -j ACCEPT\n\n#nftables (SSH, HTTP, HTTPS)\ntcp dport {22, 80, 443} accept\n\n\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n# iptables (Block a single IP address)\niptables -A INPUT -s 192.168.1.10 -j DROP\niptables -A INPUT -s 192.168.1.20 -j DROP\niptables -A INPUT -s 192.168.1.30 -j DROP\n\n# nftables (Block a single IP address)\nip saddr {192.168.1.10, 192.168.1.20, 192.168.1.30} drop\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n# iptables Full ruleset (DROP, loopback, established, ssh, http, https)\niptables -P INPUT DROP\niptables -A INPUT -i lo -j ACCEPT\niptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT\niptables -A INPUT -p tcp --dport 22 -j ACCEPT\niptables -A INPUT -p tcp --dport 80 -j ACCEPT\niptables -A INPUT -p tcp --dport 443 -j ACCEPT\niptables -A INPUT -p icmp -j ACCEPT\n\n# nftables Full ruleset (DROP, loopback, established, ssh, http, https)\n\nchain input {\n    type filter hook input priority 0; policy drop;\n    iif &quot;lo&quot; accept\n    ct state established,related accept\n    tcp dport {22,80,443} accept\n    icmp type echo-request accept\n}\n\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n# Quick Reference with Examples\n# 1. Basic structure\n# iptables: separate commands for filter, nat, mangle, etc.\n# nftables: one unified syntax, everything managed with nft.\n\n# 2. Allow SSH (port 22)\n# iptables\nsudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT\n\n# nftables\nsudo nft add rule inet filter input tcp dport 22 accept\n\n# 3. Allow HTTP\/HTTPS (ports 80, 443)\n# iptables\nsudo iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT\n\n# nftables\nsudo nft add rule inet filter input tcp dport {80, 443} accept\n\n# 4. Allow ICMP (ping)\n# iptables\nsudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT\n\n# nftables\nsudo nft add rule inet filter input icmp type echo-request accept\n\n# 5. Allow traffic from a specific IP\n# iptables\nsudo iptables -A INPUT -s 192.168.1.100 -j ACCEPT\n\n# nftables\nsudo nft add rule inet filter input ip saddr 192.168.1.100 accept\n\n# 6. Drop all other traffic\n# iptables\nsudo iptables -A INPUT -j DROP\n\n# nftables\nsudo nft add rule inet filter input drop\n\n# 7. Logging packets\n#iptables\n# Log and drop invalid packets\nsudo iptables -A INPUT -m conntrack --ctstate INVALID -j LOG --log-prefix &quot;INVALID: &quot;\nsudo iptables -A INPUT -m conntrack --ctstate INVALID -j DROP\n\n# nftables\nsudo nft add rule inet filter input ct state invalid log prefix &quot;INVALID: &quot; drop\n\n# 8. NAT (port forwarding)\n# iptables\nsudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.50:80\n\n# nftables\nsudo nft add table ip nat\nsudo nft add chain ip nat prerouting { type nat hook prerouting priority 0; }\nsudo nft add rule ip nat prerouting tcp dport 8080 dnat to 192.168.1.50:80\n\n# 9. Save &amp; restore rules\n# iptables\nsudo iptables-save &gt; \/etc\/iptables\/rules.v4\nsudo iptables-restore &lt; \/etc\/iptables\/rules.v4\n\n# nftables\nsudo nft list ruleset &gt; \/etc\/nftables.conf\nsudo nft -f \/etc\/nftables.conf\n\n\n# Summary\n# iptables = old but still works, rule-by-rule.\n# nftables = modern replacement, shorter syntax, one tool for everything.\nBoth support logging, but nftables logging is cleaner and more flexible.\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n# Example (Full version)\n#!\/usr\/sbin\/nft -f\nflush ruleset\n\n# =========================\n# nftables: base template\n# =========================\n# \u0422\u0430\u0431\u043b\u0438\u0446\u044b:\n# - inet filter : general filtration for IPv4\/IPv6\n# - ip nat      : NAT for IPv4 (SNAT\/MASQ, DNAT)\n\n# ---------- FILTER ----------\ntable inet filter {\n\n  # Sets\n  set allowed_tcp_ports = {                    # Allowed services\n    type inet_service;                         # 0..65535\n    elements = { 22, 80, 443 }                 # SSH, HTTP, HTTPS\n (add more if needed)\n  }\n\n  # Example: SSH access from selected subs and IP only\n  # set admin_src = { type ipv4_addr; flags interval; elements = { 192.0.2.0\/24, 203.0.113.10 } }\n\n  chain input {\n    type filter hook input priority 0; policy drop;\n\n    # Base level trust\n    iif &quot;lo&quot; accept\n    ct state established,related accept\n\n    # ICMP\/ICMPv6: ICMP and important messages, with rate-limit\n    ip protocol icmp icmp type { echo-request, echo-reply, destination-unreachable, time-exceeded } limit rate 20\/second accept\n    ip6 nexthdr icmpv6 icmpv6 type { echo-request, echo-reply, destination-unreachable, time-exceeded, packet-too-big } limit rate 20\/second accept\n\n    # DHCPv6 for a client (if the server gets IP v6 address)\n    udp dport 546 udp sport 547 accept\n\n    # SSH \/ HTTP \/ HTTPS (see Sets above)\n    tcp dport @allowed_tcp_ports accept\n\n    # Example: SSH access \u2014 only for admin_src (see above and uncomment if needed)\n    # tcp dport 22 ip saddr @admin_src accept\n\n    # Logs\n    limit rate 10\/second counter log prefix &quot;NFT DROP: &quot; group 0 drop\n  }\n\n  chain forward {\n    type filter hook forward priority 0; policy drop;\n\n    # Allow from LAN to WAN \n    # See your interfaces and use them instead &quot;lan0&quot; \u0438 &quot;wan0&quot;\n    iif &quot;lan0&quot; oif &quot;wan0&quot; accept\n    ct state established,related accept\n\n    # Log and Drop\n    limit rate 10\/second counter log prefix &quot;NFT FWD DROP: &quot; group 0 drop\n  }\n\n  chain output {\n    type filter hook output priority 0; policy accept;\n    # Usually all outgoes traffic is allowed. If no - add rules\n  }\n}\n\n# ---------- NAT (IPv4) ----------\ntable ip nat {\n  chain prerouting {\n    type nat hook prerouting priority -100;\n\n    # Example DNAT (port-forvarding)\n    # WAN: tcp\/2222  --&gt;  LAN: 192.168.10.50:22\n    # iif &quot;wan0&quot; tcp dport 2222 dnat to 192.168.10.50:22\n  }\n\n  chain postrouting {\n    type nat hook postrouting priority 100;\n\n    # Masquerade to go out (dynamic SNAT)\n    # Change the &quot;wan0&quot; to your interface\n    oif &quot;wan0&quot; masquerade\n  }\n}\n\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\nsudo apt install nftables netfilter-persistent\nsudo systemctl enable --now nftables netfilter-persistent\n<\/pre><\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"categories":[],"tags":[],"_links":{"self":[{"href":"https:\/\/itgen.itbumper.com\/index.php?rest_route=\/wp\/v2\/pages\/1049"}],"collection":[{"href":"https:\/\/itgen.itbumper.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/itgen.itbumper.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/itgen.itbumper.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/itgen.itbumper.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1049"}],"version-history":[{"count":6,"href":"https:\/\/itgen.itbumper.com\/index.php?rest_route=\/wp\/v2\/pages\/1049\/revisions"}],"predecessor-version":[{"id":1061,"href":"https:\/\/itgen.itbumper.com\/index.php?rest_route=\/wp\/v2\/pages\/1049\/revisions\/1061"}],"wp:attachment":[{"href":"https:\/\/itgen.itbumper.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1049"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/itgen.itbumper.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1049"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/itgen.itbumper.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1049"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}