0041_iptables_vs_nftables

sudo apt-get update && sudo apt-get install -y nftables
sudo systemctl enable --now nftables
sudo nft -f /etc/nftables.conf
sudo nft list ruleset   # check
# 1. Check and manage rules
# Show all rules
sudo nft list ruleset

# Save rules to a file
sudo nft list ruleset > /etc/nftables.conf

# Load rules from a file
sudo nft -f /etc/nftables.conf

# 2. Working with tables
# Create a table
sudo nft add table inet filter

# Delete a table
sudo nft delete table inet filter

# 3. Working with chains
# Create a chain for incoming traffic
sudo nft add chain inet filter input { type filter hook input priority 0; }

# Delete a chain
sudo nft delete chain inet filter input

#4. Adding rules
# Allow SSH (port 22)
sudo nft add rule inet filter input tcp dport 22 accept

# Allow HTTP and HTTPS
sudo nft add rule inet filter input tcp dport { 80, 443 } accept

# Allow ICMP (ping)
sudo nft add rule inet filter input icmp type echo-request accept

# Allow traffic from a specific IP
sudo nft add rule inet filter input ip saddr 192.168.1.100 accept

# Deny everything else
sudo nft add rule inet filter input drop

# 5. Managing rules
# Delete a specific rule (by handle)

# First, list the rules:
sudo nft list chain inet filter input

# Then delete, e.g., rule with handle 2:
sudo nft delete rule inet filter input handle 2

# 6. System integration
# Enable rules at boot
# Main config file: /etc/nftables.conf
# Enable service:
sudo systemctl enable nftables
sudo systemctl start nftables


# Concepts:
table = a ruleset (e.g., filter, nat).
chain = a hook for traffic (input, forward, output).
rule = the actual filtering rule (accept, drop, etc.).
# iptables (SSH, HTTP, HTTPS)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

#nftables (SSH, HTTP, HTTPS)
tcp dport {22, 80, 443} accept


# iptables (Block a single IP address)
iptables -A INPUT -s 192.168.1.10 -j DROP
iptables -A INPUT -s 192.168.1.20 -j DROP
iptables -A INPUT -s 192.168.1.30 -j DROP

# nftables (Block a single IP address)
ip saddr {192.168.1.10, 192.168.1.20, 192.168.1.30} drop
# iptables Full ruleset (DROP, loopback, established, ssh, http, https)
iptables -P INPUT DROP
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p icmp -j ACCEPT

# nftables Full ruleset (DROP, loopback, established, ssh, http, https)

chain input {
    type filter hook input priority 0; policy drop;
    iif "lo" accept
    ct state established,related accept
    tcp dport {22,80,443} accept
    icmp type echo-request accept
}

# Quick Reference with Examples
# 1. Basic structure
# iptables: separate commands for filter, nat, mangle, etc.
# nftables: one unified syntax, everything managed with nft.

# 2. Allow SSH (port 22)
# iptables
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# nftables
sudo nft add rule inet filter input tcp dport 22 accept

# 3. Allow HTTP/HTTPS (ports 80, 443)
# iptables
sudo iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT

# nftables
sudo nft add rule inet filter input tcp dport {80, 443} accept

# 4. Allow ICMP (ping)
# iptables
sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

# nftables
sudo nft add rule inet filter input icmp type echo-request accept

# 5. Allow traffic from a specific IP
# iptables
sudo iptables -A INPUT -s 192.168.1.100 -j ACCEPT

# nftables
sudo nft add rule inet filter input ip saddr 192.168.1.100 accept

# 6. Drop all other traffic
# iptables
sudo iptables -A INPUT -j DROP

# nftables
sudo nft add rule inet filter input drop

# 7. Logging packets
#iptables
# Log and drop invalid packets
sudo iptables -A INPUT -m conntrack --ctstate INVALID -j LOG --log-prefix "INVALID: "
sudo iptables -A INPUT -m conntrack --ctstate INVALID -j DROP

# nftables
sudo nft add rule inet filter input ct state invalid log prefix "INVALID: " drop

# 8. NAT (port forwarding)
# iptables
sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.50:80

# nftables
sudo nft add table ip nat
sudo nft add chain ip nat prerouting { type nat hook prerouting priority 0; }
sudo nft add rule ip nat prerouting tcp dport 8080 dnat to 192.168.1.50:80

# 9. Save & restore rules
# iptables
sudo iptables-save > /etc/iptables/rules.v4
sudo iptables-restore < /etc/iptables/rules.v4

# nftables
sudo nft list ruleset > /etc/nftables.conf
sudo nft -f /etc/nftables.conf


# Summary
# iptables = old but still works, rule-by-rule.
# nftables = modern replacement, shorter syntax, one tool for everything.
Both support logging, but nftables logging is cleaner and more flexible.
# Example (Full version)
#!/usr/sbin/nft -f
flush ruleset

# =========================
# nftables: base template
# =========================
# Таблицы:
# - inet filter : general filtration for IPv4/IPv6
# - ip nat      : NAT for IPv4 (SNAT/MASQ, DNAT)

# ---------- FILTER ----------
table inet filter {

  # Sets
  set allowed_tcp_ports = {                    # Allowed services
    type inet_service;                         # 0..65535
    elements = { 22, 80, 443 }                 # SSH, HTTP, HTTPS
 (add more if needed)
  }

  # Example: SSH access from selected subs and IP only
  # set admin_src = { type ipv4_addr; flags interval; elements = { 192.0.2.0/24, 203.0.113.10 } }

  chain input {
    type filter hook input priority 0; policy drop;

    # Base level trust
    iif "lo" accept
    ct state established,related accept

    # ICMP/ICMPv6: ICMP and important messages, with rate-limit
    ip protocol icmp icmp type { echo-request, echo-reply, destination-unreachable, time-exceeded } limit rate 20/second accept
    ip6 nexthdr icmpv6 icmpv6 type { echo-request, echo-reply, destination-unreachable, time-exceeded, packet-too-big } limit rate 20/second accept

    # DHCPv6 for a client (if the server gets IP v6 address)
    udp dport 546 udp sport 547 accept

    # SSH / HTTP / HTTPS (see Sets above)
    tcp dport @allowed_tcp_ports accept

    # Example: SSH access — only for admin_src (see above and uncomment if needed)
    # tcp dport 22 ip saddr @admin_src accept

    # Logs
    limit rate 10/second counter log prefix "NFT DROP: " group 0 drop
  }

  chain forward {
    type filter hook forward priority 0; policy drop;

    # Allow from LAN to WAN 
    # See your interfaces and use them instead "lan0" и "wan0"
    iif "lan0" oif "wan0" accept
    ct state established,related accept

    # Log and Drop
    limit rate 10/second counter log prefix "NFT FWD DROP: " group 0 drop
  }

  chain output {
    type filter hook output priority 0; policy accept;
    # Usually all outgoes traffic is allowed. If no - add rules
  }
}

# ---------- NAT (IPv4) ----------
table ip nat {
  chain prerouting {
    type nat hook prerouting priority -100;

    # Example DNAT (port-forvarding)
    # WAN: tcp/2222  -->  LAN: 192.168.10.50:22
    # iif "wan0" tcp dport 2222 dnat to 192.168.10.50:22
  }

  chain postrouting {
    type nat hook postrouting priority 100;

    # Masquerade to go out (dynamic SNAT)
    # Change the "wan0" to your interface
    oif "wan0" masquerade
  }
}

sudo apt install nftables netfilter-persistent
sudo systemctl enable --now nftables netfilter-persistent