Docker を利用して Web キャッシュサーバーを構築する(Squid/Ubuntu)
少しでも Web ブラウジングを快適にするために Web キャッシュサーバーを構築する。そうすることで画像などのデータが LAN 内に蓄積されるので少しでも速度が上がればいいなという自己満足。
Web キャッシュサーバーは dolipo(polipo) や SquidMan(Squid) などを利用してきていたが、近年の https 推進の影響によりこれらのキャッシュサーバーの活躍度が減ってしまっていた。今回は https 化されたサイトも含めて画像をサーバ側に蓄積させてキャッシュできるかの何度目かの実験です。
今回は Docker を利用します。Docker Desktop のセットアップについては 前回の記事 をご参照ください。
更新履歴
- 2025年3月19日 … LINE に繋がっていなかったので PAC ファイルに .line-apps.com を追加、Docker コンテナの自動起動設定を追加
- 2025年3月18日 … PAC ファイル置き場として使用していた Simple PHP Server が思ったよりも安定しなかったので、Apache2 の Docker コンテナに移行
- 2025年3月17日 … 掲載
▼ Squid のセットアップおよび設定(https 通信も対応させる)
1. https://hub.docker.com/r/ubuntu/squid にアクセスし、最新の docker run を確認

2. docker run のタイムゾーンを JST に変更
3. 下記のコマンドを実行
本来なら docker run 時に -v オプションでパスを Docker の外に出すことができるハズなんだけど、私の環境では -v を付けると Docker コンテナが正しく立ち上がらないため、今回は素の状態で docker run しています。
docker run -d --name squid-container -e TZ=JST -p 3128:3128 ubuntu/squid:5.2-22.04_beta docker exec -it squid-container /bin/bash apt-get update apt-get install vim apt-get install squid-openssl cd /etc/squid/ openssl req -new -newkey rsa:2048 -days 3653 -nodes -x509 -keyout bump.key -out bumpCA.crt
Country Name (2 letter code) [AU]:JP State or Province Name (full name) [Some-State]:Tokyo Locality Name (eg, city) []: Organization Name (eg, company) [Internet Widgits Pty Ltd]: Organizational Unit Name (eg, section) []: Common Name (e.g. server FQDN or YOUR name) []:Squid Private CA Email Address []:
openssl dhparam -outform PEM -out bump_dhparam.pem 2048 chown proxy:proxy /etc/squid/bump* chmod 400 /etc/squid/bump* mkdir /var/lib/squid /usr/lib/squid/security_file_certgen -c -s /var/lib/squid/ssl_db -M 16MB chown -R proxy:proxy /var/lib/squid openssl x509 -in bumpCA.crt -out tmp.der -outform DER openssl x509 -in tmp.der -inform DER -out bumpCA.pem -outform pem
参考:Squidを使ってHTTPSのWebサイトへの通信を復号してみよう #Security - Qiita
3. /etc/squid/bumpCA.pem をダウンロード
Docker Desktop を開く
Containers > squid-container > Files を開く
Last modified ↓ でソート
etc > squid を開く
bumpCA.pem を右クリック、Save をクリック
Drobo > Temp などに保存

4. squid.conf を更新(/etc/squid/squid.conf)- 上記と同じフォルダにある

5. コンテナを Restart
6. bumpCA.pem を iCloud Drive に保存
▼ 証明書(bumpCA.pem)のインストール for iOS/iPadOS
iOS デバイスにプロキシをそのまま(手動)で設定するとすべてのアプリの通信が Squid 経由になってしまいます。一部のアプリケーションでは正しく動かないので、特定の Web サイトを除外するために PAC ファイル(プロキシ自動設定ファイル)を利用します。
PAC ファイルをアップロードする場所については Web Server があればどこにアップしてもいいですが、今回は https://hub.docker.com/_/httpd を参考に Docker コンテナを設置しました。
docker run -dit --name apache2-pac -p 3129:80 httpd:2.4
/usr/local/apache2/htdocs/ に squid.pac を Import
1. すべてのアプリを終了
2. ファイル.app > 書類フォルダを開く
3. bumpCA.pem をタップし、ダウンロード
4. デバイスを選択:iPhone

5. プロファイルがダウンロードされました:閉じる
6. 設定.app > ダウンロード済みのプロファイル > インストール
→ 
7. パスコードを入力し、再びインストールをタップ > 完了

8. 設定 > 一般 > 情報 > 証明書信頼設定 > ルート証明書を全面的に信頼:オン

9. Wi-Fi > i > HTTP プロキシ > プロキシを構成 > 自動
10. URL:http://192.168.1.3:3129/squid.pac

ブラウザでネットにアクセス出来れば OK
▼ 証明書(bumpCA.pem)のインストール for macOS
1. bumpCA.pem をダブルクリックし、キーチェーンアクセスにインポート

2. 証明書を再読み込みするためにいったん デフォルトキーチェーン > iCloud を表示
3. その後、ログイン > 証明書 タブを開く

4. Squid Private CA をダブルクリック
5. "信頼" を開く、この証明書を使用するとき:常に信頼 に変更

6. Squid Private CA ウィンドウを閉じる
7. パスワードを入力し、設定をアップデート

備考:キーチェーンアクセス.app は下記の場所にある
MacHD: システム > ライブラリ > CoreServices > Applications > キーチェーンアクセス.app
'/System/Library/CoreServices/Applications/Keychain Access.app'
8. Firefox を再起動
9. Firefox で設定
Firefox > 設定 を開く
一般 > ネットワーク設定 > 接続設定... を開く
インターネット接続に使用するプロキシーの設定:手動でプロキシーを設定する
このプロキシーを HTTPS でも使用する:有効

keepa は上手く動かなかったので除外
私は Firefox 派なのでその他のブラウザについては動作確認していません。
その他のブラウザで試す場合は、プロキシを指定するアドオン(機能拡張)をいれるか、システム側で PAC ファイルを読み込むなどの方法をご検討ください。
▼ Squid のメンテナンス
アクセステスト
docker exec -it squid-container /bin/bash tail -f /var/log/squid/access.log
動かないサイトやアプリがある場合はアクセスログをチェックし、それっぽいアドレスを "ブラウザで除外(プロキシーなしで接続)"、"squid.conf で ssl_bump splice を設定"、"PAC ファイルで除外" のいずれかで対処する必要があるかもしれません。
コンフィグの調整
docker exec -it squid-container /bin/bash vi /etc/squid/squid.conf
キャッシュ容量チェック
docker exec -it squid-container /bin/bash du -sh /var/spool/squid

たまにチェックして容量が増えていることを確認。ある程度はパージされていくので増えすぎることはないハズ。
▼ 各コンテナの自動起動を設定
ホストとなる Mac を再起動したときも自動的に立ち上がるように設定
docker inspect -f "{{.Name}} {{.HostConfig.RestartPolicy.Name}}" $(docker ps -aq) | grep alwaysこのコマンドで何も出てこない場合はコンテナの自動起動が設定されていません。
docker update --restart=always squid-container docker update --restart=always apache2-pac
設定を行うと下記のように反応が返ってくるようになります。

== squid.pac sample ==
PAC ファイル(プロキシ自動設定ファイル)では Apple/iCloud 関連の通信に関してプロキシを経由しないように除外する設定を追加しています。これらのサイトは ssl_bump splice で指定しても上手く動作しなかったので苦肉の策として PAC ファイルを使用することにしました。
function FindProxyForURL(url, host)
{
//Access images directly
if (dnsDomainIs(host, ".apple.com")) return "DIRECT";
if (dnsDomainIs(host, ".icloud.com")) return "DIRECT";
if (dnsDomainIs(host, ".mzstatic.com")) return "DIRECT";
if (dnsDomainIS(host, ".line-apps.com")) return "DIRECT";
//For everything else use stg proxy
return "PROXY 192.168.1.3:3128";
}
== squid.conf sample ==
こちらは参考までに。外からアクセスすることはまったく想定しておらず LAN 内で利用するようにセットアップしています。
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 acl localnet src 192.168.1.0/24 # LAN IP range acl localnet src 192.168.3.0/24 # Wi-Fi IP range acl domain ssl::server_name api.twitter.com acl domain_https dstdomain api.twitter.com 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 http_access allow !Safe_ports http_access allow CONNECT !SSL_ports # http_access allow localhost manager # http_access deny manager include /etc/squid/conf.d/*.conf # http_access allow localhost # http_access deny all http_access allow domain http_access allow domain_https http_access allow all # SSL Bumpのオプションを追加 # http_port 3128 tcpkeepalive=60,30,3 ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=16MB tls-cert=/etc/squid/bumpCA.crt tls-key=/etc/squid/bump.key cipher=HIGH:MEDIUM:!LOW:!RC4:!SEED:!IDEA:!3DES:!MD5:!EXP:!PSK:!DSS options=NO_TLSv1,NO_SSLv3,SINGLE_DH_USE,SINGLE_ECDH_USE tls-dh=prime256v1:/etc/squid/bump_dhparam.pem http_port 3128 tcpkeepalive=60,30,3 ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=16MB tls-cert=/etc/squid/bumpCA.crt tls-key=/etc/squid/bump.key cipher=HIGH:MEDIUM:!LOW:!RC4:!SEED:!IDEA:!3DES:!MD5:!EXP:!PSK:!DSS options=SINGLE_DH_USE,SINGLE_ECDH_USE tls-dh=prime256v1:/etc/squid/bump_dhparam.pem # 証明書生成設定 sslcrtd_program /usr/lib/squid/security_file_certgen -s /var/lib/squid/ssl_db -M 16MB # 証明書の検証エラーでも許可する sslproxy_cert_error allow all # すべての通信をデコード対象とする ssl_bump splice domain ssl_bump splice domain_https ssl_bump stare all # disk and memory cache settings cache_dir ufs /var/spool/squid 160000 16 256 maximum_object_size 16 MB cache_mem 2 GB maximum_object_size_in_memory 4 MB coredump_dir /var/spool/squid refresh_pattern ^ftp: 1440 20% 10080 refresh_pattern ^gopher: 1440 0% 1440 refresh_pattern -i (/cgi-bin/|\?) 0 0% 0 refresh_pattern \/(Packages|Sources)(|\.bz2|\.gz|\.xz)$ 0 0% 0 refresh-ims refresh_pattern \/Release(|\.gpg)$ 0 0% 0 refresh-ims refresh_pattern \/InRelease$ 0 0% 0 refresh-ims refresh_pattern \/(Translation-.*)(|\.bz2|\.gz|\.xz)$ 0 0% 0 refresh-ims refresh_pattern . 0 20% 4320 logformat squid %tl %>a %Ss/%03>Hs %<st %rm %ru %[un %Sh/%<a %mt httpd_suppress_version_string on visible_hostname unknown forwarded_for off # performance options pipeline_prefetch 10 cache_miss_revalidate on read_ahead_gap 256 KB cache_replacement_policy lru memory_replacement_policy lru