Establishing an SSH client and server with the asyncSSH and asyncio modules

Establishing an SSH client and server with the asyncSSH and asyncio modules

AsyncSSH and asyncio are Python modules that provide tools for asynchronous communication with SSH servers. They enable you to handle multiple SSH connections concurrently, improving performance and responsiveness in applications that require frequent communication with remote servers.

AsyncSSH:

AsyncSSH is an asynchronous SSH client library that provides a high-level interface for interacting with SSH servers using asynchronous programming techniques. It allows you to establish asynchronous connections, execute commands, transfer files, and manage SFTP sessions without blocking the main thread of execution.

Key Features of AsyncSSH:

  • Asynchronous SSH operations: Perform SSH operations, including connection establishment, command execution, and file transfers, in an asynchronous manner.
  • Improved performance: Handle multiple SSH connections concurrently, enhancing responsiveness and efficiency.
  • Non-blocking I/O: Utilize non-blocking I/O operations to avoid blocking the main thread and improve overall responsiveness.
  • Support for various SSH features: Supports a wide range of SSH features, including key-based authentication, port forwarding, and SFTP.

asyncio:

asyncio is a standard library in Python that provides a framework for asynchronous programming. It allows you to write concurrent code that utilizes event loops and callbacks to manage multiple tasks without blocking the main thread.

Benefits of Using AsyncSSH and asyncio:

  • Improved scalability: Asynchronous programming enables handling more concurrent connections and requests efficiently, enhancing scalability.
  • Reduced latency: Non-blocking I/O and event-driven programming minimize response times for SSH operations.
  • Resource utilization: Efficiently utilizes system resources by handling multiple tasks without blocking the main thread.
  • Simplified asynchronous development: The asyncio framework provides a structured approach to writing and managing asynchronous code.

Application Scenarios:

  • Network monitoring and management: Asynchronous SSH connections facilitate real-time monitoring and control of remote devices.
  • Automated file transfers: Asynchronous SFTP sessions enable efficient file transfers between local and remote systems.
  • Remote command execution: Asynchronous command execution allows concurrent tasks on remote servers without blocking the main application.
  • SSH tunneling for secure communication: Asynchronous SSH tunneling facilitates secure data exchange between networks asynchronously.

Integration with AsyncSSH and asyncio:

AsyncSSH integrates seamlessly with the asyncio framework, enabling you to leverage its asynchronous features and event loops for efficient SSH operations. You can define coroutines for SSH tasks, utilize asynchronous callbacks, and manage concurrent SSH connections within the asyncio event loop.

In summary, AsyncSSH and asyncio provide powerful tools for asynchronous SSH communication in Python. Their combination enables developers to build responsive and scalable applications that handle multiple SSH connections efficiently, improving performance and resource utilization.

Overview SSH client

This Python script utilizes the asyncssh library to establish an SSH (Secure Shell) connection to a remote server asynchronously. It then executes a specified command on the remote server and prints the output.

Importing Libraries

Python
import asyncssh
import asyncio
import getpass
  • asyncssh for asynchronous SSH functionality.
  • asyncio for managing asynchronous tasks.
  • getpass to securely input the password without displaying it on the screen.

Async Function: execute_command

Python
async def execute_command(host, command, username, password):
    async with asyncssh.connect(host, username=username, password=password) as connection:
        result = await connection.run(command)
        return result.stdout

  • Parameters:

    • host: Target SSH server hostname.
    • command: Command to be executed on the remote server.
    • username: SSH username.
    • password: SSH password.
  • Functionality:

    • Establishes an asynchronous SSH connection to the specified host using the provided credentials.
    • Executes the specified command on the remote server.
    • Returns the standard output (stdout) of the command.

    Main Block

    Python
    if __name__ == '__main__':
        hostname = input("Enter the target hostname: ")
        command = input("Enter command: ")
        username = input("Enter username: ")
        password = getpass.getpass(prompt="Enter password: ")
        loop = asyncio.get_event_loop()
        output_command = loop.run_until_complete(execute_command(hostname, command, username, password))
        print(output_command)
    • Execution:
    • If the script is executed as the main program:
      • Takes user input for the target hostname, command, username, and password.
      • Creates an event loop using asyncio.get_event_loop().
      • Calls the execute_command async function with the provided input values using loop.run_until_complete.
      • Prints the output of the executed command.

    Input Gathering

    • The script prompts the user to enter the target hostname, command, username, and password interactively using the input function.
    • The getpass.getpass function is used to securely input the password without displaying it on the screen.
    Python
    import asyncssh
    import asyncio
    import getpass
    
    async def execute_command(host, command, username, password):
        async with asyncssh.connect(host, username = username, password= password) as connection:
            result = await connection.run(command)
            return result.stdout
    
    if __name__ == '__main__':
        hostname = input("Enter the target hostname: ")
        command = input("Enter command: ")
        username = input("Enter username: ")
        password = getpass.getpass(prompt="Enter password: ")
        loop = asyncio.get_event_loop()
        output_command = loop.run_until_complete(execute_command(hostname, command, username, password))
        print(output_command)

    Note

    • This script is designed to work with Python 3.7 and later versions that support asynchronous features. It allows for non-blocking execution of the SSH connection and command execution, making it suitable for handling multiple concurrent operations.

    Overview SSH server

    This Python script uses the asyncssh library to create a simple asynchronous SSH server. The server listens for incoming SSH connections on localhost at port 22 and prints a message when a connection is established.

    Importing Libraries

    Python
    import asyncio
    import asyncssh
    import sys
    • asyncio for managing asynchronous tasks.
    • asyncssh for asynchronous SSH functionality.
    • sys for system-specific functionality.

    MySSHServer Class

    Python
    class MySSHServer(asyncssh.SSHServer):
        def connection_made(self, conn):
            print('SSH connection received from %s.' % conn.get_extra_info('peername')[0])
    • Class Overview:
      • Inherits from asyncssh.SSHServer.
      • Overrides the connection_made method, which is called when a new connection is established.
      • Prints a message with the IP address of the connecting client.

    Async Function: start_server

    Python
    async def start_server():
        await asyncssh.create_server(MySSHServer, 'localhost', 22,
                                     server_host_keys=['/etc/ssh/ssh_host_ecdsa_key'])
    • Functionality:
      • Creates an asynchronous SSH server using asyncssh.create_server.
      • Uses the MySSHServer class as the server implementation.
      • Listens on localhost at port 22.
      • Specifies the server host key file (/etc/ssh/ssh_host_ecdsa_key).

    Main Block

    Python
    loop = asyncio.get_event_loop()
    
    try:
        print("Starting SSH server on localhost:22")
        loop.run_until_complete(start_server())
    except (OSError, asyncssh.Error) as exc:
        sys.exit('Error starting server: ' + str(exc))
    
    loop.run_forever()
    • Execution:
      • Creates an event loop using asyncio.get_event_loop().
      • Attempts to start the SSH server using loop.run_until_complete(start_server()).
      • If there’s an error (e.g., OSError or asyncssh.Error), it exits with an error message.
      • Starts the event loop to run the server indefinitely using loop.run_forever().
    Python
    import asyncio, asyncssh, sys
    
    class MySSHServer(asyncssh.SSHServer):
        def connection_made(self, conn):
            print('SSH connection received from %s.' % conn.get_extra_info('peername')[0])
    
    async def start_server():
        await asyncssh.create_server(MySSHServer, 'localhost', 22,
                                     server_host_keys=['/etc/ssh/ssh_host_ecdsa_key'])
    
    loop = asyncio.get_event_loop()
    
    try:
        print("Starting SSH server on localhost:22")
        loop.run_until_complete(start_server())
    except (OSError, asyncssh.Error) as exc:
        sys.exit('Error starting server: ' + str(exc))
    
    loop.run_forever()

    Note

    • This script is a basic example and may need additional configuration, security measures, and error handling for a production environment.
    • It assumes the existence of an ECDSA host key file at the specified path (/etc/ssh/ssh_host_ecdsa_key). Ensure that the file exists or update the path accordingly.
    • Make sure to handle authentication, authorization, and other security aspects based on your specific requirements.
    Total
    3
    Shares

    Leave a Reply

    Previous Post
    Using Paramiko to brute-force SSH user credentials

    Establishing an SSH connection with pysftp in python

    Next Post
    Checking the security of SSH servers with ssh-audit tool in python

    Checking the security of SSH servers with ssh-audit tool in python

    Related Posts