InfraRunBook
    Back to articles

    Why Your Server Logs Show Repeated Unauthorized Login Attempts

    Cyber Security for Servers
    Published: Aug 25, 2026
    Updated: Aug 25, 2026

    A troubleshooting guide to the eight most common causes of repeated unauthorized login attempts in server logs, with detection commands and concrete fixes for each.

    Why Your Server Logs Show Repeated Unauthorized Login Attempts

    Symptoms

    You SSH into sw-infrarunbook-01 to check on something unrelated, run a quick

    tail /var/log/auth.log
    out of habit, and there it is again: a wall of failed login attempts, most of them for users that don't exist on the box. Sometimes it's a slow trickle, a handful of attempts an hour from different countries. Other times it's a flood, hundreds of attempts a minute from a single subnet, all trying variations of admin, root, and oracle. Either way, once you notice it, you can't unsee it.

    In my experience, this is one of the most common tickets that gets filed and then immediately dismissed as noise. Sometimes that dismissal is correct. Sometimes it isn't. The trouble is that repeated unauthorized login attempts can mean anything from routine internet background radiation to an active, targeted attack against a specific account that's about to succeed. The log line looks the same either way:

    Aug 25 03:14:02 sw-infrarunbook-01 sshd[19823]: Failed password for invalid user admin from 198.51.100.44 port 51322 ssh2
    Aug 25 03:14:05 sw-infrarunbook-01 sshd[19825]: Failed password for root from 198.51.100.44 port 51410 ssh2
    Aug 25 03:14:09 sw-infrarunbook-01 sshd[19827]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=198.51.100.44 user=root

    Other symptoms that usually show up alongside this: elevated CPU on the box from spawned sshd processes, fail2ban (if it's installed) constantly banning and unbanning the same handful of IP ranges, alerting tools flagging a spike in auth failures, and occasionally a support request from a legitimate user saying "I can't log in, it says too many attempts." Let's go through the actual causes, one at a time, and how to tell them apart.

    Cause 1: Mass internet scanning (the default explanation, and usually the right one)

    The overwhelming majority of unauthorized login attempts against internet-facing servers have nothing to do with you specifically. Botnets and research scanners (Shodan-adjacent crawlers, university projects, and plenty of outright malicious infrastructure) constantly sweep the entire IPv4 address space looking for open port 22, port 3389, or exposed database ports. If your server has a public IP and SSH listening on the default port, you will get scanned within hours of it going live, guaranteed.

    You can confirm this pattern by looking at the diversity of source IPs and usernames being tried:

    grep 'Failed password' /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -20

    If you see dozens of distinct IPs, each only trying a handful of times, and usernames like admin, test, oracle, ubuntu, pi, and postgres, that's textbook mass scanning. Nobody is targeting sw-infrarunbook-01 specifically; they're targeting the entire internet and your server happened to answer.

    The fix here isn't really a "fix" for the scanning itself; you can't stop the internet from scanning you. Instead, you reduce the attack surface. Move SSH off port 22:

    sudo sed -i 's/^#Port 22/Port 22022/' /etc/ssh/sshd_config
    sudo systemctl restart sshd

    This won't stop a determined attacker, but it drops the volume of automated noise by well over 90% in most environments I've managed, since most scanners only check the default port. Pair it with fail2ban so that even the reduced volume gets automatically banned after a few attempts.

    Cause 2: Credential stuffing against known usernames

    This is a step up from generic scanning. Here the attacker already has a list of usernames, often scraped from a data breach unrelated to your infrastructure, and is trying those specific usernames with common or previously-leaked passwords across many servers. You'll notice the same real-looking usernames (not "admin" or "root" but things like actual employee names or your infrastructure-admin naming convention) recurring across attempts.

    grep 'Failed password' /var/log/auth.log | grep -v 'invalid user' | awk '{print $9}' | sort | uniq -c | sort -rn

    If you run this and see a valid, existing account like infrarunbook-admin showing up repeatedly with failed attempts (not "invalid user," meaning the account actually exists on the box), that's a real threat, not noise. Someone either found this username in a breach dump or guessed it from your naming pattern.

    Aug 25 04:02:11 sw-infrarunbook-01 sshd[20011]: Failed password for infrarunbook-admin from 203.0.113.77 port 44012 ssh2

    Fix: rotate the password or, better, disable password auth for that account entirely and force key-based authentication. Check whether that username or its password pattern appears in any known breach corpus you have access to internally, and if the same password is reused anywhere else, treat all those systems as potentially compromised.

    Cause 3: A leaked or weak SSH key, not a password

    People assume "unauthorized login attempts" means password guessing, but I've seen plenty of cases where the log shows repeated connection attempts that get past the initial handshake and fail at key exchange or key verification instead:

    Aug 25 05:10:44 sw-infrarunbook-01 sshd[20233]: Connection closed by authenticating user infrarunbook-admin 192.0.2.150 port 39211 [preauth]
    Aug 25 05:10:47 sw-infrarunbook-01 sshd[20235]: error: maximum authentication attempts exceeded for infrarunbook-admin from 192.0.2.150 port 39218 ssh2 [preauth]

    This pattern, especially "maximum authentication attempts exceeded," often means someone has a list of stolen or generated private keys and is trying them one after another against your server, because your public key infrastructure (an authorized_keys file, a CI system, a shared bastion) leaked somewhere. Check who has valid keys authorized on the box and cross-reference with recent key rotations:

    cat /home/infrarunbook-admin/.ssh/authorized_keys | wc -l
    sudo find / -name authorized_keys -exec ls -la {} \;

    If you find keys you don't recognize, or an authorized_keys file with a suspiciously recent modification time, that's your answer. Fix: strip unrecognized keys immediately, rotate the legitimate ones, and lock down permissions (chmod 600 on the file, 700 on .ssh).

    Cause 4: A compromised host on your own network scanning laterally

    This one gets missed constantly because people assume "unauthorized login attempts" always means external attackers. Sometimes the source IP is inside your own RFC 1918 range:

    Aug 25 06:33:19 sw-infrarunbook-01 sshd[20599]: Failed password for root from 10.20.4.17 port 55210 ssh2
    Aug 25 06:33:22 sw-infrarunbook-01 sshd[20601]: Failed password for admin from 10.20.4.17 port 55214 ssh2

    If 10.20.4.17 is a machine you know isn't supposed to be initiating SSH connections to this box, this is a serious signal that the source host itself has been compromised and is now trying to pivot laterally. I've walked into this exact situation before: an internal monitoring VM got popped through an unpatched web app, and it started brute-forcing every other host on the subnet within minutes.

    Fix: isolate the source host from the network immediately, don't just block it at the firewall on the destination side, because it's likely also attacking other machines you haven't checked yet. Investigate that host separately as its own incident.

    sudo iptables -A INPUT -s 10.20.4.17 -j DROP
    # then go quarantine and investigate 10.20.4.17 itself

    Cause 5: Misconfigured application or cron job hammering its own auth

    Not everything that looks like an attack is one. I've spent an embarrassing amount of time once chasing what looked like a brute-force pattern, only to discover it was a cron job on another server with a stale, incorrect password in its config, retrying an SSH-based backup sync every five minutes.

    Aug 25 02:00:01 sw-infrarunbook-01 sshd[18211]: Failed password for backup-svc from 172.16.8.30 port 60122 ssh2
    Aug 25 02:05:01 sw-infrarunbook-01 sshd[18344]: Failed password for backup-svc from 172.16.8.30 port 60310 ssh2
    Aug 25 02:10:01 sw-infrarunbook-01 sshd[18477]: Failed password for backup-svc from 172.16.8.30 port 60501 ssh2

    The giveaway is the suspiciously exact timing interval. Real attackers don't usually retry every five minutes on the dot for days; scripts and cron jobs do. Check the source machine's crontab and any systemd timers for scheduled jobs that touch this host:

    crontab -l -u backup-svc
    sudo systemctl list-timers --all

    Fix: update the stale credential or, better, switch that job to key-based auth so a rotated password can never cause this again.

    Cause 6: Exposed non-SSH services with their own auth (RDP, database ports, web admin panels)

    SSH gets all the attention, but the same pattern shows up against any exposed authentication surface: RDP on Windows boxes, MySQL or PostgreSQL bound to 0.0.0.0, phpMyAdmin, or a web app's admin login. Check what's actually listening publicly before you assume this is purely an SSH problem:

    sudo ss -tulnp | grep LISTEN
    tcp   LISTEN  0  128  0.0.0.0:3306   0.0.0.0:*  users:(("mysqld",pid=1122,fd=23))
    tcp   LISTEN  0  128  0.0.0.0:22     0.0.0.0:*  users:(("sshd",pid=901,fd=3))

    Seeing MySQL bound to 0.0.0.0 instead of 127.0.0.1 is a red flag by itself, regardless of whether you've noticed failed logins against it yet. Check the database's own auth log too:

    grep 'Access denied' /var/log/mysql/error.log | tail -30

    Fix: bind the service to localhost or an internal-only interface, put it behind a VPN or bastion, and use a firewall rule restricting the port to known source ranges rather than relying on the application's own password checks as your only line of defense.

    Cause 7: Root login enabled over SSH

    This isn't a cause of the attempts themselves, but it massively raises the stakes of every other cause on this list. If PermitRootLogin is still enabled, every attempt against "root" isn't just noise, it's a direct shot at the most privileged account on the box, and attackers know this account exists on every Linux server without having to guess a username.

    sudo sshd -T | grep permitrootlogin

    If that comes back as anything other than "no," fix it now:

    sudo sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
    sudo sshd -t && sudo systemctl restart sshd

    Always run

    sshd -t
    to test the config before restarting; a syntax error here locks you out of remote access to the box entirely, which is a bad time to discover you don't have console access.

    Cause 8: Log noise from IPv6 or dual-stack misreads inflating the count

    A subtler one I've run into on dual-stack hosts: monitoring tools sometimes double-count attempts because the same client hits both the IPv4 and IPv6 listener, or because a load balancer health check with a slightly misconfigured probe gets logged as a failed auth attempt. Before escalating a spike as an active attack, verify the actual attempt count against what your alerting tool reported:

    grep 'Failed password' /var/log/auth.log | wc -l
    journalctl -u sshd --since "1 hour ago" | grep -c 'Failed password'

    If these two numbers disagree significantly, or if your monitoring dashboard is reporting a number way higher than either, the alerting pipeline itself might be the thing that's broken, not your server's security posture. I've chased false alarms before that turned out to be a Filebeat config double-shipping the same log file.

    Prevention

    You will never make repeated login attempts stop entirely; as long as a server has a public IP, someone somewhere is going to knock on the door. What you can control is whether those attempts have any chance of succeeding, and how fast you notice when the pattern changes from background noise to something targeted.

    Disable password authentication for SSH entirely and require keys:

    sudo sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
    sudo systemctl restart sshd

    Install and tune fail2ban so that repeat offenders get banned automatically instead of relying on you noticing manually:

    sudo apt install fail2ban
    sudo systemctl enable --now fail2ban
    sudo fail2ban-client status sshd

    Restrict SSH access at the firewall level to known source ranges wherever possible, rather than leaving it open to the entire internet. Rotate keys and audit authorized_keys files on a schedule, not just when something looks wrong. Move any exposed database or admin service off the public interface and behind a VPN. And keep an eye on the baseline: know roughly how many failed attempts per day is "normal" for your environment so you can actually tell when something has changed, instead of treating every log entry as either a non-event or a five-alarm fire.

    Most of all, don't let repeated unauthorized login attempts become wallpaper. The scanning noise is real and mostly harmless, but it's also the exact camouflage a targeted attempt against a real account will hide inside. Check the usernames, check whether the account exists, check where the source IP actually sits, and you'll know within a couple of minutes which of these eight situations you're actually looking at.

    Frequently Asked Questions

    Are repeated failed SSH login attempts always a sign of an active attack?

    No. The majority of them come from automated internet-wide scanning that targets every public IP indiscriminately, not your server specifically. You can usually tell the difference by checking whether the attempted usernames correspond to real accounts on your system and whether the same source IP keeps retrying persistently over hours or days.

    What is the fastest way to reduce the volume of unauthorized login attempts on a server?

    Move SSH off port 22, disable password authentication in favor of key-based login, and install fail2ban. In most environments this combination removes well over 90% of automated attempt volume within a day.

    How do I tell if a failed login attempt is coming from inside my own network?

    Check the source IP against your RFC 1918 ranges (10.x, 172.16-31.x, 192.168.x). If it's internal and shouldn't be initiating SSH connections to that host, treat the source machine itself as potentially compromised and investigate it separately.

    Should I ban an IP the moment I see a failed login attempt from it?

    Not manually one by one. Let fail2ban or an equivalent tool handle automatic banning based on a threshold, and reserve manual investigation for patterns involving valid usernames, internal source IPs, or unusually persistent single-source activity.

    Why do I see failed login attempts for usernames that don't exist on my server?

    This is typical of mass scanning tools that try a fixed dictionary of common usernames like admin, root, oracle, and pi against every host they find with an open SSH port, regardless of what accounts actually exist there.

    Related Articles