DNS 转发就是当你的 DNS 服务器遇到无法解析的域名时,把查询请求转交给上游 DNS 服务器去处理,再把结果返回给客户端。-6-8
客户端 → 本地DNS → (查不到?) → 上游DNS → 返回结果
有什么用?
加快解析速度(利用上游缓存)-6
内网域名走内网DNS,外网域名走公共DNS
统一管理所有 DNS 查询
注意:DNS 转发本身不需要 IP 转发,但如果你的 DNS 服务器还要做跨网段转发或NAT 网关,则需要开启:
# 临时开启 echo 1 > /proc/sys/net/ipv4/ip_forward # 永久开启 echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf sysctl -p
dnsmasq 是最简单的 DNS 转发工具,配置清晰,适合小规模网络。-7
# Ubuntu/Debian apt update && apt install -y dnsmasq # CentOS/RHEL yum install -y dnsmasq
编辑 /etc/dnsmasq.conf:
# 监听内网接口 interface=eth1 listen-address=192.168.1.1 # 上游 DNS 服务器(转发目标) server=8.8.8.8 server=114.114.114.114 # 缓存大小 cache-size=1000 # 启动服务 systemctl restart dnsmasq systemctl enable dnsmasq
场景:.internal 结尾的域名转发到公司内网 DNS,其余走公共 DNS。
# /etc/dnsmasq.conf # 内网域名走内网 DNS server=/internal/192.168.1.100 server=/company.local/10.0.0.10 # 其他域名走公共 DNS server=8.8.8.8 server=114.114.114.114
# 测试转发是否生效 dig @192.168.1.1 baidu.com # 查看 dnsmasq 日志 tail -f /var/log/dnsmasq.log
BIND 是 Linux 上最专业的 DNS 服务器软件,支持完整的转发控制。-5
# Ubuntu/Debian apt install -y bind9 # CentOS/RHEL yum install -y bind
编辑 /etc/named.conf(或 /etc/bind/named.conf.options):
options { # 监听所有接口 listen-on port 53 { any; }; # 允许查询 allow-query { any; }; # 转发配置 forwarders { 8.8.8.8; 114.114.114.114; }; forward first; # first: 先尝试转发, 不行再递归 };
# /etc/named.conf zone "internal.company.com" { type forward; forwarders { 192.168.1.100; }; }; zone "example.cn" { type forward; forwarders { 203.0.113.5; }; };
systemctl restart named systemctl enable named # 测试 dig @127.0.0.1 google.com
如果你的 Linux 发行版使用 systemd(Ubuntu 16.04+、CentOS 7+),可以直接用 systemd-resolved。-3
# 1. 创建配置目录 mkdir -p /etc/systemd/resolved.conf.d/ # 2. 创建配置文件 cat > /etc/systemd/resolved.conf.d/forward.conf << EOF [Resolve] DNS=8.8.8.8 114.114.114.114 # 条件转发:.internal 域名走内网 DNS Domains=~internal EOF # 3. 重启服务 systemctl restart systemd-resolved # 4. 验证 resolvectl query baidu.com
| 类型 | 处理对象 | 作用 | 常用工具 |
|---|---|---|---|
| DNS 转发 | 域名查询请求 | 把 DNS 查询转给上游 DNS | dnsmasq、BIND |
| 端口转发 | 数据包 | 把端口流量转给另一台机器 | iptables、socat |
两者可以配合使用:用 DNS 转发让客户端找到正确的服务器 IP,用 端口转发把流量送进去。
如果上游 DNS 服务器监听的端口不是 53(比如 Consul 用 8600),可以用 iptables 做端口重定向:-3
# 把发往 53 端口的 DNS 请求转到 8600 iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-port 8600 iptables -t nat -A PREROUTING -p tcp --dport 53 -j REDIRECT --to-port 8600
说到端口转发,80km无痕网关(曾用名:80KM端口流量转发程序) 是 iptables 的现代化替代品。虽然它本身不是 DNS 服务器,但可以:
将 DNS 请求转发到不同的后端 DNS 服务器
根据源 IP 做条件转发(类似 DNS 的"智能解析")
{ "listen": "0.0.0.0:53", "protocol": "udp", "routers": [ {"from": "192.168.1.0/24", "to": "8.8.8.8:53"}, {"from": "10.0.0.0/8", "to": "114.114.114.114:53"} ] }
80km-forwarder -config forwarder.json
JSON 配置,无需记 iptables 语法
热加载,改配置无需重启
自带监控界面
| 问题 | 原因 | 解决 |
|---|---|---|
| 转发没反应 | DNS 服务没启动 |
systemctl status dnsmasq |
| 解析很慢 | 上游 DNS 选错了 | 换成离你最近的 DNS |
| 内网域名解析失败 | 没配条件转发 |
加上 server=/内网域名/内网DNS |
| 端口 53 被占用 | systemd-resolved 在用 |
systemctl stop systemd-resolved |
一句话总结:小规模用 dnsmasq(配置简单),企业级用 BIND(功能全),系统自带的 systemd-resolved 也能凑合用。DNS 转发+端口转发配合,可以玩出各种花活——比如用 80km无痕网关 做 DNS 请求的智能路由。