やりたいこと〜
ツール類やデスクトップアプリケーションを作る際に HTTP プロキシ対応をしたりしますが、テストする際に環境がなくて困ったりします。
この記事では docker-compose を使って、テスト用の HTTP プロキシ環境をいつでも再現できるようにします。
UNIX 系 OS ベースの話になります。
NTLM はしません。
コード
本記事のすぐ動くコードは ↓ にあります。
単に HTTP プロキシを立てる
以下のコードを書きます。
docker-compose.yml
Dockerfile
-
squid.conf.template
(envsubst 用のテンプレートファイル) -
.env
(環境変数 = 変更可能なパラメータ)
まず .env
ファイルで Squid HTTP Proxy の待受ポートと、BASIC 認証の有無を、環境変数として指定できるようにします。
# 待受ポート
HTTP_PORT=3128
# BASIC 認証の設定 (default ではコメントアウト → "#" で OFF)
BASIC_AUTH_COMMENT_OUT=#
BASIC_AUTH_USERNAME=squid
BASIC_AUTH_PASSWORD=password
オーケストレーションファイル docker-compose.yml
でコンテナの起動方法を定義します。
version: '3.1'
services:
squid:
build: ./squid
expose:
- "${HTTP_PORT}"
ports:
- "${HTTP_PORT}:${HTTP_PORT}"
environment:
- HTTP_PORT
- BASIC_AUTH_COMMENT_OUT
- BASIC_AUTH_USERNAME
- BASIC_AUTH_PASSWORD
コンテナイメージ定義 Dockerfile
で Squid HTTP Proxy の構築をします。
FROM alpine:3.10
# Set correct environment variables.
ENV HOME /root
ENV LANG en_US.UTF-8
ENV LC_ALL en_US.UTF-8
# install PKGs.
RUN apk update && \
apk --no-cache add squid libintl apache2-utils && \
apk --no-cache add --virtual .gettext gettext && \
cp /usr/bin/envsubst /usr/local/bin/envsubst && \
apk del .gettext
# edit squid settings.
COPY squid.conf.template /etc/squid/squid.conf.template
# user.
RUN chown -R squid:squid /etc/squid/ /var/run/
USER squid
# entrypoint.
ENTRYPOINT /bin/sh -c " \
/bin/touch /etc/squid/passwd && \
/usr/bin/htpasswd -b /etc/squid/passwd ${BASIC_AUTH_USERNAME} ${BASIC_AUTH_PASSWORD} && \
/usr/local/bin/envsubst < /etc/squid/squid.conf.template > /etc/squid/squid.conf && \
/usr/sbin/squid -N -d 1 -f /etc/squid/squid.conf "
最後に squid.conf.template
です。 長いので 設定ファイルのリンク だけ。
標準の squid.conf
に、以下の設定と envsubst
用の変数を埋め込んでいます。
- BASIC 認証 の設定を追加しました
- 待受ポート は環境変数で変更できるようにしました
- キャッシュは OFF にしました
- ログは stdout に出す 様にしました (コンテナ化の流儀)
あとはビルドして起動します。
docker-compose build
docker-compose up -d
待受ポートをホストにフォワードしているので、ローカルアクセスできます。
[面倒] HTTP プロキシを経由しないとインターネットに出れない環境を作る
実際にテストする際に、Default Gateway からインターネットに出れちゃう環境だと、ちゃんとプロキシ経由してるか (漏れてて直接インターネットアクセスしてるのあるかも) 保証できないので、そういう環境を作りたいと思います。
作業用の OS イメージは、比較的ユーザーが多いであろう
ubuntu:18.04
でいきます。
先程の docker-compose.yml
を修正します。
version: '3.1'
services:
# ↓ここを足しました。
app:
image: ubuntu:18.04
entrypoint:
- tail
- -f
- /dev/null
privileged: true
squid:
build: ./squid
expose:
- "${HTTP_PORT}"
ports:
- "${HTTP_PORT}:${HTTP_PORT}"
environment:
- HTTP_PORT
- BASIC_AUTH_COMMENT_OUT
- BASIC_AUTH_USERNAME
- BASIC_AUTH_PASSWORD
コンテナ起動しなおします。
docker-compose down
docker-compose up -d
コンテナ app
に入ります。
docker exec -it squid-for-http-proxy-testing_app_1 bash
ネットワークをいじる為に必要なコマンドを入れます。
apt update
apt install -y net-tools iputils-ping curl
アプリケーションを動作させる為に必要な物があれば、このタイミングで一緒にインストールしておきます。
この時点ではインターネットにアクセスできます。
curl google.com
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com/">here</A>.
</BODY></HTML>
ルーティングテーブルを見てみます。
① Default Gateway と ② Docker ネットワーク (他のコンテナ) へのルーティングがあります。
route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default 172.23.0.1 0.0.0.0 UG 0 0 0 eth0
172.23.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
① Default Gateway のルーティングを消します。 (かなり荒っぽい方法ですが...)
route delete default
route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
172.23.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
インターネットにアクセスできなくなりました。
curl google.com
curl: (6) Could not resolve host: google.com
プロキシ設定をします。
export http_proxy=http://squid:3128
export https_proxy=${http_proxy}
- ホスト名
squid
は、Squid Proxy コンテナの IP172.xx.xx.xx
を指してします。- 当然ですが、上記の設定は、この bash プロセス上だけで有効です。
HTTP プロキシを経由してインターネットに出れました。
curl google.com
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com/">here</A>.
</BODY></HTML>
あとは docker cp {ローカルファイル} {コンテナ名}:/root/
等を使って、この環境にアプリケーションを送信し、アプリケーションの動作・テストします。