Block SSH brute-force source IPs on Linux endpoints with iptables or firewalld rules built from sshd authentication logs
This Automox Worklet™ reads the sshd authentication log on a Linux endpoint, extracts IP addresses that have repeatedly failed to authenticate, and installs iptables or firewalld rules that drop their traffic. The Worklet detects which firewall backend is present by running which iptables and which firewalld, then writes its rules into the matching subsystem so they sit alongside the rest of your firewall policy.
Three independent toggles drive the block list. block_invalid_username_signins captures IPs that appeared with more than five invalid user log entries. block_too_many_failed_authentications captures IPs that appeared with more than five Too many authentication failures entries. block_max_authentication_attempts reads MaxAuthTries from sshd -T and installs a rate-limit rule that drops any source exceeding that ceiling within a 60-second window, which closes the loop attackers exploit by opening fresh TCP connections to reset per-connection counters.
On iptables hosts, the Worklet flushes or creates a dedicated chain named AX_FailedLogins and appends iptables -A AX_FailedLogins -s <ip> -j DROP for each offender. On firewalld hosts, it recreates the AX_FailedLogins zone, populates two named ipsets (invalid_user_ip_set and failed_authentication_ip_set), and binds them with rich rules that drop matching sources. Both layouts isolate the Worklet's rules from your existing firewall configuration, so you can audit, list, or flush them without touching anything else.
Authentication events are read from /var/log/secure when present, otherwise /var/log/auth.log, otherwise a temporary file generated from journalctl -u ssh.service. exclude_private_ips defaults to true and skips RFC 1918 ranges (10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12 through 172.31.0.0/16) so a misconfigured internal jump host or a forgetful developer does not get firewalled out of production.
Any Linux endpoint exposing port 22 to the internet absorbs continuous brute-force traffic from botnets running credential stuffing against leaked password databases and dictionary attacks against common usernames (root, admin, ubuntu, ec2-user, oracle). sshd MaxAuthTries caps attempts per connection, but it does nothing about an attacker that simply opens a new TCP session for each guess. Without source-IP enforcement, the log file fills, the daemon burns CPU on key exchange and PAM lookups, and the connection table edges toward saturation.
CIS Benchmark control 5.2 and NIST 800-53 AC-7 both call for account-lockout behavior on remote access, and a firewall-level source ban is one reliable way to satisfy that control on sshd, which has no native lockout. SSH brute-force exposure is a routine finding in CIS 5.2 and PCI-DSS 8.3 audits, and fail2ban-style controls are often missing from the long tail of Linux servers, container hosts, and developer VMs that never made it into the original hardening sweep. This Worklet parses the sshd log for repeat-offender source IPs, builds iptables or firewalld DROP rules from three independent failure patterns, and rebuilds the block set on every run so it stays current with the active log window.
Evaluation phase: The Worklet detects whether iptables or firewalld owns the firewall by running which iptables and which firewalld. It locates the sshd log at /var/log/secure, /var/log/auth.log, or a temporary file written from journalctl -u ssh.service. It then checks for the AX_FailedLogins chain (iptables -nL AX_FailedLogins) or zone (firewall-cmd --get-zones). The endpoint is flagged for remediation if the chain or zone is missing, if a sample offending IP from the current log window is not yet present in AX_FailedLogins or in the invalid_user_ip_set ipset, or if the MaxAuthTries rate-limit rule (the recent-module 60-second hit_count rule on iptables, or the SSH Auth Failure log rich rule on firewalld) is absent.
Remediation phase: The script flushes or creates AX_FailedLogins (iptables -F AX_FailedLogins || iptables -N AX_FailedLogins) or recreates the firewalld zone (firewall-cmd --permanent --delete-zone=AX_FailedLogins then --new-zone=AX_FailedLogins). It greps the sshd log for invalid user lines and Too many authentication failures lines, extracts public source IPs, strips RFC 1918 ranges when exclude_private_ips=true, and keeps any IP that appears more than five times. On iptables, it appends iptables -A AX_FailedLogins -s <ip> -j DROP per offender, then adds two rate-limit rules with -m conntrack --ctstate NEW -m recent --set and --update --seconds 60 --hitcount $MaxAuthTries -j DROP scoped to the active sshd port (sshd -T port). On firewalld, it populates invalid_user_ip_set and failed_authentication_ip_set, binds each to a rich rule that drops matching sources, and adds two SSH Auth Failure rich rules that log and rate-limit at MaxAuthTries per minute. The script then reloads firewalld, prints the count of DROP rules created, and exits 0 on success or non-zero on failure.
Linux endpoint running iptables or firewalld (Debian, Ubuntu, RHEL, CentOS, Rocky, Alma, Fedora, Amazon Linux)
sshd_config must have SyslogFacility AUTH enabled so failed-login events land in /var/log/secure, /var/log/auth.log, or the systemd journal under ssh.service
Root or sudo context for the Automox agent (default agent context already qualifies) to modify iptables chains or firewalld zones and to read MaxAuthTries from sshd -T
ipset package installed on firewalld hosts; the remediation creates invalid_user_ip_set and failed_authentication_ip_set as hash:ip sets
MaxAuthTries set in /etc/ssh/sshd_config (commonly 3 to 6); the Worklet reads this value with sshd -T to build its rate-limit rule
Three policy toggles let you opt into each rule independently: block_invalid_username_signins, block_too_many_failed_authentications, and block_max_authentication_attempts. All three default to true
Recommended: deploy via FixNow or the endpoint detail page Run Policy rather than a recurring schedule; the script header marks scheduled execution as not recommended because each run flushes and rebuilds AX_FailedLogins from the current log window
Optional: set exclude_private_ips=true (default) to skip 10.0.0.0/8, 192.168.0.0/16, and 172.16.0.0/12 through 172.31.0.0/16 sources and avoid blocking internal jump hosts or misconfigured colleagues
Conflict note: do not run this Worklet alongside fail2ban on the same endpoint; both will manage firewall rules from the same log signals and duplicate the offender list across two managers
On iptables endpoints, list the active block set with iptables -L AX_FailedLogins -n -v. Each offender appears as a DROP rule with a packet and byte counter that climbs as the botnet keeps retrying. Confirm the rate-limit hook by running iptables -L AX_FailedLogins -n -v and looking for the recent-module rules with --seconds 60 --hitcount <MaxAuthTries> -j DROP. On firewalld endpoints, run firewall-cmd --zone=AX_FailedLogins --list-all to see the bound ipsets and the SSH Auth Failure rich rules, and ipset list invalid_user_ip_set or ipset list failed_authentication_ip_set to see active members.
Connection attempts from a blocked IP terminate at the kernel netfilter layer. sshd never accepts the socket, PAM is never invoked, and the auth log stops growing for that source. The Automox Activity Log captures the count of DROP rules created during the run and which patterns matched (invalid user, failed authentication, MaxAuthTries excess) so the policy is auditable against CIS 5.2 and NIST 800-53 AC-7 evidence requests.
Each Worklet run rebuilds the block set from the current log window rather than appending to the previous run, because the remediation flushes AX_FailedLogins on iptables and deletes and recreates the AX_FailedLogins zone on firewalld before writing fresh rules. To clear the block list outside a Worklet run (after a network change or a false-positive incident), execute iptables -F AX_FailedLogins on iptables hosts or firewall-cmd --permanent --delete-zone=AX_FailedLogins followed by firewall-cmd --reload on firewalld hosts.


Loading...
Consider Worklets your easy button
A Worklet is an automation script, written in Bash or PowerShell, designed for seamless execution on endpoints – at scale – within the Automox platform. Worklets deploy named-CVE mitigations within hours of disclosure, perform configuration, remediation, and install or remove applications and settings across Windows, macOS, and Linux.

AUTOMOX + WORKLETS™
Uncover new possibilities with simple, powerful automation.
By submitting this form you agree to our Master Services Agreement and Privacy Policy
By submitting this form you agree to our Master Services Agreement and Privacy Policy.
Already have an account? Log in