背景
社内の認証ありプロキシサーバーはソフトウェア開発を行う上では邪魔でしかありません.
認証ありプロキシに対応していないアプリ,パスワード変更による毎回の設定変更,開発メンバー間での設定差分……これらの問題にいつも頭を悩まされていました.
そこで調べてみると先人たちがSquidを使って認証代行プロキシサーバーを立てている1ことを知り,私もMac上にSquidを立てて使っていました.(とても便利!)
しかし,開発メンバーから「そんなの使っててセキュリティは大丈夫なの?」,「他のメンバーと環境変わっちゃうからそんなのだめだよ」みたいなことを言われうようになりました.
仕方がないのでMac用の認証代行プロキシ構築スクリプトをメンバーに展開して環境の統一には一応成功しました.
しかし,中身(特にSquid)の仕組みはあんまり展開していないので,もし問題があった場合は自分が見なきゃいけない状況になってしまっており,他プロジェクトへの展開があまりできていない状況です.
今回はDockerのみで極力シンプルに認証代行プロキシサーバーを構築できるようにしたので,その仕組みをSquidの設定を中心に紹介します.
つくったもの
今回は以下リポジトリを紹介します.
最新の情報はここを参照するようにしてください.
前提条件
Docker(Docker Compose)がインストールされていれば動作するはずです.
私が使ったDockerのバージョンは以下でした.
$ docker version
(中略)
Server: Docker Engine - Community
Engine:
Version: 19.03.12
API version: 1.40 (minimum version 1.12)
(後略)
$ docker --version
Docker version 19.03.9, build 9d988398e7
$ docker-compose --version
docker-compose version 1.26.2, build eefe0d31
全体像
Dockerコンテナ上に認証代行プロキシサーバー(Squid)を立てて,認証情報(Authorizationヘッダー)を付与するようにします.
こうすることでプロキシを利用するアプリケーションからは,認証なしでインターネットに接続できるようなります.
Squidの設定
squid.conf.templateの設定を1つずつ説明していきます.
基本的な設定
待受ポートは8080に設定します.
visible_hostname
は設定しないと「未設定だよ」とエラーが表示されるためnone
に設定します2.
DNSはONにします.これを設定しておくとドメイン名のプロキシサーバーを指定できるようになります.(ならない環境もあるみたいですが……要因わからずです)
http_port 8080
visible_hostname none
dns_defnames on
ACLの定義
SquidのACL(Access Control)を定義します.
localnet
はローカルネットワークからのアクセス,to_localnet_fast
はローカルネットワークへのアクセス,to_localhost_fast
はローカルホストへのアクセス,to_direct_access_domains
は指定ドメインへのアクセスを定義しています.
dst
(デスティネーション)のACLでは-n
フラグを指定して,DNS Lookupを無効にしています.有効にしてしまうと,ネットワークアクセスがものすごく低速になります.
また,to_direct_access_domains
は.direct_access_domains
に指定されたドメインを取り込むように指定しています3.
acl localnet src 0.0.0.1-0.255.255.255
acl localnet src 10.0.0.0/8
(中略)
acl to_localnet_fast dst -n 0.0.0.1-0.255.255.255
acl to_localnet_fast dst -n 10.0.0.0/8
(中略)
acl to_localhost_fast dst -n 127.0.0.0/8
acl to_direct_access_domains dstdomain -n "/.direct_access_domains"
Squidへのアクセス許可
Squidへのアクセスを許可するネットワークを指定します.
内部ネットワークからのアクセスのみを許可しています4.
http_access allow localhost
http_access allow localnet
認証ありプロキシサーバーへの転送設定
認証ありプロキシサーバーへの転送を行うリクエストを指定します.
Squidはデフォルトでは「cache_peer
で指定されたプロキシへの転送を試みて,無理なら直接接続を試みる」動作なので,never_direct allow <直接接続を許可する接続先以外の接続先>
で直接接続を禁止する接続先を指定します5.
cache_peer
で親プロキシ(認証ありプロキシ)を指定します.
$proxy_port
などの変数はDockerコンテナの起動時にenvsubst
で置き換えます.
never_direct allow !to_localhost_fast !to_localnet_fast !to_direct_access_domains
cache_peer $proxy_host parent $proxy_port 0 proxy-only no-digest no-netdb-exchange login=$proxy_auth
Squidを秘匿化する設定
SquidなどのプロキシサーバーはデフォルトではPROXY_VIA
などの「プロキシを通していますよ」という情報を乗せる動作となります.
環境によっては通信ヘッダが異なると通信できなくなってしまう可能性があるので,Squidが勝手に乗せる情報を削除します.
また,転送のみの動作とさせるため,cache deny all
でSquidのキャッシュを無効化しています.
forwarded_for delete
via off
cache deny all
request_header_access Cache-Control deny all
request_header_access Connection deny all
request_header_add Proxy-Connection "Keep-Alive" all
Dockerでの認証代行プロキシ立ち上げ
Dockerイメージのビルドと起動はDocker Compose経由で行います.
ビルドするのにもプロキシの設定が必要なので,環境変数にHTTP_PROXY_FOR_PROXY
を設定してビルド,起動を行うようにします.
ベースイメージ(Alpine)のpullを行うにはDocker Daemon側へのプロキシ設定が必要ですが,Docker実行環境によって設定方法が異なっているので,pullでダウンロードするのではなくloadでローカルのイメージを読み込むようにしています.
<proxy_user>
,<proxy_password>
に記号が入っている場合はURLエンコードした値を入れる必要があります.
cd proxy-docker
docker load ./alpine.tar
HTTP_PROXY_FOR_PROXY=http://<proxy_user>:<proxy_password>@<proxy_host>:<proxy_port> HOST_PORT=8080 docker-compose up -d
Docker Composeの設定
docker-compose.yml
にビルド,起動を行うときのパラメータを定義しています.
HTTP_PROXY
とHTTPS_PROXY
をargs
(ビルド時の環境変数),environment
(起動時の環境変数)に入れるようにしています.
また,HOST_PORT
でホスト側のポートを設定できるようにしています.
8080ポートが既に埋まっている場合は別のポートを指定できます.
version: "3.4"
x-proxy_settings: &proxy_settings
HTTP_PROXY: "${HTTP_PROXY_FOR_PROXY:?HTTP_PROXY_FOR_PROXY must be set. Prease read README}"
HTTPS_PROXY: "${HTTP_PROXY_FOR_PROXY}"
services:
proxy:
build:
context: .
args:
<<: *proxy_settings
environment:
<<: *proxy_settings
ports:
- "${HOST_PORT:-8080}:8080"
Dockerfileの設定
長いので中身は割愛しますが,以下を行っています.
- ビルド時
HTTP_PROXY
に設定された値を使ってインターネットに接続し,Squidをインストール - 起動時
HTTP_PROXY
に設定された値を使ってSquidの設定ファイルを修正,Squidを立ち上げ
まとめ
Squidを使った認証代行プロキシサーバーの設定について,それをDockerで立ち上げる方法について簡単に紹介しました.
これらの情報を使って少しでも多くの方が認証ありプロキシの不便から脱却できることを願っています.
-
認証ありプロキシを認証なしにするDockerコンテナとか,squid で認証ありプロキシによるストレスを軽減するとか,mac上にHTTPプロキシを立てることで認証プロキシの認証をスキップするとか,他にもたくさんあります. ↩
-
社内ポータルサイトなどのプロキシ除外ドメインを簡単に設定できるように別ファイルから取り込むようにしています. ↩
-
VirtualBoxなどの仮想環境からのアクセスを許可するために,localhostだけでなくlocalnetからのアクセスも許可しています. ↩
-
always_direct allow <直接接続を許可する接続先>
としないのはVPN経由で社内ネットワークに接続しているときはプロキシ経由で接続するからです. ↩