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.

  • 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. 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. Sep 1 '19 at 17:31

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.
    – user147505
    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. 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. Sep 1 '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 2 '19 at 18:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.