Overview
- このドキュメントでは、Public Subnet上のサーバーにDockerized HTTP Proxy (Squid) を構築し、Private Subnet上のサーバーから一時的にインターネットに接続するための手順を説明します。
- 特に、
apt install
などの作業を想定しています
0. アーキテクチャ概要
この構成は、オンプレミス環境のネットワークをPublic SubnetとPrivate Subnetに分割し、Private Subnet内のサーバーが直接インターネットにアクセスできないようにしつつ、一時的にプロキシ経由でインターネット接続を可能にするものです。
主要コンポーネント:
Public Subnet: インターネットに直接接続可能なネットワーク領域
Public Subnet Server (例: 172.31.33.121): このサーバーはPublic Subnet内に配置され、インターネットへのアウトバウンド接続が許可されています。このサーバー上でDockerが動作し、HTTP Proxy (Squid) コンテナが稼働します。
- Docker Engine: Public Subnet Server上で動作し、Squidコンテナをホストします
- Squid HTTP Proxy (Docker コンテナ): Dockerコンテナとして動作し、Public Subnet ServerのTCPポート3128でリクエストを待ち受けます。Private SubnetからのHTTP/HTTPSリクエストを受け取り、インターネットに転送します
- ファイアウォール/セキュリティグループ: Public Subnet Serverへのインバウンドトラフィック(特にPrivate SubnetからのTCP 3128ポートへのアクセス)と、アウトバウンドトラフィック(インターネットへのHTTP/HTTPSアクセス)を制御します。
Private Subnet: インターネットに直接接続できないネットワーク領域
Private Subnet Server (例: 172.31.13.168): このサーバーはPrivate Subnet内に配置され、通常はインターネットへの直接接続が制限されています
- apt updateやapt installなどの作業を行う際に、Public Subnet Server上のSquidプロキシを経由してインターネットにアクセスします
- インターネットへの接続ではaptは実行できないことに注意します
通信フロー:
- Private Subnet Server上でapt updateやcurlなどのコマンドが実行されます
- これらのコマンドは、設定されたhttp_proxyおよびhttps_proxy環境変数(または-oオプション)に従い、Public Subnet ServerのIPアドレス(例: 172.31.33.121)のTCPポート3128へリクエストを送信します
- Private Subnet ServerからPublic Subnet Serverへの通信は、ネットワークACLやセキュリティグループによって許可されている必要があります
- Public Subnet Server上のDockerで動作するSquidコンテナが、Private Subnet Serverからのリクエストを受け取ります
- Squidは受け取ったリクエストを解析し、インターネット上のUbuntuリポジトリやその他の宛先に転送します
- Squidコンテナからインターネットへの通信は、Public Subnet Serverのファイアウォールやセキュリティグループによって許可されている必要があります
- インターネットからのレスポンスはSquidを経由してPrivate Subnet Serverに返され、aptコマンドなどが処理を続行します
このアーキテクチャにより、Private Subnetのセキュリティを維持しつつ、必要な場合にのみ制御された方法でインターネット接続を提供できます。
1. HTTP ProxyのDockerコンテナー作成
SquidをHTTP Proxyとして使用します。以下のファイルを作成し、Public Subnet上のサーバーに配置します。
1.1. Dockerfile
Squidプロキシを構築するためのDockerfileです。ネットワーク診断ツール(iputils-ping, curl, wget)を追加でインストールするようにしました。
# Ubuntu 22.04をベースイメージとして使用
FROM ubuntu:22.04
# aptパッケージリストを更新し、Squidとネットワーク診断ツールをインストール
# インストール後にaptキャッシュをクリーンアップし、イメージサイズを削減
RUN apt-get update && apt-get install -y squid iputils-ping curl wget && \
rm -rf /var/lib/apt/lists/*
# ホスト側のsquid.confをコンテナ内の/etc/squid/squid.confにコピー
COPY squid.conf /etc/squid/squid.conf
# Squidが使用するディレクトリを作成し、適切な所有者と権限を設定します。
# これにより、Squidがキャッシュディレクトリに書き込む際に権限エラーが発生するのを防ぎます。
RUN mkdir -p /var/spool/squid && \
chown -R proxy:proxy /var/spool/squid && \
chmod -R 755 /var/spool/squid
# Squidのキャッシュディレクトリを初期化します。
# 'proxy'ユーザーで実行することで、権限の問題を回避します。
RUN /usr/sbin/squid -z -F -N -f /etc/squid/squid.conf
# Squidのデフォルトポート3128を公開
EXPOSE 3128
# コンテナ起動時にSquidデーモンをフォアグラウンドで実行
# -N: デーモン化しない (フォアグラウンドで実行)
# -f: 設定ファイルを指定
# -F: フォアグラウンドで実行(-Nと併用することで、より確実にフォアグラウンドで動作)
CMD ["/usr/sbin/squid", "-N", "-F", "-f", "/etc/squid/squid.conf"]
1.2. squid.conf(Dockerfileと同じディレクトリに配置)
Private Subnetからのアクセスを許可するための基本的なSquid設定です。HTTPSトラフィックのためのCONNECTメソッドを明示的に許可する設定を追加しました。172.31.0.0/16
は適当なCIDRに変更してください
# HTTPプロキシがリッスンするポート
http_port 3128
# アクセス制御リスト (ACL) の定義
# localnet ACLを定義し、Private SubnetのIPレンジを指定します。
# 例: Private Subnetが192.168.1.0/24の場合
# acl localnet src 192.168.1.0/24
# 今回は一時的な利用のため、全てのIPからのアクセスを一時的に許可します。
# ただし、本番環境では絶対に避けるべき設定です。
acl localnet src 172.31.0.0/16
# CONNECTメソッドを許可するポートを定義
# apt updateはHTTPS (ポート443) を使用するため、CONNECTメソッドを許可する必要があります
acl SSL_ports port 443
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 # https
acl Safe_ports port 70 # gopher
acl Safe_ports port 210 # wais
acl Safe_ports port 1025-65535 # unregistered ports
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl Safe_ports port 591 # filemaker
acl Safe_ports port 777 # multiling http
acl CONNECT method CONNECT
# localnet ACLからのHTTPアクセスを許可
http_access allow localnet
# SSL_portsへのCONNECTメソッドを許可 (HTTPSトラフィック用)
http_access allow CONNECT localnet SSL_ports
# 安全なポートへのアクセスを許可
http_access deny !Safe_ports
# その他の全てのHTTPアクセスを拒否
http_access deny all
# キャッシュディレクトリの設定
# ufs: Unix Filesystem (一般的なファイルシステム)
# /var/spool/squid: キャッシュディレクトリのパス
# 100: 最大キャッシュサイズ (MB)
# 16: 第1レベルのサブディレクトリ数
# 256: 第2レベルのサブディレクトリ数
cache_dir ufs /var/spool/squid 100 16 256
# コアダンプディレクトリの設定
coredump_dir /var/spool/squid
# キャッシュリフレッシュパターンの設定
# 各種プロトコルやURLパターンに対するキャッシュの有効期限とリフレッシュ頻度を定義
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern . 0 20% 4320
1.3. docker-compose.yml
Dockerfileとsquid.confを使って、HTTP Proxyコンテナを簡単に管理するためのdocker-compose.ymlです。
services:
http-proxy:
build: . # 現在のディレクトリにあるDockerfileを使用してイメージをビルド
container_name: http-proxy-squid # コンテナの名前を指定
ports:
# ホストの3128ポートをコンテナの3128ポートにマッピング
# これにより、Public SubnetのサーバーのIPアドレスと3128ポートでプロキシにアクセス可能になります
- "3128:3128"
volumes:
# ホスト側のsquid.confファイルをコンテナ内の/etc/squid/squid.confにマウント
# これにより、ホスト側でsquid.confを編集し、コンテナを再起動するだけで設定が反映されます
- ./squid.conf:/etc/squid/squid.conf
restart: unless-stopped # コンテナが停止した場合、手動で停止しない限り自動的に再起動
1.4. Dockerコンテナの起動
Public Subnetのサーバーで、上記3つのファイルを同じディレクトリに配置し、以下のコマンドを実行します。
docker-compose up -d
2. Private Subnet側のネットワーク設定方法
Private SubnetのサーバーからHTTP Proxyを経由してインターネットにアクセスするための設定です。作業完了後に元のネットワーク構成に戻せるよう、一時的な設定方法を重視します。Public SubnetにあるHTTP ProxyサーバーのIPアドレスを PUBLIC_PROXY_IP とします。(例: 192.168.0.100)
2.1. squidへの通信確認
nc
コマンドにより、squid
に接続できることを確認します。PUBLIC_PROXY_IP
はあとの設定でも使うので必ず実行すること
PUBLIC_PROXY_IP="172.31.33.121"
$ nc -vz ${PUBLIC_PROXY_IP} 3128
Connection to 172.31.33.121 3128 port [tcp/*] succeeded!
2.2. http proxyの環境変数を設定
aptコマンドがHTTP Proxyを使用するように設定します。環境変数に加えて、aptコマンドに直接プロキシオプションを指定する方法です。この方法は、sudoを使用する場合でもプロキシ設定が確実に適用されます。
export http_proxy="http://${PUBLIC_PROXY_IP}:3128/"
export https_proxy="http://${PUBLIC_PROXY_IP}:3128/"
念の為の確認
cat << ETX
http_proxy=${http_proxy}
https_proxy=${https_proxy}
ETX
2.3. インターネットへの接続確認
200
が返ってくればインターネットの接続ができています。
$ curl -s -o /dev/null -w "%{http_code}\n" https://www.google.com/
200
2.4. aptの設定と実行
aptは上記の環境変数だけではsquidに接続できません。
apt update
および apt install
の実行します。-o
オプションでプロキシを直接指定し、IPv4を強制します。
sudo apt update -y -o Acquire::http::Proxy=${http_proxy} -o Acquire::https::Proxy=${https_proxy}
sudo apt install '<パッケージ名>' -y -o Acquire::http::Proxy=${http_proxy} -o Acquire::https::Proxy=${https_proxy}
作業完了後、環境変数をクリアして元の構成に戻します
unset http_proxy
unset https_proxy
参考