2

I have this small script for connecting to new machines I don't have ssh-key to:

function my_ssh () {
    ip=$1
    optional_cmd=$2

    ssh -o "BatchMode yes" user_name@$ip exit > /dev/null 2>&1

    if [ $? -gt 0 ]; then
        echo "1st time connection - adding key to authorized keys list"
        sshpass -p "secret_password" ssh-copy-id user_name@$ip
    fi

    echo $optional_cmd
    ssh -X user_name@$ip $optional_cmd
}

This works weel for servers that either have my ssh-key, or only ask for a password in order to use ssh-copy-id. However, some servers require a "yes/no" after the following question:

The authenticity of host 'A.B.C.D ()' can't be established. ECDSA key fingerprint is SHA256:****. Are you sure you want to continue connecting (yes/no)?

How can I add a "yes" string echoed into the server question stdin and then use the sshpass?

ps, I went over the sshpass code from github but it doesn't seem sshpass is designed for something like this. I think I can modify it to suite my needs, but I prefer using a normal Linux mechanism if possible

4 Answers4

1

To answer the OP's question about entering "yes" on the ECDSA key fingerprint prompt, and I would only advise this for localhost SSHds - never in anything more than an experimental docker container setup, you can do the following:

sshpass -p 'password' ssh \
  -o StrictHostKeyChecking=no \
  username@127.0.0.1 -p 2222 'whoami'

A use case? You could have a nobody user that is the only user who is allowed to password-SSH into a machine (all other users are set to require keys). You could then just get some system info you need, say, as you experiment with orchestration.

sshpass -p 'meminfo' ssh \
  -o StrictHostKeyChecking=no \
  meminfo@127.0.0.1 -p 2222 "egrep 'Mem|Cache|Swap' /proc/meminfo"

The result would be something like this.

Warning: Permanently added '[127.0.0.1]:2222' (ECDSA) to the list of known hosts.
SSHPASS searching for password prompt using match "assword"
meminfo@127.0.0.1's password: 
SSHPASS detected prompt. Sending password.
SSHPASS read:

MemTotal: 16369628 kB MemFree: 683412 kB MemAvailable: 8847748 kB Cached: 6544572 kB SwapCached: 460 kB SwapTotal: 2097148 kB SwapFree: 2071928 kB

Then you can nmap a cluster or Pis (or docker containers) on your LAN and then automate checking how they are doing without adding NodeJS or Python or a health API service.

If you're finished experimenting and want to clean up those rubber-stamped ECDSA fingerprints, you can run:

ssh-keygen -f "~/.ssh/known_hosts" -R "[127.0.0.1]:2222"

Warning: I must remind everyone that even the above with a nobody user can be dangerous if they find some privileged command that has the suid bit set - nobodys could still run as root!

Drakes
  • 269
0

I had the same problem, and solved it by ading this two lines:

UserKnownHostsFile=/dev/null
StrictHostKeyChecking=no

in /etc/ssh/ssh_config

seems like sshpass is actually reading that file instead of having an -o option

user40404
  • 316
  • 1
  • 3
  • 8
0

A safer way to do is add

Host *
        StrictHostKeyChecking accept-new

to ~/.ssh/config file.
The newer option accept-new in open-ssh client will accept new keys but will reject if the existing keys don't match. You can also use no however accept-new is a better way of doing it.

Shivam Anand
  • 143
  • 1
  • 4
-1

Workaround:

list.txt
vm1.example.com
vm2.example.com
vm3.example.com
...

for i in $(cat list.txt); do timeout 1 ssh -o StrictHostKeyChecking=no user@$i; done
for i in $(cat list.txt); do ssh-copy-id -i user@$i; done

ssh user@vm1.example.com -- no pass
karel
  • 122,292
  • 133
  • 301
  • 332
Lsn
  • 1