SSH Security Best Practices: Hardening Your Server and Client

Harden SSH with key authentication, least-privilege access, safer client habits, firewall rules, MFA, and brute-force protection.

SSH Security Best Practices: Hardening Your Server and Client

SSH security best practices matter because SSH is often the front door to your servers. A weak SSH setup can turn one guessed password, stolen key, or trusted-host mistake into full shell access.

You do not need exotic settings to harden SSH well. Start with key-based login, restricted users, no direct root login, careful client behavior, and logs that show you when something is wrong.

Server-Side Security Hardening

Your SSH server configuration (sshd_config) sets the rules for how clients connect and authenticate.

1. Disable Password Authentication

Password authentication is inherently vulnerable to brute-force attacks. Replacing it with SSH key-based authentication is one of the most effective security enhancements you can make.

  • Why: SSH keys are far more complex than passwords and cannot be easily guessed or cracked through brute-force methods. They provide a much stronger form of authentication.

  • How: Edit your sshd_config file (typically located at /etc/ssh/sshd_config) and set PasswordAuthentication no. After making changes, restart the SSH service:

    sudo sshd -t
    sudo systemctl reload sshd
    

    Important: Ensure you have successfully set up and tested SSH key-based authentication before disabling password authentication to avoid locking yourself out.

On some distributions the service is named ssh, not sshd. Use the service name your system provides, and keep an existing session open while testing a new login.

2. Treat Port Changes as Noise Reduction

Changing the default SSH port from 22 can reduce automated scan noise. It is not a substitute for keys, patching, and access control.

  • How: In sshd_config, change the Port directive. For example, to use port 2222:

    Port 2222
    

    Remember to update your firewall rules to allow traffic on the new port and specify the port when connecting from your client:

    ssh -p 2222 user@your_server_ip
    

3. Limit User and Group Access

Control which users and groups are allowed to log in via SSH.

  • AllowUsers and AllowGroups: Use these directives in sshd_config to explicitly specify who can connect.
    AllowUsers admin user1
    AllowGroups sshusers
    
  • DenyUsers and DenyGroups: Alternatively, use these to block specific users or groups.

4. Disable Root Login

Direct root login via SSH should be disabled to prevent attackers from targeting the most powerful account immediately. Instead, users should log in with their own accounts and use sudo for administrative tasks.

  • How: Set PermitRootLogin no in sshd_config.

5. Configure Idle Timeout and Keepalives

Prevent unattended, active SSH sessions from remaining open indefinitely.

  • ClientAliveInterval and ClientAliveCountMax: These server-side settings send null packets to the client at regular intervals to check if the connection is still alive. If the client doesn't respond after ClientAliveCountMax attempts, the server disconnects the session.
    ClientAliveInterval 300  # Send a packet every 5 minutes
    ClientAliveCountMax 2    # Disconnect after 2 missed replies (10 minutes)
    

6. Harden Host Keys

Ensure your server's host keys are protected and properly managed.

  • Permissions: Verify that the host key files (e.g., /etc/ssh/ssh_host_rsa_key) have restrictive permissions (e.g., 600) and are owned by root.
  • Algorithms: Prefer modern host keys such as Ed25519 when your clients support them. Do not delete existing host keys without planning, because clients will see that as a host identity change.
  • Rotation: Rotate host keys deliberately and announce the new fingerprints through a trusted channel.

Client-Side Security Best Practices

Securing your client machine and your SSH keys is just as crucial as server-side hardening.

1. Protect Your Private Keys

Your private SSH key is the gateway to your servers. Treat it with the utmost care.

  • Permissions: Ensure your private key file (e.g., ~/.ssh/id_rsa) has strict permissions (e.g., 600 or 400) so only you can read it.
    chmod 600 ~/.ssh/id_rsa
    
  • Passphrases: Always use a strong passphrase to encrypt your private key. This adds an extra layer of security, requiring the passphrase even if the key file is compromised.
  • Avoid Copying: Do not share your private key with anyone or store it in insecure locations.

2. Use SSH Agent Forwarding Carefully

SSH agent forwarding allows you to use your local SSH keys to authenticate to remote servers without copying your private keys to those servers. While convenient, it can be a security risk if the remote server is compromised.

  • Enable: ssh -A user@your_server_ip
  • Best Practice: Disable agent forwarding by default. Use it only for hosts you trust, and prefer alternatives such as deploy keys, bastion ProxyJump, or short-lived credentials when they fit your workflow.

3. Verify Host Key Fingerprints

When you connect to an SSH server for the first time, your client prompts you to verify the server's host key fingerprint. This helps prevent man-in-the-middle attacks.

  • How: Always verify the fingerprint against a trusted source, such as your cloud console, provisioning logs, or an administrator. If the fingerprint changes unexpectedly, stop and investigate before accepting it.

4. Keep SSH Client Software Updated

Ensure your SSH client software (OpenSSH, PuTTY, etc.) is kept up-to-date to benefit from the latest security patches and features.

Advanced Security Measures

Beyond the fundamental steps, consider these advanced techniques:

1. Multi-Factor Authentication

Add MFA for human SSH access where your environment supports it. This usually combines SSH keys with a one-time code, push approval, or hardware-backed authentication.

  • Tools: PAM modules, Duo, authenticator apps, and hardware security keys can all be part of an SSH MFA design.

2. Fail2ban

Fail2ban scans logs for repeated failed authentication attempts and can add temporary firewall blocks for the source IP. Log paths vary by distribution; Debian and Ubuntu commonly use /var/log/auth.log, while many RHEL-family systems log through journald or /var/log/secure.

  • Installation: Typically available via package managers (sudo apt install fail2ban or sudo yum install fail2ban).
  • Configuration: Configure jails in /etc/fail2ban/jail.local to monitor SSH logs and define ban times and thresholds.

3. Firewall Configuration

Employ a firewall (like ufw, firewalld, or iptables) to restrict access to your SSH port (whether default or custom) only from trusted IP addresses or ranges.

  • Example (ufw):
    sudo ufw allow from trusted_ip to any port 22
    sudo ufw enable
    

Takeaway

Securing SSH is an ongoing habit. Use key-based authentication, disable direct root login, restrict who can connect, protect your private keys, and verify host fingerprints. Then add firewall limits, MFA, and brute-force protection where the risk justifies the extra setup.