Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
e4d74f6
IP Filtering changes with EP script
varungupta-msft Aug 9, 2022
1701d89
Fixing Get-AllNIcInformation inclusion path error
SharmaAkash1 Aug 9, 2022
ec96559
Update:
varungupta-msft Aug 9, 2022
3bd2867
Flag changes, logging improvement, bug fixes
SharmaAkash1 Aug 9, 2022
bc5ba65
Use exchangeServer and skipExchangeServer flag during mitigation oper…
SharmaAkash1 Aug 9, 2022
aeed75d
Validate Mitigation bug fixes
varungupta-msft Aug 9, 2022
5471571
empty iprange file disclaimer
SharmaAkash1 Aug 9, 2022
bf74475
Remove restrict type from ValidateMitiagtion parameter set
SharmaAkash1 Aug 10, 2022
268c35e
Fixing Validating rules status
SharmaAkash1 Aug 10, 2022
917c1f9
IP limit check, empty ExchangeServer param, null reference issue fix
SharmaAkash1 Aug 10, 2022
a7e22a3
Fixed issues with strings
varungupta-msft Aug 10, 2022
0745291
Remove Enum type, Check invalid ip file before prereq
SharmaAkash1 Aug 10, 2022
f9869fa
Output expected value of flags
SharmaAkash1 Aug 10, 2022
8e13a7e
Move logger initialization to start of script
SharmaAkash1 Aug 10, 2022
05942fb
fixing issue in printing expected flag values
SharmaAkash1 Aug 10, 2022
695b3c1
Validation fix for empty iprange list
SharmaAkash1 Aug 10, 2022
6199df0
Fixed issue in validate: didn't compare ip.allow
varungupta-msft Aug 10, 2022
16a088c
Merge branch 'guptavarun-V2script' of https://github.com/microsoft/CS…
varungupta-msft Aug 10, 2022
f63fade
code formatter
varungupta-msft Aug 10, 2022
0922670
added a log statement in mitigation script
varungupta-msft Aug 10, 2022
3377c53
Resolved some comments
varungupta-msft Aug 11, 2022
2a1956c
ConfigureMitigation Whatif and logging changes
SharmaAkash1 Aug 11, 2022
ac3baa9
Merging Mitigation into Enable EP feature
varungupta-msft Aug 11, 2022
f23f184
Add easy override type option to Extended Protection Configuration
dpaulson45 Aug 11, 2022
a89dc75
incorporated Mitigationappliedtype parameter
varungupta-msft Aug 12, 2022
2fa7034
Rollback whatif, Rollback logging change, Configure ip rules limit check
SharmaAkash1 Aug 13, 2022
0391c52
Changed Restrict type to array for invoke configure mitigation and in…
varungupta-msft Aug 13, 2022
037cfe1
trun on ep during rollback
SharmaAkash1 Aug 15, 2022
885f8b1
String changes
SharmaAkash1 Aug 15, 2022
f67af76
Made restrict type as list for backing up IP filtering rules
varungupta-msft Aug 15, 2022
7b56cf0
IPRangePathFile param name change + outputFilePath check fix
SharmaAkash1 Aug 15, 2022
b1ff6be
Minor fixes for rollback
varungupta-msft Aug 15, 2022
51c632e
Find exchange servers IP don't consider edge server
varungupta-msft Aug 16, 2022
aaa6f01
resolved comments
varungupta-msft Aug 16, 2022
b910d73
Bring in latest changes from main
bill-long Aug 16, 2022
e0e95ba
fixed minor issues
varungupta-msft Aug 16, 2022
cd5dcbb
Fix issue when rolling back 1 ip
SharmaAkash1 Aug 16, 2022
140088c
minor fix
varungupta-msft Aug 16, 2022
4f7e21b
Merge branch 'guptavarun-V2script' of https://github.com/microsoft/CS…
varungupta-msft Aug 16, 2022
d40726c
reverted list<object> to array
varungupta-msft Aug 16, 2022
2d5104c
Merge branch 'next-release' into guptavarun-V2script
bill-long Aug 16, 2022
75e9dfa
minor issue fixed. unable to add ips to iis
varungupta-msft Aug 16, 2022
9c9f54f
Merge branch 'guptavarun-V2script' of https://github.com/microsoft/CS…
varungupta-msft Aug 16, 2022
129da40
Fixing rollback issue when we need to rollback to no rules state
SharmaAkash1 Aug 16, 2022
3ea769b
resolved the $ipRangeAllowListString print issue
varungupta-msft Aug 16, 2022
73ee42d
Merge branch 'guptavarun-V2script' of https://github.com/microsoft/CS…
varungupta-msft Aug 16, 2022
c94b7cb
Fixing formatting
SharmaAkash1 Aug 16, 2022
0c00d0c
Fixing formatting
SharmaAkash1 Aug 16, 2022
d8988a6
Simplify $PsCmdlet.ParameterSetName being used
dpaulson45 Aug 16, 2022
5ec5ab5
Resolved parameter set issue for $ShowExtendedProtection parameter
varungupta-msft Aug 16, 2022
fef569d
Fix - change rollbackType to array from string
SharmaAkash1 Aug 16, 2022
76c4fa5
Merge branch 'guptavarun-V2script' of https://github.com/microsoft/CS…
SharmaAkash1 Aug 16, 2022
4371337
Rollback Unreachable server fix
SharmaAkash1 Aug 16, 2022
4fcb868
Fixing connection issues in validate-mitigation
SharmaAkash1 Aug 16, 2022
f0c1361
RollbackType param fix
SharmaAkash1 Aug 16, 2022
81d73a3
Merge branch 'next-release' into guptavarun-V2script
bill-long Aug 16, 2022
ee6712a
Fixing failure case for get-exchangeServerIps
SharmaAkash1 Aug 17, 2022
7d18af9
Merge branch 'guptavarun-V2script' of https://github.com/microsoft/CS…
SharmaAkash1 Aug 17, 2022
c8ff101
made minor logging changes
varungupta-msft Aug 17, 2022
925fdac
String changes
SharmaAkash1 Aug 17, 2022
951dfac
Resolved Nit comments; added functionality to display list of servers…
varungupta-msft Aug 17, 2022
c225370
Replaced GetCommaSaperatedString function with string::join
varungupta-msft Aug 17, 2022
8a0549f
Merged string changes with remote changes
SharmaAkash1 Aug 17, 2022
a6d5eee
Merge branch 'guptavarun-V2script' of https://github.com/microsoft/CS…
SharmaAkash1 Aug 17, 2022
f70f957
Fix failed server configure mitigation issue
SharmaAkash1 Aug 17, 2022
3f4482f
Configure Mitigations already applied message fix
SharmaAkash1 Aug 17, 2022
3051cac
Change writing successful application of rules (when nothing changes)
SharmaAkash1 Aug 17, 2022
94ac64d
ValidateMitigation write-verbose foreground color fix
SharmaAkash1 Aug 17, 2022
7aae263
string changes
varungupta-msft Aug 18, 2022
8aa2016
Fix for findip warning
SharmaAkash1 Aug 18, 2022
bbe0ac3
Merge branch 'main' into guptavarun-V2script
bill-long Aug 18, 2022
080d8ef
Merge branch 'main' into guptavarun-V2script
bill-long Aug 18, 2022
a287721
Changing ValidateMitigation flag to ValidateType
varungupta-msft Aug 22, 2022
1efe4fe
Merge branch 'guptavarun-V2script' of https://github.com/microsoft/CS…
varungupta-msft Aug 22, 2022
81cad04
Don't consider E15 servers for mitigation
SharmaAkash1 Sep 8, 2022
987aa9a
resolved comments on build version
varungupta-msft Sep 9, 2022
f20b3cc
Nit changes (ip -> IP)
varungupta-msft Sep 12, 2022
fddbd47
Removed extra code that was not needed
SharmaAkash1 Sep 12, 2022
e80fab0
Merge branch 'next-release' into guptavarun-V2script resolved conflicts
dpaulson45 Sep 15, 2022
cf98f2f
Fixed typo
dpaulson45 Sep 15, 2022
a68cc77
Merge pull request #40 from microsoft/guptavarun-V2script
bill-long Sep 15, 2022
c569ab2
Merge branch 'main' into ews-mitigation
bill-long Sep 15, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,310 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

. $PSScriptRoot\..\..\..\..\Shared\Invoke-ScriptBlockHandler.ps1
. $PSScriptRoot\..\..\..\..\Shared\Write-ErrorInformation.ps1

function Invoke-ConfigureMitigation {
[OutputType([System.Collections.Hashtable])]
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[string[]]$ExchangeServers,
[Parameter(Mandatory = $true)]
[object[]]$IPRangeAllowListRules ,
[Parameter(Mandatory = $true)]
[string[]]$SiteVDirLocations
)

begin {
$FailedServersFilter = @{}
$UnchangedFilterServers = @{}

$progressParams = @{
Activity = "Applying IP filtering Rules"
Status = [string]::Empty
PercentComplete = 0
}

Write-Verbose "Calling: $($MyInvocation.MyCommand)"

$ConfigureMitigation = {
param(
[Object]$Arguments
)

$SiteVDirLocations = $Arguments.SiteVDirLocations
$IpRangesForFiltering = $Arguments.IpRangesForFiltering
$WhatIf = $Arguments.PassedWhatIf

$results = @{
IsWindowsFeatureInstalled = $false
IsGetLocalIPSuccessful = $false
LocalIPs = New-Object 'System.Collections.Generic.List[string]'
ErrorContext = $null
}

function BackupCurrentIPFilteringRules {
param(
[Parameter(Mandatory = $true)]
[string]$BackupPath,
[Parameter(Mandatory = $true)]
[string]$Filter,
[Parameter(Mandatory = $true)]
[string]$IISPath,
[Parameter(Mandatory = $true)]
[string]$SiteVDirLocation,
[Parameter(Mandatory = $false)]
[object[]]$ExistingRules
)

$DefaultForUnspecifiedIPs = Get-WebConfigurationProperty -Filter $Filter -PSPath $IISPath -Location $SiteVDirLocation -Name "allowUnlisted"
if ($null -eq $ExistingRules) {
$ExistingRules = New-Object 'System.Collections.Generic.List[object]'
}

$BackupFilteringConfiguration = @{Rules=$ExistingRules; DefaultForUnspecifiedIPs=$DefaultForUnspecifiedIPs }
if (-not $WhatIf) {
$BackupFilteringConfiguration | ConvertTo-Json -Depth 2 | Out-File $BackupPath
}

return $true
}

function GetLocalIPAddresses {
$ips = New-Object 'System.Collections.Generic.List[string]'
$interfaces = Get-NetIPAddress -ErrorAction Stop
foreach ($interface in $interfaces) {
if ($interface.AddressState -eq 'Preferred') {
$ips += $interface.IPAddress
}
}

return $ips
}

# Create IP allow list from user provided IP subnets
function CreateIPRangeAllowList {
param (
[Parameter(Mandatory = $true)]
[string]$SiteVDirLocation,
[Parameter(Mandatory = $true)]
[object[]]$IpFilteringRules,
[Parameter(Mandatory = $true)]
[hashtable] $state
)

$backupPath = "$($env:WINDIR)\System32\inetsrv\config\IpFilteringRules_" + $SiteVDirLocation.Replace('/', '-') + "_$([DateTime]::Now.ToString("yyyyMMddHHMMss")).bak"
$Filter = 'system.webServer/security/ipSecurity'
$IISPath = 'IIS:\'
$ExistingRules = @(Get-WebConfigurationProperty -Filter $Filter -Location $SiteVDirLocation -name collection)
$state.IsBackUpSuccessful = BackupCurrentIPFilteringRules -BackupPath $backupPath -Filter $Filter -IISPath $IISPath -SiteVDirLocation $SiteVDirLocation -ExistingRules $ExistingRules

$RulesToBeAdded = @()

foreach ($IpFilteringRule in $IpFilteringRules) {
$ExistingIPSubnetRule = $ExistingRules | Where-Object { $_.ipAddress -eq $IpFilteringRule.IP -and
($_.subnetMask -eq $IpFilteringRule.SubnetMask -or $IpFilteringRule.Type -eq "Single IP")
}

if ($null -eq $ExistingIPSubnetRule) {
if ($IpFilteringRule.Type -eq "Single IP") {
$RulesToBeAdded += @{ipAddress=$IpFilteringRule.IP; allowed=$IpFilteringRule.Allowed; }
} else {
$RulesToBeAdded += @{ipAddress=$IpFilteringRule.IP; subnetMask=$IpFilteringRule.SubnetMask; allowed=$IpFilteringRule.Allowed; }
}
} else {
if ($ExistingIPSubnetRule.allowed -ne $IpFilteringRule.Allowed) {
if ($IpFilteringRule.Type -eq "Single IP") {
$IpString = $IpFilteringRule.IP
} else {
$IpString = ("{0}/{1}" -f $IpFilteringRule.IP, $IpFilteringRule.SubnetMask)
}

$state.IPsNotAdded += $IpString
}
}
}

if ($RulesToBeAdded.Count + $ExistingRules.Count -gt 500) {
$state.IPsNotAdded += $RulesToBeAdded
throw 'Too many IP filtering rules (Existing rules [$($ExistingRules.Count)] + New rules [$($RulesToBeAdded.Count)] > 500). Please reduce the specified entries by providing appropriate subnets.'
}

if ($RulesToBeAdded.Count -gt 0) {
$state.AreIPRulesModified = $true
Add-WebConfigurationProperty -Filter $Filter -PSPath $IISPath -Location $SiteVDirLocation -Name "." -Value $RulesToBeAdded -ErrorAction Stop -WhatIf:$WhatIf
}

$state.IsCreateIPRulesSuccessful = $true

# Setting default to deny
Set-WebConfigurationProperty -Filter $Filter -PSPath $IISPath -Location $SiteVDirLocation -Name "allowUnlisted" -Value $false -WhatIf:$WhatIf
$state.IsSetDefaultRuleSuccessful = $true
}

try {
try {
$baseError = "Installation of IP and Domain filtering Module failed."
$InstallResult = Install-WindowsFeature Web-IP-Security -ErrorAction Stop -WhatIf:$WhatIf
if (-not $InstallResult.Success) {
throw $baseError
}
} catch {
throw "$baseError Inner exception: $_"
}

$results.IsWindowsFeatureInstalled = $true

$localIPs = GetLocalIPAddresses
$results.IsGetLocalIPSuccessful = $true

foreach ($localIP in $localIPs) {
if ($null -eq ($IpRangesForFiltering | Where-Object { $_.Type -eq "Single IP" -and $_.IP -eq $localIP })) {
$IpRangesForFiltering += @{Type="Single IP"; IP=$localIP; Allowed=$true }
}
}

$results.LocalIPs = $localIPs
foreach ($SiteVDirLocation in $SiteVDirLocations) {
$state = @{
IsBackUpSuccessful = $false
IsCreateIPRulesSuccessful = $false
IsSetDefaultRuleSuccessful = $false
ErrorContext = $null
IPsNotAdded = New-Object 'System.Collections.Generic.List[string]'
AreIPRulesModified = $false
}

try {
CreateIPRangeAllowList -SiteVDirLocation $SiteVDirLocation -IpFilteringRules $IpRangesForFiltering -state $state
} catch {
$state.ErrorContext = $_
}

$results[$SiteVDirLocation] = $state
}
} catch {
$results.ErrorContext = $_
}

return $results
}
} process {
$scriptblockArgs = [PSCustomObject]@{
SiteVDirLocations = $SiteVDirLocations
IpRangesForFiltering = $IPRangeAllowListRules
PassedWhatIf = $WhatIfPreference
}

$counter = 0
$totalCount = $ExchangeServers.Count

if ($null -eq $IPRangeAllowListRules ) {
$IPRangeAllowListString = "null"
} else {
$IPStrings = @()
$IPRangeAllowListRules | ForEach-Object {
if ($_.Type -eq "Single IP") {
$IPStrings += $_.IP
} else {
$IPStrings += ("{0}/{1}" -f $_.IP, $_.SubnetMask)
}
}
$IPRangeAllowListString = [string]::Join(", ", $IPStrings)
}

$SiteVDirLocations | ForEach-Object {
$FailedServersFilter[$_] = New-Object 'System.Collections.Generic.List[string]'
$UnchangedFilterServers[$_] = New-Object 'System.Collections.Generic.List[string]'
}

foreach ($Server in $ExchangeServers) {
$baseStatus = "Processing: $Server -"
$progressParams.PercentComplete = ($counter / $totalCount * 100)
$progressParams.Status = "$baseStatus Applying rules"
Write-Progress @progressParams
$counter ++;

Write-Verbose ("Calling Invoke-ScriptBlockHandler on Server {0} with arguments SiteVDirLocation: {1}, IPRangeAllowListRules : {2}" -f $Server, $SiteVDirLocation, $IPRangeAllowListString)
$resultsInvoke = Invoke-ScriptBlockHandler -ComputerName $Server -ScriptBlock $ConfigureMitigation -ArgumentList $scriptblockArgs

Write-Verbose ("Adding IP Restriction rules on Server {0}" -f $Server)
if ($resultsInvoke.IsWindowsFeatureInstalled) {
Write-Verbose ("Successfully installed windows feature - Web-IP-Security on server {0}" -f $Server)
} else {
Write-Host ("Script failed to install windows feature - Web-IP-Security on server {0} with the Inner Exception:" -f $Server) -ForegroundColor Red
Write-HostErrorInformation $resultsInvoke.ErrorContext
$FailedServersFilter[$SiteVDirLocation] += $Server
continue
}

if ($resultsInvoke.IsGetLocalIPSuccessful) {
Write-Verbose ("Successfully retrieved local IPs for the server")
if ($null -ne $resultsInvoke.LocalIPs -and $resultsInvoke.LocalIPs.Length -gt 0) {
Write-Verbose ("Local IPs detected for this server: {0}" -f [string]::Join(", ", [string[]]$resultsInvoke.LocalIPs))
} else {
Write-Verbose ("No Local IPs detected for this server")
}
} else {
Write-Host ("Script failed to retrieve local IPs for server {0}. Reapply IP filtering on server. Inner Exception:" -f $Server) -ForegroundColor Red
Write-HostErrorInformation $resultsInvoke.ErrorContext
$FailedServersFilter[$SiteVDirLocation] += $Server
continue
}

foreach ($SiteVDirLocation in $SiteVDirLocations) {
$state = $resultsInvoke[$SiteVDirLocation]

if ($state.IsBackUpSuccessful) {
Write-Verbose ("Successfully backed up IP filtering allow list for VDir $SiteVDirLocation on server $Server")
} else {
Write-Host ("Script failed to backup IP filtering allow list for VDir $SiteVDirLocation on server $Server with the Inner Exception:") -ForegroundColor Red
Write-HostErrorInformation $state.ErrorContext
$FailedServersFilter[$SiteVDirLocation] += $Server
continue
}

if ($state.IsCreateIPRulesSuccessful) {
if ($state.IPsNotAdded.Length -gt 0) {
$line = ("Some IPs provided in the IPRange file were present in deny rules, hence these IPs were not added in the Allow List for VDir $SiteVDirLocation on server $Server. If you wish to add these IPs in allow list, remove these IPs from deny list in module name and reapply IP restrictions again.")
Write-Warning ($line + "Check logs for further details.")
Write-Verbose $line
Write-Verbose ([string]::Join(", ", $state.IPsNotAdded))
}

if (-not $state.AreIPRulesModified) {
Write-Verbose ("No changes were made to IP filtering rules for VDir $SiteVDirLocation on server $Server")
$UnchangedFilterServers[$SiteVDirLocation] += $Server
} else {
Write-Host ("Successfully updated IP filtering allow list for VDir $SiteVDirLocation on server $Server")
}
} else {
Write-Host ("Script failed to update IP filtering allow list for VDir $SiteVDirLocation on server $Server with the Inner Exception:") -ForegroundColor Red
Write-HostErrorInformation $state.ErrorContext
$FailedServersFilter[$SiteVDirLocation] += $Server
continue
}

if ($state.IsSetDefaultRuleSuccessful) {
Write-Verbose ("Successfully set the default IP filtering rule to deny for VDir $SiteVDirLocation on server $Server")
} else {
Write-Host ("Script failed to set the default IP filtering rule to deny for VDir $SiteVDirLocation on server $Server with the Inner Exception:") -ForegroundColor Red
Write-HostErrorInformation $state.ErrorContext
$FailedServersFilter[$SiteVDirLocation] += $Server
continue
}
}
}
} end {
foreach ($SiteVDirLocation in $SiteVDirLocations) {
if ($FailedServersFilter[$SiteVDirLocation].Length -gt 0) {
Write-Host ("Unable to create IP Filtering Rules for VDir $SiteVDirLocation on the following servers: {0}" -f [string]::Join(", ", $FailedServersFilter[$SiteVDirLocation])) -ForegroundColor Red
}

if ($UnchangedFilterServers[$SiteVDirLocation].Length -gt 0) {
Write-Host ("IP Restrictions are applied. No changes made in IP Restriction rules for VDir $SiteVDirLocation in : {0}" -f [string]::Join(", ", $UnchangedFilterServers[$SiteVDirLocation]))
}
}
}
}
Loading