I have a service running on with port 2222. I need to forward all requests to (outside IP) only from subnet to

I'm trying to use this, but it's not working.

$ iptables -t nat -I PREROUTING -p tcp -d --dport 2222 -j DNAT --to-destination

How can I get this to work?

UPD: Edit address scheme.

  • We need some clarification. Where is the traffic coming from? Where is the traffic originally going to? Where should the traffic be going to? As I read it, you want traffic from to to be redirected to But Warren's answer assumes you want traffic from to to be redirected to
    – phemmer
    Jan 29, 2014 at 13:37
  • 2
    Traffic comes from subnet to and should be translated to service on I'm corrected address scheme.
    – SimWhite
    Jan 29, 2014 at 14:27
  • 1
    You want a rule that allows traffic to port 2222 on the loopback interface from subnet That isn't just a single rule type of setup. See here: debuntu.org/…
    – slm
    Jan 29, 2014 at 14:35
  • Yes. As I understand I need to add masq rule? IP forwarding is already enabled of course.
    – SimWhite
    Jan 29, 2014 at 14:47
  • Why not run it on a "real" IP, and filter out traffic comming from unwanted sources? That is what firewalls are for, essentially...
    – vonbrand
    Feb 3, 2014 at 1:04

3 Answers 3


The iptables rule you are using will work, but there is one additional change you need to make:

sysctl -w net.ipv4.conf.eth0.route_localnet=1

(replacing eth0 with the nic resides on)

By default this value is 0, which instructs the kernel to not route external traffic destined to This is just for security as such traffic is not normal.

  • 19
    This info is surprisingly hard to find.
    – Wren T.
    May 16, 2014 at 4:06
  • Yes, very valuable hard-to-find information! Thank you! But I don't have route_localnet. Have there been other names for it? (in linux 2.6.30) ls /proc/sys/net/ipv4/conf/lan/: accept_redirects arp_accept arp_filter arp_notify disable_policy force_igmp_version log_martians medium_id proxy_arp secure_redirects shared_media accept_source_route arp_announce arp_ignore bootp_relay disable_xfrm forwarding mc_forwarding promote_secondaries rp_filter send_redirects tag Mar 31, 2015 at 22:39
  • I see, the patch for route_localnet is more recent (June 7, 2012) than my kernel ( 2.6.30-std-def-alt15 #1 SMP Mon Dec 14 08:45:48 UTC 2009). Ok, I'll simply achieve the wanted port-forwarding (from outside to inside) with a forwarding process like netcat (nc), xinetd, or the port-forwarding options of ssh (the latter is ineffective and stupid, of course, but I mention it, because, well, this possibility is there). Mar 31, 2015 at 22:50
  • 4
    My 2 cents: you may enable this parameter for all interfaces with sysctl -w net.ipv4.conf.all.route_localnet=1
    – Dmitriusan
    Nov 10, 2017 at 12:39
  • Like others, this info was hard to come by. Thanks, if I'd found this earlier, would have saved me a tonne of effort. Feb 12, 2019 at 10:40

You can redirect to localhost but not to loopback ( Loopback is a loophole. You have to redirect to one of your real interfaces. Try using REDIRECT.

iptables -t nat -A PREROUTING ..... -j REDIRECT --to-port 222

  • This is probably the best answer without the sysctl voodo... Jun 3, 2016 at 2:30
  • 2
    Still doesn't help if port 222 is only being listened on localhost (the rule won't change destination address)
    – sanmai
    Dec 20, 2016 at 4:35
  • 4
    In that case, use -j DNAT --to-destination w.x.y.z:222
    – dresende
    Dec 21, 2016 at 0:58
  • 4
    Thanks @dresende, -j DNAT --to-destination<port> works great!<br/> This is the full command I used to forward connection to a MariaDB server listening on port 1186: iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 1186 -j DNAT --to-destination
    – maximus
    Jul 13, 2020 at 9:14

What if the correct answer with route_localnet doesn't work?..

If your kernel doesn't include the patch for route_localnet, then... upgrade the kernel!

Or there are other ways to forward the traffic coming to one interface to another port on another interface (in particular, to localhost) by running a process that would listen on the external interface and forward the traffic.

netcat (nc), xinetd, and ssh (and perhaps more) are all examples of programs able to do this (although choosing ssh would be strange and ineffective).

I've written a configuration for xinetd for this. Now this service is automatically brought up:

# cat /etc/xinetd.d/z-from-outside 
# default: off
# description: Forward connections to the z port.
service z-from-outside
    disable         = no
    socket_type     = stream
    type        = UNLISTED
    wait            = no
    user            = nobody
    bind        = vaio.ob
    port        = 7070
    redirect    = localhost 7070

(vaio.ob is the name of this host on the external network interface.)

After a service xinetd reload, let's check that it is listening:

# lsof -i -P | fgrep 7070
xinetd    556      root    6u  IPv4 1797906      0t0  TCP vaio.ob:7070 (LISTEN)
sshd    27438 tun_zzoom    4u  IPv4 1059100      0t0  TCP localhost.localdomain:7070 (LISTEN)

And indeed, connections do go through!

You must log in to answer this question.

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