3

What I am trying to do (in bash) is:

for i in <host1> <host2> ... <hostN>; do ssh leroy@$i "sudo -i; grep Jan\ 15 /var/log/auth.log" > $i;done

to get just today's entries from these hosts auth.logs and aggregate them on my local filesystem. sudo is required because auth.log only allows root access. Using the root user isn't an option because that account is disabled. Using key-based authentication isn't an option because the systems implement 2FA (key and password).

When I do the above (after initial authentication) I get

sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper

I have tried various parameters to the -S option and included the -M option, nothing works. Searching the web doesn't surface anything with this exact situation.

ilkkachu
  • 138,973

2 Answers2

3

Further research surfaced the sudo -S option which worked with some significant caveats. Below is what I used:

for host in ...; do
    read -p "Password for $host sudo:" pswd; 
    ssh leroy@$host "echo $pswd | sudo -S grep ^Jan\ 15 /var/log/{auth.log,auth.log.1,syslog,syslog.1}" > $host;
done

Caveats:

The prompts can be confusing which is why a very clear prompt for "read" is needed. The remote system's prompt for a password needs to be responded to. The sudo prompt for a password appears on the local system but is answered by the echo. If the command passed to sudo runs for a time (note I added syslog which, in some cases, caused the grep to process for a number of seconds) it appears that sudo is waiting for a reply when in fact the command is processing.

Second, the password is displayed on the local system, not great but in my case I was at home so it wasn't an issue

Third, the final password remains in the environment, in retrospect an unset pswd should have been added.

Any suggested enhancements or alternatives are appreciated.

ilkkachu
  • 138,973
  • You can use sudo -p to set the prompt, e.g. sudo -p "" would make it empty (but it might still print the newline), or you could use something like sudo -p "sudo password for host $host: ". If you have the whole thingy in a script, you don't need to unset pswd, it'll be gone when the shell exits (barring issues like someone dumping the whole system memory on the kernel or hardware level, and finding an uncleared temporary value somewhere). The echo issue is why I suggested stty -echo, but with Bash's read, you could also use read -s (s for "secret", I guess) – ilkkachu Jan 16 '22 at 09:55
  • Excellent points, thanks. – Senior Geek Jan 21 '22 at 02:57
2

With ssh ... 'sudo -S ...', without the -t, sudo would ask for the password from stdin, but couldn't disable the terminal echo for the password prompt.

ssh doesn't set up a terminal on the remote by default if it's given a command to run. That's what sudo complains about. You could use the -t option have it do that... But as mentioned in the comments, that would break the output redirection, and the password prompt will go to the output file. You could remove the prompt afterwards, but you'd need to know to enter the password without seeing the prompt and you couldn't know if something went wrong before entering the password...

So, a workaround might be to use sudo -S after all, just disable echo on the local side for the duration of the session. That should be ok if you don't need to enter any other input than the password.

Also, sudo -i; grep ... won't work, it'll run an interactive sudo'ed shell, and then run grep after that shell exits. So run sudo grep instead.

So, perhaps something like this:

for host in ...; do
    stty -echo
    ssh leroy@"$host" 'sudo -S grep "Jan 15" /var/log/auth.log' > "$host"
    stty echo
done
ilkkachu
  • 138,973
  • Note with ssh -t one loses the ability to locally tell apart stdout, stderr and /dev/tty of the remote command. In other words: whatever the remote command prints to the terminal it is given (no matter if it prints to stdout, stderr or /dev/tty) will be locally printed by ssh to its stdout. Specifically in this case the prompt for password from the remote sudo will be redirected to the local file! This is elaborated (and solved) here: ssh with separate stdin, stdout, stderr AND tty. – Kamil Maciorowski Jan 15 '22 at 20:59
  • @KamilMaciorowski, right, of course I didn't test it with the output redirected... Ok, back to sudo -S... – ilkkachu Jan 15 '22 at 22:04
  • @KamilMaciorowski, thanks, that is a long and involved reference which I'll take some time to digest. – Senior Geek Jan 16 '22 at 05:57