一、背景
工作过程中遇到需要频繁切换测试和现网域名的问题,每次都去修改C:\Windows\System32\drivers\etc\hosts,感觉比较麻烦,而且修改之后由于系统和浏览器DNS缓存问题可能需要等一会才能切换成功。
于是想通过浏览器自定义DNS来实现不同浏览器访问不同域名的需求,如用Chrome浏览器访问测试环境,Edge浏览器访问现网环境。搜索发现Chrome浏览器有使用安全DNS的相关设置(chrome://settings/security),可以自定义安全DNS的服务地址:
二、准备
Chrome浏览器中说的安全DNS指的是DoH(DNS over HTTPS),它是一个安全的域名解析方案。其意义在于以加密的HTTPS协议进行DNS解析请求,避免原始DNS协议中用户的DNS解析请求被窃听或者修改的问题(例如中间人攻击)来达到保护用户隐私的目的。因此,攻击者将无法查看请求的URL并对其进行更改,如果使用了基于HTTPS的DNS,数据在传输过程中发生丢失时,DoH中的传输控制协议(TCP)会做出更快的反应。
因此本地要自建支持DoH的DNS服务器,像dnsmasq就无法直接满足要求,需要增加前置代理。后来发现coredns可以直接支持DoH,因此就选择用coredns来搭建本地DNS服务器。coredns官网(CoreDNS: DNS and Service Discovery)上可以下载到Linux,Windows等系统的发布版本。
因为要支持HTTPS所以还要生成私有的证书,可以使用openssl命令来完成,具体如下:
1.生成根证书
openssl genrsa -out rootca.key 2048
openssl req -new -x509 -key rootca.key -days 3650 -subj "/C=CN/ST=Jiangsu/L=Suzhou/O=MITO/OU=Development/CN=root" -out rootca.crt
2.生成本地证书请求
openssl req -new -newkey rsa:2048 -keyout localhost.key -subj "/C=CN/ST=Jiangsu/L=Suzhou/O=MITO/OU=Development/CN=localhost" -out localhost.csr -nodes
3.用根证书颁发本地证书
openssl x509 -req -in localhost.csr -CA rootca.crt -CAkey rootca.key -CAcreateserial -out localhost.crt -days 3650 -extfile localhost.ext
localhost.ext文件内容:
authorityKeyIdentifier = keyid, issuer
basicConstraints = CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement
extendedKeyUsage = serverAuth, clientAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
IP.1 = 127.0.0.1
生成的localhost.crt和localhost.key用于后续HTTPS服务的搭建。
4.系统导入根证书
如果不导入根证书,那么本地证书启动的HTTPS服务是不可用的。导入根证书步骤如下:
1.Win + R打开运行窗口,输入certlm.msc:
2.选择受信任的根证书颁发机构->证书,然后右击选择所有任务的导入:
3.按向导提示选择根证书rootca.crt:
4.完成导入之后会显示导入成功,在证书列表中就可以看到导入的根证书了:
三、搭建DNS
使用coredns搭建本地DNS服务比较简单,将下载到的coredns解压放到某个目录下,例如D:\coredns目录下,将上面生成的localhost.crt和localhost.key放到D:\coredns\cert目录下,自定义的域名写入到D:\coredns\tests.host文件中(文件名自定义),最后创建coredns的配置文件D:\coredns\Corefile,如下图所示:
其中Corefile内容如下:
https://.:8053 {
tls cert/localhost.crt cert/localhost.key
hosts test.hosts {
fallthrough
}
forward . 114.114.114.114
cache
log
errors
}
1.8053为服务端口,https表示提供DoH服务;
2.tls行指定证书路径;
3.host行指定本地hosts文件,里面可以写入自定义域名,格式和系统hosts(C:\Windows\System32\drivers\etc\hosts)文件一样;
4.forward行指定本地查询不到域名时去转发DNS请求到哪,这里指定的是114的DNS服务器;
四、启动脚本
本地DNS服务搭建好之后还需要一个启动脚本,不然需要通过cmd命令行来执行coredns.exe,不是很方便。我们创建一个批处理脚本coredns.bat,内容如下:
@ECHO OFF
taskkill /F /T /IM coredns.exe
%1 start mshta vbscript:createobject("wscript.shell").run("""%~0"" ::",0)(window.close)&&exit
start /d "D:\coredns" /b coredns.exe
这样我们只需要双击这个批处理脚本即可启动本地DNS服务了。
五、测试
启动本地DNS服务后,首先测试本地DNS服务是否正常,在浏览器地址栏输入:https://localhost:8053/dns-query,如果可以正常访问说明DNS服务正常:
然后在Chrome浏览器安全DNS设置页面(chrome://settings/security)自定义安全DNS的服务地址:https://localhost:8053/dns-query
我们在test.hosts文件中添加一个自定义的域名(新增加的话要重启coredns)来验证自定义DNS是否生效:
1.2.3.4 www.mycoredns.com
进入Chrome浏览器的DNS查询页面:chrome://net-internals/?#dns
查询www.mycoredns.com对应的IP:
这样后面如果有需要自定义的域名就可以写入到test.hosts文件中然后重启coredns来实现了。