5

I have two Docker containers that I'm trying to network together in a specific way. Container A is running a Redis server on port 6379. Container B is running an interactive shell and needs to access Redis. Using Docker's linking feature, a user inside container B can connect to Redis on through 10.1.0.2:6379, which travels through the virtual eth0 interface set up by Docker.

There is a program that will be running in container B that expects Redis to be available at port 6379 on the loopback interface. Assume that this program cannot be configured to point at a different IP.

I'd like to forward traffic to 127.0.0.1:6379 to 10.1.0.2:6379. I have tried several variations of iptables rules on the NAT table, but I either get "connection refused" when trying to connect to the local address/port, or the connection just hangs forever. What iptables rules can I use to achieve this effect?

Here is one of the things I tried:

$ sudo iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-A INPUT -d 10.1.0.2/32 -p tcp -m tcp --dport 6379 -j SNAT --to-source 127.0.0.1
-A OUTPUT -p tcp -m tcp --dport 6379 -j DNAT --to-destination 10.1.0.2:6379

Attempting to connect to Redis with redis-cli using the above rules just hangs forever. I've tried a version of this that uses PREROUTING/POSTROUTING instead of INPUT/OUTPUT and that resulted in an immediate "connection refused."

Jimmy
  • 193
  • 2
  • 6

1 Answers1

3

I would use socat for that:

socat TCP-LISTEN:6379,fork TCP:10.1.0.2:6379

You might want to run this using supervisor or a similar tool. On ubuntu:

apt-get install socat supervisor

cat > /etc/supervisor/conf.d/redis-socat.conf << EOF
[program:redis-socat]
command = socat TCP-LISTEN:6379,fork TCP:10.1.0.2:6379
autorestart = true
user = nobody
EOF

supervisorctl reload

Now you can start/stop the redis-socat process using:

supervisorctl start redis-socat 
supervisorctl stop redis-socat

It will also automatically start at boot time.

andrekeller
  • 499
  • 2
  • 5
  • I did end up using socat to achieve what I wanted, but I'm gonna leave the question open to see if there's a way it could be done at the firewall level. It seems like it should be possible! Thanks for your response. :} – Jimmy Feb 11 '15 at 04:35
  • I'd be interessted in a iptables solution as-well. Both given that loopback addresses are handled in a special way by the kernel, I could imagine there is no feasible way to do this. – andrekeller Feb 11 '15 at 13:06
  • Docker containers don't have access to iptables. If they did, something like http://unix.stackexchange.com/questions/111433/iptables-redirect-outside-requests-to-127-0-0-1 would work. – Eric Drechsel Sep 29 '15 at 23:27