写作时间:20230526
环境:centos-7.9.2009 coredns-1.10.1
DNS的视图功能可实现不同的客户端(不同的IP),同样的域名,可得到不同的解析值。
coredns实现此功能是通过自带的view插件来实现的。
在官方文档https://coredns.io/plugins/view/中查看了view的配置,如下
. {
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
}
}
问题点:官方文档中的例子中每个view只有一个网段,我想要实现多个网段在一个view中。
解决思路:找incidr函数的具体用法
1.clone源码
#小编的具体命令如下,可根据不同的版本修改对应的tag
git clone -b v1.10.1 https://github.com/coredns/coredns.git
2.在coredns的源码目录,执行grep -nr incidr
找到函数在如下文件中
coredns\plugin\pkg\expression\expression.go
省略...
// DefaultEnv returns the default set of custom state variables and functions available to for use in expression evaluation.
func DefaultEnv(ctx context.Context, state *request.Request) map[string]interface{} {
return map[string]interface{}{
"incidr": func(ipStr, cidrStr string) (bool, error) {
省略
3.分析函数
“incidr”: func(ipStr, cidrStr string) (bool, error) {
从这行源码中我们看到incidr的输入只有2个字符串,一个是客户端IP,一个的要匹配的网段。所以想在一个incidr函数中匹配多个网段是不可行的。
4.找到解决办法
但是incidr函数的返回值是布尔值,于是找到思路了。如果一个视图有多个网段,可执行多个incidr函数,在函数间做或运算。尝试后果然成功。
配置效果如下:
. {
view example1 {
#多个网段就用如下这种方法来配置
expr incidr(client_ip(), '127.0.0.0/24') || incidr(client_ip(), '192.168.0.0/24')
}
hosts {
1.1.1.1 test
}
}