IrineSistiana / mosdns

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

[Bug] nftset 共用 set: netlink receive: file exists #702

Open wangmice opened 1 year ago

wangmice commented 1 year ago

在提交之前,请确认

mosdns 版本

fix_667

操作系统

ubuntu

Bug 描述和复现步骤

在第一次启动mosdns后,第一次查询被墙域名,会返回servfail。如果取消将ip加入nftset的动作,则正常,估计是这个插件的原因 debug日志: 2023-07-29T08:33:02.234+0800 WARN udp_server entry err {"query": {"uqid": 1, "client": "::ffff:127.0.0.1", "qname": "www.google.com.", "qtype": 1, "qclass": 1, "rcode": 0, "elapsed": "583.769324ms"}, "error": "nftable: failed to add ipv4 elems [172.217.12.100/24]: conn.Receive: netlink receive: file exists"} 估计是第一次查询域名时未cache,但是添加进nft时因ip已经存在(ip已经被其他程序添加了),添加ip进nft set失败导致该错误。第二次查询因为cache命中,没有添加nftset的动作,所以查询正常。

使用的配置文件

log:
  level: debug
  file: "/var/run/mosdns/mosdns.log"

plugins:
  # 缓存
  - tag: cache
    type: cache
    args:
      size: 10240
      lazy_cache_ttl: 86400

  # 重定向域名
  - tag: redirect
    type: redirect
    args:
      rules:
        - www.cnbeta.com www.cnbeta.com.cdn.cloudflare.net

  # 转发至国内DNS,并发查询
  - tag: forward_local
    type: forward
    args:
      concurrent: 2
      upstreams:
        - addr: udp://119.29.29.29
        - addr: udp://223.5.5.5

  # 转发至国外DNS,并发查询
  - tag: forward_remote
    type: forward
    args:
      concurrent: 2
      upstreams:
        - tag: google_doh
          addr: "https://dns.google/dns-query"
          dial_addr: "8.8.8.8"
          socks5: "127.0.0.1:1085"
          idle_timeout: 30
          enable_pipeline: false
          enable_http3: false
          max_conns: 4
        - addr: tcp://8.8.4.4
          dial_addr: "8.8.4.4"
          socks5: "127.0.0.1:1085"
          idle_timeout: 30
          enable_pipeline: true
          enable_http3: false
          max_conns: 4

  # 自定义hosts
  - tag: hosts
    type: hosts
    args:
      files:
        - "/usr/local/etc/mosdns/hosts.txt"

  # china ip和自己的vps ip
  - tag: local_ip
    type: ip_set
    args:
      files:
        - /usr/local/etc/mosdns/cn.txt
        - /usr/local/etc/mosdns/myvpsip.txt

  # fallback的primary服务器,返回非国内ip则drop_resp
  - tag: local_sequence
    type: sequence
    args:
      - exec: $forward_local
      - matches: "resp_ip $local_ip"
        exec: accept
      - exec: drop_resp

  # fallback的secondary服务器,返回非国内ip则添加至ipset,返回国内ip只接受不会添加ipset
  - tag: remote_sequence
    type: sequence
    args:
      - exec: prefer_ipv4
      - exec: $forward_remote
      - matches:
          - has_wanted_ans
          - "!resp_ip $local_ip"
        exec: nftset ip,xray,gfwlist,ipv4_addr,24 ip6,xray,gfwlist6,ipv6_addr,64
      - matches: has_wanted_ans
        exec: accept

  # fallback sequence
  - tag: fallback
    type: fallback
    args:
      primary: local_sequence
      secondary: remote_sequence
      threshold: 500
      always_standby: true

  # gfwlist解析出的ip添加至ipset,添加前先判断是否为国内ip或内网ip
  - tag: gfw-list
    type: sequence
    args:
      - exec: ttl 300-3600
      - matches: "!resp_ip $local_ip"
        exec: nftset ip,xray,gfwlist,ipv4_addr,24 ip6,xray,gfwlist6,ipv6_addr,64
      - exec: accept

  # 主运行序列
  - tag: main_sequence
    type: sequence
    args:
      - exec: $hosts
      - matches: has_resp
        exec: accept

      # - matches: qtype 65
      #   exec: reject 3

      - matches: qname &./reject-list.txt &./my-reject-list.txt
        exec: reject

      - exec: prefer_ipv4

      - exec: $redirect

      # 动态域名跳过缓存
      - matches: "!qname mnwk.xyz"
        exec: $cache
      - matches: has_resp
        exec: accept

      - matches: qname &./direct-list.txt
        exec: $forward_local
      - matches: has_wanted_ans
        exec: accept

      - matches: qname &./proxy-list.txt
        exec: $remote_sequence
      #- matches: has_wanted_ans
      #  exec: goto gfw-list

      - exec: $fallback

  # 启动监听服务
  - tag: udp_server
    type: udp_server
    args:
      entry: main_sequence
      listen: :5335

  - tag: tcp_server
    type: tcp_server
    args:
      entry: main_sequence
      listen: :5335

mosdns 的 log 记录

2023-07-29T08:32:57.960+0800    INFO    service is shutting down
2023-07-29T08:32:57.960+0800    INFO    starting shutdown sequences
2023-07-29T08:32:57.960+0800    INFO    closing plugin  {"tag": "cache"}
2023-07-29T08:32:57.960+0800    INFO    closing plugin  {"tag": "local_sequence"}
2023-07-29T08:32:57.960+0800    INFO    closing plugin  {"tag": "tcp_server"}
2023-07-29T08:32:57.960+0800    INFO    closing plugin  {"tag": "forward_remote"}
2023-07-29T08:32:57.960+0800    INFO    closing plugin  {"tag": "gfw-list"}
2023-07-29T08:32:57.960+0800    INFO    closing plugin  {"tag": "udp_server"}
2023-07-29T08:32:57.961+0800    INFO    closing plugin  {"tag": "forward_local"}
2023-07-29T08:32:57.961+0800    INFO    closing plugin  {"tag": "remote_sequence"}
2023-07-29T08:32:57.961+0800    INFO    closing plugin  {"tag": "main_sequence"}
2023-07-29T08:32:57.961+0800    INFO    all plugins were closed
2023-07-29T08:32:57.961+0800    INFO    server exited
2023-07-29T08:32:58.022+0800    INFO    loading plugin  {"tag": "cache", "type": "cache"}
2023-07-29T08:32:58.023+0800    INFO    loading plugin  {"tag": "redirect", "type": "redirect"}
2023-07-29T08:32:58.023+0800    INFO    redirect    redirect rules loaded   {"length": 1}
2023-07-29T08:32:58.023+0800    INFO    loading plugin  {"tag": "forward_local", "type": "forward"}
2023-07-29T08:32:58.023+0800    INFO    loading plugin  {"tag": "forward_remote", "type": "forward"}
2023-07-29T08:32:58.023+0800    INFO    loading plugin  {"tag": "hosts", "type": "hosts"}
2023-07-29T08:32:58.023+0800    INFO    loading plugin  {"tag": "local_ip", "type": "ip_set"}
2023-07-29T08:32:58.029+0800    INFO    loading plugin  {"tag": "local_sequence", "type": "sequence"}
2023-07-29T08:32:58.029+0800    INFO    loading plugin  {"tag": "remote_sequence", "type": "sequence"}
2023-07-29T08:32:58.029+0800    INFO    loading plugin  {"tag": "fallback", "type": "fallback"}
2023-07-29T08:32:58.029+0800    INFO    loading plugin  {"tag": "gfw-list", "type": "sequence"}
2023-07-29T08:32:58.029+0800    INFO    loading plugin  {"tag": "main_sequence", "type": "sequence"}
2023-07-29T08:32:58.162+0800    INFO    loading plugin  {"tag": "udp_server", "type": "udp_server"}
2023-07-29T08:32:58.162+0800    INFO    loading plugin  {"tag": "tcp_server", "type": "tcp_server"}
2023-07-29T08:32:58.163+0800    INFO    all plugins are loaded
2023-07-29T08:33:02.234+0800    WARN    udp_server  entry err   {"query": {"uqid": 1, "client": "::ffff:127.0.0.1", "qname": "www.google.com.", "qtype": 1, "qclass": 1, "rcode": 0, "elapsed": "583.769324ms"}, "error": "nftable: failed to add ipv4 elems [172.217.12.100/24]: conn.Receive: netlink receive: file exists"}
wangmice commented 1 year ago

现在代码也没人更新了,问题也没人解答了 @

zxbeltm commented 1 year ago

不会被抓了吧

wangmice commented 1 year ago

应该能处理一下这个nftset的错误,即使执行失败,也不应该导致解析结果不返回

skill7899 commented 10 months ago

我刚想用这个功能,因为有些ip已经在其它应用加载进来了,我再用nftset一些在mosdns认为是china_ip的,插入进去。看了你上面,应该是已经存在了,就会报错了。

IrineSistiana commented 10 months ago

如果 nftset 要写入的 ip 和 里面存在的 ip 不一样而且有重叠。会报错。

不建议和别的程序共用 set 。

wangmice commented 10 months ago

跟是否共用set无关,除非添加ip时先判断是否存在,原先存在的ip也可能是mosdns在先前查询时添加的。其实只要mosdns忽略添加失败的情况就行,就算ip没加set成功,也正常返回解析结果给客户端。

am009 commented 5 months ago

跟是否共用set无关,除非添加ip时先判断是否存在,原先存在的ip也可能是mosdns在先前查询时添加的。其实只要mosdns忽略添加失败的情况就行,就算ip没加set成功,也正常返回解析结果给客户端。

对,我也遇到了这个问题,要不直接(改一下代码)nft set模块那边直接忽略file exists报错吧,发现是file exists报错就直接当成功

am009 commented 5 months ago

我改了一下,可以在release里下载我的修改版:https://github.com/am009/mosdns OpenWRT ipk:https://github.com/am009/luci-app-mosdns/actions/runs/8338725563