SSH security hardening is less about building a fortress and more about politely showing unwanted guests the door, then locking it behind them.

Let’s see what "locking down" sshd_config actually looks like in practice. Imagine you’ve got a server, say 192.168.1.100, and you want to make sure only authorized users can SSH in, and that they’re doing it securely.

Here’s a typical scenario. You’ve got a user, alice, who needs to SSH into 192.168.1.100.

# On alice's local machine
ssh alice@192.168.1.100

Now, let’s dive into the server’s sshd_config file, usually located at /etc/ssh/sshd_config. We’ll make some changes to tighten things up.

# On the server: 192.168.1.100
sudo nano /etc/ssh/sshd_config

Disable Root Login

First, and most importantly, stop anyone from logging in directly as root.

PermitRootLogin no

This prevents brute-force attacks from targeting the most powerful account. Instead, users log in with their own accounts and then use sudo to elevate privileges.

Disable Password Authentication

This is a huge security win. If you’re not using passwords, attackers can’t brute-force them.

PasswordAuthentication no
PubkeyAuthentication yes

This forces users to use SSH keys. You’ll need to ensure PubkeyAuthentication is set to yes.

Limit SSH Access to Specific Users or Groups

You can get granular about who can SSH in.

AllowUsers alice bob
# OR, for groups:
# AllowGroups sshusers

This is great for environments where only a few people need server access. AllowUsers takes a space-separated list of usernames.

Change the Default SSH Port

While not a primary security measure (port scanners will find it), it cuts down on the noise from automated bots.

Port 2222

Remember to update your SSH command on the client:

# On alice's local machine
ssh -p 2222 alice@192.168.1.100

Disable Protocol 1

SSH protocol version 1 is old and insecure. You should only be using version 2.

Protocol 2

This is usually the default, but it’s good to confirm.

Use Stronger Ciphers and MACs (Advanced)

This is for when you want to ensure the encryption and integrity checks are top-notch. You’d typically configure these with Ciphers and MACs directives. For example:

Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com

These are modern, strong algorithms. chach20-poly1305 is particularly fast and secure.

Limit Login Attempts

Prevent brute-force attacks by limiting how many times a user can try to log in.

MaxAuthTries 3
LoginGraceTime 30

MaxAuthTries sets the number of attempts, and LoginGraceTime is how long the server waits for authentication after a connection is established, in seconds.

Disable X11 Forwarding if Not Needed

If you don’t need to run graphical applications remotely, disable it.

X11Forwarding no

This reduces the attack surface.

Disable Agent Forwarding if Not Needed

Agent forwarding can be a security risk if the agent on your local machine is compromised.

AllowAgentForwarding no

After making these changes, you must restart the SSH service for them to take effect.

# On the server: 192.168.1.100
sudo systemctl restart sshd
# or
# sudo service ssh restart

The most common mistake after making these changes is forgetting to restart the sshd service, which leaves you unable to connect.

Once you’ve successfully locked down sshd_config, the next hurdle you’ll likely face is managing SSH keys for a growing team.

Want structured learning?

Take the full Ssh course →