I have a web service running on port X. It was never intended to run outside a local network, but I would like to access it over the internet. Therefore, I need to change the source IP address of all incoming packets to a local one (, for example). Otherwise the web service responds with an error.

So here is what I need:

If I send a packet from my home computer with the public IP X to the public IP address Y of my server, the source IP address (in that case X) needs to be changed to a local one (, for example). After that, the packet should be passed on to the web application which is running on the same server on port 80.

  • If it was never intended to run across the internet, then is it using HTTP rather than HTTPS? If so, then do you really want to run transactions across the internet unencrypted? You could kill 2 birds with one stone by using stunnel or similar.
    – symcbean
    Jun 10, 2016 at 15:51

2 Answers 2


OK, now I think I understand what you want. This is a very special case and different from the normal port-forwarding approach which I posted earlier (see below). The following rules should do it.

SNAT on incoming packets

I assume the following:

  • <x>: public IP of the server
  • <y>: public IP of the client
  • <a>: internal IP of the server (
  • <b>: internal "faked" IP of the client (
  • <if>: external interface (i.e. eth0)

SNAT only

This rule will alter the packet's source address:

iptables -t nat -A INPUT -p tcp -d <x> --dport 80 -s <y> -j SNAT --to-source <b>

Combined DNAT and SNAT:

These rules will alter the packet's source and destination address:

iptables -t nat -A PREROUTING -i <if> -p tcp -d <x> --dport 80 -s <y> \
    -j DNAT --to-destination <a>:80
iptables -t nat -A INPUT -p tcp -d <a> -s <y> --dport 80 \
    -j SNAT --to-source <b>

Don't forget to ACCEPT the packets in the filter table.

Usual DNAT port forwarding rule for comparison (without SNAT):

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 \
    -j DNAT --to-destination

This will forward port 8080 on incoming packets on the external interface (in this example eth0) to the internal host to port 80. Replace interface, protocol, dport and to-destination with your settings.

This rule will accept the modified packet:

iptables -A FORWARD -i eth0 -p tcp -d --dport 80 -j ACCEPT
  • I changed the rule to fit my environment: iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 1337 -j DNAT --to-destination but the request doesn't reach the webserver anymore. I also used your second rule: iptables -A FORWARD -i eth0 -p tcp -d --dport 80 -j ACCEPT
    – Ka Rl
    Jun 9, 2016 at 8:04
  • This will not work with the loopback interface. The loopback interface with IP is just for requests originating from the local host itself. Please clarify your question what you want to do exactly with ports, IP addresses, network layout and so on.
    – rda
    Jun 9, 2016 at 8:08
  • I edited my initial post. Hopefully it is now a bit better to understand.
    – Ka Rl
    Jun 9, 2016 at 8:20
  • @KaRl, I updated my answer with a solution, which should do what you want. I tested this with apache2, which is correctly showing the altered source address. What I do not understand is why you need to do this at all. Are the IP addresses hard-coded in your application?
    – rda
    Jun 9, 2016 at 10:51

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport *$srcPortNumber* -j REDIRECT --to-port *$dstPortNumber*

You will change -i attribut if yours NIC is not on eth0

Edit #1

You can for --dport and --to-port set ip adress whit port for exm:

  • Doesn't this command changes the ports and not the ip adress?
    – Ka Rl
    Jun 9, 2016 at 7:23
  • @KaRl: Why don't you test it? I think it would work. Jun 9, 2016 at 7:27
  • @JuliePelletier Thats a good point. I tried it right now and the redirect works but I get the same error message, that the ip XYZ is not a local ip adress.
    – Ka Rl
    Jun 9, 2016 at 7:40
  • This rule will just modify the target port of the packet. The packet will still arrive on the local host where the setting was made.
    – rda
    Jun 9, 2016 at 7:51
  • @rda thx a lot.
    – Gruja
    Jun 9, 2016 at 7:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .