Exposed SSH: Detection, Hardening, and Continuous Monitoring
SSH on port 22 is not automatically critical — the configuration decides. Password authentication enabled, root login permitted, or an OpenSSH version with known CVEs makes an internet-facing SSH server a P1. Move to key-only authentication, set PermitRootLogin no, add rate limiting, and confirm the setting has not drifted back.
You hardened SSH once — but is it still hardened? SSH exposed to the internet receives constant automated attacks, and configurations drift over time. Password authentication gets re-enabled during troubleshooting, new servers deploy with default settings, and firewall rules change. Continuous monitoring detects when your SSH security posture degrades.
- Why exposed SSH attracts immediate automated attacks
- The difference between secure and insecure SSH configurations
- How to harden SSH for internet exposure
- When SSH exposure is acceptable vs. when it's P1
- Key-based authentication and MFA requirements
Risk Assessment: When Is SSH Exposure a P1?
Unlike RDP, SSH exposure isn't automatically a P1. The risk depends heavily on configuration:
SSH with password authentication enabled and exposed to the internet is a P1.Password-based SSH is routinely compromised through brute force and credential stuffing. Attackers have massive password lists and botnets dedicated to SSH brute forcing.
SSH with key-only authentication but missing other hardening measures (root login allowed, outdated version, weak key algorithms) is P2-P3 depending on specifics.
SSH with key-only auth, disabled root login, current version, and strong algorithms is the lowest risk. Still monitor for attacks and consider VPN/bastion architecture for sensitive systems.
Quick Assessment Checklist
| Configuration | Risk Level | Priority |
|---|---|---|
| Password authentication enabled | Critical | P1 |
| Root login permitted | High | P1 |
| Outdated OpenSSH version (known CVEs) | High | P1 |
| Weak key exchange algorithms | Medium | P2 |
| No fail2ban or rate limiting | Medium | P3 |
| Key-only, hardened, current version | Low | P4 |
The Attack Landscape
Every SSH server on the internet receives thousands of login attempts per day.This isn't targeted—it's automated botnets scanning the entire IPv4 space continuously. Within minutes of exposing port 22, your server will be discovered and attacked.
Attack Volume Reality
- Average internet-facing SSH server: thousands to tens of thousands of failed login attempts daily
- Peak attack volume: significantly higher during active botnet campaigns
- Time to first attack after exposure: often within minutes of going online
- Common usernames targeted: root, admin, ubuntu, test, guest, user, oracle, postgres
Attack Types
- Brute force: Trying common passwords (123456, password, admin123)
- Credential stuffing: Using leaked username/password pairs from breaches
- Dictionary attacks: Systematic password guessing with wordlists
- Exploit attempts: Targeting known SSH vulnerabilities
- Post-compromise: Crypto mining, botnet recruitment, lateral movement
Once attackers gain SSH access, typical actions include:
- Installing cryptocurrency miners (immediate monetization)
- Adding the server to botnets for DDoS or further scanning
- Pivoting to internal network resources
- Exfiltrating data or credentials
- Establishing persistence for later ransomware deployment
Secure vs. Insecure SSH Configuration
Insecure Configuration (Common Defaults)
PasswordAuthentication yes ← Allows brute forcePermitRootLogin yes ← Direct root accessPermitEmptyPasswords yes ← Critical vulnerability# No MaxAuthTries limit ← Unlimited attemptsSecure Configuration
PasswordAuthentication no ← Key-onlyPermitRootLogin no ← No direct rootPubkeyAuthentication yes ← Require keysMaxAuthTries 3 ← Limit attemptsAllowUsers specificuser ← Explicit allowlistKexAlgorithms / Ciphers ← Pin to modern algorithmsSSH key authentication is exponentially more secure than passwords:
- Ed25519 or RSA 3072-4096 keys—not brute-forceable in practice
- No password to phish, stuff, or guess
- Private key never leaves your machine
- Can require passphrase on key for additional security
Immediate Hardening Steps
If you've discovered exposed SSH with password authentication, take these steps immediately:
Step 1: Assess Current Risk (15 minutes)
- Check if password authentication is enabled:
grep PasswordAuthentication /etc/ssh/sshd_config - Check if root login is permitted:
grep PermitRootLogin /etc/ssh/sshd_config - Review recent authentication attempts:
grep sshd /var/log/auth.log | tail -100 - Check for successful logins from unknown IPs
Step 2: Disable Password Authentication (30 minutes)
Ensure you have SSH key access configured before disabling password authentication.Test key-based login in a separate session before making changes. Locking yourself out of a remote server is a real risk.
- Generate SSH key pair on your local machine (if you don't have one)
- Copy public key to server's authorized_keys
- Test key-based login in new terminal (keep existing session open)
- Edit /etc/ssh/sshd_config: set
PasswordAuthentication no - Set
PermitRootLogin no - Restart SSH service:
sudo systemctl restart sshd - Verify password login is rejected
Step 3: Implement Rate Limiting (30 minutes)
- Install fail2ban:
sudo apt install fail2ban - Configure SSH jail with aggressive ban settings
- Consider iptables rate limiting as additional layer
Step 4: Check for Compromise (1 hour)
- Review all successful SSH logins during exposure period
- Check for new user accounts or authorized_keys modifications
- Look for unexpected processes, especially crypto miners
- Check cron jobs and systemd services for persistence
- Review network connections for suspicious outbound traffic
Long-Term Security Architecture
Option 1: Bastion Host / Jump Box
Route all SSH access through a hardened bastion host:
- Single, hardened entry point with maximum logging
- Internal servers not directly exposed to internet
- MFA on bastion authentication
- Session recording for audit
Option 2: VPN-Only Access
Require VPN before SSH is accessible:
- SSH port only accessible from VPN IP ranges
- VPN requires MFA
- Defense in depth—two authentication layers
Option 3: Zero Trust SSH
Modern identity-aware access:
- Certificate-based SSH authentication
- Short-lived certificates issued after MFA
- No static keys to manage or compromise
- Examples: Teleport, Boundary, Cloudflare Access
Any administrative access to production systems should require MFA.This includes SSH. Options include:
- MFA at VPN/bastion level (most common)
- PAM-based MFA (Google Authenticator PAM module)
- Certificate-based auth with MFA-gated certificate issuance
Monitoring & Detection
What to Monitor
- Failed authentication attempts: Baseline and alert on spikes
- Successful logins from new IPs: Especially for privileged accounts
- Logins outside business hours: Unusual access patterns
- Geographic anomalies: Logins from unexpected countries
- Configuration changes: Modifications to sshd_config or authorized_keys
Log Sources
/var/log/auth.log(Debian/Ubuntu)/var/log/secure(RHEL/CentOS)- Systemd journal:
journalctl -u sshd - Centralized SIEM for correlation across hosts
Alert Thresholds
| Event | Threshold | Response |
|---|---|---|
| Failed auth attempts (single IP) | >10 in 5 minutes | Auto-block IP (fail2ban) |
| Failed auth attempts (aggregate) | >100 in 1 hour | Alert security team |
| Successful root login | Any | Immediate alert |
| Login from new country | Any | Alert and verify |
| authorized_keys modified | Any | Immediate alert |
Continuous SSH Monitoring: Detecting Configuration Drift
Hardening SSH is a point-in-time action. Without continuous monitoring, configurations drift: a colleague re-enables password auth to troubleshoot a login issue, a new server deploys with default settings, or a firewall rule change unexpectedly exposes port 22 on a production system.
Configuration drift is how security breaks quietly. External monitoring detects these changes by scanning from the outside — the same perspective an attacker has — and alerting when your SSH security posture degrades.
- New SSH exposure: Port 22 appearing on an asset where it wasn't before
- Authentication method changes: Detecting when password auth is re-enabled
- Version changes: Tracking OpenSSH version across scans to catch downgrades
- Cipher suite drift: Identifying when secure configurations weaken
- Banner changes: Detecting service modifications that may indicate compromise
How DriftAlarm Helps
DriftAlarm's drift detection engine monitors your SSH configurations continuously from the outside. When any SSH-related change occurs — new exposure, version change, or configuration drift — you get an alert with full context.
Related Security Guides
SSH exposure is often found alongside other attack surface issues. Review these related guides:
- Configuration Drift Guide — Understand how security configurations change over time and why drift detection is essential for ongoing SSH security.
- TLS/SSL Drift Guide — Certificate and cipher suite changes often affect the same servers running SSH — monitor both protocols.
- Exposed RDP Guide — RDP (port 3389) is even more dangerous than SSH when exposed. If you found SSH, check for RDP too.
- Exposed Admin Panels Guide — Web-based admin interfaces (Jenkins, phpMyAdmin, etc.) are often found on the same servers.
- Attack Surface Monitoring Guide — Learn how to continuously monitor for new SSH exposures before attackers find them.
- Exposed SSH Monitoring Solution — See how DriftAlarm continuously monitors for exposed SSH with automated drift alerts.
Summary: SSH Hardening Checklist
- Disable password authentication
- Disable root login
- Use SSH key authentication only
- Keep OpenSSH updated
- Implement fail2ban or equivalent
- Use AllowUsers/AllowGroups directives
- Disable empty passwords
- Set MaxAuthTries to 3
- Use bastion host or VPN for access
- Implement MFA for administrative access
- Centralize and monitor SSH logs
- Consider certificate-based authentication
Frequently Asked Questions
Is it safe to leave SSH open to the internet?
It can be, if the configuration is right. SSH restricted to key-only authentication, with root login disabled, a current OpenSSH build, and strong key exchange algorithms is the lowest-risk case. Exposed SSH with password authentication enabled is a P1, because password-based SSH is routinely broken by brute force and credential stuffing. For sensitive systems, put a bastion host or VPN in front regardless.
How do I check if SSH password authentication is enabled?
Run grep PasswordAuthentication /etc/ssh/sshd_config on the host, and check PermitRootLogin the same way. Because Match blocks and drop-in files under /etc/ssh/sshd_config.d/ can override those lines, confirm the effective setting by running sshd -T and reading its passwordauthentication line. Then review recent attempts in /var/log/auth.log or /var/log/secure.
How do I disable SSH password login without locking myself out?
Keep your current session open the entire time. Generate a key pair locally, copy the public key into the server's authorized_keys, then open a second terminal and confirm key-based login works before changing anything. Only then set PasswordAuthentication no and PermitRootLogin no and restart the service. Verify from a third session that password login is rejected.
Why does my SSH server get thousands of failed login attempts?
That volume is background noise, not a targeted attack. Automated botnets scan the entire IPv4 space continuously, so any internet-facing SSH server sees thousands of failed attempts a day, usually against common usernames like root, admin, ubuntu and postgres. With key-only authentication the attempts cannot succeed. Use fail2ban to trim log volume, and alert on successful logins rather than failed ones.