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 (192.168.2.100, 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 (192.168.2.1, 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 '16 at 15:51
up vote 6 down vote accepted

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 (192.168.2.1)
  • <b>: internal "faked" IP of the client (192.168.2.100)
  • <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 192.168.2.1:80

This will forward port 8080 on incoming packets on the external interface (in this example eth0) to the internal host 192.168.2.1 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 192.168.2.1 --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 127.0.0.1:80 but the request doesn't reach the webserver anymore. I also used your second rule: iptables -A FORWARD -i eth0 -p tcp -d 127.0.0.1 --dport 80 -j ACCEPT – Ka Rl Jun 9 '16 at 8:04
  • This will not work with the loopback interface. The loopback interface with IP 127.0.0.1 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 '16 at 8:08
  • I edited my initial post. Hopefully it is now a bit better to understand. – Ka Rl Jun 9 '16 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 '16 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: 192.168.0.1:80

  • Doesn't this command changes the ports and not the ip adress? – Ka Rl Jun 9 '16 at 7:23
  • @KaRl: Why don't you test it? I think it would work. – Julie Pelletier Jun 9 '16 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 '16 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 '16 at 7:51
  • @rda thx a lot. – Gruja Jun 9 '16 at 7:53

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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