Telnet vs SSH – How to secure your Switch Management (Transport) protocols, explained and labbed!


The point of this post is to discuss how to secure Switch management in the network, by not only using SSH (as it encrypts traffic!), but also how to disable Telnet sessions AND even create our old friend an Access-Class map to act as our Management ACL!

I will get right to it, by first stating Telnet is not Secure, and needs to be disabled!

Clear text is unacceptable (but a necessary evil at times like for CDP), so our only other option is SSH, unless the device is not capable of SSH connections (which happens).

Prerequisite to line configuration

Now the first thing you want to do, is create an Enable Secret to allow for remote login, along with a reachable Mgmt IP Address – Host A is in with a Mgmt IP of but Inter-Vlan routing makes the Mgmt IP reachable.

I know you probably know this, but for those of you who have forgotten.

First a look at the HUGE options list for line configuration mode

I’ll highlight the sub-commands we will be using along the way.

Line configuration commands:
access-class Filter connections based on an IP access list
autocommand Automatically execute an EXEC command
autocommand-options Autocommand options
data-character-bits Size of characters being handled
databits Set number of data bits per character
default Set a command to its defaults
domain-lookup Enable domain lookups in show commands
editing Enable command line editing
escape-character Change the current line’s escape character
exec Configure EXEC
exec-banner Enable the display of the EXEC banner
exec-character-bits Size of characters to the command exec
exec-timeout Set the EXEC timeout
exit Exit from line configuration mode
flowcontrol Set the flow control
full-help Provide help to unprivileged user
help Description of the interactive help system
history Enable and control the command history function
international Enable international 8-bit character support
ip IP options
ipv6 IPv6 options
length Set number of lines on a screen
location Enter terminal location description
logging Modify message logging facilities
login Enable password checking
modem Configure the Modem Control Lines
monitor Copy debug output to the current terminal line
motd-banner Enable the display of the MOTD banner
no Negate a command or set its defaults
notify Inform users of output from concurrent sessions
padding Set padding for a specified output character
parity Set terminal parity
password Set a password
prc PRC commands
privilege Change privilege level for line
refuse-message Define a refuse banner
rotary Add line to a rotary group
rxspeed Set the receive speed
session-timeout Set interval for closing connection when there is no
input traffic
special-character-bits Size of the escape (and other special) characters
speed Set the transmit and receive speeds
start-character Define the start character
stop-character Define the stop character
stopbits Set async line stop bits
terminal-type Set the terminal type
timeout Timeouts for the line
transport Define transport protocols for line
txspeed Set the transmit speeds
vacant-message Define a vacant banner
width Set width of the display terminal


Tons of stuff there:

  • Access-Class = An IP Access-List used to limit Layer 3 connectivity
  • Exec-timeout = Time before you are booted back to the login prompt
  • Login = Define how users will log into the VTY lines (configured shortly)
  • Transport = What types of Protocol are allowed to connect

Exec-Timeout is something I generally turn to 0 to disable, or issue “no exec-t” on the line, as getting logged out completely is irritating, but for security purposes there should be some sort of value set (maybe 5 minutes)?

Note we will not be using the “Password” option, that is for Telnet, we are configuring SSH for Secure remote access!

Lets take a look at login options:

SW1(config-line)#login ?
local Local password checking

SW1(config-line)#login local ?

SW1(config-line)#login local

This configures the switch to use the locally configured username / password database for remote access credentials.

Lets take a look at transport options:

SW1(config-line)#transport ?
input Define which protocols to use when connecting to the terminal
output Define which protocols to use for outgoing connections
preferred Specify the preferred protocol to use

SW1(config-line)#transport input ?
all All protocols
none No protocols
ssh TCP/IP SSH protocol
telnet TCP/IP Telnet protocol

SW1(config-line)#transport input ssh ?
telnet TCP/IP Telnet protocol

SW1(config-line)#transport input ssh

I chose input because the SSH connection will be coming in, I don’t need to configure output for it to return traffic also in SSH, and it also gives several options for that input:

  • All = I use this on my Access-Server router, it allows ALL connection types
  • None = No remote access protocols allowed
  • SSH = Allow SSH only
  • Telnet = Allow Telnet only

We saw it gave us an option to add the other protocol (telnet) on the tail end there, but I just ended the command with SSH, so Telnet has been effectively disabled.

That is all there is to the VTY Line configuration, be sure to save your config!

Setting an IP Domain, RSA Encryption Key, and Creating a Username / PW Database!

For SSH to work, it needs the LANs domain name, or really any domain name.

SW1(config)#ip domain-name

Of course you always want to use the companies domain name, but any can work.

I am not sure exactly why the Crypto Key needs to be generated for SSH to work, I haven’t really researched it, but from what I have I know that using the minimum 512-bit key will run SSH 1.5 which is pretty weak.

The next step up I’ve seen is a 1024 key, that ran SSH 1.99, which is probably enough encryption / security on the line, however this is a lab so I’m going all the way!

Now for Generating the RSA Crypto Key required for SSH to work:

SW1(config)#crypto ?
call Configure Crypto Call Admission Control
dynamic-map Specify a dynamic crypto map template
engine Enter a crypto engine configurable menu
gdoi Configure GDOI policy
identity Enter a crypto identity list
ikev2 Configure IKEv2 Options
ipsec Configure IPSEC policy
isakmp Configure ISAKMP policy
key Long term key operations
keyring Key ring commands
logging logging messages
map Enter a crypto map
mib Configure Crypto-related MIB Parameters
pki Public Key components
xauth X-Auth parameters

SW1(config)#crypto key ?
decrypt Decrypt a keypair.
encrypt Encrypt a keypair.
export Export keys
generate Generate new keys
import Import keys
move Move keys
pubkey-chain Peer public key chain management
storage default storage location for keypairs
zeroize Remove keys

SW1(config)#crypto key generate ?
ec Generate EC keys for ECDSA
rsa Generate RSA keys

SW1(config)#crypto key generate rsa ?
encryption Generate a general purpose RSA key pair for signing and
exportable Allow the key to be exported
general-keys Generate a general purpose RSA key pair for signing and
label Provide a label
modulus Provide number of modulus bits on the command line
on create key on specified device.
redundancy Allow the key to be synced to high-availability peer
signature Generate a general purpose RSA key pair for signing and
storage Store key on specified device
usage-keys Generate separate RSA key pairs for signing and encryption

SW1(config)#crypto key generate rsa
The name for the keys will be:
Choose the size of the key modulus in the range of 360 to 4096 for your
General Purpose Keys. Choosing a key modulus greater than 512 may take
a few minutes.

How many bits in the modulus [512]: 4096
% Generating 4096 bit RSA keys, keys will be non-exportable…

This actually pegged my session!

I had to go back to the Access-Server, and back to SW1, and it took 596 seconds to create:

[Resuming connection 1 to sw1 … ]

[OK] (elapsed time was 562 seconds)


So to verify what version of SSH we are using, lets do that with “sh ip ssh” :

SW1#sh ip ssh
SSH Enabled – version 1.99
Authentication timeout: 120 secs; Authentication retries: 3
Minimum expected Diffie Hellman key size : 1024 bits
IOS Keys in SECSH format(ssh-rsa, base64 encoded):
(Lots of code redacted)

I’m not exactly sure what the rest means, but I do know its running Version 1.99, which also runs when you create a 1024-bit RSA key, so no need to go any higher in my mind unless asked to on exam day!

Next step is to make the username / password Database for local login

So easy a caveman can do it:

SW1(config)#username joe privilege 15 password blow
SW1(config)#username fire password fox
SW1(config)#username hello secret goodbye

SW1(config)#aaa ?
new-model Enable NEW access control commands and functions.(Disables OLD

SW1(config)#aaa new-model ?

I wanted to demonstrate a few things here, that first yes IOS 15.x hasn’t gotten rid of that stupid “privilege” line in the middle of the username/password that puts users straight into User Exec mode – I personally feel that is a security flaw that should be weeded out.

Next is the standard username / password which is what you regularly will use / see.

Next is an odd one I haven’t tested yet, “secret” instead of password, we’ll see how that shows up in the running config!

Lastly just wanted to forewarn here that this is where AAA will be configured for SSH (and many other Access related configs) will be placed, so wanted to preview that here!

A look at how they appear in the running config:

username joe privilege 15 password 0 blow
username fire password 0 fox
username hello secret 5 $1$k3ub$5Ul7Z9NU5w4lEvN3H4MFb0

Well I’ll be, username / secret encrypted the password without need “service password-encryption” added to the device, so that may be the way to go (if you need it encrypted).

Either way, service password-encryption would tighten this up either way!

Now to finish this bad boy off, to make an Access-Class list to limit L3 mgmt traffic!

I don’t really ever see these in the real world, because you might have to SSH to a Router at 3am from ANYWHERE, however for the exam we better know how to do this.

In this example I’ll make Host A our only machine with Mgmt Access.

First the “Standard” Access List configuration:

SW1(config)#ip access-list standard SSH_Line

Now to apply that “Standard” Access-List to the line vty 0 15:

SW1(config)#line vty 0 15
SW1(config-line)#access-class ?
<1-199> IP access list
<1300-2699> IP expanded access list
WORD Access-list name

SW1(config-line)#access-class SSH_Line ?
in Filter incoming connections
out Filter outgoing connections

SW1(config-line)#access-class SSH_Line in ?
vrf-also Same access list is applied for all VRFs

SW1(config-line)#access-class SSH_Line in

It ONLY needs to be a standard list, because we are not allowing certain Protocols to certain Destinations, also it needs that “in” at the end to signify it is an inbound list.

And that is all there is to securing the remote access of Cisco switches!


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s