0

I have a Linux based router that I’m trying to “control” with a home automation controller. On my automation controller I’m able to utilize a ‘two way strings’ driver to send a string to the Linux router upon the push of a button on the remote control. I’m wanting the string sent to be executed on the router.

I’m able to accomplish this by running the commands below while ssh’d into the router:

$ rm -f /tmp/f; mkfifo /tmp/f
$ cat /tmp/f | /bin/sh -i 2>&1 | nc -l 127.0.0.1 1234 > /tmp/f

As long as I keep the terminal window open the automation controller is able to send strings that alter the iptables.

The problem I’m running into is that this does not persist after I close the ssh connection. Is there a way to have the router continue to listen and execute commands from the controller after ssh connection is closed?

Here is an example of the string I’m sending:

iptables%20-I%20INPUT%20-s%20192.168.1.214%20-j%20DROP%0A

Basically my end goal is to be able to drop traffic to a particular device on the network at the push of a button.

Security is not a concern as this is a home lab environment.

3
  • Why is the string you send percent-encoded? bash won't understand it. Commented Dec 30, 2018 at 18:09
  • 1
    This feels like a X-Y-Question. Any reason you cannot use ssh on the push-button client-side? Commented Dec 30, 2018 at 18:10
  • using the %20 was the only way I could get the string to be executed. The automation controller I'm using does not have ssh capabilities - it is a closed system. I'm only able to send strings using the controller. Commented Dec 30, 2018 at 18:49

2 Answers 2

2

You want to use nohup for letting your commands run even after the ssh connection is closed (the remote operator hangs up the phone). The procedure is the same as in this answer:

nohup sh -c 'rm -f /tmp/f ; mkfifo /tmp/f && cat /tmp/f | /bin/sh -i 2>&1 | nc -l 127.0.0.1 1234 > /tmp/f'
6
  • This does not work. I get the following output when issuing the above command and the strings from the automation controller do not get executed. [root @ untangle] /tmp # nohup sh -c 'rm -f /tmp/f ; mkfifo /tmp/f && cat /tmp/f | /bin/sh -i 2>&1 | nc -l 192.168.1.1 > /tmp/f' nohup: ignoring input and appending output to 'nohup.out' Commented Dec 30, 2018 at 17:51
  • Also, sorry for the formatting in the above reply. I'm unable to get linebreaks to work properly, I entered two spaces where I want the linebreaks to happen but it didn't work. I'm new to commenting on this forum so I must be missing something obvious. Commented Dec 30, 2018 at 17:54
  • @RaaGee The message is informative, not an error. If the message annoys you, you can redirect nohup's output explicitly: nohup sh -c 'rm -f /tmp/f ; mkfifo /tmp/f && cat /tmp/f | /bin/sh -i 2>&1 | nc -l 127.0.0.1 1234 > /tmp/f' 1>/tmp/f.out 2>/tmp/f.err Commented Dec 30, 2018 at 18:07
  • thanks for the info. The message is not necessarily a problem to me but the command does not allow the strings to be executed so in that regard does not acoomplish what I'm wanting. Commented Dec 30, 2018 at 18:52
  • How about nohup socat tcp-listen:1234,reuseaddr,fork EXEC:bash on the router then? Works with commands sent via something like echo 'iptables -I INPUT -s 192.168.1.214 -j DROP' | netcat localhost 1234. Commented Dec 30, 2018 at 19:10
1

You can use screen to do this.

https://www.gnu.org/software/screen/

The steps are:

  1. Open ssh session as normal.
  2. Install screen. (If not already installed)
  3. start a new screen session. (Just type screen and press enter)
  4. Run your command as you have it
  5. Type in ctrl + 'a' and then release both ctrl and a, and press 'd' to disconnect the screen session.

The session stays running in the background. Even if you log out and close out the ssh session completely.

If you're using an enterprise linux such as centos, you can use yum to install screen from the distribution's package repository.

yum -y install screen

If you're using a debian based OS try using:

apt-get install screen

Once installed start a new screen session by just typing screen.

[user@localhost ~]$ screen

Note: This will clear the screen and start a new session.

Run your command:

[user@localhost ~]$ rm -f /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/sh -i 2>&1 | nc -l 127.0.0.1 1234 > /tmp/f

Detach the screen session:

ctrl +a, d

[detached]

You can verify that your process is still running with netstat. If your OS supports it, you can use the -p flag to show the running process ID.

-p, --program Show the PID and name of the program to which each socket belongs.

[user@localhost ~]$ netstat -anp | grep 1234
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp        0      0 127.0.0.1:1234              0.0.0.0:*                   LISTEN      30599/nc

And you can use ps to show that the process is still running:

[user@localhost~]$ ps -ef | grep [3]1037
500      31037 31019  0 21:45 pts/2    00:00:00 nc -l 127.0.0.1 1234

Note: placing square braces '[]' around the first number of the pid, is a little regex trick to avoid showing the grep process itself. Essentially a false match, and not your actual process.

You can show the detached screen session with screen -ls

[user@localhost~]$ screen -ls
There is a screen on:
        30562.pts-0.localhost  (Detached)
1 Socket in /var/run/screen/S-user.

And you can re-attach to it with screen -r, or screen -x and the session name

[user@localhost ~]$ screen -x 30562.pts-0.localhost
1
  • disown -a && exit will also let you close out the terminal. disown is a bash shell built in. Commented Apr 23, 2019 at 5:42

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.