That's fine but why not using the apache functionality to log failed logins ?
Add these lines to your Apache Config (i.e:/etc/apache2/conf.d/phpmyadmin.conf) in the according VirtualHost Section:
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %{userID}n %{userStatus}n" pma_combined
CustomLog /var/log/apache2/phpmyadmin_access.log pma_combined
Then create the fail2ban filter:
/etc/fail2ban/filter.d/phpmyadmin.conf
[Definition]
denied = mysql-denied|allow-denied|root-denied|empty-denied
failregex = ^<HOST> -.*(?:%(denied)s)$
ignoreregex =
Now add the jail to /etc/fail2ban/jail.local
[phpmyadmin]
enabled = true
port = http,https
filter = phpmyadmin
logpath = /var/log/apache2/phpmyadmin_access.log
Restart apache and fail2ban:
service apache2 reload
service fail2ban reload
and you are done, no need of php scripts so on..
While fail2ban creates an iptables chain per service (eg fail2ban-ssh), the check for an existing ban is based on the IP address. A possibility to fix the problem is to make fail2ban unban an IP (ticket) if it is already in the banned-list just before it is going to ban it (again)
These actions happen in the python script located (when installed via apt-get install
) in
/usr/share/fail2ban/server
edit the file actions.py
, you should see the following code for the __checkban
definition
def __checkBan(self):
ticket = self.jail.getFailTicket()
if ticket != False:
aInfo = dict()
bTicket = BanManager.createBanTicket(ticket)
aInfo["ip"] = bTicket.getIP()
aInfo["failures"] = bTicket.getAttempt()
aInfo["time"] = bTicket.getTime()
aInfo["matches"] = "".join(bTicket.getMatches())
if self.__banManager.addBanTicket(bTicket):
logSys.warn("[%s] Ban %s" % (self.jail.getName(), aInfo["ip"]))
for action in self.__actions:
action.execActionBan(aInfo)
return True
else:
logSys.warn("[%s] %s already banned" % (self.jail.getName(), aInfo["ip"]))
return False
modify/replace the definition with
def __checkBan(self):
ticket = self.jail.getFailTicket()
if ticket != False:
aInfo = dict()
bTicket = BanManager.createBanTicket(ticket)
aInfo["ip"] = bTicket.getIP()
aInfo["failures"] = bTicket.getAttempt()
aInfo["time"] = bTicket.getTime()
aInfo["matches"] = "".join(bTicket.getMatches())
# changes from here ...
if not self.__banManager.addBanTicket(bTicket):
logSys.warn("[%s] first unban %s before ban" % (self.jail.getName(), aInfo["ip"]))
self.__unBan(ticket)
self.__banManager.addBanTicket(bTicket)
logSys.warn("[%s] Ban %s" % (self.jail.getName(), aInfo["ip"]))
for action in self.__actions:
action.execActionBan(aInfo)
return True
# else:
# logSys.warn("[%s] %s already banned" % (self.jail.getName(),
# aInfo["ip"]))
#return False
and restart fail2ban (e.g. /etc/init.d/fail2ban restart
) while it is probably not necessary...
Note: if you want to 'play around' with this, you can list the firewall (iptables) rules
iptables -L
and delete the rule that was created by fail2ban in order to access and force a "re-ban"
iptables -D fail2ban-ssh xxxx
where xxxx is the number of the rule in that chain from the list iptables -L fail2ban-ssh
Best Answer
You must specify the custom port in the
[ssh]
section, something like this: