0
1

AWS/AppRunner上でフォワードプロキシサーバの構築を試みた

Last updated at Posted at 2024-07-28

経緯

  • EC2上にSquidを導入してフォワードプロキシサーバとして運用しているのですが、可用性向上/運用負担軽減を目的にAppRunner上でSquidのDockerイメージが動作可能か試してみました。

結論

  • AppRuuner上でフォワードプロキシは動作不可。(Fargateでは動作可)

リバースプロキシとフォワードプロキシの違い

  • リバースプロキシとフォワードプロキシはhttp(s)通信を中継する点では役割同じですが、リバースプロキシをフォワードプロキシとして使ってしまうと、

    • 外部送信を避けたい組織内の情報(X-Forwarded-forに個別端末のIPアドレスが付与される等)が転送される。

    • 送信先のURLとリバースプロキシのURLが分離されない。

というとわかりやすくなるかもしれません。

送信先URLの指定方法のイメージ(yahooにアクセスする場合を想定)

 # フォワードプロキシの場合(プロキシサーバのURLと送信先URLは分離されている)
 curl https://www.yahoo.co.jp -x forward-proxy-url:3128
 
 # リバースプロキシの場合(プロキシサーバのURLと送信先URLは分離されていない)
 # 構築方法でURL(含むクエリストリング)の組み方は変えられる
 curl https://reverse-proxy-url?dest_url=www.yahoo.co.jp
 curl https://reverse-proxy-url/www.yahoo.co.jp
 
  • 比較表を作ると以下のような感じですが、双方http(s)通信を中継する役割は同じなので少しわかりにくいかもしれず、上記解説にて補足したものです。
特徴 リバースプロキシ フォワードプロキシ
役割 クライアントからのリクエストを受け取り、適切なサーバーに転送する。 クライアントの代理として外部のリソースにアクセスする。
主な目的 負荷分散、キャッシング、セキュリティ インターネットアクセスの制御、匿名化、キャッシング
主な用途 - ウェブサーバーの負荷分散
- SSL終端
- キャッシング
- 社内ネットワークのインターネットアクセス制御
- 匿名ブラウジング
- コンテンツフィルタリング
設置場所 サーバーの前面 クライアントの前面
接続の方向 インバウンドトラフィック(クライアント→サーバー) アウトバウンドトラフィック(クライアント→インターネット)
IPアドレス クライアントにはリバースプロキシのIPアドレスが見える 外部サイトにはフォワードプロキシのIPアドレスが見える
セキュリティ機能 Webアプリケーションファイアウォール(WAF)、DoS攻撃の緩和 フィルタリング、アクセス制御、匿名化
クライアントからサーバに送信するデータの取り扱い 極力サーバに転送しようとする 必要最小限にとどめる
有名なソフトウェア Squid Apache、Nginx

ざっくり手順

  • squidのコンテナイメージを作成するDockerfile
Dockerfile-squid
# 使用するベースイメージ
FROM ubuntu/squid:latest

# デフォルトのSquid設定ファイルをバックアップ
RUN mv /etc/squid/squid.conf /etc/squid/squid.conf.original

# Squid設定を直接書き込み
RUN echo "\
# Allow local machine to access\n\
http_access allow localhost\n\
\n\
# IPアドレスによるアクセス制限の設定\n\
acl allowed_ips src xxx.xxx.xxx.xxx \n\
http_access allow allowed_ips\n\
\n\
# Squid の設定\n\
acl Safe_ports port 1-65535          # all ports\n\
acl SSL_ports port 443\n\
acl CONNECT method CONNECT\n\
\n\
http_access allow Safe_ports\n\
http_access allow CONNECT SSL_ports\n\
http_access deny all\n\
\n\
# デフォルトのポート\n\
http_port 3128\n\
\n\
# キャッシュを無効にする設定\n\
cache deny all\n\
cache_mem 0 MB\n\
maximum_object_size_in_memory 0 KB\n\
cache_dir null /tmp\n\
\n\
# ログファイルの場所\n\
access_log /var/log/squid/access.log\n\
cache_log /var/log/squid/cache.log\n\
\n\
# その他のオプション\n\
coredump_dir /var/spool/squid" > /etc/squid/squid.conf

# 必要なログファイルとキャッシュディレクトリの作成
RUN mkdir -p /var/spool/squid \
    && chown -R proxy:proxy /var/spool/squid \
    && mkdir -p /var/log/squid \
    && chown -R proxy:proxy /var/log/squid \
    && squid -z

# Squidサーバーを起動
CMD ["squid", "-N", "-d", "1"]
squidのDockerイメージをECRにプッシュ( your-account-id を適宜変更)
# Dockerfile-squidを使ってSquidのDockerイメージをビルドし、イメージ名をhogehoge-squidにタグ付けする
docker build -f Dockerfile-squid -t hogehoge-squid .

# AWS ECRにログインするためのパスワードを取得し、Dockerにログインする
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin <your-account-id>.dkr.ecr.ap-northeast-1.amazonaws.com

# hogehoge-squidイメージに最新タグを付け、AWS ECRリポジトリのsquid:latestとしてタグ付けする
docker tag hogehoge-squid:latest your-id.dkr.ecr.ap-northeast-1.amazonaws.com/squid:latest

# 最新タグが付いたSquidイメージをAWS ECRリポジトリにプッシュする
docker push <your-account-id>.dkr.ecr.ap-northeast-1.amazonaws.com/squid:latest

  • AWSマネジメントコンソールからAppRunnerを選択して、プッシュしたイメージを元にサービスを起動。(実際の手順は公式に委ねますが、体感して簡単に設定可能でした。)

検証結果

  • 上記コンテナをAppRunnerにデプロイすると標準出力にログ出力されることになるが、端末からデプロイしたサービス経由で接続してもタイムアウトになり、サービス上のログもヘルスチェック用のログしか記録されない。

通信シーケンスまで確認できていないですが、フォワードプロキシの場合、通信開始する際にHTTPのCONNECTメソッド(送信元がプロキシサーバーに送信先とTCP接続を確立するよう要求する役割)を使うのですが、AppRunnerの目的からして当然ではありますがAppRunnerはこのメソッドをサポートしていないからだと思われます。

07-15-2024 12:15:45 AM 1720970144.822      0 169.254.175.249 NONE_NONE/000 0 - error:transaction-end-before-headers - HIER_NONE/- -
07-15-2024 12:15:55 AM 1720970154.823      0 169.254.175.249 NONE_NONE/000 0 - error:transaction-end-before-headers - HIER_NONE/- -
07-15-2024 12:16:05 AM 1720970164.823      0 169.254.175.249 NONE_NONE/000 0 - error:transaction-end-before-headers - HIER_NONE/- -
  • AppRunner上にデプロイしても、以下のようなSquidのエラーページは表示されました。(以下は検証時と全く同じものではないです)

image.png

補足

  • AWS上でフォワードプロキシを構築する際は、踏み台にならないように必ず送信元制限はかけましょう。(AWSの規約違反になります)

  • 上記は厳密に検証/整理したわけではありませんので、その点割り引いてお読みください。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1