pythonsshexceptionparamiko

How can I verify that an SSH connection is possible without login information?


I'm trying to write a python2.7 function that can tell whether or not a specific IP address (host) can be connected to using SSH protocol. The problem is I have to do it without having the login information of the device I'm connecting to. My plan is to attempt to connect with an empty string as the username and password, then use the exception it throws to determine if it could be connected to or not. My reasoning is that if it throws an AuthenticationException for example, it must have attempted to connect but simply determined the login information to be invalid. This is my code so far:

def ssh(host):
try:
    s = paramiko.SSHClient()
    s.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    s.connect(host, username=None, password=None)

except(paramiko.ssh_exception.AuthenticationException,
       paramiko.ssh_exception.BadAuthenticationType,
       paramiko.ssh_exception.BadHostKeyException,
      paramiko.ssh_exception.PasswordRequiredException,
      paramiko.ssh_exception.PartialAuthentication):
    return True

except Exception as e:
    print(e)
    return False

When I run this, it always returns false and outputs: No authentication methods available

My questions are:

  1. Is this a feasible strategy to accomplish what I want?
  2. Which exceptions are caused by bad credentials and which are caused by more serious issues that would prevent a connection even with the right credentials?
  3. Which function is printing to the console and how do I stop it? I'd like to handle error messages on my own.

Thanks in advance!


Solution

  • Just try to connect on the destination port:

    import socket
    
    def check_ssh(server_ip, port=22):
        try:
            test_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            test_socket.connect((server_ip, port))
        except Exception as ex:
            # not up, log reason from ex if wanted
            return False
        else:
            test_socket.close()
        return True