main blog post image for ssh hardening ,

SSH Hardening: Lock Down Your Network Devices Properly

Right, so SSH hardening. Let me tell you something that still makes me cringe.

Few years back I did a security audit on a network I’d inherited. Ran a basic vulnerability scan against the management range. Came back with a list of findings longer than my arm. Weak ciphers. SSHv1 still accepted. No login rate limiting. Session timeouts either massive or completely disabled. Forty-odd devices all with basically the same problem.

More General Networking Posts

Took me the best part of a week to work through the lot. And the worst part? Every single one of those devices had SSH “working.” Nobody had ever thought to harden it properly. Just got SSH enabled, tested they could log in, moved on.

That’s the thing isn’t it. SSH working and SSH being secure are two completely different things. This post is going to sort that out.

Split diagram showing an unsecured SSH configuration with weak ciphers and defaults on the left versus a  configuration with SSH Hardening and  strong settings on the right. Clean technical diagram style with red/green colour coding to highlight insecure versus secure settings

SSH Hardening Matters More Than You Think

Most SSH scanning on the internet is automated. Bots just work through IP ranges trying everything. Default credentials. Known weak cipher combinations. Brute force attempts.

Your management network probably isn’t directly internet-facing. Doesn’t mean it’s safe though. Compromised device on the same network. Rogue laptop plugged into the wrong port. VPN user with a dodgy machine. Plenty of ways something nasty can end up trying to get into your network gear.

And then there’s audits. If your organisation does any kind of security assessment, SSH configuration on network devices always comes up. Walking in with default SSH settings is not a conversation you want to have.

So let’s go through it properly.

SSH Version: Sort This First

SSHv1 is broken. Not “a bit old” or “probably fine internally.” Actually cryptographically broken with real attacks against it.

ip ssh version 2

One line. Should be in every single device config. If you’re auditing a network and a device is missing that, that’s your first fix before anything else.

Verify it:

show ip ssh

You want SSH Enabled – version 2.0. If you see 1.99 that means it’s accepting both versions. Version 1 fallback still enabled. Not good enough.

Had a device once where someone had explicitly configured SSHv1 because they were using an ancient jump host that wouldn’t do v2. Instead of fixing the jump host they’d downgraded SSH on thirty switches. Took some explaining that one.

SSH Hardening for Ciphers and Encryption

This is where most people stop. SSHv2 configured, job done. But SSHv2 supports a range of algorithms and not all of them are considered strong anymore.

3DES is weak. CBC mode ciphers have known vulnerabilities. If your device still advertises these a client can request them and the session uses them.

On IOS-XE you can lock this down:

ip ssh server algorithm encryption aes128-ctr aes192-ctr aes256-ctr
ip ssh server algorithm mac hmac-sha2-256 hmac-sha2-512
ip ssh server algorithm kex diffie-hellman-group14-sha1 diffie-hellman-group-exchange-sha256

CTR mode AES instead of CBC. SHA-2 for message authentication. Proper key exchange algorithms.

Older IOS might not give you this granularity. Another good reason to push firmware updates where you can.

Want to see what your device is actually advertising? Run ssh-audit against it. You’ll see quickly whether weak algorithms are still being offered.

Table showing SSH cipher algorithm comparison - columns for Algorithm Name, Type, Security Status, and Recommendation. Rows covering common ciphers showing which are deprecated/weak versus recommended. Clean professional table format

TimeoTimeouts and Retries

Every incomplete login attempt ties up a session. Without a timeout someone doing a slow brute force just leaves connections hanging indefinitely.

ip ssh time-out 60
ip ssh authentication-retries 3

Sixty seconds to complete authentication then disconnect. Three failed attempts then disconnect.

Idle session timeouts on VTY lines too. This catches something people forget constantly – authenticated sessions left open after an engineer walks away from their desk.

line vty 0 15
 exec-timeout 10 0

Ten minutes idle then the session closes. Set this to 0 0 and you’ve disabled it entirely. Seen networks where someone had done exactly that because they found getting disconnected annoying. Found sessions from users who’d left the business still sitting open. Brilliant.

Login Protection

Not enabled by default. No idea why because it’s dead easy and makes a massive difference.

login block-for 120 attempts 5 within 60

Five failed login attempts within sixty seconds and all logins blocked for two minutes. Stops automated brute force tools dead.

Add a delay between attempts:

login delay 5

Five second pause between each authentication attempt. Legitimate user who gets in first time doesn’t notice it. Something trying thousands of combinations is going to take forever.

Check what’s been blocked:

show login failures
show login

First time I ran that on a production network I was genuinely surprised at what was showing up. Nothing had got in but they were certainly trying.

Restrict Where Connections Come From

SSH being enabled doesn’t mean you have to accept connections from everywhere. Lock it to your management range.

ip access-list standard MGMT-ACCESS
 permit 192.168.100.0 0.0.0.255
 deny   any log

Apply it to VTY lines:

line vty 0 15
 access-class MGMT-ACCESS in

Now SSH only accepts connections from 192.168.100.0/24. Everything else gets dropped before it even gets to authentication.

The log keyword on the deny is worth having. Every dropped connection attempt gets logged. Gives you visibility when something is probing devices from unexpected sources.

RSA Key Length

When you first set up SSH you generate an RSA key pair. Default on older IOS is 1024-bit. Weak by modern standards.

Check what you’ve got:

show crypto key mypubkey rsa

If it says 1024, regenerate it:

crypto key zeroize rsa
crypto key generate rsa modulus 2048

Zeroize first then generate clean. 2048-bit minimum. IOS-XE supports 4096 if you want to go further.

Kill Telnet

Telnet sends everything in cleartext. Passwords. Commands. Everything. There is no argument for having Telnet enabled on network gear.

line vty 0 15
 transport input ssh

SSH only. Done.

AUX port too if the device has one. Often forgotten about completely.

line aux 0
 transport input none
 no exec

Not using it? Shut it down.

Login Banners

Two reasons. First, legal. A notice saying authorised access only establishes you’ve warned people. Matters if you ever need to prosecute unauthorised access.

Second, don’t advertise your kit. “Welcome to Cisco IOS 15.7 on SW1-ACCESS” is giving information away before anyone’s authenticated. Keep it generic.

banner login ^
AUTHORISED ACCESS ONLY
Unauthorised access is prohibited and will be prosecuted.
All activity is monitored and logged.
Disconnect immediately if you are not an authorised user.
^

The Full SSH Hardening Baseline

Right, putting it all together. Here’s a baseline you can adapt for your environment:

ip ssh version 2
ip ssh time-out 60
ip ssh authentication-retries 3

login block-for 120 attempts 5 within 60
login delay 5

ip access-list standard MGMT-ACCESS
 permit 192.168.100.0 0.0.0.255
 deny   any log

line vty 0 15
 access-class MGMT-ACCESS in
 exec-timeout 10 0
 transport input ssh
 login local

line aux 0
 transport input none
 no exec

banner login ^
AUTHORISED ACCESS ONLY
Unauthorised access is prohibited.
All activity is monitored and logged.
^

Apply that across your estate and you’re in a significantly better position than default. Not the most restrictive possible but it addresses everything that repeatedly comes up in security audits.

Verification

Before ending the change window verify everything’s working. Sounds obvious. Do it anyway.

show ip ssh
show line vty 0 4
show access-lists MGMT-ACCESS
show login
show crypto key mypubkey rsa

Actually test you can SSH in from an authorised host. Test that connections from outside the management range get refused. Always have console access available as a fallback when touching access control. Made the mistake of not having console access once when I locked myself out with a dodgy ACL. Not my finest hour. Don’t be like me.

Mistakes That Come Up Constantly

exec-timeout 0 0. Disables the timeout completely. People do it because they find getting disconnected annoying. What they’re actually doing is leaving sessions open indefinitely.

Forgetting the access class on higher VTY lines. Some platforms let you configure 0-4 and 5-15 separately. Configure all of them or connections can still come in on the lines you forgot.

enable password instead of enable secret. Password keyword stores a weak reversible hash. Always use enable secret.

Not zeroing the RSA key before regenerating. Zeroize first then generate. Cleaner every time.


External Link: NIST Guidelines for Secure Shell (SSH) – NIST guidance on SSH configuration and security covering key management, cipher selection and access control


SSH Hardening on Cisco Devices

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top