iptables redirect outside requests to 127.0.0.1

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 192.168.2.2 resides on)

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


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 can redirect to localhost but not to loopback (127.0.0.0/8). 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