ローカルに検証用のプロキシサーバーを立てる方法を調べていて、Squid を使った方法を備忘録のためメモしておく。
Linux 向けの情報はよく出てくるけど、Mac 環境です。
インストール
Mac の場合、Homebrew 経由でインストールできる。
$ brew install squid
起動
ref. https://docs.brew.sh/Manpage#services-subcommand
$ brew services run squid
または
$ brew services start squid
を使う。
前者は一回きりの起動、後者は以後ログイン時に自動的に起動するようになる(はず。未確認)。
動作確認(Basic 認証なし)
この時点で一度動作を確認してみる。
デフォルトで、ポートは 3128 で起動するので、curl の場合
$ curl https://example.com -x http://localhost:3128
を試す。
起動していない、プロキシの URL が間違っているなどの場合は
curl: (7) Failed to connect to localhost port 3129: Connection refused
が返る。
設定ファイル(squid.conf)を確認する
Homebrew でインストールした場合、/usr/local/etc/squid.conf
に設定ファイルが存在する。
ポート番号もここに書かれている。
# # Recommended minimum configuration: # # Example rule allowing access from your local networks. # Adapt to list your (internal) IP networks from where browsing # should be allowed acl localnet src 0.0.0.1-0.255.255.255 # RFC 1122 "this" network (LAN) acl localnet src 10.0.0.0/8 # RFC 1918 local private network (LAN) acl localnet src 100.64.0.0/10 # RFC 6598 shared address space (CGN) acl localnet src 169.254.0.0/16 # RFC 3927 link-local (directly plugged) machines acl localnet src 172.16.0.0/12 # RFC 1918 local private network (LAN) acl localnet src 192.168.0.0/16 # RFC 1918 local private network (LAN) acl localnet src fc00::/7 # RFC 4193 local private network range acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines ... # Squid normally listens to port 3128 http_port 3128 ...
Basic 認証を設定する
ここまでで Basic 認証なしのプロキシサーバーは構築できたので、ここに Basic 認証を設定していく。
htpasswd でユーザー名・パスワードの設定ファイルを生成する
squid の設定の前に、Basic 認証のユーザー名とパスワードを記録したファイルを用意する。
これには htpasswd
というコマンドを使用する。
# コマンドを実行する場所は任意 $ htpasswd -c path/to/.htpasswd [ユーザー名] New password: Re-type new password: Adding password for user [ユーザー名]
.htpasswd
を生成する場所やファイル名はなんでもいい。
squid.conf に Basic 認証用の設定を追加する
先に結論から。
squid.conf の INSERT YOUR OWN RULE(S) ...
の直後に以下を追加する。
# # INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS # auth_param basic program /usr/local/opt/squid/libexec/basic_ncsa_auth [先ほど生成した .htpasswd へのパス] auth_param basic children 5 startup=5 idle=1 auth_param basic realm Squid proxy-caching web server auth_param basic credentialsttl 2 hours acl basic_ncsa proxy_auth REQUIRED http_access allow basic_ncsa
参考
まず、一行目の
auth_param basic program /usr/local/opt/squid/libexec/basic_ncsa_auth [先ほど生成した .htpasswd へのパス]
については、
auth_param <認証方式> program <helper program> <引数>
Squid は Basic 認証以外にも複数の認証方式をサポートしているが、一行目はどれも同じ書き方で、↑のようなフォーマット。
helper program とは
http://www.squid-cache.org/Doc/man/
に一覧があるプログラムのいずれかを指定するよう。
今回のように htpasswd
コマンドで生成したパスワードファイルを扱う場合は NCSA というのを使えばいいらしい。Homebrew でインストールした場合、これらは /usr/local/opt/squid/libexec/
にあるため、上のような指定になった。ググると basic_ncsa_auth
ではなく ncsa_auth
を指定している例が見つかったが、この記事を書いたときの Squid のバージョン(4.11) では basic_ncsa_auth
しか存在しなかった。
また、この program が引数にパスワードファイルを受け取るので、続けて先ほど生成した .htpasswd へのパスを記述する。
auth_param basic
から始まる残りの数行はきちんと理解していない。
http://www.squid-cache.org/Versions/v4/cfgman/auth_param.html を読むとわかるかも。
動作確認(Basic 認証あり)
設定ができたので、Basic 認証ありバージョンを動作確認してみる。
$ brew services stop squid
$ brew services run squid
# または
$ brew services restart squid
で Squid を再起動するのを忘れずに。
curl の場合
$ curl https://example.com -x http://[ユーザー名]:[パスワード]@localhost:3128
でレスポンスが返ってくれば成功。
認証に失敗すると
curl: (56) Received HTTP code 407 from proxy after CONNECT
が返る。
ブラウザで動作確認
システム設定 > ネットワーク > 詳細 > プロキシ
1点ハマったポイントとして、自分の環境では Firefox は問題なかったが、Chrome だとこのプロキシ設定をうまく認識してくれないのか、ローディング中のまま画面が真っ白になった。
回避策としては、
Google Chromeでプロキシを使う方法(Chromeのみ・OS全体) - [開発環境 ツール類/プログラム全般] ぺんたん info
を参考に、Chrome を --proxy-server
オプションつきでコマンドラインから起動したところうまくいった。
$ cd /Applications/Google Chrome.app/Contents/MacOS $ ./Google\ Chrome --proxy-server=localhost:3128
わからなかったこと
Basic 認証用の設定の最後の二行、
acl basic_ncsa proxy_auth REQUIRED http_access allow basic_ncsa
なぜこれが必要なのかよくわからなかった。
# Example rule allowing access from your local networks. # Adapt localnet in the ACL section to list your (internal) IP networks # from where browsing should be allowed http_access allow localnet http_access allow localhost
で、ローカルネットワークからのアクセスが全部OKになっているので、
acl localhost proxy_auth REQUIRED
のようにするのかと思ったが、これだとうまくいかなかった。