2

So I've got an SSH reverse tunnel open, and I'm using tail to pipe the output of the sshd log into awk to detect certain login events and trigger an action. It looks like this:

ssh -NR 2222:127.0.0.1:22 server &

tail -fn 0 /var/log/auth.log | \
awk '/Invalid user [a-z]+ from 127.0.0.1/ 
    {system("rsync -a source dest")}'

(To be clear, I'm initiating these failed logins from the server myself, on purpose, as a way to trigger rsync on the client machine, as suggested to me in this thread.)

What I'd like to do now is be able to suspend the whole detection process, so that I can make it ignore a given login attempt. My thinking is to do one of three things:

  1. Prevent ssh from producing the "Invalid user" message,
  2. Prevent tail from outputting it, or
  3. Prevent awk from seeing it.

I've tried suspending and then resuming all three processes, and here's what happens:

ssh: While the tunnel is suspended, the server waits indefinitely when trying to connect back to the client. If I specify a ConnectionTimeout option when connecting from the server, I can make the connection fail and get it to produce a different error message – success! – but I feel like this approach is asking for trouble with race conditions.

tail & awk: Input is accumulated while these programs are suspended, rather than ignored. Output is merely suppressed until the process is resumed.

is there any way to accomplish what I'm after?

Ryan Lue
  • 1,076

1 Answers1

2

You could suspend only awk and flush the pipe it's reading from under its feet before resuming it. On Linux-based systems and with GNU dd:

Where $pid is the PID of awk:

kill -s STOP "$pid"

to stop it and

dd iflag=nonblock if="/proc/$pid/fd/0" > /dev/null; kill -s CONT "$pid"

to resume.

That's assuming the pipe did not get full (64KiB by default on Linux), as otherwise, tail could have been blocked as well. To work around that you could flush the pipe with:

socat -T0.2 -u "/proc/$pid/fd/0" /dev/null

That would flush what's currently in the pipe and keep reading until there's no more coming for 0.2 seconds to allow tail to catch up with what it hasn't read from the file yet if any.