NFT - Guide
Organizing Configuration Files
A good practice is to organize `nft` configuration files into logical sections to ensure clarity and maintainability. Avoid putting all rules into a single file. Instead, create different files for different contexts (e.g., input, output, forward, etc.) and then include them in a master configuration file.
Example:
# Main configuration file
table inet filter {
include "/etc/nftables/ipv4.rules"
include "/etc/nftables/ipv6.rules"
}
This approach allows easy updates and segregation of IPv4 and IPv6 rules.
Use of Tables, Chains, and Rules
When setting up firewall rules, tables, chains, and rules should be logically named to clarify their purpose. Use meaningful names that represent the function of the table or chain, such as `filter`, `nat`, `mangle`, and `security`.
Example:
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
iifname lo accept
ip protocol icmp accept
}
chain output {
type filter hook output priority 0; policy accept;
}
}
In the example above, `input` and `output` chains are set up under the `filter` table, and rules are defined with appropriate conditions and actions.
Using State Matching for Connections
One of the key features in firewall rule configuration is stateful inspection. Ensure that connection tracking is enabled by using the `ct state` match, which can help optimize performance and ensure that return traffic for established connections is properly handled.
Example:
chain input {
ct state established,related accept
ip protocol tcp dport 22 accept
ip protocol icmp accept
drop
}
This rule allows established or related connections to be accepted without re-checking the connection state for every packet.
Limiting Rule Scope for Performance
A crucial best practice is to limit the scope of rules to the minimum necessary. Avoid overly broad rules that could slow down the system. For example, instead of allowing all traffic on a network interface, define more specific matches for each protocol or port.
Example:
chain input {
ip protocol tcp dport 80 accept
ip protocol tcp dport 443 accept
drop
}
By narrowing the scope, the system will process fewer rules, improving performance.
Logging with Care
While logging can be useful for debugging, avoid excessive logging as it can degrade performance and fill up system logs. Only log critical or suspicious traffic and ensure logging is done with specific criteria.
Example:
chain input {
ip daddr 192.168.1.10 log prefix "Suspicious IP: "
drop
}
Logging suspicious IP addresses can help identify unauthorized access attempts without overwhelming the system with unnecessary log entries.
Using Sets for Efficient Matching
Sets are a powerful feature of `nft` for managing large numbers of items, such as IP addresses or ports. Use sets when you need to match against many values, as they provide better performance than individual rules.
Example:
set blocked_ips {
type ipv4_addr
elements = { 192.168.1.100, 192.168.1.101 }
}
chain input {
ip saddr @blocked_ips drop
}
In this case, the set `blocked_ips` contains a list of blocked IP addresses. This approach is more efficient than writing individual drop rules for each address.
Regular Backups of Configuration
Always back up your `nft` rules before making changes. You can dump the current rules to a file for safekeeping. This is especially important in production environments.
Example:
nft list ruleset > /etc/nftables/rules.backup
Regular backups help prevent accidental rule loss and enable easy restoration if issues arise.
Enable Persistent Configuration
Ensure that the firewall configuration persists across system reboots. Most Linux distributions provide a mechanism to automatically apply `nft` rules at boot time. For example, on Debian-based systems, you can save your configuration and ensure it is loaded at boot using the following:
Example:
nft list ruleset > /etc/nftables.conf
Then enable `nftables` to load this file on boot:
systemctl enable nftables systemctl start nftables
This ensures that your firewall rules are automatically applied each time the system starts.
Test Changes in a Staging Environment
Before applying firewall changes to production systems, always test them in a controlled environment. Misconfigurations can lead to loss of connectivity or downtime, so it is essential to test all changes thoroughly before implementing them live.
IPv6 Best Practices
When configuring `nft` for IPv6, be sure to include specific rules for handling IPv6 traffic. By default, IPv6 might not be covered by your IPv4 rules.
Example:
table inet filter {
chain input {
ip6 protocol icmpv6 accept
ip6 saddr fe80::/10 accept
drop
}
}
This configuration ensures that only essential IPv6 traffic (such as ICMPv6) is allowed, and other traffic is dropped.
Troubleshooting Tips
In case of connectivity issues, use the `nft` command to diagnose and troubleshoot:
- List the active ruleset to verify the current firewall configuration:
nft list ruleset
- Check if a specific rule is matched:
nft monitor
This will display real-time packet flow and help identify where packets are being dropped or accepted.
