テレビのインターネット接続をスケジューリングしたい話

子どもが使うスマホには利用時間を管理するアプリが色々出ているけど、家電に搭載されているインターネット機能、特にリビングのテレビで視聴出来るYoutubeなどを制限することを試みてみる。

一部のルーター製品には似たような機能があるので、それで満足出来る人は不要な記事です。

私の自宅ルーター(Ｎ○Ｃ製)も機能はありましたが、管理画面が非常に使いづらいのと、近々ＩＳＰを変更する予定があったので自前で作りました。
（子どもも大きくなれば不要になるので、あくまで一時的な用途として考えました）

## 実現方法の検討

手元に使っていないRaspberryPiがあったので、これを再利用することにします。
テレビやルーターは現在のものを使うので、方法論としては２つ考えられます。
1. RaspberryPiをブリッジとして経路上に挟み込み、対象の通信をコントロールする方法
1. 同一LAN上から対象機器の通信を阻害する方法

１の方法は将来対象機器が増えると、挟み込む場所やブリッジの通信速度を考慮する必要が出てくるので、２の方式を採用します。
具体的にはテレビに対して**ARPポイズニング**をしかけて、ルーターの場所を混乱させることにします。

::: note warn
当然ですが、自分の管理外のネットワークへの**ARPポイズニング**は止めましょう。
:::


## 環境構築
いつも通り**RaspberryPi OS**で環境を作ろうと思いましたが、ハッキングツール盛り沢山の**Kali Linux**に[RaspberryPi用のMetaPackage](https://www.kali.org/get-kali/#kali-arm)が用意されていると知りましたので、それをSDカードに焼くことにします。
Ubuntu等でもdsniffパッケージを導入すれば、ここで説明している内容は実行できるハズです（未確認）。

※環境作成手順は省略

## 動作確認
ひとまず動きを確認してみます。
お目当てのコマンドは`arpspoof`になります。
```shell:
arpspoof -i <interface> -t <target> -r <host> 
```
ARPパケットを投げる`interface`と、対象機器`target`、対象機器から見た「阻害したい通信先」`host`を指定します。
`-r`オプションを付けることで「target → host」方向と「host→target」方向の両方の通信を阻害することが可能になります。

【テスト環境】
+ interface(有線LAN) eth0　[MACアドレス　dc:a6:32:**:**:1d]
+ target(テレビ) 192.168.1.11　[MACアドレス　4:7c:16:**:**:d0]
+ host(ルーター) 192.168.1.1　[MACアドレス　54:9b:49:**:**:48]

コマンドの実行結果は以下の通りでした。
標準出力に延々と実行結果が表示されます。１秒ごとに偽装ARPを流しているようです。
```console:
(root㉿kali-raspberry-pi)-[/etc/network/interfaces.d]
# arpspoof -i eth0 -t 192.168.1.11 -r 192.168.1.1
dc:a6:32:**:**:1d 4:7c:16:**:**:d0 0806 42: arp reply 192.168.1.1 is-at dc:a6:32:**:**:1d
dc:a6:32:**:**:1d 54:9b:49:**:**:48 0806 42: arp reply 192.168.1.11 is-at dc:a6:32:**:**:1d
dc:a6:32:**:**:1d 4:7c:16:**:**:d0 0806 42: arp reply 192.168.1.1 is-at dc:a6:32:**:**:1d
dc:a6:32:**:**:1d 54:9b:49:**:**:48 0806 42: arp reply 192.168.1.11 is-at dc:a6:32:**:**:1d
dc:a6:32:**:**:1d 4:7c:16:**:**:d0 0806 42: arp reply 192.168.1.1 is-at dc:a6:32:**:**:1d
dc:a6:32:**:**:1d 54:9b:49:**:**:48 0806 42: arp reply 192.168.1.11 is-at dc:a6:32:**:**:1d
```
テレビ側でYoutubeを流しながら確認しましたが、既にキャッシュされた部分は動画が継続されるものの新たにキャッシュが進むことは無く、キャッシュが枯渇したタイミングで動画が停止しました。いい感じです。

止めたいときは`Ctrl+C`を投げると、ちゃんと元のARP情報を5回投げた後にコマンドが終了しました(ARPクリーニング)。Youtubeも読み込みを再開してくれました。
```console:
^CCleaning up and re-arping targets...
dc:a6:32:**:**:1d 4:7c:16:**:**:d0 0806 42: arp reply 192.168.1.1 is-at 54:9b:49:**:**:48
dc:a6:32:**:**:1d 54:9b:49:**:**:48 0806 42: arp reply 192.168.1.11 is-at 4:7c:16:**:**:d0
dc:a6:32:**:**:1d 4:7c:16:**:**:d0 0806 42: arp reply 192.168.1.1 is-at 54:9b:49:**:**:48
dc:a6:32:**:**:1d 54:9b:49:**:**:48 0806 42: arp reply 192.168.1.11 is-at 4:7c:16:**:**:d0
dc:a6:32:**:**:1d 4:7c:16:**:**:d0 0806 42: arp reply 192.168.1.1 is-at 54:9b:49:**:**:48
dc:a6:32:**:**:1d 54:9b:49:**:**:48 0806 42: arp reply 192.168.1.11 is-at 4:7c:16:**:**:d0
dc:a6:32:**:**:1d 4:7c:16:**:**:d0 0806 42: arp reply 192.168.1.1 is-at 54:9b:49:**:**:48
dc:a6:32:**:**:1d 54:9b:49:**:**:48 0806 42: arp reply 192.168.1.11 is-at 4:7c:16:**:**:d0
dc:a6:32:**:**:1d 4:7c:16:**:**:d0 0806 42: arp reply 192.168.1.1 is-at 54:9b:49:**:**:48
dc:a6:32:**:**:1d 54:9b:49:**:**:48 0806 42: arp reply 192.168.1.11 is-at 4:7c:16:**:**:d0
```
これらの挙動を踏まえ、バッチを作成します。
後々の変更が楽なように、通信疎外を発生させるバッチ`nightblock_start.sh`と阻害を停止するバッチ`nightblock_stop.sh`を別々に作り、cronで実行するようにします。
※停止するバッチはpkillでまとめて停止させています。
※標準出力が煩わしいので/dev/nullに葬ることにしました。

```shell:nightblock_start.sh
#!/bin/bash

/usr/sbin/arpspoof -i eth0 -t 192.168.1.11 -r 192.168.1.1 > /dev/null 2>&1 &

exit 0
```
```shell:nightblock_stop.sh
#!/bin/bash

/usr/bin/pkill -f arpspoof

exit 0

```
`arpspoof`は22:00～23:59の範囲で実行するようにcronを設定します。
```conf:crontab -e
# m h  dom mon dow   command
00 22 * * * /root/nightblock_start.sh
59 23 * * * /root/nightblock_stop.sh
```

こんな感じです。