The task is as follows: execute the ssh -p 2356 root@192.168.43.98 echo OK , so that the ssh -p 2356 root@192.168.43.98 echo OK in ~ / .ssh.

since I connect for the first time, a notification should pop up:

The authenticity of host '[192.168.43.98]: 2356 ([192.168.43.98]: 2356)' can't be established. ECDSA key fingerprint is SHA256: c1zdKx4q0dVTg7WjhslTmYbXm2D4dX37me9u0Mm6B6A. Are you sure you want to continue connecting (yes / no)?

after which I have to enter "yes", and get known_hosts.

I try to organize it through subprocess on python:

 import subprocess,time args = 'ssh -p 2356 root@192.168.43.98 echo OK'.split() go = subprocess.Popen(args,stdin=subprocess.PIPE,universal_newlines=True) time.sleep(1) go.stdin.write('yes\n') 

however, an error creeps in:

ssh_askpass: exec (/ usr / bin / ssh-askpass): Host key verification failed.

When I write it with my hands all the rules, and through the subprocess it asks for some kind of ssh-askpass. You do not need to enter a password, I just want to get prints. What did I do wrong, and how to fix it?

    2 answers 2

    Try using Paramiko, and view construction.

     client = paramiko.SSHClient() # данная строчка решает проблему с known_hosts client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(hostname='your_host', username='user', password='secret', port=2356) stdin, stdout, stderr = client.exec_command('ls -l') data = stdout.read() + stderr.read() client.close() 
    • Known_hosts did not appear, although the connection of norms passed - Andrey Yurevich
    • @AndreyYurevich: to save keys to a file, call client.load_host_keys(os.path.expanduser('~/.ssh/known_hosts')) before client.connect() . It is worth noting that, just like the ssh -o StrictHostKeyChecking=no command, connecting with paramiko.AutoAddPolicy() subject to a MITM attack. - jfs

    ssh in this case does not use its standard input ( stdin ), but waits for input directly from the terminal ( tty ). See the first reason in Q: Why not just use a pipe (popen ())?

    pty module allows you to pass such input, for example, using the pexpect module :

     output, rc = pexpect.run('ssh ... echo OK', events={b'\(yes/no\)\?': b'yes\r\n'}, withexitstatus=1, timeout=1) 

    If ssh would accept standard input here, it would be possible to write:

     p = subprocess.run(['command', 'arg 1', 'arg 2'], input=b'yes\n', timeout=1) 

    Unlike your option, it is guaranteed to flush the internal buffer and close our end of the pipe connected to the standard input of the child process.


    It is worth mentioning that if the task is to replenish the known_hosts file, it is not necessary to call ssh -o StrictHostKeyChecking=no for each node. You can call ssh-keyscan instead to get fingerprints for several nodes at once. As well as ssh (at the first connection) it is subject to MITM attack, if you do not check the validity of the corresponding keys.