{"id":436,"date":"2016-06-17T20:43:59","date_gmt":"2016-06-17T19:43:59","guid":{"rendered":"http:\/\/jonika.nu\/JonasBlogg\/?p=436"},"modified":"2016-06-17T20:43:59","modified_gmt":"2016-06-17T19:43:59","slug":"a10-aflex-temporary-blacklist-clients-based-on-failed-logins","status":"publish","type":"post","link":"https:\/\/jonika.nu\/JonasBlogg\/archives\/436","title":{"rendered":"A10 aFlex: Temporary blacklist clients based on failed logins"},"content":{"rendered":"<p>I was asked if i could find a way to temporary blacklist clients after x failed logins. The reason was to avoid lockout in AD when users changed their passwords, but forgot to change the password in their phones connected through ActiveSync.<\/p>\n<p>If a phone connects to ActiveSync with the wrong password, resulting in a error 401, i should be able to catch that and save the IP in a table. If it re-occurs 4 times or more in less then 10 minutes than the A10 should remember this and drop the traffic, resulting in request not being sent to the mail server and the AD account not being locked out.<\/p>\n<p>Thats the theory. Below is my current solution, very much in POC state but my initial testing looks promising \ud83d\ude42 But i&#8217;m sure there are many aFlex\/TCL gurus out there to correct me. I&#8217;m certainly not one of them!<\/p>\n<p>A few notes:<\/p>\n<ul>\n<li>Because i write failed attempt to temp-table, the blacklist is 10 minutes after the last failed logins. This is probably longer than needed.<\/li>\n<li>maxfadiledrequests is set to 5, because it always start at 2 for me.. and i&#8217;m not sure why. I did expect it to start at 1 since the initial status from server is 401, but not 2.<\/li>\n<li>holdtime is the the in seconds the address is blocked<\/li>\n<li>You should probably not write to log in a production environment<\/li>\n<\/ul>\n<pre class=\"lang:default decode:true\">when RULE_INIT {\r\n    set ::maxfailedrequests 5\r\n    set ::holdtime 600\r\n}\r\n\r\nwhen HTTP_REQUEST {\r\n    set key [IP::client_addr]\r\n    if { [table lookup \"blacklist\" $key] != \"\" } {\r\n        reject\r\n        log \"$first_key is blocked\"\r\n        return\r\n    }\r\n\r\n    if { [table lookup tmp_table $key] == \"\" } {\r\n        table set tmp_table $key 1 indef $::holdtime\r\n        log \"$key's session table created.\"\r\n        return\r\n    }\r\n}\r\n\r\nwhen HTTP_RESPONSE {\r\n    if { ([HTTP::status] == 401) } {\r\n        set count [table incr tmp_table $key]\r\n        log \"failed request count: $count\"\r\n        if { $count &gt; $::maxfailedrequests } {\r\n            table add \"blacklist\" $key \"blocked\" indef $::holdtime\r\n            log \"$key blacklisted for $::holdtime seconds \"\r\n            table delete tmp_table $key\r\n            reject\r\n            return\r\n        }\r\n    }\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<a href=\"https:\/\/twitter.com\/jonlin76\" class=\"twitter-follow-button\" data-show-count=\"false\" data-size=\"small\">Follow jonlin76<\/a>\n<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=\/^http:\/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+':\/\/platform.twitter.com\/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');<\/script>","protected":false},"excerpt":{"rendered":"<p>I was asked if i could find a way to temporary blacklist clients after x failed logins. The reason was to avoid lockout in AD when users changed their passwords, but forgot to change the password in their phones connected through ActiveSync. If a phone connects to ActiveSync with the wrong password, resulting in a &hellip; <a href=\"https:\/\/jonika.nu\/JonasBlogg\/archives\/436\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">A10 aFlex: Temporary blacklist clients based on failed logins<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[59,32],"tags":[103,105,104,106],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/jonika.nu\/JonasBlogg\/wp-json\/wp\/v2\/posts\/436"}],"collection":[{"href":"https:\/\/jonika.nu\/JonasBlogg\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jonika.nu\/JonasBlogg\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jonika.nu\/JonasBlogg\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/jonika.nu\/JonasBlogg\/wp-json\/wp\/v2\/comments?post=436"}],"version-history":[{"count":1,"href":"https:\/\/jonika.nu\/JonasBlogg\/wp-json\/wp\/v2\/posts\/436\/revisions"}],"predecessor-version":[{"id":437,"href":"https:\/\/jonika.nu\/JonasBlogg\/wp-json\/wp\/v2\/posts\/436\/revisions\/437"}],"wp:attachment":[{"href":"https:\/\/jonika.nu\/JonasBlogg\/wp-json\/wp\/v2\/media?parent=436"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jonika.nu\/JonasBlogg\/wp-json\/wp\/v2\/categories?post=436"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jonika.nu\/JonasBlogg\/wp-json\/wp\/v2\/tags?post=436"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}