feat(dns_query): add expected IP validation and metrics for domain hijacking detection#1475
Merged
Merged
Conversation
…jacking detection
Contributor
There was a problem hiding this comment.
Pull request overview
This PR enhances the dns_query input to support “expected IP” validation for DNS answers (aimed at detecting domain hijacking / unexpected resolution changes) and updates the accompanying docs/config/dashboard artifacts.
Changes:
- Add
expect_query_ipsconfiguration and emitdns_query_status_change/dns_query_status_change_detailmetrics. - Add an
ipstag (comma-separated resolved IPs) to the maindns_querymetrics. - Update README/README_CN, example TOML config, and dashboard to surface the new behavior.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| inputs/dns_query/dns_query.go | Implements expected-IP comparison, new metrics, and adds ips tag to samples. |
| inputs/dns_query/README.md | Documents the new config knob and metrics. |
| inputs/dns_query/README_CN.md | Chinese documentation for the new config knob and metrics. |
| conf/input.dns_query/dns_query.toml | Adds commented example and explanation for expect_query_ips. |
| inputs/dns_query/dashboard.json | Updates dashboard to visualize new metrics (and restructures dashboard format). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+183
to
+203
| if v, ok := ins.ExpectQueryIps[domain]; ok && v != nil { | ||
| sort.Slice(ips, func(i, j int) bool { | ||
| ip1 := net.ParseIP(ips[i]) | ||
| ip2 := net.ParseIP(ips[j]) | ||
| return bytes.Compare(ip1, ip2) < 0 | ||
| }) | ||
| minus, _ := diff(v, ips) | ||
| status := 0 | ||
| if len(minus) > 0 { | ||
| status = 1 | ||
|
|
||
| diffTags := make(map[string]string) | ||
| for k, v := range tags { | ||
| diffTags[k] = v | ||
| } | ||
| diffTags["diff"] = strings.Join(minus, ",") | ||
| diffTags["ips"] = strings.Join(ips, ",") | ||
| slist.PushSample(inputName, "status_change_detail", status, diffTags) | ||
| } | ||
| slist.PushSample(inputName, "status_change", status, tags) | ||
| } |
Comment on lines
+214
to
+216
| if len(ips) > 0 { | ||
| tags["ips"] = strings.Join(ips, ",") | ||
| } |
Comment on lines
+45
to
+46
| - `dns_query_status_change`: When `expect_query_ips` is configured, this value is 1 if any expected IP is missing from the result, otherwise 0. | ||
| - `dns_query_status_change_detail`: Reported only when there is a diff (value is 1). Includes a `diff` tag for missing IPs, and an `ips` tag for all returned IPs. |
Comment on lines
+45
to
+46
| - `dns_query_status_change`: 当配置了预期 IP 校验时,如果实际查询到的 IP 中缺失了预期 IP,则该值为 1,否则为 0。 | ||
| - `dns_query_status_change_detail`: 当开启 IP 校验且存在差异时才会上报此指标(值为 1)。带有 `diff` 标签记录缺失的 IP 列表,`ips` 标签记录所有实际返回的 IP 列表。 |
| # timeout = 2 | ||
|
|
||
| ## 监控域名劫持 | ||
| ## record_type必须为A/AAA, expect_query_ips中必须包含对应的域名和IP列表(ip列表越全越好) |
Comment on lines
1
to
+12
| { | ||
| "title": "DNS Query Quality", | ||
| "uid": "82f9567e", | ||
| "tags": [ | ||
| "dns query quality" | ||
| "version": "3.0.0", | ||
| "var": [ | ||
| { | ||
| "name": "datasource", | ||
| "type": "datasource", | ||
| "definition": "prometheus", | ||
| "defaultValue": 1, | ||
| "label": "Datasource", | ||
| "hide": false | ||
| }, | ||
| { |
Comment on lines
+164
to
+184
| if v, ok := ins.ExpectQueryIps[domain]; ok && v != nil { | ||
| sort.Slice(ips, func(i, j int) bool { | ||
| ip1 := net.ParseIP(ips[i]) | ||
| ip2 := net.ParseIP(ips[j]) | ||
| return bytes.Compare(ip1, ip2) < 0 | ||
| }) | ||
| minus, _ := diff(v, ips) | ||
| status := 0 | ||
| if len(minus) > 0 { | ||
| status = 1 | ||
|
|
||
| diffTags := make(map[string]string) | ||
| for k, v := range tags { | ||
| diffTags[k] = v | ||
| } | ||
| diffTags["diff"] = strings.Join(minus, ",") | ||
| diffTags["ips"] = strings.Join(ips, ",") | ||
| slist.PushSample(inputName, "status_change_detail", status, diffTags) | ||
| } | ||
| slist.PushSample(inputName, "status_change", status, tags) | ||
| } |
Comment on lines
+195
to
+197
| if len(ips) > 0 { | ||
| tags["ips"] = strings.Join(ips, ",") | ||
| } |
| # timeout = 2 | ||
|
|
||
| ## 监控域名劫持 | ||
| ## record_type必须为A/AAA, expect_query_ips中必须包含对应的域名和IP列表(ip列表越全越好) |
| ## record_type必须为A/AAA, expect_query_ips中必须包含对应的域名和IP列表(ip列表越全越好) | ||
| ## 对比响应中的IP与如下配置的IP,会生成两个新的指标 dns_query_status_change 与 dns_query_status_change_detail | ||
| ## 当diff 不为空的时候 dns_query_status_change 为1 , diff 为空的时候 dns_query_status_change=0 | ||
| ## dns_query_status_change_detail{ips="响应的IP列表", diff="响应IP列表-期望IP列表"} |
Comment on lines
1
to
+12
| { | ||
| "title": "DNS Query Quality", | ||
| "uid": "82f9567e", | ||
| "tags": [ | ||
| "dns query quality" | ||
| "version": "3.0.0", | ||
| "var": [ | ||
| { | ||
| "name": "datasource", | ||
| "type": "datasource", | ||
| "definition": "prometheus", | ||
| "defaultValue": 1, | ||
| "label": "Datasource", | ||
| "hide": false | ||
| }, | ||
| { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ExpectQueryIpsconfiguration to specify expected IPs for target domains.status_changeandstatus_change_detailmetrics upon mismatch.ipstag containing all returned IPs to the basedns_querymetrics.dns_query.toml.