squid3で エルサゲートを緩和する

# はじめに

[エルサゲート](https://ja.wikipedia.org/wiki/%E3%82%A8%E3%83%AB%E3%82%B5%E3%82%B2%E3%83%BC%E3%83%88)、怖いですね。まわりの親御さんからは「それがあるからパソコンを使わせるのはちょっと...」といった意見もちらほら聞かれます。

プロキシを使ってフィルタすれば良い話なのですが、YouTubeは常時SSL化されているので何を見ているのか分からなかったり、再生の可不可判定をどんな情報に基づいて行えば良いのか考えないといけなかったり、微妙に手間がかかります。

今回はそれをsquid3のssl-bump機能を使ってなんとかしてみよう、というお話になります。

なおターゲット環境は dockerが動くlinuxです。こちらではdebian x64 jessieで確認しました。

# DISCLAIMER

ここで紹介する内容は、言ってみれば中間者攻撃とやっていることは同じです。国や値域によっては、監視対象者の同意があったとしても違法となる可能性があります。また違法ではない場合でも、道義的な責任は発生すると考えています。
今回は自分の子供を守るという名目で実施しておりますが、それでも何歳まで保護対象とすべきなのか、本人にどこまで告知すべきなのか、どこまで理解したら同意を得たことになるのかなど、一概には判断出来ない問題もあります。
さらには、そもそも子供にYouTubeを見せることの是非についても、議論があるかとは思ますが、ここではそこまで踏み込みません。ご自身でご判断頂きますようお願いします。

また本対策は100%完璧に機能するものではなく、なんの保証もない点についてもご了承ください。あくまで無いよりマシかも、という位置づけでお願いします。

# 流れ

完成形は:

- squid3をプロキシとする。
- YouTube宛の接続があった場合にSSLをほどいて、判定用pythonスクリプトにURLを渡す。
- URLから動画情報を取り出し、YouTube Data APIを利用して視聴回数・いいね/悪いね比を基準に、再生してよいかどうかを判断する。
- OKならそのまま、ダメなら www.google.com にリダイレクトする。

となります。以下の様に順を追って準備していきましょう。

- YouTube Data API 鍵の入手
- オレオレ証明書の作成
- squid3 on dockerを起動
- クライアントブラウザへのオレオレ証明書インストール

## YouTube Data API 鍵の入手

見ようとしている動画の統計情報を得るために、 YouTube Data API を利用します。
利用のためにはAPIキーが必要ですので、[ここ](https://developers.google.com/youtube/registering_an_application?hl=ja)などを参照して、サラッとキーを入手しましょう。
欲しいのは "APIキー(サーバーキー)" です。

## オレオレ証明書の作成

下記のコマンドを実行して、オレオレ証明書を作成します。

```shell
openssl req -batch -new -newkey rsa:2048 -sha256 -days 365 -subj /CN=ssl-bump.example/O="squid3 ssl-bump" -nodes -x509 -keyout squid.pem -out squild.pem
openssl x509 -in squid.pem -outform DER -out squid_public.der
```

## squid3 on dockerを起動

必要なスクリプト・設定などは、こちらにご用意しました。

https://github.com/sumomoneko/olaf

一応dockerhubにも登録しましたので、イメージ `sumomoneko/olaf` が利用可能です。
では動かしてみます。

``` shell
docker run --name olaf -d -p3128:3128 --rm --init \
       -e "SQUID_YT_LIMIT_MINUTES=90" \
       -e "SQUID_YT_VIEW_LOW_WATERMARK=1000" \
       -e "SQUID_YT_GOOD_BAD_RATE=60" \
       -e "SQUID_YT_API_KEY=hogeAPIKEYfugafuGA" \
       -v /etc/localtime:/etc/localtime:ro \
       -v /dev/log:/dev/log \
       -v /オレオレ/の/ディレクトリ/squid.pem:/etc/squid3/squid.pem \
       sumomoneko/olaf

```

それぞれの環境変数、マウントしているファイルの意味は以下の通りです:

- `SQUID_YT_LIMIT_MINUTES` 一日あたりの視聴許可時間[分]。これを超えると拒否。デフォルト120
- `SQUID_YT_VIEW_LOW_WATERMARK` この回数未満の視聴数しかないビデオは拒否。デフォルト 1000
- `SQUID_YT_GOOD_BAD_RATE` good/badの比がこの値[%]以上無いビデオは拒否。デフォルト 70
- `SQUID_YT_API_KEY` 入手した YouTube Data APIキー
- `-v /etc/localtime:/etc/localtime:ro` ホストOSがdebian/ubuntuの場合のみ使える小技で、ホストとコンテナのタイムゾーンを合わせます。さもないと、視聴時間のリセットタイミングがUTC(日本だと朝9時)基準になります。
-  `-v /dev/log:/dev/log` コンテナ内で投げたsyslogをホスト側で拾えるようにします。フィルタ結果のログはsyslogに投げていまして、一般には /var/log/user.log に出ます。
-  `-v /オレオレ/の/ディレクトリ/squid.pem:/etc/squid3/squid.pem` 作成した証明書を指定します。

# クライアントブラウザへのオレオレ証明書インストール

`squid_public.der`をブラウザに入れてください。これはいわば白紙委任状ですので、自分が責任を持てるところにのみ入れてください。入れ方は各自の演習とします! (手抜きすいません

あとブラウザへのプロキシ設定も忘れずに。

# 内部の話など

## ログはどこに？

- `docker logs olaf`
- `docker exec -it olaf tail -f /var/log/squid3/access.log`
- `tail /var/log/user.log`

あたりをご確認ください。

## SSL bump有効化

YouTubeはSSLのみ許可するようになっているようですので、そのままでは見ようとしている動画がなんなのかわかりません。そこで、SSL bumpと呼ばれる、SSL通信の間に割り込んで、中身をみる機能を使っています。
一般のディストリビューションではその危なっかしさからか、ssl bump機能を切った状態で配布されていますので、`docker build`時にsquild3をソースからビルドして有効化しています。

c.f. https://debian-base.blogspot.jp/2015/05/install-squid-34-with-ssl-bump-on.html

## パッチ `99-squid3-key-usage.patch`

firefoxでssl bumpが動かない問題があったため、その対策としてビルド時に合わせてパッチ適用しています。
※[ここらへん](http://squid-web-proxy-cache.1019090.n4.nabble.com/sslbump-firefox-sec-error-inadequate-key-usage-td4665537.html)参照のこと

## スマホ専用アプリでの視聴は？

iOSのYouTube専用アプリなどは、iOSにオレオレ証明書を登録してもそちらは見ていないようです。専用アプリでの再生はできませんでした。当然ではありますが、ちゃんと作られていて感心しました。

## その他

フィルタスクリプトは、再生NGの場合は www.google.com にリダイレクトするようにしています。その結果、我が家ではgoogleのホーム画面が子供から憎しみの対象となってしまいました。ごめんなさいgoogle...

フィルタ用のpythonスクリプトは同時起動を1つに制限しています。複数プロセスが立ち上がると、視聴時間の同期とかが面倒だったための単なる手抜きです。
たとえば兄弟が10人いて一斉に視聴開始するなどした場合に、残念な挙動になる可能性があります。

# おわりに

元々debianサーバ上でベタに運用していたモノを、説明のためdockerコンテナに仕立てました。簡単にテストしていますが、ログの散らばりなどグデっている部分はご容赦ください。

プロキシ設定を変えられるとあっさりとバイパスされてしまいますが、むしろそれは望むところではあります。

>仲間になれ。父と子２人で銀河を支配するのだ。

あとYouTube Data API呼び出しに失敗すると、しれっと再生許可しそうですね、あのスクリプト。あかんやん..