内网里那台文件服务器,你还在敲 192.168.1.50 访问?给同事发个 fileserver.example.local 它不香吗。本文就带你在一台 Linux 上把 BIND9 搭起来,从零让全公司都能用域名访问内网资源。
内网域名是什么
一句话:只在内部网络生效的域名,公网 DNS 查不到它,由你自己架的 DNS 服务器负责解析。好处很直接——内部系统、打印机、文件服务器都用可读的名字访问,换 IP 不用挨台机器改配置,访问路径也收口在自己手里。
整体思路
搭一套能用的内网域名解析,本质是四步串起来的链路:
下面逐步展开,重点放在第 2 步的 Linux BIND9 实操上。
第一步:规划内网域名结构
先决定用什么后缀。常见选择是 .local、.lan 这类保留域,比如拿 example.local 当顶级域,下属资源按用途命名:
- fileserver.example.local —— 文件服务器
- printer.example.local —— 打印机
- nas.example.local —— NAS
💡要点:.local 严格来说被 mDNS(Avahi/Bonjour)占用,小型内网用没问题;如果环境里有 macOS 设备或跑着 Avahi,建议换 .lan 或 .internal 避免解析打架。
第二步:安装并配置 DNS 服务器
Windows Server 走图形界面即可:在"添加角色和功能"里装 DNS 服务器角色,用 DNS 管理器创建正向查找区域(如 example.local),再逐条添加主机 A 记录。这里不展开。
Linux 阵营两个主流选择:BIND9(功能全、最主流)和 dnsmasq(轻量、适合小网)。本文以 BIND9 为主线。
安装 BIND9
Ubuntu/Debian:
# 更新包索引
sudo apt update
# 安装 BIND9
sudo apt install bind9 bind9utils -y
⚠️坑:安装过程可能自动放行防火墙规则,但别指望它配得完美,后面务必手动检查 53 端口状态。
核心配置文件
主配置在 /etc/bind/named.conf.local(新版本习惯把自定义区域放这里,而不是直接改 named.conf)。加一个正向区域:
zone "example.local" {
type master;
file "/etc/bind/db.example.local";
};
三个关键参数记住就行:
| directory | 区域文件存储路径 | 默认 /etc/bind 即可 |
| listen-on | 监听哪些网卡 IP | 只填内网 IP,别暴露到公网口 |
| allow-query | 谁能来查询 | 收紧到内网网段 |
然后是区域文件本身 /etc/bind/db.example.local,必填三类记录:
- SOA 记录:声明主服务器和管理员邮箱
- NS 记录:指定名称服务器
- A 记录:域名 → IP 映射
最小可用示例:
$TTL 604800
@ IN SOA ns1.example.local. admin.example.local. (
2025032101 ; 序列号,每次改完区域文件要 +1
3600 ; 从服务器刷新间隔
1800 ; 重试间隔
604800 ; 过期时间
600 ) ; 否定应答缓存 TTL
@ IN NS ns1.example.local.
ns1 IN A 192.168.1.10
fileserver IN A 192.168.1.50
printer IN A 192.168.1.60
✅说明:末尾的点(ns1.example.local.)表示绝对域名,漏了点会被拼成 ns1.example.local.example.local.,这是新手最高频的报错来源。
反向解析(可选但推荐)
正向是"域名查 IP",反向是"IP 查域名",安全审计、日志排查时很好使。给 192.168.1.0/24 段配反解,先在 named.conf.local 加区域:
zone "1.168.192.in-addr.arpa" {
type master;
file "/etc/bind/db.192.168.1";
};
再创建 /etc/bind/db.192.168.1:
$TTL 604800
@ IN SOA ns1.example.local. admin.example.local. (
2025032102 ; 新序列号
3600
1800
604800
600 )
@ IN NS ns1.example.local.
10 IN PTR ns1.example.local.
50 IN PTR fileserver.example.local.
60 IN PTR printer.example.local.
数字前缀对应 IP 末段:10 就是 192.168.1.10。
启动服务与测试
改完配置,按这个顺序验证,别直接重启了才发现语法错:
# 1. 检查主配置语法
sudo named-checkconf
# 2. 检查区域文件语法(无输出即正确)
sudo named-checkzone example.local /etc/bind/db.example.local
# 3. 重启服务加载新配置
sudo systemctl restart bind9
# 4. 本机测试解析
dig @127.0.0.1 fileserver.example.local
# 预期输出: status: NOERROR, ANSWER 段显示 192.168.1.50
# 或者用 nslookup
nslookup fileserver.example.local 127.0.0.1
💡要点:named-checkzone 输出里看到 OK 才算区域文件合格;如果报 could not load zone,九成是文件权限问题——确保 bind 用户可读。
第三步:配置 DHCP 下发 DNS
客户端不可能一台台手动填 DNS。如果内网用 DHCP 分 IP,在 DHCP 作用域选项里指定 DNS 服务器地址(Linux 常用 ISC DHCP 的话,是在 dhcpd.conf 的作用域段里加 option domain-name-servers 192.168.1.10;)。这样客户端拿到 IP 的同时自动获得 DNS 指向。
第四步:客户端配置与验证
没走 DHCP 的设备,手动在 IPv4 属性(或 Linux 的 /etc/resolv.conf / systemd-resolved)里把 DNS 指向上面这台服务器,然后:
ping fileserver.example.local # 看是否解析出 192.168.1.50
nslookup printer.example.local # 验证任意一条 A 记录
能解析出正确 IP、ping 有响应,这套内网 DNS 就算跑通了。
进阶优化与安全
- 每日看日志 /var/log/syslog(Debian 系 BIND 日志通常进 syslog,而非独立的 /var/log/bind/,除非单独配置过 logging 通道)
- 每次改区域文件记得递增序列号,否则从服务器不认你的新数据
常见问题解答
Q:客户端无法解析域名? A:三步定位——① DNS 服务器上 dig @127.0.0.1 自己查得通吗?不通查区域文件;② 客户端 /etc/resolv.conf 是否指向这台 DNS;③ 中间防火墙是否拦了 UDP 53。
Q:防火墙拦截了 DNS 端口? A:开放 53 端口(TCP + UDP 都要,区域传输走 TCP):
sudo ufw allow 53/tcp; sudo ufw allow 53/udp
# 或 firewalld:
sudo firewall-cmd –add-port=53/udp –permanent && sudo firewall-cmd –reload
Q:改了区域文件但解析还是旧结果? A:十有八九忘了改序列号。BIND 靠 SOA 序列号判断区域是否更新,每次修改后把它 +1(惯例用日期式 YYYYMMDDnn),再重启服务。
参考链接
- BIND 9 官方文档
- named.conf man page
- ISC DHCP 配置文档

