Tell me more ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

Is it possible to ban an IP address after X number of unsuccessful login attempts to a Windows Server? Not to a particular account, which I know how to do, but to the whole machine.

We get hit pretty hard by brute force attacks trying to guess usernames, so this would really help get some load off the server.

share|improve this question
6  
*nix has fial2ban... not sure if there's a Windows equivalent/port. fail2ban.org/wiki/index.php/Main_Page – Chris Nava Feb 11 '11 at 19:06
3  
From Evan Anderson: serverfault.com/questions/43360/… ...looks to be a good equivalent of fail2ban's functionality but as your question is not specific enough, I don't know if you're looking to ban IPs attempting to login to a hosted website, your server (via SSH) or your domain. Clarification would go a long way. Additionally you could rate limit at your firewall, but that is implementation-dependent. – kce Feb 11 '11 at 19:35
2  
You might want to have a look at serverfault.com/questions/216995/… for a previous discussion about how useful automated banning based on IP is. – pehrs Feb 13 '11 at 18:16
If you're talking about Terminal Services / Remote Desktop have a look here: serverfault.com/a/335976/7200 – Evan Anderson Nov 29 '11 at 23:57
2  
I made a windows service on github to do just that: github.com/jjxtra/Windows-IP-Ban-Service – PsychoDad Feb 20 '12 at 18:06
show 1 more comment

7 Answers

You can do this with powershell and task manager. It's probably not perfect solution, but it works quite well and i have about 100 blocked IP addresses in two months. I wrote script, that select from EventLog specified events ("audit failure"). If there are many failed logins from any IP address, then it's added to firewall rule (created manually) named "BlockAttackers" which blocks any traffic to specified ip addresses.

PS1 Script:

$DT = [DateTime]::Now.AddDays(-1) # check only last 24 hours

$l = Get-EventLog -LogName 'Security' -InstanceId 4625 -After $DT | Select-Object @{n='IpAddress';e={$_.ReplacementStrings[-2]} } # select Ip addresses that has audit failure 
$g = $l | group-object -property IpAddress  | where {$_.Count -gt 20} | Select -property Name # get ip adresses, that have more than 20 wrong logins

$fw = New-Object -ComObject hnetcfg.fwpolicy2 # get firewall object

$ar = $fw.rules | where {$_.name -eq 'BlockAttackers'} # get firewall rule named 'BlockAttackers' (must be created manually)

$arRemote = $ar.RemoteAddresses -split(',') #split the existing IPs into an array so we can easily search for existing IPs

$w = $g | where {$_.Name.Length -gt 1 -and  !($arRemote -contains $_.Name + '/255.255.255.255') } # get ip addresses that are not already in firewal rule. Include the subnet mask which is automatically added to the firewall remote IP declaration.

$w| %{$ar.remoteaddresses += ',' + $_.Name} # add IPs to firewall rule

Create task in scheduler and set trigger to event 4625 (windows login including terminal services). But you can set trigger to run e.g. twice per hour to avoid unnecessary loading the server.

Scheduler trigger

and after trigger run powershell script. You must also set higher privileges to run this script, otherwise it will fail with security exception.

runing powershell script

You can also bind this script to other security events.

share|improve this answer

I know this question is old but it was actually the first forum post I stumbled across when I started trying to do this exact same thing a couple weeks ago. I've managed to come up with a working script that will parse the event logs 24 hours back for only bad login event log entries, grab the ones that have more than 10 bad logins, and then put them into an ipsec filter list using the netsh command. Then I wrote a batch file with this line powershell .\*scriptname.ps1* and created a scheduled task to run the batch file every 24 hours (for some reason it wouldn't execute directly).

$DATE = [DateTime]::Now.AddDays(-1)

$EVS = Get-EventLog Security -InstanceId 529 -after $DATE

$EVS | select-string -inputobject {$_.message} -pattern "Source Network Address:(.)*\.*\.*\.*"  -allmatches | foreach-object {$_.Matches} | foreach-object {$_.Value} | foreach-object {$_.replace("Source Network Address:", "")} | group-object -property $_ | where-object {$_.count -gt 10} | select-object -property name | format-list | out-file c:\rdpblock.txt 

get-content -path c:\rdpblock.txt | foreach-object {$_.replace("Name :", "")} | out-file c:\rdpblockcleaned.txt 

get-content -path c:\rdpblockcleaned.txt | select-object -unique | out-file c:\rdpblocknospaces.txt

$RDPIP = get-content -path c:\rdpblocknospaces.txt | select-object -skip 1

$RDPIP | foreach-object {$_.replace("     ", "")} | foreach-object {netsh ipsec static add filter filterlist=RDP_BLOCK srcaddr=$($_) dstaddr=any}

I know that this script is probably inefficient but when I started working on this I had absolutely no experience in powershell, so my ability to optimize scripts leaves alot to be desired. However, despite this fact I thought I would share this with anyone who could use it.

I thank Remunda for giving me the initial idea, that poster is the one that turned me on to the idea of using powershell to search the event logs.

share|improve this answer

It's generally not a good idea to let somebody else control your firewall rules. That's basically what you're asking for here.

share|improve this answer
1  
+1, this is an excellent way to set yourself up for a denial of service attack. And if you're using rate-limiting, most automated brute force tools space their login attempts far enough apart to avoid getting caught. – kce Feb 11 '11 at 19:40
8  
Automatically banning IPs after a certain number of failed logins is very common practice. I see hosts being banned on an hourly basis after trying to guess FTP passwords. The only way this can be a DoS attack is if someone managed to spoof your IP (impossible on TCP connections), or if you repeatedly mistype your password (in which case it's not someone else controlling firewall rules, it's you) – devicenull Feb 12 '11 at 2:35
14  
Sorry, but I didn't ask if it was a good idea. – HeavyWave Feb 13 '11 at 2:24
1  
Of course there is no reason exceptions couldn't be set for one or more specific IP addresses, which would pretty much eliminate the DoS concern. – John Gardeniers Feb 15 '11 at 1:56

This script builds on remunda's answer and goes a little further http://serverfault.com/a/397637/155102 It accounts for the "BlockAttackers" rule not have any IPs entered yet (which returns a "*" as a string). It also writes a comment to a log file to let you know when the IP was added to the rule.

A good tip is to create the "BlockAttackers" rule that blocks the IP addresses BUT make it disabled at first. Then, run this script once manually so it can populate the "RemoteAddresses" field with actual IP addresses that should be blocked. Take a look at those IP addresses to make sure nothing critical has been added and then enable the firewall rule. Add this rule to your firewall as remunda described.

The git for this script

#Checks for IP addresses that used incorrect password more than 10 times
#within 24 hours and blocks them using a firewall rule 'BlockAttackers'

#Check only last 24 hours
$DT = [DateTime]::Now.AddHours(-24)

#Select Ip addresses that has audit failure
$l = Get-EventLog -LogName 'Security' -InstanceId 4625 -After $DT | Select-Object @{n='IpAddress';e={$_.ReplacementStrings[-2]} }

#Get ip adresses, that have more than 10 wrong logins
$g = $l | group-object -property IpAddress | where {$_.Count -gt 10} | Select -property Name

#Get firewall object
$fw = New-Object -ComObject hnetcfg.fwpolicy2

#Get firewall rule named 'BlockAttackers' (must be created manually)
$ar = $fw.rules | where {$_.name -eq 'BlockAttackers'}

#Split the existing IPs into an array so we can search it for existing IPs
$arRemote = $ar.RemoteAddresses -split(',')

#Only collect IPs that aren't already in the firewall rule
$w = $g | where {$_.Name.Length -gt 1 -and !($arRemote -contains $_.Name + '/255.255.255.255') }

#Add the new IPs to firewall rule
$w| %{
  if ($ar.RemoteAddresses -eq '*') {
    $ar.remoteaddresses = $_.Name
  }else{
    $ar.remoteaddresses += ',' + $_.Name
  }
}

#Write to logfile
if ($w.length -gt 1) {
  $w| %{(Get-Date).ToString() + ' ' + $_.Name >> '.\blocked.txt'}
}
share|improve this answer

Do you mean logging on to the server/domain or logging on to a web site running on the server? If you mean logging on to the server/domain then the answer is no. Windows has no concept of blocking ip addresses based on failed logon attempts as ip addresses aren't security entities. There may be third party tools that can do this, but I'm not aware of any as I've never looked in to it.

share|improve this answer

If there is a webserver that is being attacked you can install the dynamic IP restrictions extension. If this is for standard authentication to the server then you should be able to implement domain and server isolation which would limit the scope of the attacks to domain joined computers, and could be set to only allow attempts from the systems you need to have access to the server. In windows the prevention of brute force attacks is to set the account lockout policy to a setting like 10 mins and a bad password policy to 3 attempts - this means that the account being attacked would lock for 10 mins after 3 attempts. IP connections are not lockable by default in windows. ( As an aside I am also curious as to how many logon attempts it is taking per second to impact the system)

share|improve this answer
On my AWS small instance, 1 attempt every 4 seconds is enough to consume 50% CPU. Pretty crap if you ask me... – romkyns Mar 2 '12 at 22:34
Wow, I wonder why the utilization is so high. I'll have to do some testing to see how many attempts it takes on my VMs to register. – Jim B Mar 4 '12 at 1:57
I think it’s because I’m not using Network Level Authentication, so every login attempt spins up a logon UI to actually present to the attacker through a remote desktop session. I can see why that might be expensive. – romkyns Mar 4 '12 at 14:46

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.