In this answer, How can I open a range of ports in ubuntu using (g)ufw, a simple command for opening a range of ports is given.

For example, using this command I can open the ports 1000-1999 very easily for my firewall on my local machine.

Now, though, I would like to set-up port forwarding on the local machine, so that:

  • Port 1001 forwards to port 1
  • Port 1002 forwards to port 2
  • Port 1003 forwards to port 3
  • ... etc
  • -

Does anyone have a simple bash script for doing this?

I have to do this for multiple machines on a local network. Constraints by the router are making this more difficult than it needs to be.

So machine A, ports 1000-1999 on the router would be opened to link to machine A. On machine A, they would be forwarded to the traditional port. For machine B, ports 2000-2999 on the router would be used (mapped to the appropriate port locally). Etc

  • 1
    Please tell us exactly what you're trying to accomplish with all of this port forwarding. It sounds like you're making this more complicated than it needs to be. – heynnema Jan 8 at 18:15
  • I agree, but it has to do with the router's constraints. I can specify a range of ports to receive in the router, but only map within the router to "SAME" or "SINGLE" ports at the host -- I can't specify a range of ports to map from within the router. – nick carraway Jan 8 at 19:15

[Mostly Stolen from the Internet]

Enable IP forwarding:

sysctl net.ipv4.ip_forward=1

Use the "nat" table to forward traffic:

iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination X.X.X.X:80

Don't forget about HTTPS:

iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to-destination X.X.X.X:443

Ask iptables to masquerade:

 iptables -t nat -A POSTROUTING -j MASQUERADE

....and if you want that for each port in a range, i suggest something alike:

 y=0;  //first port to map to = 1, but y++ happens before mapping, so 0
 for i in {2000..2999}
       echo "forwarding port $i to port $y";
       iptables -t nat -A PREROUTING -p tcp --dport $i -j DNAT --to-destination X.X.X.X:$y;


  • system ports 1-1000 are reserved, so the above script is a bad idea ;)
  • offcourse substitute X.X.X.X with localhost or wherever you want to nat-forward
  • 1
    But if I'm mapping TO 1-1000, then it doesn't matter? – nick carraway Jan 8 at 19:16
  • 1
    no.. you cannot map to 1-1000 unless you know what you are doing. You should never map a range to 1-1000. ofc, if you want e.g. to map 8080 to 443 or 80, thats perfectly ok, but the <1000 ports are considered reserved and in most cases shouldn't be all mapped to. check out: en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers – Gewure Jan 8 at 19:46
  • 1
    Quote "The port numbers in the range from 0 to 1023 are the well-known ports or system ports.[2] They are used by system processes that provide widely used types of network services. On Unix-like operating systems, a process must execute with superuser privileges to be able to bind a network socket to an IP address using one of the well-known ports.[4]" – Gewure Jan 8 at 19:47
  • 1
    Oh right duh. i would disturb an underlying system process listening on that port. – nick carraway Jan 8 at 21:45
  • would you mind accepting my answer @nickcarraway? :) – Gewure Jun 29 at 2:54

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.