Last active
May 7, 2024 04:40
-
-
Save ghotz/1b99470bce5caed245c1b024040ec263 to your computer and use it in GitHub Desktop.
Auto ban IP addresses by POST requests total size over a certain threshold in the last http log file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Warning: remember to whitelist who you want to allow to post by entering their IP addresses in the Azure Portal | |
import-module Az; | |
$TenantID = 'YOURTENANTID'; | |
$SubscriptionID = 'YOURSUBID' | |
$ResourceGroupName = 'WebSite'; | |
$AppServiceName = 'YOURSERVICENAME'; | |
$MyIP = (Invoke-WebRequest -uri "http://ifconfig.me/ip").Content; #avoid self-banning | |
$MaxPostsBytes = 100KB; | |
# Authenticate to Azure if not already authenticated | |
if (!$Connection) { $Connection = Connect-AzAccount -Tenant $TenantID -Subscription $SubscriptionID }; | |
# Get Log files technique from https://hkarthik7.github.io/azure%20devops/powershell/azure/2021/01/16/Parse-http-logs-of-Azure-webapp-using-Azure-DevOps-CI-pipeline.html | |
$SCM = "https://$($AppServiceName).scm.azurewebsites.net/api/vfs/LogFiles/http/rawlogs/" # to get zip file $SCM.Replace("vfs", "zip") | |
# Get authentication details from the publishing profile | |
Write-Output "Getting the authentication details from the publishing profile..."; | |
if (!$WebApp) { $WebApp = Get-AzWebApp -ResourceGroupName $ResourceGroupName -Name $AppServiceName }; | |
if (!$PublishingProfile) { [xml]$PublishingProfile = Get-AzWebAppPublishingProfile -WebApp $WebApp }; | |
$UserName = $PublishingProfile.publishData.publishProfile[0].userName; | |
$Password = $PublishingProfile.publishData.publishProfile[0].userPWD; | |
$Base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $UserName,$Password))); | |
# Get the log files | |
Write-Output "Getting the log files..."; | |
$LogFiles = Invoke-RestMethod -Uri $SCM -Headers @{Authorization=("Basic {0}" -f $Base64AuthInfo)} -Method GET; | |
#$LogFiles = $LogFiles | Where-Object { (Get-Date $_.crtime).Date -eq (Get-Date).Date } | Select * -Last 1; # filter by date as needed | |
$LogFile = $LogFiles | Sort-Object -Property mtime -Descending | Select -First 1; | |
$RawLog = Invoke-RestMethod -Uri "$SCM/$($LogFile.name)" -Headers @{Authorization=("Basic {0}" -f $Base64AuthInfo)} -Method GET; # to export -OutFile "PATH" -ContentType "text/plain" or "multipart/form-data" if zip file | |
# Parse the log files and get the IP addresses to ban | |
Write-Output "Parsing the log files and getting the IP addresses to ban..."; | |
$ParsedLog = $RawLog | ConvertFrom-Csv -Delimiter " " -Header 'date','time','s-sitename','cs-method','cs-uri-stem','cs-uri-query','s-port,cs-username','c-ip','cs(User-Agent)','cs(Cookie)','cs(Referer)','cs-host','sc-status','sc-substatus','sc-win32-status','sc-bytes','cs-bytes','time-taken'; | |
$IPAdressesToBan = $ParsedLog | ? { $_.'cs-method' -eq 'POST' -and $_.'cs(User-Agent)' -ne $MyIP } | Group-object -Property 'cs(User-Agent)' | % {[pscustomobject]@{IPAddress=$_.Name;PostsCount=$_.Count;PostsBytes = ($_.group | measure-object 'cs-bytes' -Sum).Sum}} | ? PostsBytes -gt $MaxPostsBytes | Select *; | |
# Get the IP addresses already banned | |
Write-Output "Getting the IP addresses already banned..."; | |
$Restrictions = Get-AzWebAppAccessRestrictionConfig -ResourceGroupName $ResourceGroupName -Name $AppServiceName; | |
$IPAddressBanned = $Restrictions.MainSiteAccessRestrictions | ? { $_.Action -eq 'deny' -and $_.IpAddress -ne 'Any' -and ($_.IpAddress -split '/')[1] -eq '32' } | % { ($_.IpAddress -split '/')[0] }; | |
# Ban the new IP addresses | |
$IPAdressesToBan | ? { $_.IPAddress -notin $IPAddressBanned } | % { | |
Write-Output "Banning $($_.IPAddress)..." | |
Add-AzWebAppAccessRestrictionRule -ResourceGroupName $ResourceGroupName -WebAppName $AppServiceName -Name "BL $($_.IPAddress)" -Priority 90 -Action Deny -IpAddress ("{0}/{1}" -f $_.IPAddress,'32') | |
}; | |
Write-Host "Top 10 IP address L2 prefixes with the most POSTs and bytes:"; | |
$IPAddressBanned | % { | |
[pscustomobject]@{ | |
L1 = ($_ -split '\.')[0]; | |
L2 = ("{0}.{1}" -f ($_ -split '\.')[0],($_ -split '\.')[1]); | |
L3 = ("{0}.{1}.{2}" -f ($_ -split '\.')[0],($_ -split '\.')[1],($_ -split '\.')[2]); | |
L4 = $_; | |
} | |
} | | |
Group-Object -Property L2 | sort count -Descending | select -First 10 | ft; | |
Write-Host "Top 10 IP address L3 prefixes with the most POSTs and bytes:"; | |
$IPAddressBanned | % { | |
[pscustomobject]@{ | |
L1 = ($_ -split '\.')[0]; | |
L2 = ("{0}.{1}" -f ($_ -split '\.')[0],($_ -split '\.')[1]); | |
L3 = ("{0}.{1}.{2}" -f ($_ -split '\.')[0],($_ -split '\.')[1],($_ -split '\.')[2]); | |
L4 = $_; | |
} | |
} | | |
Group-Object -Property L3 | sort count -Descending | select -First 10 | ft; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment