Exposed SSH: Securing Port 22 on the Internet
SSH exposed to the internet receives constant automated attacks. While SSH is more secure than RDP by design, password-based SSH authentication is routinely compromised. Every internet-facing SSH server is being scanned and attacked right now.
- 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 allowlistProtocol 2 ← Modern protocol onlySSH key authentication is exponentially more secure than passwords:
- Keys are typically 2048-4096 bits—impossible to brute force
- 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 |
Related Security Guides
SSH exposure is often found alongside other attack surface issues. Review these related guides:
- 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.
- EOL Software Guide — Outdated OpenSSH versions with known CVEs require the same urgency as EOL software.
- Attack Surface Monitoring Guide — Learn how to continuously monitor for new SSH exposures before attackers find them.
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