vault backup: 2026-08-17 17:11:21
This commit is contained in:
@@ -0,0 +1,336 @@
|
|||||||
|
# Matrix 设备认证(SAS)— 知识沉淀
|
||||||
|
|
||||||
|
> 本文档是 `ha-matrix-e2e`(`custom_components/matrix_e2ee`,基于 matrix-nio 0.26.0 + vodozemac)在
|
||||||
|
> Matrix 设备验证方面**全部已知知识的汇总**,范围:官方规范、官方文档/实现偏差、认证流程、代码定位、
|
||||||
|
> 注意事项。目的:避免重复排查、重复实现、重复踩坑。
|
||||||
|
>
|
||||||
|
> 配套文档:[`docs/DEVICE_VERIFICATION.md`](DEVICE_VERIFICATION.md)(人话操作指南 + 源码级流程)、
|
||||||
|
> [`SECURITY.md`](../SECURITY.md)(信任模型与威胁边界)、[`docs/DEVELOPMENT.md`](DEVELOPMENT.md)(测试纪律)。
|
||||||
|
>
|
||||||
|
> 维护约定:完成/发现新的验证相关 issue 后,把结论同步到本文档对应章节和「Issue 索引表」,不要只留在 Linear。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 官方规范(Matrix Spec)
|
||||||
|
|
||||||
|
规范来源:matrix-spec `content/client-server-api/modules/end_to_end_encryption.md`(注意:**不是**
|
||||||
|
`sas_verification.md`,后者 404)。涉及两个机制:**验证框架**(`m.key.verification.request/ready/start/.../done/cancel`)
|
||||||
|
与 **SAS 方法**(`m.sas.v1`)。
|
||||||
|
|
||||||
|
### 1.1 验证框架
|
||||||
|
|
||||||
|
- **消息通道**:同一账号内验证用 **to-device** 消息;不同用户之间建议用 **in-room** 消息。本项目(bot 验证自己的
|
||||||
|
另一台设备)走 to-device。
|
||||||
|
- **Session ID**:to-device 用 `transaction_id`;in-room 用 event ID。
|
||||||
|
- **流程**:`request`(发起方声明支持的 methods)→ 对方提示接受 → `ready`(接受方回 methods 交集)→ 用户选方法 →
|
||||||
|
`start` → 方法内交换 → `done`。**任意时点**任一方都可发 `cancel`(带 code)。
|
||||||
|
- **多设备广播**:to-device 的 `request` 广播到对方所有设备(同一 txn)。其中一台接受后,对其他设备发 `cancel`
|
||||||
|
(code `m.accepted`);用户在另一台拒绝则 code `m.user`。in-room 只发一次 request,无 cancel-to-others。
|
||||||
|
- **提示自动消失**:to-device 按 `timestamp`(in-room 按 `origin_server_ts`)起 **10 分钟**,或收到后 **2 分钟**,
|
||||||
|
先到为准。拒绝请求**必须**发 `cancel`,code=`m.user`。
|
||||||
|
|
||||||
|
### 1.2 SAS 方法 `m.sas.v1` — 安全原理
|
||||||
|
|
||||||
|
灵感来自 **ZRTP hash commitment**:responder 在 `accept` 里先发**自己公钥的 hash(commitment)**,initiator 收到
|
||||||
|
commitment 后才发自己的公钥。攻击者只有一次猜的机会:验证 n bit 则成功率 `1/2^n`(SAS 全 40+ bit → ~1/10^12)。
|
||||||
|
分两个阶段:
|
||||||
|
|
||||||
|
1. **密钥协商**:双方各生成临时 Curve25519 密钥对,交换公钥(带 commitment 保护),ECDH 得共享秘密。
|
||||||
|
2. **密钥验证**:用共享秘密派生 HMAC,互相认证各自的设备 ed25519 key。
|
||||||
|
|
||||||
|
### 1.3 SAS 全流程(18 步,initiator = Alice / responder = Bob)
|
||||||
|
|
||||||
|
| # | 动作 | 消息 | 内容要点 |
|
||||||
|
|---|---|---|---|
|
||||||
|
| 1 | 线下安全会面 | — | 双方对照设备显示内容 |
|
||||||
|
| 2 | 开始验证 | — | 任一方发起 |
|
||||||
|
| 3 | Alice 发 start | `m.key.verification.start` | **必须先拿到 Bob 设备 key**;含 key_agreement/hash/mac_method/short_authentication_string |
|
||||||
|
| 4 | Bob 选算法 | — | 从 Alice 支持列表里挑 key agreement/hash/MAC/SAS 方法 |
|
||||||
|
| 5 | Bob 需已持 Alice 设备 key | — | 否则先 key query |
|
||||||
|
| 6 | Bob 生成临时 Curve25519 对 | — | 对公钥做 SHA-256 |
|
||||||
|
| 7 | Bob 回 accept | `m.key.verification.accept` | 含 `commitment`(自己公钥的 hash) |
|
||||||
|
| 8 | Alice 存 commitment | — | 后续校验 |
|
||||||
|
| 9 | Alice 生成临时对、发 key | `m.key.verification.key` | **只发公钥** |
|
||||||
|
| 10 | Bob 发自己 key | `m.key.verification.key` | 已无 commitment 保护风险 |
|
||||||
|
| 11 | Alice 校验 commitment | — | `commitment == hash(Bob 公钥 + Alice 的 start content)` |
|
||||||
|
| 12 | 双方 ECDH | — | 临时密钥 → 共享秘密 |
|
||||||
|
| 13 | 双方显示 SAS | — | emoji/decimal(多方法时用户选) |
|
||||||
|
| 14 | 用户比对 | — | 两边一致才继续 |
|
||||||
|
| 15 | 算 MAC | — | 对每个要验证的 key + key ID 列表 |
|
||||||
|
| 16 | 双方发 mac | `m.key.verification.mac` | |
|
||||||
|
| 17 | 校验对方 MAC | — | 每个 key 的 MAC + key 列表 MAC 全对 → 设备已验证 |
|
||||||
|
| 18 | 双方发 done | `m.key.verification.done` | |
|
||||||
|
|
||||||
|
**要验证哪些 key**:本设备的 ed25519 key + master signing key(跨用户时**应**含 MSK;「验证他人单设备」的做法已废弃)。
|
||||||
|
|
||||||
|
### 1.4 错误处理与 cancel code
|
||||||
|
|
||||||
|
- 随时可 cancel;**10 分钟超时**(txn 闲置 10min 也过期)。
|
||||||
|
- 同一设备多次发起 → recipient 全部 cancel。
|
||||||
|
- **未知 txn → cancel**(入站 `start`/`cancel` 除外)。
|
||||||
|
- 无共同方法 → cancel;SAS 不符 → cancel;乱序 → cancel。
|
||||||
|
- SAS 专属 cancel code:`m.unknown_method`、`m.mismatched_commitment`、`m.mismatched_sas`。
|
||||||
|
- 框架层 code:`m.user`(用户拒绝)、`m.accepted`、`m.timeout`、`m.unexpected_message`、`m.key_mismatch`。
|
||||||
|
|
||||||
|
### 1.5 MAC 计算(wire 格式,容易错)
|
||||||
|
|
||||||
|
- **HKDF 参数**:HKDF-SHA256,IKM = 共享秘密,**无 salt**。
|
||||||
|
- **MAC info 串**(逐字节拼接,无分隔符):
|
||||||
|
`MATRIX_KEY_VERIFICATION_MAC` + 发 MAC 方 `user_id` + `device_id` + 对方 `user_id` + `device_id` + `transaction_id`
|
||||||
|
+ `key_id`(单个 key);对 key 列表用字符串 `KEY_IDS`。
|
||||||
|
- **HMAC 对象**:
|
||||||
|
- 单个 key → **unpadded base64** 编码的公钥;
|
||||||
|
- key 列表 → 字典序排序、**逗号连接、无空格**的 `alg:id` 列表,例如
|
||||||
|
`ed25519:Cross+Signing+Key,ed25519:DEVICEID`。
|
||||||
|
- MAC 值 base64 编码后放进 `mac` 消息的 `mac` 与 `keys` 字段。
|
||||||
|
- **版本(关键)**:规范要求「所有当前实现都应用 `hkdf-hmac-sha256.v2`」。legacy `hkdf-hmac-sha256`(v1)因 libolm
|
||||||
|
原始实现 bug 使用了**错误 base64 编码**,v2 修正;**v1 已废弃,双方都支持 v2 时 MUST NOT 用 v1**。
|
||||||
|
|
||||||
|
### 1.6 SAS 派生
|
||||||
|
|
||||||
|
- **HKDF info(`curve25519-hkdf-sha256`)**:
|
||||||
|
`MATRIX_KEY_VERIFICATION_SAS|` + start 发起方 `user_id|` + `device_id|` + start 方公钥(unpadded base64)`|`
|
||||||
|
+ accept 方 `user_id|` + `device_id|` + accept 方公钥(unpadded base64)`|` + `transaction_id`。
|
||||||
|
废弃的 `curve25519` 方法:无 `|` 分隔、不含公钥。
|
||||||
|
- **decimal**:取 5 字节 → 3 个 13-bit 数(0–8191)各 +1000 → 三个 1000–9191 的数。
|
||||||
|
位运算:`(B0<<5|B1>>3)+1000`;`((B1&0x7)<<10|B2<<2|B3>>6)+1000`;`((B3&0x3F)<<7|B4>>1)+1000`。
|
||||||
|
- **emoji**:取 6 字节 → 前 42 bit → 7 组 6-bit → 7 个 0–63 索引 → 查 64 格 emoji 表
|
||||||
|
(JSON 在 `matrix-org/matrix-spec` 仓库 `data-definitions/sas-emoji.json`)。
|
||||||
|
|
||||||
|
### 1.7 Cross-signing(本项目的「不做」依据)
|
||||||
|
|
||||||
|
三把 ed25519 对:**MSK**(master signing key,签 USK/SSK,代表用户身份)、**USK**(user-signing key,只自己可见,
|
||||||
|
签他人 MSK)、**SSK**(self-signing key,签自己的设备 key)。作用:只需验证一次 MSK 即可信任该用户所有设备。
|
||||||
|
本集成因 **nio 0.26 不支持自签 cross-signing key**,且自签会把 cross-signing 权威放到 HA 主机上(违背信任边界),
|
||||||
|
故**不做** SSSS / Key Backup 导入(W1N-147 结论)。可对他人设备验证其 MSK,但 bot 自身无法 bootstrap 新设备。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 官方规范 vs nio 0.26 的偏差(文档/实现漂移 — 最容易重复踩)
|
||||||
|
|
||||||
|
| # | 规范/预期 | nio 0.26.0 实际 | 修复 | 出处 |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| 1 | `request → ready` 由框架处理 | **没有实现**;request 被解析为 `UnknownToDeviceEvent` 丢弃 → Element 端显示取消 | 集成自建 `_handle_verification_request` + `_send_verification_ready` | W1N-173, PR #25 |
|
||||||
|
| 2 | 会话有 10 分钟活动窗口 | `Sas._last_event_time` 只在 `__init__` 赋值、**从不刷新** → `timed_out` 60s 后必真;`clear_verifications()` 每 sync 取消 | monkeypatch `Sas.timed_out`:只留 5min `_max_age`;集成超时 240s 先行触发 | W1N-172, PR #23 |
|
||||||
|
| 3 | commitment 为 **unpadded base64** | 迁移 vodozemac 后发 **hexdigest**,Element 拒收(`m.key_mismatch`) | `_apply_sas_commitment_patch`:`from_key_verification_start` + `_check_commitment` 都改回 unpadded base64 | PR #28, v0.2.8 |
|
||||||
|
| 4 | emoji 索引由底层算出 | vodozemac 已返回 7 个最终索引,nio 仍按 libolm 时代 bit-slicing **二次转换** → 两端 emoji 不一致、`m.mismatched_sas` | monkeypatch `_generate_emoji` 直接用 indices | W1N-175, PR #29 |
|
||||||
|
| 5 | 协商 `hkdf-hmac-sha256`(v1) 时 wire 用 libolm **invalid base64** | nio 用标准 `calculate_mac` → MAC 阶段失败 | monkeypatch `get_mac` + `receive_mac_event`,按 `chosen_mac_method` 选 `calculate_mac_invalid_base64`(libolm-compat feature) | W1N-177, PR #30 |
|
||||||
|
| 6 | 应优先/只用 `.v2` MAC | nio 0.26 **只协商 v1,不提供 `.v2`** | 保持 v1 + invalid_base64 与 rust-sdk/Element 互操作;**不要**自己加 `.v2`(会扩大协商面但 nio 没实现) | W1N-177 |
|
||||||
|
| 7 | `keys_query` 应覆盖会话各方 | 只取「共享加密房间用户」→ bot 与自身设备不共享房间 → **永不查询自己** → 入站 SAS 建不起来 | 登录/恢复后把自身 `user_id` 加进 `users_for_key_query` 并预热 | W1N-166, PR #18 |
|
||||||
|
| 8 | 收到 start 前应有设备 key | 新设备首次 start 命中 device_store KeyError → 丢弃 + 不建 SAS | `_repair_dropped_start`:查 key 后把同一 start 重喂给 `nio.olm.handle_key_verification` | W1N-170, PR #23 |
|
||||||
|
| 9 | 校验失败应发 `m.key_mismatch` cancel | `receive_mac_event`「无已验证设备」分支置 canceled 后**缺 return**,下一行覆盖为 `mac_received` | 上游 bug,**Backlog**(W1N-179) | W1N-179 |
|
||||||
|
|
||||||
|
另:nio 的 `Sas.verified = (state == mac_received) ∧ sas_accepted`,`get_mac()` 在 `sas_accepted=False` 时抛
|
||||||
|
`LocalProtocolError`——集成代码曾因裸调 get_mac 被 `except Exception` 吞掉而卡死(W1N-142)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 认证流程(本项目实际路径)
|
||||||
|
|
||||||
|
### 3.1 对外接口(已定型)
|
||||||
|
|
||||||
|
**服务(admin-only 用 `async_register_admin_service` 强制,W1N-150)**:
|
||||||
|
|
||||||
|
| 服务 | 权限 | 说明 |
|
||||||
|
|---|---|---|
|
||||||
|
| `start_verification` | **admin** | bot 发起 SAS(入站由 Element 发起时无需调用) |
|
||||||
|
| `confirm_verification` | **admin** | 人工比对 emoji 后确认;内部 = `accept_sas` + `get_mac`(verified 时再 `verify_device`) |
|
||||||
|
| `cancel_verification` | **admin** | 取消 |
|
||||||
|
| `verify_device_by_fingerprint` | **admin** | 单向信任;`user_id` + `device_id` + `ed25519` **精确匹配**,否则 `fingerprint_mismatch` |
|
||||||
|
| `reauthenticate` | **admin** | Config Flow reauth |
|
||||||
|
| `get_fingerprint` | 普通注册 | 只读;返回 bot 的 `ed25519`/`curve25519` |
|
||||||
|
| `send_message` | 普通注册 | 发消息 |
|
||||||
|
|
||||||
|
**事件**:
|
||||||
|
- `matrix_e2ee_verification` — 各 `stage`:`started` / `sas`(含 `emojis`)/ `done` / `canceled`,带 `expires_at`
|
||||||
|
(W1N-145 `VerificationPrompt`:`transaction_id/user_id/device_id/emojis/expires_at`)。
|
||||||
|
- `matrix_e2ee_fingerprint` — 启动后 emit bot 指纹。
|
||||||
|
- `matrix_e2ee_command` / `matrix_e2ee_error` — 命令事件(仅 `verified=True` 且 allowlist 命中才触发)。
|
||||||
|
|
||||||
|
**错误码**(`const.py`):`verification_peer_denied`(发起者非 bot 自身账号或 `allowed_users`)、`verification_timeout`
|
||||||
|
(集成超时 4min)、`fingerprint_mismatch`、`invalid_transaction`、`device_missing`。
|
||||||
|
|
||||||
|
### 3.2 双向流程(wire 时序)
|
||||||
|
|
||||||
|
**方向 A:Element 发起(入站)** — 由 `handle_to_device_event` + `_handle_verification_request` 驱动:
|
||||||
|
|
||||||
|
```
|
||||||
|
Element HA bot (matrix_e2ee)
|
||||||
|
│ m.key.verification.request {txn, methods:[m.sas.v1], timestamp}
|
||||||
|
│ ──────────────────────────────────────────────► _handle_verification_request
|
||||||
|
│ 校验: sender 允许 / from_device、txn 非空 /
|
||||||
|
│ methods 含 m.sas.v1 / timestamp 界内
|
||||||
|
│ ◄────────────────────────────────────────────── m.key.verification.ready {methods:[m.sas.v1]}
|
||||||
|
│ m.key.verification.start {txn, ...}
|
||||||
|
│ ──────────────────────────────────────────────► handle_to_device_event (start 分支)
|
||||||
|
│ _get_sas==None → _repair_dropped_start(查 key 重喂)
|
||||||
|
│ accept_key_verification(txn) → emit started
|
||||||
|
│ ◄────────────────────────────────────────────── m.key.verification.accept(nio 内部,含 commitment)
|
||||||
|
│ m.key.verification.key ... key 交换 → 双方显示 emoji
|
||||||
|
│ ──────────────────────────────────────────────► (key 分支) emit sas {emojis, expires_at}
|
||||||
|
│ HA 侧人工比对 emoji → confirm_verification(txn)
|
||||||
|
│ confirm_short_auth_string(txn)
|
||||||
|
│ = accept_sas + get_mac + (verified→verify_device)
|
||||||
|
│ ◄────────────────────────────────────────────── m.key.verification.mac(只发一次, W1N-169)
|
||||||
|
│ m.key.verification.mac → (mac 分支) sas.verified → emit done
|
||||||
|
```
|
||||||
|
|
||||||
|
**方向 B:bot 发起(出站)** — `start_verification(user_id, device_id)` → `nio.start_key_verification(device)` 发出
|
||||||
|
start;后续 accept/key/emoji 同方向 A;比对后同样 `confirm_verification` 完成。key 的发送**完全由 nio 内部负责**
|
||||||
|
(`handle_key_verification` 里 `if not sas.we_started_it: share_key()`),集成不再手动 `share_key()`(W1N-169)。
|
||||||
|
|
||||||
|
**状态机要点**:
|
||||||
|
- 集成只在 start 分支记录 monotonic 时间(`_mark_sas_started`);超时判断 = `sas.timed_out` **或**
|
||||||
|
monotonic 差 ≥ 240s(`_sas_is_timed_out`),超时 → `_timeout_verification`:cancel + emit `verification_timeout`。
|
||||||
|
- `confirm_verification` 是**唯一**完成验证的路径:先查超时,再 `nio.confirm_short_auth_string(txn)`,`sas.verified`
|
||||||
|
→ emit `done`,否则 emit `sas`(等用户再次 confirm)。
|
||||||
|
- 入站门控:所有分支(start/key/mac/cancel)统一 `_bootstrap_allowed(sender)`——`sender == session.user_id`
|
||||||
|
**或** `sender ∈ allowed_users`,否则 emit `verification_peer_denied`(W1N-143)。
|
||||||
|
|
||||||
|
### 3.3 路径二:单向指纹验证(降级/备选)
|
||||||
|
|
||||||
|
`get_fingerprint` 取 bot 指纹 → Element「Manually Verify by Text」;信任对端用 `verify_device_by_fingerprint`
|
||||||
|
(精确匹配后 `nio.olm.verify_device`,**本地单向信任,不是 SAS,不产生 SAS 事件**)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. 代码地图(`custom_components/matrix_e2ee/`)
|
||||||
|
|
||||||
|
### client.py(1525 行;无 models.py,模型在此文件)
|
||||||
|
|
||||||
|
**nio 补丁区(160–398)**:
|
||||||
|
|
||||||
|
| 函数 | 行 | 作用 |
|
||||||
|
|---|---|---|
|
||||||
|
| `_apply_sas_timeout_patch` | 164 | monkeypatch `Sas.timed_out`:verified/canceled→False;`now-creation ≥ _max_age(5min)`→canceled+`_timeout_error`+True。**忽略 nio 60s 事件超时 bug** |
|
||||||
|
| `_sas_commitment(pubkey, canonical)` | 197 | SHA-256(pubkey+canonical) 的 unpadded base64 |
|
||||||
|
| `_apply_sas_commitment_patch` | 208 | patch `from_key_verification_start`(accept commitment)+ `_check_commitment`(initiator 校验)→ unpadded base64 |
|
||||||
|
| `_apply_sas_emoji_patch` | 256 | `_generate_emoji` 直接用 `established_sas.bytes(info).emoji_indices` 映射,不做 bit-slicing |
|
||||||
|
| `_apply_sas_mac_patch` | 286 | 见下 |
|
||||||
|
| `_select_mac_func` | 304 | `chosen_mac_method=="hkdf-hmac-sha256"` → `calculate_mac_invalid_base64`,否则 `calculate_mac` |
|
||||||
|
| `get_mac`(patch) | 309 | `sas_accepted=False`/canceled 抛 `LocalProtocolError`;按规范拼 info、`ed25519:{own_device}` + `KEY_IDS` |
|
||||||
|
| `receive_mac_event`(patch) | 339 | verified→return;`state!=key_received`→canceled;KEY_IDS 校验→`_key_mismatch_error`;逐 key device_id 匹配 + MAC 校验 → verified_devices;空→canceled(**缺 return,复刻 W1N-179 bug**) |
|
||||||
|
| `_patch_nio_sas_timeout/_commitment/_emoji/_mac` | 188/246/277/390 | `try: from nio … except Exception: return`(测试无 nio 时 no-op) |
|
||||||
|
|
||||||
|
**验证服务(936–1525)**:
|
||||||
|
|
||||||
|
| 函数 | 行 | 作用 |
|
||||||
|
|---|---|---|
|
||||||
|
| `enable_verification_callbacks` | 936 | 注册 `handle_to_device_event`(KeyVerificationEvent)+ `_handle_verification_request`(ToDeviceEvent) |
|
||||||
|
| `_emit_verification(stage, **extra)` | 947 | fire `matrix_e2ee_verification` + warning log |
|
||||||
|
| `_verification_expires_at` | 953 | now UTC + `_verification_timeout` ISO 串 |
|
||||||
|
| `_lookup_device` / `_get_sas` | 959 / 972 | device_store 查设备 / `nio.key_verifications.get(txn)` |
|
||||||
|
| `_sas_party` / `_sas_emojis` | 978 / 990 | 提取对端 (user,device) / `sas.get_emoji()`(异常吞掉→None,`list[list[str]]`) |
|
||||||
|
| `_mark_sas_started` / `_sas_is_timed_out` | 1006 / 1009 | monotonic 记录 / 超时判断 |
|
||||||
|
| `async_start_verification` | 1018 | 拒软登出;查设备→`nio.start_key_verification`;emit `started` |
|
||||||
|
| `async_verify_device_by_fingerprint` | 1060 | `actual.strip()!=ed25519.strip()` 精确等值(W1N-159)→`fingerprint_mismatch`;`nio.olm.verify_device` |
|
||||||
|
| `async_confirm_verification` | 1090 | 超时检查→`nio.confirm_short_auth_string(txn)`;verified→emit `done`,否则 emit `sas`。**唯一验设备路径** |
|
||||||
|
| `async_cancel_verification` | 1139 | `nio.cancel_key_verification(txn, reject=False)` → emit `canceled` |
|
||||||
|
| `_timeout_verification` | 1169 | cancel + emit `verification_timeout` + `timeout` |
|
||||||
|
| `_bootstrap_allowed(sender)` | 1187 | `sender==session.user_id` 或 `sender in allowed_users`(W1N-143 门控) |
|
||||||
|
| `_repair_dropped_start` | 1196 | `_query_device_keys(sender)` 后重喂 `nio.olm.handle_key_verification(event)`(W1N-170) |
|
||||||
|
| `_handle_verification_request` | 1222 | 解析 request;校验 sender/txn/methods/timestamp → `_send_verification_ready`;**不建 SAS 状态**(W1N-173) |
|
||||||
|
| `_send_verification_ready` | 1283 | 回 `ready` {from_device: own, methods:[m.sas.v1], transaction_id} |
|
||||||
|
| `handle_to_device_event` | 1314 | 主分发:门控→cancel→timeout→start(emoji 检查/repair/accept/emit)→key(emit sas)→mac(verified→emit done) |
|
||||||
|
| `_verification_kind` | 1458 | 类名/type 串 → start/key/mac/cancel |
|
||||||
|
| `_request_timestamp_valid` | 1447 | 未来≤5min 且 age≤10min |
|
||||||
|
| `_transaction_id_from_verifications` | 1480 | 匹配 other user+device;唯一则兜底 |
|
||||||
|
| `_verification_error_code` | 1496 | timeout→`verification_timeout`;LocalProtocolError/does not exist→`invalid_transaction`;unverified→`unverified_device`;否则 `send_failed` |
|
||||||
|
|
||||||
|
### const.py(79 行)
|
||||||
|
|
||||||
|
`SERVICE_START/CONFIRM/CANCEL_VERIFICATION`、`SERVICE_VERIFY_DEVICE_BY_FINGERPRINT`;`ATTR_ED25519/TRANSACTION_ID/
|
||||||
|
USER_ID/DEVICE_ID`;`EVENT_VERIFICATION`/`EVENT_FINGERPRINT`;错误码见 §3.1;`VERIFICATION_TIMEOUT_SECONDS=240`;
|
||||||
|
`VERIFICATION_REQUEST_MAX_FUTURE_MS`/`MAX_AGE_MS`;`SAS_METHOD_V1="m.sas.v1"`;`VERIFICATION_REQUEST/READY/START/
|
||||||
|
ACCEPT/KEY/MAC/DONE/CANCEL` 类型串。
|
||||||
|
|
||||||
|
### __init__.py
|
||||||
|
|
||||||
|
`_register_services`(136) 服务→client 方法映射;`_fire_event`(123);`_options`(126) 读 `allowed_users/allowed_rooms`;
|
||||||
|
`async_setup_entry`(268)/`async_unload_entry`(321)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. 注意的问题(Checklist / 教训)
|
||||||
|
|
||||||
|
**协议 / wire 层**
|
||||||
|
1. **MAC 生成与校验必须一起改**(`get_mac` + `receive_mac_event` 同步 monkeypatch),只改一边 = 互不兼容。
|
||||||
|
2. **`.v2` 不要自己加**:nio 不提供 `_mac_v2`,不要扩大协商面。
|
||||||
|
3. **accept/key/mac 的发送权要分清**:key 归 nio 内部(`we_started_it` 判断),mac 只由 `confirm_verification` 发;
|
||||||
|
集成只做事件映射与人工 confirm 触发(W1N-169 双发教训)。
|
||||||
|
4. commitment 必须 unpadded base64(不是 hexdigest);emoji 索引不得二次转换;legacy MAC 用 invalid base64。
|
||||||
|
5. SAS HKDF info / MAC info 都是**无分隔符逐字节拼接**,字段顺序(发起方在前)与方向不能错。
|
||||||
|
|
||||||
|
**nio 状态机坑**
|
||||||
|
6. `Sas.timed_out` 被 nio 60s bug 污染 → 必须 monkeypatch,用 240s 集成超时先行。
|
||||||
|
7. `get_mac()` 在 `sas_accepted=False` 抛异常 → 必须走 `confirm_short_auth_string`,别裸调。
|
||||||
|
8. 入站 start 需设备 key:`_get_sas==None` 时先 `_repair_dropped_start`(查 key 重喂),不要直接放弃。
|
||||||
|
9. `keys_query` 默认不含 bot 自己 → 登录/恢复后主动预热自身 keys。
|
||||||
|
|
||||||
|
**信任 / 安全**
|
||||||
|
10. **无自动信任**:同账号 ≠ 可信,包括 `@bot` 自身设备(W1N-153)。
|
||||||
|
11. 指纹比较**必须精确等值**,禁 `casefold()`(unpadded base64 大小写敏感,W1N-159)。
|
||||||
|
12. 验证/指纹/reauth 服务必须 admin-only(W1N-150);入站所有分支统一门控 `_bootstrap_allowed`(W1N-143)。
|
||||||
|
13. request 的 timestamp 校验:未来≤5min、age≤10min(W1N-173)。
|
||||||
|
14. fail-closed:未验证设备不触发命令事件、不回退明文、`ignore_unverified_devices` 永不开启、日志不落 secret(W1N-136)。
|
||||||
|
|
||||||
|
**运维 / 测试**
|
||||||
|
15. 设备 ID 变了 = store 丢失 → 按 runbook 重新验证,不静默新建设备(W1N-134/138)。
|
||||||
|
16. 测试只用 FakeNio/FakeSas,**协议级问题单测不可见** → 缺真实 homeserver e2e(W1N-171 Backlog)。
|
||||||
|
17. 上游 nio `receive_mac_event` 缺 return bug 已复刻到我们的 patch 里(W1N-179 Backlog),改上游时同步改。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Issue 索引表(Linear → 知识)
|
||||||
|
|
||||||
|
状态:✅ Done | ⏳ Backlog
|
||||||
|
|
||||||
|
| Issue | 主题 | 知识章节 | 状态 |
|
||||||
|
|---|---|---|---|
|
||||||
|
| W1N-134 | M2 E2EE 登录/原子 session/恢复同一设备 | §5-15 | ✅ |
|
||||||
|
| W1N-135 | M2 加密收发 + sync tokens(消费验证状态) | §3 | ✅ |
|
||||||
|
| W1N-136 | M2 fail-closed、allowlist、不记录 secret | §5-14 | ✅ |
|
||||||
|
| W1N-137 | M3 SAS 服务/事件 + verified-device 策略 | §3.1 | ✅ |
|
||||||
|
| W1N-138 | M4 软登出/store 丢失恢复/diagnostics | §5-15 | ✅ |
|
||||||
|
| W1N-141 | 集成设备安全验证指南(parent of A–F) | — | ✅ |
|
||||||
|
| W1N-142 | A SAS auto-completion(修 get_mac 卡死)→ 后被 W1N-153 撤销自动分支 | §2 / §5-7 | ✅ |
|
||||||
|
| W1N-143 | B 入站 SAS 发起者门控 | §3.2 / §5-12 | ✅ |
|
||||||
|
| W1N-144 | C 单向指纹验证(get_fingerprint / verify_device) | §3.3 | ✅ |
|
||||||
|
| W1N-145 | D VerificationPrompt 模型 + expires_at | §3.1 | ✅ |
|
||||||
|
| W1N-147 | F SECURITY.md + SAS/指纹指南(cross-signing 不做 SSSS) | §1.7 | ✅ |
|
||||||
|
| W1N-149 | 安全加固总纲(P0 自动确认 / P0 admin-only / P1 指纹门控) | §5 | ✅ |
|
||||||
|
| W1N-150 | B admin-only 强制 | §3.1 / §5-12 | ✅ |
|
||||||
|
| W1N-151 | C verify_device_by_fingerprint(ed25519 精确门控) | §3.3 | ✅ |
|
||||||
|
| W1N-153 | A 删除同账号 SAS 自动确认 | §5-10 | ✅ |
|
||||||
|
| W1N-154 | E 文档改为手动确认 + 新指纹服务名 | — | ✅ |
|
||||||
|
| W1N-156 | 加固跟进:allowlist 拆分 + P2 质量(**未做**) | §8 | ⏳ |
|
||||||
|
| W1N-157 | F 人话版验证指南(docs/DEVICE_VERIFICATION.md) | — | ✅ |
|
||||||
|
| W1N-158 | M5 Config Flow(reauth/设备验证 UI 路径动机) | — | ✅ |
|
||||||
|
| W1N-159 | casefold 指纹比较 bug → 精确匹配 | §5-11 | ✅ |
|
||||||
|
| W1N-162 | Config Flow reconfigure + reauth | — | ✅ |
|
||||||
|
| W1N-165 | 文档更新 + release 0.2.0(SAS 保持 service/event-based) | §8 | ✅ |
|
||||||
|
| W1N-166 | keys_query 不查同账号 → 预热 own device keys | §2-7 / §5-9 | ✅ |
|
||||||
|
| W1N-169 | key/mac 双发(协议正确性) | §5-3 | ✅ |
|
||||||
|
| W1N-170 | 启动后新增设备首次 start 被丢 → 自动查 key 重喂 | §2-8 / §5-8 | ✅ |
|
||||||
|
| W1N-171 | 缺真实 homeserver 端到端 SAS 测试 | §5-16 | ⏳ |
|
||||||
|
| W1N-172 | nio 60s 必死超时(_last_event_time 不刷新) | §2-2 / §5-6 | ✅ |
|
||||||
|
| W1N-173 | request → ready 桥接(nio 缺框架) | §2-1 / §5-13 | ✅ |
|
||||||
|
| W1N-174/176 | 部署 matrix_e2ee(e) 到 hass.windy.lan | — | ✅ |
|
||||||
|
| W1N-175 | emoji 双转换(vodozemac indices) | §2-4 | ✅ |
|
||||||
|
| W1N-177 | legacy MAC invalid-base64 | §2-5/6 / §5-1/2 | ✅ |
|
||||||
|
| W1N-178 | 部署 v0.2.10(含 legacy MAC 修复) | — | ✅ |
|
||||||
|
| W1N-179 | receive_mac_event 缺 return 覆盖 canceled(**未做**) | §2-9 / §5-17 | ⏳ |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. 当前版本状态与待办
|
||||||
|
|
||||||
|
- 已发布至 **v0.2.10**(wire 修复线:commitment v0.2.8 → emoji v0.2.9 → legacy MAC v0.2.10,均已部署
|
||||||
|
hass.windy.lan)。
|
||||||
|
- SAS 保持 **service/event-based**(v0.2.x);HA 内 live SAS emoji UI 延后到 v0.3(W1N-165 / SECURITY.md)。
|
||||||
|
|
||||||
|
**Backlog(避免重复工作,动手前先查这 3 条)**:
|
||||||
|
1. **W1N-156** — 拆分 `allowed_users` 为「命令权限」与「SAS 验证权限」两组;SAS 不支持算法显式 cancel;
|
||||||
|
setup/stop/reauth async lock;事务绑定(存预期 user/device/创建时间);CI manifest 依赖校验;ruff。
|
||||||
|
2. **W1N-179** — nio `receive_mac_event` 缺 return(上游 + 我们的 monkeypatch 同步修,加单测)。
|
||||||
|
3. **W1N-171** — 真实 homeserver 端到端 SAS 测试(docker Synapse 或人工 runbook)。
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
# 低打印量黑白激光一体机:采购决策树(2026-08)
|
||||||
|
|
||||||
|
## 结论
|
||||||
|
|
||||||
|
对于“打印量很小、20 页/分钟足够、不需要 ADF”的需求,不应为 34 页/分钟、250 页纸盒或双面 ADF 付费。它们解决的是连续文档处理,而不是偶尔打印。优先级应为:**不被耗材/账号绑定、稳定的局域网打印、平板扫描、紧凑尺寸和可获得的原装耗材**。
|
||||||
|
|
||||||
|
首选是 **Brother DCP-L1638W 或 DCP-L1848W**:两者都是传统鼓粉分离路线,20 ppm、150 页纸盒、百兆有线网口及 2.4/5 GHz Wi-Fi;官方资料不能证实 1848 相比 1638 有实质功能升级,因此按正规渠道的含税到手价和保修选较便宜、在售的一台即可。[L1638W 官方参数表](https://www.brother.cn/-/media/ap/cn/products/pdf-file/prt/ESL-done/DCP-L1628L1638W.ashx);[L1848W 官方参数表](https://www.brother.cn/-/media/ap/cn/products/pdf-file/prt/ESL_DCP-L1848W.ashx)
|
||||||
|
|
||||||
|
不把 Brother DCP-11W 作为默认首选。它是 Brother 当前标为新品的同级机器,却是“云充”按页模式:激活后含 700 页,页数用完要通过绑定的微信账户购买套餐才能继续打印;粉仓和硒鼓由官方免费提供。这适合愿意换取三年保修和明确按页预算的人,不适合希望长期离线、自主选择耗材的人。[新品发布](https://www.brother.cn/info/news/20250613);[云充规则](https://www.brother.cn/minisite/sppackage/esl/)
|
||||||
|
|
||||||
|
## 先按需求分流,而不是按品牌或 ppm
|
||||||
|
|
||||||
|
```text
|
||||||
|
需要批量扫描/复印多页原稿?
|
||||||
|
├─ 是 → 本指南不适用;选择带 ADF 的 L2648DW 等级,双面原稿高频则看双 CIS 机型。
|
||||||
|
└─ 否
|
||||||
|
└─ 需要自动双面打印?
|
||||||
|
├─ 是 → 选择 B7628DW 等带 duplex 的型号;这是功能升级,不是速度升级。
|
||||||
|
└─ 否
|
||||||
|
└─ 必须有有线网口或 5 GHz Wi-Fi?
|
||||||
|
├─ 是 → Brother L1638W/L1848W 为基准选择。
|
||||||
|
└─ 否 / 接受仅 2.4 GHz Wi-Fi
|
||||||
|
└─ 是否接受按页充值并绑定微信?
|
||||||
|
├─ 是 → Brother DCP-11W(先比较套餐与传统耗材总价)。
|
||||||
|
└─ 否 → L1638W/L1848W;或比较下列 Canon/HP/Pantum。
|
||||||
|
```
|
||||||
|
|
||||||
|
### 采购前的一票否决项
|
||||||
|
|
||||||
|
- 需要 macOS、iPhone/iPad:确认 AirPrint;不要假定“Wi-Fi”就等于无需驱动。
|
||||||
|
- 打印机准备接交换机:确认具体 SKU 有 **Ethernet**,不能把 Wi-Fi Direct 当作局域网网口。HP MFP 1188w 的中国规格仅列 USB 和 2.4 GHz Wi-Fi,不列有线网口。
|
||||||
|
- 偶尔使用也建议选激光,但纸张要长期放在干燥、封闭处;低使用量时,受潮纸和旧粉盒造成的底灰、掉粉或卡纸比 20/22 ppm 差异更常见。
|
||||||
|
- 需要自动双面打印、ADF、双面扫描时,直接跳级;入门平板机硬凑这些功能没有性价比。
|
||||||
|
|
||||||
|
## 候选机型:仅保留与需求相符者
|
||||||
|
|
||||||
|
| 机型 | 联网 / 移动打印 | 核心纸路与扫描 | 耗材结构 | 面向本需求的判断 |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| **Brother DCP-L1638W / L1848W** | USB、100M Ethernet、2.4/5 GHz Wi-Fi;AirPrint、Mopria、Wireless Direct、Brother Mobile Connect | 20 ppm、150 页进/50 页出、平板 CIS;无 ADF、无自动双面 | TN118 约 1,500 页 + DR118 约 10,000 页,鼓粉分离 | **首选**:功能刚好够用,网络规格最好,自主耗材路径最清晰。两台按价格/现货择一。 |
|
||||||
|
| **Brother DCP-11W** | USB、100M Ethernet、2.4/5 GHz Wi-Fi / Wi-Fi Direct | 20 ppm、150 页纸盒、平板扫描;未列 ADF 或自动双面 | 云充按页;耗材由官方供给 | 只有明确接受微信充值、看重三年保修时才选;不是“便宜传统激光机”。 |
|
||||||
|
| **Pantum M6509NW** | USB、100M Ethernet、2.4 GHz 802.11b/g/n Wi-Fi;自带热点 | 22 ppm、150 页进/100 页出、平板扫描;手动双面 | 鼓粉一体 PD-219,官方标称 1,600 页 | **价格明显更低时的可比替代**。接口齐全,支持扫 PC/邮件/FTP/移动端,但机身较宽、仅 2.4 GHz,且鼓粉一体意味着每次换耗材同时更换感光组件。 |
|
||||||
|
| **HP Laser MFP 1188w** | USB、2.4 GHz 802.11b/g/n、Wi-Fi Direct、AirPrint/Mopria/HP 应用;**无 Ethernet** | 22 ppm、150 页进/100 页出、平板扫描;手动双面 | 一体式黑色硒鼓;随机约 1,500 页 | 仅无线且 2.4 GHz 能满足时再比价。优点是 AirPrint/Mopria 明确、首张页快;不符合“网口或双频”优先条件。 |
|
||||||
|
| **Canon iC MF232w** | Ethernet、2.4 GHz Wi-Fi、AirPrint、网络/移动扫描 | 23 ppm、250 页纸盒、平板扫描;无自动双面 | CRG337 一体式硒鼓 2,400 页 | 纸盒需求确实较大才考虑。官方建议价较高,且产品规格呈现的是较老的 IPv4 / 2.4 GHz 组合,不是本需求下的优先解。 |
|
||||||
|
| **Canon iC MF272dw** | Ethernet、2.4 GHz Wi-Fi、AirPrint/Mopria | 29 ppm、150 页纸盒、平板扫描、自动双面打印 | CRG071:700 页随机、1,200/2,500 页商品硒鼓 | 功能不错但属于为自动双面打印升级;官方建议价 ¥3,838,不适合低量、单面为主时以性价比为目标的采购。 |
|
||||||
|
|
||||||
|
Brother 规格与耗材页数以官方参数表为准;Pantum 的接口、PD-219 和建议月印量 250–2,000 页见[官方产品页](https://www.pantum.cn/product-center/1487019260672548865.html)。HP 的 22 ppm、150 页、仅 Wi-Fi/USB、手动双面和一年保修见[中国官方规格](https://support.hp.com/cn-zh/product/product-specs/hp/2101513893)。Canon MF232w 的 23 ppm、250 页、CRG337、IPv4 和接口见[官方规格](https://www.canon.com.cn/product/icmf232w/spec.html);MF272dw 的 29 ppm、自动双面、接口及 CRG071 页数见[官方规格](https://www.canon.com.cn/product/icmf272dw/spec.html)。
|
||||||
|
|
||||||
|
## 耗材与锁定:应怎样理解
|
||||||
|
|
||||||
|
**不要只用“每页成本”决定低量用户。** 一年只打印几十到几百页时,机器差价、过期/存放不当的耗材风险和购买便利性,通常超过高容量粉盒带来的单位页优势。页产量也是 ISO 覆盖率下的额定值,不等于实际能稳定打印的页数。
|
||||||
|
|
||||||
|
- **传统耗材(Brother L1638W/L1848W)**:粉盒和硒鼓分开,硒鼓寿命远高于单盒粉量;这是长期低量使用中最可预测的结构。原装 TN118 / DR118 的料号和页数已由 Brother 公布。第三方粉盒或灌粉可以降低成本,但不属于厂商性能/保修承诺;低量用户省下的钱很有限,反而更容易把故障归因变复杂。建议首个生命周期使用原装或可靠授权渠道耗材。
|
||||||
|
- **云充(DCP-11W)**:这里的锁定不是“第三方粉盒风险”,而是服务依赖:打印资格、套餐和耗材供给都依赖绑定的微信/官方流程。购买前应把预计三年页数代入套餐,确认账号更换、迁移、停服或转让场景的处理规则;并接受双面一张按两页计。
|
||||||
|
- **一体式硒鼓(Pantum、HP、Canon)**:换粉即换鼓,维护动作简单;缺点是无法像鼓粉分离机那样只更换粉盒。不要据此推断“第三方一定不能用”或“必然会被固件锁死”——厂商公开资料通常只承诺原装耗材效果/保修,兼容耗材的芯片兼容性、质量和售后由销售方承担,应按批次验证。
|
||||||
|
|
||||||
|
## 最终推荐与购买动作
|
||||||
|
|
||||||
|
1. **默认买 Brother DCP-L1638W 或 DCP-L1848W**:选到手价更低、可开票、有本地退换/保修的那个;功能层面无需为 1848 付溢价。
|
||||||
|
2. 若二者断货或溢价过大,**Pantum M6509NW** 是功能不降级的对照品;要求 5 GHz Wi-Fi 时排除它。
|
||||||
|
3. 若只用手机/2.4 GHz Wi-Fi,且 HP 的即时价格有明显优势,才纳入 **HP 1188w**;它没有网口,不能接入现有有线网络。
|
||||||
|
4. **不要因为“最新”买 DCP-11W**,除非云充模式本身是主动选择。对低量家庭用户,耗材自主权通常比三年保修更重要。
|
||||||
|
|
||||||
|
到货后先完成一次有线或基础 Wi-Fi 配网、AirPrint/Windows/macOS 实测、扫描为 PDF、睡眠唤醒和一张双面手动测试;保留试机页与发票。将设备放在受信任 LAN;如果启用 Wi-Fi Direct,设置强口令,平时不需要则关闭。
|
||||||
|
|
||||||
|
## 调研边界
|
||||||
|
|
||||||
|
本表只比较中国市场仍可由厂商官方页面/支持页核实的代表 SKU,价格、实际库存和促销会实时变化,未把电商标价写入结论。所谓“最新”以 Brother 中国目录/公告为准,而非“功能最强”或“最适合”。资料核查日期:2026-08-11。
|
||||||
@@ -0,0 +1,158 @@
|
|||||||
|
# 希力威视 SR-S25G3218F 调查(2026-08-08)
|
||||||
|
|
||||||
|
**结论:** 若需求是大量 2.5G 终端、少量 10G 光上联,`SR-S25G3218F` 的端口密度
|
||||||
|
更合适;厂商已公开该型号的固件页,但仍缺少完整规格书、管理手册与兼容矩阵。若需求是 8 条全部可协商
|
||||||
|
1/2.5/5/10G 的铜缆链路,且希望有可查的 L3 能力和固件入口,兮克
|
||||||
|
`SKS8300-8T` 是资料更完整、风险更低的选择;它的代价是主动风扇、外置 12 V 电源、
|
||||||
|
无 SFP+ 光口,且仍不应把消费级/SMB 设备当作安全边界或唯一核心。两者都应在
|
||||||
|
到货可退换期内完成实机验收。
|
||||||
|
|
||||||
|
本页为采购前资料调查,不代表已接入本地网络;检索日期为 2026-08-08。
|
||||||
|
|
||||||
|
## 已能核实的事项
|
||||||
|
|
||||||
|
| 项目 | 结论与证据强度 |
|
||||||
|
|---|---|
|
||||||
|
| 型号/端口 | 京东的希力威视商品标题称该 SKU 为 `SR-S25G3218F`,有 16 个 2.5G 电口和 2 个万兆光口,并宣传 VLAN、端口隔离与 LACP。该店铺被厂商官网列为可购买的「京东旗舰店」,因此可作为销售规格,非技术手册。[京东商品页](https://item.jd.com/100165071727.html);[厂商购买渠道说明](https://en.sirivision.com/contactus/) |
|
||||||
|
| 厂商身份 | 厂商官网为 Shenzhen/Guangdong Sirivision Communication;英文官网说明其自 2016 年起提供接入、汇聚和核心交换机方案。[厂商首页](https://en.sirivision.com/) |
|
||||||
|
| 公开的二手厂家资料 | 同一制造商名义的 Alibaba 出口页将精确型号写成 `16*2.5G+2*10G`、`120Gbps`,并列出 QoS、VLAN、SNMP、L3 与 stackable。这是制造商发布在平台上的销售资料,**不是**官网数据表;其中后五项不能据此视为已验收的功能承诺。[制造商平台页](https://www.alibaba.com/pla/SR-S25G3218F-QoS-Managed-SFP-Switch-1625G210G_1601494946214.html) |
|
||||||
|
| 固件入口 | 厂商已发布此精确型号的[固件页](https://www.sirivision.com/sr-s25g3218f%E5%9B%BA%E4%BB%B6/)。公开变更记录提到“光口自适应”和“增加 DAC 配置”;这证明厂商维护过该路径,**不**代表任意 SFP+/DAC/铜模块均兼容。 |
|
||||||
|
| 本机可计算的带宽 | 端口线速相加为单向 60 Gb/s(16 × 2.5 + 2 × 10);若厂商所谓 `120Gbps` 是全双工交换容量,则数学上吻合。它**不**证明缓冲、PPS、表项规模或实际无阻塞性能。 |
|
||||||
|
|
||||||
|
## 网管/L2/L3 能力边界
|
||||||
|
|
||||||
|
京东标题足以支持把 VLAN、端口隔离、LACP 作为「卖家声称提供」的功能;不得由此推导出
|
||||||
|
ACL、IPv4/IPv6 静态路由、SVI 数量、DHCP relay、OSPF/RIP、VRRP、IGMP、ERPS、
|
||||||
|
802.1X、RADIUS/TACACS+、SSH/HTTPS 管理、SNMP 版本、日志/审计、配置备份或固件
|
||||||
|
安全维护一定存在。
|
||||||
|
|
||||||
|
尤其要注意:厂商官网把真正列出的 2.5G L3 产品标为
|
||||||
|
`SR-S25G3412F (8 × 2.5G + 4 × 10G SFP+)`;其 2.5G 类目只显示 7 个型号,
|
||||||
|
不含 `SR-S25G3218F`。官网也把 L2+、Web Smart、L3 分成不同产品类别。这个目录
|
||||||
|
差异**不是**证明 3218F 没有 L3,而是说明「三层」无法通过官网的精确型号文档确认。
|
||||||
|
[2.5G 产品目录](https://en.sirivision.com/product-category/products/2-5g-switches/);
|
||||||
|
[官网的 10G L3 目录](https://en.sirivision.com/product-category/products/10g-switches/10g-layer3-managed-switches/);
|
||||||
|
[官网的 L2+ 分类示例](https://en.sirivision.com/product-category/products/gigabit-switches/gigabit-layer2-managed-switches/)。
|
||||||
|
|
||||||
|
采购前请向京东/厂商索取**与机身 SKU、硬件 revision 和固件版本对应**的 PDF
|
||||||
|
数据表、管理手册和 release notes,并要求书面回答至少以下问题:
|
||||||
|
|
||||||
|
1. L3 是只有 VLAN Interface/IPv4 静态路由,还是另有 IPv6、ACL、动态路由、DHCP relay
|
||||||
|
等;每项的最大 VLAN、MAC、ARP、路由、ACL、LAG 数量分别是多少?
|
||||||
|
2. LACP 是否符合 802.3ad、一个 LAG 最多多少成员、能否跨两台设备(若销售页的
|
||||||
|
`stackable` 属实,堆叠的线缆/模块、最大成员、控制面和软件版本为何)?
|
||||||
|
3. 管理面是否支持 HTTPS/SSH、禁用 HTTP/Telnet、独立管理 VLAN、SNMPv3、syslog、NTP、
|
||||||
|
配置导出/回滚和已签名或可校验的固件;默认凭据首次登录是否强制修改?
|
||||||
|
|
||||||
|
## 供电、散热和光口:当前不能确认
|
||||||
|
|
||||||
|
针对该精确 SKU,厂商官网目录与公开搜索未找到说明书/数据表,所以以下均为**待确认,
|
||||||
|
不能猜测**:
|
||||||
|
|
||||||
|
- 是否为内置 AC 电源、额定输入范围/最大功耗、是否带电源开关和接地端子;是否完全
|
||||||
|
不提供 PoE(本型号名和京东标题均未写 PoE,但这不足以替代规格书)。
|
||||||
|
- 风扇数量、常态/满载噪声、风向、环境温湿度、机架深度与安装耳;不要将「金属壳」
|
||||||
|
或产品照片等同于无风扇/静音。
|
||||||
|
- 两个槽是否均为 **10G SFP+**,是否可协商 1G SFP;支持的 SR/LR/BiDi 波长距离、
|
||||||
|
DAC/AOC 长度、第三方模块/EERPOM 兼容策略、10GBASE-T SFP+ 模块的功耗/温度限制,
|
||||||
|
以及是否支持 GPON/XPON ONU「猫棒」。
|
||||||
|
|
||||||
|
厂商确实单列「SFP Optical Modules」产品分类,但这不构成 3218F 的兼容清单。
|
||||||
|
[厂商产品导航](https://en.sirivision.com/)。购买光模块/直连线时,应要求厂商按这台
|
||||||
|
设备的硬件/固件 revision 出具兼容型号清单;没有书面清单时,先在可退换期实测两端的
|
||||||
|
链路、重启恢复、热插拔与长时间满载错误计数。
|
||||||
|
|
||||||
|
## 风险与建议验收
|
||||||
|
|
||||||
|
- **文档/生命周期风险(中到高):** 精确型号不在厂商当前官网 2.5G 目录,虽有固件下载页,
|
||||||
|
但未公开完整型号手册、明确 release notes 或兼容矩阵。官网的售后条款也要求按具体产品查询保修期,配件(含光纤头)
|
||||||
|
的保修条款与主机不同;不要把平台页的「3 年」当作中国零售 SKU 的已确认保修。
|
||||||
|
[厂商售后条款](https://en.sirivision.com/after-sale-protection/)
|
||||||
|
- **功能表述风险(高):** 页面将 L2 特性和「三层网管」并列;在命令/网页菜单、
|
||||||
|
手册和测试证明之前,将其当作 L2 VLAN/LACP 设备部署,跨 VLAN 路由仍由现有网关承担。
|
||||||
|
- **双 10G 上联约束(中):** 两个 SFP+ 可作双上联或一个二成员 LAG,但 LAG 增加的是
|
||||||
|
多流量总吞吐,单一 TCP/UDP 流通常仍受一条 10G 链路限制;上级设备也必须匹配 LACP
|
||||||
|
配置。
|
||||||
|
- **管理面风险(中到高):** 家用/低价网管设备常见明文管理、弱默认口令或不透明的固件
|
||||||
|
更新周期;采购后先置于受限管理 VLAN,改口令、升级已验证固件,且不将管理界面暴露
|
||||||
|
到 WAN/访客网。
|
||||||
|
|
||||||
|
最低验收应包括:逐口协商 100M/1G/2.5G、两只不同厂家 SFP+/DAC(仅在卖家承诺支持的
|
||||||
|
范围内)、VLAN trunk/access/PVID、STP/环路保护、LACP 故障切换、端口隔离、满载
|
||||||
|
双向 iperf3 与错误计数、冷启动后的配置保留,以及管理面的 HTTPS/SSH/SNMPv3/配置备份。
|
||||||
|
如无法提供与型号匹配的正式资料或其中任一关键项失败,应在退换期内退货,并选择公开
|
||||||
|
数据表、固件与兼容矩阵更完整的型号。
|
||||||
|
|
||||||
|
## 备选:兮克 SKS8300-8T 对比
|
||||||
|
|
||||||
|
### 已核实的厂商规格
|
||||||
|
|
||||||
|
兮克官网的精确型号页明确将 `SKS8300-8T` 定位为三层管理型 10G 全电口交换机,并列出:
|
||||||
|
|
||||||
|
- 8 × 1/2.5/5/10GBASE-T RJ45;160 Gb/s 交换容量、119.05 Mpps、12 Mbit 缓存、
|
||||||
|
16K MAC、12 KB 巨帧、512 MB DRAM、32 MB Flash,尺寸 207 × 136 × 35 mm;
|
||||||
|
- QoS、ACL、IP+MAC+端口绑定、流分类/优先级标记、多端口镜像、静态/灵活 QinQ、
|
||||||
|
sFlow,以及「基于策略的 IPv4/IPv6 单播路由」。
|
||||||
|
|
||||||
|
这些是厂商能力声明,并非对每一种路由协议或表项上限的承诺;但相对 3218F 的仅有
|
||||||
|
销售标题,它给出了精确型号、转发性能和 L3 范围。[兮克 SKS8300-8T
|
||||||
|
产品页](https://seekswan.com/user/custom-pages/SKS8300-8T.html)
|
||||||
|
|
||||||
|
独立的 OpenWrt 设备资料将其识别为 Realtek RTL9303、512 MB RAM,记录了原厂固件
|
||||||
|
下载入口和串口/TFTP 恢复路径;其硬件数据页列为 12 V / 4 A。这支持「可恢复、可替换
|
||||||
|
系统」的可操作性,但**不是**兮克对原厂功能的支持承诺。
|
||||||
|
[OpenWrt 设备页](https://openwrt.org/toh/xikestor/sks8300-8t);
|
||||||
|
[OpenWrt 硬件数据](https://openwrt.org/toh/hwdata/xikestor/xikestor_sks8300-8t)。
|
||||||
|
|
||||||
|
### 能力、物理与运维比较
|
||||||
|
|
||||||
|
| 维度 | 希力威视 SR-S25G3218F | 兮克 SKS8300-8T |
|
||||||
|
|---|---|---|
|
||||||
|
| 接口/典型用途 | 16 × 2.5G 电口 + 2 × 10G SFP+(销售规格);适合很多 2.5G 终端/NAS,以 10G 光或 DAC 上联。 | 8 × 1/2.5/5/10GBASE-T;适合 10G 铜缆设备、2.5/5G 多速率 NAS/主机。没有 SFP+,光纤上联必须经媒体转换或选另一型号。 |
|
||||||
|
| 可确认的三层范围 | 仅销售/平台资料称 L3;没有精确型号官方手册,不能确认静态路由以外的功能。 | 官网明确写策略型 IPv4/IPv6 单播路由、ACL/QoS/sFlow/QinQ;动态路由、VRRP、IPv6 ACL/SNMP/认证等仍须按当前固件手册确认。 |
|
||||||
|
| 冗余/二层 | 卖家声称 VLAN、端口隔离、LACP;STP/环网的实现与规格未知。 | 官网声明 L3 和多项转发特性,但未在产品页给出 STP/LACP/ERPS 的精确限制;购买前仍索取手册。 |
|
||||||
|
| 散热/噪声 | 无可核实的精确型号风扇、噪声、功耗或风向数据。 | 独立手册镜像和产品图均称智能温控风扇,但厂商产品页未给 dBA;应按「有风扇、可能听得见」规划,不能承诺静音。 |
|
||||||
|
| 供电 | 未找到精确型号官方输入/功耗资料。 | OpenWrt 硬件数据记录 12 V / 4 A;确认随附电源适配器的插头、余量和地区认证。官方产品页未给满载功耗。 |
|
||||||
|
| 固件/恢复 | 有精确型号官方固件页;公开记录包含光口自适应与 DAC 配置改动,但未找到完整 release notes、恢复步骤或兼容矩阵。 | 厂商产品页提供「相关下载」区,OpenWrt 还记录原厂固件入口、RJ45 串口和 U-Boot/TFTP 恢复;原厂镜像是否签名、漏洞修复 SLA、配置回退仍未知。 |
|
||||||
|
|
||||||
|
关于 8T 的风扇、满载功耗(常见转述为 ≤36 W)、温度范围、芯片型号等,本次未找到
|
||||||
|
相应的**厂商原始数据表**;不将第三方手册转录当作已核实规格。若噪声、UPS 容量或
|
||||||
|
机柜散热是购买约束,请先让卖家提供产品铭牌照片、适配器铭牌照片、额定/实测功耗和
|
||||||
|
dBA 测试条件。
|
||||||
|
|
||||||
|
### 选择与验收建议
|
||||||
|
|
||||||
|
- 选 **3218F**:必须有 ≥12 个 2.5G 接入端、10G 光/DAC 上联、且 L3 留给现有路由器。
|
||||||
|
下单前先取得精确型号手册和 SFP+/DAC 兼容承诺;否则端口数量优势不足以抵消资料风险。
|
||||||
|
- 选 **8T**:最多 8 个设备但需要多速率 10G RJ45、明确的 IPv4/IPv6 静态/策略路由和
|
||||||
|
以后自行维护/恢复的余地。不要把其 160 Gb/s 标称交换容量误解为 8 端口同时 10G
|
||||||
|
全双工的性能保证——该标称与端口总线速数学相等,但仍须以实测和厂商 PPS/缓冲说明为准。
|
||||||
|
- 两台都不应单独承担防火墙、访客/IoT 安全隔离或 WAN 暴露;VLAN 的跨网段策略和公网
|
||||||
|
边界留在受支持的网关/防火墙上。先为管理面创建专用 VLAN,仅从管理主机访问,禁用
|
||||||
|
未使用的远程管理协议,备份配置和原厂固件后再接入生产网络。
|
||||||
|
|
||||||
|
## 低功耗核心备选(8 × 2.5G + 2 × SFP+)
|
||||||
|
|
||||||
|
如果核心只需接最多 8 台铜缆终端、上联/连接 NAS 使用 DAC 或光纤 10G,优先考虑没有
|
||||||
|
PoE 的以下两款。它们都满足 VLAN trunk、LACP 和至少两个 10G SFP+ 的需求;不要为
|
||||||
|
AP 选 PoE 版来承担核心,因为 PoE 预算、风扇和待机损耗都会明显增加。
|
||||||
|
|
||||||
|
| 型号 | 端口与管理能力(厂商声明) | 厂商功耗 / 噪声资料 | 对当前 LAN 的判断 |
|
||||||
|
|---|---|---|---|
|
||||||
|
| **TP-Link Omada SG3210X-M2** | 8 × 100M/1G/2.5G RJ45、2 × 10G SFP+,并有 RJ45 和 Micro-USB console。厂商规格列出 802.1Q VLAN、STP/RSTP/MSTP、静态 LAG 和 802.3ad LACP(最多 8 个聚合组、每组最多 8 端口);L3 是 32 个 IPv4/IPv6 接口、48 条静态路由。 | **无风扇**;100–240 V AC 内置电源。`UN 1.20` 数据表:待机最高 **6.0 W**(220 V/50 Hz、25 °C),最高 **15.3 W**(220 V)或 **15.0 W**(110 V)。 | **首选低功耗方案。** 足以做 LAN66 核心、给 PVE/gfw 与 U6 Lite 做 VLAN 10 trunk,并以 SFP+ DAC/光口连接 10G NAS/主机;它不提供 5G/10G RJ45,10G 铜缆需外置转换或 SFP+ 10GBASE-T 模块。 |
|
||||||
|
| **MikroTik CRS310-8G+2S+IN** | 8 × 2.5G RJ45、2 × 10G SFP+;SFP+ 笼支持 1G/2.5G/10G。RouterOS v7(也可选 SwOS)支持 VLAN、链路聚合与 ACL。 | 18–57 V DC 外置供电;官方给出“无附件”最高 **21 W**、总体最高 **34 W**,且机内 **1 个风扇**。厂商没有在该页给出 dBA。 | 可用且软件/文档/恢复路径成熟,但不是本题的静音低功耗优先项:官方最大功耗显著高于 TP-Link,且有风扇。适合明确偏好 RouterOS/SwOS 与其可维护性时选。 |
|
||||||
|
|
||||||
|
功耗数字是各厂商的**上限/待机测试条件**,不是你实际墙插读数;SFP+ 光模块、DAC/AOC,尤其
|
||||||
|
10GBASE-T SFP+ 模块,会另增功耗和热量。对于本网络,用被动 DAC 或短距光模块连接 10G
|
||||||
|
设备,通常比全 RJ45 10G 核心更容易保持低温、低噪。
|
||||||
|
|
||||||
|
`SG3210X-M2` 的上表数据对应 TP-Link 的 `UN 1.20` 数据表;不同地区/硬件版本的包装、
|
||||||
|
认证和功耗标注可能不同,购买中国零售版本前应让卖家确认**准确硬件版本、保修渠道和固件地区**。
|
||||||
|
本次未找到 TP-Link 中国官网的该精确型号页,因此不能把海外官方页面当作大陆现货/售后承诺。
|
||||||
|
MikroTik 同样应通过其官方零售商查询渠道确认本地库存和保修。两台购买前还应确认所选
|
||||||
|
SFP+/DAC 的兼容清单。
|
||||||
|
|
||||||
|
来源:[TP-Link 产品规格](https://www.tp-link.com/uk/business-networking/omada-switch-access-pro/sg3210x-m2/);
|
||||||
|
[TP-Link `UN 1.20` 数据表](https://static.tp-link.com/upload/product-overview/2025/202512/20251224/SG3210X-M2%28UN%29%201.20_datasheet.pdf);
|
||||||
|
[MikroTik 产品页](https://mikrotik.com/product/crs310_8g_2s_in);
|
||||||
|
[MikroTik 用户手册](https://help.mikrotik.com/docs/spaces/UM/pages/214630429/CRS310-8G%2B2S%2BIN)。
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
# API keys
|
||||||
|
## pi
|
||||||
|
```
|
||||||
|
sk-WxUkJJ8kRv4hLDUV3utBws8NJZ3GyN1bed1VNs0WwWSJ671n
|
||||||
|
```
|
||||||
@@ -21,3 +21,8 @@ hermes :
|
|||||||
```
|
```
|
||||||
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
|
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
|
||||||
```
|
```
|
||||||
|
|
||||||
|
pi:
|
||||||
|
```
|
||||||
|
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
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user