(原) 个人DNS: coredns

原创文章,请后转载,并注明出处。

基于之前在思考“解决越来越难申请好域名的问题”,对DNS相关进行更多的了解了测试。

在Ubuntu20中,系统有带DNS服务,也不知道它是做啥用的,暂且不表

sudo lsof -i :53

COMMAND     PID            USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
systemd-r 16944 systemd-resolve   12u  IPv4 254690      0t0  UDP localhost:domain 
systemd-r 16944 systemd-resolve   13u  IPv4 254691      0t0  TCP localhost:domain (LISTEN)

将它暂时停掉: sudo service systemd-resolved stop

或者禁止: sudo systemctl disable systemd-resolved.service

注意,若本机有dns请求,它会自己重启运选择。

或者象网友提到的编辑 /etc/systemd/resolved. conf 。我并没有试,暂时还没计划长期使用。

[Resolve]

DNS=192.168.1.254 # <-- change to your router address

#FallbackDNS=8.8.8.8 8.8.4.4 2001:4860:4860::8888 2001:4860:4860::8844

Domains=lan # <-- change to your localdomain name (maybe .local)

#LLMNR=yes <-- I dabbled with this for a while but it doesn't matter

#DNSSEC=no

#Cache=yes

#DNSStubListener=udp

ln -sf /var/run/resolved/resovl.conf /etc/resolv.conf


测试一下coredns,一个用go的开源软件。Github文档在这里

下载压缩包或git后,进入目录make即可生成可执行程序,它自己会下载依赖,还是很简单的。

直接运行,所有网页都不能访问了(DNS均解析错误)

针对我需要指向本地服务器,配置还是比较简单

.:53 {
    bind 0.0.0.0

    hosts {
        192.168.100.4 pi.me
        ttl 60
        reload 1m      # 重载hosts配置
        fallthrough    # 继续执行
    }


    forward . /etc/resolv.conf   # 最后所有的都转发到系统配置的上游dns服务器去解析
    cache 120                   # 缓存时间ttl
    reload 6s                 # 自动加载配置文件的间隔时间
    log
    errors                    # 输出错误
}

./coredns -conf ./config 带上配置文件,访问pi.me是直接跳向192.168.100.4的。

dig pi.me 可以查看到它已指向

修改一下配置文件,让它可以转发给相关dns服务器,避免上列中只能解析指定域名的问题。其实只需要改torward

.:53 {
    bind 0.0.0.0

    hosts {
        192.168.100.4 pi.me
        192.168.100.4 m.cn
        ttl 60
        reload 1m
        fallthrough
    }

    forward . 61.139.2.69  #没有配置的转到其它DNS
    cache 120
    reload 6s
    log
    errors
}

这样它就能够正确解析所有域名了。

为了方便定义和修改自己的域名,应该让它自动读取域名配置文件

看起来hosts是一个插件,它会先读取本的/etc/hosts.

如何编写一个 CoreDNS 插件

CoreDNS 系列:插件开发入门篇


插件编写:

  1. 在 coredns/plugin 目录下创建自己的插件 package

  2. 在插件 package 下,创建 setup.go 在其中的 init 方法中,做插件配置工作(init 调用 setup 方法)

  3. setup 方法中做3个事情:参数解析、实例化插件实体、将插件实体注册到CoreDNS中。

  4. 实现插件实现:实现 ServeDNS 和 Name 方法。

  5. 更改 plugin.cfg 文件添加你的插件,执行 go generate coredns.go 生成代码,最后执行 go build (或者 make)构建。

每次都需要构建的方法比较麻烦,特别是对于编写/调试阶段。


hosts插件:

hosts [FILE [ZONES...]] {
    [INLINE]
    fallthrough [ZONES...]
}

FILE:需要读取与解析的hosts文件;如果省略,默认取值"/etc/hosts";每5s扫描一次hosts文件的变更。

ZONES:如果为空,取配置块中的zone。

INLINE:宿主机hosts文件在corefile中的内联;在"fallthrough"之前的所有"INLINE"都可视为hosts文件的附加内容,hosts文件中相同条目将被覆盖,以"INLINE"为准。

fallthrough:如果zone匹配且无法生成记录,将请求传递给下一个插件;如果省略,对所有zones有效,如果列出特定zone,则只有列出的zone受到影响。

.:53 {
    errors
    health
    ready
    kubernetes cluster.local. in-addr.arpa ip6.arpa {
        pods insecure
        fallthrough in-addr.arpa ip6.arpa
    }
    hosts {
        192.168.1.122     sample1.xx.com
        192.168.1.123     sample2.xx.com
        fallthrough
    }
    prometheus :9153
    forward . /etc/resolv.conf
    cache 30
    loop
    reload
    loadbalance
}

devops-dns-server是一款简单易用的dns服务器,支持从外部数据源获取数据(比如从CMDB中获取数据,只要API返回固定格式的数据)、支持读取某个文件(必须是/etc/hosts文件一样的格式), 从而可以使解析主机名为IP.

也可以转发DNS请求到指定的DNS服务器, 可以作为内网DNS服务器。

看起来比较简单