Fail2Ban.psm1
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # + SETUP # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++++++++ # + Install Fail2Ban function Install-F2B(){ # Test Elevated User $AdminUser = Test-F2BAdmin if($AdminUser -eq $false) { Write-Warning "You do not have Administrator rights to run this script!`nPlease re-run this script as an Administrator!" break } # Get install configuration write-debug "# Get install configuration" Try { $ConfigFile = Get-Content (Join-Path -Path $PSScriptRoot -ChildPath "Config/Install.json") -ErrorAction Stop $Config = $ConfigFile | ConvertFrom-Json } Catch { Write-Error "Unable to get configuration file : $_" break } # Create Registry Item Write-Debug "# Create Registry Items :" try { foreach($Item in $Config.Registry.Item){ $RegistryPath = "$($Item.Path)/$($Item.Name)" Write-Debug "#`t- $RegistryPath" if((Test-Path $RegistryPath) -eq $false) { New-Item -Path $Item.Path -Name $Item.Name -ErrorAction Stop | Out-Null } } } Catch { write-error "Unable to create registry Item ($RegistryPath) : $_" break } # Create Registry Property Write-Debug "# Create Registry Propertys :" Try { foreach($Item in $Config.Registry.Property){ $RegistryPath = "$($Item.Path)/$($Item.Name)" $ItemCollection = (Get-Item $Item.Path).Property Write-Debug "#`t- $RegistryPath" if($ItemCollection.Contains($Item.Name) -eq $false) { New-ItemProperty -Path $Item.Path -Name $Item.Name -Value $Item.Value -PropertyType $Item.Type -ErrorAction Stop | Out-Null } } } Catch { write-error "Unable to create Property Item ($RegistryPath) : $_" break } # Create Folders Write-Debug "# Create Folders :" Try { foreach($Item in $Config.Registry.folders){ Write-Debug "#`t- $Item" if((Test-Path $Item) -eq $false) { New-Item -ItemType directory -Path $Item -ErrorAction Stop | Out-null } } } Catch { write-error "Unable to create Folder ($Item) : $_" exit } # Create EventLog Source Write-Debug "# Create EventLog Source" if((Test-Path "HKLM:\SYSTEM\CurrentControlSet\Services\EventLog\Application\Fail2Ban") -eq $false) { Try { New-EventLog -LogName Application -Source "Fail2Ban" -ErrorAction Stop } Catch { Write-Error "Unable to create source into EventLog : $_" break } } # Create Scheduled Task Write-Debug "# Create Scheduled Task" if((Get-ScheduledTask -TaskName Fail2ban -ErrorAction SilentlyContinue) -eq $null) { Try { $action = New-ScheduledTaskAction -Execute 'Powershell.exe' -Argument '-NoProfile -WindowStyle Hidden -command "& {Retart-F2B}"' $trigger = New-ScheduledTaskTrigger -Daily -At 0am Register-ScheduledTask -Action $action -Trigger $trigger -User "System" -TaskName "Fail2ban" -Description "Fail2Ban is an intrusion prevention Powershell framework that protects computer servers from brute-force attacks" -ErrorAction Stop | Out-Null } Catch { Write-Error "Unable to create Scheduled Task : $_" break } } } # ++++++++++++++++++++++++++ # + Remove Fail2Ban function Remove-F2B(){ $Choice = Read-Host 'Do you really want to delete all data [yes/NO] ' if($Choice -eq "yes") { # Remove Folder Write-Debug "# Remove Folder" Try { Remove-Item -Path "$($env:PROGRAMFILES)\Fail2Ban" -Recurse -Force -ErrorAction Stop } Catch { Write-Error "Unable to remove properly this folder : $_" } # Remove Registry Key Write-Debug "# Remove Registry Key" Try { Remove-Item -Path "HKLM:\SOFTWARE\Fail2Ban\" -Recurse -Force -ErrorAction Stop } Catch { Write-Error "Unable to remove properly this registry Key : $_" } # Remove scheduled Task Write-Debug "# Remove scheduled Task" Try { Unregister-ScheduledTask -TaskName "Fail2Ban" -Confirm:$false } Catch { write-error "Unable to Remove scheduled Task" } } else { Write-Output "Operation canceled" } } # ++++++++++++++++++++++++++ # + Update Fail2Ban function Update-F2B(){ # Update Module Write-Debug "# Module update from Powershell Gallery" Try { Update-Module -Name "Fail2Ban" -Force } Catch { Write-Error "Unable to update Module : $_" } # Execute install } # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # + REGISTRY # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++++++++ # + Test Registry IP Function Test-F2BRegistryIP(){ Param( [Parameter(Mandatory=$true)] [String]$IP, [Parameter(Mandatory=$true)] [ValidateSet('Black','White')] [String]$Type ) $Data = (Get-Item HKLM:\SOFTWARE\Fail2Ban\List\$Type\).Property if($Data -ne $null) { if($Data.Contains($IP)) { return $true } else { return $false } } else { return $false } } # ++++++++++++++++++++++++++ # + Add Registry IP Function Add-F2BRegistryIP(){ Param( [Parameter(Mandatory=$true)] [String]$IP, [Parameter(Mandatory=$true)] [ValidateSet('Black','White')] [String]$Type, [Parameter(Mandatory=$false)] [ValidateSet($true,$false)] [bool]$Unlimited=$false ) # If not Exist if((Test-F2BRegistryIP -IP $IP -Type $Type) -eq $false) { # Set Duration if($Unlimited -eq $true) { $Value = 'Unlimited' } else { $Value = ([String](Get-Date)) } # Add IP Try { New-ItemProperty -Path "HKLM:\SOFTWARE\Fail2Ban\List\$Type" -Name $IP -Value $Value -PropertyType "String" return $true } Catch { Write-Warning "Unable to add property to registry : $_" return $false } } else { Write-Warning "The property already exists" return $false } } # ++++++++++++++++++++++++++ # + Remove Registry IP Function Remove-F2BRegistryIP(){ Param( [Parameter(Mandatory=$true)] [String]$IP, [Parameter(Mandatory=$true)] [ValidateSet('Black','White')] [String]$Type ) if((Test-F2BRegistryIP -IP $IP -Type $Type) -eq $true) { Try { Remove-ItemProperty -Path "HKLM:\SOFTWARE\Fail2Ban\List\$Type" -Name $IP return $true } Catch { Write-Warning "Unable to remove property to registry : $_" return $false } } else { Write-Warning "The property is not exists" return $false } } # ++++++++++++++++++++++++++ # + Get Registry IP Function Get-F2BRegistryIP(){ Param( [Parameter(Mandatory=$true)] [ValidateSet('Black','White')] [String]$Type ) $Items = (Get-Item "HKLM:\SOFTWARE\Fail2Ban\List\$Type").Property $hashtable = @{} foreach( $Item in $Items ){ $hashtable[$Item] = (Get-ItemPropertyValue -Path "HKLM:\SOFTWARE\Fail2Ban\List\$Type" -Name $Item) } return $hashtable } # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # + FIREWALL # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++++++++ # + Test Firewall Rule function Test-F2BFirewallRule(){ Param( [Parameter(Mandatory=$true)] [String]$IP ) $Test = Get-NetFirewallRule -DisplayName "Fail2Ban - Block $IP" -ErrorAction SilentlyContinue if($Test -ne $null) { return $true } else { return $false } } # ++++++++++++++++++++++++++ # + Add Firewall Rule function Add-F2BFirewallRule(){ Param( [Parameter(Mandatory=$true)] [String]$IP ) if((Test-F2BFirewallRule -IP $IP) -eq $false) { Try { $Params = @{ DisplayName = "Fail2Ban - Block $IP" Direction = "Inbound" RemoteAddress = $IP Profile = "Any" Action = "Block" } New-NetFirewallRule @PArams return $true } Catch { return $false } } else { return $false } } # ++++++++++++++++++++++++++ # + Remove Firewall Rule function Remove-F2BFirewallRule(){ Param( [Parameter(Mandatory=$true)] [String]$IP ) if((Test-F2BFirewallRule -IP $IP) -eq $true) { Try { Remove-NetFirewallRule -DisplayName "Fail2Ban - Block $IP" return $true } Catch { return $false } } else { return $false } } # ++++++++++++++++++++++++++ # + Test Firewall Status function Test-F2BFirewallStatus(){ $Interface = Get-NetIPConfiguration | Where-Object { $_.IPv4DefaultGateway -ne $null } | Get-NetConnectionProfile if($Interface -ne $null) { if((Get-NetFirewallProfile -Name $Interface.NetworkCategory).Enabled -eq $true){ return $true } else { return $false } } else { return $false } } # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # + System # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++++++++ # + Get Config function Get-F2BConfig(){ $Items = (Get-Item "HKLM:\SOFTWARE\Fail2Ban\Config").Property $hashtable = @{} foreach( $Item in $Items ){ $hashtable[$Item] = (Get-ItemPropertyValue -Path "HKLM:\SOFTWARE\Fail2Ban\Config" -Name $Item) } return $hashtable } # ++++++++++++++++++++++++++ # + Set Config function Set-F2BConfig(){ Param( [Parameter(Mandatory=$true)] [String]$Name, [Parameter(Mandatory=$true)] [String]$Value ) if(((Get-F2BConfig).($Name)) -ne $null) { Try { Set-ItemProperty -Path "HKLM:\SOFTWARE\Fail2Ban\Config" -Name $Name -Value $Value } Catch { write-error "unable to set Config value" } } else { Write-Host "Config Not found" } } # ++++++++++++++++++++++++++ # + Get Event Log function Get-F2BEventLog(){ $Config = Get-F2BConfig $CheckTime = ($Config | Where-Object { $_.Name -eq 'CheckTime'}).value $AfterDate = (Get-Date).AddSeconds(-$CheckTime) $EventLogs = Get-EventLog -log Security -After $AfterDate -InstanceId 4625 $Obj = @() foreach($EventLog in $EventLogs) { $Return = [PSCustomObject]@{ Index = $EventLog.Index Time = $EventLog.TimeWritten Type = $EventLog.EntryType Username = Get-Match -Patern "account name:\s+\w+" -Data $EventLog.message IP = Get-Match -Patern "Source Network Address:\s+\d{1,3}(\.\d{1,3}){3}" -Data $EventLog.message } $Obj += $Return } Return $Obj } # ++++++++++++++++++++++++++ # + Add Event Log function Add-F2BEventLog(){ Param( [Parameter(Mandatory=$true)] [ValidateSet('Information','Error','Warning')] [String]$Type, [Parameter(Mandatory=$true)] [String]$Message, [Parameter(Mandatory=$false)] [String]$Service='System', [Parameter(Mandatory=$true)] [Object]$Config ) if($Config.FileLog_Enabled -eq "True") { # Add Message to Log File if($Config.FileLog_Format -eq 'csv'){ $OutputObject = [PSCustomObject] @{ Date = Get-Date -Format "MM/dd/yyyy hh:mm:ss.fff tt" Type = $Type Service = $Service Message = $Message } $LogFile = Join-Path -Path $Config.FileLog_Folder -ChildPath "Fail2Ban-Service.$($Config.FileLog_Format)" Export-Csv -Path $LogFile -InputObject $OutputObject -Append -NoTypeInformation -Encoding UTF8 -Delimiter ";" } else { $Output = '{0} [{1}] {2}' -f (Get-Date -Format s),$Type,$Message Add-Content -Path (Join-Path -Path $Config.FileLog_Folder -ChildPath "Fail2Ban-Service.log") -Value $Output } } # ------------- # Windows Log if($Config.EventLog_Enabled -eq "True") { $Params = @{ LogName = $Config.EventLog_Name Source = "Fail2Ban" EntryType = $Type EventId = $Config.EventLog_Id Message = $Message } Write-EventLog @Params } } # ++++++++++++++++++++++++++ # + Start Fail2ban function Start-F2B(){} # ++++++++++++++++++++++++++ # + Stop Fail2ban function Stop-F2B(){} # ++++++++++++++++++++++++++ # + Restart Fail2ban function Restart-F2B(){} # ++++++++++++++++++++++++++ # + Test Status Fail2ban function Test-F2BStatus(){} # ++++++++++++++++++++++++++ # + Cleaning log file function Initialize-F2BFileLogCleaning(){} # ++++++++++++++++++++++++++ # + File log rotate function Initialize-F2BFileLogRotate(){} # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # + Process # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++++++++ # + Add Blocked IP function Add-F2BBlockedIP () { Param( [Parameter(Mandatory=$true)] [String]$IP ) if((Get-F2BRegistryIP -Type White).contains($IP) -eq $false) { if((Add-F2BRegistryIP -IP $IP -Type Black) -eq $true) { if((Add-F2BFirewallRule -IP $IP) -eq $true) { return $true } else { return $false } } else { return $false } } else { return $false } } function Remove-F2BBlockedIP () { Param( [Parameter(Mandatory=$true)] [String]$IP ) if((Remove-F2BRegistryIP -IP $IP -Type Black) -eq $true) { if((Remove-F2BFirewallRule -IP $IP) -eq $true) { return $true } else { return $false } } else { return $false } } # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # + INTERNAL TOOL # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++++++++ # + Get Match Patern function Get-Match(){ Param( [Parameter(Mandatory=$true)] [String]$Patern, [Parameter(Mandatory=$true)] [String]$Data ) $Content = $Data | Find-Matches -Pattern $Patern if($content.Count -eq 2) { $Match = $content[1] } else { $Match = $content } $Match = (($Match -split ":")[1]) -replace "\s+","" return $Match } # ++++++++++++++++++++++++++ # + Test Admon Elevation function Test-F2BAdmin(){ $CurrentWindowsIdentity = [Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent() If ($CurrentWindowsIdentity.IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator") -eq $true){ return $true } else { return $false } } |