I'm trying to create a proxy of sorts using just iptables.

The linux computer (my proxy) has two ports:

  • p2p1 is connected to the Internet.
  • em1 is connected to a local network.

There are two devices on the local network (not including the linux machine). To connect to these, we should type (from any computer on the Internet):

  • xx.xx.xx.xx:10001
  • xx.xx.xx.xx:10002

where xx.xx.xx.xx is the public IP (and is dynamic).

These devices can be accessed from the linux machine on the em1 port by accessing the following IPs:


So, all traffic that gets routed into xx.xx.xx.xx:10001 on p2p1 should be redestined for on em1.

I also need to retain the source IP, or something to that effect, so the packets can find their way back.

Here's what I'm using in my IP tables script.

iptables -t nat -F  # Clear out any old rules.


iptables -t nat -A PREROUTING --dst $MyIP -p tcp --dport $MyPort -j DNAT --to-destination $DestIP:$DestPort
iptables -t nat -A POSTROUTING -p tcp --dst $DestIP --dport $DestPort -j SNAT --to-source $MyIP
iptables -t nat -A OUTPUT --dst $MyIP -p tcp--dport $MyPort -j DNAT --to-destination $DestIP:$DestPort

Obviously there are some problems because my IP is dynamic, yet I'm hard coding it in every time. Furthermore, the packets, once they return to the computer, don't know how to get to their original source.

I don't know where to go from here.


To forward a port, the first thing you need to do is enable forwarding in the kernel using one of two methods:

  • Modify settings in /proc as root; only lasts until reboot:

    echo 1 > /proc/sys/net/ipv4/ip_forward

  • Modify settings in /etc/sysctl.conf; this is persistent:

    append net.ipv4.ip_forward=1 to /etc/sysctl.conf then execute $ sudo sysctl -p

The second thing you need to do is configure the forwarding rule in iptables using the following syntax:

iptables -t nat -A PREROUTING -i [external_interface] -p [protocol] \ 
--dport [external_port] -j DNAT --to-destination [internal_ip]:[internal_port]

So using your script:

iptables -t nat -A PREROUTING -i $external_iface -p tcp \
--dport $MyPort -j DNAT --to-destination ${DestIP}:${DestPort}

This will forward all traffic from port 10001 on psp1 (regardless of it's IP address) to port 80 on On, the traffic will appear to come from whatever IP address is assigned to em1.

The \ is not required in the rule. It's only used to break the rule into 2 lines.

  • So this is working for me if I do a public IP, such as Google's. However, it fails to get anything if I'm connecting to a server within my local network. Also, I've checked to make sure that my local server is working, as I can connect to it from the computer I'm using as a proxy. Also, for some context, I added the following line to my script to get it to work: iptables -t nat -A POSTROUTING -j MASQUERADE – jack b May 28 '14 at 19:53
  • A little more detail: I used a log to determine that the packets are indeed going out the right interface, but I think because they have the source of my proxy computer, the response can't find its way back to the computer I'm connecting from. To test it, I'm literally typing "" into the url bar (and this is how it will be used in its final incarnation). – jack b May 28 '14 at 20:02
  • @jackb the local computer you're using as a proxy should be the default gateway for your network. One interface should be exposed to the public Internet and the other interface connected to your LAN with your client computer using that IP address as it's default gateway. – Creek May 28 '14 at 20:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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