说明
view 定义一个表达式,该表达式在 DNS 请求路由到服务器块时必须计算结果为 true。这便能实现高级服务器块路由功能,例如分离 DNS。
语法
view NAME {
expr EXPRESSION
}
view
NAME - 度量使用并作为元数据导出的视图名称(符合视图的表达式的请求)expr
EXPRESSION - 如果 EXPRESSION 计算结果为 true,CoreDNS 才会将传入查询路由到封闭的服务器块。有关可用变量和函数,请参阅 Expressions 部分。如果定义多个 view 实例,所有 EXPRESSION 都必须计算结果为 true,CoreDNS 才会将传入查询路由到封闭的服务器块。
有关表达式语法和示例,请参阅表达式和示例部分。
示例
实施基于 CIDR 的分离 DNS 路由。这样,会根据客户端的 IP 地址为 test.
返回不同的答案。会返回 …
test. 3600 IN A 1.1.1.1
,针对源地址在 127.0.0.0/24 中的查询test. 3600 IN A 2.2.2.2
,针对源地址在 192.168.0.0/16 中的查询test. 3600 IN A 3.3.3.3
,针对所有其他情况
. {
view example1 {
expr incidr(client_ip(), '127.0.0.0/24')
}
hosts {
1.1.1.1 test
}
}
. {
view example2 {
expr incidr(client_ip(), '192.168.0.0/16')
}
hosts {
2.2.2.2 test
}
}
. {
hosts {
3.3.3.3 test
}
}
将所有 A
和 AAAA
请求发送到 10.0.0.6
,并将所有其他请求发送到 10.0.0.1
。
. {
view example {
expr type() in ['A', 'AAAA']
}
forward . 10.0.0.6
}
. {
forward . 10.0.0.1
}
将针对 abc.*.example.com
的所有请求(其中 * 可以是任意数量的标签)发送到 10.0.0.2
,并将所有其他请求发送到 10.0.0.1
。请注意,正则表达式模式用单引号引起来,并且反斜杠用反斜杠转义。
. {
view example {
expr name() matches '^abc\\..*\\.example\\.com\\.$'
}
forward . 10.0.0.2
}
. {
forward . 10.0.0.1
}
表达式
为了计算表达式,view 使用 antonmedv/expr 包 (https://github.com/antonmedv/expr)。例如,表达式可以看起来像:(type() == 'A' && name() == 'example.com') || client_ip() == '1.2.3.4'
。
所有表达式都应编写为计算结果为布尔值。
有关有效语法的详细参考,请参阅 https://github.com/antonmedv/expr/blob/master/docs/Language-Definition.md。
可用的表达式函数
在 view 插件的上下文中,表达式可以通过使用下面定义的实用程序函数来引用 DNS 查询信息。
DNS 查询函数
bufsize() int
:查询中宣传的 EDNS0 缓冲区大小class() string
:请求的类(IN、CH、…)client_ip() string
:客户端的 IP 地址(对于 IPv6 地址,它们用方括号括起来:[::1]
)do() bool
:在查询中设置的 EDNS0 DO(DNSSEC OK)位id() int
:查询 IDname() string
:请求的名称(请求的域名)opcode() int
:查询 OPCODEport() string
:客户端端口proto() string
:用于的协议(tcp 或 udp)server_ip() string
:服务器的 IP 地址;对于 IPv6 地址,它们被括在方括号中:[::1]
server_port() string
:服务器的端口size() int
:以字节为单位的请求大小type() string
:请求的类型(A、AAAA、TXT、…)
实用程序函数
incidr(ip string, cidr string) bool
:如果ip 在cidr 中,则返回 truemetadata(label string)
- 返回匹配标签 的元数据的值
元数据
如果元数据插件也已启用,则视图插件将发布以下元数据
view/name
:处理当前请求的视图的名称