Now supports MSSQL
Edit 2019/06/25:
hMailServer Firewall Ban - Ban rejected IPs to Windows Defender Firewall
The basic functionality is EventHandlers.vbs calls the firewall ban function based on the trigger of your choice. I'm using GeoIP and Spamhaus rejection mainly, plus a couple of other things that don't get triggered often. The IP, country and reason for the ban are written to the database. Then a powershell script on a scheduled task reads the new database entries and creates a new rule for Windows Defender Firewall. The powershell script also deletes firewall rules that you designate as "released" in the webadmin as well as auto-expire entries.
This project is now in beta phase. Please feel free to try it out. There is a demo here: http://hmsfirewallbandemo.ddns.net/
New rejected IPs from my system get added to the demo database so the content is always fresh, but the demo does not control my firewall.

Files are located here: https://github.com/palinkas-jo-reggelt/ ... rewall-Ban
ORIGINAL POST
I'm giving a run at a simple firewall ban script.
1) create table on hmailserver: hm_fwban
2) trigger records IP and reason to db
3) powershell script run by task scheduler 1) checks new IPs on db and adds each IP as a rule to windows firewall, and 2) checks db for IP entries older than __ days and removes them from firewall rules.
I wanted to do the whole thing within hmailserver eventhandlers but I got hung up on the fact that firewall changes require UAC. I got around that by running it from powershell through task scheduler, which can use any credentials you want.
Bear in mind - I'm not very good at this.

Create table in hmailserver db:
Code: Select all
CREATE TABLE hm_FWBan (
ID int NOT NULL AUTO_INCREMENT,
ipaddress VARCHAR (192) NOT NULL,
timestamp TIMESTAMP,
ban_reason VARCHAR (192)
PRIMARY KEY (ID)
);
Eventhandlers.vbs:
Code: Select all
Function FWBan(sIPAddress, sReason)
Dim strSQL, oDB : Set oDB = GetDatabaseObject
strSQL = "INSERT INTO hm_FWBan (timestamp,ipaddress,ban_reason) VALUES (NOW(),'" & sIPAddress & "','" & sReason & "');"
Call oDB.ExecuteSQL(strSQL)
End Function
Code: Select all
Result.Value = 1
Call FWBan(oClient.IPAddress, "Spamhaus")
hmsFirewallBan.ps1:
Code: Select all
Function MySQLQuery($Query) {
$MySQLAdminUserName = 'hmailserver'
$MySQLAdminPassword = 'supersecretpassword'
$MySQLDatabase = 'hmailserver'
$MySQLHost = 'localhost'
$ConnectionString = "server=" + $MySQLHost + ";port=3306;uid=" + $MySQLAdminUserName + ";pwd=" + $MySQLAdminPassword + ";database="+$MySQLDatabase
Try {
[void][System.Reflection.Assembly]::LoadWithPartialName("MySql.Data")
$Connection = New-Object MySql.Data.MySqlClient.MySqlConnection
$Connection.ConnectionString = $ConnectionString
$Connection.Open()
$Command = New-Object MySql.Data.MySqlClient.MySqlCommand($Query, $Connection)
$DataAdapter = New-Object MySql.Data.MySqlClient.MySqlDataAdapter($Command)
$DataSet = New-Object System.Data.DataSet
$RecordCount = $dataAdapter.Fill($dataSet, "data")
$DataSet.Tables[0] | Out-File C:\scripts\hmailserver\FWBan\IP.txt #<<<<<<< CHANGE PATH IF YOU WANT
}
Catch {
Write-Host "ERROR : Unable to run query : $query `n$Error[0]"
}
Finally {
$Connection.Close()
}
}
# Look for new entries and add them to firewall
$Query = "SELECT ipaddress FROM hm_fwban WHERE timestamp >= now() - interval 5 minute"
MySQLQuery $Query
$regex = "(((\d){1,3})\.((\d){1,3})\.((\d){1,3})\.((\d){1,3}))"
$IPList = Get-Content C:\scripts\hmailserver\FWBan\IP.txt
foreach ($IPAddress in $IPList) {
if ($IPAddress -match $regex){
$IPAddress = $IPAddress.replace('\s','')
& netsh advfirewall firewall add rule name=`"$IPAddress`" dir=in interface=any action=block remoteip=$IPAddress
}
}
# Look for old entries and remove them from firewall
$Days = "30"
$Query = "SELECT ipaddress FROM hm_fwban WHERE timestamp < now() - interval $Days day AND ban_reason = 'Spamhaus'"
MySQLQuery $Query
$regex = "(((\d){1,3})\.((\d){1,3})\.((\d){1,3})\.((\d){1,3}))"
$IPList = Get-Content C:\scripts\hmailserver\FWBan\IP.txt
foreach ($IPAddress in $IPList) {
if ($IPAddress -match $regex){
$IPAddress = $IPAddress.replace('\s','')
& netsh advfirewall firewall delete rule name=`"$IPAddress`"
}
}

Now create a task in windows task scheduler that runs every 5 minutes. !!HIGHEST PRIVELEGES REQUIRED!! in order to get around UAC and actually add a rule to the firewall.
If you change the scheduled task to run at a different interval than 5 minutes, be sure to update the first query to match the interval.
If you want to add another query for expiration with a different interval, just repeat the last section (after "# Look for old entries and remove them from firewall") and change $Days and the ban_reason in $Query.