During a recent audit of a Tier-4 data center in Mumbai, I observed over 45,000 failed SSH login attempts targeting a single bastion host within a 24-hour window. The majority of these attempts originated from botnets specifically targeting Indian IP ranges assigned to NIXI and major local ISPs. This is not an anomaly; it is the baseline for any internet-facing Linux instance in the current threat landscape, often requiring secure SSH access for teams to mitigate direct exposure.
Recent vulnerabilities like CVE-2024-6387 (regreSSHion) have demonstrated that even the most trusted protocols are susceptible to race conditions that lead to remote code execution. In Indian enterprise environments, where the Digital Personal Data Protection (DPDP) Act 2023 now mandates strict access controls and auditability, relying on default SSH configurations is a liability that can lead to both technical compromise and regulatory penalties.
What is Security Hardening?
Security hardening is the process of reducing the attack surface of a system by eliminating unnecessary functions, services, and access points. It moves a system from its "out-of-the-box" state—which prioritizes ease of use—to a "production-ready" state that prioritizes defense.
In my experience, hardening is not a one-time setup but a continuous configuration lifecycle. We start by stripping away the defaults and then layering defensive controls that increase the cost of an attack for the adversary, similar to the strategies used for detecting industrialized botnets in complex networks.
What is SSH Hardening?
SSH (Secure Shell) hardening specifically targets the sshd daemon and its underlying authentication mechanisms. While SSH provides encrypted communication, the default settings on distributions like Ubuntu, CentOS, or Debian often allow legacy protocols, weak ciphers, and password-based authentication.
Hardening SSH involves reconfiguring the /etc/ssh/sshd_config file, modifying PAM (Pluggable Authentication Modules) stacks, and enforcing cryptographic standards that resist modern decryption and brute-force techniques.
Why Default SSH Configurations are a Security Risk
Most default Linux installations permit root login via password. This provides a clear target for automated credential stuffing attacks. If an attacker gains access to the root account, the entire server—and potentially the internal network it resides in—is compromised instantly.
Default configurations also frequently support older versions of the SSH protocol and weak Message Authentication Codes (MACs). These are vulnerable to downgrade attacks such as "Terrapin" (CVE-2023-48795), which allows attackers to manipulate sequence numbers during the handshake to disable security extensions.
Protecting Against Brute Force Attacks
Brute force attacks against Indian infrastructure often leverage leaked credentials from local government and educational portal breaches. We see high-frequency targeting of the admin, root, and ubuntu usernames.
By implementing rate limiting and mandatory key-based authentication, we effectively neutralize 99% of automated brute-force attempts. A password can be guessed; a 256-bit Ed25519 private key cannot be practically brute-forced with current computing power.
Preventing Unauthorized Root Access
Direct root login is the single greatest risk factor in SSH security. When root login is enabled, an attacker only needs to solve for one variable: the password. By disabling direct root access, we force an attacker to first compromise a low-privileged user account and then attempt local privilege escalation, providing more opportunities for our detection systems to trigger alerts.
Mitigating Man-in-the-Middle (MITM) Risks
MITM attacks in SSH typically occur during the initial key exchange. If an attacker can intercept this exchange, they can present a rogue host key. Hardening includes enforcing strict host key checking and using modern Key Exchange (KEX) algorithms like curve25519-sha256.
Disabling Root Login via SSH
The first step in any hardening checklist is to verify the current state of the sshd configuration. I use the following command to audit the active settings without reading the entire config file:
$ sshd -T | grep -E 'permitrootlogin|passwordauthentication|pubkeyauthentication|authenticationmethods'
permitrootlogin prohibit-password passwordauthentication yes pubkeyauthentication yes authenticationmethods (unset)
To disable root login and enforce a non-privileged user entry point, edit /etc/ssh/sshd_config and set:
PermitRootLogin no
After making this change, you must restart the service. I always recommend testing the configuration syntax before restarting to avoid being locked out:
$ sudo sshd -t
$ sudo systemctl restart ssh
Transitioning from Passwords to SSH Key-Based Authentication
I recommend moving away from RSA keys entirely. Ed25519 keys are shorter, faster, and offer higher security margins. Generate a hardened key pair with a significant number of KDF (Key Derivation Function) rounds to resist offline cracking of the private key passphrase:
$ ssh-keygen -t ed25519 -a 100 -f ~/.ssh/id_ed25519_hardened -C "admin@enterprise-node-01"
Once the key is generated, transfer it to the server and disable password authentication in sshd_config:
PasswordAuthentication no
AuthenticationMethods publickey
Changing the Default SSH Port (Port 22)
While changing the port from 22 to a non-standard port (e.g., 2222 or 4848) is "security by obscurity," it is highly effective at reducing log noise. In Indian data centers, I've seen this reduce the size of auth logs by 90%, making it easier for SIEM tools to identify genuine targeted attacks rather than generic botnet probes.
# In /etc/ssh/sshd_config
Port 4848
Note that if you change the port, you must update your firewall rules (UFW, firewalld, or cloud security groups in AWS/Azure) immediately.
Disabling Empty Passwords and Weak Authentication Methods
Ensure that the system explicitly rejects empty passwords and legacy Rhosts authentication. These are often left as "yes" in older templates used by some local VPS providers.
PermitEmptyPasswords no
IgnoreRhosts yes HostbasedAuthentication no
Implementing Multi-Factor Authentication (MFA) for SSH
For Indian enterprises complying with the DPDP Act 2023, MFA is no longer optional for administrative access. We can implement Time-based One-Time Password (TOTP) using the Google Authenticator PAM module.
First, install the required library:
$ sudo apt update && sudo apt install libpam-google-authenticator -y
Run the configuration tool as the user who will be logging in. Use the -t (TOTP), -d (disallow reuse), -f (force save), and -r (rate limit) flags:
$ google-authenticator -t -d -f -r 3 -R 30 -W
This generates a QR code. Scan this into your authenticator app. Next, modify the PAM configuration at /etc/pam.d/sshd. You must comment out the standard password inclusion and add the authenticator module:
# Standard common-auth inclusion (comment this out if using ONLY keys + MFA)@include common-auth
Add this to the top of the file
auth [success=done default=ignore] pam_google_authenticator.so nullok auth required pam_deny.so
Finally, update sshd_config to require both the public key and the keyboard-interactive (MFA) step:
KbdInteractiveAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
Restricting User Access with AllowUsers and AllowGroups
Instead of allowing every system user to attempt SSH login, define a whitelist. This is a critical defense-in-depth measure. If a service account (like www-data or postgres) is compromised, this setting prevents the attacker from using that account to pivot via SSH.
AllowUsers sysadmin-rahul devops-priya
AllowGroups ssh-access-group
Configuring Idle Timeout Intervals to Prevent Persistent Sessions
Unattended SSH sessions are a major risk in shared office environments. We enforce server-side termination of idle connections by setting the ClientAliveInterval and ClientAliveCountMax.
# Terminate after 5 minutes (300 seconds) of inactivity
ClientAliveInterval 300 ClientAliveCountMax 0
Using Fail2Ban to Automate IP Blocking
Fail2Ban monitors log files for repeated failed login attempts and updates firewall rules to ban the source IP addresses. For Indian servers, I recommend aggressive banning policies.
Create a local jail configuration:
# /etc/fail2ban/jail.local
[sshd] enabled = true port = 4848 filter = sshd logpath = /var/log/auth.log maxretry = 3 bantime = 1d findtime = 10m
This configuration bans an IP for 24 hours if they fail three times within a 10-minute window.
Regularly Auditing SSH Access Logs
Under CERT-In directions, Indian organizations must maintain logs for 180 days. To ensure these logs contain actionable forensic data, increase the log verbosity in sshd_config:
LogLevel VERBOSE
VERBOSE level captures the fingerprint of the SSH key used, which is vital for non-repudiation. To audit recent login attempts manually, use ausearch:
$ sudo ausearch -m USER_LOGIN,USER_AUTH -ts recent -i
For a quick view of failed attempts by IP, this one-liner is effective:
$ journalctl -u ssh --since '24 hours ago' | grep 'Failed password' | awk '{print $11}' | sort | uniq -c | sort -nr
Keeping OpenSSH and System Packages Updated
The "regreSSHion" vulnerability (CVE-2024-6387) reminded us that even a perfectly configured sshd_config cannot protect against flaws in the binary itself. Reviewing OpenSSH security advisories and setting up unattended-upgrades is critical for Indian enterprise environments.
$ sudo apt install unattended-upgrades
$ sudo dpkg-reconfigure --priority=low unattended-upgrades
Enforcing Strong Encryption Ciphers and MACs
To mitigate attacks like Terrapin and ensure compliance with modern cryptographic standards, we must explicitly define which ciphers the server will accept. This prevents the client from negotiating a weak or legacy algorithm.
Add the following to your sshd_config:
# Supported KEX algorithms
KexAlgorithms curve25519-sha256,[email protected],diffie-hellman-group16-sha512,diffie-hellman-group18-sha512
Supported Ciphers
Ciphers [email protected],[email protected],[email protected]
Supported MACs
Forensic Compliance and SIEM Integration
In the context of the DPDP Act 2023, the ability to prove who accessed what data is paramount. If your Linux instances are in AWS Mumbai (ap-south-1), you should be streaming these logs to a centralized SIEM (Security Information and Event Management) system like an ELK stack or a local deployment of Wazuh.
For forensic readiness, I implement a custom auditd rule to track every modification to the SSH configuration and the authorized keys files:
# /etc/audit/rules.d/ssh_audit.rules
-w /etc/ssh/sshd_config -p wa -k sshd_config_changes -w /home/sysadmin/.ssh/authorized_keys -p wa -k auth_keys_changes
This ensures that even if an attacker gains root and tries to hide their tracks by adding their own key, the change is recorded in the immutable audit log.
Final Technical Insight
Hardening is not merely about blocking access; it is about creating a predictable environment. When 99% of your traffic is blocked by key-based authentication and MFA, the remaining 1% of traffic becomes much easier to analyze.
If you are managing a large fleet of servers across Indian regions, do not apply these changes manually. Use an Ansible playbook to enforce this sshd_config across your entire infrastructure to prevent configuration drift.
To verify your current SSH security posture from an external perspective, use the ssh-audit tool:
$ pip install ssh-audit
$ ssh-audit -p 4848
This tool will highlight any remaining weak ciphers or vulnerabilities like Terrapin that your current configuration might still be susceptible to.
