i've tried to get port forwarding working on a machine. I've read many topics here regarding that problem, but i can't get it work. Plan is to get all incoming traffic on ppp0 on port 5000 forwarded to a device on eth0. Here are the Rules i have tried (gathered from this site):

iptables -t nat -A PREROUTING -p tcp -i ppp0 --dport 5000 -j DNAT --to-destination
iptables -A FORWARD -p tcp -d --dport 5000 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A POSTROUTING -j MASQUERADE -o ppp0

That didn't work. Next try was this:

iptables -A PREROUTING -t nat -i ppp0 -p tcp --dport 5000 -j DNAT --to
iptables -A INPUT -p tcp -m state --state NEW --dport 5000 -i ppp0 -j ACCEPT
iptables -t nat -A POSTROUTING -j MASQUERADE -o ppp0

When accessing that machine on that port i get a connection refused without those rules and a connection timeout with the rules. So something is working, but not in the way intended.

How can i check what i'm doing wrong?


You need to use a FORWARD rule with PREROUTING. The reason is that the change to the destination IP is made before any rules from the FILTER table are applied - check this graphic for the order in which the rules of the different tables of iptables are applied to packets.

So you would need the NAT on the way in and forwarding for that NAT. The retranslation on the way out (if the connection was initialized from outside while addressing ppp0:5000) will be taken care of by the DNAT rule.

iptables -A PREROUTING -t nat -i ppp0 -p tcp --dport 5000 -j DNAT --to
iptables -A FORWARD -p tcp -d --dport 5000 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

You also need to activate IP forwarding per se; if you only want that temporarily (until the next system shutdown), you can go with

echo 1 > /proc/sys/net/ipv4/ip_forward

If you want to persistently activate port forwarding, you need to change the file /etc/sysctl.conf, changing the value of net.ipv4.ip_forward to 1.

If you also want to use NAT on the way out so the computers within your private network can reach the outside world, you can use

iptables -t nat -A POSTROUTING -j MASQUERADE -o ppp0

Note: you do not need a FORWARDING rule for this one.

To see which table holds which rules, you can use

iptables -t [table] -S

for an unstructured view of the rules of [table] (FILTER NAT MANGLE are the tables of iptables; if you want FILTER, you don't need -t FILTER since FILTER is the default table all calls of iptables evaluate to), or

iptables -t [table] -L

for a view of the rules split up into the chains of the table.

Check the man pages for a REALLY detailed look at iptables - bring a lot of time if you want to go deeper :)


First of all, allowing only the NEW connections is not enough. So, you have to use a rule like:

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

You may need to enable IPv4 routing. The value of /proc/sys/net/ipv4/ip_forward should be 1. Try to use echo 1 > /proc/sys/net/ipv4/ip_forward as super user.

  • /proc/sys/net/ipv4/ip_forward is enabled and adding RELATED and ESTABLISHED to the states didn't change anything. Something else i can check? – Andre Dec 22 '11 at 13:35
  • You can check the output of iptables -L -n -t nat -v. This will show the rules with counters to see the number of times a specific rule is hit. – Khaled Dec 22 '11 at 13: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.