Languages

Using Paramiko and Netmiko for SSH and Telnet Connections in Python

JGJaya Gupta21 Mar 2023 Β· Updated 04 Oct 2026 Β· 7 min read
Using Paramiko and Netmiko for SSH and Telnet Connections in Python

Quick answer: Paramiko is a low-level Python implementation of the SSH protocol; Netmiko is a higher-level library built on top of Paramiko that understands network device prompts, paging and configuration modes for Cisco, Juniper, Arista and more than a hundred other platforms. Use Netmiko for routers and switches; drop down to Paramiko when you need raw SSH control or are talking to Linux servers. Netmiko also handles legacy Telnet through its _telnet device types.

Almost every network automation script begins with “connect to the device and run a command”. This guide shows how to do that with both libraries, explains exactly what Netmiko adds on top of Paramiko, covers Telnet for the old gear still in your racks, and lists the connection mistakes that cause hanging scripts and locked accounts.

Paramiko versus Netmiko: what each one does

SSH is a general-purpose protocol. A Linux server gives you a shell, runs your command, and returns when it finishes. A Cisco switch behaves differently: it shows a prompt like Switch> or Switch#, paginates long output with --More--, has an enable mode and a configuration mode, and never signals “the command finished” β€” it just prints the prompt again.

Paramiko handles the SSH part β€” key exchange, authentication, channels β€” and leaves the prompt handling to you. Netmiko handles the network-device part: it detects the prompt, disables paging, waits for output to finish, and knows the commands to enter configuration mode on each vendor.

Feature Paramiko Netmiko
Protocol SSH only (SSHv2) SSH, plus Telnet and serial via dedicated device types
Prompt detection Manual Automatic
Disable paging (terminal length 0) You send it Automatic per platform
Enable / config mode You script it enable(), send_config_set()
Structured output No TextFSM, TTP and Genie parsing built in
Vendor knowledge None 100+ device types
Best for Linux servers, SFTP, custom protocols Routers, switches, firewalls

Install both with pip install netmiko β€” Netmiko lists Paramiko as a dependency, so you get it automatically. If you are still deciding whether automation is worth the learning curve, Why Use Python for Network Engineering? makes the case before you write a line of code.

Hands-on: SSH with Paramiko

This example connects to a Cisco IOS device, opens an interactive shell, disables paging and runs a command. Notice how much manual work is involved compared with the Netmiko version that follows.

import os
import time
import paramiko

HOST = "192.168.1.1"

client = paramiko.SSHClient()
client.load_system_host_keys()
# RejectPolicy is the secure default; AutoAddPolicy only in a trusted lab
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

client.connect(
    HOST,
    username=os.environ["NET_USER"],
    password=os.environ["NET_PASS"],
    look_for_keys=False,
    allow_agent=False,
    timeout=10,
)

shell = client.invoke_shell()
shell.send("terminal length 0\n")
time.sleep(1)
shell.send("show ip interface brief\n")
time.sleep(2)                                  # crude: wait for output

output = shell.recv(65535).decode("utf-8")
print(output)
client.close()

The time.sleep() calls are the weak point. Too short and you miss output; too long and the script crawls. Production Paramiko code loops on shell.recv_ready() and looks for the prompt β€” which is exactly the logic Netmiko packages for you. Paramiko’s exec_command() method is cleaner for Linux hosts but many network operating systems do not support it.

Hands-on: SSH with Netmiko

import os
from netmiko import ConnectHandler

router = {
    "device_type": "cisco_ios",
    "host": "192.168.1.1",
    "username": os.environ["NET_USER"],
    "password": os.environ["NET_PASS"],
    "secret": os.environ.get("NET_ENABLE", ""),
    "conn_timeout": 10,
}

with ConnectHandler(**router) as conn:
    conn.enable()

    # Raw text, paging already disabled
    print(conn.send_command("show ip interface brief"))

    # Structured data via TextFSM
    interfaces = conn.send_command("show ip interface brief", use_textfsm=True)
    for intf in interfaces:
        print(f"{intf['interface']:25} {intf['ip_address']:16} {intf['status']}")

    # Configuration change
    result = conn.send_config_set([
        "interface Loopback100",
        " description Managed by Netmiko",
        " ip address 10.255.0.1 255.255.255.255",
    ])
    print(result)
    conn.save_config()

Five lines of Paramiko boilerplate became a dictionary and a context manager. Netmiko waits for the prompt rather than sleeping, handles enable mode, and returns the exact output you would see in a terminal. The with block guarantees disconnect() is called even when an exception is raised.

Device types to remember: cisco_ios, cisco_xe, cisco_nxos, cisco_asa, juniper_junos, arista_eos, hp_procurve, fortinet, paloalto_panos and linux. If you are unsure, from netmiko import SSHDetect can guess the platform for you.

Telnet connections for legacy devices

Telnet sends passwords in clear text and should be disabled wherever possible, but older switches and lab equipment sometimes leave you no choice. Netmiko supports it with the same API β€” only the device_type changes:

import os
from netmiko import ConnectHandler

legacy_switch = {
    "device_type": "cisco_ios_telnet",   # note the _telnet suffix
    "host": "192.168.1.20",
    "username": os.environ["NET_USER"],
    "password": os.environ["NET_PASS"],
    "port": 23,
}

with ConnectHandler(**legacy_switch) as conn:
    print(conn.send_command("show version | include Version"))
    # First automation task on a Telnet device: turn on SSH
    conn.send_config_set([
        "ip domain-name lab.local",
        "crypto key generate rsa modulus 2048",
        "ip ssh version 2",
        "line vty 0 15",
        " transport input ssh",
    ])
    conn.save_config()

Paramiko does not do Telnet at all. If you need Telnet without Netmiko, Python’s standard library telnetlib was removed in Python 3.13, so use the telnetlib3 package instead.

Connection errors you will meet and what they mean

  • NetmikoTimeoutException – TCP connection failed. Check reachability, firewall rules, and that SSH is actually enabled on the device.
  • NetmikoAuthenticationException – wrong username or password, or the account lacks SSH privilege. On Cisco, make sure login local or AAA is configured on the VTY lines.
  • paramiko.ssh_exception.SSHException: Incompatible ssh peer – the device offers only legacy key-exchange or cipher algorithms. Newer Paramiko and OpenSSH disable these; pass disabled_algorithms or, better, upgrade the device firmware.
  • ReadTimeout – the command took longer than Netmiko expected (for example show tech-support). Increase read_timeout on send_command() or use send_command_timing().
  • Script hangs forever – usually a prompt Netmiko did not recognise, such as a confirmation question. Use send_command(cmd, expect_string=r"\[confirm\]") and then send the answer.

Six connection mistakes to avoid

  1. AutoAddPolicy() everywhere. It accepts any host key, which defeats SSH’s man-in-the-middle protection. Fine in a lab; in production load a known-hosts file.
  2. Passwords in the script. Use os.environ, getpass.getpass(), or a secrets manager. Netmiko also supports use_keys=True with key_file for SSH key authentication.
  3. No timeouts. A single unreachable device blocks a 200-device run indefinitely. Set conn_timeout and catch the exceptions above.
  4. Forgetting disconnect(). Devices have a VTY line limit (often five on Cisco IOS). Leaked sessions lock everyone out until they time out. Always use the with block.
  5. Running config commands with send_command(). It never enters configuration mode. Use send_config_set() or send_config_from_file().
  6. Parsing with string positions. Column widths change between software versions. Prefer use_textfsm=True or regular expressions β€” see Parsing Network Device Output with Regular Expressions in Python.

Frequently asked questions

Can Netmiko connect to Linux servers?

Yes, with device_type: "linux". For heavy server automation, though, plain Paramiko with exec_command() or a tool such as Fabric or Ansible is usually a better fit.

Does Netmiko support SSH keys instead of passwords?

Yes. Add "use_keys": True and "key_file": "~/.ssh/id_ed25519" to the device dictionary. Key-based authentication is both more secure and easier to automate.

How many devices can I connect to at once?

Netmiko connections are blocking, so use concurrent.futures.ThreadPoolExecutor or move to Nornir, which manages a thread pool and inventory for you. Twenty to fifty concurrent sessions is a common safe ceiling, limited mostly by the devices and your AAA server.

Is Scrapli a replacement for Netmiko?

Scrapli is a newer alternative with async support and very fast transports. Netmiko remains the most widely used and documented option, and the concepts transfer directly between the two.

Key takeaways

  • Paramiko gives you raw SSH; Netmiko adds everything network devices need β€” prompts, paging, config mode and 100+ platforms.
  • Reach for Netmiko first for routers and switches; keep Paramiko for servers and custom SSH work.
  • Telnet still works through Netmiko’s _telnet device types, but use it mainly to enable SSH.
  • Always set timeouts, handle exceptions, use the with block, and keep credentials out of code.

Want to master Python from the basics through to real automation and data projects? Our Python & Data Science course includes mentor support, hands-on labs and placement assistance. Prefer learning by watching? Subscribe to our YouTube channel for step-by-step demos.

JG
Written byJaya Gupta

Part of the Techknowledgehub team of industry mentors, writing practical guides to help you build a job-ready tech career.

More articles by Jaya Gupta β†’
Keep reading

Related articles

What is Python programming?
Languages

What is Python programming?

A beginner-friendly explanation of what Python programming is, its uses, why it is popular, developer salaries, and hands-on first programs.

30 Mar 2023Β· 7 min read

Leave a Reply