I completely agree with everybody who says this is almost certainly a very bad idea. However, if you've evaluated your needs and want to know how it is done, it is certainly possible without using keys and without installing any other programs, just using Bourne Shell mechanisms.
USE AT YOUR OWN RISK AFTER EVALUATING THE SECURITY HAZARDS
Answer
Make a program /path/to/saypass
which outputs the password, such as this minimal script:
#!/bin/sh
echo 'secret'
Make it executable with
chmod +x /path/to/saypass
Then this is the main command:
SSH_ASKPASS="/path/to/saypass" DISPLAY=anything setsid ssh username@hostname [farcommand]
In brief, this runs ssh
in a special way which uses your saypass
program to get the password. (/path/to
must be replaced with the path to your script; anything
is can be literally this string; replace username@hostname
by your details.)
In detail:
- sets the two environment variables
SSH_ASKPASS
and DISPLAY
- and then runs
setsid
- which then runs
ssh
without a controlling terminal
- which connects to the far
hostname
- ... runs
saypass
locally to get the password
- ... tells it to the far server
- ... and assuming it's correct
- which then runs
farcommand
(if given), or an interactive shell.
I normally test with date
or hostname
for the optional farcommand
.
There are lots of places for this to go wrong.
Explanation
The trick to this is that standard Linux command line ssh
has a couple of environment variables you can use to choose a program which gets executed to supply the password. This is designed to be used with an X11 user interface, but can be used for our purpose.
The ssh(1)
manual page says:
SSH_ASKPASS
If ssh
needs a passphrase, it will read the passphrase from the current terminal if it was run from a terminal. If ssh
does not have a terminal associated with it but DISPLAY
and SSH_ASKPASS
are set, it will execute the program specified by SSH_ASKPASS
and open an X11 window to read the passphrase.
So: you need a program (shell script or any other kind) which will output the password. Then you need to convince ssh
to use it:
- With
SSH_ASKPASS
set to /path/to/saypass
- With
DISPLAY
set to something silly
- With no controlling terminal (this is what
setsid
does)
Which you put together in the following sh
command:
SSH_ASKPASS="/path/to/saypass" DISPLAY=anything setsid ssh username@hostname [command]
ssh
will execute one of these two commands:
/path/to/saypass "Password:"
/path/to/saypass "username@hostname's password:"
Fingerprint check
If the fingerprint is needed, where you'd normally see the message
The authenticity of host '*hostname* (*ipaddress*)' can't be established.
ECDSA key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
Are you sure you want to continue connecting (yes/no)?
Then ssh
will run your command like this:
/path/to/saypass "Please type 'yes' or 'no':"
All-in-one script
The following is a single script for creating, using, and removing a saypass
within the main script. Everyone will tell you do not put plaintext passwords in files and also never hardcode a password. They tell you this for good reason: it will cause you a lot of trouble. Use at your own risk.
#!/bin/sh
echo "#!/bin/sh\necho 'secret';rm -f /tmp/saypass.$$" > /tmp/saypass.$$
chmod 775 /tmp/saypass.$$
SSH_ASKPASS="/tmp/saypass.$$" DISPLAY=anything setsid ssh "$@"
SCP
This also works for scp
, the copy program on top of ssh
:
SSH_ASKPASS=/path/to/saypas DISPLAY=anything setsid scp username@hostname:/path/to/farfile .
Caveat
Really don't use this except in dire, dire, circumstances, such as where you have hundreds of computers and you can't install anything like ssh keys, sshpass
even expect
.
If you have to use this technique, put your passwords in a file and make saypass
get it from there. Make saypass
as secure as you're able; you can pass information into it through the environment.
I don't know what the man page means about "open an X11 window", no such thing happens in my testing.
Tested on
- OpenSSH_6.6.1p1 Ubuntu-2ubuntu2, OpenSSL 1.0.1f 6 Jan 2014 on Ubuntu 14.04.1 LTS,
- OpenSSH_7.2p2 Ubuntu-4ubuntu2.1, OpenSSL 1.0.2g 1 Mar 2016 on Ubuntu 16.04.2 LTS
- OpenSSH_7.6p1 Ubuntu-4ubuntu0.3, OpenSSL 1.0.2n 7 Dec 2017 on Ubuntu 18.04.5 LTS