Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

[BUG]作为DOH服务端的时候请求报错400 #162

Closed
linusxiong opened this issue Sep 12, 2021 · 11 comments
Closed

[BUG]作为DOH服务端的时候请求报错400 #162

linusxiong opened this issue Sep 12, 2021 · 11 comments
Labels
bug Something isn't working

Comments

@linusxiong
Copy link

出现了什么问题
使用HTTP或者DOH服务时,使用DOH均报错400,且debug模式下日志中未检测到有dns请求,使用udp,dot,tcp均正常,使用caddy反向代理http同样报错400,但是使用http模式本地curl正常返回200,doh没试,但是应该是一样正常的,唯独远程请求时报错400

root@debian:~# curl -H 'accept: application/dns-message' 'http://127.0.0.1:60199/dns-query?dns=q80BAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB' -k -v
* Expire in 0 ms for 6 (transfer 0x564bfedbdfb0)
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x564bfedbdfb0)
* Connected to 127.0.0.1 (127.0.0.1) port 60199 (#0)
> GET /dns-query?dns=q80BAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB HTTP/1.1
> Host: 127.0.0.1:60199
> User-Agent: curl/7.64.0
> accept: application/dns-message
> 
< HTTP/1.1 200 OK
< Content-Type: application/dns-message
< Date: Sun, 12 Sep 2021 18:01:10 GMT
< Content-Length: 75
< 
Warning: Binary output can mess up your terminal. Use "--output -" to tell 
Warning: curl to output it to your terminal anyway, or consider "--output 
Warning: <FILE>" to save to a file.
* Failed writing body (0 != 75)
* Closing connection 0

如何重现

描述一下如何重现该问题。请尽可能的包含:

mosdns 的版本号(mosdns -v):1.8.6

使用的启动参数或启动方式:systemctl启动

操作系统和平台:debian 10 x64

使用的配置文件:

log:
  level: info
  file: "./log.log"
plugin:
  - tag: inbound_server
    type: server
    args:
      entry:
        - ecs
        - cache
        - main_sequence
      server:
        - protocol: doh
          addr: :60190
          timeout: 5
          idle_timeout: 30
          cert: '/root/.acme.sh/脱敏/fullchain.cer'
          key: '/root/.acme.sh/脱敏.key'
          url_path: '/dns-query'
          get_user_ip_from_header: 'X-Forwarded-For'
        - protocol: udp
          addr: :60150
        - protocol: tcp
          addr: :60151
        - protocol: dot
          addr: :60195
          timeout: 5
          idle_timeout: 30
          cert: '/root/.acme.sh/脱敏/fullchain.cer'
          key: '/root/.acme.sh/脱敏.key'
  - tag: main_sequence
    type: sequence
    args:
      exec:
        - if:
            - query_is_local_domain   # 已知的cn域名
            - '!_query_is_common'     # 和不常见的请求类型
          exec:
            - forward_dnspod           # 用dnspod服务器
            - _end

        - if:
            - query_is_non_local_domain  # 已知的非cn域名
          exec:
            - forward_google             # 用google服务器
            - _end

        - forward_dnspod               # 先请求转发至本地服务器
        - if:
            - response_has_local_ip   # 如果应答包含cn IP
          exec:
            - _end                    # 就直接采用结果
        - forward_google             # 否则去请求google服务器的结果
# 匹配本地域名的插件
  - tag: query_is_local_domain
    type: query_matcher
    args:
      domain:
        - 'ext:./geosite.dat:cn'

  # 匹配非本地域名的插件
  - tag: query_is_non_local_domain
    type: query_matcher
    args:
      domain:
        - 'ext:./geosite.dat:geolocation-!cn'

  # 匹配广告域名的插件
  # - tag: query_is_ad_domain
  #   type: query_matcher
  #   args:
  #     domain:
  #       - 'ext:./geosite.dat:category-ads-all'

  # 匹配本地 IP 的插件
  - tag: response_has_local_ip
    type: response_matcher
    args:
      ip:
        - 'ext:./geoip.dat:cn'
  # 添加ECS的插件
  - tag: ecs
    type: ecs
    args:
      auto: true
      force_overwrite: false
  # 缓存插件
  - tag: cache
    type: cache
    argus: 
      size: 10000
      cleaner_interval: 180
  # 转发插件
  - tag: forward_google
    type: fast_forward
    args:
      upstream:
        - addr: 1.1.1.1
          trusted: true 
      deduplicate: true
  - tag: forward_dnspod
    type: fast_forward
    args:
      upstream:
        - addr: 119.29.29.29
          trusted: true 
      deduplicate: true
@linusxiong
Copy link
Author

linusxiong commented Sep 13, 2021

0.0.0.0地址请求400, https模式

root@debian:~# curl https://0.0.0.0:60199 -k -v
* Expire in 0 ms for 6 (transfer 0x55ecce553fb0)
*   Trying 0.0.0.0...
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x55ecce553fb0)
* Connected to 0.0.0.0 (127.0.0.1) port 60199 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: none
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=脱敏
*  start date: Sep 11 15:34:32 2021 GMT
*  expire date: Dec 10 15:34:31 2021 GMT
*  issuer: C=US; O=Let's Encrypt; CN=R3
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x55ecce553fb0)
> GET / HTTP/2
> Host: 0.0.0.0:60199
> User-Agent: curl/7.64.0
> Accept: */*
> 
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* Connection state changed (MAX_CONCURRENT_STREAMS == 250)!
< HTTP/2 404 
< content-length: 0
< date: Mon, 13 Sep 2021 01:20:26 GMT
< 
* Connection #0 to host 0.0.0.0 left intact
root@debian:~# curl https://0.0.0.0:60199/dns-query -k -v
* Expire in 0 ms for 6 (transfer 0x563aefc54fb0)
*   Trying 0.0.0.0...
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x563aefc54fb0)
* Connected to 0.0.0.0 (127.0.0.1) port 60199 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: none
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=脱敏
*  start date: Sep 11 15:34:32 2021 GMT
*  expire date: Dec 10 15:34:31 2021 GMT
*  issuer: C=US; O=Let's Encrypt; CN=R3
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x563aefc54fb0)
> GET /dns-query HTTP/2
> Host: 0.0.0.0:60199
> User-Agent: curl/7.64.0
> Accept: */*
> 
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* Connection state changed (MAX_CONCURRENT_STREAMS == 250)!
< HTTP/2 400 
< content-length: 0
< date: Mon, 13 Sep 2021 01:20:49 GMT
< 
* Connection #0 to host 0.0.0.0 left intact

@linusxiong
Copy link
Author

linusxiong commented Sep 13, 2021

貌似加上dns-message参数就200了,但是实际使用doggo查询依旧400

root@debian:~# curl -H 'accept: application/dns-message' 'https://127.0.0.1:60199/dns-query?dns=q80BAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB' -k -v
* Expire in 0 ms for 6 (transfer 0x55c186360fb0)
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x55c186360fb0)
* Connected to 127.0.0.1 (127.0.0.1) port 60199 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: none
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=脱敏
*  start date: Sep 11 15:34:32 2021 GMT
*  expire date: Dec 10 15:34:31 2021 GMT
*  issuer: C=US; O=Let's Encrypt; CN=R3
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x55c186360fb0)
> GET /dns-query?dns=q80BAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB HTTP/2
> Host: 127.0.0.1:60199
> User-Agent: curl/7.64.0
> accept: application/dns-message
> 
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* Connection state changed (MAX_CONCURRENT_STREAMS == 250)!
< HTTP/2 200 
< content-type: application/dns-message
< content-length: 75
< date: Mon, 13 Sep 2021 01:26:19 GMT
< 
Warning: Binary output can mess up your terminal. Use "--output -" to tell 
Warning: curl to output it to your terminal anyway, or consider "--output 
Warning: <FILE>" to save to a file.
* Failed writing body (0 != 75)
* stopped the pause stream!
* Connection #0 to host 127.0.0.1 left intact
doggo www.google.com @https://脱敏:60199/dns-query
ERROR[2021-09-13T09:19:36+08:00] error looking up DNS records                  error="error from nameserver 400 Bad Request"

@IrineSistiana
Copy link
Owner

#160 可能相关。

有的 curl http 头不对。

Accept: /

@linusxiong
Copy link
Author

#160 可能相关。

有的 curl http 头不对。

Accept: /

但是貌似根据doggo的源码看,好像是有添加http头的
https://github.com/mr-karan/doggo/blob/main/pkg/resolvers/doh.go

@linusxiong
Copy link
Author

目前在quantumult x中测试正常,但是感觉还是有点别扭,使用doggo之类的工具没办法测试是否有效,希望作者能够帮忙适配一下,另外作者有doq的计划嘛?

@IrineSistiana
Copy link
Owner

IrineSistiana commented Sep 13, 2021

doggo 居然用的 POST 而不是 GET.....比较罕见。检查发现 mosdns 处理 POST 请求有 bug。是mosdns 的问题。

内置 doq 服务端暂时没想法。因为标准还没定。先套娃吧....

@IrineSistiana IrineSistiana added the bug Something isn't working label Sep 13, 2021
@linusxiong
Copy link
Author

另外当使用ecs的时候,谷歌dns作为上游不会返回数据

@rampageX
Copy link

另外当使用ecs的时候,谷歌dns作为上游不会返回数据

谷歌的 EDNS 好像禁止了 /32 这个精度的值,只允许 /24 。

dig @8.8.8.8 wsj.com +subnet=1.1.1.1

服务器会返回这个信息:

"..Provided ECS subnet includes 32 bits, but no more than 24 are allowed. https://developers.google.com/speed/public-dns/docs/ecs"

换成 /24 没问题:

dig @8.8.8.8 wsj.com +subnet=1.1.1.0/24

@linusxiong
Copy link
Author

另外当使用ecs的时候,谷歌dns作为上游不会返回数据

谷歌的 EDNS 好像禁止了 /32 这个精度的值,只允许 /24 。

dig @8.8.8.8 wsj.com +subnet=1.1.1.1

服务器会返回这个信息:

"..Provided ECS subnet includes 32 bits, but no more than 24 are allowed. https://developers.google.com/speed/public-dns/docs/ecs"

换成 /24 没问题:

dig @8.8.8.8 wsj.com +subnet=1.1.1.0/24

ecs那个插件那里写了,默认mask就是/24呀

@linusxiong
Copy link
Author

不仅仅是这些问题,chrome的doh和edge的doh都无法使用,包括安卓自带的dot,也无法使用

9月 13 19:13:16 localhost.localdomain mosdns[211888]: 2021/09/13 19:13:16 http: TLS handshake error from 124.64.xxx.xxx:2205: read tcp 192.168.xxx.xxx:443->124.64.xxx.xxx:2205: read: connection reset by peer
9月 13 19:13:17 localhost.localdomain mosdns[211888]: 2021/09/13 19:13:17 http: TLS handshake error from 120.239.xxx.xxx:43138: EOF
9月 13 19:24:26 localhost.localdomain mosdns[211888]: 2021/09/13 19:24:26 http2: server connection error from 120.37.xxx.xxx:55989: connection error: PROTOCOL_ERROR

@linusxiong
Copy link
Author

doggo 居然用的 POST 而不是 GET.....比较罕见。检查发现 mosdns 处理 POST 请求有 bug。是mosdns 的问题。

内置 doq 服务端暂时没想法。因为标准还没定。先套娃吧....

日志中又出现几种报错,加上chrome自带的doh和edge的doh无法使用,还有安卓自带的dot无法使用,tls握手问题

2021-09-13T19:42:21.040+0800	warn	inbound_server	dns_handler/server_handler.go:88	entry returned an err	{"query": "msg.qy.net. IN AAAA 0 23", "error": "plugin tag ecs not defined"}
2021-09-13T19:42:25.313+0800	warn	inbound_server	dns_handler/server_handler.go:88	entry returned an err	{"query": "weather-data.apple.com. IN HTTPS 0 347", "error": "main_sequence: exec command failed: forward_domestic: context canceled"}
2021-09-13T19:42:26.059+0800	warn	forward_domestic	utils/utils.go:316	upstream failed	{"query": "i.vip.iqiyi.com. IN A 0 82", "from": "119.28.28.28", "error": "read timeout"}
2021-09-13T19:46:00.151+0800	warn	inbound_server	dns_handler/server_handler.go:104	write response	{"query": "c.passcloud.xyz. IN A 64870 28540", "error": "use of closed network connection"}

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants