4

用于本地开发使用的 DNS 方案

 3 years ago
source link: https://soulteary.com/2021/08/19/dns-for-local-development.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

本篇文章,我将介绍下方便本地开发和调试的方案,本地 DNS 代理服务器。

不论是你做前端还是后端开发,本地调试带有域名的接口或页面是大概率绕不开的事情。甚至,如果你使用了自签名证书或者使用了“虚拟域名”进行 HomeLab 服务搭建,在某些不能使用网络默认 DNS 服务器时,也需要一些“灵活”的方案来动态切换一系列域名的指向。

不过,也不能因为手持锤子就看哪里都是钉子。简单的场景下,比如就修改一次的情况下,直接修改 hosts 文件解决问题会是更简单的方案,关于 “Hosts Editor” 类的工具的推荐,可以阅读文末章节。

言归正传,先来聊一个我使用了六个多月的方案。

方案一:带有界面的 dnsmasq 容器

dnsmasq 作为 DNS Server 被广泛用于 Linux 发行版。我们常见的 Ubuntu Server 版以及 Open WRT 路由器固件中,不少版本默认使用的都是它。

但是它是一个命令行软件,默认并不支持自动重载有修改后的配置文件,配置文件的编辑和我们常规修改 /etc/hosts 别无二致,国外有一个工程师为了解决这个问题,开发了一个简单的带有界面的配置工具 docker-dnsmasq,在配置文件被修改后,能够发送命令重启或重载 dnsmasq 主程序,达到“方便使用”的目的。

因为作者许久不更新软件,在今年二月的时候,我做了一个 fork 版本,soulteary/docker-dnsmasq,你可以使用下面的配置快速运行一个属于你的本地 DNS 服务器。

以往我们编辑 hosts 文件,会用下面的形式来进行域名绑定:

10.11.12.123 docker.lab.com
10.11.12.123 maven.lab.com
10.11.12.123 npm.lab.com
10.11.12.123 pypi.lab.com
...

所以当域名很多的时候,使用起来就会非常麻烦,相比之下 dnsmasq 的配置文件就会简单许多,因为它允许使用“泛解析”的方式,除此之外还能指定上游服务器,近一步扩展能力,下面就是一个 dnsmasq.conf 的配置文件的例子:

# HomeLab
## Use Home DNS Upstream
server=10.11.12.13

# HomeLab Domain Example:
address=/.lab.com/10.11.12.123
address=/*.lab.com/10.11.12.123
address=/*.demo.lab.com/10.11.12.123
address=/*.api.lab.com/10.11.12.123
address=/*.some.api.lab.com/10.11.12.123

# localhost
address=/.lab.io/127.0.0.1
address=/*.lab.io/127.0.0.1

在上面的例子中,将 lab.com 和一些子域名指向了内网的一台机器,而将 lab.io 全部指向了本机,将上面的内容保存为 dnsmasq.conf,我们来编写容器编排文件:

version: "3"
services:

  dns:
    image: soulteary/docker-dnsmasq
    restart: always
    # 如果你需要一个简单的 Basic Auth 认证
    #environment:
    #  - HTTP_USER=user
    #  - HTTP_PASS=pass
    ports:
      - "53:53/udp"
      - "53:53/tcp"
      - "8080:8080"
    volumes:
      - ./dnsmasq.conf:/etc/dnsmasq.conf:rw

将上面的内容保存为 docker-compose.yml,然后使用 docker-compose up -d 启动服务,接着使用浏览器访问 8080 端口,就能看到控制面板了,开始使用啦。

一个简单的 dnsmasq 管理面板

一个简单的 dnsmasq 管理面板

需要额外注意的是,为了减少后续设置的复杂,我们默认使用 53 端口来提供服务,管理面板默认使用的端口是 8080,如果你有端口冲突,建议进行调整或修改。

软件界面比较简单,使用方式就是使用所见即所得的编辑器修改内容,然后点击保存等待配置生效。如果你在配置存放一些不同环境的配置,然后批量选中某个环境的记录,通过快捷键(CMD+/)切换记录的注释状态,就能进行不同环境 DNS 记录的快速切换了。(最近半年里,我就是这么解决不同环境的 DNS 记录切换的,配置示例):

# HomeLab
## Use Home DNS
server=10.11.12.13

# Office
## Use Dev NS Servers
# server=219.141.136.10
# server=219.141.140.10

## Use CloudFlare NS Servers
# server=1.0.0.1
# server=1.1.1.1


# Local
address=/.lab.io/127.0.0.1
address=/*.lab.io/127.0.0.1

address=/.lab.com/10.11.12.123
address=/*.lab.com/10.11.12.123
address=/*.demo.lab.com/10.11.12.123
address=/*.api.lab.com/10.11.12.123
address=/*.some.api.lab.com/10.11.12.123

# address=/.lab.com/192.11.12.123
# address=/*.lab.com/192.11.12.123
# address=/*.demo.lab.com/192.11.12.123
# address=/*.api.lab.com/192.11.12.123
# address=/*.some.api.lab.com/192.11.12.123

当然,这个程序同时会读取容器内的 /etc/hosts,你也可以通过左侧侧边栏切换编辑器打开 hosts 文件,用传统的方式添加修改 DNS 记录。

在软件使用过程中,也会有一些体验不好的地方,比如程序重载需要几秒的时间,过程中会有服务不可用的状态,编辑器只有最基础的功能,缺少快捷键等。

偶尔有的时候程序会出现一些异常的资源使用,经过查找,发现社区里也有人反馈,虽说重启一下容器就能解决问题,但是毕竟有瑕疵,所以我开始考虑对这个方案进行替换调整。

结合系统使用

当我们启动了本地服务之后,默认请求并不会有任何改变,除非我们将这个配置应用到系统网络配置中。

以 macOS 为例,打开网络设置,选择当前网络,点击“高级”按钮,然后切换到 DNS 选项卡,在左侧的 DNS 服务器里,添加 “127.0.0.1”即可。

调整 macOS 的网络DNS配置

调整 macOS 的网络DNS配置

这里有一个小技巧,为了保证网络完全不间断(比如重启服务的时候),这里可以除了添加我们指定的 DNS 服务之外,将当前网络的 DNS 服务器也添加进去。

配合Traefik 使用 dnsmasq

如果你是我的老读者,那么应该对 Traefik 不会感到陌生,这里提供一个简单的配置,方便你使用 Traefik:

version: "3"
services:

  dns:
    image: soulteary/docker-dnsmasq
    restart: always
	# 如果你需要一个简单的 Basic Auth 认证
    # 使用 Traefik 推荐使用 Forward Auth 进行取代
    #environment:
    #  - HTTP_USER=user
    #  - HTTP_PASS=pass
    ports:
      - "53:53/udp"
      - "53:53/tcp"
      - "8080:8080"
    volumes:
      - ./dnsmasq.conf:/etc/dnsmasq.conf:rw
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=traefik"
      - "traefik.http.routers.dnsmasq-web.entrypoints=http"
      - "traefik.http.routers.dnsmasq-web.rule=Host(`dns.lab.io`)"
      - "traefik.http.routers.dnsmasq-ssl.entrypoints=https"
      - "traefik.http.routers.dnsmasq-ssl.tls=true"
      - "traefik.http.routers.dnsmasq-ssl.rule=Host(`dns.lab.io`)"
      - "traefik.http.services.dnsmasq-backend.loadbalancer.server.scheme=http"
      - "traefik.http.services.dnsmasq-backend.loadbalancer.server.port=8080"
    networks:
      - traefik

networks:
  traefik:
    external: true

关于 “Traefik 鉴权”话题,之前有提到过,感兴趣可以自取(上篇/下篇),另外,最近有做一个小项目,可以进一步简化这个场景的操作。

接下来,来聊聊新的方案。

方案二:使用 go-dnsmasq 方案

go-dnsmasq 是一个轻量到只有 1.2MB 的 DNS 缓存/转发工具,但是可惜的是作者在 16 年之后就没有继续进行项目维护了。在翻阅了几十个 fork 衍生版之后,我最终将两个国外的改进版本合并成了一个新的版本 https://github.com/soulteary/go-dnsmasq,并制作了一个 2.7 MB 左右的容器镜像。

使用方法其实比上面还要简单,先来看配置文件:

127.0.0.1 lab.com
127.0.0.2 *.lab.com

平凡无奇的 hosts 记录的语法中,支持了泛解析,比 dnsmasq.conf 少了不少符号记忆的负担。虽然日常使用肯定会使用复制粘贴,但是少一个字符,出错的可能就少了一分,不是吗?将上面的内容保存为 hosts.conf,稍后使用。

先来继续编写容器配置文件:

version: "3"
services:

  dns:
    image: soulteary/go-dnsmasq
    command: dnsmasq -l 0.0.0.0:53 -f /hosts.conf -p 1s --nameservers 10.11.12.13:53
    restart: always
    ports:
      - "53:53/udp"
      - "53:53/tcp"
    volumes:
      - ./hosts.conf:/hosts.conf:rw

相比较方案一,这个方案显然更“轻量环保”。至于切换环境配置,只需要准备多份不同环境的配置文件,使用 docker 挂载的时候切换文件就可以啦。

配置中的启动命令中,我定义了几个参数,只需要关注最后一个参数即可:

dnsmasq -l 0.0.0.0:53 -f /hosts.conf -p 1s --nameservers 10.11.12.13:53

参数中的 --nameservers 需要设定为你的网络环境中的默认 DNS,当然如果你参考上文中提到的“结合系统使用”的方式,不进行指定也不会影响使用。

接着,来聊聊文章开头聊到的编辑本地 Hosts 文件。

其他:如何简单的修改 Hosts 文件

如果你只需要管理几个域名,也不太想启动一个服务(哪怕它只有2M),可以尝试编辑系统的 Hosts 文件来完成域名指向,如果你厌倦了命令行或者记事本修改文件,也可以考虑下载一些 Hosts Editor 类的工具。

最初的时候,我使用过 Gas MaskHostsMan,以及一些类似的软件,在第一次去淘宝工作的时候,被安利了一个内网神器“iHosts”(不是搜索引擎搜索出的同名软件),除了多了清新的界面之外,还支持记录分组,以及本地 DNS 服务器,对于调试移动端场景、或者虚拟机场景还是挺方便的。

Switch Hosts 默认界面

Switch Hosts 默认界面

在许多年前离开淘宝后,因为无法再从内网下载“ihosts”,于是就切换到了 “SwitchHosts!”(最新版本改名字去掉了“!”),虽然没有内置 DNS 服务、请求日志等功能,但是胜在功能简单够用,加上作者靠谱,也就一直用了下来。

为什么说作者靠谱呢?早些时候和刚从淘宝离开的作者季札大神一起吃饭,聊起招聘困难,当时玩笑的说要不要在 SwitchHosts README 里加个招聘广告,季札说希望这个软件能够一直纯粹下去,然后这些年这个软件,至今为止就一直这么干净纯粹着,还是挺难得的。

但是,在使用过程中难免会遇到需要做“泛解析”的场景,批量改动记录总归是比较麻烦的事情,以及我的电脑常年不关机,经常休眠唤醒,基于 Electron 的 SwitchHosts 经常会出现内存溢出的问题,所以只好忍痛把主力方案切换到了上文中的 DNS 方式。

其实解决的方案也很简单,和方案一一样,就是每次使用完 SwitchHosts 之后,把它的进程彻底关掉,再重启就好了。后续我应该会继续使用 SwitchHosts 这个功能,不过,应该不会再作为主力工具,毕竟泛解析能够省不少事儿。

其他:如何制作和使用自签名证书

HTTPS 时代中,本地调试有的时候也躲不开配置证书,关于如何方便的制作和使用自签名证书,我曾写过一篇文章进行介绍,如果你有这方面的需求,可以自行取用。

原本以为离职休假能够把草稿箱里的文章清理一下,没想到积累的草稿更多了,感谢令人头疼的好奇心,和追求最优解的倔强。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK