Redirecting TCP-traffic to a UNIX domain socket under Linux - linux

Assume a legacy Linux application listening on a UNIX domain socket /tmp/foo.
In addition to communicating with this legacy application over the UNIX domain socket mechanism I want to be able to connect to it via a TCP-connection on port say 1234.
What is the easiest way to bind to TCP port 1234 and then redirect all incoming connections to the UNIX domain socket /tmp/foo?

Turns out socat can be used to achieve this:
socat TCP-LISTEN:1234,reuseaddr,fork UNIX-CLIENT:/tmp/foo
And with a bit of added security:
socat TCP-LISTEN:1234,bind=127.0.0.1,reuseaddr,fork,su=nobody,range=127.0.0.0/8 UNIX-CLIENT:/tmp/foo
These examples have been tested and work as expected.

Easiest? Probably Netcat (aka nc):
nc -l 1234 | nc -U /tmp/foo
The first command listens on port 1234 for incoming connections, and pipes the resulting data to the second command. The second connects to the Unix domain socket /tmp/foo, and writes its input to that socket. Note that this will only accept a single connection, and exit as soon as that connection is dropped. If you want to keep listening for more connections, use the -k option:
nc -lk 1234 | nc -U /tmp/foo
You can test that this is working by setting up a listener for that socket in one terminal:
nc -lUk /tmp/foo
And writing to it in another:
nc localhost 1234
socat, as recommended by knorv, is more capable, but more complicated to use.

You should be able to bind to TCP 1234, get a socket fd for /tmp/foo and use the select call to 'listen' for data on both 1234, and /tmp/foo. Any data written to 1234, you rewrite to /tmp/foo and vice-versa.
You now act as a proxy and transfer data back and forth.
And here is a web-page which might help: http://osr507doc.sco.com/en/netguide/dusockC.io_multiplexing.html

In additons to #knorv's answer: with xinetd it can work like a daemon
# cat /etc/xined.d/mysrv
service mysrv
{
disable = no
type = UNLISTED
socket_type = stream
protocol = tcp
wait = no
server = /usr/bin/socat
server_args = STDIN UNIX-CLIENT:/tmp/mysocket.sock
bind = 127.0.0.1
port = 1234
}

Not tried it : but it looks like 'lighttpd' can do this for you:
http://redmine.lighttpd.net/wiki/lighttpd/Docs:ModProxyCore

Related

Using netcat to pipe unix socket to tcp socket

I am trying to expose a unix socket as a tcp socket using this command:
nc -lkv 44444 | nc -Uv /var/run/docker.sock
When I try to access localhost:44444/containers/json from a browser, it doesn't load anything but keeps the connection open (the loading thingy keeps spinning), but the console (because of the -v flag) shows proper http response.
Any ideas on how to get this working?
PS: I know I can use socat, or just tell docker to also listen on a tcp socket, but I am using the project atomic vm image, and it won't let me modify anything except /home.
You are only redirecting incoming data, not outgoing data.
try with:
mkfifo myfifo
nc -lkv 44444 <myfifo | nc -Uv /var/run/docker.sock >myfifo
See http://en.wikipedia.org/wiki/Netcat#Proxying
Edit: in a script you would want to generate the name for the fifo at random, and remove it after opening it:
FIFONAME=`mktemp -u`
mkfifo $FIFONAME
nc -lkv 44444 < $FIFONAME | nc -Uv /var/run/docker.sock > $FIFONAME &
rm $FIFONAME
fg

Continuously send the content of a file through a server socket with netcat

I have a linux machine which is listening for connections on port 4450. Where there is an incomming connection, this is supposed to send continuously over the socket the content of a file. Did you do this before ?
What I've done so far was to send once the content of the file like this:
x=$(filename); echo $x | nc -l 4450
On the client side I have an Android app, which connects to the server and then using a BufferedReader gets the data from the stream and processes it.
Any help would be highly appreciated.
Thanks
Use socat instead of netcat (nc). With socat you can do almost everything that can be done with netcat. But socat has a lot more features and is easier to use.
socat TCP-LISTEN:4450,fork OPEN:/tmp/filename,rdonly
You can also use the output of a command instead of some file contents:
socat TCP-LISTEN:4450,fork EXEC:/bin/date

combine netcat with chat on bash for automatic udp responses

I want to combine "chat" and "nc" on linux, so I will create a tiny udp server that responds on a specific request and sends back an answer.
In fact I want to redirect the stdout of "nc" to the stdin of "chat" and vice versa. My first attempt was:
nc -w 3000 -u -n -l -p 30000 >&1111 <2222 &
chat -V 'request' 'answer' >&2222 <1111
But it didn't work.
use socat instead of netcat. Something like this :
socat UDP-LISTEN:5555 EXEC:"chat -sv ping pong",pty
To test it, you can open another terminal, and use socat to bridge stdio and an UDP socket :
socat - UDP:localhost:5555
Type ping, and you will get pong !

Simple Socket Server in Bash?

Is there a way to quickly bind to a TCP port/ip address and simply print out all information to STDOUT? I have a simple debugging solution which writes things to 127.0.0.1:4444 and I'd like to be able to simply bind up a port from bash and print everything that comes across. Is there an easy way to do this?
$ nc -k -l 4444 > filename.out
see nc(1)
Just because you asked how to do it in bash, though netcat answer is very valid:
$ exec 3<>/dev/tcp/127.0.0.1/4444
$ cat <&3
That is working as you expecting:
nc -k -l 4444 |bash
and then you
echo "ls" >/dev/tcp/127.0.0.1/4444
then you see the listing performed by bash.
[A Brief Security Warning]
Of course if you leave a thing like this running on your computer, you have a wide open gateway for all kinds of attacks because commands can be sent from any user account on any host in your network. This implements no security (authentication, identification) whatsoever and sends all transmitted commands unencrypted over the network, so it can very easily be abused.
Adding an answer using ncat that #Freedom_Ben alluded to:
ncat -k -l 127.0.0.1 4444
and explanation of options from man ncat:
-k, --keep-open Accept multiple connections in listen mode
-l, --listen Bind and listen for incoming connections

Best way to monitor for a server on a TCP port

I have a remote Music Player Daemon(MPD) server running on a linux machine. I have a client listening to this stream on another linux machine.
When the MPD server is asked to pause or stop the stream, it disconnects all clients connected on the TCP port. Consequently, when the server starts streaming again, the clients have to be manually reconnected.
I want to write a program that will monitor the TCP port for a server accepting connections, and then automatically restart the clients. Can I do better than running connect() and sleep() in a loop? Are there any command-line utilities to do this?
I can run the client on the machine running the MPD server, if it will help. The following will tell me if a process is listening on a local port, but they do not block if a process isn't, so I still need to wrap them in a loop.
$ sudo fuser -n tcp 8000
8000/tcp: 9677
$ sudo netstat -nlp | grep 8000
tcp 0 0 0.0.0.0:8000 0.0.0.0:* LISTEN 9677/mpd
I can try any solution that does not involve changing the behaviour of the MPD server.
There is always the possibility of writing a relay server that proxies for MPD.
It sits there listening on a different port for your clients and makes connections to MPD in their stead. When MPD disconnects, the relay just attempts to reconnect every few seconds without disconnecting its clients.
Here you go:
echo -n "" | nc -q 0 localhost 8000 && echo "made a connection" || echo "server was down"
echo -n "" puts an EOF immediately on stdin; nc -q 0 returns immediately after seeing that EOF on stdin. nc (netcat) tries to make a connection to localhost on port 8000. If it connects successfully, then it returns a successful error code and we echo "made a connection"; otherwise, if the connection was refused, we echo "server was down".
If you want to test it out, then in another terminal run
nc -lvvp 8000
which will start an instance of netcat listening on port 8000, with verbose output. In your other terminal, run the first command. The first time you run it, it will say made a connection. Then the server/listener will close, so the next time you run it, it will say server was down.

Resources