Skip to content

Commit

Permalink
feat: Multi-Geolocations DNS (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
sjzar authored Dec 1, 2023
1 parent e6b2afe commit 140bedf
Show file tree
Hide file tree
Showing 14 changed files with 792 additions and 617 deletions.
82 changes: 82 additions & 0 deletions cmd/ips/cmd_mdns.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Copyright (c) 2023 [email protected]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package ips

import (
"fmt"

"github.com/spf13/cobra"
)

func init() {
rootCmd.AddCommand(mdnsCmd)

// mdns
mdnsCmd.Flags().StringVarP(&dnsClientNet, "net", "", "udp", "Specifies the network protocol to be used by the DNS client. tcp, udp, tcp-tls.")
mdnsCmd.Flags().IntVarP(&dnsClientTimeoutMs, "client-timeout", "", 1000, "Defines the timeout in milliseconds for DNS client requests.")
mdnsCmd.Flags().BoolVarP(&dnsClientSingleInflight, "single-inflight", "", false, "Indicates whether the DNS client should avoid making duplicate queries concurrently.")
mdnsCmd.Flags().IntVarP(&mdnsTimeoutS, "timeout", "", 20, "Specifies the timeout in seconds for MDNS operations.")
mdnsCmd.Flags().StringVarP(&mdnsExchangeAddress, "exchange-address", "", "119.29.29.29", "Defines the address of the DNS server to be used for MDNS queries.")
mdnsCmd.Flags().IntVarP(&mdnsRetryTimes, "retry-times", "", 3, "Sets the number of times an MDNS query should be retried on failure.")

// operate
mdnsCmd.Flags().StringVarP(&fields, "fields", "f", "", UsageFields)
mdnsCmd.Flags().BoolVarP(&useDBFields, "use-db-fields", "", false, UsageUseDBFields)
mdnsCmd.Flags().StringVarP(&rewriteFiles, "rewrite-files", "r", "", UsageRewriteFiles)
mdnsCmd.Flags().StringVarP(&lang, "lang", "", "", UsageLang)

// database
mdnsCmd.Flags().StringSliceVarP(&rootFile, "file", "i", nil, UsageQueryFile)
mdnsCmd.Flags().StringSliceVarP(&rootFormat, "format", "", nil, UsageQueryFormat)
mdnsCmd.Flags().StringSliceVarP(&rootIPv4File, "ipv4-file", "", nil, UsageQueryIPv4File)
mdnsCmd.Flags().StringSliceVarP(&rootIPv4Format, "ipv4-format", "", nil, UsageQueryIPv4Format)
mdnsCmd.Flags().StringSliceVarP(&rootIPv6File, "ipv6-file", "", nil, UsageQueryIPv6File)
mdnsCmd.Flags().StringSliceVarP(&rootIPv6Format, "ipv6-format", "", nil, UsageQueryIPv6Format)
mdnsCmd.Flags().StringVarP(&readerOption, "database-option", "", "", UsageReaderOption)
mdnsCmd.Flags().StringVarP(&hybridMode, "hybrid-mode", "", "aggregation", UsageHybridMode)

// output
mdnsCmd.Flags().StringVarP(&rootTextValuesSep, "text-values-sep", "", "", UsageTextValuesSep)
}

var mdnsCmd = &cobra.Command{
Use: "mdns <domain>",
Short: "Execute Multi-Geolocation DNS queries.",
Long: `The 'ips mdns' command is designed to query domain name resolutions across multiple regions.
Utilizing EDNS capabilities, this command sends the client's IP address to the DNS server, which then returns the domain name resolution results for the corresponding region.
The command provides a global perspective on domain name resolutions, enabling users to quickly identify any anomalies in DNS resolutions.
For more detailed information and advanced configuration options, please refer to https://github.com/sjzar/ips/blob/main/docs/mdns.md`,
PreRun: PreRunInit,
Run: MDNS,
}

func MDNS(cmd *cobra.Command, args []string) {

if len(args) == 0 {
_ = cmd.Help()
return
}

ret, err := manager.MDNSResolve(args[0])
if err != nil {
return
}
fmt.Println(ret)
}
45 changes: 45 additions & 0 deletions cmd/ips/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,27 @@ var (

// addr specifies the server address.
addr string

// mdns

// dnsClientNet specifies the network protocol to be used by the DNS client. tcp, udp, tcp-tls.
dnsClientNet string

// dnsClientTimeoutMs defines the timeout in milliseconds for DNS client requests.
dnsClientTimeoutMs int

// dnsClientSingleInflight indicates whether the DNS client should avoid making duplicate
// queries concurrently.
dnsClientSingleInflight bool

// mdnsTimeoutS specifies the timeout in seconds for MDNS operations.
mdnsTimeoutS int

// mdnsExchangeAddress defines the address of the DNS server to be used for MDNS queries.
mdnsExchangeAddress string

// mdnsRetryTimes sets the number of times an MDNS query should be retried on failure.
mdnsRetryTimes int
)

// GetFlagConfig initializes and returns the configuration for the IP service.
Expand Down Expand Up @@ -260,6 +281,30 @@ func GetFlagConfig() *ips.Config {
conf.MyIPTimeoutS = myIPTimeoutS
}

if len(dnsClientNet) > 0 {
conf.DNSClientNet = dnsClientNet
}

if dnsClientTimeoutMs > 0 {
conf.DNSClientTimeoutMs = dnsClientTimeoutMs
}

if dnsClientSingleInflight {
conf.DNSClientSingleInflight = dnsClientSingleInflight
}

if mdnsTimeoutS > 0 {
conf.MDNSTimeoutS = mdnsTimeoutS
}

if len(mdnsExchangeAddress) > 0 {
conf.MDNSExchangeAddress = mdnsExchangeAddress
}

if mdnsRetryTimes > 0 {
conf.MDNSRetryTimes = mdnsRetryTimes
}

return conf
}

Expand Down
65 changes: 65 additions & 0 deletions docs/mdns.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# IPS 多地域域名解析命令说明

## 简介

`ips mdns` 命令旨在查询多地域的域名解析结果。

该命令利用了 EDNS 功能,向 DNS 服务器发送客户端 IP 地址,以获取相应地域的域名解析结果。

命令提供了域名解析的全球视角,能够帮助用户快速识别 DNS 解析中的异常情况。

## 使用方法

通过 `ips mdns` 命令,用户可以指定域名和 DNS 服务器地址进行查询。结果将以表格形式显示,清晰地展示不同地理位置的解析结果。

## 命令语法

```shell
ips mdns <domain> [flags]
```

- `--net string`: 指定 DNS 请求的网络类型,可选值为 `tcp``udp``tcp-tls`,默认为 `udp`
- `--client-timeout int`: 指定每个 DNS 请求客户端超时时间,单位为毫秒,默认为 1000 毫秒。
- `--single-inflight`: 指定是否合并并发的 DNS 请求,默认为 `false`
- `--timeout int`: 指定 MDNS 命令的总超时时间,单位为秒,默认为 20 秒。
- `--exchange-address string`: 指定 DNS 服务器地址,默认为 `119.29.29.29`
- `--retry-times`: 指定 DNS 请求的重试次数,默认为 3 次。

## 示例

### 查询域名的多地域解析结果

```shell
ips mdns i0.hdslb.com
+--------------------+-------------------------------------------------+-------------------------------------------------+
| GEOISP | CNAME | IP |
+--------------------+-------------------------------------------------+-------------------------------------------------+
| 27.224.0.0 | i0.hdslb.com.04f6a54d.c.cdnhwc1.com [华为] | 60.165.116.47 [中国 甘肃 兰州 电信] |
| [中国 甘肃 电信] | hcdnw.biliv6.c.cdnhwc2.com [华为] | 60.165.116.48 [中国 甘肃 兰州 电信] |
+--------------------+-------------------------------------------------+-------------------------------------------------+
| 36.133.72.0 | i0.hdslb.com.w.kunlunno.com [阿里] | 221.181.64.184 [中国 上海 上海 移动] |
| [中国 上海 移动] | | 221.181.64.148 [中国 上海 上海 移动] |
+--------------------+-------------------------------------------------+-------------------------------------------------+
| 36.133.108.0 | i0.hdslb.com.04f6a54d.c.cdnhwc1.com [华为] | 39.136.138.59 [中国 重庆 重庆 移动] |
| [中国 重庆 移动] | hcdnw.biliv6.d.cdn.chinamobile.com [移动] | 39.136.138.58 [中国 重庆 重庆 移动] |
+--------------------+-------------------------------------------------+-------------------------------------------------+
| 1.56.0.0 | i0.hdslb.com.04f6a54d.c.cdnhwc1.com [华为] | 218.10.185.43 [中国 黑龙江 鹤岗 联通] |
| [中国 黑龙江 联通] | hcdnw.biliv6.c.cdnhwc2.com [华为] | 218.60.101.84 [中国 辽宁 大连 联通] |
+--------------------+-------------------------------------------------+-------------------------------------------------+
| 42.202.0.0 | i0.hdslb.com.download.ks-cdn.com [金山] | 123.184.57.130 [中国 辽宁 沈阳 电信] |
| [中国 辽宁 电信] | k1-ipv6.gslb.ksyuncdn.com [金山] | 123.184.57.129 [中国 辽宁 沈阳 电信] |
+--------------------+-------------------------------------------------+-------------------------------------------------+
| TOTAL | 11 | 730 |
+--------------------+-------------------------------------------------+-------------------------------------------------+
<省略部分输出>
```

### 使用自定义 DNS 服务器

```shell
ips mdns i0.hdslb.com --exchange-address 8.8.8.8
```

## 注意事项

- 如果不同地理位置的解析结果相同,建议检查本地 DNS 劫持问题,例如防火墙在端口 53 上的流量重定向。
65 changes: 65 additions & 0 deletions docs/mdns_en.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# IPS MDNS Command Documentation

## Introduction

The `ips mdns` command is designed to query domain name resolutions across multiple regions.

Utilizing EDNS capabilities, this command sends the client's IP address to the DNS server, which then returns the domain name resolution results for the corresponding region.

The command provides a global perspective on domain name resolutions, enabling users to quickly identify any anomalies in DNS resolutions.

## Usage

Using the `ips mdns` command, users can specify a domain and a DNS server address for querying. The results are displayed in a table format, clearly showing the resolution results from different geographical locations.

## Command Syntax

```shell
ips mdns <domain> [flags]
```

- `--net string`: Specifies the network type for DNS requests, options include `tcp`, `udp`, and `tcp-tls`, with the default being `udp`.
- `--client-timeout int`: Sets the client-side timeout for each DNS request in milliseconds, defaulting to 1000 milliseconds.
- `--single-inflight`: Specifies whether to merge concurrent DNS requests, defaulting to `false`.
- `--timeout int`: Sets the overall timeout for the MDNS command in seconds, with a default of 20 seconds.
- `--exchange-address string`: Specifies the DNS server address, defaulting to `119.29.29.29`.
- `--retry-times`: Determines the number of retry attempts for DNS requests, defaulting to 3 times.

## Examples

### Querying Multi-Region Domain Name Resolutions

```shell
ips mdns i0.hdslb.com
+--------------------+-------------------------------------------------+-------------------------------------------------+
| GEOISP | CNAME | IP |
+--------------------+-------------------------------------------------+-------------------------------------------------+
| 27.224.0.0 | i0.hdslb.com.04f6a54d.c.cdnhwc1.com [华为] | 60.165.116.47 [中国 甘肃 兰州 电信] |
| [中国 甘肃 电信] | hcdnw.biliv6.c.cdnhwc2.com [华为] | 60.165.116.48 [中国 甘肃 兰州 电信] |
+--------------------+-------------------------------------------------+-------------------------------------------------+
| 36.133.72.0 | i0.hdslb.com.w.kunlunno.com [阿里] | 221.181.64.184 [中国 上海 上海 移动] |
| [中国 上海 移动] | | 221.181.64.148 [中国 上海 上海 移动] |
+--------------------+-------------------------------------------------+-------------------------------------------------+
| 36.133.108.0 | i0.hdslb.com.04f6a54d.c.cdnhwc1.com [华为] | 39.136.138.59 [中国 重庆 重庆 移动] |
| [中国 重庆 移动] | hcdnw.biliv6.d.cdn.chinamobile.com [移动] | 39.136.138.58 [中国 重庆 重庆 移动] |
+--------------------+-------------------------------------------------+-------------------------------------------------+
| 1.56.0.0 | i0.hdslb.com.04f6a54d.c.cdnhwc1.com [华为] | 218.10.185.43 [中国 黑龙江 鹤岗 联通] |
| [中国 黑龙江 联通] | hcdnw.biliv6.c.cdnhwc2.com [华为] | 218.60.101.84 [中国 辽宁 大连 联通] |
+--------------------+-------------------------------------------------+-------------------------------------------------+
| 42.202.0.0 | i0.hdslb.com.download.ks-cdn.com [金山] | 123.184.57.130 [中国 辽宁 沈阳 电信] |
| [中国 辽宁 电信] | k1-ipv6.gslb.ksyuncdn.com [金山] | 123.184.57.129 [中国 辽宁 沈阳 电信] |
+--------------------+-------------------------------------------------+-------------------------------------------------+
| TOTAL | 11 | 730 |
+--------------------+-------------------------------------------------+-------------------------------------------------+
<omitted part of the output>
```

### Using a Custom DNS Server

```shell
ips mdns i0.hdslb.com --exchange-address 8.8.8.8
```

## Important Notes

- If the resolution results are identical across different geographical locations, it is advised to check for local DNS hijacking issues, such as firewalls redirecting traffic on port 53.
1 change: 1 addition & 0 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
- [IPS 转存命令说明](./dump.md) - 转存 IP 地理位置数据库。
- [IPS 打包命令说明](./pack.md) - 打包 IP 地理位置数据库。
- [IPS 查询命令说明](./query.md) - 查询 IP 地理位置。
- [IPS 多地域域名解析命令说明](./mdns.md) - 查询多地域域名解析结果。
- [IPS 服务命令说明](./server.md) - 启动 IPS 服务。

## 支持的数据库格式
Expand Down
1 change: 1 addition & 0 deletions docs/usage_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Welcome to IPS! This is a command-line tool and library designed to help you eas
- [IPS Dump Command Documentation](./dump_en.md) - Dump IP geolocation databases.
- [IPS Pack Command Documentation](./pack_en.md) - Package IP geolocation databases.
- [IPS Command Documentation](./query_en.md) - Query IP geolocation information.
- [IPS MDNS Command Documentation](./mdns_en.md) - Query Multi-Geolocations DNS resolution results.
- [IPS Server Command Documentation](./server_en.md) - Start the IPS service.

## Supported Database Formats
Expand Down
52 changes: 51 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
module github.com/sjzar/ips

go 1.16
go 1.18

require (
github.com/dilfish/awdb-golang/awdb-golang v1.0.20210701
github.com/gin-gonic/gin v1.9.1
github.com/maxmind/mmdbwriter v1.0.0
github.com/miekg/dns v1.1.41
github.com/olekukonko/tablewriter v0.0.5
github.com/oschwald/maxminddb-golang v1.12.0
github.com/pion/stun/v2 v2.0.0
github.com/schollz/progressbar/v3 v3.13.1
Expand All @@ -17,3 +18,52 @@ require (
golang.org/x/net v0.14.0
golang.org/x/text v0.12.0
)

require (
github.com/bytedance/sonic v1.9.1 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.14.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.0.1 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/magiconair/properties v1.8.6 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/pion/dtls/v2 v2.2.7 // indirect
github.com/pion/logging v0.2.2 // indirect
github.com/pion/transport/v2 v2.2.1 // indirect
github.com/pion/transport/v3 v3.0.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/spf13/afero v1.9.2 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.4.1 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
go4.org/netipx v0.0.0-20220812043211-3cc044ffd68d // indirect
golang.org/x/arch v0.3.0 // indirect
golang.org/x/crypto v0.12.0 // indirect
golang.org/x/sys v0.11.0 // indirect
golang.org/x/term v0.11.0 // indirect
google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading

0 comments on commit 140bedf

Please sign in to comment.