ssh-blocker
NAME ssh-blocker - read a log pipe and block attacks with ipset
OVERVIEW ssh-blocker is a program that reads log lines from a named pipe (FIFO) and tries to find IP addresses in lines containing login attempts. On a successful login attempt, the address is added to a whitelist. When a certain number of invalid login attempts is reached within a pre-defined period, the address will be added to a blacklist.
The whitelist and blacklists are stored with ipset[1], a relevant iptables
rule must exist that take care of it. Using ipset, the blocked address will
expire after some time.
REQUIREMENTS This program needs the following libraries:
libipset - for keeping a blacklist and whitelist of IP addresses
The following programs are recommended:
OpenSSH - the service to protect by reading its logs.
One log provider must be available:
systemd - for retrieving log messages from the systemd journal.
Debian Wheezy has been used for testing. Older versions of the above software may also work, but is no guaranteed.
CONFIGURATION The file ssh-blocker.h can be changed to adapt to your configuration. Some interesting defaults are shown below:
BLOCK_TIME - If an IP address is blocked, it will last 3600 seconds (one hour).
For more options, see the comments in ssh-blocker.h.
Edit your sshd configuration (/etc/ssh/sshd_config) and set "UseDNS no". This will prevent IP addresses from being resolved to hostnames. Reload the SSH configuration thereafter.
Exactly one log provider can be used, this must be specified at compile time.
(for rsyslog only) Assuming the named pipe to be located at /run/ssh-blocker.fifo, create a new rsyslog configuration file (/etc/rsyslog.d/ssh-blocker.conf) containing:
:programname,isequal,"sshd" |/run/ssh-blocker.fifo
For best security, create a new system user, say "ssh-blocker". Its shell can be /sbin/nologin with /nonexistent as home directory.
To finish, you need to perform actions in the correct order and add iptables rules. Continue reading the USAGE section.
USAGE There are some ways to set-up this program:
Manually create the whitelist and blacklist ipsets, set iptables rules and start this program. Alternative: start this program and set iptables rules thereafter.
The command is invoked as follows:
ssh-blocker -d username log-pipe-file
Or if systemd is used instead of a pipe:
ssh-blocker -d username
"-d" is optional, it causes the program to daemonize. This happens just before log entries are read, so any errors in opening the fifo, dropping privileges can be caught earlier. Note that "-d" can be specified only as the first argument, getopt is not used for now.
"username" is the user under which the program should run. Do not run this program under someone like "nobody" because all "nobody" users can kill this program, write junk to the FIFO or ptrace it if settings/permissions allow it. When using the systemd (journal) source, be sure that this user is a member of the 'systemd-journal' group).
(only applicable in log pipe configuration) "log-pipe-file" must be replaced by the path to a named pipe. If it does not exist at start-up, it will be created with permissions 0600 (read/write for owner only) under the user and group the program was started with. If the file already exists, it must be a FIFO that is owned by root (or the user that started this program) and not be world-writable.
(only applicable in log pipe configuration) Suggested start-up order:
(rsyslog starts here)
When the iptables rules are loaded:
Recommended: add your own IP addresses to the ssh-whitelist. For example, if your IP is 203.0.113.1:
ipset -exist add ssh-whitelist 203.0.113.1 timeout 0
Since the the ipsets are created with no timeout by default, this will be permanently saved (well, as long as you do not destroy or flush the sets).
An example ipset ruleset for SSH: -N ssh -A INPUT -p tcp --dport 22 -j ssh
-A ssh -m set --match-set ssh-whitelist src -j ACCEPT -A ssh -m set --match-set ssh-blocklist src -j DROP
-A ssh -m recent --name ssh --update --seconds 60 --hitcount 10 -j DROP -A ssh -m recent --name ssh --set -A ssh -j ACCEPT
SECURITY This program was originally created to reduce syslog spam. It can also be used as a replacement for Fail2ban or DenyHosts if you do not need fancy features. As with any program that monitors syslog, note that syslog can usually be written by everyone. That means that rogue local users can insert bogus entries into the syslog. It is as trivial as:
logger -p auth.notice -t sshd[1337] '...'
Therefore, use this program with care. Add known good IP addresses to the
whitelist and do not let untrusted users to your system.
When the program is run as root, it tightens its capabilities to
CAP_NET_ADMIN (for ipset) and CAP_SETUID+CAP_SETGID (for changing users).
Then it changes to the user as specified in the command line arguments. When
the user has succesfully changed its real, effective and saved uid/gid, it
will further tighten its privileges to include CAP_NET_ADMIN only. Note that
the log file is created and/ or opened before changing users.
TODO
AUTHORS Written by Peter Wu.
REPORTING BUGS Report bugs to Peter Wu peter@lekensteyn.nl.
COPYRIGHT Copyright (c) 2013-2016 Peter Wu. License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.