Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

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 am trying to forward traffic from one server to another, while keeping the origin requestor IP. Therefor I cannot use SNAT or MASQUERADE.

Public IP:
Private IP:

Public IP:
Private IP:

I want to forward traffic från Server A ( to Server B (

This works fine:

iptables -t nat -A PREROUTING -d -p tcp --dport 80 -j DNAT --to-destination
iptables -t nat -A POSTROUTING -j MASQUERADE

However, because I am using MASQUERADE in this case, the destination server ( sees all traffic as it would be comming from, i.e apache-logs and others are showing all requests as they are comming from

How can I setup this instead, so that the origin source IP-address is kept, like a home-router is doing it when using port forwarding.

I assume I need to setup a "route" somehow, so that the outgoing traffic from goes out through Server A and not trying to respond on Server B's public IP?

share|improve this question
I think you must use iproute and separate routing table. You can find more at . P.S. if you need forward only http traffic you could use nginx – ALex_hha Jul 18 '13 at 10:11
nginx would work if configure to add the remote address as an extra header (like proxy_set_header X-Forwarded-For $remote_addr;, see for more detail) and if what-ever is doing the logging is (or can be made) aware of this information (for Apache, configure the rpaf module to be aware of the new header, see Using nginx as a proxy will add more latency than arranging this via NAT though, but the difference may be as small that you don't care. – David Spillett Jul 18 '13 at 10:23
I do not only want to forward HTTP traffic. All traffic should be forwarded. I am just starting out with a certain port. – Daniele Testa Jul 18 '13 at 11:14
Why are you attempting to use NAT at all? – Michael Hampton Jul 18 '13 at 18:21
@DanieleTesta - Why do you need the origin IP? is it for logging purposes or something else. Please update your question with a bit more background info. It might be that you're trying to solve with the wrong method. – Matt Jul 11 '14 at 0:17

It seems you are confused about networking.

What you want at the NAT level makes no sense at all.
The address MUST be rewritten in the Layer3 network packets for NAT to work at all.
And private IP space is NOT routable (over the internet, intrAnets may behave differently) in the first place.

The place where you want to see the original ip-addresses is in Layer 4: The application layer. (Logs, etc.) The information there is NOT affected by the NAT at all. You may see the ip-address of the NAT router, but the Apache logs should still indicate which machine/hostname/user from behind the NAT requested the info on basis of the HTPP header information.

You are mixing up different things that are not related.

share|improve this answer

Your DNAT rule alone should be sufficient for the address translation without any need to add MASQUERADE in POSTROUTING, you just need to tell the firewall to then accept the translated packet.

For instance on of my incoming routes:

/sbin/iptables -t nat -A PREROUTING -p tcp -d $EXTERNALIP  --dport 22 -j DNAT --to $INTERNALTARGET:22
/sbin/iptables -A FORWARD -p tcp -d $INTERNALTARGET --dport 22 -j ACCEPT

From the wording of your question you seem to be trying to route public requests into on private subnet then on to another - if that is the case then you may need to make routing tweaks so that the return packets know where to go. In my example above I'm passing requests on a public interface ($EXTERNALIP) to a machine ($INTERNALTARGET) connected to the one private network leg the router is connected directly to, and that router is the default route out so return packets know where to go without extra help.

share|improve this answer
With your rules INTERNALTARGET will be reply to original ip. For example, Client A connect to server A on port 22 with ip The server forward all packets to the Server B on the same port with ip yyy.yyy.yyy.yyy. Server B will send reply packets to Client A. How do you think, what will happens with these packets on the client side? – ALex_hha Jul 18 '13 at 10:18
@ALex_hha The router is the default gateway for this network, so returning packets will be sent out through it and get picked up by the second half of the address translation process (their source address will be translated back to the public address). This works for incoming connections, to make connections made from the internal machine a little extra is needed. If you have only one public address then MASQUERADE is probably already configured and will work, I have several so use specific SNAT rules as needed like so: iptables -t nat -A POSTROUTING -s $INTERNALIP1 -j SNAT --to $EXTERNALIP1 – David Spillett Jul 18 '13 at 10:29
Yes, I know that. But @Daniele Testa said that he can't use SNAT/MASQUERADE at all (I don't know why) or did I miss something? – ALex_hha Jul 18 '13 at 10:33
Yes, I needed to setup a default route for my subnet on Server B to force the response back throug Server A. Then it worked with just DNAT :) I am using GRE to setup the network now. Is there a way to make all this work even without that GRE link? – Daniele Testa Jul 18 '13 at 11:17
@Alex_haa: To answer the specific problem in the question (routing incoming TCP connections through) the SNAT is not needed. It isn't necessary required for outgoing connections either - it is only needed if you need the outgoing connections to appear to come from a specific external interface/address rather than the default. – David Spillett Jul 18 '13 at 13:27

Iptables are wonderful, but if you keep everything in nginx, then it can do the job it was designed for. It's possible to do other advanced tricks with iptables like logging and packet marking, but if you don't have a reason to do it outside of nginx, you should go through nginx. That way if you move to a different system like (Ugly)windows server or FreeBSD, then the configuration is done in nginx and not at a system dependent level. If you're worried about speed, that is what nginx was designed for, so if you use some of the premade or develop your own log monitors, it is the same on every system you work with. Linux rocks, and there shouldn't be a reason to move off of it, but incase you have to implement more servers with other environments, all of your configs are Environment independent.

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.