See this post from the IIS newsgroup for some code to resolve the issue
Also below is Chrissy Lemaire's script
'****************************************************************************
' This script created by Chrissy LeMaire (clemaire@gmail.com)
' Website: http://netnerds.net/
'
' NO WARRANTIES, etc.
'
' This script instantly bans IP addresses trying to login to FTP
' using the NT account "Administrator"
'
' Run this script on the FTP server. It sits in the back and waits for an
' event viewer "push" that lets it know someone failed FTP authentication.
'
' This script has only been tested on Windows Server 2003. It assumes, as it
' should, that there are no legitimate Administrator account FTP logins.
'
' "What it does"
' 1. Sets an Async Event Sink to notify the script when someone fails MS-FTP auth
' 2. When alerted, the script parses the last day's FTP logs for all FTP sites (this
' is because the Event Viewer doesn't tell you which FTP site, if you have more than
' one, is the one getting hit)
' 3. Compiles the list of IPs to be banned and then bans them using IIS /and/
' IP level banning (thanks Spencer @ netortech.com for the idea)
'*****************************************************************************
' Push Event Viewer Alert
Set objWMIService = GetObject("winmgmts:{(security)}!root/cimv2")
Set eventSink = wscript.CreateObject("WbemScripting.SWbemSink", "EVSINK_")
strWQL = "Select * from __InstanceCreationEvent where TargetInstance isa 'Win32_NTLogEvent' and TargetInstance.SourceName = 'MSFTPSVC' and TargetInstance.EventCode = 100"
objWMIService.ExecNotificationQueryAsync eventSink,strWQL
' Keep it going forever
While (True)
Wscript.Sleep(1000)
Wend
Sub EVSINK_OnObjectReady(objObject, objAsyncContext)
If InStr(LCase(objObject.TargetInstance.Message),"administrator") > 0 Then
Set objFTPSVC = GetObject("IIS://localhost/MSFTPSVC")
Set WshShell = CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objLog = CreateObject("MSWC.IISLog")
Set objDictionary = CreateObject("Scripting.Dictionary")
Set objFTPIPSec = objFTPSVC.IPSecurity
'Get IP address of server so we can use it later to give the offending IP a bad route
Set IPConfigSet = GetObject("winmgmts:\\.\root\cimv2").ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled=TRUE")
for each IPConfig in IPConfigSet
if Not IsNull(IPConfig.DefaultIPGateway) then serverIP = IPConfig.IPAddress(0)
Next
Set IPConfigSet = Nothing
'Iterate through each FTP site. See #2 up above.
For Each objSITE in objFTPSVC
If lcase(objSITE.class) = "iisftpserver" Then
ftpLogFilePath = WshShell.ExpandEnvironmentStrings(objSITE.LogFileDirectory) & "\msftpsvc" & objSITE.Name
Set objFolder = objFSO.GetFolder(ftpLogFilePath)
Set objFiles = objFolder.Files
For Each fileName In objFiles
lastFile = fileName
Next
strLogFile = lastFile
Set file = Nothing
Set objFolder = Nothing
'Use the IIS log file parser provided by MSFT
objLog.OpenLogFile strLogFile, 1, "MSFTPSVC", 1, 0
'(FileName,IOMode,ServiceName,ServiceInstance,OutputLogFileFormat)
' 0 = NotApplicable, 1 = ForReading
While NOT objLog.AtEndOfLog
objLog.ReadLogRecord
If LCase(objLog.URIStem) = "administrator" Then
ClientIP = objLog.ClientIP
If objDictionary.Exists(ClientIP) = False Then
'Kill the route to the machine then add it to the array of banned IPs.
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run "ROUTE ADD " & clientIP & " MASK 255.255.255.255 " & serverIP, 1, True
Set WshShell = Nothing
objDictionary.Add ClientIP, "255.255.255.255" '255 is just there for padding.
End If
End If
Wend
objLog.CloseLogFiles 1
End If
Next
'Append the newly banned IPs to the currently banned IPs
If objDictionary.Count > 0 And objFTPIPSec.GrantByDefault = True Then
bannedIPArray = objFTPIPSec.IPDeny
For i = 0 to ubound(bannedIPArray)
clientIP = Left(bannedIPArray(i),InStr(bannedIPArray(i),",")-1)
If objDictionary.Exists(ClientIP) = False Then
objDictionary.Add bannedIPArray(i), "255.255.255.255"
End If
Next
objFTPIPSec.IPDeny = objDictionary.Keys
objFTPSVC.IPSecurity = objFTPIPSec
objFTPSVC.SetInfo
End If
Set objFTPIPSec = Nothing
Set objDictionary = Nothing
Set objLog = Nothing
Set objFSO = Nothing
Set objFTPSVC = Nothing
End If
End Sub
Would you like to do this through command line scripts or through the user interface? Not sure what you mean by flexibility, but I find it easiest to create firewall rules from the command line and then manage the list of whitelisted IPs through the user interface.
Assuming a new SQL Server installation, enabled Windows firewall, and no current allowance for SQL Server through the firewall, this command will set up a new rule with only the IPs you desire (run as Administrator):
C:\Users\Administrator>netsh advfirewall firewall add rule name="SQL Server Whitelist" dir=in action=allow localport=1433 protocol=tcp remoteip=1.1.1.1,1.1.8.10
In your case, just replace the list of IPs after remoteip=
with a comma-separated list of the IPs you wish to whitelist. Then to manage the list, you can either run this command to update the list:
C:\Users\Administrator>netsh advfirewall firewall set rule name="SQL Server Whitelist" new remoteip=1.1.1.1,1.1.8.10
Or to avoid retyping the list every time you can use the user interface, under Start > Programs > Administrative Tools > Windows Firewall with Advanced Security. Then choose "Inbound Rules" and you will see your "SQL Server Whitelist" rule in the main window. Double click your rule, and choose the "Scope" tab to manage the allowed IPs.
Alternatively, if you like managing the list through the command line, you can create a separate rule for each IP.
C:\Users\Administrator>netsh advfirewall firewall add rule name="SQL Server Whitelist 1.1.1.1" dir=in action=allow localport=1433 protocol=tcp remoteip=1.1.1.1
C:\Users\Administrator>netsh advfirewall firewall add rule name="SQL Server Whitelist 1.1.8.10" dir=in action=allow localport=1433 protocol=tcp remoteip=1.1.8.10
You can then remove rules when you need to change the list like so:
C:\Users\Administrator>netsh advfirewall firewall delete rule name="SQL Server Whitelist 1.1.8.10"
Best Answer
I wrote a program to block IP addresses like you're asking for a couple of years ago, but did it for a Customer as a work-for-hire. Since I ended up with some "spare" time this evening I opted to re-implement the whole thing from the ground up, write some useful documentation, and generally make it a presentable program. Since I've heard from multiple people that this would be a handy thing to have it seems like it's probably worth the time. Hopefully you, and other members of the community, can get some use out of it.
Windows sshd_block
sshd_block is a VBScript program that acts as a WMI event sink to receive Windows Event Log entries logged by sshd. It parses these log entries and acts upon them as follows:
If the IP address attempts to logon with a username flagged as "ban immediately" the IP address is banned immediately.
If the IP address attempts to logon with more frequently than is allowed in a given time period the IP address is banned.
The "ban immediately" usernames and thresholds associated with repeated logon attempts are configurable in the "Configuration" section of the script. Default settings are as follows:
Once a second any IP addresses that have been banned for the ban duration are unbanned (by having the black-hole route removed from the routing table).
You can download the software here and can browse the archive here.
Edit:
As of 2010-01-20 I've updated the code to support using the "Advanced Firewall" on Windows Vista / 2008 / 7 / 2008 R2 to perform black-holding of traffic via creating firewall rules (which is much more in line with the behavior of "fail2ban"). I also added some additional matching strings to catch OpenSSH versions that "invalid user" as opposed to "illegal user".