Max Allan
Max Allan

Reputation: 959

netcat to return the result of a command (run when connection happens)

I want to use netcat to return the result of a command on a server. BUT here is the trick, I want the command to run when the connection is made. Not when I start the netcat.

Here is a simplified single shell example. I want the ls to run when I connect to 1234 (which I would normally do from a remote server, obviously this example is pointless I could do an ls locally)

max $ ls | nc -l 1234 &
[1] 36685
max $ touch file
max $ nc 0 1234
[1]+  Done                    ls | nc -l 1234
max $ ls | nc -l 1234 &
[1] 36699
max $ rm file
max $ nc 0 1234
file
[1]+  Done                    ls | nc -l 1234

You can see the ls runs when I start the listener, not when I connect to it. So in the first instance I had no file when I started it and created the file, then made the connection and it reported the state of the filesystem when the listen command started (empty), not the current state. And the second time around when file was already gone it showed it as still present.

Something similar to the way it works when you redirect from a file. eg:

max $ touch file
max $ nc -l 1234 < file &
[1] 36768
max $ echo content > file
max $ nc 0 1234
content
[1]+  Done                    nc -l 1234 < file

The remote connection gets the latest content of the file, not the content when the listen command started.

I tried using the "file redirect" style with a subshell and that doesn't work either.

max $ nc -l 1234 < <(cat file) &
[1] 36791
max $ echo bar > file
max $ nc 0 1234
content
[1]+  Done                    nc -l 1234 < <(cat file)

The only thing I can think of is adding my command |netcat to xinetd.conf/systemd... I was probably going to have to add it to systemd as a service anyway.

(Actual thing I want to do : provide the list of users of the VPN to a network port for a remote service to get a current user list. My command to generate the list looks like :

awk '/Bytes/,/ROUTING/' /etc/openvpn/openvpn-status.log | cut -f1 -d. | tail -n +2 | tac | tail -n +2 | sort -b | join -o 2.2 -j1 - <(sort -k1b,1 /etc/openvpn/generate-new-certs.sh)

)

Upvotes: 1

Views: 1648

Answers (1)

Mark Setchell
Mark Setchell

Reputation: 207818

I think you want something like this, which I actually did with socat:

# Listen on port 65500 and exec '/bin/date' when a connection is received
socat -d -d -d TCP-LISTEN:65500 EXEC:/bin/date

Then in another Terminal, a few seconds later:

echo Hi | nc localhost 65500

Note: For macOS users, you can install socat with homebrew using:

brew install socat

Upvotes: 1

Related Questions