Before SSH existed, network engineers commonly used Telnet to remotely manage routers and switches. Telnet works, but it sends everything — including usernames and passwords — as plain, readable text across the network. Anyone capturing traffic on the path could read your login credentials instantly.
SSH (Secure Shell) solves this problem by encrypting the entire session. This article explains, from first principles, how SSH works, why it replaced Telnet, and exactly how to configure, verify, and troubleshoot SSH access on Cisco devices and Linux servers.
Why Remote Access Matters
Network devices are often physically located in server rooms, wiring closets, or remote branch offices that engineers cannot walk to every time a change is needed. Remote access protocols let an administrator connect to a device’s Command Line Interface (CLI) over the network itself, as if they were sitting at the console — but this convenience is dangerous if the connection isn’t secured.
Telnet vs SSH — Why the Difference Matters
| Feature | Telnet | SSH |
|---|---|---|
| Port | TCP 23 | TCP 22 |
| Encryption | None (cleartext) | Full session encryption |
| Authentication | Plaintext username/password | Password or public-key, encrypted |
| Data Integrity Checking | No | Yes (via MAC — Message Authentication Code) |
| Modern Usage | Deprecated for production | Industry standard |
sequenceDiagram
participant Attacker
participant Admin
participant Router
Note over Admin,Router: Telnet Session (cleartext)
Admin->>Router: username: admin, password: Cisco123 (visible!)
Attacker-->>Admin: Packet capture reveals credentials
Note over Admin,Router: SSH Session (encrypted)
Admin->>Router: Encrypted key exchange + login
Attacker-->>Admin: Packet capture shows only ciphertextHow SSH Works, From First Principles
SSH relies on asymmetric (public-key) cryptography to set up a secure, encrypted channel, and then typically uses a password or key for authentication within that channel. The process happens in stages:
- TCP connection is established on port 22.
- Key exchange — client and server agree on a shared secret using algorithms like Diffie-Hellman, without ever sending the secret itself over the network.
- Server authentication — the client verifies the server’s identity using the server’s public key (this is why you see “the authenticity of host X can’t be established” the first time you connect).
- Session encryption begins — from this point, all traffic, including login credentials, is encrypted.
- User authentication — via password or SSH key pair.
- Encrypted session — the CLI session now runs entirely inside this encrypted tunnel.
SSH Versions: SSH1 vs SSH2
SSH version 1 had known cryptographic weaknesses and is now considered insecure. SSH version 2 (SSHv2) is the current standard and should always be enforced explicitly on Cisco devices.
Prerequisites for Enabling SSH on a Cisco Device
Before SSH will work, the device needs:
- A hostname other than the default (SSH requires a unique hostname for key generation).
- A domain name configured.
- RSA (or ECDSA) key pair generated locally.
- A local username/password database or AAA authentication configured.
- VTY lines configured to accept SSH (not Telnet).
Step-by-Step: Configuring SSH on a Cisco Router/Switch
Step 1: Set Hostname and Domain Name
Router(config)# hostname R1
R1(config)# ip domain-name mycompany.localStep 2: Generate the RSA Key Pair
R1(config)# crypto key generate rsa
% You already have RSA keys defined...
How many bits in the modulus [512]: 2048Use at least 2048 bits for a modern, secure key.
Step 3: Create a Local User Account
R1(config)# username admin privilege 15 secret StrongP@ssw0rd!Using secret (not password) ensures the credential is stored as an encrypted hash, not reversible plaintext.
Step 4: Enable SSH Version 2 Only
R1(config)# ip ssh version 2Step 5: Configure VTY Lines for SSH-Only Access
R1(config)# line vty 0 4
R1(config-line)# transport input ssh
R1(config-line)# login local
R1(config-line)# exec-timeout 10 0transport input ssh explicitly disables Telnet on these lines — a critical security step many engineers forget.
Step 6: (Optional but Recommended) Harden SSH Further
R1(config)# ip ssh time-out 60
R1(config)# ip ssh authentication-retries 3Verifying SSH Configuration
R1# show ip ssh
R1# show ssh
R1# show crypto key mypubkey rsa
R1# show running-config | section line vtySample output of show ip ssh:
SSH Enabled - version 2.0
Authentication timeout: 60 secs; Authentication retries: 3Sample output of show ssh (active sessions):
Connection Version Mode Encryption Hmac State Username
0 2.0 IN aes256-cbc hmac-sha1 Session started admin
0 2.0 OUT aes256-cbc hmac-sha1 Session started adminTesting the Connection
From another Cisco device:
R2# ssh -l admin 192.168.1.1From a Linux/Mac terminal:
ssh admin@192.168.1.1From Windows, using PuTTY or the built-in OpenSSH client:
ssh admin@192.168.1.1SSH Key-Based Authentication (More Secure Than Passwords)
Instead of a password, you can configure public-key authentication, removing the risk of password guessing entirely.
On the client (Linux example):
ssh-keygen -t rsa -b 4096 -f ~/.ssh/router_key
cat ~/.ssh/router_key.pubOn the Cisco device (IOS supports this on newer platforms via ip ssh pubkey-chain):
R1(config)# ip ssh pubkey-chain
R1(conf-ssh-pubkey)# username admin
R1(conf-ssh-pubkey-user)# key-string
R1(conf-ssh-pubkey-data)# AAAAB3NzaC1yc2EAAAADAQABAAAB...
R1(conf-ssh-pubkey-data)# exitThen connect with:
ssh -i ~/.ssh/router_key admin@192.168.1.1Configuring SSH Server on a Linux Machine
Most Linux distributions ship with OpenSSH.
sudo apt update
sudo apt install openssh-server -y
sudo systemctl enable ssh
sudo systemctl start ssh
sudo systemctl status sshHardening /etc/ssh/sshd_config:
Port 2222
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AllowUsers adminsudo systemctl restart sshAutomating SSH Connections with Python (Netmiko)
Network engineers commonly use the netmiko Python library to automate SSH logins to dozens or hundreds of devices at once — for backups, audits, or bulk configuration changes.
from netmiko import ConnectHandler
device = {
"device_type": "cisco_ios",
"host": "192.168.1.1",
"username": "admin",
"password": "StrongP@ssw0rd!",
"secret": "StrongP@ssw0rd!",
}
connection = ConnectHandler(**device)
connection.enable()
output = connection.send_command("show ip ssh")
print(output)
connection.disconnect()This kind of script is the foundation of network automation pipelines — instead of manually SSHing into each device, engineers script the same task across an entire fleet.
Best Practices for SSH on Network Devices
- Always disable Telnet (
transport input ssh) once SSH is confirmed working. - Use SSH version 2 only — never allow version 1.
- Use RSA keys of at least 2048 bits.
- Set an exec-timeout on VTY lines to auto-disconnect idle sessions.
- Limit SSH access with an ACL applied via
access-classon the VTY lines. - Use AAA (TACACS+/RADIUS) for centralized authentication in larger environments instead of local usernames.
- Rotate/change default and shared passwords regularly.
- Log all SSH login attempts to a syslog server for auditing.
- Prefer key-based authentication over passwords where the platform supports it.
Troubleshooting SSH Access
| Symptom | Likely Cause | Fix |
|---|---|---|
| “Connection refused” | SSH not enabled, wrong port, or ACL blocking port 22 | Verify show ip ssh, check ACLs |
| “% SSH keys have not been generated” | RSA key pair missing | Run crypto key generate rsa |
| Login fails despite correct password | login local missing, or user account not created | Verify username command and login local on VTY |
| Falls back to Telnet unexpectedly | transport input still allows telnet | Set transport input ssh explicitly |
| Session hangs / very slow | DNS lookup failure delays login | Disable DNS lookup: no ip domain-lookup |
| “Too many authentication failures” | Multiple SSH keys offered before password | Use ssh -o IdentitiesOnly=yes or increase ip ssh authentication-retries |
Real-World Example: Securing a Branch Office Router
A company has 20 branch routers, previously managed via Telnet. The security team mandates SSH-only access with a maximum of 3 login attempts and a 5-minute idle timeout, restricted to the IT team’s subnet (10.0.99.0/24).
hostname BR-R1
ip domain-name branch.company.com
crypto key generate rsa modulus 2048
ip ssh version 2
ip ssh authentication-retries 3
username netadmin privilege 15 secret VeryStr0ngPass!
access-list 50 permit 10.0.99.0 0.0.0.255
access-list 50 deny any log
line vty 0 4
transport input ssh
login local
access-class 50 in
exec-timeout 5 0This configuration, replicated (ideally via automation) across all 20 routers, closes the Telnet security gap company-wide.
Conclusion
SSH is the modern standard for securely managing network devices remotely. It replaces the plaintext vulnerabilities of Telnet with strong encryption, supports both password and public-key authentication, and integrates cleanly with automation tools like Netmiko for large-scale operations. Mastering SSH configuration, verification, and troubleshooting is essential for any network professional operating in a real production environment.
References
- Cisco Configuring Secure Shell (SSH) — https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/sec_usr_ssh/configuration/xe-16/sec-usr-ssh-xe-16-book.html
- OpenSSH Documentation — https://www.openssh.com/manual.html
- RFC 4251 – The Secure Shell (SSH) Protocol Architecture — https://datatracker.ietf.org/doc/html/rfc4251
- Netmiko GitHub Repository — https://github.com/ktbyers/netmiko
- Cisco IOS Security Command Reference — https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/security/command/reference/sec-cr-book.html
- NIST Guidelines for SSH Key Management — https://csrc.nist.gov/publications/detail/sp/800-77/rev-1/final