Option 1: Disable Filtering on Storage Interfaces (Recommended)
For dedicated storage networks, disable firewall filtering on storage interfaces to eliminate CPU overhead from packet inspection. This is critical for high-throughput NVMe-TCP storage.
Why disable filtering on storage interfaces:
-
CPU overhead: Firewall packet inspection adds latency and consumes CPU cycles
-
Performance impact: At high IOPS (millions with NVMe-TCP), filtering overhead becomes significant
-
Network isolation: Dedicated storage VLANs provide security at the network layer
-
Simplicity: No port rules to maintain for storage traffic
Using UFW
# Allow all traffic on storage interfaces (no filtering)
sudo ufw allow in on ens1f0
sudo ufw allow in on ens1f1
# Verify
sudo ufw status
Using iptables
# Accept all traffic on storage interfaces (no filtering)
sudo iptables -A INPUT -i ens1f0 -j ACCEPT
sudo iptables -A INPUT -i ens1f1 -j ACCEPT
# Save rules
sudo apt install -y iptables-persistent
sudo netfilter-persistent save
Using nftables (Debian 11+)
# Add to nftables.conf - accept all on storage interfaces
iifname "ens1f0" accept
iifname "ens1f1" accept
Option 2: Port Filtering (For Shared or Non-Isolated Networks)
Use port filtering only when storage interfaces share a network with other traffic or when additional host-level security is required by policy.
Port filtering adds CPU overhead for every packet. For production storage with high IOPS requirements, use Option 1 with network-level isolation instead.
Using UFW (Ubuntu Default)
# Allow NVMe-TCP ports
# Port 4420 = Data port (connections)
# Port 8009 = Discovery port (optional, for nvme discover)
sudo ufw allow 4420/tcp
sudo ufw allow 8009/tcp
# Or allow from specific subnet only
sudo ufw allow from 10.100.1.0/24 to any port 4420 proto tcp
sudo ufw allow from 10.100.1.0/24 to any port 8009 proto tcp
sudo ufw allow from 10.100.2.0/24 to any port 4420 proto tcp
sudo ufw allow from 10.100.2.0/24 to any port 8009 proto tcp
# Enable UFW
sudo ufw enable
# Check status
sudo ufw status verbose
Using iptables (Debian/Advanced)
# Allow NVMe-TCP from storage network
sudo iptables -A INPUT -i ens1f0 -p tcp --dport 4420 -j ACCEPT
sudo iptables -A INPUT -i ens1f0 -p tcp --dport 8009 -j ACCEPT
sudo iptables -A INPUT -i ens1f1 -p tcp --dport 4420 -j ACCEPT
sudo iptables -A INPUT -i ens1f1 -p tcp --dport 8009 -j ACCEPT
# Or allow from specific subnet
sudo iptables -A INPUT -s 10.100.1.0/24 -p tcp --dport 4420 -j ACCEPT
sudo iptables -A INPUT -s 10.100.1.0/24 -p tcp --dport 8009 -j ACCEPT
# Save rules
sudo apt install -y iptables-persistent
sudo netfilter-persistent save
Using nftables (Debian 11+)
# Install nftables
sudo apt install -y nftables
# Create configuration
sudo tee /etc/nftables.conf > /dev/null <<'EOF'
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# Allow established connections
ct state established,related accept
# Allow loopback
iif lo accept
# Allow NVMe-TCP on storage interfaces (4420=data, 8009=discovery)
iifname "ens1f0" tcp dport { 4420, 8009 } accept
iifname "ens1f1" tcp dport { 4420, 8009 } accept
# Allow SSH
tcp dport 22 accept
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
EOF
# Enable and start
sudo systemctl enable --now nftables