Netgate Discussion Forum
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Search
    • Register
    • Login

    Office 365 URLs and IP address ranges

    Scheduled Pinned Locked Moved Firewalling
    19 Posts 6 Posters 8.1k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • D
      daschenbrener
      last edited by

      @kuberan thanks for the info, how would you go about implementing this?

      1 Reply Last reply Reply Quote 0
      • K
        kuberan
        last edited by

        I would like to automate this… but for now I edited the XML file Aliases and loaded that... I think pfBlockerNG  can be used.. but I need to test it first.... I was hoping there is a simpler solution

        1 Reply Last reply Reply Quote 0
        • K
          kpa
          last edited by

          You won't achieve full automation easily because XML is essentially free form and to write a parser for an arbitrary XML file you need to know a bit about the structure of the file (called the schema). There are XML parsers for PHP but the parts that know about a particular XML schema (like this what MS uses) are not going be included in base pfSense, they are a clear case for an addon package.

          1 Reply Last reply Reply Quote 0
          • D
            daschenbrener
            last edited by

            well it is working and updating from their files, so unless they change their format etc, Ill continue to use it.

            1 Reply Last reply Reply Quote 0
            • K
              kuberan
              last edited by

              @daschenbrener what advice do you have. How did you do it?

              1 Reply Last reply Reply Quote 0
              • D
                daschenbrener
                last edited by

                how i used it is through pfBlockerNG.

                I added it to the rules

                see picture attached

                and it automatically parsed the file and is working

                ![xml file.png](/public/imported_attachments/1/xml file.png)
                ![xml file.png_thumb](/public/imported_attachments/1/xml file.png_thumb)

                1 Reply Last reply Reply Quote 0
                • K
                  kpa
                  last edited by

                  Is that a lucky accident or is PFBlockerNG smart enough to parse the XML properly?

                  1 Reply Last reply Reply Quote 0
                  • D
                    daschenbrener
                    last edited by

                    this is a first for me, but i believe that it is designed that way as pfsense can uses xml files already as well.

                    1 Reply Last reply Reply Quote 0
                    • D
                      doktornotor Banned
                      last edited by

                      @kpa:

                      Is that a lucky accident or is PFBlockerNG smart enough to parse the XML properly?

                      It doesn't really parse it, it uses a bunch of crazy regexps to get IPs out of the XML/HTML/whatnot file.

                      https://github.com/pfsense/FreeBSD-ports/blob/devel/net/pfSense-pkg-pfBlockerNG/files/usr/local/pkg/pfblockerng/pfblockerng.inc#L4037

                      1 Reply Last reply Reply Quote 0
                      • K
                        kuberan
                        last edited by

                        @daschenbrener: thank you… I will give this a try.... :-)

                        1 Reply Last reply Reply Quote 0
                        • D
                          daschenbrener
                          last edited by

                          my pleasure ,now to find files like this for other companies , hmm, maybe there is something here i can start, a list of the various locations for ip address . Just like the one for microsoft.

                          1 Reply Last reply Reply Quote 0
                          • K
                            kuberan
                            last edited by

                            Good idea… it just needs to be a trusted list....

                            1 Reply Last reply Reply Quote 0
                            • T
                              Tomoko @kuberan
                              last edited by

                              @kuberan
                              I use the Powershell script from Microsoft. It generates the IPv4 addresses in a text file. This is uploaded daily to an FTP server via task scheduling. I have deactivated ipv6 and Urls in the Powershell-Script.
                              Maybe this will help other users.

                              <# Get-O365WebServiceUpdates.ps1
                              From https://aka.ms/ipurlws
                              v1.1 8/6/2019
                              DESCRIPTION
                              This script calls the REST API of the Office 365 IP and URL Web Service (Worldwide instance)
                              and checks to see if there has been a new update since the version stored in an existing
                              $Env:TEMP\O365_endpoints_latestversion.txt file in your user directory's temp folder
                              (usually C:\Users\<username>\AppData\Local\Temp).
                              If the file doesn't exist, or the latest version is newer than the current version in the
                              file, the script returns IPs and/or URLs that have been changed, added or removed in the latest
                              update and writes the new version and data to the output file $Env:TEMP\O365_endpoints_data.txt.
                              
                              USAGE
                              Run as a scheduled task every 60 minutes.
                              
                              PARAMETERS
                              n/a
                              
                              PREREQUISITES
                              PS script execution policy: Bypass
                              PowerShell 3.0 or later
                              Does not require elevation
                              https://docs.microsoft.com/en-us/microsoft-365/enterprise/microsoft-365-ip-web-service?view=o365-worldwide
                              #>
                              
                              #Requires -Version 3.0
                              
                              # web service root URL
                              $ws = "https://endpoints.office.com"
                              # path where output files will be stored
                              #$versionpath = $Env:TEMP + "\O365_endpoints_latestversion.txt"
                              $versionpath = "C:\Powershell\O365_endpoints_latestversion.txt"
                              #$datapath = $Env:TEMP + "\O365_endpoints_data.txt"
                              $datapath = "C:\Powershell\O365_endpoints_data.txt"
                              # fetch client ID and version if version file exists; otherwise create new file and client ID
                              if (Test-Path $versionpath) {
                                  $content = Get-Content $versionpath
                                  $clientRequestId = $content[0]
                                  $lastVersion = $content[1]
                                  Write-Output ("Version file exists! Current version: " + $lastVersion)
                              }
                              else {
                                  Write-Output ("First run! Creating version file at " + $versionpath + ".")
                                  $clientRequestId = [GUID]::NewGuid().Guid
                                  $lastVersion = "0000000000"
                                  @($clientRequestId, $lastVersion) | Out-File $versionpath
                              }
                              
                              # call version method to check the latest version, and pull new data if version number is different
                              $version = Invoke-RestMethod -Uri ($ws + "/version/Worldwide?clientRequestId=" + $clientRequestId)
                              if ($version.latest -gt $lastVersion) {
                                  Write-Host "New version of Office 365 worldwide commercial service instance endpoints detected"
                                  # write the new version number to the version file
                                  @($clientRequestId, $version.latest) | Out-File $versionpath
                                  # invoke endpoints method to get the new data
                                  $endpointSets = Invoke-RestMethod -Uri ($ws + "/endpoints/Worldwide?clientRequestId=" + $clientRequestId)
                                  # filter results for Allow and Optimize endpoints, and transform these into custom objects with port and category
                                  # URL results
                                  $flatUrls = $endpointSets | ForEach-Object {
                                      $endpointSet = $_
                                      $urls = $(if ($endpointSet.urls.Count -gt 0) { $endpointSet.urls } else { @() })
                                      $urlCustomObjects = @()
                                      if ($endpointSet.category -in ("Allow", "Optimize")) {
                                          $urlCustomObjects = $urls | ForEach-Object {
                                              [PSCustomObject]@{
                                                  category = $endpointSet.category;
                                                  url      = $_;
                                                  tcpPorts = $endpointSet.tcpPorts;
                                                  udpPorts = $endpointSet.udpPorts;
                                              }
                                          }
                                      }
                                      $urlCustomObjects
                                  }
                                  # IPv4 results
                                  $flatIp4s = $endpointSets | ForEach-Object {
                                      $endpointSet = $_
                                      $ips = $(if ($endpointSet.ips.Count -gt 0) { $endpointSet.ips } else { @() })
                                      # IPv4 strings contain dots
                                      $ip4s = $ips | Where-Object { $_ -like '*.*' }
                                      $ip4CustomObjects = @()
                                      if ($endpointSet.category -in ("Allow", "Optimize")) {
                                          $ip4CustomObjects = $ip4s | ForEach-Object {
                                              [PSCustomObject]@{
                                                  category = $endpointSet.category;
                                                  ip = $_;
                                                  tcpPorts = $endpointSet.tcpPorts;
                                                  udpPorts = $endpointSet.udpPorts;
                                              }
                                          }
                                      }
                                      $ip4CustomObjects
                                  }
                                  # IPv6 results
                                  $flatIp6s = $endpointSets | ForEach-Object {
                                      $endpointSet = $_
                                      $ips = $(if ($endpointSet.ips.Count -gt 0) { $endpointSet.ips } else { @() })
                                      # IPv6 strings contain colons
                                      $ip6s = $ips | Where-Object { $_ -like '*:*' }
                                      $ip6CustomObjects = @()
                                      if ($endpointSet.category -in ("Optimize")) {
                                          $ip6CustomObjects = $ip6s | ForEach-Object {
                                              [PSCustomObject]@{
                                                  category = $endpointSet.category;
                                                  ip = $_;
                                                  tcpPorts = $endpointSet.tcpPorts;
                                                  udpPorts = $endpointSet.udpPorts;
                                              }
                                          }
                                      }
                                      $ip6CustomObjects
                                  }
                              
                                  # write output to screen
                                  Write-Output ("Client Request ID: " + $clientRequestId)
                                  Write-Output ("Last Version: " + $lastVersion)
                                  Write-Output ("New Version: " + $version.latest)
                                  Write-Output ""
                                  Write-Output "IPv4 Firewall IP Address Ranges"
                                  ($flatIp4s.ip | Sort-Object -Unique) -join "," | Out-String
                                  Write-Output "IPv6 Firewall IP Address Ranges"
                                  ($flatIp6s.ip | Sort-Object -Unique) -join "," | Out-String
                                  Write-Output "URLs for Proxy Server"
                                  ($flatUrls.url | Sort-Object -Unique) -join "," | Out-String
                                  Write-Output ("IP and URL data written to " + $datapath)
                              
                                  # write output to data file
                              #    Write-Output "Office 365 IP and UL Web Service data" | Out-File $datapath
                              #    Write-Output "Worldwide instance" | Out-File $datapath -Append
                              #    Write-Output "" | Out-File $datapath -Append
                              #   Write-Output ("Version: " + $version.latest) | Out-File $datapath -Append
                              #    Write-Output "" | Out-File $datapath -Append
                              #    Write-Output "IPv4 Firewall IP Address Ranges" | Out-File $datapath -Append
                                  ($flatIp4s.ip | Sort-Object -Unique) -join "`r`n" | Out-File $datapath -Append
                              #    Write-Output "" | Out-File $datapath -Append
                              #    Write-Output "IPv6 Firewall IP Address Ranges" | Out-File $datapath -Append
                              #    ($flatIp6s.ip | Sort-Object -Unique) -join "," | Out-File $datapath -Append
                                  Write-Output "" | Out-File $datapath -Append
                              #    Write-Output "URLs for Proxy Server" | Out-File $datapath -Append
                              #    ($flatUrls.url | Sort-Object -Unique) -join "," | Out-File $datapath -Append
                              }
                              else {
                                  Write-Host "Office 365 worldwide commercial service instance endpoints are up-to-date."
                              }
                              
                              $file = "C:\Powershell\O365_endpoints_data.txt"
                              # Do not use special characters # . / % & etc. for password!!!
                              $ftpuri = "ftp://username:password@my-ftp-server.com/ms365.txt"
                              $webclient = New-Object System.Net.WebClient
                              $uri = New-Object System.Uri($ftpuri)
                              $webclient.UploadFile($uri, $file)
                              
                              

                              aliase

                              1 Reply Last reply Reply Quote 1
                              • First post
                                Last post
                              Copyright 2025 Rubicon Communications LLC (Netgate). All rights reserved.