Nowadays I’m working a lot with Docker containers and sometimes I was asked to allow someone access the database in production. But how to do it easy and fast?
Due security reasons the database in production has bind only for localhost so it is not possible to connect directly from my machine.
- allow remote connection
- only specific IPs could have access to it
- easy to enable or disable it
And I achieved it using socat \o/
What is socat?
Socat allow establish two bidirectional byte streams and transfers data between them. It has support for many channels type (e.g. file, serial line, socket Unix, TCP) and can be used, e.g., as TCP port forwarder or for redirecting TCP oriented programs to a serial line.
Forwarding port 15432 to socket
socat -d -d TCP4-LISTEN:15432,fork UNIX-CONNECT:/srv/mongodb-27017.sock
-d -d: prints fatal, error, warning, and notice messages
TCP4-LISTEN: Listens on <port>, accepts a TCP/IP connection and only supports IPv4 protocol
fork: forks a new child process for each connection
UNIX_CONNECT: connects to filename assuming it is a UNIX domain socket
With that command running in the server then you can connect there from your local machine.
Was missing only allow specific IPs use this proxy. Also the main ideas was to be easy enable the proxy. Therefore I created this script below:
if [ $# != 2 ]; then
echo "usage: $0 <public-port> <path-private-socket>"
echo "example: $0 15432 /srv/my-service.sock"
echo "--> socat forwarding:\n\t- from port: $PUBLIC_PORT\n\t- to socket: $PRIVATE_SOCKET"
echo "--> allowed ips:\n\t$(cat socat-allow)"
echo "--> logs: $SOCAT_LOG"
socat -d -d -lf $SOCAT_LOG \
./forward-port-to-socket.sh 15432 /srv/mongodb-27017.sock
lf: writes messages to logfile
reuseaddr: allows immediate restart of the server process
tcpwrap: uses Wietse Venema's libwrap (tcpd) library to determine if the client is allowed to connect
allow-table: takes the specified file instead of /etc/hosts.allow
deny-table: takes the specified file instead of /etc/hosts.deny