Lafine系統設計·技術文件

適用於 Linux 的 RoamSwitch
架構與安全白皮書

解釋 RoamSwitch for Linux 在其權限邊界上執行的操作的技術文件。它避免了行銷語言;可以根據分散式套件的實際行為和附錄中的自我檢測來檢查聲明。

版本 v1.11.1 適用對象 RoamSwitch for Linux 1.11.1(核心 LPE 強化/eBPF 執行時防護/攻擊程序 SIGSTOP 凍結/Falco 低負載最佳化/DNS 隧道偵測/鑑識證據保全/蜜令牌/弱點檢測 pass_age 追蹤/NIST CSF・CIS Controls 對應/診斷再評估/MCP 設定稽核) 需求 systemd + nftables 發布日期 2026-10-08

§1

RoamSwitch for Linux 是一種常駐網路安全和系統診斷應用程序,它將 macOS RoamSwitch 的零信任網路防禦模型引入 Linux(systemd + nftables 環境)。

此版本針對客戶端電腦(工作站、筆記型電腦、單板電腦),並假設機器在網路之間移動時遵循機器的自主行為。強化伺服器/無頭基礎設施版本(RoamSwitch 伺服器版本 - 始終在線預設拒絕、關鍵路徑 FIM 完整性、遠端 Webhooks 和靜態策略實作)作為專用伺服器版本提供。

它依閘道 MAC 位址識別目前連線的 Wi-Fi/有線網路,並自動切換 nftables 防火牆設定檔。此外,針對不受信任網路上的中間人攻擊(MITM),提供三層防護,包括 VPN 隧道 + 終止開關(WireGuard 或 Tailscale,主要防護)、預防性 ARP/NDP 鎖定與 ARP 欺騙偵測。另有勒索軟體行為偵測(fanotify + Shannon 熵 + 誘餌檔案)、會警告或阻擋釣魚連線的被動連結防護(NFQUEUE + SNI)、連接埠異常防護、BadUSB 防護、核心本地權限提升(LPE)防護(作為 Frag Gap CVE-2026-53362 的緩解措施,可選擇啟用在不受信任網路上拒絕非特權使用者命名空間,預設為關閉)、整合 eBPF 執行階段威脅感測器(Falco / Tetragon),以毫秒級凍結攻擊行程(SIGSTOP)並自動啟動 Air-Gap 隔離、27 項安全健康診斷,以及標準內建的 Model Context Protocol(MCP)伺服器。

本白皮書說明架構、威脅模型與各防禦機制的設計,以及「完全本機處理。預設情況下,唯一離開本機的是對簽章偵測資料的請求,其中不包含任何使用者資訊」這項隱私原則如何在程式碼層級獲得保證。需由維運人員明確啟用的選用功能(例如事件轉送)是此預設行為的例外,均列於下表與 §9.4。文中避免宣傳性措辭,所述內容可透過發行套件(二進位檔)的實際行為與本書附錄的自我檢查加以驗證。RoamSwitch for Linux 為專有免費軟體,不公開原始碼(§11)。

設計原則
原理詳情
零遙測本產品預設不會向外部傳送任何有關使用者或裝置的資訊。不存在遙測、分析、當機報告、使用統計、遠端設定或授權啟用伺服器。唯一可能產生通訊的,是維運人員明確啟用的選用功能,已列在下一列「預設行為的例外」和 9.4 中。
預設行為的例外(皆為選用啟用)只有在維運人員明確啟用時,以下功能才會對外通訊。目的地僅限維運人員所設定的,沒有內建目的地。(1) 事件轉送(forward_enabled,預設 OFF)——將偵測事件轉送到維運人員指定的 syslog / JSON Lines 檔案 / 簽章 Webhook。(2) Fleet(Business 層,僅裝置端程式碼)——未註冊的裝置不會傳送任何內容,也不會解析 Fleet 主機名稱;管理服務尚未部署或發行。包括由使用者操作觸發的更新檢查在內,其餘情況均列於 9.4。
僅接收更新本產品預設發出的唯一對外通訊,是每天一次對固定 URL(lafine.net/updates/v1)上已簽章清單的 GET 請求。若已安裝 ClamAV,每次執行時也會啟動 ClamAV 自身的更新工具 freshclam,但該通訊屬於 ClamAV 本身,已另列於 §9.4。從清單取得的內容包括連結防護的詐騙網站清單、本體最新版本、核心與作業系統套件(Debian/Ubuntu/Arch/RHEL 系/SUSE)及語言套件(npm/PyPI/crates.io/RubyGems/Packagist/Go/Maven)的 CVE 對照表、實證型弱點檢測的 CVE 對照表,以及用於仿冒套件名稱偵測的熱門 npm 套件名稱清單。每天取得的只有清單及其簽章(2 次 GET);連結防護清單、實證型弱點檢測的 CVE 對照表和熱門 npm 清單只在清單版本更新時取得,核心和套件的 CVE 對照表只在距上次更新約 30 天後才取得。Ubuntu 的 CVE 對照表只有執行受支援版本 Ubuntu 的裝置才會取得;尚未安裝的裝置不必等 30 天,而是在下一次每日執行時取得。請求不含查詢字串與 Cookie,能表明軟體身分的標頭只有固定的 User-Agent: RoamSwitch-Updater,也不包含任何使用者資訊。設定 updates.enabled = false 即可完全停止;此時僅使用內建資料運作,只要不啟用選用功能,對外接觸為零。
完全本地處理每個評估、檢測和審核都在本機電腦上運行完成。 URL 安全分析和秘密掃描會啟發式地評估其輸入,而無需將其傳輸到任何地方。
最小權限特權操作僅限 root 常駐程式執行,UI、CLI 與 MCP 透過 Unix 網域通訊端 IPC 提出請求。常駐程式預設不開啟 TCP/UDP 通訊端(維運人員啟用的選用功能除外,見 §9.4)。連結防護僅使用 AF_NETLINK 的 NFQUEUE verdict 通道(核心 ↔ 使用者空間,不送出封包)。會改變狀態的 IPC 呼叫僅接受來自 root 或具有本機登入工作階段的 UID 的請求(自 1.10.4 起;唯讀呼叫不變)。
失敗關閉Air-Gap(緊急隔離)在守護程序重新啟動後仍然存在,如果其規則已外部刪除,則會在幾秒鐘內重新生效。
離線授權Pro / Business 授權純粹透過 Ed25519 簽章檢查進行驗證。不會調用激活伺服器。

§2

RoamSwitch for Linux 主要針對在不受信任網路之間漫遊的 筆記型電腦/行動工作站。

範圍內的攻擊者

  • 相同 LAN 上的攻擊者 — 共享 Wi-Fi 上的連接埠掃描、ARP/NDP 欺騙(包括惡意路由器廣告)以查找中間人、惡意 DHCP、MAC 泛洪後的被動嗅探、對開發伺服器的未經授權的存取或意外綁定到 __X00 的本地 LLM API。
  • 惡意 USB 裝置 (BadUSB) — 冒充鍵盤並在螢幕鎖定前註入按鍵;未註冊的 USB 大容量存儲,用於資料外洩或攜帶惡意軟體。
  • 勒索軟體/無檔案惡意軟體 — 透過下載的檔案進入並對使用者的文件進行批次加密。
  • 基於 DNS 的 C2 和網路釣魚 — 使用名稱解析到達 C2 伺服器或網路釣魚網站的惡意軟體。

超出範圍

  • 已經擁有root權限的攻擊者;核心或韌體級 Rootkit。
  • 實體刪除磁碟的攻擊(全碟加密領域;RoamSwitch 診斷是否有加密但不加密)。
  • AirDrop 式近距離無線共享控制(Linux 上沒有作業系統本機機制;不支援)。

§3

適用於 Linux 的 RoamSwitch 以 Rust 實作,套件內含 8 個可執行檔(roamswitch-daemon・roamswitch-app・roamswitch(CLI)・roamswitch-mcp・roamswitch-updater・roamswitch-honeytokens・roamswitch-incident-capture,以及屬實驗性質且預設停用的 roamswitch-xdp-gate)。共用邏輯位於 roamswitch-core 函式庫,roamswitchkit 則是用戶端 SDK。與守護程式的所有通訊都透過 /run/roamswitch/roamswitch.sock(Unix 域套接字)進行。守護程式、應用程式與 MCP 伺服器都沒有任何 TCP/UDP 偵聽套接字。應用程式唯一 bind 的只有一個用於防止重複啟動的 Unix 套接字。

# 使用者空間(非特權)
roamswitch-app      GTK3 + AppIndicator 系統匣
roamswitch (CLI)    面向 shell 的輕量前端
roamswitch-mcp      stdio JSON-RPC(由 AI 用戶端啟動)
      │
      │  AF_UNIX  /run/roamswitch/roamswitch.sock  (僅限本機 IPC)
      ▼
roamswitch-daemon   root / systemd Type=notify + WatchdogSec=30
  · nftables 設定檔控制(inet roamswitch 表)
  · sentinel 迴圈(網路判定與設定檔套用)
  · VPN 隧道 + 終止開關(WireGuard: wg-quick / roamswitch_vpn,Tailscale: roamswitch_ts)
  · 預防性 ARP/NDP 鎖定(neigh 表固定) / 偵測
  · 連接埠異常防護(roamswitch_dev_guard)
  · fanotify 防護(勒索軟體/惡意軟體)
  · 連結防護(NFQUEUE — inet roamswitch_linkguard)
  · 金絲雀引擎 / 隔離 Vault
  · 核心 LPE 防護(拒絕非特權 userns 為選用設定,預設關閉)
  · eBPF 執行階段聯動(/var/run/roamswitch/events.sock)
  · 以毫秒級 SIGSTOP 凍結攻擊行程並聯動 Air-Gap
  · USB 監控(evdev EVIOCGRAB — BadUSB) / 核准佇列
  · Ed25519 授權驗證

roamswitch-updater  獨立的 systemd 計時器 helper。是唯一擁有
                    HTTP/TLS 協定堆疊的 crate(每日取得一次簽署清單)
roamswitch-honeytokens          由守護程式啟動的輔助行程(佈放並監控誘餌憑證)
roamswitch-incident-capture     由守護程式啟動的輔助行程(封鎖隔離時採集證據套件)
roamswitch-core     純邏輯函式庫(所有 crate 共用)
roamswitchkit       MCP 用戶端 SDK
權限分離
組件特權角色
漫遊交換器守護程式根(systemd,Type=notify + WatchdogSec=30)所有特權操作。作為單一編寫者,控制 nftables、DNS 和 systemd 單元。
漫遊交換器應用程式登入用戶GTK3 GUI + AppIndicator 托盤。僅配置編輯和視覺化;每個特權操作都經過IPC。
漫遊交換器 (CLI)登入用戶薄殼前端使用相同的IPC插座。
漫遊交換器-MCP由AI客戶端產生的進程stdio JSON-RPC。提供唯讀診斷資訊。

與守護程式的所有通訊都透過 /run/roamswitch/roamswitch.sock(目錄權限為 0755,套接字權限為 0666)進行。存取控制不依賴檔案權限,而是檢查連線來源:以 SO_PEERCRED 取得 UID,拒絕系統帳號(UID 1 至 999 與 nobody)的連線,且會變更狀態的呼叫僅限 root 或持有本機登入工作階段的 UID(§1)。使用者設定以純文字 JSON 儲存於 ~/.config/roamswitch/config.json。守護程式以 root 權限掃描並讀取 /home/*/.config/roamswitch/config.json(因為守護程式以 HOME=/root 運行)。讀取的對象僅限由該帳號本人擁有、不是符號連結、且其他使用者無法寫入的檔案。設定永遠不會離開本機;既沒有帳號註冊,也沒有雲端同步。

§4

sentinel 迴圈(每 3 秒一次)從 /proc/net/arp 和 ip neigh 讀取預設閘道的 MAC 位址,並與 config.json 中已註冊的 MAC 比對。使用 MAC 而不是 SSID,是因為 SSID 很容易被偽造。設定檔切換時顯示的桌面通知會附上切換原因(「因為是未註冊的網路」/「依已註冊網路『〇〇』的設定」/「因為未連線到網路」)。

型材
公司簡介情況nftables 行為
開放(可信)已註冊的家庭或公司網絡policy accept。允許本地交通。
平衡未註冊但配置為相對安全預設拒絕入站。僅允許已建立的連線、lo 與 ICMP/ICMPv6。監控對外公開的連接埠。
鎖定(離開保護)公共 Wi-Fi/未註冊網絡隱形丟棄所有入站封包。共享服務會自動停止,回到可信任網路後還原(預設開啟,可隨時關閉)。

所有規則都隔離在名為 inet roamswitch 的專用 nftables 表中,並且永遠不會與其他防火牆配置(ufw/firewalld)發生衝突。手動覆蓋到期(1 小時/2 小時/4 小時/直到午夜/直到清除/直到下次斷開連接)由守護程序作為單一寫入者強制執行。 GUI 永遠不會寫過期日期;它會重新讀取守護程序在下一個時脈週期重寫的 config.json 並將其反映在 UI 中(避免衝突)。

Air-Gap(緊急網路隔離)

一種完全隔離模式,在 inet roamswitch 表的輸入和輸出掛鉤上設定 policy drop(優先權 -100),僅允許 lo。

  • 失敗關閉 — 在守護程序重新啟動時,偵測標記檔案 (/run/roamswitch/airgap.active) 重新斷言隔離。
  • 自我修復 — 如果外部程序刪除帶有 nft delete table 的規則,哨兵循環會在幾秒鐘內重新套用。
  • 低確度觸發由短計時器解除。未在警告情境下按下的手動 Air-Gap(GUI 按鈕或 roamswitch airgap)等低確度觸發,會在短計時器(airgap_low_confidence_secs,預設 600 秒)到期後完整恢復,以免因誤操作或誤報而使裝置長時間斷網。lockdown 之外的 ARP 異常、連接埠異常,以及 eBPF 的 Error 以下等級,在共用狀態機中同樣歸類為低確度,但在用戶端中這些情況不會自動啟動 Air-Gap,僅止於通知與記錄,或封鎖相關連接埠。
  • 高確度觸發不會悄悄恢復。金絲雀遭竄改、eBPF 的 Emergency/Alert(Critical 僅在無法封鎖隔離個別行程時)、與 lockdown 期間閘道相關的 ARP 欺騙,以及為回應 ARP 警告而按下的 Air-Gap(僅在選擇啟用時,還包括執行記錄器的高嚴重度規則,§5),無論經過多久都不會自動恢復。短計時器到期後,每個週期都會複查原因是否仍然存在(被凍結的 PID 是否仍存活、金絲雀是否再次被改寫、ARP 異常是否持續等),只有確認原因已消失時才會附帶通知地解除。無法確認時(包括無法判定)視為「未解決」。勒索軟體的熵突增在以 SIGSTOP 凍結相關行程並發出通知之外,也會啟動 Air-Gap,並同樣視為高可信度觸發條件。
  • DEGRADED(降級)模式 — 高信賴度隔離達到上限時間(airgap_hard_cap_secs,預設 3600 秒,0 = 無上限)後,如果使用者未解除且未確認原因已消失,則轉入 DEGRADED。用戶端版的 DEGRADED 與 FULL 一樣丟棄除迴環外的所有流量(已建立的連線也不放行),差別在於絕不會因時間流逝而自動放開。解除方式只有本機使用者(GUI 的解除按鈕或 roamswitch emergency-restore),或確認原因已消失的複查。Air-Gap 預設還會透過 rfkill 關閉 Wi-Fi 無線(airgapAutoRfkill),DEGRADED 中除非將 airgap_degraded_lift_rfkill 設為 true,否則維持關閉。
  • 轉換的記錄與通知 — 從 FULL 轉入 DEGRADED、各類自動解除以及使用者的解除,都會記錄到事件時間軸並彈出桌面通知。隔離狀態儲存於 /run/roamswitch/airgap_isolation.json,常駐程式重新啟動後仍會保持(重新啟動會使 ARP 複查的連續計數從頭開始,這偏向於繼續維持隔離,即 fail-closed)。
table inet roamswitch {
    chain input {
        type filter hook input priority -100; policy <accept|drop>;
        iif "lo" accept
        ct state established,related accept
        # open 為 policy accept 且無規則。balanced / lockdown 為 policy drop(僅 balanced 允許 ICMP・ICMPv6)
    }
    chain output {
        type filter hook output priority -100; policy <accept|drop>;
        # Air-Gap(隔離)期間會重建同一個表。input / output 皆為 policy drop,僅允許 lo(已建立的連線也不放行)
    }
}

被動式連結防護(網路釣魚連線偵測)

此守護程序監視出站連線的去向,並標記(或者,對於狹窄的「明顯的網路釣魚」集,阻止)與危險主機的連線。它取代了舊的貼上 URL 檢查器,後者需要用戶採取行動。

  • Interception — 專用的 nftables 表 inet roamswitch_linkguard 掛鉤 output 路徑,並透過 NFQUEUE 將 DNS 問題和新的/早期的 Web 連線排隊到使用者空間工作執行緒。 NFQUEUE 是一個基於 AF_NETLINK 的核心↔用戶空間判決通道;守護程序不綁定任何套接字,也不產生任何資料包。佇列規則帶有 bypass,因此如果工作執行緒未運行,流量將暢通無阻(Air-Gap 仍然是單獨的硬停止)。
  • Hostnamesources — DNS 問題名稱、TLS ClientHello SNI(因此使用 DoH 的瀏覽器仍被主機名稱覆蓋)以及明文 HTTP Host 標頭。加密的 ClientHello (ECH) 一旦廣泛部署,就是一個已知的盲點。
  • Verdict(roamswitch-core,純粹邏輯)— 根據本地網路釣魚/威脅來源和一組離線啟發式檢查主機:受保護品牌的 IDN/易混淆同形異義字、非官方網域中的品牌令牌、原始 IP 主機、高風險 TLD。
模式 (linkGuard.mode)Feed 命中或品牌同形異義詞其他可疑訊號
off未檢查未檢查
warn 連線保持長達 8 s + 允許/阻止核准提示既不通知也不阻擋
block(預設) 連線中斷 + 允許對話方塊(每台主機一次)既不通知也不阻擋

只有命中情資來源或屬於品牌同形異義字的主機才會被硬性阻擋(hard-block);僅由啟發式規則單獨標記的項目,一律只停留在警告層級的判定,既不阻擋也不通知。warn 模式會對危險主機的連線最多保留 8 秒並詢問使用者,若保留到期仍無回應,則為 fail-closed(丟棄封包,且不快取判定)。「對確認無回應」不會被視為「允許」,下次存取時會再次確認。即使在 block 模式下,每個主機也只顯示一次通知與允許對話方塊(瀏覽器對同一主機的大量連線不會使通知氾濫)。針對危險目標的核准對話方塊,預設按鈕是「維持阻擋」,「允許」則採用不顯眼的配色。被阻擋的主機若在核准對話方塊中選擇「允許」,會被永久加入 linkGuard.allowlist,在從設定中移除之前都會放行。

DNS 只檢查、不偽造:列入封鎖清單的 DNS 查詢只會產生通知,強制執行發生在後續的 TCP 連線上,RoamSwitch 不會注入偽造的 DNS 回應。情資來源(feed)是編譯好的釣魚/詐騙網域清單,隨套件提供,並由每日更新程式(§11)更新。即使沒有 feed,離線啟發式規則仍會運作。feed 的 Ed25519 簽章與 SHA-256 會在每日更新程式安裝前驗證,不符的資料不會被採用。連結防護會載入已安裝的 feed(若無則使用套件內建的版本),兩者皆無時以「僅啟發式」運作(不會變成「全部允許」)。

VPN 隧道 + 終止開關(主要的 MITM 防禦)

不依賴第 2 層完整性的反 MITM 保護。在不受信任的網路上,到受信任端點的始終在線加密隧道使本地 ARP/NDP 欺騙、惡意 DHCP 和被動嗅探變得無關緊要 — 攻擊者只能看到密文。 ARP/NDP 鎖定和下面的偵測是此功能的次要功能。

兩個後端可供選擇 —「WireGuard(設定檔)」或「Tailscale(退出節點)」。 RoamSwitch 沒有實作自己的加密技術,也不是 VPN 提供者。兩個後端都是可選的依賴項;如果不存在,GUI 將顯示安裝命令。

(A) WireGuard 後端

  • 不提供 VPN 伺服器 — 使用使用者提供的 WireGuard 設定:來自 Mullvad、IVPN 或 Proton VPN 等提供者的 .conf,或使用者自己的 WireGuard 伺服器(VPS 或家庭伺服器)。没有提供默认配置。
  • Config — 守護程序驗證 .conf 並將其儲存在 /etc/wireguard/roamswitch.conf(0600,介面 roamswitch)。它不能存在於其他地方:Ubuntu 24.04+ / Debian 13 上的 AppArmor wg-quick 設定檔拒絕 wg-quick 讀取 /etc/wireguard/ 之外的 .conf — 即使作為 root 也是如此。分割隧道配置(AllowedIPs 不是 0.0.0.0/0 / ::/0)被標記為「並非所有流量都受到保護」。
  • Kill-switch — 專用的 nftables 表 inet roamswitch_vpn(policy drop,兩個鉤子) 丟棄除環回、隧道介面(roamswitch,與 oifname 相符)、固定端點 IP、DHCP 和 ICMP 之外的所有內容。它是在 之前安裝的 隧道啟動(首先透過 getent ahosts 解析到固定 IP 的端點),因此不存在洩漏視窗。如果 wg-quick up 失敗,終止開關將保持開啟狀態。

(B) Tailscale 後端

  • 对于已经运行 Tailscale 的用户。 RoamSwitch not 執行 tailscale up / 登入 / 安裝 tailscaled — 它讀取 tailscale status --json 並執行 tailscale set --exit-node=<node> / --exit-node= (清除)。
  • 需要出口節點 — 反 MITM 保護僅適用於路由所有流量的出口節點。如果未配置任何內容,則不會啟用保護,且 UI 會警告「未受保護」。如果所選節點離線,保護會自動解除並通知使用者(透過死節點路由所有內容將使連線陷入黑洞)。
  • Kill-switch (inet roamswitch_ts, policy drop) — Tailscale 的傳輸無法固定到單一端點 IP(DERP 中繼 + 漫遊對等點),因此這比 WireGuard 更寬鬆 X12__。它允許:環回、隧道介面 (tailscale0)、CGNAT 範圍 100.64.0.0/10 和 fd7a:115c:a1e0::/48、STUN (udp/3478)、DERP (tcp/443)、udp/41641、DHCP、ICMP、MagicDNS (100.100.100.100:53)、已建立的連接。 其他所有內容 — 任意 UDP、本機解析器的 DNS、SMB、mDNS、純文字 HTTP、任意 TCP — 均丟棄。
  • Kill-switch 警告 — (1) 比 WireGuard 後端更廣泛的允許清單(udp/3478、tcp/443、整個 CGNAT /10)。 (2) 路徑上的攻擊者仍然可以看到元資料(Tailscale 正在使用、DERP 區域、計時)並且可以丟棄/延遲 — 但無法讀取隧道有效負載。 (3) 當直接 UDP 被阻止時,機密性將依賴 Tailscale 自己的固定憑證 DERP TLS。 (4) 在 MagicDNS 關閉 + 本機解析器的情況下,DNS 在武裝時中斷(UI 警告)。 (5) 啟用前必須先登入強制門戶。

共通。僅在 vpn_on_untrusted_enabled 且處於 lockdown(外出保護)時才會運作。在 open 與 balanced 下不建立隧道,Tailscale 則清除 Exit Node 並移除終止開關(不會執行 tailscale down)。預設關閉,需選擇啟用。對外通訊的目的地,無論 WireGuard 或 Tailscale,都是使用者自己的 VPN 端點/tailnet,與 lafine 的基礎設施無關(§9)。

預防性 ARP/NDP 鎖定

一旦加入不受信任的網絡,MITM 攻擊者需要模擬的鏈路基礎設施的 MAC 位址就會被 作為 PERMANENT(靜態)條目 固定到核心鄰居表中。一旦固定,核心就會忽略欺騙性的 ARP 回應/鄰居通告。

  • 固定的內容 — (1) IPv4 預設網關,(2) IPv6 預設路由器(通常是鏈路本地 fe80:: 位址),(3) 任何連結 DNS 解析器(透過網關到達公共解析器並被跳過)。 IPv6 鄰居透過 ip -6 neigh replace ... nud permanent 固定。
  • 受信任的網路永遠不會被固定 - 因此家庭路由器重新啟動不會使用戶陷入黑洞。重新固定在每個網路交換器上(TOFU);下次重新連線時將進行合法的故障轉移。固定條目記錄在 /var/lib/roamswitch/arp_lock.json 中。
  • 預設啟用(社群版政策;與 macOS Pro 版本的細分相同)。切換:gateway_arp_lock_enabled。

ARP 欺騙偵測(通知優先)

監控 /proc/net/arp,偵測單一 MAC 對應到多個 IP 的狀態(重複 MAC),以及閘道 MAC 的可疑突然變化。lockdown 期間,只要偵測牽涉閘道,就會全面阻斷通訊(Air-Gap)並發出通知。在 balanced/受信任網路上,則不會立即阻斷,只發出通知,使用者可從 RoamSwitch 執行緊急阻斷。這樣做是為了 (a) 防止攻擊者僅憑一個偽造的 ARP 封包就讓使用者自己斷網的 DoS,並 (b) 避免路由器重新啟動或存取點漫遊時誤觸發。設定項為 arp_spoof_guard_enabled。

解除 Air-Gap 前的確認(ARP 複查)

由 ARP 詐騙引發的 Air-Gap(在 lockdown 期間偵測到,或為回應 ARP 警告而按下)只有在滿足以下條件時才會被視為「原因已消失」而解除。讀取核心鄰居表(ip -j neigh show,備用為 /proc/net/arp)與預設路由,預設閘道的 MAC 必須與觸發時記錄的可信 MAC 一致(狀態為 REACHABLE/STALE/DELAY/PROBE/PERMANENT 之一,且同一裝置上沒有其他 IPv4 主機宣稱擁有該 MAC),並且該狀態連續 arp_recheck_consecutive 次(預設 3)且持續至少 arp_recheck_min_secs 秒(預設 60)。僅當鄰居表項缺失或處於失敗狀態,且連結已連通(有 carrier、operstate 為 up、Wi-Fi 未被 rfkill 阻擋)時,才會向閘道傳送一次 ARP who-has(間隔至少 20 秒,經由 AF_PACKET)進行確認(arp_recheck_active_probe,預設 true)。收到的回應中只要有一個 MAC 不是可信 MAC,即視為不一致。不一致、表項缺失、MAC 重複、讀取失敗、未記錄可信 MAC,均視為「未解決」(fail-closed)並重置連續計數。已知限制:複製真實閘道 MAC 的攻擊者,無論快取判斷或主動探測,任何 MAC 比較都無法偵測。

偵測到 ARP 欺騙時,只有在牽涉閘道的情況下才會自動啟動 Air-Gap。閘道的 MAC 發生變化,以及閘道的 IP 與其他 IP 共用同一個 MAC,都屬於這種情況。其他主機的 MAC 發生變化,或一台裝置以同一個 MAC 回應多個 IP(執行虛擬機器的電腦、帶有別名位址的 NAS 等),只會通知,不會阻斷。解除判定也適用同樣的規則,只有牽涉閘道的重複才會被算作「原因仍在」。在 1.10.7 修正時(2026-09-26),於真實區域網路中從另一台機器傳送偽造的閘道 ARP,約 1 秒就啟動了 Air-Gap,停止攻擊約 11 分鐘後(預設的 10 分鐘加上 60 秒確認)自動解除。即使兩個無關的 IP 持續使用同一個 MAC,也能解除(在採用這項規則之前,會啟動全面阻斷,而且無法解除)。

端口異常守衛

自動包含新暴露給外部 LAN 的偵聽連接埠(後門、C2 或意外綁定至 0.0.0.0 的開發伺服器/本機 LLM API)。結論是 baseline-relative,而不是「危險連接埠號碼」。啟用後,目前公開的可執行檔被學習為「已知」;此後,僅標記 新出現的 公開的可執行檔(身分 = 可執行檔路徑,快照標準化為 snap:<name>)。系統守護程序超出範圍。遏制是透過 inet roamswitch_dev_guard 表進行的:將 TCP 從 lo 以外的任何連接埠丟棄到該連接埠 — 機器本身繼續使用它。自動遏制後,會立即出現桌面通知和確認對話方塊(「允許此連接埠」/「保持封鎖」),允許一鍵永久列入白名單。還可以從端口診斷螢幕單獨允許任何端口,並重新捕獲基線。預設開啟。切換:port_anomaly_guard_enabled。從 macOS 移植。

DNS 隧道/資料外洩偵測

作為被動連結防護既有 DNS 路徑的一部分持續運作(沒有獨立的設定開關)。符合以下任一特徵的查詢會被計為「可疑形狀」,這些都是 iodine、dnscat2 等 DNS 隧道工具的典型特徵:標籤長度超過 40 位元組且 Shannon 熵超過 3.8,或 qtype 為 TXT/NULL 記錄。僅當最近 60 秒內此類查詢達到 10 件時才發出通知(對同一個 apex domain 的重複通知設有 300 秒冷卻時間,通知持續出現時會依序延長為 600 秒、1200 秒,上限為 1800 秒;若超過冷卻時間的 2 倍都沒有通知,則回到 300 秒)。檢查對象僅限 DNS(UDP/TCP 的 53 號連接埠),不檢查其他通訊。僅用於通知,不會自動阻擋。僅有對 clamav.net 的 TXT 查詢不會計入,因為 freshclam 會用它來確認資料新鮮度。底層的 NFQUEUE 規則帶有 bypass,因此即使偵測行程停止或無回應,DNS 流量仍會照常放行。名稱解析不會因為此功能故障而中斷(與被動連結防護本身相同的 fail-open 設計)。

已知限制。以連字號分隔的長主機名稱(例如 prod-us-east-1-web-server-node-0042),以及不區分目的網域的單一全域計數器統計 TXT/NULL 突發查詢的方式,經實測確認會在此處引發誤判。這兩點皆已於 2026-09-23 處理完畢。已透過可設定的 entropy 允許清單,以及按 apex domain(以 QNAME 末尾兩個標籤做的簡易近似,並非嚴格的 Public Suffix List 實作)分開計數突發計數器的方式解決。允許清單預設內建 16 個主流 CDN/雲端服務與 PaaS 的尾碼(cloudfront.net・akamaiedge.net・akamaized.net・edgekey.net・edgesuite.net・fastly.net・azureedge.net・googleusercontent.com・amazonaws.com・r2.dev・workers.dev・vercel.app・netlify.app・supabase.co・firebaseapp.com・web.app),營運者可透過 LinkGuardCfg.dns_tunnel_entropy_allowlist 加入自己組織的內部網域(roamswitch-app 的連結防護設定中有專用欄位,以逗號分隔輸入)。允許清單僅豁免依標籤長度+熵值做出的可疑判定;TXT/NULL 的 qtype 判定不論是否在允許清單內都一律適用,因此可防止攻擊者在允許清單網域下偽裝隧道(僅 TXT 部分,freshclam 用於確認新鮮度的 clamav.net 底下,另以一份小型排除清單不予計數)。突發計數器已按 apex domain 分開計數,消除了因不區分目的地的單一全域計數器而產生的誤判(60 秒滑動視窗的判定邏輯本身未變更。重複通知的冷卻時間從 300 秒開始,通知持續出現時延長至 1800 秒)。iodine、dnscat2 等真實惡意流量只會在單一由攻擊者控制的網域下輪換標籤與 qtype,因此即使改為按 apex domain 計數,偵測能力也不會下降。

Docker 風險偵測與防火牆繞過防護

Docker 的公開連接埠(-p)存在繞過主機標準防火牆的已知問題,因此會始終在 DOCKER-USER 鏈中插入檢查規則,封鎖未被明確允許的外部流量(無需設定,預設始終啟用)。此外,還會即時監視 docker events,在 --privileged 容器啟動或掛載 /var/run/docker.sock(容器逃逸風險)的瞬間偵測並立即通知。由於這僅是有風險的設定而非確認的入侵,因此僅提供通知,不會自動封鎖。

涵蓋範圍 — 此 DOCKER-USER 鏈檢查支援 iptables(IPv4)、IPv6 以及 Docker 原生 nftables 後端,並每 60 秒重新檢查並自我修復(桌面版自 1.10.4 起同樣如此;更早的版本僅涵蓋 iptables(IPv4)後端)。

機密資訊/API 金鑰洩漏掃描器

透過夏農熵與模式比對偵測 OpenAI、Anthropic、AWS、GitHub、Slack、Stripe 等 API 金鑰及 SSH 私鑰。roamswitch audit-secrets <text|檔案|目錄> 除文字、檔案外,還可遞迴掃描整個目錄(自動跳過 .git、node_modules 等,超過 2MB 或疑似二進位的檔案將被跳過)。也可透過 audit_secrets MCP 工具(傳入 text 或 path)以及公開 SDK 的 Rust 用戶端 roamswitch-linux-kit(文字用 audit_secrets(),檔案與目錄用 audit_secrets_path())呼叫相同的偵測。內容絕不會傳送到任何地方。

SSH 暴力破解的偵測與阻斷(僅在 sshd 執行時)

用戶端版的常駐程式也執行與伺服器版相同的引擎(ssh_guard_enabled,預設 true)。差異有三點。第一,只在 sshd 執行時運作:每分鐘檢查一次 SSH 連接埠上是否有監聽,連續三次沒有就停止。沒有 sshd 的終端不會即時讀取日誌,也不會觸碰 nftables 資料表。第二,設定是 config.json 中與伺服器版相同的 10 個鍵(ssh_guard_*)和相同的預設值,約 1 分鐘內生效。第三,通知是桌面通知和用戶端的事件記錄,不會啟動 Air-Gap。失敗次數達到門檻(預設 600 秒內 6 次)的來源,其新連線會被丟棄,同時該來源已建立到 SSH 的連線也會被切斷(已驗證的工作階段與豁免的來源不會被切斷)。當 fail2ban(sshd 的 jail 已啟用)或 CrowdSec 已在保護 sshd 時,只做偵測與通知。封鎖的清單與解除使用 sudo roamswitch bans 與 sudo roamswitch unban <IP>,GTK 介面中沒有,只能透過 config.json 與指令操作。在用戶端的預設防護等級下,入站是關閉的,連線可能根本到不了 SSH。

首次運行設定精靈和確認 UI

軟體包附帶 /etc/xdg/autostart/roamswitch.desktop,因此安裝精靈在安裝後首次登入時啟動(此後它僅駐留在托盤中)。啟用/停用安全防護會顯示與 macOS 版本相同的防護的確認對話框(連接埠異常、ARP 自動遏制、USB 儲存、BadUSB 鍵盤、藍牙)。事件時決策(未知的 USB 鍵盤、未註冊的 USB 隨身碟、自動封鎖的未知連接埠、緊急氣隙)以模式對話方塊的形式呈現。

§5

香農熵突發檢測·YARA掃描

寫入事件依 PID 追蹤。若單一行程在 5 秒內產生 20 個以上熵值達 7.92 以上的不同檔案,即視為勒索軟體的批次加密,並以 SIGSTOP 凍結該行程。同時會發出桌面通知、記錄到事件時間軸,並採集證據套件。此項偵測同樣會啟動 Air-Gap(阻斷整個網路),與金絲雀遭竄改、eBPF 高嚴重度事件一樣,屬於高可信度觸發條件。

在真實機器(Ubuntu 24.04,核心 7.0)上,以改寫 40 個檔案的重現程式進行了測量(2026-09-26 的測量,對象是加入部分加密偵測、包含在 1.10.7 中的版本的守護程式)。全量加密在超過 20 個檔案後即被偵測到,並在第 31 個檔案處凍結。即使行程把自己的名稱改成 python3 或 git,也會被偵測到(允許清單現在不只看名稱,還核對可執行檔與腳本名稱是否一致;此前僅憑名稱,40 個檔案全部漏過)。cp -r、rsync -a、tar -x 和 Python 腳本在看到寫入的時刻就完成行程識別,因此即使很快結束也不會誤報(此前在判定時行程已結束,被通知為「未知行程」)。每 32 位元組只加密 16 位元組的部分加密(LockBit 系的寫法),因整體平均熵達不到 7.92,此前無法偵測,但自 1.10.7 起可以偵測。它辨識的是每 16 位元組交替出現類似亂數的區塊與類似文字的區塊的形態,偵測到模擬檔案的 94%,在 19,997 個一般檔案中誤報為 2 件(0.01%)。不在每個檔案之間停頓、全速寫入的重現程式,會在 20 件的判定之前就寫完 40 件,因此停下來時行程已經結束;若每件間隔 0.2 秒,則會在第 20 件停下。只加密開頭、跳著區段加密,以及把加密後內容寫成 Base64 的情況,不計入偵測,只寫入記錄而不凍結(因為可能誤報一般檔案)。用允許清單中的真實程式(如 python3)撰寫的勒索軟體,也無法藉由名稱區分。

  • YARA 掃描與熵偵測分離 — YARA 惡意軟體偵測會對所有寫入的檔案執行,包括 ~/.cache/、node_modules/ 與各種壓縮檔,不以副檔名排除(使用者設定的 scan_exclusions、隔離 Vault、/dev/shm 以及記憶體上或已刪除的檔案、/proc・/sys・/dev 等位置,以及守護程式本身、ClamAV、桌面基礎元件等系統行程所寫入的內容除外。讀取的是開頭 256 KB)。另一方面,熵加密突發判定則排除原本就已壓縮的格式(.zip, .tgz, .tar.gz, .gz, .png, .jpg, .mp4, .wasm 等)、開頭仍保持正規壓縮/媒體格式的檔案(1.10.25 起),以及正規套件管理器(npm, npx, cargo, rustc, dpkg, apt, tar 等)的快取作業,以避免展開正規工具時因誤報而被 SIGSTOP 凍結。
  • 相同檔案的重複覆蓋 (例如 shred 的三次)算一個事件。
  • 關鍵行程保護 — 與寫死的受保護行程清單(PROTECTED_PROCESS_NAMES,含 systemd / dockerd / NetworkManager / sshd / gnome-shell 等)比對,名稱相符且可執行檔位於系統區域(/usr、/opt 等)的行程絕不凍結(防止整台機器當機)。僅名稱相似、位於 /tmp 或 /home 的程式則不受保護。

Web 應用層偵測規則(Web Shell 與注入程式碼)

用專用規則偵測 PHP、JavaScript、JSP、ASP 的 Web Shell、被注入的混淆程式碼、偽裝成圖片的 PHP,以及透過 .htaccess 劫持執行的手法。它與針對 ELF 和 shell 的內建偵測各自獨立,以一種簡單的語言撰寫,只含字面值、帶間隔上限的字面值序列與兩個統計值(極長的單行、巨大的 Base64)。不使用正規表示式,因此處理不會膨脹或卡死,即使規則檔是惡意的,也最多造成誤報。規則不含從真實樣本擷取的簽章,也不綁定任何具名惡意軟體家族:18 條規則只描述公開記載的手法(執行解碼函式的輸出、直接執行請求值、上傳目錄中可執行的 PHP、圖片中的 PHP、.htaccess 處理器對應、用 unescape 組出的注入腳本、瀏覽器內挖礦函式庫)。

規則分三層:產品內建的、由每日更新程式(11.3)在驗證簽章後安裝的,以及 /etc/roamswitch/rules.d/*.json 中的自訂規則(只讀取 root 所有且群組與其他使用者不可寫的檔案)。嚴重度為 critical、high、medium、low;critical 與 high 進入確認或隔離流程,medium 以下僅回報。自動隔離預設僅限 critical(/etc/roamswitch/web_rules.conf 的 quarantine),用戶端版在寫入或執行時的偵測仍由使用者在確認對話框中決定。tests/、fixtures/、.git/ 之下因測試程式碼會使用相同寫法,預設不偵測。

偵測之後,若在 /etc/roamswitch/hooks/post-detection 放置可執行檔,偵測內容(JSON)會透過標準輸入傳給它(僅執行 root 所有、不可寫且父目錄也安全的檔案;不經過 shell,環境變數極少,30 秒後終止)。選用的帳號處置(預設關閉)會停用被隔離檔案擁有者的登入 shell。它不會處理 root、UID 低於 account_min_uid(預設 1000)的帳號、已登入的使用者與常駐程式自身的使用者,並會記錄原 shell,可用 roamswitch web-rules unlock-account 還原。誤報實測:WordPress 核心 2,409 個檔案、phpMyAdmin 3,356 個檔案、npm 相依套件 14,743 個檔案均為 0 筆。限制:只讀取開頭 256 KB(寫入/執行時)與 4 MB(掃描),無法追蹤變數名稱拼接('ev'.'al')這類拆分;因沒有真實樣本,未附帶針對已知惡意軟體的個別簽章。

金絲雀(誘餌文件)

誘餌檔案被放置在使用者的文件、桌面、下載和圖片資料夾以及專用目錄中,並以 3 秒為週期與 SHA-256 基線進行比較。任何重新命名、刪除、截斷或內容變更都會立即觸發 Air-Gap。因為守護程式以 root 身分執行,所以它會列舉 /home/* 並將金絲雀部署到每個真實使用者的目錄中。

證據保全包(鑑識自動採集)

只有在勒索軟體的熵突發偵測被觸發,或 eBPF 執行階段威脅感測器的 Critical 嚴重度事件促成了針對單一行程的定點隔離(SIGSTOP + 網路阻斷)時,roamswitch-incident-capture 才會啟動,並將證據套件儲存到 <狀態目錄>/incident-evidence/<時間戳>-<短 ID>/。採集內容包括:於預設路由介面上以 tshark 進行、限定 30 秒的封包擷取(若未安裝 tshark 則記錄為跳過),以及在有傳入 PID 時,目標行程的 /proc/<pid> 快照(status/cmdline/maps,將疑似機密資訊的值替換為 [REDACTED] 的 environ,已開啟檔案描述符的連結目標清單——不採集其內容——以及祖先行程的系譜)。單一證據項採集失敗不會視為致命錯誤,只會記錄該情況並繼續採集其餘內容。eBPF 事件會傳入目標行程的 PID。熵突發偵測在能特定出寫入的行程時會傳入 PID;若在判定突發之前該行程已結束,則以無 PID 的方式啟動,因此只採集封包擷取。當定點隔離無法執行或失敗而回退為整個主機的 Air-Gap 隔離時,以及由 Emergency/Alert 類事件觸發的整個主機隔離,皆不會執行證據採集。截至 1.10.4 的發行套件並未包含執行此功能所需的 roamswitch-incident-capture,因此以套件安裝的環境中該功能並未運作。自 1.10.5 起已隨附。

採集結果彙整於 manifest.json 中,其中也內嵌了包內其他所有檔案的 SHA-256 雜湊(供事後偵測竄改)。證據包不會自動刪除——只有在明確執行 roamswitch-incident-capture prune(預設保留 30 天)時,舊的證據包才會被刪除。

採集到的證據在採集當下並不會被驗證。若需事後確認是否遭竄改,請執行 roamswitch-incident-capture verify <證據包目錄> [--json]。此指令會對證據包內目前的所有檔案重新計算雜湊,並與 manifest.json 中記錄的值比對,將差異分別回報為「已修改」「遺失」或「未記錄」(存在但清單中未記錄的檔案)。

已知限制 — 此驗證會把 manifest.json 的 SHA-256 與保存在證據包之外的記錄進行比對,記錄在兩處:證據包之外的雜湊鏈(evidence_anchor.log,每一行都連接到上一行,並在檔案系統允許時設為僅附加)和系統日誌(標籤 roamswitch-evidence)。採集後改寫 manifest.json 會使 verify 失敗;修改或刪除鏈中的某一行也會因鏈斷裂而失敗。但如果擁有 root 權限的攻擊者能同時改寫這條鏈和系統日誌的轉送目的地,則無法防範。建議把系統日誌轉送到另一台機器。尚未實作簽章。沒有記錄的證據包(由舊版本採集)會顯示為「無記錄」,表示沒有外部佐證。

蜜令牌(憑證誘餌)

守護行程啟動時,會在攻擊者及自動化竊取憑證工具實際會掃描的已知真實路徑——~/.aws/credentials、~/.ssh/id_rsa、~/.docker/config.json・~/.pypirc・~/.env.backup(位於呼叫使用者的主目錄下)——冪等地部署包含 ROAMSWITCH_HONEYTOKEN 標記的偽造憑證檔案。若該路徑下已存在真實檔案,則絕不覆寫(部署前一律先檢查檔案是否存在)。對蜜令牌的實際存取還可能觸發連鎖部署,追加相關的誘餌檔案。截至 1.10.4 的發行套件未包含此功能所需的 roamswitch-honeytokens,因此以套件安裝的環境中該功能並未執行。自 1.10.5 起已隨附。自 1.11.1 起,RoamSwitch 本身執行的 docker 指令,會以空的專用目錄作為 DOCKER_CONFIG 啟動,因此不會對誘餌 ~/.docker/config.json 產生反應。其他程式讀取時,會和以往一樣偵測。

背景監控行程以僅用於通知的 fanotify(以檔案為單位監控對各誘餌的 FAN_OPEN/FAN_ACCESS),監看對各誘餌的讀取與開啟。在無法使用 fanotify 的環境(例如非 root 執行)則切換為 inotify。由於正常行程原本沒有理由讀取這些檔案,因此任何存取都會被視為入侵者得手後偵察(MITRE ATT&CK T1552)的強烈訊號,系統會嘗試識別存取來源行程,並以 Critical 嚴重度記錄到事件時間軸(不會顯示桌面彈出通知;若已啟用事件轉送,則屬於轉送對象)。不過,RoamSwitch 自身可執行檔的存取,以及 OpenSSH 用戶端系列(ssh、scp、sftp、ssh-add、ssh-agent)對 SSH 誘餌的存取,為避免誤報而不記錄。無法特定可執行檔的存取則會記錄。此功能僅用於記錄,不會對存取來源行程進行凍結或阻斷等額外處置。

已知限制 — ~/.ssh/id_rsa 誘餌的主體包含可讀文字,作為正規 OpenSSH 私密金鑰的 base64 主體仍屬無效格式。不過多數機密掃描工具僅憑比對 -----BEGIN ... PRIVATE KEY----- 標頭的正規表示式就會標記,因此我們判斷這對實際運作中的偵測率影響有限。另外,存取來源行程的識別,通常是從 fanotify 事件所帶的 PID 取得。只有在無法使用 fanotify 而切換為 inotify 時才會呼叫 fuser,因此對於讀取後立即結束的極短命行程,可能無法取得其 PID 與行程名稱。此時僅視為未知,不影響對存取本身的偵測(事件觸發與記錄)。

fanotify 監控 · 隔離函式庫 · ClamAV

  • 守護程式以 FAN_CLASS_CONTENT(許可模式;不可用時改用 FAN_CLASS_NOTIF),以檔案系統為單位的標記監控 /home・/tmp・/var/tmp・/dev/shm(1.10.18 起;以掛載點為單位的標記,是檔案系統單位不被接受時的替代方式),寫入完成的通知則對整個 / 也以檔案系統為單位設定。自 1.10.4 起,許可事件僅限執行(FAN_OPEN_EXEC_PERM),open 則作為通知處理(可用 fanotify_open_perm 恢復舊行為)。已判定為乾淨的可執行檔會快取 60 秒,守護程式自身的子行程不在監控之列。
  • notify-first・確認前不隔離(fanotify 防護)。fanotify 防護對於 YARA/ClamAV 的單純命中,不會在未經確認下隔離,也不會執行 FAN_DENY。偵測到真實特徵碼時,會在 /run/roamswitch/approvals.json 中提出對話請求(隔離/允許/稍後),在使用者確認之前不會進入 Vault。只有實際的 execve,在 pre_exec_blocking_enabled 啟用時才會 FAN_DENY。核准逾時時為 fail-open。下載監控(預設為 ~/Downloads 與 ~/Desktop,可用 watched_folders 追加)是另一條路徑,對於 YARA 或 ClamAV(EICAR 除外)偵測到的檔案,會不經確認直接移入隔離 Vault 並發出通知。
  • EICAR 等測試簽章僅記錄至通知歷史 — 業界標準測試字串不會發出通知,只會記錄至通知歷史,並且在 fanotify 防護和下載防護中都不會被隔離或阻止。
  • YARA 和 ClamAV 掃描器都遵循使用者配置的 scan_exclusions 路徑清單(絕對路徑,遞歸應用;它包含舊版 clamav_exclusions)。提示上的「允許」和「隔離」標籤中的「復原」都附加到它,因此不會重新標記相同檔案。
  • 偵測到的真實惡意軟體(在 fanotify 防護中為使用者已確認者)會退避到僅限 root 存取的 /var/lib/roamswitch/quarantine/(以前是各使用者的 ~/.local/share/roamswitch/quarantine/,啟動時會從舊儲存位置自動遷移)。Vault 目錄為 root 擁有的 0700,樣本為 root 擁有的 0400(唯讀、不可執行)。使用者只能透過守護程式的 IPC 操作,且只能列出、還原、刪除自己隔離的項目。還原時,由降權為呼叫者使用者權限的子行程,以 0644 的檔案寫出(不會覆寫既有檔案)。
  • 許可事件迴圈不讀取設定檔——設定由專用的背景執行緒讀取到 Mutex<GuardConfig> 快照中,熱路徑上對設定的處理只有鎖定+複製(讀取即將執行的檔案開頭來做判定的處理則另當別論)。這是為了避免延遲 FAN_OPEN_EXEC_PERM 而讓機器卡死所設計的不變條件。
  • 若有 ClamAV(clamav_enabled,預設啟用),對於出現在下載監控目標資料夾(預設為 ~/Downloads 與 ~/Desktop)中的新檔案,會在內建 YARA 之後再以本機資料庫掃描。.exe 等 Windows 用的可執行格式會發出通知,.sh・.deb・.elf 等 Linux 的發行格式只記錄到歷史紀錄,危險的 AI 模型(.pkl・.pt)則會連同來源一併通知。ClamAV 是可選的相依元件,即使未安裝,其他防禦仍會運作。若已安裝,每日更新程式(§11)會執行 freshclam,讓特徵碼資料庫保持最新。

行程執行記錄器(僅本機)

這是一個僅限本機的記錄功能,透過 netlink 行程連接器(proc connector)記錄 exec 與 uid 變化。記錄內容包括可執行檔路徑、命令列參數(最多 64 個、每個 512 字元、合計 4096 字元,超出截斷,控制字元跳脫)、父行程譜系、uid、目前目錄、容器 ID、可執行檔的 SHA-256 等。預設啟用,但在記憶體不足 1 GiB 的機器上預設關閉(明確設定 exec_recorder_enabled 優先)。其自身 CPU 使用限制在單核的 3% 以內(exec_recorder_cpu_budget_pct),並以 nice 10 執行。無法開啟行程連接器時,會降級為低頻率的 /proc 掃描(會漏掉生命週期很短的行程)。

  • 儲存 — 記錄以按 8 MiB 分段的 JSON Lines 形式儲存於 /var/lib/roamswitch/exec_log(0600)。預設保留 200 MB/14 天(exec_recorder_retention_mb/exec_recorder_retention_days)。附帶雜湊鏈,可以偵測竄改,但無法防止竄改(取得 root 的攻擊者可以重寫整條鏈)。檢索使用 roamswitch events search|tree|export|verify,面向 AI 用戶端的唯讀 MCP 工具是 search_exec_events/get_process_tree。
  • 僅通知的關聯規則(EXR-001~010) — 共 10 種:由 Web 服務啟動 shell、從 /tmp、記憶體上檔案(memfd)或已刪除檔案執行、下載後立即執行、base64/eval 單行指令、沒有 setuid 路徑卻取得 uid 0、執行緊隨 cron/systemd 設定之後放置的二進位檔、/etc/ld.so.preload 變更後的執行、本機快照(btrfs、LVM)被 snapper 或 timeshift 等已知管理工具以外的對象刪除(EXR-008,1.10.11)、同一個執行來源在 30 秒內以 which 等方式尋找 8 種以上的攻擊工具(EXR-009,1.11.0)、python 或 node 等腳本直譯器在 2 分鐘內啟動 3 種以上的攻擊工具(EXR-010,1.11.0;由人在 sshd・login・終端機之下輸入的情況不在此限),每條規則都標註 MITRE ATT&CK 的技術 ID。規則只發通知,單獨不會隔離;僅當維運人員明確啟用 exec_rules_isolation_optin(預設 false)時,高嚴重度規則才會被當作 Air-Gap 的高確度觸發(§4)。
  • 不會傳送到裝置之外 — 原始日誌不會被轉送。僅當啟用事件轉送(§9.4)時,才會把規則通知(嚴重度、規則 ID、行程名稱、摘要)與分段封印雜湊,且僅傳送到維運人員所設定的目的地。

憑證檔案存取監控(預設開啟,僅通知)

預設啟用(credential_access_watch_enabled 為 true;設為 false 即停止,也可以用惡意軟體防護畫面中的開關切換)。當 SSH 私密金鑰(~/.ssh/id_*)、~/.aws/credentials、~/.config/gcloud/ 底下的憑證檔案(credentials.db 等 4 種)以及主流瀏覽器的憑證/Cookie 儲存區被意料之外的程式開啟時,會發出通知(僅通知)。它只是對少數檔案個別設定 fanotify 通知類別的 FAN_OPEN,完全不會阻擋、凍結或拒絕,核心也不等待回應。開啟檔案的程式的可執行檔名稱,會與依類別劃分的允許清單(ssh/git/gpg-agent、瀏覽器、aws/terraform/kubectl 等)比對,同一(程式,檔案)的重複通知會被抑制 10 分鐘。備份工具(restic、borg 等)和索引器(tracker、baloo 等)從一開始就被允許。其他不希望收到通知的程式,請加入 config.json 的 credential_access_watch_allow。針對 AWS 的憑證,像 boto3 腳本或 Ansible 這類以 python/python3/ansible 身分執行的工具也被允許(gcloud 則允許 python/python3)。不過 python -c 這類單行指令仍會通知。這項允許的代價是,以 python 腳本檔形式執行的憑證竊取程式也不會被通知。node、ruby 等其他直譯器,以及 grep、rclone 之類通用的搜尋與同步工具,由於竊取憑證的程式也會以相同形式執行,因此沒有加入允許清單,可能會產生通知。不過,對於 cat 或 head 這類極短的讀取,若程式在 RoamSwitch 識別出其可執行檔之前就已結束,可能不會通知(持續執行一段時間的程式所做的讀取會通知)。RoamSwitch 不會為了避開這項限制而使用權限判定類別的 fanotify,因為這可能導致系統停止運作。變更約 30 秒內生效,不需重新啟動。

附在檔案竄改通知中的入侵路徑

用戶端版的關鍵檔案完整性監控(FIM)與相依鎖定檔監控的通知中,也會附上做出修改的行程(帳號、可執行檔、指令)以及該行程所屬的 SSH 登入(來源、時間、驗證方式)(config.json 中的 fim_intrusion_context_enabled,預設 true,不會向外部傳送任何內容)。憑證檔案存取監控的通知,只有在該行程屬於某個 SSH 登入時才會多出一行。運作方式、信任的值,以及三種答案(找到了/沒有找到 SSH 登入/無法查明登入路徑)的區分,都與伺服器版相同。無法查明的情況,絕不會寫成「不是登入」。記錄保存在 /var/lib/roamswitch/fim_intrusions.json 以及 MCP verify_fim 的 recentIntrusionContext 欄位中。

核心本地權限提升 (LPE) 搶佔與強化

當攻擊者或惡意軟體取得非特權使用者立足點時,深度防禦可防止利用 Linux 核心漏洞取得 root 權限。

  • 非特權使用者命名空間的處理方式(Frag Gap CVE-2026-53362 對策) — 許多現代 Linux 核心權限提升漏洞,起因於非特權使用者呼叫 unshare(CLONE_NEWUSER) 建立使用者命名空間後,在其中對未初始化的結構或舊的網路子系統進行非法存取。診斷會檢查並顯示 user.max_user_namespaces 與 kernel.unprivileged_userns_clone 的狀態,但由於可能導致瀏覽器、Flatpak、Electron、rootless 容器等無法運作,Client 版不建議停用,也不納入一鍵強化(若 user.max_user_namespaces = 0,會引導還原為標準值)。停用只是暫時緩解,僅能堵住需要建立使用者命名空間的攻擊路徑,對其他途徑無效。只在不受信任網路期間把 kernel.unprivileged_userns_clone 設為 0 的行為,只有在 guard.yaml 的 adaptive_security.untrusted_network_actions.auto_enable_userns_restriction 明確啟用時才會套用(預設為停用。在沒有此設定項的核心上不會執行任何動作)。Server Edition 預設會永久套用(harden_userns_enabled)。根本的辦法是更新到已修復的核心並重新開機。
  • Yama LSM 內存保護 — 強制執行 kernel.yama.ptrace_scope = 1(或 2)可防止未經授權的進程透過 ptrace 附加或透過 /proc/$pid/mem 讀取內存,從而保護瀏覽器會話和 GPG/SSH 私鑰。
  • Core Dump Suppression — 設定 fs.suid_dumpable = 0 可防止敏感進程將純文字記憶體轉儲寫入磁碟而導致崩潰。
  • /tmp 和 /dev/shm noexec 安裝防禦 — 為了防止有效負載丟棄並執行攻擊,RoamSwitch 在連接到不受信任的網路時會使用 noexec,nosuid,nodev 重新安裝 /tmp 和 /dev/shm。

eBPF 運行時威脅感測器和自主進程凍結(桌面 eBPF Guard)

RoamSwitch 用戶端守護程式包含與核心內現代 eBPF 感測器(Falco / Tetragon / BTF)的本機整合。

# eBPF 執行階段威脅偵測與自主攔截流程
[惡意行程 (LPE/惡意軟體)]
    │ 非法系統呼叫執行 (Frag Gap 利用嘗試)
    ▼
[Linux 核心 (eBPF 探針)]
    │ eBPF 環形緩衝區 (2MB 精簡設計)
    ▼
[Falco (RoamSwitch Optimized)]
    │ 記憶體內 UNIX 套接字直接通訊 (/var/run/roamswitch/events.sock)
    ▼
[roamswitch-daemon (root)]
    ├─► ① 以毫秒級凍結攻擊行程:kill(pid, SIGSTOP) [狀態:Ts]
    ├─► ② 阻斷網路:Critical 僅限該行程的使用者 (roamswitch_isolate),Emergency/Alert 則為 nftables input/output drop [啟動 Air-Gap]
    └─► ③ 桌面緊急通知:GTK3 模態視窗 & libnotify 通知
  • Direct UNIX Domain Socket IPC (/var/run/roamswitch/events.sock) — 來自 Falco 或其他 eBPF 感測器的警報直接透過記憶體中 UNIX 套接字接收,無需寫入磁碟日誌,從而消除磁碟 I/O 延遲並實現亞秒響應切換。
  • 毫秒級自主回應(行程凍結&網路阻斷) — 當收到的事件優先順序為 Critical(核心 LPE、權限提升、勒索軟體加密等)時,守護程式會對該 PID 送出 SIGSTOP 使行程完全停止(狀態:Ts),並以 roamswitch_isolate 表僅阻斷該行程的實際使用者(容器則為其 cgroup)發出的通訊,執行「定點隔離」,同時發出桌面通知。當無法特定 PID、因屬於受保護行程而拒絕凍結、對 root 行程等隔離失敗,以及優先順序為 Emergency/Alert 時,會在 inet roamswitch 表部署 policy drop(Air-Gap),若知道 PID 也會送出 SIGSTOP。低於 Critical 的事件不會阻斷,只記錄到歷史紀錄。
  • 面向桌面的低負載及日誌膨脹防止調校(RoamSwitch Optimized) 為了抑制筆記型電腦與工作站的電池消耗、CPU 負載與磁碟耗盡,針對導入 Falco 的環境,提供了最佳化設定檔(99-roamswitch-optimized.yaml)與 logrotate 設定。Client 版的套件與 install.sh 的桌面模式不會安裝 Falco,也不會放置此設定檔(Server Edition 的套件與 install.sh --server 才會放置)。若要在 Client 上使用 Falco,需由使用者自行安裝 Falco,必要時自行放置此設定檔。主要設定如下。
    • 嚴重性過濾 (priority: warning) — 過濾掉 95% 的常規通知/資訊事件。
    • Kernel Early Drop (drop_failed_exit: true) — 直接在核心驅動程式中丟棄失敗的系統呼叫退出,將上下文切換和 CPU 負載減半。
    • 緊湊環形緩衝區 (cpus_for_each_buffer: 2) — 將環形緩衝區大小減少至 2MB,將常駐 RAM 保持在 30–50MB,CPU 使用率 <1%。
    • 強制日誌輪替上限 (/etc/logrotate.d/roamswitch-falco) — 透過 7 代壓縮輪換強制實施嚴格的 50MB 上限。
  • 獨立強化與 eBPF 擴充的混合韌性 — 即使未安裝 Falco,也能以核心 sysctl(Yama 的 ptrace 限制、停用核心傾印、網路防護;每次切換設定檔時套用)、nftables 設定檔、fanotify 與金絲雀監控自主防禦。安裝 Falco 後,更加上即時 eBPF 事件的零時差攔截與行程凍結,實現最高強度的防禦。

§6

USB事件被監控;追蹤鍵盤類別 (HID) 裝置和 USB 大容量儲存。 預設為關閉 (出貨 isEnabled = false,與 macOS USBKeyboardGuard / USBStorageGuard 相符)。從首次執行精靈或 USB 標籤中選擇加入;啟用會顯示確認對話方塊。

流氓 USB 鍵盤(擊鍵注入)

  • 無核心層級實體連接埠取消授權(重要)。舊的實作(≤1.0.6)將 0 寫入 /sys/bus/usb/devices/*/authorized 對於未註冊的鍵盤,物理上斷開連接。在鍵盤+滑鼠組合接收器(常見於 Raspberry Pi 或迷你 PC)上,這也會斷開滑鼠連接,從而鎖定沒有內建輸入的機器。 RoamSwitch 現在硬拒絕將 authorized=0 寫入任何暴露 HID 介面 (bInterfaceClass 03) 的設備,守護程式在啟動時重新授權任何 authorized==0 HID 設備,以自我修復先前版本變磚的機器。
  • 按鍵在軟體中刪除。 在偵測到未註冊的鍵盤時,會在該裝置的 /dev/input/eventN 上取得獨佔的 evdev EVIOCGRAB(僅在 /proc/bus/input/devices 中具有 kbd 處理程序的節點,與 VID:PID 相符)。滑鼠節點未受影響。這是 macOS CGEventTap 的 Linux 版本;裝置保持通電狀態。
  • Safety — 只有在有另一個鍵盤可供輸入(內建鍵盤或經批准並連接的 USB 鍵盤)時才會進行抓取,因此具有單一新鍵盤的機器永遠不會被鎖定。
  • 核准對話框 — 抓取鍵盤的同時,會將核准請求寫入 /run/roamswitch/approvals.json,GUI 顯示強制回應視窗(允許/拒絕)。允許後將裝置加入白名單並解除抓取。若 3 分鐘內無人核准,預設不再釋放鍵盤(1.10.4 起;更早的版本在 3 分鐘後故障開放,啟用 usb_keyboard_timeout_release 可恢復舊行為)。

流氓 USB 大容量儲存設備

當插入未註冊的 USB 大容量儲存裝置(不含 HID 者)且防護已啟用時,會以 authorized=0 保留(因不含 HID 而安全),並顯示核准對話方塊。是否為受信任網路在所不問。已掛載或正用於 swap 的磁碟(使用中的外接磁碟、Live USB 等),因可能形同被直接拔除而損壞,不會保留,只寫入記錄。選擇允許時會重新授權並登錄到白名單,選擇拒絕則持續保留。macOS 版自 1.7.4 起統一採用這種「唯讀保留+核准提示」方式。

識別和追溯

HID 的判定依據 bInterfaceClass == "03" 與 /proc/bus/input/devices 的 Handlers= 行。組合接收器(單一 VID:PID 同時具有 kbd 與 mouse 兩個區段)依 VID:PID 合併。把既有鍵盤登錄到允許清單的 grandfathering,是由 GUI 而非守護程式執行。在初次設定精靈中啟用時(以及防護已啟用且已完成初次設定、但連線中的鍵盤在允許清單中一個也沒有的既有環境,首次遷移時),會把當時已連線的鍵盤登錄到允許清單。之後才在 USB 分頁啟用,則不會登錄。守護程式啟動時已連線但未登錄的鍵盤,因可能在啟動前被替換,會視為未登錄,若還有其他可輸入的鍵盤,則成為抓取(grab)對象。

§7

roamswitch-core 的 LinuxHealthChecker 評估 27 個項目,產生 0 至 100 的分數、S/A/B/C 等級(100 分為 S,85 至 99 為 A,70 至 84 為 B,低於此為 C)以及各項目的改善建議。不論從 GTK 儀表板、CLI(roamswitch status)或 MCP(get_security_report)查看,全部 27 個項目的標題、詳細資訊與建議文字都以使用者的語言顯示(支援 10 種語言)。

評估類別
類別範例專案
磁碟/啟動LUKS / dm-crypt 加密、UEFI 安全啟動
存取控制LSM (AppArmor / SELinux)、SSH / sudo 設定審核
內核強化sysctl 強化、非特權使用者命名空間的狀態確認(Frag Gap 對策;Client 版不建議停用)、Yama 的 ptrace 限制、核心傾印控制、/tmp 和 /dev/shm 的 noexec
更新自動安全性更新配置
網路ARP欺騙監控、閘道ARP/NDP鎖定狀態、暴露埠稽核、Wi-Fi加密強度
惡意軟體確認 ClamAV(含以 EICAR 進行的偵測實際運作測試)/ fanotify(也確認防護的實際運作,以及是否因佇列溢位而遺失事件)/ 熵監控 / noexec / 輔助程式(honeytoken 與證據採集)的安裝
瀏覽器Firefox / Chrome / Chromium 安全瀏覽設置
網域解析/USB威脅防護 DNS、USB 匯流排的零信任狀態
容器與弱點Docker Socket 掛載暴露、特權容器(--privileged)稽核、容器執行階段隔離等級(runc / gVisor / Kata)、執行中核心的已知 CVE 暴露

每次檢查都基於讀取本機檔案和命令輸出(getenforce、mokutil、resolvectl、ss、...)。 沒有任何類型的外部查詢。

信任感知分級. RoamSwitch 故意在受信任(家庭)網路上套用 not 進行強化 — 將網關 MAC 固定為永久(這將在路由器重新啟動時使 LAN 陷入黑洞)、重新安裝 /tmp 和 /dev/shm noexec 下的系統套件顯示為綠色帶有解釋而不是紅色的“未強化”,並指出它會自動應用於不受信任的網路。執行時期真相來自 /run/roamswitch/state.json (active_level / network_trusted / fanotify_ready),由守護程式在每個週期寫入。 fanotify 項檢查防護是否確實被標記並且正在運作(/run/roamswitch/fanotify.ready),而不僅僅是核心支援它。暴露連接埠項目讀取守護程式的即時設定檔(MCP 硬程式碼已消失)。

每項強化。 具有自動修復功能的失敗項目(核心 sysctl / Yama / 核心轉儲、/tmp noexec、USB 零信任、網關 ARP 固定、威脅保護 DNS、fanotify 防護關閉時重新啟動守護程序)在 GTK 儀表板中帶有「🔧 強化」按鈕。守護程式以 root 身分執行,因此除了守護程式重新啟動之外不需要 pkexec 。

NIST CSF 2.0/CIS Controls v8 對應

為 27 個項目各自標註 NIST CSF 2.0 的功能/類別識別碼(例如 PR.DS-01、DE.CM-09),並僅針對能取得高確度對應的項目,一併標註 CIS Controls v8 的控制編號(例如 3.11、4.1)。對應關係不明確的項目不會被勉強標註,而是維持未對應狀態。MCP(get_security_report)與 CLI 的 JSON 輸出(roamswitch status --json)包含此對應(nistCsf/cisControl)。GUI 以及 Client 版 CLI 的一般顯示不會出現(Server 版 roamswitch status --server 的顯示則會出現)。這項對應是為了讓需要符合法遵要求的維運人員與稽核人員,能將 RoamSwitch 的各項檢查機械式地對應到既有框架。

§8

roamswitch-mcp 是透過 stdio 使用 JSON-RPC 的 MCP 伺服器,由 Claude Desktop、Cursor、Antigravity 等 AI 用戶端啟動。所有工具都是唯讀的,且絕大多數完全在本機完成。唯一可能連線外部主機的是預設關閉的 run_npm_audit_signatures。診斷評估(get_security_report 與 verify_security_findings)不會向區域網路傳送任何內容,閘道也只從 ARP 快取等本機資訊中讀取。只有在重新取得閘道 MAC 的其他處理(常駐程式的 ARP 監控、緊急復原、Sensor 配對、get_guard_status 等)中才可能送出 ping。

主要公開工具(完整清單見 MCP 連線設定)
工具目的
取得安全報告27項評估、評分、建議
verify_security_findings依目前狀態重新評估 get_security_report 中的各項目(checkId),並為每個項目回傳 stillPresent(仍然存在)、resolved(已解決,或依設計不適用)、inconclusive(無法判定)三者之一,以及與語言無關的原因代碼。用於在修復之後確認問題是否真的消除;因權限不足、特權輔助程式未連線、無法存取 Docker 等原因而未能量測的項目,不會被回報為安全,而是回傳 inconclusive。省略 checkIds 時檢查所有項目(最多可指定 Mac 50 項、Linux 64 項;Linux 還可指定 isServer)。Mac 上的 host_firewall、network_stealth_mode、gateway_arp_lock、malware_scanning、dns_threat_guard、usb_zero_trust 由 RoamSwitch 應用程式內設定的值決定是否合格,因此這些項目反映的是應用程式內設定,而不是對作業系統實際狀態的重新量測。唯讀,不會連線外部主機,也不會進行修復或變更任何設定。在 Linux 上也不會向區域網路傳送任何內容,只會從本機快取讀取閘道。在 Mac 上,為查詢閘道的 MAC 位址,可能會向區域網路內的閘道傳送 ICMP ping,通常 1 次(查不到 MAC 時最多數次)。
audit_mcp_configs讀取 AI 用戶端的 MCP 設定檔(Claude Desktop、Claude Code、Cursor、Windsurf、VS Code、Cline、Gemini CLI,以及已登錄專案資料夾中的 .mcp.json 等),指出有風險的設定。會偵測不需逐次確認就自動核准的工具(auto_approve)、非 loopback 主機上的明文 http:// 伺服器(不僅是 url 欄位,以 --server http://… 這類啟動參數傳入的連線目的地也包括在內。remote_plain_http)、以 shell 或直譯器單行指令啟動(shell_wrapper)、取得未固定版本的套件或映像檔的 npx / uvx / docker run 等啟動方式(unpinned_package_launcher)、帶有 --privileged 或掛載了 Docker 套接字、根檔案系統的 docker run(container_host_access)、讓行程在啟動時載入額外程式碼的環境變數(如 LD_PRELOAD、NODE_OPTIONS 中的 --require;名稱不區分大小寫,不回傳值;code_loading_env)、指向無認證攻擊工具後端 HexStrike AI 的設定(hexstrike)、群組或其他使用者可寫入的設定檔(world_writable_config),Claude Code 的 enableAllProjectMcpServers(auto_trust_project_servers),以及同一設定檔中同時存在讀取他人撰寫文字(網頁、郵件、聊天、Issue)的伺服器和可執行指令或修改檔案的伺服器的組合(間接提示注入的前提條件;依知名套件名稱判斷,不檢視伺服器工具的內容;injection_exposure)。無參數、唯讀,不會向網路傳送任何內容。不會回傳環境變數或標頭的值、參數與任何機密,只回傳伺服器名稱、指令名稱、URL 主機,以及(為登錄庫名稱時的)套件或映像檔名稱。無法解析的檔案會列在 unreadableFiles 中,表示未被稽核。
audit_agent_setup讀取提供給 AI 代理的指示檔與技能(~/.claude 下的 CLAUDE.md、commands、agents、skills,以及 ~/.codex、~/.cursor/rules、~/.gemini、~/.agents、~/.openclaw,和已登錄專案資料夾中的 CLAUDE.md、AGENTS.md、.cursorrules 等)和 OpenClaw 的 openclaw.json,指出危險的內容與設定。對於指示與技能檔,會偵測隱藏在不可見 Unicode 標籤字元中的句子(hidden_tag_characters)、零寬字元和改變文字方向的控制字元(invisible_characters)、要求忽略先前指示或向使用者隱瞞的措辭(override_instruction)、curl … | sh 這類下載後直接執行的寫法(remote_script_exec)、解碼後執行編碼字串(encoded_payload_exec)、對金鑰與憑證存放位置的引用(credential_access)及其附近的外送或資料接收服務位址(credential_exfil_shape、exfil_endpoint)、設定重新啟動後仍保留的機制(persistence_instruction)、技能中的已編譯程式碼(skill_precompiled_code)和他人可寫入的檔案(agent_file_writable)。HTML 註解中的內容在渲染後會被隱藏,因此以較高風險處理。對於 OpenClaw,會偵測驗證被關閉(openclaw_auth_disabled)、可從網路存取的監聽方式(openclaw_wide_bind)、不足 24 個字元的權杖(openclaw_weak_token)、允許所有來源(openclaw_origin_wildcard)、已開啟的 dangerously… 開關(openclaw_dangerous_flag)、信任所有對象的代理設定(openclaw_broad_trusted_proxy、openclaw_proxy_trust_loosened)、對任何人開放的私訊或群組策略(openclaw_open_dm)、mDNS 的 full(openclaw_mdns_full)、被隱藏的自我檢查結果(openclaw_audit_suppressed)以及寬鬆的權限(openclaw_loose_permissions)。所有規則都是確定性的,符合只表示「需要人來讀一讀」,並不斷定為惡意。無參數、唯讀,不會向網路傳送任何內容。不會回傳檔案本文或機密(權杖只回報長度),只回傳規則名稱、行號、URL 主機和設定鍵路徑。無法讀取的檔案會列在 unreadableFiles 中,表示未被稽核。
取得暴露端口暴露的連接埠及其防火牆阻止狀態
獲取守衛狀態目前保護等級和防禦模組狀態
審核網址安全啟發式 URL 安全分析(不取得目標)
審計秘密偵測文字中的 API 金鑰/秘密(不傳輸文字)
審計安全日誌本機日誌/驗證日誌的聚合
get_quarantine_status / get_canary_status檢疫和加那利州
取得應用程式協助搜尋內建知識庫
run_active_vuln_scan僅限 127.0.0.1 的非破壞性實證型漏洞驗證。不會連線其他主機,但屬於會發送網路請求的工具,因此預設關閉,需在設定中主動啟用。
run_package_cve_scan將已安裝的套件(Mac:Homebrew / Linux:dpkg・dnf・zypper・pacman)與本機 CVE 對照表比對。完全不產生任何網路通訊。在 Linux 上,如果無法取得套件清單或逾時,不會回報「無符合項目」,而是 complete 為 false,並在 incompleteReason 中給出原因(未完成的結果不等於沒有問題)。 在 Ubuntu(20.04、22.04、24.04、26.04)上,使用 Ubuntu 專用資料,依來源套件名稱與來源版本比對,只檢查 Ubuntu 已發布修復、CVSS 7.0 以上的 CVE,因此「無符合項目」不代表沒有已知 CVE。結果中增加 ecosystem 與 release,每筆偵測帶有 binary(已安裝的二進位套件名稱);只有 Ubuntu Pro 才能修復的漏洞帶有 proOnly。Ubuntu 衍生版(Linux Mint、Pop!_OS 等)與不支援的版本會回傳 complete 為 false,並在 incompleteReason 中給出原因,不會改用 Debian 的資料。
run_package_cve_scan_languages將 npm / PyPI / crates.io / RubyGems / Packagist / Go / Maven 等相依性鎖定檔與同一本機 CVE 對照表比對。完全不產生任何網路通訊。
get_vulnerability_scan_history針對 scan-vulns --confirm 記錄的每個探測項,回傳自上次實際執行並確認以來經過的天數(pass_age_days)。
verify_fim重新計算 23 個固定的關鍵系統檔案、認證/cron/systemd/SSH 設定等 12 個目錄下的全部檔案、RoamSwitch 自身的二進位檔以及各使用者的 authorized_keys 的雜湊,並與基準線比對,驗證是否遭竄改及是否有新增檔案。以 root 執行時,結果中還會包含新增欄位 recentIntrusionContext。對每次最近的變更,會給出做出修改的行程(帳號、可執行檔、指令)、該行程所屬的 SSH 登入(來源、登入時間、驗證方式),或無法查明的原因。
get_file_scan_guard_status回傳檔案掃描防護(ClamAV)的設定,以及其所用隔離 Vault 的狀態(這是供 Server Edition 使用的工具,並非用戶端版惡意軟體防護的設定)。
get_port_anomaly_incidents回傳連接埠異常防護的基準狀態、目前自動阻斷的連接埠,以及最近 50 筆事件。回應中明確註明:目前自動阻斷的連接埠是不含時間戳記的當前狀態快照,與含時間戳記的事件歷史是兩回事。
get_ebpf_incidents回傳 eBPF 執行期防護的目前隔離狀態,以及觸發隔離的事件歷程。在 Server Edition 上,每筆記錄還會附帶從偵測到處置的時間(毫秒,detect_to_receive_ms、receive_to_action_ms、detect_to_action_ms),結果中還包含 Falco 心跳檢測的狀態(heartbeat)。
get_ssh_guard_incidents傳回 SSH 暴力破解防護的狀態與紀錄。包括:是否執行封鎖還是只做偵測(例如另一個防禦工具已在保護 sshd)、目前被封鎖的來源位址與剩餘時間,以及最近的紀錄(封鎖、僅偵測、失敗累積的來源位址登入成功,三者之一,最多 200 筆)。嘗試過的使用者名稱本身在 Linux 上不儲存(只記數量),在 Mac 上經過無害化處理後最多傳回 5 個。Mac 還會傳回最近的 SSH 登入(來源位址、使用者、驗證方式、金鑰指紋)。唯讀,沒有解除封鎖的 MCP 工具。Linux 上封鎖清單只有 root 能讀取,因此以一般使用者執行時只傳回數量。Linux 可用於 Server Edition,以及 sshd 正在執行的 Client Edition;Mac 僅限 Pro 版。
get_resource_guard_incidents回傳資源耗盡/行程異常偵測防護的歷程(記憶體洩漏、當機迴圈),並附確度等級(此防護屬於 Server Edition,在用戶端版中不會運作,因此結果恆為空)。
get_notification_history回傳 RoamSwitch 傳送的通知(安全記錄稽核異常、ClickFix 偵測等)歷史記錄,最近1週、最新在前。
get_incident_timeline將各防護模組的偵測結果整合為單一時間軸回傳(含行程譜系與 MITRE ATT&CK 標籤,實驗性)。

實證型弱點檢測也會為每個已確認的探測項記錄自上次實際執行並確認以來經過的天數(pass_age),藉此區分「該檢查存在」與「該檢查確實最近被驗證過」。由於目前尚無排程執行機制,此數值僅反映實際執行掃描的頻率。CLI(roamswitch vuln-status)、GUI 與 MCP(get_vulnerability_scan_history)皆可查看相同的經過天數,讓維運人員或稽核人員能掌握上次實際確認的時間,而非僅憑功能存在就假定近期已確認。

MCP 伺服器本身不開啟任何網路連線。直接連到守護程式 Unix 套接字(/run/roamswitch/roamswitch.sock)的只有 get_sensor_audit_results,其他工具都只是直接呼叫 roamswitch-core 的邏輯,或讀取守護程式寫入的狀態檔(roamswitchkit 方向相反,是供 CLI 等以子行程方式啟動 roamswitch-mcp 的 SDK)。例外是兩個預設關閉的工具:run_active_vuln_scan 會向 127.0.0.1 的主機本身送出非破壞性探測;run_npm_audit_signatures 會啟動 npm 指令,由 npm 向 npm 登錄庫發出查詢(MCP 執行檔本身不含 HTTP / TLS 堆疊)。診斷評估(get_security_report 與 verify_security_findings)不會向區域網路傳送任何內容,閘道的確認也只是參照 ARP 快取等本機資訊。只有在重新取得閘道 MAC 的其他處理(守護程式的 ARP 監控、緊急復原、Sensor 配對、get_guard_status 等)中才會送出 ping。

在本機 LLM 實戰演練中發現並修正的錯誤歸因問題
2026 年 9 月,我們使用本 MCP 伺服器讓本機 LLM(Qwen 3.8 27B)進行一次事件調查實戰演練(fire drill)時,發現模型誤讀了 get_port_anomaly_incidents 回傳的資料,把一個與本次事件無關的舊連接埠阻斷紀錄,錯誤地編入了目前正在發生的事件敘述中。原因在於:不含時間戳記的「目前阻斷連接埠」快照,與含時間戳記的真實事件歷史,在同一個回應中未加區分地一併回傳。修正方案是新增說明欄位,明確標註哪一部分是時間軸資料、哪一部分只是快照。修正後,用同一情境對同一模型重新執行,模型引用了說明欄位中的文字,明確拒絕將舊連接埠歸因於目前事件。我們透過自動迴歸測試與真實本機 LLM 重現兩種方式,驗證了修正的有效性。

§9

RoamSwitch for Linux 預設發出的對外通訊只有一種:每日更新程式對已簽章清單的 GET 請求(§11)。其餘所有診斷、偵測與稽核均在本機完成。只有在維運人員或使用者明確啟用或觸發時才會發生的通訊,列於 9.4。RoamSwitch for Linux 為專有免費軟體,原始碼不公開,因此下列檢查由 lafine 執行,結果見 9.2,附錄 C 的步驟僅憑發行套件即可重現。

9.1 審核方法

  1. crate 隔離 — 只允許一個 crate 使用 HTTP 用戶端/TLS 堆疊,即建置計時器驅動更新程式二進位檔的 roamswitch-updater。scripts/audit_no_network.sh(在 CI 中作為閘門執行)在下列情況會使建置失敗:roamswitch-core、roamswitch-daemon、roamswitch-app、roamswitch-mcp、roamswitchkit(以及 CLI 與 Server 系列 crate)引入了 reqwest / ureq / rustls / native-tls / openssl-sys 等 HTTP 用戶端/TLS 堆疊;或 roamswitch-updater 及 9.4 所列檔案之外的 .rs 使用了 TcpStream / TcpListener / UdpSocket / to_socket_addrs / lookup_host。唯一額外的許可是僅在 roamswitch-core 中允許 tonic / hyper,用於經由 UNIX 網域通訊端與 eBPF 感測器(Tetragon)進行 gRPC 通訊;同一腳本禁止將其與 TLS 搭配使用。
  2. 依賴樹檢查 — 搜尋完整的 Cargo.lock 以尋找遙測/分析/崩潰報告 SDK(sentry、opentelemetry,...)。
  3. roamswitch-updater review — 它的單一請求目標,沒有查詢字串與 cookies,且能表明軟體身分的標頭只有固定的 User-Agent,以及它下載的所有內容的 Ed25519 驗證。
  4. 子程序列舉 - 每個Command::new(...)呼叫站點都經過審查。

9.2 結果

審核結果
審核項目結果
HTTP / TLS 堆疊僅存在於 roamswitch-updater (ureq + rustls) 中。不在 core / daemon / app / mcp / kit 中
遙測/分析/崩潰報告 SDK不存在任何地方
TcpStream / TcpListener / UdpSocket除 roamswitch-updater 外,僅存在於 9.4 所列的四個選用功能檔案中
使用的 Socket APIAF_UNIX(本機 IPC)/AF_NETLINK(NFQUEUE verdict 通道、nftables 與 ip neigh 控制——不向外傳送)/AF_INET 僅用於 roamswitch-updater 與 9.4 的選用功能(TLS/HTTP 交由系統的 openssl/curl 子行程處理)/AF_PACKET 僅在 ARP 複查(§4)向閘道傳送一個 ARP who-has 時使用(區域網路內)。啟用 VPN 通道(§4)時,由 wg-quick(WireGuard 後端)或 tailscaled(Tailscale 後端)——兩者皆為子行程而非常駐程式——向使用者自己的端點/tailnet 傳送流量
每日更新約每 24 小時對 GET https://lafine.net/updates/v1/manifest 與簽章 manifest.sig 各發出一次(資料本體僅在版本更新時額外取得)。無查詢字串、無 Cookie、固定的 User-Agent: RoamSwitch-Updater(唯一表明軟體身分的標頭)、無裝置專屬識別碼。所有內容均以 Ed25519 驗證。設定 updates.enabled = false 即可完全停止
VPN 隧道 (§4)預設關閉。啟用後,wg-quick 會建置一條到 使用者自己的 .conf 端點的 WireGuard 隧道 — 與 lafine 無關。透過 getent ahosts (glibc NSS) 解析端點主機名,而非 Rust 套接字 API
許可證啟動離線Ed25519簽章驗證。與啟動伺服器沒有通信
結論

RoamSwitch for Linux 預設發起的對外通訊只有一種:每天一次、僅接收的簽章清單確認,以及有新版本時的簽章偵測資料下載。兩者都不含任何使用者或裝置資訊。除非維運人員或使用者明確啟用或操作,產品的其他任何部分都不會聯繫外部伺服器(9.4)。為了鄰居表固定與 ARP 監控而送往 LAN 內的 ping(9.3 的 #2),目的地僅限於 loopback、私有、link-local 與 ULA 位址,不會送往公開位址。

9.3 面向外部的操作的完整列表

無論直接或間接,可能使封包離開本機的預設路徑操作(下表;僅在維運人員或使用者啟用或觸發時才發生的操作見 9.4):

#操作目的地觸發發送了什麼
1每日更新程式 — GET /v1/manifest 及其簽章。各項資料僅在版本更新時取得(核心、作業系統套件與語言的 CVE 對照表約每 30 天確認一次;尚無 Ubuntu CVE 對照表的 Ubuntu 裝置於下一次每日執行時取得)lafine.net/updates/v1 (CDN)systemd 計時器。啟動 15 分鐘後開始,之後約每 24 小時一次(最多隨機延遲 3 小時)。updates.enabled = false 或停用 roamswitch-update.timer 時不會發生普通的 HTTPS GET:沒有查詢字串,沒有 cookies,固定的 User-Agent: RoamSwitch-Updater, 與使用者或機器無關。接收簽署的清單 + feed
1afreshclam(ClamAV 自己的更新程式),安裝 ClamAV 時由每日更新程式呼叫ClamAV 計畫的 CDN屬於 #1 的一部分。此外,使用者按下畫面上的「立即更新病毒定義 (freshclam)」按鈕時也會啟動ClamAV 本身的流量(一個單獨的專案); RoamSwitch 只啟動它
2ping -c 1 -w 1 -W 1 <閘道 IP>(對 IPv6 路由器,以及 LAN 內的 DNS 伺服器也各執行一次同類的 ping)LAN 的預設閘道。在確認 ARP/NDP 固定時,則包括 IPv6 預設路由器,以及 resolv.conf(systemd-resolved 則為 /run/systemd/resolve/resolv.conf)中列出的 DNS 伺服器之中,位址為 loopback、私有、link-local 或 ULA 者。不會向公用解析器(威脅防護 DNS 如 Quad9 等)傳送封包閘道僅在 ARP 監控等需要 MAC,但 ARP 快取、鄰居表、15 秒內的備份都沒有時才會發出(對同一目的地最多每 8 秒一次)。對 IPv6 路由器與 DNS 伺服器,則是在閘道 ARP 固定(gateway_arp_lock_enabled,預設開啟)重新做鄰居表固定時發出(切換到非受信任網路時,以及切換設定時)僅一次 ICMP 回應請求(含 ping 的標準資料)。不做 DNS 解析
3啟動系統瀏覽器 (xdg-open)https://roamswitch.com/linux(產品網站)、https://lafine.net/(營運者網站、服務條款、聯絡我們)、https://github.com/lafine1211/roamswitch-support(版本說明與支援)僅當使用者點選按鈕(例如「開啟發行說明」)時RoamSwitch 進程未開啟套接字;它將 URL 傳遞給作業系統瀏覽器
4解析 dns ...—(RoamSwitch 本身不發出任何通訊)不受信任網路上的威脅保護 DNS(預設開啟,可關閉)。 <iface> 是每個帶有預設路由的實體網路卡(同時有線+無線;lo / tailscale* / wg* / docker* / veth* 除外);當 dns_scope = always_on 時也應用於可信任網路;協調每個哨兵週期僅變更作業系統的解析器設定。RoamSwitch 本身不送出 DNS 查詢。設定後,這張網路卡的名稱解析會改走所選的威脅防護 DNS(預設為 Quad9)
5套件管理器更新發行版的 apt / dnf / zypper / pacman 儲存庫當使用者執行 apt upgrade 等,或按下 GUI 的「立即升級」按鈕(透過 pkexec 執行 apt-get / dnf / zypper / pacman)時apt 系只會讀取本機 apt-cache policy 的輸出並啟動套件管理器。dnf 系在開啟更新分頁等情況下會執行 dnf check-update,可能向已設定的儲存庫查詢(zypper 為 zypper list-updates,pacman 為 pacman -Qu)。這些都與 lafine 無關
6VPN 隧道 (§4) — WireGuard 後端:隧道 wg-quick 建造/Tailscale 後端:tailscale set --exit-node 透過出口節點路由所有流量使用者自己的VPN端點/tailnet(WireGuard:.conf中的端點;Tailscale:所選的出口節點和DERP中繼)當 vpn_on_untrusted_enabled 且網路不受信任時。預設關閉加密的 WireGuard / Tailscale 流量;目的地是使用者自己的VPN伺服器/tailnet,與lafine無關。透過 getent ahosts (glibc NSS) 進行 WireGuard 端點解析; Tailscale 由 tailscaled 驅動(一個單獨的進程)

除上述內容外,RoamSwitch 的所有功能(nftables 控制、neigh 表的 ARP/NDP 固定(ip neigh,不傳送封包)、連結防護(NFQUEUE,僅 AF_NETLINK)、連接埠掃描(解析 ss 輸出)、ARP 監控、健康診斷、熵監控、金絲雀、fanotify、USB 監控(evdev 獨占)、隔離、日誌稽核、URL 與機密資訊稽核)均僅透過讀取本機檔案與解析子行程輸出完成。§4 的 VPN 通道屬於「使用者明確設定的對外通訊」,其目的地是使用者自己的 VPN 伺服器,沒有任何資料流向 lafine 的基礎設施。9.4 中各項功能的目的地於 9.4 逐一說明。

9.4 僅在選擇啟用或使用者操作時才會對外接觸的操作

9.3 的表格是預設情況下發生的操作。以下是程式碼中開啟套接字或把通訊委託給外部程式(curl/openssl/npm)的位置,且只有在維運人員或使用者明確啟用或操作時才會執行。scripts/audit_no_network.sh 只允許 event_forward.rs・webhook_guard.rs・active_vuln_scan.rs・web_vuln_scan.rs・sensor_pairing.rs 這 5 個檔案使用套接字 API(webhook_guard.rs 僅在啟用預設關閉的設定 forward_webhook_block_private_addresses 時,才會用系統解析器查詢 Webhook 目的地的名稱,以確認是否為內部位址,並不會建立連線。另有 tests/fleet_roundtrip.rs 僅用於測試,只連線 127.0.0.1 上的模擬伺服器),其他原始碼若使用 TcpStream 等則建置失敗。這些功能同樣不會引入 HTTP/TLS crate:TLS 交給系統的 openssl,HTTP 交給系統的 curl 子行程。

  • 事件轉送(event_forward.rs)——預設 OFF(forward_enabled = false),目的地也只有維運人員手動設定的,沒有內建目的地。支援的目的地類型有:syslog(RFC 5424 或 CEF,UDP/TCP/TLS)、JSON Lines 檔案、附 HMAC-SHA256 簽章的 Webhook。TLS syslog 透過系統的 openssl s_client,Webhook 透過系統的 curl(URL、簽章等機密經由標準輸入的設定傳遞,不出現在命令列參數中),常駐程式本身沒有 TLS/HTTP crate。傳送的只有主機名稱、事件 ID、時間、來源、嚴重度、規則、處置、PID、行程名稱與摘要這些欄位(不含檔案內容,也不含執行記錄的原始日誌)。經 TCP/TLS/Webhook 未能送達的事件會存入 0600 的磁碟佇列(預設上限 20 MB/72 小時)並重試。
  • Fleet(Business 層,僅裝置端)(roamswitch-core/src/fleet/)——裝置端程式碼包含在主程式中,但未註冊的裝置不會傳送任何內容,也不會解析 Fleet 主機名稱(工作執行緒只讀取一個本機狀態檔案)。只有維運人員執行 roamswitch fleet enroll 時才會註冊。管理服務端尚未部署或發行,目前沒有可連線的對象。程式碼中體現的設計保證如下。(a) 裝置只接收由組織簽章的政策設定資料,並以註冊時固定的組織公開金鑰驗證,驗證未通過的政策不會被套用。設計上組織的簽章金鑰由客戶持有,lafine 不持有。(b) 不存在遠端命令通道(裝置端沒有任何可以命令其隔離、解除、收集或執行的端點、欄位或程式碼路徑)。(c) 政策無法削弱本機下限(停用防護、妨礙解除/緊急復原在綱要中根本無法表達,取值採用「較嚴格的一方」)。政策要變更事件轉送目的地,也只能改為本機 root 允許的主機(fleet_forwarding_allowed_hosts,預設為空)。(d) 裝置傳送的僅是最小狀態摘要——應用程式版本、作業系統類別、隔離狀態(正常/隔離中)、已套用的政策版本、健康評分(0~100)與金鑰世代——以及簽章標頭中的裝置 ID 與組織 ID。通訊使用系統的 curl(TLS),且僅限已註冊的裝置。
  • Sensor 配對(sensor_pairing.rs)——預設 OFF(sensor_pairing_enabled)。只會直接連線維運人員輸入的 Sensor 位址,沒有內建目的地。支援 TLS 1.3(透過系統的 openssl,並固定憑證指紋),但沒有指紋的舊式配對會在警告後退回為明文。Sensor 是另一款產品,不在本文件 Zero Telemetry 的適用範圍內。
  • 實證型弱點檢測(active_vuln_scan.rs/web_vuln_scan.rs)——預設停用,需要在設定中選擇啟用。本終端版的路徑僅限於對本機已觀測到的監聽連接埠向 127.0.0.1 發出探測(由模組自身的測試固定)。
  • GUI 的「檢查更新」按鈕 — 只有使用者按下按鈕時,在 apt 系的發行版中,GUI 才會用系統的 curl 對 https://lafine.net/apt/dists/stable/main/<arch>/Packages 發出一次 GET 以查詢最新版本(逾時 4 秒;不含機密的公開 URL,不附加識別碼或查詢字串)。dnf・zypper・pacman 系則不使用 curl,而是向各自的套件管理器查詢(9.3 的 #5)。
  • npm 簽章驗證 — roamswitch audit-npm-signatures <DIR> --confirm 只有在啟用設定 npm_audit_signatures_enabled(預設 false)且使用者加上 --confirm 執行時才會運作,由 npm 本身向 registry.npmjs.org 查詢。

§10

  • 沒有帳戶 — 無需用戶註冊,無需登錄,也無需請求電子郵件地址。
  • 配置僅在本機 — 以明文形式儲存在 ~/.config/roamswitch/config.json 處,並且永遠不會離開機器。沒有雲端同步。
  • 評估結果僅在本機 — 安全性報告和日誌審核結果僅顯示在螢幕上,如果使用者選擇,也可以匯出至本機檔案。
  • 許可證金鑰已離線驗證 — Pro / Business 許可證令牌包含 Ed25519 簽章並使用公鑰進行驗證。不會向 lafine 伺服器發出任何查詢。
  • 沒有崩潰報告 — 發生緊急情況時,不會向任何地方發送堆疊追蹤。
  • 每日更新程式不會傳送任何有關您的資訊 — 沒有查詢字串、沒有cookie、沒有裝置或安裝層級的識別碼,能表明軟體身分的標頭只有固定的 User-Agent: RoamSwitch-Updater。這是下載,不是報告。連結防護判決、封鎖的主機和掃描結果僅寫入本機活動視圖/日誌,從不傳送。
  • 使用威脅防護 DNS 期間,DNS 查詢會送達外部解析器。威脅防護 DNS(§4.5。預設開啟,僅針對不受信任的網路)會將作業系統的 DNS 解析器指向 Quad9(9.9.9.9,也可選擇 Cloudflare 的 1.1.1.2)。這段期間的查詢是由作業系統而非 RoamSwitch 送往該解析器,RoamSwitch 本身不會傳送任何內容。若要停止,請將 dns_enabled 設為 false。
  • 通知歷史 7 天後自動刪除,且限制長度 — 已傳送通知的歷史儲存在本機,每次寫入時都會刪除超過 7 天的項目。每則標題最多 200 個字元,內文最多 2000 個字元(桌面通知彈窗內文最多 1000 個字元)。除非啟用事件轉送(預設 OFF),該歷史不會離開本機。
  • 執行記錄同樣僅限本機 — 行程執行記錄器(§5)的記錄預設也只儲存在本機(/var/lib/roamswitch/exec_log,0600)。由於包含命令列參數,會依保留期限(預設 14 天)與容量(預設 200 MB)自動刪除。

§11

版本
版本對於價格許可證
社群版Linux 個人使用、公司內部業務使用(不限台數)免費專有免費軟體(捆綁 EULA)
業務(計劃)車隊管理、策略分發、簽署內部 apt、組織 SLA付費商業許可證。相同的二元+層門

Business 層級開始提供時,方針是向 macOS 版 Pro Lifetime 的購買者免費授予其本人 Linux 電腦上的 Business 功能。目前尚未提供 Business 層級,也沒有管理伺服器。

經銷和供應鏈

頻道詳情
APThttps://lafine.net/apt (stable main)。 Release 使用 RSA-4096 金鑰簽名
轉速https://lafine.net/rpm(單獨的 Fedora / openSUSE)。 repomd.xml GPG 簽名
尿素尿率roamswitch-bin(準備中。由於 AUR 暫停了新帳號註冊,目前請從 https://lafine.net/linux/dl/PKGBUILD 以 makepkg 安裝。lafine.net/linux/dl 的 tarball 以 sha256 與分離簽章(validpgpkeys)驗證)
壓縮包https://lafine.net/linux/dl/ 提供 x86_64 / aarch64 的 .tar.gz + .sha256 + .asc(以儲存庫簽署金鑰產生的分離簽章)。原始碼儲存庫不公開,因此一般使用者的取得來源是此處,而非 GitHub Releases
  • 固定 glibc 地板 — 發行版二進位檔案建置在 Debian 12(書蟲、glibc 2.36)容器內。這可以防止 Debian 12 / Ubuntu 22.04 及更高版本上的符號版本不符。如果引入需要超過 2.36 的依賴項,「驗證 glibc 底層」CI 步驟將導致建置失敗。
  • 簽署金鑰管理 — apt/rpm 儲存庫簽署的私鑰僅存在於 GitHub Actions 加密金鑰中;僅將公鑰提交至儲存庫。

11.3 每日更新程序

roamswitch-updater 是由 systemd 計時器(roamswitch-update.timer,開機 15 分鐘後執行,之後每 24 小時一次,最多隨機延遲 3 小時)執行的獨立二進位檔。預設情況下,它是唯一會連向外部發行 URL 的元件(9.4 的選用功能除外)。每次執行:

  1. GET https://lafine.net/updates/v1/manifest 及其獨立簽章。
  2. 使用專用的威脅來源簽章金鑰驗證清單的 Ed25519 簽章 - 與 Sparkle 應用程式更新金鑰分開。伺服器端 CI 每天都會對 feed 進行重新簽名,以便私鑰存在於 CI 秘密中;將其範圍限定為提要意味著洩漏只會讓攻擊者提供錯誤的阻止清單(污水坑/警告 - 沒有程式碼路徑,沒有應用程式更新路徑)。應用程式更新簽章金鑰永遠不會離開 macOS 鑰匙圈。未驗證的清單將被丟棄 - 更新程式永遠不會回退到未簽署的資料。
  3. 如果威脅來源版本發生更改,請下載該來源,驗證其 SHA-256 和 Ed25519 簽名,並為連結防護自動安裝它 (§4)。其他資料只在清單版本更新時取得(實證型弱點檢測的 CVE 對照表和熱門 npm 套件名稱清單)。核心、作業系統套件和語言生態系的 CVE 對照表,只在距上次更新約 30 天後才取得。Ubuntu 的 CVE 對照表只在受支援版本的 Ubuntu 上取得;尚未安裝的裝置不等 30 天,於下一次每日執行時取得。所有資料都在驗證簽章後才安裝。
  4. 清單版本更新時,也會取得Web 應用層偵測規則(§5)。先驗證 SHA-256 與 Ed25519 簽章,並確認其可作為規則讀取,然後以原子方式安裝。無法讀取的檔案不會被安裝,正在使用的規則也不會被取代。不會新增連線目標,而是併入同一次清單取得。Server Edition 遵循 cve_kernel_map_updates_enabled,關閉後完全不進行網路通訊。
  5. 如果安裝了 ClamAV,則呼叫 freshclam。
  6. 記錄最新的應用程式版本以取得通知(更新程式 never 安裝應用程式;在 Linux 上,使用者執行 apt upgrade)。

任何步驟的失敗(離線、簽章不正確、找不到 freshclam)都會記錄在 updates.json 的 lastError,且行程一律以 exit 0 結束,因此計時器執行不會產生 systemd 的失敗通知。整個機制可用 updates.json 的 "enabled": false,或 systemctl disable --now roamswitch-update.timer 停用,此時僅以套件內建的資料運作。威脅情資來源也內建於套件中,因此全新安裝後立即可用,即使停用更新程式,也會隨 apt upgrade 更新。

§12

  • OS:Ubuntu 22.04 / 24.04 以上、Debian 12 以上、Linux Mint / Pop!_OS / elementary / Zorin、Fedora / RHEL 系、openSUSE、Arch 系(AUR 準備中,需由 PKGBUILD 安裝)、Raspberry Pi OS 64bit(Bookworm)、Ubuntu for Raspberry Pi
  • 架構:x86_64 / aarch64
  • 必要:systemd、nftables、iproute2(ip neigh、ARP/NDP 固定)、conntrack、libnotify(桌面通知)(systemd 以外皆由 .deb / .rpm 的相依性自動安裝)
  • 選用:clamav(惡意軟體掃描)、nmcli(Wi-Fi 加密判定)、iw(無線資訊的替代方案)、bluez(Bluetooth 防護)、systemd-resolved(威脅防護 DNS 的設定)、lsof(偵測監聽連接埠的替代方案)、nmap(主動式弱點驗證的輔助)、wireguard-tools(VPN 隧道 + 終止開關的 WireGuard 後端,§4)、tailscale(同為 Tailscale 後端,§4)、polkit / pkexec(從 GUI 升級、解除安裝、重新啟動守護程式)
  • 不支援:非systemd發行版(Alpine / Void / Devuan)
  • Display:1280×720或更大(視窗和字體自動縮放到螢幕尺寸,支援小型Raspberry Pi顯示器)

附錄 A

板條箱目的網路
serde / serde_json配置和IPC的序列化無
東京非同步執行環境(features = ["full"];預設僅使用 Unix 通訊端)無(預設不使用 TCP;選用的 Sensor 配對除外)
追蹤/追蹤訂閱者日誌記錄(本地/日誌)無
這個錯誤/無論如何錯誤處理無
正規表示式字串解析(診斷、CSS 縮放)無
網址URL 解析(audit_url_safety 啟發式)無(不獲取)
計時日期/時間處理無
ed25519-dalek離線驗證授權簽章,以及更新程式的清單、威脅情資來源等簽章資料(選擇啟用的 Sensor 配對也會使用)無
Base64/SHA2許可證令牌、金絲雀哈希無
庫chown / kill / 系統調用無
伊德娜解碼 IDN/punycode 主機以進行同形異義字偵測無
nfq(僅限守護程式)連結防護的 NFQUEUE 綁定 — 純 Rust,AF_NETLINK無(判定通道,無出口)
打開為開啟「開啟版本說明」以及 EULA、支援頁面的連結而呼叫 xdg-open進程本身不進行通信
GTK3 / ksni(僅限應用程式)GUI 和托盤無
serde_yaml讀取 /etc/roamswitch/guard.yaml(core)無
toml解析 Cargo.lock / poetry.lock(語言套件的 CVE 掃描,core)無
md-5連結防護 (Link Guard) 的 JA3 指紋雜湊(非用於認證或完整性,core)無
bs58加密資產私密金鑰的 Base58 檢查(機密資訊偵測,core)無
rand產生選擇性啟用的 Sensor 配對所用的裝置金鑰(core)無
tonic / tonic-prost / prost / tower / hyper-util與 Tetragon 感測器之間的 gRPC。僅使用 Unix 網域通訊端,無 TLS(core)無(僅 Unix 通訊端)
flate2RHEL 系套件 CVE 對照表的 gzip 解壓縮(僅 updater。純 Rust)無(僅解壓縮)
inotify監控對蜜令牌(認證資訊誘餌)的存取(roamswitch-honeytokens)無
aya實驗性 XDP 開機閘門的載入器(roamswitch-xdp-gate。由 daemon 參照)無(僅 bpf() / netlink)
urlencoding / gdk / gdk-pixbuf / glib / pangoGUI 的 URL 解碼與 GTK3 的周邊 crate(僅 app)無
ureq + rustls(僅限 roamswitch-updater)每日更新程式的 HTTPS GET(清單、簽章、有更新的資料)樹中唯一的 HTTP/TLS 堆疊;僅限於更新程式二進位文件
要點

roamswitch-core・roamswitch-daemon・roamswitch-app・roamswitch-mcp・roamswitchkit 中沒有任何連向網際網路的 HTTP 用戶端、TLS 堆疊或遙測 SDK。roamswitch-core 所含的 tonic / hyper 僅用於與 Tetragon 之間 Unix 域套接字上的 gRPC,不含 TLS,也不會連到網路。ureq + rustls 僅存在於 roamswitch-updater(由 CI 的 scripts/audit_no_network.sh 強制執行)。任何地方都沒有遙測 SDK。

附錄 B

table inet roamswitch {                 # 設定檔防火牆(open / balanced / lockdown)
    chain input {
        type filter hook input priority 0; policy <accept|drop>;
        ct state established,related accept
        iif "lo" accept
        ip protocol icmp accept            # open 為 policy accept 且無規則。balanced / lockdown 為 policy drop(僅 balanced 允許 ICMP・ICMPv6)
    }
    chain output {
        type filter hook output priority 0; policy accept;
    }
}

table inet roamswitch {                 # Air-Gap(隔離)期間會重建同一個表。input / output 皆為 policy drop,僅允許 lo(已建立的連線也不放行)
    chain input  { type filter hook input  priority -100; policy drop; iif "lo" accept }
    chain output { type filter hook output priority -100; policy drop; oif "lo" accept }
}

table inet roamswitch_linkguard {        # §4.5 — 獨立於設定檔表
    chain output {
        type filter hook output priority 0; policy accept;
        udp dport 443 reject with icmpx type port-unreachable   # 僅在啟用 block_quic 時(預設為關閉)
        meta l4proto udp udp dport 53      queue num 92 bypass
        meta l4proto tcp tcp dport 53      queue num 92 bypass
        meta l4proto tcp tcp dport { 80, 443 } ct state new,established ct original packets 1-14 queue num 92 bypass   # 每個連線只將最初的 14 個封包送去檢查
    }
}

table inet roamswitch_dev_guard {        # §4 連接埠異常防護/手動連接埠隔離,獨立的表
    chain input {
        type filter hook input priority -10; policy accept;
        iif != "lo" tcp dport { … } drop
    }
}

table inet roamswitch_portscan {        # 連接埠掃描的偵測與阻擋(預設開啟)
    chain block  { type filter hook input priority -200; policy accept; ip saddr @blocked_ips ct state new log … drop }
    chain detect { type filter hook input priority -100; policy accept; iifname != "lo" ct state new tcp flags syn log … }
}

table inet roamswitch_egress_block {     # 對惡意 IP 的對外通訊封鎖清單(預設開啟)
    chain output  { type filter hook output  priority -150; policy accept; ip daddr { … } log … drop }
    chain forward { type filter hook forward priority -150; policy accept; ip daddr { … } log … drop }
}

table inet roamswitch_docker_guard {     # 針對 Docker 公開連接埠繞過防火牆的對策(僅在有 Docker 原生 nftables 後端時)
    chain forward { type filter hook forward priority -10; policy accept; … iifname { … } drop }
}

table inet roamswitch_isolate {          # eBPF 偵測時以處理程序為單位的阻斷(以 cgroup / UID 指定)
    chain process_block { type filter hook output priority -100; policy accept; … drop }
}

table inet roamswitch_vpn {              # §4 WireGuard 後端網路阻斷開關
    chain output {
        type filter hook output priority -150; policy drop;
        oifname "lo" accept
        oifname "roamswitch" accept
        meta l4proto { icmp, ipv6-icmp } accept
        udp sport 68 udp dport 67 accept          # DHCP
        ip  daddr { <endpoint v4> } udp dport <port> accept
        ip6 daddr { <endpoint v6> } udp dport <port> accept
        ct state established,related accept
    }
    chain input  { type filter hook input priority -150; policy drop; … }  # 對稱
}

table inet roamswitch_ts {               # §4 Tailscale 後端網路阻斷開關(較寬鬆)
    chain output {
        type filter hook output priority -150; policy drop;
        oifname "lo" accept
        oifname "tailscale0" accept
        meta l4proto { icmp, ipv6-icmp } accept
        udp sport 68 udp dport 67 accept          # DHCP(v6 端同樣對稱)
        ip  daddr 100.64.0.0/10 accept            # tailnet CGNAT
        ip6 daddr fd7a:115c:a1e0::/48 accept
        ip  daddr 100.100.100.100 udp dport 53 accept   # MagicDNS
        ip  daddr 100.100.100.100 tcp dport 53 accept
        udp dport 3478 accept                     # STUN
        udp dport 41641 accept                    # WireGuard 直連
        tcp dport 443 accept                      # DERP 回退
        ct state established,related accept
    }
    chain input  { type filter hook input priority -150; policy drop; … }  # 對稱
}

網關/IPv6 路由器/DNS 解析器 (§4) 的 ARP/NDP 固定是在核心鄰居表 (ip neigh replace … nud permanent) 中完成的,而不是在 nftables 中完成的。固定條目記錄在 /var/lib/roamswitch/arp_lock.json 中。

附錄 C

本文檔中的每項聲明都可以在您自己的機器上進行驗證。以下命令在安裝了 roamswitch 軟體包的主機上執行。

C.1 出站流量驗證

守護程式/應用程式/MCP二進位檔案連結沒有HTTP/TLS庫:

for b in roamswitch-daemon roamswitch-app roamswitch-mcp; do
  ldd "$(command -v $b)" | grep -iE 'ssl|crypto|nghttp|curl' && echo "  ^ in $b"
done
# → 無輸出。HTTP/TLS 協定堆疊僅靜態連結至 roamswitch-updater。

正在運作的守護程式沒有網路套接字:

sudo lsof -p "$(pgrep -x roamswitch-daem)" -a -i
# → 無輸出 = 沒有任何 TCP/UDP 網際網路連線
sudo lsof -p "$(pgrep -x roamswitch-daem)" -a -U | grep roamswitch
# → 僅 /run/roamswitch/roamswitch.sock 與 events.sock(接收 eBPF 偵測事件)(連結防護另外使用 AF_NETLINK 套接字,
#   但這是核心通道,並非網際網路通訊端)

RoamSwitch 唯一的出口是每日更新:

watch -n 5 'sudo ss -tupn | grep -E "roamswitch-(daem|app|mcp)" || echo "(none)"'
# → 始終為 "(none)"。這三者從不開啟任何網際網路通訊端。
systemctl list-timers roamswitch-update.timer
sudo systemctl start roamswitch-update.service
journalctl -u roamswitch-update.service -n 20 --no-pager
# → 僅對 lafine.net/updates/v1 發出 HTTPS GET(清單、簽章、有更新的資料)後即結束。若已安裝 ClamAV,freshclam 也會連線到 ClamAV 的鏡像站。

停用它並確認完全沉默:

sudo systemctl disable --now roamswitch-update.timer
# 或將 /var/lib/roamswitch/updates.json 編輯為 "enabled": false
sudo strace -f -e trace=network -p "$(pgrep -x roamswitch-daem)" 2>&1 | grep -i 'connect('
# → 僅 connect 至 AF_UNIX / AF_NETLINK。AF_INET / AF_INET6 從未出現。

C.2 可重複的防禦驗證(Docker 測試套件)

RoamSwitch 的各種防禦機制(Air-Gap 阻斷、防火牆被強制清除時的自我修復、勒索軟體偵測、/tmp noexec、Yama LSM、同形異義字偵測等),可以使用官方支援儲存庫(roamswitch-support)公開的 Docker 測試套件在本機重現執行。該套件只操作獨立的網路命名空間與容器內的檔案,因此不會影響主機的網路與檔案。不過因為是以 --privileged 執行,像 Yama 的 ptrace_scope 或 suid_dumpable 這類由整個核心共用的設定,也會反映到主機上,即使刪除容器也不會恢復。請在可丟棄的環境中執行。

# 取得並重現驗證套件(使用官方發行套件,在隔離容器內自動驗證)
git clone https://github.com/lafine1211/roamswitch-support.git
cd roamswitch-support/test/docker
docker build -t roamswitch-test .
docker run --rm --privileged roamswitch-test

測試容器會自動從官方 APT 儲存庫(lafine.net/apt)取得發行套件,並在獨立的網路命名空間與掛載命名空間內執行驗證並判定。公開套件為 pentest.sh(PENT-1 至 7 的 7 個情境)與 selftest.sh(Air-Gap、自我修復、金絲雀、突發偵測、隔離 Vault 等守護程式的破壞性自我檢查)。下表的 ID 是驗證記錄上的流水編號,與腳本內的檢查並非一對一對應。BadUSB(SP-6)、連結防護的各模式(SP-7 系列)、ARP 固定與 VPN 終止開關(SP-8 至 10)、核心強化的個別確認(SP-11 系列),以及 PENT-8・9,不包含在公開套件中,而是以實機、獨立 netns、手動注入事件等其他程序確認的項目。

(1) 自主網路防禦與氣隙自愈

身分證號場景驗證方法通過標準
SP-3氣隙啟用 → 出口下降發送 enable_air_gap IPCpolicy drop 應用於輸出掛鉤;所有出站流量均被阻止
SP-3b防火牆強制清除和自我修復透過 nft delete table inet roamswitch 清除規則Anti-Clobber 自癒功能可在 5 秒內恢復掉落規則
SP-3c跨守護程式重新啟動時失敗關閉在 Air-Gap 期間終止守護程式(selftest.sh 以 kill 送出 SIGTERM)並重新啟動出口丟棄策略在重啟後無縫持續
SP-3d授權氣隙恢復發送授權disable_air_gap IPC取消丟棄策略,刪除所有標記文件,恢復出口
SP-8預防性 ARP/NDP 固定在隔離的netns網關環境中啟用→傳送欺騙性的免費ARP網關鄰居條目仍為 PERMANENT;欺騙 ARP 被忽略
SP-9VPN 終止開關 (WireGuard)單獨網路中的 Live WireGuard 伺服器,導入 .conf → vpn_up握手透過inet roamswitch_vpn完成;隧道死亡時零洩漏
SP-10VPN 終止開關(Tailscale)存根 tailscale CLI + 單獨的網絡,tailscale0 IF隧道外明文 TCP/80 和本機 DNS 被封鎖;允許 DERP 和 MagicDNS

(2) 內核與掛載強化

身分證號場景驗證方法通過標準
SP-11a網路系統強化運行 apply_kernel_sysctl_hardening IPCrp_filter=1、tcp_syncookies=1、accept_redirects=0 達到目標值
SP-11b記憶體保護和 Yama LSM驗證 ptrace_scope 和 suid_dumpablekernel.yama.ptrace_scope=1(阻擋窺探),fs.suid_dumpable=0(無核心轉儲)
SP-11c/tmp 和 /dev/shm noexec 防禦運行 apply_mount_hardening IPC/tmp 和 /dev/shm 重新安裝 noexec,nosuid,nodev;執行被拒絕
SP-11d保留合法使用者執行執行標準主目錄 (~/) 中的腳本不受阻礙地運行,不會破壞合法的開發人員/管理工作流程

(3) 多層惡意軟體和勒索軟體防禦和金絲雀

身分證號場景驗證方法通過標準
SP-1金絲雀篡改檢測截斷或重新命名 ~/Documents/ 中的誘餌金絲雀檔案 (.xlsx)在幾秒鐘內偵測到篡改,立即觸發氣隙
SP-2勒索軟體批量加密突發檢測单个进程快速生成多个高熵文件違規工作程序被 SIGSTOP 凍結;氣隙觸發
SP-2bshred 上沒有誤報跨测试文件运行 shred -n 3 -u允許清單匹配可防止誤報檢測或凍結
SP-2c關鍵流程從未凍結在突发检测期间验证冻结目标逻辑關鍵守護程式(dockerd、systemd、containerd)永遠不會被凍結
SP-4EICAR 測試字串僅用於通知将 EICAR 测试字符串写入 ~/Downloads/不發出通知,僅記錄至通知歷史;檔案永遠不會被自動隔離
SP-4b真正的惡意軟體簽章首先確認在監視資料夾外寫入真實簽名引發模式核准對話框;僅在使用者確認後才隔離
SP-4cQuarantine Vault 權限強化檢查 Vault 目錄和範例檔案的權限保管庫目錄設定為 0700,隔離樣本設定為 0400
SP-4d特權IPC安全原始檔案恢復發送 restore_quarantine_file IPC檔案已使用使用者權限 (0644) 恢復到原始路徑並新增至排除項

(4) 被動式連結防護與網路釣魚防禦

身分證號場景驗證方法通過標準
SP-7mode = block 嚴格執行連接到 feed-listed 或 blocklistExtra 主機在 TLS 層丟棄(SNI 解析);未列出的安全主機達到 HTTP 200
SP-7bmode = warn 故障關閉保持連接到警告主機,無用戶回應(超時 8 秒)逾時時丟棄資料包 (fail-close);僅在明確批准的情況下才允許
SP-7cmode = off 完整拆解停用連結防護inet roamswitch_linkguard 表已完全卸載

(5) BadUSB 緩解與設備控制

身分證號場景驗證方法通過標準
SP-6連接鍵盤祖父檢查守護程式啟動時連接的鍵盤現有設備不再適用;僅抓取後續熱插拔

(6) 模擬攻擊的自我檢查項目(PENT-1 至 7 為公開 Docker 套件,PENT-8・9 為另外的手動驗證)

身分證號攻擊向量模擬細節防禦/偵測標準
彭特-1C2 滲漏在氣隙下嘗試將出口 HTTP/TCP 傳送至 C2所有資料包均在 netfilter 處丟棄;零洩漏
PENT-1b韌體強制刪除使用 nft delete table inet roamswitch 清除規則防破壞自我修復可在幾秒鐘內恢復規則
PENT-1c氣隙安全恢復發出經過驗證的 disable_air_gap IPC刪除刪除規則;標記已刪除;連線恢復
PENT-2/tmp 後門在 /tmp 中執行刪除的後門腳本被 noexec 安裝保護 (Permission denied) 拒絕
PENT-2b/dev/shm 共享內存執行放置在 /dev/shm 中的二進位有效負載被 noexec 坐騎防禦阻擋
PENT-2c使用者空間保留在合法使用者目錄(/home/tester/)中執行腳本執行暢通無阻;零工作流程中斷
PENT-3ptrace內存窺探PTRACE_ATTACH 目標提取秘密/令牌被 Yama LSM kernel.yama.ptrace_scope=1 拒絕
PENT-3b核心轉儲秘密抓取觸發進程崩潰以獲取記憶體核心轉儲由 fs.suid_dumpable=0 阻止
PENT-4金絲雀篡改~/Documents/ 中的清零金絲雀誘餌文件即時檢測大小異常和哈希變化
PENT-4b金絲雀批量擦拭大規模刪除金絲雀誘餌文件立即偵測到檔案遺失,引發事件
PENT-5IP位址欺騙發送帶有欺騙來源IP的資料包由 rp_filter=1 刪除(反向路徑過濾器)
PENT-5bSYN 洪水 DoS淹沒半開 TCP 連接受 tcp_syncookies=1 保護的狀態表
PENT-5cICMP 路由劫持注入偽造的 ICMP 重定向封包由於 accept_redirects=0 被忽略
PENT-6西里爾文同形異義字網釣魚導覽至 gооgle.com(西里爾字母同形異義詞)由 LinkGuard 識別,得分 40(危險/區塊)
PENT-6b原始 IP 和明文流量直接出站連接到原始 IP準確標記為安全風險因素
PENT-7OpenAI API 金鑰洩露在程式碼或日誌中公開 sk-proj-... 令牌透過香農熵分析檢測並屏蔽
PENT-7bGitHub 令牌洩漏在代碼中公開 ghp_... 個人令牌透過token模式和熵驗證進行匹配
PENT-8內核 LPE(碎片間隙)搶佔非特權 unshare -U -r(CVE-2026-53362 嘗試)在 v1.1.0 的測量中,因 user.max_user_namespaces = 0 而以 Operation not permitted 立即拒絕。現行的 Client Edition 預設不執行此項拒絕(guard.yaml 的 auto_enable_userns_restriction 預設為停用。Server Edition 則一律套用)
PENT-9eBPF 威脅感測器和流程凍結透過 Falco eBPF 套接字注入關鍵/緊急警報進程在幾毫秒內透過 SIGSTOP 凍結(狀態:Ts);已部署氣隙

關於驗證的種類,上表中 PENT-2・2b(noexec)、PENT-3・3b(Yama、核心傾印)、PENT-5・5b・5c(rp_filter、SYN Cookie、ICMP 重新導向)是確認 RoamSwitch 所設定的核心或 mount 標準功能確實生效的項目。PENT-8(禁止使用者命名空間)也屬於同一種類,但這是 v1.1.0 時點的記錄,現行的 Client Edition 預設不會套用。從攻擊方測試 RoamSwitch 自身偵測與阻斷邏輯的項目是 PENT-1・1b・1c(Air-Gap 與自我修復)、PENT-4・4b(金絲雀)、PENT-6・6b(連結防護)、PENT-7・7b(機密資訊偵測)與 PENT-9(eBPF 偵測後的凍結與阻斷)。PENT-2c 用於確認日常工作不會被破壞。

(7) 自我檢查總結(無 Falco [獨立運作] 與有 Falco [eBPF 連動])

在獨立的 Docker 驗證環境(Target:Ubuntu 24.04 + RoamSwitch Client Edition、Attacker:Nmap / curl / hping3 等)中,針對模擬攻擊所進行的完整自我檢查,以下為其結果總結。下表是 2026-09-06 對 Client v1.1.0 的實測結果;2026-09-25 以 1.10 系列原始碼建置的修正版,在用戶端版測試套件的 11 個項目中 11 項全部通過(並非公開版本。請參閱公開儲存庫的 audit/RESULTS-PENTEST-2026-09-25.ja.md)。

驗證類別不含 Falco(獨立強化)使用 Falco(eBPF 增強型)辯方判決
外部連接埠掃描電阻(Nmap SYN)PASS(100% 過濾/放入 Lockdown)PASS(100% 過濾/放入 Lockdown)總外部隱身
外部直接存取截止(TCP/80、3306)PASS(逾時下降/零回應)PASS(逾時下降/零回應)零入境曝光
內核 LPE(碎片間隙)緩解PASS(v1.1.0 的實測。在 user.max_user_namespaces = 0 的環境下阻斷 unshare。目前的 Client Edition 預設為關閉)PASS(eBPF 警報 + SIGSTOP 凍結 + 氣隙)深度防禦驗證
未授權埠偵測(異常)PASS(0.0.0.0 綁定標記為高風險)PASS(0.0.0.0 綁定標記為高風險)100% 偵測與引導
日誌膨脹和 CPU 開銷預防零日誌佔用(已卸載)PASS(95% 雜訊消除/2MB 緩衝區/50MB 上限)桌面最佳化

C.3 已知限制

限制影響緩解措施
在某些核心上,tmpfs (/tmp) 上的 FAN_MARK_MOUNT 不提供任何事件fanotify 不監控 /tmp 下的檔案寫入/tmp 是臨時資料夾,不是受監控的使用者資料夾;勒索軟體的目標是 ~/。明確記錄標記失敗
容器 Overlayfs / tmpfs 上沒有 fanotify 交付無法驗證容器內熵爆發檢測在真實硬體 (ext4) 上進行驗證;線束透過探針自動跳過
RoamSwitch 的 nftables 操作與 Docker 的 iptables-nft 共用 netfilter 空間RoamSwitch 規則操作可能會幹擾 Docker 的 NAT 規則以專用資料表(inet roamswitch 及其他 roamswitch_*)隔離,但應避免 nft flush ruleset 等針對整個規則集的操作
連結防護只能透過 TLS SNI 查看瀏覽器的 DoH;加密的 Client Hello (ECH) 也隱藏了這一點一旦 ECH 被廣泛部署,使用 ECH 的連接到支援 ECH 的站點就無法透過主機名稱來識別本機封鎖清單和啟發式仍作用於 DNS/HTTP 和非 ECH TLS; DNS 威脅保護(§4.5,預設開啟)涵蓋解析器路徑
當 updates.json 的 enabled 為 false 時,資料來源的新鮮度取決於發布間隔關閉更新後,提要僅與最後一個 apt upgrade 一樣最新最嚴重的偵測(品牌同形異義詞)無需饋送;選擇重新加入或啟用威脅防護 DNS,以獲得始終最新的覆蓋範圍
本文件基於 RoamSwitch for Linux v1.11.1(核心 LPE 強化/eBPF 執行時防護/攻擊程序 SIGSTOP 凍結/Falco 低負載最佳化/即時監控 Vault 隔離及權限 IPC 原樣還原/Air-Gap 自我修復機制/DNS 隧道偵測/鑑識證據保全/蜜令牌/弱點檢測 pass_age 追蹤/NIST CSF・CIS Controls 對應/診斷再評估/MCP 設定稽核)當時的實作。逐項變更歷史請參閱 roamswitch-support 的 CHANGELOG。最新資訊請參閱 roamswitch.com/linux。