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

I'd like to set up a TCP DNAT from, port 4242 to, port 5353 on Linux 3.x (currently 3.2.52, but I can upgrade if needed).

It looks like the simple DNAT rule setup doesn't work, telnet 4242 hangs for a minute in Trying, and then it times out. Maybe it's because the kernel is discarding the returning packets (e.g. SYN+ACK), because it considers them Martian. I don't need an explanation why the simple solution doesn't work, I need a solution, even if it's complicated (e.g. it involves creating may rules).

I could set up a usual DNAT from another local IP address, outside the network, but now I need as the destination address. I know that I can set up a user-level port forwarding process, but now I need a solution which can be set up using iptables and doesn't need helper processes.

I was googling for this for an hour. It was asked multiple times, but I couldn't find any working solutions.

Also there are many questions about DNAT to, but I don't need that, I need the opposite.

Please note that a single iptables -j REDIRECT rule wouldn't work, because I need to change the IP address of the outgoing packet from to, and -j REDIRECT can't change the IP address.

share|improve this question

Is it something like this you need ? iptables port redirect not working for localhost

iptables -t nat -I OUTPUT -p tcp -d --dport 443 -j REDIRECT --to-ports 8080


share|improve this answer
Thank you for writing your answer. Unfortunately it doesn't solve my problem, because -j REDIRECT can't change the IP address, and I need to change it from to If I didn't need to change the IP address, it would work. – pts Nov 8 '13 at 7:21
iptables won't change the IP address. What are you trying to achieve ? Why do you want to change the IP address ? – Lawrence Nov 8 '13 at 7:48
Sorry, missed some lines. So, it's not a REDIRECT that you need, but rather something like : iptables -t nat -A PREROUTING -d -j DNAT --to But according to what you're trying to do, if you only change the packet, you'll also need to change the return packet ( => Have a look on this Schema to understand placement of tables : – Adrien M. Nov 8 '13 at 8:18
@Adrien M.: Yes, this (with -j DNAT) is the standard solution, but it doesn't work for telnet 4242 (it works with all other local IP address), because Linux is dropping the response packets (see the details in the question). If you think you have a solution which solves the problem, please post it. – pts Nov 8 '13 at 13:19
@Lawrence: I'm trying to achieve that the connection initiated by telnet 4242 gets forwarded to by the kernel, without using a user-level port forwarder process. Sorry if this was not clear from the question. – pts Nov 8 '13 at 13:21

This works for me, routing traffic from localhost:8081 to, where is a veth behind the bridge interface named docker0.

sysctl -w net.ipv4.conf.docker0.route_localnet=1
iptables -t nat -A OUTPUT -o lo -p tcp -m tcp --dport 8081 -j DNAT --to-destination
iptables -t nat -A POSTROUTING -o docker0 -m addrtype --src-type LOCAL --dst-type UNICAST -j MASQUERADE

A key piece of the puzzle is the MASQUERADE rule.

Further inspiration:

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.