V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
phpfpm
V2EX  ›  宽带症候群

记录一次 DNS 故障:三层做网关,机器总是请求三层网关的 AAAA DNS 然后超时

  •  
  •   phpfpm · 2023-03-14 10:49:26 +08:00 · 1649 次点击
    这是一个创建于 619 天前的主题,其中的信息可能已经有所发展或是发生改变。

    TL;DR

    正常环境下三层交换机没有配置 ipv6 出口,不应该对 AAAA 的请求有响应。

    因为错误配置三层交换机的一个 VLANIP 为 DHCP ,导致三层上的 DNS Server 多了一个 STATIC 的 DNS SERVER ,会尝试走这个出口解析 AAAA ,导致超时。

    每次请求的时候都会尝试解析一次之前没有正常解析的 AAAA ,然后就一直超时

    下掉这个 DHCP 的 VLANIP 之后一切恢复正常。

    正确的处理思路

    1. 在业务代码 curl 侧诊断,定位速度慢的瓶颈( dns 解析)
    2. 抓 dns 的包,发现第一次请求新域名会同时返回 A 和 AAAA 结果,AAAA 较慢且超时
    3. 看交换机的上游 DNS (见最后),DNSv6 的解析结果列表出现了域名对应的 v6 地址,不符合预期
    4. 下掉不合适的三层网关,问题解决

    网络拓扑

    从外向内看:

    1. 光猫
    2. Openwrt(192.168.0.20/24, 出口, DNS)
    3. 三层交换机(192.168.0.50/24, DHCP(GW=三层,DNS=三层), DNS Proxy)
    4. 服务器(192.168.0.178/24), 走 dhcp ,网关是 50,ubuntu 22.04

    抓包

    root@port:/etc/ipsec.d/certs# tcpdump -nn port 53
    tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
    listening on ens160, link-type EN10MB (Ethernet), snapshot length 262144 bytes
    10:39:21.024461 IP 192.168.0.167.44834 > 192.168.0.50.53: 25756+ A? xyzw.example.com. (32)
    10:39:21.024583 IP 192.168.0.167.36106 > 192.168.0.50.53: 26490+ AAAA? xyzw.example.com. (32)
    10:39:21.026904 IP 192.168.0.50.53 > 192.168.0.167.36106: 26490 ServFail- 0/0/0 (32)
    10:39:21.051091 IP 192.168.0.50.53 > 192.168.0.167.44834: 25756 1/0/0 A 120.25.87.140 (48)
    
    

    很明显,机器发起请求的时候,都会同时请求 A 解析和 AAAA 解析,AAAA 解析延迟也会造成这样的效果。

    机器的 ip 的结果

    user@web:/opt$ ip a
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
        inet6 ::1/128 scope host
           valid_lft forever preferred_lft forever
    2: enp0s25: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
        link/ether 68:f7:28:2a:59:4d brd ff:ff:ff:ff:ff:ff
        inet 192.168.0.178/24 brd 192.168.0.255 scope global dynamic enp0s25
           valid_lft 74054sec preferred_lft 74054sec
    3: wlp3s0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
        link/ether e8:b1:fc:ad:03:90 brd ff:ff:ff:ff:ff:ff
    user@web:/opt$ ip r
    default via 192.168.0.50 dev enp0s25 proto dhcp src 192.168.0.178 metric 100
    192.168.0.0/24 dev enp0s25 proto kernel scope link src 192.168.0.178
    192.168.0.50 dev enp0s25 proto dhcp scope link src 192.168.0.178 metric 100
    
    

    在机器上基于 php/curl 请求

    curl 请求正常发,curl_getinfo诊断显示:

        [total_time] => 4.252037
        [namelookup_time] => 4.114418
        [connect_time] => 4.168542
        [pretransfer_time] => 4.222082
    

    也即在 dns 上花费了较多时间

    加上这句之后 dns 解析时间正常

    curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
    

    也即强制不解析 ipv6 就好

    在机器上 dig 的结果

    dig -4

    1. dig -4 baidu.com
    2. 秒回
    3. dns 走的是 127.0.0.53#53, resolvd
    4. dig -4 @192.168.0.50 baidu.com
    5. 秒回
    6. dig -4 @192.168.0.20 baidu.com
    7. 秒回

    dig -6

    1. dig -6 baidu.com
    2. 15s 后超时
    3. dig -6 @192.168.0.50 baidu.com
    4. 秒回
    5. 显示的 dns 服务器是
    6. ;; SERVER: ::ffff:192.168.0.50#53(::ffff:192.168.0.50)
    7. 0.20 同理,不赘述

    traceroute 的结果

    ygs@port:~$ traceroute baidu.com
    traceroute to baidu.com (110.242.68.66), 30 hops max, 60 byte packets
     1  _gateway (192.168.0.50)  0.800 ms  1.084 ms  1.458 ms
     2  bogon (192.168.0.20)  17.737 ms  0.200 ms  17.719 ms
     3  bogon (10.119.0.1)  27.133 ms  27.209 ms  27.127 ms
     4  211.136.62.225 (211.136.62.225)  25.922 ms  25.888 ms  17.708 ms
     ...
     ...
    

    这里出现了最近出现的一个问题:我的 mac 和内网其他机器有时候都会显示为 bogon ,不知道为啥

    原因

    回到开头,网关上面有一台机器错误的返回了我的子网的 dns 反向解析,当然不认识了,返回 bogon

    H3C 交换机诊断结果

    已解析 IP

    ipv6 部分出现了已解析的 ip ,很明显我的 op 是不可能响应 AAAA 的

    DNS 列表

    web 侧只看到了 op 的地址,但是深挖一下

    [H3C]display dns server
    Type:
      D: Dynamic    S: Static
    
    No. Type  IP address
    1   S     192.168.0.21
    2   D     192.168.100.1
    
    ##### 去掉三层接口之后
    [H3C]display dns server
    Type:
      D: Dynamic    S: Static
    
    No. Type  IP address
    1   S
    
    

    恢复正常

    10 条回复    2023-03-14 22:21:38 +08:00
    Sekai
        1
    Sekai  
       2023-03-14 11:34:34 +08:00
    哈哈哈 又是 ipv6 闯祸
    maybeonly
        2
    maybeonly  
       2023-03-14 11:53:05 +08:00
    emmmmmm
    怎么说
    给不给回 AAAA 记录和你用 v4 还是 v6 解析是完全无关的才对
    虽然有一些有 bug 或者配置的 dns 服务器没能正确处理 AAAA 记录,但是和他本身有没有 v6 也没有关系才对
    回 servfail 虽然不好,但是也不是完全不能接受的
    至于 dig 的-6 参数,是指其应当通过 v4 还是 v6 解析……man 里边是这么写的
    ```
    If no server argument is provided, dig consults /etc/resolv.conf; if an address is found there, it queries the name server at that address. If either of
    the -4 or -6 options are in use, then only addresses for the corresponding transport will be tried. If no usable addresses are found, dig will send the
    query to the local host. The reply from the name server that responds is displayed.
    ```
    而且 dns 这东西是可以被缓存的,连续来同样的查询的话后续可能就是缓存命中而已(没命中的话就要向转发的 dns 查询或者自己做递归)
    还有 traceroute 之类的不想让他反向解析的话加上-n 就好了,内网 ip 反解变成 bogon 并没有错。
    最后……192.168.100.1 哪儿来的?不管用不用三层交换,建议还是直接下发可靠的 dns ,这个结论上倒是没有错。个人理解不直接使用运营商的 dns 的原因,一来是客户到运营商可能有些 rtt (特别是在 cpe 接入的场合),另一方面会在出口上产生大量的 dns 的 nat 。至于自家的三层交换这俩都不存在,那直接用可靠的内网 dns 就好了。
    jsq2627
        3
    jsq2627  
       2023-03-14 12:09:13 +08:00
    DNS 是否响应 AAAA 记录,和你网络是否支持 ipv6 、DNS 服务器是否监听 ipv6 都无关。把 AAAA 想象成 CNAME 你就理解了,他们不过是 DNS packet 的 payload 而已

    真正决定是否请求 AAAA 记录、是否走 ipv6 是客户端决定的。比如 https://en.wikipedia.org/wiki/Happy_Eyeballs 算法,就会在首次请求时同时获取 A 和 AAAA 记录,并根据多重因素判断是否使用 AAAA 的解析结果
    phpfpm
        4
    phpfpm  
    OP
       2023-03-14 12:30:38 +08:00
    @maybeonly 100.1 三层接的另外一个路由器,本来就接着就好,就当不存在(三层作为路由器的一个基于 vlan 的交换机,做二层交换机)然后我要死不死设置一个三层 ip ,导致 100.1 做 dhcp 的时候顺手下发了一个 dns 。

    所以我一直想求一个内网 dns 的最佳实践
    目前是通过 op 的内外分流,国内外分别用阿里的 DoH 和谷歌的 DoH


    我想要一个稳定的,单独部署的 dns 服务作为三层交换机的上游 dns 服务~?
    phpfpm
        5
    phpfpm  
    OP
       2023-03-14 12:31:53 +08:00
    @jsq2627 是的,之前我踩过 dnsv6 的坑,我能理解为什么做 aaaa 解析
    只是没想明白我明明没有 dnsv6 的出口( op 我设置的忽略所有的 aaaa 解析,应该会立即返回失败才对)

    至于你说的算法我理解了,现代一点的操作系统基本都会这么做,这也就导致了我请求变慢失败
    maybeonly
        6
    maybeonly  
       2023-03-14 13:15:56 +08:00
    本机 dns 是 127.0.0.53:53 的话,应该是开了 resolved (叫什么?反正是用 resolvectl 控制的那个东西),应当检查它的配置。
    如果单纯是抓包抓到的这些的话,你的 dns 确实即刻 4a 解析失败了,没有拖累网速。
    内网稳定的 dns 一般无需单独部署,一般用 op 上的 dnsmasq 即可,dhcp 直接下发该 dns 而不需要再经过其他设备中转。
    defunct9
        7
    defunct9  
       2023-03-14 13:31:13 +08:00   ❤️ 2
    什么乱七八糟的
    phpfpm
        8
    phpfpm  
    OP
       2023-03-14 14:24:08 +08:00
    @maybeonly resolvd 是根据 dhcp 配置的,这个工作一直正常
    核心还是三层的逻辑(因为有其他出接口,导致错误引入其他出接口分发的 dns )

    @defunct9 看第一段就像,后面是辅助判断一些信息
    defunct9
        9
    defunct9  
       2023-03-14 15:18:29 +08:00
    我觉得像是 Openwrt(192.168.0.20/24, 出口, DNS)这个玩意没配好。具体的还得查。
    neroxps
        10
    neroxps  
       2023-03-14 22:21:38 +08:00 via iPhone
    跨三层的 ipv6 还没空仔细研究。

    我搞了个国内就解析完整 aaaa 国外就解析 fake-ip 的 dns ( coredns 插件实现,国外的是 clash 规则 dnsmasq list 等规则均支持 ) 舒服至极。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2235 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 00:59 · PVG 08:59 · LAX 16:59 · JFK 19:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.