nat table within nftables. This process involves creating a new chain in the ip nat family, adding rules that match the destination address, and applying a dnat verdict to rewrite the packet's target. The following guide details the precise commands required to implement this network redirection safely and effectively.
Understanding nftables Structure
Before modifying any rules, it is essential to understand hownftables organizes its configuration compared to its predecessor, iptables. Unlike iptables, which uses flat tables with implicit chains like PREROUTING, nftables relies on an explicit hierarchy of families, tables, and chains. For local traffic redirection, we are primarily concerned with the ip family and the nat table.
The nat table is responsible for Network Address Translation. It operates at the netfilter hooks that allow packets to be modified before routing decisions are finalized or after they have been routed. In our case, since we are dealing with local requests (traffic generated by the machine itself), we will focus on the output path. This ensures that applications running on the host sending traffic to the original IP see their packets redirected to the new IP without requiring external interface involvement.
Prerequisites and Verification
Ensure your system is running Debian 10 or a newer version, as older releases may default toiptables-legacy compatibility layers that do not support modern nftables syntax directly. You can verify the installed version using the command nft --version. Additionally, confirm that the nftables service is active and enabled. On Debian systems, this is typically managed via systemd.
You should also check the current state of your firewall to avoid conflicts. Run sudo nft list ruleset to view existing rules. If there are existing nat rules, note them down, as adding new rules incorrectly could disrupt current network functionality. It is often safer to start with a clean slate or append to existing configurations carefully.
Creating the NAT Chain
The first step is to create a dedicated chain within theip nat table where our redirection logic will reside. We will name this chain LOCAL_DNAT. This separation helps keep your configuration organized and makes future maintenance easier. Execute the following command to create the chain:
sudo nft add chain ip nat LOCAL_DNAT { type nat hook output priority -100 ; policy accept ; }
This command defines a chain named LOCAL_DNAT inside the ip nat table. The hook output specifies that this chain processes packets leaving the local system. The priority -100 places it early in the processing pipeline, ensuring the redirection happens before other potential manipulations. The policy accept means that if no rules match in this chain, the packet continues normally.
Adding Redirection Rules
With the chain established, you need to add rules that define the source and destination conditions for the redirection. Suppose you want to redirect all traffic destined for192.168.1.100 to 192.168.1.200. Use the following command:
sudo nft add rule ip nat LOCAL_DNAT ip daddr 192.168.1.100 dnat to 192.168.1.200
This rule matches packets where the destination address (ip daddr) is exactly 192.168.1.100. When a match occurs, the dnat to action rewrites the destination address to 192.168.1.200. If you need to redirect a range of IPs, you can use CIDR notation, such as ip daddr 192.168.1.0/24. Similarly, you can restrict the redirection to specific protocols or ports by adding tcp dport or udp dport criteria to the rule.
Persisting Configuration
Rules added via the command line are volatile and will be lost upon reboot. To make these changes permanent, you must save the current ruleset to a configuration file. On Debian, the standard location for this file is/etc/nftables.conf. First, export the current ruleset:
sudo nft list ruleset > /etc/nftables.conf
After saving, ensure that the nftables service is configured to load this file on boot. Verify the service status with systemctl status nftables. If the service is not enabled, run sudo systemctl enable nftables. This ensures that your redirection rules are applied automatically every time the system starts.
For more context on managing default behaviors in nftables, you might find Understanding the Default Verdict with nftables Rule: A Comprehensive Guide helpful, as it explains how policies interact with custom chains.
Testing and Troubleshooting
Once the rules are in place, test the redirection by attempting to connect to the original IP address from a local application. For example, usecurl http://192.168.1.100 or ping 192.168.1.100. If the redirection is working correctly, the connection should succeed but actually communicate with 192.168.1.200. You can verify this by checking logs on the target server or using tcpdump to observe the rewritten packets.
If the redirection fails, check the following:
1. Ensure the nftables service is active and loaded the correct configuration.
2. Verify that no other firewall rules are dropping the traffic.
3. Confirm that the target IP (192.168.1.200) is reachable and accepting connections.
4. Check for any conflicting rules in the nat table that might override your new entry.
See Unable to traceroute but able to ping if you suspect intermediate routing issues affecting your local requests.
Frequently Asked Questions
Does this method work for IPv6?
No, the examples provided use the ip family which handles only IPv4. For IPv6, you must use the ip6 family instead, changing ip nat to ip6 nat in all commands. The syntax for addresses and redirection remains similar, but you must use IPv6 addresses.
Will this affect incoming traffic from other hosts?
No, because we used the output hook, this rule only applies to traffic generated locally on the machine. Incoming traffic from remote hosts is processed by the prerouting hook, which requires separate rules if you wish to redirect those as well.
How do I remove a specific rule?
You can delete a rule by listing the ruleset with nft list chain ip nat LOCAL_DNAT to get the handle number, then using sudo nft delete rule ip nat LOCAL_DNAT handle <number>. Alternatively, you can flush the entire chain with nft flush chain ip nat LOCAL_DNAT if you want to clear all rules within it.
Can I redirect based on source IP as well?
Yes, you can add a condition for the source address using ip saddr. For example, ip saddr 10.0.0.5 ip daddr 192.168.1.100 dnat to 192.168.1.200 would only redirect traffic originating from 10.0.0.5 to the specified target.
What happens if the new IP is unreachable?
If the destination IP 192.168.1.200 is unreachable, the connection attempt will likely timeout or fail with a "No route to host" error. The redirection itself succeeds, but the underlying network connectivity determines the outcome. Ensure the new IP is valid and accessible from the local machine.