跳到內容
Syno Package Land
語言: 繁體中文

執行固定的管理員操作

root 操作讓你的 App 以 root 執行一小組 shell 指令碼。指令碼寫在你的專案裡,由管理員核准一次,之後你的後端用 root.run 依名稱執行。App 無法執行不在核准範圍內的任何東西,也無法傳入引數。

建立含此能力的新專案,或把它加進既有的 native-go 專案:

Terminal window
synopkgland init -t native-go --with root-ops my-app
Terminal window
synopkgland add root-ops

兩者都會把 capabilities: {rootOps: true} 寫入 dsm-package.yaml。os_min_ver 必須至少是 7.1-42661:init 預設就是這個值,而 add root-ops 會把較低的值提高到它並印出此變更。新專案含有範例 root/whoami.sh,它會印出程序的使用者 id:

#!/bin/sh
set -eu
id -u

rootOps: true 至少需要一個 root/<name>.sh。有 root/ 目錄卻沒有 rootOps: true,check 會失敗。

規則值
檔名^[a-z][a-z0-9_]{0,31}\.sh$,例如 restart_service.sh
root/ 內的其他檔案不允許
檔案類型一般檔案。不可是符號連結或目錄。
大小最多 16 KiB(16384 位元組)
第一行必須剛好是 #!/bin/sh,後面接換行
內容UTF-8 文字,不含 NUL 位元組
引數無。指令碼以不帶引數的 /bin/sh 執行。
環境PATH=/usr/syno/bin:/usr/syno/sbin:/usr/bin:/bin、LANG=C、HOME=/。工作目錄為 /。
執行時間20 秒,逾時即停止
輸出標準輸出與標準錯誤合併,最多回傳 1 MiB。

管理員在 App 的「管理員設定」面板,用 DSM 密碼核准套件一次。Vue UI 使用 SDK 的 ExecutorSettings,DSM 視窗不會另外加入自己的面板。產生的 Vue 專案在 ExecutorGate.vue 用 SDK 的 ExecutorApproval 接管頁面,直到 executor 核准為止,並加上 preload:頁面在 executor 第一次讀取狀態期間先隱藏掛載,自己的讀取與核對並行。掛載時會自行開對話框的頁面,要等 SDK 的 useExecutorPreload() 變成 false。plain UI 則由 DSM 視窗顯示核准面板,文字跟隨 DSM 語言,管理員在面板內輸入密碼;密碼空白時不會送出。核准會記錄每個 root/*.sh 檔案的 digest(SHA-256),因此只有管理員核准過的那些指令碼可以執行。

Vue 核准畫面會先說明 App 為何需要系統權限,再請求密碼。ExecutorApproval 使用置中的 consent 卡片;ExecutorSettings 與 ExecutorNotice 對話框使用 inline 版面。管理員輸入目前登入的 DSM 帳號密碼,再按「核准」。密碼由 DSM 直接驗證,不會傳給 App 服務或儲存。「關於這次核准」可展開查看宣告工作限制、更新行為與解除安裝步驟。一般使用者只會看到請管理員核准的指引,沒有密碼欄。

空白送出會在欄位下顯示提示,不送出請求。密碼遭拒時,錯誤會顯示在欄位下,保留輸入供重試;其他設定失敗保留具體錯誤訊息。ExecutorApproval、ExecutorNotice、ExecutorSettings 的 purpose 可提供 App 自己需要系統權限的用途;AppShell 內建通知使用通用用途。背景存檔會自動提供離線檔案工作的用途。

下列變更會強制重新核准:

變更需要重新核准
修改任何 root/*.sh 檔案是
新增或移除 root/*.sh 檔案是
修改 dsm-package.yaml 的 entry是
修改 delegate 的 scope、destinations、operations 或 lifetime是
只改版本號或 UI否

在管理員核准前,synopkgland status 會顯示 needs-admin-approval;核准與已安裝的套件相符時顯示 ready。

executor 會自己核對核准任務:啟動時一次,通過後每 10 分鐘、失敗後每 1 分鐘再核對。executor.status 以 tasks 回報結果(checking、ready、stale 或 failed)。釘選中、執行中的 executor 回報 ready 時,DSM 視窗直接向管理員顯示 App,不自己讀取任務排程表與 EventScheduler。其他管理員在核對之後更改的任務,會在下一次核對(最晚 15 分鐘後)被發現;在那之前,被更改的 control 任務仍會在下一次 start、stop 或 purge 前被擋下。核准、control 任務的 start、stop 與 purge,以及範圍選擇,一律先讀回兩個任務。

DSM 7.1 沒有 SYNO.Core.TaskScheduler.Root 與 SYNO.Core.EventScheduler.Root,所以在 DSM 7.1 上核准改用較舊的 API:

步驟DSM 7.1DSM 7.2 以後
確認密碼PasswordConfirm v1PasswordConfirm v2,會回傳一次性 token
建立 taskEventScheduler create v1 與 TaskScheduler create v3EventScheduler.Root 與 TaskScheduler.Root,並帶上 token
讀回 taskTaskScheduler list v2 與 get v3TaskScheduler list v3 與 get v4

App、status、deploy 與卸載只有在 DSM 對排程讀取或密碼確認回應「不支援的版本」時,才改用 DSM 7.1 的 API:錯誤 104(版本高於該 API 的最高版本,例如 PasswordConfirm v2 與 TaskScheduler get v4)或錯誤 103(該版本沒有這個 method,例如 TaskScheduler list v3)。其他錯誤,例如密碼錯誤(3121)、權限或 session 錯誤,會直接回報,不會換版本重試;建立 task 也一律不重試。兩條路徑都會讀回兩個 task,擁有者、類型與指令碼完全相符前不會執行任何東西。

如果核准在建立了一個 task 之後中斷,例如 boot task 已建立而 control task 沒有,App 會刪除這次核准建立的 task,不會留下沒有 control task 的 root 開機 task。兩個 task 都已建立並讀回,但 executor 之後沒有啟動或沒有回報正常時,也一樣會刪除:executor 沒有執行就沒有 task 清單,卸載會找不到它們。先前核准建立的 task 會保留。核准失敗時,App 的設定畫面會顯示原因與 DSM 錯誤碼;密碼錯誤或核准已撤回之後,視窗面板與設定畫面仍提供再次核准。

在 DSM 7.1 上密碼仍會被確認,但 DSM 不會把建立 root task 綁定到這次確認。任何已登入的管理員 session 不透過你的 App 也能在 DSM 7.1 上建立 root task。這次確認記錄的是管理員的同意,不是 DSM 7.2 以後那種由伺服器強制的證明。

DSM 7.1 路徑已依 DSM 7.1.1-42962 實測的 API 組合與錯誤碼測試;加入 104 回退後尚未在 NAS 上驗證。

事件影響
停止套件root 操作暫停,核准保留。
升級只有已核准的政策與指令碼仍然相符時才會恢復(符合 INFO 錨點的新 executor 不需核准),否則 App 停在 needs-admin-approval。
解除安裝核准、root 任務與這個 App 的應用程式權限規則都會被移除,portal 網址也會停止。重新安裝需要重新核准。請見資料與移除。

產生的 root.run 路由存在於 native-go 專案。產生的 UI 沒有對應的按鈕,請從你自己的 UI 程式碼呼叫。只有管理員可以呼叫。

const result = await ctx.call<{ output: string }>('root.run', { name: 'whoami' })

name 是不含 .sh 的檔名。結果是 { output },即指令碼合併後的輸出。

executor.status 會回報核准是否為 ready,並附 tasks(executor 自己對核准任務的核對結果),所有已登入的使用者都能呼叫。套件停止,或升級後等待核准時,executor 會暫停,狀態為 ready: false、state: "paused",下一步寫在 next:啟動套件,或在套件執行中時重新核准;只有 root 能讀的 /usr/local/etc/synopkgland/<package>/executor.log 會寫明原因。

限制值
最低 DSM 版本7.1-42661
架構x86_64、aarch64 與 armv7。armv7 尚未在 NAS 上驗證。
指令碼大小16 KiB
執行時間20 秒
回傳的輸出1 MiB
引數無
誰能呼叫 root.run管理員
症狀或錯誤碼原因解法
root.run 回傳 internalroot 操作的每一種失敗,到 App 端都是 internal:名稱不明、結束碼非 0、逾時、尚未核准,或執行器未運作。檢查 synopkgland status,用 sh 手動執行指令碼,並讓它在 20 秒內完成。
admin_required呼叫者不是管理員。用管理員的工作階段呼叫 root.run。
session_required沒有有效的 DSM 工作階段。重新登入 DSM。
STANDALONE_ROOT_OPS_UNUSED有 root/,但缺少 rootOps: true。加入能力,或刪除 root/。
synopkgland status 顯示 needs-admin-approval尚未核准,或指令碼或政策已改變。管理員在「管理員設定」重新核准。
check 拒絕某個指令碼名稱、大小或第一行違反上表的規則。修正該檔案。
解除安裝很久executor 透過 DSM 刪除 boot 與 control 工作,再刪除其受保護的資料夾。在系統記錄中找 synopkgland-executor 行:task cleanup timing 列出每個工作的查詢、刪除與驗證時間,purge timing 列出工作與檔案階段,都附套件名稱。DSM 7.1 上這些行只在 journal,不在 /var/log/messages:執行 journalctl -t synopkgland-executor。

所有錯誤碼請見錯誤碼。