Resources: Maxlogins
This page contains information about free programs and utilities made available to the public. Please read the license terms and disclaimer accompanying each before using.
- Download (opens in browser as a text file for easy copy/paste)
Documentation is also at the end of the program code (perldoc maxlogins.plor maxlogins.pl -h).
Documentation
NAME
maxlogins.pl - block ssh break-in attempts.
DESCRIPTION
Maxlogins tracks (in real time) repeated bad ssh login
attempts and adds offending IPs to a blacklist used by
/etc/hosts.allow (tcp wrappers) to block further access.
It is not designed to be run from a shell prompt and does
not permanently occupy a process.
COPYRIGHT AND VERSION HISTORY
Copyright (c) 2005,2006 ITS, Inc. Written by Steve Yates.
Latest version at www.teamITS.com/resources.
Originally based upon a concept from a script by Matt Smith and
David Godsey from CodeNameHosting.com, posted to the
vps2@providertalk.com mailing list 2005/03/22 as maxsec.pl.
Thanks also for ideas to Scott's Rascals program and blog
(scott.wiersdorf.org/blog), and a tip from Phil.
v2.0 - 2006/09/12
Major rewrite. Add tracking of multiple IPs, self-
expiring blocks, process killing, command line
options, and improved log entry processing and file
locking.
v1.3 - 2005/07/10
v1.2 - 2005/07/01
v1.0 - 2005/06/19
LICENSE
This program is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public
License as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any
later version.
This program is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU General Public License for more
details.
For a copy of the GNU General Public License visit
http://www.gnu.org or write to the Free Software Founda-
tion, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
INSTRUCTIONS
1) Copy this file to /usr/local/bin/maxlogins.pl or your
favorite location. If you paste it into a text editor,
use one that won't wrap long lines like "ee" or "pico -w".
2) Run chown root:wheel /usr/local/bin/maxlogins.pl.
3) Run chmod 750 /usr/local/bin/maxlogins.pl.
4) Add to /etc/syslog.conf a second entry for auth logs
like so:
auth.info;authpriv.info /var/log/auth.log # original line
auth.info;authpriv.info |exec /usr/local/bin/maxlogins.pl # added
5) Optional: add command line options to the line in
/etc/syslog.conf to change settings.
6) Back up /etc/hosts.allow, and add the following lines
to the top of the file (above "ALL : ALL : allow").
sshd : 127.0.0.1 : allow
sshd : /var/log/maxlogins : deny
This will effectively whitelist any "allow"ed IPs
(127.0.0.1, above) that appear before the "deny" entry.
7) Restart syslogd (killall -HUP syslogd).
COMMAND LINE OPTIONS
badipfile (-b)
Sets location of the list of blocked IP addresses.
Should be located in a directory writeable only by root,
for security purposes. Default: /var/log/maxlogins.
Note an associated lock file will be created (e.g.,
/var/log/maxlogins.lock) as well as a temporary file
(e.g., /var/log/maxlogins.new.*). The temp file will be
removed rather quickly after creation.
expire (-e)
Sets the time before a blocked IP address "expires" and
the block is removed. Accepts day/hour/minute/second
notation, e.g. 1d, 24h, 1440m, and 86400s are all equiv-
alent. Default: 12h.
Note: blocks expire and are removed when maxlogins runs,
i.e., when something writes to auth.log. You can also
run maxlogins from cron at any desired interval (> 5
seconds) to clean out expired IPs on a regular basis.
kill (-k)
Set to 1 to kill the sshd process being used by the
cracker, to prevent additional login attempts on the
already-open connection. Set to 0 if you do not want to
do this. Default: 1.
loglevel (-l)
Sets logging level for entries in /var/log/auth.log.
Default: 1.
1: informational (e.g., new blocks)
2: above, plus IP expirations
9: verbose logging
maxattempts (-a)
Sets number of failed login attempts before an IP
address is blocked. As you lower the number of failed
login attempts you may want to decrease the expiration
(e.g., 1 failed login, expires in 1 minute). The author
has found that most "bots" move on after the first
failed connection attempt, and do not try again. If you
set this to 1, beware of a password typo triggering the
block! Max: 50. Default: 3.
maxsuspects (-s)
Set to the number of IP addresses for which maxlogins
will track the number of failed logins. To protect
against a widely distributed attack, set this number
higher. Suspects expire after 24 hours or when a new
suspect is added and maxsuspects is exceeded. Max: 50.
Default: 3.
version (-v)
Displays version number and exits.
Examples:
(at end of line in syslog.conf; see INSTRUCTIONS...in
particular, restart syslogd after modifying sys-
log.conf):
... |exec /usr/local/bin/maxlogins.pl -a=2 -l=9 -e=1d
... |exec /usr/local/bin/maxlogins.pl --loglevel=2 --expire=6h
TESTING
Do not lock yourself out! Do not lock yourself out! Either
add your IP to hosts.allow (see above), keep a second SSH
session open during testing, test by connecting from
another host (besides your computer), or test via the com-
mand line using one of the following:
(1) After modifying /etc/syslog.conf and restarting sys-
logd (enter all on one line):
logger -p auth.info "sshd[00000]: Failed password for root from 10.0.0.1 port 55555 test"
(note: change something ("test2", "test3", "test4") each
time (or wait 1 second between tries) when using logger,
otherwise subsequent attempts will just generate a "last
message repeated _ times" entry and not trigger a block)
(2) Or, this also works before modifying /etc/syslog.conf
(enter all on one line):
echo "sshd[00000]: Failed password for root from 10.0.0.1 port 55555 test" |/usr/local/bin/maxlogins.pl
If logging is enabled, grep maxlogins /var/log/auth.log
will show log entries. Use "--loglevel=9" to show
detailed logging.
Always use process ID 00000 when testing. Maxlogins will
not attempt to kill PID 00000, but by default will kill
other PIDs, unless "--kill=0" is specified. If you use a
random number you will kill a random process!
RECOMMENDATIONS
- Consider running sshd from inetd, to throttle connection
attempts. Maxlogins runs for each log entry, however, it
will remain running until log activity ceases. An inetd
entry like so:
ssh stream tcp nowait/30/5/15 root /usr/sbin/sshd sshd -i -4
...will limit sshd to 30 child processes, 5 connections
per IP per minute, and 15 simultaneous invocations per IP
address. This is the default setup for ViaVerio VPS/MPS
servers.
- Create a backup of /etc/hosts.allow before starting.
Backups never hurt.
- Strongly consider whitelisting your IP (see INSTRUCTIONS
above) or leaving a second ssh session open during test-
ing, in case maxlogins works and you lock yourself out.
An open SSH session will not be cut off via adding a block
to hosts.allow.
- Do not pick a very large expiration time. Most bots do
not continue trying to connect to a denied connection, and
the bigger the blacklist gets the (slightly) slower maxlo-
gins may become.
IDEAS
/etc/hosts.allow examples
sshd : /var/log/maxlogins : spawn /bin/sleep 30 : twist /bin/echo "go away"
sshd : /var/log/maxlogins : twist /bin/echo "Access denied."
Too long a sleep period may use up many processes if the
attacker is using multiple connections.
Crontab example
@hourly /usr/local/bin/maxlogins.pl
Runs maxlogins every hour to remove expired IP addresses
from the list. Not required, but guarantees maxlogins is
run on a regular basis, as opposed to waiting until the
next line is written to auth.log. Maxlogins will run and
exit on its own after a few seconds.
COMPATIBILITY
Tested under Perl 5.8.4 and 5.6.1, and FreeBSD 4.7. Should
work with later syslogd-based systems and Perl versions.







