はじめに
この記事では、Microsoft Global Secure Access (GSA) プライベートアクセス と 社内のプロキシサービスを併用する場合に必要な PAC ファイル の構成を検討した結果を紹介しています。
ローカルブレイクアウトとは?
「社内ネットワークを経由せず、端末から直接インターネットに出す仕組み」のことです。
- すべての通信を本社のプロキシ/FW に集約すると 負荷が集中するので分散したい
- ローカルブレイクアウトは 端末の近く(支店・拠点・自宅)から直接クラウドへ接続させるルート
- 信頼できる Microsoft 365 や Teams のようなクラウドサービスだけを分散し、負荷・遅延を減らすことが目的
ポイント
理想的なローカルブレイクアウトを実現するためには、柔軟な制御が可能な PAC ファイルを 活用する必要があります。
プロキシ設定方式 の構成方法
2か月前 (2025/11/2) に、以下の記事を投稿しているのですが、あちらは PAC を使わずに シンプルな プロキシ設定 を使っており、ローカルブレイクアウトは必要最小限で、社内プロキシを全面的に使っていく設定になっています。
[GSA] グローバルセキュアアクセスクライアント用のプロキシ除外設定
https://qiita.com/carol0226/items/df821a681986b1020ab3
2種類の設定箇所の違い
いずれも、インターネットオプション の ローカルエリアネットワーク (LAN) の設定配下にあります。
「PAC ファイル方式」と「プロキシ設定方式」の違い
PAC ファイルは スクリプトを書く必要があり、難易度が高い反面 非常に柔軟な制御が可能です。
プロキシ設定は 設定欄に決まった値を記入するだけなので、難易度は低い反面 基本的な制御しかできません。
本記事では、PAC ファイルの柔軟性を活かして、Microsoft サービスの通信を 無理のない範囲で DIRECT にする(プロキシをなるべく使わない)構成を目指しています。
結果的に 両者の違いは、下記のイメージ図で、緑色 の Microsoft 365 の通信がローカルブレイクアウトの対象になっているかどうか・・が違います。
比較表(ユーザー権限で動作する WinINET プロキシの動作)
| 設定方法 ▶ ▼ 制御対象 |
PAC ファイル (本記事の内容) |
プロキシ設定 |
|---|---|---|
| 難易度 | 高 | 低 |
| GSA | Direct | Direct |
| Entra 認証 | Direct | Direct |
| Microsoft 365 サービス |
おおむね : Direct 一部 : Proxy |
Proxy |
| その他の インターネット 通信 |
Proxy | Proxy |
| 参考:システム権限 WinHTTP プロキシ |
Direct | Direct |
WinHTTP プロキシについて
システム権限で動作する WinHTTP プロキシ は、別プロセスで動作しています。
netsh winhttp show proxy を実行した結果が現在の設定値です。

Intune / Microsoft Defender for Endpoint / Windows Update などのバックグラウンド処理は、システム権限で動作しているため、プロキシは使われていない点を認識しておくと良いと思います。
GSA プライベートアクセス利用時の注意点
GSA のプライベートアクセスは、WinHTTP プロキシは非サポートです。
仮に、プライベートアドレスのプロキシ設定があったとしても、疎通できず 利用することができません。WinHTTP は 直接アクセス (Direct) のままで運用してください。
WinINET と WinHTTP の違いは、以下も参考にしてみてください。
Support Blog:IE からみるプロキシの設定について
https://microsoft.github.io/jpbrowsers/internet-explorer-microsoft-edge/ProxySettings/
本記事が目指すところ
ローカルブレイクアウトを実現する手段として、PAC ファイルを活用することは、多くの賛同を得られると思っています。
しかし、どの URL を対象とすべきかは 賛否両論で 意見の分かれる部分となります。
企業ポリシー/トラフィック量/アクセス制御/運用負荷/対象とする製品 などによって制御すべき URL が異なってきます。
初めに断っておきますが、本記事では、プロキシを止めてしまうと、Microsoft 365 サービス が完全には動作しません。
あくまで、運用管理を楽にしつつ、主要なトラフィックの大半を プロキシから逃がすことでの負荷軽減を狙った設定を目指しています。
参考:私が用意した PAC ファイルの自己評価(5点満点)
トラフィック削減:★★★★
アクセス制御 :★★★
管理の負荷軽減 :★★★★★
対象製品の範囲 :★★★★★
処理の高速性 :★★★★
プロキシ無しで Microsoft 365 サービス を完全動作させる PAC を作りたい人は本記事の設定をもとに、さらなるカスタマイズを施してください。これを目指した場合、管理の負荷が増大する可能性が高いです。
本構成の PAC ファイルを利用するために必要なこと
PAC ファイルを使うためには、以下の技術要件を満たしている必要があります。
そのため、全体を構成するには、手間・時間・スキル が必要で難易度が高くなっていますが、幸い ①~④ のすべてを私の記事でカバーしています。うまく組み合わせて、このハードルを乗り越えてみてください!
① PAC ファイル内のスクリプトを記述する知見が必要
本記事の PAC ファイルを流用することで難易度は下がっていると思います。
② PAC ファイルは Web サーバー上に配置する必要がある
以下の記事を参考にしてみてください。これでクリアできると思います。
プロキシ自動構成ファイル(PAC ファイル)の配置場所を作成する
https://qiita.com/carol0226/items/ed3c69f40ad659ff3b58
③ プロキシサーバーを配置する
以下の私の記事のうち、「PROXYアプリ の導入」と「Windows Firewall の設定」の章が参考になると思います。今回の PAC の検証時も BlackJumboDog を使っています。
Azure で Hyper-V on VM を動作させる
https://qiita.com/carol0226/items/b5ca1ec882742e208e00
④ GSA プライベートアクセス
以下の私の記事を参考に GSA プライベートアクセス を使って オンプレス環境へリモート接続できる環境を構築してください。
Microsoft Entra Global Secure Access の全体像
https://qiita.com/carol0226/items/29cba6c32a22893a1349
GSA x Microsoft 365 の PAC ベストプラクティス
以下のポイントを踏まえて PAC ファイルを作成しました。これを章ごとに解説を記載しています。
- PAC ファイルは必ず DIRECT で取得させる
- PAC の評価順序は“上から順”なので例外は前に書く
- DNS 依存のロジックは負荷がかかるため、高速性を意識して後半に書く
- Microsoft 365 は 管理が容易な Get-PacFile から生成
- GSA の FQDN は DIRECT が基本
最終的な PAC ファイル(コピペ可)
コピペ利用の際は、以下の項目だけは 環境に合わせてカスタマイズしてください。
コピペ可能な PAC ファイルの参照は、【ココ】 を押してください
function FindProxyForURL(url, host)
{
var direct = "DIRECT";
var proxyServer = "PROXY 10.10.10.6:8080";
// ===== 0) PAC ファイルのダウンロード先(DIRECT) =====
if (shExpMatch(host, "officeiis.japaneast.cloudapp.azure.com")) { return direct; }
// ===== 1) ホスト名がローカル(ピリオドなし)(DIRECT) =====
if (isPlainHostName(host)) {
return direct;
}
// ===== 2) オンプレミス企業ドメイン(DIRECT) =====
if (dnsDomainIs(host, ".avd.server-on.net")
|| shExpMatch(host, "avd.server-on.net")) {
return direct;
}
// ===== 3) 任意カスタマイズ用(DIRECT) =====
if (dnsDomainIs(host, ".qiita.com")
|| shExpMatch(host, "qiita.com")) { return direct; }
if (dnsDomainIs(host, ".msn.com")
|| shExpMatch(host, "msn.com")) { return direct; }
if (dnsDomainIs(host, ".bing.com")
|| shExpMatch(host, "bing.com")) { return direct; }
if (dnsDomainIs(host, ".google.com")
|| shExpMatch(host, "google.com")) { return proxyServer; }
// ===== 4) M365 ローカルブレイクアウト(DIRECT) =====
// Microsoft 365 統合ドメイン
if (dnsDomainIs(host, ".cloud.microsoft")
|| shExpMatch(host, "cloud.microsoft")) { return direct; }
if (dnsDomainIs(host, ".static.microsoft")
|| shExpMatch(host, "static.microsoft")) { return direct; }
if (dnsDomainIs(host, ".usercontent.microsoft")
|| shExpMatch(host, "usercontent.microsoft")) { return direct; }
// Get-PacFile にて取得
if (shExpMatch(host, "cdn.odc.officeapps.live.com")
|| shExpMatch(host, "cdn.uci.officeapps.live.com"))
{
return direct;
}
if (shExpMatch(host, "*.auth.microsoft.com")
|| shExpMatch(host, "*.lync.com")
|| shExpMatch(host, "*.mail.protection.outlook.com")
|| shExpMatch(host, "*.msftidentity.com")
|| shExpMatch(host, "*.msidentity.com")
|| shExpMatch(host, "*.mx.microsoft")
|| shExpMatch(host, "*.officeapps.live.com")
|| shExpMatch(host, "*.online.office.com")
|| shExpMatch(host, "*.protection.office.com")
|| shExpMatch(host, "*.protection.outlook.com")
|| shExpMatch(host, "*.security.microsoft.com")
|| shExpMatch(host, "*.sharepoint.com")
|| shExpMatch(host, "*.teams.cloud.microsoft")
|| shExpMatch(host, "*.teams.microsoft.com")
|| shExpMatch(host, "account.activedirectory.windowsazure.com")
|| shExpMatch(host, "accounts.accesscontrol.windows.net")
|| shExpMatch(host, "adminwebservice.microsoftonline.com")
|| shExpMatch(host, "api.passwordreset.microsoftonline.com")
|| shExpMatch(host, "autologon.microsoftazuread-sso.com")
|| shExpMatch(host, "becws.microsoftonline.com")
|| shExpMatch(host, "ccs.login.microsoftonline.com")
|| shExpMatch(host, "clientconfig.microsoftonline-p.net")
|| shExpMatch(host, "companymanager.microsoftonline.com")
|| shExpMatch(host, "compliance.microsoft.com")
|| shExpMatch(host, "defender.microsoft.com")
|| shExpMatch(host, "device.login.microsoftonline.com")
|| shExpMatch(host, "graph.microsoft.com")
|| shExpMatch(host, "graph.windows.net")
|| shExpMatch(host, "login.microsoft.com")
|| shExpMatch(host, "login.microsoftonline.com")
|| shExpMatch(host, "login.microsoftonline-p.com")
|| shExpMatch(host, "login.windows.net")
|| shExpMatch(host, "logincert.microsoftonline.com")
|| shExpMatch(host, "loginex.microsoftonline.com")
|| shExpMatch(host, "login-us.microsoftonline.com")
|| shExpMatch(host, "nexus.microsoftonline-p.com")
|| shExpMatch(host, "office.live.com")
|| shExpMatch(host, "outlook.cloud.microsoft")
|| shExpMatch(host, "outlook.office.com")
|| shExpMatch(host, "outlook.office365.com")
|| shExpMatch(host, "passwordreset.microsoftonline.com")
|| shExpMatch(host, "protection.office.com")
|| shExpMatch(host, "provisioningapi.microsoftonline.com")
|| shExpMatch(host, "purview.microsoft.com")
|| shExpMatch(host, "security.microsoft.com")
|| shExpMatch(host, "smtp.office365.com")
|| shExpMatch(host, "teams.cloud.microsoft")
|| shExpMatch(host, "teams.microsoft.com"))
{
return direct;
}
// ===== 5) GSA クライアント接続用 host(DIRECT) =====
if (dnsDomainIs(host, ".globalsecureaccess.microsoft.com")
|| shExpMatch(host, "globalsecureaccess.microsoft.com")) { return direct; }
if (dnsDomainIs(host, ".onmicrosoft.com")
|| shExpMatch(host, "onmicrosoft.com")) { return direct; }
if (dnsDomainIs(host, ".outlook.com")
|| shExpMatch(host, "outlook.com")) { return direct; }
if (dnsDomainIs(host, ".sharepointonline.com")
|| shExpMatch(host, "sharepointonline.com")) { return direct; }
if (dnsDomainIs(host, ".svc.ms")
|| shExpMatch(host, "svc.ms")) { return direct; }
if (dnsDomainIs(host, ".wns.windows.com")
|| shExpMatch(host, "wns.windows.com")) { return direct; }
if (shExpMatch(host, "admin.onedrive.com")) { return direct; }
if (shExpMatch(host, "g.live.com")) { return direct; }
if (shExpMatch(host, "officeclient.microsoft.com")) { return direct; }
if (shExpMatch(host, "oneclient.sfx.ms")) { return direct; }
if (shExpMatch(host, "spoprod-a.akamaihd.net")) { return direct; }
// ===== 6) プライベート IP アドレス帯を DIRECT にする(DIRECT) =====
var ip = dnsResolve(host);
if (ip != null) {
if (isInNet(ip, "10.0.0.0", "255.0.0.0") ||
isInNet(ip, "172.16.0.0", "255.240.0.0") ||
isInNet(ip, "192.168.0.0", "255.255.0.0")) {
return direct;
}
}
// ===== 7) GSA クライアント接続用 ip(DIRECT) =====
if (ip != null) {
if (isInNet(ip, "150.171.19.0", "255.255.255.0")) { return direct; }
if (isInNet(ip, "150.171.20.0", "255.255.255.0")) { return direct; }
if (isInNet(ip, "13.107.232.0", "255.255.255.0")) { return direct; }
if (isInNet(ip, "13.107.233.0", "255.255.255.0")) { return direct; }
if (isInNet(ip, "150.171.15.0", "255.255.255.0")) { return direct; }
if (isInNet(ip, "150.171.18.0", "255.255.255.0")) { return direct; }
if (isInNet(ip, "151.206.0.0", "255.255.0.0")) { return direct; }
if (isInNet(ip, "6.6.0.0", "255.255.0.0")) { return proxyServer; }
}
// ===== 8) GSA 未使用時(PROXY) =====
if (shExpMatch(host, "*.cman.jp")) { return direct; }
return proxyServer;
}
| 設定項目 | 元の値 | カスタマイズ内容 |
|---|---|---|
| var proxyServer | "PROXY 10.10.10.6:8080" | 利用するプロキシサーバーアドレス |
| 0) PAC ファイルの ダウンロード先 |
officeiis.japaneast.cloudapp.azure.com | PAC ファイルの置き場所 |
| 2) オンプレミス 企業ドメイン |
.avd.server-on.net | 利用しているドメイン名 |
| 3) 任意カスタマイズ用 | .qiita.com .msn.com .bing.com .google.com |
個別に Direct / Proxy を制御したいサイト |
| 9) その他:GSA 未使用時 | return proxyServer; | PAC の設定に引っかからなかったサイトを Proxy にするか Direct にするかどうかを決めてください。左記の設定だと PROXY になります。 |
注意事項
カスタマイズを行った際は、つまらないミスをしないようにしてください。
カッコ ( ) や { } の閉じ忘れや、過剰な閉じる があるだけでも、スクリプト全体がエラーになって機能しません。微細な修正をする際にも、必ず 全体のテストを怠らないようにしましょう。
章ごとの解説
0)PAC ファイルのダウンロード先 → DIRECT
1)ホスト名がローカル(ピリオドなし)→ DIRECT
2)オンプレミス企業ドメイン → DIRECT
3)任意カスタマイズ用 → DIRECT or PROXY
4)M365 ローカルブレイクアウト → DIRECT
5)GSA クライアント接続用 FQDN → DIRECT
6)プライベート IP アドレス帯 → DIRECT
7)GSA クライアント接続用 IP → DIRECT
8)その他:GSA 未使用時 → DIRECT or PROXY
0) PAC ファイルのダウンロード先(DIRECT)
if (shExpMatch(host, "officeiis.japaneast.cloudapp.azure.com")) { return direct; }
PAC ファイルを 以下の私の記事のとおり、Azure VM 上に配置した場合の対策です。
上記の URL を、PAC ファイルを保存したサイトの URL に修正してください。
プロキシ自動構成ファイル(PAC ファイル)の配置場所を作成する
https://qiita.com/carol0226/private/ed3c69f40ad659ff3b58
この設定が無い場合、鶏と卵 状態となってループして、PAC ファイルを読み込めなくなります。
PAC ファイルの置き場所は、プロキシを必要とせずに、直接取得できるように構成しています。
shExpMatch の使い方は 以下の公開情報を参照してください。
公開情報:Use proxy auto-configuration (.pac) files with IEAK 11:shExpMatch
https://learn.microsoft.com/ja-jp/previous-versions/windows/internet-explorer/ie-it-pro/internet-explorer-11/ie11-ieak/proxy-auto-config-examples?wt.mc_id=MVP_407731#example-5-determine-the-connection-type-based-on-the-host-domain
1) ホスト名がローカル(ピリオドなし)(DIRECT)
if (isPlainHostName(host)) { return direct;}
FQDN (host.domain.com) ではなく ホスト名のみ (host) の場合は、社内のホストへの通信だと断定できるため、この時点で プロキシを使用しないように制御しています。
この設定を入れない場合でも、「13) プライベート IP アドレス帯を DIRECT にする」の処理で プライベート判定はされるのですが、13) に到達するまで時間が掛かりますし、13) は DNS 参照が必要なため 処理に負荷がかかります。処理高速化のために あえてここで ホスト名のみの分岐を判断させて 処理を高速化しています。
※isPlainHostName は、DNS を参照せず 文字列 にて判断している分 高速となります。
isPlainHostName の使い方は 以下の公開情報を参照してください。
公開情報:Use proxy auto-configuration (.pac) files with IEAK 11:isPlainHostName
https://learn.microsoft.com/ja-jp/previous-versions/windows/internet-explorer/ie-it-pro/internet-explorer-11/ie11-ieak/proxy-auto-config-examples?wt.mc_id=MVP_407731#example-1-connect-directly-if-the-host-is-local
2) オンプレミス企業ドメイン(DIRECT)
if (dnsDomainIs(host, ".avd.server-on.net")
|| shExpMatch(host, "avd.server-on.net")) {
return direct;
}
AD ドメイン名(host.domain.com)が使用された場合は、プロキシを使用しないように制御しています。理由は、1) ホスト名がローカル と同様に 高速化 のためです。
dnsDomainIs は、サブドメインを評価するために使っています。
".domain.com" で終わる名前 つまり、x.domain.com , y.x.domain.com , z.y.x.domain.com が評価されますが、"domain.com" は評価されません。
"domain.com" も評価対象にするために、shExpMatch を使って or (||) で評価させています。
dnsDomainIs の使い方は 以下の公開情報を参照してください。
公開情報:Use proxy auto-configuration (.pac) files with IEAK 11:dnsDomainIs
https://learn.microsoft.com/ja-jp/previous-versions/windows/internet-explorer/ie-it-pro/internet-explorer-11/ie11-ieak/proxy-auto-config-examples?wt.mc_id=MVP_407731#example-2-connect-directly-if-the-host-is-inside-the-firewall
上記の公開情報の例で、以下の記載があります。
私は採用しませんでしたが、以下の意味は、.company.com で終わる名前を DIRECT にしていますが、例外として www.company.com_と home.company.com は社外の Web サイトなので PROXY を経由させたい・・という場合の事例になっているようです。つまり 社内ドメインと 外部公開のドメイン名が同一の場合は、この例を活用して制御してあげる必要があるという事です。
※localHostOrDomainIs の前に ! があるので否定形 になっています。
if ((isPlainHostName(host) ||
dnsDomainIs(host, ".company.com")) &&
!localHostOrDomainIs(host, "www.company.com") &&
!localHostOrDoaminIs(host, "home.company.com"))
return "DIRECT";
else
return "PROXY proxy:80";
3) 任意カスタマイズ用(DIRECT / PROXY)
if (dnsDomainIs(host, ".qiita.com")
|| shExpMatch(host, "qiita.com")) { return direct; }
if (dnsDomainIs(host, ".msn.com")
|| shExpMatch(host, "msn.com")) { return direct; }
if (dnsDomainIs(host, ".bing.com")
|| shExpMatch(host, "bing.com")) { return direct; }
if (dnsDomainIs(host, ".google.com")
|| shExpMatch(host, "google.com")) { return proxyServer; }
任意の URL を設定するための場所を用意しておきました。
Google を Proxy 経由、 Qiita と MSN、Bing を Direct となる設定例にしてあります。
これを元に、カスタマイズしてください。
ポイント
google.com は、サブドメインの動作を確認しやすいので 用意しておきました。
map.google.com や mail.google.com、news.google.com など。
yahoo.co.jp のサイトは、このドメインを許可しただけでは サイトを表示できません。
追加で、yimg.jp というドメインも許可する必要があります。
このように、見た目の URL だけでは表示できないサイトもあることを認識しておきましょう。
4) M365 ローカルブレイクアウト(DIRECT)
// Microsoft 365 統合ドメイン
if (dnsDomainIs(host, ".cloud.microsoft")
|| shExpMatch(host, "cloud.microsoft")) { return proxyServer; }
if (dnsDomainIs(host, ".static.microsoft")
|| shExpMatch(host, "static.microsoft")) { return direct; }
if (dnsDomainIs(host, ".usercontent.microsoft")
|| shExpMatch(host, "usercontent.microsoft")) { return direct; }
// Get-PacFile にて取得
if (shExpMatch(host, "cdn.odc.officeapps.live.com")
|| shExpMatch(host, "cdn.uci.officeapps.live.com"))
{
return direct;
}
if (shExpMatch(host, "*.auth.microsoft.com")
|| shExpMatch(host, "*.lync.com")
|| shExpMatch(host, "*.mail.protection.outlook.com")
|| shExpMatch(host, "*.msftidentity.com")
|| shExpMatch(host, "*.msidentity.com")
|| shExpMatch(host, "*.mx.microsoft")
|| shExpMatch(host, "*.officeapps.live.com")
|| shExpMatch(host, "*.online.office.com")
|| shExpMatch(host, "*.protection.office.com")
|| shExpMatch(host, "*.protection.outlook.com")
|| shExpMatch(host, "*.security.microsoft.com")
|| shExpMatch(host, "*.sharepoint.com")
|| shExpMatch(host, "*.teams.cloud.microsoft")
|| shExpMatch(host, "*.teams.microsoft.com")
|| shExpMatch(host, "account.activedirectory.windowsazure.com")
|| shExpMatch(host, "accounts.accesscontrol.windows.net")
|| shExpMatch(host, "adminwebservice.microsoftonline.com")
|| shExpMatch(host, "api.passwordreset.microsoftonline.com")
|| shExpMatch(host, "autologon.microsoftazuread-sso.com")
|| shExpMatch(host, "becws.microsoftonline.com")
|| shExpMatch(host, "ccs.login.microsoftonline.com")
|| shExpMatch(host, "clientconfig.microsoftonline-p.net")
|| shExpMatch(host, "companymanager.microsoftonline.com")
|| shExpMatch(host, "compliance.microsoft.com")
|| shExpMatch(host, "defender.microsoft.com")
|| shExpMatch(host, "device.login.microsoftonline.com")
|| shExpMatch(host, "graph.microsoft.com")
|| shExpMatch(host, "graph.windows.net")
|| shExpMatch(host, "login.microsoft.com")
|| shExpMatch(host, "login.microsoftonline.com")
|| shExpMatch(host, "login.microsoftonline-p.com")
|| shExpMatch(host, "login.windows.net")
|| shExpMatch(host, "logincert.microsoftonline.com")
|| shExpMatch(host, "loginex.microsoftonline.com")
|| shExpMatch(host, "login-us.microsoftonline.com")
|| shExpMatch(host, "nexus.microsoftonline-p.com")
|| shExpMatch(host, "office.live.com")
|| shExpMatch(host, "outlook.cloud.microsoft")
|| shExpMatch(host, "outlook.office.com")
|| shExpMatch(host, "outlook.office365.com")
|| shExpMatch(host, "passwordreset.microsoftonline.com")
|| shExpMatch(host, "protection.office.com")
|| shExpMatch(host, "provisioningapi.microsoftonline.com")
|| shExpMatch(host, "purview.microsoft.com")
|| shExpMatch(host, "security.microsoft.com")
|| shExpMatch(host, "smtp.office365.com")
|| shExpMatch(host, "teams.cloud.microsoft")
|| shExpMatch(host, "teams.microsoft.com"))
{
return direct;
}
Microsoft 365 の用のセクションは、今後のメンテナンスを考慮した構成にしてあります。
"// Microsoft 365 統合ドメイン" と "// Get-PacFile にて取得" のセクションに分けてあります。
Microsoft 365 統合ドメイン
Microsoft 365 統合ドメイン は、今後 FQDN の管理が簡単になるように Microsoft 側で用意してくれたものであり、今後は この FQDN のみを管理していけば良い形になっていきます。
しかしながら、現時点では すべてのサイトが移行されておらず、まだ 数年は Get-PacFile との共存が必要になるものと思われます。
公開情報:Microsoft 365 統合ドメイン
https://learn.microsoft.com/ja-jp/microsoft-365/enterprise/urls-and-ip-address-ranges?view=o365-worldwide&wt.mc_id=MVP_407731#microsoft-365-unified-domains
Get-PacFile
Microsoft 365 向けの FQDN が頻繁に更新されるため、これを維持するのは大変です。
このメンテナンスが楽になる方法を考案しました。
公開情報の最終更新日を確認しつつ、更新があった際には Get-PacFile を使ってスクリプトを取得してください。これを 後述する手順どおりに コピペ するだけでメンテナンスが完了します。
公開情報:Microsoft 365 の URL と IP アドレスの範囲
https://learn.microsoft.com/ja-jp/microsoft-365/enterprise/urls-and-ip-address-ranges?wt.mc_id=MVP_407731
Microsoft 365 URL の更新頻度や メンテナンスする重要性は、以下の公開情報で説明されています。
公開情報:Microsoft 365 の IP アドレスと URL の変更管理
https://learn.microsoft.com/ja-jp/microsoft-365/enterprise/managing-office-365-endpoints?view=o365-worldwide&wt.mc_id=MVP_407731#change-management-for-microsoft-365-ip-addresses-and-urls
Get-PacFile は、多岐にわたる FQDN を自動的に PAC ファイル化してくれるツールです。以下の公開情報に説明が記載されてます。
公開情報:重要な Microsoft 365 トラフィックの直接ルーティングに PAC ファイルを使用する
https://learn.microsoft.com/ja-jp/microsoft-365/enterprise/managing-office-365-endpoints?wt.mc_id=MVP_407731#use-a-pac-file-for-direct-routing-of-vital-microsoft-365-traffic
Get-PacFile は、以下のサイトからダウンロードして利用することができます。
GitHub:Get-PacFile
https://www.powershellgallery.com/packages/Get-PacFile/1.0.4
Get-PacFile 実行手順
1.以下のキャプチャを参考に、インストールを行います(初回のみ)

2.以下のパラメーターで、GetPacfile.ps1 を実行します。
.\GetPacfile.ps1 -ClientRequestId $guid -type 2 -DefaultProxySettings "PROXY xxx.xxx.xxx.xxx:8080"
3.以下のキャプチャが実行結果です。画像の 緑の場所をコピーして // Get-PacFile にて取得 のセクションに貼り付けます。

上記の 緑の枠内のうち 赤下線 の return proxyServer の箇所は、私のオリジナルな判断で direct に変更していますので、貼り付けた後に この箇所だけ編集してください。
5) GSA クライアント接続用 FQDN(DIRECT)
if (dnsDomainIs(host, ".globalsecureaccess.microsoft.com")
|| shExpMatch(host, "globalsecureaccess.microsoft.com")) { return direct; }
if (dnsDomainIs(host, ".onmicrosoft.com")
|| shExpMatch(host, "onmicrosoft.com")) { return direct; }
if (dnsDomainIs(host, ".outlook.com")
|| shExpMatch(host, "outlook.com")) { return direct; }
if (dnsDomainIs(host, ".sharepointonline.com")
|| shExpMatch(host, "sharepointonline.com")) { return direct; }
if (dnsDomainIs(host, ".svc.ms")
|| shExpMatch(host, "svc.ms")) { return direct; }
if (dnsDomainIs(host, ".wns.windows.com")
|| shExpMatch(host, "wns.windows.com")) { return direct; }
if (shExpMatch(host, "admin.onedrive.com")) { return direct; }
if (shExpMatch(host, "g.live.com")) { return direct; }
if (shExpMatch(host, "officeclient.microsoft.com")) { return direct; }
if (shExpMatch(host, "oneclient.sfx.ms")) { return direct; }
if (shExpMatch(host, "spoprod-a.akamaihd.net")) { return direct; }
通常は、社外から GSA に接続する場合、プロキシが有効になっていると接続できません。
この設定によって、デバイスが 社内・社外 のいずれにある状態でも、GSA への接続ができるようにしています。
該当の FQDN を選定した理由(なぜ この FQDN なのか?)は、以下の私の記事を参照してください。
[GSA] グローバルセキュアアクセスクライアント用のプロキシ除外設定
https://qiita.com/carol0226/items/df821a681986b1020ab3
公開情報:Global Secure Access サービスでトラフィックを受信する FQDN と IP アドレス
https://learn.microsoft.com/ja-jp/entra/global-secure-access/reference-points-of-presence?wt.mc_id=MVP_407731#fqdn-and-ip-addresses-where-the-global-secure-access-service-receives-traffic
6) プライベート IP アドレス帯を DIRECT にする(DIRECT)
var ip = dnsResolve(host);
if (ip != null) {
if (isInNet(ip, "10.0.0.0", "255.0.0.0") ||
isInNet(ip, "172.16.0.0", "255.240.0.0") ||
isInNet(ip, "192.168.0.0", "255.255.0.0")) {
return direct;
}
}
名前解決された宛先が、プライベートアドレス帯 だった場合は、プロキシを使用しないようにしています。
IP アドレスが直接指定された場合も、この設定でカバーされ プロキシは使用されません。
公開情報:Use proxy auto-configuration (.pac) files with IEAK 11:isInNet
https://learn.microsoft.com/ja-jp/previous-versions/windows/internet-explorer/ie-it-pro/internet-explorer-11/ie11-ieak/proxy-auto-config-examples?wt.mc_id=MVP_407731#example-4-connect-directly-if-the-host-is-in-specified-subnet
7) GSA クライアント接続用 IP(DIRECT)
if (ip != null) {
if (isInNet(ip, "150.171.19.0", "255.255.255.0")) { return direct; }
if (isInNet(ip, "150.171.20.0", "255.255.255.0")) { return direct; }
if (isInNet(ip, "13.107.232.0", "255.255.255.0")) { return direct; }
if (isInNet(ip, "13.107.233.0", "255.255.255.0")) { return direct; }
if (isInNet(ip, "150.171.15.0", "255.255.255.0")) { return direct; }
if (isInNet(ip, "150.171.18.0", "255.255.255.0")) { return direct; }
if (isInNet(ip, "151.206.0.0", "255.255.0.0")) { return direct; }
以下の設定が GSA でプロキシを使う場合の最重要項目です。
if (isInNet(ip, "6.6.0.0", "255.255.0.0")) { return proxyServer; }
}
GSA では、社内の宛先、社外の宛先 のいずれも、 6.6.0.0/16 の IPアドレスが返されます。
この仕様が 今回 この PAC ファイルを設計する上で十分に考慮する必要があります。
6.6.0.0/16 課題の解決策
この条件分岐を すべての社内アクセスの判断後に配置することで解決を図ることにしました。
既に、前章までの設定で評価された FQDN は、プロキシを使用せず ダイレクト通信で処理されています。
つまり、この時点でアクセスされた 6.6.0.0/16 のアドレスは、社外のアドレス であると判断できるため、プロキシサーバーを利用するように制御しています。
下図のとおり、社外のアドレスに対して 6.6.. のアドレスが返されていることが判ります。
8) その他:GSA 未使用時(PROXY / DIRECT)
if (dnsDomainIs(host, ".cman.jp")) { return direct; }
return proxyServer;
}
下図の通り、GSA が利用されていない場合は、cman.jp サイトの グローバル IP アドレス が返されています。この場合は、7) GSA クライアント接続用 IP に引っかからずに、8) まで流れてきます。
ポイント
cman.jp のサイトは、現在の ソース IP が何であるのかを確認することが出来るサイトです。
PCが GSA が無効な場合と、GSA が有効な場合とで、ソース IP が異なるため、cman.jp の結果を見て切り替わったのかどうかを確認しやすくしてみました。
【CMAN:IP アドレス確認サイト】
https://www.cman.jp/network/support/go_access.cgi
→ GSA と プロキシが利用されている場合は、プロキシサーバーの パブリック IP アドレス が返されます。
→ GSA が 無効な場合は、自宅 や Wi-Fi ルーターなどがもつ パブリック IP アドレス が返されます。
この段階まで処理されていない宛先は、プロキシを使用すべき インターネット宛の通信であると断定できます。
社内 LAN に接続している場合の インターネット宛の通信を想定し、プロキシを使用するように構成しています。
※なお、社内LAN に接続せず、GSA も接続していない場合は、プロキシにアクセスできないため、インターネット上のサイトにはアクセスできません(不正利用させないために、このような構成にしています)
別の設定
最後の return proxyServer; を return direct; に変更すると、GSA 未接続時は direct 接続になり、GSA 接続時は PROXY 経由の接続になります。この制御も なかなか良いのではないかと思います。要件によって いずれかを選択して運用してみてください。
まとめ
今回の PAC ファイルは、単に「動く PAC」を作るだけではなく、なぜその条件が必要なのか、どのような背景があるのかという “理由” を丁寧に整理しながら形にしていきました。
Microsoft 365 のエンドポイントは年々増え続け、GSA の登場によってネットワーク設計はさらに複雑になりました。
その中で、運用者が迷わず判断できるように、「必要なものだけを残し、不要なものは削る」という姿勢を徹底したのが今回の PAC ファイルです。
また、Microsoft 365 の統合ドメインを採用したことで、今後の PAC ファイル の保守性向上に寄与できたのではないかと感じています。




