It seems that DNAT for loopback traffic is not possible.
Loopback traffic skip both PREROUTING and OUTPUT chains.
RFC 5735 (page 3) says that network 127.0.0.0/8
could not be routed outside of the host itself :
127.0.0.0/8 - This block is assigned for use as the Internet host
loopback address. A datagram sent by a higher-level protocol to an
address anywhere within this block loops back inside the host. This
is ordinarily implemented using only 127.0.0.1/32 for loopback. As
described in [RFC1122], Section 3.2.1.3, addresses within the entire
127.0.0.0/8 block do not legitimately appear on any network anywhere.
Also, traffic to loopback interface
are considered as Martian Packets
:
these packets cannot actually originate as claimed, or be delivered
Workaround :
A simple alternative is to use an inted
server on Server side, and its redirect
feature.
This way, you can define un service within inetd
and set the port where this service will listen to. Then, set the redirect
directive to bind this port to 127.0.0.1:port
.
In my sample below i will use xinetd
(on Ubuntu 12.04 LTS) to bind a mysql
server running on 127.0.0.1:10000
:
Step 1 : Install the package : apt-get install xinetd
Step 2 : Edit de the config file /etc/xinetd.conf
Add a service definition similar to the one below :
service my_redirector
{
type = UNLISTED
disable = no
socket_type = stream
protocol = tcp
user = root
wait = no
port = 15000
redirect = 127.0.0.1 10000
log_type = FILE /tmp/somefile.log
}
Step 3 : Restart xinetd
daemon : service xinetd restart
Step 4 : let's check for the listener on port 15000
:
# netstat -anp | grep 15000
tcp 0 0 0.0.0.0:15000 0.0.0.0:* LISTEN 4654/xinetd
Step 5 : Add your iptables
rules :
iptables -A INPUT -i eth0 -p tcp -d 192.168.0.60 --dport 15000 -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp -s 192.168.0.60 --sport 15000 -j ACCEPT
Let's test it :
For testing i have setup mysql
to listen on 127.0.0.1:10000
. I will try to access it through the xinetd
service on port 15000
.
First, on Server side, i make sure that mysql
server is only listening on 127.0.0.1:10000
:
# netstat -anp | grep :10000
tcp 0 0 127.0.0.1:10000 0.0.0.0:* LISTEN 4247/mysqld
Then, on Client side, let's check if we can connect using port 15000
:
# telnet 192.168.0.60 15000
Trying 192.168.0.60...
Connected to 192.168.0.60.
Escape character is '^]'.
_
5.5.35-0ubuntu0.12.04.2-logD46S}<P`.6cr4ITIQ<wcmysql_native_password
Seems we can ! :)
Let's try to connect to mysql
server :
# mysql -h 192.168.0.60 --port=15000 -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 67
Server version: 5.5.35-0ubuntu0.12.04.2-log (Ubuntu)
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
Done !