用 dnsmasq 快速搭建本地 DNS Server
什么是 DNS Server
简单的说,DNS Sever 就是把域名转换为 IP 地址的一个服务。如 Google 提供了 8.8.8.8
为什么需要搭建本地的 DNS Server?
最常见的两种情况是:
- 你有一些虚拟主机,本次都通过 IP 地址去访问的太麻烦,因为 IP 地址很不容易记。
- 本地开发时,不想每次都用 http://127.0.0.1:3000, http://127.0.0.1:3001 这种来访问,而是想用 http://app1.dev
这两种情况都需要把虚拟的域名转换为对应的 IP, 最简单的方式是直接修改 /etc/hosts
, 还有一种方式就是搭建一个本地的 DNS Server
安装前
/本文所有操作都是在 macOS 下完成,其他 *nix 操作系统会稍有区别/
首先查看一下当前配置了哪些的 DNS resolver
scutil --dns
可以看到类似这样的输出
DNS configuration
resolver #1
nameserver[0] : 192.168.31.1
if_index : 4 (en0)
flags : Request A records
reach : Reachable, Directly Reachable Address
后面还有 resolver #2
resolver #3
等
另外先了解一下 dig
命令, dig
是用来查询 DNS 的一个工具。
dig www.google.com
输出
; <<>> DiG 9.8.3-P1 <<>> www.google.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 11696
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;www.google.com. IN A
;; ANSWER SECTION:
www.google.com. 30 IN A 93.46.8.89
;; Query time: 7 msec
;; SERVER: 192.168.31.1#53(192.168.31.1)
;; WHEN: Wed Apr 5 22:23:18 2017
;; MSG SIZE rcvd: 48
这里可以看到,域名 www.google.com
在我的电脑中解析出来 IP 地址是 93.46.8.9
安装 dnsmasq
brew install dnsmasq
然后 copy 一下配置文件
cp /usr/local/opt/dnsmasq/dnsmasq.conf.example /usr/local/etc/dnsmasq.conf
配置文件所有的配置都是已经注释掉的,可根据自己的需要取消注释并修改。dnsmasq 同时还提供了如 DHCP 的其他功能,这里我们只关注 DNS Server 这一块。
先在文件最底部增加一行
address=/dev/127.0.0.1
重启dnsmasq
sudo brew services restart dnsmasq
然后通过 dig
命令来检查是否生效
dig abc.dev @127.0.0.1
这里的 @127.0.0.1
用来告诉 dig
去 127.0.0.1 这个 dns server 来查询
输出结里(隐藏了头尾)
;; QUESTION SECTION:
;abc.dev. IN A
;; ANSWER SECTION:
abc.dev. 0 IN A 127.0.0.1
此时已经可以看到,域名abc.dev
的 IP 地址已经被解析为 127.0.0.1
但时我们用 ping
命令来测试,是不正确的。这里ping
和没用指定 @127.0.0.1
的dig
是一样的,默认都是使用 /etc/resolv.conf
指定的 nameserver
来查询的。
给 macOS 增加更多的nameserver
新建一个 /etc/resolver
目录,然后新建一个 /etc/resolver/dev
文件,然后增加新的 nameserver
sudo mkdir -p /etc/resolver
echo 'nameserver 127.0.0.1' | sudo tee /etc/resolver/dev
然后每次系统做 DNS 查询时,发现是以 dev 结尾的域名时,就会使用 /etc/resolver/dev
这个文件里指定的 nameserver 来解析。同样的,我们也可以创建一个 /etc/resolver/staging
,然后让所有的以 staging 为结尾的域名都用该文件指定的 nameserver 来解析。
再次执行
scutil --dns
会发现输出多了一个 resolver
resolver #8
domain : dev
nameserver[0] : 127.0.0.1
flags : Request A records, Request AAAA records
reach : Reachable, Local Address, Directly Reachable Address
我们可以用 traceroute
命令来查看解析的路径
traceroute abc.dev
输出为
traceroute to abc.dev (127.0.0.1), 64 hops max, 52 byte packets
1 localhost (127.0.0.1) 0.196 ms 0.034 ms 0.034 ms
这里可以看到,只有一跳就完成了解析。
至此,一个本地的 DNS server 就搭建完成了
More
- 可在 dnsmasq 的配置文件中增加一行
conf-dir=/usr/local/etc/dnsmasq.d/,*.conf
然后按需在相应的目录创建 dev.conf
, staing.conf
等文件。注意每次修改完配置文件要重启 dnsmasq
-
address=/dev/127.0.0.1
是一种通配方式,把所有的以 dev 结尾的域名都解析为 127.0.0.1。
也可以为每个域名都指定一个独立的 IP ,如在/usr/local/etc/dnsmasq.d/staging.conf
里,我们可以指定各种 staging 相关的 服务
address=/db.staging/192.168.1.10
address=/app.staging/192.168.1.11
address=/job.staging/192.168.1.12
注意增加新的域名后缀要在 /etc/resolver/
下创建相应的文件并增加 nameserver
-
dnsmasq
默认监听的端口为 53, 所有启动该服务需要用sudo