I've just installed fail2ban on my CentOS server in response to an SSH brute force attempt. The default regular expressions in fail2ban's sshd.conf file do not match any entries in audit.log, which is where SSH seems to be logging all connection attempts, so I am trying to add an expression that will match.

The string I am trying to match is as follows:

type=USER_LOGIN msg=audit(1333630430.185:503332): user pid=30230 uid=0 auid=500
 subj=user_u:system_r:unconfined_t:s0-s0:c0.c1023 msg='acct="root": exe="/usr
/sbin/sshd" (hostname=?, addr=<HOST IP>, terminal=sshd res=failed)'

The regular expression I am attempting to use is:

^.*addr=<HOST>, terminal=sshd res=failed.*$

I've used regextester.com and regexr to try to build the regex. The testers give me a match for this regex:^.*addr=\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}, terminal=sshd res=failed.*$ but fail2ban-regex complains if I don't use the <HOST> tag in the regex. However, using ^.*addr=<HOST>, terminal=sshd res=failed.*$ gives me 0 matches.

At this point, I am totally stuck and I would greatly appreciate any assistance. What am I doing wrong in the regex I am trying to use?


Apparently this is a case of RTFM. After digging around for a while, I found a page on the fail2ban website that states that it makes two regex matches per line, one for the timestamp and one for the rest of the line following the timestamp. The timestamp in the audit.log is in Epoch format, and was apparently failing the first regex match. Using fail2ban-regex to compare /var/log/secure to my fail2ban sshd.conf file resulted in the desired behavior.

The correct solution was to point the appropriate section of my jail.conf at /var/log/secure.

For people who still want to make their own regular expressions, this section has a lot of good information, including this little tidbit that eventually helped me solve this:

In order for a log line to match your failregex, it actually has to match in two parts: the beginning of the line has to match a timestamp pattern or regex, and the remainder of the line has to match your failregex. If the failregex is anchored with a leading ^, then the anchor refers to the start of the remainder of the line, after the timestamp and intervening whitespace.

I hope that my RTFM moment will help someone down the line.

  • It absolutely did -- the manpages (and wiki, and web site, and other articles on this topic) aren't very obvious in this respect. It turns out I had my own regex (for detecting dragnet-style spamming of random inboxes) almost spot on... except I was trying to match the date strings... Which were already being matched. (And yes, I was using fail2ban-regex!) What confounds me is the slightly non-standard format fail2ban allows for its regex; it's far more 'compliant' when pattern matching. Both a blessing and a curse if you're trying to learn best practices. :-) Jun 8 '12 at 1:01
  • Actually I think the anchor refers to the point after the timestamp but before intervening whitespace.
    – augurar
    Mar 24 '16 at 23:58
  • 1
    fail2ban doc: 'The pattern or regex to match the time stamp is currently not documented, and not available for users to read or set.' - I was hoping they could do better May 28 '20 at 16:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.