個人的な備忘録：AWS上に2台構成で多段プロキシを構築し、PACファイルでアクセス制御を試してみた

## はじめに
今回は、過去の技術検証を組み合わせて、AWS上にプロキシサーバーを2台構築し、多段プロキシによるネットワーク検証を行います。

先にお伝えしておくと、今回の技術検証は成功したとは言いがたい結果でした。（***PACファイルでの制御としては成功していますが、多段プロキシの観点からは正直、微妙な結果です。***）

:::note warn
***しかし、自分の備忘録として、現時点で把握している内容を整理するため、記事としてまとめています。***
:::

***この記事は個人レベルでの検証内容に基づいています。*** そのため、内容が実運用環境に適さない場合があることをご了承ください。

***この内容が、どなたかの技術的な参考になれば幸いです。***

## 書こうと思ったきっかけ
以前から、AWSのパブリッククラウド上にプロキシサーバーを構築した際、「**いつか多段プロキシの技術検証をしてみたい**」と思っていました。

:::note info
***実は1年前にも同じことに挑戦したのですが、仕組みを十分に理解できず、途中で諦めた経験があります。***
:::

今回は、多くの情報を調べながら、なんとか構築から実装まで進めることができたので、備忘録としてこの記事にまとめます。

## 正直、多段プロキシは難しい
私の認識では、例えばYahoo!のサイトにアクセスした場合、1つ目のプロキシサーバーを経由し、その後2つ目のプロキシサーバーを経由してインターネットに出ていく仕組みになると考えていました。

:::note alert
**しかし、今回の検証ではそのような挙動にはならず、どちらかというとアプリケーションロードバランサーのように冗長化された仕組みになっていました。**
:::

この結果については、私自身がS3バケットに配置しているPACファイルでアクセス制御を行っていることが大きな原因だと認識しています。

以下のサイトなどによると、Squidの設定ファイルのみでプロキシを構成することも可能なようです。***この点については改めて学び直し、キャッチアップする必要があると感じています。***

https://sig9.org/blog/2022/05/08/

## 今回の検証で使用したPACファイルについて
1年前、AWSパブリッククラウド環境にSquidを使用してプロキシサーバーを2台構築した際に、以下のPACファイルを使用して検証を行っていました。

```javascript
function FindProxyForURL(url, host) {
    // Yahoo!のドメインに一致する場合は多段プロキシを経由
    if (dnsDomainIs(host, ".yahoo.co.jp") || shExpMatch(host, "www.yahoo.co.jp")) {
        return "PROXY 3.112.81.93:3128; PROXY 35.72.182.170:3128"; // 多段プロキシ
    }
    // それ以外のすべてのアクセスを拒否
    return "PROXY 127.0.0.1:0"; // 無効なプロキシを指定
}
```

PACファイルはJavaScript形式で記述しており、この設定に基づき、1つ目のプロキシを経由した後に2つ目のプロキシを経由するのが「多段プロキシ」だと考えていました。

:::note info
***しかし、今回の技術検証を通じて、以下のような挙動が確認されました。***
:::

- **1つ目のプロキシサーバーで通信が成功した場合**  
  通信のログは1つ目のプロキシに記録され、2つ目のプロキシは使用されません。
  
- **1つ目のプロキシサーバーが停止している場合**  
  2つ目のプロキシサーバーに通信がフォールバックし、そのログが記録されます。

この結果から、PACファイルによる制御では、記述された順にプロキシを試行し、**最初に成功したプロキシで処理が完了する仕組み**であることが分かりました。

## 補足事項：前回構築したSquidのプロキシサーバーをAMIから復元して構築
プロキシサーバーを2台用意する必要がある場合、まずはSquidを使用したプロキシサーバーを準備します。

![Screenshot 2025-01-12 at 14.38.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/5d8dff71-136c-d3e8-f158-8c0ae8bf8c82.png)

私の場合、前回構築したプロキシサーバーのAMIを取得しており、そのAMIを使ってプロキシサーバーを復元し構築しました。

![Screenshot 2025-01-12 at 14.36.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/7703b73a-1b1f-06ac-28b3-881be2c8607a.png)

***AMIの復元方法については、以下の記事で詳しく解説していますので、ぜひ参考にしてください。***

https://qiita.com/free-honda/items/a2eb7f57787b93436a3b

## エラー発生：`The requested URL could not be retrieved`

当初は、前回構築したプロキシサーバーのAMIを取得して復元すれば、そのまま多段プロキシ環境が実現できると考えていました。

:::note alert
**しかし、クライアント端末からインターネットにアクセスした際、以下のようなエラーが記録されていました。**
:::

これを受けて原因を調査しました。

```bash
1736655921.162      8 xx.xx.xx.xx TCP_TUNNEL/403 0 CONNECT www.yahoo.co.jp:443 - FIRSTUP_PARENT/35.72.182.170 -
1736655927.532      2 xx.xx.xx.xx TCP_TUNNEL/403 0 CONNECT www.yahoo.co.jp:443 - FIRSTUP_PARENT/35.72.182.170 -
1736655927.567      3 xx.xx.xx.xx TCP_TUNNEL/403 0 CONNECT www.yahoo.co.jp:443 - FIRSTUP_PARENT/35.72.182.170 -
1736655927.645      1 xx.xx.xx.xx TCP_TUNNEL/403 0 CONNECT www.yahoo.co.jp:443 - FIRSTUP_PARENT/35.72.182.170 -
1736655927.679      3 xx.xx.xx.xx TCP_TUNNEL/403 0 CONNECT www.yahoo.co.jp:443 - FIRSTUP_PARENT/35.72.182.170 -
1736655927.700      3 xx.xx.xx.xx TCP_MISS/403 4720 GET http://www.yahoo.co.jp/ - FIRSTUP_PARENT/35.72.182.170 text/html
1736655927.770      2 xx.xx.xx.xx TCP_HIT/200 13104 GET http://ip-10-0-1-132.ap-northeast-1.compute.internal:3128/squid-internal-static/icons/SN.png - HIER_NONE/- image/png
1736655927.965      1 xx.xx.xx.xx TCP_MISS/403 4678 GET http://www.yahoo.co.jp/favicon.ico - FIRSTUP_PARENT/35.72.182.170 text/html
```

**ブラウザ側のエラー画面**

以下は、ブラウザに表示されたエラー画面です。

![Screenshot 2025-01-12 at 13.57.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/61b7a674-f7bc-1081-32bb-1d61c7bef3f7.png)

### 原因

**上流プロキシの設定で制限がかかっている**

上流プロキシ（`35.72.182.170`）がリクエストを拒否していることが原因でした。  
考えられる理由は以下の通りです：

- 上流プロキシのACL（アクセス制御リスト）がクライアントIP（`147.192.171.64`）を許可していない。

## エラー解決：中間プロキシと上流プロキシの関係性について

### 中間プロキシと上流プロキシの関係

中間プロキシとして動作するサーバーは、上流プロキシ（parent proxy）を指定する役割を持っています。このため、**中間プロキシの Squid設定ファイル** を編集する必要があります。

#### 理由
中間プロキシサーバーが、どの上流プロキシ（`3.112.81.93` と `35.72.182.170`）を利用するかを指示する役割を担っているためです。この設定は、`cache_peer` ディレクティブを使用して行います。

#### 注意点
上流プロキシの設定は、特定の要件がない限り変更は不要です。


### 中間プロキシサーバーの位置づけ

ここでの中間プロキシサーバーは、以下のPACファイルで指定されている **1つ目のプロキシサーバー** を指します：

```javascript
return "PROXY 3.112.81.93:3128; PROXY 35.72.182.170:3128";
```

**Squid設定例**

以下は、中間プロキシが上流プロキシを指定するための設定例です。

```/etc/squid/squid.conf
# 上流プロキシの設定
cache_peer 35.72.182.170 parent 3128 0 no-query default
```

私の環境では、上記のように設定を修正しました。

:::note alert
**ただし、こちらの設定はご自身の環境に合わせて適宜変更してください。**
:::

## 実際にアクセスして確認してみた
前回作成したプロキシサーバーとS3バケットに配置したPACファイルを使用し、検証を進めていきます。

![Screenshot 2025-01-12 at 15.17.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/37ec03b6-3264-92b1-868e-969e61e127f8.png)

***過去の関連内容については、以下の記事をご確認ください。***

https://qiita.com/free-honda/items/35471fde808a558c81f9

https://qiita.com/free-honda/items/99170d4d481e7937d893

### アクセスしながらログを確認
私の環境では、PACファイルによる制御において、多段プロキシは冗長化の仕組みとして機能することがわかりました。***まず、中間プロキシサーバーのログを確認しました。***

Yahoo!のサイトにアクセスした際、中間プロキシサーバーに正常にログが記録されていることを確認しました。

![Screenshot 2025-01-12 at 14.09.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/49d2887a-3bd7-c85a-83ae-f924a4ba204f.png)

次に、中間プロキシサーバーのOSを停止し、上流プロキシへのフォールバック動作を確認しました。

![Screenshot 2025-01-12 at 14.10.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/ea4a38ef-2c6f-cabc-4782-844bd539cec4.png)

中間プロキシが停止した場合、上流プロキシにログが記録されることが確認できました。***この挙動は想定通りであり、問題なく動作していることがわかりました。***

![Screenshot 2025-01-12 at 14.11.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/6b367190-afe9-bf33-89ba-20bfac0015a0.png)

:::note warn
**※注意：**
***今回使用したPACファイルの設定では、Yahoo!関連のURLのみを許可しているため、一部の要素が表示されない場合がありますが、これは想定通りの挙動です。***
:::

## まとめ
ここまでお読みいただきありがとうございました。
今回の技術検証については、正直、自分の中で全てを完全に理解できたわけではなく、「***なんとなくこんな仕組みなのだろう***」といった程度の理解に留まりました。

:::note info
**そもそも最近では、プロキシサーバー自体を多段構成にすることが減ってきていると思います。**
:::

そのため、今回の技術検証は面白い試みではありましたが、必ずしも必要な作業ではなかったのかもしれません...。

***それでも、ネットワークの動きをログで確認しながら切り分け作業を進められたことは、とても良い経験になりました。***

## 参考記事

https://luminati.site/archives/1947

https://takeda-h.hatenablog.com/entry/2022/04/30/113933

https://qiita.com/kaws/items/b7718e2f6941c3c9ae60