fail2ban does not seem to ban an IP after repeated failed ssh login attempts

6,189

Solution 1

The following issue can be useful for more information: https://github.com/fail2ban/fail2ban/issues/2765, although it relates to more recent versions of fail2ban than the one mentioned in the question.

By default, the sshd filter doesn't ban repeated failed passkey login attempts for an existing/valid user.

On more recent versions (although not yet available in 0.11.1), the sshd filter has a publickey parameter than can be set to any in order to capture these failed attempts:

[sshd]
publickey = any
...

Otherwise, there is the option to use ddos (equivalent to your older ssh-dos filter?) or aggressive mode for the sshd filter (which would catch the 'connection closed' log entries followed by unsuccessful login attempts):

[sshd]
mode = aggressive
...

Finally (and this should be useful on any fail2ban version not having the publickey parameter in the sshd filter), you could add the following regex to your filter as suggested here:

[sshd]
failregex = %(known/failregex)s
            ^Failed publickey for <F-USER>.+</F-USER> from <HOST>

Solution 2

This worked for me under debian 10.

[sshd]
failregex = %(known/failregex)s
            ^.*Connection closed by authenticating user [a-z][-a-z0-9_]* <HOST> port \d+ \[preauth\]
Share:
6,189

Related videos on Youtube

Sean Hammond
Author by

Sean Hammond

Updated on September 18, 2022

Comments

  • Sean Hammond
    Sean Hammond almost 2 years

    I'm trying to figure out why Fail2Ban doesn't seem to be doing anything on my server.

    This is an Ubuntu 14.04 server:

    $ lsb_release -a
    No LSB modules are available.
    Distributor ID: Ubuntu
    Description:    Ubuntu 14.04.5 LTS
    Release:    14.04
    Codename:   trusty
    

    Fail2Ban v0.8.11 installed from the Ubuntu / Debian repos:

    $ fail2ban-client --version
    Fail2Ban v0.8.11
    ...
    

    Fail2Ban does appear to be running:

    $ sudo fail2ban-client status
    Status
    |- Number of jail:  3
    `- Jail list:       pam-generic, ssh-ddos, ssh
    

    But if I ssh into a Digital Ocean VM and from there repeatedly try and fail to ssh into the server it doesn't seem to ban me. I can do this as many times as I want:

    $ ssh -p 6879 ubuntu@my_server.net
    Permission denied (publickey).
    

    I don't see anything in the fail2ban logs other than messages about it starting up:

    $ sudo tail -n 10 /var/log/fail2ban.log
    2018-02-26 14:48:42,691 fail2ban.jail   : INFO   Creating new jail 'ssh-ddos'
    2018-02-26 14:48:42,691 fail2ban.jail   : INFO   Jail 'ssh-ddos' uses pyinotify
    2018-02-26 14:48:42,694 fail2ban.jail   : INFO   Initiated 'pyinotify' backend
    2018-02-26 14:48:42,694 fail2ban.filter : INFO   Added logfile = /var/log/auth.log
    2018-02-26 14:48:42,695 fail2ban.filter : INFO   Set maxRetry = 6
    2018-02-26 14:48:42,696 fail2ban.filter : INFO   Set findtime = 600
    2018-02-26 14:48:42,696 fail2ban.actions: INFO   Set banTime = 86400
    2018-02-26 14:48:42,700 fail2ban.jail   : INFO   Jail 'ssh' started
    2018-02-26 14:48:42,702 fail2ban.jail   : INFO   Jail 'pam-generic' started
    2018-02-26 14:48:42,703 fail2ban.jail   : INFO   Jail 'ssh-ddos' started
    

    My fail2ban config is just what's packaged with Ubuntu / Debian, plus a jail.local file of my own.

    Here's my /etc/fail2ban/jail.local file (note: I've tried changing [ssh] to [sshd] and adding filter=sshd and logpath = /var/log/auth.log to it - no difference):

    [DEFAULT]
    
    ignoreip  = 127.0.0.1 10.1.3.105
    bantime   = 86400
    destemail = <MY EMAIL>
    banaction = iptables-multiport
    action    = %(action_)s
    
    # JAILS
    [ssh]
    enabled  = true
    maxretry = 3
    port     = 6879
    
    [pam-generic]
    enabled   = true
    banaction = iptables-allports
    
    [ssh-ddos]
    enabled = true
    

    And here's my /etc/fail2ban/jail.conf file, this is unmodified from what's packaged with Ubuntu 14.04:

    # Fail2Ban configuration file.
    #
    # This file was composed for Debian systems from the original one
    # provided now under /usr/share/doc/fail2ban/examples/jail.conf
    # for additional examples.
    #
    # Comments: use '#' for comment lines and ';' for inline comments
    #
    # To avoid merges during upgrades DO NOT MODIFY THIS FILE
    # and rather provide your changes in /etc/fail2ban/jail.local
    #
    
    # The DEFAULT allows a global definition of the options. They can be overridden
    # in each jail afterwards.
    
    [DEFAULT]
    
    # "ignoreip" can be an IP address, a CIDR mask or a DNS host. Fail2ban will not
    # ban a host which matches an address in this list. Several addresses can be
    # defined using space separator.
    ignoreip = 127.0.0.1/8
    
    # "bantime" is the number of seconds that a host is banned.
    bantime  = 600
    
    # A host is banned if it has generated "maxretry" during the last "findtime"
    # seconds.
    findtime = 600
    maxretry = 3
    
    # "backend" specifies the backend used to get files modification.
    # Available options are "pyinotify", "gamin", "polling" and "auto".
    # This option can be overridden in each jail as well.
    #
    # pyinotify: requires pyinotify (a file alteration monitor) to be installed.
    #            If pyinotify is not installed, Fail2ban will use auto.
    # gamin:     requires Gamin (a file alteration monitor) to be installed.
    #            If Gamin is not installed, Fail2ban will use auto.
    # polling:   uses a polling algorithm which does not require external libraries.
    # auto:      will try to use the following backends, in order:
    #            pyinotify, gamin, polling.
    backend = auto
    
    # "usedns" specifies if jails should trust hostnames in logs,
    #   warn when reverse DNS lookups are performed, or ignore all hostnames in logs
    #
    # yes:   if a hostname is encountered, a reverse DNS lookup will be performed.
    # warn:  if a hostname is encountered, a reverse DNS lookup will be performed,
    #        but it will be logged as a warning.
    # no:    if a hostname is encountered, will not be used for banning,
    #        but it will be logged as info.
    usedns = warn
    
    #
    # Destination email address used solely for the interpolations in
    # jail.{conf,local} configuration files.
    destemail = root@localhost
    
    #
    # Name of the sender for mta actions
    sendername = Fail2Ban
    
    #
    # ACTIONS
    #
    
    # Default banning action (e.g. iptables, iptables-new,
    # iptables-multiport, shorewall, etc) It is used to define
    # action_* variables. Can be overridden globally or per
    # section within jail.local file
    banaction = iptables-multiport
    
    # email action. Since 0.8.1 upstream fail2ban uses sendmail
    # MTA for the mailing. Change mta configuration parameter to mail
    # if you want to revert to conventional 'mail'.
    mta = sendmail
    
    # Default protocol
    protocol = tcp
    
    # Specify chain where jumps would need to be added in iptables-* actions
    chain = INPUT
    
    #
    # Action shortcuts. To be used to define action parameter
    
    # The simplest action to take: ban only
    action_ = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
    
    # ban & send an e-mail with whois report to the destemail.
    action_mw = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
                %(mta)s-whois[name=%(__name__)s, dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s", sendername="%(sendername)s"]
    
    # ban & send an e-mail with whois report and relevant log lines
    # to the destemail.
    action_mwl = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
                %(mta)s-whois-lines[name=%(__name__)s, dest="%(destemail)s", logpath=%(logpath)s, chain="%(chain)s", sendername="%(sendername)s"]
    
    # Choose default action.  To change, just override value of 'action' with the
    # interpolation to the chosen action shortcut (e.g.  action_mw, action_mwl, etc) in jail.local
    # globally (section [DEFAULT]) or per specific section
    action = %(action_)s
    
    #
    # JAILS
    #
    
    # Next jails corresponds to the standard configuration in Fail2ban 0.6 which
    # was shipped in Debian. Enable any defined here jail by including
    #
    # [SECTION_NAME]
    # enabled = true
    
    #
    # in /etc/fail2ban/jail.local.
    #
    # Optionally you may override any other parameter (e.g. banaction,
    # action, port, logpath, etc) in that section within jail.local
    
    [ssh]
    
    enabled  = true
    port     = ssh
    filter   = sshd
    logpath  = /var/log/auth.log
    maxretry = 6
    
    [dropbear]
    
    enabled  = false
    port     = ssh
    filter   = dropbear
    logpath  = /var/log/auth.log
    maxretry = 6
    
    # Generic filter for pam. Has to be used with action which bans all ports
    # such as iptables-allports, shorewall
    [pam-generic]
    
    enabled  = false
    # pam-generic filter can be customized to monitor specific subset of 'tty's
    filter   = pam-generic
    # port actually must be irrelevant but lets leave it all for some possible uses
    port     = all
    banaction = iptables-allports
    port     = anyport
    logpath  = /var/log/auth.log
    maxretry = 6
    
    [xinetd-fail]
    
    enabled   = false
    filter    = xinetd-fail
    port      = all
    banaction = iptables-multiport-log
    logpath   = /var/log/daemon.log
    maxretry  = 2
    
    
    [ssh-ddos]
    
    enabled  = false
    port     = ssh
    filter   = sshd-ddos
    logpath  = /var/log/auth.log
    maxretry = 6
    
    
    # Here we use blackhole routes for not requiring any additional kernel support
    # to store large volumes of banned IPs
    
    [ssh-route]
    
    enabled = false
    filter = sshd
    action = route
    logpath = /var/log/sshd.log
    maxretry = 6
    
    # Here we use a combination of Netfilter/Iptables and IPsets
    # for storing large volumes of banned IPs
    #
    # IPset comes in two versions. See ipset -V for which one to use
    # requires the ipset package and kernel support.
    [ssh-iptables-ipset4]
    
    enabled  = false
    port     = ssh
    filter   = sshd
    banaction = iptables-ipset-proto4
    logpath  = /var/log/sshd.log
    maxretry = 6
    
    [ssh-iptables-ipset6]
    
    enabled  = false
    port     = ssh
    filter   = sshd
    banaction = iptables-ipset-proto6
    logpath  = /var/log/sshd.log
    maxretry = 6
    
    
    #
    # HTTP servers
    #
    
    [apache]
    
    enabled  = false
    port     = http,https
    filter   = apache-auth
    logpath  = /var/log/apache*/*error.log
    maxretry = 6
    
    # default action is now multiport, so apache-multiport jail was left
    # for compatibility with previous (<0.7.6-2) releases
    [apache-multiport]
    
    enabled   = false
    port      = http,https
    filter    = apache-auth
    logpath   = /var/log/apache*/*error.log
    maxretry  = 6
    
    [apache-noscript]
    
    enabled  = false
    port     = http,https
    filter   = apache-noscript
    logpath  = /var/log/apache*/*error.log
    maxretry = 6
    
    [apache-overflows]
    
    enabled  = false
    port     = http,https
    filter   = apache-overflows
    logpath  = /var/log/apache*/*error.log
    maxretry = 2
    
    # Ban attackers that try to use PHP's URL-fopen() functionality
    # through GET/POST variables. - Experimental, with more than a year
    # of usage in production environments.
    
    [php-url-fopen]
    
    enabled = false
    port    = http,https
    filter  = php-url-fopen
    logpath = /var/www/*/logs/access_log
    
    # A simple PHP-fastcgi jail which works with lighttpd.
    # If you run a lighttpd server, then you probably will
    # find these kinds of messages in your error_log:
    #   ALERT – tried to register forbidden variable ‘GLOBALS’
    #   through GET variables (attacker '1.2.3.4', file '/var/www/default/htdocs/index.php')
    
    [lighttpd-fastcgi]
    
    enabled = false
    port    = http,https
    filter  = lighttpd-fastcgi
    logpath = /var/log/lighttpd/error.log
    
    # Same as above for mod_auth
    # It catches wrong authentifications
    
    [lighttpd-auth]
    
    enabled = false
    port    = http,https
    filter  = suhosin
    logpath = /var/log/lighttpd/error.log
    
    [nginx-http-auth]
    
    enabled = false
    filter  = nginx-http-auth
    port    = http,https
    logpath = /var/log/nginx/error.log
    
    # Monitor roundcube server
    
    [roundcube-auth]
    
    enabled  = false
    filter   = roundcube-auth
    port     = http,https
    logpath  = /var/log/roundcube/userlogins
    
    
    [sogo-auth]
    
    enabled  = false
    filter   = sogo-auth
    port     = http, https
    # without proxy this would be:
    # port    = 20000
    logpath  = /var/log/sogo/sogo.log
    
    
    #
    # FTP servers
    #
    
    [vsftpd]
    
    enabled  = false
    port     = ftp,ftp-data,ftps,ftps-data
    filter   = vsftpd
    logpath  = /var/log/vsftpd.log
    # or overwrite it in jails.local to be
    # logpath = /var/log/auth.log
    # if you want to rely on PAM failed login attempts
    # vsftpd's failregex should match both of those formats
    maxretry = 6
    
    
    [proftpd]
    
    enabled  = false
    port     = ftp,ftp-data,ftps,ftps-data
    filter   = proftpd
    logpath  = /var/log/proftpd/proftpd.log
    maxretry = 6
    
    
    [pure-ftpd]
    
    enabled  = false
    port     = ftp,ftp-data,ftps,ftps-data
    filter   = pure-ftpd
    logpath  = /var/log/syslog
    maxretry = 6
    
    
    [wuftpd]
    
    enabled  = false
    port     = ftp,ftp-data,ftps,ftps-data
    filter   = wuftpd
    logpath  = /var/log/syslog
    maxretry = 6
    
    
    #
    # Mail servers
    #
    
    [postfix]
    
    enabled  = false
    port     = smtp,ssmtp,submission
    filter   = postfix
    logpath  = /var/log/mail.log
    
    
    [couriersmtp]
    
    enabled  = false
    port     = smtp,ssmtp,submission
    filter   = couriersmtp
    logpath  = /var/log/mail.log
    
    
    #
    # Mail servers authenticators: might be used for smtp,ftp,imap servers, so
    # all relevant ports get banned
    #
    
    [courierauth]
    
    enabled  = false
    port     = smtp,ssmtp,submission,imap2,imap3,imaps,pop3,pop3s
    filter   = courierlogin
    logpath  = /var/log/mail.log
    
    
    [sasl]
    
    enabled  = false
    port     = smtp,ssmtp,submission,imap2,imap3,imaps,pop3,pop3s
    filter   = postfix-sasl
    # You might consider monitoring /var/log/mail.warn instead if you are
    # running postfix since it would provide the same log lines at the
    # "warn" level but overall at the smaller filesize.
    logpath  = /var/log/mail.log
    
    [dovecot]
    
    enabled = false
    port    = smtp,ssmtp,submission,imap2,imap3,imaps,pop3,pop3s
    filter  = dovecot
    logpath = /var/log/mail.log
    
    # To log wrong MySQL access attempts add to /etc/my.cnf:
    # log-error=/var/log/mysqld.log
    # log-warning = 2
    [mysqld-auth]
    
    enabled  = false
    filter   = mysqld-auth
    port     = 3306
    logpath  = /var/log/mysqld.log
    
    
    # DNS Servers
    
    
    # These jails block attacks against named (bind9). By default, logging is off
    # with bind9 installation. You will need something like this:
    #
    # logging {
    #     channel security_file {
    #         file "/var/log/named/security.log" versions 3 size 30m;
    #         severity dynamic;
    #         print-time yes;
    #     };
    #     category security {
    #         security_file;
    #     };
    # };
    #
    # in your named.conf to provide proper logging
    
    # !!! WARNING !!!
    #   Since UDP is connection-less protocol, spoofing of IP and imitation
    #   of illegal actions is way too simple.  Thus enabling of this filter
    #   might provide an easy way for implementing a DoS against a chosen
    #   victim. See
    #    http://nion.modprobe.de/blog/archives/690-fail2ban-+-dns-fail.html
    #   Please DO NOT USE this jail unless you know what you are doing.
    #[named-refused-udp]
    #
    #enabled  = false
    #port     = domain,953
    #protocol = udp
    #filter   = named-refused
    #logpath  = /var/log/named/security.log
    
    [named-refused-tcp]
    
    enabled  = false
    port     = domain,953
    protocol = tcp
    filter   = named-refused
    logpath  = /var/log/named/security.log
    
    # Multiple jails, 1 per protocol, are necessary ATM:
    # see https://github.com/fail2ban/fail2ban/issues/37
    [asterisk-tcp]
    
    enabled  = false
    filter   = asterisk
    port     = 5060,5061
    protocol = tcp
    logpath  = /var/log/asterisk/messages
    
    [asterisk-udp]
    
    enabled  = false
    filter   = asterisk
    port     = 5060,5061
    protocol = udp
    logpath  = /var/log/asterisk/messages
    
    
    # Jail for more extended banning of persistent abusers
    # !!! WARNING !!!
    #   Make sure that your loglevel specified in fail2ban.conf/.local
    #   is not at DEBUG level -- which might then cause fail2ban to fall into
    #   an infinite loop constantly feeding itself with non-informative lines
    [recidive]
    
    enabled  = false
    filter   = recidive
    logpath  = /var/log/fail2ban.log
    action   = iptables-allports[name=recidive]
            sendmail-whois-lines[name=recidive, logpath=/var/log/fail2ban.log]
    bantime  = 604800  ; 1 week
    findtime = 86400   ; 1 day
    maxretry = 5
    
  • Osman-pasha
    Osman-pasha over 2 years
    AFAIK, it's gamin. Also, fail2ban has a polling fallback backend to read the logs if nothing is installed.