用 UniFi UDM-Pro / UDM-SE 實現小孩的網路使用時段控制

2022.12.12 更新

Unifi Network Application 新增了 Traffic Management 功能,可以針對特定裝置進行時段封鎖,設定相當簡單易懂,已無須再透過下列方法來達成網路裝置時段控制。網路上相當多教學文章或影片,這裡就不再特別介紹。


在上一篇文章 「用 UniFi Controller 實現小孩的網路使用時段控制」提到可以透過在 UniFi Controller 上設定 config.gateway.json 檔案來控制 UniFi USG 動態用對應的防火牆規則以及對應的 IP 群組控制,藉以達到控制小孩裝置的使用時段限制。

上篇文章使用的是 USG,由於 USG 可以透過承襲自 EdgeOS的參數配置方式,自訂一組 config.gateway.json 進行控制,但 UDM-Pro / UDM-SE 採用的是較新的 UniFiOS,所以無法通用 config.gateway.json 的配置。雖然從 UDM-Pro/UDM-SE 管理介面可以控管透過 WiFi 連線設備的使用時段,不過卻無法控管透過實體有線進行連線設備,所以在 Ubiquiti 還沒釋出新的管理介面前還是得想想其他方法。

UniFiOS 具備更先進對外開放的 REST-API 介面,提供給外部應用程式進行整合。所以國外就有神人寫了用 PHP 來整合 UniFi Network Controller API 的函式庫(Art-of-WiFi),其中 UniFi-API-client 提供了一系列函式,讓 PHP 開發者可以遠端呼叫取得或操作 UniFiOS 裝置。而 UniFi-API-browser 則是另一套 PHP Web 應用程式,可以透過瀏覽器直接取得 UniFiOS 裝置的相關資訊,可以用來觀察或協助開發應用程式時進行除蟲。

這套開源函式庫發表後,接著就有另一位神人,應用了 UniFi-API-client 函式庫,寫了兩支 PHP 程式來對 UniFiOS 的防火牆 IP 群組操作加入/移除,再搭配 Linux 內建的排程工具 crontab 定時啟動來達成時間的控制,最後用 Dockerfile 包裝為 docker 映像檔 (blockips-unifi) 方便我們可以快速佈署,不用自己花大把時間來自己進行整合到作業系統中。

好了,說了這麼多,今天這篇筆記是參考Ubiquiti官方論壇 Time based blocking of IP addresses on the UDM/pro 的這篇文章進行實驗,過程中記錄怎麼在 UDM-Pro / UDM-SE 上一步一步做到小孩的裝置使用時段的控制。
注意:以下操作步驟須具備 Linux crontab 排程及 Docker 容器等相關知識,我無法在這篇文章中鉅細彌遺進行說明,如有說明不足請見諒,網路上自行做功課研究。

UDM-Pro/UDM-SE 新增預計要管控裝置的區網 IP 群組

類似於在上一篇文章 「用 UniFi Controller 實現小孩的網路使用時段控制」提到的,我們也需要建立兩個 IP 群組,一個用於記錄所有小孩使用裝置的 IP (後續要用 blockips-unifi docker 映像檔 來動態新增/移除 IP),另一個則一樣是臨時有需要取消限制時,可以手動將防火牆規則改為套用在這個未設定任何 IP 的群組,藉以取消所有的限制。詳細步驟請參與上一篇文章,不過兩個群組皆無需設定任何 IP,都空著就行,因為 IP 後續會透過 docker 映像檔 (blockips-unifi) 來依據時段動態加入。

直接看圖如何設定。新增群組後,不設定任何 IP。

設定防火牆規則

同樣可以參考上一篇文章「用 UniFi Controller 實現小孩的網路使用時段控制」的步驟來建立防火牆規則,唯一不同的是不需要依照時段建立不同的防火牆規則,只需要在 WAN-OUT 設定單獨一條規則即可,這是因為在前一步驟建立的規則套用的 IP 群組,群組裡面的 IP 清單雖然是空的,但 IP 清單會透過 docker 映像檔 呼叫 UniFiOS 的 REST-API 在需要限制的時段被自動加入,在網路開放的時段又自動從清單中被移除,所以去控制時段即可,這邊不用區分不同的規則。
設定方法一樣請參考上一篇文章,這邊就不再多加贅述,直接看圖照著設定。

規則設定細節

Docker 映像檔安裝與設定

其實這篇筆記的重點現在才開始,這篇文章將以群暉 DSM Docker 套件的形式來介紹如何安裝 blockips-unifi,如果要自行在習慣的作業系統中安裝 docker 就請自行研究。

大致說明一下安裝的步驟

  1. 從 github 下載 blockips-unifi 專案

下載後在任意目錄(我放在 DSM 共用目錄 docker/blockips-unifi)解開zip後只需要保留 crontab / config.php 這兩個檔案,其他均可以刪除。

  1. 從 github 下載最新版本的 UniFi-API-client 專案

為何需要更新最新版本的 UniFi-API-client ?

由於 blockips-unifi 目前下載回來 docker 映像檔內嵌的 UniFi-API-client 版本過舊,用內嵌的舊版本搭配我的 UDM-SE + Network Controller v7.1.66 實測結果無法正確進行連線,查看 php 的執行紀錄發現錯誤都是無法登入 UDM-SE,所以需要嘗試將內嵌的 UniFi-API-client 版本更新看看。

一種方法是用 Dockerfile 重新包裝映像檔,把最新的函式庫包進映像檔。但測試的當下我無法確定更新版本是否就可以正常與 UDM-SE 連線,所以我改採比較簡單的方式,由 docker 外部目錄對映的方式將映像檔內部的目錄進行置換,如此就不要再花額外時間重新包裝映像檔。

從 github 下載後在任意目錄(我放在 DSM 共用目錄 docker/blockips-unifi/unifi-api-client)下解開
我更新到目前的最新版本(v1.1.79)後,重新測試連線就一切正常了。

  1. 安裝 docker 執行神人包裝好的 blockips-unifi 映像檔

在「倉庫伺服器」中搜尋 blockips,應該只會出現一個映像檔,直接按下「下載」即可。

下載下來的映像檔會出現在「映像檔」中

  1. 佈署 blockips-unifi 映像檔

點選 blockips-unifi 映像檔然後選擇「佈署」,網路選擇預設的 bridge 即可

容器名稱可自訂,另外請點選「進階設定」

新增時區 TZ 環境變數為 Asia/Taipei,設定正確的時區,後面的時間排程才能正確按時執行。設定好後儲存離開。

下一步,連接埠設定可直接跳過,此 docker 映像檔並無需要對映對外監聽埠。

儲存空間一共需要設定四組,兩組檔案,兩組資料夾

兩個檔案 crontab/config.php 請對應至步驟1 github 中 blockips-unifi 解開的檔案
資料夾 unifi-api-client 請對應至步驟2 github 中UniFi-API-client 解開的資料夾

檔案 crontab,docker 中的掛載路徑請設定為 /etc/crontabs/root
檔案 config.php,docker 中的掛載路徑請設定為 /config.php,可以設定為唯讀
資料夾 unifi-api-client,docker 中的掛載路徑請設定為 /vendor/art-of-wifi/unifi-api-client,可以設定為唯讀
新增一個資料夾 log,用來記錄 crontab 排程執行輸出結果,docker 中的掛載路徑請設定為 /var/log請勿設定為唯讀

  1. 設定好 config.php 中的對應參數

直接編輯 DSM 資料夾中的 config.php,將 UDM-Pro/UDM-SE 相關參數設定進去,docker 映像檔啟動時由於 config.php 已在前一步驟被置換為外部檔案,所以就會使用我們所配置的參數進行啟動。

$controlleruser,請設定為具有administrator權限的帳號。
$controllerpassword,沒什麼好解釋的,就是密碼。
$controllerurl,請設定為 UDM-Pro/UDM-SE 的網址,例如 https://192.168.60.1。
$controllerversion,設定 UniFi Network Controller 的版本號碼。截至本文撰寫時的最新版本 7.1.66 都可以正常支援。
$site_id,站台代號,可以參考上篇文章「用 UniFi Controller 實現小孩的網路使用時段控制」中的「在 UniFi Controller 主機上設定參數檔」章節說明,預設站台代號是 default
$group_name,最前面在 UDM-Pro/UDM-SE 防火牆中新增的 IP 群組名稱,在本例中是「小孩的裝置」。
$rule_name,最前面在 UDM-Pro/UDM-SE 防火牆中新增的防火牆規則名稱,在本例中是「小孩裝置停止使用控制」。
$debug,設定為 true 可以輸出更多除錯訊息,後續運作正常後可以修改為 false 來減少 log 輸出檔案大小。

  1. 調整 crontab 裡的排程時間

直接編輯 DSM 資料夾中的 Linux crontab 排程設定檔(docker 映像檔內的 crontab 也已在前一步驟被置換為外部檔案)。
Linux 的 crontab 的設定語法也不在此篇文章的涵蓋範圍,請自行研究,網路上可以找到很多文章。

我想控制週日~週四每天的 21:00~7:00 之間把六組 IP 限制連線,但週日~週四 7:00~21:00 就打開允許連線。
但週五週六兩天則延長到23:00才開始限制連線,直到隔天早上 7:00 再度打開允許連線

以下貼出我自己的設定

# 週日到週四的 21:00~06:59,每分鐘執行一次把所有小孩使用裝置的 IP 遠端設定到 UDM-Pro/USM-SE
# 重複執行沒關係,add_block_firewall.php 會偵測如果 IP 已經在 IP 群組中,則忽略不再執行
*	21-6	*	*	0-4 /usr/bin/php /add_block_firewall.php 192.168.60.90 192.168.60.91 192.168.60.92 192.168.60.93 192.168.60.94 192.168.60.95  1>> /var/log/blockfile.txt 2>> /var/log/blockfile.txt
# 週五到週六的 23:00~06:59,每分鐘執行一次把所有小孩使用裝置的 IP 遠端設定到 UDM-Pro/USM-SE
*	23-6	*	*	5-6	/usr/bin/php /add_block_firewall.php 192.168.60.90 192.168.60.91 192.168.60.92 192.168.60.93 192.168.60.94 192.168.60.95  1>> /var/log/blockfile.txt 2>> /var/log/blockfile.txt

# 週日到週四的 07:00~20:59,每分鐘執行一次把所有小孩使用裝置的 IP 從 UDM-Pro/USM-SE 中刪除
*	7-20	*	*	0-4	/usr/bin/php /del_block_firewall.php 192.168.60.90 192.168.60.91 192.168.60.92 192.168.60.93 192.168.60.94 192.168.60.95  1>> /var/log/blockfile.txt 2>> /var/log/blockfile.txt
# 週五到週六的 07:00~22:59,每分鐘執行一次把所有小孩使用裝置的 IP 從 UDM-Pro/USM-SE 中刪除
*	7-22	*	*	5-6 /usr/bin/php /del_block_firewall.php 192.168.60.90 192.168.60.91 192.168.60.92 192.168.60.93 192.168.60.94 192.168.60.95  1>> /var/log/blockfile.txt 2>> /var/log/blockfile.txt

啟動 Docker 映像檔

可以從兩個地方來確認是否正常

  1. Docker blockips-unifi 的日誌中可以確認是否 crontab 是否有依照配置時段來啟動。

從下面日誌可以看到21:00之後每分鐘都啟動執行 /add_block_firewall.php

  1. 從 UDM-Pro / UDM-SE 的防火牆群組中是否可以看到在 crontab 中設定的小孩裝置IP

接著從 UDM-Pro/UDM-SE Network 管理介面中可以確認六組 IP 已正確被加入「小孩的裝置」IP群組中。

最後從小孩使用的這六組裝置確認無法連線即可。

 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料