やりたいこと
- Rockylinux9 で SQUID を構築し、クライアントからインターネット接続できるようにする
- ssl_bump の設定を行い、https 通信の access_log を CONNECT だけでなく GET や POST など復号状態でとれるようにする
前提
RockyLinux9 の minimal install を以下手順で SETUP した状態から始めます。
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 にしか接続させない、と言った設定ができます。
https と ssl_bump について
近年では https 通信が当たり前ですが、https 通信はクライアントと Web サーバ間の End-to-End で暗号化され、経路途中の機器は基本的には通信の中身は確認できません。
では Proxy はどのように動作するかというと、TCP コネクションは「クライアント⇔Proxy」と「Proxy⇔Web サーバ」の 2 つなのですが、TLS コネクションは 1 つというフローになります。クライアントは "CONNECT" というメソッドを使って Proxy へ TCP 接続し、それを受けて Proxy は Web サーバへ TCP 接続し、その後はクライアントとサーバ間の TLS 通信を丸っと乗せ換えするだけです。
具体的なフローは以下を参照ください。
さきほど https について「経路途中の機器は基本的には通信の中身は確認できません」としましたが、例外として ssl_bump の設定をすれば中身を覗けるようになります。これは TLS コネクションを TCP コネクションと同じ単位に分割します。
これは「SSL intercept」「SSL 可視化」などと呼ばれたりします。詳細は以下を参照してください。
これを実現するためには 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
クライアント側のルート証明書インストール
クライアントはそのままでは毎回証明書警告が表示されてしまいますが、ルート証明書をインストールすると解消されます。
以下に手順がありますのでご参照ください。
コメント