It would be very nice to read this question thoroughly before marking it as duplicate. I have read dozens of other questions (here, at superuser.com, serverfault.com and so on), all dealing with SSH not finding /dev/tty, but none of them with relation to
keychain, which actually should prevent this problem.
Having said this:
I have a Linux (Debian stretch) router which is connected to the Internet via
pppoe. My provider gives me a dynamic IP address which changes from time to time. Whenever this happens, the router should run a script on another host via SSH.
I have correctly set up SSH on the router and the other host, using public key authentication. The SSH keys are protected by a passphrase.
Furthermore, I have set up
keychain as advised here. According to my understanding of this page (and others),
keychain "provides" the same
ssh-agent process to any SSH client; when I am logging in, it starts
ssh-agent (if none is running yet) and asks (or makes ssh ask) for the passphrase(s); from then on, the SSH keys are in
ssh-agent's memory and readily available to other processes.
This works with the following exception:
I have put a script into
/etc/ppp/ip-up.d; that script contains (among others) the following lines:
eval `/usr/bin/keychain --noask --agents ssh --eval id_rsa_ipupdate` ssh -i /root/.ssh/id_rsa_ipupdate firstname.lastname@example.org '/path/to/remote/command'
Although the script itself gets executed as expected every time the provider assigns a new IP address, the SSH command fails, i.e. the script on the remote host doesn't get executed. It took me a while to debug this, but after making
pppd log its debug messages in a separate file, I finally found the reason. Some relevant lines from pppd's debug messages:
debug1: Server accepts key: pkalg ssh-rsa blen 535 debug2: input_userauth_pk_ok: fp SHA256:BZSkP9mMIB+cCi5WfgYnqT2QmskTgsKHsWuNXHxIQu0 debug3: sign_and_send_pubkey: RSA SHA256:BZSkP9mMIB+cCi5WfgYnqT2QmskTgsKHsWuNXHxIQu0 debug1: read_passphrase: can't open /dev/tty: No such device or address debug2: no passphrase given, try next key debug2: we did not send a packet, disable method debug1: No more authentication methods to try. Permission denied (publickey).
So SSH does not find /dev/tty, which is probably normal, given that it is executed from within
pppd in this case and thus can't read the passphrase from the keyboard. So far, so good.
But the key point is: Why does SSH (obviously) want to read the passphrase from the keyboard although an
ssh-agent is running, managed by
keychain and having the key readily available?
Please note the first line in the script snippet above. It should make sure that
SSH_AGENT_PID are set and exported correctly.
Please note also that the script works perfectly (without asking for a passphrase) when I run it from the command line.
To make things absolutely clear: I first log in into the router. As I have set up
keychain as advised on its homepage, I am immediately asked for the passphrase(s) when logging in. When then calling my script from the command line, it works as expected without asking for the passphrase. But when the script is called by
pppd, the SSH line fails.
Could anybody please explain why SSH wants /dev/tty although it could load the keys from ssh-agent, and how to get around that problem?
P.S. Yes, I can live with the fact that the script will inevitably fail after the router has rebooted, until I log in at least once :-)
I have done further research and noticed the following: The line
eval `/usr/bin/keychain --noask --agents ssh --eval id_rsa_ipupdate`
from the script above definitely creates a second
ssh-agent process when the script is executed by
pppd due to a change of the public IP address. That means that
keychain does not find the first one (which has the SSH keys available) for some weird reason.
Again, this only happens when the script is executed by
pppd; when I call the script from the command line, everything is fine.
I am now thinking about opening a bug report or something like that. By the way, my
keychain version is