With the recent Exchange vulnerabilities comes a moment to reflect on further ways to reduce the attach surface of Exchange Servers.
Many organizations still host an Exchange Server solely to maintain a hybrid connectivity link to Office 365. The server therefore has to be publicly accessible, but only to Microsoft. Often this is not the case.
If you don’t have a professional firewall to restrict traffic to only that coming from Microsoft, you can also do so at the IIS level. Microsoft publishes a list of IP’s they use here:
https://endpoints.office.com/endpoints/worldwide
We can then take that source address data and add each IP in it to an Allow entry at the global level in IIS using PowerShell:
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Web")
$res = [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls12
$allRanges = @("fe80::946:a60c:3d5:ec11%3","127.0.0.1","::1")
$o365IPs = Invoke-RestMethod -Method GET -UseBasicParsing -Uri "https://endpoints.office.com/endpoints/worldwide?clientrequestid=b10c5ed1-bad1-445f-b386-b919946339a7"
$o365IPs | % {$_.ips | %{if($allRanges -notcontains $_){$allRanges += $_}}}
$allRanges | % {
if($_.IndexOf("/")){
$payLoad = @{ipAddress=$_.Split("/")[0];allowed="true";subnetMask=$(([ipaddress]([double]4294967296-(1-shl32-$($_.Split("/")[1])))).IPAddressToString);}
}else{
$payLoad = @{ipAddress=$_;allowed="true";}
}
try{$null = Add-WebConfigurationProperty -Filter 'system.webServer/security/ipSecurity' -PSPath "IIS:\" -Name "." -Value $payLoad -ErrorAction SilentlyContinue}catch{$Null}
}
Finally, set IIS’s IP Address and Domain restriction mode to Deny:
note: you can add additional ranges to $allRanges as needed for internal management, monitoring etc.
hello. would you kindly update to include client request guid. otherwise script will fail.
cheers.
And how do you block access from EXO Tenants that are not yours?
Hey I am getting a 503 error on the when running this. Any idea on how to solve that? the URL loads fine for me in a browser
Is that script something you have to run in a specific location, or is it a script you have to run daily? Sorry I’m not a powershell pro. Or is it just a script I would run on the exchange server, once?