どうもネトヲです。
いま関わっている業務にて、端末ログ取得用にプロキシサーバが必要になりましたので、備忘録がてら構築手順を記録しておきます。
ゴールとしては、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でアクセスし、一応、諸々更新します。
1.3. squid-openssl等インストール
今回はSSL intercept対応プロキシサーバとなるので、squid-opensslをインストールします。
これで必要なパッケージが全て入ります。
apt install -y squid-openssl
squid -v
ついでに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コンフィグ追加
んで、私は追加したのは以下です(全て最終行に追加)。
ログフォーマットは色々とカスタム出来ます。今回は取り上げないのでググってください。
# キャッシュしない
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
あと待ち受けポートは
のままとしてますので、ufwにてポートを空けておきます。
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
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
としてますが、脳死で
としてもいいと思います。
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 となるように設定が必要になります。
具体的には以下のサイトの通りやればいいです。
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箇所を編集していきます。
先頭に挿入
# 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
# 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)