1
0

feat: DNS checker,自研 codec/transport,支持 system/server 双模式,UDP/TCP + TC fallback

This commit is contained in:
2026-05-24 17:06:22 +08:00
parent 4f33fba793
commit 483cdc596b
21 changed files with 5686 additions and 16 deletions

127
README.md
View File

@@ -10,11 +10,11 @@
---
DiAL 是一个自托管的拨测监控工具,支持 **HTTP**、**命令行**、**数据库**、**TCP**、**UDP**、**ICMP** 和 **LLM** 多种拨测类型。通过 YAML 配置文件定义拨测目标,后端定时并发执行拨测并将结果持久化到本地 SQLite前端 Dashboard 展示各目标的实时状态、可用率和耗时趋势。
DiAL 是一个自托管的拨测监控工具,支持 **HTTP**、**命令行**、**数据库**、**TCP**、**UDP**、**DNS**、**ICMP** 和 **LLM** 多种拨测类型。通过 YAML 配置文件定义拨测目标,后端定时并发执行拨测并将结果持久化到本地 SQLite前端 Dashboard 展示各目标的实时状态、可用率和耗时趋势。
**功能亮点:**
- 多种拨测类型HTTPGET/POST/PUT 等、Cmd命令行执行、DBPostgreSQL/MySQL/SQLite、TCP端口可达性 + Banner 探测、UDP自定义 payload 请求-响应、ICMP存活检测、延迟、丢包率、LLM大模型服务应用层健康检查
- 多种拨测类型HTTPGET/POST/PUT 等、Cmd命令行执行、DBPostgreSQL/MySQL/SQLite、TCP端口可达性 + Banner 探测、UDP自定义 payload 请求-响应)、DNS本机解析检查 + DNS server 深度拨测)、ICMP存活检测、延迟、丢包率、LLM大模型服务应用层健康检查
- 丰富的校验规则状态码、响应头、JSONPath、CSS 选择器、XPath、正则匹配、数值比较等
- 结构化观测数据:检查结果保留按需读取的 HTTP body 预览、TCP/UDP 响应摘要、ICMP 丢包率、CMD 输出预览、LLM token 用量等 observation便于排障和后续分析
- 响应式 Dashboard实时状态、可用率统计、动态粒度趋势图avg/P95 + 状态条)、手动/自动刷新、版本号展示
@@ -269,7 +269,7 @@ targets: # 拨测目标列表(必填)
| `id` | 目标唯一标识,最长 30 字符,支持字母数字、下划线、连字符,不参与变量替换 | 是 | |
| `name` | 展示名称,最长 30 字符,支持变量替换,可省略或显式 null前端展示时 null 回退到 `id` | 否 | |
| `description` | 目标描述,最长 500 字符,支持变量替换,可省略或显式 null允许空字符串 | 否 | |
| `type` | 目标类型:`http``cmd``db``tcp``udp``icmp``llm` | 是 | |
| `type` | 目标类型:`http``cmd``db``tcp``udp``dns``icmp``llm` | 是 | |
| `group` | 分组名称 | 否 | `default` |
| `interval` | 拨测间隔,未配置时使用内置默认值 `30s` | 否 | `30s` |
| `timeout` | 超时时间,未配置时使用内置默认值 `10s` | 否 | `10s` |
@@ -523,6 +523,127 @@ ICMP checker 通过系统 `ping` 命令执行 ICMP 探测,支持 Linux、macOS
---
### DNS Checker`type: dns`
DNS Checker 支持两种解析模式,通过 `dns.resolver` 字段区分:
- **`system` 模式**:使用本机 DNS 解析器检查域名是否能解析到预期地址,输出有限 observation。
- **`server` 模式**:直接向指定 DNS server 发起 UDP/TCP 深度拨测,检查 DNS 协议级响应RCODE、TTL、flags、记录值等
#### `dns.resolver: system` 配置项
| 字段 | 说明 | 必填 | 默认值 |
| -------------- | ---------- | ---- | -------- |
| `dns.resolver` | 解析模式 | 是 | `system` |
| `dns.name` | 待解析域名 | 是 | |
| `dns.family` | 地址族 | 否 | `any` |
`family` 可选值:`any`(返回 IPv4 和 IPv6`ipv4`(仅 IPv4`ipv6`(仅 IPv6
**system 模式 expect 校验项**
| 字段 | 说明 | 断言模型 |
| ------------ | -------------------- | --------------------------------- |
| `values` | 解析结果地址集合断言 | DNS 集合include/exclude/exact |
| `valueCount` | 解析结果数量 | ValueMatcher |
| `durationMs` | 解析耗时 | ValueMatcher |
**示例**
```yaml
- id: "dns-system-api"
name: "本机 DNS 解析"
type: dns
dns:
resolver: system
name: "api.example.com"
family: any
expect:
values:
exact:
- "203.0.113.10"
durationMs:
lte: 500
```
#### `dns.resolver: server` 配置项
| 字段 | 说明 | 必填 | 默认值 |
| ---------------------- | --------------------------------- | ---- | -------- |
| `dns.resolver` | 解析模式 | 是 | `server` |
| `dns.server` | DNS server 地址 | 是 | |
| `dns.name` | 查询域名 | 是 | |
| `dns.port` | DNS server 端口 | 否 | `53` |
| `dns.protocol` | 传输协议:`udp` / `tcp` | 否 | `udp` |
| `dns.recordType` | DNS 记录类型 | 否 | `A` |
| `dns.recursionDesired` | 是否设置 RD flag | 否 | `true` |
| `dns.tcpFallback` | UDP 响应 TC=1 时是否 TCP fallback | 否 | `true` |
| `dns.maxResponseBytes` | 响应最大字节数 | 否 | `4KB` |
`recordType` 可选值:`A``AAAA``CNAME``NS``MX``TXT``SOA``SRV``CAA``PTR`
**server 模式 expect 校验项**
| 字段 | 说明 | 断言模型 |
| -------------------- | ---------------------------------- | --------------------------------- |
| `responded` | 是否收到 DNS response | boolean |
| `rcode` | 期望 RCODE 列表(如 `NOERROR` | string[] |
| `values` | 目标类型记录值集合断言 | DNS 集合include/exclude/exact |
| `valueCount` | 目标类型记录数量 | ValueMatcher |
| `answerCount` | answer section 总记录数 | ValueMatcher |
| `ttlMin` | answer 中最小 TTL | ValueMatcher |
| `ttlMax` | answer 中最大 TTL | ValueMatcher |
| `authoritative` | AA flag | boolean |
| `recursionAvailable` | RA flag | boolean |
| `truncated` | TC flag | boolean |
| `authenticatedData` | AD flag | boolean |
| `result` | 完整结构化响应的 JSONPath 兜底断言 | ContentExpectations |
| `durationMs` | 完整查询耗时 | ValueMatcher |
**示例**
```yaml
- id: "dns-server-api"
name: "Cloudflare DNS A 记录"
type: dns
dns:
resolver: server
server: "1.1.1.1"
port: 53
protocol: udp
name: "api.example.com"
recordType: A
expect:
rcode: ["NOERROR"]
values:
include:
- "203.0.113.10"
ttlMin:
gte: 60
durationMs:
lte: 200
- id: "dns-nxdomain-check"
name: "负向 DNS 检查"
type: dns
dns:
resolver: server
server: "1.1.1.1"
name: "nxdomain.example.com"
recordType: A
expect:
rcode: ["NXDOMAIN"]
```
**Notes**
- 未配置 expect 时,`system` 模式默认要求解析成功且 `valueCount > 0``server` 模式默认要求 `NOERROR + valueCount > 0`
- 显式配置非 `NOERROR` rcode`NXDOMAIN`)时,不自动要求 `valueCount > 0`
- `values.exact` 忽略返回顺序(集合匹配);对 A/AAAA 查询CNAME 链不计入 `values`,单独放入 `cnameChain`
- `values` 按记录类型规范化为字符串格式MX=`"10 mail.example.com"`、SOA=空格分隔字段、SRV=`"10 60 443 server.example.com"`、CAA=`"0 issue letsencrypt.org"` 等。
---
### LLM Checker`type: llm`
**配置项**