LoginSignup
5
3

More than 3 years have passed since last update.

認証代行プロキシサーバーをDockerを使って構築する

Last updated at Posted at 2020-11-14

背景

社内の認証ありプロキシサーバーはソフトウェア開発を行う上では邪魔でしかありません.
認証ありプロキシに対応していないアプリ,パスワード変更による毎回の設定変更,開発メンバー間での設定差分……これらの問題にいつも頭を悩まされていました.
そこで調べてみると先人たちが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ヘッダー)を付与するようにします.
こうすることでプロキシを利用するアプリケーションからは,認証なしでインターネットに接続できるようなります.

alt

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_PROXYHTTPS_PROXYargs(ビルド時の環境変数),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で立ち上げる方法について簡単に紹介しました.
これらの情報を使って少しでも多くの方が認証ありプロキシの不便から脱却できることを願っています.


  1. 認証ありプロキシを認証なしにするDockerコンテナとか,squid で認証ありプロキシによるストレスを軽減するとか,mac上にHTTPプロキシを立てることで認証プロキシの認証をスキップするとか,他にもたくさんあります. 

  2. squidを久々に起動しようとしたらerrorになる、visible_hostnameを設定やて! 

  3. 社内ポータルサイトなどのプロキシ除外ドメインを簡単に設定できるように別ファイルから取り込むようにしています. 

  4. VirtualBoxなどの仮想環境からのアクセスを許可するために,localhostだけでなくlocalnetからのアクセスも許可しています. 

  5. always_direct allow <直接接続を許可する接続先>としないのはVPN経由で社内ネットワークに接続しているときはプロキシ経由で接続するからです. 

5
3
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
5
3