{"id":1474,"date":"2014-06-09T16:07:37","date_gmt":"2014-06-09T08:07:37","guid":{"rendered":"http:\/\/www.computersolutions.cn\/blog\/?p=1474"},"modified":"2014-06-09T16:35:04","modified_gmt":"2014-06-09T08:35:04","slug":"roundcube-login-attack-prevention-with-fail2ban","status":"publish","type":"post","link":"https:\/\/www.computersolutions.cn\/blog\/2014\/06\/roundcube-login-attack-prevention-with-fail2ban\/","title":{"rendered":"RoundCube login attack prevention with Fail2ban"},"content":{"rendered":"<p>I&#8217;ve noticed a little spate of password attack attempts via Roundcube &#8211; a webmail program we use for mail over at <a href=\"https:\/\/mail.computersolutions.cn\">https:\/\/mail.computersolutions.cn<\/a><\/p>\n<p>Roundcube does have captcha plugins available which will mitigate this, but users will complain if they have to type in a captcha to login for mail.<\/p>\n<p>Fail2ban provides an easy solution for this.<\/p>\n<p>Roundcube stores its logs in a logs\/errors file.<\/p>\n<p>If I take a look at a sample login failure, it looks something like the example below<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">&#x5B;09-Jun-2014 13:43:38 +0800]: IMAP Error: Login failed for admin from 105.236.42.200. Authentication failed. in rcube_imap.php on line 184 (POST \/?_task=login&amp;_action=login)<\/pre>\n<p>We should be able to use a regex like:<br \/>\nIMAP Error: Login failed for .* from <HOST><\/p>\n<p>However fail2ban&#8217;s host regex then  includes a trailing ., and fail2ban doesn&#8217;t recognise the ip.<br \/>\nI eventually came up with the overly complicated regex below, which seems to work:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">IMAP Error: Login failed for .* from &lt;HOST&gt;(\\. .* in .*?\/rcube_imap\\.php on line \\d+ \\(\\S+ \\S+\\))?$<\/pre>\n<p>Lets add detection for that into fail2ban.<br \/>\nFirst up, we need to add roundcube into \/etc\/fail2ban\/jail.conf<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">&#x5B;roundcube]\r\nenabled  = false\r\nport     = http,https\r\nfilter   = roundcube\r\naction   = iptables-multiport&#x5B;name=roundcube, port=&quot;http,https&quot;]\r\nlogpath  = &#x5B;YOUR PATH TO ROUNDCUBE HERE]\/logs\/errors\r\nmaxretry = 5\r\nfindtime = 600\r\nbantime = 3600<\/pre>\n<p>Note that we are not enabling the filter <strong>yet<\/strong>.<\/p>\n<p><strong>Change [YOUR PATH TO ROUNDCUBE HERE] in the above to your actual roundcube folder<\/strong><br \/>\neg \/home\/roundcube\/public_html\/logs\/errors<\/p>\n<p>Next, we need to create a filter.<\/p>\n<p>Add \/etc\/fail2ban\/filter.d\/roundcube.conf<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">&#x5B;Definition]\r\nfailregex = IMAP Error: Login failed for .* from &lt;HOST&gt;(\\. .* in .*?\/rcube_imap\\.php on line \\d+ \\(\\S+ \\S+\\))?$\r\n\r\nignoreregex =<\/pre>\n<p>Now we have the basics in place, we need to test out our filter.<br \/>\nFor that, we use fail2ban-regex.<br \/>\nThis accepts 2 (or more) arguments.  <\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">fail2ban-regex LOGFILE  FILTER \r\n<\/pre>\n<p>For our purposes, we&#8217;ll pass it our logfile, and the filter we want to test with.<\/p>\n<p>eg<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">fail2ban-regex  \/home\/roundcube\/public_html\/logs\/errors \/etc\/fail2ban\/filter.d\/roundcube.conf  |more\r\n<\/pre>\n<p>If you&#8217;ve passed your log file, and it contains hits, you should see something like this:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">Running tests\r\n=============\r\n\r\nUse regex file : \/etc\/fail2ban\/filter.d\/roundcube.conf\r\nUse log file   : \/home\/www\/webmail\/public_html\/logs\/errors\r\n\r\n\r\nResults\r\n=======\r\n\r\nFailregex\r\n|- Regular expressions:\r\n|  &#x5B;1] IMAP Error: Login failed for .* from &lt;HOST&gt;(\\. .* in .*?\/rcube_imap\\.php on line \\d+ \\(\\S+ \\S+\\))?$\r\n|\r\n`- Number of matches:\r\n   &#x5B;1] 14310 match(es)\r\n\r\nIgnoreregex\r\n|- Regular expressions:\r\n|\r\n`- Number of matches:\r\n\r\nSummary\r\n=======\r\n\r\nAddresses found:\r\n&#x5B;1]\r\n    61.170.8.8 (Thu Dec 06 13:10:03 2012)\r\n    ...&#x5B;14309 more results in our logs!]<\/pre>\n<p>If you see hits, great, that means our regex worked, and you have some failed logins in the logs.<br \/>\nIf you don&#8217;t get any results, check your log (use grep) and see if the log warning has changed.  The regex I&#8217;ve posted works for roundcube 0.84 <\/p>\n<p>Once you&#8217;re happy, edit jail.conf, enable the plugin.<br \/>\n(set enabled = true), and restart fail2ban with<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">service fail2ban restart<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve noticed a little spate of password attack attempts via Roundcube &#8211; a webmail program we use for mail over at https:\/\/mail.computersolutions.cn Roundcube does have captcha plugins available which will mitigate this, but users will complain if they have to type in a captcha to login for mail. Fail2ban provides an easy solution for this. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[73,48,25],"tags":[132,492,134],"class_list":["post-1474","post","type-post","status-publish","format-standard","hentry","category-email","category-exploits","category-technical-mumbo-jumbo","tag-fail2ban","tag-roundcube","tag-security"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.computersolutions.cn\/blog\/wp-json\/wp\/v2\/posts\/1474","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.computersolutions.cn\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.computersolutions.cn\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.computersolutions.cn\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.computersolutions.cn\/blog\/wp-json\/wp\/v2\/comments?post=1474"}],"version-history":[{"count":9,"href":"https:\/\/www.computersolutions.cn\/blog\/wp-json\/wp\/v2\/posts\/1474\/revisions"}],"predecessor-version":[{"id":1483,"href":"https:\/\/www.computersolutions.cn\/blog\/wp-json\/wp\/v2\/posts\/1474\/revisions\/1483"}],"wp:attachment":[{"href":"https:\/\/www.computersolutions.cn\/blog\/wp-json\/wp\/v2\/media?parent=1474"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.computersolutions.cn\/blog\/wp-json\/wp\/v2\/categories?post=1474"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.computersolutions.cn\/blog\/wp-json\/wp\/v2\/tags?post=1474"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}