解放你的 hosts 文件!从零开始内网搭建 DNS 服务器 CoreDNS 实战

本文结合实际场景,从零开始搭建内网 CoreDNS 服务器并完成配置
内网中物理机、虚拟机等设备较多,配置 hosts 文件太麻烦,因此想到利用一台设备搭建 DNS 服务器以解救 hosts 文件
由于之前没有搭建 DNS 服务器的经验,在 GitHub 上搜了一下后,选择了 CoreDNS

内网搭建 DNS 服务器

  • 前言
  • clone 源码,编译,测试
    • clone & make
      • 本地 Golang 环境直接编译
      • 基于 Docker Golang 编译
    • 测试
  • 域名解析配置
    • coredns 基本参数
    • 创建配置文件
      • hello, world 配置
      • 按照需求进行配置
      • 启动 coredns 并验证配置
        • 验证内网域名解析
        • 验证其他域名解析
      • 修改路由器 DNS 配置或部署到公网
  • 将 CoreDNS 作为服务 Service 运行

前言

以前内网都是通过 hosts 管理内网的域名解析,如果设备少还好说,设备多了后,逐个设备维护 hosts 文件非常不现实。
如果能够在内网搭建 DNS 服务器,并调整路由器的 DNS 实现内网域名解析,就能够省去 hosts 配置的时间。

本文实践环境网络拓扑图:
解放你的 hosts 文件!从零开始内网搭建 DNS 服务器 CoreDNS 实战_第1张图片

clone 源码,编译,测试

clone & make

本地 Golang 环境直接编译

CoreDNS 使用 Golang 开发,因此编译需要 Golang 环境。
clone 源码并编译

git clone https://github.com/coredns/coredns
cd coredns
make

如果网络环境访问 GitHub 有困难,可以使用 Gitee 提供的镜像源 coredns:

git clone https://gitee.com/mirrors/coredns.git
cd coredns
make

基于 Docker Golang 编译

同样,先 clone 项目到本地

git clone https://github.com/coredns/coredns
cd coredns

如果本地没有 Golang 环境,也可以直接用 Docker 拉一个 Golang 镜像编译,以下为官方文档给出的命令

docker run --rm -i -t -v $PWD:/v -w /v golang:1.12 make

考虑到网络环境的问题,国内用户建议指定环境变量 GOPROXY

docker run --rm -i -t -e GOPROXY="https://goproxy.cn" -v $PWD:/v -w /v golang:1.12 make

测试

编译完成后,项目目录下多了一个 40MB 的二进制可执行文件 coredns

pi@rpi4:~/CoreDNS$ ls -lh
total 40M
-rw-r--r--  1 pi sudo 3.6K Mar  9 00:39 ADOPTERS.md
lrwxrwxrwx  1 pi sudo   26 Mar  9 00:39 CODE_OF_CONDUCT.md -> .github/CODE_OF_CONDUCT.md
-rw-r--r--  1 pi sudo 2.4K Mar  9 00:39 CODEOWNERS
lrwxrwxrwx  1 pi sudo   23 Mar  9 00:39 CONTRIBUTING.md -> .github/CONTRIBUTING.md
drwxr-xr-x  4 pi sudo 4.0K Mar  9 00:39 core

-rwxr-xr-x  1 pi sudo  40M Mar 10 20:56 coredns

-rw-r--r--  1 pi sudo 1.4K Mar  9 00:39 coredns.1.md
-rw-r--r--  1 pi sudo  246 Mar  9 00:39 coredns.go
-rw-r--r--  1 pi sudo 3.3K Mar  9 00:39 corefile.5.md
drwxr-xr-x  2 pi sudo 4.0K Mar  9 00:39 coremain
-rw-r--r--  1 pi sudo 2.4K Mar  9 00:39 directives_generate.go
-rw-r--r--  1 pi sudo  254 Mar  9 00:39 Dockerfile
-rw-r--r--  1 pi sudo 2.2K Mar  9 00:39 go.mod
-rw-r--r--  1 pi sudo  62K Mar  9 00:39 go.sum
-rw-r--r--  1 pi sudo 6.6K Mar  9 00:39 GOVERNANCE.md
-rw-r--r--  1 pi sudo  12K Mar  9 00:39 LICENSE
-rw-r--r--  1 pi sudo 1.9K Mar  9 00:39 Makefile
-rw-r--r--  1 pi sudo 1.6K Mar  9 00:39 Makefile.doc
-rw-r--r--  1 pi sudo 1.7K Mar  9 00:39 Makefile.fuzz
-rw-r--r--  1 pi sudo 7.0K Mar  9 00:39 Makefile.release
drwxr-xr-x  2 pi sudo 4.0K Mar 10 20:16 man
drwxr-xr-x  2 pi sudo 4.0K Mar  9 00:39 notes
-rw-r--r--  1 pi sudo 1.7K Mar  9 00:39 owners_generate.go
drwxr-xr-x  2 pi sudo 4.0K Mar  9 00:39 pb
drwxr-xr-x 49 pi sudo 4.0K Mar  9 00:39 plugin
-rw-r--r--  1 pi sudo 1.3K Mar  9 00:39 plugin.cfg
-rw-r--r--  1 pi sudo 5.7K Mar  9 00:39 plugin.md
-rw-r--r--  1 pi sudo 8.4K Mar  9 00:39 README.md
drwxr-xr-x  2 pi sudo 4.0K Mar  9 00:39 request
lrwxrwxrwx  1 pi sudo   19 Mar  9 00:39 SECURITY.md -> .github/SECURITY.md
drwxr-xr-x  2 pi sudo 4.0K Mar  9 00:39 test

运行 coredns 并监听 1053 端口,此时由于没有配置文件,只能验证 DNS 服务器是否工作

./coredns -dns.port 1053

使用 dig 命令验证 DNS 服务器运行状况

dig @localhost -p 1053 a whiami.expamle.org

输出结果:

; <<>> DiG 9.11.5-P4-5.1-Debian <<>> @localhost -p 1053 a whiami.expamle.org
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 20349
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 3
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: c1c711345e8fb2e2 (echoed)
;; QUESTION SECTION:
;whiami.expamle.org.            IN      A

;; ADDITIONAL SECTION:
whiami.expamle.org.     0       IN      AAAA    ::1
_udp.whiami.expamle.org. 0      IN      SRV     0 0 13225 .

;; Query time: 0 msec
;; SERVER: ::1#1053(::1)
;; WHEN: Tue Mar 10 21:01:06 CST 2020
;; MSG SIZE  rcvd: 147

没有解析结果,但是 DNS 服务器已经在工作了,接下来就需要配置域名解析。

域名解析配置

coredns 基本参数

pi@rpi4:~/CoreDNS$ ./coredns -h
Usage of ./coredns:
  -conf string
        Corefile to load (default "Corefile")
  -dns.port string
        Default port (default "53")
  -pidfile string
        Path to write pid file
  -plugins
        List installed plugins
  -quiet
        Quiet mode (no initialization output)
  -version
        Show version
参数 解释
-conf 指定配置文件(默认为当前目录的 Corefile
-dns.port 指定 DNS 服务监听端口
-pidfile 指定 pid 文件的存放路径
-plugins 列出已安装的插件
-quiet 不打印日志
-version 显示版本信息

创建配置文件

hello, world 配置

在 coredns 所在目录下,新建文件 Corefile,并写入以下内容:

.:1053 {
    forward . 8.8.8.8:53
    log
}

上面配置为监听 1053 端口,将所有域名解析请求转发到 8.8.8.8:53,保存后运行 coredns 并 dig 一下:

dig @localhost -p 1053 a www.baidu.com

输出结果:

; <<>> DiG 9.11.5-P4-5.1-Debian <<>> @localhost -p 1053 a www.baidu.com
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 25306
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.baidu.com.                 IN      A

;; ANSWER SECTION:
www.baidu.com.          259     IN      CNAME   www.a.shifen.com.
www.a.shifen.com.       237     IN      CNAME   www.wshifen.com.
www.wshifen.com.        157     IN      A       104.193.88.123
www.wshifen.com.        157     IN      A       104.193.88.77

;; Query time: 19 msec
;; SERVER: ::1#1053(::1)
;; WHEN: Tue Mar 10 22:20:20 CST 2020
;; MSG SIZE  rcvd: 192

可以看到,域名解析成功了。

按照需求进行配置

网络拓扑图如下:
解放你的 hosts 文件!从零开始内网搭建 DNS 服务器 CoreDNS 实战_第2张图片
DNS 服务器将运行在 rpi4 / rpi4-wifi 上面,并给局域网中的每个 IP 配一个域名。

由于内网环境比较简单,不需要复杂的配置,所以选择使用 CoreDNS 的 hosts 插件,文档参考:hosts 插件官方文档

创建一个 hosts 风格的文件 /etc/coredns/hosts,并按照拓扑图配置,内网域名为 lo

192.168.3.254   rpi4.lo
192.168.99.254  rpi4-wifi.lo
192.168.3.253   rpi3.lo
192.168.99.253  rpi3-wifi.lo
192.168.3.252   mix2.lo
192.168.3.233   sia.lo
192.168.3.200   hyper-sia.lo
192.168.3.201   hyper-tesla.lo
192.168.3.99    ws5200.lo
192.168.3.1     pro2.lo

创建一个 Corefile /etc/coredns/Corefile
配置解释:

  • 将所有 lo 域名根据同一目录下的 hosts 文件解析
  • 所有其他的域名转发到 DNS 服务器 202.96.128.86:53
lo:53 {
    hosts /etc/coredns/hosts
    log
}

.:53 {
    forward . 202.96.128.86:53
    log
}

配置完成后启动 coredns,由于使用 53 端口,需要 root 权限:

sudo coredns -conf /etc/coredns/Corefile

启动 coredns 并验证配置

验证内网域名解析

使用 dig 验证解析域名 sia.lo

dig @localhost a sia.lo

解析结果:

; <<>> DiG 9.11.5-P4-5.1-Debian <<>> @localhost sia.lo
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 50021
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 2acae2295223fd2b (echoed)
;; QUESTION SECTION:
;sia.lo.                                IN      A

;; ANSWER SECTION:
sia.lo.                 3600    IN      A       192.168.3.233

;; Query time: 0 msec
;; SERVER: ::1#53(::1)
;; WHEN: Wed Mar 11 00:06:05 CST 2020
;; MSG SIZE  rcvd: 69

可以看到,内网域名 sia.lo 已被成功解析到 192.168.3.233

验证其他域名解析

使用 dig 验证解析域名 github.com

dig @localhost github.com

解析结果:

; <<>> DiG 9.11.5-P4-5.1-Debian <<>> @localhost github.com
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1439
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 8, ADDITIONAL: 12

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 36e32dedc12b437a (echoed)
;; QUESTION SECTION:
;github.com.                    IN      A

;; ANSWER SECTION:
github.com.             600     IN      A       13.250.177.223

;; AUTHORITY SECTION:
github.com.             333     IN      NS      ns-1283.awsdns-32.org.
github.com.             333     IN      NS      ns-421.awsdns-52.com.
github.com.             333     IN      NS      ns-520.awsdns-01.net.
github.com.             333     IN      NS      ns-1707.awsdns-21.co.uk.
github.com.             333     IN      NS      ns4.p16.dynect.net.
github.com.             333     IN      NS      ns2.p16.dynect.net.
github.com.             333     IN      NS      ns1.p16.dynect.net.
github.com.             333     IN      NS      ns3.p16.dynect.net.

;; ADDITIONAL SECTION:
ns-1283.awsdns-32.org.  172465  IN      A       205.251.197.3
ns-1707.awsdns-21.co.uk. 122490 IN      A       205.251.198.171
ns-421.awsdns-52.com.   50849   IN      A       205.251.193.165
ns-520.awsdns-01.net.   36645   IN      A       205.251.194.8
ns1.p16.dynect.net.     80219   IN      A       208.78.70.16
ns3.p16.dynect.net.     40730   IN      A       208.78.71.16
ns4.p16.dynect.net.     77364   IN      A       204.13.251.16
ns-1283.awsdns-32.org.  172314  IN      AAAA    2600:9000:5305:300::1
ns-1707.awsdns-21.co.uk. 122491 IN      AAAA    2600:9000:5306:ab00::1
ns-421.awsdns-52.com.   61826   IN      AAAA    2600:9000:5301:a500::1
ns-520.awsdns-01.net.   35373   IN      AAAA    2600:9000:5302:800::1

;; Query time: 5 msec
;; SERVER: ::1#53(::1)
;; WHEN: Wed Mar 11 00:09:40 CST 2020
;; MSG SIZE  rcvd: 871

根据输出可见,非本地域名能够正常解析。
至此,coredns 配置完成。

修改路由器 DNS 配置或部署到公网

coredns 配置完毕后,需要将路由器 DNS 服务器指向配置好的 coredns。

但是一般家用路由器可能无法设置 IP 地址为内网的 DNS,因此我选择部署到自己的云服务器上,作为个人 DNS 服务器。

将 CoreDNS 作为服务 Service 运行

把 CoreDNS 作为 Service 运行,有助于我们管理进程。

以 Debian 系统为例,其他系统的 Service 可能有差异。

创建文件 /lib/systemd/system/coredns.service,本人目前对 Service 不太熟悉,因此配置从简:

[Unit]
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/coredns -conf /etc/coredns/Corefile -pidfile /var/run/coredns/coredns.pid

[Install]
Alias=coredns.service

启动服务并查看运行状况:

sudo systemctl start coredns
sudo systemctl status coredns

服务运行状况:

● coredns.service
   Loaded: loaded (/lib/systemd/system/coredns.service; linked; vendor preset: enabled)
   Active: active (running) since Wed 2020-03-11 00:44:45 CST; 3s ago
 Main PID: 10987 (coredns)
    Tasks: 11 (limit: 4546)
   Memory: 5.0M
   CGroup: /system.slice/coredns.service
           └─10987 /usr/local/bin/coredns -conf /etc/coredns/Corefile -pidfile /var/run/coredns/coredns.pid

Mar 11 00:44:45 rpi4 systemd[1]: Started coredns.service.
Mar 11 00:44:45 rpi4 coredns[10987]: .:53
Mar 11 00:44:45 rpi4 coredns[10987]: lo.:53
Mar 11 00:44:45 rpi4 coredns[10987]: CoreDNS-1.6.7
Mar 11 00:44:45 rpi4 coredns[10987]: linux/arm64, go1.13.5, a64f0c75

设置自动启动:

sudo systemctl enable coredns

CoreDNS 服务配置完成。

你可能感兴趣的:(实践)