6

I have openSMPTD running a mail server. It seems I am getting brute forced attacked currently, although I doubt they will get in. That being said, I would like to alleviate the burden on my server with the constant log-in attempts. I am configuring fail2ban to ban the offenders. However, I can not quite get the correct regex and it is driving me mad! I saw this link on the freeBSD forum about the fail2ban regex to catch it. However, even that regex did not seem to capture the example text they provided. I edited their regex to no avail. I am hoping someone can give me some pointers as I am super weak in regexs.

My log files looks like:

Dec 25 20:03:29 frick mail.info smtpd[16849]: f7fa148a43b34578 smtp connected address=193.169.254.42 host=<unknown>
Dec 25 20:03:30 frick mail.info smtpd[16849]: f7fa148a43b34578 smtp tls ciphers=TLSv1.2:ECDHE-RSA-AES128-SHA256:128
Dec 25 20:03:30 frick mail.info smtpd[16849]: f7fa148a43b34578 smtp authentication user=info result=permfail
Dec 25 20:03:30 frick mail.info smtpd[16849]: f7fa148a43b34578 smtp failed-command command="AUTH LOGIN (password)" result="535 Authentication failed"
Dec 25 20:03:30 frick mail.info smtpd[16849]: f7fa148a43b34578 smtp disconnected reason=quit
"

So let's break this down: the line that shows they are brute forcing is:

f7fa148a43b34578 smtp failed-command command="AUTH LOGIN (password)" result="535 Authentication failed"

Where we see authentication failed. However, oddly, openSMTPD does not include their ip address to ban in that line: We have to look a variable number above it to:

f7fa148a43b34578 smtp connected address=193.169.254.42 host=<unknown>

Where we can see the offender's ip address. Okay, fair enough. The current regex I have that selects all the text is:

^.*smtp connected address=\w[1-9.]* host=[a-z<>]*\n*[a-zA-Z0-9_.-\s\]\[:=<>"()]*

although fail2ban wants a more fine grained one. I am not sure I have a clean way of getting the appropiate ip address to ban as it is possible two people connect at once, and then the wrong line is picked up to ban.

Any suggestions?

6
  • 1
    address=\w[ - what is the \w for? The IP starts with a number right away. The host section I read zero or more of a-z<>, then zero or more newlines, then zero or more of mostly anything. I would consider to preprocess the lines to match the correct mail ids together and then use it fail2ban, it may be quite annoying, but I think you have to match the correct pairs of "f7fa148a43b34578" lines together. Dec 26, 2020 at 21:32
  • 1
    @petr, you know, you might be right. Maybe different log in attempts have that different hash or identifier or whatever it is at the beginning. Edit: you are correct. genius Dec 27, 2020 at 3:01
  • Man I suck with regexs. But I think based on your login: it is select the log identifier 'f7..78..' and the ip address where the person connects, then match it to auth failed where the log identifier is the same. Dec 27, 2020 at 21:59
  • Heres what I have for the token: (?<=: )(?<token_identifier>[a-zA-Z0-9]*) Dec 27, 2020 at 22:44
  • (?<=: )(?<token_identifier>[a-zA-Z0-9]*) smtp connected address=(?<ipaddress>[0-9:.])* This gets me the token and the ip address in a capture group Dec 27, 2020 at 22:47

1 Answer 1

1

The newer and cleaner way to use a multi-line regex would be to use the <F-...> tags which were introduced in the 0.10.0 version and are unfortunately still not well documented.

[Definition]

prefregex = <F-MLFID>: \w{16} </F-MLFID><F-CONTENT>.+</F-CONTENT>$

failregex = <F-NOFAIL>smtp connected address=(?:<IP6>|<IP4>)</F-NOFAIL>
            smtp failed-command command="AUTH LOGIN \(password\)" result="535 Authentication failed"
            <F-NOFAIL><F-MLFFORGET>smtp disconnected</F-MLFFORGET></F-NOFAIL>

Explanation

The pre-filter regex is used to preprocess each line and capture the session id, which I assume is the f7fa148a43b34578 part, and identify the same session spanning in multiple lines. The text inside <F-CONTENT> is the part we are interested in and which will be processed by the failregex.

In the failregex, the first one matches the line with the IP address, which will be needed if a ban is to be issued, and is enclosed in the <F-NOFAIL> tags to indicate that the line is not considered a failure. The second regex is the actual authentication failure, which if matched, then fail2ban will block the previously captured IP address. The last one is surrounded by the <F-MLFFORGET> directive, to signal that it's time to drop the captured connection ID (since the user has disconnected), and it is also enclosed between <F-NOFAIL> tags because that line by itself is not a failure either.

You can use the fail2ban-regex tool to test this.

I can see why the regex from the linked forum post didn't work for you; the string is different in more than one parts. So obviously you will need to change the 2nd failregex from above if you'd like to match more generic cases (I'm not using opensmtpd so I can't help you with that).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .