Search code examples
pythonsshpexpect

python pexpect login: remote host identification has changed


I Have made a script with pexpect where i can login with ssh, but sometimes on some servers i'm getting:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that the RSA host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
3d:1b:02:9e:b2:b8:f0:f7:c6:4f:94:96:f6:e3:c0:d1.
Please contact your system administrator.
Add correct host key in /root/.ssh/known_hosts to get rid of this message.
Offending key in /root/.ssh/known_hosts:8
RSA host key for 10.10.10.69 has changed and you have requested strict checking.Host key verification failed.

and the script brakes.

I know that is possible to pass this warning using:

os.system('ssh-keygen -f "/home/alex/.ssh/known_hosts" -R %s' % (ip))

This is my code:

from pexpect import pxssh

try:
    s = pxssh.pxssh()
    s.login(ip, user, password)

How can i get the output from login to check if the output contains WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED so that i can use the above command.


Solution

  • From the pexpect docs:

    The pattern given to expect() may be a regular expression or it may also be a list of regular expressions. This allows you to match multiple optional responses. The expect() method returns the index of the pattern that was matched.

    So, you can do something like:

    pattern_index = server.expect(["WARNING:", "Normal response"])
    
    if pattern_index == 0:
        #handle the warning message
    else:
        server.sendline(....)
        server.expect(....)