Operations 10 min read

Using Paramiko for SSH Connections, Remote Command Execution, and File Transfer in Python

This tutorial demonstrates how to install Paramiko, establish SSH connections, execute remote commands, upload and download files via SFTP, and close connections, while also covering advanced topics such as key‑based authentication, channel operations, interactive sessions, concurrent commands, jump hosts, proxy commands, and proxy servers.

Test Development Learning Exchange
Test Development Learning Exchange
Test Development Learning Exchange
Using Paramiko for SSH Connections, Remote Command Execution, and File Transfer in Python

1. Install Paramiko – Ensure Paramiko is installed using pip install paramiko .

2. Establish SSH Connection – Create an SSH client, set the missing‑host‑key policy, and connect to the remote server:

import paramiko
def ssh_connect(hostname, port, username, password):
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(hostname, port, username, password)
    return ssh

if __name__ == "__main__":
    hostname = 'example.com'
    port = 22
    username = 'your_username'
    password = 'your_password'
    ssh = ssh_connect(hostname, port, username, password)
    if ssh:
        print("Connected successfully.")

3. Execute Remote Command – Run a command on the remote host and capture output and errors:

def execute_command(ssh, command):
    stdin, stdout, stderr = ssh.exec_command(command)
    output = stdout.read().decode()
    errors = stderr.read().decode()
    return output, errors

if __name__ == "__main__":
    command = 'ls -l'
    output, errors = execute_command(ssh, command)
    if output:
        print("Output:")
        print(output)
    if errors:
        print("Errors:")
        print(errors)

4. Upload File via SFTP – Open an SFTP client, transfer a local file to the remote path, and close the client:

def upload_file(ssh, local_path, remote_path):
    sftp = ssh.open_sftp()
    sftp.put(local_path, remote_path)
    sftp.close()

if __name__ == "__main__":
    local_path = '/path/to/local/file'
    remote_path = '/path/to/remote/file'
    upload_file(ssh, local_path, remote_path)
    print("File uploaded successfully.")

5. Download File via SFTP – Retrieve a remote file to a local destination:

def download_file(ssh, remote_path, local_path):
    sftp = ssh.open_sftp()
    sftp.get(remote_path, local_path)
    sftp.close()

if __name__ == "__main__":
    remote_path = '/path/to/remote/file'
    local_path = '/path/to/local/file'
    download_file(ssh, remote_path, local_path)
    print("File downloaded successfully.")

6. Close SSH Connection – Properly close the SSH client:

def close_ssh_connection(ssh):
    ssh.close()

if __name__ == "__main__":
    close_ssh_connection(ssh)
    print("Connection closed.")

Complete Example – Combines all steps into a single script that connects, runs a command, uploads and downloads files, and then closes the connection.

import paramiko

def ssh_connect(hostname, port, username, password):
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(hostname, port, username, password)
    return ssh

def execute_command(ssh, command):
    stdin, stdout, stderr = ssh.exec_command(command)
    output = stdout.read().decode()
    errors = stderr.read().decode()
    return output, errors

def upload_file(ssh, local_path, remote_path):
    sftp = ssh.open_sftp()
    sftp.put(local_path, remote_path)
    sftp.close()

def download_file(ssh, remote_path, local_path):
    sftp = ssh.open_sftp()
    sftp.get(remote_path, local_path)
    sftp.close()

def close_ssh_connection(ssh):
    ssh.close()

if __name__ == "__main__":
    hostname = 'example.com'
    port = 22
    username = 'your_username'
    password = 'your_password'
    ssh = ssh_connect(hostname, port, username, password)
    if ssh:
        print("Connected successfully.")
        command = 'ls -l'
        output, errors = execute_command(ssh, command)
        if output:
            print("Output:")
            print(output)
        if errors:
            print("Errors:")
            print(errors)
        local_path = '/path/to/local/file'
        remote_path = '/path/to/remote/file'
        upload_file(ssh, local_path, remote_path)
        print("File uploaded successfully.")
        download_file(ssh, remote_path, local_path)
        print("File downloaded successfully.")
    close_ssh_connection(ssh)
    print("Connection closed.")

Advanced Cases

1. Public‑Key Authentication – Use an RSA private key for password‑less login:

def ssh_connect_with_key(hostname, port, username, key_filename):
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    pkey = paramiko.RSAKey.from_private_key_file(key_filename)
    ssh.connect(hostname, port, username, pkey=pkey)
    return ssh

2. Channel Operations – Open a channel to execute commands concurrently:

def open_channel_and_execute(ssh, command):
    channel = ssh.get_transport().open_session()
    channel.exec_command(command)
    output = channel.recv(1024).decode()
    errors = channel.recv_stderr(1024).decode()
    channel.close()
    return output, errors

3. Interactive Session – Create an interactive shell to send and receive data:

def interactive_session(ssh):
    channel = ssh.invoke_shell()
    while True:
        data = channel.recv(1024).decode()
        if not data:
            break
        print(data, end='')
        if data.endswith("$ "):
            command = input() + "\n"
            channel.send(command)

4. Concurrent Command Execution – Run multiple commands in parallel using separate channels:

def concurrent_commands(ssh, commands):
    channels = []
    for command in commands:
        channel = ssh.get_transport().open_session()
        channel.exec_command(command)
        channels.append(channel)
    outputs = []
    for channel in channels:
        output = channel.recv(1024).decode()
        channel.close()
        outputs.append(output)
    return outputs

5. Jump Host (Proxy) – Connect to a target server through an intermediate jump host:

def jump_through(ssh, target_hostname, target_port, target_username, target_password):
    transport = ssh.get_transport()
    dest_addr = (target_hostname, target_port)
    local_addr = ('', 0)
    channel = transport.open_channel('direct-tcpip', dest_addr, local_addr)
    ssh_target = paramiko.SSHClient()
    ssh_target.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh_target.connect(target_hostname, target_port, target_username, target_password, sock=channel)
    return ssh_target

6. Proxy Command – Use a ProxyCommand defined in SSH configuration:

def ssh_connect_with_proxy_command(ssh_config):
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(ssh_config['hostname'], port=ssh_config['port'], username=ssh_config['username'],
                password=ssh_config['password'], sock=paramiko.ProxyCommand(ssh_config['proxy_command']))
    return ssh

7. SOCKS/HTTP Proxy – Route SSH traffic through a SOCKS5 proxy using the socks module:

import socks

def ssh_connect_with_proxy(proxy_type, proxy_host, proxy_port):
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    socks.setdefaultproxy(proxy_type, proxy_host, proxy_port)
    socket = socks.socksocket()
    ssh.connect('example.com', 22, username='your_username', password='your_password', sock=socket)
    return ssh

Summary – Paramiko offers a rich set of capabilities ranging from basic SSH connections to advanced channel handling, key‑based authentication, jump hosts, and proxy support, enabling flexible automation of remote server interactions.

DevOpsSSHParamikoRemote ExecutionSFTP
Test Development Learning Exchange
Written by

Test Development Learning Exchange

Test Development Learning Exchange

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.