4

I would like to run a bash command when a remote connection is successfully established to a specified local open port. I have looked into netcat and socat, but I'm not sure if either have the functionality that I want. I do not care about the content of the communication, only that a connection has been established (the connection can be immediately dropped after starting).

This is because, I have a local resource (a Minecraft server) that I want to start only when requested. In theory, a client should attempt a connection (which will of course fail, initially), the server will then start, and after a few moments the client can connect once more to a running server.

roaima
  • 107,089
  • 14
  • 139
  • 261
sgbrown
  • 303
  • 1
  • 3
  • 11
  • 1
    portknocking works like that: a service is started (or some firewall rules are changed) only after a specific packet is sent to a specific port (and sometimes with specific content). You may get ideas from such features. – Patrick Mevzek Jun 11 '19 at 23:00
  • You could use `netcat` with the `-l` option to listen to a port (and `-k` if you want netcat to remain open for the next connection, although I don't think (my version of) netcat can do parallel connections). I think you can also do it with `socat`, or with `tcpserver`. `socat` has more complicated arguments, so I ended up using `tcpserver`. IIRC I got `tcpserver` (along with other stuff) using `sudo apt-get install ucspi-tcp`. – David Knipe Sep 01 '19 at 17:31

1 Answers1

2

There's the -F option to nc:

-F Pass the first connected socket using sendmsg(2) to stdout and exit. This is useful in conjunction with -X to have nc perform connection setup with a proxy but then leave the rest of the connection to another program (e.g. ssh(1) using the ssh_config(5) ProxyUseFdpass option).

I guess you could use it along this line:

nc -Fl 22222 | true && echo connection arrived

Of course you'd start the server instead of echoing. 22222 is the port and l stands for listening.

  • I'm not sure what's going on, but I actually don't have that functionality on my netcat version. On the man-page, the flags of my version go straight from `-d` to `-h`! From a quick Google search, it looks like the NetBSD version of netcat has that flag, do you have any idea how I can get it onto my system? I'm currently running Ubuntu 16.04.6 LTS – sgbrown Jun 11 '19 at 23:25
  • 1
    @sgbrown It looks like I have a BSD version on Debian. Depending on your OS, you could just install it, or probably download the source code, compile it and then install. –  Jun 11 '19 at 23:30
  • "I guess you could use it along this line..." I guessed that too, but it didn't work for me. `-F` seems to have no effect: I get a netcat process which I can connect to by running another netcat command. I'm on Ubuntu; `nc -h` gives me `OpenBSD netcat (Debian patchlevel 1.187-1ubuntu0.1)` as the version. And my manpage does have the text quoted above about `-F`. – David Knipe Aug 21 '19 at 23:07
  • Update: When I run `-F` without `-l`, it tries to do something interesting, but fails. I think `-F` is not intended for general purpose, it was only invented for one particular use case involving ssh. Also it uses `sendmsg`, and I don't know how to work with that. – David Knipe Sep 01 '19 at 17:35
  • After a bunch of tinkering, I ended up just using `nc -l $port >> $touch_file 2>/home/***/logs/nc_errors.log &` to create a listening nc process in the background that fed data into a file that was previously `touch`'d, and then a blocking `inotifywait` command was used to monitor modifications, creations, and openings of the file. The next line of the script assumed that a connection was received, so it killed the nc process (using `pid=$!` right after creation and `kill $pid` after the `inotifywait` command), and then continued the script to be run upon some connection. – sgbrown Sep 02 '19 at 18:27