Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

So I have a VPN on ppp0 and I setup so I can use either ppp0 or eth1 to connect out with the default route being eth1.

Both reply to "ping" (uses eth1) and "ping -I ppp0" (uses VPN)

Goal: If I connect to eth1 on port 12345 it will forward out ppp0 to a specific ip address (

eth1: local network
ppp0: vpn service
local network:
forwarding ip:
port: 12345

ports can be different the same doesnt matter, if it works :)

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

After searching this is what most people say. Use the PREROUTE to set new destination. Then forward out ppp0. But its not working and I don't know how to actually see what its doing.

share|improve this question

You can try to mark your packets with iptables with MARK, somethink like that after or before your dnat :

iptables -t mangle -A PREROUTING -p tcp -d --dport 12345 -j MARK --set-mark 111

After you can set a specific route for this :

ip rule add fwmark 111 lookup 100

ip route add local dev ppp0 table 100

share|improve this answer

That's probably because the NAT rule just gives it a new destination IP address, which then gets routed trough eth1. Then the filter rule does not apply.

You'd need to either create a route for this specific destination going trough ppp0 (if it is fine for all the traffic bound to this destination to go trough the vpn), or use the mangle table to hand-pick a destination for this traffic.

share|improve this answer
iptables -t nat -A PREROUTING -p tcp -i eth1 -d \
  --dport 12345 -j DNAT --to-destination

Locally generated traffic will never pass through the PREROUTING chain. You can verify this by adding a rule like this:

iptables -t nat -A PREROUTING -j log -m limit --limit 1/s

If you're not familiar with iptables, the above rule means:

  • Log (at a maximum rate of 1 message/second) any packets traversing the PREROUTING chain.

Watch your log files while you make outbound connections, and you'll see that nothing is passing through this chain. The PREROUTING chain only comes into play for traffic coming into your system from an outside source.

You might think you could do this in the OUTPUT chain:

iptables -t nat -A OUTPUT ... -j DNAT ...

But by the time a packet hits the OUTPUT chain the routing decision has already been made. You can probably get you want by using a REDIRECT rule in the OUTPUT chain and then running a tcp proxy on a local port that redirects connections to your destination. That is, you can add a rule like this:

iptables -t nat -A OUTPUT -p tcp -d --dport 12345 \
  -j REDIRECT --to-ports 12345

And then run a tcp proxy locally on port 12345.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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