前言:不少企业会碰到这样的拧巴网络场景:只有一个固定IPv4已加入域名IP白名单,但IPv6是动态地址(每次变更需重新配置白名单,操作繁琐),因此未将IPv6加入白名单;更棘手的是------域名商后台的"IPv6兼容性"开关必须保持开启(业务要求无法关闭),哪怕终端能正常访问的只有固定IPv4,仍会优先发起IPv6请求,而这些动态IPv6不在白名单内会被拦截,最终导致业务域名频繁超时、无法访问。
同时还叠加了这些痛点:CDN节点IP频繁变更需要手动改解析、公网DNS存在劫持风险、多分支跨网访问延迟高。最终选择搭一套内网DNS,既彻底过滤IPv6解析记录,强制终端仅使用已加白的固定IPv4,又解决CDN同步、安全访问的问题。下面是从踩坑到落地的全流程,主体都是实际跑通的操作,针对这类场景补全了关键逻辑。
一、这类拧巴的网络痛点(通用企业场景)
这类场景的核心矛盾很典型:
- 网络访问规则:只有一个固定IPv4已加入域名IP白名单,IPv6为动态地址(每次变更需重新配置白名单,操作成本高),因此未将任何IPv6加入白名单,IPv6访问会被拦截;
- 解析优先级问题:IPv6解析优先级高于IPv4,即使配置了IPv4(A记录),终端仍优先发起IPv6请求;
- 域名商限制:域名管理后台的"IPv6兼容性"开关必须保持开启,无法通过关闭该开关屏蔽IPv6请求;
- 实际问题:终端优先发起的动态IPv6请求因未加白被拦截,导致业务域名访问超时/失败;
- 附加痛点:CDN IP定期变更、公网DNS存在安全风险、多分支跨网访问效率低。
核心目标:搭建一套内网DNS,彻底过滤IPv6解析记录,强制终端仅使用已加白的固定IPv4,同时解决CDN自动同步、安全访问的问题。

二、部署载体选择(通用企业场景)
情况1:已有内网Linux服务器
直接使用现有机器即可,需满足:Ubuntu 24.04系统、内网静态IP为已加白的固定IPv4、可访问SD-WAN网段,跳过VM安装步骤,直接从"系统级IPv6关闭"开始操作。
情况2:无现成服务器,通过VM部署
参考通用流程搭建环境:
- 安装VM虚拟机(选择桥接模式,确保虚拟机IP为已加白的固定IPv4、可接入企业内网);
- 在VM中安装Ubuntu 24.04系统;
- 配置内网静态IP:内网静态IPv4(已加白)(该IP为已加白的固定IPv4,对应SD-WAN内网网段:需根据实际环境配置)。
三、系统级+应用级双关IPv6(针对"动态IPv6白名单繁琐"的关键操作)
因动态IPv6配置白名单成本高且未加白,必须从系统到应用层彻底屏蔽IPv6解析请求------仅关应用层没用,系统级仍会触发终端发起IPv6请求,操作如下:
步骤1:编辑sysctl配置,添加IPv6禁用规则
bash
sudo bash -c 'cat >> /etc/sysctl.conf << EOF
# 禁用系统全局IPv6(彻底屏蔽IPv6请求,避免终端优先发起未加白的动态IPv6访问)
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
# 禁用指定网卡的IPv6(根据实际业务网卡名调整,如eth0/ensXX)
net.ipv6.conf.实际业务网卡名.disable_ipv6 = 1
EOF'
步骤2:使配置生效
bash
sudo sysctl -p
步骤3:验证IPv6是否关闭
bash
ip a | grep inet6
预期结果 :无inet6相关输出,说明系统级IPv6已彻底关闭,终端不会发起任何IPv6请求,仅使用已加白的固定IPv4访问。
四、Bind9核心部署步骤(踩坑后调整的通用流程)
先明确通用配置:
| 配置项 | 通用信息 |
|---|---|
| 服务器IP | 内网静态IPv4(已加白) |
| 开放网段 | SD-WAN内网网段(需根据实际环境配置)(该网段终端均需通过此DNS解析) |
| 企业域名 | dev-domain.com(开发)、test-domain.com(测试)、prod-domain.com(生产) |
| BIND版本 | Ubuntu 24.04自带的BIND 9.18+ |
步骤1:前置准备(踩坑后调整的正确配置)
最初错误禁用systemd-resolved、配置公网DNS,导致系统不使用本地Bind9,调整后流程:
bash
# 1. 系统包更新
sudo apt update && sudo apt upgrade -y
# 2. 安装Bind9工具集
sudo apt install -y bind9 bind9utils bind9-doc
# 3. 保留systemd-resolved并配置使用本地Bind9(避免依赖服务故障)
sudo mkdir -p /etc/systemd/resolved.conf.d
sudo bash -c 'echo -e "[Resolve]\nDNS=127.0.0.1" > /etc/systemd/resolved.conf.d/local.conf'
sudo systemctl restart systemd-resolved
# 4. 配置系统DNS指向本地Bind9(避免绕开本地解析,确保仅使用过滤后的固定IPv4记录)
sudo unlink /etc/resolv.conf
sudo touch /etc/resolv.conf
sudo bash -c 'echo "nameserver 127.0.0.1" > /etc/resolv.conf'
步骤2:配置Bind9主规则(安全监听+双关IPv6)
最初使用any监听所有网卡存在安全风险,调整为仅监听本地+内网IP,同时二次关闭Bind9的IPv6监听(确保不返回任何IPv6记录):
bash
sudo bash -c 'cat > /etc/bind/named.conf.options << EOF
options {
directory "/var/cache/bind";
# 非企业域名转发至公共DNS(仅获取IPv4记录)
forwarders { 1.1.1.1; 223.5.5.5; };
forward only;
# 禁用Bind9的IPv6监听(确保不返回任何IPv6解析记录)
listen-on-v6 { none; };
# 仅允许SD-WAN网段+本地访问(限定使用范围,需替换为实际SD-WAN内网网段)
allow-query { SD-WAN内网网段(需根据实际环境配置); localhost; };
recursion yes;
dnssec-validation no; # 内网环境简化配置(需注明安全妥协)
listen-on { 127.0.0.1; 内网静态IPv4(已加白); }; # 仅监听本地+内网IP,避免公网暴露
};
EOF'
步骤3:配置企业域名解析区域
关联开发、测试、生产环境域名与解析文件(仅配置已加白的固定IPv4记录):
bash
sudo bash -c 'cat > /etc/bind/named.conf.local << EOF
# 开发环境域名
zone "dev-domain.com" {
type master;
file "/etc/bind/db.dev-domain.com";
};
# 测试环境域名
zone "test-domain.com" {
type master;
file "/etc/bind/db.test-domain.com";
};
# 生产环境域名
zone "prod-domain.com" {
type master;
file "/etc/bind/db.prod-domain.com";
};
EOF'
步骤4:编写解析文件(避免$TTL报错+仅保留已加白固定IPv4记录)
确保每个文件开头含$TTL 3600(解决"no owner"报错),且仅配置已加白的固定IPv4(A记录),不配置任何IPv6(AAAA)记录:
4.1 开发环境:db.dev-domain.com
bash
sudo bash -c 'cat > /etc/bind/db.dev-domain.com << EOF
$TTL 3600
@ IN SOA ns.dev-domain.com. admin.dev-domain.com. (
2025122601 ; 版本号修改时递增
3600 ; 刷新间隔1小时
1800 ; 重试间隔30分钟
604800 ; 过期时间7天
3600 ) ; 负缓存时间1小时
@ IN NS ns.dev-domain.com.
ns IN A 内网静态IPv4(已加白)
@ IN A 内网静态IPv4(已加白)
dev-api IN A 已加白的CDN固定IPv4地址 ; 已加白的CDN固定IPv4
dev-web IN A 已加白的备用CDN固定IPv4地址 ; 已加白的备用CDN固定IPv4
EOF'
4.2 测试环境:db.test-domain.com
bash
sudo bash -c 'cat > /etc/bind/db.test-domain.com << EOF
$TTL 3600
@ IN SOA ns.test-domain.com. admin.test-domain.com. (
2025122601
3600 1800 604800 3600 )
@ IN NS ns.test-domain.com.
ns IN A 内网静态IPv4(已加白)
@ IN A 内网静态IPv4(已加白)
test-api IN A 已加白的固定IPv4地址 ; 已加白的固定IPv4
test-web IN A 已加白的固定IPv4地址 ; 已加白的固定IPv4
EOF'
4.3 生产环境:db.prod-domain.com
bash
sudo bash -c 'cat > /etc/bind/db.prod-domain.com << EOF
$TTL 3600
@ IN SOA ns.prod-domain.com. admin.prod-domain.com. (
2025122601
3600 1800 604800 3600 )
@ IN NS ns.prod-domain.com.
ns IN A 内网静态IPv4(已加白)
@ IN A 内网静态IPv4(已加白)
prod-api IN A 已加白的固定IPv4地址 ; 已加白的固定IPv4
prod-web IN A 已加白的固定IPv4地址 ; 已加白的固定IPv4
EOF'
步骤5:验证配置语法
配置后必须验证,避免启动报错:
bash
# 验证主配置(无输出即正常)
sudo named-checkconf
# 验证解析文件(输出"OK"即正常)
sudo named-checkzone dev-domain.com /etc/bind/db.dev-domain.com
sudo named-checkzone test-domain.com /etc/bind/db.test-domain.com
sudo named-checkzone prod-domain.com /etc/bind/db.prod-domain.com
步骤6:启动Bind9并设置开机自启
bash
sudo systemctl restart bind9
sudo systemctl enable bind9
# 验证服务状态(显示active(running)即正常)
sudo systemctl status bind9
步骤7:防火墙安全配置(仅开放SD-WAN网段)
bash
# 启用防火墙
sudo ufw enable
# 删除冗余规则
sudo ufw delete allow 53/tcp 2>/dev/null
sudo ufw delete allow 53/udp 2>/dev/null
# 仅允许SD-WAN网段访问53端口(DNS使用TCP+UDP,需替换为实际SD-WAN内网网段)
sudo ufw allow from SD-WAN内网网段(需根据实际环境配置) to any port 53 proto tcp
sudo ufw allow from SD-WAN内网网段(需根据实际环境配置) to any port 53 proto udp
# 验证规则
sudo ufw status
预期结果:仅SD-WAN内网网段(需根据实际环境配置)可访问53端口。
五、CDN IP自动同步脚本(通用版+可靠验证)
针对CDN IP频繁变更(需同步至已加白列表)的痛点,编写自动同步脚本,优化验证逻辑:
步骤1:安装依赖
bash
sudo apt install -y python3 python3-pip
pip3 install requests
步骤2:编写同步脚本(替换为可靠的退出状态验证)
bash
sudo bash -c 'cat > /opt/cf_sync.py << EOF
import requests
import os
import datetime
# 替换为实际Cloudflare信息(仅同步已加白的CDN固定IPv4)
CF_API_TOKEN = "你的Cloudflare API令牌"
CF_ZONE_IDS = {
"dev-domain.com": "开发域区域ID",
"test-domain.com": "测试域区域ID",
"prod-domain.com": "生产域区域ID"
}
LOCAL_IP = "内网静态IPv4(已加白)" # 已加白的DNS服务器固定IPv4
def get_cf_records(zone_id):
url = f"https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records?type=A"
headers = {"Authorization": f"Bearer {CF_API_TOKEN}"}
try:
res = requests.get(url, headers=headers, timeout=10)
# 仅保留已加白的固定IPv4记录(可根据实际白名单过滤)
return [r for r in res.json()["result"] if r["content"] in ["已加白的CDN固定IPv4列表(需根据实际白名单更新)"]]
except Exception as e:
print(f"拉取失败:{e}")
return []
def generate_db(domain, records):
ver = datetime.datetime.now().strftime("%Y%m%d%H")
content = f"""$TTL 3600
@ IN SOA ns.{domain}. admin.{domain}. (
{ver} 3600 1800 604800 3600 )
@ IN NS ns.{domain}.
ns IN A {LOCAL_IP}
@ IN A {LOCAL_IP}
"""
for r in records:
name = r["name"].replace(f".{domain}", "")
content += f"{name:12} IN A {r['content']}\n"
return content
def update_db(domain, content):
path = f"/etc/bind/db.{domain}"
with open(path, "w") as f:
f.write(content)
# 用命令退出状态验证(0=成功),替代不可靠的字符串匹配
return os.system(f"named-checkzone {domain} {path}") == 0
if __name__ == "__main__":
all_ok = True
for domain, zone_id in CF_ZONE_IDS.items():
recs = get_cf_records(zone_id)
if not recs:
continue
db_content = generate_db(domain, recs)
if not update_db(domain, db_content):
all_ok = False
if all_ok:
os.system("systemctl restart bind9")
print("同步完成!仅同步已加白的CDN固定IPv4")
EOF'
步骤3:配置定时任务(每10分钟同步)
bash
sudo crontab -e
# 添加任务,日志保存至/var/log/cf_sync.log
*/10 * * * * /usr/bin/python3 /opt/cf_sync.py >> /var/log/cf_sync.log 2>&1
# 验证定时任务
sudo crontab -l
六、交付给SD-WAN团队的通用配置
整理配置说明,便于快速对接:
SD-WAN内网DNS配置:
首选DNS服务器:内网静态IPv4(已加白)
说明:
1. 仅对SD-WAN内网网段(需根据实际环境配置)开放,无公网暴露风险;
2. 企业域名仅返回已加白的固定IPv4 CDN地址,已彻底过滤IPv6(解决动态IPv6白名单配置繁琐、优先访问被拦截的问题);
3. 非企业域名转发至公共DNS(仅获取IPv4记录),兼顾解析速度;
4. CDN IP每10分钟自动同步(仅同步已加白的固定IP),无需手动维护;
5. 服务已设开机自启,重启后自动恢复。
七、效果验证(通用流程)
连接SD-WAN后,在终端执行验证(核心验证IPv6被过滤、仅返回已加白的固定IPv4):
cmd
# 验证开发域名解析(仅返回已加白的固定IPv4,无任何IPv6记录)
nslookup dev-api.dev-domain.com 内网静态IPv4(已加白)
# 验证连通性(丢包率0最佳,说明固定IPv4在白名单内可正常访问)
ping 内网静态IPv4(已加白) -t
关键验证点:解析结果无任何IPv6(inet6)相关输出,仅显示已加白的固定IPv4地址。
八、通用维护要点
- 解析文件开头的
$TTL 3600不可删除,否则会触发"no owner"报错; - 配置修改后需重启Bind9:
sudo systemctl restart bind9,确保配置生效; - 日志排查:服务异常看
sudo journalctl -u bind9 -f,同步脚本异常看cat /var/log/cf_sync.log; - IPv6相关:必须系统+Bind9双关,避免终端发起未加白的动态IPv6请求;
- 安全配置:避免禁用systemd-resolved、避免配置公网DNS(防止绕开本地过滤)、避免
any监听网卡; - 白名单维护:CDN IP变更后需及时更新脚本中的已加白列表,确保同步的IP均在放行范围内;
- 网段/IP替换:所有标注"需根据实际环境配置"的网段/IP,需替换为企业实际的内网网段、已加白固定IPv4。
总结
- 所有具体IP地址已替换为通用文字描述(如「内网静态IPv4(已加白)」「SD-WAN内网网段(需根据实际环境配置)」),无企业专属IP信息;
- 保留方案核心逻辑(双关IPv6、Bind9安全配置、CDN自动同步),仅调整IP的表述形式,不影响方案落地;
- 新增维护要点提示,明确需根据企业实际环境替换通用表述为具体网段/IP。
