靠这套内网DNS解决“IPv6优先级高+动态IPv6白名单配置繁琐+域名商IPv6不能关”的访问死局

前言:不少企业会碰到这样的拧巴网络场景:只有一个固定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部署

参考通用流程搭建环境:

  1. 安装VM虚拟机(选择桥接模式,确保虚拟机IP为已加白的固定IPv4、可接入企业内网);
  2. 在VM中安装Ubuntu 24.04系统;
  3. 配置内网静态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地址。

八、通用维护要点

  1. 解析文件开头的$TTL 3600不可删除,否则会触发"no owner"报错;
  2. 配置修改后需重启Bind9:sudo systemctl restart bind9,确保配置生效;
  3. 日志排查:服务异常看sudo journalctl -u bind9 -f,同步脚本异常看cat /var/log/cf_sync.log
  4. IPv6相关:必须系统+Bind9双关,避免终端发起未加白的动态IPv6请求;
  5. 安全配置:避免禁用systemd-resolved、避免配置公网DNS(防止绕开本地过滤)、避免any监听网卡;
  6. 白名单维护:CDN IP变更后需及时更新脚本中的已加白列表,确保同步的IP均在放行范围内;
  7. 网段/IP替换:所有标注"需根据实际环境配置"的网段/IP,需替换为企业实际的内网网段、已加白固定IPv4。

总结

  1. 所有具体IP地址已替换为通用文字描述(如「内网静态IPv4(已加白)」「SD-WAN内网网段(需根据实际环境配置)」),无企业专属IP信息;
  2. 保留方案核心逻辑(双关IPv6、Bind9安全配置、CDN自动同步),仅调整IP的表述形式,不影响方案落地;
  3. 新增维护要点提示,明确需根据企业实际环境替换通用表述为具体网段/IP。
相关推荐
GCKJ_08242 小时前
【观成科技】银狐再进化:新型变种加密通信机制分析
运维·服务器·网络
Lueeee.2 小时前
RTMP协议
linux·网络
未来之窗软件服务4 小时前
幽冥大陆(六十八) PHP8.x SSL 文字加密—东方仙盟古法结界
网络·网络协议·ssl·仙盟创梦ide·东方仙盟·文字加密
G_H_S_3_10 小时前
【网络运维】Docker 存储:镜像层与数据卷的管理应用
linux·运维·网络·docker
还鮟12 小时前
靶机远程控制实验命令与入门实践(Linux)
linux·网络·安全
Hello.Reader13 小时前
Flink Process Table Functions(PTF)实战详解:把 SQL 变成“可编程算子”,状态、时间、定时器一把梭
网络·sql·flink
2301_7737303115 小时前
网络编程—TCP传输控制协议
服务器·网络·tcp/ip
云老大TG:@yunlaoda36015 小时前
华为云国际站代理商DAS的跨境合规适配是如何保障数据合规的?
网络·数据库·华为云
TG:@yunlaoda360 云老大15 小时前
华为云国际站代理商DAS的跨境合规适配在游戏出海场景中的应用
服务器·网络·游戏·华为云