IrineSistiana / mosdns

一个 DNS 转发器
GNU General Public License v3.0
3k stars 340 forks source link

google DNS服务器会拒绝特定的ECS请求 #621

Open zhaibin18 opened 1 year ago

zhaibin18 commented 1 year ago

在提交之前,请确认

mosdns 版本

v4.5.3-0-g760a660

操作系统

openwrt

Bug 描述和复现步骤

google DNS服务器会拒绝特定的ECS请求

dig e2490.dscf.akamaiedge.net
; <<>> DiG 9.18.7 <<>> e2490.dscf.akamaiedge.net
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: **REFUSED**, id: 59697
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;e2490.dscf.akamaiedge.net.     IN      A

;; Query time: 49 msec
;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
;; WHEN: Tue Feb 21 23:07:47 CST 2023
;; MSG SIZE  rcvd: 54

使用的配置文件

- tag: 'ecs0'
    type: 'ecs'
    args:
      auto: false
      ipv4: '193.110.202.3'
      force_overwrite: true
      mask4: 24

        - forward_local
        - if: response_has_local_ip
          exec:
            - _return
        - ecs0
        - forward_remote

mosdns 的 log 记录

Frame 14: 109 bytes on wire (872 bits), 109 bytes captured (872 bits)
Linux cooked capture v1
Internet Protocol Version 4, Src: 8.8.8.8, Dst: 123.123.100.103
User Datagram Protocol, Src Port: 53, Dst Port: 38020
Domain Name System (response)
    Transaction ID: 0x3099
    Flags: 0x8185 Standard query response, Refused
        1... .... .... .... = Response: Message is a response
        .000 0... .... .... = Opcode: Standard query (0)
        .... .0.. .... .... = Authoritative: Server is not an authority for domain
        .... ..0. .... .... = Truncated: Message is not truncated
        .... ...1 .... .... = Recursion desired: Do query recursively
        .... .... 1... .... = Recursion available: Server can do recursive queries
        .... .... .0.. .... = Z: reserved (0)
        .... .... ..0. .... = Answer authenticated: Answer/authority portion was not authenticated by the server
        .... .... ...0 .... = Non-authenticated data: Unacceptable
        .... .... .... 0101 = Reply code: Refused (5)
    Questions: 1
    Answer RRs: 0
    Authority RRs: 0
    Additional RRs: 1
    Queries
        e2490.dscf.akamaiedge.net: type A, class IN
            Name: e2490.dscf.akamaiedge.net
            [Name Length: 25]
            [Label Count: 4]
            Type: A (Host Address) (1)
            Class: IN (0x0001)
    Additional records
        <Root>: type OPT
            Name: <Root>
            Type: OPT (41)
            UDP payload size: 512
            Higher bits in extended RCODE: 0x00
            EDNS0 version: 0
            Z: 0x0000
                0... .... .... .... = DO bit: Cannot handle DNSSEC security RRs
                .000 0000 0000 0000 = Reserved: 0x0000
            Data length: 11
            Option: CSUBNET - Client subnet
                Option Code: CSUBNET - Client subnet (8)
                Option Length: 7
                Option Data: 00011800677566
                Family: IPv4 (1)
                Source Netmask: 24
                Scope Netmask: 0
                Client Subnet: 103.117.102.0
    [Request In: 9]
    [Time: 0.055988000 seconds]
IrineSistiana commented 1 year ago

https://groups.google.com/g/public-dns-discuss/c/JUc79GnmnQk

zhaibin18 commented 1 year ago

在mosdns能否把这种Refused没有结果的响应过滤掉。

urlesistiana commented 1 year ago

RFC7871 https://www.rfc-editor.org/rfc/rfc7871#section-7.1.1 的意思应该是“附加的 ECS 的请求如果收到 REFUSE ,用无 ECS 的请求重试”

zhaibin18 commented 1 year ago

这个问题的本质是我设置了4个上游dns server,包含google的,只是google的响应最快但是因为带了ecs返回了refused的结果,其他的dns server还是能返回正确地址的,从最终使用者的角度,只要能有一个正确的返回结果就行,所以建议如果上游返回了refused的结果就过滤掉,改用其他上游返回的结果就可以,希望作者可以考虑,多谢!

sieveLau commented 1 year ago

用v4版本写response matcher,rcode不是0的就forward到另一个上游,直到rcode为0为止就可以了。示例:

plugins:
  - tag: upstream_success
    type: response_matcher
    args:
      rcode: [0]

  - tag: main_sequence
    type: sequence
    args:
      exec:

        # 优先返回ipv4结果
        - _prefer_ipv4
        - ecs_auto
        - to_google
        - if: (! upstream_success)
          exec:
            - ecs_auto
            - to_quad9
        - if: (! upstream_success)
          exec:
            - _no_ecs
            - to_cloudflare
        - _return