Office 365 PAC File


When we talk about Office 365 services with our customers, a lot of the discussion revolves around the networking components.  While we generally have a "good idea" of networking, we're not experts in your technology and will frequently tell you to go talk to your vendors.  We have some guidance on how to configure your environments, but generally don't provide configuration files or samples that can be used in products that are not our own (understandably).

One area that we typically have a lot of talks on is the proxy environment.  Typically, the security people want all of the organization's egress traffic to flow through a proxy (presumably to categorize site visit frequency and bandwidth consumption patterns).  However, all Office 365 traffic is encrypted, so aside from seeing the request URL, none of the content will be visible.  As such, the proxies will terminate this traffic and then start a new session on the requesting client's behalf (hence, "proxy.")  This works fine for simple HTTP web requests from browsers.  Office applications (such as Outlook) were originally designed for LAN environments and consequently, still sometimes behave like that.  An Outlook client with a few open mailboxes and a GAL query may consume 10 or 15 sessions by itself on the proxy sever; at some point, with enough users doing this, you will exhaust the resources in your proxy environment for no discernable benefit.  Thus, we recommend customers bypass the proxy of Office 365 requests.

Typically, you can configure your proxy server environment (if its an implicit proxy) or configure desktops (if it's explicit) with a PAC file, which contains instructions for handling URLs and IP addresses (such as "go to proxy" or "go direct").  Successfully bypassing your proxy requires two parts:

  1. Configure a bypass list.  Possible options include a proxy automatic configuration file (PAC) or a Group Policy Object that explicitly defines which sites to not send to a proxy server.
  2. Configure an outbound firewall rule to allow access to the appropriate IPs and URLs.

Some modern firewalls include URL filtering, but many in the field do not.  For those customers with more traditional hardware, you will  need to configure those two line items separately.  The sticky wicket is that many administrators don't know how to actually write a proxy PAC file.  A PAC file is a JavaScript construct that tells the browser where to send URL requests.  Once you deploy a Proxy PAC file, you need to keep it up to date (which can be tedious).  I have attempted to kill both of those birds with this script.  You can schedule it and set its output to a network location, and then point a GPO or WPAD discovery to this output.

For more information on how a PAC file works, you can head over to http://en.wikipedia.org/wiki/Proxy_auto-config, which shows the structure of a PAC file and some of the instructions that can be used.  You can also download the PacParser tool from https://github.com/pacparser/pacparser/releases, which you can use to validate this (or any other) PAC file.

pac-2

You can download the full script below over at the TN Gallery.  If you'd like some information on how to distribute the PAC file, please see my other blog post, "Deploying of Office 365 Proxy PAC to Manage Your Users."

Check out https://gallery.technet.microsoft.com/Office-365-Proxy-Pac-60fb28f7 for the latest version of this tool.

Comments (21)

  1. Dennis says:

    When a wildcard “*” is used should the function not be shExpMatch? Example below.

    if (shExpMatch(host, “*.local”))
    return “DIRECT”;

    I do not believe this will work:

    if (dnsDomainIs(host, “*.local”))
    return “DIRECT”;

    Someone correct me if I am wrong.

    1. It’s valid according to PacParser.

      pactester -p testpac.pac -u http://*.local
      PROXY 10.2.2.2; DIRECT

      I’ll check the FindProxyForUrl guidelines to see if I can dig up some more information.

      1. Darren says:

        autoprox,exe (which calls InternetGetProxyInfo inside IE) doesn’t seem to agree with the wildcard matching under dnsDomain like that

        you need to drop the *, so for example dnsDomainIs(host, “.azurerms.com”)
        not dnsDomainIs(host, “*.azurerms.com”)

        1. Darren,

          Can you give me some more information? I ran autoprox and got this result:

          C:\temp>autoprox.exe http://portal.azurerms.com Test_PAC.pac
          The Winsock 2.2 dll was found okay
          url: http://portal.azurerms.com
          autoproxy file path is : c:\temp\Test_PAC.pac
          Calling InternetInitializeAutoProxyDll with c:\temp\Test_PAC.pac
          Calling InternetGetProxyInfo with url http://portal.azurerms.com and host portal.azurerms.com
          Proxy returned for url http://portal.azurerms.com is:
          PROXY 10.0.0.1:8080; DIRECT

          How are you testing?

    2. While PacParser and AutoProxy didn’t return errors for me, I did update the Proxy configuration tool to use shExpMatch. I’ve also added a lot of new features, so check out the new tool!

      https://gallery.technet.microsoft.com/Office-365-Proxy-Pac-60fb28f7

    3. I’ve updated the tool, so you can try again.

  2. Dario says:

    Hi, I am having performance issues with this .pac file. Maybe a .pac file with 300 lines is too large… What do you think?

    1. I have customers with PAC files that are thousands of lines long. What type of problem are you seeing?

      1. Simon Bentley says:

        Hi, we have implemented the .pac file but we are also seeing slow web browsing from browsers using this PAC file. Any ideas?

  3. Johan Parlevliet says:

    There are many duplicates in the output.
    I see 5 times: dnsDomainIs(host, “login.microsoftonline.com”)|| in the proxy.pac
    I see 3 times shExpMatch(host, “*.microsoftonline.com”)|| which makes “login.microsoftonline.com” unnecessary
    etc

    1. It’s because they’re listed as URLs for other services. I don’t filter them out.

  4. Colin says:

    This will only work if you have a DIRECT route from the clients to the Internet gateway. Many large enterprise environments do not have this for security reasons. The other challenge is configuring the IP list on the Firewall as Microsoft are constantly changing the list. As you say, URL filtering would be better but many Firewalls do not support this.

    1. Colin,

      We do recommend direct routes for Office 365 services. You have to think of Office 365 really as an extension of your datacenter. You’re trusting us by putting a large chunk of business-critical infrastructure in our cloud when you migrate to us, so it doesn’t really seem to make sense proxying or firewalling traffic destined for an extranet-type of resource.

      From the proxying perspective, almost everything is over SSL anyway, so unless you’re doing SSL bridging (like some Bluecoat devices can do, which is really amounting a corporate-sponsored MITM) and decrypting the packets going to us, you’re really just adding overhead. And, even if you’re decrypting traffic to Exchange, for example, I’m not certain about what you’re going gain from inspecting it. Exchange Online is receiving specific traffic sets from a purpose-built application to send and receive mail, so it’s unlikely that someone is using Outlook to bypass network filters so they can watch cat videos. 😉

      If you do outbound filtering, we do recommend dynamic URL filtering as opposed to IP filtering.

  5. Karen says:

    Is there something similar that can be used on a user workstation? Recently I updated my laptop. I have McAfee Security Center installed, and some how I can no longer access any site that has file sharing capabilities. I also connected this laptop to azure, so is fully managed via Office 365 Mobile capabilities. Since the updates, I cannot access Office 365 One Drive or SharePoint and I’m running out of items to test. Outlook and Skype for Business work great, and so are all other components (i.e., Word, PowerPoint, Excel, etc.).

    I looked into the firewall policies and even added some rules with the IPs provided, but no luck. Any help would be highly appreciate it. Granted, I could reset the whole computer once more, but I’m just hoping I don’t have to.

  6. David says:

    Hi Aaron – I’ve just been getting to grips with your script in preparation for a migration into a hybrid Office 365 environment.

    I note in the XML file of URLs and IP addresses to whitelist or bypass the proxy, for some of the products the XML lists URLs instead of FQDNs and wildcard domains. Consequently your script now produces lines with text such as this:
    dnsDomainIs(host, “https://www.digicert.com/CACerts/DigiCertGlobalRootCA.crt”), which I suspect is not going to work.

    Should we in practice be producing something like this in those cases:
    shExpMatch(url, “https://www.digicert.com/CACerts/DigiCertGlobalRootCA.crt”)

    I don’t think the problem is your script (which is excellent, BTW) – more likely the content of the XML has changed

    David

    1. David, that’s a good catch. It looks like we just started publishing the CRLs with an actual cert name, and some of the other formatting has changed. There’s a shExpMatch for all of the CRLs and a dnsDomainIs entry for most of them. For example, for DigiCert, it looks like it just generated

      dnsDomainis(host,”http://ocsp.digicert.com”)

      But others like Omniroot have multiple entries:

      shExpMatch(host, “*.omniroot.com”)
      dnsDomainIs(host, “http://ocsp.omniroot.com/baltimoreroot”)

      I’ll take a look at the format of the XML file and see why it’s generating that and then post back.

  7. ISMAIL KHAN says:

    Hi Aaron, If we are using proxy PAC in our environment and we have white listed office365 url’s. This works fine with https & outlook clients as you have mentioned. How this will be supported if we want to use POP3, IMAP & SMTP?

    Server name Port Encryption method
    POP3 Outlook.office365.com 995 TLS
    IMAP4 Outlook.office365.com 993 TLS
    SMTP Smtp.office365.com 587 TLS

    Thanks & Regards
    Ismail khan

    1. I think *.office365.com is already in the bypass list. Just make sure you allow those ports outbound on your firewall.

      1. ISMAIL KHAN says:

        Hi Aaron, Thanks for your reply their are no restriction in firewall for outbound ports. Once the request reach by the client through proxy pac on the proxy server mentioned over 8080 then all ports are open. Just want to know how this will understand by POP3, IMAP & SMTP when we configure getting below error

        Log onto incoming mail server (pop3): Cannot find the email server. Verify the server information in your account properties
        Send test e-mail message: Cannot find the e-mail server. Verify the server information in your account properties

        1. What is the client? And what does the network infrastructure look like? Typically, only browser-based requests will make it to a proxy that is defined explicitly. Policy-based routing can also affect your network path.

          If you have an implicit proxy (where the network path goes through the proxy without interaction from the client), you’ll want to whitelist those URLs on the proxy appliance/solution.

          If you have policy-based routing deployed, you may need to figure out which direction your traffic is going to see if it’s hitting a proxy or other edge device.

          1. ISMAIL KHAN says:

            Hi Aaron, Here is the few details.

            Outlook client version is 2013, Here we use WPAD Proxy Pac, Which is used by Automation Configuration Script. Similar to your screen shot proxy url’s has been white-listed as below. Once the client reach over the proxy then all the ports are open from their. But i am just wondering how POP, IMAP knows to take proxy to reach office365.
            if (dnsDomainIs(host, “.onmicrosoft.com”)
            || dnsDomainIs(host, “.activedirectory.windowsazure.com”)
            || dnsDomainIs(host, “office365servicehealthcommunications.cloudapp.net”)
            || dnsDomainIs(host, “.outlook.com”)
            || dnsDomainIs(host, “.office365.com”)
            || dnsDomainIs(host, “.lync.com”)
            || dnsDomainIs(host, “.sharepoint.com”)
            || dnsDomainIs(host, “.sharepointonline.com”)
            || dnsDomainIs(host, “.powerbi.com”)
            || dnsDomainIs(host, “.onenote.com”)
            )
            return “PROXY internaldomainFQDN:8080”;

            Thanks! for your prompt responses. I just posted in Microsoft community as well but they also redirected you as your one of the expert in Proxy Pac. Just looking for something to achieve this. Even we have logged premiere case with Microsoft team.

Skip to main content