What the attack traffic actually looks like
Every server with a public address and port 22 open receives credential attempts continuously. This is not targeted; it is botnets working through address space. On a typical internet-facing server the volume runs to thousands of attempts a day, and it starts within minutes of the port opening.
The overwhelming majority fail and are harmless noise. Two things in that stream matter: the attempt that succeeds, and the pattern that indicates someone is working through a credential list they have reason to believe in.
Where per-IP threshold blocking runs out
The standard model counts failures per source address and bans that address once it crosses a limit inside a window. Against a single noisy host this works well and is worth having.
It has a structural limit. If an attacker spreads attempts across a large pool of addresses, one or two tries each, no single address ever reaches the threshold. Your logs fill with failures, every jail reports healthy, and the ban count stays at zero. No combination of findtime and maxretry changes this, because the model is counting the wrong thing.
The second gap is what happens after success. A threshold tool bans failures. Once credentials work, the session is a normal authenticated login and there is nothing left for it to count.
How SecAI handles it
The agent parses SSH authentication events on the server, handling both the classic file location and the journald-forwarded format that modern distributions use, and reports them continuously to the platform rather than only counting locally.
Blocking is applied using the tooling already present: fail2ban, CrowdSec, or iptables and ufw directly. Because the decision is made on the pattern rather than on a per-address counter, thinly distributed attempts are visible as one campaign rather than as unrelated single failures.
What one server learns is applied across your fleet, so an address that attacked one machine can be blocked on the others before it reaches them.
The part that matters most: after a successful login
- New user accounts, or an existing account gaining new group membership.
- New authorized_keys entries, which is the most common way persistent access is retained after a password compromise.
- Changes to sshd_config and its drop-in directory, for example password authentication being quietly re-enabled.
- Privilege escalation: sudoers changes, new setuid binaries, unexpected capabilities on executables.
- New cron entries or systemd units, which is where persistence usually lives.
- Processes and outbound connections that do not fit the server baseline.
Not getting locked out of your own server
Automatic blocking that can lock out the administrator is worse than no automatic blocking, because it will eventually fire during an incident when access matters most.
Your own servers and administrator IP addresses are held on a trusted list and are exempt from automatic blocking. Every block is recorded and reversible from the dashboard.
What this does not replace
Key-based authentication with passwords disabled remains the single highest-value change you can make, and monitoring is not a substitute for it. The same is true of not exposing SSH to the whole internet where a bastion or a VPN is practical.
What monitoring adds is the answer to what happens when those controls are bypassed rather than absent: a stolen key, a compromised laptop, a colleague who re-enabled password auth for an afternoon.