【Linux从入门到精通】第36篇:DNS服务探秘——自己搭建一个内网DNS

目录

一、引言:为什么需要DNS?

二、/etc/hosts:DNS出现之前的解决方案

[2.1 hosts文件的工作原理](#2.1 hosts文件的工作原理)

[2.2 hosts文件的局限性](#2.2 hosts文件的局限性)

三、Dnsmasq:最轻量的DNS服务器

[3.1 什么是Dnsmasq?](#3.1 什么是Dnsmasq?)

[3.2 安装与启动](#3.2 安装与启动)

[3.3 配置自定义域名解析](#3.3 配置自定义域名解析)

[3.4 验证自定义域名解析](#3.4 验证自定义域名解析)

四、BIND9简介:企业级的DNS方案

五、实战:用DNS劫持广告域名

[5.1 原理](#5.1 原理)

[5.2 配置Dnsmasq广告屏蔽](#5.2 配置Dnsmasq广告屏蔽)

[5.3 使用社区维护的广告域名列表](#5.3 使用社区维护的广告域名列表)

六、故障排查清单

[6.1 DNS配置排查命令](#6.1 DNS配置排查命令)

[6.2 常见问题速查](#6.2 常见问题速查)

七、本篇小结

动手练习

八、下篇预告


一、引言:为什么需要DNS?

假如没有DNS,你访问百度不是输入baidu.com,而是输入110.242.68.66。你能记住几个这样的IP地址?

DNS(Domain Name System)就是为解决这个问题而生的------它把人类容易记忆的域名,翻译成计算机需要的IP地址。

但DNS的作用远不止"翻译"。在运维工作中,自己搭建DNS服务器有两个非常实用的场景:

  1. 内网域名解析 :公司内部的服务(如GitLab、Jenkins、Nexus)都在内网,没有公网DNS记录。自己搭一个DNS,员工就能用gitlab.internal这样的域名访问,不用记IP

  2. 广告过滤 :把所有广告域名的解析结果指向一个不存在的地址,广告自然就加载不出来了------这是网络级别的广告屏蔽,不用装任何浏览器插件

二、/etc/hosts:DNS出现之前的解决方案

2.1 hosts文件的工作原理

在DNS出现之前,互联网上的每一台计算机都用一个文件来记录"域名→IP"的映射关系------这就是/etc/hosts

bash

复制代码
cat /etc/hosts

输出(典型的Linux hosts文件):

text

复制代码
127.0.0.1    localhost
127.0.1.1    myhostname

# 你可以手动添加自定义映射
192.168.1.100   gitlab.internal
192.168.1.101   jenkins.internal

当你访问gitlab.internal时,系统会先查hosts文件,如果找到了对应的IP,就直接使用,不会再发起DNS查询。

优先级 :现代Linux系统默认先查hosts文件,再查DNS服务器。这个顺序由/etc/nsswitch.conf中的hosts: files dns控制------files代表hosts文件,dns代表DNS服务器查询,排在前面优先级更高。

2.2 hosts文件的局限性

局限 说明
单机生效 每台机器都得单独维护,机器多了根本无法同步
静态配置 IP变了就得手动改,DHCP动态分配IP的场景根本没法用
无高级功能 不支持泛域名解析(*.internal)、不支持负载均衡、不支持故障转移
无法应付大规模 互联网有上亿个域名,一个hosts文件不可能装下

当你管理三台以上的服务器时,hosts文件就会变成噩梦------每加一台新机器,你都得在所有机器上更新hosts。这时候就需要一个集中式的DNS服务器了。

三、Dnsmasq:最轻量的DNS服务器

3.1 什么是Dnsmasq?

Dnsmasq是一个轻量级的DNS和DHCP服务器,专为小型网络设计。它的特点:

  • 配置极简:核心配置往往只需要几行

  • 资源占用极低:几十MB内存就能跑,树莓派上也能流畅运行

  • 自动读取/etc/hosts:你只需要把内网域名写进服务器的hosts文件,Dnsmasq就能把它们作为DNS记录对外提供

  • 支持DNS缓存:加速重复查询,减轻上游DNS负担

对于几十台到几百台规模的内网环境,Dnsmasq是性价比最高的选择。

3.2 安装与启动

bash

复制代码
# Ubuntu/Debian
sudo apt update && sudo apt install dnsmasq -y

# CentOS/RHEL
sudo dnf install dnsmasq -y

# 启动并设为开机自启
sudo systemctl start dnsmasq
sudo systemctl enable dnsmasq

Dnsmasq默认监听53端口(DNS标准端口)。Ubuntu/Debian系统可能自带systemd-resolved,它也占用53端口,会导致Dnsmasq启动失败。排查方法:

bash

复制代码
# 查看53端口被谁占用
sudo ss -tulnp | grep :53

# 如果systemd-resolved占用了53端口,停止它并禁用
sudo systemctl stop systemd-resolved
sudo systemctl disable systemd-resolved

# 处理/etc/resolv.conf软链接(避免被systemd-resolved覆盖)
sudo rm /etc/resolv.conf
echo "nameserver 127.0.0.1" | sudo tee /etc/resolv.conf

3.3 配置自定义域名解析

Dnsmasq的默认配置非常精简,大部分功能都需要手动配置。编辑配置文件:

bash

复制代码
sudo vim /etc/dnsmasq.conf

在文件末尾追加以下内容:

ini

复制代码
# 监听所有网络接口(生产环境建议指定具体IP,如 interface=eth0)
interface=*

# 上游DNS服务器(Dnsmasq自己解析不了的域名,转发给Google和Cloudflare的DNS)
server=8.8.8.8
server=8.8.4.4

# 监听地址(绑定的内网IP,根据你的服务器IP修改)
listen-address=192.168.1.100

# 禁止读取 /etc/resolv.conf 获取上游DNS(我们用 server= 手动指定)
no-resolv

# DNS缓存大小(缓存1000条查询结果,加快重复访问速度)
cache-size=1000

然后配置内网自定义域名:

bash

复制代码
# 方法一:直接写入服务器的 /etc/hosts
echo "192.168.1.10  gitlab.internal" | sudo tee -a /etc/hosts
echo "192.168.1.20  jenkins.internal" | sudo tee -a /etc/hosts
echo "192.168.1.30  nexus.internal" | sudo tee -a /etc/hosts

bash

复制代码
# 方法二:通过Dnsmasq的专用配置文件(更规范)
sudo mkdir -p /etc/dnsmasq.d
sudo vim /etc/dnsmasq.d/internal.conf

添加内容:

text

复制代码
# 内网自定义域名
address=/gitlab.internal/192.168.1.10
address=/jenkins.internal/192.168.1.20
address=/nexus.internal/192.168.1.30

# 泛域名解析(所有 .app.internal 都解析到这个IP)
address=/.app.internal/192.168.1.50

重启Dnsmasq:

bash

复制代码
sudo systemctl restart dnsmasq

3.4 验证自定义域名解析

在DNS服务器本机测试:

bash

复制代码
# 测试自定义域名(@127.0.0.1 指定用本机的DNS服务查询)
nslookup gitlab.internal 127.0.0.1

# 或者用dig
dig @127.0.0.1 gitlab.internal

在其他内网机器上测试(将它们的DNS设置为你的Dnsmasq服务器IP):

bash

复制代码
# Linux:临时修改DNS
echo "nameserver 192.168.1.100" | sudo tee /etc/resolv.conf

# 测试
ping gitlab.internal
nslookup jenkins.internal

Windows上修改DNS:控制面板 → 网络和共享中心 → 更改适配器设置 → 右键网卡属性 → IPv4属性 → DNS服务器填192.168.1.100

四、BIND9简介:企业级的DNS方案

Dnsmasq适合小型内网,但如果需要更复杂的功能------比如多区域管理、主从DNS同步、动态更新------就需要BIND9

BIND(Berkeley Internet Name Domain)是互联网上使用最广泛的DNS服务器软件,大部分公网DNS服务器都在运行BIND。它功能强大但配置复杂得多,这里只做简要对比:

对比维度 Dnsmasq BIND9
适用规模 几十~几百台 几百~几万台以上
配置复杂度 ★☆☆☆☆ ★★★★☆
内存占用 ~50MB ~200MB+
区域传输 不支持 支持主从同步
学习成本 10分钟上手 需要系统学习DNS协议

如果你的环境和需求符合以下条件之一,可以考虑学习BIND9:

  • 需要管理多个DNS区域(zone)

  • 需要部署主从DNS服务器实现高可用

  • 需要支持DDNS(动态DNS更新)

  • 对DNS协议有深入学习的兴趣

五、实战:用DNS劫持广告域名

这是本篇最有趣的部分------利用DNS实现网络级别的广告屏蔽

5.1 原理

广告加载的流程通常是:网页 → 请求ads.example.com/some_ad.js → DNS查询 → 获取广告服务器IP → 加载广告。

如果在DNS层面,把ads.example.com解析到127.0.0.1(或者0.0.0.0),浏览器就无法加载广告内容------因为广告请求全被"黑洞"了。

5.2 配置Dnsmasq广告屏蔽

bash

复制代码
sudo vim /etc/dnsmasq.d/adblock.conf

添加以下内容:

text

复制代码
# 把所有常见广告域名指向 0.0.0.0(指向自己或空地址,浏览器发起请求后立即失败)
address=/doubleclick.net/0.0.0.0
address=/googleadservices.com/0.0.0.0
address=/googlesyndication.com/0.0.0.0
address=/adservice.google.com/0.0.0.0

# 一些常见的第三方广告域名
address=/ads.example.com/0.0.0.0
address=/tracker.analytics.com/0.0.0.0

效果验证:重启Dnsmasq后,在本机试试:

bash

复制代码
# 解析广告域名(应该返回 0.0.0.0)
nslookup doubleclick.net 127.0.0.1

# ping 测试
ping ads.example.com    # 输出 "PING ads.example.com (0.0.0.0)" 说明劫持成功

5.3 使用社区维护的广告域名列表

手动维护广告域名费时费力,社区已经有现成的列表可用:

bash

复制代码
# 下载一个经过整理的hosts广告屏蔽列表,转换为Dnsmasq格式
curl -s https://someonewhocares.org/hosts/zero/hosts | \
    grep '^0\.0\.0\.0' | \
    awk '{print "address=/"$2"/0.0.0.0"}' | \
    sudo tee /etc/dnsmasq.d/adblock_community.conf

# 重启Dnsmasq
sudo systemctl restart dnsmasq

注意:社区列表可能包含数千甚至上万条域名,Dnsmasq的处理性能在普通服务器上完全够用。但建议只选择你信任的列表来源,避免误拦截正常网站。

六、故障排查清单

6.1 DNS配置排查命令

bash

复制代码
# 查看当前系统DNS配置
cat /etc/resolv.conf

# 检查53端口是否被占用
sudo ss -tulnp | grep :53

# 查看Dnsmasq日志(排查配置错误)
sudo journalctl -u dnsmasq -f

# 测试DNS解析(逐步定位)
nslookup baidu.com                    # 用系统默认DNS
nslookup baidu.com 127.0.0.1          # 用本机DNS
nslookup gitlab.internal 192.168.1.100  # 用内网DNS

6.2 常见问题速查

问题现象 可能原因 解决方案
Dnsmasq无法启动 53端口被占用(通常是systemd-resolved) `sudo ss -tulnp
内网域名解析不到 其他机器的DNS没指向Dnsmasq 检查/etc/resolv.conf(Linux)或网卡DNS设置(Windows)
某些网站打不开 广告列表误伤了正常网站 检查/etc/dnsmasq.d/下的屏蔽列表,注释掉怀疑的域名后重启Dnsmasq
解析变慢 上游DNS延迟高或cache-size太小 检查server=上游DNS配置,增大cache-size

七、本篇小结

DNS层次

text

复制代码
/etc/hosts(单机)→ Dnsmasq(小型内网DNS)→ BIND9(企业级DNS)

Dnsmasq核心配置

配置项 作用 示例
server=IP 指定上游DNS server=8.8.8.8
address=/域名/IP 自定义域名解析 address=/gitlab.internal/192.168.1.10
address=/域名/0.0.0.0 屏蔽域名(广告过滤的核心) address=/ads.com/0.0.0.0
cache-size=N DNS缓存条数 cache-size=1000

DNS劫持广告的原理 :把广告域名的DNS指向127.0.0.10.0.0.0,浏览器就无法加载广告内容------无需插件,网络级别生效。

动手练习

bash

复制代码
# 1. 确认Dnsmasq安装并运行
sudo apt install dnsmasq -y
sudo systemctl status dnsmasq

# 2. 添加一个自定义域名并测试
sudo mkdir -p /etc/dnsmasq.d
echo "address=/myapp.internal/192.168.1.100" | sudo tee /etc/dnsmasq.d/myapp.conf
sudo systemctl restart dnsmasq
nslookup myapp.internal 127.0.0.1

# 3. 劫持一个常见广告域名体验DNS屏蔽效果
echo "address=/doubleclick.net/0.0.0.0" | sudo tee /etc/dnsmasq.d/adtest.conf
sudo systemctl restart dnsmasq
nslookup doubleclick.net 127.0.0.1

八、下篇预告

DNS把域名解析为IP,但一个域名往往只对应一个IP。如果这台服务器挂了怎么办?如果流量太大一台服务器撑不住怎么办?

下一篇我们将学习NFS网络文件系统------它是分布式存储的基础,让多台服务器共享同一份文件数据。你将理解"无状态协议"的设计哲学,以及为什么NFS会让进程进入我们第11篇学过的"D状态"不可中断睡眠。


延伸思考 :DNS虽然解决了集中式域名解析的问题,但/etc/hosts并没有消失------你可以在服务器上把127.0.0.1 localhost这一行删掉,看看会发生什么?很多服务的本地通信都会依赖localhost解析。这就是为什么hosts文件在单机配置中依然重要:它是绕过DNS最快、最可靠的解析方式。

相关推荐
2023自学中1 小时前
make clean 与 make distclean
linux·嵌入式
BenD-_-2 小时前
CVE-2026-31431 Copy Fail:Linux 内核本地提权漏洞风险与缓解
linux·网络·安全
Web极客码2 小时前
2026年Linux VPS安全加固清单:SSH、防火墙与审计就绪配置
运维·服务器·数据库
无敌的黑星星2 小时前
Java8 CompletableFuture 实战指南
linux·前端·python
星恒讯工业路由器2 小时前
配网自动化多网融合应用解决方案
运维·自动化
智慧物业老杨2 小时前
智慧物业收费系统的数智化落地实践:从人工硬扛到自动化闭环
运维·自动化
Championship.23.243 小时前
Linux Top 命令族深度解析与实战指南
java·linux·服务器·top·linux调试
techdashen3 小时前
Cloudflare 为何抛弃 NGINX,用 Rust 自研了一个代理
运维·nginx·rust
南城猿3 小时前
保姆级 Ubuntu 部署 禅道
linux·运维·ubuntu