Your SSH log has thousands of failed logins from addresses you have never heard of, so you install fail2ban, the noise stops, and the problem feels solved. It is a sensible move. It is also only a small part of what protecting SSH means.
What fail2ban actually does
Fail2ban’s own README describes it as a tool to “ban hosts that cause multiple authentication errors.” It scans log files such as /var/log/auth.log and, when an address fails too often, adds a firewall rule that rejects new connections from it for a set time.
The stock settings in its jail.conf are modest: a bantime of 10 minutes, a findtime of 10 minutes and a maxretry of 5. The sshd jail uses those defaults, and jails are switched off until you enable them. So out of the box, one address gets five wrong guesses in ten minutes, then a ten-minute timeout, then five more.
That is real friction against a lazy bot on a single address. It is not a wall.
Where fail2ban stops
It cannot fix weak authentication. The README says so itself: fail2ban “cannot eliminate the risk presented by weak authentication,” and recommends two-factor or public/private key authentication for services you want to protect. A tool that counts failed passwords has little to offer once the password is the weak point.
It reacts after the attempt. Fail2ban reads the log, so the connection and the guess have already reached sshd. It limits how many guesses one address gets. It does not stop the first ones.
It watches addresses, not the whole attack. A ban is per address. An attacker who spreads attempts across many sources, or tries one password per account, may never reach your threshold. CISA’s ransomware guide names password spraying alongside brute force, and tells you to log and monitor for both.
It leaves the port open. The service still answers, so anything that goes wrong before login, such as a flaw in the daemon, is outside fail2ban’s view. It never sees a failed login because there is no login yet. The same reasoning applied in is it safe to expose RDP to the internet: a strong gate on the front does not help if the lock itself has a bug.
It can lock out the wrong people. A colleague who mistypes a password a few times, or a whole office behind one shared address, can be banned. Plan a way in that does not depend on that address.
What to do in sshd itself
Most of the protection you want is in sshd_config, and it costs nothing. The OpenBSD manual documents the options:
| Setting | What it does | Default |
|---|---|---|
PasswordAuthentication |
Allows password logins | yes |
PubkeyAuthentication |
Allows public-key logins | yes |
PermitRootLogin |
Controls direct root login | prohibit-password |
MaxAuthTries |
Attempts allowed per connection | 6 |
LoginGraceTime |
Time to log in before disconnect | 120 seconds |
MaxStartups |
Concurrent unauthenticated connections | 10:30:100 |
The key row is the first one. Password authentication is on by default. Set PasswordAuthentication no, keep keys, and there is no password left to guess. Fail2ban then goes from guarding your login to tidying your logs.
Keys are not magic either: they need to be protected, rotated and removed when people leave. CISA’s guidance for ransomware defence asks for phishing-resistant MFA on services that reach critical systems, and account lockout plus monitoring of login attempts. Treat key-only login as the floor, not the ceiling.
What fail2ban does and doesn’t cover
- Reads sshd logs
- Bans repeat offenders
- Cuts guessing from one address
- Quiets the logs
- Key-only logins
- MFA on admin access
- Restricted source addresses
- Fewer open ports
The step that makes the rest matter less
CISA’s exposure guidance is blunt: “Close or restrict access to ports that do not have a documented operational need.” For assets that must stay reachable, it adds patching, a jump host, monitoring and MFA. Its ransomware guide is shorter still: “Do not expose services, such as remote desktop protocol, on the web.” The reasoning transfers to SSH, which sits on the same list of remote access ports CISA says to check.
So the order of effort is roughly:
- Switch off password logins and enforce keys.
- Add MFA for administrators.
- Restrict source addresses with a firewall rule or allow-list, where your team has stable addresses.
- Keep fail2ban if you want it, for log hygiene and throttling.
- Close the listener on servers that do not need to accept connections from the internet at all.
Scanners find open ports quickly, as covered in how attackers find open ports. Step five is the only one that removes the target rather than defending it.
Where SSHepherd fits
If a server has no business listening on the internet, SSHepherd® closes the SSH port. The server and your administrators each connect outward to a broker, which joins them only for authorised identities, so a scan finds no port 22 to try and fail2ban has no failed logins to count. Sessions can be monitored, recorded and ended on demand, and a server can be protected in about ten minutes without re-architecting the network. See the SSHepherd page for the detail.
The bottom line
Fail2ban is a good, cheap layer that slows guessing from a single address, but it is not enough on its own because it leaves SSH open and reacts after the attempts. Turn off passwords, add MFA, restrict who can reach the port, and close it altogether wherever you can.