ROAMSwitch for LINUX · 操作参考
CLI/无头操作指南
如何在没有 GUI 的情况下在云 VPS 实例上通过 SSH、从 cron、监控脚本和编程式 AI 代理 (MCP) 操作适用于 Linux 的 RoamSwitch。
- 客户端版本 (
roamswitch):专为笔记本电脑、移动工作站和开发人员设备而设计。根据连接网络的信任级别自动切换 nftables 防火墙配置文件。本指南主要关注客户端版本的无头/CLI 管理。 - 服务器版 (
roamswitch-server):专为云 VPS 实例(AWS、GCP、DigitalOcean、Linode 等)和直接暴露于 Internet 的本地服务器而设计。具有入站默认丢弃过滤、SSH 锁定预防、关键路径文件完整性监控 (FIM)、eBPF / Falco 运行时集成和即时通知(Telegram / LINE / Webhooks)的功能。有关完整的安装和管理说明,请参阅RoamSwitch 服务器版操作手册 和服务器安全白皮书.
1. 组件
| 组件 | 运行为 | 角色 |
|---|---|---|
roamswitch-daemon(客户端) |
根(systemd Type=notify) |
所有客户端特权操作:nftables 控制、网络检测、勒索软件/恶意软件监控、fanotify、ARP/NDP 固定、DNS 强制。不打开 TCP/UDP 侦听套接字。 |
roamswitch-server-daemon(服务器) |
根(systemd Type=notify) |
所有服务器特权操作:入站默认丢弃、SSH 和管理堡垒保留、FIM(150 多个关键二进制哈希)、具有自主 SIGSTOP 冻结功能的 Falco eBPF UNIX 套接字侦听器、警报调度。 |
roamswitch (命令行) |
登录用户(某些操作需要 sudo) | 瘦客户端读取守护进程状态。在客户端版本上使用 /run/roamswitch/roamswitch.sock IPC,或在服务器版本上提供 --server、server、fim 和 emergency-restore 子命令。 |
roamswitch-mcp |
由人工智能客户端催生 | 只读 MCP 服务器(stdio / JSON-RPC),用于 AI 代理以编程方式检索状态。请参见 MCP 设置 |
roamswitch-app |
登录用户 | GTK GUI(仅限客户端版)。在无头环境中不需要。 |
无头部署在守护程序 + roamswitch CLI 上运行(如果需要,还可添加 roamswitch-mcp)。 所有自主防御机制都无需任何 GUI 即可工作。
roamswitch) 和服务器版 (roamswitch-server) 是互斥的包 (Conflicts)。在服务器环境上部署 roamswitch-server。2.守护进程(systemd服务)
客户端版
sudo systemctl status roamswitch.service # 运行状态
sudo systemctl enable roamswitch.service # 开机自动启动(安装时已启用)
sudo systemctl restart roamswitch.service # 重启
journalctl -u roamswitch.service -f # 日志追踪
journalctl -u roamswitch.service --since "1h ago"
客户端守护进程在启动时和每个周期(3 秒)自主执行的操作:
- 识别连接的网关 MAC 并针对
trusted_networks应用 nftables 配置文件 (open/balanced/lockdown) - 行为勒索软件检测(fanotify + Shannon entropy + canary)
- 按访问恶意软件扫描(fanotify,可选 ClamAV)
- ARP 欺骗监控和预防性网关 ARP/NDP 固定在不受信任的网络上
- 每个配置文件的内核强化(sysctl / Yama / core dumps /
/tmpnoexec) - 威胁防护 DNS 强制执行 (
dns_enabled+dns_scope) - 用于网络钓鱼拦截的链接防护 (NFQUEUE)
- 运行时状态输出到
/run/roamswitch/state.json
服务器版
sudo systemctl status roamswitch-server.service # 运行状态
sudo systemctl restart roamswitch-server.service # 重启
sudo systemctl reload roamswitch-server.service # 重新加载配置文件
journalctl -u roamswitch-server.service -f # 日志追踪
3. CLI 命令参考
基本语法:roamswitch <command> [options]。不带参数运行默认为 status。输出语言自动遵循操作系统区域设置 (LC_ALL / LC_MESSAGES / LANG)。
| 命令 | 权限 | 描述 |
|---|---|---|
status [--server](别名 report / server-status) |
用户 | 安全健康评估(对客户端进行 24 次检查,对 --server 进行 30 次检查)、0–100 分、等级和每项建议 |
server [config|setup|test-notify|restart|ebpf] |
用户/根用户 | 服务器版配置管理、交互式设置向导和测试通知。ebpf(别名 incidents)显示 eBPF 运行时防护的当前隔离状态和已检测到的事件记录 |
fim [verify|update] |
用户/根用户 | 关键路径文件完整性监控验证 (verify) 和基线哈希数据库更新 (update) |
emergency-restore |
根 | 解除所有紧急 eBPF/防火墙隔离并恢复网络基线 |
ports [-a|--all] |
用户 | 监听 0.0.0.0、未经身份验证的数据库和开发服务器上的端口。 -a 包括仅环回端口 |
guards |
用户 | 自动防御卫士的状态(端口异常、ARP、USB存储、下载、DNS威胁、金丝雀、开发服务器隔离器、蓝牙) |
wifi |
用户 | Wi-Fi 加密强度(开放/WEP/WPA/有线)和 SSID |
sharing [status|on|off] |
用户 | 在不受信任的网络上自动停止/恢复 SSH/Samba/RDP(on 在不受信任时断开活动的 SSH) |
audit-url <URL> |
用户 | 通过本地源 + 启发式检查 URL 网络钓鱼和威胁风险(从不获取目标) |
audit-secrets <text|path|directory> |
用户 | 检测文本、文件或目录(递归扫描,自动跳过 .git/node_modules 等)中的 API 密钥、私钥和令牌(从不传输数据) |
audit-logs [hours] |
用户 | 聚合并分类过去 N 小时的系统日志/身份验证日志(默认 24)。API 密钥和令牌会自动脱敏。同时显示日志模式异常检测结果(新模式与统计频率激增) |
canary |
用户 | 勒索软件金丝雀诱饵文件状态和完整性,以及已检测到的事件记录(最近50条) |
port-anomaly(别名 port-guard) |
一般 | 未知端口暴露防护的基线获取状态、当前自动阻断的端口,以及已检测到的事件记录(最近50条) |
quarantine [list] |
用户 | 恶意软件隔离库的内容(样本、原始路径、威胁名称、日期) |
knowledge [query](别名 faq) |
用户 | 搜索离线知识库 |
airgap [enable|disable] |
用户/根用户 | 触发或解除紧急气隙隔离(enable 丢弃所有外部流量) |
help (--help / -h) |
用户 | 显示帮助(roamswitch <command> --help 表示子命令帮助) |
scan-packages [文件夹...] |
普通 | 将已安装的OS软件包(自动判定dpkg/pacman/dnf/zypper)与本地已知CVE映射进行比对。传入文件夹参数后,还会将该项目的依赖关系(npm/PyPI/crates.io等7个生态系统)的锁定文件一并纳入比对。完全不进行任何网络活动 |
scan-vulns [--confirm] |
普通 | 仅当 active_vuln_scan_enabled: true(默认关闭)时执行:仅限127.0.0.1的Redis/Memcached/MongoDB/dockerd无认证可达性确认、对检测到的开发服务器进行CORS配置错误・路径遍历・开放重定向诊断、SMTP开放中继诊断,以及Telnet/FTP/SSH的实证型暴露诊断。不带 --confirm 则为演练模式 |
notifications(别名 notification-history) |
用户 | RoamSwitch 发送的通知(日志审计异常、ClickFix 检测等)历史记录(过去1周,最新在前) |
frozen [list|resume <PID>|resume all] |
用户/root | 列出各防护模块(勒索软件高速加密检测、诱饵文件被篡改、内核漏洞攻击检测)当前以 SIGSTOP 冻结的进程,若属误报可解除(SIGCONT)。冻结并非强制结束,解除后将从暂停处原样继续。resume all 可全部解除。解除 root 所有的进程需要 sudo |
resource-guard(别名: leak-guard) |
用户 | 资源耗尽/进程异常检测防护(仅 Server Edition)的检测事件历史。以置信等级显示网络公开服务的持续 RSS 增长(内存泄漏/DoS)与崩溃循环 |
timeline(别名: incident-timeline) |
用户 | 将链接防护(ARP 欺骗)、勒索软件 Canary、eBPF 运行时防护与资源防护的检测合并为单一时间线,含进程谱系与 MITRE ATT&CK 标签(实验性) |
xdp-gate [status|enable|disable] |
用户/root | 显示或切换 XDP 启动时闸门(实验性)。status 显示 roamswitch-xdp-gate.service 是否启用及当前程序状态。默认关闭 |
sensor [key|list|pair|unpair|request-audit|results] |
普通用户/root | 与另一仓库中、安装在通用设备上的网络传感器「RoamSwitch Sensor」之间基于配对码的相互信任。pair --addr <IP> --code <配对码> 使用 Sensor 一侧发放的配对码完成配对(前提是 Sensor 以固定 IP 运行),key 显示本端点自身的公钥/地址,unpair 解除配对,request-audit 向 Sensor 请求执行主动漏洞审计(通过 results 获取结果)。需要 sensor_pairing_enabled: true(默认关闭)。详情请参阅 Sensor 运维手册 |
port-scan (alias portscan) |
普通用户 | 显示入站端口扫描检测防护的检测历史(来源 IP、是否自动封锁及封锁时长)。与检测新增「暴露」未知端口的 port-anomaly 是不同的功能 |
示例
sudo roamswitch status # 客户端综合诊断(24项)
sudo roamswitch status --server # 服务器版综合诊断(30项)
sudo roamswitch ports -a # 全部监听端口
roamswitch guards # 防护运行状态
roamswitch audit-url https://examp1e-login.com
roamswitch audit-secrets ./deploy.env
roamswitch audit-secrets . # 递归扫描当前目录
roamswitch audit-logs 72 # 分析最近72小时的日志
sudo roamswitch sharing on # 在不受信网络下自动停止 SSH/Samba/RDP
sudo roamswitch fim verify # FIM 文件完整性校验
sudo roamswitch fim update # 更新 FIM 基线
sudo roamswitch emergency-restore # 完全解除紧急隔离并恢复
sudo roamswitch airgap enable # 紧急隔离
sudo roamswitch airgap disable # 解除
sudo roamswitch server ack # 确认应答安全计时器(停止自动恢复)
roamswitch canary # 金丝雀诱饵事件记录
roamswitch port-anomaly # 未知端口暴露防护事件记录
roamswitch server ebpf # eBPF 防护的隔离状态和事件记录
roamswitch notifications # 过去1周的通知历史
roamswitch frozen # 列出被冻结的进程
sudo roamswitch frozen resume 12345 # 解除误报冻结的进程
sudo roamswitch sensor pair --addr 192.168.1.50 --code AB3DFGH2 # 使用配对码与 Sensor 配对
sudo roamswitch sensor key # 显示本端点自身的公钥/地址
roamswitch port-scan # 端口扫描检测历史
服务器版守护进程以root权限运行,因此需要读取nftables规则集或识别进程所有者的命令(status / status --server / ports -a)在没有sudo的情况下会返回不准确的结果(错误的“未运行”判定或进程信息缺失)。更改配置的命令(sharing / fim update / airgap / emergency-restore等)同样需要sudo。其他只读命令即使不使用sudo也能正确运行。
- 通过
roamswitch <command> --help. 支持特定于子命令的帮助
- 机器可读状态应通过 MCP (§6) 或
/run/roamswitch/state.json(§5). 查询
- 在客户端版本中,没有直接命令来强制防火墙配置文件;守护进程根据网络信任自主管理这一点。要强制级别,请在
config.json中配置manual_override或直接调用set_security_levelIPC (§5).
无论分数如何, status都会返回退出代码 0。对于自动监控,解析分数线(参见§7).
4. 配置文件
客户端版本 (~/.config/roamswitch/config.json)
该守护进程以 root 身份运行,并使用它找到的第一个有效文件(或仅 root 环境中的 /root/.config/roamswitch/config.json)扫描 /home/*/.config/roamswitch/config.json。
| 钥匙 | 类型/默认 | 描述 |
|---|---|---|
language | 字符串/操作系统区域设置 | UI 和 CLI 语言(ja / en / ko / zh-Hans / zh-Hant / de / fr / es / it / pt-PT) |
trusted_networks | [{name, mac, level}] | 值得信赖的网络; mac 是网关 MAC,level 是 open / balanced / lockdown |
away_protection_level | 字符串/lockdown | 未知网络上的默认配置文件 |
manual_override | 字符串/空 | 强制 open / balanced / lockdown (自动为空) |
dns_enabled | 布尔 / true | 威胁防护 DNS 实施 |
dns_provider | 字符串/quad9 | quad9 / cloudflare / adguard / cleanBrowsing |
dns_scope | 字符串/untrusted_only | untrusted_only / always_on |
arp_spoof_guard_enabled | 布尔 / true | ARP欺骗监控 |
gateway_arp_lock_enabled | 布尔 / true | 不受信任网络上的预防性网关 ARP/NDP 锁定 |
port_anomaly_guard_enabled | 布尔 / true | 自动阻止新的监听端口 |
system_wide_fanotify_enabled | 布尔 / true | 系统范围内的 fanotify 恶意软件防护 |
pre_exec_blocking_enabled | 布尔 / true | 执行前阻塞 (FAN_DENY) |
entropy_freeze_enabled | 布尔 / true | 勒索软件快速冻结 (SIGSTOP) |
mount_hardening_enabled | 布尔 / true | /tmp 和 /dev/shm 上的 noexec(应用于非开放配置文件) |
yama_memory_protect_enabled | 布尔 / true | Yama ptrace 限制 |
usb_storage_guard_enabled / usb_keyboard_guard_enabled | 布尔 / false | USB 存储 / BadUSB 键盘防护(默认关闭) |
usb_zero_trust_enabled | 布尔 / false | USB总线authorized_default=0 |
bluetooth_guard_enabled | 布尔 / false | 在不受信任的网络上禁用蓝牙无线电 |
sharing_service_control_enabled | 布尔 / true | 自动停止/恢复 SSH / Samba / RDP |
scan_exclusions | [string] | 排除扫描的绝对路径 |
link_guard | 对象 | {enabled, mode: "off"|"warn"|"block", allowlist, blocklist_extra, use_threat_dns} |
vpn_on_untrusted_enabled | 布尔 / false | 在不受信任的网络上自动启动 VPN 隧道 |
vpn_backend | 字符串/wireguard | wireguard / tailscale |
active_vuln_scan_enabled | bool / false | 允许执行 scan-vulns(默认关闭)。因会发送仅限127.0.0.1的可达性探测,需要明确启用 |
pkgcve_watched_folders | [string] | GUI版依赖关系照合所对象的项目文件夹列表(绝对路径)。CLI的 scan-packages 不参照此设置,仅以命令行参数指定的文件夹为对象 |
sensor_pairing_enabled | bool / false | 允许与 RoamSwitch Sensor 之间基于配对码的相互信任(默认关闭)。使用 sensor 命令的前提条件 |
port_scan_detect_enabled | bool / true | 入站端口扫描检测防护 |
port_scan_detect_min_distinct_ports | int / 15 | 在检测窗口内连接到不少于此数量不同端口的来源将被判定为扫描 |
port_scan_detect_window_secs | int / 300 | 扫描判定的统计窗口(秒) |
port_scan_block_enabled | bool / true | 自动封锁检测到的扫描来源 IP |
port_scan_block_duration_secs | int / 600 | 自动封锁的持续时间(秒) |
sharing_service_control_enabled: true,连接到不受信任的网络 会断开活动的 SSH 会话。在无头服务器上将其禁用。服务器版 (/etc/roamswitch/server.conf)
服务器版使用具有严格权限(0600,仅限 root)的 INI 格式配置文件。参见服务器版操作手册
5. 日志和运行时状态文件
| 路径 | 目标 | 描述 |
|---|---|---|
journalctl -u roamswitch.service | 客户 | 客户端守护程序日志(配置文件切换、检测、错误) |
journalctl -u roamswitch-server.service | 服务器 | 服务器守护程序日志(FIM 事件、Falco 检测、隔离) |
/run/roamswitch/roamswitch.sock | 客户 | 客户端守护进程 IPC Unix 域套接字 |
/run/roamswitch/events.sock | 服务器 | Falco / Tetragon eBPF 集成套接字(root:root,模式 0660;Falco 默认以 root 身份运行,启用零配置直接套接字写入) |
/run/roamswitch/state.json | 客户 | 循环状态:{active_level, network_trusted, fanotify_ready} |
/run/roamswitch/alerts.json | 客户 | 最近的警报队列 |
/run/roamswitch/approvals.json | 客户 | 待批准队列 |
/run/roamswitch/fanotify.ready | 客户 | 指示 fanotify 防护正在运行的标志文件 |
/var/lib/roamswitch/fim_baseline.db | 服务器 | FIM SHA-256 基线哈希数据库 |
~/.local/share/roamswitch/quarantine/ | 两者都 | 隔离库(0700,样本 0400)+ .metadata.json |
直接调用IPC(高级)
守护进程在 /run/roamswitch/roamswitch.sock 上接受换行符分隔的 JSON:
# 强制切换配置文件(客户端版)
printf '{"id":1,"method":"set_security_level","params":{"level":"lockdown"}}\n' \
| sudo socat - UNIX-CONNECT:/run/roamswitch/roamswitch.sock
# 立即核对网关 ARP 锁定
printf '{"id":1,"method":"reconcile_gateway_lock","params":null}\n' \
| sudo socat - UNIX-CONNECT:/run/roamswitch/roamswitch.sock
6. 程序化状态 (MCP)
roamswitch-mcp 在 stdio 上通过 JSON-RPC 公开只读工具 (get_security_report / get_exposed_ports / get_guard_status / audit_url_safety / audit_secrets / audit_security_logs / get_app_help / get_quarantine_status / get_file_scan_guard_status / verify_fim / get_port_anomaly_incidents / get_ebpf_incidents / get_resource_guard_incidents / get_canary_status / get_notification_history / get_incident_timeline / run_active_vuln_scan / run_package_cve_scan / run_package_cve_scan_languages)。
它不使用外部网络通信,本地连接到守护程序套接字或调用 roamswitch-core。请参阅 MCP 设置指南
7. 自动化食谱
每日 cron 健康检查 → 如果分数低于阈值则发送电子邮件
#!/usr/bin/env bash
# /etc/cron.daily/roamswitch-health
out=$(runuser -u "$SUDO_USER" -- roamswitch status 2>&1)
score=$(printf '%s\n' "$out" | grep -oE '[0-9]+/100' | head -1 | cut -d/ -f1)
if [ -n "$score" ] && [ "$score" -lt 80 ]; then
printf '%s\n' "$out" | mail -s "RoamSwitch health: ${score}/100" root
fi
监控警报队列(轮询alerts.json)
#!/usr/bin/env bash
last=0
while :; do
ts=$(jq -r 'max_by(.timestamp).timestamp // 0' /run/roamswitch/alerts.json 2>/dev/null || echo 0)
if [ "$ts" -gt "$last" ]; then
jq -c ".[] | select(.timestamp > $last)" /run/roamswitch/alerts.json | logger -t roamswitch-alert
last=$ts
fi
sleep 10
done
验证 fanotify 防护健康状况 (state.json)
jq -e '.fanotify_ready == true' /run/roamswitch/state.json >/dev/null \
|| echo "WARNING: fanotify guard is not running" >&2
8. 故障排除
| 症状 | 分辨率 |
|---|---|
roamswitch 退出并显示“检查漫游交换机-mcp 是否已安装” |
守护进程未运行 → sudo systemctl start roamswitch.service(或 roamswitch-server.service)。验证套接字是否存在 |
roamswitch status 显示 fanotify 🔴 “守卫停了下来” |
短暂的 fs.fanotify.max_user_groups 疲惫。使用 sudo systemctl restart roamswitch.service 重新启动并在日志中验证 |
配置文件停留在 balanced,永远不会达到 open |
验证网关 MAC 已在 trusted_networks 中注册到 level: open |
| SSH 意外断开 | 客户端版本在不受信任的网络上有 sharing_service_control_enabled: true。通过 roamswitch sharing off 禁用 |
| 配置更改不生效 | The client daemon reads the first of /home/*/.config/…; apply with systemctl restart roamswitch.service. For the server edition, edit /etc/roamswitch/server.conf then run sudo roamswitch server restart (no reload). |
| 服务器通信意外被阻止 | 访问云控制台(VNC/串口)并运行sudo roamswitch emergency-restore |