子供を守る、SquidguardとELKスタックで作るネットフィルタリングシステム

# 背景
近頃の子供たちは、小学生のうちからタブレットやスマフォに慣れ親しんでいて、その活用の仕方も大人顔負けのようです。習い事に電車で通う子供たちは必ずと言っていいほどスマフォを携帯していて、乗り換え案内や待ち時間の暇つぶしにスマフォを活用しています。格安SIMの普及によって、低価格で所有できるようになったことも後押ししているのでしょう。
我が家の子供達も、クラブ活動の相互連絡にLINEを使うことになり、スマフォを携帯させることにしたのですが、色々と気になる点がでてきました。

# 課題
子供がいつでも、どこでも、自由にネットを閲覧できることに少し不安を覚えました。たとえば、人に怪我を負わせる飛び道具の作り方を解説したサイトなども誰でもアクセスできるので、工作が好きな子だったら出来心で興味を持ってしまいそうです。そこで、まずはサイトのフィルタリングをすることを考えました。加入している携帯キャリアに有害サイトをフィルタリングできるオプションがあったので、まずはこれの導入を検討したのですが、兄弟で入るとちょっと費用が嵩むな〜という塩梅。そこで、サーバ系の勉強をかねて、OSSで組み上げる方向で検討してみました。

# 対応方針
* 家庭内LANにプロキシを立てる（家庭内プロキシ）。
* 子供のスマフォはWiFiで繋がる場合のみ必ず家庭内プロキシを通る設定とする。
* プロキシにはSquidを使う。
* プロキシのログを溜め込んで分析できるようにする。

# その他諸々
* ネットフィルタリングのみを対象とする（アプリフィルタリングはDinnerTime+に任せる）。
* 4G回線でのフィルタリングは一旦は考慮しないで、家庭内LANでのフィルタリングに対応する。
* 子供はスマフォの設定がいじれない程度のスキルを想定（いつ突破されるかわかりませんが）。
* 子供にはフィルタリングしている事実は伝える。
* 大人はフィルタリングしない（笑）。

# システム構成
ちょうどいいdocker-composeのパッケージを見つけました。

[docker-squidguard-elk(MITライセンス)](https://github.com/muenchhausen/docker-squidguard-elk)

SquidにフィルタリングのためのSquidguardをアドインさせ、squidのログをelasticsearchへ放り込み、kibanaで解析できるようにするという至れり尽くせりのdockerコンテナによるパッケージシステムです。
図にするとこんな感じですね。

![Squidguard_ELK-2.png](https://qiita-image-store.s3.amazonaws.com/0/121442/0d34c2e8-0b74-d378-dd02-00b2cccc4cc1.png)

導入する環境は以下の通りです。

| 項目 | 内容 | 
|:-----------:|:------------:|
| OS | Ubuntu 15.04 |
| docker | 1.9.1 |
| docker-compose | 1.9.0 |

# システム構築
## /etc/security/limits.confを修正

```bash:/etc/security/limits.conf
*               hard    nofile          65535  
*               soft    nofile          65535
```
* ログアウトして再度ログイン
* ulimit -nにより反映されていることを確認する

## /etc/sysctl.confを修正

```bash:/etc/sysctl.conf
vm.max_map_count=262144
```
```bash:prompt
# 修正を適用する
sudo sysctl -p
# 値が反映されていることを確認
cat /proc/sys/vm/max_map_count
```

## gitからダウンロードして起動

```bash:prompt
git clone https://github.com/muenchhausen/docker-squidguard-elk.git
cd docker-squidguard-elk
docker-compose -f docker-compose.yml up
```

# 動作確認
## プロキシのログを蓄える

```bash:prompt
# 正常ケース
curl --proxy http://<hostname>:3128 http://www.google.com
# ブロックされるケース
curl --proxy http://<hostname>:3128 http://lemonlime.de
```

## kibanaで確認する
* ブラウザでhttp://\<hostname>:5601へ接続する。
* 左メニューの"Management"から"Saved Objects"->"import"をクリックする。
![スクリーンショット 2018-07-16 23.56.58.png](https://qiita-image-store.s3.amazonaws.com/0/121442/aaf487d8-bb98-a3af-a64c-90619b22465c.png)
* gitにある"kibana-sample-export.json"をロードする。
* "MyDashboard"が登録されることを確認する。
* 左メニューの"Dashboard"をクリックする。
![スクリーンショット 2018-07-16 21.16.34.png](https://qiita-image-store.s3.amazonaws.com/0/121442/d82f2564-6c3d-ccec-7aef-0fbc0dec4664.png)

# カスタマイズ
## elasticsearch
* ホストのポートを変更したい場合は、portsとexposeを合わせて修正する。

```yaml:docker-compose.yml
elk:
  build: ./elk
  hostname: elk
  environment:
    - TZ=Asia/Tokyo
  ports:
    - "5601:5601"
    - "9201:9200"
    - "5000:5000"
    - "5044:5044"
  expose:
    - 5601
    - 9201
    - 5000
    - 5044
```

## ブロック表示
* myconfig/block.htmlを修正する。

## ブロックするドメインを追加
* myconfig/additionalBlackDomainsへドメインを追加する。

# Future work
* VPS上に構築して4G回線でもフィルタリングする。
* サイトの特徴を機械学習でモデル化して自動的にBlackDomainsへ追加する仕組みを作る。

# 編集後記
１０年ほど前は、得体の知れないOSSを活用するよりも、シンプルな構成・ライブラリを自分で作った方が良い、そのポリシーを貫いて来ましたが、ここ最近は考え方が変わって来ました。Hyperledger Fabricの技術開発を行うプロジェクトを経験してからは、周辺OSSの進歩に本当に驚いていて、可能な限りOSSを活用する考え方に変わりました。一方で、制御しにくいところはスクラッチ開発で、という手をかけるところも残しておきたいですね。最近はちょっとしたシステムでも、流用できるOSSがないものか、ググる癖がついてきました。