OSS

【Rockylinux9】SQUID+ssl_bumpの仕組みと設定

やりたいこと

  1. Rockylinux9 で SQUID を構築し、クライアントからインターネット接続できるようにする
  2. ssl_bump の設定を行い、https 通信の access_log を CONNECT だけでなく GET や POST など復号状態でとれるようにする

前提

RockyLinux9 の minimal install を以下手順で SETUP した状態から始めます。

Rocky Linux 9 minimal (最小限) インストール手順 on VirtualBOX
Rocky Linux 9 を VirtualBOX へインストールする手順を紹...

SQUID 構築手順

まずは squid をインストールします。

[root@localhost ~]# dnf -y install squid

squid サービスを有効化+起動 (enable --now) し、ステータス確認 (status) します。

[root@localhost ~]# systemctl enable --now squid
[root@localhost ~]# systemctl status squid

firewalld で squid のポート (3128/tcp) を穴あけします。

[root@localhost ~]# firewall-cmd --permanent --add-service=squid
[root@localhost ~]# firewall-cmd --reload
[root@localhost ~]# firewall-cmd --list-all

--add-service=squid は --add-port=3128/tcp でも OK です。(service=squid の定義は /usr/lib/firewalld/services/squid.xml に記載されています。)

これだけで SQUID が使えるようになります。

動作確認のため、ログが流れる状態にします。

[root@localhost ~]# tail -f /var/log/squid/access.log

クライアントにて Proxy として {IP= [このサーバの IP], ポート=3128/tcp} を設定し、任意のサイトへ接続し、上記ログが流れることを確認します。

必要に応じて acl の設定をしましょう。例えば特定の送信元 IP からのリクエストは特定の宛先 URL にしか接続させない、と言った設定ができます。

【squid.conf】acl設定書式 ~複数条件や正規表現(url_regex), http_accessの順番, whitelist~
squid.conf の設定 squid.conf では主に acl を定義し...

https と ssl_bump について

近年では https 通信が当たり前ですが、https 通信はクライアントと Web サーバ間の End-to-End で暗号化され、経路途中の機器は基本的には通信の中身は確認できません。

では Proxy はどのように動作するかというと、TCP コネクションは「クライアント⇔Proxy」と「Proxy⇔Web サーバ」の 2 つなのですが、TLS コネクションは 1 つというフローになります。クライアントは "CONNECT" というメソッドを使って Proxy へ TCP 接続し、それを受けて Proxy は Web サーバへ TCP 接続し、その後はクライアントとサーバ間の TLS 通信を丸っと乗せ換えするだけです。

具体的なフローは以下を参照ください。

【図解】httpプロキシサーバの仕組み(http GET/https CONNECTメソッド)や必要性・役割・メリットデメリット・DNSの名前解決の順序
プロキシサーバとは プロキシサーバとは、クライアントからサーバへ http 通...

さきほど https について「経路途中の機器は基本的には通信の中身は確認できません」としましたが、例外として ssl_bump の設定をすれば中身を覗けるようになります。これは TLS コネクションを TCP コネクションと同じ単位に分割します。

これは「SSL intercept」「SSL 可視化」などと呼ばれたりします。詳細は以下を参照してください。

【図解】SSL/TLS可視化(復号化,インターセプト)ソリューションの仕組み
SSL/TLS可視化ソリューションの背景 2013年、スノーデン氏がカミングア...

これを実現するためには Proxy サーバが証明書を動的に生成しなければなりません。これを実現するためには以降のように設定します。

ssl_bump の設定手順

まず、selinux を permissive にします。

[root@localhost ~]# setenforce 0
[root@localhost ~]# sed -ie 's/SELINUX=enforcing/SELINUX=permissive/g' /etc/selinux/config

次に、ルート証明書 (自己署名証明書) を作ります。このルート証明書を使って SQUID+ssl_bump が動的に各サイトの偽のサーバ証明書を生成します。

[root@localhost ~]# cd /etc/squid/
[root@localhost squid]# openssl genrsa -out bump.key 4096
[root@localhost squid]# openssl req -new -key bump.key -out bump.csr
~~~
Country Name (2 letter code) [XX]:JP
~~~
Common Name (eg, your name or your server's hostname) []:SQUID
~~~
[root@localhost squid]# openssl x509 -req -days 365 -in bump.csr -signkey bump.key -out bump.crt

パーミッションを変更します。

[root@localhost squid]# chown squid: /etc/squid/bump*
[root@localhost squid]# chmod 400 /etc/squid/bump*

次に、クライアントとの Diffie-Hellman 鍵共有に関するパラメータファイルを生成します。

[root@localhost squid]# openssl dhparam -outform PEM -out /etc/squid/bump_dhparam.pem 2048

サイトへアクセスする際に動的にサーバ証明書を生成するわけですが、毎回作ると大変なので証明書をキャッシュできるよう DB を作ります。

[root@localhost squid]# mkdir -p /var/lib/squid
[root@localhost squid]# /usr/lib64/squid/security_file_certgen -c -s /var/lib/squid/ssl_db -M 20MB
Initialization SSL db...
Done
[root@localhost squid]# chown -R squid: /var/lib/squid

そして /etc/squid/squid.conf に設定を追加します。

まずは先頭に以下を追記します。

acl intermediate_fetching transaction_initiator certificate-fetching
http_access allow intermediate_fetching

次に、最後尾に以下を追記します。

sslcrtd_program /usr/lib64/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

そして http_port 3128 の箇所を以下に差し替えます。

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

そして squid を再起動し、ステータスを確認します。

[root@localhost squid]# systemctl restart squid
[root@localhost squid]# systemctl status squid

ステータスが無事 active (running) になっていることを確認し、動作確認します。

[root@localhost squid]# tail -f /var/log/squid/access.log

クライアントから接続します。以下のような感じで "GET https://" 等のログが取れていれば成功です。

1668349667.277    133 192.168.1.45 NONE_NONE/200 0 CONNECT milestone-of-se.nesuke.com:443 - HIER_DIRECT/183.181.91.134 -
1668349667.278    133 192.168.1.45 NONE_NONE/200 0 CONNECT milestone-of-se.nesuke.com:443 - HIER_DIRECT/183.181.91.134 -
1668349667.282     42 192.168.1.45 TCP_MISS/200 759 GET https://milestone-of-se.nesuke.com/wp-content/themes/cocoon-child-master/javascript.js? - HIER_DIRECT/183.181.91.134 application/javascript
1668349667.289     33 192.168.1.45 TCP_MISS/200 3793 GET https://milestone-of-se.nesuke.com/wp-includes/js/clipboard.min.js? - HIER_DIRECT/183.181.91.134 application/javascript
1668349667.292     35 192.168.1.45 TCP_MISS/200 1070 GET https://milestone-of-se.nesuke.com/wp-content/cache/autoptimize/js/autoptimize_single_93463aeeee2a3f2aa6180e699b62d7e9.js? - HIER_DIRECT/183.181.91.134 application/javascript

クライアント側のルート証明書インストール

クライアントはそのままでは毎回証明書警告が表示されてしまいますが、ルート証明書をインストールすると解消されます。

以下に手順がありますのでご参照ください。

【図解/Windows】ルート証明書のインストール方法と確認方法
デジタル証明書の確認 Windows でデジタル証明書のエラーが出た際、クライ...

コメント

タイトルとURLをコピーしました