Spain · 2026 World Cup champions
AXTO
EngineeringJuly 21, 2026· 8 min read

SSH Hardening: The Checklist That Blocks 99% of Drive-By Attacks

Every internet-facing server gets brute-forced within minutes of boot. Fifteen minutes of SSH configuration ends the conversation.

Expose port 22 to the internet and the login attempts begin within minutes — automated, global, and relentless. None of them succeed against a hardened configuration, and hardening takes a quarter of an hour.

The non-negotiables

Keys only: PasswordAuthentication no. Password guessing is the entire business model of SSH botnets; removing passwords removes the market. Root stays home: PermitRootLogin no — log in as a user, escalate with sudo, keep the audit trail. Modern keys: ed25519 over aging RSA defaults.

The strong upgrades

Restrict who: AllowUsers or AllowGroups turns 'any valid account' into a short list. Restrict where, if your admins have stable networks: firewall port 22 to known ranges or behind a VPN/bastion. Rate-limit the rest with fail2ban or nftables connection limits, so even the doorknob-rattling costs the attacker time.

The often-forgotten

Audit authorized_keys everywhere — old laptops, departed contractors, and forgotten automation live in those files; each entry is a permanent credential someone once issued and nobody reviews. Alert on success, not just failure: the login that matters is the successful one from a country where you have no admins, at an hour when nobody works. That single alert has caught more real intrusions than any signature engine.

None of this requires new software — just decisions. Make them once, template them into your provisioning, and every future server is born hardened.

How the drive-by attacks actually work

The constant stream of failed logins in an internet-facing server's authentication log comes from automated scanners. They sweep large ranges of addresses looking for open SSH ports, then try lists of common usernames and passwords, leaked credentials and default accounts left by appliances and cloud images. Most are unsophisticated and fully automated; their success depends entirely on finding the occasional server that still accepts weak passwords.

Understanding this matters because it tells you where to spend effort. Against automated guessing, removing password authentication is decisive. Against a targeted attacker who has stolen a key from a developer's laptop, other controls matter more: limiting which accounts can log in, alerting on unusual successful logins and keeping keys short-lived.

A hardened configuration, explained line by line

A sensible baseline for the server configuration is short. Set PasswordAuthentication and KbdInteractiveAuthentication to no so that only keys are accepted. Set PermitRootLogin to no, so that administrators log in as themselves and use sudo, which records who did what. Use AllowGroups to restrict logins to a dedicated group of administrators. Keep MaxAuthTries low so that each connection gets only a few attempts. Disable X11Forwarding and, unless you need them, agent and TCP forwarding, which can turn a compromised session into a pivot point. Set LoginGraceTime to a short value so idle unauthenticated connections are dropped quickly.

After changing the configuration, validate it with the server's built-in test mode before reloading, and keep an existing session open while you test a new login. Locking yourself out of a remote server is the most common hardening mistake.

Keys done properly

Generate keys with a modern algorithm such as Ed25519 and protect them with a passphrase. Keep private keys on the devices where people work, ideally in hardware such as a security key or the secure enclave of a laptop, which prevents them from being copied even if the device is compromised. Use one key per person and per device rather than sharing keys across a team, so that revoking access for one person or one lost laptop does not affect everyone else.

Record which public key belongs to whom. A comment on each entry in authorized_keys with the owner's name and the date is a simple habit that makes later audits possible.

SSH certificates for teams

As a team grows, managing authorized_keys files on every server becomes error-prone. SSH certificates solve this elegantly. An internal certificate authority signs users' public keys with a validity period — often a working day — and servers are configured to trust that authority instead of individual keys. Access then expires automatically, offboarding requires no server changes and every certificate can carry the user's identity for auditing. Several open-source and commercial tools issue certificates after the user signs in with the organization's identity provider and multi-factor authentication.

Bastion hosts and alternatives to open ports

The strongest way to protect SSH from internet scanning is not to expose it at all. A bastion host — a single, heavily monitored entry point — can be the only machine reachable from outside, with all other servers accepting SSH only from it. Alternatively, a VPN or an identity-aware access proxy can make SSH reachable only to authenticated users. Some cloud platforms offer session managers that provide shell access through their API without any open inbound port. Each of these reduces the attack surface from the whole internet to a handful of authenticated people.

Logging and alerting that catch real intrusions

Failed logins are noise; successful ones are signal. Forward authentication logs to a central system and alert on the events that matter: a successful login from a new country or network, a login at an unusual hour, a login by an account that rarely uses SSH, a new key added to an authorized_keys file and sudo use by an unexpected account. Keep these logs off the server, because an intruder with root access will often try to erase them.

Automating the baseline

Hardening by hand does not scale and drifts over time. Put the configuration into your provisioning templates or configuration-management tool so that every new server starts hardened, and run a periodic check that compares each server's effective configuration with the baseline. Combine it with automatic security updates for the SSH server itself, which receives important fixes from time to time.

Emergency access

Strict configurations need a recovery path. Keep a documented break-glass procedure: the cloud provider's serial or recovery console, an out-of-band management interface for physical servers, or a sealed emergency key stored securely and monitored for use. Test it occasionally, because the moment you need it is the worst moment to discover it does not work.

A fifteen-minute checklist

Disable passwords and root login, restrict logins to an administrators group, limit authentication attempts, turn off forwarding you do not use, confirm that every authorized key has a known owner and remove the rest, forward logs and alert on unusual successful logins, enable automatic security updates and, where possible, close port 22 to the internet behind a bastion, VPN or access proxy. Fifteen minutes of work removes an entire category of attacks for the life of the server.

Port changes and other half-measures

Moving SSH to a non-standard port is a popular suggestion. It does reduce the volume of automated noise in the logs, which can make real events easier to spot, but it is not a security control: scanners find services on unusual ports quickly, and a targeted attacker will not be slowed at all. Treat it, at most, as housekeeping on top of the real measures. The same applies to hiding version banners. What actually protects the server is key-only authentication, a short list of allowed accounts, network restrictions and good alerting.

Protecting the client side

Server hardening means little if the keys on administrators' laptops are easy to steal. Encourage passphrases and hardware-backed keys, keep laptops encrypted and updated, and be careful with agent forwarding, which allows a compromised intermediate server to use your keys while you are connected. When you need to reach internal machines through a bastion, use the ProxyJump option instead of forwarding the agent. Keep the known_hosts file meaningful by verifying host keys the first time you connect, ideally through fingerprints published in your documentation or via SSH certificates for hosts.

Reviewing access over time

Hardening is a state that decays. People change roles, contractors finish projects and laptops are replaced. Schedule a quarterly review of who can log in to each class of server, which keys or certificates they use and which accounts have sudo rights. Remove anything without a current owner and purpose. If you use certificates with short lifetimes, this review becomes much easier, because access that is not renewed simply disappears.

Multi-factor authentication for SSH

For the most sensitive servers, a second factor adds meaningful protection against stolen keys. Options include hardware security keys that the SSH client uses directly for authentication, certificate-based access issued only after the user completes multi-factor sign-in with the identity provider, and server-side modules that request a one-time code. Hardware-backed keys are the simplest and strongest choice for small teams: the private key never leaves the device, and every login requires a physical touch, which defeats remote theft.

The bottom line

SSH is one of the oldest and most reliable tools in system administration, and it can be made very hard to abuse with a handful of decisions. Make those decisions once, encode them in templates and review access regularly, and the endless scanning in your logs becomes what it should be: background noise with no chance of success.

Run AI on your own terms

AXTO gives you world-class AI apps and self-hosted editions — on your own keys, your own data.