跳轉到

授權掃描網段(Scan Zone Manage)

功能群:系統管理|三層 RBAC 模型先讀 功能群總覽 §2

事實基準:2026-10-05 從 FE src/views/scan-zone/、jedi-detection api/routes/scan_zone_route.py/app/service/scan_zone_service.py、BE core/plugins/detection.py、DEV compliance.tenant_scan_zones 實查掃出

變更紀錄

日期 FR 變更
2026-10-05 FR-129 新頁:租戶登記授權掃描網段;網段型掃描目標必須整段落在已授權網段內,agent 端心跳也拿這份清單做連線前比對

1. 功能描述

授權掃描網段是檢測線的授權範圍設定頁:客戶 IT 在這裡登記「貴單位准許被掃描的網段」(通常一到五條 CIDR)。這份清單有兩個消費者:

  1. 雲端存檔與派工守門:任務配置裡的網段型掃描目標(Nmap targets、OpenVAS hosts)必須整段落在本頁「已授權」的網段內,否則存檔與派工都被擋(DETECTION_TOOLS_400024)。
  2. agent 端二次比對:雲端心跳把「設備清冊內網 IP+本頁已授權網段」下發給 agent(見檔案 Agent 管理 §6.6),agent 每次連線前自己比對,清冊外、網段外一律拒連。雲端被打穿時,這一層照樣擋。

逐台型目標(CINC Auditor/GCB/OpenSCAP 的 hosts、Nmap 的執行主機)不看本頁,看設備清冊。兩條規則的分工見 任務配置頁「Agent 分派區塊」。

列有兩種狀態:

狀態 畫面 算不算授權 從哪來
active 綠色「已授權」 算 人工新增,或把待確認列按「確認授權」
pending 黃色「待確認」 不算 按「依 Agent 位址產生建議」,由系統依 agent 所在內網位址推 /24(IPv6 推 /64)

主要使用者:租戶管理員(持 scan-zone.update)。能派掃描的人(plugin.update)預設沒有本頁權限——不能自己擴大可掃範圍。

角色速覽

角色 一句話
租戶管理員(scan-zone.read+scan-zone.update,seed 只配給 is_admin 角色) 唯一可增刪改、確認建議的人
只有 scan-zone.read 的角色 看得到清單、所有按鈕隱藏,頁上提示「修改需要租戶管理員權限」
其他使用者 選單不出現;手打網址會被導回首頁

1.1 功能總覽(本頁全部功能)

# 功能 說明 位置 詳述
1 網段清單 依租戶列出全部網段(待確認排最前),欄位:功能/網段/狀態/說明/最後異動(時間+暱稱) 主表格 §5
2 新增網段 Dialog 填網段(必填)+說明;新增一律 active Header「新增網段」 UC-SZ-01
3 編輯網段 同一 Dialog 改網段或說明 列上「編輯」 UC-SZ-01
4 刪除網段 確認框後刪除;刪除後網段型目標落在這段的任務存檔與派工會被擋 列上「刪除」 UC-SZ-01
5 依 Agent 位址產生建議 對本租戶每台 agent 的內網位址推一筆 pending;已被涵蓋或重複的略過 Header 按鈕 UC-SZ-02
6 確認授權 pending → active;說明欄尾端「(待確認)」字樣自動拿掉 待確認列的綠色勾 UC-SZ-02
7 授權唯讀模式 授權到期進唯讀時寫入按鈕 disabled,tooltip 說明原因 全部寫入按鈕 §4

2. Use Case

視覺慣例:判斷框=分支條件;擋下=標 error code;成功終點=寫入完成。

UC-SZ-01 新增/編輯/刪除網段

項目 內容
角色 持 scan-zone.update
前置條件 已登入;頁面可見
產出 / 後置條件 compliance.tenant_scan_zones 寫一列;稽核事件一筆;寄信通知該租戶全部管理員

流程:

  1. 填網段 → 後端正規化:
  2. 不是合法網段,或主機位元非零(10.1.2.3/16)→ 400 DETECTION_TOOLS_400022,不自動截成 10.1.0.0/16(自動放大範圍等於替使用者多授權一大段)。
  3. 單一 IP 視為 /32(IPv6 /128)。
  4. 同租戶已有同一網段 → 409 DETECTION_TOOLS_409020。
  5. 寫入後記稽核事件:新增 SCAN_ZONE_CREATED(6127)、修改與確認 SCAN_ZONE_UPDATED(6128)、刪除 SCAN_ZONE_DELETED(6129),內容帶改前改後的網段、狀態、說明。
  6. 寄信通知該租戶全部管理員(「誰、加/改/刪/確認、哪一段」)。寄信失敗只記錯誤日誌,不回滾已寫入的授權變更。

UC-SZ-02 依 Agent 位址產生建議並確認

項目 內容
角色 持 scan-zone.update
前置條件 本租戶已有註冊過的 agent
產出 / 後置條件 新增 0~N 筆 pending;確認後轉 active

流程:

  1. 逐台取 agent 位址:agent 自報的內網 IP 優先(hardware_info.ip),沒有才用雲端看到的連線來源 IP(經 NAT 時可能是閘道)。
  2. 不是內網位址(公網、loopback、未指定)→ 略過;推公網 IP 的 /24 等於替人授權別人的網段。
  3. 推出的網段已存在、或已被某筆 active 網段整段涵蓋 → 略過。重複按不會重複建。
  4. 建成 pending,說明預設「agent <名稱> 所在網段(待確認)」,source_agent_uid 記來源 agent。建議本身不寫稽核、不寄信——真正的授權變更發生在確認那一刻。
  5. 管理員按「確認授權」→ PUT status=active → 記 6128(action=confirm)+寄信。
  6. active 改回 pending 一律拒絕(400 DETECTION_TOOLS_400023);要收回授權就刪除。

3. 權限矩陣

操作 FE 判定 BE 強制 BE 檢查位置
選單可見 ui_routes 的 scan-zone(掛在「系統管理」群,排在設備管理之後) — web-menu
進頁/讀清單 hasCap('scan-zone.read'),無則導回首頁 capability_required(scan-zone.read) scan_zone_route.py::ScanZonesRoute.get
新增/編輯/刪除/產生建議/確認 hasCap('scan-zone.update'),無則按鈕與功能欄隱藏 capability_required(scan-zone.update) ScanZonesRoute.post、ScanZoneDetailRoute.put/delete、ScanZoneSuggestRoute.post
租戶歸屬 — 租戶一律取自登入身分,body 帶的租戶不收;改刪先比對該列 tenant_id,他租戶的 uid 回 404 DETECTION_TOOLS_404009;資料庫 RLS 再擋一道 scan_zone_service.py::_get_owned
授權(license) useLicenseReadonly require_license("scan-zone"),scan-zone 列在授權豁免清單(基礎設施設定,不隨販售模組開關) common/authz/license.py

分權是本頁的設計重點:執行掃描(plugin.update/任務執行權限)、改設備清冊(device.*)、改授權網段(scan-zone.update)是三顆不同的能力點。三者都落在同一個帳號上,帳號被盜時攻擊者可以「先擴大範圍再掃」;分開之後每一步都要不同的帳號,而且改網段會留事件、發信。手冊建議見檢測 Agent 手冊「檢測目標授權範圍」。

4. 狀態機與前置條件

(產生建議)──▶ pending ──(確認授權)──▶ active
                  │                        │
                  └──────(刪除)◀──────────┘
人工新增 ─────────────────────────────▶ active
active ──▶ pending:拒絕(DETECTION_TOOLS_400023)
條件 效果 出處
主機位元非零/不是網段 400 DETECTION_TOOLS_400022 scan_zone_service.py::normalize_cidr
同租戶同網段已存在 409 DETECTION_TOOLS_409020 _assert_cidr_free
status 不是 active/pending,或 active→pending 400 DETECTION_TOOLS_400023 update_zone
授權到期唯讀 寫入按鈕 disabled(writeDisabled()) ScanZoneManage.vue

5. UI 設計

單頁:Header(標題+「依 Agent 位址產生建議」+「新增網段」)、藍色說明列、DataTable、新增/編輯 Dialog。

欄 內容
功能(只對 scan-zone.update 顯示) 待確認列多一顆綠色勾「確認授權」;編輯;刪除
網段 正規化後的 CIDR,粗體
狀態 Tag:已授權(綠)/待確認(黃)
說明 自由文字,最長 255
最後異動 YYYY-MM-DD HH:mm+修改者暱稱(暱稱查不到才顯示帳號)

Dialog:網段(必填,placeholder「例如 192.168.50.0/24」,下方提示「主機位元必須為零」)、說明(選填)。錯誤由全域 interceptor 依 error code 顯示,Dialog 留著讓使用者改。

確認與刪除都走確認框;確認框文字明講後果(確認:「確認後檢測工具即可掃描此網段內的主機」;刪除:「刪除後檢測工具將不能再掃描此網段」)。

6. API 規格

Envelope 見功能群總覽。全部端點屬 jedi-detection 套件 routing,宿主不另掛 route。

6.1 總清單

Method + Path 說明 能力點
GET /scan-zones 列出本租戶網段(待確認排最前) scan-zone.read
POST /scan-zones 新增(一律 active) scan-zone.update
PUT /scan-zones/{uid} 改網段/說明,或 status=active 確認建議 scan-zone.update
DELETE /scan-zones/{uid} 刪除 scan-zone.update
POST /scan-zones/suggest-from-agents 依 agent 位址產生 pending 建議,回傳新建的列 scan-zone.update

6.2 回應欄位(ScanZoneResponseSchema)

欄位 型別 說明
uid string 對外識別碼
cidr string 正規化後的網段
label string|null 說明
status string active/pending
source_agent_uid string|null 建議來源 agent(人工新增為 null)
created_user / updated_user string|null 帳號
created_user_name / updated_user_name string|null 暱稱
created_at / updated_at datetime

6.3 寫入 Request

端點 欄位 說明
POST cidr(必填)、label 未知欄位忽略(unknown=EXCLUDE)
PUT cidr、label、status 只套用 body 有帶的欄位;label 帶空字串=清空

6.4 錯誤碼

碼 HTTP 情境
DETECTION_TOOLS_400022 400 網段格式錯或主機位元非零
DETECTION_TOOLS_400023 400 狀態值不合法,或把已授權改回待確認
DETECTION_TOOLS_404009 404 網段不存在或不屬本租戶
DETECTION_TOOLS_409020 409 同一網段已登記

本頁的網段被使用時(任務存檔/派工),網段外的目標回 DETECTION_TOOLS_400024,見任務配置。

7. 前端檔案地圖(compliance-manager-fe/)

檔案 角色
src/views/scan-zone/ScanZoneManage.vue 主頁:清單、產生建議、確認、刪除、能力點判定
src/views/scan-zone/ScanZoneDialog.vue 新增/編輯 Dialog
src/service/ScanZoneService.js API 包裝
src/config/scanZone.js 能力點常數 SCAN_ZONE_READ/SCAN_ZONE_UPDATE
src/config/router/index.js route scan-zone,path /system/scan-zone
src/config/locales/i18n/{zh-tw,en}/scan-zone.json 頁面字串

8. 後端檔案地圖

層 檔案
Route jedi-detection api/routes/scan_zone_route.py(三個 Resource)、api/routing.py 註冊
App service jedi-detection app/service/scan_zone_service.py::ScanZoneService(全部 @transaction)
Domain jedi-detection domain/scan_zone/service/scan_zone_domain_service.py(contains/zones_contain:目標整段落在 active 網段內才算,IPv4/IPv6 版本不同直接不算)
宿主 adapter BE core/plugins/detection.py(通知寄送、agent 目錄、身分暱稱);core/plugins/remote_agent.py::AllowedTargetsProvider(心跳下發,讀同一張表的 active 列)
稽核事件碼 BE common/enum/event_code.py、jedi-detection common/event_code.py(6127~6129)

9. DB

9.1 資料表

表 讀/寫 說明
compliance.tenant_scan_zones 寫 本頁唯一寫入表
compliance.remote_agents 讀 產生建議時取 agent 位址
public.users 讀 審計欄暱稱

9.2 compliance.tenant_scan_zones

欄位 型別 說明
id bigint PK
uid varchar(36) 對外識別碼,UNIQUE
tenant_id integer NOT NULL → tenants.id(ON DELETE CASCADE)
org_unit_id integer|null → org_units.id
cidr cidr NOT NULL 網段;(tenant_id, cidr) UNIQUE
label varchar(255)|null 說明
status varchar(16) NOT NULL default active CHECK active/pending
source_agent_uid varchar(36)|null 建議來源 agent
created_user / updated_user varchar(255)|null 審計欄
created_at / updated_at timestamptz NOT NULL

RLS policy tenant_scan_zones_tenant_isolation:super admin 或 app_tenant_allowed_for_session(tenant_id)。索引 (tenant_id, status) 供心跳與守門查 active 列。

Migration:scripts/sql/2026-10-05-fr129-2-tenant-scan-zones.sql(表、RLS、能力點 scan-zone.read/scan-zone.update 只配 is_admin 角色、選單)。

10. 頁面邏輯與資料對應

  • 載入:onMounted 先判 scan-zone.read,沒有就 router.replace('/');有才 GET /scan-zones。
  • 寫入後一律重新 GET 整份清單(清單很短,不做局部更新)。
  • 產生建議回傳新建列數:>0 顯示「已新增 N 筆待確認建議」,=0 顯示「所有 Agent 所在網段都已登記」。
  • 錯誤由全域 interceptor 依 error code 顯示 i18n 訊息,頁面不另處理。

11. 背景行為與外部依賴

類型 內容
通知 每次新增/修改/確認/刪除寄信給該租戶全部管理員;產生建議不寄
稽核 6127/6128/6129 落 system_logs,帶改前改後值
心跳下發 agent 每次心跳,雲端把本租戶 active 網段連同設備清冊內網 IP 組成授權目標清單;清單內容變了版本號就變,agent 帶舊版本時拿到整份新清單。本頁改動最慢一個心跳週期後生效到 agent 端
jedi-* 套件 jedi-detection(本頁全部 domain/route)、jedi-remote-agent(心跳下發的 port)

12. 邊界情況與已知坑

  1. 待確認不算授權,兩端判準一致:雲端守門(DetectionTargetAuthorizer)與心跳下發(AllowedTargetsProvider)都只看 active。兩邊寬窄不同會出現「雲端准派、agent 拒連」,改任一邊都要同步另一邊。
  2. 刪除網段不會改已存的任務設定:已存在任務裡落在被刪網段的目標,下次存檔或派工時才被擋(DETECTION_TOOLS_400024);已在 agent 手上排程的工作,agent 下一次心跳拿到新清單後也會拒連。
  3. 建議用 agent 自報 IP,經 NAT 可能推錯:agent 沒自報內網 IP 時退回雲端看到的連線來源;那是閘道位址時,推出來的 /24 不是 agent 真正所在網段。建議只是建議,確認前請核對。
  4. 建議不是在 agent 註冊當下自動產生:要管理員按按鈕。已註冊的 agent 也能補產。
  5. 逐台型目標不看本頁:CINC Auditor/GCB/OpenSCAP 的 hosts 與 Nmap 執行主機只驗「在設備清冊內且為內網位址」,不要求落在授權網段內(存量任務遷移時自動建的設備可能不在任何網段內,要求落在網段內會讓存量任務整批無法執行)。

13. 開發與驗證

  • 導航路徑:租戶管理員登入 → 系統管理 → 授權掃描網段(/system/scan-zone)
  • 測試帳號:租戶管理員(角色有 is_admin 旗標);對照組用一般 IT Manager 確認選單不出現、手打網址導回首頁。密碼見 .env/部署文件
  • 驗收:新增 192.168.50.0/24 → system_logs 有 6127、管理員收到信;輸入 10.1.2.3/16 → 400022;按產生建議 → 出現待確認列 → 確認 → 轉已授權
  • 相關文件:設計決策 D1~D7 在 FR-129 母卡(Notion CM-2485);手冊見檢測 Agent 手冊第十二章