I am running a Debian 10 server which has multiple network interfaces. Can I create rules that will route all network traffic coming in to one IP address on one of the interfaces from the outside (i.e. from other devices on the network), to another IP address not on the same machine but elsewhere on the network? Similarly to WAN-to-LAN routing.

I know how to do it on e.g pfSense but I am quite lost with iptables..

Non-iptables solutions are also welcome.

  • Do you want to only forward traffic coming from outside of the box to that interface, or also traffic coming from other interfaces on the same box and/or traffic generated by programs locally? – Gerrit Feb 19 '20 at 15:57
  • Only forward traffic coming from outside the box. Edited my question for clarification, will try your suggested answer! – Oleg Feb 19 '20 at 18:12
  • Please do not use NAT as a substitute for routing. If the networks are addresses differently, then simply route the packets between the networks. Changing the addresses on the packets causes more trouble, and NAT is resource intenive, slowing packet forwarding. – Ron Maupin Feb 19 '20 at 22:41

Quick examples for forwarding traffic coming from outside and interfaces within the same machine from address original to another address for ip versions 4 and 6 (possibly excluding ipsec traffic with an endpoint on the original address and existing connections at point of execution). This also does NOT redirect traffic generated by locally executing programs, for that you need the OUTPUT chain.

#Activate forwarding
#Note: These forward settings are not reboot persistent
sysctl -w net.ipv6.conf.all.forwarding=1
sysctl -w net.ipv4.ip_forward=1

iptables -t nat -A PREROUTING -d original.add.re.ss -j DNAT --to-destination ipv4.add.re.ss
iptables -t nat -A POSTROUTING -j MASQUERADE

ip6tables -t nat -A PREROUTING -d [original.add.re.ss] -j DNAT --to-destination [2001::]
ip6tables -t nat -A POSTROUTING -j MASQUERADE

If you want to limit the forwarding to only packets from outside you have to modify the rules, either add a -i interface naming the interface where they come in or match everything that did not originate from a local address -m addrtype ! --src-type LOCAL. You could further exclude broadcast and multicast traffic by using -m addrtype --dst-type UNICAST --src-type UNICAST. You should also check that the default policy for the FORWARD chain is ACCEPT or add specific rules in that chain.

Dumping the existing filter and nat tables can be done with iptables -S -t filter and iptables -S -t nat. The filter table is where you configure the FORWARD rules if there is a DROP policy.The -A before PREROUTING/POSTROUTING means Append. If you need to insert the rule, because there is a DROP at the end, you have to use -I and put a number behind the chain name.

  • echo 1 > /proc/sys/net/ipv4/ip_forward is equal to sysctl -w net.ipv4.ip_forward=1. Also echo 1 >/proc/sys/net/ipv6/conf/all/forwarding is equal to sysctl -w net.ipv6.conf.all.forwarding=1. I think it would be better to use the same form of setting for the same stuff. – Kamil J Feb 19 '20 at 21:54
  • @KamilJ, yes you are right. Thanks. – Gerrit Feb 19 '20 at 22:42
  • 1
    To have iptables rule persistent you should handle loading with the reboot or network stack reset. On some distributions (e.g. Red Hat, CentOS) there is package iptables-services which contain stuff targeting this automatic reload of the rules. In the rest of cases you should handle it with "boot up" scripts to load it (unfortunately the case of network stack reset would be more tricky)... Related to sysctl "persistency" there is option in /etc/sysctl.conf file or /etc/sysctl.d/ directory approach (this way it can be handled with the reload). – Kamil J Feb 19 '20 at 22:50
  • 1
    On Ubuntu you can install package iptables-persistent, and save a ruleset for restore on reboot with netfilter-persistent save. – Gerrit Feb 19 '20 at 22:58
  • 1
    @Oleg. Always nice to have a happy customer. About the matching, it shouldn't be negative, because when you match, you redirect, and it is the UNICAST packets that you do want to redirect. Incidentally matching on address family allows you to modify the matches by changing your routing table. If you declare a blackhole in your routing locally for a certain ip, then the UNICAST type would not match anymore. – Gerrit Feb 20 '20 at 9:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.