# Using fail2ban to stop brute-force attacks on Samba-server?

One of the facilities which Linux systems have, at least under Debian / Jessie and Debian / Stretch, is a package named ‘fail2ban‘, which can be configured using ‘root’ privileges on a host-machine, to protect specific services against brute-force attacks. This package relies on the ‘iptables’ command-line, but is highly adaptable to give different levels of security. If an attacker has failed too many times, to guess at the log-in credentials of a given server / user-id, that attacker is banned for a specified amount of time. And, because of that amount of time, brute-force attacks would become ineffective, at guessing the log-in.

I have fail2ban set up out-of-the-box, to protect my ‘ssh’, my ‘apache’, and my ‘vsftp’ servers. But one fact which many people have lamented, is that there is no packaged recipe, to protect Samba servers. One reason for this omission, is the mere fact that a Samba server should never be exposed to the Internet, i.e., the WAN, only to the LAN.

But just last night it happened to me, that two Android devices were running security software which had recently been updated, and that both these Android devices sounded an alarm simultaneously, indicating that my Home-WiFi had been hacked. I understood that these alarms could have been false-positives at the time, but just in case they were not, I decided to button down access to my computers, which is granted to members of my Home-LAN, even if those members appear to be authenticated into my LAN. One of the tasks which I assigned myself was, to reduce write-access to Samba shares even to authenticated members, by way of Usershares. And another measure which I undertook, was to devise my own recipe, to extend the protection that fail2ban gives, to include Samba servers.

Long story short, the two simultaneous alarms were in fact false-positives, which can be recognized by the fact that on both Android devices, the alarms became silent, as soon as a (very hurried) update was downloaded and installed, only to the security software which was giving the alarms. But now, I seem to have a recipe left over from last night, for securing my Samba server against brute-force attacks, using fail2ban…

I cannot really guarantee that this recipe will secure a Samba server which may have been left open entirely to the Internet / WAN, because in addition to the patterns this will recognize, Samba can give other messages, which could be due to some more-subtle spoofing. What I am hoping is that If a brute-force approach was being used, just to obtain the Password associated with one User-Id, that could be foiled. This recipe is untested – because last night’s attack was not real – but with some more tweaking, may prove useful after all.

The first task which needs to be fulfilled, is that a definition must be written, which should recognize an attacker. This definition is to be stored in the file

‘/etc/fail2ban/filter.d/samba.conf’ :


#Samba brute-force detection, by Dirk Mittler
[INCLUDES]

# Read common prefixes. If any customizations available -- read them from
# common.local
before = common.conf

[Definition]

_daemon = smbd

failregex = ^%(__prefix_line)s.*[aA]uthentication for user .* from <HOST> .* FAILED\s.*$^%(__prefix_line)s.*Failed [-/\w]+ for .* from <HOST>\s.*$
^%(__prefix_line)s.*ROOT LOGIN REFUSED .* FROM <HOST>\s.*$^%(__prefix_line)s.*[iI](?:llegal|nvalid) user .* from <HOST>\s.*$



This definition won’t work as it is – see below!

This particular pattern-match will be the most susceptible to errors, from me, and if other power-users see error messages in their syslog (see below), they may want to add definitions.

But, the next challenge when devising such a scheme would be, that by default, Samba does not output its logs to one file. Instead, Samba is usually configured – in my experience – to log to a set of files, whose names generally end in the host-name or host-ip, of whichever client is attempting access. And so this behavior of Samba would need to be modified, and several recipes have been suggested on the Web, all of which I find to be too-massively complex to implement directly. Instead, I have told Samba to raise its logging-levels, particularly in response to ‘auth_audit’, and to send all messages whose numbers are smaller than 3, to the syslog, by putting the following lines under the ‘[Global]’ section, of

‘/etc/samba/smb.conf’ :


[global]

syslog = 3
log level = 1 passdb:3 auth:3 winbind:3



These options could be overridden by other options, which the reader may have set, but which I’m not aware of, resulting in failure.

Finally, to activate the setup, the following configuration needs to be added, to

‘/etc/fail2ban/jail.local’ :


[samba]

enabled = true
port = 135,139,445,137,138
filter = samba
logpath  = /var/log/syslog
maxretry = 4



This set of custom-filters may result in a configuration of fail2ban which will not start. I know this, because I, myself had to make several attempts at it, before fail2ban ran, and before it created the jails successfully in the ‘iptables‘. In case the reader’s configurations need to be different, I urge the reader to test whether this configuration works for them, and if not, to tweak it.

Note:

The above configuration will spam the syslog, with messages that have a smaller (= higher) level-number than 3, and which seem to amount to gibberish, according to first-order inspection. These messages are harmless, especially since I, myself, am only interested in counting the number of actual attempts, to guess a password, and since the approach I’ve given would be the simplest way to do that.

Some sources would suggest activating a full audit, which of course would also generate even-more logging messages. Those approaches would also require creating a separate output file, for which log-rotations would need to be set up as well. I did not find that level of logging-detail necessary, and will consequently not need to set up special log-rotations either.

Erratum:

The above filter has as main weakness, that simply by logging debug-class ‘auth’ , I do not cause the IP-address of the party to be output with the message. In other words, the part of the pattern that reads ‘ .* from <HOST> .* ‘ will never happen.

In order to correct this problem, I’d need to use debug-class ‘auth_audit’. But wouldn’t the reader have guessed, that my Samba version (4.2) does not support that debug-class yet. It could only be Samba versions (4.5) that started support for that class, in which case we’d see what the output-line is supposed to be:

So this kind of puts a damper, on how much good my filter can do.

(Edit 04/02/2018 :

Another reason why the regex above wouldn’t work, is the fact that it uses the greedy pattern ‘ .* ‘ . This pattern will match as many characters as it can, not leaving some matches to the next occurrence of ‘ .* ‘ . In order to rectify this, the pattern would need to be changed to:

.*?A

For example, so that pattern-matching stops, with the first occurrence of ‘A’. Doing it this proper way, makes writing the regex much more difficult. )

Can’t use full_audit either!

The problem when setting up the ‘vfs_full_audit’ facility is, that although doing so will log every file-manipulation, and even log the IP-address of the client that commanded it, this facility fails to log authentication-attempts. It just assumes that a session has already been established…

Dirk

## 4 thoughts on “Using fail2ban to stop brute-force attacks on Samba-server?”

1. Wouter Samaey says:

Does this still work for the newest Samba versions like 4.9?

1. Dirk Mittler says:

I think that the most important thing to understand about this posting is, that on my Debian 8 / Jessie machine, the regular expression which I showed will not work, but that in order to do the job properly, a version of Samba is needed, which supports Full_Audits. According to the article which I just linked to, this started from Samba v4.7 .

In other words, on your Samba v4.9 box, you’ll be able to do in full, what I realized in this posting, I could not do on my box.

Dirk

2. jofan says:

Thank you for this great tip!

If you are on a lan and have whitelisted the /24 IPs (ie ‘ignoreip = 127.0.0.1 192.168.1.0/24′) adding the regex

‘(?:Allowed\ connection\ from\ )(?:\ $$)(?:.*)(?:$$)’

and setting

maxretry = 1

will block all new connections every 1 second (fail2ban default)

This is useful if you need to DMZ your server for whatever reason.

All the best

1. jofan says:

for some reason it’s not showing

‘(?:Allowed\ connection\ from\ ) alligatormouthrightHOSTalligatormouthleft (?:\ $$)(?:.*)(?:$$)’

I guess it’s a security feature

This site uses Akismet to reduce spam. Learn how your comment data is processed.