るるぷらす

るるぷらす、だおー

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