During our recent audit of a Tier-2 MSP infrastructure based in Bengaluru, we identified over 400 instances of OpenSSH 8.9p1 vulnerable to CVE-2024-6387 (regreSSHion). The vulnerability, a race condition in the signal handler, allows unauthenticated remote code execution as root. In the Indian context, where many DevOps teams rely on default OS images from local providers like E2E Networks or Netmagic, these "out-of-the-box" configurations represent a massive, unmitigated attack surface.
What is SSH Hardening and Why is it Essential for Server Security?
SSH hardening is the process of moving beyond the "functional" state of remote access to a "defensible" state. By default, OpenSSH prioritizes compatibility over security, often enabling legacy ciphers and insecure authentication methods to ensure users can connect regardless of their client version. We define hardening as the systematic reduction of this attack surface through cryptographic tightening and identity-centralized access control.
Defining SSH Hardening
Hardening is not a one-time setup but a continuous enforcement of the principle of least privilege. It involves disabling unnecessary features like X11 forwarding, restricting the available ciphers to those that offer Perfect Forward Secrecy (PFS), and transitioning from static, long-lived credentials to ephemeral, identity-based access. In a Zero-Trust framework, we treat every SSH connection as potentially malicious until verified by a short-lived, signed certificate, often managed through secure SSH access for teams.
Common Vulnerabilities in Default SSH Configurations
We frequently observe three critical failures in Indian production environments:
- Static Password Authentication: Still prevalent in legacy internal systems, making them susceptible to brute-force attacks from botnets.
- Shared SSH Keys: A common "Jugaad" practice where entire teams share a single private key stored on a company Google Drive or Slack channel, violating SSH security hardening best practices.
- Weak Key Exchange (KEX) Algorithms: Default configurations often allow SHA-1 based hashes or 1024-bit RSA keys, which are no longer considered secure against modern computational power.
The Importance of Securing Remote Access
Under the Digital Personal Data Protection (DPDP) Act 2023, Indian entities are now legally mandated to implement "reasonable security safeguards" to prevent personal data breaches. A compromised SSH daemon is an entry point for lateral movement. If an attacker gains root access via an unhardened SSH service, the resulting data exfiltration could lead to penalties of up to ₹250 Crore under Section 33 of the Act.
Core SSH Hardening Guidelines: Best Practices for 2024
The first step in any hardening exercise is the deprecation of legacy cryptographic primitives. We observed that many older systems still support ssh-dss or ssh-rsa with SHA-1. These must be explicitly disabled in accordance with OpenSSH Security standards.
Enforcing Strong Cryptographic Algorithms
We recommend using the Ed25519 signature algorithm for keys. It provides better security than RSA 4096-bit while being significantly faster and having shorter key lengths. To enforce this, modify your /etc/ssh/sshd_config to limit the allowed KEX, Ciphers, and MACs.
Restricting to modern, secure primitives
KexAlgorithms curve25519-sha256,[email protected],diffie-hellman-group-exchange-sha256 Ciphers [email protected],[email protected],[email protected] MACs [email protected],[email protected],[email protected]
Limiting User Access and Group Permissions
Never allow all users on a system to have SSH access. We use the AllowGroups or AllowUsers directive to create a strict whitelist. This ensures that even if a service account (like www-data) is compromised, the attacker cannot use it to pivot via SSH.
Only allow members of the 'sysadmin' and 'devops' groups
AllowGroups sysadmin devops
Implementing Multi-Factor Authentication (MFA)
For critical production infrastructure, we enforce MFA using the AuthenticationMethods directive. This requires both a valid SSH key AND a secondary factor (like a TOTP code or a hardware security key).
Enforce Key + Keyboard-Interactive (for TOTP)
AuthenticationMethods publickey,keyboard-interactive
The Ultimate SSH Hardening Checklist
This checklist provides the baseline configuration we use for all high-compliance environments in India.
Disabling Root Login via SSH
Direct root login is a primary target for automated scanners. We disable it entirely, forcing users to log in with their personal accounts and use sudo for administrative tasks. This creates an audit trail linked to a specific identity.
/etc/ssh/sshd_config
PermitRootLogin no
Transitioning from Passwords to SSH Key-Based Authentication
Password authentication is the weakest link in remote access. We disable it globally to mitigate brute-force risks. Ensure your public keys are distributed before applying this change, or you will be locked out of your instance.
Disable password-based logins
PasswordAuthentication no ChallengeResponseAuthentication no UsePAM yes
Changing the Default SSH Port (Port 22)
While "security through obscurity" is not a primary defense, changing the default port from 22 to a high-numbered port (e.g., 2222 or 4822) significantly reduces the noise in your logs. We observed a 95% reduction in automated brute-force attempts on a test node after shifting to port 4434.
Configuring Client Alive Intervals and Idle Timeouts
To prevent orphaned sessions and mitigate the risk of an unattended terminal being hijacked, we implement strict timeouts.
Terminate idle sessions after 5 minutes
ClientAliveInterval 300 ClientAliveCountMax 0
Disabling X11 Forwarding and Port Forwarding
Unless specifically required for a legacy GUI application, X11 forwarding should be disabled as it can be exploited by an attacker to intercept keystrokes on the client side. Similarly, port forwarding can be used for unauthorized tunneling (lateral movement).
X11Forwarding no AllowTcpForwarding no AllowStreamLocalForwarding no GatewayPorts no
Implementing Zero-Trust SSH with Certificate Authorities
The pinnacle of SSH hardening is the move to SSH Certificates. Unlike static keys, certificates have an expiration date and are signed by a trusted internal Certificate Authority (CA). This eliminates the need for authorized_keys management across thousands of servers.
Setting Up an Internal SSH CA
We start by generating a dedicated CA key pair on an offline or highly secured machine.
Generate the CA key
ssh-keygen -t ed25519 -f /etc/ssh/ssh_ca -C "Internal-DevOps-CA"
Signing User Keys
When a developer needs access, they generate a local key and send the public portion to the CA. The CA signs it with a limited Validity Period (e.g., 8 hours for a work shift).
Sign a user's public key with 8 hours of validity
ssh-keygen -s /etc/ssh/ssh_ca -I "dev-user-01" -n ubuntu,ec2-user -V +8h id_ed25519.pub
This command generates id_ed25519-cert.pub. The -n flag specifies which remote usernames the certificate is valid for.
Configuring Servers to Trust the CA
On all target servers, we add the CA's public key to the SSH configuration. This allows the server to verify any certificate signed by that CA without needing the user's individual public key in ~/.ssh/authorized_keys.
Add this to /etc/ssh/sshd_config
TrustedUserCAKeys /etc/ssh/ssh_ca.pub
Conducting an SSH Audit: A Hardening Guide for Compliance
CERT-In mandates that all service providers and corporate entities maintain logs for 180 days. For SSH, this means logging not just the login events, but the specific cryptographic parameters used during the session.
Tools for Auditing SSH Configurations
We use ssh-audit, an open-source tool that scans a target SSH server and identifies weak ciphers, outdated versions, and potential vulnerabilities.
Running an audit against a local server
$ ssh-audit 192.168.1.50
Output will highlight insecure KEX and Ciphers in red
Reviewing the /etc/ssh/sshd_config File
A manual review is necessary to ensure no "shadow" configurations exist in /etc/ssh/sshd_config.d/. We recommend aggregating all configurations into a single, immutable file for production environments.
Analyzing SSH Logs for Brute Force Attempts
In Ubuntu/Debian systems, SSH logs are located in /var/log/auth.log. We use the following command to identify the top 10 IP addresses attempting to brute-force our infrastructure.
grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -nr | head -n 10
For Indian organizations, we recommend feeding these logs into a centralized SIEM or using Fail2Ban to automate the blocking of these IPs at the firewall level.
Automating Security: Using an SSH Hardening Script
Manually hardening 50+ servers is prone to human error. We utilize Ansible to ensure a consistent security posture across multi-cloud environments (AWS, Azure, and local data centers).
Benefits of Using Ansible for Hardening
Ansible allows us to define the "Desired State" of our SSH configuration. If a developer manually changes a setting to "troubleshoot" an issue, the next Ansible run will automatically revert it to the hardened state.
How to Safely Deploy an SSH Hardening Script
When deploying hardening scripts, always use the sshd -t command to test the configuration for syntax errors before restarting the service. A single typo in sshd_config can result in a complete loss of remote access.
Sample Ansible Task for SSH Hardening
- name: Hardening sshd_config
lineinfile: path: /etc/ssh/sshd_config regexp: "^#?{{ item.key }}" line: "{{ item.key }} {{ item.value }}" state: present with_items: - { key: "PermitRootLogin", value: "no" } - { key: "PasswordAuthentication", value: "no" } - { key: "MaxAuthTries", value: "3" } - { key: "LogLevel", value: "VERBOSE" } notify: restart sshd
- name: Validate SSH Config
command: /usr/sbin/sshd -t register: sshd_test failed_when: sshd_test.rc != 0
Top Open-Source Hardening Scripts and Tools
- DevSec SSH Baseline: An InSpec profile that tests your SSH configuration against industry best practices.
- Teleport: A modern replacement for OpenSSH that implements Zero-Trust principles and certificate-based access out of the box.
- Bastion: An Indian-developed open-source tool for managing SSH access in distributed teams.
Maintaining a Hardened SSH Environment
Hardening is a lifecycle, not a project. As new vulnerabilities like regreSSHion emerge, the "hardened" state of yesterday becomes the "vulnerable" state of today.
Regular Security Patching and Updates
We recommend using unattended-upgrades on Debian-based systems specifically for security repositories. This ensures that critical OpenSSH patches are applied within hours of release.
Enable automatic security updates
sudo apt install unattended-upgrades sudo dpkg-reconfigure -plow unattended-upgrades
Continuous Monitoring and Re-Auditing
We integrate SSH auditing into our CI/CD pipeline. Every time a new staging or production environment is spun up via Terraform, a post-deployment script runs ssh-audit. If the server fails to meet the Ed25519/No-Password requirement, the deployment is automatically rolled back.
To verify your current authentication methods and ensure no legacy "backdoors" exist, run the following nmap command against your subnet:
nmap -p 22 --script ssh-auth-methods --script-args='ssh.user=admin'
