SSH and FTP brute-force protection for Linux

Stop SSH brute-force attacks on your Linux servers

SSH Protector is a lightweight Linux agent that stops SSH, SFTP and FTP brute-force attacks. It reads the host's own authentication log - journald or auth.log - and when an attacker keeps failing, it drops their whole /24 with a single nftables rule that survives a reboot. The decision is made on the server itself, so protection keeps running when the connection to the panel does not. Setup takes a couple of minutes and needs no configuration.

Install with one command
curl -fsSL https://sshprotector.com/download/installer | sudo sh

The free version includes full protection for one server.

One agent for every Linux distribution

Debian · Ubuntu · FedoraRHEL · Alma · Rocky · Alpinex64 · x86 · ARM64near-zero CPU usage
00

Install the agent

One binary for everyone, no account needed to download it. Install now and connect the server whenever you like - the agent asks for an enrollment token from your panel, and protects nothing until you paste one.

Download install script

Any modern systemd-based Linux - Debian, Ubuntu, RHEL/CentOS/Alma/Rocky, Fedora - on x86-64 or ARM64. The script installs the same service and is the practical choice for a fleet.

01Why

An open SSH port is attacked around the clock

Bots scan the entire internet address space and try passwords on every reachable server. It does not matter whether it is a corporate machine or a single VPS.

Thousands of login attempts per day
Within hours of going online a server starts receiving login attempts from all over the world. A typical machine with an exposed SSH port logs thousands of failed logons every day.
Server resources burned for nothing
Every attempt costs CPU time, memory, an event-log write and network traffic. A constant stream of brute-force requests creates permanent background load, slows the server down and bloats the logs.
One guessed password from a breach
A single successful guess gives full access to the machine: ransomware, data theft, spam sent from your address. Weak and reused passwords fall to dictionaries within days.
Attackers can lock out your admin account
Linux (via PAM faillock) locks an account after too many failed logons. By guessing a valid username an attacker trips that limit and locks out the real administrator - a denial of service, even without ever guessing the password.

SSH Protector cuts attacks off at the firewall

The agent notices a series of failed logons and blocks the attacker's whole subnet with one nftables rule. Blocked packets are dropped before the system spends anything on them - CPU load and log noise go down, the server runs faster, and bots never get enough tries to guess a password.

02How to stop it

How to stop SSH brute-force attacks on Linux (3 methods)

Three changes actually reduce what reaches sshd. They stack, and this is the order worth doing them in.

  1. 01Authenticate with keys, not passwords

    A password-guessing attack has nothing left to guess once sshd stops accepting passwords. Copy your key first, confirm in a second session that it logs you in, and only then switch passwords off - in that order, so a typo cannot lock you out of the machine.

    # /etc/ssh/sshd_config.d/10-keys-only.conf
    PasswordAuthentication no
    KbdInteractiveAuthentication no
    PermitRootLogin prohibit-password
    Full guide
  2. 02Cut how much of the internet reaches the port

    Moving sshd off port 22 removes most untargeted scanning and protects you from nothing else. Restricting the port to a VPN or a known allowlist removes the attacker rather than the noise; do both when the server has a fixed set of admins.

    # /etc/ssh/sshd_config.d/20-exposure.conf
    Port 2202
    AllowGroups ssh-admins
    
    # nftables: only the VPN and the office reach it at all
    nft add rule inet filter input tcp dport 2202 \
      ip saddr { 10.8.0.0/24, 203.0.113.7 } accept
    Full guide
  3. 03Ban the source before it gets enough tries

    fail2ban is the right first answer: it reads the auth log, counts failures and drops the address for a while. Its limits are structural - one address at a time, state that expires, nothing shared between hosts, and a jail that can quietly stop matching after a log format change. SSH Protector bans the attacker's whole /24 with one nftables rule, keeps the ban across reboots, and shares what one protected server learned with the others.

    # /etc/fail2ban/jail.d/sshd.local
    [sshd]
    enabled  = true
    backend  = systemd
    maxretry = 4
    findtime = 10m
    bantime  = 1h
    Full guide

What one subnet rule covers

Move the sliders. This is arithmetic, not a benchmark.

Banning one address at a time

32 firewall rules

128 attempts that still reach sshd

Banning the whole /24

1 firewall rules

4 attempts that still reach sshd

A /24 holds 256 addresses. When bans are per-address, a bot moving to the next one in the range gets a fresh allowance every time; when the ban covers the range, it gets none. Nothing here is measured - it is the same counting the agent does.

03How it works

From download to a protected server in minutes

No config files and no command line: download the installer, run it, confirm the sudo prompt.

  1. Create an account

    Sign up with email or through Google/GitHub. No credit card needed.

  2. Download the installer

    You get a personal signed installer with your access token already embedded.

  3. Run it on the server

    The agent detects the SSH port on its own and adds your current IP to the whitelist so you cannot lock yourself out.

  4. Done

    The server shows up online in the panel within seconds and starts blocking attackers with sensible default settings.

04Features

Everything you need to protect and manage your servers

Brute-force protection at the core, extended with shared attacker intelligence, geo rules, temporary access and central management.

SSH and FTP brute-force protection01

The agent reads failed logons from the systemd journal (journald) and the FTP server logs and blocks the attacker locally - instantly, even with no cloud connection.

Bans whole subnets, not single addresses02

Attackers rotate addresses within their network. SSH Protector bans the whole subnet, using ASN data, with one consolidated firewall rule.

Shared attacker database03

An attack on one customer protects everyone: subnet reputation is aggregated across the platform and the worst networks are blocked before they reach you.

Geo rules04

Allow SSH only from the countries you actually work from. Everything is evaluated locally on the agent, so it stays fast and works offline.

Temporary access05

Keep the port closed by default and open it for a specific address after an MFA-confirmed request, with a timer and automatic close.

Whitelist and strict mode06

Trusted addresses and dynamic DNS names are never blocked. In strict mode only whitelisted sources may reach the port at all.

Notifications and audit07

Ban spikes, a server going offline, configuration drift - delivered by email, Telegram, Slack or webhook. Every action is recorded in an audit log.

One lightweight agent08

A single small executable running as a service. A few megabytes of memory, near-zero CPU, every major Linux distribution and architecture.

Central management09

Server list, policies, version rollback, groups and bulk actions - all from the panel, with no inbound ports opened on your servers.

Always-On lockout protection10

Guarantees your account is never locked out under brute force: the agent bans attackers before the PAM faillock threshold and auto-unlocks protected accounts (admins + your list). On by default, on every plan.

05Pricing

Flat plans, no per-server surprises

Free stays free forever, no card required. Paid plans have a fixed price with a set number of servers included.

Free

1 server
$0/mo

Basic SSH protection for a single server.

  • SSH brute-force protection
  • Soft whitelist
  • Minimal statistics

Solo

1 server
$9/mo

Full protection for one production server.

  • Everything in Free
  • FTP brute-force protection
  • Full statistics
  • Email notifications
  • Basic audit log

Pro

PopularUp to 5 servers
$15/mo

For teams and small server fleets.

  • Everything in Solo
  • Strict whitelist and groups
  • Full audit with export
  • Extended statistics
  • Shared behavioral blocklist

Enterprise

Up to 50 servers
$99/mo

For companies with a large server fleet.

  • Everything in Pro
  • Admin and moderator roles
  • Priority support
  • Shared behavioral blocklist

Need one more server than your plan includes? Add servers individually for $3 per server per month instead of jumping a tier.

14 days of Pro, free - no card

Sign up and try subnet bans, Telegram alerts, GeoIP and the shared threat database on your own server. When the trial ends your account returns to Free on its own and protection keeps running. Nothing is charged, and there is nothing to cancel.

Start the free trial
06Cases

When protecting a Linux server actually becomes necessary

Fifteen situations in which remote access to a Linux machine stops being a theoretical risk and starts being a daily one. If you recognise your own server in any of them, the port is already being tried.

0.0.0.0/022 · 21LISTEN 0.0.0.0$sshduptime 412dno consoleone host · always on

When protecting an SSH server on Linux is necessary

The first group is about the machine itself - where it stands, who reaches it and what else listens on it. None of these situations involve a mistake. They are ordinary, sensible ways to run a Linux server, and every one of them puts a login prompt in front of the entire internet.

  1. 01

    SSH is reachable from anywhere and passwords still work

    Port 22 answers every address in the world, with no VPN in front of it and no bastion host. This is the default state of a rented machine: the provider hands over a public address, SSH is how you set the server up, and once setup is finished the port simply stays where it is - usually with password authentication still enabled alongside keys.

    Scanning the full IPv4 range takes minutes, not days. A newly issued address starts receiving connection attempts within hours of first appearing online, long before the server has a name, a certificate or a single real user. From that moment the machine is answering strangers around the clock.

    • A VPS or cloud instance reachable at its public address
    • An office machine behind a router with port 22 forwarded to it
    • A server that was 'temporarily' opened for a migration and never closed
    • A machine whose address was never published anywhere, but is inside a scanned range all the same
  2. 02

    The cloud image ships with a username everybody already knows

    Distribution and provider images come with a known first account: root on a bare VPS, ubuntu on Ubuntu, ec2-user, debian, admin, pi. Half of the guessing problem - finding a valid username - is solved before the machine has finished booting for the first time.

    That is why an exposed server sees the same short list of names in its log all day. The attacker does not need to enumerate anything: the account is standard, it exists on a large share of the internet's Linux hosts, and on many of them it can still be used to log in directly.

  3. 03

    One rented VPS carries the site, the database and the backups

    Small companies and single-developer projects frequently run everything on one machine: the web server, the database, the queue, the nightly dump. There is no second host to fail over to and no separate administrator - the person who signs in to deploy is the one who maintains it.

    The provider's own protection does not extend to this. Hosting companies filter volumetric traffic floods, not password guessing: a few attempts a second from constantly rotating addresses look like ordinary traffic from the network's point of view, and the abuse desk will never see them.

    • No spare capacity: if the machine is compromised, the project stops rather than degrades
    • Backups often live on the same disk, which is what ransomware counts on
    • Nobody is paid to read auth.log, so the attempts accumulate unseen
  4. 04

    The Linux box is a router, a NAS or an appliance nobody thinks of as a server

    A firewall appliance, a network storage box, a Raspberry Pi running a shop's till software, a controller in a plant room, a mini PC under a desk running a backup job - all of them are Linux, all of them have SSH enabled, and none of them appear on anyone's list of servers.

    Machines like these are the ones that get forgotten. They are set up once, they keep working, and years pass between the day the password was chosen and the day anyone looks at them again. Meanwhile the port has been answering the internet the entire time.

  5. 05

    FTP listens on the same host as SSH

    Linux servers rarely publish one service. An FTP endpoint for exchanging files with a client or a designer, plus SSH for administration, commonly live together on the same address, and the FTP accounts are usually older than everything else on the machine.

    Each open port is a separate door with its own login prompt, and attackers do not specialise. The same scanning infrastructure tries both in sequence, and the weakest of them decides the outcome for the whole host, because whoever gets in through either one is standing on the same operating system.

    • FTP accounts created once for a contractor and never reviewed again
    • Plain FTP credentials that cross the network in the clear
    • A shared upload account whose password half the office knows
users triedrootadminubuntudeploypostgrestestpassword:PasswordAuthentication yesfailed9 999

When accounts and keys stop being under your control

The second group is about who holds credentials to the machine. Keys, deploy accounts, contractors and old passwords accumulate faster than anyone reviews them, and every one of them ends at the same prompt. This is where most real intrusions begin.

  1. 06

    Developers and contractors have their own logins

    An outsourced developer, a designer who needs to upload a build, an agency maintaining the site, the vendor of a line-of-business application - each one asked for access, each one got an account or a key added to authorized_keys, and most of that access is still live long after the work finished.

    You cannot see how those credentials are stored. A private key may sit unencrypted on a laptop, in a shared cloud folder, or in the home directory of an employee who left that company a year ago. Access granted once tends to outlive both the project and the person it was granted to.

    • Keys added for a single deployment and never removed
    • One account shared by everyone at the contractor rather than an account per person
    • Nobody is notified when the contractor's own staff change
  2. 07

    Deploy and automation accounts cannot use a second factor

    CI pipelines, backup scripts, monitoring agents, rsync jobs and configuration tools all need to sign in without a human present. They therefore cannot be protected by anything that asks a person for a code, and they usually hold broader rights than any individual does.

    So these accounts stay as they are: predictable names, keys or passwords that have not been rotated in years, and a login path that works at three in the morning without anybody noticing. They are the accounts an attacker aims for, precisely because they are the ones that never change.

  3. 08

    Password authentication was left on 'just in case'

    Key-based login is set up, and passwords are kept enabled as a fallback - for the day a key is lost, for a colleague without one, for the console that nobody has tested in a year. The intention is reasonable; the effect is that the whole key policy is optional from the attacker's side.

    Guessing does not care that keys exist. As long as PasswordAuthentication is yes for any account on the machine, the dictionary attack has a way in, and the strongest key on the server does nothing to slow it down.

  4. 09

    Passwords that already appear in a breach dump

    Most successful intrusions are not clever. Somebody reused a password from a forum, a shop or an old mail account that has since been leaked, and the same string now sits in a dictionary that every scanning bot works through.

    Guessing then stops being a matter of probability and becomes a matter of scheduling: the correct password is already on the list, and the only question is when the bot reaches your address. Complexity rules do not help here, because the password may well satisfy every rule you have written.

    • A password reused between a server account and a personal service
    • Credentials leaked from a contractor's systems rather than your own
    • Patterns a policy accepts and a dictionary already contains - Summer2024!, CompanyName1
  5. 10

    A private key with no passphrase on somebody's laptop

    Keys are stronger than passwords right up to the moment the key file is copied. An unencrypted id_rsa on a stolen laptop, in a synced cloud folder, in a container image pushed to a public registry, or in a repository committed by accident is a working credential that needs no guessing at all.

    The server cannot tell the difference. The signature is valid, the account is real, and the session looks exactly like the developer's - which is why the useful question is not only who holds a key, but what happens when someone connects from somewhere that developer has never been.

/var/log/auth.log22:0023:0124:0225:0326:0427:0528:0629:07this month12 480blockedexported · signed

When the log, the auditor or the provider force the question

The third group is about the consequences that arrive before any breach does. Attempts that never succeed still cost disk, CPU, attention and credibility - and sooner or later somebody outside the technical team asks a question that has to be answered with evidence rather than assurance.

  1. 11

    An auditor, an insurer or a customer asks how remote access is protected

    Cyber insurance applications, security questionnaires from corporate clients, and regulatory regimes covering payment or personal data all ask the same thing in different words: what stops repeated password guessing against your remote access, and how do you know it works.

    'We use keys' is not an answer that survives follow-up, because the follow-up is about the accounts that still accept passwords and the attempts that reach the port anyway. What is wanted is a control that exists independently of any one credential, and a record showing it was in force throughout the period under review.

    • A cyber-insurance questionnaire before a policy is issued or renewed
    • A large customer's supplier security review before signing a contract
    • Payment or personal-data rules that require brute-force controls on remote access
  2. 12

    auth.log and the disk fill with failed logins

    Every rejected attempt is written down. On an exposed server that means tens of thousands of log lines a day, and the effect compounds: rotation discards genuine events within hours, log shipping charges by ingested volume, and a small root filesystem can genuinely run out of space because of traffic that was never going to be let in.

    The cost is not only storage. Each attempt takes a TCP connection, a key exchange and a credential check, so the machine spends a measurable share of its CPU all day answering people it will never admit. On a one-core VPS that share is large enough to be felt by whatever the server is actually meant to be doing.

  3. 13

    Hand-maintained ban rules have become their own maintenance job

    The usual first response is a local filter and a growing pile of firewall rules. It works, for a while - and then the rule set is thousands of lines long, nobody remembers why half of it is there, an office was blocked during a busy morning, and the same address ranges are being rediscovered from scratch on every new machine.

    What an estate actually needs is one policy that is decided once and applied everywhere, exceptions that are recorded rather than remembered, and blocking that does not have to be reconstructed by hand every time a server is rebuilt.

  4. 14

    One administrator looks after servers belonging to many clients

    Managed service providers, freelance system administrators and small hosting shops carry dozens of Linux machines across different companies, providers and network layouts. Each has its own rules, its own accounts and its own tolerance for downtime.

    Configuring each one by hand does not scale, and neither does discovering a problem only when a client telephones. Such an estate needs one consistent baseline applied everywhere, per-machine exceptions where a client genuinely differs, and a single place where all of them can be seen at once.

    • Machines spread across several providers and address ranges
    • A client whose branch office must never be blocked, however unusual it looks
    • Handovers between administrators without losing the reasoning behind a setting
  5. 15

    The link to the server is unreliable, and protection still has to hold

    Uplinks drop, providers reroute, DNS breaks, and a machine in a remote rack can spend hours with no route to anywhere. Attacks do not pause for this; if anything, a network fault is precisely when the server is least observed.

    Whatever defends the login prompt therefore has to keep deciding locally, on the machine, with no dependency on reaching an outside service. Anything that stops enforcing when the internet is unavailable is protection only on the days you did not need it.

07FAQ

Frequently asked questions

Is it safe to install on a production server?

Is it safe to install on a production server?

Yes. The agent only reads the auth log of its own operating system and blocks inbound connections to the protected ports on that same machine. It makes outbound HTTPS requests only and opens no inbound ports.

Does protection work without an internet connection?

Does protection work without an internet connection?

Yes. The decision to block an attacker is made locally on the agent, so protection keeps working with the last applied policy even when the cloud is unreachable.

What if I changed the SSH port?

What if I changed the SSH port?

The agent detects the actual SSH port automatically from sshd_config and listening sockets, and rebuilds its rules when the port changes. The FTP port is detected the same way.

Can I lock myself out?

Can I lock myself out?

No. During installation your current IP address is added to the whitelist, and whitelisted sources always take priority over any block.

Which Linux distributions are supported?

Which Linux distributions are supported?

Any modern systemd-based distribution - Debian, Ubuntu, RHEL/CentOS/Alma/Rocky, Fedora - on x86-64 and ARM64. One static binary with no additional runtimes to install.

How does payment work?

How does payment work?

International payments go through PayPro Global, payments in Russia through YooKassa, with cryptocurrency available as a fallback. The Free plan is permanent and requires no card.

SSH protection with password authentication enabled

I left PasswordAuthentication enabled and SSH listened on the public address of the Linux server. There are thousands of Failed passwords from different IPs and logins in auth.log, moving port 22 does not help, and access cannot be completely blocked. How can I set up SSH protection against password brute force before successful login?

With SSH Protector I install the agent as a systemd service: it reads the authentication log locally, determines the actual sshd port, and after a threshold of a window of time, blocks the source network in the system firewall. I add my address or VPN to the whitelist in advance, control the history in the panel and save the latest policy when I lose the Internet.

As a free alternative to SSH Protector, I disable PasswordAuthentication and PermitRootLogin, leave the keys to Ed25519, limit AllowUsers/AllowGroups and only allow the port from VPN or trusted CIDRs. If a password is temporarily required, I configure fail2ban using journald/auth.log, check nftables/iptables, set findtime, maxretry and bantime, and regularly test exceptions from the backup console.

Protecting the standard login of a cloud Linux image

I deployed Ubuntu/Debian/RHEL from a public cloud image, so the username ubuntu, debian, ec2-user or root is known to the bots in advance. Even with a good password, the log is filled with targeted attempts, and one mistaken password leaves the account vulnerable. How can I secure SSH on a cloud VPS with a standard login?

With SSH Protector I block the source on actual failed logins no matter what name it tries, and can extend the ban to the attacker's network. I check the SSH port found, add the administrative VPN to the whitelist, and use a local agent solution so that protection does not depend on panel availability.

For free, I disable password and root logins, create a separate user with sudo, upload a unique key via cloud-init, and close the Security Group to the VPN/my networks. I remove unused authorized_keys, enable MFA on bastion, configure fail2ban and Accepted password/publickey alerts for unknown sources; I consider changing the port only to reduce noise.

Protecting a single Linux VPS with a website and database

I have one Linux VPS, where the website, database and backups work simultaneously, and SSH is needed for administration. Successfully logging in as the sudo user will give the attacker access to all layers and allow the attacker to delete local backup files. How can I secure SSH on a critical VPS with minimal load?

With SSH Protector I install a static agent that reads local events and blocks the source in the firewall until the account is compromised. I use free first server protection, whitelist my channel, and make sure the agent continues to work offline; I leave backup and least privilege as separate layers.

For free, I lock SSH behind WireGuard/Tailscale, disable passwords and root, require a key with passphrase, and limit to sudo. I store backups outside of the VPS with separate credentials, enable automatic security updates, fail2ban and audit of successful logins; I check the provider's emergency console before tightening the firewall.

SSH protection on router, NAS and Linux device

I manage a Linux router, NAS or ARM device, which I don’t consider a full-fledged server, but it runs sshd and the port is accessible from the external network. The device is rarely updated, resources are scarce, and compromise will give it a foothold within the local network. How do I secure SSH on a low-power Linux device?

With SSH Protector I use a supported static binary for the appropriate architecture and systemd, enable local log parsing and firewall blocking without an incoming control port. I check OS and firewall compatibility before installation, set up a management whitelist, and make sure the agent doesn't overwhelm limited device resources.

For free, I don’t publish SSH externally at all: I connect the device via VPN, disable password and root, allow one key and one control subnet. I update the firmware, disable unused services, set the minimum fail2ban only if there is enough memory and save the firewall configuration; For an unsupported OS, I choose an external gateway rather than an unknown binary.

Unified SSH and FTP Security on Linux

I have SSH and FTP open on a Linux host, and bots are traversing both services through different logs. The IP blocked by the sshd script continues to attack FTP, and the manual iptables chains diverge. How can I centrally block password guessing via SSH and FTP?

With SSH Protector, I enable reading of supported SSH and FTP logs, let the agent determine the ports, and apply a single local rule to the source network. I add trusted integrations to the whitelist, check the history in the dashboard, and take into account that advanced FTP protection and additional features may depend on the selected plan.

For free, I replace regular FTP with SFTP over SSH or FTPS, if the protocol is really needed, and close the service from the entire Internet. I create separate fail2ban jails for sshd and FTP, direct them to one nftables set with timeout, check the log format after updates and disable shared accounts.

Controlling SSH logins of developers and contractors

I issued separate Linux logins and SSH keys to developers and contractors, but some of the keys were copied to personal laptops, and the list of owners was out of date. I need to stop brute force, quickly recall a person and understand who entered without using one shared key. How do I secure multi-user SSH access?

With SSH Protector, I leave automatic network blocking on all external sources and whitelist only the controlled VPN, and not every home IP. I use the panel for attacks, but I save the identity in separate Unix accounts and keys: the agent protects the perimeter, and I revoke access by deleting a specific key.

For free, I manage authorized_keys centrally through Ansible, issue one key per person and device with a clear comment, disable shared accounts and limit sudo. I enable VPN/MFA on the bastion, set the access period in inventory, collect Accepted publickey with fingerprint in SIEM and automatically delete the key at the end of the contract.

Securing business SSH accounts without MFA

I have deployment/backup accounts that are used by CI and automation, so interactive MFA does not apply to them. Their keys should work without an operator, but compromising the runner or repeating passwords could open the server. How can I protect machine SSH access without breaking the deployment?

With SSH Protector, I separate trusted runner addresses through a precise whitelist, and leave all other sources blocked by failed logins. I don't consider this to be a replacement for key control: the agent reduces the brute force from the outside while the restrictions of the service account itself contain the consequences of successful authentication.

For free, I use a separate Ed25519 key for the job, store it in a secret store, restrict it in authorized_keys via from=, command=, no-port-forwarding, no-agent-forwarding and no-pty. I only allow SSH from the runner network, issue minimal sudo commands, rotate the key regularly, and record a fingerprint in the deployment log.

Securely disable password login via SSH

I left the password SSH login "just in case" because I'm afraid of losing the key or getting locked out after changing sshd_config. As a result, PasswordAuthentication yes remains for years, and auth.log constantly shows password-guessing attempts. How can I switch to SSH keys without the risk of losing access to the server?

With SSH Protector, I first install an additional protective layer and whitelist the current administrative address while I perform the migration. The agent blocks active brute force, automatically takes into account the actual port and leaves the policy offline, but after successfully verifying the keys, I still disable the password login.

For free, I open a second SSH session and the provider console, add a unique key, check ~/.ssh 700 and authorized_keys 600 permissions, run sshd -t and reload without closing the first session. Then I set PasswordAuthentication no, KbdInteractiveAuthentication no and PermitRootLogin no, check the new login and save the emergency key separately.

Reaction to leaked SSH password

I found out that the Linux user's password was leaked, and attempts with his name from several countries appeared in auth.log. I'm not sure if the login was successful because the server is being used from different networks. How can I urgently stop the SSH attack and check for compromise?

With SSH Protector I immediately block active sources and networks, check the history of attacks and leave access only through a trusted whitelist. Then I change the password/key, end the sessions and separately analyze the Accepted password/publickey; blocking reduces the attack window, but does not prove the absence of an already successful login.

For free, I temporarily close the SSH Security Group or nftables to the VPN, block the user, revoke the keys and change the associated secrets. I check last/lastlog, journalctl, sudo, new users/keys, cron/systemd units, processes and network connections, then restore key-only access and disable reused passwords.

SSH private key protection without passphrase

I found a private SSH key without a passphrase on an employee's laptop; the key is allowed on several servers and could have ended up in backup or malware. Such a login will not create a series of incorrect passwords, so regular anti-brute force will not stop it. How can I limit the damage and properly protect SSH keys?

With SSH Protector I continue to block external brute force and see suspicious sources, but do not rely on it against the correct stolen key. I immediately remove the fingerprint from all servers, issue a new key with passphrase and leave the whitelist only for VPN; I will investigate successful entries separately.

For free, I look up the old public key across all authorized_keys, revoke it by configuration management, and check the Accepted publickey by fingerprint and source. I issue a hardware FIDO2/ed25519-sk or key with passphrase and ssh-agent timeout, disable agent forwarding unless necessary, and keep a registry of owner, device, and rotation dates.

Confirm SSH Security for Audit

I have to show the auditor, client or insurer how administrative SSH access is protected: what ports and hosts are controlled, how automated password guessing is blocked, who is in the whitelist and what happens when the Internet is lost. How can I collect verifiable evidence of SSH brute force protection?

With SSH Protector I am attaching a history of attacks and blocking, policy settings, a list of protected services and approved exceptions. I document the agent's local solution, the outgoing TLS channel, and the lack of an incoming control port, then perform controlled bad logins and save the log lines, firewall rule, and notification.

For free, I export sshd_config, nftables/ufw, fail2ban jail and changelog from Git, and send auth.log/journald to a secure storage. I check PasswordAuthentication, PermitRootLogin, MFA/VPN and test key revocation monthly, sign the result and store evidence for the required period.

Decrease in auth.log volume due to SSH brute force

My auth.log or journald is filled with Failed password and Invalid user, useful history is lost due to rotation, and the log parser wastes resources. I don't want to disable auditing because successful login needs to be investigated. How can I reduce the flow of SSH brute force events?

With SSH Protector I block the source in the firewall after a series of failures, so the next TCP connections don't reach sshd and don't create as many entries. I keep a system audit, separately control the size/retention of the journald, and use the attack history in the panel as an index, not as a replacement for the original log.

For free, I close SSH to VPN/allowlist, disable passwords and standard logins, and send fail2ban to nftables set with timeout. I configure SystemMaxUse and journald/rsyslog rotation, send Accepted and key Failed events to an external syslog, and do not reduce LogLevel below the value needed for investigation.

Automation of Linux blocking instead of manual blacklist

I manually copy IP from auth.log to ufw/iptables, but addresses change quickly, old rules are not deleted, the chain grows and one mistake can close my access. Blacklist support has become a separate daily task. How can I automate SSH brute force blocking securely?

With SSH Protector I set the threshold and window once, after which the agent creates and releases locks locally and the whitelist takes precedence. I use a network ban where the attacker rotates neighboring addresses, check the changes in the panel and save a backup console before the first policy.

For free, I replace individual permanent iptables rules with nftables set with timeout or fail2ban action, set maxretry/findtime/bantime and ignoreip for VPN. I test the filter on real log lines, enable recidive carefully, limit the set size, and monitor for reload errors after a distribution update.

Managing SSH security across multiple clients

I maintain Linux servers for several customers on Debian, Ubuntu, RHEL and ARM, each with their own ports, trusted networks and contacts. Local fail2ban and firewall configs diverge, and a common whitelist between clients is unacceptable. How can I centralize SSH security in a multi-tenant fleet?

With SSH Protector I connect hosts with a supported agent, see detected ports and attacks from one panel, but keep exceptions and policies within the boundaries of the desired server/client. I apply baseline values, document deviations separately, and notify the customer responsible.

For free, I describe sshd, fail2ban and nftables in Ansible roles with a separate inventory and vault for each client, check for changes in CI and collect logs in Wazuh/central syslog with tenant tags. I automatically compare the config with the baseline and never combine keys, CIDRs and secrets from different customers.

Offline SSH protection on unstable internet

My Linux server is in a branch office or behind an unstable channel: the cloud panel and DNS are sometimes unavailable, but SSH inside or through a forwarded port continues to respond. Security doesn't have to wait for a remote API for every solution. How do I keep SSH brute force blocking offline?

With SSH Protector I enforce the policy on the agent in advance; it continues to read the local log and change the system firewall to the latest configuration when communication with the panel is lost. I sync the whitelist before the shutdown, check the accumulated history after the restore, and don't open the incoming agent control port.

For free, I make the control completely local: nftables/ufw allows SSH only from a VPN or the required subnets, and fail2ban works via journald without an external network. I save the rules for loading, set up a local queue for notifications, test a restart without DNS, and leave the physical/provider console to restore the erroneous rule.

Replacing fail2ban without a gap in protection

fail2ban has been running on this Linux server for two years and the sshd jail works. I want to try a managed agent instead, but I cannot leave port 22 unprotected for even a few minutes, and I do not want two tools fighting over the same firewall rules. How do I replace fail2ban with SSH Protector without downtime?

I install the SSH Protector agent while fail2ban keeps running. The agent owns a dedicated nftables table of its own (inet sshprotector, or a prefixed ipset namespace on older hosts) and rebuilds only that table, so it never touches fail2ban's chains and neither tool reverts the other. I whitelist my own address at install time, then watch the panel for a day to see that the agent is catching the same sources the jail is. Only then do I stop fail2ban and remove its rules. If I change my mind, uninstalling the agent takes its own rules with it and leaves the firewall as it was.

Without any agent, a switch between two log-reading tools is done the same way. Leave the old one running, give the new one its own chain or table name so their rules cannot collide, compare what each one caught over a full day of real traffic, and disable the old one only once the new one's ban count has stopped being the lower of the two. Never remove the working tool first: a few unprotected minutes on an exposed SSH port is enough for a botnet that is already scanning you.

Choosing between CrowdSec and a managed agent

I am comparing options for SSH brute-force protection on a small Linux fleet and CrowdSec keeps coming up. It is open source, it has a community blocklist, and it covers more than SSH. What does SSH Protector do that CrowdSec does not, and how do I decide between them?

The two solve overlapping problems from different ends, and I pick on shape rather than on a score. CrowdSec is an engine with a scenario language, remediation components you install and wire up yourself, and a blocklist fed by everyone running it; its reach goes well past SSH. SSH Protector is one binary that does one thing: it reads the SSH, SFTP and FTP authentication log, bans the attacker's whole /24 in its own nftables table, keeps that ban across reboots, detects the real sshd port instead of assuming 22, and reports to a panel that tells me when a protected server has gone quiet. Reputation is shared between protected accounts rather than with the public internet.

So the decision is about what I actually have. If I need breadth - HTTP, databases, arbitrary log sources, detection scenarios of my own - CrowdSec has the room for that and costs nothing to run. If what I have is a handful of Linux boxes with an exposed SSH port and nobody to maintain a detection stack, I want the narrow thing that is correct with no configuration. I have not benchmarked the two against each other on the same host, so I do not choose on performance numbers, and neither should anybody quoting them at me.

Protect your first server today

The Free plan stays free forever. Upgrade in one click whenever you need more.

08Trust

Who builds this, who you are paying, and what the agent can do on your server

Three questions worth answering before you install anything with administrative rights on a production server.

Who builds it01

SSH Protector is written by Victor G. Bobrov, lead server security specialist at Recovery Toolbox, with 20+ years in systems and security engineering and Microsoft MCSD/MCDBA certifications. The detection rules, the ban logic and the guides on this site are his work, published under his name rather than an anonymous brand. About the author →

Who you are paying02

The vendor is File Master LLC, a company registered in Bulgaria (EU) - Bulstat/VAT 180842207, office in Varna, reachable by phone and email. Payments are handled by PayPro Global as merchant of record; the terms, the privacy policy and the data-processing agreement are published in full, not summarised. Terms of Service · Privacy Policy · DPA

What the agent can and cannot do03

The agent reads its own host's SSH authentication log and writes nftables rules on that same host. It opens no inbound port, has no remote-command channel, and talks outbound over HTTPS only. It has no offensive capability: nothing in it can attack another machine. Ban decisions are made locally, so protection keeps working with the cloud unreachable, and your current IP is whitelisted at install time so the agent cannot lock you out of your own server. The installer is code-signed. How it works →

09Resources

Resources: the protocol, the attacks, and the standards this all sits inside

SSH brute-force protection is not a subject of its own - it is where a protocol, a class of attack and a set of published standards meet. These are the sources that define each of them.

Links open on the sources themselves - Wikidata where the entity has an ID, the primary source where it does not.

Recovery Toolbox / File Master LLC

Contact Recovery Toolbox

Contact details for Recovery Toolbox and File Master LLC, plus the profile of Victor G. Bobrov, the company's lead security specialist.

Company office

File Master LLC is the legal entity behind the Recovery Toolbox online services and software products.

File Master LLC
Serena app., office C13
Golden Sands, Varna, 9007
Bulgaria, European Union
Bulstat/VAT
180842207

About Recovery Toolbox

File Master LLC develops and supports Recovery Toolbox online services and software products for repairing damaged files, databases and mail storage formats. The company focuses on practical recovery tools for users, IT specialists and businesses that need to restore access to corrupted data.

Comments and suggestions are welcome. Please send website feedback by email: webmaster@recoverytoolbox.com

Victor G. Bobrov, server security specialist and author of SSH Protector
Security specialist

Victor G. Bobrov

Server security specialist · 20+ years in systems and security engineering

Victor G. Bobrov leads security engineering at File Master LLC / Recovery Toolbox. He designs the detection and banning logic behind SSH Protector: reading the SSH authentication log, telling a brute-force or password-spraying attack from a mistyped password, banning the attacking subnet with a single nftables rule, and sharing attacker reputation across protected fleets.

  • Brute-force protection
  • Linux and SSH hardening
  • nftables and network policy
  • MCSD
  • MCDBA
About the author →

Microsoft certifications

Microsoft Certified Solutions Developer - MCSD. Microsoft Certified Database Administrator - MCDBA.

MCSD MCDBA