Raspberry Pi OS + SQUID + SSL BumpでHTTPS対応プロキシサーバを立てる方法(ルート証明書インストールまで)

どうもネトヲです。

いま関わっている業務にて、端末ログ取得用にプロキシサーバが必要になりましたので、備忘録がてら構築手順を記録しておきます。

ゴールとしては、SSL interceptに対応したプロキシサーバをRasbperry Pi上に構築することになります。

注意としては

  • LinuxのCLI操作に抵抗がない方が対象
  • オレオレ証明書を使用するのでクライアントに証明書をインストールする必要はある
  • 不正アクセスや踏み台等セキュリティーに関する設定はスキップ(=そのままの設定で運用するのはNG)

構築と検証に用いた環境です

  • MacBook Pro v15.2
  • Raspberry Pi4 ModelB 4GB
  • iPad Pro v18.2
  • Pixel 7 Pro v15

今回の作業にて使用した端末はMacですが、Windowsでも大丈夫かと思います。

1. 基本設定

1.1. Raspberry Pi OSインスコ

もはや説明不要ですが公式が配布しているインストーラを使ってSDカードにOSを焼きます。

公式インストーラにてRaspberry Pi OSをインストールすると、ユーザ名やSSHなどの設定が事前に出来るのでオススメです(固定IPアドレスが出来るといいんだがね)。

1.2. 起動 & パッケージ更新

適当な端末からラズパイにSSHでアクセスし、一応、諸々更新します。

  • apt update
  • apt upgrade

1.3. squid-openssl等インストール

今回はSSL intercept対応プロキシサーバとなるので、squid-opensslをインストールします。

これで必要なパッケージが全て入ります。

  • apt install -y squid-openssl
  • squid -v
Squid Cache: Version 5.7

ついでにufwもインストールしておきましょう

  • apt install -y ufw

2. 非SSL interceptなSQUID構築

2.1. SQUIDコンフィグファイルバックアップ

トラブったときに役立つのでやっておくのが吉です。

  • cp -p /etc/squid/squid.conf /etc/squid/squid.conf.org

2.2. SQUIDコンフィグ確認

Rocky LinuxのSQUIDのコンフィグと結構違うっぽいです。

そしてほぼコメントアウトなので、それを除くための魔法のコマンドを投入します(私は全く理解してない)。

  • cat /etc/squid/squid.conf | grep -v “^\s$” | grep -v “^\s#”
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 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 deny !Safe_ports
http_access deny 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_port 3128
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 .		0	20%	4320

ググってみると「基本コレでええよ」とのことです。

例えば

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

はlocalnetの定義が書いており、今回、アクセス元端末は特に限定しないので、まあ確かに「これでええか」ってなりました。

2.3. SQUIDコンフィグ追加

んで、私は追加したのは以下です(全て最終行に追加)。

ログフォーマットは色々とカスタム出来ます。今回は取り上げないのでググってください。

  • vi /etc/squid/squid.conf
# キャッシュしない
acl NOCACHE src all
cache deny NOCACHE
# 日時を読みやすいフォーマットに変更
logformat localtime %{%Y-%m-%d %H:%M:%S}tl.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %[un %Sh/%<a %mt
access_log daemon:/var/log/squid/access.log localtime

あと待ち受けポートは

http_port 3128

のままとしてますので、ufwにてポートを空けておきます。

  • ufw status
Status: inactive
  • ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup 
  • ufw allow proto tcp to 0.0.0.0/0 port 3128
  • ufw allow proto tcp to 0.0.0.0/0 port 22
Rules updated
  • ufw reload
Firewall reloaded
  • ufw status
Status: active

To                         Action      From
--                         ------      ----
3128/tcp                   ALLOW       Anywhere                  
22/tcp                     ALLOW       Anywhere   

今回はv4アドレスだけが対象なので一応

ufw allow proto tcp to 0.0.0.0/0 port 3128

としてますが、脳死で

ufw allow 3128

としてもいいと思います。

2.4. SQUID再起動

  • systemctl restart squid
  • systemctl status squid
● squid.service - Squid Web Proxy Server
     Loaded: loaded (/lib/systemd/system/squid.service; enabled; preset: enabled)
     Active: active (running) since Mon 2025-01-06 16:21:44 JST; 20s ago

コンフィグ投入後、SQUIDを再起動します。

大したコンフィグを入れてないのでエラーなくサービスが上がりました。

2.5. 動作確認

Macにプロキシ設定を投入し動作確認を行います。

プロキシ設定方法で注意なのが「保護されたWebプロキシ」にも設定を入れておかないと、HTTPSでの通信がパススルーという点です。

よく考えれば当たり前の話ですが、実は私ココでハマってました。。

プロキシ設定後、「阿部 寛のホームページ」にアクセスすると

「指定された URL を取得できませんでした」と表示されました。

明らかにSQUIDのACLで弾かれてる感じですね。

2.6. トラシュー

コンフィグを見直します。

http_access allow localhost

あ、ここよくみるとlocalhostになってますね。localnetだと勘違いしてました。

なので、

#http_access allow localnet
http_access allow localhost

#http_access allow localnet
http_access allow localnet
http_access allow localhost

と変更しました。

すると無事「阿部 寛のホームページ」が閲覧でき、

ログにも

  • tail -f /var/log/squid/access.log
2025-01-06 17:15:22.274     39 192.168.100.7 TCP_MISS/200 882 GET http://abehiroshi.la.coocan.jp/ - HIER_DIRECT/222.158.205.72 text/html
2025-01-06 17:15:29.942     28 192.168.100.7 TCP_MISS/200 2742 GET http://abehiroshi.la.coocan.jp/image/movie.jpg - HIER_DIRECT/222.158.205.72 image/jpeg

と、アクセス先のpath含めロギング出来ていることが確認できました。

HTTPSなサイト(私のブログ)についても、アクセスは出来ているんですが…

  • tail -f /var/log/squid/access.log
2025-01-06 17:19:44.461 240178 192.168.100.7 TCP_TUNNEL/200 5687 CONNECT googleads.g.doubleclick.net:443 - HIER_DIRECT/172.217.31.130 -
2025-01-06 17:19:45.684   5190 192.168.100.7 TCP_TUNNEL/200 5047 CONNECT www.tuuzyouno3bai.com:443 - HIER_DIRECT/203.136.219.119 -

と、pathが消えているのがわかりますね。

それを出すためにSSL Bumpを使うというワケです。

2.7. 2章での最終的なSQUIDコンフィグ

ってなわけで本章での最終的なコンフィグです。

  • cat /etc/squid/squid.conf | grep -v “^\s$” | grep -v “^\s#”
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 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 deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
include /etc/squid/conf.d/*.conf
http_access allow localnet
http_access allow localhost
http_access deny all
http_port 3128
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 .		0	20%	4320
acl NOCACHE src all
cache deny NOCACHE
logformat localtime %{%Y-%m-%d %H:%M:%S}tl.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %[un %Sh/%<a %mt
access_log daemon:/var/log/squid/access.log localtime

3. SSL interceptなSQUID構築

3.1. 設定の仕込み

恐らくネットに転がっている構築方法ではいきなり自己署名証明書の作成をしているかと思いますが、その証明書をAndroidにインストールしようとすると

証明書をインストールするには、秘密鍵が必要です

と表示されインストールできません。

その対策として証明書作成で、CA証明書を作成する際に、証明書の詳細で X509v3 Basic Constraints: CA:TRUE となるように設定が必要になります。

具体的には以下のサイトの通りやればいいです。

Androidで、自己署名証明書を入れようとしたら”証明書をインストールするには、秘密鍵が必要です” と出る

Android11以降では、自己署名証明書を入れようとしたら、下の画像のように「証明書をインストールするには、秘密鍵が必要です」と出てインストールできません。プライベート認証局(オレオレ認証局)の証明書作成時に、本記事で説明の設定が必要です…

  • cd /etc/squid/
  • echo ‘basicConstraints=CA:true’ > android_options.txt

こちらにて仕込み完了です。

3.2. 自己署名証明書(ルート証明書)作成

ここはほぼ「ネットに転がっている構築方法」通りです。

  • cd /etc/squid/
  • openssl genrsa -out bump.key 4096
  • openssl req -new -key bump.key -out bump.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:JP
State or Province Name (full name) [Some-State]:
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
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

先ほど仕込んだファイルを指定するのを忘れずに。

  • openssl x509 -in bump.csr -out bump.crt -req -signkey bump.key -days 3650 -sha256 -extfile ./android_options.txt
Certificate request self-signature ok
subject=C = JP, ST = Some-State, O = Internet Widgits Pty Ltd, CN = SQUID

3.3. 証明書パーミッション変更

作成した証明書の所有者を「proxy」にするなど、パーミッションを変更します。

  • chown proxy: /etc/squid/bump*
  • chmod 400 /etc/squid/bump*

3.4. なんかする

Diffie-Helmanの鍵交換アルゴリズムのなんかをなんかします(よくわからん)。

ラズパイの性能が終わっているせいか、5分くらい待たされます。

  • openssl dhparam -outform PEM -out /etc/squid/bump_dhparam.pem 2048

3.5. サーバ証明書キャッシュDB作成

security_file_certgenのpathに注意してください。

  • mkdir -p /var/lib/squid
  • /usr/lib/squid/security_file_certgen -c -s /var/lib/squid/ssl_db -M 20MB
Initialization SSL db...
Done
  • chown -R proxy: /var/lib/squid

3.6. SQUIDコンフィグ編集

3箇所を編集していきます。

  • vi /etc/squid/squid.conf

先頭に挿入

#       WELCOME TO SQUID 5.7
#       ----------------------------

↓

# SSL Bump用            
acl intermediate_fetching transaction_initiator certificate-fetching
http_access allow intermediate_fetching
#       WELCOME TO SQUID 5.7
#       ----------------------------

2100行あたりを編集

http_port 3128 

↓

#http_port 3128                               
# SSL Bump用
http_port 3128 tcpkeepalive=60,30,3 ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=20MB tls-cert=/etc/squid/bump.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
  • 末尾に追記(pathに注意)
# SSL Bump用
sslcrtd_program /usr/lib/squid/security_file_certgen -s /var/lib/squid/ssl_db -M 20MB
sslproxy_cert_error allow all 
sslproxy_flags DONT_VERIFY_PEER
always_direct allow all
ssl_bump stare all

コンフィグ編集後、SQUIDを再起動します。

  • systemctl restart squid
  • systemctl status squid
● squid.service - Squid Web Proxy Server
     Loaded: loaded (/lib/systemd/system/squid.service; enabled; preset: enabled)
     Active: active (running) since Mon 2025-01-06 18:17:33 JST; 18s ago

3.7. 動作確認

「阿部 寛のホームページ」は問題なく閲覧できロギングも出来てます。

  • tail -f /var/log/squid/access.log
2025-01-06 18:22:03.966     31 192.168.100.7 TCP_MISS/200 882 GET http://abehiroshi.la.coocan.jp/ - HIER_DIRECT/222.158.205.72 text/html
2025-01-06 18:22:08.434     25 192.168.100.7 TCP_MISS/200 2089 GET http://abehiroshi.la.coocan.jp/photo/photo.htm - HIER_DIRECT/222.158.205.72 text/html

一方、HTTPSなサイト(私のブログ)にアクセスすると、「接続はプライベートではありません」とでました。

証明書をチェックしてみると、先ほど作成した「SQUID」にちゃんとなってました(私のブログはR11を使ってます)。

んではログはどうなっているかというと

  • tail -f /var/log/squid/access.log
2025-01-06 18:25:26.033    159 192.168.100.7 TCP_MISS/200 30895 GET https://www.google.com/recaptcha/api2/anchor? - HIER_DIRECT/172.217.175.100 text/html
2025-01-06 18:25:26.034    144 192.168.100.7 TCP_MISS/200 139322 GET https://www.tuuzyouno3bai.com/wp-content/uploads/2024/12/DSC01932.jpg - HIER_DIRECT/203.136.219.119 image/jpeg

以下の通り、path含めてちゃんとロギング出来ていることが確認できました。

GET https://www.tuuzyouno3bai.com/wp-content/uploads/2024/12/DSC01932.jpg

4. 自己署名証明書をクライアントへインストール

HTTPSについてもロギングができるようになりましたが、このままでは使い勝手が非常に悪いのでクライアントに自己署名証明書をインストールしていきます。

4.1. 下準備

3.2. にて作成した自己署名証明書(/etc/squid/bump.crt)をSCPなりでローカルに落としておいてください。

4.2. Mac

bump.crtをダブルクリックすると「キーチェーンアクセス」が開きます。

そのなかに先ほど作成した「SQUID」がいますので「情報を見る」で開きます。

そしたら「信頼」を押して「システムデフォルトを使用」から「常に信頼」に変更します。

そしてウィンドウを閉じると、Macのパスポートを聞かれるので、入力したら完了です。

そして再びHTTPSなサイト(私のブログ)にアクセスすると、「この証明書は有効です」と表示が変わっていることが確認できました。

また、先ほどはアクセスしていないYahooについても警告がでることなくアクセスでき、証明書も「SQUID」になっていました。

4.3. iPad(iPhone)

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です