リバプロ配下のSquidでSSL複合化をしてみた
近頃のWebサイトはHTTPS接続が多くなっており、
通信経路上のProxyやFirewallでトラフィックを見れなくなっている。
そこで重要になるのがSSL複合化を実行する事で、
PCとサーバ間のSSL/TLS通信を一度解いてトラフィックを監査する手法となる。
いわゆる中間者攻撃をセキュリティ設備で実行する事になるのだが、
複合化・最暗号化はシステム負荷が高くエンタープライズでは専用装置を用いるのが常となる。
とは言っても、SquidでもSSL複合化は可能で検証程度ならコレでも十分だったりするので、
自宅サーバで運用しているSquidにもSSL複合化を実装して、負荷がどんな物かテストしてみた。
参考サイト
- Kaspersky > SquidサービスでのSSL Bumpの設定
- 技術メモメモ > SquidのSSL Bumpを使ってHTTPS(SSL)通信を可視化する
- Mailing lists > [squid-users] SSL_bump and source IP
SSL複合化を仕込むのはSquidだが、
前段にリバースプロキシ型の負荷分散装置を挟んでいるので一種の多段Proxyと同じになる。
この良くある負荷分散構成がクセ物で、通信次第でアクセスログを正しく記録出来ない場合がある。
Squidが負荷分散装置配下で動いている場合、
HTTPヘッダに追加されたX-Forwarded-Forを参照する事でクライアントPCのIPを識別するのだが、
SSL複合化をした時点でクライアントPCのIPがパケット上は無くなるらしく、
クライアントのIPではなく負荷分散装置のIPになる場合が出てくる。
エンタープライズ環境でアクセスログのIPが正しく記録出来ないのは大問題だが、
今回は自宅サーバなので深追いはせずに使ってみた。
………
前述の通りロードバランサはSSL通信をそのままバイパスさせて、
SquidでSSL Bumpを設定する事でSSL複合化を実装したのだが、
この構成の大きな課題はSSL複合化・再暗号化の処理をSquidで実装する所にある。
ぶっちゃけ、どれだけCPUコアを積んでも処理が確実に追いつかなくなる。
SSL複合化は設定せず、秒間30セッションのSSL通信を普通に処理している状況が上の画像となる。
CPUコアは2コアでメモリは6GB積んだサーバでテストしてみた。
Squidの負荷が高騰するのは新規セッションが張られた時なので、
SSL通信をCONNECTメソッドで素通ししているだけなら以外とCPU負荷は高騰しない。
大容量通信を流すとCPU負荷も上がるが、パケットを捌いている影響なので問題とはちょっと違う。
コチラが同条件の秒間30セッションを出しつつSSL複合化を実施している時の負荷状況となる。
2コアなので負荷がかかりやすい環境ではあるが、平常時とは比にならない高付加になっている。
CPUコアを増強してSquidのworkerをCPUコア最大まで増強すればある程度緩和が出来るが、
CPU負荷が上がってしまう点はどうしようも無いので完全解消にはならない。
分かっていた事だが、SquidでSSL複合化を実施するにはサーバと負荷分散が前提となる。
今回は自宅サーバだから適当でも良いが、
それを加味しても負荷が高すぎて使い物にならないので、宛先を限定してSSL複合化する事にした。
コレが意外と大変でログが記録されない問題と戦いながらテストしたら年末年始が溶けた (´・ω・`)
………
年末年始を使って調査した特定の宛先のみSquidでSSL複合化をする設定は次の通り。
細かい部分はググれば出てくるので割愛するがバックスラッシュの部分を1行で書けば動く。
設定が出来たら意外とあっけなく、SSL Bumpをpeek・bump・spliceに分割するだけで動いた。
acl step1 at_step SslBump1
acl sslbump dstdomain .example.co.jp
acl sslbump dstdomain .example.ne.jp
http_port 8080 tcpkeepalive=60,30,3 ssl-bump generate-host-certificates=on \
dynamic_cert_mem_cache_size=16MB \
tls-dh=prime256v1:/usr/local/squid/etc/dhparam.pem \
cert=/usr/local/squid/etc/squid.crt \
key=/usr/local/squid/etc/squid.key \
cipher=HIGH:MEDIUM:!LOW:!RC4:!SEED:!IDEA:!3DES:!MD5:!EXP:!PSK:!DSS \
options=NO_TLSv1,NO_SSLv3,NO_SSLv2,SINGLE_DH_USE,SINGLE_ECDH_USE
sslcrtd_children 5
sslcrtd_program \
/usr/local/squid/libexec/security_file_certgen -s /var/squid/sslcrt -M 16MB
sslproxy_cert_error allow all
ssl_bump peek step1
ssl_bump bump localnet sslbump
ssl_bump splice all
|
サンプルではACLにlocalnetを設定しているが、SSL複合化をしたいクライアントIPのACLを作り、
localnetの部分を差し替えれば複合化対象を限定する事も出来る。
この辺りのACL基本構文はSquidのACL挙動と同じだった。
………
設定が出来た後に問題になるのは、SSL複合化をする宛先ドメインのリスト化となる。
Webブラウザのアクセス先がwww.example.co.jpだとしても裏では様々な所にアクセスしているので、
SSL複合化対象には全部登録する必要がある。
Squidのアクセスログから調査しても良いが面倒なのでSSL証明書のSANsからぶっこ抜いた。
次の様なコマンドで証明書のSANsをリスト化出来るのでコレを元にスクリプトを組めば良い筈。
しかし、Squidは1個のACLに重複したドメイン・サブドメインがあるとエラーになるので、
上位ドメインが登録されていないかチェックする機構が必要になる。
筆者は手抜きしたかったのでSquidの書式チェックコマンドで都度確認してみた。
openssl s_client -connect example.co.jp:443 -showcerts < /dev/null \
openssl x509 -text | fgrep DNS | tr ', ' '\r\n' | \
sed -e "s/DNS://" -e "s/^\*//" | sort -nf
|
www.yahoo.co.jpのSSL証明書には大量のSANsが登録されているので参考になる筈。
スクリプトを作り込めば自動化も出来そうだが、
その規模だとエンタープライズ環境だと思うので専用設備の導入を絶対に推奨する。
………
SSL複合化は負荷がかかると言われるので実際にやってみたが、
CPU使用率が予想以上に高騰したのでエンタープライズの環境で常用するのは無理と感じた。
自宅サーバでテストする位ならアリだが、それでも複合化対象のドメインは厳選する必要がある。
とは言っても、一度セッションを張れば通信速度は出るので環境次第では使えるかもしれない。
筆者の環境ではサーバもガッツリとチューニングした上で実環境で試しているが、
1週間使っても特に問題は出ておらず、Twitterも使えたしYoutubeとかも見る事が出来た。
もう少し確認は必要だが、前述のログ問題以外は正常に動作しているので、
お遊びでサクッと使う程度ならアリだと思う。