Cybersecurity

SSH Hardening Linux: Complete Guide 2026 (10 Critical Settings)

SSH Hardening Linux: Complete Guide 2026 (10 Critical Settings)

Linux server security is a top priority for any IT professional. In today’s ever-evolving threat landscape, a single weak link can spell operational disaster. SSH (Secure Shell) is the backbone of remote administration, but a default or misconfigured setup is an open invitation to attackers. Over the years, I’ve seen far too many infrastructures exposed to unnecessary risk due to weak SSH configurations. This article walks you through ten essential settings to lock down your Linux servers, drastically reducing your attack surface and bolstering resilience against intrusion attempts. By implementing these practices, you can protect your 2,000 endpoints and over 300 VMware VMs from unauthorized access, ensuring robust, proactive control over your infrastructure.

Prerequisites / Test Environment

To follow along, you’ll need a Linux server (preferably a recent distro like Ubuntu Server 22.04 LTS or CentOS Stream 9) with sudo access. All commands will be run from the terminal. Before making any changes to your SSH configuration, it’s critical to back up the original sshd_config file. This allows you to restore the previous configuration if something goes wrong, preventing you from locking yourself out of the server. Our primary focus here is Linux SSH hardening to ensure maximum security.

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

Change the Default SSH Port

The default SSH port (22) is the primary target for automated attacks and port scanners. Changing it to a non-standard value doesn’t provide intrinsic security (a determined attacker can still scan all ports), but it significantly reduces noise and automated brute-force attempts. Choose a high port that isn’t used by other services.

In the /etc/ssh/sshd_config file, find the Port 22 line and modify it:

#Port 22
Port 2222

Make sure to open the new port in your server’s firewall (e.g., sudo ufw allow 2222/tcp for UFW or sudo firewall-cmd --permanent --add-port=2222/tcp --zone=public && sudo firewall-cmd --reload for Firewalld).

Disable Root Login

Allowing direct root login via SSH is a risky practice. If an attacker manages to guess the root password, they gain full control of the system. It’s much safer to log in with a standard user and escalate privileges via sudo when needed. This adds an essential layer of protection.

In the /etc/ssh/sshd_config file, set:

PermitRootLogin no

Enforce Public Key Authentication Only

Password authentication is vulnerable to brute-force and dictionary attacks. Public key authentication, based on cryptographic key pairs (a public key on the server and a private key on the client), is far more secure and strongly recommended for production environments. It requires the private key to be securely stored on the client side.

In the /etc/ssh/sshd_config file, set:

PasswordAuthentication no
PubkeyAuthentication yes

Make sure you’ve already configured SSH key access before disabling password authentication, or you’ll lock yourself out of the server.

Limit SSH User Access

Not every system user needs SSH access. Restrict access to only the accounts that strictly require it. This further shrinks the attack surface and mitigates the risk of compromised accounts being used for remote access.

In the /etc/ssh/sshd_config file, add or modify:

AllowUsers username

You can specify multiple users separated by spaces: AllowUsers user1 user2.

Set an Idle Session Timeout

Unattended, idle SSH sessions pose a security risk. If a user walks away from their terminal without locking it, a malicious actor could hijack the active session. Configuring an automatic timeout for idle sessions helps mitigate this risk.

In the /etc/ssh/sshd_config file, add:

ClientAliveInterval 300
ClientAliveCountMax 2

ClientAliveInterval 300 tells the server to send a “keep-alive” message to the client every 300 seconds (5 minutes). ClientAliveCountMax 2 means that if the client fails to respond to 2 of these messages, the session will be terminated. In this example, an idle session will be dropped after 10 minutes (300 seconds * 2 attempts = 600 seconds).

Disable Legacy SSH Protocols

Older SSH protocol versions (particularly SSHv1) contain known vulnerabilities. Ensure your server only uses the latest, most secure version, SSHv2. This is usually the default on modern distributions, but it’s always best to verify explicitly.

In the /etc/ssh/sshd_config file, set:

Protocol 2

Limit Login Attempts (MaxAuthTries)

To thwart brute-force attacks, you can limit the number of authentication attempts allowed per connection. Once this limit is exceeded, the SSH connection is dropped.

In the /etc/ssh/sshd_config file, add or modify:

MaxAuthTries 3

This sets the maximum number of attempts to 3. A value too low might frustrate legitimate users, while one too high renders the protection ineffective.

Use AllowUsers and DenyUsers

In addition to AllowUsers, you can use DenyUsers to explicitly deny SSH access to specific users. AllowGroups and DenyGroups work similarly for entire groups. It’s a best practice to use AllowUsers or AllowGroups for stricter control by whitelisting only those who need access, rather than blacklisting those who don’t.

Example of AllowUsers (as seen above) and DenyUsers:

AllowUsers alice bob
DenyUsers guest

Enable Verbose Logging

To facilitate troubleshooting and security monitoring, it’s helpful to enable a more detailed logging level for the SSH service. This provides deeper insight into login events, failed attempts, and other activities—essential for a SIEM (Security Information and Event Management) or EDR (Endpoint Detection and Response) tool like Wazuh to detect anomalies.

In the /etc/ssh/sshd_config file, set:

LogLevel VERBOSE

Verify Configuration with sshd -t

Before restarting the SSH service, it’s crucial to verify the syntax of the configuration file. A typo can lock you out. The sshd -t command runs a syntax check without applying the changes.

sudo sshd -t

If there’s no output, the syntax is correct. If there are errors, messages will indicate the issue and the specific line number in the file.

Final Testing and Service Restart

After verifying the configuration, you can restart the SSH service. It’s highly recommended to keep your current SSH session open while testing the new configuration from another terminal. That way, if the new configuration breaks something, you won’t be locked out and can revert to the previous setup.

sudo systemctl restart sshd

Connect from a new terminal using the new port and settings (e.g., ssh -p 2222 username@ip_address). If the connection succeeds, you can safely close the old session.

Common Pitfalls and Troubleshooting

  • Locked out of the server: The most common issue. If you lose SSH access, your first step is to log in via a direct console (e.g., VMware vSphere Console, OCI Console, KVM) and restore the /etc/ssh/sshd_config.bak file you created earlier. Restart sshd and try again.
  • Firewall issues: If you changed the SSH port but forgot to open it in the firewall, connections will be blocked. Verify your firewall rules (sudo ufw status or sudo firewall-cmd --list-all).
  • SSH key permissions: Private keys must have 600 permissions (chmod 600 ~/.ssh/id_rsa) and the .ssh directory must have 700 permissions (chmod 700 ~/.ssh). On the server, the ~/.ssh/authorized_keys file must also have 600 permissions.
  • sshd -t reports errors: Read the command output carefully. It usually points to the exact line in sshd_config where the syntax error occurred.

[Read also: SSH Hardening on Linux: A Practical Guide for 2026]

Key Takeaways

SSH hardening on Linux isn’t optional; it’s a necessity. Implementing these ten essential configurations will give you much tighter control over server access, significantly reducing the risk of compromise. Disabling root login, enforcing public key authentication, and changing the default port are changes that offer immediate security returns with minimal effort. Every Linux server exposed to the internet should have these configurations in place. To dive deeper into configuration options, check out the sshd_config man page.

Always remember to test changes in a staging environment before pushing to production, and always have a rollback plan. Security is an ongoing process, and staying up to date with best practices is critical for maintaining the integrity of your infrastructure.

Share this article:

Written by

Rosario Giordano

Rosario Giordano is a system administrator and IT consultant specializing in cybersecurity and cloud, with over 20 years of experience managing enterprise Linux infrastructures. His areas of expertise include SSH hardening, Kubernetes platforms, PostgreSQL databases, VMware/ Proxmox virtualization, and compliance with NIS2 and ISO 27001 security frameworks