Ejabberd. Crutch protection
Prologue. For a long time I did not dare to write this article. Because even without being a programmer, I understand that the code above can be simpler and more elegant. But I hope that the article will help those who are faced with the same dilemma, and maybe encourage someone to write a more worthy script. So, in one city, in some company, a jabber server appeared ...
The service turned out to be necessary and in demand, but the trouble is, many users work remotely and not everyone has a VPN. Of course, opening ports outward is not a problem, but since the jabber is tied to mail LDAP, the issue of security is gaining a critical degree. Having climbed the ejabberd config and seeing that no protection was provided, I thought: “Ah, what nonsense. Now set up fail2ban. ”And broke off. Neither about ejabberd, nor about openfire, nor about any other xmpp, fail2ban was not up to date. “Bullshit question!” I thought again. “We’ll set it up now.” And he climbed to watch the ejabberd log. And then the complexity of the task confronted me in full growth. It seemed that the service log was specially created so that fail2ban could not be configured on it. Roughly speaking, a message about a failed password entry consists of four lines:
1. = Date, time ====
2. Connection message from ip address
3. = Date, time ====
4. Error message.
Yes, in the ip address, the commas O_o are used as a separator.
And fail2ban analyzes the logs one line at a time. Moreover, the line must have at least two values - the ip address of the attacker and the time. Googling for 'ejabberd protection' gave a grain of useful information. There are two modules that can help here and here in this situation But! I have not mastered ejabberd enough to be able to install them. The first requires the installation of patches. And the second is installed, but does not write anything to the log. Apparently a patch is also needed. As a result, "niasilil", forgive me my French and was sad.
However, if the mountain does not go to Mohammed, then the mountain to Mohammed is carried. We will write a script that reads the jabber log and creates a selection with erroneous connections. What I think about my creation I wrote at the very beginning. And the code looks like this.
#!/bin/bash
cp /dev/null /var/log/ejabberd/tofail.log #Можно заменить логротейтом, если есть необходимость хранить этот лог
log="/var/log/ejabberd/ejabberd.log" #Исходный лог ejabberd
itog="/var/log/ejabberd/tofail.log" #Оптимизированный лог ejabberd
shab='I(.*) : (.*) Failed authentication for \w*@\w*.\w*.\w*'
i="0"
cat $log | while read line
do
dan[$i]="$line"
if [[ ${dan[$i]} =~ $shab ]]; then #Если находим соответствие шаблону...
i=`expr $i - 4`
vrem="${dan[$i]}" # ...вычисляем предыдущие
i=`expr $i + 1`
con="${dan[$i]}" # ...две
i=`expr $i + 3`
fai="${dan[$i]}" # ...строки
echo "$vrem $con $fai" >>$itog #Записываем в оптимизированный лог
fi
i=`expr $i + 1`
done
sed -i 's/,/./g' "$itog" #Заменяем все запятые на точки
What the script does. It looks through ejabberd.log, when it finds a line with a message about entering the wrong password, it enters the previous two lines into the variables with the time and ip address of the connection. After that, all three values are written to the log.
After that, prepare fail2ban. In /etc/fail2ban/filter.d/ create an ejabberd.conf file with the following contents:
# Fail2Ban configuration file
[Definition]
failregex = Accepted connection \{\{\}
ignoreregex =
You can verify that the filter works by using the fail2ban-regex /var/log/ejabberd/tofail.log /etc/fail2ban/filter.d/ejabberd.conf command.
In jail.cfg, write
[ejabberd]
enabled = true
port = 5222
filter = ejabberd
action = iptables-allports[name=EJABBERD, protocol=all]
logpath = /var/log/ejabberd/tofail.log
maxretry = 3
Further. This creation is thoughtful and works for a long time. In order not to load the system once again, we will run the script only when the size of the ejabberd log changes. Therefore, we hang in crontab say the file filesize.sh with the following contents:
#!/bin/bash
logf="/var/log/ejabberd/ejabberd.log"
filesize="/etc/ejabberd/size.txt"
live=`stat -c%s $logf`
cat $filesize |while read line
do
if [ $live -ne $line ]
then
/etc/ejabberd/expres.sh
fi
done
echo `stat -c%s $logf` >$filesize
It starts once a minute. The frequency of updates you have, choose yourself.
That's actually with such crutches, the jabber was released outside. There are unsuccessful connections, but so far the employees themselves are mistaken when entering the password. In the near future it will be necessary to test how this whole system will handle jBrute and jbbl. I will accept any comments regarding the optimization of the code with great gratitude and will post it after verification.