プロキシ自動設定(PAC)ファイルを S3 バケットに格納して Mac から参照してみた

PAC を Mac に。

コンバンハ、千葉(幸)です。

プロキシを設定する際に、PAC(Proxy Auto-Configuration)ファイルを使用することがあるかと思います。

PAC ファイルの配布のために専用の Web サーバーを使用しているケースにおいて、当該サーバを S3 バケットに置き換えたいという要件があり、実現可能なものか検証してみました。

先にまとめ

  • S3 においた PAC ファイルは http/https 経由で問題なく参照できる
  • オブジェクトのアクセス権を考慮する必要あり
  • メタデータは特に考慮する必要なし

PAC とは

クライアントが参照することで自動的にプロキシ設定を行ってくれるファイルです。 JavaScript の関数で、参照先のプロキシサーバの情報を定義しておきます。接続先ホストやクライアントによって、プロキシサーバを振り分けたり、直接アクセスを許可するといった条件設定も可能です。

クライアントから PAC ファイルを http (もしくは https )で参照することで、自動的にその構成が適用されます。

Macだと「プロキシ構成ファイル」という項目で指定することになるものです。

Proxy

PAC ファイルの詳細については以下を参照してください。

やってみた

今回検証を行う構成は以下のとおりです。

  • S3 に PAC ファイルを配置
  • PAC ファイルでは以下を定義
    • 接続先が*.amazonaws.comの場合は直接アクセスする
    • それ以外の場合はプロキシサーバを経由する
  • 当該 PAC ファイルを適用したクライアントから以下にアクセスし、送信元グローバル IP を確認

「 S3 に格納した PAC ファイルを参照できるか」が今回の検証の意図のため、構成にはあまり意味はありません。

プロキシサーバの構築

今回は squid を使用します。

パブリックサブネットに構築した Amazon Linux2 のインスタンスで、以下を実行します。

sudo yum install squid -y
sudo systemctl enable squid
sudo systemctl start squid

インストール時のログは以下です。

折り畳み
sh-4.2$ sudo yum install squid -y
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
Resolving Dependencies
--> Running transaction check
---> Package squid.x86_64 7:3.5.20-17.amzn2.4.1 will be installed
--> Processing Dependency: squid-migration-script for package: 7:squid-3.5.20-17.amzn2.4.1.x86_64
--> Processing Dependency: perl(Digest::MD5) for package: 7:squid-3.5.20-17.amzn2.4.1.x86_64
--> Processing Dependency: perl(Data::Dumper) for package: 7:squid-3.5.20-17.amzn2.4.1.x86_64
--> Processing Dependency: perl(DBI) for package: 7:squid-3.5.20-17.amzn2.4.1.x86_64
--> Processing Dependency: libltdl.so.7()(64bit) for package: 7:squid-3.5.20-17.amzn2.4.1.x86_64
--> Processing Dependency: libecap.so.3()(64bit) for package: 7:squid-3.5.20-17.amzn2.4.1.x86_64
--> Running transaction check
---> Package libecap.x86_64 0:1.0.0-1.amzn2.0.2 will be installed
---> Package libtool-ltdl.x86_64 0:2.4.2-22.2.amzn2.0.2 will be installed
---> Package perl-DBI.x86_64 0:1.627-4.amzn2.0.2 will be installed
--> Processing Dependency: perl(RPC::PlServer) >= 0.2001 for package: perl-DBI-1.627-4.amzn2.0.2.x86_64
--> Processing Dependency: perl(RPC::PlClient) >= 0.2000 for package: perl-DBI-1.627-4.amzn2.0.2.x86_64
---> Package perl-Data-Dumper.x86_64 0:2.145-3.amzn2.0.2 will be installed
---> Package perl-Digest-MD5.x86_64 0:2.52-3.amzn2.0.2 will be installed
--> Processing Dependency: perl(Digest::base) >= 1.00 for package: perl-Digest-MD5-2.52-3.amzn2.0.2.x86_64
---> Package squid-migration-script.x86_64 7:3.5.20-17.amzn2.4.1 will be installed
--> Running transaction check
---> Package perl-Digest.noarch 0:1.17-245.amzn2 will be installed
---> Package perl-PlRPC.noarch 0:0.2020-14.amzn2 will be installed
--> Processing Dependency: perl(Net::Daemon) >= 0.13 for package: perl-PlRPC-0.2020-14.amzn2.noarch
--> Processing Dependency: perl(Net::Daemon::Test) for package: perl-PlRPC-0.2020-14.amzn2.noarch
--> Processing Dependency: perl(Net::Daemon::Log) for package: perl-PlRPC-0.2020-14.amzn2.noarch
--> Processing Dependency: perl(Compress::Zlib) for package: perl-PlRPC-0.2020-14.amzn2.noarch
--> Running transaction check
---> Package perl-IO-Compress.noarch 0:2.061-2.amzn2 will be installed
--> Processing Dependency: perl(Compress::Raw::Zlib) >= 2.061 for package: perl-IO-Compress-2.061-2.amzn2.noarch
--> Processing Dependency: perl(Compress::Raw::Bzip2) >= 2.061 for package: perl-IO-Compress-2.061-2.amzn2.noarch
---> Package perl-Net-Daemon.noarch 0:0.48-5.amzn2 will be installed
--> Running transaction check
---> Package perl-Compress-Raw-Bzip2.x86_64 0:2.061-3.amzn2.0.2 will be installed
---> Package perl-Compress-Raw-Zlib.x86_64 1:2.061-4.amzn2.0.2 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

==============================================================================================================
 Package                          Arch            Version                           Repository           Size
==============================================================================================================
Installing:
 squid                            x86_64          7:3.5.20-17.amzn2.4.1             amzn2-core          3.1 M
Installing for dependencies:
 libecap                          x86_64          1.0.0-1.amzn2.0.2                 amzn2-core           21 k
 libtool-ltdl                     x86_64          2.4.2-22.2.amzn2.0.2              amzn2-core           49 k
 perl-Compress-Raw-Bzip2          x86_64          2.061-3.amzn2.0.2                 amzn2-core           32 k
 perl-Compress-Raw-Zlib           x86_64          1:2.061-4.amzn2.0.2               amzn2-core           58 k
 perl-DBI                         x86_64          1.627-4.amzn2.0.2                 amzn2-core          804 k
 perl-Data-Dumper                 x86_64          2.145-3.amzn2.0.2                 amzn2-core           48 k
 perl-Digest                      noarch          1.17-245.amzn2                    amzn2-core           23 k
 perl-Digest-MD5                  x86_64          2.52-3.amzn2.0.2                  amzn2-core           30 k
 perl-IO-Compress                 noarch          2.061-2.amzn2                     amzn2-core          260 k
 perl-Net-Daemon                  noarch          0.48-5.amzn2                      amzn2-core           51 k
 perl-PlRPC                       noarch          0.2020-14.amzn2                   amzn2-core           36 k
 squid-migration-script           x86_64          7:3.5.20-17.amzn2.4.1             amzn2-core           51 k

Transaction Summary
==============================================================================================================
Install  1 Package (+12 Dependent packages)

Total download size: 4.6 M
Installed size: 14 M
Downloading packages:
(1/13): libtool-ltdl-2.4.2-22.2.amzn2.0.2.x86_64.rpm                                   |  49 kB  00:00:00
(2/13): perl-Compress-Raw-Bzip2-2.061-3.amzn2.0.2.x86_64.rpm                           |  32 kB  00:00:00
(3/13): libecap-1.0.0-1.amzn2.0.2.x86_64.rpm                                           |  21 kB  00:00:00
(4/13): perl-Compress-Raw-Zlib-2.061-4.amzn2.0.2.x86_64.rpm                            |  58 kB  00:00:00
(5/13): perl-Data-Dumper-2.145-3.amzn2.0.2.x86_64.rpm                                  |  48 kB  00:00:00
(6/13): perl-DBI-1.627-4.amzn2.0.2.x86_64.rpm                                          | 804 kB  00:00:00
(7/13): perl-Digest-1.17-245.amzn2.noarch.rpm                                          |  23 kB  00:00:00
(8/13): perl-Digest-MD5-2.52-3.amzn2.0.2.x86_64.rpm                                    |  30 kB  00:00:00
(9/13): perl-Net-Daemon-0.48-5.amzn2.noarch.rpm                                        |  51 kB  00:00:00
(10/13): perl-IO-Compress-2.061-2.amzn2.noarch.rpm                                     | 260 kB  00:00:00
(11/13): perl-PlRPC-0.2020-14.amzn2.noarch.rpm                                         |  36 kB  00:00:00
(12/13): squid-migration-script-3.5.20-17.amzn2.4.1.x86_64.rpm                         |  51 kB  00:00:00
(13/13): squid-3.5.20-17.amzn2.4.1.x86_64.rpm                                          | 3.1 MB  00:00:00
--------------------------------------------------------------------------------------------------------------
Total                                                                          15 MB/s | 4.6 MB  00:00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : perl-Data-Dumper-2.145-3.amzn2.0.2.x86_64                                                 1/13
  Installing : libtool-ltdl-2.4.2-22.2.amzn2.0.2.x86_64                                                  2/13
  Installing : 7:squid-migration-script-3.5.20-17.amzn2.4.1.x86_64                                       3/13
  Installing : perl-Digest-1.17-245.amzn2.noarch                                                         4/13
  Installing : perl-Digest-MD5-2.52-3.amzn2.0.2.x86_64                                                   5/13
  Installing : perl-Compress-Raw-Bzip2-2.061-3.amzn2.0.2.x86_64                                          6/13
  Installing : libecap-1.0.0-1.amzn2.0.2.x86_64                                                          7/13
  Installing : perl-Net-Daemon-0.48-5.amzn2.noarch                                                       8/13
  Installing : 1:perl-Compress-Raw-Zlib-2.061-4.amzn2.0.2.x86_64                                         9/13
  Installing : perl-IO-Compress-2.061-2.amzn2.noarch                                                    10/13
  Installing : perl-PlRPC-0.2020-14.amzn2.noarch                                                        11/13
  Installing : perl-DBI-1.627-4.amzn2.0.2.x86_64                                                        12/13
  Installing : 7:squid-3.5.20-17.amzn2.4.1.x86_64                                                       13/13
  Verifying  : 1:perl-Compress-Raw-Zlib-2.061-4.amzn2.0.2.x86_64                                         1/13
  Verifying  : perl-IO-Compress-2.061-2.amzn2.noarch                                                     2/13
  Verifying  : perl-Net-Daemon-0.48-5.amzn2.noarch                                                       3/13
  Verifying  : 7:squid-3.5.20-17.amzn2.4.1.x86_64                                                        4/13
  Verifying  : perl-Data-Dumper-2.145-3.amzn2.0.2.x86_64                                                 5/13
  Verifying  : perl-PlRPC-0.2020-14.amzn2.noarch                                                         6/13
  Verifying  : perl-Digest-MD5-2.52-3.amzn2.0.2.x86_64                                                   7/13
  Verifying  : libecap-1.0.0-1.amzn2.0.2.x86_64                                                          8/13
  Verifying  : perl-Compress-Raw-Bzip2-2.061-3.amzn2.0.2.x86_64                                          9/13
  Verifying  : perl-Digest-1.17-245.amzn2.noarch                                                        10/13
  Verifying  : 7:squid-migration-script-3.5.20-17.amzn2.4.1.x86_64                                      11/13
  Verifying  : perl-DBI-1.627-4.amzn2.0.2.x86_64                                                        12/13
  Verifying  : libtool-ltdl-2.4.2-22.2.amzn2.0.2.x86_64                                                 13/13

Installed:
  squid.x86_64 7:3.5.20-17.amzn2.4.1

Dependency Installed:
  libecap.x86_64 0:1.0.0-1.amzn2.0.2                    libtool-ltdl.x86_64 0:2.4.2-22.2.amzn2.0.2
  perl-Compress-Raw-Bzip2.x86_64 0:2.061-3.amzn2.0.2    perl-Compress-Raw-Zlib.x86_64 1:2.061-4.amzn2.0.2
  perl-DBI.x86_64 0:1.627-4.amzn2.0.2                   perl-Data-Dumper.x86_64 0:2.145-3.amzn2.0.2
  perl-Digest.noarch 0:1.17-245.amzn2                   perl-Digest-MD5.x86_64 0:2.52-3.amzn2.0.2
  perl-IO-Compress.noarch 0:2.061-2.amzn2               perl-Net-Daemon.noarch 0:0.48-5.amzn2
  perl-PlRPC.noarch 0:0.2020-14.amzn2                   squid-migration-script.x86_64 7:3.5.20-17.amzn2.4.1

Complete!

今回はインターネット経由でアクセスを行うため、以下の許可を追加し、リロードを行います。

sh-4.2$ sudo cat /etc/squid/squid.conf
#
# Recommended minimum configuration:
#

# Example rule allowing access from your local networks.
# Adapt to list your (internal) IP networks from where browsing
# should be allowed
acl localnet src 10.0.0.0/8     # RFC1918 possible internal network
acl localnet src 172.16.0.0/12  # RFC1918 possible internal network
acl localnet src 192.168.0.0/16 # RFC1918 possible internal network
acl localnet src 202.xx.xx.xx/32 # クライアントのグローバル IP
acl localnet src fc00::/7       # RFC 4193 local private network range
acl localnet src fe80::/10      # RFC 4291 link-local (directly plugged) machines
(以下略)

念のため SecuriryGroup でも送信元を制限し、準備完了です。

PAC ファイルの作成

上記のページのサンプルを加工し、sample.pacという名称で以下を作成しました。

function FindProxyForURL(url, host) {
  if (isPlainHostName(host) || dnsDomainIs(host, ".amazonaws.com")) {
    return "DIRECT";
  } else {
    return "PROXY 18.xx.xx.xx:3128; DIRECT";
  }
}

大まかに、以下のとおり機能します。

  • 接続先がホスト名のみでドメインが付与されていない(isPlainHostName(host))か、
  • 接続先のドメインが .amazonaws.com (dnsDomainIs(host, ".amazonaws.com"))の場合、
  • 直接アクセスする(return "DIRECT";)。
  • それ以外の場合、指定のプロキシを経由する(PROXY 18.xx.xx.xx:3128;
    • (プロキシに接続できなければ直接アクセスする)

S3 に格納する前にローカルでfile://<PACファイルのパス>の形式で指定して動作確認しようとしたのですが、macOS 10.14 Mojave 以降では対応していないようでした。

(今更ですが、今回使用しているのは macOS Catalina 10.15.7 です。)

S3 への PAC ファイルの格納

今回は IAM の権限を使用しないでクライアントから S3 内のファイル(オブジェクト)を取得したいため、アクセス権を考慮する必要があります。

大まかには、 S3 バケット側(バケットポリシー、バケット ACL)かオブジェクト側(オブジェクト ACL)のいずれか、もしくはその両方で Allow を定義する必要があります。

今回はchibayuki-pubという名称のバケットを作成し、以下の設定としました。

  • バケットのパブリックアクセスブロックをすべてオン
  • バケットポリシーで送信元 IP を条件とした上で全てのプリンシパルを許可
  • バケット ACL はデフォルト(所有者のみ読み書き可)
  • オブジェクト ACL もデフォルト(所有者のみ読み書き可)

バケットポリシーは具体的には以下です。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::chibayuki-pub/*",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": "202.xx.xx.xx"
                }
            }
        }
    ]
}

このポリシーから Condition部を除外すると「パブリックに読み取り可能」と解釈されるため、パブリックアクセスブロックを考慮する必要が出てきます。

タイプとメタデータ

ファイルsample.pacをアップロードしたところ、オブジェクトのタイプはそのまま pacと解釈されました。

S3_Management_Console

メタデータを確認すると、Content-Type はデフォルトのbinary/octet-streamとなっていました。

S3_Management_Console-3030988

場合によってはここを変更する必要があるかと考えていたのですが、結果的にはこのままで問題ありませんでした。

Mac から参照してみる

先ほど格納したオブジェクトが問題なく参照できるか、先に curl でアクセスしてみます。

% curl https://chibayuki-pub.s3-ap-northeast-1.amazonaws.com/sample.pac
function FindProxyForURL(url, host) {
  if (isPlainHostName(host) || dnsDomainIs(host, ".amazonaws.com")) {
    return "DIRECT";
  } else {
    return "PROXY 18.xx.xx.xx:3128; DIRECT";
  }
}

内容が取得できたため、アクセス権限は問題なさそうです。

Mac のネットワークの設定画面より、「自動プロキシ構成」にチェックを入れた上で、「プロキシ構成ファイル」にオブジェクト URL を入力します。

MacPac

設定を適用したのち、ブラウザで IP 確認サイトにアクセスします。

再掲すると、送信元 グローバル IP は以下のとおりです。

  • クライアント:202.xx.xx.xx
  • プロキシサーバ:18.xx.xx.xx

checkip.amazonaws.com では、意図通りプロキシを経由せず直接アクセスが行われています。

checkip_amazonaws_com

アクセス情報【使用中のIPアドレス確認】では、こちらも意図通りプロキシを経由してアクセスを行っています。

CMAN

S3 に格納した PAC ファイルが正常に適用されたことを確認できました。

ちなみに

ここまでの PAC ファイルを適用した状態で curl でアクセスを行うと、その内容が解釈されていないことが分かりました。( アクセス情報【使用中のIPアドレス確認】に curl を行っても、プロキシサーバでなくクライアントのグローバル IP が返却される。)

これは PAC ファイルの宿命のようで、 curl にも適用したければ環境変数にセットするといった一手間が必要とのことです。

終わりに

PAC ファイルを S3 に格納してみました。今回の検証ではインターネット経由でアクセスする構成としたので、「現状社内展開しているものを置き換える」といったケースには向いていないと思います。

個人用の PAC ファイルを持っているがローカルに置いても参照できないという場合の回避策や、少人数での利用で、使えるケースがあるかと想像しています。

参考になれば幸いです。

以上、千葉(幸)がお送りしました。

参考

VPC内から参照するパターンを以下に書きました。