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.3k Views 1 Watching
    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.
    • K Offline
      kuberan
      last edited by

      It is in XML format, that is how it is published, which is machine readable…..
      "Use the https://go.microsoft.com/fwlink/?LinkId=533185 to view a single list with all of the endpoints or to automatically process changes."

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

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

        1 Reply Last reply Reply Quote 0
        • K Offline
          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 Offline
            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 Offline
              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 Offline
                kuberan
                last edited by

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

                1 Reply Last reply Reply Quote 0
                • D Offline
                  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 Offline
                    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 Offline
                      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 Offline
                        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 Offline
                          kuberan
                          last edited by

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

                          1 Reply Last reply Reply Quote 0
                          • D Offline
                            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 Offline
                              kuberan
                              last edited by

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

                              1 Reply Last reply Reply Quote 0
                              • T Offline
                                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.