PiHole(家庭内ローカルDNS)による端末ごとのアクセス制御について

子供の携帯電話からインターネットへのアクセスを時間帯によって制限するために、PiHole(家庭内ローカルDNS on Raspberry Pi Zero W)を導入して2ヶ月余り、うまく制限できているのですが現状は一括での制限しかできていなくて不便なところもありました。

しかし、PiHoleでは端末/端末グループ(IPサブネット範囲)での制限も可能だということが判りましたので覚書として残しておきます。(日本語ではほとんど解説されていないようなので)




いままでは cronを使って時間帯によって

ブロック開始:
pihole -b --wild hogehoge.com

ブロック解除:
pihole -b --wild hogehoge.com -d

を実行してました。
しかし、この方法ではPiHoleを利用するすべてのクライアント(端末)に対してブロックが適用されてしまいます。


公式のドキュメント(英文)を調べてみると PiHoleには「クライアント(端末)」と「グループ」という機能が用意されていて、端末あるいは端末グループでブロックを制御できるそうです。

正確に言うと、ブロック情報をグループにリンク(割当)し、端末をグループにリンク(割当)するという2段階で制御するということになります。

参考:
"Examples - Pi-hole documentation"
https://docs.pi-hole.net/group_management/example/

※ 英語ですが、Webインタフェースの操作画面はこのドキュメントに記載されています。




前準備:
1. グループを作成する(Groupsメニュー)
2. 対象となる端末(IPアドレス/IPサブネット範囲/MACアドレス)を登録する(Clientsメニュー)
3. ブロックしたいドメインを登録し、デフォルトのグループ(0)を解除し、ブロックしたいグループにリンク(割当)する(Domainsメニュー)

基本的には PiHoleのWebインタフェースで前準備を実行できるようになっていますが、Webインタフェースで端末を登録できない場合は 次の2つのコマンドで直接登録することも可能です。

sudo sqlite3 /etc/pihole/gravity.db "INSERT INTO client (ip) VALUES ('192.168.xxx.xxx');"
pihole restartdns reload-lists

※ sudo usermod -aG pihole <自分のユーザーID> しておくと sudo無しで sqlite3の書き込みを実行できるようになります。

※ pihole restartdns reload-lists はデータベースの変更を PiHole に反映させるための操作です。




特定の端末(グループ)のブロックの有効化:
グループと端末をリンクする(端末にグループを割り当てる) (Clientsメニュー)

特定の端末(グループ)のブロックの無効化:
グループと端末のリンクを解除する(端末のグループ割り当てを取り消す) (Clientsメニュー)


特定の端末(グループ)のブロックの有効/無効をコマンドで制御する方法:
sqlite3コマンドを用いてグループと端末のリンク情報を追加/削除することでブロックの有効/無効を制御できます。
また、これらのコマンドを cronで実行することにより端末ごとに時間帯による制御も可能になります。(時間帯による制限を複数のグループに分けることで段階的な制限も可能です)

ただし、データベースに登録されている「端末のレコードID」と「グループのレコードID」を事前に確認しておく必要があります。

端末のレコードIDを確認するコマンド
sudo sqlite3 /etc/pihole/gravity.db "SELECT * FROM client;"

グループのレコードIDを確認するコマンド
sudo sqlite3 /etc/pihole/gravity.db "SELECT * FROM group;"

端末とグループのリンク情報を確認するコマンド
sudo sqlite3 /etc/pihole/gravity.db "SELECT * FROM client_by_group;"


端末のレコードIDを 999、グループのレコードIDを 888とすると次の2コマンドでリンク情報を登録できます。

sudo sqlite3 /etc/pihole/gravity.db "INSERT INTO client_by_group (client_id, group_id) VALUES (999, 888);"
pihole restartdns reload-lists


またリンク情報を解除するのは次の2コマンドになります。

sudo sqlite3 /etc/pihole/gravity.db "DELETE FROM client_by_group WHERE client_id = 999 AND group_id = 888;"
pihole restartdns reload-lists


以上、ご参考になれば幸いです。

この記事へのコメント