Files

27 KiB
Raw Permalink Blame History

ROS-DPI

给 MikroTik RouterOS 用的终端流量、应用识别与上网审计面板。

不换路由器、不做旁路串接:RouterOS 把流量统计(IPFIX)和握手包镜像(TZSP)发给 ROS-DPI,它算出每台设备、每个人用了多少流量、用在了哪些应用上,并按规则记录访问、推送告警。界面参照维盟 / Panabit,审计参照深信服 AC。

中文 · English · 更新日志 · RouterOS 配置详解

全网概览


中文

功能

页面 能看到 / 能做什么
全网概览 路由器状态、网络健康指数(逐项扣分和改进建议)、在线终端、DHCP 地址池、每条 WAN 线路的状态和速率;流量构成饼图;实时 / 历史流量;Top 应用与 Top 终端
主机监控 每台设备的类型(手机、电脑、电视、摄像头……自动识别)、IP、MAC、主机名、归属人、在线时长、实时速率、今日 / 本周 / 本月流量;按 MAC 或 IP 命名;单台设备的应用构成、访问过的域名、访问日志、上网时间线;导出 CSV
应用统计 三级下钻:应用大类 → 小类 → 应用。大类照维盟的 17 类,共 50 个小类、约 2970 个应用(抖音、B 站、微信、Steam、银行、券商、ToDesk、DeepSeek……)
流量流向 实时连接、访问目标排行、流向世界地图、代理分流(sing-box 的策略组 / 出口节点)
家庭成员 / 员工 把一个人的设备归到一起按人统计。家庭场景看孩子上网健康(屏幕时间、游戏和短视频、熬夜),企业场景看效率与合规
审计日志 访问日志;审计规则(应用、域名、时段、流量阈值、大流量外发、私接路由、新设备);14 种通知渠道(Telegram、飞书、企业微信、钉钉、Bark、邮件、Server酱、Pushplus、Discord、Slack、ntfy、Gotify、QQ、Webhook);日报 / 周报;操作日志
管控命令 按应用、时段生成 RouterOS 命令(封禁应用、定时断网、限速)并附撤销命令。只生成,不会改路由器
识别规则 按域名 / IP 段 / 端口自定义规则;未识别域名 Top 一键归类;各识别库的规模与更新状态

中英双语,浅色 / 深色主题,手机上也能用。

应用统计

流量流向

家庭成员

三步上手

  1. 部署 ROS-DPI:Linux 一条命令,或 Docker Compose(见部署)。
  2. 配置 RouterOS:在 系统设置 → 接入与自检 复制命令到路由器执行(见RouterOS 配置)。
  3. 打开网页:约 1 分钟后概览页开始有数据。再选场景(家庭 / 企业)、把设备分给成员、配好通知渠道和审计规则。

部署

方式一:Linux 一键安装 方式二:Docker Compose
适合 一台 Linux 小主机 / 虚拟机 已有 Docker、NAS 或 MySQL
数据库 默认 SQLite,零配置;可改 MySQL MySQL 5.7 / 8.x(可一起启动)
升级 网页上点「一键更新」 docker compose pull && docker compose up -d
架构 x86_64、aarch64 amd64、arm64

方式一:Linux 一键安装

curl -fsSL https://raw.githubusercontent.com/suyijun8182/ros-dpi/main/install.sh | sudo bash

脚本会下载最新版单文件二进制(含前端)并校验 SHA256,创建专用账号 ros-dpi,注册并启动 systemd 服务。装完浏览器打开 http://<本机IP>:8080。

位置 用途
/opt/ros-dpi/bin/ros-dpi 程序(/usr/local/bin/ros-dpi 是指向它的软链接)
/opt/ros-dpi/data/ 数据:SQLite 库、识别库文件
/etc/ros-dpi.env 你的配置(DATABASE_URL、ADMIN_PASSWORD、LAN_CIDRS……),重装 / 升级都不会覆盖
  • 改配置后执行 sudo systemctl restart ros-dpi;看日志用 journalctl -u ros-dpi -f。
  • 安装时可以用 ROS_DPI_PORT(默认 8080)和 ROS_DPI_DIR(默认 /opt/ros-dpi)指定端口和目录,例如 curl … | sudo ROS_DPI_PORT=9000 bash。
  • 服务以 ros-dpi 账号运行,不是 root,只能写 bin/ 和 data/。0.6.23 及以前装的是 root 服务,重新执行一次安装命令即可迁移,数据和配置原样保留。

方式二:Docker Compose

还没有 MySQL:用 docker-compose.with-mysql.yml,会一起启动 MySQL 8.4 并自动建库、写好连接,网页上不会出现数据库设置。

mkdir ros-dpi && cd ros-dpi
curl -o docker-compose.yml https://raw.githubusercontent.com/suyijun8182/ros-dpi/main/docker-compose.with-mysql.yml
cat > .env <<'EOF'
MYSQL_PASSWORD=改成强密码
MYSQL_ROOT_PASSWORD=改成另一个强密码
EOF
# 把 docker-compose.yml 里的 LAN_CIDRS 改成你的内网网段
docker compose up -d

已有 MySQL:先建库和账号(命令行用 mysql -u root -p,也可以在 phpMyAdmin、Navicat、NAS 的数据库管理页里操作;表会自动创建):

CREATE DATABASE rosdpi CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'rosdpi'@'%' IDENTIFIED BY 'your-password';
GRANT ALL PRIVILEGES ON rosdpi.* TO 'rosdpi'@'%';
FLUSH PRIVILEGES;

再保存下面的 docker-compose.yml(或 curl -O https://raw.githubusercontent.com/suyijun8182/ros-dpi/main/docker-compose.yml),改好 LAN_CIDRS 后 docker compose up -d。首次打开网页时在安装向导里填 MySQL 信息。

services:
  ros-dpi:
    image: suyijun8182/ros-dpi:latest        # 也可用 ghcr.io/suyijun8182/ros-dpi:latest
    container_name: ros-dpi
    restart: unless-stopped
    ports:
      - "8080:8080/tcp"     # Web 界面
      - "2055:2055/udp"     # IPFIX:RouterOS Traffic Flow 发到这里
      - "37008:37008/udp"   # TZSP:RouterOS 镜像的 DNS 应答和 HTTPS / QUIC 握手包发到这里
    environment:
      TZ: Asia/Shanghai
      LAN_CIDRS: 192.168.88.0/24     # 必改:内网网段,逗号分隔
      ADMIN_PASSWORD: ""             # 留空则首次打开网页时设置
    volumes:
      - ./data:/app/data             # 保存数据库连接配置和识别库,务必保留

镜像发布在 Docker Hub(suyijun8182/ros-dpi)和 GHCR(ghcr.io/suyijun8182/ros-dpi),每次发版都有版本号标签。群晖 / 飞牛 / 威联通在 Container Manager 里新建“项目”,粘贴 compose 即可。

首次使用

打开 http://<主机IP>:8080:

  1. 连接数据库(只有 Docker 且没用自带 MySQL 时才有这一步):填 MySQL 信息,可以先测试连接。MySQL 和 ROS-DPI 在同一台机器上时填局域网 IP,不能填 127.0.0.1。
  2. 设置管理员密码,设置后自动登录。
  3. 到 系统设置 → 接入与自检 复制 RouterOS 命令去路由器执行。自检会检查规则是否齐全、端口是否写错、FastTrack 是否挡住了握手包。

只读账号(只能看、不能改)在 系统设置 → 用户管理 添加。

现象 处理
连不上 MySQL 地址 / 端口不通,或填了 127.0.0.1;MySQL 要允许远程连接(bind-address),防火墙放行 3306
账号或密码错误 检查密码;账号的主机要是 %
重启后显示“正在连接数据库” MySQL 还没就绪,会自动重试,不用重填
要换数据库 删掉 data/db_config.json 后重启,重新出现向导
忘记管理员密码 让其他管理员在 用户管理 里重置;都忘了就执行 DELETE FROM rosdpi.users; 后重新设置(统计数据不受影响)
概览一直没数据 看 接入与自检 的结果;确认路由器能访问本机的 udp/2055、udp/37008

RouterOS 配置

把 192.168.88.10 换成 ROS-DPI 主机的 IP。系统设置 → 接入与自检 里有替换好地址的版本,可以直接复制。

# 1. 流量统计(IPFIX)
/ip traffic-flow set enabled=yes interfaces=all active-flow-timeout=1m inactive-flow-timeout=15s
/ip traffic-flow target add dst-address=192.168.88.10 port=2055 version=ipfix

# 2. DNS 嗅探:远端 IP 是哪个域名解析出来的
/ip firewall mangle add chain=output protocol=udp src-port=53 action=sniff-tzsp sniff-target=192.168.88.10 sniff-target-port=37008 comment=ROSDPI-DNS
/ip firewall mangle add chain=forward protocol=udp src-port=53 action=sniff-tzsp sniff-target=192.168.88.10 sniff-target-port=37008 comment=ROSDPI-DNS

# 3. SNI 识别(推荐):只镜像每条 HTTPS / QUIC 连接开头的握手,终端用加密 DNS 也能识别
/ip firewall mangle add chain=forward protocol=tcp dst-port=443 connection-bytes=0-4000 action=sniff-tzsp sniff-target=192.168.88.10 sniff-target-port=37008 comment=ROSDPI-SNI
/ip firewall mangle add chain=forward protocol=udp dst-port=443 connection-bytes=0-4000 action=sniff-tzsp sniff-target=192.168.88.10 sniff-target-port=37008 comment=ROSDPI-SNI

# 4. 开了 IPv6 时再加一份(国内宽带大多有 IPv6,视频、下载优先走 IPv6)
/ipv6 firewall mangle add chain=output protocol=udp src-port=53 action=sniff-tzsp sniff-target=192.168.88.10 sniff-target-port=37008 comment=ROSDPI-DNS
/ipv6 firewall mangle add chain=forward protocol=udp src-port=53 action=sniff-tzsp sniff-target=192.168.88.10 sniff-target-port=37008 comment=ROSDPI-DNS
/ipv6 firewall mangle add chain=forward protocol=tcp dst-port=443 connection-bytes=0-4000 action=sniff-tzsp sniff-target=192.168.88.10 sniff-target-port=37008 comment=ROSDPI-SNI
/ipv6 firewall mangle add chain=forward protocol=udp dst-port=443 connection-bytes=0-4000 action=sniff-tzsp sniff-target=192.168.88.10 sniff-target-port=37008 comment=ROSDPI-SNI

# 5. 开了 FastTrack 时:每条连接的前 10KB 不走 FastTrack,否则握手包镜像不到
/ip firewall filter set [find action=fasttrack-connection] connection-bytes=10000-0
/ipv6 firewall filter set [find action=fasttrack-connection] connection-bytes=10000-0

# 6. 只读 API 账号(可选):主机名、IP↔MAC、WAN 口速率、DHCP 地址池
/user group add name=rosdpi policy=read,rest-api,api,!write,!policy,!sensitive
/user add name=rosdpi group=rosdpi password=<强密码> address=192.168.88.10

第 6 步的地址和账号填在 系统设置 → 接入与自检,或者用环境变量 ROS_URL / ROS_USER / ROS_PASSWORD。SNI 的开销、双层 NAT、排错等见 docs/RouterOS配置.md。

应用是怎么识别出来的

RouterOS ──IPFIX udp/2055 ──▶ 每条连接:哪台终端、远端 IP、端口、字节数
RouterOS ──TZSP  udp/37008──▶ DNS 应答:远端 IP ← 哪个域名
                             HTTPS / QUIC 握手:这条连接的目标域名(SNI)
RouterOS ◀── REST 只读(可选)── 主机名、IP↔MAC、WAN 速率
                       ↓
           域名 / IP → 应用 → 按分钟、小时、天汇总入库

先确定域名,由准到粗:这条连接的 SNI → DNS 嗅探 → 这台终端最近的 DNS / SNI 记录 → 全网 IP→域名 表。终端按 MAC 区分,IP 变了不影响统计。

再把域名 / IP 对应到应用,四层依次查:

  1. 公开识别库(自动更新):内置手工库、v2fly、blackmatrix7、Hagezi / UT1 分类列表、ASN、国内域名列表、云厂商官方 IP 段。上游有新目录时,先下载再用现有识别库投票决定它属于哪个应用,不用人工整理。
  2. 本地自学习库:你的网络里实测到的「IP → 应用」「域名 → 应用」会长期记住,DNS 缓存过期、用 DoH 的终端、直接连 IP 的流量都能按记忆归类,每小时重建一次。
  3. 社区共享库:各个部署实例匿名汇总的识别结论,本地查不到时兜底(见下节)。
  4. 都查不到,才归到「HTTPS」「国内网络」这类笼统分类。

识别库更新后,或者每天过了零点,会自动把以前的历史流量按新规则重算一遍(只会从笼统改成具体,不会反过来);识别规则 页也可以手动重算。

局限:没开 SNI、只开 DNS 嗅探时,用 DoH / DoT 的终端只能识别成 HTTPS / QUIC;启用了 ECH 的少数网站只能看到外层的公共域名。

社区共享库

每个部署实例学到的东西不一样,汇总起来识别会更准。项目自带一个社区主站,不依赖第三方存储。

  • 上报什么:远端 IP / 域名、应用 ID、票数。不含本机终端、访问记录、自定义应用;私网地址会被剔除。
  • 怎么防作假:主站按来源网络计票(IPv4 /24、IPv6 /56,只存加盐哈希),至少 2 个不同网络的实例投给同一个应用、而且票数领先才会发布;一个人开再多实例也只算一票。每个实例有主站发的令牌,别人冒充不了。
  • 不需要公网 IP:各实例都是主动连主站,能上外网就行。社区库缓存在本地,主站暂时连不上也照常用。
  • 在哪里看、怎么关:系统设置 → 外部数据源 → 社区共享库,能看到连接状态、社区库规模、全球已部署 / 在线 / 离线数量。默认打开,关掉后不再上报,也不再使用社区库。
  • 自建私有社区:deploy/hub/ 有 VPS 部署模板(Docker + Caddy 自动 HTTPS;或已有 Lucky + MySQL 的版本),步骤见 docs/社区主站部署.md。各实例在上面的页面填写“社区主站地址”即可。

外部数据源(可选)

用了旁路代理或自建 DNS 时,可以把它们接进来补全识别。都在 系统设置 → 外部数据源 填写,不填就不启用。

来源 补上什么
sing-box(Clash API) 走代理的流量:哪台终端、哪个域名、多少字节,以及策略组和出口节点
MosDNS(审计 API) 每台终端查了哪个域名、解析出哪些 IP
AdGuard Home 双层 NAT(RouterOS 下面还挂了一台路由器)时,下级终端的 DNS 查询路由器看不到,从 AdGuard Home 的查询日志补上

升级

  • Linux 一键安装:系统设置 → 版本更新 出现新版本时点「一键更新」,程序会下载新版、校验 SHA256、替换后自动重启,旧版本留一份 ros-dpi.bak。也可以重新执行安装命令。
  • Docker:docker compose pull && docker compose up -d。想固定版本,就把镜像标签从 latest 改成具体版本号(如 0.6.24)。

每个版本改了什么见 CHANGELOG.md。

接入 Home Assistant 等外部程序

在 系统设置 → 用户管理 → API 令牌 新建一个令牌(只读、不过期,删除后立即失效;原文只在创建时显示一次),请求时放在请求头里:

Authorization: Bearer rdp_xxxxxxxx
GET http://<ROS-DPI 地址>:8080/api/ha/summary?limit=30

/api/ha/summary 一次返回首页常用的数:今日 / 本周 / 本月流量、实时速率、在线终端数、识别率、健康指数、应用大类构成、Top 应用,以及按今日流量排序的前 limit 台终端(名称、IP、MAC、类型、实时速率、今日 / 本周 / 本月流量、今日前 3 个应用)。字节数单位是 bytes,速率是 bytes/s。令牌也能读其它只读接口(等同普通用户),但不能修改任何设置。

Home Assistant 里用 RESTful 传感器读取即可,例如:

rest:
  - resource: http://192.168.88.10:8080/api/ha/summary
    headers:
      Authorization: !secret rosdpi_token     # secrets.yaml 里写 "Bearer rdp_..."
    scan_interval: 60
    sensor:
      - name: rosdpi_summary
        value_template: "{{ value_json.online }}"
        json_attributes: [totals, rate, hosts, groups, top_apps, identified, health]

安全建议

  • 内网有不可信设备时,设 COLLECTOR_ALLOWED=<路由器IP>,采集端口只接收路由器发来的包,防止别人伪造流量或 DNS 记录。
  • 不要把 8080 端口直接暴露到公网;需要外网访问时放在反向代理后面并启用 HTTPS。从公网打开安装向导时,需要填写启动日志里打印的安装码。
  • RouterOS 账号只给只读权限(上面第 6 步的用户组);管控页生成的命令要你自己检查后再执行。

环境变量

Linux 一键安装写在 /etc/ros-dpi.env,Docker 写在 compose 的 environment。标了“网页可改”的,网页上的设置优先。

基础

变量 默认值 说明
DATABASE_URL 空 留空则用网页安装向导(Linux 一键安装默认 SQLite)。MySQL 格式:mysql+pymysql://user:pass@host:3306/rosdpi?charset=utf8mb4
LAN_CIDRS 私网三段 + fd00::/8 内网网段,逗号分隔(网页可改)
ADMIN_PASSWORD 空 首次启动时创建 admin 的密码;留空则在网页上设置
TZ Asia/Shanghai 统计用的时区;每周从周一开始
HTTP_PORT / IPFIX_PORT / TZSP_PORT 8080 / 2055 / 37008 端口
DATA_DIR ./data 数据目录;Docker 里是 /app/data
SECRET_KEY 自动生成 登录令牌的签名密钥

RouterOS 与采集

变量 默认值 说明
ROS_URL / ROS_USER / ROS_PASSWORD 空 RouterOS REST 地址和只读账号(网页可改)
ROS_VERIFY_TLS false 是否校验 RouterOS 的证书
ROS_POLL_SECONDS / ROS_RATE_SECONDS 30 / 5 完整轮询间隔 / WAN 口速率采样间隔(秒)
WAN_INTERFACE 自动 WAN 接口名,默认按默认路由判断
COLLECTOR_ALLOWED 空 采集端口只收这些地址的包(一般填路由器 IP);留空不限制

外部数据源(都可在网页填写)

变量 默认值 说明
SINGBOX_URL / SINGBOX_SECRET 空 sing-box 的 Clash API 地址和密钥
PROXY_IPS 空 旁路代理自己的 IP;留空时取 SINGBOX_URL 里的地址
FAKEIP_CIDRS 198.18.0.0/15,fc00::/18 FakeIP 地址段
MOSDNS_URL 空 MosDNS 审计 API 地址
ADGUARD_URL / ADGUARD_USERNAME / ADGUARD_PASSWORD 空 AdGuard Home 地址和账号

识别库与社区

变量 默认值 说明
ASN_DB / CHINA_DB / IPLIST_DB / BM7_DB / HAGEZI_DB / UT1_DB / OUI_DB true 各识别库是否自动下载;机器上不了外网时设 false
SHARE_ENABLED true 社区共享库总开关(网页可改)
SHARE_HUB_URL https://rosdpi.vviip.dpdns.org:8443 社区主站地址,一般不用改(网页可改)
SHARE_VERIFY_TLS true 校验主站证书;私有社区用自签证书时才设 false
SHARE_HUB false 把本实例当作社区主站(只有主站部署才设 true)
SHARE_TRUSTED_PROXIES 空 主站用:只信任这些反向代理传来的 X-Forwarded-For;留空 = 内网和本机地址

数据保留(网页可改)

变量 默认值(天)
RETENTION_MINUTE_DAYS / RETENTION_HOUR_DAYS / RETENTION_DAY_DAYS 2 / 45 / 730(分钟、小时、每日汇总)
RETENTION_DOMAIN_DAYS / RETENTION_LOG_DAYS / RETENTION_EVENT_DAYS 31 / 30 / 180(域名明细、访问日志、审计事件)

开发

技术栈:后端 FastAPI + SQLAlchemy(MySQL / SQLite),前端 Vue 3 + Vite + ECharts。

# 后端
cd backend && python -m venv .venv && .venv/bin/pip install -r requirements.txt pytest
DATABASE_URL=sqlite:///./dev.db .venv/bin/uvicorn app.main:app --port 8080
.venv/bin/python -m pytest

# 前端:http://localhost:5173,/api 代理到 8080
cd frontend && npm install && npm run dev

# 灌一些模拟流量
backend/.venv/bin/python scripts/simulate.py --minutes 5

# 打包 Linux 单文件二进制(产物 dist/ros-dpi)
cd frontend && npm run build && cd ..
pip install -r backend/requirements.txt pyinstaller && pyinstaller ros-dpi.spec

补充应用规则:改 backend/app/classify/apps.yaml(手工维护,优先级最高,欢迎 PR)。apps_v2fly.yaml 由 scripts/import_v2fly.py 生成,不要手改。


English

ROS-DPI is a traffic, application and access-audit dashboard for networks behind a MikroTik RouterOS router. RouterOS exports flow records (IPFIX) and mirrors DNS answers and TLS/QUIC handshakes (TZSP); ROS-DPI turns them into per-device and per-person traffic by application, with access logs and alert rules. No inline box, no router replacement.

Features

  • Overview: router status, network health score with fixes, online hosts, DHCP pool, per-WAN status and rate, traffic mix, live and historical traffic, top apps and hosts.
  • Hosts: device type detection (phone, PC, TV, camera…), IP / MAC / hostname / owner, online time, live rate, daily / weekly / monthly totals, per-device app mix, domains, access log and timeline; CSV export.
  • Applications: three-level drill-down (group → category → app) — 17 groups, 50 categories, ~2,970 apps.
  • Flows: live connections, top destinations, world flow map, proxy routing per sing-box policy group and outbound.
  • People: group devices per person. Home scenario focuses on children's screen time and habits; Business on productivity and compliance.
  • Audit: access log, rules (app, domain, time window, traffic threshold, large upload, rogue router, new device), 14 notification channels, daily / weekly reports, operation log.
  • Control commands: generates RouterOS commands (block an app, scheduled cut-off, rate limit) with undo commands. It never changes the router by itself.
  • Chinese and English UI, light and dark themes, mobile friendly.

Quick start

Linux (single binary, SQLite by default, one-click updates from the UI):

curl -fsSL https://raw.githubusercontent.com/suyijun8182/ros-dpi/main/install.sh | sudo bash

It verifies the download's SHA256, creates a dedicated ros-dpi user and starts a systemd service on port 8080. The binary lives in /opt/ros-dpi/bin, data in /opt/ros-dpi/data, and your settings in /etc/ros-dpi.env (kept across reinstalls). Installs from 0.6.23 or earlier ran as root — re-run the command to migrate; data and settings are kept.

Docker, with a bundled MySQL:

curl -o docker-compose.yml https://raw.githubusercontent.com/suyijun8182/ros-dpi/main/docker-compose.with-mysql.yml
printf 'MYSQL_PASSWORD=change-me\nMYSQL_ROOT_PASSWORD=change-me-too\n' > .env
# set LAN_CIDRS in docker-compose.yml, then:
docker compose up -d

Docker, with your own MySQL: create the database and user with the SQL in the Chinese section, use docker-compose.yml, and enter the MySQL details in the setup wizard on first launch (use the host's LAN IP, not 127.0.0.1). Images: suyijun8182/ros-dpi on Docker Hub and ghcr.io/suyijun8182/ros-dpi, amd64 / arm64, tagged per release.

Then open http://<host>:8080, set the admin password, and copy the RouterOS commands from Settings → Setup & check (also listed in the RouterOS section above and in docs/RouterOS配置.md). The self-check there flags missing rules, wrong ports and FastTrack bypassing the sniffer.

How apps are identified

The domain of each connection comes from its TLS/QUIC SNI, then sniffed DNS answers, then the host's recent lookups, then a network-wide IP→domain table. Domains and IPs map to apps through four layers: (1) public libraries, updated automatically — built-in rules, v2fly, blackmatrix7, Hagezi / UT1 categories, ASN, China domain lists and official cloud IP ranges; (2) a local self-learning library of mappings observed on your own network; (3) the community library; (4) generic fallbacks such as "HTTPS". When the libraries change, past traffic is reclassified automatically.

With DNS sniffing alone, DoH/DoT clients show up as generic HTTPS/QUIC — enable the SNI rules to cover them. Sites using ECH only expose their outer public name.

Community library

Instances share anonymous votes (remote IP / domain → app) through the built-in community hub — no hosts, no access logs and no private addresses are sent. A mapping is published only when instances on at least two different networks (IPv4 /24, IPv6 /56, stored as salted hashes) agree, so one person running many instances still counts once. Instances need no public IP. Toggle it and see its status under Settings → External sources; to run a private hub, see deploy/hub/ and docs/社区主站部署.md.

Optional sources

sing-box (Clash API) adds per-host, per-domain byte counts for proxied traffic; MosDNS adds per-host DNS lookups; AdGuard Home fills in domains behind a second NAT. Configure them under Settings → External sources.

Home Assistant and other programs

Create a read-only API token under Settings → Users → API tokens (it never expires and stops working when deleted; the token is shown only once). Send it as Authorization: Bearer rdp_…. GET /api/ha/summary?limit=30 returns today / week / month totals, live rate, online hosts, identification rate, health score, app groups, top apps and the top hosts by today's traffic with their top three apps (bytes and bytes/s). See the Chinese section for a Home Assistant RESTful sensor example.

Security notes

Set COLLECTOR_ALLOWED=<router IP> if untrusted devices share the LAN. Don't expose port 8080 to the internet directly — put it behind an HTTPS reverse proxy. Give RouterOS a read-only user only.

All environment variables are listed in the Chinese section.

License

MIT

backend/app/classify/apps_v2fly.yaml is generated from v2fly/domain-list-community (MIT License, Copyright (c) 2019-present V2Fly Community). World map data from Natural Earth (public domain).

These data sources are not included in this repository or the Docker image; ROS-DPI downloads them at runtime into its data directory, and each keeps its own license / 以下数据不在仓库和镜像里,运行时下载,各自沿用原许可证: