关键字:dnsmasq dns 局域网IP private ip ERR_NAME_NOT_RESOLVED rebind_protection
约定:后续我用example.com
这个域名作为演示,大家自行替换为自己的域名
背景
今天内网服务无法通过域名访问,但是通过nslookup
发现如果指定服务器dnspod则正常,只要dns服务器是openwrt的dnsmasq则会提示找不到记录,但实际上dnsmasq的上游就是dnspod(119.29.29.29)!
最主要的是昨天明明还好好的,今天怎么不行了这个是题外话后面再说,一如既往,先看解决方案。
解决方案
在Openwrt中找到 设置 -> 网络 -> DHCP/DNS -> 常规设置
找到【重绑定保护】和下面的【域名白名单】
这里有提供3种解决方案:
- 最直接的直接关闭【重绑定保护】,这样Dnsmasq就不会过滤局域网IP了
- 使用【域名白名单】,比如你只想你自己的域名可以返回局域网IP,非白名单里的域名如果返回了局域网IP还是会被过滤掉
- 使用内置的Dnsmasq管理局域网IP的域名,方法是使用【主机名映射】或者【CNAME】,这里你也可以绑定域名和IP,相当于一个简易的DNS控制台,缺点是其他电脑手机的DNS服务器必须要指定为openwrt的IP,不过一般这个操作是Openwrt的在DHCP中自动完成的。
如果你不是使用的openwrt而是直接在Linux下使用的Dnsmasq的话你可以在Dnsmasq的配置文件直接配置,
- 方案1对应选项为
stop-dns-debind
- 方案2对应的选项为
rebind-domain-ok=/qb.example.com/其他域名白名单1/其他域名白名单2/
,多个域名时使用/
分隔 - 方案3对应的配置为
address=/你的域名/你的IP
a. 单个域名配置时直接写全,如:qb.example.com=192.168.1.1
写为address=/qb.example.com/192.168.1.1
b. 泛域名配置时去除保留开头的.
,如:*.example.com=192.168.1.1
写为address=/.example.com/192.168.1.1
c. CNAME的话可以用cname=bt.example.com,qb.example.com
,这表示bt.example.com
是qb.example.com
的别名,访问bt.example.com
就相当于访问qb.example.com
。注意这里address
配置不同,没有使用/
做分隔而是用了英文的逗号做分隔
经过(可以不看)
我在自己的Homelab上搭建了几个内网服务,比如qBittorrent (qb.example.com
),并且配置好了DNS,使用Chrome访问时一直报 ERR_NAME_NOT_RESOLVED
这个错误,很明显时一个DNS问题,通过 nslookup
开始了排查
> nslookup qb.example.com
服务器: openwrt.lan
Address: 192.168.2.1
*** 没有 qb.example.com 可以使用的 internal type for both IPv4 and IPv6 Addresses (A+AAAA)记录
> nslookup baidu.com
服务器: openwrt.lan
Address: 192.168.2.1
非权威应答:
名称: baidu.com
Addresses: 110.242.68.66
39.156.66.10
> nslookup qb.example.com 119.29.29.29
服务器: pdns.dnspod.cn
Address: 119.29.29.29
非权威应答:
名称: qb.example.com
Address: 192.168.1.250
从上面可以看到我在DNS控制台上的配置是生效了的,通过公共DNS服务商 DNSPOD 可以正常解析该域名,那为什么通过dnsmasq就不行呢,我开始怀疑是不是Dnsmasq把局域网IP给过滤了,首先 baidu 能返回结果说明dnsmasq工作正常,而我自己的qb.example.com又是一个局域网IP,通过在网上一通搜索发现还真是,上面已经给出解决办法了,这里我就不赘述了,那在背景那部分说的昨晚还正常是怎么一回事儿呢,我们接着往下看。
我的网络架构以及DNS配置如下图所示
问题的原因就是远端DNS的CNAME配置问题,在 openwrt 中通过DHCP 或 静态地址分配 下发的IP默认都会创建一条DNS映射记录,比如我的手机(名字是s23) 的IP是 192.168.2.88,那么我们可以直接通过 s23代替 192.168.2.88
> nslookup s23
服务器: openwrt.lan
Address: 192.168.2.1
名称: s23.lan
Address: 192.168.2.88
由于我的Homelab在网络中是和Openwrt同级的,所有Homelab的IP并不是受Openwrt的管理,自然也就不会自动创建DNS映射记录,所有为了方便我在Openwrt中创建了一个 pve=192.168.1.250
的DNS记录。
最开始的配置可行就是因为我当时在远端的DNS配置的CNAME记录是qb.example.com=pve,当时我没有意识到cname是需要写全名的,所以当请求 qb.example.com
时返回的 CNAME记录是 pve
然后再查 pve
时命中了我在 Openwrt 中创建的 pve=192.168.1.250 所以正常工作起来了。
那我又是怎么发现我在DNS配置有问题的呢?
由于配置的pve=192.168.1.250
这条记录是在Openwrt上的,所以当我在 PVE 上想通过 curl 访问 qb.example.com
时发现DNS解析不出来,我才意识到我在远端的DNS上配置的CNAME记录配错了,所以我直接修改完在 PVE上发现解析正常、访问正常就下线睡觉了,直到今早发现PC上发现 qb.example.com
报错了才有了这篇文章。。。
结束语
距离写最后一篇未锁定的文章一晃居然将近6年过去了,今天乘着周末正好遇到了这个问题国内也没搜到太多文章就顺手写了一篇,希望对大家有帮助吧